TSUMUGI 1.0.1__py3-none-any.whl

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 (64) hide show
  1. TSUMUGI/annotator.py +103 -0
  2. TSUMUGI/argparser.py +599 -0
  3. TSUMUGI/core.py +185 -0
  4. TSUMUGI/data/impc_phenodigm.csv +3406 -0
  5. TSUMUGI/data/mp.obo +143993 -0
  6. TSUMUGI/filterer.py +36 -0
  7. TSUMUGI/formatter.py +122 -0
  8. TSUMUGI/genewise_annotation_builder.py +94 -0
  9. TSUMUGI/io_handler.py +189 -0
  10. TSUMUGI/main.py +300 -0
  11. TSUMUGI/network_constructor.py +603 -0
  12. TSUMUGI/ontology_handler.py +62 -0
  13. TSUMUGI/pairwise_similarity_builder.py +66 -0
  14. TSUMUGI/report_generator.py +122 -0
  15. TSUMUGI/similarity_calculator.py +498 -0
  16. TSUMUGI/subcommands/count_filterer.py +47 -0
  17. TSUMUGI/subcommands/genes_filterer.py +89 -0
  18. TSUMUGI/subcommands/graphml_builder.py +158 -0
  19. TSUMUGI/subcommands/life_stage_filterer.py +48 -0
  20. TSUMUGI/subcommands/mp_filterer.py +142 -0
  21. TSUMUGI/subcommands/score_filterer.py +22 -0
  22. TSUMUGI/subcommands/sex_filterer.py +48 -0
  23. TSUMUGI/subcommands/webapp_builder.py +358 -0
  24. TSUMUGI/subcommands/zygosity_filterer.py +48 -0
  25. TSUMUGI/validator.py +65 -0
  26. TSUMUGI/web/app/css/app.css +1129 -0
  27. TSUMUGI/web/app/genelist/network_genelist.html +339 -0
  28. TSUMUGI/web/app/genelist/network_genelist.js +421 -0
  29. TSUMUGI/web/app/js/data/dataLoader.js +41 -0
  30. TSUMUGI/web/app/js/export/graphExporter.js +214 -0
  31. TSUMUGI/web/app/js/graph/centrality.js +495 -0
  32. TSUMUGI/web/app/js/graph/components.js +30 -0
  33. TSUMUGI/web/app/js/graph/filters.js +158 -0
  34. TSUMUGI/web/app/js/graph/highlighter.js +52 -0
  35. TSUMUGI/web/app/js/graph/layoutController.js +454 -0
  36. TSUMUGI/web/app/js/graph/valueScaler.js +43 -0
  37. TSUMUGI/web/app/js/search/geneSearcher.js +93 -0
  38. TSUMUGI/web/app/js/search/phenotypeSearcher.js +292 -0
  39. TSUMUGI/web/app/js/ui/dynamicFontSize.js +30 -0
  40. TSUMUGI/web/app/js/ui/mobilePanel.js +77 -0
  41. TSUMUGI/web/app/js/ui/slider.js +22 -0
  42. TSUMUGI/web/app/js/ui/tooltips.js +514 -0
  43. TSUMUGI/web/app/js/viewer/pageSetup.js +217 -0
  44. TSUMUGI/web/app/viewer.html +515 -0
  45. TSUMUGI/web/app/viewer.js +1593 -0
  46. TSUMUGI/web/css/sanitize.css +363 -0
  47. TSUMUGI/web/css/top.css +391 -0
  48. TSUMUGI/web/image/tsumugi-favicon.ico +0 -0
  49. TSUMUGI/web/image/tsumugi-icon.png +0 -0
  50. TSUMUGI/web/image/tsumugi-logo.png +0 -0
  51. TSUMUGI/web/image/tsumugi-logo.svg +69 -0
  52. TSUMUGI/web/js/genelist_formatter.js +123 -0
  53. TSUMUGI/web/js/top.js +338 -0
  54. TSUMUGI/web/open_webapp_linux.sh +25 -0
  55. TSUMUGI/web/open_webapp_mac.command +25 -0
  56. TSUMUGI/web/open_webapp_windows.bat +37 -0
  57. TSUMUGI/web/serve_index.py +110 -0
  58. TSUMUGI/web/template/template_index.html +197 -0
  59. TSUMUGI/web_deployer.py +150 -0
  60. tsumugi-1.0.1.dist-info/METADATA +504 -0
  61. tsumugi-1.0.1.dist-info/RECORD +64 -0
  62. tsumugi-1.0.1.dist-info/WHEEL +4 -0
  63. tsumugi-1.0.1.dist-info/entry_points.txt +3 -0
  64. tsumugi-1.0.1.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,1129 @@
