@jbrowse/plugin-linear-genome-view 1.6.5 → 1.6.6

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 (25) hide show
  1. package/dist/BaseLinearDisplay/models/baseLinearDisplayConfigSchema.d.ts +1 -1
  2. package/dist/LinearBareDisplay/configSchema.d.ts +1 -1
  3. package/dist/LinearBasicDisplay/configSchema.d.ts +1 -1
  4. package/dist/LinearGenomeView/components/TrackContainer.d.ts +3 -2
  5. package/dist/index.d.ts +1 -1
  6. package/dist/plugin-linear-genome-view.cjs.development.js +118 -228
  7. package/dist/plugin-linear-genome-view.cjs.development.js.map +1 -1
  8. package/dist/plugin-linear-genome-view.cjs.production.min.js +1 -1
  9. package/dist/plugin-linear-genome-view.cjs.production.min.js.map +1 -1
  10. package/dist/plugin-linear-genome-view.esm.js +120 -230
  11. package/dist/plugin-linear-genome-view.esm.js.map +1 -1
  12. package/package.json +2 -2
  13. package/src/BaseLinearDisplay/components/BaseLinearDisplay.tsx +1 -1
  14. package/src/BaseLinearDisplay/models/BaseLinearDisplayModel.tsx +6 -1
  15. package/src/LinearBasicDisplay/model.ts +1 -1
  16. package/src/LinearGenomeView/components/HelpDialog.tsx +14 -1
  17. package/src/LinearGenomeView/components/LinearGenomeViewSvg.tsx +1 -13
  18. package/src/LinearGenomeView/components/OverviewScaleBar.tsx +7 -3
  19. package/src/LinearGenomeView/components/TrackContainer.tsx +24 -39
  20. package/src/LinearGenomeView/components/__snapshots__/LinearGenomeView.test.js.snap +194 -197
  21. package/src/LinearGenomeView/index.test.ts +44 -42
  22. package/src/LinearGenomeView/index.tsx +55 -131
  23. package/src/LinearGenomeView/volvoxDisplayedRegions.json +16 -0
  24. package/dist/LinearGenomeView/components/ReturnToImportFormDialog.d.ts +0 -9
  25. package/src/LinearGenomeView/components/ReturnToImportFormDialog.tsx +0 -83
@@ -58,13 +58,13 @@ var ArrowBackIcon = _interopDefault(require('@material-ui/icons/ArrowBack'));
58
58
  var IconButton = _interopDefault(require('@material-ui/core/IconButton'));
59
59
  var Slider = _interopDefault(require('@material-ui/core/Slider'));
60
60
  var ZoomOut = _interopDefault(require('@material-ui/icons/ZoomOut'));
61
- var Paper = _interopDefault(require('@material-ui/core/Paper'));
62
61
  var MoreVertIcon = _interopDefault(require('@material-ui/icons/MoreVert'));
63
62
  var DragIcon = _interopDefault(require('@material-ui/icons/DragIndicator'));
64
63
  var normalizeWheel = _interopDefault(require('normalize-wheel'));
65
64
  var colorManipulator = require('@material-ui/core/styles/colorManipulator');
66
65
  var Popover = _interopDefault(require('@material-ui/core/Popover'));
67
66
  var Tooltip$1 = _interopDefault(require('@material-ui/core/Tooltip'));
67
+ var Paper = _interopDefault(require('@material-ui/core/Paper'));
68
68
  var ErrorMessage = _interopDefault(require('@jbrowse/core/ui/ErrorMessage'));
69
69
  var AssemblySelector = _interopDefault(require('@jbrowse/core/ui/AssemblySelector'));
70
70
  var ArrowDown = _interopDefault(require('@material-ui/icons/KeyboardArrowDown'));
