@genspectrum/dashboard-components 0.1.5 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/custom-elements.json +1161 -928
  2. package/dist/dashboard-components.js +663 -237
  3. package/dist/dashboard-components.js.map +1 -1
  4. package/dist/genspectrum-components.d.ts +177 -140
  5. package/dist/style.css +247 -50
  6. package/package.json +2 -3
  7. package/src/constants.ts +1 -1
  8. package/src/lapisApi/lapisApi.ts +46 -2
  9. package/src/lapisApi/lapisTypes.ts +14 -0
  10. package/src/preact/aggregatedData/aggregate.stories.tsx +4 -2
  11. package/src/preact/aggregatedData/aggregate.tsx +31 -29
  12. package/src/preact/components/error-boundary.stories.tsx +54 -0
  13. package/src/preact/components/error-boundary.tsx +22 -0
  14. package/src/preact/components/error-display.stories.tsx +32 -4
  15. package/src/preact/components/error-display.tsx +48 -1
  16. package/src/preact/components/loading-display.stories.tsx +6 -6
  17. package/src/preact/components/loading-display.tsx +1 -1
  18. package/src/preact/components/no-data-display.tsx +5 -1
  19. package/src/preact/components/resize-container.tsx +5 -14
  20. package/src/preact/dateRangeSelector/date-range-selector.stories.tsx +19 -0
  21. package/src/preact/dateRangeSelector/date-range-selector.tsx +38 -7
  22. package/src/preact/locationFilter/fetchAutocompletionList.ts +15 -1
  23. package/src/preact/locationFilter/location-filter.stories.tsx +23 -6
  24. package/src/preact/locationFilter/location-filter.tsx +28 -18
  25. package/src/preact/mutationComparison/mutation-comparison.stories.tsx +6 -3
  26. package/src/preact/mutationComparison/mutation-comparison.tsx +33 -32
  27. package/src/preact/mutationComparison/queryMutationData.ts +2 -3
  28. package/src/preact/mutationFilter/mutation-filter.stories.tsx +18 -3
  29. package/src/preact/mutationFilter/mutation-filter.tsx +26 -7
  30. package/src/preact/mutations/mutations.stories.tsx +6 -3
  31. package/src/preact/mutations/mutations.tsx +28 -26
  32. package/src/preact/prevalenceOverTime/prevalence-over-time.stories.tsx +14 -7
  33. package/src/preact/prevalenceOverTime/prevalence-over-time.tsx +50 -32
  34. package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.stories.tsx +6 -3
  35. package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.tsx +46 -32
  36. package/src/preact/textInput/text-input.stories.tsx +26 -0
  37. package/src/preact/textInput/text-input.tsx +25 -3
  38. package/src/query/queryPrevalenceOverTime.ts +4 -10
  39. package/src/types.ts +4 -1
  40. package/src/web-components/ResizeContainer.mdx +13 -0
  41. package/src/web-components/app.stories.ts +1 -2
  42. package/src/web-components/app.ts +7 -3
  43. package/src/web-components/index.ts +1 -1
  44. package/src/web-components/input/{date-range-selector-component.stories.ts → gs-date-range-selector.stories.ts} +29 -4
  45. package/src/web-components/input/{date-range-selector-component.tsx → gs-date-range-selector.tsx} +32 -10
  46. package/src/web-components/input/{location-filter-component.stories.ts → gs-location-filter.stories.ts} +32 -5
  47. package/src/web-components/input/{location-filter-component.tsx → gs-location-filter.tsx} +11 -1
  48. package/src/web-components/input/{mutation-filter-component.stories.ts → gs-mutation-filter.stories.ts} +23 -4
  49. package/src/web-components/input/gs-mutation-filter.tsx +126 -0
  50. package/src/web-components/input/{text-input-component.stories.ts → gs-text-input.stories.ts} +34 -6
  51. package/src/web-components/input/{text-input-component.tsx → gs-text-input.tsx} +16 -4
  52. package/src/web-components/input/index.ts +4 -4
  53. package/src/web-components/input/introduction.mdx +11 -0
  54. package/src/web-components/introduction.mdx +15 -0
  55. package/src/web-components/visualization/data_visualization_statistical_analysis.mdx +26 -0
  56. package/src/web-components/{display/aggregate-component.stories.ts → visualization/gs-aggregate.stories.ts} +23 -11
  57. package/src/web-components/visualization/gs-aggregate.tsx +88 -0
  58. package/src/web-components/{display/mutation-comparison-component.stories.ts → visualization/gs-mutation-comparison.stories.ts} +21 -16
  59. package/src/web-components/{display/mutation-comparison-component.tsx → visualization/gs-mutation-comparison.tsx} +27 -18
  60. package/src/web-components/{display/mutations-component.stories.ts → visualization/gs-mutations.stories.ts} +20 -15
  61. package/src/web-components/{display/mutations-component.tsx → visualization/gs-mutations.tsx} +20 -10
  62. package/src/web-components/{display/prevalence-over-time-component.stories.ts → visualization/gs-prevalence-over-time.stories.ts} +29 -20
  63. package/src/web-components/{display/prevalence-over-time-component.tsx → visualization/gs-prevalence-over-time.tsx} +47 -22
  64. package/src/web-components/{display/relative-growth-advantage-component.stories.ts → visualization/gs-relative-growth-advantage.stories.ts} +12 -7
  65. package/src/web-components/{display/relative-growth-advantage-component.tsx → visualization/gs-relative-growth-advantage.tsx} +21 -9
  66. package/src/web-components/visualization/index.ts +5 -0
  67. package/src/web-components/display/aggregate-component.tsx +0 -72
  68. package/src/web-components/display/index.ts +0 -5
  69. package/src/web-components/input/mutation-filter-component.tsx +0 -83
@@ -93,7 +93,7 @@ const { is: i$1, defineProperty: e$1, getOwnPropertyDescriptor: r$2, getOwnPrope
93
93
  return i2;
94
94
  } }, f$2 = (t2, s2) => !i$1(t2, s2), y$1 = { attribute: true, type: String, converter: u$2, reflect: false, hasChanged: f$2 };
95
95
  Symbol.metadata ?? (Symbol.metadata = Symbol("metadata")), a$1.litPropertyMetadata ?? (a$1.litPropertyMetadata = /* @__PURE__ */ new WeakMap());
96
- class b extends HTMLElement {
96
+ let b$1 = class b extends HTMLElement {
97
97
  static addInitializer(t2) {
98
98
  this._$Ei(), (this.l ?? (this.l = [])).push(t2);
99
99
  }
@@ -303,8 +303,8 @@ class b extends HTMLElement {
303
303
  }
304
304
  firstUpdated(t2) {
305
305
  }
306
- }
307
- b.elementStyles = [], b.shadowRootOptions = { mode: "open" }, b[d$1("elementProperties")] = /* @__PURE__ */ new Map(), b[d$1("finalized")] = /* @__PURE__ */ new Map(), p$1 == null ? void 0 : p$1({ ReactiveElement: b }), (a$1.reactiveElementVersions ?? (a$1.reactiveElementVersions = [])).push("2.0.4");
306
+ };
307
+ b$1.elementStyles = [], b$1.shadowRootOptions = { mode: "open" }, b$1[d$1("elementProperties")] = /* @__PURE__ */ new Map(), b$1[d$1("finalized")] = /* @__PURE__ */ new Map(), p$1 == null ? void 0 : p$1({ ReactiveElement: b$1 }), (a$1.reactiveElementVersions ?? (a$1.reactiveElementVersions = [])).push("2.0.4");
308
308
  /**
309
309
  * @license
310
310
  * Copyright 2017 Google LLC
@@ -400,6 +400,31 @@ function makeLapisResponse(data) {
400
400
  data
401
401
  });
402
402
  }
403
+ const problemDetail = z$1.object({
404
+ title: z$1.string().optional(),
405
+ status: z$1.number(),
406
+ detail: z$1.string().optional(),
407
+ type: z$1.string(),
408
+ instance: z$1.string().optional()
409
+ });
410
+ const lapisError = z$1.object({
411
+ error: problemDetail
412
+ });
413
+ class UnknownLapisError extends Error {
414
+ constructor(message, status) {
415
+ super(message);
416
+ this.status = status;
417
+ this.name = "UnknownLapisError";
418
+ }
419
+ }
420
+ class LapisError extends Error {
421
+ constructor(message, status, problemDetail2) {
422
+ super(message);
423
+ this.status = status;
424
+ this.problemDetail = problemDetail2;
425
+ this.name = "LapisError";
426
+ }
427
+ }
403
428
  async function fetchAggregated(lapisUrl, body, signal) {
404
429
  const response = await fetch(aggregatedEndpoint(lapisUrl), {
405
430
  method: "POST",
@@ -450,9 +475,26 @@ async function fetchReferenceGenome(lapisUrl, signal) {
450
475
  const handleErrors = async (response) => {
451
476
  if (!response.ok) {
452
477
  if (response.status >= 400 && response.status < 500) {
453
- throw new Error(`${response.statusText}: ${JSON.stringify(await response.json())}`);
478
+ const json = await response.json();
479
+ const lapisErrorResult = lapisError.safeParse(json);
480
+ if (lapisErrorResult.success) {
481
+ throw new LapisError(
482
+ response.statusText + lapisErrorResult.data.error.detail,
483
+ response.status,
484
+ lapisErrorResult.data.error
485
+ );
486
+ }
487
+ const problemDetailResult = problemDetail.safeParse(json);
488
+ if (problemDetailResult.success) {
489
+ throw new LapisError(
490
+ response.statusText + problemDetailResult.data.detail,
491
+ response.status,
492
+ problemDetailResult.data
493
+ );
494
+ }
495
+ throw new UnknownLapisError(`${response.statusText}: ${JSON.stringify(json)}`, response.status);
454
496
  }
455
- throw new Error(`${response.statusText}: ${response.status}`);
497
+ throw new UnknownLapisError(`${response.statusText}: ${response.status}`, response.status);
456
498
  }
457
499
  };
458
500
  const aggregatedEndpoint = (lapisUrl) => `${lapisUrl}/sample/aggregated`;
@@ -491,10 +533,11 @@ let App = class extends LitElement {
491
533
  }
492
534
  render() {
493
535
  return this.updateReferenceGenome.render({
494
- complete: () => html` <slot></slot>`,
495
- error: () => html`<p>Error</p>`,
496
- // TODO(#143): Add more advanced error handling
497
- pending: () => html` <p>Loading reference genomes...</p> `
536
+ complete: () => html``,
537
+ // Children will be rendered in the light DOM anyway. We can't use slots without a shadow DOM.
538
+ error: () => html` <div class="m-2 w-full alert alert-error">
539
+ Error: Cannot fetch reference genome. Is LAPIS available?
540
+ </div>`
498
541
  });
499
542
  }
500
543
  createRenderRoot() {
@@ -586,6 +629,14 @@ function P(n3) {
586
629
  var u2 = r.context[n3.__c], i2 = h(t++, 9);
587
630
  return i2.c = n3, u2 ? (null == i2.__ && (i2.__ = true, u2.sub(r)), u2.props.value) : n3.__;
588
631
  }
632
+ function b2(n3) {
633
+ var u2 = h(t++, 10), i2 = p();
634
+ return u2.__ = n3, r.componentDidCatch || (r.componentDidCatch = function(n4, t2) {
635
+ u2.__ && u2.__(n4, t2), i2[1](n4);
636
+ }), [i2[0], function() {
637
+ i2[1](void 0);
638
+ }];
639
+ }
589
640
  function j() {
590
641
  for (var n3; n3 = f.shift(); )
591
642
  if (n3.__P && n3.__H)
@@ -850,45 +901,45 @@ const bases = {
850
901
  "-"
851
902
  ]
852
903
  };
853
- const sortSubstitutionsAndDeletions = (a2, b2) => {
854
- if (a2.segment !== b2.segment) {
855
- compareSegments(a2.segment, b2.segment);
904
+ const sortSubstitutionsAndDeletions = (a2, b3) => {
905
+ if (a2.segment !== b3.segment) {
906
+ compareSegments(a2.segment, b3.segment);
856
907
  }
857
- if (a2.position !== b2.position) {
858
- return comparePositions(a2.position, b2.position);
908
+ if (a2.position !== b3.position) {
909
+ return comparePositions(a2.position, b3.position);
859
910
  }
860
911
  const aIsDeletion = a2 instanceof Deletion;
861
- const bIsDeletion = b2 instanceof Deletion;
912
+ const bIsDeletion = b3 instanceof Deletion;
862
913
  if (aIsDeletion !== bIsDeletion) {
863
914
  return aIsDeletion ? 1 : -1;
864
915
  }
865
916
  if (!aIsDeletion && !bIsDeletion) {
866
- if (a2.substitutionValue !== b2.substitutionValue) {
867
- return compareSubstitutionValues(a2.substitutionValue, b2.substitutionValue);
917
+ if (a2.substitutionValue !== b3.substitutionValue) {
918
+ return compareSubstitutionValues(a2.substitutionValue, b3.substitutionValue);
868
919
  }
869
920
  }
870
921
  return 0;
871
922
  };
872
- const compareSegments = (a2, b2) => {
923
+ const compareSegments = (a2, b3) => {
873
924
  if (a2 === void 0) {
874
925
  return -1;
875
926
  }
876
- if (b2 === void 0) {
927
+ if (b3 === void 0) {
877
928
  return 1;
878
929
  }
879
- return a2.localeCompare(b2);
930
+ return a2.localeCompare(b3);
880
931
  };
881
- const comparePositions = (a2, b2) => {
882
- return a2 - b2;
932
+ const comparePositions = (a2, b3) => {
933
+ return a2 - b3;
883
934
  };
884
- const compareSubstitutionValues = (a2, b2) => {
935
+ const compareSubstitutionValues = (a2, b3) => {
885
936
  if (a2 === void 0) {
886
937
  return -1;
887
938
  }
888
- if (b2 === void 0) {
939
+ if (b3 === void 0) {
889
940
  return 1;
890
941
  }
891
- return a2.localeCompare(b2);
942
+ return a2.localeCompare(b3);
892
943
  };
893
944
  const formatProportion = (proportion) => {
894
945
  return `${(proportion * 100).toFixed(2)}%`;
@@ -1081,11 +1132,11 @@ class SortOperator {
1081
1132
  }
1082
1133
  function querySubstitutionsOrDeletions(variant, sequenceType, lapis, signal) {
1083
1134
  const fetchData = new FetchSubstitutionsOrDeletionsOperator(variant, sequenceType, 0);
1084
- const sortData = new SortOperator(fetchData, (a2, b2) => {
1085
- if (a2.mutation.segment !== b2.mutation.segment) {
1086
- return (a2.mutation.segment ?? "").localeCompare(b2.mutation.segment ?? "");
1135
+ const sortData = new SortOperator(fetchData, (a2, b3) => {
1136
+ if (a2.mutation.segment !== b3.mutation.segment) {
1137
+ return (a2.mutation.segment ?? "").localeCompare(b3.mutation.segment ?? "");
1087
1138
  }
1088
- return a2.mutation.position - b2.mutation.position;
1139
+ return a2.mutation.position - b3.mutation.position;
1089
1140
  });
1090
1141
  return sortData.evaluate(lapis, signal);
1091
1142
  }
@@ -1218,12 +1269,48 @@ const CsvDownloadButton = ({
1218
1269
  };
1219
1270
  return /* @__PURE__ */ u$1("button", { className, onClick: download, children: label });
