Commit
·
19a56ad
1
Parent(s):
8be71fe
add missing tasks and improve style
Browse files
app.py
CHANGED
|
@@ -294,7 +294,11 @@ class TransformersTimelineParser:
|
|
| 294 |
# Import the model mappings from transformers
|
| 295 |
from transformers.models.auto.modeling_auto import (
|
| 296 |
MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING_NAMES,
|
|
|
|
|
|
|
|
|
|
| 297 |
MODEL_FOR_CAUSAL_LM_MAPPING_NAMES,
|
|
|
|
| 298 |
MODEL_FOR_DEPTH_ESTIMATION_MAPPING_NAMES,
|
| 299 |
MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING_NAMES,
|
| 300 |
MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES,
|
|
@@ -302,15 +306,21 @@ class TransformersTimelineParser:
|
|
| 302 |
MODEL_FOR_IMAGE_TEXT_TO_TEXT_MAPPING_NAMES,
|
| 303 |
MODEL_FOR_IMAGE_TO_IMAGE_MAPPING_NAMES,
|
| 304 |
MODEL_FOR_INSTANCE_SEGMENTATION_MAPPING_NAMES,
|
|
|
|
|
|
|
| 305 |
MODEL_FOR_MASK_GENERATION_MAPPING_NAMES,
|
|
|
|
| 306 |
MODEL_FOR_MASKED_LM_MAPPING_NAMES,
|
|
|
|
| 307 |
MODEL_FOR_OBJECT_DETECTION_MAPPING_NAMES,
|
| 308 |
MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES,
|
| 309 |
MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING_NAMES,
|
| 310 |
MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES,
|
| 311 |
MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES,
|
|
|
|
| 312 |
MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING_NAMES,
|
| 313 |
MODEL_FOR_TEXT_TO_SPECTROGRAM_MAPPING_NAMES,
|
|
|
|
| 314 |
MODEL_FOR_TIME_SERIES_CLASSIFICATION_MAPPING_NAMES,
|
| 315 |
MODEL_FOR_TIME_SERIES_PREDICTION_MAPPING_NAMES,
|
| 316 |
MODEL_FOR_TIME_SERIES_REGRESSION_MAPPING_NAMES,
|
|
@@ -331,6 +341,7 @@ class TransformersTimelineParser:
|
|
| 331 |
"question-answering": MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES,
|
| 332 |
"fill-mask": MODEL_FOR_MASKED_LM_MAPPING_NAMES,
|
| 333 |
"text2text-generation": MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES,
|
|
|
|
| 334 |
"image-classification": MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES,
|
| 335 |
"object-detection": MODEL_FOR_OBJECT_DETECTION_MAPPING_NAMES,
|
| 336 |
"image-segmentation": MODEL_FOR_IMAGE_SEGMENTATION_MAPPING_NAMES,
|
|
@@ -338,8 +349,16 @@ class TransformersTimelineParser:
|
|
| 338 |
"instance-segmentation": MODEL_FOR_INSTANCE_SEGMENTATION_MAPPING_NAMES,
|
| 339 |
"universal-segmentation": MODEL_FOR_UNIVERSAL_SEGMENTATION_MAPPING_NAMES,
|
| 340 |
"depth-estimation": MODEL_FOR_DEPTH_ESTIMATION_MAPPING_NAMES,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 341 |
"video-classification": MODEL_FOR_VIDEO_CLASSIFICATION_MAPPING_NAMES,
|
| 342 |
"audio-classification": MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING_NAMES,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 343 |
"image-to-text": MODEL_FOR_VISION_2_SEQ_MAPPING_NAMES,
|
| 344 |
"image-text-to-text": MODEL_FOR_IMAGE_TEXT_TO_TEXT_MAPPING_NAMES,
|
| 345 |
"visual-question-answering": MODEL_FOR_VISUAL_QUESTION_ANSWERING_MAPPING_NAMES,
|
|
@@ -350,6 +369,7 @@ class TransformersTimelineParser:
|
|
| 350 |
"image-to-image": MODEL_FOR_IMAGE_TO_IMAGE_MAPPING_NAMES,
|
| 351 |
"mask-generation": MODEL_FOR_MASK_GENERATION_MAPPING_NAMES,
|
| 352 |
"text-to-audio": MODEL_FOR_TEXT_TO_SPECTROGRAM_MAPPING_NAMES,
|
|
|
|
| 353 |
"time-series-classification": MODEL_FOR_TIME_SERIES_CLASSIFICATION_MAPPING_NAMES,
|
| 354 |
"time-series-regression": MODEL_FOR_TIME_SERIES_REGRESSION_MAPPING_NAMES,
|
| 355 |
"time-series-prediction": MODEL_FOR_TIME_SERIES_PREDICTION_MAPPING_NAMES,
|
|
@@ -536,6 +556,7 @@ def get_tasks():
|
|
| 536 |
"question-answering": {"name": "Question Answering", "color": "#c084fc"},
|
| 537 |
"fill-mask": {"name": "Fill Mask", "color": "#d8b4fe"},
|
| 538 |
"text2text-generation": {"name": "Text2Text Generation", "color": "#e879f9"},
|
|
|
|
| 539 |
"image-classification": {"name": "Image Classification", "color": "#06b6d4"},
|
| 540 |
"object-detection": {"name": "Object Detection", "color": "#0891b2"},
|
| 541 |
"image-segmentation": {"name": "Image Segmentation", "color": "#0e7490"},
|
|
@@ -543,6 +564,10 @@ def get_tasks():
|
|
| 543 |
"instance-segmentation": {"name": "Instance Segmentation", "color": "#164e63"},
|
| 544 |
"universal-segmentation": {"name": "Universal Segmentation", "color": "#1e40af"},
|
| 545 |
"depth-estimation": {"name": "Depth Estimation", "color": "#1d4ed8"},
|
|
|
|
|
|
|
|
|
|
|
|
|
| 546 |
"zero-shot-image-classification": {"name": "Zero-Shot Image Classification", "color": "#2563eb"},
|
| 547 |
"zero-shot-object-detection": {"name": "Zero-Shot Object Detection", "color": "#3b82f6"},
|
| 548 |
"image-to-image": {"name": "Image to Image", "color": "#60a5fa"},
|
|
@@ -554,7 +579,15 @@ def get_tasks():
|
|
| 554 |
"table-question-answering": {"name": "Table Question Answering", "color": "#064e3b"},
|
| 555 |
"video-classification": {"name": "Video Classification", "color": "#dc2626"},
|
| 556 |
"audio-classification": {"name": "Audio Classification", "color": "#ea580c"},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 557 |
"text-to-audio": {"name": "Text to Audio", "color": "#f97316"},
|
|
|
|
| 558 |
"time-series-classification": {"name": "Time Series Classification", "color": "#84cc16"},
|
| 559 |
"time-series-regression": {"name": "Time Series Regression", "color": "#65a30d"},
|
| 560 |
"time-series-prediction": {"name": "Time Series Prediction", "color": "#4d7c0f"},
|
|
@@ -604,7 +637,8 @@ def create_timeline_template():
|
|
| 604 |
body {
|
| 605 |
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
| 606 |
background: linear-gradient(135deg, #fef3c7 0%, #fed7aa 100%);
|
| 607 |
-
|
|
|
|
| 608 |
color: #333;
|
| 609 |
display: flex;
|
| 610 |
flex-direction: column;
|
|
@@ -1198,7 +1232,7 @@ def create_timeline_template():
|
|
| 1198 |
flex: 1;
|
| 1199 |
display: flex;
|
| 1200 |
flex-direction: column;
|
| 1201 |
-
height:
|
| 1202 |
transition: all 0.3s ease;
|
| 1203 |
}
|
| 1204 |
|
|
@@ -1409,23 +1443,22 @@ def create_timeline_template():
|
|
| 1409 |
position: absolute;
|
| 1410 |
top: 0;
|
| 1411 |
bottom: 0;
|
| 1412 |
-
width:
|
| 1413 |
-
|
| 1414 |
-
opacity: 0.
|
| 1415 |
pointer-events: none;
|
| 1416 |
-
z-index: 1; /* In background, below everything */
|
| 1417 |
transition: all 0.3s ease;
|
| 1418 |
}
|
| 1419 |
|
| 1420 |
/* Dark mode date markers */
|
| 1421 |
[data-theme="dark"] .date-marker {
|
| 1422 |
-
|
| 1423 |
-
opacity: 0.
|
| 1424 |
}
|
| 1425 |
|
| 1426 |
.date-label {
|
| 1427 |
position: absolute;
|
| 1428 |
-
top:
|
| 1429 |
left: 8px; /* Offset to the right of the line */
|
| 1430 |
font-size: 0.75rem;
|
| 1431 |
color: #6b7280;
|
|
@@ -1437,7 +1470,7 @@ def create_timeline_template():
|
|
| 1437 |
border: 1px solid rgba(156, 163, 175, 0.4);
|
| 1438 |
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
|
| 1439 |
white-space: nowrap;
|
| 1440 |
-
z-index:
|
| 1441 |
backdrop-filter: blur(4px);
|
| 1442 |
transition: all 0.3s ease;
|
| 1443 |
}
|
|
@@ -1451,15 +1484,15 @@ def create_timeline_template():
|
|
| 1451 |
}
|
| 1452 |
|
| 1453 |
.date-marker.year {
|
| 1454 |
-
opacity: 0.
|
| 1455 |
-
|
| 1456 |
-
width:
|
| 1457 |
}
|
| 1458 |
|
| 1459 |
/* Dark mode year markers */
|
| 1460 |
[data-theme="dark"] .date-marker.year {
|
| 1461 |
-
|
| 1462 |
-
opacity:
|
| 1463 |
}
|
| 1464 |
|
| 1465 |
.date-marker.year .date-label {
|
|
@@ -2203,6 +2236,76 @@ def create_timeline_template():
|
|
| 2203 |
const maxZoom = 3.0; // Maximum zoom (300%)
|
| 2204 |
let taskData = {}; // Store task data for easy lookup
|
| 2205 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2206 |
// Theme management
|
| 2207 |
let currentTheme = 'light';
|
| 2208 |
|
|
@@ -2433,6 +2536,9 @@ def create_timeline_template():
|
|
| 2433 |
// Add date markers before adding models
|
| 2434 |
addDateMarkers(sortedModels, actualSpacing);
|
| 2435 |
|
|
|
|
|
|
|
|
|
|
| 2436 |
// Create wave patterns for stacking - simpler pattern
|
| 2437 |
const abovePattern = [1, 2, 3]; // 3 levels above
|
| 2438 |
const belowPattern = [1, 2, 3]; // 3 levels below
|
|
@@ -2461,6 +2567,19 @@ def create_timeline_template():
|
|
| 2461 |
item.className = `timeline-item ${positionClass}`;
|
| 2462 |
item.style.left = position + 'px';
|
| 2463 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2464 |
const dot = document.createElement('div');
|
| 2465 |
dot.className = 'timeline-dot';
|
| 2466 |
|
|
@@ -2480,12 +2599,31 @@ def create_timeline_template():
|
|
| 2480 |
|
| 2481 |
const connector = document.createElement('div');
|
| 2482 |
connector.className = 'timeline-connector';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2483 |
|
| 2484 |
const label = document.createElement('div');
|
| 2485 |
label.className = 'timeline-label';
|
| 2486 |
label.style.borderLeftColor = model.modality_color || '#8B5CF6';
|
| 2487 |
// Set the modality color as a CSS custom property for hover effects
|
| 2488 |
label.style.setProperty('--modality-color', model.modality_color || '#8B5CF6');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2489 |
|
| 2490 |
// Ensure the model name is always displayed
|
| 2491 |
const modelName = model.display_name || model.model_name || 'Unknown Model';
|
|
@@ -2529,10 +2667,17 @@ def create_timeline_template():
|
|
| 2529 |
<div class="timeline-date">${otherLabel.dataset.modelDate}</div>
|
| 2530 |
`;
|
| 2531 |
|
| 2532 |
-
//
|
| 2533 |
setTimeout(() => {
|
| 2534 |
-
|
| 2535 |
-
otherLabel.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2536 |
otherLabel.style.left = '';
|
| 2537 |
otherLabel.style.right = '';
|
| 2538 |
otherLabel.style.transform = 'translateX(-50%)';
|
|
@@ -2659,10 +2804,17 @@ def create_timeline_template():
|
|
| 2659 |
<div class="timeline-date">${label.dataset.modelDate}</div>
|
| 2660 |
`;
|
| 2661 |
|
| 2662 |
-
//
|
| 2663 |
setTimeout(() => {
|
| 2664 |
-
|
| 2665 |
-
label.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2666 |
label.style.left = '';
|
| 2667 |
label.style.right = '';
|
| 2668 |
// Reset transform: depends on current position
|
|
@@ -2816,11 +2968,8 @@ def create_timeline_template():
|
|
| 2816 |
// Check if the marker date falls between these two models
|
| 2817 |
// The marker should appear where the time period actually starts
|
| 2818 |
if (currentModelDate < currentDate && currentDate <= nextModelDate) {
|
| 2819 |
-
// Position the marker between these two models
|
| 2820 |
-
|
| 2821 |
-
const nextPos = (i + 1) * spacing + 100;
|
| 2822 |
-
const midpoint = (currentPos + nextPos) / 2;
|
| 2823 |
-
boundaryPosition = midpoint - (spacing / 2); // Move left by half segment length
|
| 2824 |
break;
|
| 2825 |
}
|
| 2826 |
}
|
|
@@ -2839,45 +2988,64 @@ def create_timeline_template():
|
|
| 2839 |
const position = boundaryPosition;
|
| 2840 |
|
| 2841 |
// Create marker only if it's within visible range and not too close to adjacent markers
|
|
|
|
| 2842 |
const existingMarkers = timeline.querySelectorAll('.date-marker');
|
| 2843 |
-
let
|
| 2844 |
-
|
| 2845 |
-
|
| 2846 |
-
|
| 2847 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2848 |
}
|
| 2849 |
-
}
|
| 2850 |
|
| 2851 |
-
if (
|
| 2852 |
-
|
| 2853 |
-
marker
|
| 2854 |
-
|
| 2855 |
-
|
| 2856 |
-
|
| 2857 |
-
|
| 2858 |
-
|
| 2859 |
-
|
| 2860 |
-
|
| 2861 |
-
|
| 2862 |
-
|
| 2863 |
-
const line = document.createElement('div');
|
| 2864 |
-
line.style.position = 'absolute';
|
| 2865 |
-
line.style.top = '0px';
|
| 2866 |
-
line.style.bottom = '0px';
|
| 2867 |
-
line.style.left = '0px';
|
| 2868 |
-
line.style.width = '2px';
|
| 2869 |
-
line.style.background = '#9ca3af';
|
| 2870 |
-
line.style.opacity = '0.6';
|
| 2871 |
-
line.style.zIndex = '1';
|
| 2872 |
-
if (markerType === 'year') {
|
| 2873 |
-
line.style.width = '3px';
|
| 2874 |
-
line.style.background = '#6b7280';
|
| 2875 |
-
line.style.opacity = '0.8';
|
| 2876 |
}
|
| 2877 |
-
|
| 2878 |
|
| 2879 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2880 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2881 |
|
| 2882 |
// Move to next marker
|
| 2883 |
currentDate.setMonth(currentDate.getMonth() + increment);
|
|
@@ -3161,6 +3329,7 @@ def create_timeline_template():
|
|
| 3161 |
"question-answering": "#c084fc",
|
| 3162 |
"fill-mask": "#d8b4fe",
|
| 3163 |
"text2text-generation": "#e879f9",
|
|
|
|
| 3164 |
|
| 3165 |
"image-classification": "#06b6d4",
|
| 3166 |
"object-detection": "#0891b2",
|
|
@@ -3169,6 +3338,10 @@ def create_timeline_template():
|
|
| 3169 |
"instance-segmentation": "#164e63",
|
| 3170 |
"universal-segmentation": "#1e40af",
|
| 3171 |
"depth-estimation": "#1d4ed8",
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3172 |
"zero-shot-image-classification": "#2563eb",
|
| 3173 |
"zero-shot-object-detection": "#3b82f6",
|
| 3174 |
"image-to-image": "#60a5fa",
|
|
@@ -3182,7 +3355,12 @@ def create_timeline_template():
|
|
| 3182 |
|
| 3183 |
"video-classification": "#dc2626",
|
| 3184 |
"audio-classification": "#ea580c",
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3185 |
"text-to-audio": "#f97316",
|
|
|
|
| 3186 |
|
| 3187 |
"time-series-classification": "#84cc16",
|
| 3188 |
"time-series-regression": "#65a30d",
|
|
@@ -3225,7 +3403,7 @@ def create_timeline_template():
|
|
| 3225 |
checkbox.type = 'checkbox';
|
| 3226 |
checkbox.value = modality.key;
|
| 3227 |
checkbox.id = `modality-${modality.key}`;
|
| 3228 |
-
checkbox.checked =
|
| 3229 |
|
| 3230 |
const label = document.createElement('label');
|
| 3231 |
label.htmlFor = `modality-${modality.key}`;
|
|
@@ -3244,8 +3422,7 @@ def create_timeline_template():
|
|
| 3244 |
loadTimeline();
|
| 3245 |
});
|
| 3246 |
|
| 3247 |
-
// Set initial state
|
| 3248 |
-
checkboxContainer.classList.add('checked');
|
| 3249 |
|
| 3250 |
modalityFilters.appendChild(checkboxContainer);
|
| 3251 |
});
|
|
@@ -3255,11 +3432,19 @@ def create_timeline_template():
|
|
| 3255 |
}
|
| 3256 |
}
|
| 3257 |
|
| 3258 |
-
// Window resize handler
|
|
|
|
| 3259 |
window.addEventListener('resize', () => {
|
| 3260 |
-
|
| 3261 |
-
|
| 3262 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3263 |
});
|
| 3264 |
|
| 3265 |
document.addEventListener('DOMContentLoaded', async () => {
|
|
@@ -3304,10 +3489,17 @@ def create_timeline_template():
|
|
| 3304 |
<div class="timeline-date">${label.dataset.modelDate}</div>
|
| 3305 |
`;
|
| 3306 |
|
| 3307 |
-
//
|
| 3308 |
setTimeout(() => {
|
| 3309 |
-
|
| 3310 |
-
label.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3311 |
label.style.transform = 'translateX(-50%)';
|
| 3312 |
label.parentElement.style.zIndex = '';
|
| 3313 |
}, 50);
|
|
@@ -3364,6 +3556,27 @@ def create_timeline_template():
|
|
| 3364 |
btn.textContent = '▸';
|
| 3365 |
localStorage.setItem('filtersCollapsed', 'true');
|
| 3366 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3367 |
}
|
| 3368 |
</script>
|
| 3369 |
</body>
|
|
|
|
| 294 |
# Import the model mappings from transformers
|
| 295 |
from transformers.models.auto.modeling_auto import (
|
| 296 |
MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING_NAMES,
|
| 297 |
+
MODEL_FOR_AUDIO_FRAME_CLASSIFICATION_MAPPING_NAMES,
|
| 298 |
+
MODEL_FOR_AUDIO_XVECTOR_MAPPING_NAMES,
|
| 299 |
+
MODEL_FOR_CAUSAL_IMAGE_MODELING_MAPPING_NAMES,
|
| 300 |
MODEL_FOR_CAUSAL_LM_MAPPING_NAMES,
|
| 301 |
+
MODEL_FOR_CTC_MAPPING_NAMES,
|
| 302 |
MODEL_FOR_DEPTH_ESTIMATION_MAPPING_NAMES,
|
| 303 |
MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING_NAMES,
|
| 304 |
MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES,
|
|
|
|
| 306 |
MODEL_FOR_IMAGE_TEXT_TO_TEXT_MAPPING_NAMES,
|
| 307 |
MODEL_FOR_IMAGE_TO_IMAGE_MAPPING_NAMES,
|
| 308 |
MODEL_FOR_INSTANCE_SEGMENTATION_MAPPING_NAMES,
|
| 309 |
+
MODEL_FOR_KEYPOINT_DETECTION_MAPPING_NAMES,
|
| 310 |
+
MODEL_FOR_KEYPOINT_MATCHING_MAPPING_NAMES,
|
| 311 |
MODEL_FOR_MASK_GENERATION_MAPPING_NAMES,
|
| 312 |
+
MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING_NAMES,
|
| 313 |
MODEL_FOR_MASKED_LM_MAPPING_NAMES,
|
| 314 |
+
MODEL_FOR_MULTIPLE_CHOICE_MAPPING_NAMES,
|
| 315 |
MODEL_FOR_OBJECT_DETECTION_MAPPING_NAMES,
|
| 316 |
MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES,
|
| 317 |
MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING_NAMES,
|
| 318 |
MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES,
|
| 319 |
MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES,
|
| 320 |
+
MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING_NAMES,
|
| 321 |
MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING_NAMES,
|
| 322 |
MODEL_FOR_TEXT_TO_SPECTROGRAM_MAPPING_NAMES,
|
| 323 |
+
MODEL_FOR_TEXT_TO_WAVEFORM_MAPPING_NAMES,
|
| 324 |
MODEL_FOR_TIME_SERIES_CLASSIFICATION_MAPPING_NAMES,
|
| 325 |
MODEL_FOR_TIME_SERIES_PREDICTION_MAPPING_NAMES,
|
| 326 |
MODEL_FOR_TIME_SERIES_REGRESSION_MAPPING_NAMES,
|
|
|
|
| 341 |
"question-answering": MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES,
|
| 342 |
"fill-mask": MODEL_FOR_MASKED_LM_MAPPING_NAMES,
|
| 343 |
"text2text-generation": MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES,
|
| 344 |
+
"multiple-choice": MODEL_FOR_MULTIPLE_CHOICE_MAPPING_NAMES,
|
| 345 |
"image-classification": MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES,
|
| 346 |
"object-detection": MODEL_FOR_OBJECT_DETECTION_MAPPING_NAMES,
|
| 347 |
"image-segmentation": MODEL_FOR_IMAGE_SEGMENTATION_MAPPING_NAMES,
|
|
|
|
| 349 |
"instance-segmentation": MODEL_FOR_INSTANCE_SEGMENTATION_MAPPING_NAMES,
|
| 350 |
"universal-segmentation": MODEL_FOR_UNIVERSAL_SEGMENTATION_MAPPING_NAMES,
|
| 351 |
"depth-estimation": MODEL_FOR_DEPTH_ESTIMATION_MAPPING_NAMES,
|
| 352 |
+
"masked-image-modeling": MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING_NAMES,
|
| 353 |
+
"causal-image-modeling": MODEL_FOR_CAUSAL_IMAGE_MODELING_MAPPING_NAMES,
|
| 354 |
+
"keypoint-detection": MODEL_FOR_KEYPOINT_DETECTION_MAPPING_NAMES,
|
| 355 |
+
"keypoint-matching": MODEL_FOR_KEYPOINT_MATCHING_MAPPING_NAMES,
|
| 356 |
"video-classification": MODEL_FOR_VIDEO_CLASSIFICATION_MAPPING_NAMES,
|
| 357 |
"audio-classification": MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING_NAMES,
|
| 358 |
+
"audio-frame-classification": MODEL_FOR_AUDIO_FRAME_CLASSIFICATION_MAPPING_NAMES,
|
| 359 |
+
"audio-xvector": MODEL_FOR_AUDIO_XVECTOR_MAPPING_NAMES,
|
| 360 |
+
"automatic-speech-recognition": MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING_NAMES,
|
| 361 |
+
"connectionist-temporal-classification": MODEL_FOR_CTC_MAPPING_NAMES,
|
| 362 |
"image-to-text": MODEL_FOR_VISION_2_SEQ_MAPPING_NAMES,
|
| 363 |
"image-text-to-text": MODEL_FOR_IMAGE_TEXT_TO_TEXT_MAPPING_NAMES,
|
| 364 |
"visual-question-answering": MODEL_FOR_VISUAL_QUESTION_ANSWERING_MAPPING_NAMES,
|
|
|
|
| 369 |
"image-to-image": MODEL_FOR_IMAGE_TO_IMAGE_MAPPING_NAMES,
|
| 370 |
"mask-generation": MODEL_FOR_MASK_GENERATION_MAPPING_NAMES,
|
| 371 |
"text-to-audio": MODEL_FOR_TEXT_TO_SPECTROGRAM_MAPPING_NAMES,
|
| 372 |
+
"text-to-waveform": MODEL_FOR_TEXT_TO_WAVEFORM_MAPPING_NAMES,
|
| 373 |
"time-series-classification": MODEL_FOR_TIME_SERIES_CLASSIFICATION_MAPPING_NAMES,
|
| 374 |
"time-series-regression": MODEL_FOR_TIME_SERIES_REGRESSION_MAPPING_NAMES,
|
| 375 |
"time-series-prediction": MODEL_FOR_TIME_SERIES_PREDICTION_MAPPING_NAMES,
|
|
|
|
| 556 |
"question-answering": {"name": "Question Answering", "color": "#c084fc"},
|
| 557 |
"fill-mask": {"name": "Fill Mask", "color": "#d8b4fe"},
|
| 558 |
"text2text-generation": {"name": "Text2Text Generation", "color": "#e879f9"},
|
| 559 |
+
"multiple-choice": {"name": "Multiple Choice", "color": "#c026d3"},
|
| 560 |
"image-classification": {"name": "Image Classification", "color": "#06b6d4"},
|
| 561 |
"object-detection": {"name": "Object Detection", "color": "#0891b2"},
|
| 562 |
"image-segmentation": {"name": "Image Segmentation", "color": "#0e7490"},
|
|
|
|
| 564 |
"instance-segmentation": {"name": "Instance Segmentation", "color": "#164e63"},
|
| 565 |
"universal-segmentation": {"name": "Universal Segmentation", "color": "#1e40af"},
|
| 566 |
"depth-estimation": {"name": "Depth Estimation", "color": "#1d4ed8"},
|
| 567 |
+
"masked-image-modeling": {"name": "Masked Image Modeling", "color": "#7c3aed"},
|
| 568 |
+
"causal-image-modeling": {"name": "Causal Image Modeling", "color": "#6d28d9"},
|
| 569 |
+
"keypoint-detection": {"name": "Keypoint Detection", "color": "#4338ca"},
|
| 570 |
+
"keypoint-matching": {"name": "Keypoint Matching", "color": "#3730a3"},
|
| 571 |
"zero-shot-image-classification": {"name": "Zero-Shot Image Classification", "color": "#2563eb"},
|
| 572 |
"zero-shot-object-detection": {"name": "Zero-Shot Object Detection", "color": "#3b82f6"},
|
| 573 |
"image-to-image": {"name": "Image to Image", "color": "#60a5fa"},
|
|
|
|
| 579 |
"table-question-answering": {"name": "Table Question Answering", "color": "#064e3b"},
|
| 580 |
"video-classification": {"name": "Video Classification", "color": "#dc2626"},
|
| 581 |
"audio-classification": {"name": "Audio Classification", "color": "#ea580c"},
|
| 582 |
+
"audio-frame-classification": {"name": "Audio Frame Classification", "color": "#fb923c"},
|
| 583 |
+
"audio-xvector": {"name": "Audio X-Vector", "color": "#fdba74"},
|
| 584 |
+
"automatic-speech-recognition": {"name": "Automatic Speech Recognition", "color": "#e11d48"},
|
| 585 |
+
"connectionist-temporal-classification": {
|
| 586 |
+
"name": "Connectionist Temporal Classification",
|
| 587 |
+
"color": "#be123c",
|
| 588 |
+
},
|
| 589 |
"text-to-audio": {"name": "Text to Audio", "color": "#f97316"},
|
| 590 |
+
"text-to-waveform": {"name": "Text to Waveform", "color": "#fb923c"},
|
| 591 |
"time-series-classification": {"name": "Time Series Classification", "color": "#84cc16"},
|
| 592 |
"time-series-regression": {"name": "Time Series Regression", "color": "#65a30d"},
|
| 593 |
"time-series-prediction": {"name": "Time Series Prediction", "color": "#4d7c0f"},
|
|
|
|
| 637 |
body {
|
| 638 |
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
| 639 |
background: linear-gradient(135deg, #fef3c7 0%, #fed7aa 100%);
|
| 640 |
+
height: 100vh;
|
| 641 |
+
overflow: hidden;
|
| 642 |
color: #333;
|
| 643 |
display: flex;
|
| 644 |
flex-direction: column;
|
|
|
|
| 1232 |
flex: 1;
|
| 1233 |
display: flex;
|
| 1234 |
flex-direction: column;
|
| 1235 |
+
min-height: 400px;
|
| 1236 |
transition: all 0.3s ease;
|
| 1237 |
}
|
| 1238 |
|
|
|
|
| 1443 |
position: absolute;
|
| 1444 |
top: 0;
|
| 1445 |
bottom: 0;
|
| 1446 |
+
width: 1px;
|
| 1447 |
+
border-left: 1px dashed #9ca3af;
|
| 1448 |
+
opacity: 0.5;
|
| 1449 |
pointer-events: none;
|
|
|
|
| 1450 |
transition: all 0.3s ease;
|
| 1451 |
}
|
| 1452 |
|
| 1453 |
/* Dark mode date markers */
|
| 1454 |
[data-theme="dark"] .date-marker {
|
| 1455 |
+
border-left-color: #6b7280;
|
| 1456 |
+
opacity: 0.6;
|
| 1457 |
}
|
| 1458 |
|
| 1459 |
.date-label {
|
| 1460 |
position: absolute;
|
| 1461 |
+
top: 10px; /* Near the top of timeline viewport */
|
| 1462 |
left: 8px; /* Offset to the right of the line */
|
| 1463 |
font-size: 0.75rem;
|
| 1464 |
color: #6b7280;
|
|
|
|
| 1470 |
border: 1px solid rgba(156, 163, 175, 0.4);
|
| 1471 |
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
|
| 1472 |
white-space: nowrap;
|
| 1473 |
+
z-index: 9; /* Just above the dotted line but below cards */
|
| 1474 |
backdrop-filter: blur(4px);
|
| 1475 |
transition: all 0.3s ease;
|
| 1476 |
}
|
|
|
|
| 1484 |
}
|
| 1485 |
|
| 1486 |
.date-marker.year {
|
| 1487 |
+
opacity: 0.7;
|
| 1488 |
+
border-left: 1px dashed #6b7280;
|
| 1489 |
+
width: 1px;
|
| 1490 |
}
|
| 1491 |
|
| 1492 |
/* Dark mode year markers */
|
| 1493 |
[data-theme="dark"] .date-marker.year {
|
| 1494 |
+
border-left-color: #9ca3af;
|
| 1495 |
+
opacity: 0.8;
|
| 1496 |
}
|
| 1497 |
|
| 1498 |
.date-marker.year .date-label {
|
|
|
|
| 2236 |
const maxZoom = 3.0; // Maximum zoom (300%)
|
| 2237 |
let taskData = {}; // Store task data for easy lookup
|
| 2238 |
|
| 2239 |
+
// Function to calculate dynamic card spacing based on available height
|
| 2240 |
+
function getCardSpacing() {
|
| 2241 |
+
const timelineWrapper = document.querySelector('.timeline-wrapper');
|
| 2242 |
+
if (!timelineWrapper) return { above: [60, 120, 180], below: [60, 120, 180] };
|
| 2243 |
+
|
| 2244 |
+
const availableHeight = timelineWrapper.clientHeight;
|
| 2245 |
+
const centerLineOffset = availableHeight / 2;
|
| 2246 |
+
const usableHeight = Math.max(centerLineOffset - 80, 80); // Leave margin for card height
|
| 2247 |
+
|
| 2248 |
+
// Calculate spacing between levels (3 levels each side)
|
| 2249 |
+
// Use the minimum of: default spacing OR available space divided by 3
|
| 2250 |
+
const levelSpacing = Math.max(40, Math.min(60, usableHeight / 3)); // At least 40px, max 60px
|
| 2251 |
+
|
| 2252 |
+
return {
|
| 2253 |
+
above: [
|
| 2254 |
+
levelSpacing,
|
| 2255 |
+
levelSpacing * 2,
|
| 2256 |
+
levelSpacing * 3
|
| 2257 |
+
],
|
| 2258 |
+
below: [
|
| 2259 |
+
levelSpacing,
|
| 2260 |
+
levelSpacing * 2,
|
| 2261 |
+
levelSpacing * 3
|
| 2262 |
+
]
|
| 2263 |
+
};
|
| 2264 |
+
}
|
| 2265 |
+
|
| 2266 |
+
// Efficiently update card positions without re-rendering
|
| 2267 |
+
function updateCardPositions() {
|
| 2268 |
+
const cardSpacing = getCardSpacing();
|
| 2269 |
+
const timeline = document.getElementById('timeline');
|
| 2270 |
+
if (!timeline) return;
|
| 2271 |
+
|
| 2272 |
+
// Update all timeline items
|
| 2273 |
+
const items = timeline.querySelectorAll('.timeline-item');
|
| 2274 |
+
items.forEach(item => {
|
| 2275 |
+
const positionClass = item.className.match(/(above|below)-(\\d)/);
|
| 2276 |
+
if (!positionClass) return;
|
| 2277 |
+
|
| 2278 |
+
const isAbove = positionClass[1] === 'above';
|
| 2279 |
+
const level = parseInt(positionClass[2]) - 1; // 0, 1, or 2
|
| 2280 |
+
|
| 2281 |
+
// Update connector height
|
| 2282 |
+
const connector = item.querySelector('.timeline-connector');
|
| 2283 |
+
if (connector) {
|
| 2284 |
+
if (isAbove) {
|
| 2285 |
+
connector.style.height = cardSpacing.above[level] + 'px';
|
| 2286 |
+
} else {
|
| 2287 |
+
connector.style.height = cardSpacing.below[level] + 'px';
|
| 2288 |
+
}
|
| 2289 |
+
}
|
| 2290 |
+
|
| 2291 |
+
// Update label position
|
| 2292 |
+
const label = item.querySelector('.timeline-label');
|
| 2293 |
+
if (label) {
|
| 2294 |
+
if (isAbove) {
|
| 2295 |
+
const dynamicBottom = cardSpacing.above[level] + 'px';
|
| 2296 |
+
label.style.bottom = dynamicBottom;
|
| 2297 |
+
label.style.top = '';
|
| 2298 |
+
label.dataset.dynamicBottom = dynamicBottom;
|
| 2299 |
+
} else {
|
| 2300 |
+
const dynamicTop = cardSpacing.below[level] + 'px';
|
| 2301 |
+
label.style.top = dynamicTop;
|
| 2302 |
+
label.style.bottom = '';
|
| 2303 |
+
label.dataset.dynamicTop = dynamicTop;
|
| 2304 |
+
}
|
| 2305 |
+
}
|
| 2306 |
+
});
|
| 2307 |
+
}
|
| 2308 |
+
|
| 2309 |
// Theme management
|
| 2310 |
let currentTheme = 'light';
|
| 2311 |
|
|
|
|
| 2536 |
// Add date markers before adding models
|
| 2537 |
addDateMarkers(sortedModels, actualSpacing);
|
| 2538 |
|
| 2539 |
+
// Get dynamic card spacing based on available height
|
| 2540 |
+
const cardSpacing = getCardSpacing();
|
| 2541 |
+
|
| 2542 |
// Create wave patterns for stacking - simpler pattern
|
| 2543 |
const abovePattern = [1, 2, 3]; // 3 levels above
|
| 2544 |
const belowPattern = [1, 2, 3]; // 3 levels below
|
|
|
|
| 2567 |
item.className = `timeline-item ${positionClass}`;
|
| 2568 |
item.style.left = position + 'px';
|
| 2569 |
|
| 2570 |
+
// Apply dynamic positioning based on available height
|
| 2571 |
+
const levelIndex = parseInt(positionClass.split('-')[1]) - 1; // Get 0, 1, or 2
|
| 2572 |
+
const isAbove = positionClass.includes('above');
|
| 2573 |
+
|
| 2574 |
+
// Store the dynamic spacing as data attributes for later use
|
| 2575 |
+
if (isAbove) {
|
| 2576 |
+
item.dataset.dynamicBottom = cardSpacing.above[levelIndex] + 'px';
|
| 2577 |
+
item.dataset.dynamicHeight = cardSpacing.above[levelIndex] + 'px';
|
| 2578 |
+
} else {
|
| 2579 |
+
item.dataset.dynamicTop = cardSpacing.below[levelIndex] + 'px';
|
| 2580 |
+
item.dataset.dynamicHeight = cardSpacing.below[levelIndex] + 'px';
|
| 2581 |
+
}
|
| 2582 |
+
|
| 2583 |
const dot = document.createElement('div');
|
| 2584 |
dot.className = 'timeline-dot';
|
| 2585 |
|
|
|
|
| 2599 |
|
| 2600 |
const connector = document.createElement('div');
|
| 2601 |
connector.className = 'timeline-connector';
|
| 2602 |
+
// Apply dynamic height to connector
|
| 2603 |
+
if (isAbove) {
|
| 2604 |
+
connector.style.bottom = '9px';
|
| 2605 |
+
connector.style.height = cardSpacing.above[levelIndex] + 'px';
|
| 2606 |
+
} else {
|
| 2607 |
+
connector.style.top = '9px';
|
| 2608 |
+
connector.style.height = cardSpacing.below[levelIndex] + 'px';
|
| 2609 |
+
}
|
| 2610 |
|
| 2611 |
const label = document.createElement('div');
|
| 2612 |
label.className = 'timeline-label';
|
| 2613 |
label.style.borderLeftColor = model.modality_color || '#8B5CF6';
|
| 2614 |
// Set the modality color as a CSS custom property for hover effects
|
| 2615 |
label.style.setProperty('--modality-color', model.modality_color || '#8B5CF6');
|
| 2616 |
+
// Apply dynamic positioning to label and store for later restoration
|
| 2617 |
+
if (isAbove) {
|
| 2618 |
+
const dynamicBottom = cardSpacing.above[levelIndex] + 'px';
|
| 2619 |
+
label.style.bottom = dynamicBottom;
|
| 2620 |
+
label.dataset.dynamicBottom = dynamicBottom;
|
| 2621 |
+
} else {
|
| 2622 |
+
const dynamicTop = cardSpacing.below[levelIndex] + 'px';
|
| 2623 |
+
label.style.top = dynamicTop;
|
| 2624 |
+
label.dataset.dynamicTop = dynamicTop;
|
| 2625 |
+
}
|
| 2626 |
+
label.dataset.positionClass = positionClass; // Store for collapse restoration
|
| 2627 |
|
| 2628 |
// Ensure the model name is always displayed
|
| 2629 |
const modelName = model.display_name || model.model_name || 'Unknown Model';
|
|
|
|
| 2667 |
<div class="timeline-date">${otherLabel.dataset.modelDate}</div>
|
| 2668 |
`;
|
| 2669 |
|
| 2670 |
+
// Restore dynamic positioning after content change
|
| 2671 |
setTimeout(() => {
|
| 2672 |
+
// Restore the dynamically calculated position
|
| 2673 |
+
const isAbove = otherLabel.dataset.positionClass && otherLabel.dataset.positionClass.includes('above');
|
| 2674 |
+
if (isAbove && otherLabel.dataset.dynamicBottom) {
|
| 2675 |
+
otherLabel.style.bottom = otherLabel.dataset.dynamicBottom;
|
| 2676 |
+
otherLabel.style.top = '';
|
| 2677 |
+
} else if (!isAbove && otherLabel.dataset.dynamicTop) {
|
| 2678 |
+
otherLabel.style.top = otherLabel.dataset.dynamicTop;
|
| 2679 |
+
otherLabel.style.bottom = '';
|
| 2680 |
+
}
|
| 2681 |
otherLabel.style.left = '';
|
| 2682 |
otherLabel.style.right = '';
|
| 2683 |
otherLabel.style.transform = 'translateX(-50%)';
|
|
|
|
| 2804 |
<div class="timeline-date">${label.dataset.modelDate}</div>
|
| 2805 |
`;
|
| 2806 |
|
| 2807 |
+
// Restore dynamic positioning after content change
|
| 2808 |
setTimeout(() => {
|
| 2809 |
+
// Restore the dynamically calculated position
|
| 2810 |
+
const isAbove = label.dataset.positionClass && label.dataset.positionClass.includes('above');
|
| 2811 |
+
if (isAbove && label.dataset.dynamicBottom) {
|
| 2812 |
+
label.style.bottom = label.dataset.dynamicBottom;
|
| 2813 |
+
label.style.top = '';
|
| 2814 |
+
} else if (!isAbove && label.dataset.dynamicTop) {
|
| 2815 |
+
label.style.top = label.dataset.dynamicTop;
|
| 2816 |
+
label.style.bottom = '';
|
| 2817 |
+
}
|
| 2818 |
label.style.left = '';
|
| 2819 |
label.style.right = '';
|
| 2820 |
// Reset transform: depends on current position
|
|
|
|
| 2968 |
// Check if the marker date falls between these two models
|
| 2969 |
// The marker should appear where the time period actually starts
|
| 2970 |
if (currentModelDate < currentDate && currentDate <= nextModelDate) {
|
| 2971 |
+
// Position the marker between these two models
|
| 2972 |
+
boundaryPosition = (i + 1) * spacing + 68;
|
|
|
|
|
|
|
|
|
|
| 2973 |
break;
|
| 2974 |
}
|
| 2975 |
}
|
|
|
|
| 2988 |
const position = boundaryPosition;
|
| 2989 |
|
| 2990 |
// Create marker only if it's within visible range and not too close to adjacent markers
|
| 2991 |
+
// Only check VS the last existing marker, since markers are added more recent each time.
|
| 2992 |
const existingMarkers = timeline.querySelectorAll('.date-marker');
|
| 2993 |
+
let shouldRemovePrevious = false;
|
| 2994 |
+
let lastMarker = null;
|
| 2995 |
+
let lastPos = null;
|
| 2996 |
+
|
| 2997 |
+
if (existingMarkers.length > 0) {
|
| 2998 |
+
lastMarker = existingMarkers[existingMarkers.length - 1];
|
| 2999 |
+
lastPos = parseFloat(lastMarker.style.left);
|
| 3000 |
+
if (Math.abs(position - lastPos) < 60) { // Minimum spacing between markers
|
| 3001 |
+
shouldRemovePrevious = true;
|
| 3002 |
}
|
| 3003 |
+
}
|
| 3004 |
|
| 3005 |
+
if (shouldRemovePrevious && lastMarker) {
|
| 3006 |
+
lastMarker.remove();
|
| 3007 |
+
// Also remove the label associated with that marker (next sibling in .date-label)
|
| 3008 |
+
const timelineLabels = timeline.querySelectorAll('.date-label');
|
| 3009 |
+
// Find the label with the left matching the previous marker
|
| 3010 |
+
for (let i = 0; i < timelineLabels.length; i++) {
|
| 3011 |
+
const lbl = timelineLabels[i];
|
| 3012 |
+
// label.style.left is like "123px"
|
| 3013 |
+
if (Math.abs(parseFloat(lbl.style.left) - (lastPos + 8)) < 2) { // allow for rounding errors
|
| 3014 |
+
lbl.remove();
|
| 3015 |
+
break;
|
| 3016 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3017 |
}
|
| 3018 |
+
}
|
| 3019 |
|
| 3020 |
+
// Create marker
|
| 3021 |
+
const marker = document.createElement('div');
|
| 3022 |
+
marker.className = `date-marker ${markerType}`;
|
| 3023 |
+
marker.style.left = position + 'px';
|
| 3024 |
+
|
| 3025 |
+
// Create vertical line (dashed)
|
| 3026 |
+
const line = document.createElement('div');
|
| 3027 |
+
line.style.position = 'absolute';
|
| 3028 |
+
line.style.top = '0px';
|
| 3029 |
+
line.style.bottom = '0px';
|
| 3030 |
+
line.style.left = '0px';
|
| 3031 |
+
line.style.width = '1px';
|
| 3032 |
+
line.style.borderLeft = '1px dashed #9ca3af';
|
| 3033 |
+
line.style.opacity = '0.5';
|
| 3034 |
+
line.style.zIndex = '0';
|
| 3035 |
+
if (markerType === 'year') {
|
| 3036 |
+
line.style.borderLeft = '1px dashed #6b7280';
|
| 3037 |
+
line.style.opacity = '0.7';
|
| 3038 |
}
|
| 3039 |
+
marker.appendChild(line);
|
| 3040 |
+
|
| 3041 |
+
// Create label (as a separate sibling, not a child)
|
| 3042 |
+
const label = document.createElement('div');
|
| 3043 |
+
label.className = 'date-label';
|
| 3044 |
+
label.textContent = format(currentDate);
|
| 3045 |
+
label.style.left = position + 8 + 'px'; // offset similar to CSS left: 8px for label
|
| 3046 |
+
|
| 3047 |
+
timeline.appendChild(marker);
|
| 3048 |
+
timeline.appendChild(label);
|
| 3049 |
|
| 3050 |
// Move to next marker
|
| 3051 |
currentDate.setMonth(currentDate.getMonth() + increment);
|
|
|
|
| 3329 |
"question-answering": "#c084fc",
|
| 3330 |
"fill-mask": "#d8b4fe",
|
| 3331 |
"text2text-generation": "#e879f9",
|
| 3332 |
+
"multiple-choice": "#c026d3",
|
| 3333 |
|
| 3334 |
"image-classification": "#06b6d4",
|
| 3335 |
"object-detection": "#0891b2",
|
|
|
|
| 3338 |
"instance-segmentation": "#164e63",
|
| 3339 |
"universal-segmentation": "#1e40af",
|
| 3340 |
"depth-estimation": "#1d4ed8",
|
| 3341 |
+
"masked-image-modeling": "#7c3aed",
|
| 3342 |
+
"causal-image-modeling": "#6d28d9",
|
| 3343 |
+
"keypoint-detection": "#4338ca",
|
| 3344 |
+
"keypoint-matching": "#3730a3",
|
| 3345 |
"zero-shot-image-classification": "#2563eb",
|
| 3346 |
"zero-shot-object-detection": "#3b82f6",
|
| 3347 |
"image-to-image": "#60a5fa",
|
|
|
|
| 3355 |
|
| 3356 |
"video-classification": "#dc2626",
|
| 3357 |
"audio-classification": "#ea580c",
|
| 3358 |
+
"audio-frame-classification": "#fb923c",
|
| 3359 |
+
"audio-xvector": "#fdba74",
|
| 3360 |
+
"automatic-speech-recognition": "#e11d48",
|
| 3361 |
+
"connectionist-temporal-classification": "#be123c",
|
| 3362 |
"text-to-audio": "#f97316",
|
| 3363 |
+
"text-to-waveform": "#fb923c",
|
| 3364 |
|
| 3365 |
"time-series-classification": "#84cc16",
|
| 3366 |
"time-series-regression": "#65a30d",
|
|
|
|
| 3403 |
checkbox.type = 'checkbox';
|
| 3404 |
checkbox.value = modality.key;
|
| 3405 |
checkbox.id = `modality-${modality.key}`;
|
| 3406 |
+
checkbox.checked = false; // All modalities unchecked by default
|
| 3407 |
|
| 3408 |
const label = document.createElement('label');
|
| 3409 |
label.htmlFor = `modality-${modality.key}`;
|
|
|
|
| 3422 |
loadTimeline();
|
| 3423 |
});
|
| 3424 |
|
| 3425 |
+
// Set initial state (unchecked, so no 'checked' class)
|
|
|
|
| 3426 |
|
| 3427 |
modalityFilters.appendChild(checkboxContainer);
|
| 3428 |
});
|
|
|
|
| 3432 |
}
|
| 3433 |
}
|
| 3434 |
|
| 3435 |
+
// Window resize handler - use efficient position update
|
| 3436 |
+
let resizeTimeout;
|
| 3437 |
window.addEventListener('resize', () => {
|
| 3438 |
+
// Update immediately for responsiveness
|
| 3439 |
+
updateCardPositions();
|
| 3440 |
+
|
| 3441 |
+
// Debounce full re-render for final adjustment
|
| 3442 |
+
clearTimeout(resizeTimeout);
|
| 3443 |
+
resizeTimeout = setTimeout(() => {
|
| 3444 |
+
if (currentModels.length > 0) {
|
| 3445 |
+
renderTimeline(currentModels, true);
|
| 3446 |
+
}
|
| 3447 |
+
}, 250);
|
| 3448 |
});
|
| 3449 |
|
| 3450 |
document.addEventListener('DOMContentLoaded', async () => {
|
|
|
|
| 3489 |
<div class="timeline-date">${label.dataset.modelDate}</div>
|
| 3490 |
`;
|
| 3491 |
|
| 3492 |
+
// Restore dynamic positioning after content change
|
| 3493 |
setTimeout(() => {
|
| 3494 |
+
// Restore the dynamically calculated position
|
| 3495 |
+
const isAbove = label.dataset.positionClass && label.dataset.positionClass.includes('above');
|
| 3496 |
+
if (isAbove && label.dataset.dynamicBottom) {
|
| 3497 |
+
label.style.bottom = label.dataset.dynamicBottom;
|
| 3498 |
+
label.style.top = '';
|
| 3499 |
+
} else if (!isAbove && label.dataset.dynamicTop) {
|
| 3500 |
+
label.style.top = label.dataset.dynamicTop;
|
| 3501 |
+
label.style.bottom = '';
|
| 3502 |
+
}
|
| 3503 |
label.style.transform = 'translateX(-50%)';
|
| 3504 |
label.parentElement.style.zIndex = '';
|
| 3505 |
}, 50);
|
|
|
|
| 3556 |
btn.textContent = '▸';
|
| 3557 |
localStorage.setItem('filtersCollapsed', 'true');
|
| 3558 |
}
|
| 3559 |
+
|
| 3560 |
+
// Update card positions immediately
|
| 3561 |
+
updateCardPositions();
|
| 3562 |
+
|
| 3563 |
+
// Continue updating during animation for smooth transition
|
| 3564 |
+
const startTime = performance.now();
|
| 3565 |
+
const animationDuration = 250; // Match CSS transition time
|
| 3566 |
+
|
| 3567 |
+
const animatePositions = (currentTime) => {
|
| 3568 |
+
const elapsed = currentTime - startTime;
|
| 3569 |
+
|
| 3570 |
+
if (elapsed < animationDuration) {
|
| 3571 |
+
updateCardPositions();
|
| 3572 |
+
requestAnimationFrame(animatePositions);
|
| 3573 |
+
} else {
|
| 3574 |
+
// Final update after animation completes
|
| 3575 |
+
updateCardPositions();
|
| 3576 |
+
}
|
| 3577 |
+
};
|
| 3578 |
+
|
| 3579 |
+
requestAnimationFrame(animatePositions);
|
| 3580 |
}
|
| 3581 |
</script>
|
| 3582 |
</body>
|