{"id":516,"date":"2026-04-27T02:35:38","date_gmt":"2026-04-27T02:35:38","guid":{"rendered":"https:\/\/qubicportal.org\/?page_id=516"},"modified":"2026-04-27T03:21:09","modified_gmt":"2026-04-27T03:21:09","slug":"science","status":"publish","type":"page","link":"https:\/\/qubicportal.org\/?page_id=516","title":{"rendered":"Science"},"content":{"rendered":"    <div id=\"imm-mindmap-wrapper\" style=\"position:relative; width:100%; height:auto; min-height:600px; overflow:visible; border:0; background:transparent; isolation:isolate; contain:layout style paint;\">\n        <div id=\"imm-container\" style=\"width:100%; height:80dvh; min-height:600px; position:relative; overflow:hidden; border:0; background:transparent; opacity:0; transition:opacity 0.4s ease;\">\n            <div id=\"imm-loading\" style=\"position:absolute; top:50%; left:50%; transform:translate(-50%, -50%); z-index:10; color:#888; font-family:system-ui,Arial,sans-serif; text-align:center; pointer-events:none;\">\n                <div style=\"margin-bottom:12px;\">Loading mindmap...<\/div>\n                <div style=\"width:40px; height:40px; border:4px solid #ddd; border-top:4px solid #8bf; border-radius:50%; animation:spin 1s linear infinite; margin:0 auto;\"><\/div>\n            <\/div>\n\n            \n            <div id=\"imm-tooltip\" style=\"position:absolute; display:none; background:rgba(0,0,0,0.92); color:#fff; padding:8px 12px; border-radius:6px; font-family:system-ui,Arial,sans-serif; font-size:14px; pointer-events:none; z-index:10002; box-shadow:0 4px 12px rgba(0,0,0,0.5); white-space:nowrap; max-width:280px;\"><\/div>\n\n            <div id=\"imm-youtube-panel\" style=\"display:none; position:fixed; top:50%; left:50%; transform:translate(-50%, -50%); width:512px; height:425px; max-width:92vw; max-height:85vh; background:#000; border:3px solid #fff; border-radius:11px; box-shadow:0 0 30px rgba(0,0,0,0.9); z-index:10001; overflow:hidden;\">\n                <div id=\"imm-video-header\" style=\"background:rgba(0,0,0,0.85); padding:5px 5px; color:#fff; font-weight:bold; cursor:move; user-select:none; display:flex; align-items:center; gap:12px;\">\n                    <button id=\"imm-enter-site-btn\" style=\"background:#8bf; color:white; border:none; padding:3px 10px; border-radius:6px; font-weight:bold; cursor:pointer;\">Enter Site<\/button>\n                    <span style=\"flex:1; text-align:center;\">Video Player<\/span>\n                    <button id=\"imm-close-btn\" style=\"background:none; border:none; color:#fff; font-size:32px; font-weight:bold; cursor:pointer; padding:0 8px;\">\u00d7<\/button>\n                <\/div>\n                <iframe id=\"imm-youtube-iframe\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen style=\"width:100%; height:calc(100% - 52px);\"><\/iframe>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <style>\n    @keyframes spin { to { transform: rotate(360deg); } }\n    #imm-mindmap-wrapper svg,\n    #imm-container svg {\n        position: absolute;\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 100%;\n        z-index: 3;\n    }\n    .clickable-node { cursor: pointer; }\n\n    .energy-pulse {\n        stroke-width: 2.5;\n        stroke-linecap: round;\n        filter: url(#energy-glow);\n        pointer-events: none;\n        opacity: 0.75;\n    }\n\n    .paid-border {\n        stroke: #fc0;\n        stroke-width: 0;\n        fill: none;\n    }\n\n    .paid-border-pulse {\n        animation: paidBorderPulse 300ms ease-out forwards;\n    }\n    @keyframes paidBorderPulse {\n        0%   { stroke-width: 5; filter: brightness(1.6); }\n        100% { stroke-width: 3; filter: brightness(1); }\n    }\n    <\/style>\n\n    <script>\n    document.addEventListener('DOMContentLoaded', () => {\n        const container = document.getElementById('imm-container');\n        const loadingEl = document.getElementById('imm-loading');\n        const tooltip = document.getElementById('imm-tooltip');\n\n        async function preloadAndMeasureImages(nodes) {\n            const imageUrls = new Set();\n            nodes.forEach(node => {\n                if (node.image_light) imageUrls.add(node.image_light);\n                if (node.image_dark)  imageUrls.add(node.image_dark);\n                if (node.overlay_light) imageUrls.add(node.overlay_light);\n                if (node.overlay_dark)  imageUrls.add(node.overlay_dark);\n            });\n\n            await Promise.all(Array.from(imageUrls).map(src => {\n                return new Promise(resolve => {\n                    if (!src) return resolve();\n                    const img = new Image();\n                    img.onload = () => resolve();\n                    img.onerror = () => resolve();\n                    img.src = src;\n                });\n            }));\n\n            await Promise.all(nodes.map(node => {\n                return new Promise(resolve => {\n                    const src = node.image_light || node.image_dark;\n                    if (!src) {\n                        node.realWidth = 50;\n                        node.realHeight = 50;\n                        return resolve();\n                    }\n                    const img = new Image();\n                    img.onload = () => {\n                        node.realWidth = img.width;\n                        node.realHeight = img.height;\n                        resolve();\n                    };\n                    img.onerror = () => {\n                        node.realWidth = 50;\n                        node.realHeight = 50;\n                        resolve();\n                    };\n                    img.src = src;\n                });\n            }));\n        }\n\n        let rawData = {\"title\":\"Science\",\"nodes\":[{\"id\":1,\"label\":\"Science\",\"url\":\"https:\/\/qubicportal.org\",\"image_light\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/04\/Science-center.png\",\"image_dark\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/04\/Science-center.png\",\"overlay_light\":\"\",\"overlay_dark\":\"\",\"overlay_width\":80,\"overlay_height\":80,\"youtube_id\":\"\",\"isRoot\":true,\"node_type\":\"newroot\",\"category\":\"Qubic Resources\",\"open_behavior\":\"self\",\"pulse_rate\":40},{\"id\":2,\"label\":\"Neuraxon Research\",\"url\":\"https:\/\/www.researchgate.net\/publication\/397331336_Neuraxon\",\"image_light\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/04\/Neuraxon.png\",\"image_dark\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/04\/Neuraxon.png\",\"overlay_light\":\"\",\"overlay_dark\":\"\",\"overlay_width\":80,\"overlay_height\":80,\"category\":\"Qubic Resources\",\"youtube_id\":\"\",\"isRoot\":false,\"node_type\":\"leaf\",\"open_behavior\":\"popup\",\"pulse_rate\":40},{\"id\":3,\"label\":\"AGI Research\",\"url\":\"https:\/\/www.researchgate.net\/publication\/387364505_Qubic_AGI_Journey_Human_and_Artificial_Intelligence_Toward_an_AGI_with_Aigarth\",\"image_light\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/04\/AGIResearch.png\",\"image_dark\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/04\/AGIResearch.png\",\"overlay_light\":\"\",\"overlay_dark\":\"\",\"overlay_width\":80,\"overlay_height\":80,\"category\":\"Qubic Resources\",\"youtube_id\":\"\",\"isRoot\":false,\"node_type\":\"leaf\",\"open_behavior\":\"popup\",\"pulse_rate\":40},{\"id\":4,\"label\":\"The AntHill\",\"url\":\"https:\/\/x.com\/_qubic_\/status\/2047677623338213777?s=46\",\"image_light\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/04\/anthill-1.png\",\"image_dark\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/04\/anthill.png\",\"overlay_light\":\"\",\"overlay_dark\":\"\",\"overlay_width\":80,\"overlay_height\":80,\"category\":\"Qubic Resources\",\"youtube_id\":\"\",\"isRoot\":false,\"node_type\":\"leaf\",\"open_behavior\":\"popup\",\"pulse_rate\":40},{\"id\":5,\"label\":\"Qubic AMAs\",\"url\":\"https:\/\/www.youtube.com\/@_qubic_\",\"image_light\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/04\/Qamas.png\",\"image_dark\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/04\/Qamas.png\",\"overlay_light\":\"\",\"overlay_dark\":\"\",\"overlay_width\":80,\"overlay_height\":80,\"category\":\"Qubic Resources\",\"youtube_id\":\"\",\"isRoot\":false,\"node_type\":\"leaf\",\"open_behavior\":\"popup\",\"pulse_rate\":40},{\"id\":6,\"label\":\"David Vivancos on X\",\"url\":\"https:\/\/x.com\/VivancosDavid\",\"image_light\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/Vivancos.png\",\"image_dark\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/Vivancos.png\",\"overlay_light\":\"\",\"overlay_dark\":\"\",\"overlay_width\":80,\"overlay_height\":80,\"category\":\"Qubic Resources\",\"youtube_id\":\"\",\"isRoot\":false,\"node_type\":\"leaf\",\"open_behavior\":\"popup\",\"pulse_rate\":40},{\"id\":7,\"label\":\"Jose S\\u00e1nchez on X\",\"url\":\"https:\/\/x.com\/josesanchezhb\",\"image_light\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/Sanchez.png\",\"image_dark\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/Sanchez.png\",\"overlay_light\":\"\",\"overlay_dark\":\"\",\"overlay_width\":80,\"overlay_height\":80,\"category\":\"Qubic Resources\",\"youtube_id\":\"\",\"isRoot\":false,\"node_type\":\"leaf\",\"open_behavior\":\"popup\",\"pulse_rate\":40},{\"id\":8,\"label\":\"Qubic Blog\",\"url\":\"https:\/\/qubic.org\/blog-grid\",\"image_light\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/04\/blog.png\",\"image_dark\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/04\/blog.png\",\"overlay_light\":\"\",\"overlay_dark\":\"\",\"overlay_width\":80,\"overlay_height\":80,\"category\":\"Qubic Resources\",\"youtube_id\":\"\",\"isRoot\":false,\"node_type\":\"leaf\",\"open_behavior\":\"popup\",\"pulse_rate\":40},{\"id\":9,\"label\":\"Neuraxon Intelligence Part I\",\"url\":\"https:\/\/qubic.org\/blog-detail\/neuraxon-time-why-intelligence-is-not-computed-in-steps-but-in-time\",\"image_light\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/neuraxon-1.png\",\"image_dark\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/neuraxon-1.png\",\"overlay_light\":\"\",\"overlay_dark\":\"\",\"overlay_width\":80,\"overlay_height\":80,\"category\":\"Qubic Resources\",\"youtube_id\":\"\",\"isRoot\":false,\"node_type\":\"leaf\",\"open_behavior\":\"popup\",\"pulse_rate\":40},{\"id\":10,\"label\":\"Neuraxon Intelligence Part II\",\"url\":\"https:\/\/qubic.org\/blog-detail\/beyond-binary-ternary-dynamics-as-a-model-of-living-intelligence\",\"image_light\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/neuraxon-2.png\",\"image_dark\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/neuraxon-2.png\",\"overlay_light\":\"\",\"overlay_dark\":\"\",\"overlay_width\":80,\"overlay_height\":80,\"category\":\"Qubic Resources\",\"youtube_id\":\"\",\"isRoot\":false,\"node_type\":\"leaf\",\"open_behavior\":\"popup\",\"pulse_rate\":40},{\"id\":11,\"label\":\"Neuraxon Intelligence Part III\",\"url\":\"https:\/\/qubic.org\/blog-detail\/neuromodulation-brain-inspired-ai-neuraxon-intelligence-academy-vol-3\",\"image_light\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/neuraxon-3.png\",\"image_dark\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/neuraxon-3.png\",\"overlay_light\":\"\",\"overlay_dark\":\"\",\"overlay_width\":80,\"overlay_height\":80,\"category\":\"Qubic Resources\",\"youtube_id\":\"\",\"isRoot\":false,\"node_type\":\"leaf\",\"open_behavior\":\"popup\",\"pulse_rate\":40},{\"id\":12,\"label\":\"Neuraxon Intelligence Part IV\",\"url\":\"https:\/\/qubic.org\/blog-detail\/neural-networks-biological-artificial-neuraxon-intelligence\",\"image_light\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/neuraxon-4.png\",\"image_dark\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/neuraxon-4.png\",\"overlay_light\":\"\",\"overlay_dark\":\"\",\"overlay_width\":80,\"overlay_height\":80,\"category\":\"Qubic Resources\",\"youtube_id\":\"\",\"isRoot\":false,\"node_type\":\"leaf\",\"open_behavior\":\"popup\",\"pulse_rate\":40},{\"id\":13,\"label\":\"Neuraxon Intelligence Part 5\",\"url\":\"https:\/\/qubic.org\/blog-detail\/astrocytes-neuraxon-intelligence-academy-vol-5\",\"image_light\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/neuraxon-5.png\",\"image_dark\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/neuraxon-5.png\",\"overlay_light\":\"\",\"overlay_dark\":\"\",\"overlay_width\":80,\"overlay_height\":80,\"category\":\"\",\"youtube_id\":\"\",\"isRoot\":false,\"node_type\":\"leaf\",\"open_behavior\":\"popup\",\"pulse_rate\":40},{\"id\":14,\"label\":\"Neuraxon Intelligence Part VI\",\"url\":\"https:\/\/qubic.org\/blog-detail\/conscious-machines-intelligent-organisms-ai-consciousness-neuraxon-vol-6\",\"image_light\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/neuraxon-6.png\",\"image_dark\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/neuraxon-6.png\",\"overlay_light\":\"\",\"overlay_dark\":\"\",\"overlay_width\":80,\"overlay_height\":80,\"category\":\"Qubic Resources\",\"youtube_id\":\"\",\"isRoot\":false,\"node_type\":\"leaf\",\"open_behavior\":\"popup\",\"pulse_rate\":40},{\"id\":15,\"label\":\"Neuraxon Intelligence Part VII\",\"url\":\"https:\/\/qubic.org\/blog-detail\/conways-game-of-life-artificial-life-digital-ecosystems-qubic-neuraxon-nia-vol-7\",\"image_light\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/neuraxon-7.png\",\"image_dark\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/neuraxon-7.png\",\"overlay_light\":\"\",\"overlay_dark\":\"\",\"overlay_width\":80,\"overlay_height\":80,\"category\":\"Qubic Resources\",\"youtube_id\":\"\",\"isRoot\":false,\"node_type\":\"leaf\",\"open_behavior\":\"popup\",\"pulse_rate\":40},{\"id\":16,\"label\":\"Neuraxon Info\",\"url\":\"https:\/\/huggingface.co\/spaces\/DavidVivancos\/\",\"image_light\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/neuraxon-Info.png\",\"image_dark\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/neuraxon-Info.png\",\"overlay_light\":\"\",\"overlay_dark\":\"\",\"overlay_width\":80,\"overlay_height\":80,\"category\":\"Qubic Resources\",\"youtube_id\":\"\",\"isRoot\":false,\"node_type\":\"leaf\",\"open_behavior\":\"popup\",\"pulse_rate\":40},{\"id\":17,\"label\":\"Neuraxon Intelligence Part VIII\",\"url\":\"https:\/\/qubic.org\/blog-detail\/brain-criticality-branching-ratio-neural-artificial-networks-neuraxon-nia-vol-8\",\"image_light\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/neuraxon-8.png\",\"image_dark\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/neuraxon-8.png\",\"overlay_light\":\"\",\"overlay_dark\":\"\",\"overlay_width\":80,\"overlay_height\":80,\"category\":\"Qubic Resources\",\"youtube_id\":\"\",\"isRoot\":false,\"node_type\":\"leaf\",\"open_behavior\":\"popup\"},{\"id\":18,\"label\":\"Neuraxon on GitHub\",\"url\":\"https:\/\/github.com\/DavidVivancos\/Neuraxon\",\"image_light\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/NeuraxononGithub-1.png\",\"image_dark\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/NeuraxononGithub-1.png\",\"overlay_light\":\"\",\"overlay_dark\":\"\",\"overlay_width\":80,\"overlay_height\":80,\"category\":\"Qubic Resources\",\"youtube_id\":\"\",\"isRoot\":false,\"node_type\":\"leaf\",\"open_behavior\":\"popup\"},{\"id\":19,\"label\":\"Neuraxon Intelligence Part IX\",\"url\":\"https:\/\/qubic.org\/blog-detail\/g-factor-general-intelligence-artificial-life-neuraxon-nia-vol-9\",\"image_light\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/Neuraxon-9.png\",\"image_dark\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/Neuraxon-9.png\",\"overlay_light\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/Neuraxon-9.png\",\"overlay_dark\":\"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/05\/Neuraxon-9.png\",\"overlay_width\":80,\"overlay_height\":80,\"category\":\"Qubic Resources\",\"youtube_id\":\"\",\"isRoot\":false,\"node_type\":\"leaf\",\"open_behavior\":\"popup\"}],\"links\":[{\"source\":1,\"target\":2},{\"source\":1,\"target\":3},{\"source\":1,\"target\":4},{\"source\":1,\"target\":5},{\"source\":1,\"target\":8},{\"source\":1,\"target\":9},{\"source\":1,\"target\":6},{\"source\":1,\"target\":7},{\"source\":1,\"target\":10},{\"source\":1,\"target\":11},{\"source\":1,\"target\":12},{\"source\":1,\"target\":13},{\"source\":1,\"target\":14},{\"source\":1,\"target\":15},{\"source\":1,\"target\":16},{\"source\":1,\"target\":17},{\"source\":1,\"target\":18},{\"source\":1,\"target\":19}],\"custom_layout\":{\"1\":{\"x\":0.48886213124623723,\"y\":0.4946875,\"scale\":1},\"2\":{\"x\":0.2937989163154726,\"y\":0.1182589285714286,\"scale\":1},\"3\":{\"x\":0.1672800603547926,\"y\":0.7932589285714285,\"scale\":1},\"4\":{\"x\":0.08679504990889446,\"y\":0.4246875,\"scale\":1},\"5\":{\"x\":0.3179438887516282,\"y\":0.9239732142857143,\"scale\":1},\"6\":{\"x\":0.12576403756019214,\"y\":0.6032440403529576,\"scale\":1},\"7\":{\"x\":0.16499556382883954,\"y\":0.2161011832101004,\"scale\":1},\"8\":{\"x\":0.43123389524382894,\"y\":0.05,\"scale\":1},\"9\":{\"x\":0.5715308660604455,\"y\":0.0857143293108259,\"scale\":1},\"10\":{\"x\":0.7198385620603416,\"y\":0.12571435110909598,\"scale\":1},\"11\":{\"x\":0.8315033190214728,\"y\":0.23000004359654014,\"scale\":1},\"12\":{\"x\":0.9170536581077646,\"y\":0.3814286150251116,\"scale\":1},\"13\":{\"x\":0.9177872784502298,\"y\":0.5171429007393973,\"scale\":1},\"14\":{\"x\":0.8479237199812097,\"y\":0.6257142857142857,\"scale\":1},\"15\":{\"x\":0.7773570728520776,\"y\":0.7285714285714285,\"scale\":1},\"16\":{\"x\":0.48555434352714094,\"y\":0.9385714285714286,\"scale\":1},\"17\":{\"x\":0.6860077664057797,\"y\":0.82,\"scale\":1},\"18\":{\"x\":0.33613690547862735,\"y\":0.4857142857142857,\"scale\":1},\"19\":{\"x\":0.6016559903672486,\"y\":0.89,\"scale\":1}},\"custom_layout_portrait\":{\"1\":{\"x\":0.14268512944009631,\"y\":0.48111607142857143,\"scale\":1},\"2\":{\"x\":0.45771725728397217,\"y\":0.8739732142857143,\"scale\":1},\"3\":{\"x\":0.45902867005408987,\"y\":0.11825892857142857,\"scale\":1},\"4\":{\"x\":0.8099047043984808,\"y\":0.3196875,\"scale\":1},\"5\":{\"x\":0.8220983665717111,\"y\":0.6254017857142857,\"scale\":1},\"6\":{\"x\":0.1667397899862173,\"y\":0.9032440185546875,\"scale\":1},\"7\":{\"x\":0.1582303485808357,\"y\":0.10324404035295758,\"scale\":1},\"8\":{\"x\":0.6201758080313418,\"y\":0.17142857142857143,\"scale\":1},\"9\":{\"x\":0.21664575091058863,\"y\":0.16857145036969867,\"scale\":1},\"10\":{\"x\":0.3607290789596389,\"y\":0.19,\"scale\":1},\"11\":{\"x\":0.482969430146015,\"y\":0.2328571428571429,\"scale\":1},\"12\":{\"x\":0.5739812373423925,\"y\":0.32142857142857145,\"scale\":1},\"13\":{\"x\":0.654815996856769,\"y\":0.4214285714285715,\"scale\":1},\"14\":{\"x\":0.6566591505271604,\"y\":0.5442857142857143,\"scale\":1},\"15\":{\"x\":0.5877736504507096,\"y\":0.64,\"scale\":1},\"16\":{\"x\":0.8787912211797019,\"y\":0.46714285714285714,\"scale\":1},\"17\":{\"x\":0.47228109572546656,\"y\":0.72,\"scale\":1},\"18\":{\"x\":0.6510074653822998,\"y\":0.7885714285714286,\"scale\":1},\"19\":{\"x\":0.31146935580975316,\"y\":0.7942857142857143,\"scale\":1}}};\n        let nodesData = rawData.nodes.map(d => ({...d}));\n        let linksData = rawData.links.map(d => ({...d}));\n\n        preloadAndMeasureImages(nodesData).then(() => {\n            loadingEl.style.opacity = '0';\n            setTimeout(() => {\n                loadingEl.style.display = 'none';\n                container.style.opacity = '1';\n                initMindmap();\n            }, 300);\n        });\n\n        function initMindmap() {\n            let svg, g, defs, lineGroup, nodeGroup, lines, nodeElements, currentNodes, currentLinks, energyGroup;\n            let currentIsDark = isDarkTheme();\n            let width = container.clientWidth;\n            let height = container.clientHeight;\n\n            let activePulses = new Map();\n            let currentOpenNodeId = null;\n\n            function isDarkTheme() {\n                const bodyTheme = document.body.getAttribute('data-theme');\n                if (bodyTheme === 'dark') return true;\n                if (bodyTheme === 'light') return false;\n                return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;\n            }\n\n            function getPulseColor() {\n                return currentIsDark ? '#fff' : '#8cf';\n            }\n\n            function getBorderColor() {\n                return currentIsDark ? '#fff' : '#8cf';\n            }\n\n            function getHoverBorderColor() {\n                return currentIsDark ? '#fff' : '#000';\n            }\n\n            function getHighlightColor() {\n                return currentIsDark ? '#fff' : '#333333';\n            }\n\n            function getLinkColor(link) {\n                const isPaidLink = (link.source && link.source.node_type === 'paid') ||\n                                   (link.target && link.target.node_type === 'paid');\n                return isPaidLink ? '#fc0' : (currentIsDark ? '#2ff' : '#88ccff');\n            }\n\n            function isPortrait() {\n                return window.innerHeight > window.innerWidth * 1.05;\n            }\n\n            function isTablet() {\n                const w = window.innerWidth;\n                return w >= 768 && w <= 1024;\n            }\n\n            function cleanupPulses() {\n                if (energyGroup) energyGroup.selectAll('.energy-pulse').interrupt().remove();\n                activePulses.clear();\n            }\n\n            function createMindmapElements() {\n                if (svg) svg.remove();\n\n                svg = d3.select('#imm-container').append('svg')\n                    .attr('width', width)\n                    .attr('height', height)\n                    .attr('viewBox', `0 0 ${width} ${height}`)\n                    .attr('preserveAspectRatio', 'xMidYMid meet');\n\n                g = svg.append('g');\n                defs = svg.append('defs');\n\n                const glowFilter = defs.append('filter').attr('id', 'root-glow')\n                    .attr('x', '-50%').attr('y', '-50%')\n                    .attr('width', '200%').attr('height', '200%');\n                glowFilter.append('feGaussianBlur').attr('stdDeviation', '10').attr('result', 'coloredBlur');\n                const feMerge = glowFilter.append('feMerge');\n                feMerge.append('feMergeNode').attr('in', 'coloredBlur');\n                feMerge.append('feMergeNode').attr('in', 'SourceGraphic');\n\n                const energyGlow = defs.append('filter').attr('id', 'energy-glow')\n                    .attr('x', '-200%').attr('y', '-200%')\n                    .attr('width', '400%').attr('height', '400%');\n                energyGlow.append('feGaussianBlur').attr('stdDeviation', '6.5').attr('result', 'blur');\n                const energyMerge = energyGlow.append('feMerge');\n                energyMerge.append('feMergeNode').attr('in', 'blur');\n                energyMerge.append('feMergeNode').attr('in', 'SourceGraphic');\n\n                const hexPath = \"M 0,-1 L 0.866,-0.5 L 0.866,0.5 L 0,1 L -0.866,0.5 L -0.866,-0.5 Z\";\n\n                let root = nodesData.find(n => n.isRoot) || nodesData[0];\n                const rootId = root.id;\n\n                const filteredNodes = nodesData.filter(n => n.isRoot || linksData.some(l => (l.target.id || l.target) === n.id && (l.source.id || l.source) === rootId));\n                const filteredLinks = linksData.filter(l => {\n                    const s = l.source.id || l.source;\n                    const t = l.target.id || l.target;\n                    return filteredNodes.some(n => n.id === s) && filteredNodes.some(n => n.id === t);\n                });\n\n                currentNodes = filteredNodes.map(d => ({...d}));\n                currentLinks = filteredLinks.map(l => ({\n                    source: currentNodes.find(n => n.id === (l.source.id || l.source)),\n                    target: currentNodes.find(n => n.id === (l.target.id || l.target))\n                })).filter(l => l.source && l.target);\n\n                lineGroup = g.append('g');\n                nodeGroup = g.append('g');\n                energyGroup = lineGroup.append('g').attr('class', 'energy-group');\n\n                const portrait = isPortrait();\n                const tablet   = isTablet();\n                let baseScale = 0.8;\n                let rootScale = 0.8;\n                if (tablet) {\n                    baseScale = 0.75;\n                    rootScale = 0.75;\n                } else if (portrait) {\n                    baseScale = 0.60;\n                    rootScale = 0.5;\n                }\n\n                lines = lineGroup.selectAll('line')\n                    .data(currentLinks)\n                    .join('line')\n                    .attr('stroke', d => getLinkColor(d))\n                    .attr('stroke-width', d => ((d.source && d.source.node_type === 'paid') || (d.target && d.target.node_type === 'paid')) ? 5 : 1)\n                    .attr('data-source', d => d.source.id)\n                    .attr('data-target', d => d.target.id);\n\n                nodeElements = nodeGroup.selectAll('g')\n                    .data(currentNodes)\n                    .join('g')\n                    .attr('class', 'clickable-node');\n\n                nodeElements.each(function(d) {\n                    const gNode = d3.select(this);\n                    let nodeScale = d.isRoot ? rootScale : baseScale;\n                    nodeScale *= (d.custom_scale || 1.15);\n\n                    if (d.isRoot) {\n                        const mainSrc = currentIsDark ? (d.image_dark || d.image_light) : d.image_light;\n                        const rootImg = gNode.append('image')\n                            .attr('class', 'root-main-image')\n                            .attr('xlink:href', mainSrc)\n                            .attr('height', 155 * nodeScale)\n                            .attr('preserveAspectRatio', 'xMidYMid meet');\n\n                        rootImg.on('load', function() {\n                            const bbox = this.getBBox();\n                            d3.select(this).attr('x', -bbox.width \/ 2).attr('y', -bbox.height \/ 2);\n                        });\n\n                        const overlayUrl = currentIsDark ? (d.overlay_dark || d.overlay_light) : d.overlay_light;\n                        if (overlayUrl) {\n                            const overlayW = (parseFloat(d.overlay_width) || 80) * nodeScale;\n                            const overlayH = (parseFloat(d.overlay_height) || 80) * nodeScale;\n                            gNode.append('image')\n                                .attr('class', 'root-overlay')\n                                .attr('xlink:href', overlayUrl)\n                                .attr('width', overlayW)\n                                .attr('height', overlayH)\n                                .attr('x', -overlayW \/ 2)\n                                .attr('y', -overlayH \/ 2)\n                                .attr('preserveAspectRatio', 'xMidYMid meet');\n                        }\n                    } \n                    else if (d.node_type === 'paid') {\n                        const radius = 55 * nodeScale;\n\n                        const border = gNode.append('circle')\n                            .attr('class', 'paid-border')\n                            .attr('r', radius + 1)\n                            .attr('stroke', getBorderColor())\n                            .attr('stroke-width', 0)\n                            .attr('fill', 'none');\n\n                        border.attr('data-original-width', '0')\n                              .attr('data-original-color', getBorderColor());\n\n                        const clipId = 'clip-paid-' + d.id;\n                        defs.append('clipPath').attr('id', clipId)\n                            .append('circle').attr('r', radius);\n\n                        const mainImageUrl = currentIsDark ? (d.image_dark || d.image_light) : d.image_light;\n                        const mainImg = gNode.append('image')\n                            .attr('xlink:href', mainImageUrl)\n                            .attr('width', radius * 2)\n                            .attr('height', radius * 2)\n                            .attr('x', -radius)\n                            .attr('y', -radius)\n                            .attr('preserveAspectRatio', 'xMidYMid cover');\n\n                        const overlayUrl = currentIsDark ? (d.overlay_dark || d.overlay_light) : d.overlay_light;\n                        if (overlayUrl) {\n                            mainImg.on('mouseover', function() {\n                                d3.select(this).attr('xlink:href', overlayUrl);\n                            }).on('mouseout', function() {\n                                d3.select(this).attr('xlink:href', mainImageUrl);\n                            });\n                        }\n                    } \n                    else if (d.node_type === 'newroot') {\n                        const radius = 50 * nodeScale;\n                        const clipId = 'clip-hex-' + d.id;\n                        if (!defs.select('#' + clipId).empty()) defs.select('#' + clipId).remove();\n\n                        defs.append('clipPath').attr('id', clipId)\n                            .append('path').attr('d', hexPath).attr('transform', `scale(${radius})`);\n\n                        const hexBorder = gNode.append('path')\n                            .attr('class', 'hex-border')\n                            .attr('d', hexPath)\n                            .attr('transform', `scale(${radius})`)\n                            .attr('fill','none')\n                            .attr('stroke', '#2ff')\n                            .attr('stroke-width', 0.10);\n\n                        hexBorder.attr('data-original-width', '0.10')\n                                 .attr('data-original-color', '#2ff');\n\n                        const mainImageUrl = currentIsDark ? (d.image_dark || d.image_light) : d.image_light;\n                        const mainImg = gNode.append('image')\n                            .attr('xlink:href', mainImageUrl)\n                            .attr('width', 90 * nodeScale)\n                            .attr('height', 90 * nodeScale)\n                            .attr('x', -45 * nodeScale)\n                            .attr('y', -45 * nodeScale)\n                            .attr('clip-path', `url(#${clipId})`)\n                            .attr('preserveAspectRatio', 'xMidYMid slice');\n\n                        const overlayUrl = currentIsDark ? (d.overlay_dark || d.overlay_light) : d.overlay_light;\n                        if (overlayUrl) {\n                            mainImg.on('mouseover', function() {\n                                d3.select(this).attr('xlink:href', overlayUrl);\n                            }).on('mouseout', function() {\n                                d3.select(this).attr('xlink:href', mainImageUrl);\n                            });\n                        }\n                    } \n                    else if (d.node_type === 'square') {\n                        const size = 90 * nodeScale;\n                        const mainImageUrl = currentIsDark ? (d.image_dark || d.image_light) : d.image_light;\n                        const overlayUrl = currentIsDark ? (d.overlay_dark || d.overlay_light) : d.overlay_light;\n\n                        const mainImg = gNode.append('image')\n                            .attr('xlink:href', mainImageUrl)\n                            .attr('x', -size\/2 + 6)\n                            .attr('y', -size\/2 + 6)\n                            .attr('width', size - 12)\n                            .attr('height', size - 12)\n                            .attr('preserveAspectRatio', 'xMidYMid meet');\n\n                        if (overlayUrl) {\n                            mainImg.on('mouseover', function() {\n                                d3.select(this).attr('xlink:href', overlayUrl);\n                            }).on('mouseout', function() {\n                                d3.select(this).attr('xlink:href', mainImageUrl);\n                            });\n                        }\n                    } \n                    else {\n                        const baseHeight = 60 * nodeScale;\n                        const realW = d.realWidth  || 52;\n                        const realH = d.realHeight || 52;\n\n                        const heightScale = baseHeight \/ realH;\n                        const renderW = realW * heightScale;\n                        const renderH = baseHeight;\n\n                        const borderCircle = gNode.append('circle')\n                            .attr('r', 37 * nodeScale)\n                            .attr('fill','none')\n                            .attr('stroke', 'none')\n                            .attr('stroke-width', 0);\n\n                        borderCircle.attr('data-original-width', '0')\n                                    .attr('data-original-color', 'none');\n\n                        const mainImageUrl = currentIsDark ? (d.image_dark || d.image_light) : d.image_light;\n                        const overlayUrl = currentIsDark ? (d.overlay_dark || d.overlay_light) : d.overlay_light;\n\n                        const mainImg = gNode.append('image')\n                            .attr('xlink:href', mainImageUrl)\n                            .attr('width', renderW)\n                            .attr('height', renderH)\n                            .attr('x', -renderW \/ 2)\n                            .attr('y', -renderH \/ 2)\n                            .attr('preserveAspectRatio', 'xMidYMid meet');\n\n                        if (overlayUrl) {\n                            mainImg.on('mouseover', function() {\n                                d3.select(this).attr('xlink:href', overlayUrl);\n                            }).on('mouseout', function() {\n                                d3.select(this).attr('xlink:href', mainImageUrl);\n                            });\n                        }\n                    }\n\n                    gNode.on('click', function(event) {\n                        event.stopImmediatePropagation();\n                        const hasVideo = !!(d.youtube_id && d.youtube_id.trim());\n\n                        if (hasVideo) {\n                            let videoId = d.youtube_id.trim();\n                            if (videoId.includes('youtube.com') || videoId.includes('youtu.be')) {\n                                const match = videoId.match(\/(?:v=|youtu\\.be\\\/)([^&\\n?#]+)\/);\n                                if (match) videoId = match[1];\n                            }\n                            currentOpenNodeId = d.id;\n\n                            const youtubePanel = document.getElementById('imm-youtube-panel');\n                            const youtubeIframe = document.getElementById('imm-youtube-iframe');\n\n                            if (youtubePanel.style.display === 'block') {\n                                youtubePanel.style.display = 'none';\n                                youtubeIframe.src = '';\n                                currentOpenNodeId = null;\n                            } else {\n                                youtubeIframe.src = `https:\/\/www.youtube.com\/embed\/${videoId}?autoplay=1&loop=1&playlist=${videoId}&mute=0&controls=1`;\n                                youtubePanel.style.display = 'block';\n                            }\n                            return;\n                        }\n\n                        if (d.url) {\n                            const url = d.url.trim();\n                            const behavior = d.open_behavior || 'popup';\n                            if (behavior === 'popup') {\n                                let w = Math.min(920, window.innerWidth * 0.92);\n                                let h = Math.min(720, window.innerHeight * 0.85);\n                                const left = (screen.width - w) \/ 2;\n                                const top = (screen.height - h) \/ 2 - 40;\n                                window.open(url, '_blank', `width=${Math.round(w)},height=${Math.round(h)},top=${Math.round(top)},left=${Math.round(left)},resizable=yes,scrollbars=yes`);\n                            } else if (behavior === 'self') {\n                                window.location.href = url;\n                            } else {\n                                window.open(url, '_blank');\n                            }\n                        }\n                    });\n                });\n\n                return { lines, nodeElements, energyGroup, currentNodes };\n            }\n\n            function layoutNodes() {\n                width = container.clientWidth;\n                height = container.clientHeight;\n\n                const portraitMode = isPortrait();\n                const layoutKey = portraitMode ? 'custom_layout_portrait' : 'custom_layout';\n\n                if (rawData[layoutKey] && Object.keys(rawData[layoutKey]).length > 0) {\n                    currentNodes.forEach(node => {\n                        const saved = rawData[layoutKey][node.id];\n                        if (saved) {\n                            node.x = saved.x * width;\n                            node.y = saved.y * height;\n                            node.custom_scale = saved.scale || 1.0;\n                        }\n                    });\n                    return;\n                }\n\n                let root = currentNodes.find(n => n.isRoot);\n                root.x = portraitMode ? 45 : width \/ 2;\n                root.y = height \/ 2;\n\n                let children = currentNodes.filter(n => !n.isRoot);\n                if (children.length === 0) return;\n\n                children.sort((a, b) => a.id - b.id);\n\n                const hexes   = children.filter(n => n.node_type === 'newroot');\n                const squares = children.filter(n => n.node_type === 'square');\n                const paids   = children.filter(n => n.node_type === 'paid');\n                const leaves  = children.filter(n => n.node_type === 'leaf' || !n.node_type);\n\n                const baseMaxDist = Math.min(width, height) * 0.42;\n                const leafMaxDistLandscape = width * 0.43;\n\n                const angleSpan = portraitMode ? Math.PI : Math.PI * 2;\n\n                let hexDistFactor    = 0.43;\n                let squareDistFactor = 0.87;\n                let paidDistFactor   = 0.70;\n                let leafDistFactor   = 1.3;\n\n                if (portraitMode) {\n                    hexDistFactor    = 5\/13;\n                    squareDistFactor = 12\/13;\n                    paidDistFactor   = 9\/13;\n                    leafDistFactor   = 19\/13;\n                }\n\n                function placeType(group, radiusFraction, typeOffset = 0) {\n                    const count = group.length;\n                    if (count === 0) return;\n                    let startAngle = portraitMode ? -Math.PI \/ 2 : -Math.PI \/ 2 + 0.2;\n                    startAngle += typeOffset * (angleSpan \/ 20);\n                    const step = angleSpan \/ Math.max(count, 1);\n                    group.forEach((node, i) => {\n                        const angle = startAngle + i * step;\n                        const dist = baseMaxDist * radiusFraction;\n                        node.x = root.x + Math.cos(angle) * dist;\n                        node.y = root.y + Math.sin(angle) * dist;\n                    });\n                }\n\n                placeType(hexes,   hexDistFactor,    -0.7);\n                placeType(squares, squareDistFactor,  0.0);\n                placeType(paids,   paidDistFactor,    0.3);\n                placeType(leaves,  leafDistFactor,    0.6);\n\n                children.forEach(node => {\n                    node.angle = Math.atan2(node.y - root.y, node.x - root.x);\n                    if (node.angle < 0) node.angle += Math.PI * 2;\n                });\n                children.sort((a, b) => a.angle - b.angle);\n\n                const globalStep = angleSpan \/ children.length;\n                const startAngle = portraitMode ? -Math.PI \/ 2 : -Math.PI \/ 2 + 0.1;\n\n                children.forEach((node, i) => {\n                    const targetAngle = startAngle + i * globalStep;\n                    const currentDist = Math.hypot(node.x - root.x, node.y - root.y);\n                    node.x = root.x + Math.cos(targetAngle) * currentDist;\n                    node.y = root.y + Math.sin(targetAngle) * currentDist;\n                });\n\n                for (let iter = 0; iter < 10; iter++) {\n                    let moved = false;\n                    for (let a = 0; a < children.length; a++) {\n                        for (let b = a + 1; b < children.length; b++) {\n                            const A = children[a], B = children[b];\n                            if (A.node_type !== 'leaf' || B.node_type !== 'leaf') continue;\n                            const dx = Math.abs(A.x - B.x);\n                            const dy = A.y - B.y;\n                            if (dx > 150) continue;\n                            const minSep = Math.max(A.realHeight || 50, B.realHeight || 50) * 1.05 + 25;\n                            if (Math.abs(dy) < minSep) {\n                                moved = true;\n                                const push = (minSep - Math.abs(dy)) \/ 2 * 0.85;\n                                if (dy >= 0) { A.y += push; B.y -= push; } else { A.y -= push; B.y += push; }\n                            }\n                        }\n                    }\n                    if (!moved) break;\n                }\n\n                staggerSameTypeDistances(squares, root, baseMaxDist);\n                applyEvenAngularSpacing(children, root, baseMaxDist, portraitMode, angleSpan);\n                separateOverlappingLeaves(children, height);\n\n                const portraitLeaves = children.filter(n => n.node_type === 'leaf' || !n.node_type);\n                if (portraitMode && portraitLeaves.length >= 3) {\n                    const degToRad = Math.PI \/ 180;\n                    const topAngle    = -Math.PI \/ 2 + 1 * degToRad;\n                    const bottomAngle =  Math.PI \/ 2 - 1 * degToRad;\n                    const leafSpan    = bottomAngle - topAngle;\n                    const leafStep    = leafSpan \/ (portraitLeaves.length - 1);\n\n                    portraitLeaves.sort((a, b) => a.id - b.id);\n\n                    portraitLeaves.forEach((node, i) => {\n                        const angle = topAngle + i * leafStep;\n                        const dist  = baseMaxDist * leafDistFactor;\n                        node.x = root.x + Math.cos(angle) * dist;\n                        node.y = root.y + Math.sin(angle) * dist;\n                    });\n                }\n\n                if (!portraitMode) {\n                    portraitLeaves.forEach(node => {\n                        const currentDist = Math.hypot(node.x - root.x, node.y - root.y);\n                        if (currentDist > leafMaxDistLandscape) {\n                            const angle = Math.atan2(node.y - root.y, node.x - root.x);\n                            node.x = root.x + Math.cos(angle) * leafMaxDistLandscape;\n                            node.y = root.y + Math.sin(angle) * leafMaxDistLandscape;\n                        }\n                    });\n                }\n\n                const padding = 55;\n                children.forEach(node => {\n                    node.x = Math.max(padding, Math.min(width - padding, node.x));\n                    node.y = Math.max(padding, Math.min(height - padding, node.y));\n                });\n\n                staggerLeavesAfterClamp(portraitLeaves, root, baseMaxDist);\n            }\n\n            function staggerSameTypeDistances(group, root, maxDist) {\n                if (group.length < 2) return;\n                const staggerAmount = maxDist \/ 11;\n                group.forEach((node, i) => {\n                    const currentDist = Math.hypot(node.x - root.x, node.y - root.y);\n                    const sign = (i % 2 === 0) ? -1 : -2.5;\n                    const newDist = Math.max(maxDist * 0.5, currentDist + sign * staggerAmount);\n                    const angle = Math.atan2(node.y - root.y, node.x - root.x);\n                    node.x = root.x + Math.cos(angle) * newDist;\n                    node.y = root.y + Math.sin(angle) * newDist;\n                });\n            }\n\n            function staggerLeavesAfterClamp(leaves, root, maxDist) {\n                if (leaves.length < 2) return;\n                const staggerAmount = maxDist \/ 13;\n                leaves.sort((a, b) => a.angle - b.angle);\n                leaves.forEach((node, i) => {\n                    const currentDist = Math.hypot(node.x - root.x, node.y - root.y);\n                    const sign = (i % 2 === 0) ? 1 : -1.5;\n                    const newDist = Math.max(maxDist * 0.55, currentDist + sign * staggerAmount);\n                    const angle = Math.atan2(node.y - root.y, node.x - root.x);\n                    node.x = root.x + Math.cos(angle) * newDist;\n                    node.y = root.y + Math.sin(angle) * newDist;\n                });\n            }\n\n            function applyEvenAngularSpacing(children, root, maxDist, portrait, angleSpan) {\n                if (children.length < 2) return;\n                const startAngle = portrait ? -Math.PI \/ 2 : -Math.PI \/ 2 + 0.1;\n                const step = angleSpan \/ children.length;\n                children.forEach((node, i) => {\n                    const idealAngle = startAngle + i * step;\n                    const dist = Math.hypot(node.x - root.x, node.y - root.y);\n                    node.x = root.x + Math.cos(idealAngle) * dist;\n                    node.y = root.y + Math.sin(idealAngle) * dist;\n                });\n            }\n\n            function separateOverlappingLeaves(children, screenHeight) {\n                const leaves = children.filter(n => n.node_type === 'leaf' || !n.node_type);\n                if (leaves.length < 2) return;\n                const centerY = screenHeight \/ 2;\n                const minGap = 5;\n                for (let iter = 0; iter < 12; iter++) {\n                    let moved = false;\n                    for (let i = 0; i < leaves.length; i++) {\n                        for (let j = i + 1; j < leaves.length; j++) {\n                            const A = leaves[i];\n                            const B = leaves[j];\n                            const dx = Math.abs(A.x - B.x);\n                            if (dx > 120) continue;\n                            const halfA = (A.realHeight || 50) \/ 2;\n                            const halfB = (B.realHeight || 50) \/ 2;\n                            const minSep = halfA + halfB + minGap;\n                            const dy = A.y - B.y;\n                            if (Math.abs(dy) < minSep) {\n                                moved = true;\n                                const push = (minSep - Math.abs(dy)) * 0.2;\n                                const distA = Math.abs(A.y - centerY);\n                                const distB = Math.abs(B.y - centerY);\n                                if (distA < distB) {\n                                    if (dy > 0) A.y += push; else A.y -= push;\n                                } else {\n                                    if (dy > 0) B.y -= push; else B.y += push;\n                                }\n                            }\n                        }\n                    }\n                    if (!moved) break;\n                }\n            }\n\n            function updatePositions(linesSel, nodesSel) {\n                linesSel.each(function(d) {\n                    d3.select(this)\n                        .attr('x1', d.source.x).attr('y1', d.source.y)\n                        .attr('x2', d.target.x).attr('y2', d.target.y);\n                });\n                nodesSel.attr('transform', d => `translate(${d.x}, ${d.y})`);\n            }\n\n            function updateAllImages() {\n                const isDark = isDarkTheme();\n                if (isDark === currentIsDark) return;\n                currentIsDark = isDark;\n\n                nodeElements.each(function(d) {\n                    const gNode = d3.select(this);\n                    if (d.isRoot) {\n                        const mainSrc = isDark ? (d.image_dark || d.image_light) : d.image_light;\n                        gNode.select('.root-main-image').attr('xlink:href', mainSrc);\n                        const overlaySrc = isDark ? (d.overlay_dark || d.overlay_light) : d.overlay_light;\n                        const overlayImg = gNode.select('.root-overlay');\n                        if (!overlayImg.empty() && overlaySrc) overlayImg.attr('xlink:href', overlaySrc);\n                    } else {\n                        const mainSrc = isDark ? (d.image_dark || d.image_light) : d.image_light;\n                        gNode.select('image').filter(function() {\n                            return !d3.select(this).classed('root-overlay');\n                        }).attr('xlink:href', mainSrc);\n                    }\n                });\n\n                lines.attr('stroke', d => getLinkColor(d));\n            }\n\n            function createPulseOnLink(link, baseDelay = 0) {\n                const linkId = `${link.source.id}-${link.target.id}`;\n                if (activePulses.has(linkId)) return;\n\n                const dx = link.target.x - link.source.x;\n                const dy = link.target.y - link.source.y;\n                const length = Math.sqrt(dx*dx + dy*dy);\n                if (length < 20) return;\n\n                const pulseColor = getPulseColor();\n                const pulse = energyGroup.append('path')\n                    .attr('class', 'energy-pulse')\n                    .attr('stroke', pulseColor)\n                    .attr('d', `M ${link.source.x} ${link.source.y} L ${link.target.x} ${link.target.y}`)\n                    .attr('stroke-dasharray', '23, ' + (length - 23))\n                    .attr('stroke-dashoffset', length);\n\n                activePulses.set(linkId, true);\n\n                const extraRandomDelay = Math.random() * 650;\n                const duration = 750 + Math.random() * 950;\n\n                pulse.transition()\n                    .delay(baseDelay + extraRandomDelay)\n                    .duration(duration)\n                    .ease(d3.easeLinear)\n                    .attr('stroke-dashoffset', 0)\n                    .on('end', () => {\n                        pulse.remove();\n                        activePulses.delete(linkId);\n                    });\n            }\n\n            function startEnergyFlow() {\n                const rootLinks = currentLinks.filter(l => l.source.isRoot);\n                const otherLinks = currentLinks.filter(l => !l.source.isRoot);\n                rootLinks.forEach((link, i) => createPulseOnLink(link, i * 180));\n                otherLinks.forEach(link => createPulseOnLink(link, Math.random() * 400));\n                setTimeout(startEnergyFlow, 900 + Math.random() * 1100);\n            }\n\n            let result = createMindmapElements();\n            lines = result.lines;\n            nodeElements = result.nodeElements;\n            energyGroup = result.energyGroup;\n            currentNodes = result.currentNodes;\n\n            layoutNodes();\n            updatePositions(lines, nodeElements);\n\n            \/\/ Hover handlers (placed AFTER layout & positioning so transforms are correct)\n            nodeElements.filter(d => !d.isRoot).each(function(d) {\n                const nodeSel = d3.select(this);\n                const nodeId = d.id;\n\n                const connectedLine = lines.filter(l => \n                    (l.source && l.source.id === nodeId) || (l.target && l.target.id === nodeId)\n                );\n\n                let borderEl = null;\n                if (d.node_type === 'paid') {\n                    borderEl = nodeSel.select('.paid-border');\n                } else if (d.node_type === 'newroot') {\n                    borderEl = nodeSel.select('.hex-border');\n                } else {\n                    borderEl = nodeSel.select('circle[stroke]');\n                }\n\n                const originalLineWidth = connectedLine.attr('stroke-width') || 1;\n\n                nodeSel.on('mouseover', function() {\n                    \/\/ Scale around center (content is already at local (0,0))\n                    const tx = d.x || 0;\n                    const ty = d.y || 0;\n                    nodeSel.transition().duration(120)\n                        .attr('transform', `translate(${tx}, ${ty}) scale(1.05)`);\n\n                    if (borderEl && borderEl.node()) {\n                        const origW = parseFloat(borderEl.attr('data-original-width') || 0);\n                        if (origW > 0) {\n                            borderEl\n                                .attr('stroke', getHoverBorderColor())\n                                .attr('stroke-width', origW * 1.5);\n                        }\n                    }\n\n                    if (connectedLine.node()) {\n                        connectedLine\n                            .attr('stroke', getHoverBorderColor())\n                            .attr('stroke-width', 5);\n                    }\n                })\n                .on('mouseout', function() {\n                    const tx = d.x || 0;\n                    const ty = d.y || 0;\n                    nodeSel.transition().duration(120)\n                        .attr('transform', `translate(${tx}, ${ty})`);\n\n                    if (borderEl && borderEl.node()) {\n                        const origW = parseFloat(borderEl.attr('data-original-width') || 0);\n                        const origColor = borderEl.attr('data-original-color') || getBorderColor();\n                        if (origW > 0) {\n                            borderEl\n                                .attr('stroke', origColor)\n                                .attr('stroke-width', origW);\n                        }\n                    }\n\n                    if (connectedLine.node()) {\n                        connectedLine\n                            .attr('stroke', getLinkColor(connectedLine.datum()))\n                            .attr('stroke-width', originalLineWidth);\n                    }\n                });\n            });\n\n            setTimeout(() => startEnergyFlow(), 150);\n\n            const observer = new MutationObserver(updateAllImages);\n            observer.observe(document.body, { attributes: true, attributeFilter: ['data-theme'] });\n            if (window.matchMedia) window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', updateAllImages);\n\n            let resizeTimeout;\n            function resizeAndUpdate() {\n                clearTimeout(resizeTimeout);\n                resizeTimeout = setTimeout(() => {\n                    cleanupPulses();\n                    width = container.clientWidth;\n                    height = container.clientHeight;\n\n                    result = createMindmapElements();\n                    lines = result.lines;\n                    nodeElements = result.nodeElements;\n                    energyGroup = result.energyGroup;\n                    currentNodes = result.currentNodes;\n\n                    layoutNodes();\n                    updatePositions(lines, nodeElements);\n\n                    svg.attr('width', width).attr('height', height).attr('viewBox', `0 0 ${width} ${height}`);\n\n                    setTimeout(() => startEnergyFlow(), 80);\n                }, 180);\n            }\n\n            window.addEventListener('resize', resizeAndUpdate);\n            window.addEventListener('orientationchange', () => setTimeout(resizeAndUpdate, 150));\n\n            const youtubePanel = document.getElementById('imm-youtube-panel');\n            const youtubeIframe = document.getElementById('imm-youtube-iframe');\n            const closeBtn = document.getElementById('imm-close-btn');\n            const enterSiteBtn = document.getElementById('imm-enter-site-btn');\n\n            function makeDraggable(panel, handle) {\n                let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;\n                handle.onmousedown = function(e) {\n                    if (e.target.tagName === 'BUTTON') return;\n                    e.preventDefault();\n                    pos3 = e.clientX; pos4 = e.clientY;\n                    document.onmouseup = () => { document.onmouseup = document.onmousemove = null; };\n                    document.onmousemove = function(ev) {\n                        ev.preventDefault();\n                        pos1 = pos3 - ev.clientX;\n                        pos2 = pos4 - ev.clientY;\n                        pos3 = ev.clientX; pos4 = ev.clientY;\n                        panel.style.top = (panel.offsetTop - pos2) + \"px\";\n                        panel.style.left = (panel.offsetLeft - pos1) + \"px\";\n                        panel.style.transform = \"none\";\n                    };\n                };\n            }\n            makeDraggable(youtubePanel, document.getElementById('imm-video-header'));\n\n            closeBtn.addEventListener('click', () => {\n                youtubePanel.style.display = 'none';\n                youtubeIframe.src = '';\n                currentOpenNodeId = null;\n            });\n\n            enterSiteBtn.addEventListener('click', () => {\n                if (!currentOpenNodeId) return;\n                const openNode = currentNodes.find(n => n.id === currentOpenNodeId);\n                if (openNode && openNode.url && openNode.url.trim() !== '') {\n                    youtubePanel.style.display = 'none';\n                    youtubeIframe.src = '';\n                    const url = openNode.url.trim();\n                    let w = Math.min(920, window.innerWidth * 0.92);\n                    let h = Math.min(720, window.innerHeight * 0.85);\n                    const left = (screen.width - w) \/ 2;\n                    const top = (screen.height - h) \/ 2 - 40;\n                    window.open(url, '_blank', `width=${Math.round(w)},height=${Math.round(h)},top=${Math.round(top)},left=${Math.round(left)},resizable=yes,scrollbars=yes`);\n                    currentOpenNodeId = null;\n                }\n            });\n        }\n    });\n    <\/script>\n    \n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_angie_page":false,"footnotes":""},"class_list":["post-516","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Science - qubicportal.org<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/qpmainsite-858e54.ingress-haven.ewp.live\/?page_id=516\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Science - qubicportal.org\" \/>\n<meta property=\"og:url\" content=\"https:\/\/qpmainsite-858e54.ingress-haven.ewp.live\/?page_id=516\" \/>\n<meta property=\"og:site_name\" content=\"qubicportal.org\" \/>\n<meta property=\"article:modified_time\" content=\"2026-04-27T03:21:09+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/qpmainsite-858e54.ingress-haven.ewp.live\\\/?page_id=516\",\"url\":\"https:\\\/\\\/qpmainsite-858e54.ingress-haven.ewp.live\\\/?page_id=516\",\"name\":\"Science - qubicportal.org\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/qubicportal.org\\\/#website\"},\"datePublished\":\"2026-04-27T02:35:38+00:00\",\"dateModified\":\"2026-04-27T03:21:09+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/qpmainsite-858e54.ingress-haven.ewp.live\\\/?page_id=516#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/qpmainsite-858e54.ingress-haven.ewp.live\\\/?page_id=516\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/qpmainsite-858e54.ingress-haven.ewp.live\\\/?page_id=516#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/qubicportal.org\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Science\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/qubicportal.org\\\/#website\",\"url\":\"https:\\\/\\\/qubicportal.org\\\/\",\"name\":\"qubicportal.org\",\"description\":\"the gateway to the qubic ecosystem\",\"publisher\":{\"@id\":\"https:\\\/\\\/qubicportal.org\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/qubicportal.org\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/qubicportal.org\\\/#organization\",\"name\":\"qubicportal.org\",\"url\":\"https:\\\/\\\/qubicportal.org\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/qubicportal.org\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/qubicportal.org\\\/wp-content\\\/uploads\\\/2026\\\/04\\\/newclearQP-ezgif.com-gif-maker-1.png\",\"contentUrl\":\"https:\\\/\\\/qubicportal.org\\\/wp-content\\\/uploads\\\/2026\\\/04\\\/newclearQP-ezgif.com-gif-maker-1.png\",\"width\":824,\"height\":190,\"caption\":\"qubicportal.org\"},\"image\":{\"@id\":\"https:\\\/\\\/qubicportal.org\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Science - qubicportal.org","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/qpmainsite-858e54.ingress-haven.ewp.live\/?page_id=516","og_locale":"en_US","og_type":"article","og_title":"Science - qubicportal.org","og_url":"https:\/\/qpmainsite-858e54.ingress-haven.ewp.live\/?page_id=516","og_site_name":"qubicportal.org","article_modified_time":"2026-04-27T03:21:09+00:00","twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/qpmainsite-858e54.ingress-haven.ewp.live\/?page_id=516","url":"https:\/\/qpmainsite-858e54.ingress-haven.ewp.live\/?page_id=516","name":"Science - qubicportal.org","isPartOf":{"@id":"https:\/\/qubicportal.org\/#website"},"datePublished":"2026-04-27T02:35:38+00:00","dateModified":"2026-04-27T03:21:09+00:00","breadcrumb":{"@id":"https:\/\/qpmainsite-858e54.ingress-haven.ewp.live\/?page_id=516#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/qpmainsite-858e54.ingress-haven.ewp.live\/?page_id=516"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/qpmainsite-858e54.ingress-haven.ewp.live\/?page_id=516#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/qubicportal.org\/"},{"@type":"ListItem","position":2,"name":"Science"}]},{"@type":"WebSite","@id":"https:\/\/qubicportal.org\/#website","url":"https:\/\/qubicportal.org\/","name":"qubicportal.org","description":"the gateway to the qubic ecosystem","publisher":{"@id":"https:\/\/qubicportal.org\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/qubicportal.org\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/qubicportal.org\/#organization","name":"qubicportal.org","url":"https:\/\/qubicportal.org\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/qubicportal.org\/#\/schema\/logo\/image\/","url":"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/04\/newclearQP-ezgif.com-gif-maker-1.png","contentUrl":"https:\/\/qubicportal.org\/wp-content\/uploads\/2026\/04\/newclearQP-ezgif.com-gif-maker-1.png","width":824,"height":190,"caption":"qubicportal.org"},"image":{"@id":"https:\/\/qubicportal.org\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/qubicportal.org\/index.php?rest_route=\/wp\/v2\/pages\/516","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/qubicportal.org\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/qubicportal.org\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/qubicportal.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/qubicportal.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=516"}],"version-history":[{"count":5,"href":"https:\/\/qubicportal.org\/index.php?rest_route=\/wp\/v2\/pages\/516\/revisions"}],"predecessor-version":[{"id":533,"href":"https:\/\/qubicportal.org\/index.php?rest_route=\/wp\/v2\/pages\/516\/revisions\/533"}],"wp:attachment":[{"href":"https:\/\/qubicportal.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=516"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}