1220
1271
  };
1272
+ class UserFacingError extends Error {
1273
+ constructor(headline, message) {
1274
+ super(message);
1275
+ this.headline = headline;
1276
+ this.name = "UserFacingError";
1277
+ }
1278
+ }
1221
1279
  const ErrorDisplay = ({ error }) => {
1222
- return /* @__PURE__ */ u$1("div", { children: [
1223
- "Error: ",
1224
- error.message
1280
+ console.error(error);
1281
+ const ref = F(null);
1282
+ return /* @__PURE__ */ u$1("div", { className: "h-full w-full rounded-md border-2 border-gray-100 p-2 flex items-center justify-center flex-col", children: [
1283
+ /* @__PURE__ */ u$1("div", { className: "text-red-700 font-bold", children: "Error" }),
1284
+ /* @__PURE__ */ u$1("div", { children: [
1285
+ "Oops! Something went wrong.",
1286
+ error instanceof UserFacingError && /* @__PURE__ */ u$1(Fragment, { children: [
1287
+ " ",
1288
+ /* @__PURE__ */ u$1(
1289
+ "button",
1290
+ {
1291
+ className: "text-sm text-gray-600 hover:text-gray-300",
1292
+ onClick: () => {
1293
+ var _a;
1294
+ return (_a = ref.current) == null ? void 0 : _a.showModal();
1295
+ },
1296
+ children: "Show details."
1297
+ }
1298
+ ),
1299
+ /* @__PURE__ */ u$1("dialog", { ref, class: "modal", children: [
1300
+ /* @__PURE__ */ u$1("div", { class: "modal-box", children: [
1301
+ /* @__PURE__ */ u$1("form", { method: "dialog", children: /* @__PURE__ */ u$1("button", { className: "btn btn-sm btn-circle btn-ghost absolute right-2 top-2", children: "✕" }) }),
1302
+ /* @__PURE__ */ u$1("h1", { class: "text-lg", children: error.headline }),
1303
+ /* @__PURE__ */ u$1("p", { class: "py-4", children: error.message })
1304
+ ] }),
1305
+ /* @__PURE__ */ u$1("form", { method: "dialog", class: "modal-backdrop", children: /* @__PURE__ */ u$1("button", { children: "close" }) })
1306
+ ] })
1307
+ ] })
1308
+ ] })
1225
1309
  ] });
1226
1310
  };
1311
+ const ResizeContainer = ({ children, size }) => {
1312
+ return /* @__PURE__ */ u$1("div", { style: size, children });
1313
+ };
1227
1314
  const Headline = ({ heading, children }) => {
1228
1315
  if (!heading) {
1229
1316
  return /* @__PURE__ */ u$1(Fragment, { children });
@@ -1244,6 +1331,13 @@ const ResizingHeadline = ({ heading, children }) => {
1244
1331
  /* @__PURE__ */ u$1("div", { style: { height: `calc(100% - ${h1Height})` }, children })
1245
1332
  ] });
1246
1333
  };
1334
+ const ErrorBoundary = ({ size, headline, children }) => {
1335
+ const [internalError] = b2();
1336
+ if (internalError) {
1337
+ return /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(ErrorDisplay, { error: internalError }) }) });
1338
+ }
1339
+ return /* @__PURE__ */ u$1(Fragment, { children });
1340
+ };
1247
1341
  const Info = ({ children, size }) => {
1248
1342
  const [showHelp, setShowHelp] = p(false);
1249
1343
  const toggleHelp = () => {
@@ -1277,7 +1371,7 @@ const InfoLink = ({ children, href }) => {
1277
1371
  return /* @__PURE__ */ u$1("a", { className: "text-blue-600 hover:text-blue-800", href, target: "_blank", rel: "noopener noreferrer", children });
1278
1372
  };
1279
1373
  const LoadingDisplay = () => {
1280
- return /* @__PURE__ */ u$1("div", { children: "Loading..." });
1374
+ return /* @__PURE__ */ u$1("div", { "aria-label": "Loading", className: "h-full w-full skeleton" });
1281
1375
  };
1282
1376
  const MutationTypeSelector = ({
1283
1377
  displayedMutationTypes,
@@ -1296,7 +1390,7 @@ const MutationTypeSelector = ({
1296
1390
  );
1297
1391
  };
1298
1392
  const NoDataDisplay = () => {
1299
- return /* @__PURE__ */ u$1("div", { children: "No data available." });
1393
+ return /* @__PURE__ */ u$1("div", { className: "h-full w-full rounded-md border-2 border-gray-100 p-2 flex items-center justify-center", children: /* @__PURE__ */ u$1("div", { children: "No data available." }) });
1300
1394
  };
1301
1395
  const MinMaxRangeSlider = ({
1302
1396
  min,
@@ -1466,15 +1560,6 @@ const ProportionSelectorDropdown = ({
1466
1560
  ) }) })
1467
1561
  ] });
1468
1562
  };
1469
- const ResizeContainer = ({ children, size, defaultSize }) => {
1470
- return /* @__PURE__ */ u$1("div", { style: extendByDefault(size, defaultSize), children });
1471
- };
1472
- const extendByDefault = (size, defaultSize) => {
1473
- if (size === void 0) {
1474
- return defaultSize;
1475
- }
1476
- return { ...defaultSize, ...size };
1477
- };
1478
1563
  const Tabs = ({ tabs, toolbar }) => {
1479
1564
  const [activeTab, setActiveTab] = p(tabs[0].title);
1480
1565
  const [heightOfTabs, setHeightOfTabs] = p("3rem");
@@ -1538,23 +1623,32 @@ const MutationComparison = ({
1538
1623
  variants,
1539
1624
  sequenceType,
1540
1625
  views,
1541
- size,
1626
+ width,
1627
+ height,
1542
1628
  headline = "Mutation comparison"
1629
+ }) => {
1630
+ const size = { height, width };
1631
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, headline, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(MutationComparisonInner, { variants, sequenceType, views }) }) }) });
1632
+ };
1633
+ const MutationComparisonInner = ({
1634
+ variants,
1635
+ sequenceType,
1636
+ views
1543
1637
  }) => {
1544
1638
  const lapis = P(LapisUrlContext);
1545
1639
  const { data, error, isLoading } = useQuery(async () => {
1546
1640
  return queryMutationData(variants, sequenceType, lapis);
1547
1641
  }, [variants, sequenceType, lapis]);
1548
1642
  if (isLoading) {
1549
- return /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(LoadingDisplay, {}) });
1643
+ return /* @__PURE__ */ u$1(LoadingDisplay, {});
1550
1644
  }
1551
1645
  if (error !== null) {
1552
- return /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(ErrorDisplay, { error }) });
1646
+ return /* @__PURE__ */ u$1(ErrorDisplay, { error });
1553
1647
  }