@@ -1349,7 +1349,7 @@ var useStyles$2 = /*#__PURE__*/core.makeStyles(function (theme) {
1349
1349
  color: theme.palette.common.white,
1350
1350
  fontFamily: theme.typography.fontFamily,
1351
1351
  padding: '4px 8px',
1352
- fontSize: theme.typography.pxToRem(10),
1352
+ fontSize: theme.typography.pxToRem(12),
1353
1353
  lineHeight: "".concat(round(14 / 10), "em"),
1354
1354
  maxWidth: 300,
1355
1355
  wordWrap: 'break-word'
@@ -2394,9 +2394,10 @@ var BaseLinearDisplay$1 = /*#__PURE__*/mobxStateTree.types.compose('BaseLinearDi
2394
2394
  case 0:
2395
2395
  _context2.prev = 0;
2396
2396
  aborter = new AbortController();
2397
- view = util.getContainingView(self);
2397
+ view = util.getContainingView(self); // extra check for contentBlocks.length
2398
+ // https://github.com/GMOD/jbrowse-components/issues/2694
2398
2399
 
2399
- if (view.initialized) {
2400
+ if (!(!view.initialized || !view.staticBlocks.contentBlocks.length)) {
2400
2401
  _context2.next = 5;
2401
2402
  break;
2402
2403
  }
@@ -3245,7 +3246,8 @@ var Cytobands = /*#__PURE__*/mobxReact.observer(function (_ref2) {
3245
3246
  var overview = _ref2.overview,
3246
3247
  block = _ref2.block,
3247
3248
  assembly = _ref2.assembly;
3248
- var offsetPx = block.offsetPx;
3249
+ var offsetPx = block.offsetPx,
3250
+ reversed = block.reversed;
3249
3251
  var cytobands = assembly === null || assembly === void 0 ? void 0 : (_assembly$cytobands = assembly.cytobands) === null || _assembly$cytobands === void 0 ? void 0 : _assembly$cytobands.map(function (f) {
3250
3252
  return {
3251
3253
  refName: assembly.getCanonicalRefName(f.get('refName')),
@@ -3268,6 +3270,9 @@ var Cytobands = /*#__PURE__*/mobxReact.observer(function (_ref2) {
3268
3270
  coord: end
3269
3271
  }), type];
3270
3272
  });
3273
+ var arr = cytobands || [];
3274
+ var lcap = reversed ? arr.length - 1 : 0;
3275
+ var rcap = reversed ? 0 : arr.length - 1;
3271
3276
  var firstCent = true;
3272
3277
  return cytobands ? /*#__PURE__*/React__default.createElement("g", {
3273
3278
  transform: "translate(-".concat(offsetPx, ")")
@@ -3296,13 +3301,13 @@ var Cytobands = /*#__PURE__*/mobxReact.observer(function (_ref2) {
3296
3301
  });
3297
3302
  }
3298
3303
 
3299
- if (index === 0) {
3304
+ if (lcap === index) {
3300
3305
  return /*#__PURE__*/React__default.createElement("path", {
3301
3306
  key: key,
3302
3307
  d: leftRoundedRect(Math.min(start, end), 0, Math.abs(end - start), HEADER_OVERVIEW_HEIGHT, 8),
3303
3308
  fill: colorMap[type]
3304
3309
  });
3305
- } else if (index === cytobands.length - 1) {
3310
+ } else if (rcap === index) {
3306
3311
  return /*#__PURE__*/React__default.createElement("path", {
3307
3312
  key: key,
3308
3313
  d: rightRoundedRect(Math.min(start, end), 0, Math.abs(end - start) - 2, HEADER_OVERVIEW_HEIGHT, 8),
@@ -3481,20 +3486,6 @@ function OverviewScaleBar(_ref7) {
3481
3486
 
3482
3487
  var OverviewScaleBar$1 = /*#__PURE__*/mobxReact.observer(OverviewScaleBar);
3483
3488
 
3484
- function getBpDisplayStr(totalBp) {
3485
- var displayBp;
3486
-
3487
- if (Math.floor(totalBp / 1000000) > 0) {
3488
- displayBp = "".concat(parseFloat((totalBp / 1000000).toPrecision(3)), "Mbp");
3489
- } else if (Math.floor(totalBp / 1000) > 0) {
3490
- displayBp = "".concat(parseFloat((totalBp / 1000).toPrecision(3)), "Kbp");
3491
- } else {
3492
- displayBp = "".concat(Math.floor(totalBp), "bp");
3493
- }
3494
-
3495
- return displayBp;
3496
- }
3497
-
3498
3489
  function ScaleBar$1(_ref) {
3499
3490
  var model = _ref.model,
3500
3491
  fontSize = _ref.fontSize;
@@ -3502,7 +3493,7 @@ function ScaleBar$1(_ref) {
3502
3493
  _model$dynamicBlocks = model.dynamicBlocks,
3503
3494
  totalWidthPx = _model$dynamicBlocks.totalWidthPxWithoutBorders,
3504
3495
  totalBp = _model$dynamicBlocks.totalBp;
3505
- var displayBp = getBpDisplayStr(totalBp);
3496
+ var displayBp = util.getBpDisplayStr(totalBp);
3506
3497
  var x0 = Math.max(-offsetPx, 0);
3507
3498
  var x1 = x0 + totalWidthPx;
3508
3499
  return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("line", {
@@ -4377,51 +4368,7 @@ function ExportSvgDlg(_ref) {
4377
4368
  }, "Submit")));
4378
4369
  }
4379
4370
 
4380
- var useStyles$9 = /*#__PURE__*/styles.makeStyles(function (theme) {
4381
- return {
4382
- closeButton: {
4383
- position: 'absolute',
4384
- right: theme.spacing(1),
4385
- top: theme.spacing(1),
4386
- color: theme.palette.grey[500]
4387
- }
4388
- };
4389
- });
4390
-
4391
- function ReturnToImportFormDialog(_ref) {
4392
- var model = _ref.model,
4393
- handleClose = _ref.handleClose;
4394
- var classes = useStyles$9();
4395
- return /*#__PURE__*/React__default.createElement(core.Dialog, {
4396
- maxWidth: "xl",
4397
- open: true,
4398
- onClose: handleClose
4399
- }, /*#__PURE__*/React__default.createElement(core.DialogTitle, null, "Reference sequence", handleClose ? /*#__PURE__*/React__default.createElement(core.IconButton, {
4400
- className: classes.closeButton,
4401
- onClick: function onClick() {
4402
- handleClose();
4403
- }
4404
- }, /*#__PURE__*/React__default.createElement(CloseIcon, null)) : null), /*#__PURE__*/React__default.createElement(core.Divider, null), /*#__PURE__*/React__default.createElement(core.DialogContent, null, /*#__PURE__*/React__default.createElement(core.Typography, null, "Are you sure you want to return to the import form? This will lose your current view")), /*#__PURE__*/React__default.createElement(core.DialogActions, null, /*#__PURE__*/React__default.createElement(core.Button, {
4405
- onClick: function onClick() {
4406
- model.clearView();
4407
- handleClose();
4408
- },
4409
- variant: "contained",
4410
- color: "primary",
4411
- autoFocus: true
4412
- }, "OK"), /*#__PURE__*/React__default.createElement(core.Button, {
4413
- onClick: function onClick() {
4414
- handleClose();
4415
- },
4416
- color: "secondary",
4417
- variant: "contained",
4418
- autoFocus: true
4419
- }, "Cancel")));
4420
- }
4421
-
4422
- var ReturnToImportFormDlg = /*#__PURE__*/mobxReact.observer(ReturnToImportFormDialog);
4423
-
4424
- var useStyles$a = /*#__PURE__*/styles.makeStyles({
4371
+ var useStyles$9 = /*#__PURE__*/styles.makeStyles({
4425
4372
  container: {
4426
4373
  display: 'flex',
4427
4374
  flexDirection: 'row',
@@ -4434,7 +4381,7 @@ var useStyles$a = /*#__PURE__*/styles.makeStyles({
4434
4381
 
4435
4382
  function ZoomControls(_ref) {
4436
4383
  var model = _ref.model;
4437
- var classes = useStyles$a();
4384
+ var classes = useStyles$9();
4438
4385
  var maxBpPerPx = model.maxBpPerPx,
4439
4386
  minBpPerPx = model.minBpPerPx,
4440
4387
  bpPerPx = model.bpPerPx,
@@ -4481,7 +4428,7 @@ function ZoomControls(_ref) {
4481
4428
 
4482
4429
  var ZoomControls$1 = /*#__PURE__*/mobxReact.observer(ZoomControls);
4483
4430
 
4484
- var useStyles$b = /*#__PURE__*/core.makeStyles(function (theme) {
4431
+ var useStyles$a = /*#__PURE__*/core.makeStyles(function (theme) {
4485
4432
  return {
4486
4433
  headerBar: {
4487
4434
  height: HEADER_BAR_HEIGHT,
@@ -4516,7 +4463,7 @@ var useStyles$b = /*#__PURE__*/core.makeStyles(function (theme) {
4516
4463
  });
4517
4464
  var HeaderButtons = /*#__PURE__*/mobxReact.observer(function (_ref) {
4518
4465
  var model = _ref.model;
4519
- var classes = useStyles$b();
4466
+ var classes = useStyles$a();
4520
4467
  return /*#__PURE__*/React__default.createElement(core.Button, {
4521
4468
  onClick: model.activateTrackSelector,
4522
4469
  className: classes.toggleButton,
@@ -4530,7 +4477,7 @@ var HeaderButtons = /*#__PURE__*/mobxReact.observer(function (_ref) {
4530
4477
 
4531
4478
  function PanControls(_ref2) {
4532
4479
  var model = _ref2.model;
4533
- var classes = useStyles$b();
4480
+ var classes = useStyles$a();
4534
4481
  return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(core.Button, {
4535
4482
  variant: "outlined",
4536
4483
  className: classes.panButton,
@@ -4548,7 +4495,7 @@ function PanControls(_ref2) {
4548
4495
 
4549
4496
  var RegionWidth = /*#__PURE__*/mobxReact.observer(function (_ref3) {
4550
4497
  var model = _ref3.model;
4551
- var classes = useStyles$b();
4498
+ var classes = useStyles$a();
4552
4499
  var coarseTotalBp = model.coarseTotalBp;
4553
4500
  return /*#__PURE__*/React__default.createElement(core.Typography, {
4554
4501
  variant: "body2",
@@ -4559,7 +4506,7 @@ var RegionWidth = /*#__PURE__*/mobxReact.observer(function (_ref3) {
4559
4506
 
4560
4507
  var Controls = function Controls(_ref4) {
4561
4508
  var model = _ref4.model;
4562
- var classes = useStyles$b();
4509
+ var classes = useStyles$a();
4563
4510
  return /*#__PURE__*/React__default.createElement("div", {
4564
4511
  className: classes.headerBar
4565
4512
  }, /*#__PURE__*/React__default.createElement(HeaderButtons, {
@@ -4593,7 +4540,7 @@ var LinearGenomeViewHeader = /*#__PURE__*/mobxReact.observer(function (_ref5) {
4593
4540
  }));
4594
4541
  });
4595
4542
 
4596
- var useStyles$c = /*#__PURE__*/core.makeStyles(function (theme) {
4543
+ var useStyles$b = /*#__PURE__*/core.makeStyles(function (theme) {
4597
4544
  return {
4598
4545
  root: {
4599
4546
  background: core.alpha(theme.palette.background.paper, 0.8),
@@ -4627,7 +4574,7 @@ var useStyles$c = /*#__PURE__*/core.makeStyles(function (theme) {
4627
4574
  var TrackLabel = /*#__PURE__*/React__default.forwardRef(function (props, ref) {
4628
4575
  var _session$getTrackActi;
4629
4576
 
4630
- var classes = useStyles$c();
4577
+ var classes = useStyles$b();
4631
4578
 
4632
4579
  var _React$useState = React__default.useState(null),
4633
4580
  _React$useState2 = _slicedToArray(_React$useState, 2),
@@ -4721,13 +4668,11 @@ var TrackLabel = /*#__PURE__*/React__default.forwardRef(function (props, ref) {
4721
4668
  });
4722
4669
  var TrackLabel$1 = /*#__PURE__*/mobxReact.observer(TrackLabel);
4723
4670
 
4724
- var useStyles$d = /*#__PURE__*/styles.makeStyles(function (theme) {
4671
+ var useStyles$c = /*#__PURE__*/core.makeStyles(function (theme) {
4725
4672
  return {
4726
4673
  root: {},
4727
4674
  resizeHandle: {
4728
4675
  height: RESIZE_HANDLE_HEIGHT,
4729
- boxSizing: 'border-box',
4730
- position: 'relative',
4731
4676
  zIndex: 2
4732
4677
  },
4733
4678
  overlay: {
@@ -4739,13 +4684,6 @@ var useStyles$d = /*#__PURE__*/styles.makeStyles(function (theme) {
4739
4684
  zIndex: 3,
4740
4685
  borderRadius: theme.shape.borderRadius
4741
4686
  },
4742
- renderingComponentContainer: {
4743
- position: 'absolute',
4744
- // -1 offset because of the 1px border of the Paper
4745
- left: -1,
4746
- height: '100%',
4747
- width: '100%'
4748
- },
4749
4687
  trackLabel: {
4750
4688
  zIndex: 3,
4751
4689
  margin: theme.spacing(1)
@@ -4763,22 +4701,22 @@ var useStyles$d = /*#__PURE__*/styles.makeStyles(function (theme) {
4763
4701
  whiteSpace: 'nowrap',
4764
4702
  position: 'relative',
4765
4703
  background: 'none',
4766
- zIndex: 2,
4767
- boxSizing: 'content-box'
4704
+ zIndex: 2
4768
4705
  }
4769
4706
  };
4770
4707
  });
4771
4708
 
4772
- function TrackContainer(props) {
4773
- var classes = useStyles$d();
4774
- var model = props.model,
4775
- track = props.track;
4709
+ function TrackContainer(_ref) {
4710
+ var model = _ref.model,
4711
+ track = _ref.track;
4712
+ var classes = useStyles$c();
4776
4713
  var display = track.displays[0];
4777
- var horizontalScroll = model.horizontalScroll,
4714
+ var id = model.id,
4715
+ trackLabels = model.trackLabels,
4716
+ horizontalScroll = model.horizontalScroll,
4778
4717
  draggingTrackId = model.draggingTrackId,
4779
4718
  moveTrack = model.moveTrack;
4780
4719
  var height = display.height;
4781
- var view = util.getContainingView(display);
4782
4720
  var trackId = configuration.getConf(track, 'trackId');
4783
4721
  var ref = React.useRef(null);
4784
4722
  React.useEffect(function () {
@@ -4803,10 +4741,7 @@ function TrackContainer(props) {
4803
4741
  var dimmed = draggingTrackId !== undefined && draggingTrackId !== display.id;
4804
4742
  return /*#__PURE__*/React__default.createElement("div", {
4805
4743
  className: classes.root
4806
- }, view.trackLabels !== 'hidden' ? /*#__PURE__*/React__default.createElement(TrackLabel$1, {
4807
- track: track,
4808
- className: clsx(classes.trackLabel, view.trackLabels === 'overlapping' ? classes.trackLabelOverlap : classes.trackLabelInline)
4809
- }) : null, /*#__PURE__*/React__default.createElement(Paper, {
4744
+ }, /*#__PURE__*/React__default.createElement(core.Paper, {
4810
4745
  variant: "outlined",
4811
4746
  className: classes.trackRenderingContainer,
4812
4747
  style: {
@@ -4817,11 +4752,13 @@ function TrackContainer(props) {
4817
4752
  display.setScrollTop(target.scrollTop);
4818
4753
  },
4819
4754
  onDragEnter: debouncedOnDragEnter,
4820
- "data-testid": "trackRenderingContainer-".concat(view.id, "-").concat(trackId),
4755
+ "data-testid": "trackRenderingContainer-".concat(id, "-").concat(trackId),
4821
4756
  role: "presentation"
4822
- }, /*#__PURE__*/React__default.createElement("div", {
4757
+ }, trackLabels !== 'hidden' ? /*#__PURE__*/React__default.createElement(TrackLabel$1, {
4758
+ track: track,
4759
+ className: clsx(classes.trackLabel, trackLabels === 'overlapping' ? classes.trackLabelOverlap : classes.trackLabelInline)
4760
+ }) : null, /*#__PURE__*/React__default.createElement("div", {
4823
4761
  ref: ref,
4824
- className: classes.renderingComponentContainer,
4825
4762
  style: {
4826
4763
  transform: "scaleX(".concat(model.scaleFactor, ")")
4827
4764
  }
@@ -4835,7 +4772,7 @@ function TrackContainer(props) {
4835
4772
  left: 0,
4836
4773
  top: display.height - 20
4837
4774
  }
4838
- }, ' ', /*#__PURE__*/React__default.createElement(DisplayBlurb, {
4775
+ }, /*#__PURE__*/React__default.createElement(DisplayBlurb, {
4839
4776
  model: display
4840
4777
  })) : null), /*#__PURE__*/React__default.createElement("div", {
4841
4778
  className: classes.overlay,
@@ -4852,7 +4789,7 @@ function TrackContainer(props) {
4852
4789
 
4853
4790
  var TrackContainer$1 = /*#__PURE__*/mobxReact.observer(TrackContainer);
4854
4791
 
4855
- var useStyles$e = /*#__PURE__*/styles.makeStyles(function (theme) {
4792
+ var useStyles$d = /*#__PURE__*/styles.makeStyles(function (theme) {
4856
4793
  var background = theme.palette.tertiary ? colorManipulator.alpha(theme.palette.tertiary.main, 0.7) : colorManipulator.alpha(theme.palette.primary.main, 0.7);
4857
4794
  return {
4858
4795
  rubberBand: {
@@ -4891,7 +4828,7 @@ var useStyles$e = /*#__PURE__*/styles.makeStyles(function (theme) {
4891
4828
  var VerticalGuide = /*#__PURE__*/mobxReact.observer(function (_ref) {
4892
4829
  var model = _ref.model,
4893
4830
  coordX = _ref.coordX;
4894
- var classes = useStyles$e();
4831
+ var classes = useStyles$d();
4895
4832
  return /*#__PURE__*/React__default.createElement(Tooltip$1, {
4896
4833
  open: true,
4897
4834
  placement: "top",
@@ -4935,7 +4872,7 @@ function RubberBand(_ref2) {
4935
4872
 
4936
4873
  var controlsRef = React.useRef(null);
4937
4874
  var rubberBandRef = React.useRef(null);
4938
- var classes = useStyles$e();
4875
+ var classes = useStyles$d();
4939
4876
  var mouseDragging = startX !== undefined && anchorPosition === undefined;
4940
4877
  var setOffsets = model.setOffsets,
4941
4878
  pxToBp = model.pxToBp;
@@ -5138,7 +5075,7 @@ RubberBand.defaultProps = {
5138
5075
  var RubberBand$1 = /*#__PURE__*/mobxReact.observer(RubberBand);
5139
5076
 
5140
5077
  var _excluded$1 = ["model", "style", "className"];
5141
- var useStyles$f = /*#__PURE__*/styles.makeStyles(function (theme) {
5078
+ var useStyles$e = /*#__PURE__*/styles.makeStyles(function (theme) {
5142
5079
  return {
5143
5080
  scaleBarContainer: {
5144
5081
  overflow: 'hidden',
@@ -5182,7 +5119,7 @@ var useStyles$f = /*#__PURE__*/styles.makeStyles(function (theme) {
5182
5119
  });
5183
5120
  var RenderedRefNameLabels = /*#__PURE__*/mobxReact.observer(function (_ref) {
5184
5121
  var model = _ref.model;
5185
- var classes = useStyles$f(); // find the block that needs pinning to the left side for context
5122
+ var classes = useStyles$e(); // find the block that needs pinning to the left side for context
5186
5123
 
5187
5124
  var lastLeftBlock = 0;
5188
5125
  model.staticBlocks.forEach(function (block, i) {
@@ -5204,7 +5141,7 @@ var RenderedRefNameLabels = /*#__PURE__*/mobxReact.observer(function (_ref) {
5204
5141
  });
5205
5142
  var RenderedScaleBarLabels = /*#__PURE__*/mobxReact.observer(function (_ref2) {
5206
5143
  var model = _ref2.model;
5207
- var classes = useStyles$f();
5144
+ var classes = useStyles$e();
5208
5145
  return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, model.staticBlocks.map(function (block, index) {
5209
5146
  if (block instanceof blockTypes.ContentBlock) {
5210
5147
  var ticks = makeTicks(block.start, block.end, model.bpPerPx, true, false);
@@ -5257,7 +5194,7 @@ var ScaleBar$2 = /*#__PURE__*/React__default.forwardRef(function (_ref3, ref) {
5257
5194
  className = _ref3.className,
5258
5195
  other = _objectWithoutProperties(_ref3, _excluded$1);
5259
5196
 
5260
- var classes = useStyles$f();
5197
+ var classes = useStyles$e();
5261
5198
  var offsetLeft = model.staticBlocks.offsetPx - model.offsetPx;
5262
5199
  return /*#__PURE__*/React__default.createElement(Paper, Object.assign({
5263
5200
  "data-resizer": "true" // used to avoid click-and-drag scrolls on trackscontainer
@@ -5285,7 +5222,7 @@ var ScaleBar$2 = /*#__PURE__*/React__default.forwardRef(function (_ref3, ref) {
5285
5222
  });
5286
5223
  var ScaleBar$3 = /*#__PURE__*/mobxReact.observer(ScaleBar$2);
5287
5224
 
5288
- var useStyles$g = /*#__PURE__*/styles.makeStyles(function (theme) {
5225
+ var useStyles$f = /*#__PURE__*/styles.makeStyles(function (theme) {
5289
5226
  return {
5290
5227
  verticalGuidesZoomContainer: {
5291
5228
  position: 'absolute',
@@ -5316,7 +5253,7 @@ var useStyles$g = /*#__PURE__*/styles.makeStyles(function (theme) {
5316
5253
  });
5317
5254
  var RenderedVerticalGuides = /*#__PURE__*/mobxReact.observer(function (_ref) {
5318
5255
  var model = _ref.model;
5319
- var classes = useStyles$g();
5256
+ var classes = useStyles$f();
5320
5257
  return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, model.staticBlocks.map(function (block, index) {
5321
5258
  if (block instanceof blockTypes.ContentBlock) {
5322
5259
  var ticks = makeTicks(block.start, block.end, model.bpPerPx);
@@ -5356,7 +5293,7 @@ var RenderedVerticalGuides = /*#__PURE__*/mobxReact.observer(function (_ref) {
5356
5293
 
5357
5294
  function VerticalGuides(_ref2) {
5358
5295
  var model = _ref2.model;
5359
- var classes = useStyles$g(); // find the block that needs pinning to the left side for context
5296
+ var classes = useStyles$f(); // find the block that needs pinning to the left side for context
5360
5297
 
5361
5298
  var offsetLeft = model.staticBlocks.offsetPx - model.offsetPx;
5362
5299
  return /*#__PURE__*/React__default.createElement("div", {
@@ -5377,7 +5314,7 @@ function VerticalGuides(_ref2) {
5377
5314
 
5378
5315
  var VerticalGuides$1 = /*#__PURE__*/mobxReact.observer(VerticalGuides);
5379
5316
 
5380
- var useStyles$h = /*#__PURE__*/styles.makeStyles(function () {
5317
+ var useStyles$g = /*#__PURE__*/styles.makeStyles(function () {
5381
5318
  return {
5382
5319
  centerLineContainer: {
5383
5320
  background: 'transparent',
@@ -5406,7 +5343,7 @@ function CenterLine(_ref) {
5406
5343
  tracks = model.tracks,
5407
5344
  width = model.width;
5408
5345
  var ref = React.useRef(null);
5409
- var classes = useStyles$h();
5346
+ var classes = useStyles$g();
5410
5347
  var startingPosition = width / 2;
5411
5348
  return tracks.length ? /*#__PURE__*/React__default.createElement("div", {
5412
5349
  "data-testid": "centerline_container",
@@ -5433,7 +5370,7 @@ CenterLine.propTypes = {
5433
5370
  };
5434
5371
  var CenterLine$1 = /*#__PURE__*/mobxReact.observer(CenterLine);
5435
5372
 
5436
- var useStyles$i = /*#__PURE__*/styles.makeStyles(function (theme) {
5373
+ var useStyles$h = /*#__PURE__*/styles.makeStyles(function (theme) {
5437
5374
  return {
5438
5375
  tracksContainer: {
5439
5376
  position: 'relative',
@@ -5450,7 +5387,7 @@ var useStyles$i = /*#__PURE__*/styles.makeStyles(function (theme) {
5450
5387
  function TracksContainer(_ref) {
5451
5388
  var children = _ref.children,
5452
5389
  model = _ref.model;
5453
- var classes = useStyles$i(); // refs are to store these variables to avoid repeated rerenders associated
5390
+ var classes = useStyles$h(); // refs are to store these variables to avoid repeated rerenders associated
5454
5391
  // with useState/setState
5455
5392
 
5456
5393
  var delta = React.useRef(0);
@@ -5616,7 +5553,7 @@ var TracksContainer$1 = /*#__PURE__*/mobxReact.observer(TracksContainer);
5616
5553
  var SearchResultsDialog = /*#__PURE__*/React.lazy(function () {
5617
5554
  return Promise.resolve().then(function () { return SearchResultsDialog$2; });
5618
5555
  });
5619
- var useStyles$j = /*#__PURE__*/core.makeStyles(function (theme) {
5556
+ var useStyles$i = /*#__PURE__*/core.makeStyles(function (theme) {
5620
5557
  return {
5621
5558
  importFormContainer: {
5622
5559
  padding: theme.spacing(2)
@@ -5630,7 +5567,7 @@ var ImportForm = /*#__PURE__*/mobxReact.observer(function (_ref) {
5630
5567
  var _regions$;
5631
5568
 
5632
5569
  var model = _ref.model;
5633
- var classes = useStyles$j();
5570
+ var classes = useStyles$i();
5634
5571
  var session = util.getSession(model);
5635
5572
  var assemblyNames = session.assemblyNames,
5636
5573
  assemblyManager = session.assemblyManager,
@@ -5930,7 +5867,7 @@ var MiniControls = /*#__PURE__*/mobxReact.observer(function (props) {
5930
5867
  }));
5931
5868
  });
5932
5869
 
5933
- var useStyles$k = /*#__PURE__*/core.makeStyles(function (theme) {
5870
+ var useStyles$j = /*#__PURE__*/core.makeStyles(function (theme) {
5934
5871
  return {
5935
5872
  loadingMessage: {
5936
5873
  padding: theme.spacing(5)
@@ -6026,7 +5963,7 @@ function _fetchSequence() {
6026
5963
  function SequenceDialog(_ref) {
6027
5964
  var model = _ref.model,
6028
5965
  handleClose = _ref.handleClose;
6029
- var classes = useStyles$k();
5966
+ var classes = useStyles$j();
6030
5967
  var session = util.getSession(model);
6031
5968
 
6032
5969
  var _useState = React.useState(),
@@ -6191,7 +6128,7 @@ function SequenceDialog(_ref) {
6191
6128
 
6192
6129
  var SequenceDialog$1 = /*#__PURE__*/mobxReact.observer(SequenceDialog);
6193
6130
 
6194
- var useStyles$l = /*#__PURE__*/core.makeStyles(function (theme) {
6131
+ var useStyles$k = /*#__PURE__*/core.makeStyles(function (theme) {
6195
6132
  return {
6196
6133
  dialogContent: {
6197
6134
  width: '80em'
@@ -6210,7 +6147,7 @@ function SearchResultsDialog$1(_ref) {
6210
6147
  var model = _ref.model,
6211
6148
  optAssemblyName = _ref.optAssemblyName,
6212
6149
  handleClose = _ref.handleClose;
6213
- var classes = useStyles$l();
6150
+ var classes = useStyles$k();
6214
6151
  var session = util.getSession(model);
6215
6152
 
6216
6153
  var _getEnv = mobxStateTree.getEnv(session),
@@ -6331,11 +6268,11 @@ function SearchResultsDialog$1(_ref) {
6331
6268
 
6332
6269
  var SearchResultsDialog$2 = {
6333
6270
  __proto__: null,
6334
- useStyles: useStyles$l,
6271
+ useStyles: useStyles$k,
6335
6272
  'default': SearchResultsDialog$1
6336
6273
  };
6337
6274
 
6338
- var useStyles$m = /*#__PURE__*/core.makeStyles(function (theme) {
6275
+ var useStyles$l = /*#__PURE__*/core.makeStyles(function (theme) {
6339
6276
  return {
6340
6277
  note: {
6341
6278
  textAlign: 'center',
@@ -6371,7 +6308,7 @@ var LinearGenomeView = /*#__PURE__*/mobxReact.observer(function (_ref) {
6371
6308
  hideHeader = model.hideHeader,
6372
6309
  initialized = model.initialized,
6373
6310
  hasDisplayedRegions = model.hasDisplayedRegions;
6374
- var classes = useStyles$m();
6311
+ var classes = useStyles$l();
6375
6312
 
6376
6313
  if (!initialized && !error) {
6377
6314
  return /*#__PURE__*/React__default.createElement(core.Typography, {
@@ -6452,7 +6389,7 @@ function calculateVisibleLocStrings(contentBlocks) {
6452
6389
  assemblyName: isSingleAssemblyName ? undefined : block.assemblyName
6453
6390
  }));
6454
6391
  });
6455
- return locs.join(';');
6392
+ return locs.join(' ');
6456
6393
  }
6457
6394
 
6458
6395
  var HEADER_BAR_HEIGHT = 48;
@@ -7016,100 +6953,73 @@ function stateModelFactory$1(pluginManager) {
7016
6953
  throw new Error("invalid track selector type ".concat(self.trackSelectorType));
7017
6954
  },
7018
6955
  navToLocString: function navToLocString(locString, optAssemblyName) {
6956
+ var assemblyNames = self.assemblyNames;
6957
+
7019
6958
  var _getSession3 = util.getSession(self),
7020
6959
  assemblyManager = _getSession3.assemblyManager;
7021
6960
 
7022
6961
  var isValidRefName = assemblyManager.isValidRefName;
7023
- var locStrings = locString.split(';');
7024
-
7025
- if (self.displayedRegions.length > 1) {
7026
- var locations = locStrings.map(function (ls) {
7027
- return util.parseLocString(ls, isValidRefName);
6962
+ var assemblyName = optAssemblyName || assemblyNames[0];
6963
+ var parsedLocStrings = locString.split(' ').filter(function (f) {
6964
+ return !!f.trim();
6965
+ }).map(function (l) {
6966
+ return util.parseLocString(l, function (ref) {
6967
+ return isValidRefName(ref, assemblyName);
7028
6968
  });
7029
- this.navToMultiple(locations);
7030
- return;
7031
- }
7032
-
7033
- var assemblyName = optAssemblyName;
7034
- var defaultRefName = '';
7035
-
7036
- if (self.displayedRegions.length !== 0) {
7037
- // defaults
7038
- assemblyName = self.displayedRegions[0].assemblyName;
7039
- defaultRefName = self.displayedRegions[0].refName;
7040
- }
7041
-
7042
- var assembly = assemblyName && assemblyManager.get(assemblyName);
7043
-
7044
- if (!assembly) {
7045
- throw new Error("Could not find assembly ".concat(assemblyName));
7046
- }
7047
-
7048
- var _assembly = assembly,
7049
- regions = _assembly.regions;
7050
-
7051
- if (!regions) {
7052
- throw new Error("Regions for assembly ".concat(assemblyName, " not yet loaded"));
7053
- }
7054
-
7055
- if (locStrings.length > 1) {
7056
- throw new Error('Navigating to multiple locations is not allowed when viewing a whole chromosome');
7057
- }
7058
-
7059
- var parsedLocString = util.parseLocString(locStrings[0], function (refName) {
7060
- return isValidRefName(refName, assemblyName);
7061
6969
  });
7062
- var changedAssembly = false;
7063
-
7064
- if (parsedLocString.assemblyName && parsedLocString.assemblyName !== assemblyName) {
7065
- var newAssembly = assemblyManager.get(parsedLocString.assemblyName);
6970
+ var locations = parsedLocStrings.map(function (region) {
6971
+ var asmName = region.assemblyName || assemblyName;
6972
+ var asm = assemblyManager.get(asmName);
6973
+ var refName = region.refName;
7066
6974
 
7067
- if (!newAssembly) {
7068
- throw new Error("Could not find assembly ".concat(parsedLocString.assemblyName));
6975
+ if (!asm) {
6976
+ throw new Error("assembly ".concat(asmName, " not found"));
7069
6977
  }
7070
6978
 
7071
- assembly = newAssembly;
7072
- changedAssembly = true;
7073
- var newRegions = newAssembly.regions;
6979
+ var regions = asm.regions;
7074
6980
 
7075
- if (!newRegions) {
7076
- throw new Error("Regions for assembly ".concat(parsedLocString.assemblyName, " not yet loaded"));
6981
+ if (!regions) {
6982
+ throw new Error("regions not loaded yet for ".concat(asmName));
7077
6983
  }
7078
6984
 
7079
- regions = newRegions;
7080
- }
7081
-
7082
- var canonicalRefName = assembly.getCanonicalRefName(parsedLocString.refName);
6985
+ var canonicalRefName = asm.getCanonicalRefName(region.refName);
7083
6986
 
7084
- if (!canonicalRefName) {
7085
- throw new Error("Could not find refName ".concat(parsedLocString.refName, " in ").concat(assembly.name));
7086
- }
6987
+ if (!canonicalRefName) {
6988
+ throw new Error("Could not find refName ".concat(refName, " in ").concat(asm.name));
6989
+ }
7087
6990
 
7088
- if (changedAssembly || canonicalRefName !== defaultRefName) {
7089
- var newDisplayedRegion = regions.find(function (region) {
6991
+ var parentRegion = regions.find(function (region) {
7090
6992
  return region.refName === canonicalRefName;
7091
6993
  });
7092
6994
 
7093
- if (newDisplayedRegion) {
7094
- this.setDisplayedRegions([newDisplayedRegion]);
7095
- } else {
7096
- throw new Error("Could not find refName ".concat(parsedLocString.refName, " in ").concat(assembly.name));
6995
+ if (!parentRegion) {
6996
+ throw new Error("Could not find refName ".concat(refName, " in ").concat(asmName));
7097
6997
  }
7098
- }
7099
6998
 
7100
- var displayedRegion = regions.find(function (region) {
7101
- return region.refName === canonicalRefName;
6999
+ return _objectSpread2(_objectSpread2({}, region), {}, {
7000
+ assemblyName: asmName,
7001
+ parentRegion: parentRegion
7002
+ });
7102
7003
  });
7103
7004
 
7104
- if (displayedRegion) {
7105
- var _parsedLocString$star, _parsedLocString$end;
7106
-
7107
- var start = util.clamp((_parsedLocString$star = parsedLocString === null || parsedLocString === void 0 ? void 0 : parsedLocString.start) !== null && _parsedLocString$star !== void 0 ? _parsedLocString$star : 0, 0, displayedRegion.end);
7108
- var end = util.clamp((_parsedLocString$end = parsedLocString === null || parsedLocString === void 0 ? void 0 : parsedLocString.end) !== null && _parsedLocString$end !== void 0 ? _parsedLocString$end : displayedRegion.end, 0, displayedRegion.end);
7109
- this.navTo(_objectSpread2(_objectSpread2({}, parsedLocString), {}, {
7110
- start: start,
7111
- end: end
7005
+ if (locations.length === 1) {
7006
+ var loc = locations[0];
7007
+ this.setDisplayedRegions([_objectSpread2({
7008
+ reversed: loc.reversed
7009
+ }, loc.parentRegion)]);
7010
+ var start = loc.start,
7011
+ end = loc.end,
7012
+ parentRegion = loc.parentRegion;
7013
+ this.navTo(_objectSpread2(_objectSpread2({}, loc), {}, {
7014
+ start: util.clamp(start !== null && start !== void 0 ? start : 0, 0, parentRegion.end),
7015
+ end: util.clamp(end !== null && end !== void 0 ? end : parentRegion.end, 0, parentRegion.end)
7016
+ }));
7017
+ } else {
7018
+ this.setDisplayedRegions( // @ts-ignore
7019
+ locations.map(function (r) {
7020
+ return r.start === undefined ? r.parentRegion : r;
7112
7021
  }));
7022
+ this.showAllRegions();
7113
7023
  }
7114
7024
  },
7115
7025
 
@@ -7231,26 +7141,6 @@ function stateModelFactory$1(pluginManager) {
7231
7141
  if (location.refName !== region.refName) {
7232
7142
  throw new Error("Entered location ".concat(util.assembleLocString(location), " does not match with displayed regions"));
7233
7143
  }
7234
-
7235
- if (locationIndex > 0) {
7236
- // does it reach the left side?
7237
- var matchesLeft = region.reversed ? locationEnd === region.end : locationStart === region.start;
7238
-
7239
- if (!matchesLeft) {
7240
- throw new Error("".concat(region.reversed ? 'End' : 'Start', " of region ").concat(util.assembleLocString(location), " should be ").concat((region.reversed ? region.end : region.start + 1).toLocaleString('en-US'), ", but it is not"));
7241
- }
7242
- }
7243
-
7244
- var isLast = locationIndex === locations.length - 1;
7245
-
7246
- if (!isLast) {
7247
- // does it reach the right side?
7248
- var matchesRight = region.reversed ? locationStart === region.start : locationEnd === region.end;
7249
-
7250
- if (!matchesRight) {
7251
- throw new Error("".concat(region.reversed ? 'Start' : 'End', " of region ").concat(util.assembleLocString(location), " should be ").concat((region.reversed ? region.start + 1 : region.end).toLocaleString('en-US'), ", but it is not"));
7252
- }
7253
- }
7254
7144
  }
7255
7145
 
7256
7146
  locationIndex -= 1;
@@ -7545,10 +7435,10 @@ function stateModelFactory$1(pluginManager) {
7545
7435
  var menuItems = [{
7546
7436
  label: 'Return to import form',
7547
7437
  onClick: function onClick() {
7548
- util.getSession(self).queueDialog(function (doneCallback) {
7549
- return [ReturnToImportFormDlg, {
7438
+ util.getSession(self).queueDialog(function (handleClose) {
7439
+ return [ui.ReturnToImportFormDialog, {
7550
7440
  model: self,
7551
- handleClose: doneCallback
7441
+ handleClose: handleClose
7552
7442
  }];
7553
7443
  });
7554
7444
  },
@@ -7557,10 +7447,10 @@ function stateModelFactory$1(pluginManager) {
7557
7447
  label: 'Export SVG',
7558
7448
  icon: PhotoCameraIcon,
7559
7449
  onClick: function onClick() {
7560
- util.getSession(self).queueDialog(function (doneCallback) {
7450
+ util.getSession(self).queueDialog(function (handleClose) {
7561
7451
  return [ExportSvgDlg, {
7562
7452
  model: self,
7563
- handleClose: doneCallback
7453
+ handleClose: handleClose
7564
7454
  }];
7565
7455
  });
7566
7456
  }
@@ -8087,7 +7977,7 @@ var LinearGenomeViewPlugin = /*#__PURE__*/function (_Plugin) {
8087
7977
  return LinearGenomeViewPlugin;
8088
7978
  }(Plugin);
8089
7979
 
8090
- var useStyles$n = /*#__PURE__*/core.makeStyles(function (theme) {
7980
+ var useStyles$m = /*#__PURE__*/core.makeStyles(function (theme) {
8091
7981
  return {
8092
7982
  closeButton: {
8093
7983
  position: 'absolute',
@@ -8099,7 +7989,7 @@ var useStyles$n = /*#__PURE__*/core.makeStyles(function (theme) {
8099
7989
  });
8100
7990
  function HelpDialog$1(_ref) {
8101
7991
  var handleClose = _ref.handleClose;
8102
- var classes = useStyles$n();
7992
+ var classes = useStyles$m();
8103
7993
  return /*#__PURE__*/React__default.createElement(core.Dialog, {
8104
7994
  open: true,
8105
7995
  maxWidth: "xl",
@@ -8110,7 +8000,7 @@ function HelpDialog$1(_ref) {
8110
8000
  onClick: function onClick() {
8111
8001
  handleClose();
8112
8002
  }
8113
- }, /*#__PURE__*/React__default.createElement(CloseIcon, null)) : null), /*#__PURE__*/React__default.createElement(core.Divider, null), /*#__PURE__*/React__default.createElement(core.DialogContent, null, /*#__PURE__*/React__default.createElement("h3", null, "Searching"), /*#__PURE__*/React__default.createElement("ul", null, /*#__PURE__*/React__default.createElement("li", null, "Jump to a feature or reference sequence by typing its name in the location box and pressing Enter."), /*#__PURE__*/React__default.createElement("li", null, "Jump to a specific region by typing the region into the location box as: ", /*#__PURE__*/React__default.createElement("code", null, "ref:start..end"), " or ", /*#__PURE__*/React__default.createElement("code", null, "ref:start-end"), ". Commas are allowed in the start and end coordinates.")), /*#__PURE__*/React__default.createElement("h3", null, "Example Searches"), /*#__PURE__*/React__default.createElement("ul", null, /*#__PURE__*/React__default.createElement("li", null, /*#__PURE__*/React__default.createElement("code", null, "BRCA"), " - searches for the feature named BRCA"), /*#__PURE__*/React__default.createElement("li", null, /*#__PURE__*/React__default.createElement("code", null, "chr4"), " - jumps to chromosome 4"), /*#__PURE__*/React__default.createElement("li", null, /*#__PURE__*/React__default.createElement("code", null, "chr4:79,500,000..80,000,000"), " - jumps the region on chromosome 4 between 79.5Mb and 80Mb."))), /*#__PURE__*/React__default.createElement(core.Divider, null), /*#__PURE__*/React__default.createElement(core.DialogActions, null, /*#__PURE__*/React__default.createElement(core.Button, {
8003
+ }, /*#__PURE__*/React__default.createElement(CloseIcon, null)) : null), /*#__PURE__*/React__default.createElement(core.Divider, null), /*#__PURE__*/React__default.createElement(core.DialogContent, null, /*#__PURE__*/React__default.createElement("h3", null, "Searching"), /*#__PURE__*/React__default.createElement("ul", null, /*#__PURE__*/React__default.createElement("li", null, "Jump to a feature or reference sequence by typing its name in the location box and pressing Enter."), /*#__PURE__*/React__default.createElement("li", null, "Jump to a specific region by typing the region into the location box as: ", /*#__PURE__*/React__default.createElement("code", null, "ref:start..end"), " or ", /*#__PURE__*/React__default.createElement("code", null, "ref:start-end"), ". Commas are allowed in the start and end coordinates. A space-separated list of locstrings can be used to open up multiple chromosomes at a time")), /*#__PURE__*/React__default.createElement("h3", null, "Example Searches"), /*#__PURE__*/React__default.createElement("ul", null, /*#__PURE__*/React__default.createElement("li", null, /*#__PURE__*/React__default.createElement("code", null, "BRCA"), " - searches for the feature named BRCA"), /*#__PURE__*/React__default.createElement("li", null, /*#__PURE__*/React__default.createElement("code", null, "chr4"), " - jumps to chromosome 4"), /*#__PURE__*/React__default.createElement("li", null, /*#__PURE__*/React__default.createElement("code", null, "chr4:79,500,000..80,000,000"), " - jumps the region on chromosome 4 between 79.5Mb and 80Mb."), /*#__PURE__*/React__default.createElement("li", null, /*#__PURE__*/React__default.createElement("code", null, "chr1:1-100 chr2:1-100"), " - create a split view of chr1:1-100 and chr2:1-100"), /*#__PURE__*/React__default.createElement("li", null, /*#__PURE__*/React__default.createElement("code", null, "chr1 chr2 chr3"), " - open up multiple chromosomes at once"), /*#__PURE__*/React__default.createElement("li", null, /*#__PURE__*/React__default.createElement("code", null, "chr1:1-100[rev] chr2:1-100"), " - open up the first region in the horizontally flipped orientation"))), /*#__PURE__*/React__default.createElement(core.Divider, null), /*#__PURE__*/React__default.createElement(core.DialogActions, null, /*#__PURE__*/React__default.createElement(core.Button, {
8114
8004
  onClick: function onClick() {
8115
8005
  return handleClose();
8116
8006
  },
@@ -8120,11 +8010,11 @@ function HelpDialog$1(_ref) {
8120
8010
 
8121
8011
  var HelpDialog$2 = {
8122
8012
  __proto__: null,
8123
- useStyles: useStyles$n,
8013
+ useStyles: useStyles$m,
8124
8014
  'default': HelpDialog$1
8125
8015
  };
8126
8016
 
8127
- var useStyles$o = /*#__PURE__*/core.makeStyles(function (theme) {
8017
+ var useStyles$n = /*#__PURE__*/core.makeStyles(function (theme) {
8128
8018
  return {
8129
8019
  root: {
8130
8020
  width: 500
@@ -8144,7 +8034,7 @@ var useStyles$o = /*#__PURE__*/core.makeStyles(function (theme) {
8144
8034
  function SetMaxHeightDlg$1(props) {
8145
8035
  var model = props.model,
8146
8036
  handleClose = props.handleClose;
8147
- var classes = useStyles$o();
8037
+ var classes = useStyles$n();
8148
8038
  var _model$maxHeight = model.maxHeight,
8149
8039
  maxHeight = _model$maxHeight === void 0 ? '' : _model$maxHeight;
8150
8040