add ai safety file

D David Veksler · 1 year ago 52bcb67a7194d0c16911e4d0b21ff8baed73ee04
Parent: 502809fd0

2 files changed +1226 −0

Diff

diff --git a/aisafety.html b/aisafety.html
new file mode 100644
index 0000000..417eceb
--- /dev/null
+++ b/aisafety.html
@@ -0,0 +1,990 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <meta name="description" content="Explore the AI Safety ecosystem: A comprehensive, interactive directory and visual map of labs, research groups, policy orgs, funding, and resources. Toggle between list and map views.">
+  
+    <!-- ====== Open Graph / Facebook Meta Tags ====== -->
+    <meta property="og:type" content="website">
+    <meta property="og:url" content="https://aisafety.davidveksler.com"> <!-- Replace with the actual URL of your page -->
+    <meta property="og:title" content="Interactive AI Safety Ecosystem Hub (List & Map)"> <!-- The title shown in the share preview -->
+    <meta property="og:description" content="Explore labs, research, policy, funding & resources in the AI Safety field via an interactive list and map."> <!-- Short, catchy description -->
+    <meta property="og:image" content="https://aisafety.davidveksler.com/ai-safety-ecosystem-preview.png"> <!-- Replace with the FULL URL to your preview image -->
+    <meta property="og:image:width" content="1200"> <!-- Optional: Specify image width -->
+    <meta property="og:image:height" content="630"> <!-- Optional: Specify image height -->
+    <!-- <meta property="og:site_name" content="Your Site Name"> --> <!-- Optional: If your hub is part of a larger site -->
+
+    <!-- ====== Twitter Card Meta Tags ====== -->
+    <meta name="twitter:card" content="summary_large_image"> <!-- Use "summary_large_image" for the 1200x630 image -->
+    <meta name="twitter:url" content="https://aisafety.davidveksler.com"> <!-- Replace with the actual URL of your page -->
+    <meta name="twitter:title" content="Interactive AI Safety Ecosystem Hub (List & Map)"> <!-- Title for Twitter shares -->
+    <meta name="twitter:description" content="Explore labs, research, policy, funding & resources in the AI Safety field via an interactive list and map."> <!-- Description for Twitter shares -->
+    <meta name="twitter:image" content="https://aisafety.davidveksler.com/ai-safety-ecosystem-preview.png"> <!-- Replace with the FULL URL to your preview image -->
+    <!-- <meta name="twitter:site" content="@YourTwitterHandle"> --> <!-- Optional: Your site's Twitter handle -->
+    <!-- <meta name="twitter:creator" content="@CreatorTwitterHandle"> --> <!-- Optional: Content creator's handle if different -->
+
+    <!-- ====== Other Optional Meta Tags ====== -->    
+    <link rel="canonical" href="https://aisafety.davidveksler.com"> <!-- Important for SEO: The preferred URL -->
+
+    <title>Interactive AI Safety Ecosystem Hub (List & Map)</title>
+
+    <!-- Bootstrap CSS -->
+    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
+    <!-- Bootstrap Icons -->
+    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.min.css">
+    <!-- D3.js -->
+    <script src="https://d3js.org/d3.v7.min.js"></script>
+
+    <style>
+        html, body {
+            height: 100%;
+            overflow: hidden; /* Prevent body scrollbars when map is active */
+        }
+        body {
+            display: flex;
+            flex-direction: column;
+            background-color: #f0f2f5;
+            font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* Bootstrap's font stack */
+        }
+        header {
+            background-color: #087990;
+            color: white;
+            padding: 0.75rem 1rem;
+            flex-shrink: 0;
+        }
+        header h4 {
+            margin: 0;
+            font-size: 1.25rem;
+        }
+        /* Main container for tabs and content */
+        .main-content-area {
+            flex-grow: 1;
+            display: flex;
+            flex-direction: column;
+            overflow: hidden; /* Contain tab content */
+            padding: 1rem; /* Add some padding around tab area */
+            padding-bottom: 0;
+        }
+         /* Tab Styling */
+        .nav-tabs {
+            border-bottom: 1px solid #dee2e6;
+            flex-shrink: 0; /* Prevent tabs from shrinking */
+        }
+        .nav-tabs .nav-link {
+            color: #495057;
+            border-radius: 0.375rem 0.375rem 0 0;
+            padding: 0.75rem 1.25rem;
+            font-weight: 500;
+            background-color: #e9ecef; /* Lighter background for inactive tabs */
+            border-color: transparent; /* Cleaner look for inactive */
+        }
+        .nav-tabs .nav-link.active {
+            color: #087990;
+            background-color: #fff; /* Make active tab bg white */
+            border-color: #dee2e6 #dee2e6 #fff; /* Connect border */
+        }
+        .nav-tabs .nav-link:hover:not(.active) {
+            border-color: #e9ecef #e9ecef #dee2e6;
+            background-color: #f8f9fa; /* Slightly lighter hover */
+        }
+        .tab-content {
+            flex-grow: 1;
+            overflow: hidden; /* Important for child height */
+            background-color: #fff; /* White background for content */
+            border: 1px solid #dee2e6; /* Border around content */
+            border-top: none;
+            border-radius: 0 0 0.375rem 0.375rem;
+        }
+        .tab-pane {
+            height: 100%;
+            overflow: hidden; /* Children must handle own scrolling */
+            display: flex; /* Use flex for map layout */
+            flex-direction: column; /* Default for list view */
+        }
+        .tab-pane.active {
+            display: flex; /* Override Bootstrap's default block */
+        }
+
+        /* --- List View Styling --- */
+        #list-view-pane { /* The container for the scrolling list */
+             overflow-y: auto;
+        }
+        #list-view { /* The inner content div */
+             padding: 1.5rem;
+        }
+        /* --- Category Navigation (List View) --- */
+        #category-nav {
+            display: flex;
+            flex-wrap: wrap; /* Allow wrapping on smaller screens */
+            gap: 0.5rem; /* Spacing between links */
+            padding: 0.75rem 1rem;
+            background-color: #f8f9fa; /* Light background */
+            border: 1px solid #dee2e6;
+            margin-bottom: 1.5rem; /* Space below nav */
+            border-radius: 0.375rem;
+        }
+        .category-link {
+            text-decoration: none;
+            padding: 0.35rem 0.75rem;
+            border-radius: 0.375rem;
+            font-size: 0.8rem;
+            font-weight: 500;
+            display: inline-flex; /* Align icon and text */
+            align-items: center;
+            gap: 0.3rem; /* Space between icon and text */
+            border: 1px solid transparent;
+            transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
+            color: #343a40; /* Default text color */
+            background-color: #e9ecef; /* Default background */
+            border-color: #dee2e6;
+        }
+        .category-link:hover {
+            background-color: #d3d9df;
+            border-color: #adb5bd;
+            color: #000;
+        }
+        .category-link i {
+            font-size: 0.9em;
+            vertical-align: middle; /* Adjusted for flex align */
+            line-height: 1; /* Ensure consistent height */
+        }
+        /* Add category-specific colors using border - safer for accessibility */
+        /* Map View uses background colors, Nav uses border */
+        .cat-color-labs { border-left: 4px solid #dc3545; }
+        .cat-color-academic { border-left: 4px solid #fd7e14; }
+        .cat-color-policy { border-left: 4px solid #ffc107; }
+        .cat-color-advocacy { border-left: 4px solid #20c997; }
+        .cat-color-info { border-left: 4px solid #0dcaf0; }
+        .cat-color-funding { border-left: 4px solid #198754; }
+        .cat-color-field { border-left: 4px solid #0d6efd; }
+        .cat-color-community { border-left: 4px solid #6f42c1; }
+        .cat-color-forecasting { border-left: 4px solid #d63384; }
+        .cat-color-inactive { border-left: 4px solid #6c757d; }
+
+
+        #list-view h2 {
+            color: #087990;
+            border-bottom: 2px solid #e0f2f7;
+            padding-bottom: 0.5rem;
+            margin-top: 1.5rem;
+            margin-bottom: 1rem;
+            font-size: 1.5rem;
+            scroll-margin-top: 70px; /* Offset for fixed headers or nav */
+        }
+        #list-view h2:first-of-type {
+            margin-top: 0; /* No top margin for the very first header */
+        }
+        .importance-legend {
+            margin-bottom: 1.5rem;
+            padding: 1rem;
+            background-color: #e9ecef;
+            border-radius: 0.375rem;
+            border: 1px solid #dee2e6;
+        }
+         .importance-legend span { margin-right: 10px; white-space: nowrap; }
+         .importance-legend .badge { font-size: 0.8em; padding: 0.35em 0.6em; color: #fff; font-weight: bold; vertical-align: middle; }
+
+         /* Card styles */
+        .card { margin-bottom: 1.5rem; border: none; box-shadow: 0 3px 7px rgba(0, 0, 0, 0.08); display: flex; flex-direction: column; height: 100%; transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out; }
+        .card:hover { transform: translateY(-5px); box-shadow: 0 6px 12px rgba(0, 0, 0, 0.1); }
+        .card-body { display: flex; flex-direction: column; flex-grow: 1; padding: 1rem; } /* Standard padding */
+        .card-title { margin-bottom: 0; flex-grow: 1; min-width: 0; /* Allow shrinking */ display: flex; align-items: baseline; /* Align badge nicely */ flex-wrap: wrap; /* Allow wrapping if needed */ gap: 0 0.5rem; /* Horizontal gap for badge */ }
+        .card-title a { text-decoration: none; color: #0b5c6e; font-weight: 600; font-size: 1rem; /* Slightly smaller titles */ }
+        .card-title a:hover { text-decoration: underline; }
+        .card-text { margin-bottom: 0.75rem; font-size: 0.875rem; /* Smaller card text */ line-height: 1.6; color: #495057; }
+        .category-info { margin-bottom: 0.75rem; display: flex; align-items: center; }
+        .category-icon { font-size: 0.9rem; margin-right: 0.4rem; color: #6c757d; vertical-align: middle; flex-shrink: 0; line-height: 1; /* Consistency */ }
+        .category-text { font-size: 0.75rem; color: #6c757d; font-style: italic; vertical-align: middle; }
+        .importance-badge { font-size: 0.7em; padding: 0.3em 0.55em; vertical-align: baseline; color: #fff; font-weight: bold; border-radius: 0.375rem; line-height: 1; }
+        .imp-1 { background-color: #adb5bd; } .imp-2 { background-color: #5fa8d3; } .imp-3 { background-color: #1a9988; } .imp-4 { background-color: #f7b801; } .imp-5 { background-color: #f25c54; }
+        .inactive-card { opacity: 0.75; background-color: #e9ecef !important; }
+        .inactive-card .card-title a { color: #6c757d !important; }
+         /* AI Lab specific */
+        .title-logo-container { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.75rem; gap: 10px; }
+        .ai-lab-logo { max-height: 30px; max-width: 90px; margin-left: 10px; object-fit: contain; vertical-align: middle; flex-shrink: 0; }
+        .safety-links { margin-top: auto; padding-top: 0.5rem; border-top: 1px solid #eee; font-size: 0.75rem; line-height: 1.6; } /* Changed margin-top to auto */
+        .safety-links a { color: #555; text-decoration: none; margin-right: 10px; display: inline-block; white-space: nowrap; }
+        .safety-links a:hover { color: #087990; text-decoration: underline; }
+        .safety-links i { margin-right: 3px; vertical-align: middle; font-size: 0.9em; }
+
+
+        /* --- Map View Styling --- */
+        #map-view-pane { /* The container for map + controls */
+             flex-direction: row; /* Side-by-side */
+        }
+        #controls-container {
+            width: 280px; /* Fixed width for controls */
+            flex-shrink: 0;
+            padding: 1rem;
+            background-color: #e9ecef;
+            border-right: 1px solid #dee2e6;
+            overflow-y: auto;
+            height: 100%;
+        }
+        #map-container {
+            flex-grow: 1;
+            position: relative;
+            overflow: hidden;
+            height: 100%;
+            background-color: #ffffff;
+        }
+        #map-svg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; cursor: grab; }
+        #map-svg:active { cursor: grabbing; }
+
+        /* D3 Node Styling */
+        .node circle { stroke: rgba(0,0,0,0.2); stroke-width: 0.5px; transition: transform 0.1s ease-out, stroke 0.1s ease-out; }
+        .node:hover circle { stroke: #333; stroke-width: 1px; }
+        .node { filter: url(#drop-shadow); transition: filter 0.2s ease-out; } /* Smooth filter change */
+        .node text.node-label { font-size: 9px; fill: #333; text-anchor: middle; pointer-events: none; paint-order: stroke; stroke: rgba(255,255,255,0.7); stroke-width: 2.5px; stroke-linecap: butt; stroke-linejoin: miter; }
+        .node text.node-icon { font-family: 'bootstrap-icons'; font-size: 12px; fill: rgba(0, 0, 0, 0.5); text-shadow: 0px 0px 2px rgba(255, 255, 255, 0.7); text-anchor: middle; dominant-baseline: central; pointer-events: none; }
+        .node.selected { filter: url(#drop-shadow-selected); }
+        .node.selected circle { stroke: #087990; stroke-width: 2px; }
+        .node.selected text.node-label { font-weight: bold; fill: #000; stroke: rgba(255,255,255,0.8); }
+        .node.selected text.node-icon { fill: rgba(0, 0, 0, 0.7); }
+
+        /* Tooltip Styling */
+        #tooltip { position: absolute; background-color: rgba(0, 0, 0, 0.85); color: white; padding: 8px 12px; border-radius: 4px; font-size: 0.85rem; pointer-events: none; opacity: 0; transition: opacity 0.2s; white-space: normal; /* Allow wrap */ z-index: 10; box-shadow: 0 2px 5px rgba(0,0,0,0.2); max-width: 250px; /* Limit width */ }
+        #tooltip strong { display: block; margin-bottom: 3px; font-weight: 600; }
+        #tooltip .tooltip-details { font-size: 0.75rem; opacity: 0.9; margin-bottom: 4px; }
+        #tooltip .tooltip-desc { font-size: 0.75rem; opacity: 0.8; font-style: italic; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; /* Truncate description */ }
+
+        /* Info Panel Styling (Sidebar) */
+        #controls-container h5 { font-size: 1rem; margin-bottom: 0.75rem; color: #343a40; padding-top: 0.5rem; }
+        #controls-container hr { margin: 1rem 0;} /* Consistent spacing */
+        #info-panel { padding: 1rem; background-color: #fff; border-radius: 0.375rem; border: 1px solid #dee2e6; box-shadow: 0 2px 5px rgba(0,0,0,0.1); display: none; /* Hidden by default */ margin-top: 0; /* Remove top margin here */ }
+        #info-panel h5 { font-size: 1.1rem; color: #087990; margin-bottom: 0.75rem; margin-top: 0; }
+        #info-panel p { font-size: 0.85rem; margin-bottom: 0.5rem; }
+        #info-panel .badge { vertical-align: baseline; margin-left: 5px; }
+        #info-panel a.external-link { font-size: 0.85rem; word-break: break-all; }
+        #info-panel #info-safety-links { margin-top: 0.75rem; padding-top: 0.5rem; border-top: 1px solid #eee; }
+        #info-panel #info-safety-links h6 { font-size: 0.85rem; margin-bottom: 0.3rem; color: #555; }
+        #info-panel #info-safety-links a { display: block; margin-bottom: 0.2rem; font-size: 0.8rem; color: #0b5c6e; }
+         #info-panel #info-safety-links a:hover { text-decoration: underline; }
+        #info-panel #info-safety-links i { font-size: 0.9em; margin-right: 4px; color: #6c757d; }
+
+        /* Filter & Legend Styling */
+        #filter-controls .form-check { margin-bottom: 0.3rem; }
+        #filter-controls .form-check-label { font-size: 0.85rem; }
+        #legend .legend-item { display: flex; align-items: center; margin-bottom: 0.25rem; font-size: 0.85rem; }
+        .legend-color-box { width: 15px; height: 15px; margin-right: 8px; border: 1px solid #ccc; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; border-radius: 50%; }
+        .legend-color-box i { font-size: 10px; color: rgba(0, 0, 0, 0.6); text-shadow: 0px 0px 1px rgba(255, 255, 255, 0.5); }
+        .legend-item span:last-child { margin-left: 5px; }
+
+        /* Loading Spinner */
+        .spinner-container { padding: 3rem; text-align: center; }
+
+    </style>
+</head>
+<body>
+
+    <header>
+        <h4><i class="bi bi-shield-check"></i> Interactive AI Safety Ecosystem Hub</h4>
+    </header>
+
+    <div class="main-content-area">
+        <!-- Tab Navigation -->
+        <ul class="nav nav-tabs" id="viewTab" role="tablist">
+            <li class="nav-item" role="presentation">
+                <button class="nav-link active" id="list-tab" data-bs-toggle="tab" data-bs-target="#list-view-pane" type="button" role="tab" aria-controls="list-view-pane" aria-selected="true">
+                    <i class="bi bi-list-ul"></i> List View
+                </button>
+            </li>
+            <li class="nav-item" role="presentation">
+                <button class="nav-link" id="map-tab" data-bs-toggle="tab" data-bs-target="#map-view-pane" type="button" role="tab" aria-controls="map-view-pane" aria-selected="false">
+                    <i class="bi bi-diagram-3"></i> Map View
+                </button>
+            </li>
+        </ul>
+
+        <!-- Tab Content -->
+        <div class="tab-content" id="viewTabContent">
+            <!-- List View Pane -->
+            <div class="tab-pane fade show active" id="list-view-pane" role="tabpanel" aria-labelledby="list-tab" tabindex="0">
+                <div id="list-view">
+                     <!-- Category Navigation -->
+                     <nav id="category-nav">
+                         <a href="#list-ai-lab" class="category-link cat-color-labs" title="Jump to the Major AI Labs section"><i class="bi bi-robot"></i> AI Labs</a>
+                         <a href="#list-academic-research" class="category-link cat-color-academic" title="Jump to the Academic & Independent Research Groups section"><i class="bi bi-mortarboard-fill"></i> Academic/Research</a>
+                         <a href="#list-policy-gov" class="category-link cat-color-policy" title="Jump to the Policy, Governance & Strategy Organizations section"><i class="bi bi-building-gear"></i> Policy/Gov</a>
+                         <a href="#list-advocacy" class="category-link cat-color-advocacy" title="Jump to the Advocacy & Public Awareness Groups section"><i class="bi bi-megaphone-fill"></i> Advocacy</a>
+                         <a href="#list-info-media" class="category-link cat-color-info" title="Jump to the Information Hubs, Media & Foundational Resources section"><i class="bi bi-broadcast-pin"></i> Info/Media</a>
+                         <a href="#list-funding" class="category-link cat-color-funding" title="Jump to the Funding & Philanthropy section"><i class="bi bi-cash-stack"></i> Funding</a>
+                         <a href="#list-field-building" class="category-link cat-color-field" title="Jump to the Field Building, Education & Career Support section"><i class="bi bi-person-workspace"></i> Field Building</a>
+                         <a href="#list-community-infra" class="category-link cat-color-community" title="Jump to the Community Infrastructure & Research Support section"><i class="bi bi-diagram-3-fill"></i> Community/Infra</a>
+                         <a href="#list-forecasting" class="category-link cat-color-forecasting" title="Jump to the Forecasting section"><i class="bi bi-graph-up-arrow"></i> Forecasting</a>
+                         <a href="#list-inactive" class="category-link cat-color-inactive" title="Jump to the Inactive / Defunct Resources section"><i class="bi bi-slash-circle-fill"></i> Inactive</a>
+                     </nav>
+
+                     <!-- Legend for List View -->
+                     <div class="importance-legend">
+                         <strong>Importance Score Legend (Subjective Ecosystem Impact):</strong><br class="d-sm-none"> <!-- Break on small screens -->
+                         <span class="badge imp-5">5=Essential/Major Player</span>
+                         <span class="badge imp-4">4=Highly Influential/Key Resource</span>
+                         <span class="badge imp-3">3=Significant Contributor</span>
+                         <span class="badge imp-2">2=Relevant/Niche</span>
+                         <span class="badge imp-1">1=Supplementary/Inactive/Niche</span>
+                         <br><small class="text-muted d-block mt-1">Score reflects perceived impact/centrality within the broader AI Safety ecosystem.</small>
+                    </div>
+
+                    <div id="list-view-content">
+                        <div class="spinner-container">
+                            <div class="spinner-border text-primary" role="status">
+                                <span class="visually-hidden">Loading...</span>
+                            </div>
+                            <p class="mt-2">Loading Resources...</p>
+                        </div>
+                    </div>
+                </div>
+            </div>
+
+            <!-- Map View Pane -->
+            <div class="tab-pane fade" id="map-view-pane" role="tabpanel" aria-labelledby="map-tab" tabindex="0">
+                <div id="controls-container">
+                    <h5><i class="bi bi-filter"></i> Filter by Category</h5>
+                    <div id="filter-controls"> <!-- Populated by JS --> </div>
+                    <hr>
+                    <h5><i class="bi bi-palette"></i> Legend</h5>
+                    <div id="legend"> <!-- Populated by JS --> </div>
+                    <hr>
+                    <div id="info-panel"> <!-- Populated on click -->
+                        <h5 id="info-name">Select a Node</h5>
+                        <p><strong>Category:</strong> <span id="info-category"></span></p>
+                        <p><strong>Importance:</strong> <span id="info-importance"></span></p>
+                        <p><strong>Description:</strong> <span id="info-description">...</span></p>
+                        <p><a href="#" id="info-link" class="external-link" target="_blank" rel="noopener noreferrer">Visit Website <i class="bi bi-box-arrow-up-right small"></i></a></p>
+                        <div id="info-safety-links">
+                             <!-- AI Lab Safety Links added here -->
+                        </div>
+                    </div>
+                    <hr>
+                    <small class="text-muted">Hover for details. Click nodes for sidebar info. Zoom/Pan the map. Use filters.</small>
+                </div>
+                <div id="map-container">
+                    <svg id="map-svg">
+                        <defs>
+                            <!-- Drop Shadow Filters -->
+                            <filter id="drop-shadow" x="-50%" y="-50%" width="200%" height="200%"> <feGaussianBlur in="SourceAlpha" stdDeviation="2" result="blur"/> <feOffset in="blur" dx="2" dy="2" result="offsetBlur"/> <feFlood flood-color="#333" flood-opacity="0.4" result="offsetColor"/> <feComposite in="offsetColor" in2="offsetBlur" operator="in" result="offsetBlurColored"/> <feMerge> <feMergeNode in="offsetBlurColored"/> <feMergeNode in="SourceGraphic"/> </feMerge> </filter>
+                            <filter id="drop-shadow-selected" x="-50%" y="-50%" width="200%" height="200%"> <feGaussianBlur in="SourceAlpha" stdDeviation="3" result="blur"/> <feOffset in="blur" dx="3" dy="3" result="offsetBlur"/> <feFlood flood-color="#000" flood-opacity="0.5" result="offsetColor"/> <feComposite in="offsetColor" in2="offsetBlur" operator="in" result="offsetBlurColored"/> <feMerge> <feMergeNode in="offsetBlurColored"/> <feMergeNode in="SourceGraphic"/> </feMerge> </filter>
+                            <!-- Radial Gradients added by JS -->
+                        </defs>
+                    </svg>
+                    <div id="tooltip"></div> <!-- Tooltip Div -->
+                </div>
+            </div>
+        </div>
+    </div>
+
+
+    <!-- Bootstrap JS Bundle -->
+    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
+
+    <!-- Load the external data -->
+    <script src="safety_data.js"></script>
+
+    <!-- Main Application Logic -->
+    <script>
+    // --- Icon Mapping ---
+    const categoryIcons = {
+        "AI Lab": "bi-robot",
+        "Academic/Research": "bi-mortarboard-fill",
+        "Policy/Gov": "bi-building-gear",
+        "Advocacy": "bi-megaphone-fill",
+        "Info/Media": "bi-broadcast-pin",
+        "Funding": "bi-cash-stack",
+        "Field Building": "bi-person-workspace",
+        "Community/Infra": "bi-diagram-3-fill",
+        "Forecasting": "bi-graph-up-arrow",
+        "Inactive": "bi-slash-circle-fill"
+    };
+
+    // --- Process Data from data.js ---
+    // Check if raw data loaded, otherwise use an empty array to avoid errors
+    const aiSafetyData = (typeof rawAiSafetyData !== 'undefined' ? rawAiSafetyData : []).map(node => ({
+        ...node,
+        // Ensure icon exists, default if not
+        icon: categoryIcons[node.category] || 'bi-question-circle',
+        // Create a unique ID for the card element in the list view
+        cardId: `card-${node.id.replace(/[^a-zA-Z0-9]/g, '-')}`, // Basic slugify
+        // Ensure importance is a number, default to a mid-value if invalid/missing
+        importance: (typeof node.importance === 'number' && node.importance >= 1 && node.importance <= 5) ? node.importance : 3,
+        // Ensure subCategoryIcon and subCategoryText are present, even if null/undefined initially
+        subCategoryIcon: node.subCategoryIcon || null,
+        subCategoryText: node.subCategoryText || null
+    }));
+
+
+    // --- Global Variables & Constants ---
+    const categoryOrder = ["AI Lab", "Academic/Research", "Policy/Gov", "Advocacy", "Info/Media", "Funding", "Field Building", "Community/Infra", "Forecasting", "Inactive"];
+    const categoryColors = {
+        "AI Lab": "#dc3545",
+        "Academic/Research": "#fd7e14",
+        "Policy/Gov": "#ffc107",
+        "Advocacy": "#20c997",
+        "Info/Media": "#0dcaf0",
+        "Funding": "#198754",
+        "Field Building": "#0d6efd",
+        "Community/Infra": "#6f42c1",
+        "Forecasting": "#d63384",
+        "Inactive": "#6c757d"
+    };
+    let mapRendered = false; // Flag to track if map has been initially rendered
+    let categoryCenters = {}; // To store cluster center coordinates
+
+
+    // --- Core Rendering Functions ---
+
+    function renderListView(data) {
+        const container = document.getElementById('list-view-content');
+        if (!container) { console.error("List view container not found"); return; }
+        container.innerHTML = ''; // Clear previous content/spinner
+
+        // Check if data is empty after processing
+        if (!data || data.length === 0) {
+             if (typeof rawAiSafetyData === 'undefined') {
+                  container.innerHTML = '<p class="text-danger text-center">Error: Could not load data from data.js.</p>';
+             } else {
+                  container.innerHTML = '<p class="text-muted text-center">No AI Safety data to display.</p>';
+             }
+             return; // Stop execution if no data
+        }
+
+        categoryOrder.forEach(category => {
+            const categoryData = data.filter(item => item.category === category);
+            if (categoryData.length === 0) return;
+
+            const section = document.createElement('section');
+            // Generate ID matching the navigation hrefs (e.g., list-ai-lab)
+            section.id = `list-${category.toLowerCase().replace(/[^a-z0-9]+/g, '-')}`;
+            const header = document.createElement('h2');
+            header.className = 'mb-4';
+            // Use the main category icon for the list view header as well
+            header.innerHTML = `<i class="${categoryIcons[category] || 'bi-question-circle'} category-icon"></i> ${category}`;
+            section.appendChild(header);
+
+            const row = document.createElement('div');
+            row.className = 'row row-cols-1 row-cols-md-2 row-cols-xl-3 g-4'; // Adjusted grid for potentially more columns on XL
+            section.appendChild(row);
+
+            // Sort items within the category by importance (descending, so 5 is higher) then name
+            categoryData.sort((a, b) => {
+                if (a.importance !== b.importance) {
+                    // Higher importance number should come first
+                    return b.importance - a.importance;
+                }
+                return a.name.localeCompare(b.name); // Then alphabetically
+            });
+
+
+            categoryData.forEach(item => {
+                const col = document.createElement('div');
+                col.className = 'col d-flex align-items-stretch'; // Make columns align items and stretch card
+
+                const isLab = item.category === "AI Lab";
+                const isInactive = item.category === "Inactive";
+
+                let safetyLinksHTML = '';
+                if (item.safetyLinks && item.safetyLinks.length > 0) {
+                    safetyLinksHTML = `
+                        <div class="safety-links pt-2"> <!-- Removed mt-auto, handled by flex grow on desc -->
+                            ${item.safetyLinks.map(link => `
+                                <a href="${link.url}" target="_blank" rel="noopener noreferrer" title="${link.title || link.text}">
+                                    <i class="${link.icon || 'bi-link-45deg'}"></i>${link.text}
+                                </a>
+                            `).join('')}
+                        </div>`;
+                }
+
+                 // *** UPDATED: Use subCategoryIcon/Text with fallbacks ***
+                 // Fallback chain: Use item.subCategoryIcon if available, otherwise use the main category icon,
+                 // otherwise use a generic 'info' icon as the final fallback.
+                 const subIcon = item.subCategoryIcon || categoryIcons[item.category] || 'bi-info-circle';
+                 // Fallback: Use item.subCategoryText if available, otherwise use the main category name.
+                 const subText = item.subCategoryText || item.category;
+
+                col.innerHTML = `
+                    <div class="card flex-fill ${isInactive ? 'inactive-card' : ''}" id="${item.cardId}">
+                        <div class="card-body d-flex flex-column"> <!-- Flex column for card body -->
+                            ${isLab ? `
+                                <div class="title-logo-container">
+                                    <h5 class="card-title mb-0">
+                                        <a href="${item.url}" target="_blank" rel="noopener noreferrer" title="Visit the ${item.name} website">${item.name}</a>
+                                        <span class="badge importance-badge imp-${item.importance}" title="Importance Score: ${item.importance}">${item.importance}</span>
+                                    </h5>
+                                    ${item.logoUrl ? `<img src="${item.logoUrl}" alt="${item.name} Logo" class="ai-lab-logo">` : ''}
+                                </div>
+                            ` : `
+                                <h5 class="card-title">
+                                    <a href="${item.url}" target="_blank" rel="noopener noreferrer" title="Visit the ${item.name} website">${item.name}</a>
+                                    <span class="badge importance-badge imp-${item.importance}" title="Importance Score: ${item.importance}">${item.importance}</span>
+                                </h5>
+                            `}
+                            <div class="category-info">
+                                <i class="${subIcon} category-icon" title="${item.category}"></i> <!-- Title attribute still shows main category for context -->
+                                <span class="category-text">${subText}</span> <!-- Display subcategory text or main category name -->
+                            </div>
+                            <p class="card-text flex-grow-1">${item.description}</p> <!-- Allow description to grow -->
+                            ${safetyLinksHTML} <!-- Safety links will be pushed down by description growth -->
+                        </div>
+                    </div>
+                `;
+                row.appendChild(col);
+            });
+
+            container.appendChild(section);
+            // Add divider logic
+             const nextCategoryIndex = categoryOrder.indexOf(category) + 1;
+             const nextPopulatedCategory = categoryOrder.slice(nextCategoryIndex).find(cat => data.some(d => d.category === cat));
+             if (nextPopulatedCategory && category !== "Inactive") { // Don't add divider after last real category
+                  const divider = document.createElement('hr');
+                  divider.className = 'my-4'; // Bootstrap margin utility
+                  container.appendChild(divider);
+             }
+        });
+    }
+
+    function renderMapView(data) {
+        mapRendered = true; // Mark map as rendered
+        const mapContainer = document.getElementById('map-container');
+        const svg = d3.select("#map-svg");
+        svg.selectAll("*").remove(); // Clear previous map elements
+
+        let width = mapContainer.clientWidth;
+        let height = mapContainer.clientHeight;
+        if (width <= 0 || height <= 0) {
+            console.warn("Map container has zero dimensions. Map rendering aborted.");
+            d3.select(mapContainer).html('<p class="text-muted text-center p-5">Map cannot be displayed (container not visible or has no size).</p>');
+            return;
+        }
+
+        const defs = svg.append("defs");
+        // Add Filters (same as before)
+        defs.html(`
+            <filter id="drop-shadow" x="-50%" y="-50%" width="200%" height="200%"> <feGaussianBlur in="SourceAlpha" stdDeviation="2" result="blur"/> <feOffset in="blur" dx="2" dy="2" result="offsetBlur"/> <feFlood flood-color="#333" flood-opacity="0.4" result="offsetColor"/> <feComposite in="offsetColor" in2="offsetBlur" operator="in" result="offsetBlurColored"/> <feMerge> <feMergeNode in="offsetBlurColored"/> <feMergeNode in="SourceGraphic"/> </feMerge> </filter>
+            <filter id="drop-shadow-selected" x="-50%" y="-50%" width="200%" height="200%"> <feGaussianBlur in="SourceAlpha" stdDeviation="3" result="blur"/> <feOffset in="blur" dx="3" dy="3" result="offsetBlur"/> <feFlood flood-color="#000" flood-opacity="0.5" result="offsetColor"/> <feComposite in="offsetColor" in2="offsetBlur" operator="in" result="offsetBlurColored"/> <feMerge> <feMergeNode in="offsetBlurColored"/> <feMergeNode in="SourceGraphic"/> </feMerge> </filter>
+        `);
+        const mainGroup = svg.append("g");
+        const tooltip = d3.select("#tooltip");
+
+        if (!data || data.length === 0) {
+            console.warn("No data available for map view.");
+            d3.select(mapContainer).html('<p class="text-muted text-center p-5">No data to display in map view.</p>');
+            return;
+        }
+
+        const categories = categoryOrder.filter(cat => data.some(d => d.category === cat));
+        const colorScale = d3.scaleOrdinal().domain(categories).range(categories.map(cat => categoryColors[cat] || '#ccc'));
+
+        // --- Size Scale based on Importance ---
+        // Importance 5 (most important) -> largest size (e.g., 25)
+        // Importance 1 (least important) -> smallest size (e.g., 8)
+        const sizeScale = d3.scaleSqrt()
+                            .domain([1, 5]) // Input: Importance score
+                            .range([8, 25]); // Output: Radius (small to large)
+
+
+        // Define Category Cluster Centers (logic moved to handleResize to be calculated dynamically)
+        // Calculate initial centers immediately if map is visible
+        if (mapContainer.clientWidth > 0 && mapContainer.clientHeight > 0) {
+            calculateClusterCenters(width, height, categories);
+        }
+
+
+        // Create Radial Gradients (same as before)
+        categories.forEach(category => {
+             const baseColor = d3.color(colorScale(category));
+             if (!baseColor) return;
+             const gradientId = `grad-${category.replace(/[\/\s]+/g, '-')}`;
+             const radialGradient = defs.append("radialGradient").attr("id", gradientId);
+             radialGradient.append("stop").attr("offset", "0%").attr("stop-color", baseColor.brighter(1.5));
+             radialGradient.append("stop").attr("offset", "100%").attr("stop-color", baseColor.darker(0.5));
+        });
+        // Add default gradient for potential 'Inactive' or uncategorized
+        const inactiveColor = categoryColors['Inactive'] || '#cccccc';
+        const inactiveGradientId = `grad-Inactive`;
+        if(!defs.select(`#${inactiveGradientId}`).node()){ // Add only if not already added
+             const inactiveRadialGradient = defs.append("radialGradient").attr("id", inactiveGradientId);
+             inactiveRadialGradient.append("stop").attr("offset", "0%").attr("stop-color", d3.color(inactiveColor).brighter(1));
+             inactiveRadialGradient.append("stop").attr("offset", "100%").attr("stop-color", d3.color(inactiveColor).darker(0.5));
+         }
+
+
+        // Force Simulation with Clustering
+        const simulation = d3.forceSimulation(data)
+            .force("charge", d3.forceManyBody().strength(-100)) // Adjusted strength
+             // Collision radius depends on size scale
+            .force("collide", d3.forceCollide().radius(d => sizeScale(d.importance) + 5).strength(0.7)) // Adjusted strength
+            .force("center", d3.forceCenter(width / 2, height / 2).strength(0.02)) // Low center strength
+            .force("x", d3.forceX(d => categoryCenters[d.category || 'Inactive']?.x ?? width / 2).strength(0.08)) // Cluster X
+            .force("y", d3.forceY(d => categoryCenters[d.category || 'Inactive']?.y ?? height / 2).strength(0.08)) // Cluster Y
+            .on("tick", ticked);
+
+
+        // Drawing Elements
+        let node = mainGroup.selectAll(".node")
+            .data(data, d => d.id)
+            .join("g")
+              .attr("class", "node")
+              .attr("cursor", "pointer")
+              .call(drag(simulation));
+
+        node.append("circle")
+            .attr("r", d => sizeScale(d.importance))
+            .attr("fill", d => `url(#grad-${(d.category || 'Inactive').replace(/[\/\s]+/g, '-')})`);
+
+        // Add Icon Text
+        node.append("text")
+            .attr("class", d => `node-icon ${d.icon || 'bi-question-circle'}`)
+            .attr("dy", "0.1em") // Small vertical adjustment for centering
+            // Icon size can optionally scale slightly with importance
+            .style("font-size", d => `${Math.max(10, 6 + (d.importance*1.5))}px`) // Example: 1->7.5px, 5->13.5px (adjust multiplier)
+            .text(d => {
+                 // Use the main category icon from the `icon` property added during data processing
+                 // Map icon class name to Unicode character using Bootstrap Icons cheatsheet/font
+                 switch(d.icon) {
+                    case 'bi-robot': return '\uf6ec';
+                    case 'bi-mortarboard-fill': return '\uf447';
+                    case 'bi-building-gear': return '\ue124';
+                    case 'bi-megaphone-fill': return '\uf49a';
+                    case 'bi-broadcast-pin': return '\ue120';
+                    case 'bi-cash-stack': return '\uf240';
+                    case 'bi-person-workspace': return '\uf4e2';
+                    case 'bi-diagram-3-fill': return '\uf305';
+                    case 'bi-graph-up-arrow': return '\ue3f0';
+                    case 'bi-slash-circle-fill': return '\uf582';
+                    case 'bi-question-circle': return '\uf518'; // Default icon
+                    default: return '\uf518'; // question-circle
+                }
+            });
+
+        // Add Label Text
+        node.append("text")
+            .attr("class", "node-label")
+            .text(d => d.name || "Unknown")
+             // Label offset uses the size scale
+            .attr("dy", d => sizeScale(d.importance) + 10) // Position below circle
+            .style("display", "none"); // Initially hidden, shown on zoom
+
+
+        // --- Interactivity (Click, Hover, Tooltip, Info Panel - same as before) ---
+        const infoPanel = d3.select("#info-panel");
+        const infoName = d3.select("#info-name");
+        const infoCategory = d3.select("#info-category");
+        const infoImportance = d3.select("#info-importance");
+        const infoDescription = d3.select("#info-description");
+        const infoLink = d3.select("#info-link");
+        const infoSafetyLinks = d3.select("#info-safety-links");
+
+        node.on("click", (event, d) => {
+            event.stopPropagation();
+            node.classed("selected", n => n && n.id === d.id); // Check n exists
+            showInfo(d);
+            tooltip.style("opacity", 0);
+        });
+        svg.on("click", () => {
+            node.classed("selected", false);
+            infoPanel.style("display", "none");
+            tooltip.style("opacity", 0);
+        });
+
+        node.on("mouseover", (event, d) => {
+            if (d3.select(event.currentTarget).classed("selected")) return;
+            tooltip.style("opacity", 1)
+                   .html(`
+                       <strong>${d.name || 'N/A'}</strong>
+                       <div class="tooltip-details">${d.category || 'N/A'} | Imp: ${d.importance || 'N/A'}</div>
+                       <div class="tooltip-desc">${d.description || 'No description.'}</div>
+                   `);
+        })
+        .on("mousemove", (event) => {
+             const [svgX, svgY] = d3.pointer(event, document.body);
+             const tipRect = tooltip.node().getBoundingClientRect();
+             let x = svgX + 15;
+             let y = svgY + 15;
+             // Keep tooltip within viewport bounds
+             const margin = 5; // Small margin from edge
+             if (x + tipRect.width > window.innerWidth - margin) x = svgX - tipRect.width - 15;
+             if (y + tipRect.height > window.innerHeight - margin) y = svgY - tipRect.height - 15;
+             if (x < margin) x = margin;
+             if (y < margin) y = margin;
+             tooltip.style("left", `${x}px`).style("top", `${y}px`);
+         })
+        .on("mouseout", () => {
+            tooltip.style("opacity", 0);
+        });
+
+        function showInfo(d) {
+            if (!d) return; // Safety check
+            infoName.text(d.name || "N/A");
+            infoCategory.text(d.category || "N/A");
+            infoImportance.html(`<span class="badge imp-${d.importance}">${d.importance || 'N/A'}</span>`);
+            infoDescription.text(d.description || "No description available.");
+            infoLink.attr("href", d.url).style("display", d.url ? "inline-block" : "none");
+            if (d.url) { infoLink.attr("href", d.url); }
+
+             infoSafetyLinks.html('');
+             if (d.safetyLinks && d.safetyLinks.length > 0) {
+                 infoSafetyLinks.append('h6').text('Safety Links:');
+                 d.safetyLinks.forEach(link => {
+                     infoSafetyLinks.append('a')
+                         .attr('href', link.url)
+                         .attr('target', '_blank')
+                         .attr('rel', 'noopener noreferrer')
+                         .attr('title', link.title || link.text)
+                         .html(`<i class="${link.icon || 'bi-link-45deg'}"></i> ${link.text}`);
+                 });
+             }
+            infoPanel.style("display", "block");
+        }
+
+        function ticked() {
+            node.attr("transform", d => {
+                 // Optional: Add boundary constraints if nodes escape view greatly
+                 const radius = sizeScale(d.importance);
+                 d.x = Math.max(radius + 10, Math.min(width - radius - 10, d.x)); // Add margin
+                 d.y = Math.max(radius + 10, Math.min(height - radius - 10, d.y)); // Add margin
+                 return `translate(${d.x},${d.y})`
+             });
+        }
+
+        // Drag behavior
+        function drag(simulation) {
+          function dragstarted(event, d) {
+            if (!event.active) simulation.alphaTarget(0.3).restart();
+            d.fx = d.x;
+            d.fy = d.y;
+            tooltip.style("opacity", 0);
+            d3.select(this).raise(); // Bring dragged node to front
+          }
+          function dragged(event, d) {
+            d.fx = event.x;
+            d.fy = event.y;
+          }
+          function dragended(event, d) {
+            if (!event.active) simulation.alphaTarget(0);
+            // Keep node fixed if it was selected, otherwise release
+             if (!d3.select(this).classed('selected')) {
+                 d.fx = null;
+                 d.fy = null;
+             }
+          }
+          return d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended);
+        }
+
+        // Zoom behavior
+        const zoom = d3.zoom()
+            .scaleExtent([0.15, 6]) // Adjusted zoom range
+            .on("zoom", (event) => {
+                mainGroup.attr("transform", event.transform);
+                tooltip.style("opacity", 0);
+                // Show labels only when zoomed in sufficiently
+                const k = event.transform.k;
+                node.selectAll(".node-label").style("display", k > 0.7 ? null : "none");
+            });
+        svg.call(zoom);
+        // Maybe set initial zoom slightly out? Optional.
+        // svg.call(zoom.transform, d3.zoomIdentity.translate(width * 0.1, height * 0.1).scale(0.8));
+
+
+        // --- Filtering & Legend (same as before) ---
+        const filterContainer = d3.select("#filter-controls");
+        filterContainer.html('');
+        categories.forEach(category => {
+             const filterId = `filter-${category.replace(/[\/\s]+/g, '-')}`;
+             filterContainer.append("div")
+                 .attr("class", "form-check")
+                 .html(`<input class="form-check-input category-filter" type="checkbox" value="${category}" id="${filterId}" checked>
+                        <label class="form-check-label" for="${filterId}">${category}</label>`);
+         });
+        d3.selectAll(".category-filter").on("change", updateFilters);
+
+        const legendContainer = d3.select("#legend");
+        legendContainer.html('');
+        categories.forEach(category => {
+             const iconClass = categoryIcons[category] || 'bi-question-circle';
+             // Get the Unicode character for the icon (using the same switch as for node icons)
+             let iconChar = '';
+             switch(iconClass) {
+                 case 'bi-robot': iconChar = '\uf6ec'; break;
+                 case 'bi-mortarboard-fill': iconChar = '\uf447'; break;
+                 case 'bi-building-gear': iconChar = '\ue124'; break;
+                 case 'bi-megaphone-fill': iconChar = '\uf49a'; break;
+                 case 'bi-broadcast-pin': iconChar = '\ue120'; break;
+                 case 'bi-cash-stack': iconChar = '\uf240'; break;
+                 case 'bi-person-workspace': iconChar = '\uf4e2'; break;
+                 case 'bi-diagram-3-fill': iconChar = '\uf305'; break;
+                 case 'bi-graph-up-arrow': iconChar = '\ue3f0'; break;
+                 case 'bi-slash-circle-fill': iconChar = '\uf582'; break;
+                 case 'bi-question-circle': iconChar = '\uf518'; break;
+                 default: iconChar = '\uf518';
+             }
+
+             legendContainer.append("div")
+                 .attr("class", "legend-item")
+                 // Use the iconChar inside the box
+                 .html(`<span class="legend-color-box" style="background-color: ${colorScale(category)};">
+                            <i style="font-family: 'bootstrap-icons'; font-style: normal; font-weight: normal; speak: none; display: inline-block; text-decoration: inherit; width: 1em; height: 1em; text-align: center; font-variant: normal; text-transform: none; line-height: 1em; vertical-align: -0.125em; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; font-size: 10px; color: rgba(0, 0, 0, 0.6); text-shadow: 0 0 1px rgba(255,255,255,0.5);">${iconChar}</i>
+                        </span>
+                        <span>${category}</span>`);
+        });
+
+        function updateFilters() {
+            const selectedCategories = new Set();
+            d3.selectAll(".category-filter:checked").each(function() {
+                selectedCategories.add(this.value);
+            });
+            node.style("display", d => selectedCategories.has(d.category) ? null : "none");
+
+            // Hide info panel if its node's category is deselected
+            if (infoPanel.style("display") === "block") {
+                const selectedNode = d3.select(".node.selected");
+                if (!selectedNode.empty()) {
+                    const selectedNodeData = selectedNode.datum();
+                     if (selectedNodeData && !selectedCategories.has(selectedNodeData.category)) {
+                        selectedNode.classed("selected", false); // Deselect node visually
+                        infoPanel.style("display", "none"); // Hide panel
+                    }
+                }
+            }
+            // Briefly reheat simulation if filters change to adjust layout slightly
+             if(simulation) simulation.alpha(0.1).restart();
+         }
+
+        // --- Resize Handling ---
+        let resizeTimer;
+        function handleResize() {
+            clearTimeout(resizeTimer);
+            resizeTimer = setTimeout(() => {
+                const currentWidth = mapContainer.clientWidth;
+                const currentHeight = mapContainer.clientHeight;
+                // Only resize if map is rendered and container has valid dimensions
+                if (currentWidth <= 0 || currentHeight <= 0 || !mapRendered) return;
+
+                width = currentWidth;
+                height = currentHeight;
+
+                // Recalculate cluster centers on resize
+                calculateClusterCenters(width, height, categories);
+
+                if (data && data.length > 0 && simulation) { // Check simulation exists
+                    svg.attr("width", width).attr("height", height);
+                    // Update forces that depend on width/height
+                    simulation.force("center", d3.forceCenter(width / 2, height / 2).strength(0.02));
+                    simulation.force("x").x(d => categoryCenters[d.category || 'Inactive']?.x ?? width / 2);
+                    simulation.force("y").y(d => categoryCenters[d.category || 'Inactive']?.y ?? height / 2);
+
+                    simulation.alpha(0.3).restart(); // Reheat simulation
+                }
+            }, 250);
+        }
+        window.addEventListener('resize', handleResize);
+        // Call handleResize once initially IF the map tab is active
+        // Moved this logic to DOMContentLoaded where dataLoaded is checked
+    }
+
+    // --- Helper Function for Cluster Centers ---
+    function calculateClusterCenters(w, h, cats) {
+         const numCategories = cats.filter(c => c !== 'Inactive').length; // Don't count inactive for positioning
+         // Simple circular arrangement - adjust as needed (grid, ellipse etc.)
+         const clusterRadiusX = Math.min(w, h) / 3.0; // Base radius on smaller dimension, adjust factor
+         const clusterRadiusY = clusterRadiusX; // Keep it circular for now
+         const angleStep = (2 * Math.PI) / Math.max(1, numCategories); // Avoid division by zero
+
+         categoryCenters = cats.reduce((acc, category, i) => {
+             if (category === 'Inactive') {
+                 acc[category] = { x: w / 2, y: h / 2 + clusterRadiusY * 1.2 }; // Position Inactive below center
+             } else {
+                 // Calculate index excluding 'Inactive' if it exists before current cat
+                 const activeIndex = cats.slice(0, i).filter(c => c !== 'Inactive').length;
+                 acc[category] = {
+                     x: w / 2 + clusterRadiusX * Math.cos(activeIndex * angleStep - Math.PI / 2), // Offset start angle (top)
+                     y: h / 2 + clusterRadiusY * Math.sin(activeIndex * angleStep - Math.PI / 2)
+                 };
+             }
+             return acc;
+         }, {});
+         // Ensure 'Inactive' always has a center defined, even if not in cats list initially
+         if (!categoryCenters['Inactive']) {
+             categoryCenters['Inactive'] = { x: w / 2, y: h / 2 + clusterRadiusY * 1.2 };
+         }
+     }
+
+
+    // --- Initial Load ---
+    document.addEventListener('DOMContentLoaded', () => {
+        let dataLoaded = false;
+        // Check if aiSafetyData was successfully created and has items
+        if (typeof aiSafetyData !== 'undefined' && aiSafetyData && aiSafetyData.length > 0) {
+             renderListView(aiSafetyData); // Render list view first
+             dataLoaded = true;
+        } else {
+             const listContainer = document.getElementById('list-view-content');
+             if (listContainer) {
+                 listContainer.innerHTML = ''; // Clear spinner
+                 if (typeof rawAiSafetyData === 'undefined') {
+                     listContainer.innerHTML = '<p class="text-danger text-center">Error: Could not load data from data.js.</p>';
+                 } else {
+                    listContainer.innerHTML = '<p class="text-muted text-center">No AI Safety data available.</p>';
+                 }
+             }
+             console.error("AI Safety Data is missing, empty, or could not be processed.");
+         }
+
+         const mapTabEl = document.getElementById('map-tab');
+         const mapPaneEl = document.getElementById('map-view-pane');
+
+         // Initial render if map tab is active *and* data loaded
+         if (mapTabEl && mapPaneEl && mapPaneEl.classList.contains('active') && dataLoaded && !mapRendered) {
+             // Need a slight delay for the tab pane dimensions to be calculated correctly sometimes
+             setTimeout(() => {
+                 renderMapView(aiSafetyData);
+                 window.dispatchEvent(new Event('resize')); // Trigger resize calc after render
+             }, 50);
+         }
+
+         // Add listener to render/resize map when its tab becomes visible
+         if (mapTabEl) {
+             mapTabEl.addEventListener('shown.bs.tab', function (event) {
+                 // Render map if data is loaded but map hasn't been rendered yet
+                 if(dataLoaded && !mapRendered) {
+                      // Delay needed here too for dimensions
+                      setTimeout(() => {
+                         renderMapView(aiSafetyData);
+                         window.dispatchEvent(new Event('resize')); // Trigger resize after initial render on tab show
+                      }, 50);
+                 } else if (mapRendered) {
+                     // If already rendered, just ensure layout/centers/zoom are correct
+                     window.dispatchEvent(new Event('resize'));
+                 }
+             });
+         }
+
+         // Add smooth scrolling for category nav links
+         document.querySelectorAll('#category-nav a').forEach(anchor => {
+            anchor.addEventListener('click', function (e) {
+                e.preventDefault();
+                const targetId = this.getAttribute('href').substring(1); // Get ID without '#'
+                const targetElement = document.getElementById(targetId);
+                if (targetElement) {
+                    // Get the list pane element for scrolling
+                    const listPane = document.getElementById('list-view-pane');
+                    if (listPane) {
+                        // Calculate position relative to the scrollable container
+                        const offsetTop = targetElement.offsetTop - listPane.offsetTop;
+                        // Add a small top margin/padding adjustment if needed (e.g., 10px)
+                        const scrollPadding = 10;
+                        listPane.scrollTo({
+                            top: offsetTop - scrollPadding,
+                            behavior: 'smooth'
+                        });
+                    }
+                }
+            });
+        });
+     });
+
+    </script>
+
+<script defer src="https://static.cloudflareinsights.com/beacon.min.js/vcd15cbe7772f49c399c6a5babf22c1241717689176015" integrity="sha512-ZpsOmlRQV6y907TI0dKBHq9Md29nnaEIPlkf84rnaERnq6zvWvPUqr2ft8M1aS28oN72PdrCzSjY4U6VaAw1EQ==" data-cf-beacon='{"rayId":"933f9b2ffe3fe66a","version":"2025.4.0-1-g37f21b1","r":1,"token":"6e6964b5878c4e3b9fe32392cd40f886","serverTiming":{"name":{"cfExtPri":true,"cfL4":true,"cfSpeedBrain":true,"cfCacheStatus":true}}}' crossorigin="anonymous"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/safety_data.js b/safety_data.js
new file mode 100644
index 0000000..824bf97
--- /dev/null
+++ b/safety_data.js
@@ -0,0 +1,236 @@
+// --- START OF FILE data.js ---
+
+// --- Central Data Source ---
+// This array holds the raw data for the AI Safety ecosystem entries.
+// The main script in index.html will process this array (e.g., adding icons).
+const rawAiSafetyData = [
+  // AI Labs
+  { id: "openai", name: "OpenAI", url: "https://openai.com/", category: "AI Lab", importance: 5, description: "San Francisco-based capabilities lab, creator of ChatGPT. Historically significant safety team, though experienced departures in 2024.", logoUrl: "https://openai.com/icon.svg?d5c238c2cf2e4f08", subCategoryIcon: "bi-building", subCategoryText: "AI Lab (Capabilities & Safety Research)", safetyLinks: [{ text: "Safety Overview", url: "https://openai.com/safety", icon: "bi-shield-check", title:"OpenAI's official safety policies" }, { text: "Research", url: "https://openai.com/research", icon: "bi-journal-richtext", title:"OpenAI's research publications" }] },
+  { id: "deepmind", name: "Google DeepMind", url: "https://www.deepmind.com/", category: "AI Lab", importance: 5, description: "Major London-based AI capabilities lab (Google-owned) with a strong, long-standing safety research team. Created AlphaGo, AlphaFold, Gemini.", logoUrl: "https://www.gstatic.com/images/branding/productlogos/google_deepmind/v3/web-96dp/logo_google_deepmind_color_2x_web_96dp.png", subCategoryIcon: "bi-building", subCategoryText: "AI Lab (Capabilities & Safety Research)", safetyLinks: [{ text: "Responsibility & Safety", url: "https://deepmind.google/discover/responsibility-safety/", icon: "bi-shield-check", title:"DeepMind's approach to responsibility" }, { text: "Blog (incl. Safety)", url: "https://deepmind.google/discover/blog/", icon: "bi-journal-text", title:"DeepMind's blog for updates" }] },
+  { id: "anthropic", name: "Anthropic", url: "https://www.anthropic.com/", category: "AI Lab", importance: 5, description: "Research lab focusing heavily on LLM alignment and safety, particularly interpretability. Created Claude. Known for its safety-first mission.", logoUrl: "https://static.cdnlogo.com/logos/a/68/anthropic.svg", subCategoryIcon: "bi-shield-shaded", subCategoryText: "AI Lab (Safety-Focused)", safetyLinks: [{ text: "Safety Research", url: "https://www.anthropic.com/research", icon: "bi-journal-richtext", title:"Anthropic's safety research papers" }, { text: "Constitutional AI", url: "https://www.anthropic.com/constitutional-ai", icon: "bi-rulers", title:"Anthropic's Constitutional AI method" }] },
+  { id: "xai", name: "xAI", url: "https://x.ai/", category: "AI Lab", importance: 3, description: "Capabilities lab led by Elon Musk aiming to \"understand the universe.\" Created Grok. Safety stance less defined than others.", logoUrl: "https://logowik.com/content/uploads/images/xai905.logowik.com.webp", subCategoryIcon: "bi-building", subCategoryText: "AI Lab (Capabilities Research)", safetyLinks: [{ text: "About/Mission", url: "https://x.ai/about", icon: "bi-info-circle", title:"Learn about xAI's mission" }] },
+  { id: "ssi", name: "Safe Superintelligence Inc. (SSI)", url: "https://ssi.inc/", category: "AI Lab", importance: 3, description: "Research lab founded by Ilya Sutskever focused explicitly on building safe superintelligence. Newer, impact TBD.", logoUrl: null, subCategoryIcon: "bi-shield-lock-fill", subCategoryText: "AI Lab (Safety-Focused)", safetyLinks: [{ text: "Mission", url: "https://ssi.inc/", icon: "bi-bullseye", title:"SSI's mission statement" }] },
+  { id: "deepseek", name: "DeepSeek", url: "https://www.deepseek.com/", category: "AI Lab", importance: 2, description: "Chinese capabilities lab developing and releasing open-weights LLMs (e.g., DeepSeek-R1). Important international player.", logoUrl: "https://logowik.com/content/uploads/images/deepseek-ai4760.logowik.com.webp", subCategoryIcon: "bi-building", subCategoryText: "AI Lab (Capabilities Research, China)", safetyLinks: [{ text: "GitHub/Models", url: "https://github.com/deepseek-ai", icon: "bi-github", title:"DeepSeek's models on GitHub" }] },
+  { id: "obelisk", name: "Obelisk (at Astera)", url: "https://astera.org/agi-program/", category: "AI Lab", importance: 2, description: "Research team aiming to engineer AGI using an exploratory approach inspired by cognitive science/neuroscience.", logoUrl: "https://static.cdnlogo.com/logos/a/29/astera.svg", subCategoryIcon: "bi-clipboard-data", subCategoryText: "Research Team (AGI Engineering)", safetyLinks: [{ text: "AGI Program Details", url: "https://astera.org/agi-program/", icon: "bi-journal-richtext", title:"Astera's Obelisk AGI program details" }] },
+
+  // Academic/Research
+  { id: "arc", name: "Alignment Research Center (ARC)", url: "https://www.alignment.org/theory/", category: "Academic/Research", importance: 4, description: "Influential research organization trying to formalize mechanistic explanations of neural network behavior (e.g., ELK).", subCategoryIcon: "bi-diagram-3", subCategoryText: "Research Center (Conceptual)" },
+  { id: "chai", name: "Center for Human-Compatible AI (CHAI)", url: "https://humancompatible.ai/", category: "Academic/Research", importance: 4, description: "UC Berkeley group led by Stuart Russell, developing theory (CIRL) and techniques for provably beneficial AI.", subCategoryIcon: "bi-bank", subCategoryText: "University Center (Conceptual/Technical)" },
+  { id: "cais", name: "Center for AI Safety (CAIS)", url: "https://safe.ai/", category: "Academic/Research", importance: 4, description: "San Francisco nonprofit conducting safety research, field building, and advocating for safety standards.", subCategoryIcon: "bi-search-heart", subCategoryText: "Research & Advocacy Nonprofit" },
+  { id: "redwood", name: "Redwood Research", url: "https://www.redwoodresearch.org/", category: "Academic/Research", importance: 4, description: "Nonprofit researching interpretability and alignment, also consults governments and AI labs on safety practices.", subCategoryIcon: "bi-lightbulb", subCategoryText: "Research Nonprofit (Empirical)" },
+  { id: "eleutherai", name: "EleutherAI", url: "https://www.eleuther.ai/", category: "Academic/Research", importance: 3, description: "Open-source research lab focused on interpretability and alignment, operating primarily via Discord.", subCategoryIcon: "bi-code-slash", subCategoryText: "Open Source Research Lab" },
+  { id: "metr", name: "Model Evaluation & Threat Research (METR)", url: "https://metr.org/", category: "Academic/Research", importance: 3, description: "Researches, develops, and runs cutting-edge tests of AI capabilities and risks (formerly ARC Evals).", subCategoryIcon: "bi-clipboard-check", subCategoryText: "Evaluation Research Org" },
+  { id: "apollo", name: "Apollo Research", url: "https://www.apolloresearch.ai/", category: "Academic/Research", importance: 3, description: "Aims to detect deception via model evaluations and interpretability research; provides policy guidance.", subCategoryIcon: "bi-clipboard-data", subCategoryText: "Research & Policy Advice" },
+  { id: "conjecture", name: "Conjecture", url: "https://www.conjecture.dev/", category: "Academic/Research", importance: 3, description: "Alignment startup using a “Cognitive Emulation” approach for controllable LLMs and safety challenges.", subCategoryIcon: "bi-shield-check", subCategoryText: "AI Startup (Safety Focused)" },
+  { id: "farai", name: "Frontier Alignment Research (FAR.AI)", url: "https://far.ai/", category: "Academic/Research", importance: 3, description: "Incubates and accelerates research agendas for trustworthy and beneficial AI.", subCategoryIcon: "bi-box-seam", subCategoryText: "Research Incubator" },
+  { id: "ought", name: "Ought", url: "https://ought.org/", category: "Academic/Research", importance: 3, description: "Product-driven lab developing mechanisms for delegating reasoning to ML systems (built Elicit).", subCategoryIcon: "bi-wrench-adjustable-circle", subCategoryText: "Product/Research Lab" },
+  { id: "acs", name: "Alignment of Complex Systems Research Group (ACS)", url: "https://acsresearch.org/", category: "Academic/Research", importance: 2, description: "Studies multi-agent systems (humans and AI). Based at Charles University, Prague.", subCategoryIcon: "bi-bank", subCategoryText: "University Research Group" },
+  { id: "atlas", name: "Atlas Computing", url: "https://atlascomputing.org/", category: "Academic/Research", importance: 2, description: "Prototyping AI tools for formal specification generation to improve code verification.", subCategoryIcon: "bi-gear-wide-connected", subCategoryText: "R&D Nonprofit" },
+  { id: "alignedai", name: "Aligned AI", url: "https://buildaligned.ai/", category: "Academic/Research", importance: 2, description: "Oxford-based startup using mathematical techniques for safe off-distribution generalization.", subCategoryIcon: "bi-shield-check", subCategoryText: "AI Startup (Safety Focused)" },
+  { id: "cyborgism", name: "Cyborgism (Concept)", url: "https://www.lesswrong.com/posts/bxt7uCiHam4QXrQAA/cyborgism", category: "Academic/Research", importance: 2, description: "Strategy exploring human-in-the-loop systems to accelerate alignment research.", subCategoryIcon: "bi-signpost-split", subCategoryText: "Research Strategy" },
+  { id: "yampolskiy", name: "Dr. Roman V. Yampolskiy", url: "http://cecs.louisville.edu/ry/", category: "Academic/Research", importance: 2, description: "Professor researching AI safety, cybersecurity background, numerous publications.", subCategoryIcon: "bi-person", subCategoryText: "Academic Researcher" },
+  { id: "hadfieldmenell", name: "Dylan Hadfield-Menell", url: "https://people.csail.mit.edu/dhm/", category: "Academic/Research", importance: 2, description: "Assistant professor at MIT working on agent alignment. Runs the Algorithmic Alignment Group.", subCategoryIcon: "bi-person", subCategoryText: "Academic Researcher (MIT)" },
+  { id: "grayswan", name: "Gray Swan", url: "https://www.grayswan.ai/", category: "Academic/Research", importance: 2, description: "For-profit developing tools to assess AI model risks and building its own safety-focused models.", subCategoryIcon: "bi-shield-check", subCategoryText: "AI Startup (Safety Tools)" },
+  { id: "wentworth", name: "John Wentworth", url: "https://www.lesswrong.com/posts/gQY6LrTWJNkTv8YJR/the-pointers-problem-human-values-are-a-function-of-humans", category: "Academic/Research", importance: 2, description: "Independent alignment researcher working on selection theorems, abstraction, and agency.", subCategoryIcon: "bi-person", subCategoryText: "Independent Researcher" },
+  { id: "kasl", name: "Krueger AI Safety Lab (KASL)", url: "https://www.kasl.ai/publications/", category: "Academic/Research", importance: 2, description: "AI safety research group at the University of Cambridge, led by David Krueger.", subCategoryIcon: "bi-bank", subCategoryText: "University Research Lab (Cambridge)" },
+  { id: "mai", name: "Meaning Alignment Institute (MAI)", url: "https://meaningalignment.org/", category: "Academic/Research", importance: 2, description: "Applies expertise in meaning and human values to AI alignment and post-AGI futures.", subCategoryIcon: "bi-palette", subCategoryText: "Research Organization (Human Values)" },
+  { id: "mitaag", name: "MIT Algorithmic Alignment Group", url: "https://algorithmicalignment.csail.mit.edu/", category: "Academic/Research", importance: 2, description: "Working towards better conceptual understanding, algorithmic techniques, and policies for safer AI.", subCategoryIcon: "bi-bank", subCategoryText: "University Research Group (MIT)" },
+  { id: "modelingcoop", name: "Modeling Cooperation", url: "https://www.modelingcooperation.com/", category: "Academic/Research", importance: 2, description: "Conducting research on improving cooperation in competition for transformative AI development.", subCategoryIcon: "bi-diagram-3", subCategoryText: "Research Focus (Cooperation)" },
+  { id: "nyuarg", name: "NYU Alignment Research Group (ARG)", url: "https://wp.nyu.edu/arg/", category: "Academic/Research", importance: 2, description: "Conducts empirical work with language models aiming to address longer-term AI impacts.", subCategoryIcon: "bi-bank", subCategoryText: "University Research Group (NYU)" },
+  { id: "orthogonal", name: "Orthogonal", url: "https://orxl.org", category: "Academic/Research", importance: 2, description: "Formal alignment organization focused on agent foundations. Has a public Discord.", subCategoryIcon: "bi-bounding-box-circles", subCategoryText: "Research Organization (Agent Foundations)" },
+  { id: "softmax", name: "Softmax", url: "https://www.softmax.com/", category: "Academic/Research", importance: 2, description: "Develops a theory of \"organic alignment\" for human-digital agent cooperation.", subCategoryIcon: "bi-recycle", subCategoryText: "Research Organization (Organic Alignment)" },
+  { id: "byrnes", name: "Steve Byrnes's Brain-Like AGI Safety", url: "https://www.alignmentforum.org/s/HzcM2dkCq7fwXBej8", category: "Academic/Research", importance: 2, description: "Brain-inspired framework using neuroscience/RL insights for aligned AGI design.", subCategoryIcon: "bi-brain", subCategoryText: "Research Framework" },
+  { id: "shardtheory", name: "Team Shard (Shard Theory)", url: "https://www.lesswrong.com/posts/xqkGmfikqapbJ2YMj/shard-theory-an-overview", category: "Academic/Research", importance: 2, description: "Small team trying to find reward functions which reliably instill values (Shard Theory).", subCategoryIcon: "bi-gem", subCategoryText: "Research Team/Theory" },
+  { id: "timaeus", name: "Timaeus", url: "https://timaeus.co/", category: "Academic/Research", importance: 2, description: "Uses singular learning theory to understand how training data determines model behavior.", subCategoryIcon: "bi-infinity", subCategoryText: "Research Nonprofit (Singular Learning Theory)" },
+  { id: "transluce", name: "Transluce", url: "https://transluce.org/", category: "Academic/Research", importance: 2, description: "Builds open source, scalable tools to understand, analyze, and steer AI systems.", subCategoryIcon: "bi-code-square", subCategoryText: "Research Lab (Open Source Tools)" },
+  { id: "camcbl", name: "University of Cambridge Comp. & Bio. Learning Lab (CBL)", url: "https://cbl.eng.cam.ac.uk/", category: "Academic/Research", importance: 2, description: "Uses engineering approaches to understand the brain and develop AI learning systems.", subCategoryIcon: "bi-bank", subCategoryText: "University Research Lab (Cambridge)" },
+  { id: "aoi", name: "AI Objectives Institute (AOI)", url: "https://ai.objectives.institute/", category: "Academic/Research", importance: 2, description: "Builds AI tools to defend/enhance human agency via novel AI capabilities research.", subCategoryIcon: "bi-person-check", subCategoryText: "Research Nonprofit (Human Agency)" },
+  { id: "equistamp", name: "EquiStamp", url: "https://www.equistamp.com/", category: "Academic/Research", importance: 1, description: "Platform for evaluating AI model capabilities to assess trustworthiness.", subCategoryIcon: "bi-pc-display-horizontal", subCategoryText: "Platform/Startup" },
+  { id: "cavendish", name: "Cavendish Labs", url: "https://cavendishlabs.org/", category: "Academic/Research", importance: 1, description: "AI safety (and pandemic prevention) research community based in Vermont, USA.", subCategoryIcon: "bi-people-fill", subCategoryText: "Research Community" },
+
+   // Policy/Gov
+   { id: "govai", name: "Centre for the Governance of AI (GovAI)", url: "https://www.governance.ai/", category: "Policy/Gov", importance: 4, description: "Highly influential AI governance research group, producing policy research and running career programs.", subCategoryIcon: "bi-bank", subCategoryText: "University Research Group (Oxford)" },
+   { id: "cset", name: "Center for Security and Emerging Technology (CSET)", url: "https://cset.georgetown.edu/", category: "Policy/Gov", importance: 4, description: "Georgetown University think tank providing data-driven analysis on security implications of emerging tech.", subCategoryIcon: "bi-building-columns", subCategoryText: "University Think Tank (Georgetown)" },
+   { id: "ukaisi", name: "UK AI Safety Institute (UK AISI)", url: "https://www.aisi.gov.uk/", category: "Policy/Gov", importance: 4, description: "UK government organisation researching, testing safety, measuring impacts, and shaping global policy.", subCategoryIcon: "bi-flag-fill", subCategoryText: "Government Institute (UK)" },
+   { id: "usaisi", name: "U.S. AI Safety Institute (USAISI)", url: "https://www.nist.gov/artificial-intelligence/artificial-intelligence-safety-institute", category: "Policy/Gov", importance: 4, description: "US government organization (NIST) advancing AI safety science, practice, and adoption.", subCategoryIcon: "bi-flag-fill", subCategoryText: "Government Institute (US)" },
+   { id: "fli", name: "Future of Life Institute (FLI)", url: "https://futureoflife.org/", category: "Policy/Gov", importance: 4, description: "Works on steering transformative tech via outreach, policy advocacy, grantmaking, and event organisation.", subCategoryIcon: "bi-megaphone", subCategoryText: "Advocacy, Policy, Funding" }, // Primarily policy/advocacy focus here
+   { id: "miri", name: "Machine Intelligence Research Institute (MIRI)", url: "https://intelligence.org/", category: "Policy/Gov", importance: 4, description: "Original AI safety research org (Yudkowsky), now more focused on policy and public outreach. Foundational concepts.", subCategoryIcon: "bi-search-heart", subCategoryText: "Research, Policy, Advocacy" }, // Primarily policy/advocacy focus here
+   { id: "clr", name: "Center on Long-Term Risk (CLR)", url: "https://longtermrisk.org/", category: "Policy/Gov", importance: 3, description: "Focuses on AI safety research, grants, and community, particularly around conflict scenarios and cooperation.", subCategoryIcon: "bi-shield-exclamation", subCategoryText: "Research, Funding, Community (X-Risk Focus)" },
+   { id: "pai", name: "Partnership on AI (PAI)", url: "https://partnershiponai.org/", category: "Policy/Gov", importance: 3, description: "Convenes academic, civil society, industry, and media organizations to create solutions for beneficial AI.", subCategoryIcon: "bi-people-fill", subCategoryText: "Multi-stakeholder Org" },
+   { id: "cser", name: "Centre for the Study of Existential Risk (CSER)", url: "https://www.cser.ac.uk/", category: "Policy/Gov", importance: 3, description: "Cambridge interdisciplinary centre dedicated to the study and mitigation of existential risks, including AI.", subCategoryIcon: "bi-bank", subCategoryText: "University Center (Cambridge)" },
+   { id: "epochai", name: "Epoch AI", url: "https://epochai.org/", category: "Policy/Gov", importance: 3, description: "Research institute investigating key trends and questions shaping the trajectory and governance of AI.", subCategoryIcon: "bi-graph-up", subCategoryText: "Research Institute (Trends & Governance)" }, // Could also be Forecasting
+   { id: "caip", name: "Center for AI Policy (CAIP)", url: "http://aipolicy.us/", category: "Policy/Gov", importance: 3, description: "Nonpartisan research organization developing policy and conducting advocacy to mitigate catastrophic AI risks.", subCategoryIcon: "bi-megaphone-fill", subCategoryText: "Policy & Advocacy Org" },
+   { id: "iaps", name: "Institute for AI Policy and Strategy (IAPS)", url: "https://www.iaps.ai/", category: "Policy/Gov", importance: 3, description: "Focuses on policy/standards, compute governance, international governance/China.", subCategoryIcon: "bi-collection", subCategoryText: "Policy Research & Field Building" },
+   { id: "rethink", name: "Rethink Priorities", url: "https://rethinkpriorities.org/", category: "Policy/Gov", importance: 3, description: "Researches solutions and strategies to safeguard a flourishing present and future.", subCategoryIcon: "bi-compass", subCategoryText: "Research Nonprofit (Strategy)" }, // Strategy focus
+   { id: "aestudio", name: "AE Studio", url: "https://ae.studio/ai-alignment", category: "Policy/Gov", importance: 2, description: "Takes a 'Neglected Approaches' view on alignment, tackling multiple angles (technical & policy).", subCategoryIcon: "bi-person-video3", subCategoryText: "Consultancy/Research" },
+   { id: "aigscanada", name: "AI Governance & Safety Canada (AIGS Canada)", url: "https://aigs.ca/", category: "Policy/Gov", importance: 2, description: "Nonpartisan nonprofit working to ensure safe and beneficial AI in Canada.", subCategoryIcon: "bi-flag", subCategoryText: "National Nonprofit (Canada)" },
+   { id: "aipi", name: "AI Policy Institute (AIPI)", url: "https://theaipi.org/", category: "Policy/Gov", importance: 2, description: "Engages policymakers/media/public for responsible AI regulation.", subCategoryIcon: "bi-building-columns", subCategoryText: "Policy Institute" },
+   { id: "alter", name: "Association for Long Term Existence and Resilience (ALTER)", url: "https://alter.org.il/", category: "Policy/Gov", importance: 2, description: "Israeli nonprofit working to safeguard and improve humanity's future.", subCategoryIcon: "bi-flag", subCategoryText: "Research & Advocacy (Israel)" },
+   { id: "beijingaisi", name: "Beijing Institute of AI Safety and Governance (Beijing-AISI)", url: "https://beijing.ai-safety-and-governance.institute/", category: "Policy/Gov", importance: 2, description: "Develops AI safety/governance frameworks in China.", subCategoryIcon: "bi-gear-wide-connected", subCategoryText: "R&D Institute (China)" },
+   { id: "carma", name: "Center for AI Risk Management & Alignment (CARMA)", url: "https://carma.org/", category: "Policy/Gov", importance: 2, description: "Interdisciplinary research supporting global AI risk management, policy, technical work.", subCategoryIcon: "bi-intersect", subCategoryText: "Interdisciplinary Research" },
+   { id: "cltc", name: "Center for Long-Term Cybersecurity (CLTC)", url: "https://cltc.berkeley.edu/", category: "Policy/Gov", importance: 2, description: "UC Berkeley center bridging research/policy on emerging cybersecurity challenges relevant to AI.", subCategoryIcon: "bi-bank", subCategoryText: "University Center (Cybersecurity)" },
+   { id: "cltr", name: "Center for Long-Term Resilience (CLTR)", url: "https://www.longtermresilience.org/", category: "Policy/Gov", importance: 2, description: "Think tank aiming to transform global resilience to extreme risks via governance/decision-making.", subCategoryIcon: "bi-building-columns", subCategoryText: "Think Tank (Resilience)" },
+   { id: "clai", name: "Center for Long-term AI (CLAI)", url: "https://long-term-ai.center/", category: "Policy/Gov", importance: 2, description: "China-based interdisciplinary organization exploring AI's long-term societal/ecological impacts.", subCategoryIcon: "bi-tree", subCategoryText: "Research Org (China, Societal/Ecological Focus)" },
+   { id: "cfg", name: "Centre for Future Generations (CFG)", url: "https://cfg.eu/", category: "Policy/Gov", importance: 2, description: "Brussels think tank helping governments anticipate/govern impacts of technological change.", subCategoryIcon: "bi-building-columns", subCategoryText: "Think Tank (EU)" },
+   { id: "controlai", name: "ControlAI", url: "https://controlai.com/", category: "Policy/Gov", importance: 2, description: "Nonprofit developing policy and conducting public outreach to keep humanity in control of AI.", subCategoryIcon: "bi-megaphone-fill", subCategoryText: "Policy & Advocacy" },
+   { id: "eip", name: "Effective Institutions Project", url: "https://effectiveinstitutionsproject.org/", category: "Policy/Gov", importance: 2, description: "Focuses on improving institutional decision-making on critical global challenges.", subCategoryIcon: "bi-diagram-2", subCategoryText: "Advisory & Research (Institutions)" },
+   { id: "euaioffice", name: "European AI Office", url: "https://digital-strategy.ec.europa.eu/en/policies/ai-office", category: "Policy/Gov", importance: 2, description: "EU Commission's center for AI expertise, key in implementing the AI Act.", subCategoryIcon: "bi-flag-fill", subCategoryText: "Government Body (EU)" },
+   { id: "forethought", name: "Forethought Research", url: "https://www.forethought.org/", category: "Policy/Gov", importance: 2, description: "Small research nonprofit focused on navigating the transition to superintelligence.", subCategoryIcon: "bi-compass", subCategoryText: "Research Nonprofit (Strategy)" },
+   { id: "formation", name: "Formation Research", url: "https://formationresearch.com/", category: "Policy/Gov", importance: 2, description: "Researches fundamental lock-in dynamics and power concentration risks.", subCategoryIcon: "bi-lock", subCategoryText: "Research Nonprofit (Lock-in Risk)" },
+   { id: "fairargentina", name: "Frontier AI Research (FAIR)", url: "https://frontierartificialinteligenceresearch.com/", category: "Policy/Gov", importance: 2, description: "Argentine nonprofit working on frontier AI safety as a sociotechnical challenge.", subCategoryIcon: "bi-flag", subCategoryText: "Research Nonprofit (Argentina)" },
+   { id: "gcri", name: "Global Catastrophic Risk Institute (GCRI)", url: "https://gcrinstitute.org/", category: "Policy/Gov", importance: 2, description: "Small think tank developing solutions for reducing existential risk.", subCategoryIcon: "bi-building-columns", subCategoryText: "Think Tank (X-Risk)" },
+   { id: "gpai", name: "Global Partnership on AI (GPAI)", url: "https://www.oecd.org/en/about/programmes/global-partnership-on-artificial-intelligence.html", category: "Policy/Gov", importance: 2, description: "International initiative working to implement OECD AI principles for safe AI.", subCategoryIcon: "bi-globe2", subCategoryText: "International Initiative" },
+   { id: "gpi", name: "Global Priorities Institute (GPI)", url: "https://globalprioritiesinstitute.org/", category: "Policy/Gov", importance: 2, description: "Conducts foundational research to inform effective altruism/longtermist decision-making.", subCategoryIcon: "bi-bank", subCategoryText: "University Center (Oxford, Longtermism)" },
+   { id: "lawai", name: "Institute for Law & AI (LawAI)", url: "https://law-ai.org/", category: "Policy/Gov", importance: 2, description: "Think tank researching and advising on the legal challenges posed by AI.", subCategoryIcon: "bi-gavel", subCategoryText: "Legal Think Tank" },
+   { id: "iaiga", name: "International AI Governance Alliance (IAIGA)", url: "https://www.iaiga.org/", category: "Policy/Gov", importance: 2, description: "Aims to establish a global body for mitigating AI extinction risks and distributing benefits.", subCategoryIcon: "bi-globe2", subCategoryText: "Advocacy/Nonprofit" },
+   { id: "iaseai", name: "International Association for Safe & Ethical AI (IASEAI)", url: "https://www.iaseai.org/", category: "Policy/Gov", importance: 2, description: "Aims to ensure safe/ethical AI via policy, research, community building.", subCategoryIcon: "bi-shield-check", subCategoryText: "Nonprofit/Standards" },
+   { id: "lcfi", name: "Leverhulme Centre for the Future of Intelligence (CFI)", url: "http://lcfi.ac.uk/", category: "Policy/Gov", importance: 2, description: "Interdisciplinary research centre exploring the nature, ethics, and impact of AI.", subCategoryIcon: "bi-bank", subCategoryText: "University Center (Cambridge)" },
+   { id: "median", name: "Median Group", url: "http://mediangroup.org/", category: "Policy/Gov", importance: 2, description: "Models progress in AI, intelligence enhancement, sociology related to x-risks.", subCategoryIcon: "bi-calculator", subCategoryText: "Research Nonprofit (Modeling)" },
+   { id: "narrowpath", name: "Narrow Path (Proposal)", url: "https://www.narrowpath.co/", category: "Policy/Gov", importance: 2, description: "Series of policy proposals from ControlAI for surviving superintelligence.", subCategoryIcon: "bi-signpost-split", subCategoryText: "Policy Proposal" },
+   { id: "saferai", name: "SaferAI", url: "http://safer-ai.org/", category: "Policy/Gov", importance: 2, description: "French nonprofit working on policy recommendations, research, risk assessment tools.", subCategoryIcon: "bi-flag", subCategoryText: "National Nonprofit (France)" },
+   { id: "simoninst", name: "Simon Institute for Longterm Governance", url: "https://www.simoninstitute.ch/", category: "Policy/Gov", importance: 2, description: "Geneva think tank fostering international cooperation on mitigating catastrophic AI risks.", subCategoryIcon: "bi-building-columns", subCategoryText: "Think Tank (Geneva)" },
+   { id: "tfs", name: "The Future Society (TFS)", url: "https://thefuturesociety.org/", category: "Policy/Gov", importance: 2, description: "Aims to define, design, deploy projects addressing institutional barriers in AI governance.", subCategoryIcon: "bi-diagram-2", subCategoryText: "Nonprofit (US/EU, Governance Barriers)" },
+   { id: "vistainst", name: "Vista Institute for AI Policy", url: "https://vistainstituteai.org/", category: "Policy/Gov", importance: 2, description: "Promotes informed policymaking via research, knowledge-sharing, skill building.", subCategoryIcon: "bi-building-columns", subCategoryText: "Policy Institute" },
+   { id: "ailabwatch", name: "AI Lab Watch", url: "https://ailabwatch.org/", category: "Policy/Gov", importance: 2, description: "Collects actions for labs to avert risks and evaluates labs accordingly.", subCategoryIcon: "bi-binoculars", subCategoryText: "Lab Monitoring" },
+   { id: "aiplans", name: "AI-Plans", url: "https://ai-plans.com/", category: "Policy/Gov", importance: 2, description: "Ranked compendium of alignment plans and problems; runs hackathons.", subCategoryIcon: "bi-kanban", subCategoryText: "Strategy Platform" },
+   //{ id: "thecompendium", name: "The Compendium", url: "https://www.thecompendium.ai/", category: "Policy/Gov", importance: 2, description: "Living document explaining AGI race/risks for non-technical readers.", subCategoryIcon: "bi-journal-text", subCategoryText: "Living Document" }, // Moved to Info/Media
+
+   // Advocacy
+   { id: "pauseai", name: "PauseAI", url: "https://pauseai.info", category: "Advocacy", importance: 3, description: "Campaign group aiming to convince governments to pause AI development via outreach, lobbying, protests.", subCategoryIcon: "bi-sign-stop-fill", subCategoryText: "Campaign Group" },
+   { id: "caes", name: "Collective Action for Existential Safety (CAES)", url: "https://existentialsafety.org/", category: "Advocacy", importance: 2, description: "Nonprofit catalyzing collective effort towards reducing x-risk, provides action lists.", subCategoryIcon: "bi-megaphone", subCategoryText: "Nonprofit/Advocacy" },
+   { id: "ero", name: "Existential Risk Observatory (ERO)", url: "https://www.existentialriskobservatory.org/", category: "Advocacy", importance: 2, description: "Informing the public debate on existential risks to encourage risk reduction.", subCategoryIcon: "bi-binoculars-fill", subCategoryText: "Public Awareness" },
+   { id: "gaim", name: "Global AI Moratorium (GAIM)", url: "https://moratorium.ai", category: "Advocacy", importance: 2, description: "Calling on policymakers to implement a global moratorium on large AI training runs.", subCategoryIcon: "bi-sign-stop-fill", subCategoryText: "Campaign Group" },
+   { id: "tmp", name: "The Midas Project (TMP)", url: "https://www.themidasproject.com/", category: "Advocacy", importance: 2, description: "Monitors tech companies, counters propaganda, advocates for responsible AI development.", subCategoryIcon: "bi-eye-fill", subCategoryText: "Watchdog Nonprofit" },
+   { id: "aisaf", name: "AI Safety Awareness Foundation (AISAF)", url: "https://aisafetyawarenessfoundation.org/", category: "Advocacy", importance: 1, description: "Volunteer group raising public awareness of AI benefits/risks through workshops.", subCategoryIcon: "bi-person-hearts", subCategoryText: "Volunteer Group" },
+   { id: "aigsi", name: "AI Governance and Safety Institute (AIGSI)", url: "https://aigsi.org/", category: "Advocacy", importance: 1, description: "Conducts research/outreach, develops educational materials to improve institutional response.", subCategoryIcon: "bi-broadcast", subCategoryText: "Research & Outreach" },
+   { id: "convergence", name: "Convergence Analysis", url: "https://www.convergenceanalysis.org/", category: "Advocacy", importance: 1, description: "Builds reports on AI scenarios/governance and conducts public awareness efforts.", subCategoryIcon: "bi-file-earmark-text", subCategoryText: "Research & Awareness" },
+   { id: "cesia", name: "Centre pour la Sécurité de l'IA (CeSIA)", url: "https://www.securite-ia.fr/", category: "Advocacy", importance: 1, description: "French AI safety nonprofit involved in education, advocacy, and research.", subCategoryIcon: "bi-flag", subCategoryText: "National Nonprofit (France)" },
+
+  // Info/Media
+  { id: "aisf", name: "AI Safety Fundamentals (AISF)", url: "https://aisafetyfundamentals.com/", category: "Info/Media", importance: 5, description: "Runs the standard introductory courses (Alignment & Governance tracks, 8-11 weeks). Often the first structured step for learners.", subCategoryIcon: "bi-mortarboard", subCategoryText: "Course/Curriculum" }, // Also Field Building
+  { id: "lesswrong", name: "LessWrong", url: "https://www.lesswrong.com/", category: "Info/Media", importance: 4, description: "Foundational community blog/forum for rationality and AI safety topics. Essential historical context and ongoing discussion.", subCategoryIcon: "bi-chat-left-text-fill", subCategoryText: "Community Forum/Blog" },
+  { id: "alignmentforum", name: "Alignment Forum", url: "https://www.alignmentforum.org/", category: "Info/Media", importance: 4, description: "The primary online forum for technical AI alignment research discussion. Successor to LessWrong for this niche.", subCategoryIcon: "bi-chat-left-text-fill", subCategoryText: "Community Forum/Blog" },
+  { id: "eaforum", name: "Effective Altruism Forum", url: "https://forum.effectivealtruism.org/", category: "Info/Media", importance: 3, description: "Main online hub for the Effective Altruism community, often features AI safety discussions/posts.", subCategoryIcon: "bi-chat-left-text-fill", subCategoryText: "Community Forum/Blog" },
+  { id: "robertmiles", name: "Robert Miles (AI Safety YouTube)", url: "https://robertskmiles.com/", category: "Info/Media", importance: 3, description: "Popular YouTube channel explaining AI safety concepts clearly. Excellent introductory resource.", subCategoryIcon: "bi-youtube", subCategoryText: "YouTube Channel" },
+  { id: "importai", name: "Import AI (Newsletter)", url: "https://importai.substack.com/", category: "Info/Media", importance: 3, description: "Highly regarded newsletter covering AI research, policy, and industry news (by Jack Clark/Anthropic).", subCategoryIcon: "bi-newspaper", subCategoryText: "Newsletter" },
+  { id: "aisafetyinfo", name: "AI Safety Info", url: "https://aisafety.info/", category: "Info/Media", importance: 3, description: "Comprehensive resource directory for learning about AI safety.", subCategoryIcon: "bi-info-circle", subCategoryText: "Resource Directory" },
+  { id: "aisafetycom", name: "AISafety.com", url: "https://www.aisafety.com/", category: "Info/Media", importance: 3, description: "Hub for AI safety resources, including guides, job board, event listings, funder lists.", subCategoryIcon: "bi-compass", subCategoryText: "Resource Hub" },
+  { id: "aiscomstayinformed", name: "AISafety.com: Stay informed", url: "https://www.aisafety.com/stay-informed", category: "Info/Media", importance: 3, description: "Directory of key information sources (blogs, newsletters, podcasts, video) to keep up with AI safety.", subCategoryIcon: "bi-collection-play", subCategoryText: "Resource Directory (Media)" },
+  { id: "aifrontiers", name: "AI Frontiers", url: "https://www.ai-frontiers.org/", category: "Info/Media", importance: 2, description: "Platform from CAIS with articles by experts discussing AI impacts.", subCategoryIcon: "bi-pencil-fill", subCategoryText: "Blog Platform" },
+  { id: "aipolicyweekly", name: "AI Policy Weekly (Newsletter)", url: "https://aipolicyus.substack.com/", category: "Info/Media", importance: 2, description: "Weekly newsletter from CAIP on key AI policy developments.", subCategoryIcon: "bi-newspaper", subCategoryText: "Newsletter" },
+  { id: "aiseventsnews", name: "AI Safety Events & Training (Newsletter)", url: "https://aisafety.com/events-and-training", category: "Info/Media", importance: 2, description: "Weekly newsletter listing newly-announced AI safety events and training programs.", subCategoryIcon: "bi-calendar-event", subCategoryText: "Newsletter (Events/Training)" },
+  { id: "aischinanews", name: "AI Safety in China (Newsletter)", url: "https://aisafetychina.substack.com/", category: "Info/Media", importance: 2, description: "Updates on AI safety developments in China from Concordia AI.", subCategoryIcon: "bi-newspaper", subCategoryText: "Newsletter (Regional Focus)" },
+  { id: "aiwatch", name: "AI Watch", url: "https://aiwatch.issarice.com/", category: "Info/Media", importance: 2, description: "Database tracking people, orgs, and \"products\" in the AI safety community.", subCategoryIcon: "bi-database", subCategoryText: "Database" },
+  { id: "milessubstack", name: "Miles's Substack (Blog)", url: "https://milesbrundage.substack.com/", category: "Info/Media", importance: 2, description: "Blog by AI policy researcher Miles Brundage on AI evolution and governance needs.", subCategoryIcon: "bi-pencil-fill", subCategoryText: "Blog" },
+  { id: "thecompendium", name: "The Compendium", url: "https://www.thecompendium.ai/", category: "Info/Media", importance: 2, description: "Living document explaining AGI race/risks for non-technical readers.", subCategoryIcon: "bi-journal-text", subCategoryText: "Living Document" }, // Moved from Policy
+  { id: "obsoleteblog", name: "Obsolete (Blog)", url: "https://garrisonlovely.substack.com/", category: "Info/Media", importance: 1, description: "Publication by Garrison Lovely on the intersection of capitalism, geopolitics, and AI.", subCategoryIcon: "bi-pencil-fill", subCategoryText: "Blog" },
+  { id: "powerlawblog", name: "The Power Law (Blog)", url: "https://peterwildeford.substack.com/", category: "Info/Media", importance: 1, description: "Top forecaster Peter Wildeford discusses AI, national security, innovation, etc.", subCategoryIcon: "bi-pencil-fill", subCategoryText: "Blog" },
+  { id: "aistakesblog", name: "AI Safety Takes (Blog)", url: "https://substack.com/@dpaleka", category: "Info/Media", importance: 1, description: "Blog by researcher Daniel Paleka on AI safety news (posts every ~2 months).", subCategoryIcon: "bi-pencil-fill", subCategoryText: "Blog" },
+  { id: "eadomains", name: "Effective Altruism Domains", url: "https://ea.domains/", category: "Info/Media", importance: 1, description: "Directory of domains available for high-impact projects.", subCategoryIcon: "bi-globe", subCategoryText: "Resource Directory" },
+  { id: "govmap", name: "Governance Map", url: "https://aigov.world/", category: "Info/Media", importance: 1, description: "Cartoon map displaying key organizations/projects in global AI governance.", subCategoryIcon: "bi-map", subCategoryText: "Visualization" },
+  { id: "forhumanitypod", name: "For Humanity (Podcast)", url: "https://www.youtube.com/@ForHumanityAIRisk", category: "Info/Media", importance: 1, description: "Aims to speak to regular, non-tech people about the existential threat AGI poses.", subCategoryIcon: "bi-mic-fill", subCategoryText: "Podcast" },
+  { id: "siliconversations", name: "Siliconversations (YouTube)", url: "https://www.youtube.com/@Siliconversations", category: "Info/Media", importance: 1, description: "Explains AI safety concepts through entertaining stickman videos.", subCategoryIcon: "bi-youtube", subCategoryText: "Video Channel" },
+  { id: "insideview", name: "The Inside View (YouTube)", url: "https://www.youtube.com/c/TheInsideView", category: "Info/Media", importance: 1, description: "Interviews, explainers, fictional threat models, paper walk-throughs.", subCategoryIcon: "bi-youtube", subCategoryText: "Video Channel" },
+
+  // Funding
+  { id: "openphil", name: "Open Philanthropy (OP)", url: "https://www.openphilanthropy.org/", category: "Funding", importance: 5, description: "The largest funder in the existential risk space, highly influential in AI safety funding.", subCategoryIcon: "bi-bank2", subCategoryText: "Major Funder" },
+  { id: "sff", name: "Survival and Flourishing Fund (SFF)", url: "http://survivalandflourishing.fund/", category: "Funding", importance: 4, description: "The second largest funder in AI safety, uses a unique allocation process.", subCategoryIcon: "bi-bank2", subCategoryText: "Major Funder" },
+  { id: "ltff", name: "Long-Term Future Fund (LTFF)", url: "https://funds.effectivealtruism.org/funds/far-future", category: "Funding", importance: 4, description: "Major Effective Altruism fund making grants addressing global catastrophic risks, including AI.", subCategoryIcon: "bi-bank2", subCategoryText: "EA Fund" },
+  { id: "longview", name: "Longview Philanthropy", url: "https://www.longview.org/", category: "Funding", importance: 3, description: "Devises and executes bespoke giving strategies for major donors in the space.", subCategoryIcon: "bi-person-vcard", subCategoryText: "Donor Advisory" },
+  { id: "gwwc", name: "Giving What We Can (GWWC)", url: "https://www.givingwhatwecan.org/", category: "Funding", importance: 3, description: "Community of donors pledged to give significantly to effective charities (incl. AI safety).", subCategoryIcon: "bi-people-fill", subCategoryText: "Donor Community" },
+  { id: "manifund", name: "Manifund", url: "https://manifund.org/", category: "Funding", importance: 3, description: "Marketplace for new charities/projects (incl. AI safety), allowing impact certificate purchases.", subCategoryIcon: "bi-shop", subCategoryText: "Impact Marketplace" },
+  { id: "flifellowships", name: "Future of Life Institute (FLI): Fellowships", url: "https://futureoflife.org/our-work/grantmaking-work/fellowships/", category: "Funding", importance: 3, description: "Offers PhD/postdoc fellowships in technical AI safety and US-China AI governance.", subCategoryIcon: "bi-mortarboard", subCategoryText: "Fellowship Funding" },
+  { id: "armfund", name: "AI Risk Mitigation (ARM) Fund", url: "https://www.airiskfund.com/", category: "Funding", importance: 2, description: "Grants for technical research, policy, and training to reduce catastrophic AI risks.", subCategoryIcon: "bi-bank2", subCategoryText: "Grantmaking Fund" },
+  { id: "ai2050", name: "AI2050 (Schmidt Futures)", url: "https://www.schmidtfutures.com/our-work/ai2050/", category: "Funding", importance: 2, description: "Supports researchers on key AI opportunities/problems (proposals by invite only).", subCategoryIcon: "bi-bank2", subCategoryText: "Philanthropic Initiative" },
+  { id: "aiscomfunders", name: "AISafety.com: Funders Directory", url: "https://www.aisafety.com/funders", category: "Funding", importance: 2, description: "Directory of financial support sources for AI safety projects (grants, VCs).", subCategoryIcon: "bi-compass", subCategoryText: "Resource Directory" },
+  { id: "clrfund", name: "Center on Long-Term Risk (CLR): Fund", url: "https://longtermrisk.org/grantmaking/", category: "Funding", importance: 2, description: "Supports projects addressing worst-case suffering risks from advanced AI.", subCategoryIcon: "bi-bank2", subCategoryText: "Grantmaking Fund" },
+  { id: "caif", name: "Cooperative AI Foundation (CAIF)", url: "https://www.cooperativeai.com/foundation", category: "Funding", importance: 2, description: "Supports research into improving cooperative intelligence of advanced AI.", subCategoryIcon: "bi-bank2", subCategoryText: "Charity Foundation" },
+  { id: "donationslist", name: "Donations List Website", url: "https://donations.vipulnaik.com/?cause_area_filter=AI+safety", category: "Funding", importance: 2, description: "Site focused on understanding donations, donors, donees in effective altruism.", subCategoryIcon: "bi-database", subCategoryText: "Donation Tracking" },
+  { id: "eaif", name: "EA Infrastructure Fund (EAIF)", url: "https://funds.effectivealtruism.org/funds/ea-community", category: "Funding", importance: 2, description: "Aims to increase impact of EA projects via access to talent, capital, knowledge.", subCategoryIcon: "bi-bank2", subCategoryText: "EA Fund" },
+  { id: "ergoimpact", name: "Ergo Impact", url: "https://ergoimpact.org/", category: "Funding", importance: 2, description: "Helps major donors find, fund, and scale solutions to pressing problems.", subCategoryIcon: "bi-person-vcard", subCategoryText: "Donor Advisory" },
+  { id: "foresightfunding", name: "Foresight Institute: Funding", url: "https://foresight.org/ai-safety/", category: "Funding", importance: 2, description: "Funds projects in research automation, security tech, neurotech, safe AI scenarios.", subCategoryIcon: "bi-bank2", subCategoryText: "Grantmaking" },
+  { id: "flf", name: "Future of Life Foundation (FLF)", url: "https://www.flf.org/", category: "Funding", importance: 2, description: "Accelerator aiming to steer transformative technology towards benefiting life.", subCategoryIcon: "bi-rocket-takeoff", subCategoryText: "Accelerator/Funder" },
+  { id: "nonlinearnetwork", name: "Nonlinear Network", url: "https://www.nonlinear.org/network", category: "Funding", importance: 2, description: "Funder network for AI existential risk reduction; connects applications with donors.", subCategoryIcon: "bi-diagram-3", subCategoryText: "Funder Network" },
+  { id: "nsfsafesystems", name: "U.S. National Science Foundation (NSF): Safe Learning-Enabled Systems", url: "https://new.nsf.gov/funding/opportunities/safe-learning-enabled-systems", category: "Funding", importance: 2, description: "Funds research into design/implementation of safe learning-enabled systems.", subCategoryIcon: "bi-flag-fill", subCategoryText: "Government Funding" },
+  { id: "aegrants", name: "AE Grants", url: "https://research.ae.studio/", category: "Funding", importance: 1, description: "Funds innovators/scientists creating responsible AI to increase human agency.", subCategoryIcon: "bi-bank2", subCategoryText: "Grantmaking" },
+  { id: "aiscomdonationguide", name: "AISafety.com: Donation Guide", url: "https://www.aisafety.com/donation-guide", category: "Funding", importance: 1, description: "Regularly updated guide on how to donate most effectively.", subCategoryIcon: "bi-compass", subCategoryText: "Resource/Guide" },
+  { id: "aria", name: "Advanced Research + Invention Agency (ARIA)", url: "https://www.aria.org.uk/", category: "Funding", importance: 1, description: "UK R&D funding agency for scientific/technological breakthroughs.", subCategoryIcon: "bi-flag-fill", subCategoryText: "Government Funding (UK)" },
+  { id: "fundingsituation", name: "An Overview of the AI Safety Funding Situation", url: "https://forum.effectivealtruism.org/posts/XdhwXppfqrpPL2YDX/an-overview-of-the-ai-safety-funding-situation", category: "Funding", importance: 1, description: "Analysis of funding sources over time; useful background context.", subCategoryIcon: "bi-file-earmark-bar-graph", subCategoryText: "Analysis/Report" },
+  { id: "givewiki", name: "GiveWiki", url: "https://givewiki.org/", category: "Funding", importance: 1, description: "Crowdsourced charity evaluation and philanthropic networking platform.", subCategoryIcon: "bi-database", subCategoryText: "Platform" },
+  { id: "lionheart", name: "Lionheart Ventures", url: "https://www.lionheart.vc/", category: "Funding", importance: 1, description: "VC firm investing in ethical founders developing transformative technologies.", subCategoryIcon: "bi-building", subCategoryText: "Venture Capital" },
+  { id: "macroscopic", name: "Macroscopic Ventures", url: "https://macroscopic.org/", category: "Funding", importance: 1, description: "Swiss nonprofit focused on reducing suffering risks (incl. AI misuse/conflict).", subCategoryIcon: "bi-bank2", subCategoryText: "Nonprofit Funder (Swiss)" },
+  { id: "metacharity", name: "Meta Charity Funders", url: "https://www.metacharityfunders.com/", category: "Funding", importance: 1, description: "Network funding meta-charitable projects (often cross-cause area).", subCategoryIcon: "bi-people-fill", subCategoryText: "Donor Network" },
+  { id: "mythos", name: "Mythos Ventures", url: "https://www.mythos.vc/", category: "Funding", importance: 1, description: "VC investing in teams building safe AI systems scalable to post-AGI.", subCategoryIcon: "bi-building", subCategoryText: "Venture Capital" },
+  { id: "shfhs", name: "Saving Humanity from Homo Sapiens (SHfHS)", url: "http://shfhs.org/", category: "Funding", importance: 1, description: "Small organization funding work preventing human-created x-risks.", subCategoryIcon: "bi-bank2", subCategoryText: "Small Funder" },
+  { id: "navfund", name: "The Navigation Fund", url: "https://www.navigation.org/", category: "Funding", importance: 1, description: "Offers grants to high-impact organizations/projects making significant changes.", subCategoryIcon: "bi-bank2", subCategoryText: "Grantmaking Fund" },
+
+  // Field Building
+  { id: "80k", name: "80,000 Hours Career Guide", url: "https://80000hours.org/problem-profiles/artificial-intelligence/", category: "Field Building", importance: 4, description: "Essential reading for planning an impactful career in the AI safety space.", subCategoryIcon: "bi-compass", subCategoryText: "Career Guide" },
+  { id: "aiss", name: "AI Safety Support (AISS)", url: "https://www.aisafetysupport.org/", category: "Field Building", importance: 3, description: "Provides free one-on-one support calls for people exploring AI safety careers.", subCategoryIcon: "bi-person-hearts", subCategoryText: "Support Organization" },
+  { id: "bluedot", name: "BlueDot Impact", url: "https://www.bluedotimpact.com/", category: "Field Building", importance: 3, description: "Runs online courses and career services for professionals aiming for high-impact careers (incl. AI safety).", subCategoryIcon: "bi-mortarboard", subCategoryText: "Training/Courses" },
+  { id: "apart", name: "Apart Research", url: "https://www.apart-research.com/", category: "Field Building", importance: 3, description: "Trains promising researchers for independent work on AI alignment via fellowships/programs.", subCategoryIcon: "bi-mortarboard", subCategoryText: "Research Training" },
+  { id: "aisc", name: "AI Safety Camp (AISC)", url: "https://aisafety.camp/", category: "Field Building", importance: 2, description: "Runs residential programs helping aspiring researchers produce publishable alignment work.", subCategoryIcon: "bi-mortarboard", subCategoryText: "Research Program" },
+  { id: "era", name: "ERA: Evaluating Research Aptitude", url: "https://era.gregorygundersen.com/", category: "Field Building", importance: 2, description: "Helps evaluate/develop technical AI safety research aptitude (previously MLAB).", subCategoryIcon: "bi-mortarboard", subCategoryText: "Training/Evaluation" },
+  { id: "aiscommunity", name: "AI Safety Community", url: "https://www.aisafety.community/", category: "Field Building", importance: 2, description: "Lists local AI safety groups, online communities, student groups etc.", subCategoryIcon: "bi-people-fill", subCategoryText: "Community Directory" },
+  { id: "aisst", name: "AI Safety Student Teams (AISST)", url: "https://www.aistudents.org/", category: "Field Building", importance: 2, description: "Organization supporting university students interested in AI safety.", subCategoryIcon: "bi-mortarboard", subCategoryText: "Student Network" },
+  { id: "aisscholars", name: "AI Safety Scholars (AISS)", url: "https://sites.google.com/view/aiss-course/home", category: "Field Building", importance: 2, description: "Introductory summer research program for students (run by CAIS).", subCategoryIcon: "bi-mortarboard", subCategoryText: "Training Program" },
+  { id: "axrp", name: "AI Safety Research Program (AXRP)", url: "https://axrp.net/", category: "Field Building", importance: 2, description: "Podcast interviewing AI safety researchers about their work. Useful for learning research directions.", subCategoryIcon: "bi-mic-fill", subCategoryText: "Podcast/Interviews" }, // Also Info/Media
+  { id: "aisschool", name: "AI Safety School", url: "https://www.aisschool.org/", category: "Field Building", importance: 1, description: "Runs programs in the Netherlands introducing people to AI safety.", subCategoryIcon: "bi-mortarboard", subCategoryText: "Training/Community (Netherlands)" },
+  { id: "aisi", name: "AI Safety Intro Fellowship (AISI)", url: "https://aisafetyintro.com/", category: "Field Building", importance: 1, description: "Virtual introductory program (4 weeks) aimed at university students/recent grads.", subCategoryIcon: "bi-mortarboard", subCategoryText: "Introductory Program" },
+  { id: "eacourses", name: "EA Introductory Courses", url: "https://courses.effectivealtruism.org/", category: "Field Building", importance: 1, description: "Directory of various introductory courses related to Effective Altruism, often including AI Safety tracks.", subCategoryIcon: "bi-book", subCategoryText: "Course Directory" },
+  { id: "eaglobal", name: "EA Global Conferences", url: "https://www.eaglobal.org/", category: "Field Building", importance: 1, description: "Major conferences for the Effective Altruism community, significant AI safety presence.", subCategoryIcon: "bi-calendar-event", subCategoryText: "Conferences" },
+  { id: "serimats", name: "SERI MATS Scholars Program", url: "https://serimats.org/", category: "Field Building", importance: 1, description: "Mentored Alignment Theory Scholars program training researchers in theoretical alignment.", subCategoryIcon: "bi-mortarboard", subCategoryText: "Research Training" },
+  { id: "effectiveideas", name: "Effective Ideas", url: "https://www.effectiveideas.com/", category: "Field Building", importance: 1, description: "Platform for sharing ideas related to Effective Altruism.", subCategoryIcon: "bi-lightbulb", subCategoryText: "Blog Platform" }, // Also Info/Media
+  { id: "aiscareersnews", name: "AI Safety Careers Newsletter", url: "https://aisafetycareers.substack.com/", category: "Field Building", importance: 1, description: "Quarterly newsletter highlighting resources for finding/pursuing an AI safety career.", subCategoryIcon: "bi-newspaper", subCategoryText: "Newsletter" },
+  { id: "aisa", name: "AI Safety Asia (AISA)", url: "https://aisafety.asia/", category: "Field Building", importance: 1, description: "Connects junior researchers/civil servants from SE Asia with senior AI safety researchers.", subCategoryIcon: "bi-people-fill", subCategoryText: "Regional Network (Asia)" },
+  { id: "aishungary", name: "AI Safety Hungary", url: "https://www.aishungary.com/", category: "Field Building", importance: 1, description: "Supports students/professionals in Hungary contributing to safe AI via seminars etc.", subCategoryIcon: "bi-flag", subCategoryText: "National Group (Hungary)" },
+  { id: "arcadia", name: "Arcadia Impact", url: "https://www.arcadiaimpact.org/", category: "Field Building", importance: 1, description: "Runs various projects aimed at education, skill development, pathways into impact careers.", subCategoryIcon: "bi-mortarboard", subCategoryText: "Education/Skills" },
+  { id: "meridian", name: "Meridian", url: "https://www.meridiancambridge.org/", category: "Field Building", importance: 1, description: "Coworking space and field-building nonprofit in Cambridge, UK (houses CAISH, ERA:AI Fellowship).", subCategoryIcon: "bi-building", subCategoryText: "Coworking/Field Building (UK)" }, // Also Community/Infra
+
+  // Community/Infra
+  { id: "lightcone", name: "Lightcone Infrastructure", url: "https://www.lightconeinfrastructure.com/", category: "Community/Infra", importance: 4, description: "Nonprofit maintaining LessWrong, Alignment Forum, and Lighthaven (event space).", subCategoryIcon: "bi-hdd-stack-fill", subCategoryText: "Infrastructure Org" },
+  { id: "beri", name: "Berkeley Existential Risk Initiative (BERI)", url: "https://existence.org/", category: "Community/Infra", importance: 3, description: "Provides flexible funding/operations support to university x-risk research groups.", subCategoryIcon: "bi-bank", subCategoryText: "University Support Org" },
+  { id: "constellation", name: "Constellation", url: "https://www.constellation.org/", category: "Community/Infra", importance: 3, description: "Center for collaborative research in AI safety (fellowships, workshops, hosting).", subCategoryIcon: "bi-building", subCategoryText: "Research Hub/Coworking" },
+  { id: "enais", name: "European Network for AI Safety (ENAIS)", url: "https://enais.co/", category: "Community/Infra", importance: 2, description: "Community of researchers/policymakers across Europe advancing AI safety.", subCategoryIcon: "bi-globe-europe-africa", subCategoryText: "Regional Network (Europe)" },
+  { id: "lisa", name: "London Initiative for Safe AI (LISA)", url: "https://www.safeai.org.uk/", category: "Community/Infra", importance: 2, description: "Coworking space hosting organizations, acceleration programs, and researchers.", subCategoryIcon: "bi-building", subCategoryText: "Coworking/Hub (London)" },
+  { id: "aed", name: "Alignment Ecosystem Development (AED)", url: "https://alignment.dev/", category: "Community/Infra", importance: 2, description: "Builds/maintains key online resources for the AI safety community (incl. AISafety.com).", subCategoryIcon: "bi-gear", subCategoryText: "Infrastructure/Support" },
+  { id: "ashgro", name: "Ashgro", url: "https://www.ashgro.org/", category: "Community/Infra", importance: 1, description: "Provides fiscal sponsorship to AI safety projects.", subCategoryIcon: "bi-umbrella-fill", subCategoryText: "Fiscal Sponsorship" },
+  { id: "catalyze", name: "Catalyze Impact", url: "https://catalyze-impact.org", category: "Community/Infra", importance: 1, description: "Incubates early-stage AI safety research organizations (co-founder matching, mentorship, funding).", subCategoryIcon: "bi-rocket", subCategoryText: "Incubator" },
+  { id: "ceealar", name: "Centre for Enabling EA Learning & Research (CEEALAR aka EA Hotel)", url: "https://www.ceealar.org/", category: "Community/Infra", importance: 1, description: "Free/subsidised accommodation in Blackpool, UK, for people working on GCRs.", subCategoryIcon: "bi-house-door-fill", subCategoryText: "Accommodation" },
+  { id: "chinaainetwork", name: "China AI Development and Safety Network", url: "https://ai-development-and-safety-network.cn/", category: "Community/Infra", importance: 1, description: "Network for exchange/cooperation between Chinese institutions and global AI research.", subCategoryIcon: "bi-diagram-3", subCategoryText: "National Network (China)" },
+  { id: "futurematters", name: "Future Matters", url: "https://future-matters.org/", category: "Community/Infra", importance: 1, description: "Provides strategy consulting services for advancing AI safety via policy, politics etc.", subCategoryIcon: "bi-briefcase", subCategoryText: "Consulting" },
+  { id: "impactops", name: "Impact Ops", url: "https://impact-ops.org/", category: "Community/Infra", importance: 1, description: "Provides consultancy/hands-on support to help high-impact organizations upgrade operations.", subCategoryIcon: "bi-sliders", subCategoryText: "Operational Support" },
+  { id: "nonlinear", name: "Nonlinear", url: "https://www.nonlinear.org/", category: "Community/Infra", importance: 1, description: "\"Means-neutral\" org; offers bounties, runs funder network, miscellaneous projects.", subCategoryIcon: "bi-question-circle", subCategoryText: "Miscellaneous Org" },
+  { id: "saif", name: "Safe AI Forum (SAIF)", url: "https://saif.org/", category: "Community/Infra", importance: 1, description: "Fosters responsible AI governance via shared understanding/collaboration among key global actors.", subCategoryIcon: "bi-people-fill", subCategoryText: "Collaboration Forum" },
+  { id: "thirdopinion", name: "Third Opinion", url: "https://third-opinion.org/", category: "Community/Infra", importance: 1, description: "Helps concerned individuals at AI frontier get expert opinions anonymously/securely.", subCategoryIcon: "bi-shield-lock-fill", subCategoryText: "Anonymous Advice" },
+
+  // Forecasting
+  { id: "aiimpacts", name: "AI Impacts", url: "https://aiimpacts.org/", category: "Forecasting", importance: 4, description: "Answers decision-relevant questions about AI's future (research, wiki, expert surveys). Key forecasting resource.", subCategoryIcon: "bi-graph-up", subCategoryText: "Research/Wiki (Forecasting)" },
+  { id: "metaculus", name: "Metaculus", url: "https://www.metaculus.com/questions/?topic=ai", category: "Forecasting", importance: 3, description: "Well-calibrated forecasting platform covering many topics, including influential AI questions.", subCategoryIcon: "bi-bar-chart-line-fill", subCategoryText: "Prediction Platform" },
+  { id: "epochaiforecast", name: "Epoch AI", url: "https://epochai.org/", category: "Forecasting", importance: 3, description: "Investigates key trends and questions shaping AI trajectory (compute, algorithms etc.).", subCategoryIcon: "bi-graph-up", subCategoryText: "Research Institute (Trends & Governance)" }, // Duplicate from Policy? Keep here as primary focus is trends/forecasting
+  { id: "manifold", name: "Manifold Markets", url: "https://manifold.markets/", category: "Forecasting", importance: 2, description: "Prediction market platform using play money (\"mana\"); includes many AI/AI safety markets.", subCategoryIcon: "bi-bar-chart-line-fill", subCategoryText: "Prediction Platform (Play Money)" },
+  { id: "quri", name: "Quantified Uncertainty Research Institute (QURI)", url: "https://quantifieduncertainty.org/", category: "Forecasting", importance: 2, description: "Advances forecasting/epistemics for long-term future; writes research/software.", subCategoryIcon: "bi-calculator-fill", subCategoryText: "Research Institute (Forecasting/Epistemics)" },
+  { id: "aifutures", name: "AI Futures Project", url: "https://ai-futures.org/", category: "Forecasting", importance: 1, description: "Small group forecasting AI's future (created 'AI 2027' scenario).", subCategoryIcon: "bi-graph-up", subCategoryText: "Research Group" },
+  { id: "fri", name: "Forecasting Research Institute (FRI)", url: "https://forecastingresearch.org", category: "Forecasting", importance: 1, description: "Advancing forecasting science; works with policymakers/nonprofits.", subCategoryIcon: "bi-calculator-fill", subCategoryText: "Research Institute (Forecasting Science)" },
+  { id: "mitfuturetech", name: "MIT FutureTech", url: "https://futuretech.mit.edu/", category: "Forecasting", importance: 1, description: "Identifies/understands computing trends affecting economic growth/risk.", subCategoryIcon: "bi-bank", subCategoryText: "University Group (MIT)" },
+  { id: "tfi", name: "Transformative Futures Institute (TFI)", url: "https://transformative.org/", category: "Forecasting", importance: 1, description: "Explores underutilized foresight methods to anticipate societal-scale AI risks.", subCategoryIcon: "bi-binoculars", subCategoryText: "Research Institute (Foresight Methods)" },
+
+  // Inactive
+  { id: "fhi", name: "Future of Humanity Institute (FHI)", url: "https://www.fhi.ox.ac.uk/", category: "Inactive", importance: 1, description: "Highly influential longtermist/x-risk research organization led by Nick Bostrom. Closed 2024.", subCategoryIcon: "bi-slash-circle", subCategoryText: "University Center (Oxford, Inactive)" },
+  { id: "aiscc", name: "AI Safety Communications Centre (AISCC)", url: "https://aiscc.org/", category: "Inactive", importance: 1, description: "Connected journalists to AI safety experts and resources.", subCategoryIcon: "bi-slash-circle", subCategoryText: "Comms Support (Inactive)" },
+  { id: "ash", name: "AI Safety Hub (ASH)", url: "https://www.aisafetyhub.org/", category: "Inactive", importance: 1, description: "Ran AI Safety Hub Labs (now run by LASR Labs).", subCategoryIcon: "bi-slash-circle", subCategoryText: "Training Program (Superseded)" },
+  { id: "cas", name: "Campaign for AI Safety (CAS)", url: "http://campaignforaisafety.org/", category: "Inactive", importance: 1, description: "Increased public understanding, called for laws (merged with ERO).", subCategoryIcon: "bi-slash-circle", subCategoryText: "Campaign Group (Merged)" },
+  { id: "mlaisafetyupdates", name: "ML & AI Safety Updates", url: "https://www.alignmentforum.org/posts/uRosq4YtNiZxywcAq/newsletter-for-alignment-research-the-ml-safety-updates", category: "Inactive", importance: 1, description: "Weekly podcast, YouTube, newsletter with updates (dropped).", subCategoryIcon: "bi-slash-circle", subCategoryText: "Media (Inactive)" },
+  { id: "openbook", name: "OpenBook", url: "https://openbook.fyi/", category: "Inactive", importance: 1, description: "Database of grants in effective altruism (no longer maintained).", subCategoryIcon: "bi-slash-circle", subCategoryText: "Database (Inactive)" },
+  { id: "aialignmentawards", name: "AI Alignment Awards", url: "https://www.alignmentawards.com/", category: "Inactive", importance: 1, description: "Ran research paper/essay-writing contests (last round 2023).", subCategoryIcon: "bi-slash-circle", subCategoryText: "Contest (Inactive)" },
+  { id: "aisafetyideas", name: "AI Safety Ideas", url: "https://aisafetyideas.com/", category: "Inactive", importance: 1, description: "Crowdsourced repository of research projects (run by Apart Research).", subCategoryIcon: "bi-slash-circle", subCategoryText: "Repository (Inactive)" },
+  { id: "aissnewsletter", name: "AI Safety Support (AISS) Newsletter", url: "https://www.aisafetysupport.org/newsletter", category: "Inactive", importance: 1, description: "Listed opportunities in AI alignment (dropped).", subCategoryIcon: "bi-slash-circle", subCategoryText: "Newsletter (Inactive)" },
+  { id: "aizi", name: "From AI to ZI (Blog)", url: "https://aizi.substack.com/", category: "Inactive", importance: 1, description: "Blog by Robert Huben (currently semi-dormant).", subCategoryIcon: "bi-slash-circle", subCategoryText: "Blog (Semi-Dormant)" },
+  { id: "genink", name: "generative.ink (Blog)", url: "https://generative.ink/posts/", category: "Inactive", importance: 1, description: "The blog of janus the GPT cyborg (last post 2023).", subCategoryIcon: "bi-slash-circle", subCategoryText: "Blog (Inactive)" },
+  { id: "lightspeedgrants", name: "Lightspeed Grants", url: "https://lightspeedgrants.org/", category: "Inactive", importance: 1, description: "Fast funding for trajectory-changing projects (last round 2023).", subCategoryIcon: "bi-slash-circle", subCategoryText: "Grantmaking (Inactive)" },
+  { id: "preamblefoundation", name: "Preamble Windfall Foundation", url: "https://www.preambleforgood.org/", category: "Inactive", importance: 1, description: "Funding organization aiming to minimize AI risk (inactive).", subCategoryIcon: "bi-slash-circle", subCategoryText: "Funding Org (Inactive)" },
+  { id: "stopai", name: "Stop AGI", url: "http://stop.ai/", category: "Inactive", importance: 1, description: "Website communicating risks and prevention proposals.", subCategoryIcon: "bi-slash-circle", subCategoryText: "Website/Advocacy (Inactive)" },
+  { id: "superlinear", name: "Superlinear Prizes", url: "https://www.super-linear.org/", category: "Inactive", importance: 1, description: "Decentralized bounty platform for x-risk reduction/EA causes.", subCategoryIcon: "bi-slash-circle", subCategoryText: "Bounty Platform (Inactive)" }
+];
+
+// --- END OF FILE data.js ---
\ No newline at end of file