1554
1648
  if (data === null) {
1555
- return /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(NoDataDisplay, {}) });
1649
+ return /* @__PURE__ */ u$1(NoDataDisplay, {});
1556
1650
  }
1557
- return /* @__PURE__ */ u$1(ResizeContainer, { size, defaultSize: { height: "700px", width: "100%" }, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(MutationComparisonTabs, { data: data.mutationData, sequenceType, views }) }) });
1651
+ return /* @__PURE__ */ u$1(MutationComparisonTabs, { data: data.mutationData, sequenceType, views });
1558
1652
  };
1559
1653
  const MutationComparisonTabs = ({ data, views, sequenceType }) => {
1560
1654
  const [proportionInterval, setProportionInterval] = p({ min: 0.5, max: 1 });
@@ -2252,37 +2346,33 @@ html {
2252
2346
  --tw-contain-paint: ;
2253
2347
  --tw-contain-style: ;
2254
2348
  }
2255
- .container {
2349
+ .alert {
2350
+ display: grid;
2256
2351
  width: 100%;
2352
+ grid-auto-flow: row;
2353
+ align-content: flex-start;
2354
+ align-items: center;
2355
+ justify-items: center;
2356
+ gap: 1rem;
2357
+ text-align: center;
2358
+ border-radius: var(--rounded-box, 1rem);
2359
+ border-width: 1px;
2360
+ --tw-border-opacity: 1;
2361
+ border-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-border-opacity)));
2362
+ padding: 1rem;
2363
+ --tw-text-opacity: 1;
2364
+ color: var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity)));
2365
+ --alert-bg: var(--fallback-b2,oklch(var(--b2)/1));
2366
+ --alert-bg-mix: var(--fallback-b1,oklch(var(--b1)/1));
2367
+ background-color: var(--alert-bg);
2257
2368
  }
2258
2369
  @media (min-width: 640px) {
2259
2370
 
2260
- .container {
2261
- max-width: 640px;
2262
- }
2263
- }
2264
- @media (min-width: 768px) {
2265
-
2266
- .container {
2267
- max-width: 768px;
2268
- }
2269
- }
2270
- @media (min-width: 1024px) {
2271
-
2272
- .container {
2273
- max-width: 1024px;
2274
- }
2275
- }
2276
- @media (min-width: 1280px) {
2277
-
2278
- .container {
2279
- max-width: 1280px;
2280
- }
2281
- }
2282
- @media (min-width: 1536px) {
2283
-
2284
- .container {
2285
- max-width: 1536px;
2371
+ .alert {
2372
+ grid-auto-flow: column;
2373
+ grid-template-columns: auto minmax(auto,1fr);
2374
+ justify-items: start;
2375
+ text-align: start;
2286
2376
  }
2287
2377
  }
2288
2378
  .avatar.placeholder > div {
@@ -2358,6 +2448,12 @@ html {
2358
2448
  .btn:disabled {
2359
2449
  pointer-events: none;
2360
2450
  }
2451
+ .btn-circle {
2452
+ height: 3rem;
2453
+ width: 3rem;
2454
+ border-radius: 9999px;
2455
+ padding: 0px;
2456
+ }
2361
2457
  :where(.btn:is(input[type="checkbox"])),
2362
2458
  :where(.btn:is(input[type="radio"])) {
2363
2459
  width: auto;
@@ -2510,6 +2606,17 @@ html {
2510
2606
  --glass-border-opacity: 15%;
2511
2607
  }
2512
2608
 
2609
+ .btn-ghost:hover {
2610
+ border-color: transparent;
2611
+ }
2612
+
2613
+ @supports (color: oklch(0% 0 0)) {
2614
+
2615
+ .btn-ghost:hover {
2616
+ background-color: var(--fallback-bc,oklch(var(--bc)/0.2));
2617
+ }
2618
+ }
2619
+
2513
2620
  .btn-outline.btn-primary:hover {
2514
2621
  --tw-text-opacity: 1;
2515
2622
  color: var(--fallback-pc,oklch(var(--pc)/var(--tw-text-opacity)));
@@ -2732,6 +2839,69 @@ html {
2732
2839
  :where(.menu li) .badge {
2733
2840
  justify-self: end;
2734
2841
  }
2842
+ .modal {
2843
+ pointer-events: none;
2844
+ position: fixed;
2845
+ inset: 0px;
2846
+ margin: 0px;
2847
+ display: grid;
2848
+ height: 100%;
2849
+ max-height: none;
2850
+ width: 100%;
2851
+ max-width: none;
2852
+ justify-items: center;
2853
+ padding: 0px;
2854
+ opacity: 0;
2855
+ overscroll-behavior: contain;
2856
+ z-index: 999;
2857
+ background-color: transparent;
2858
+ color: inherit;
2859
+ transition-duration: 200ms;
2860
+ transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
2861
+ transition-property: transform, opacity, visibility;
2862
+ overflow-y: hidden;
2863
+ }
2864
+ :where(.modal) {
2865
+ align-items: center;
2866
+ }
2867
+ .modal-box {
2868
+ max-height: calc(100vh - 5em);
2869
+ grid-column-start: 1;
2870
+ grid-row-start: 1;
2871
+ width: 91.666667%;
2872
+ max-width: 32rem;
2873
+ --tw-scale-x: .9;
2874
+ --tw-scale-y: .9;
2875
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
2876
+ border-bottom-right-radius: var(--rounded-box, 1rem);
2877
+ border-bottom-left-radius: var(--rounded-box, 1rem);
2878
+ border-top-left-radius: var(--rounded-box, 1rem);
2879
+ border-top-right-radius: var(--rounded-box, 1rem);
2880
+ --tw-bg-opacity: 1;
2881
+ background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)));
2882
+ padding: 1.5rem;
2883
+ transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter;
2884
+ transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
2885
+ transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter;
2886
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
2887
+ transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
2888
+ transition-duration: 200ms;
2889
+ box-shadow: rgba(0, 0, 0, 0.25) 0px 25px 50px -12px;
2890
+ overflow-y: auto;
2891
+ overscroll-behavior: contain;
2892
+ }
2893
+ .modal-open,
2894
+ .modal:target,
2895
+ .modal-toggle:checked + .modal,
2896
+ .modal[open] {
2897
+ pointer-events: auto;
2898
+ visibility: visible;
2899
+ opacity: 1;
2900
+ }
2901
+ :root:has(:is(.modal-open, .modal:target, .modal-toggle:checked + .modal, .modal[open])) {
2902
+ overflow: hidden;
2903
+ scrollbar-gutter: stable;
2904
+ }
2735
2905
  .radio {
2736
2906
  flex-shrink: 0;
2737
2907
  --chkbg: var(--bc);
@@ -2793,29 +2963,6 @@ html {
2793
2963
  .select[multiple] {
2794
2964
  height: auto;
2795
2965
  }
2796
- .stack {
2797
- display: inline-grid;
2798
- place-items: center;
2799
- align-items: flex-end;
2800
- }
2801
- .stack > * {
2802
- grid-column-start: 1;
2803
- grid-row-start: 1;
2804
- transform: translateY(10%) scale(0.9);
2805
- z-index: 1;
2806
- width: 100%;
2807
- opacity: 0.6;
2808
- }
2809
- .stack > *:nth-child(2) {
2810
- transform: translateY(5%) scale(0.95);
2811
- z-index: 2;
2812
- opacity: 0.8;
2813
- }
2814
- .stack > *:nth-child(1) {
2815
- transform: translateY(0) scale(1);
2816
- z-index: 3;
2817
- opacity: 1;
2818
- }
2819
2966
  .steps {
2820
2967
  display: inline-grid;
2821
2968
  grid-auto-flow: column;
@@ -2915,6 +3062,13 @@ input.tab:checked + .tab-content,
2915
3062
  --tw-bg-opacity: 1;
2916
3063
  background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)));
2917
3064
  }
3065
+ .alert-error {
3066
+ border-color: var(--fallback-er,oklch(var(--er)/0.2));
3067
+ --tw-text-opacity: 1;
3068
+ color: var(--fallback-erc,oklch(var(--erc)/var(--tw-text-opacity)));
3069
+ --alert-bg: var(--fallback-er,oklch(var(--er)/1));
3070
+ --alert-bg-mix: var(--fallback-b1,oklch(var(--b1)/1));
3071
+ }
2918
3072
  .btm-nav > *.disabled,
2919
3073
  .btm-nav > *[disabled] {
2920
3074
  pointer-events: none;
@@ -2983,6 +3137,20 @@ input.tab:checked + .tab-content,
2983
3137
  --glass-opacity: 25%;
2984
3138
  --glass-border-opacity: 15%;
2985
3139
  }
3140
+ .btn-ghost {
3141
+ border-width: 1px;
3142
+ border-color: transparent;
3143
+ background-color: transparent;
3144
+ color: currentColor;
3145
+ --tw-shadow: 0 0 #0000;
3146
+ --tw-shadow-colored: 0 0 #0000;
3147
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
3148
+ outline-color: currentColor;
3149
+ }
3150
+ .btn-ghost.btn-active {
3151
+ border-color: transparent;
3152
+ background-color: var(--fallback-bc,oklch(var(--bc)/0.2));
3153
+ }
2986
3154
  .btn-outline.btn-primary {
2987
3155
  --tw-text-opacity: 1;
2988
3156
  color: var(--fallback-p,oklch(var(--p)/var(--tw-text-opacity)));
@@ -3304,6 +3472,29 @@ input.tab:checked + .tab-content,
3304
3472
  border-color: currentColor;
3305
3473
  opacity: 0.6;
3306
3474
  }
3475
+ .modal:not(dialog:not(.modal-open)),
3476
+ .modal::backdrop {
3477
+ background-color: #0006;
3478
+ animation: modal-pop 0.2s ease-out;
3479
+ }
3480
+ .modal-backdrop {
3481
+ z-index: -1;
3482
+ grid-column-start: 1;
3483
+ grid-row-start: 1;
3484
+ display: grid;
3485
+ align-self: stretch;
3486
+ justify-self: stretch;
3487
+ color: transparent;
3488
+ }
3489
+ .modal-open .modal-box,
3490
+ .modal-toggle:checked + .modal .modal-box,
3491
+ .modal:target .modal-box,
3492
+ .modal[open] .modal-box {
3493
+ --tw-translate-y: 0px;
3494
+ --tw-scale-x: 1;
3495
+ --tw-scale-y: 1;
3496
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
3497
+ }
3307
3498
  @keyframes modal-pop {
3308
3499
 
3309
3500
  0% {
@@ -3463,6 +3654,30 @@ input.tab:checked + .tab-content,
3463
3654
  background-position: calc(0% + 12px) calc(1px + 50%),
3464
3655
  calc(0% + 16px) calc(1px + 50%);
3465
3656
  }
3657
+ .skeleton {
3658
+ border-radius: var(--rounded-box, 1rem);
3659
+ --tw-bg-opacity: 1;
3660
+ background-color: var(--fallback-b3,oklch(var(--b3)/var(--tw-bg-opacity)));
3661
+ will-change: background-position;
3662
+ animation: skeleton 1.8s ease-in-out infinite;
3663
+ background-image: linear-gradient(
3664
+ 105deg,
3665
+ transparent 0%,
3666
+ transparent 40%,
3667
+ var(--fallback-b1,oklch(var(--b1)/1)) 50%,
3668
+ transparent 60%,
3669
+ transparent 100%
3670
+ );
3671
+ background-size: 200% auto;
3672
+ background-repeat: no-repeat;
3673
+ background-position-x: -50%;
3674
+ }
3675
+ @media (prefers-reduced-motion) {
3676
+
3677
+ .skeleton {
3678
+ animation-duration: 15s;
3679
+ }
3680
+ }
3466
3681
  @keyframes skeleton {
3467
3682
 
3468
3683
  from {
@@ -3765,6 +3980,18 @@ input.tab:checked + .tab-content,
3765
3980
  border-radius: 9999px;
3766
3981
  padding: 0px;
3767
3982
  }
3983
+ .btn-circle:where(.btn-md) {
3984
+ height: 3rem;
3985
+ width: 3rem;
3986
+ border-radius: 9999px;
3987
+ padding: 0px;
3988
+ }
3989
+ .btn-circle:where(.btn-lg) {
3990
+ height: 4rem;
3991
+ width: 4rem;
3992
+ border-radius: 9999px;
3993
+ padding: 0px;
3994
+ }
3768
3995
  .join.join-vertical {
3769
3996
  flex-direction: column;
3770
3997
  }
@@ -3879,6 +4106,42 @@ input.tab:checked + .tab-content,
3879
4106
  margin-bottom: 0px;
3880
4107
  margin-inline-start: -1px;
3881
4108
  }
4109
+ .modal-top :where(.modal-box) {
4110
+ width: 100%;
4111
+ max-width: none;
4112
+ --tw-translate-y: -2.5rem;
4113
+ --tw-scale-x: 1;
4114
+ --tw-scale-y: 1;
4115
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
4116
+ border-bottom-right-radius: var(--rounded-box, 1rem);
4117
+ border-bottom-left-radius: var(--rounded-box, 1rem);
4118
+ border-top-left-radius: 0px;
4119
+ border-top-right-radius: 0px;
4120
+ }
4121
+ .modal-middle :where(.modal-box) {
4122
+ width: 91.666667%;
4123
+ max-width: 32rem;
4124
+ --tw-translate-y: 0px;
4125
+ --tw-scale-x: .9;
4126
+ --tw-scale-y: .9;
4127
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
4128
+ border-top-left-radius: var(--rounded-box, 1rem);
4129
+ border-top-right-radius: var(--rounded-box, 1rem);
4130
+ border-bottom-right-radius: var(--rounded-box, 1rem);
4131
+ border-bottom-left-radius: var(--rounded-box, 1rem);
4132
+ }
4133
+ .modal-bottom :where(.modal-box) {
4134
+ width: 100%;
4135
+ max-width: none;
4136
+ --tw-translate-y: 2.5rem;
4137
+ --tw-scale-x: 1;
4138
+ --tw-scale-y: 1;
4139
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
4140
+ border-top-left-radius: var(--rounded-box, 1rem);
4141
+ border-top-right-radius: var(--rounded-box, 1rem);
4142
+ border-bottom-right-radius: 0px;
4143
+ border-bottom-left-radius: 0px;
4144
+ }
3882
4145
  .steps-horizontal .step {
3883
4146
  grid-template-rows: 40px 1fr;
3884
4147
  grid-template-columns: auto;
@@ -4004,9 +4267,15 @@ input.tab:checked + .tab-content,
4004
4267
  .relative {
4005
4268
  position: relative;
4006
4269
  }
4270
+ .right-2 {
4271
+ right: 0.5rem;
4272
+ }
4007
4273
  .right-6 {
4008
4274
  right: 1.5rem;
4009
4275
  }
4276
+ .top-2 {
4277
+ top: 0.5rem;
4278
+ }
4010
4279
  .top-8 {
4011
4280
  top: 2rem;
4012
4281
  }
@@ -4088,6 +4357,10 @@ input.tab:checked + .tab-content,
4088
4357
  .min-w-0 {
4089
4358
  min-width: 0px;
4090
4359
  }
4360
+ .min-w-max {
4361
+ min-width: -moz-max-content;
4362
+ min-width: max-content;
4363
+ }
4091
4364
  .max-w-screen-lg {
4092
4365
  max-width: 1024px;
4093
4366
  }
@@ -4130,6 +4403,9 @@ input.tab:checked + .tab-content,
4130
4403
  .overflow-auto {
4131
4404
  overflow: auto;
4132
4405
  }
4406
+ .overflow-scroll {
4407
+ overflow: scroll;
4408
+ }
4133
4409
  .whitespace-nowrap {
4134
4410
  white-space: nowrap;
4135
4411
  }
@@ -4148,6 +4424,9 @@ input.tab:checked + .tab-content,
4148
4424
  .rounded-lg {
4149
4425
  border-radius: 0.5rem;
4150
4426
  }
4427
+ .rounded-md {
4428
+ border-radius: 0.375rem;
4429
+ }
4151
4430
  .rounded-none {
4152
4431
  border-radius: 0px;
4153
4432
  }
@@ -4233,6 +4512,10 @@ input.tab:checked + .tab-content,
4233
4512
  padding-top: 0.5rem;
4234
4513
  padding-bottom: 0.5rem;
4235
4514
  }
4515
+ .py-4 {
4516
+ padding-top: 1rem;
4517
+ padding-bottom: 1rem;
4518
+ }
4236
4519
  .text-justify {
4237
4520
  text-align: justify;
4238
4521
  }
@@ -4273,6 +4556,10 @@ input.tab:checked + .tab-content,
4273
4556
  --tw-text-opacity: 1;
4274
4557
  color: rgb(75 85 99 / var(--tw-text-opacity));
4275
4558
  }
4559
+ .text-red-700 {
4560
+ --tw-text-opacity: 1;
4561
+ color: rgb(185 28 28 / var(--tw-text-opacity));
4562
+ }
4276
4563
  .underline {
4277
4564
  text-decoration-line: underline;
4278
4565
  }
@@ -4309,6 +4596,10 @@ input.tab:checked + .tab-content,
4309
4596
  --tw-text-opacity: 1;
4310
4597
  color: rgb(30 64 175 / var(--tw-text-opacity));
4311
4598
  }
4599
+ .hover\\:text-gray-300:hover {
4600
+ --tw-text-opacity: 1;
4601
+ color: rgb(209 213 219 / var(--tw-text-opacity));
4602
+ }
4312
4603
  .hover\\:text-gray-700:hover {
4313
4604
  --tw-text-opacity: 1;
4314
4605
  color: rgb(55 65 81 / var(--tw-text-opacity));
@@ -4371,7 +4662,8 @@ let MutationComparisonComponent = class extends PreactLitAdapterWithGridJsStyles
4371
4662
  this.variants = [];
4372
4663
  this.sequenceType = "nucleotide";
4373
4664
  this.views = ["table"];
4374
- this.size = void 0;
4665
+ this.width = "100%";
4666
+ this.height = "700px";
4375
4667
  this.headline = "Mutation comparison";
4376
4668
  }
4377
4669
  render() {
@@ -4381,7 +4673,8 @@ let MutationComparisonComponent = class extends PreactLitAdapterWithGridJsStyles
4381
4673
  variants: this.variants,
4382
4674
  sequenceType: this.sequenceType,
4383
4675
  views: this.views,
4384
- size: this.size,
4676
+ width: this.width,
4677
+ height: this.height,
4385
4678
  headline: this.headline
4386
4679
  }
4387
4680
  );