1
+ /* ======================================================== */
2
+ /* Main */
3
+ /* ======================================================== */
4
+
5
+ html,
6
+ body {
7
+ padding: 0;
8
+ height: 100%;
9
+ width: 100%;
10
+ max-width: 1500px;
11
+ font-size: 18px;
12
+ font-family: "Lato", "Arial", "Helvetica", sans-serif;
13
+ color: #333;
14
+ box-sizing: border-box;
15
+ display: flex;
16
+ flex-direction: column;
17
+ margin: 0 auto;
18
+ }
19
+
20
+ /* Inherit font settings for form elements */
21
+ button,
22
+ input,
23
+ select {
24
+ color: inherit;
25
+ font-size: inherit;
26
+ font-family: inherit;
27
+ }
28
+
29
+ a {
30
+ color: #ff8c00;
31
+ text-decoration: none;
32
+ }
33
+
34
+ .main-container {
35
+ background-color: white;
36
+ width: 90%;
37
+ max-width: 1500px;
38
+ box-sizing: border-box;
39
+ padding-bottom: 50px;
40
+ margin: 30px auto;
41
+ border-radius: 20px;
42
+ }
43
+
44
+ .header-container {
45
+ text-align: center;
46
+ box-sizing: border-box;
47
+ }
48
+
49
+ .body-container {
50
+ height: calc(100% - 60px);
51
+ max-height: 800px;
52
+ box-sizing: border-box;
53
+ align-items: stretch;
54
+ display: flex;
55
+ position: relative;
56
+ }
57
+
58
+ /* ======================================================== */
59
+ /* control-panel-container */
60
+ /* ======================================================== */
61
+ /* Left panel */
62
+ .left-control-panel-container {
63
+ flex: 1;
64
+ min-width: 120px;
65
+ padding: 10px;
66
+ box-sizing: border-box;
67
+ display: flex;
68
+ flex-direction: column;
69
+ background-color: white;
70
+ }
71
+
72
+ /* Right panel */
73
+ .right-control-panel-container {
74
+ flex: 1;
75
+ min-width: 120px;
76
+ padding: 10px;
77
+ box-sizing: border-box;
78
+ display: flex;
79
+ flex-direction: column;
80
+ align-items: stretch;
81
+ background-color: white;
82
+ }
83
+
84
+ /* Panel toggle buttons */
85
+ .panel-toggle-button {
86
+ position: absolute;
87
+ top: -28px;
88
+ display: flex;
89
+ align-items: center;
90
+ justify-content: center;
91
+ width: 36px;
92
+ height: 36px;
93
+ border-radius: 50%;
94
+ border: 2px solid #aaa;
95
+ background-color: #fff;
96
+ color: #333;
97
+ cursor: pointer;
98
+ z-index: 1200;
99
+ transition:
100
+ background-color 0.2s ease,
101
+ color 0.2s ease,
102
+ transform 0.2s ease;
103
+ }
104
+
105
+ .panel-toggle-button:hover {
106
+ background-color: #ffeddc;
107
+ color: #d65f00;
108
+ }
109
+
110
+ .panel-toggle-button i {
111
+ pointer-events: none;
112
+ transition: transform 0.2s ease;
113
+ }
114
+
115
+ .panel-toggle-button.collapsed i {
116
+ transform: rotate(180deg);
117
+ }
118
+
119
+ .left-panel-toggle {
120
+ left: 10px;
121
+ }
122
+
123
+ .right-panel-toggle {
124
+ right: 10px;
125
+ }
126
+
127
+ .body-container.left-panel-hidden .left-control-panel-container {
128
+ display: none;
129
+ }
130
+
131
+ .body-container.right-panel-hidden .right-control-panel-container {
132
+ display: none;
133
+ }
134
+
135
+ .panel-section {
136
+ margin: 0 auto;
137
+ background-color: #fff;
138
+ padding-bottom: 10px;
139
+ border-radius: 10px;
140
+ width: 100%;
141
+ box-sizing: border-box;
142
+ }
143
+
144
+ .panel-section:first-child {
145
+ border-top: none;
146
+ margin-top: 0;
147
+ }
148
+
149
+ .right-control-panel-container .boxed-section {
150
+ width: 100%;
151
+ box-sizing: border-box;
152
+ }
153
+
154
+ .panel-title {
155
+ text-align: center;
156
+ margin-bottom: 15px;
157
+ font-size: 1.2rem;
158
+ font-weight: bold;
159
+ }
160
+
161
+ /* ======================================================== */
162
+ /* cy-container */
163
+ /* ======================================================== */
164
+
165
+ .cy-container {
166
+ flex: 3;
167
+ padding: 10px;
168
+ margin: 0 auto;
169
+ box-sizing: border-box;
170
+ display: flex;
171
+ flex-direction: column;
172
+ align-items: center;
173
+ justify-content: center;
174
+ border: 2px solid #aaa;
175
+ border-radius: 10px;
176
+ min-width: 0;
177
+ /* allow shrinking back after expanding */
178
+ position: relative;
179
+ }
180
+
181
+ .cy {
182
+ width: 100%;
183
+ flex: 1;
184
+ min-height: 0;
185
+ position: relative;
186
+ }
187
+
188
+ .subnetwork-overlay {
189
+ position: absolute;
190
+ top: 0;
191
+ left: 0;
192
+ width: 100%;
193
+ height: 100%;
194
+ pointer-events: none;
195
+ z-index: 10;
196
+ }
197
+
198
+ .subnetwork-frame {
199
+ position: absolute;
200
+ border: 2px dashed rgba(60, 60, 60, 0.55);
201
+ border-radius: 14px;
202
+ background: rgba(255, 255, 255, 0.03);
203
+ box-shadow:
204
+ inset 0 0 0 1px rgba(255, 255, 255, 0.04),
205
+ 0 4px 12px rgba(0, 0, 0, 0.08);
206
+ pointer-events: none;
207
+ cursor: default;
208
+ }
209
+
210
+ .subnetwork-frame__label {
211
+ position: absolute;
212
+ top: -18px;
213
+ left: 0;
214
+ padding: 2px 8px;
215
+ border-radius: 8px;
216
+ background: rgba(0, 0, 0, 0.65);
217
+ color: #fff;
218
+ font-size: 12px;
219
+ pointer-events: auto;
220
+ cursor: move;
221
+ }
222
+
223
+ /* ======================================================== */
224
+ /* slider-container */
225
+ /* ======================================================== */
226
+
227
+ .slider-container {
228
+ display: flex;
229
+ flex-direction: column;
230
+ align-items: center;
231
+ justify-content: center;
232
+ margin-bottom: 15px;
233
+ }
234
+
235
+ .control-label {
236
+ margin-right: 10px;
237
+ justify-content: left;
238
+ }
239
+
240
+ .slider-element {
241
+ margin: 20px auto 10px auto;
242
+ width: 80%;
243
+ }
244
+
245
+ .slider-container select.exporter {
246
+ width: 100%;
247
+ max-width: 100%;
248
+ box-sizing: border-box;
249
+ padding: 8px 12px;
250
+ }
251
+
252
+ .slider-value {
253
+ display: inline-block;
254
+ width: 25px;
255
+ text-align: center;
256
+ }
257
+
258
+ .label-row {
259
+ display: flex;
260
+ flex-direction: row;
261
+ justify-content: center;
262
+ align-items: center;
263
+ gap: 10px;
264
+ flex-wrap: nowrap;
265
+ text-align: center;
266
+ }
267
+
268
+ .input-row {
269
+ display: flex;
270
+ justify-content: center;
271
+ align-items: center;
272
+ margin-top: 6px;
273
+ }
274
+
275
+ .numeric-inputs {
276
+ display: flex;
277
+ align-items: center;
278
+ gap: 6px;
279
+ }
280
+
281
+ .range-input {
282
+ width: 64px;
283
+ padding: 4px 6px;
284
+ font-size: 12px;
285
+ text-align: center;
286
+ border: 1px solid #d0d0d0;
287
+ border-radius: 6px;
288
+ background-color: #fff;
289
+ }
290
+
291
+ .range-separator {
292
+ font-size: 12px;
293
+ color: #666;
294
+ }
295
+
296
+ /* SVG */
297
+ .phenotype-scale-container {
298
+ width: 100%;
299
+ display: grid;
300
+ grid-template-columns: 1fr 3fr 1fr;
301
+ }
302
+
303
+ .phenotype-scale-wrapper {
304
+ display: flex;
305
+ flex-direction: row;
306
+ align-items: center;
307
+ justify-content: center;
308
+ gap: 20px;
309
+ grid-column: 2;
310
+ width: 90%;
311
+ margin: 0 auto;
312
+ }
313
+
314
+ .color-scale-container,
315
+ .edge-scale-container {
316
+ width: 50%;
317
+ height: auto;
318
+ text-align: center;
319
+ margin: 10px auto 0;
320
+ }
321
+
322
+ .phenotype-scale-wrapper .color-scale-container,
323
+ .phenotype-scale-wrapper .edge-scale-container {
324
+ width: 50%;
325
+ margin: 10px 0 0;
326
+ }
327
+
328
+ .color-scale-container svg,
329
+ .edge-scale-container svg {
330
+ width: 100%;
331
+ height: auto;
332
+ display: block;
333
+ }
334
+
335
+ .scale-label {
336
+ margin-top: 5px;
337
+ }
338
+
339
+ /* ======================================================== */
340
+ /* search-container */
341
+ /* ======================================================== */
342
+
343
+ /* Search container styling */
344
+ .search-container {
345
+ position: relative;
346
+ display: flex;
347
+ align-items: center;
348
+ margin: 8px 0;
349
+ width: 100%;
350
+ }
351
+
352
+ .search-container i {
353
+ position: absolute;
354
+ left: 10px;
355
+ color: #999;
356
+ z-index: 1;
357
+ }
358
+
359
+ /* Input style */
360
+ #gene-search,
361
+ #phenotype-search {
362
+ width: 100%;
363
+ padding: 10px 10px 10px 35px;
364
+ font-size: 14px;
365
+ border: 2px solid #ccc;
366
+ border-radius: 5px;
367
+ outline: none;
368
+ box-sizing: border-box;
369
+ }
370
+
371
+ /* Input focus */
372
+ #gene-search:focus,
373
+ #phenotype-search:focus {
374
+ border-color: #999;
375
+ }
376
+
377
+ /* Search button */
378
+ #search-button {
379
+ margin-top: 8px;
380
+ padding: 6px 12px;
381
+ font-size: 14px;
382
+ border: none;
383
+ border-radius: 6px;
384
+ background-color: #ccc;
385
+ cursor: pointer;
386
+ }
387
+
388
+ /* ======================================================== */
389
+ /* Selected Phenotype Tags */
390
+ /* ======================================================== */
391
+
392
+ .selected-phenotypes {
393
+ margin-top: 10px;
394
+ max-width: 100%;
395
+ }
396
+
397
+ .selected-phenotype-tag {
398
+ display: inline-flex;
399
+ align-items: center;
400
+ background-color: white;
401
+ border: 1px solid #ccc;
402
+ border-radius: 16px;
403
+ padding: 4px 8px;
404
+ margin: 2px;
405
+ font-size: 12px;
406
+ color: #555;
407
+ }
408
+
409
+ .selected-phenotype-tag .phenotype-text {
410
+ margin-right: 6px;
411
+ max-width: 200px;
412
+ overflow: hidden;
413
+ text-overflow: ellipsis;
414
+ white-space: nowrap;
415
+ }
416
+
417
+ .selected-phenotype-tag .remove-btn {
418
+ background: none;
419
+ border: none;
420
+ color: #666;
421
+ font-size: 14px;
422
+ font-weight: bold;
423
+ cursor: pointer;
424
+ padding: 0;
425
+ margin: 0;
426
+ width: 16px;
427
+ height: 16px;
428
+ border-radius: 50%;
429
+ display: flex;
430
+ align-items: center;
431
+ justify-content: center;
432
+ transition: all 0.2s ease;
433
+ }
434
+
435
+ .selected-phenotype-tag .remove-btn:hover {
436
+ background-color: #666;
437
+ color: white;
438
+ }
439
+
440
+ /* Suggestions list */
441
+ ul.suggestions {
442
+ position: absolute;
443
+ top: 100%;
444
+ left: 0;
445
+ width: 100%;
446
+ list-style: none;
447
+ margin: 4px 0 0 0;
448
+ padding: 0;
449
+ border: 1px solid #ccc;
450
+ border-radius: 10px;
451
+ max-height: 30vh;
452
+ overflow-y: auto;
453
+ background-color: white;
454
+ z-index: 1000;
455
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
456
+ }
457
+
458
+ /* Suggestion items */
459
+ ul.suggestions li {
460
+ padding: 10px;
461
+ cursor: pointer;
462
+ transition: background-color 0.3s ease;
463
+ }
464
+
465
+ ul.suggestions li:hover {
466
+ background-color: #ffebd8;
467
+ }
468
+
469
+ /* ======================================================== */
470
+ /* boxed-section */
471
+ /* ======================================================== */
472
+
473
+ .boxed-section {
474
+ border: 2px solid #aaa;
475
+ border-radius: 10px;
476
+ padding: 10px;
477
+ margin-bottom: 20px;
478
+ position: relative;
479
+ background-color: #fff;
480
+ }
481
+
482
+ /* Title-style label overlay */
483
+ .boxed-section>span {
484
+ position: absolute;
485
+ top: 0;
486
+ left: 50%;
487
+ transform: translate(-50%, -50%);
488
+ background-color: #fff;
489
+ padding: 2px 10px;
490
+ white-space: nowrap;
491
+ max-width: 90%;
492
+ text-align: center;
493
+ font-size: clamp(12px, 1.3vw, 16px);
494
+ line-height: 1.1;
495
+ }
496
+
497
+ .boxed-section form {
498
+ display: flex;
499
+ gap: 12px;
500
+ flex-wrap: wrap;
501
+ }
502
+
503
+ .boxed-section form.two-column-options {
504
+ display: grid;
505
+ grid-template-columns: repeat(2, minmax(0, 1fr));
506
+ column-gap: 16px;
507
+ row-gap: 8px;
508
+ align-items: start;
509
+ padding-left: 8px;
510
+ }
511
+
512
+ .boxed-section form.two-column-options .option-column {
513
+ display: flex;
514
+ flex-direction: column;
515
+ gap: 8px;
516
+ align-items: flex-start;
517
+ }
518
+
519
+ .boxed-section.align-center {
520
+ /* Keep the content left-aligned */
521
+ margin: 0 auto;
522
+ display: flex;
523
+ flex-direction: column;
524
+ align-items: flex-start;
525
+ text-align: left;
526
+ width: 100%;
527
+ padding: 10px;
528
+ margin-bottom: 20px;
529
+ }
530
+
531
+ /* Rounded checkbox styling */
532
+ .round-checkbox {
533
+ position: relative;
534
+ margin: 8px 0;
535
+ }
536
+
537
+ .round-checkbox input[type="checkbox"] {
538
+ display: none;
539
+ }
540
+
541
+ .round-checkbox input[type="checkbox"]+label {
542
+ position: relative;
543
+ padding-left: 35px;
544
+ line-height: 24px;
545
+ cursor: pointer;
546
+ user-select: none;
547
+ }
548
+
549
+ .round-checkbox input[type="checkbox"]+label:before {
550
+ display: block;
551
+ position: absolute;
552
+ left: 0;
553
+ top: 0;
554
+ content: "";
555
+ width: 24px;
556
+ height: 24px;
557
+ border-radius: 50%;
558
+ background-color: #fff;
559
+ border: 2px solid #aaa;
560
+ box-sizing: border-box;
561
+ }
562
+
563
+ /* Highlight in yellow only when checked */
564
+ .round-checkbox input[type="checkbox"]:checked+label:before {
565
+ background-color: #ff8c00;
566
+ }
567
+
568
+ .round-checkbox input[type="checkbox"]:checked+label:after {
569
+ display: block;
570
+ position: absolute;
571
+ content: "";
572
+ width: 12px;
573
+ height: 5px;
574
+ border-bottom: 3px solid #333;
575
+ border-left: 3px solid #333;
576
+ transform: rotate(-45deg);
577
+ top: 8px;
578
+ left: 6px;
579
+ }
580
+
581
+ /* ======================================================== */
582
+ /* Exporter */
583
+ /* ======================================================== */
584
+ .exporter {
585
+ border: 2px solid #aaa;
586
+ background-color: #fff;
587
+ border-radius: 10px;
588
+ padding: 12px 20px;
589
+ margin-top: 10px;
590
+ cursor: pointer;
591
+ }
592
+
593
+ .exporter-group {
594
+ display: flex;
595
+ justify-content: center;
596
+ align-items: center;
597
+ gap: 10px;
598
+ flex-wrap: wrap;
599
+ margin-top: 10px;
600
+ }
601
+
602
+ .mobile-exporter {
603
+ display: none;
604
+ }
605
+
606
+ /* ======================================================== */
607
+ /* Custom styles for noUiSlider */
608
+ /* ======================================================== */
609
+
610
+ .noUi-handle {
611
+ border-radius: 20%;
612
+ box-shadow: none;
613
+ outline: none;
614
+ border: 3px solid #888;
615
+ }
616
+
617
+ .noUi-horizontal {
618
+ height: 10px;
619
+ }
620
+
621
+ .noUi-connect {
622
+ background-color: #aaa;
623
+ }
624
+
625
+ /* ======================================================== */
626
+ /* Resources Section */
627
+ /* ======================================================== */
628
+
629
+ .resources-container {
630
+ max-width: 800px;
631
+ margin: 30px auto 40px;
632
+ display: flex;
633
+ flex-wrap: wrap;
634
+ gap: 30px;
635
+ justify-content: center;
636
+ }
637
+
638
+ .resource-section {
639
+ flex: 1;
640
+ min-width: 280px;
641
+ text-align: center;
642
+ }
643
+
644
+ .resource-section h3 {
645
+ margin-bottom: 15px;
646
+ font-size: 1.1em;
647
+ color: #555;
648
+ font-weight: normal;
649
+ }
650
+
651
+ .resource-buttons {
652
+ display: flex;
653
+ flex-direction: row;
654
+ gap: 10px;
655
+ justify-content: center;
656
+ }
657
+
658
+ .resource-btn {
659
+ display: inline-flex;
660
+ align-items: center;
661
+ justify-content: center;
662
+ background-color: #fff;
663
+ color: #555;
664
+ padding: 10px 16px;
665
+ border: 2px solid #ccc;
666
+ border-radius: 10px;
667
+ text-decoration: none;
668
+ font-size: 0.95em;
669
+ transition: all 0.2s ease;
670
+ }
671
+
672
+ .resource-btn:hover {
673
+ color: #333;
674
+ border-color: #ff7800;
675
+ background-color: rgba(255, 120, 0, 0.05);
676
+ }
677
+
678
+ .resource-btn i {
679
+ margin-right: 6px;
680
+ font-size: 0.9em;
681
+ }
682
+
683
+ /* ======================================================== */
684
+ /* Footer styling */
685
+ /* ======================================================== */
686
+
687
+ footer {
688
+ margin: 20px 0 10px;
689
+ padding: 20px;
690
+ color: #666;
691
+ font-size: 0.9em;
692
+ text-align: center;
693
+ }
694
+
695
+ footer p {
696
+ margin: 5px 0 0;
697
+ }
698
+
699
+ footer i {
700
+ margin-right: 8px;
701
+ }
702
+
703
+ footer a {
704
+ color: #666;
705
+ font-size: 1em;
706
+ text-decoration: none;
707
+ font-weight: bold;
708
+ }
709
+
710
+ footer a:hover {
711
+ text-decoration: underline;
712
+ }
713
+
714
+ /* ======================================================== */
715
+ /* Mobile-friendly design */
716
+ /* ======================================================== */
717
+ /* Hide the icon by default */
718
+ button.menu-toggle-icon {
719
+ display: none;
720
+ background-color: transparent;
721
+ border: none;
722
+ }
723
+
724
+ #close-panel {
725
+ display: none;
726
+ position: absolute;
727
+ top: 20px;
728
+ left: 20px;
729
+ font-size: 24px;
730
+ border: none;
731
+ background: none;
732
+ color: #333;
733
+ cursor: pointer;
734
+ z-index: 2000;
735
+ }
736
+
737
+ @media (max-width: 600px) {
738
+ h1 {
739
+ font-size: 1em;
740
+ margin: 0 auto;
741
+ text-align: center;
742
+ padding-left: 40px;
743
+ max-width: 90%;
744
+ }
745
+
746
+ #close-panel.active {
747
+ display: block;
748
+ }
749
+
750
+ .menu-toggle {
751
+ position: absolute;
752
+ left: 20px;
753
+ top: 20px;
754
+ }
755
+
756
+ button.menu-toggle-icon,
757
+ .close-button {
758
+ display: block;
759
+ font-size: 20px;
760
+ cursor: pointer;
761
+ position: absolute;
762
+ left: 20px;
763
+ top: 20px;
764
+ z-index: 2000;
765
+ }
766
+
767
+ button.menu-toggle-icon.hidden {
768
+ display: none;
769
+ }
770
+
771
+ .close-button.active {
772
+ display: block;
773
+ z-index: 2000;
774
+ }
775
+
776
+ .body-container {
777
+ flex-direction: column;
778
+ align-items: center;
779
+ justify-content: center;
780
+ }
781
+
782
+ /* Consolidated styling for panel containers */
783
+ .left-control-panel-container {
784
+ position: fixed;
785
+ top: 0;
786
+ left: -100%;
787
+ height: 100%;
788
+ width: 80%;
789
+ max-width: 300px;
790
+ background-color: #fff;
791
+ z-index: 999;
792
+ overflow-y: auto;
793
+ box-shadow: 2px 0 5px rgba(0, 0, 0, 0.2);
794
+ padding: 80px 10px 20px 10px;
795
+ transition: left 0.3s ease;
796
+ }
797
+
798
+ /* Move the right panel inside the left panel */
799
+ .right-control-panel-container {
800
+ position: static;
801
+ width: 100%;
802
+ padding: 10px;
803
+ box-shadow: none;
804
+ border-top: 2px solid #aaa;
805
+ margin-top: 20px;
806
+ }
807
+
808
+ .left-control-panel-container.active {
809
+ left: 0;
810
+ }
811
+
812
+ /* Keep the right panel visible */
813
+ .body-container {
814
+ flex-direction: column;
815
+ }
816
+
817
+ .cy-container {
818
+ margin: 20px 0;
819
+ width: 90%;
820
+ height: 400px;
821
+ /* Fixed height so Cytoscape can initialize properly */
822
+ min-height: 400px;
823
+ /* Also set the minimum height */
824
+ display: flex;
825
+ align-items: center;
826
+ justify-content: center;
827
+ }
828
+
829
+ .phenotype-scale-container {
830
+ width: 90%;
831
+ margin: 0 auto;
832
+ display: flex;
833
+ justify-content: center;
834
+ }
835
+
836
+ .phenotype-scale-wrapper {
837
+ width: 90%;
838
+ gap: 12px;
839
+ }
840
+
841
+ .cy {
842
+ width: 100%;
843
+ flex: 1;
844
+ min-height: 0;
845
+ }
846
+
847
+ .resources-container {
848
+ flex-direction: column;
849
+ gap: 20px;
850
+ margin-bottom: 30px;
851
+ }
852
+
853
+ .resource-section {
854
+ min-width: auto;
855
+ }
856
+
857
+ .resource-buttons {
858
+ flex-direction: column;
859
+ }
860
+
861
+ .mobile-exporter {
862
+ display: flex;
863
+ gap: 10px;
864
+ justify-content: center;
865
+ align-items: center;
866
+ margin: 12px 0;
867
+ flex-wrap: wrap;
868
+ }
869
+
870
+ .panel-toggle-button {
871
+ display: none;
872
+ }
873
+ }
874
+
875
+ /* ======================================================== */
876
+ /* Cytoscape Tooltip Styles */
877
+ /* ======================================================== */
878
+ .cy-tooltip {
879
+ position: absolute;
880
+ --cy-tooltip-phenotypes-max: 120px;
881
+ --cy-tooltip-diseases-max: 90px;
882
+ --cy-tooltip-modules-max: 160px;
883
+ --cy-tooltip-height: 220px;
884
+ padding: 10px 10px 18px 14px;
885
+ min-width: 220px;
886
+ min-height: 140px;
887
+ box-sizing: border-box;
888
+ overflow: hidden;
889
+ overscroll-behavior: contain;
890
+ display: flex;
891
+ flex-direction: column;
892
+ gap: 8px;
893
+ background: #fff;
894
+ border: 1px solid #ccc;
895
+ border-radius: 5px;
896
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
897
+ z-index: 1000;
898
+ cursor: move;
899
+ user-select: text;
900
+ }
901
+
902
+ .cy-tooltip__section {
903
+ overflow-y: auto;
904
+ overscroll-behavior: contain;
905
+ padding-right: 6px;
906
+ /* leave space for scrollbar */
907
+ }
908
+
909
+ .cy-tooltip__section--phenotypes {
910
+ max-height: var(--cy-tooltip-phenotypes-max);
911
+ }
912
+
913
+ .cy-tooltip__section--diseases {
914
+ max-height: var(--cy-tooltip-diseases-max);
915
+ }
916
+
917
+ .cy-tooltip__section--modules {
918
+ max-height: var(--cy-tooltip-modules-max);
919
+ }
920
+
921
+ .cy-tooltip__section-title {
922
+ margin-bottom: 4px;
923
+ line-height: 1.3;
924
+ }
925
+
926
+ .cy-tooltip__section-body {
927
+ line-height: 1.4;
928
+ }
929
+
930
+ .cy-tooltip__header {
931
+ display: flex;
932
+ align-items: center;
933
+ gap: 6px;
934
+ }
935
+
936
+ .cy-tooltip__copy {
937
+ position: absolute;
938
+ right: 6px;
939
+ bottom: 6px;
940
+ z-index: 1001;
941
+ }
942
+
943
+ .cy-tooltip__copy-btn {
944
+ background: none;
945
+ border: none;
946
+ cursor: pointer;
947
+ color: #888;
948
+ padding: 2px 5px;
949
+ }
950
+
951
+ .cy-tooltip__resize-handle {
952
+ position: absolute;
953
+ left: 6px;
954
+ bottom: 6px;
955
+ width: 16px;
956
+ height: 16px;
957
+ background: #fff;
958
+ border: 1px solid #bbb;
959
+ border-radius: 6px;
960
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.18);
961
+ cursor: sw-resize;
962
+ display: flex;
963
+ align-items: center;
964
+ justify-content: center;
965
+ user-select: none;
966
+ touch-action: none;
967
+ }
968
+
969
+ .cy-tooltip__resize-handle::before {
970
+ content: "";
971
+ width: 8px;
972
+ height: 8px;
973
+ border-left: 2px solid #999;
974
+ border-bottom: 2px solid #999;
975
+ transform: translate(-1px, 1px);
976
+ }
977
+
978
+ /* ======================================================== */
979
+ /* Info Tooltip Styles for Network Pages */
980
+ /* ======================================================== */
981
+ .info-tooltip-container {
982
+ position: relative;
983
+ display: inline-block;
984
+ margin-left: 4px;
985
+ z-index: 1;
986
+ }
987
+
988
+ .info-tooltip-icon {
989
+ display: inline-flex;
990
+ align-items: center;
991
+ justify-content: center;
992
+ width: 16px;
993
+ height: 16px;
994
+ border-radius: 50%;
995
+ background-color: #555;
996
+ color: white;
997
+ font-size: 12px;
998
+ font-weight: bold;
999
+ cursor: pointer;
1000
+ transition: background-color 0.2s ease;
1001
+ }
1002
+
1003
+ .info-tooltip-icon:hover {
1004
+ background-color: #333;
1005
+ }
1006
+
1007
+ .info-tooltip-content {
1008
+ visibility: hidden;
1009
+ opacity: 0;
1010
+ position: absolute;
1011
+ bottom: 25px;
1012
+ left: 50%;
1013
+ transform: translateX(-50%);
1014
+ background-color: #333;
1015
+ color: white;
1016
+ text-align: left;
1017
+ padding: 8px 12px;
1018
+ border-radius: 6px;
1019
+ font-size: 14px;
1020
+ font-weight: normal;
1021
+ line-height: 1.4;
1022
+ z-index: 12000;
1023
+ transition:
1024
+ opacity 0.3s ease,
1025
+ visibility 0.3s ease;
1026
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
1027
+ max-width: 300px;
1028
+ white-space: normal;
1029
+ }
1030
+
1031
+ .info-tooltip-content::after {
1032
+ content: "";
1033
+ position: absolute;
1034
+ top: 100%;
1035
+ left: 50%;
1036
+ transform: translateX(-50%);
1037
+ border: 5px solid transparent;
1038
+ border-top-color: #333;
1039
+ }
1040
+
1041
+ .info-tooltip-container:hover .info-tooltip-content,
1042
+ .info-tooltip-container.active .info-tooltip-content {
1043
+ visibility: visible;
1044
+ opacity: 1;
1045
+ }
1046
+
1047
+ .info-tooltip-content a {
1048
+ color: #4fc3f7;
1049
+ text-decoration: underline;
1050
+ }
1051
+
1052
+ .info-tooltip-content a:hover {
1053
+ color: #81d4fa;
1054
+ }
1055
+ /* ======================================================== */
1056
+ /* Cy controls (recenter / arrange) */
1057
+ /* ======================================================== */
1058
+ .cy-controls {
1059
+ position: absolute;
1060
+ right: 16px;
1061
+ bottom: 20px;
1062
+ display: flex;
1063
+ align-items: center;
1064
+ gap: 12px;
1065
+ z-index: 1200;
1066
+ }
1067
+
1068
+ .control-group {
1069
+ display: flex;
1070
+ align-items: center;
1071
+ gap: 4px;
1072
+ }
1073
+
1074
+ .recenter-button {
1075
+ position: static;
1076
+ bottom: auto;
1077
+ right: auto;
1078
+ width: 40px;
1079
+ height: 40px;
1080
+ border-radius: 50%;
1081
+ border: 2px solid #aaa;
1082
+ background-color: #fff;
1083
+ color: #333;
1084
+ cursor: pointer;
1085
+ z-index: 100;
1086
+ display: flex;
1087
+ align-items: center;
1088
+ justify-content: center;
1089
+ font-size: 18px;
1090
+ box-shadow: 0 2px 5px rgba(0,0,0,0.2);
1091
+ transition: background-color 0.2s, transform 0.2s;
1092
+ }
1093
+
1094
+ .recenter-button:hover {
1095
+ background-color: #f0f0f0;
1096
+ transform: scale(1.05);
1097
+ }
1098
+
1099
+ /* ======================================================== */
1100
+ /* No Nodes Message */
1101
+ /* ======================================================== */
1102
+ .no-nodes-message {
1103
+ position: absolute;
1104
+ top: 50%;
1105
+ left: 50%;
1106
+ transform: translate(-50%, -50%);
1107
+ background-color: rgba(255, 255, 255, 0.9);
1108
+ padding: 20px 40px;
1109
+ border-radius: 8px;
1110
+ border: 1px solid #ccc;
1111
+ font-size: 18px;
1112
+ color: #555;
1113
+ z-index: 50;
1114
+ box-shadow: 0 4px 10px rgba(0,0,0,0.1);
1115
+ pointer-events: none;
1116
+ }
1117
+ /* ======================================================== */
1118
+ /* Subnetwork Frame Borders (Drag Handles) */
1119
+ /* ======================================================== */
1120
+ .subnetwork-frame__border {
1121
+ position: absolute;
1122
+ pointer-events: auto;
1123
+ cursor: move;
1124
+ z-index: 11; /* Above frame content if any */
1125
+ }
1126
+ .subnetwork-frame__border--top { top: -5px; left: -5px; right: -5px; height: 10px; }
1127
+ .subnetwork-frame__border--bottom { bottom: -5px; left: -5px; right: -5px; height: 10px; }
1128
+ .subnetwork-frame__border--left { top: -5px; bottom: -5px; left: -5px; width: 10px; }
1129
+ .subnetwork-frame__border--right { top: -5px; bottom: -5px; right: -5px; width: 10px; }