@@ -4397,13 +4690,16 @@ __decorateClass$8([
4397
4690
  n2({ type: Array })
4398
4691
  ], MutationComparisonComponent.prototype, "views", 2);
4399
4692
  __decorateClass$8([
4400
- n2({ type: Object })
4401
- ], MutationComparisonComponent.prototype, "size", 2);
4693
+ n2({ type: String })
4694
+ ], MutationComparisonComponent.prototype, "width", 2);
4695
+ __decorateClass$8([
4696
+ n2({ type: String })
4697
+ ], MutationComparisonComponent.prototype, "height", 2);
4402
4698
  __decorateClass$8([
4403
4699
  n2({ type: String })
4404
4700
  ], MutationComparisonComponent.prototype, "headline", 2);
4405
4701
  MutationComparisonComponent = __decorateClass$8([
4406
- t$2("gs-mutation-comparison-component")
4702
+ t$2("gs-mutation-comparison")
4407
4703
  ], MutationComparisonComponent);
4408
4704
  function getInsertionsTableData(data) {
4409
4705
  return data.map((mutationEntry) => {
@@ -4427,16 +4723,16 @@ function getMutationsTableData(data, proportionInterval) {
4427
4723
  });
4428
4724
  }
4429
4725
  const pattern = /(?:([A-Za-z0-9]+):)?(\d+)$/;
4430
- const sortMutationPositions = (a2, b2) => {
4726
+ const sortMutationPositions = (a2, b3) => {
4431
4727
  const aMatch = a2.match(pattern);
4432
- const bMatch = b2.match(pattern);
4728
+ const bMatch = b3.match(pattern);
4433
4729
  if (aMatch && bMatch) {
4434
4730
  if (aMatch[1] !== bMatch[1]) {
4435
4731
  return aMatch[1].localeCompare(bMatch[1]);
4436
4732
  }
4437
4733
  return parseInt(aMatch[2], 10) - parseInt(bMatch[2], 10);
4438
4734
  }
4439
- throw new Error(`Invalid mutation position: ${a2} or ${b2}`);
4735
+ throw new Error(`Invalid mutation position: ${a2} or ${b3}`);
4440
4736
  };
4441
4737
  const getMutationsGridData = (data, sequenceType, proportionInterval) => {
4442
4738
  return accumulateByPosition(data, sequenceType).filter((row) => byProportion(row, proportionInterval));
@@ -4468,8 +4764,8 @@ const accumulateByPosition = (data, sequenceType) => {
4468
4764
  };
4469
4765
  subtractSubstitutionValue();
4470
4766
  }
4471
- const orderedPositionsToProportionAtBase = [...positionsToProportionAtBase.entries()].map(([position, proportionsAtBase]) => ({ position, proportions: proportionsAtBase })).sort((a2, b2) => {
4472
- return sortMutationPositions(a2.position, b2.position);
4767
+ const orderedPositionsToProportionAtBase = [...positionsToProportionAtBase.entries()].map(([position, proportionsAtBase]) => ({ position, proportions: proportionsAtBase })).sort((a2, b3) => {
4768
+ return sortMutationPositions(a2.position, b3.position);
4473
4769
  });
4474
4770
  return orderedPositionsToProportionAtBase.map((proportionsForBaseAtPosition) => {
4475
4771
  const proportions = bases[sequenceType].map((base) => {
@@ -4500,8 +4796,8 @@ const MutationsGrid = ({ data, sequenceType, proportionInterval }) => {
4500
4796
  {
4501
4797
  name: "Position",
4502
4798
  sort: {
4503
- compare: (a2, b2) => {
4504
- return sortMutationPositions(a2, b2);
4799
+ compare: (a2, b3) => {
4800
+ return sortMutationPositions(a2, b3);
4505
4801
  }
4506
4802
  }
4507
4803
  },
@@ -4513,9 +4809,9 @@ const MutationsGrid = ({ data, sequenceType, proportionInterval }) => {
4513
4809
  return {
4514
4810
  name: base,
4515
4811
  sort: {
4516
- compare: (a2, b2) => {
4812
+ compare: (a2, b3) => {
4517
4813
  const aProportion = a2.proportion;
4518
- const bProportion = b2.proportion;
4814
+ const bProportion = b3.proportion;
4519
4815
  if (aProportion < bProportion) {
4520
4816
  return -1;
4521
4817
  }
@@ -4549,14 +4845,14 @@ const MutationsGrid = ({ data, sequenceType, proportionInterval }) => {
4549
4845
  const tableData = getMutationsGridData(data, sequenceType, proportionInterval).map((row) => Object.values(row));
4550
4846
  return /* @__PURE__ */ u$1(Table, { data: tableData, columns: getHeaders(), pagination: true });
4551
4847
  };
4552
- const sortInsertions = (a2, b2) => {
4553
- if (a2.segment !== b2.segment) {
4554
- return compareSegments(a2.segment, b2.segment);
4848
+ const sortInsertions = (a2, b3) => {
4849
+ if (a2.segment !== b3.segment) {
4850
+ return compareSegments(a2.segment, b3.segment);
4555
4851
  }
4556
- if (a2.position !== b2.position) {
4557
- return comparePositions(a2.position, b2.position);
4852
+ if (a2.position !== b3.position) {
4853
+ return comparePositions(a2.position, b3.position);
4558
4854
  }
4559
- return a2.insertedSymbols.localeCompare(b2.insertedSymbols);
4855
+ return a2.insertedSymbols.localeCompare(b3.insertedSymbols);
4560
4856
  };
4561
4857
  const InsertionsTable = ({ data }) => {
4562
4858
  const getHeaders = () => {
@@ -4564,8 +4860,8 @@ const InsertionsTable = ({ data }) => {
4564
4860
  {
4565
4861
  name: "Insertion",
4566
4862
  sort: {
4567
- compare: (a2, b2) => {
4568
- return sortInsertions(a2, b2);
4863
+ compare: (a2, b3) => {
4864
+ return sortInsertions(a2, b3);
4569
4865
  }
4570
4866
  },
4571
4867
  formatter: (cell) => cell.toString()
@@ -4585,8 +4881,8 @@ const MutationsTable = ({ data, proportionInterval }) => {
4585
4881
  {
4586
4882
  name: "Mutation",
4587
4883
  sort: {
4588
- compare: (a2, b2) => {
4589
- return sortSubstitutionsAndDeletions(a2, b2);
4884
+ compare: (a2, b3) => {
4885
+ return sortSubstitutionsAndDeletions(a2, b3);
4590
4886
  }
4591
4887
  },
4592
4888
  formatter: (cell) => cell.toString()
@@ -4626,11 +4922,11 @@ class FetchInsertionsOperator {
4626
4922
  }
4627
4923
  function queryInsertions(variant, sequenceType, lapis, signal) {
4628
4924
  const fetchData = new FetchInsertionsOperator(variant, sequenceType);
4629
- const sortData = new SortOperator(fetchData, (a2, b2) => {
4630
- if (a2.mutation.segment !== b2.mutation.segment) {
4631
- return (a2.mutation.segment ?? "").localeCompare(b2.mutation.segment ?? "");
4925
+ const sortData = new SortOperator(fetchData, (a2, b3) => {
4926
+ if (a2.mutation.segment !== b3.mutation.segment) {
4927
+ return (a2.mutation.segment ?? "").localeCompare(b3.mutation.segment ?? "");
4632
4928
  }
4633
- return a2.mutation.position - b2.mutation.position;
4929
+ return a2.mutation.position - b3.mutation.position;
4634
4930
  });
4635
4931
  return sortData.evaluate(lapis, signal);
4636
4932
  }
@@ -4667,23 +4963,28 @@ const Mutations = ({
4667
4963
  variant,
4668
4964
  sequenceType,
4669
4965
  views,
4670
- size,
4966
+ width,
4967
+ height,
4671
4968
  headline = "Mutations"
4672
4969
  }) => {
4970
+ const size = { height, width };
4971
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, headline, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(MutationsInner, { variant, sequenceType, views }) }) }) });
4972
+ };
4973
+ const MutationsInner = ({ variant, sequenceType, views }) => {
4673
4974
  const lapis = P(LapisUrlContext);
4674
4975
  const { data, error, isLoading } = useQuery(async () => {
4675
4976
  return queryMutationsData(variant, sequenceType, lapis);
4676
4977
  }, [variant, sequenceType, lapis]);
4677
4978
  if (isLoading) {
4678
- return /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(LoadingDisplay, {}) });
4979
+ return /* @__PURE__ */ u$1(LoadingDisplay, {});
4679
4980
  }
4680
4981
  if (error !== null) {
4681
- return /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(ErrorDisplay, { error }) });
4982
+ return /* @__PURE__ */ u$1(ErrorDisplay, { error });
4682
4983
  }
4683
4984
  if (data === null) {
4684
- return /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(NoDataDisplay, {}) });
4985
+ return /* @__PURE__ */ u$1(NoDataDisplay, {});
4685
4986
  }
4686
- return /* @__PURE__ */ u$1(ResizeContainer, { size, defaultSize: { height: "700px", width: "100%" }, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(MutationsTabs, { mutationsData: data, sequenceType, views }) }) });
4987
+ return /* @__PURE__ */ u$1(MutationsTabs, { mutationsData: data, sequenceType, views });
4687
4988
  };
4688
4989
  const MutationsTabs = ({ mutationsData, sequenceType, views }) => {
4689
4990
  const [proportionInterval, setProportionInterval] = p({ min: 0.05, max: 1 });
@@ -4803,10 +5104,11 @@ var __decorateClass$7 = (decorators, target, key, kind) => {
4803
5104
  let MutationsComponent = class extends PreactLitAdapterWithGridJsStyles {
4804
5105
  constructor() {
4805
5106
  super(...arguments);
4806
- this.variant = { displayName: "" };
5107
+ this.variant = {};
4807
5108
  this.sequenceType = "nucleotide";
4808
5109
  this.views = ["table", "grid"];
4809
- this.size = void 0;
5110
+ this.width = "100%";
5111
+ this.height = "700px";
4810
5112
  this.headline = "Mutations";
4811
5113
  }
4812
5114
  render() {
@@ -4816,7 +5118,8 @@ let MutationsComponent = class extends PreactLitAdapterWithGridJsStyles {
4816
5118
  variant: this.variant,
4817
5119
  sequenceType: this.sequenceType,
4818
5120
  views: this.views,
4819
- size: this.size,
5121
+ width: this.width,
5122
+ height: this.height,
4820
5123
  headline: this.headline
4821
5124
  }
4822
5125
  );
@@ -4832,13 +5135,16 @@ __decorateClass$7([
4832
5135
  n2({ type: Array })
4833
5136
  ], MutationsComponent.prototype, "views", 2);
4834
5137
  __decorateClass$7([
4835
- n2({ type: Object })
4836
- ], MutationsComponent.prototype, "size", 2);
5138
+ n2({ type: String })
5139
+ ], MutationsComponent.prototype, "width", 2);
5140
+ __decorateClass$7([
5141
+ n2({ type: String })
5142
+ ], MutationsComponent.prototype, "height", 2);
4837
5143
  __decorateClass$7([
4838
5144
  n2({ type: String })
4839
5145
  ], MutationsComponent.prototype, "headline", 2);
4840
5146
  MutationsComponent = __decorateClass$7([
4841
- t$2("gs-mutations-component")
5147
+ t$2("gs-mutations")
4842
5148
  ], MutationsComponent);
4843
5149
  function getPrevalenceOverTimeTableData(data, granularity) {
4844
5150
  return data[0].content.map((row, rowNumber) => {
@@ -5055,14 +5361,14 @@ var padZoneStr = function padZoneStr2(instance) {
5055
5361
  var minuteOffset = minutes % 60;
5056
5362
  return (negMinutes <= 0 ? "+" : "-") + padStart(hourOffset, 2, "0") + ":" + padStart(minuteOffset, 2, "0");
5057
5363
  };
5058
- var monthDiff = function monthDiff2(a2, b2) {
5059
- if (a2.date() < b2.date())
5060
- return -monthDiff2(b2, a2);
5061
- var wholeMonthDiff = (b2.year() - a2.year()) * 12 + (b2.month() - a2.month());
5364
+ var monthDiff = function monthDiff2(a2, b3) {
5365
+ if (a2.date() < b3.date())
5366
+ return -monthDiff2(b3, a2);
5367
+ var wholeMonthDiff = (b3.year() - a2.year()) * 12 + (b3.month() - a2.month());
5062
5368
  var anchor = a2.clone().add(wholeMonthDiff, M);
5063
- var c2 = b2 - anchor < 0;
5369
+ var c2 = b3 - anchor < 0;
5064
5370
  var anchor2 = a2.clone().add(wholeMonthDiff + (c2 ? -1 : 1), M);
5065
- return +(-(wholeMonthDiff + (b2 - anchor) / (c2 ? anchor - anchor2 : anchor2 - anchor)) || 0);
5371
+ return +(-(wholeMonthDiff + (b3 - anchor) / (c2 ? anchor - anchor2 : anchor2 - anchor)) || 0);
5066
5372
  };
5067
5373
  var absFloor = function absFloor2(n3) {
5068
5374
  return n3 < 0 ? Math.ceil(n3) || 0 : Math.floor(n3);
@@ -5796,29 +6102,29 @@ function generateAllInRange(start, end) {
5796
6102
  }
5797
6103
  throw new Error(`Invalid arguments: start and end must be of the same type: ${start}, ${end}`);
5798
6104
  }
5799
- function minusTemporal(a2, b2) {
5800
- if (a2 instanceof YearMonthDay && b2 instanceof YearMonthDay) {
5801
- return a2.minus(b2);
6105
+ function minusTemporal(a2, b3) {
6106
+ if (a2 instanceof YearMonthDay && b3 instanceof YearMonthDay) {
6107
+ return a2.minus(b3);
5802
6108
  }
5803
- if (a2 instanceof YearWeek && b2 instanceof YearWeek) {
5804
- return a2.minus(b2);
6109
+ if (a2 instanceof YearWeek && b3 instanceof YearWeek) {
6110
+ return a2.minus(b3);
5805
6111
  }
5806
- if (a2 instanceof YearMonth && b2 instanceof YearMonth) {
5807
- return a2.minus(b2);
6112
+ if (a2 instanceof YearMonth && b3 instanceof YearMonth) {
6113
+ return a2.minus(b3);
5808
6114
  }
5809
- if (a2 instanceof Year && b2 instanceof Year) {
5810
- return a2.minus(b2);
6115
+ if (a2 instanceof Year && b3 instanceof Year) {
6116
+ return a2.minus(b3);
5811
6117
  }
5812
- throw new Error(`Cannot compare ${a2} and ${b2}`);
6118
+ throw new Error(`Cannot compare ${a2} and ${b3}`);
5813
6119
  }
5814
- function compareTemporal(a2, b2) {
6120
+ function compareTemporal(a2, b3) {
5815
6121
  if (a2 === null) {
5816
6122
  return 1;
5817
6123
  }
5818
- if (b2 === null) {
6124
+ if (b3 === null) {
5819
6125
  return -1;
5820
6126
  }
5821
- const diff = minusTemporal(a2, b2);
6127
+ const diff = minusTemporal(a2, b3);
5822
6128
  if (diff < 0) {
5823
6129
  return -1;
5824
6130
  }
@@ -6228,10 +6534,10 @@ class SlidingOperator {
6228
6534
  }
6229
6535
  function queryPrevalenceOverTime(numeratorFilter, denominatorFilter, granularity, smoothingWindow, lapis, signal) {
6230
6536
  const numeratorFilters = makeArray(numeratorFilter);
6231
- const denominatorData = fetchAndPrepare(getFilter(denominatorFilter), granularity, smoothingWindow);
6537
+ const denominatorData = fetchAndPrepare(denominatorFilter, granularity, smoothingWindow);
6232
6538
  const subQueries = numeratorFilters.map(async (namedLapisFilter) => {
6233
- const { displayName, ...filter } = namedLapisFilter;
6234
- const numeratorData = fetchAndPrepare(filter, granularity, smoothingWindow);
6539
+ const { displayName, lapisFilter } = namedLapisFilter;
6540
+ const numeratorData = fetchAndPrepare(lapisFilter, granularity, smoothingWindow);
6235
6541
  const divide = new DivisionOperator(
6236
6542
  numeratorData,
6237
6543
  denominatorData,
@@ -6249,10 +6555,6 @@ function queryPrevalenceOverTime(numeratorFilter, denominatorFilter, granularity
6249
6555
  });
6250
6556
  return Promise.all(subQueries);
6251
6557
  }
6252
- function getFilter(filter) {
6253
- const { displayName, ...filterWithoutDisplayName } = filter;
6254
- return filterWithoutDisplayName;
6255
- }
6256
6558
  function makeArray(arrayOrSingleItem) {
6257
6559
  if (Array.isArray(arrayOrSingleItem)) {
6258
6560
  return arrayOrSingleItem;
@@ -6297,14 +6599,14 @@ function mapDateToGranularityRange(d2, granularity) {
6297
6599
  count: d2.count
6298
6600
  };
6299
6601
  }
6300
- function dateRangeCompare(a2, b2) {
6602
+ function dateRangeCompare(a2, b3) {
6301
6603
  if (a2.dateRange === null) {
6302
6604
  return 1;
6303
6605
  }
6304
- if (b2.dateRange === null) {
6606
+ if (b3.dateRange === null) {
6305
6607
  return -1;
6306
6608
  }
6307
- return compareTemporal(a2.dateRange, b2.dateRange);
6609
+ return compareTemporal(a2.dateRange, b3.dateRange);
6308
6610
  }
6309
6611
  function averageSmoothing(slidingWindow) {
6310
6612
  const average = slidingWindow.reduce((acc, curr) => acc + curr.count, 0) / slidingWindow.length;
@@ -6379,8 +6681,30 @@ const PrevalenceOverTime = ({
6379
6681
  smoothingWindow,
6380
6682
  views,
6381
6683
  confidenceIntervalMethods,
6382
- size,
6684
+ width,
6685
+ height,
6383
6686
  headline = "Prevalence over time"
6687
+ }) => {
6688
+ const size = { height, width };
6689
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, headline, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(
6690
+ PrevalenceOverTimeInner,
6691
+ {
6692
+ numerator,
6693
+ denominator,
6694
+ granularity,
6695
+ smoothingWindow,
6696
+ views,
6697
+ confidenceIntervalMethods
6698
+ }
6699
+ ) }) }) });
6700
+ };
6701
+ const PrevalenceOverTimeInner = ({
6702
+ numerator,
6703
+ denominator,
6704
+ granularity,
6705
+ smoothingWindow,
6706
+ views,
6707
+ confidenceIntervalMethods
6384
6708
  }) => {
6385
6709
  const lapis = P(LapisUrlContext);
6386
6710
  const { data, error, isLoading } = useQuery(
@@ -6388,15 +6712,15 @@ const PrevalenceOverTime = ({
6388
6712
  [lapis, numerator, denominator, granularity, smoothingWindow]
6389
6713
  );
6390
6714
  if (isLoading) {
6391
- return /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(LoadingDisplay, {}) });
6715
+ return /* @__PURE__ */ u$1(LoadingDisplay, {});
6392
6716
  }
6393
6717
  if (error !== null) {
6394
- return /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(ErrorDisplay, { error }) });
6718
+ return /* @__PURE__ */ u$1(ErrorDisplay, { error });
6395
6719
  }
6396
6720
  if (data === null) {
6397
- return /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(NoDataDisplay, {}) });
6721
+ return /* @__PURE__ */ u$1(NoDataDisplay, {});
6398
6722
  }
6399
- return /* @__PURE__ */ u$1(ResizeContainer, { size, defaultSize: { height: "600px", width: "100%" }, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(
6723
+ return /* @__PURE__ */ u$1(
6400
6724
  PrevalenceOverTimeTabs,
6401
6725
  {
6402
6726
  views,
@@ -6404,7 +6728,7 @@ const PrevalenceOverTime = ({
6404
6728
  granularity,
6405
6729
  confidenceIntervalMethods
6406
6730
  }
6407
- ) }) });
6731
+ );
6408
6732
  };
6409
6733
  const PrevalenceOverTimeTabs = ({
6410
6734
  views,
@@ -6521,14 +6845,15 @@ var __decorateClass$6 = (decorators, target, key, kind) => {
6521
6845
  let PrevalenceOverTimeComponent = class extends PreactLitAdapterWithGridJsStyles {
6522
6846
  constructor() {
6523
6847
  super(...arguments);
6524
- this.numerator = { displayName: "" };
6525
- this.denominator = { displayName: "" };
6848
+ this.numerator = { displayName: "", lapisFilter: {} };
6849
+ this.denominator = {};
6526
6850
  this.granularity = "day";
6527
6851
  this.smoothingWindow = 0;
6528
6852
  this.views = ["bar", "line", "bubble", "table"];
6529
6853
  this.confidenceIntervalMethods = ["wilson"];
6530
6854
  this.headline = "Prevalence over time";
6531
- this.size = void 0;
6855
+ this.width = "100%";
6856
+ this.height = "700px";
6532
6857
  }
6533
6858
  render() {
6534
6859
  return /* @__PURE__ */ u$1(
@@ -6540,7 +6865,8 @@ let PrevalenceOverTimeComponent = class extends PreactLitAdapterWithGridJsStyles
6540
6865
  smoothingWindow: this.smoothingWindow,
6541
6866
  views: this.views,
6542
6867
  confidenceIntervalMethods: this.confidenceIntervalMethods,
6543
- size: this.size,
6868
+ width: this.width,
6869
+ height: this.height,
6544
6870
  headline: this.headline
6545
6871
  }
6546
6872
  );
@@ -6568,8 +6894,11 @@ __decorateClass$6([
6568
6894
  n2({ type: String })
6569
6895
  ], PrevalenceOverTimeComponent.prototype, "headline", 2);
6570
6896
  __decorateClass$6([
6571
- n2({ type: Object })
6572
- ], PrevalenceOverTimeComponent.prototype, "size", 2);
6897
+ n2({ type: String })
6898
+ ], PrevalenceOverTimeComponent.prototype, "width", 2);
6899
+ __decorateClass$6([
6900
+ n2({ type: String })
6901
+ ], PrevalenceOverTimeComponent.prototype, "height", 2);
6573
6902
  PrevalenceOverTimeComponent = __decorateClass$6([
6574
6903
  t$2("gs-prevalence-over-time")
6575
6904
  ], PrevalenceOverTimeComponent);
@@ -6759,12 +7088,30 @@ function toYearMonthDay(d2) {
6759
7088
  };
6760
7089
  }
6761
7090
  const RelativeGrowthAdvantage = ({
7091
+ views,
7092
+ width,
7093
+ height,
6762
7094
  numerator,
6763
7095
  denominator,
6764
7096
  generationTime,
6765
- views,
6766
- size,
6767
7097
  headline = "Relative growth advantage"
7098
+ }) => {
7099
+ const size = { height, width };
7100
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, headline, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(
7101
+ RelativeGrowthAdvantageInner,
7102
+ {
7103
+ views,
7104
+ numerator,
7105
+ denominator,
7106
+ generationTime
7107
+ }
7108
+ ) }) }) });
7109
+ };
7110
+ const RelativeGrowthAdvantageInner = ({
7111
+ numerator,
7112
+ denominator,
7113
+ generationTime,
7114
+ views
6768
7115
  }) => {
6769
7116
  const lapis = P(LapisUrlContext);
6770
7117
  const [yAxisScaleType, setYAxisScaleType] = p("linear");
@@ -6773,15 +7120,15 @@ const RelativeGrowthAdvantage = ({
6773
7120
  [lapis, numerator, denominator, generationTime, views]
6774
7121
  );
6775
7122
  if (isLoading) {
6776
- return /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(LoadingDisplay, {}) });
7123
+ return /* @__PURE__ */ u$1(LoadingDisplay, {});
6777
7124
  }
6778
7125
  if (error !== null) {
6779
- return /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(ErrorDisplay, { error }) });
7126
+ return /* @__PURE__ */ u$1(ErrorDisplay, { error });
6780
7127
  }
6781
7128
  if (data === null) {
6782
- return /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(NoDataDisplay, {}) });
7129
+ return /* @__PURE__ */ u$1(NoDataDisplay, {});
6783
7130
  }
6784
- return /* @__PURE__ */ u$1(ResizeContainer, { size, defaultSize: { height: "700px", width: "100%" }, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(
7131
+ return /* @__PURE__ */ u$1(
6785
7132
  RelativeGrowthAdvantageTabs,
6786
7133
  {
6787
7134
  data,
@@ -6790,7 +7137,7 @@ const RelativeGrowthAdvantage = ({
6790
7137
  views,
6791
7138
  generationTime
6792
7139
  }
6793
- ) }) });
7140
+ );
6794
7141
  };
6795
7142
  const RelativeGrowthAdvantageTabs = ({
6796
7143
  data,
@@ -6879,7 +7226,8 @@ let RelativeGrowthAdvantageComponent = class extends PreactLitAdapter {
6879
7226
  this.generationTime = 7;
6880
7227
  this.views = ["line"];
6881
7228
  this.headline = "Relative growth advantage";
6882
- this.size = void 0;
7229
+ this.width = "100%";
7230
+ this.height = "700px";
6883
7231
  }
6884
7232
  render() {
6885
7233
  return /* @__PURE__ */ u$1(
@@ -6889,7 +7237,8 @@ let RelativeGrowthAdvantageComponent = class extends PreactLitAdapter {
6889
7237
  denominator: this.denominator,
6890
7238
  generationTime: this.generationTime,
6891
7239
  views: this.views,
6892
- size: this.size,
7240
+ width: this.width,
7241
+ height: this.height,
6893
7242
  headline: this.headline
6894
7243
  }
6895
7244
  );
@@ -6911,8 +7260,11 @@ __decorateClass$5([
6911
7260
  n2({ type: String })
6912
7261
  ], RelativeGrowthAdvantageComponent.prototype, "headline", 2);
6913
7262
  __decorateClass$5([
6914
- n2({ type: Object })
6915
- ], RelativeGrowthAdvantageComponent.prototype, "size", 2);
7263
+ n2({ type: String })
7264
+ ], RelativeGrowthAdvantageComponent.prototype, "width", 2);
7265
+ __decorateClass$5([
7266
+ n2({ type: String })
7267
+ ], RelativeGrowthAdvantageComponent.prototype, "height", 2);
6916
7268
  RelativeGrowthAdvantageComponent = __decorateClass$5([
6917
7269
  t$2("gs-relative-growth-advantage")
6918
7270
  ], RelativeGrowthAdvantageComponent);
@@ -6948,26 +7300,31 @@ async function queryAggregateData(variant, fields, lapis, signal) {
6948
7300
  );
6949
7301
  }
6950
7302
  const Aggregate = ({
6951
- fields,
6952
7303
  views,
7304
+ width,
7305
+ height,
7306
+ headline = "Mutations",
6953
7307
  filter,
6954
- size,
6955
- headline = "Aggregate"
7308
+ fields
6956
7309
  }) => {
7310
+ const size = { height, width };
7311
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, headline, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(AggregateInner, { fields, filter, views }) }) }) });
7312
+ };
7313
+ const AggregateInner = ({ fields, views, filter }) => {
6957
7314
  const lapis = P(LapisUrlContext);
6958
7315
  const { data, error, isLoading } = useQuery(async () => {
6959
7316
  return queryAggregateData(filter, fields, lapis);
6960
7317
  }, [filter, fields, lapis]);
6961
7318
  if (isLoading) {
6962
- return /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(LoadingDisplay, {}) });
7319
+ return /* @__PURE__ */ u$1(LoadingDisplay, {});
6963
7320
  }
6964
7321
  if (error !== null) {
6965
- return /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(ErrorDisplay, { error }) });
7322
+ return /* @__PURE__ */ u$1(ErrorDisplay, { error });
6966
7323
  }
6967
7324
  if (data === null) {
6968
- return /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(NoDataDisplay, {}) });
7325
+ return /* @__PURE__ */ u$1(NoDataDisplay, {});
6969
7326
  }
6970
- return /* @__PURE__ */ u$1(ResizeContainer, { size, defaultSize: { height: "700px", width: "100%" }, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(AggregatedDataTabs, { data, views, fields }) }) });
7327
+ return /* @__PURE__ */ u$1(AggregatedDataTabs, { data, views, fields });
6971
7328
  };
6972
7329
  const AggregatedDataTabs = ({ data, views, fields }) => {
6973
7330
  const getTab = (view) => {
@@ -7005,7 +7362,8 @@ let AggregateComponent = class extends PreactLitAdapterWithGridJsStyles {
7005
7362
  this.fields = [];
7006
7363
  this.views = ["table"];
7007
7364
  this.filter = {};
7008
- this.size = void 0;
7365
+ this.width = "100%";
7366
+ this.height = "700px";
7009
7367
  this.headline = "Aggregate";
7010
7368
  }
7011
7369
  render() {
@@ -7015,7 +7373,8 @@ let AggregateComponent = class extends PreactLitAdapterWithGridJsStyles {
7015
7373
  fields: this.fields,
7016
7374
  views: this.views,
7017
7375
  filter: this.filter,
7018
- size: this.size,
7376
+ width: this.width,
7377
+ height: this.height,
7019
7378
  headline: this.headline
7020
7379
  }
7021
7380
  );
@@ -7031,13 +7390,16 @@ __decorateClass$4([
7031
7390
  n2({ type: Object })
7032
7391
  ], AggregateComponent.prototype, "filter", 2);
7033
7392
  __decorateClass$4([
7034
- n2({ type: Object })
7035
- ], AggregateComponent.prototype, "size", 2);
7393
+ n2({ type: String })
7394
+ ], AggregateComponent.prototype, "width", 2);
7395
+ __decorateClass$4([
7396
+ n2({ type: String })
7397
+ ], AggregateComponent.prototype, "height", 2);
7036
7398
  __decorateClass$4([
7037
7399
  n2({ type: String })
7038
7400
  ], AggregateComponent.prototype, "headline", 2);
7039
7401
  AggregateComponent = __decorateClass$4([
7040
- t$2("gs-aggregate-component")
7402
+ t$2("gs-aggregate")
7041
7403
  ], AggregateComponent);
7042
7404
  const toYYYYMMDD = (date) => {
7043
7405
  if (!date) {
@@ -7065,7 +7427,26 @@ const presets = {
7065
7427
  const DateRangeSelector = ({
7066
7428
  customSelectOptions,
7067
7429
  earliestDate = "1900-01-01",
7068
- initialValue
7430
+ initialValue,
7431
+ width,
7432
+ dateColumn
7433
+ }) => {
7434
+ const size = { width, height: "3rem" };
7435
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(
7436
+ DateRangeSelectorInner,
7437
+ {
7438
+ customSelectOptions,
7439
+ earliestDate,
7440
+ initialValue,
7441
+ dateColumn
7442
+ }
7443
+ ) }) });
7444
+ };
7445
+ const DateRangeSelectorInner = ({
7446
+ customSelectOptions,
7447
+ earliestDate = "1900-01-01",
7448
+ initialValue,
7449
+ dateColumn
7069
7450
  }) => {
7070
7451
  const fromDatePickerRef = F(null);
7071
7452
  const toDatePickerRef = F(null);
@@ -7142,8 +7523,8 @@ const DateRangeSelector = ({
7142
7523
  const dateFrom = toYYYYMMDD(dateFromPicker == null ? void 0 : dateFromPicker.selectedDates[0]);
7143
7524
  const dateTo = toYYYYMMDD(dateToPicker == null ? void 0 : dateToPicker.selectedDates[0]);
7144
7525
  const detail = {
7145
- ...dateFrom !== void 0 && { dateFrom },
7146
- ...dateTo !== void 0 && { dateTo }
7526
+ ...dateFrom !== void 0 && { [`${dateColumn}From`]: dateFrom },
7527
+ ...dateTo !== void 0 && { [`${dateColumn}To`]: dateTo }
7147
7528
  };
7148
7529
  (_a = divRef.current) == null ? void 0 : _a.dispatchEvent(
7149
7530
  new CustomEvent("gs-date-range-changed", {
@@ -7153,13 +7534,13 @@ const DateRangeSelector = ({
7153
7534
  })
7154
7535
  );
7155
7536
  };
7156
- return /* @__PURE__ */ u$1("div", { class: "join", ref: divRef, children: [
7537
+ return /* @__PURE__ */ u$1("div", { class: "join w-full", ref: divRef, children: [
7157
7538
  /* @__PURE__ */ u$1(
7158
7539
  Select,
7159
7540
  {
7160
7541
  items: selectableOptions,
7161
7542
  selected: selectedDateRange,
7162
- selectStyle: "select-bordered rounded-none join-item",
7543
+ selectStyle: "select-bordered rounded-none join-item grow",
7163
7544
  onChange: (event) => {
7164
7545
  event.preventDefault();
7165
7546
  const select = event.target;
@@ -7171,7 +7552,7 @@ const DateRangeSelector = ({
7171
7552
  /* @__PURE__ */ u$1(
7172
7553
  "input",
7173
7554
  {
7174
- class: "input input-bordered rounded-none join-item",
7555
+ class: "input input-bordered rounded-none join-item grow",
7175
7556
  type: "text",
7176
7557
  placeholder: "Date from",
7177
7558
  ref: fromDatePickerRef,
@@ -7182,7 +7563,7 @@ const DateRangeSelector = ({
7182
7563
  /* @__PURE__ */ u$1(
7183
7564
  "input",
7184
7565
  {
7185
- class: "input input-bordered rounded-none join-item",
7566
+ class: "input input-bordered rounded-none join-item grow",
7186
7567
  type: "text",
7187
7568
  placeholder: "Date to",
7188
7569
  ref: toDatePickerRef,
@@ -7257,6 +7638,8 @@ let DateRangeSelectorComponent = class extends PreactLitAdapter {
7257
7638
  this.customSelectOptions = [];
7258
7639
  this.earliestDate = "1900-01-01";
7259
7640
  this.initialValue = "last6Months";
7641
+ this.width = "100%";
7642
+ this.dateColumn = "date";
7260
7643
  }
7261
7644
  render() {
7262
7645
  return /* @__PURE__ */ u$1(
@@ -7264,7 +7647,9 @@ let DateRangeSelectorComponent = class extends PreactLitAdapter {
7264
7647
  {
7265
7648
  customSelectOptions: this.customSelectOptions,
7266
7649
  earliestDate: this.earliestDate,
7267
- initialValue: this.initialValue
7650
+ initialValue: this.initialValue,
7651
+ dateColumn: this.dateColumn,
7652
+ width: this.width
7268
7653
  }
7269
7654
  );
7270
7655
  }
@@ -7278,13 +7663,30 @@ __decorateClass$3([
7278
7663
  __decorateClass$3([
7279
7664
  n2()
7280
7665
  ], DateRangeSelectorComponent.prototype, "initialValue", 2);
7666
+ __decorateClass$3([
7667
+ n2({ type: String })
7668
+ ], DateRangeSelectorComponent.prototype, "width", 2);
7669
+ __decorateClass$3([
7670
+ n2({ type: String })
7671
+ ], DateRangeSelectorComponent.prototype, "dateColumn", 2);
7281
7672
  DateRangeSelectorComponent = __decorateClass$3([
7282
7673
  t$2("gs-date-range-selector")
7283
7674
  ], DateRangeSelectorComponent);
7284
7675
  async function fetchAutocompletionList(fields, lapis, signal) {
7285
7676
  const toAncestorInHierarchyOverwriteValues = Array(fields.length - 1).fill(0).map((_2, i2) => i2 + 1).map((i2) => fields.slice(i2).reduce((acc, field) => ({ ...acc, [field]: null }), {}));
7286
7677
  const fetchAggregatedOperator = new FetchAggregatedOperator({}, fields);
7287
- const data = (await fetchAggregatedOperator.evaluate(lapis, signal)).content;
7678
+ let data;
7679
+ try {
7680
+ data = (await fetchAggregatedOperator.evaluate(lapis, signal)).content;
7681
+ } catch (error) {
7682
+ if (error instanceof LapisError) {
7683
+ throw new UserFacingError(
7684
+ `Failed to fetch autocomplete list from LAPIS: ${error.problemDetail.status} ${error.problemDetail.title ?? ""}`,
7685
+ error.problemDetail.detail ?? error.message
7686
+ );
7687
+ }
7688
+ throw error;
7689
+ }
7288
7690
  const locationValues = data.map((entry) => fields.reduce((acc, field) => ({ ...acc, [field]: entry[field] }), {})).reduce((setOfAllHierarchies, entry) => {
7289
7691
  setOfAllHierarchies.add(JSON.stringify(entry));
7290
7692
  toAncestorInHierarchyOverwriteValues.forEach((overwriteValues) => {
@@ -7295,10 +7697,10 @@ async function fetchAutocompletionList(fields, lapis, signal) {
7295
7697
  return [...locationValues].map((json) => JSON.parse(json)).sort(compareLocationEntries(fields));
7296
7698
  }
7297
7699
  function compareLocationEntries(fields) {
7298
- return (a2, b2) => {
7700
+ return (a2, b3) => {
7299
7701
  for (const field of fields) {
7300
7702
  const valueA = a2[field];
7301
- const valueB = b2[field];
7703
+ const valueB = b3[field];
7302
7704
  if (valueA === valueB) {
7303
7705
  continue;
7304
7706
  }
@@ -7313,26 +7715,21 @@ function compareLocationEntries(fields) {
7313
7715
  return 0;
7314
7716
  };
7315
7717
  }
7316
- const LocationFilter = ({ initialValue, fields }) => {
7718
+ const LocationFilter = ({ width, initialValue, fields }) => {
7719
+ const size = { width, height: "3rem" };
7720
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(LocationFilterInner, { initialValue, fields }) }) });
7721
+ };
7722
+ const LocationFilterInner = ({ initialValue, fields }) => {
7317
7723
  const lapis = P(LapisUrlContext);
7318
7724
  const [value, setValue] = p(initialValue ?? "");
7319
7725
  const [unknownLocation, setUnknownLocation] = p(false);
7320
7726
  const formRef = F(null);
7321
7727
  const { data, error, isLoading } = useQuery(() => fetchAutocompletionList(fields, lapis), [fields, lapis]);
7322
- if (isLoading)
7323
- return /* @__PURE__ */ u$1("form", { class: "flex", children: [
7324
- /* @__PURE__ */ u$1("input", { type: "text", class: "input input-bordered grow", value, disabled: true }),
7325
- /* @__PURE__ */ u$1("button", { class: "btn ml-1", disabled: true, type: "submit", children: "Loading..." })
7326
- ] });
7728
+ if (isLoading) {
7729
+ return /* @__PURE__ */ u$1(LoadingDisplay, {});
7730
+ }
7327
7731
  if (error) {
7328
- return /* @__PURE__ */ u$1("p", { children: [
7329
- "Error: ",
7330
- error.name,
7331
- " ",
7332
- error.message,
7333
- " ",
7334
- error.stack
7335
- ] });
7732
+ return /* @__PURE__ */ u$1(ErrorDisplay, { error });
7336
7733
  }
7337
7734
  const onInput = (event) => {
7338
7735
  if (event.target instanceof HTMLInputElement) {
@@ -7363,7 +7760,7 @@ const LocationFilter = ({ initialValue, fields }) => {
7363
7760
  setUnknownLocation(true);
7364
7761
  }
7365
7762
  };
7366
- return /* @__PURE__ */ u$1("form", { class: "flex", onSubmit: submit, ref: formRef, children: [
7763
+ return /* @__PURE__ */ u$1("form", { class: "flex w-full", onSubmit: submit, ref: formRef, children: [
7367
7764
  /* @__PURE__ */ u$1(
7368
7765
  "input",
7369
7766
  {
@@ -7408,9 +7805,10 @@ let LocationFilterComponent = class extends PreactLitAdapter {
7408
7805
  super(...arguments);
7409
7806
  this.initialValue = "";
7410
7807
  this.fields = [];
7808
+ this.width = "100%";
7411
7809
  }
7412
7810
  render() {
7413
- return /* @__PURE__ */ u$1(LocationFilter, { initialValue: this.initialValue, fields: this.fields });
7811
+ return /* @__PURE__ */ u$1(LocationFilter, { initialValue: this.initialValue, fields: this.fields, width: this.width });
7414
7812
  }
7415
7813
  };
7416
7814
  __decorateClass$2([
@@ -7419,6 +7817,9 @@ __decorateClass$2([
7419
7817
  __decorateClass$2([
7420
7818
  n2({ type: Array })
7421
7819
  ], LocationFilterComponent.prototype, "fields", 2);
7820
+ __decorateClass$2([
7821
+ n2({ type: String })
7822
+ ], LocationFilterComponent.prototype, "width", 2);
7422
7823
  LocationFilterComponent = __decorateClass$2([
7423
7824
  t$2("gs-location-filter")
7424
7825
  ], LocationFilterComponent);
@@ -7427,7 +7828,15 @@ async function fetchAutocompleteList(lapis, field, signal) {
7427
7828
  const data = (await fetchAggregatedOperator.evaluate(lapis, signal)).content;
7428
7829
  return data.map((item) => item[field]);
7429
7830
  }
7430
- const TextInput = ({ lapisField, placeholderText, initialValue }) => {
7831
+ const TextInput = ({ width, lapisField, placeholderText, initialValue }) => {
7832
+ const size = { width, height: "3rem" };
7833
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(TextInputInner, { lapisField, placeholderText, initialValue }) }) });
7834
+ };
7835
+ const TextInputInner = ({
7836
+ lapisField,
7837
+ placeholderText,
7838
+ initialValue
7839
+ }) => {
7431
7840
  const lapis = P(LapisUrlContext);
7432
7841
  const inputRef = F(null);
7433
7842
  const { data, error, isLoading } = useQuery(() => fetchAutocompleteList(lapis, lapisField), [lapisField, lapis]);
@@ -7464,7 +7873,7 @@ const TextInput = ({ lapisField, placeholderText, initialValue }) => {
7464
7873
  "input",
7465
7874
  {
7466
7875
  type: "text",
7467
- class: "input input-bordered",
7876
+ class: "input input-bordered w-full",
7468
7877
  placeholder: placeholderText !== void 0 ? placeholderText : lapisField,
7469
7878
  onInput,
7470
7879
  ref: inputRef,
@@ -7492,6 +7901,7 @@ let TextInputComponent = class extends PreactLitAdapter {
7492
7901
  this.initialValue = "";
7493
7902
  this.lapisField = "";
7494
7903
  this.placeholderText = "";
7904
+ this.width = "100%";
7495
7905
  }
7496
7906
  render() {
7497
7907
  return /* @__PURE__ */ u$1(
@@ -7499,7 +7909,8 @@ let TextInputComponent = class extends PreactLitAdapter {
7499
7909
  {
7500
7910
  lapisField: this.lapisField,
7501
7911
  placeholderText: this.placeholderText,
7502
- initialValue: this.initialValue
7912
+ initialValue: this.initialValue,
7913
+ width: this.width
7503
7914
  }
7504
7915
  );
7505
7916
  }
@@ -7513,6 +7924,9 @@ __decorateClass$1([
7513
7924
  __decorateClass$1([
7514
7925
  n2()
7515
7926
  ], TextInputComponent.prototype, "placeholderText", 2);
7927
+ __decorateClass$1([
7928
+ n2({ type: String })
7929
+ ], TextInputComponent.prototype, "width", 2);
7516
7930
  TextInputComponent = __decorateClass$1([
7517
7931
  t$2("gs-text-input")
7518
7932
  ], TextInputComponent);
@@ -7592,7 +8006,11 @@ const DeleteIcon = () => {
7592
8006
  }
7593
8007
  );
7594
8008
  };
7595
- const MutationFilter = ({ initialValue }) => {
8009
+ const MutationFilter = ({ initialValue, width, height }) => {
8010
+ const size = { height, width };
8011
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(MutationFilterInner, { initialValue }) }) });
8012
+ };
8013
+ const MutationFilterInner = ({ initialValue }) => {
7596
8014
  const referenceGenome = P(ReferenceGenomeContext);
7597
8015
  const [selectedFilters, setSelectedFilters] = p(
7598
8016
  getInitialState(initialValue, referenceGenome)
@@ -7641,7 +8059,7 @@ const MutationFilter = ({ initialValue }) => {
7641
8059
  setInputValue(event.target.value);
7642
8060
  setIsError(false);
7643
8061
  };
7644
- return /* @__PURE__ */ u$1("div", { class: `rounded-lg border border-gray-300 bg-white p-2`, children: [
8062
+ return /* @__PURE__ */ u$1("div", { class: `h-full w-full rounded-lg border border-gray-300 bg-white p-2 overflow-scroll`, children: [
7645
8063
  /* @__PURE__ */ u$1("div", { class: "flex justify-between", children: [
7646
8064
  /* @__PURE__ */ u$1(
7647
8065
  SelectedMutationDisplay,
@@ -7804,11 +8222,11 @@ const SelectedFilter = ({
7804
8222
  return /* @__PURE__ */ u$1(
7805
8223
  "div",
7806
8224
  {
7807
- class: "flex items-center flex-nowrap gap-1 rounded me-1 px-2.5 py-0.5 font-medium text-xs mb-1",
8225
+ class: "flex items-center flex-nowrap gap-1 rounded me-1 px-2.5 py-0.5 font-medium text-xs mb-1 min-w-max",
7808
8226
  style: { backgroundColor, color: textColor },
7809
8227
  children: [
7810
- /* @__PURE__ */ u$1("div", { children: mutation.toString() }),
7811
- /* @__PURE__ */ u$1("button", { onClick: () => onDelete(mutation), children: /* @__PURE__ */ u$1(DeleteIcon, {}) })
8228
+ /* @__PURE__ */ u$1("div", { className: "whitespace-nowrap min-w-max", children: mutation.toString() }),
8229
+ /* @__PURE__ */ u$1("button", { type: "button", onClick: () => onDelete(mutation), children: /* @__PURE__ */ u$1(DeleteIcon, {}) })
7812
8230
  ]
7813
8231
  }
7814
8232
  );
@@ -7836,14 +8254,22 @@ let MutationFilterComponent = class extends PreactLitAdapter {
7836
8254
  constructor() {
7837
8255
  super(...arguments);
7838
8256
  this.initialValue = void 0;
8257
+ this.width = "100%";
8258
+ this.height = "6.5rem";
7839
8259
  }
7840
8260
  render() {
7841
- return /* @__PURE__ */ u$1(ReferenceGenomesAwaiter, { children: /* @__PURE__ */ u$1(MutationFilter, { initialValue: this.initialValue }) });
8261
+ return /* @__PURE__ */ u$1(ReferenceGenomesAwaiter, { children: /* @__PURE__ */ u$1(MutationFilter, { initialValue: this.initialValue, width: this.width, height: this.height }) });
7842
8262
  }
7843
8263
  };
7844
8264
  __decorateClass([
7845
8265
  n2()
7846
8266
  ], MutationFilterComponent.prototype, "initialValue", 2);
8267
+ __decorateClass([
8268
+ n2({ type: String })
8269
+ ], MutationFilterComponent.prototype, "width", 2);
8270
+ __decorateClass([
8271
+ n2({ type: String })
8272
+ ], MutationFilterComponent.prototype, "height", 2);
7847
8273
  MutationFilterComponent = __decorateClass([
7848
8274
  t$2("gs-mutation-filter")
7849
8275
  ], MutationFilterComponent);