{"id":46,"date":"2025-08-22T17:40:08","date_gmt":"2025-08-22T17:40:08","guid":{"rendered":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/?p=46"},"modified":"2026-06-04T01:53:24","modified_gmt":"2026-06-04T01:53:24","slug":"ship-database","status":"publish","type":"post","link":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/","title":{"rendered":"EVE Frontier Ship Database Explorer"},"content":{"rendered":"\r\n<div id=\"eve-frontier-article\" data-json=\"https:\/\/gamingwithdaopa.ellatha.com\/media\/evefrontier\/ships.json\">\r\n  <style>\r\n    \/* === EVE-INSPIRED THEME === *\/\r\n    :root{\r\n      --bg:#0a0c10;\r\n      --panel:#12141b;\r\n      --panel-2:#171a22;\r\n      --ink:#e6edf3;\r\n      --muted:#9aa4b2;\r\n      --accent:#39d0ff;\r\n      --accent-2:#00ffa8;\r\n      --warn:#ffbe55;\r\n      --red:#ff5555;\r\n      --grid:#1f2430;\r\n      --chip:#222635;\r\n      --shadow:0 10px 30px rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,.03);\r\n      --radius:14px;\r\n    }\r\n    #eve-frontier-article{\r\n      color:var(--ink);\r\n      font:14px\/1.5 Inter, system-ui, -apple-system, Segoe UI, Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif;\r\n      background:radial-gradient(1200px 600px at 70% -20%,rgba(57,208,255,.05),transparent 60%), var(--bg);\r\n      padding:18px;\r\n      border-radius:var(--radius);\r\n      box-shadow:var(--shadow);\r\n      position:relative;\r\n      overflow:hidden;\r\n    }\r\n    #eve-frontier-article::after{\r\n      content:\"\";\r\n      position:absolute; inset:-2px;\r\n      background:radial-gradient(800px 400px at 110% 20%,rgba(0,255,168,.06),transparent 60%);\r\n      pointer-events:none;\r\n      filter:blur(2px);\r\n    }\r\n    h1,h2,h3{ letter-spacing:.08em; text-transform:uppercase; margin:6px 0 10px }\r\n    h1{ font-size:22px }\r\n    h2{ font-size:16px; color:#fff }\r\n    p.lede{ color:var(--muted); margin:8px 0 16px }\r\n    .shell{\r\n      display:grid;\r\n      grid-template-columns: 300px 1fr;\r\n      gap:16px;\r\n      min-height:520px;\r\n    }\r\n    @media (max-width: 900px){\r\n      .shell{ grid-template-columns:1fr }\r\n    }\r\n    \/* === SIDEBAR LIST (grouped) === *\/\r\n    .sidebar{\r\n      background:linear-gradient(180deg,var(--panel),var(--panel-2));\r\n      border:1px solid #202531;\r\n      border-radius:var(--radius);\r\n      overflow:hidden;\r\n      display:flex; flex-direction:column;\r\n      min-height:480px;\r\n    }\r\n    .toolbar{\r\n      display:grid; gap:8px;\r\n      grid-template-columns:1fr 36px;\r\n      padding:10px;\r\n      border-bottom:1px solid var(--grid);\r\n      background:linear-gradient(180deg,rgba(57,208,255,.04),transparent);\r\n      position:sticky; top:0; z-index:2;\r\n    }\r\n    .search-wrap{ position:relative }\r\n    .search{\r\n      width:100%;\r\n      background:#0e1118; border:1px solid #1e2430; color:var(--ink);\r\n      border-radius:10px; padding:8px 28px 8px 30px; outline:none;\r\n    }\r\n    .search-icon{\r\n      position:absolute; left:10px; top:50%; transform:translateY(-50%); color:#7d8798; pointer-events:none;\r\n    }\r\n    .sort{\r\n      border:1px solid #1e2430; background:#0e1118; color:var(--ink);\r\n      border-radius:10px; cursor:pointer;\r\n    }\r\n    .list{\r\n      overflow:auto; flex:1;\r\n      scrollbar-width:thin; scrollbar-color:#2b3242 transparent;\r\n    }\r\n    .group{\r\n      border-bottom:1px solid rgba(255,255,255,.04);\r\n    }\r\n    .group-title{\r\n      width:100%; text-align:left;\r\n      display:flex; align-items:center; justify-content:space-between;\r\n      gap:8px; padding:8px 10px; cursor:pointer;\r\n      background:linear-gradient(180deg,#151924,#121622);\r\n      border-bottom:1px solid rgba(255,255,255,.03);\r\n      font-weight:600;\r\n    }\r\n    .group-title .left{ display:flex; align-items:center; gap:8px }\r\n    .group-title .count{ color:var(--muted); font-weight:500; font-size:12px }\r\n    .group-items{ display:none }\r\n    .group[data-open=\"true\"] .group-items{ display:block }\r\n    .group-title .caret{ transition:transform .15s ease }\r\n    .group[data-open=\"true\"] .group-title .caret{ transform:rotate(180deg) }\r\n    .item{\r\n      display:grid;\r\n      grid-template-columns:42px 1fr auto;\r\n      gap:12px;\r\n      align-items:center;\r\n      padding:10px 12px;\r\n      border-bottom:1px solid rgba(255,255,255,.03);\r\n      background:transparent;\r\n      color:var(--ink);\r\n      cursor:pointer;\r\n      transition:background .15s ease, transform .04s ease;\r\n    }\r\n    .item:hover{ background:rgba(57,208,255,.06) }\r\n    .item.active{\r\n      background:linear-gradient(90deg,rgba(57,208,255,.12),transparent 60%);\r\n      outline:1px solid rgba(57,208,255,.35);\r\n    }\r\n    .item .name{ font-weight:600 }\r\n    .item .minor{ color:var(--muted) }\r\n    .badge{\r\n      display:inline-flex; gap:6px; align-items:center;\r\n      background:var(--chip); border:1px solid #2a3144; color:#b8c0cc;\r\n      padding:3px 8px; border-radius:999px; font-size:11px;\r\n    }\r\n    .item .actions{ display:flex; gap:10px; align-items:center }\r\n    .item .actions .fa{ color:#8a93a7 }\r\n    .item .actions .fa:hover{ color:var(--accent) }\r\n\r\n    \/* === ICON STYLES (same as Blueprints page) === *\/\r\n    .bp-icon, .bp-icon-large {\r\n      border-radius:6px;\r\n      border:1px solid #2a3144;\r\n      background:#0e1118;\r\n      object-fit:contain;\r\n      box-shadow:0 2px 8px rgba(0,0,0,.35);\r\n      flex-shrink:0;\r\n      image-rendering: crisp-edges;\r\n    }\r\n    .bp-icon { width:36px; height:36px; }\r\n    .bp-icon-large { width:96px; height:96px; border-width:2px; border-color:#39d0ff; box-shadow:0 0 18px rgba(57,208,255,.4), 0 6px 22px rgba(0,0,0,.5); }\r\n    .icon-frame {\r\n      width:120px; height:120px;\r\n      background:linear-gradient(145deg, #12141b, #0a0c10);\r\n      border:1px solid #263042;\r\n      border-radius:12px;\r\n      display:flex; align-items:center; justify-content:center;\r\n      overflow:hidden;\r\n      box-shadow: inset 0 0 0 1px rgba(255,255,255,.03), 0 6px 24px rgba(0,0,0,.45);\r\n      position:relative;\r\n    }\r\n    .icon-frame::after {\r\n      content:'';\r\n      position:absolute; inset:0;\r\n      background:radial-gradient(circle at 30% 25%, rgba(57,208,255,.12), transparent 60%);\r\n      pointer-events:none;\r\n    }\r\n    .placeholder {\r\n      display:flex; align-items:center; justify-content:center;\r\n      color:#4a5468; background:#0e1118; width:100%; height:100%;\r\n    }\r\n\r\n    \/* === DETAIL PANEL === *\/\r\n    .panel{\r\n      background:linear-gradient(180deg,var(--panel),var(--panel-2));\r\n      border:1px solid #202531;\r\n      border-radius:var(--radius);\r\n      padding:16px;\r\n      min-height:480px;\r\n      position:relative; overflow:hidden;\r\n    }\r\n    .panel-grid{\r\n      display:grid; grid-template-columns: 1.2fr .8fr;\r\n      gap:16px;\r\n    }\r\n    @media (max-width: 1100px){\r\n      .panel-grid{ grid-template-columns:1fr }\r\n    }\r\n    \/* Holo header *\/\r\n    .holo{\r\n      display:grid; grid-template-columns:140px 1fr auto; gap:14px; align-items:center;\r\n      padding:12px; border:1px solid #263042; border-radius:12px;\r\n      background:linear-gradient(180deg,rgba(0,255,168,.06),rgba(57,208,255,.04));\r\n      box-shadow:inset 0 0 0 1px rgba(255,255,255,.02);\r\n    }\r\n    .wire{\r\n      width:100%; aspect-ratio:1\/1; background:radial-gradient(60% 60% at 50% 40%, rgba(57,208,255,.15), transparent 70%);\r\n      border-radius:10px; position:relative; overflow:hidden;\r\n    }\r\n    .wire svg{ position:absolute; inset:0 }\r\n    .wire .glow{\r\n      filter:drop-shadow(0 0 6px rgba(57,208,255,.85)) drop-shadow(0 0 18px rgba(0,255,168,.35));\r\n    }\r\n    @keyframes dash { to { stroke-dashoffset:-1200 } }\r\n    @keyframes ping { 0%{ opacity:.55; transform:scale(1) } 70%{ opacity:.1; transform:scale(1.08) } 100%{ opacity:.55; transform:scale(1) } }\r\n    .title{ display:flex; flex-direction:column; gap:4px }\r\n    .title h2{ margin:0; font-size:18px; letter-spacing:.12em }\r\n    .sub{ color:var(--muted); font-size:12px }\r\n    .chips{ display:flex; gap:8px; flex-wrap:wrap }\r\n    \/* Quick stats row *\/\r\n    .quick{\r\n      display:grid; grid-template-columns:repeat(4,1fr); gap:8px; margin-top:12px;\r\n    }\r\n    @media (max-width: 600px){ .quick{ grid-template-columns:repeat(2,1fr) } }\r\n    .q{\r\n      background:linear-gradient(180deg,#0e1118,#0c0f15);\r\n      border:1px solid #1d2432; border-radius:10px; padding:10px;\r\n    }\r\n    .q div:first-child{ color:var(--muted); font-size:11px; letter-spacing:.08em; text-transform:uppercase }\r\n    .q strong{ font-size:16px }\r\n    \/* Stat grid *\/\r\n    .stats{\r\n      margin-top:14px;\r\n      display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:8px;\r\n    }\r\n    @media (max-width: 900px){ .stats{ grid-template-columns:1fr } }\r\n    .stat{\r\n      background:#0f131b; border:1px solid #1e2431; border-radius:10px; padding:10px;\r\n      display:flex; justify-content:space-between; gap:12px;\r\n    }\r\n    .stat label{ color:var(--muted); font-size:12px }\r\n    .stat span{ font-weight:600 }\r\n    \/* Blueprint *\/\r\n    .bp{\r\n      background:linear-gradient(180deg,rgba(57,208,255,.05),rgba(0,255,168,.04));\r\n      border:1px dashed #284758; border-radius:12px; padding:12px;\r\n    }\r\n    .bp h3{ margin-top:0 }\r\n    .materials{\r\n      display:grid; grid-template-columns: 1fr auto; gap:6px 12px; align-items:center;\r\n      margin-top:8px;\r\n    }\r\n    .tag{\r\n      background:var(--chip); border:1px solid #2a3144; border-radius:999px;\r\n      padding:4px 10px; font-size:12px; color:#c9d3e0; width:max-content;\r\n    }\r\n    .btn-mini{\r\n      display:inline-flex; align-items:center; gap:6px;\r\n      background:#0e1118; border:1px solid #1e2431; color:#d7deea;\r\n      border-radius:999px; padding:6px 10px; cursor:pointer;\r\n    }\r\n    .btn-mini:hover{ border-color:#2b3850; color:#fff }\r\n    \/* Compare panel *\/\r\n    .compare-wrap{\r\n      margin-top:14px;\r\n    }\r\n    .compare-head{\r\n      display:flex; align-items:center; justify-content:space-between; gap:10px;\r\n      margin-bottom:8px;\r\n    }\r\n    .table-scroll{ overflow:auto; border:1px solid #223043; border-radius:10px }\r\n    .compare-table{\r\n      width:100%; border-collapse:separate; border-spacing:0;\r\n      min-width:720px;\r\n    }\r\n    .compare-table th, .compare-table td{\r\n      padding:10px; border-bottom:1px solid #1e2a3c; text-align:left; vertical-align:top;\r\n      background:#0e1219;\r\n    }\r\n    .compare-table thead th{\r\n      position:sticky; top:0; background:#151a24; z-index:1;\r\n    }\r\n    .compare-table tbody tr:nth-child(odd) td{ background:#0d1117 }\r\n    .col-attr{ width:220px; white-space:nowrap }\r\n    .remove-btn{ cursor:pointer; color:#9aa6b2 }\r\n    .remove-btn:hover{ color:#ff8080 }\r\n    \/* Footer status *\/\r\n    .status{\r\n      position:sticky; bottom:0; left:0; right:0;\r\n      margin-top:12px; padding:10px 12px;\r\n      background:linear-gradient(180deg, transparent, rgba(10,12,16,.9));\r\n      border-top:1px solid #1f2532; backdrop-filter:blur(6px);\r\n      display:flex; justify-content:space-between; gap:12px; align-items:center;\r\n      font-size:12px; color:var(--muted);\r\n    }\r\n    \/* Tiny helpers *\/\r\n    .mono{ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", monospace }\r\n    .faint{ color:var(--muted) }\r\n    .sep{ opacity:.35; margin:0 8px }\r\n    \/* New styles for ship details panel *\/\r\n    .section-title{ font-size:16px; color:#fff; letter-spacing:.08em; text-transform:uppercase; margin:16px 0 8px; }\r\n    .stat-line{ display:flex; align-items:center; gap:8px; margin-bottom:6px; }\r\n    .stat-line img{ width:32px; height:32px; }\r\n    .stat-line label{ flex:1; color:var(--muted); }\r\n    .stat-line span{ font-weight:600; }\r\n    .resistances{ display:flex; gap:8px; margin-bottom:12px; }\r\n    .res-item{ display:flex; align-items:center; gap:8px; flex:1; }\r\n    .bar-wrap{ flex:1; position:relative; }\r\n    .percent{ position:absolute; top:-18px; left:0; font-size:12px; color:var(--muted); }\r\n    .bar{ height:10px; background:var(--chip); border-radius:4px; }\r\n    .fill{ height:100%; border-radius:4px; }\r\n    .em .fill{ background:var(--accent); }\r\n    .therm .fill{ background:var(--red); }\r\n    .kin .fill{ background:var(--muted); }\r\n    .exp .fill{ background:var(--warn); }\r\n    .sensor-row{ display:flex; gap:12px; margin-top:8px; }\r\n    .sensor{ display:flex; align-items:center; gap:6px; color:var(--muted); font-size:12px; }\r\n  <\/style>\r\n\r\n  <p class=\"lede\">Plunge into the uncharted void of EVE Frontier Cycle 5 with our definitive Ship Database! Select any hull to uncover its stats, blueprint requirements, module slots, and hardpoint configurations \u2014 now with beautiful ship icons. Compare ships to craft strategies for scavenging, combat, or base-building.<\/p>\r\n\r\n  <div class=\"shell\">\r\n    <!-- SIDEBAR -->\r\n    <aside class=\"sidebar\">\r\n      <div class=\"toolbar\">\r\n        <div class=\"search-wrap\">\r\n          <i class=\"fa fa-search search-icon\" aria-hidden=\"true\"><\/i>\r\n          <input class=\"search\" id=\"search\" type=\"search\" placeholder=\"Search ship name \/ typeID\u2026\" \/>\r\n        <\/div>\r\n        <button class=\"sort\" id=\"sortBtn\" title=\"Toggle sort name A\u21c4Z\">\r\n          <i class=\"fa fa-sort-alpha-asc\" aria-hidden=\"true\"><\/i>\r\n        <\/button>\r\n      <\/div>\r\n      <div class=\"list\" id=\"list\"><\/div>\r\n    <\/aside>\r\n\r\n    <!-- DETAILS -->\r\n    <section class=\"panel\">\r\n      <div id=\"detail\">\r\n        <!-- Placeholder before selection -->\r\n        <div class=\"holo\" aria-live=\"polite\">\r\n          <div class=\"wire\">\r\n            <svg viewBox=\"0 0 200 200\" role=\"img\" aria-label=\"Holographic placeholder\">\r\n              <defs>\r\n                <linearGradient id=\"grad\" x1=\"0\" x2=\"1\" y1=\"0\" y2=\"1\">\r\n                  <stop offset=\"0%\" stop-color=\"#39d0ff\" stop-opacity=\"1\"\/>\r\n                  <stop offset=\"100%\" stop-color=\"#00ffa8\" stop-opacity=\"1\"\/>\r\n                <\/linearGradient>\r\n              <\/defs>\r\n              <polygon points=\"100,18 182,78 156,182 44,182 18,78\"\r\n                fill=\"none\" stroke=\"url(#grad)\" stroke-width=\"2\"\r\n                stroke-dasharray=\"8 6\" style=\"animation:dash 12s linear infinite\"\r\n                class=\"glow\"\/>\r\n              <circle cx=\"100\" cy=\"100\" r=\"70\" fill=\"none\" stroke=\"url(#grad)\" stroke-opacity=\".35\" stroke-width=\"1\" style=\"animation:ping 4.5s ease-in-out infinite\"\/>\r\n            <\/svg>\r\n          <\/div>\r\n          <div class=\"title\">\r\n            <h2>Select a ship<\/h2>\r\n            <div class=\"sub\">Use the left sidebar to browse all hulls from the current build of EVE Frontier. Icons now live!<\/div>\r\n            <div class=\"chips\">\r\n              <span class=\"badge\"><i class=\"fa fa-plug\"><\/i> Dynamic Data<\/span>\r\n              <span class=\"badge\"><i class=\"fa fa-bolt\"><\/i> Animated SVG<\/span>\r\n              <span class=\"badge\"><i class=\"fa fa-industry\"><\/i> Blueprint View<\/span>\r\n            <\/div>\r\n          <\/div>\r\n          <div class=\"tag\"><i class=\"fa fa-database\"><\/i> Live: ships.json + icons<\/div>\r\n        <\/div>\r\n        <div class=\"quick\">\r\n          <div class=\"q\"><div>Velocity<\/div><strong>\u2014<\/strong><\/div>\r\n          <div class=\"q\"><div>Signature<\/div><strong>\u2014<\/strong><\/div>\r\n          <div class=\"q\"><div>PG \/ CPU<\/div><strong>\u2014<\/strong><\/div>\r\n          <div class=\"q\"><div>Targets<\/div><strong>\u2014<\/strong><\/div>\r\n        <\/div>\r\n        <div class=\"stats\">\r\n          <div class=\"stat\"><label>Nothing selected<\/label><span class=\"faint\">Pick a ship to populate stats<\/span><\/div>\r\n        <\/div>\r\n        <div style=\"height:8px\"><\/div>\r\n        <div class=\"bp\">\r\n          <h3><i class=\"fa fa-cogs\"><\/i> Blueprint<\/h3>\r\n          <div class=\"faint\">Materials and build time will appear when a ship is selected.<\/div>\r\n        <\/div>\r\n      <\/div>\r\n\r\n      <!-- COMPARE (under Ship Details) -->\r\n      <div id=\"compareWrap\" class=\"compare-wrap\" style=\"display:none;\">\r\n        <div class=\"bp\">\r\n          <div class=\"compare-head\">\r\n            <h3><i class=\"fa fa-balance-scale\"><\/i> Compare<\/h3>\r\n            <button id=\"compareReset\" class=\"btn-mini\" title=\"Clear all\"><i class=\"fa fa-times\"><\/i> Reset<\/button>\r\n          <\/div>\r\n          <div class=\"table-scroll\">\r\n            <table class=\"compare-table\" id=\"compareTable\" aria-live=\"polite\"><\/table>\r\n          <\/div>\r\n        <\/div>\r\n      <\/div>\r\n\r\n      <div class=\"status\">\r\n        <span id=\"statusText\">Fetching data\u2026<\/span>\r\n        <span><span class=\"sep\">\u2022<\/span> <span id=\"count\">0<\/span> ships loaded<\/span>\r\n      <\/div>\r\n    <\/section>\r\n  <\/div>\r\n\r\n  <script>\r\n    (() => {\r\n      const root = document.getElementById('eve-frontier-article');\r\n      const JSON_URL = root.getAttribute('data-json');\r\n      const els = {\r\n        list: document.getElementById('list'),\r\n        detail: document.getElementById('detail'),\r\n        search: document.getElementById('search'),\r\n        sortBtn: document.getElementById('sortBtn'),\r\n        status: document.getElementById('statusText'),\r\n        count: document.getElementById('count'),\r\n        compareWrap: document.getElementById('compareWrap'),\r\n        compareTable: document.getElementById('compareTable'),\r\n        compareReset: document.getElementById('compareReset'),\r\n      };\r\n\r\n      \/** Utils **\/\r\n      const fmtNum = (n) => {\r\n        if (n === null || n === undefined || Number.isNaN(n)) return \"\u2014\";\r\n        const x = +n;\r\n        if (Math.abs(x) >= 1000) return x.toLocaleString();\r\n        if (Number.isInteger(x)) return x.toString();\r\n        return x.toLocaleString(undefined, {maximumFractionDigits: 3});\r\n      };\r\n\r\n      const secsToHMS = (s) => {\r\n        if (!Number.isFinite(+s)) return \"\u2014\";\r\n        const d = Math.floor(s\/86400), h = Math.floor((s%86400)\/3600), m = Math.floor((s%3600)\/60);\r\n        const parts = [];\r\n        if (d) parts.push(`${d}d`);\r\n        if (h) parts.push(`${h}h`);\r\n        if (m || (!d && !h)) parts.push(`${m}m`);\r\n        return parts.join(\" \");\r\n      };\r\n\r\n      const prefer = (obj, keys) => {\r\n        for (const k of keys){ if (obj && obj[k]) return obj[k]; }\r\n        return null;\r\n      };\r\n\r\n      const get = (obj, path, d=undefined) => path.split('.').reduce((o,k)=> (o && o[k]!==undefined) ? o[k] : d, obj);\r\n\r\n      \/** Icon helper - same logic as Blueprints page (with graphicID fallback) **\/\r\n      const ICON_BASE = 'https:\/\/gamingwithdaopa.ellatha.com\/media\/evefrontier\/icons\/';\r\n      function getIconHTML(ship, size = 'small') {\r\n        const cls = size === 'large' ? 'bp-icon-large' : 'bp-icon';\r\n        if (!ship) {\r\n          const phStyle = size === 'large' ? 'width:96px;height:96px;font-size:42px;' : 'width:36px;height:36px;';\r\n          return `<div class=\"${cls} placeholder\" style=\"${phStyle}\"><i class=\"fa fa-rocket\"><\/i><\/div>`;\r\n        }\r\n        let iconFile = null;\r\n        if (ship.iconID) {\r\n          iconFile = `${ship.iconID}.png`;\r\n        } else if (ship.graphicID) {\r\n          iconFile = `g${ship.graphicID}.png`;\r\n        }\r\n        if (iconFile) {\r\n          const safeName = (ship.name || 'Ship').replace(\/\"\/g, '&quot;');\r\n          return `<img decoding=\"async\" class=\"${cls}\" src=\"${ICON_BASE}${iconFile}\" alt=\"${safeName} icon\" loading=\"lazy\" \/>`;\r\n        }\r\n        const phStyle = size === 'large' ? 'width:96px;height:96px;font-size:42px;' : 'width:36px;height:36px;';\r\n        return `<div class=\"${cls} placeholder\" style=\"${phStyle}\"><i class=\"fa fa-rocket\"><\/i><\/div>`;\r\n      }\r\n\r\n      \/** Group order (smallest \u2192 largest) **\/\r\n      const GROUP_RANK = {\r\n        \"Shuttle\":1, \"Corvette\":1, \"Frigate\":2, \"Destroyer\":3, \"Cruiser\":4,\r\n        \"Combat Battlecruiser\":5, \"Battlecruiser\":5, \"Battleship\":6,\r\n        \"Industrial\":7, \"Industrial Ship\":7, \"Hauler\":7,\r\n        \"Capital\":8, \"Dreadnought\":8, \"Carrier\":8, \"Supercarrier\":9, \"Titan\":10, \"Other\":99\r\n      };\r\n      const rankGroup = (g) => GROUP_RANK[g] ?? 98;\r\n\r\n      \/** Group to hologram config **\/\r\n      const groupToHolo = {\r\n        \"Shuttle\": { pnts: \"100,50 150,100 100,150 50,100\", circle: {cx:100, cy:100, r:50} },\r\n        \"Corvette\": { pnts: \"100,40 160,80 140,160 60,160 40,80\", circle: {cx:100, cy:105, r:55} },\r\n        \"Frigate\": { pnts: \"100,30 170,70 155,170 45,170 30,70\", circle: {cx:95, cy:110, r:60} },\r\n        \"Destroyer\": { pnts: \"100,40 170,60 160,150 120,170 80,170 40,150 30,60\", circle: {cx:100, cy:100, r:65} },\r\n        \"Cruiser\": { pnts: \"100,35 175,65 165,155 130,175 100,180 70,175 35,155 25,65\", circle: {cx:105, cy:95, r:70} },\r\n        \"Combat Battlecruiser\": { pnts: \"110,40 180,60 170,140 140,170 110,180 90,180 60,170 30,140 20,60\", circle: {cx:100, cy:90, r:75} },\r\n        \"Battlecruiser\": { pnts: \"110,40 180,60 170,140 140,170 110,180 90,180 60,170 30,140 20,60\", circle: {cx:100, cy:90, r:75} },\r\n        \"Battleship\": { pnts: \"120,30 185,50 180,130 150,160 120,170 80,170 50,160 20,130 15,50\", circle: {cx:100, cy:85, r:80} },\r\n        \"Industrial\": { pnts: \"100,50 170,70 160,150 100,180 40,150 30,70\", circle: {cx:100, cy:100, r:70} },\r\n        \"Industrial Ship\": { pnts: \"100,50 170,70 160,150 100,180 40,150 30,70\", circle: {cx:100, cy:100, r:70} },\r\n        \"Hauler\": { pnts: \"100,50 170,70 160,150 100,180 40,150 30,70\", circle: {cx:100, cy:100, r:70} },\r\n        \"Capital\": { pnts: \"130,20 190,40 185,120 160,150 130,160 100,165 70,160 40,150 15,120 10,40\", circle: {cx:100, cy:80, r:85} },\r\n        \"Dreadnought\": { pnts: \"130,20 190,40 185,120 160,150 130,160 100,165 70,160 40,150 15,120 10,40\", circle: {cx:100, cy:80, r:85} },\r\n        \"Carrier\": { pnts: \"140,10 195,30 190,110 170,140 140,150 100,155 60,150 30,140 10,110 5,30\", circle: {cx:100, cy:75, r:90} },\r\n        \"Supercarrier\": { pnts: \"140,10 195,30 190,110 170,140 140,150 100,155 60,150 30,140 10,110 5,30\", circle: {cx:100, cy:75, r:90} },\r\n        \"Titan\": { pnts: \"150,5 198,25 195,100 180,130 150,140 100,145 50,140 20,130 5,100 2,25\", circle: {cx:100, cy:70, r:95} },\r\n        \"Other\": { pnts: \"100,18 182,78 156,182 44,182 18,78\", circle: {cx:100, cy:100, r:70} }\r\n      };\r\n\r\n      \/** State **\/\r\n      let ships = [];\r\n      let sortAsc = true;\r\n      let activeTypeID = null;\r\n      let compareList = [];\r\n\r\n      \/** Fetch **\/\r\n      async function load(){\r\n        try{\r\n          els.status.textContent = 'Fetching data\u2026';\r\n          const res = await fetch(JSON_URL, {mode:'cors'});\r\n          if(!res.ok) throw new Error(`HTTP ${res.status}`);\r\n          const data = await res.json();\r\n          if(!data || !Array.isArray(data.ships)) throw new Error('Invalid JSON: missing \"ships\" array');\r\n          ships = data.ships;\r\n          els.count.textContent = ships.length;\r\n          els.status.textContent = 'Ready';\r\n          renderList();\r\n        }catch(err){\r\n          console.error(err);\r\n          els.status.innerHTML = `Could not fetch <span class=\"mono\">ships.json<\/span>.`;\r\n          els.list.innerHTML = `<div style=\"padding:12px;color:#ff9a9a\">Fetch error: ${err.message}<\/div>`;\r\n        }\r\n      }\r\n\r\n      \/** Build grouped list with icons **\/\r\n      function renderList(){\r\n        const q = els.search.value?.trim().toLowerCase() || '';\r\n        const filtered = ships.filter(s => {\r\n          const name = (s.name||'').toLowerCase();\r\n          const typeID = String(s.typeID||'');\r\n          const groupStr = (s.group || '').toLowerCase();\r\n          return name.includes(q) || typeID.includes(q) || groupStr.includes(q);\r\n        });\r\n\r\n        const map = new Map();\r\n        for (const s of filtered){\r\n          const group = s.group || (s.groupID != null ? `Group ${s.groupID}` : 'Other');\r\n          if (!map.has(group)) map.set(group, []);\r\n          map.get(group).push(s);\r\n        }\r\n\r\n        const groups = Array.from(map.entries())\r\n          .sort(([ga],[gb]) => (rankGroup(ga) - rankGroup(gb)) || ga.localeCompare(gb));\r\n\r\n        els.list.innerHTML = '';\r\n\r\n        for (const [groupName, arr] of groups){\r\n          arr.sort((a,b)=>{\r\n            const A = (a.name||'').toLowerCase();\r\n            const B = (b.name||'').toLowerCase();\r\n            return sortAsc ? A.localeCompare(B) : B.localeCompare(A);\r\n          });\r\n\r\n          const section = document.createElement('div');\r\n          section.className = 'group';\r\n          section.dataset.open = 'true';\r\n\r\n          const title = document.createElement('button');\r\n          title.className = 'group-title';\r\n          title.innerHTML = `\r\n            <span class=\"left\">\r\n              <i class=\"fa fa-folder-open-o\" aria-hidden=\"true\"><\/i>\r\n              ${groupName}\r\n            <\/span>\r\n            <span>\r\n              <span class=\"count\">${arr.length}<\/span>\r\n              <i class=\"fa fa-caret-down caret\" aria-hidden=\"true\"><\/i>\r\n            <\/span>\r\n          `;\r\n          title.addEventListener('click', ()=>{\r\n            section.dataset.open = section.dataset.open === 'true' ? 'false' : 'true';\r\n          });\r\n\r\n          const items = document.createElement('div');\r\n          items.className = 'group-items';\r\n\r\n          for (const s of arr){\r\n            const btn = document.createElement('div');\r\n            btn.className = 'item' + (s.typeID===activeTypeID ? ' active':'');\r\n            const iconHTML = getIconHTML(s);\r\n\r\n            btn.innerHTML = `\r\n              ${iconHTML}\r\n              <div>\r\n                <div class=\"name\">${s.name||'Unnamed Ship'}<\/div>\r\n                <div class=\"chips\" style=\"margin-top:6px\">\r\n                  <span class=\"badge\" title=\"Group\"><i class=\"fa fa-tags\"><\/i> ${s.group || ('Group '+(s.groupID??'\u2014'))}<\/span>\r\n                  ${s.capacity!=null? `<span class=\"badge\"><i class=\"fa fa-archive\"><\/i> ${fmtNum(s.capacity)} m\u00b3<\/span>`:''}\r\n                <\/div>\r\n              <\/div>\r\n              <div class=\"actions\">\r\n                <i class=\"fa fa-plus-circle\" title=\"Add to compare\" aria-hidden=\"true\"><\/i>\r\n                <span class=\"tag\">Select<\/span>\r\n              <\/div>\r\n            `;\r\n\r\n            btn.addEventListener('click', (e)=>{\r\n              if (e.target && e.target.classList.contains('fa-plus-circle')) return;\r\n              selectShip(s.typeID);\r\n            });\r\n            btn.querySelector('.fa-plus-circle').addEventListener('click', (e)=>{\r\n              e.stopPropagation();\r\n              addToCompare(s.typeID);\r\n            });\r\n            items.appendChild(btn);\r\n          }\r\n\r\n          section.appendChild(title);\r\n          section.appendChild(items);\r\n          els.list.appendChild(section);\r\n        }\r\n\r\n        \/\/ Restore active highlight\r\n        if (activeTypeID) {\r\n          const activeItem = els.list.querySelector(`.item.active`);\r\n          if (!activeItem) {\r\n            const found = els.list.querySelector(`.item`);\r\n            \/\/ re-apply if needed after filter\r\n          }\r\n        }\r\n      }\r\n\r\n      \/** Detail view with large icon **\/\r\n      function selectShip(typeID){\r\n        activeTypeID = typeID;\r\n        const ship = ships.find(x=>x.typeID===typeID);\r\n        if(!ship) return;\r\n\r\n        const s = ship.stats || {};\r\n        const vVel = prefer(s, ['Maximum Velocity','Max Velocity','Velocity']);\r\n        const vSig = prefer(s, ['Signature Radius']);\r\n        const vPG = prefer(s, ['Powergrid Output','Power Grid Output']);\r\n        const vCPU = prefer(s, ['CPU Output','CPU']);\r\n        const vTgt = prefer(s, ['Maximum Locked Targets','Max Locked Targets']);\r\n        const vWarp = prefer(s, ['Warp Speed Multiplier','Warp Speed']);\r\n        const bp = ship.build || {};\r\n        const mats = Array.isArray(bp.materials) ? bp.materials : [];\r\n\r\n        const group = ship.group || (ship.groupID != null ? `Group ${ship.groupID}` : 'Other');\r\n        const holo = groupToHolo[group] || groupToHolo[\"Other\"];\r\n        const pnts = holo.pnts;\r\n        const cx = holo.circle.cx;\r\n        const cy = holo.circle.cy;\r\n        const r = holo.circle.r;\r\n\r\n        const getValue = (keys) => prefer(s, keys)?.value ?? null;\r\n        const getUnit = (keys) => prefer(s, keys)?.unit || '';\r\n\r\n        const resTypes = [\r\n          {type: 'em', key: 'EM Damage Resistance', icon: 'em.png', class: 'em'},\r\n          {type: 'therm', key: 'Thermal Damage Resistance', icon: 'therm.png', class: 'therm'},\r\n          {type: 'kin', key: 'Kinetic Damage Resistance', icon: 'kin.png', class: 'kin'},\r\n          {type: 'exp', key: 'Explosive Damage Resistance', icon: 'exp.png', class: 'exp'}\r\n        ];\r\n\r\n        const sensorTypes = [\r\n          {type: 'gravimetric', key: 'Gravimetric Sensor Strength', icon: 'gravimetric.png'},\r\n          {type: 'ladar', key: 'Ladar Sensor Strength', icon: 'ladar.png'},\r\n          {type: 'magnetometric', key: 'Magnetometric Sensor Strength', icon: 'magnetometric.png'},\r\n          {type: 'radar', key: 'RADAR Sensor Strength', icon: 'radar.png'}\r\n        ];\r\n\r\n        const warpValue = vWarp?.value ?? null;\r\n        const warpStr = warpValue !== null ? fmtNum(warpValue \/ 2) + 'k c' : '\u2014';\r\n\r\n        const largeIcon = getIconHTML(ship, 'large');\r\n\r\n        els.detail.innerHTML = `\r\n          <div class=\"holo\">\r\n            <div class=\"icon-frame\">\r\n              ${largeIcon}\r\n            <\/div>\r\n            <div class=\"title\">\r\n              <h2>${ship.name || 'Unnamed Ship'}<\/h2>\r\n              <div class=\"sub\">${ship.description || 'No description in data.'}<\/div>\r\n              <div class=\"chips\">\r\n                ${ship.group ? `<span class=\"badge\"><i class=\"fa fa-tags\"><\/i> ${ship.group}<\/span>`:''}\r\n                ${ship.groupID!=null ? `<span class=\"badge\">Group ID: ${ship.groupID}<\/span>`:''}\r\n                ${ship.raceID!=null ? `<span class=\"badge\">Race ${ship.raceID}<\/span>`:''}\r\n                ${ship.capacity!=null ? `<span class=\"badge\" title=\"Capacity\"><i class=\"fa fa-archive\"><\/i> ${fmtNum(ship.capacity)} m\u00b3<\/span>`:''}\r\n                ${ship.volume!=null ? `<span class=\"badge\" title=\"Volume\"><i class=\"fa fa-cube\"><\/i> ${fmtNum(ship.volume)} m\u00b3<\/span>`:''}\r\n                ${ship.mass!=null ? `<span class=\"badge\" title=\"Mass\"><i class=\"fa fa-balance-scale\"><\/i> ${fmtNum(ship.mass)} kg<\/span>`:''}\r\n              <\/div>\r\n            <\/div>\r\n            <div style=\"display:flex; flex-direction:column; gap:6px; align-items:flex-end\">\r\n              <div class=\"tag\"><i class=\"fa fa-id-badge\"><\/i> typeID: <span class=\"mono\">${ship.typeID}<\/span><\/div>\r\n              <button class=\"btn-mini\" id=\"btnAddCompare\"><i class=\"fa fa-plus-circle\"><\/i> Add to Compare<\/button>\r\n            <\/div>\r\n          <\/div>\r\n\r\n          <div class=\"stat-line\">\r\n            <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gamingwithdaopa.ellatha.com\/media\/evefrontier\/icons\/structure-hitpoints.png\" width=\"32\" height=\"32\" alt=\"Structure Hitpoints\">\r\n            <label>Structure Hitpoints<\/label>\r\n            <span>${fmtNum(getValue(['Structure Hitpoints']))} ${getUnit(['Structure Hitpoints'])}<\/span>\r\n          <\/div>\r\n\r\n          <div class=\"stat-line\">\r\n            <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gamingwithdaopa.ellatha.com\/media\/evefrontier\/icons\/capacity.png\" width=\"32\" height=\"32\" alt=\"Capacity\">\r\n            <label>Capacity<\/label>\r\n            <span>${fmtNum(ship.capacity)} m3<\/span>\r\n          <\/div>\r\n\r\n          <div class=\"stat-line\">\r\n            <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gamingwithdaopa.ellatha.com\/media\/evefrontier\/icons\/fuel-capacity.png\" width=\"32\" height=\"32\" alt=\"Fuel Capacity\">\r\n            <label>Fuel Capacity<\/label>\r\n            <span>${fmtNum(getValue(['Fuel Capacity']))} ${getUnit(['Fuel Capacity'])}<\/span>\r\n          <\/div>\r\n\r\n          <div class=\"stat-line\">\r\n            <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gamingwithdaopa.ellatha.com\/media\/evefrontier\/icons\/mass.png\" width=\"32\" height=\"32\" alt=\"Mass\">\r\n            <label>Mass<\/label>\r\n            <span>${fmtNum(getValue(['Mass']))} ${getUnit(['Mass'])}<\/span>\r\n          <\/div>\r\n\r\n          <div class=\"stat-line\">\r\n            <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gamingwithdaopa.ellatha.com\/media\/evefrontier\/icons\/volume.png\" width=\"32\" height=\"32\" alt=\"Volume\">\r\n            <label>Volume<\/label>\r\n            <span>${fmtNum(ship.volume)} m3 (1,000.0 m3 Packaged)<\/span>\r\n          <\/div>\r\n\r\n          <div class=\"stat-line\">\r\n            <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gamingwithdaopa.ellatha.com\/media\/evefrontier\/icons\/inertia-modifier.png\" width=\"32\" height=\"32\" alt=\"Inertia Modifier\">\r\n            <label>Inertia Modifier<\/label>\r\n            <span>${fmtNum(getValue(['Inertia Modifier']))}x<\/span>\r\n          <\/div>\r\n\r\n          <h3 class=\"section-title\">Structure<\/h3>\r\n          <div class=\"resistances\">\r\n            ${resTypes.map(res => {\r\n              const v = getValue(['Structure ' + res.key]) ?? 1;\r\n              const resistance = 1 - v;\r\n              const percent = v == null ? '\u2014' : Math.round(resistance * 100) + '%';\r\n              const width = v == null ? 0 : resistance * 100;\r\n              return `\r\n                <div class=\"res-item\">\r\n                  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gamingwithdaopa.ellatha.com\/media\/evefrontier\/icons\/${res.icon}\" width=\"32\" height=\"32\" alt=\"${res.type.toUpperCase()}\">\r\n                  <div class=\"bar-wrap\">\r\n                    <span class=\"percent\">${percent}<\/span>\r\n                    <div class=\"bar\">\r\n                      <div class=\"fill ${res.class}\" style=\"width:${width}%\"><\/div>\r\n                    <\/div>\r\n                  <\/div>\r\n                <\/div>\r\n              `;\r\n            }).join('')}\r\n          <\/div>\r\n\r\n          <h3 class=\"section-title\">Armor<\/h3>\r\n          <div class=\"resistances\">\r\n            ${resTypes.map(res => {\r\n              const v = getValue(['Armor ' + res.key]) ?? 1;\r\n              const resistance = 1 - v;\r\n              const percent = v == null ? '\u2014' : Math.round(resistance * 100) + '%';\r\n              const width = v == null ? 0 : resistance * 100;\r\n              return `\r\n                <div class=\"res-item\">\r\n                  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gamingwithdaopa.ellatha.com\/media\/evefrontier\/icons\/${res.icon}\" width=\"32\" height=\"32\" alt=\"${res.type.toUpperCase()}\">\r\n                  <div class=\"bar-wrap\">\r\n                    <span class=\"percent\">${percent}<\/span>\r\n                    <div class=\"bar\">\r\n                      <div class=\"fill ${res.class}\" style=\"width:${width}%\"><\/div>\r\n                    <\/div>\r\n                  <\/div>\r\n                <\/div>\r\n              `;\r\n            }).join('')}\r\n          <\/div>\r\n\r\n          <h3 class=\"section-title\">Shield<\/h3>\r\n          <div class=\"resistances\">\r\n            ${resTypes.map(res => {\r\n              const v = getValue(['Shield ' + res.key]) ?? 1;\r\n              const resistance = 1 - v;\r\n              const percent = v == null ? '\u2014' : Math.round(resistance * 100) + '%';\r\n              const width = v == null ? 0 : resistance * 100;\r\n              return `\r\n                <div class=\"res-item\">\r\n                  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gamingwithdaopa.ellatha.com\/media\/evefrontier\/icons\/${res.icon}\" width=\"32\" height=\"32\" alt=\"${res.type.toUpperCase()}\">\r\n                  <div class=\"bar-wrap\">\r\n                    <span class=\"percent\">${percent}<\/span>\r\n                    <div class=\"bar\">\r\n                      <div class=\"fill ${res.class}\" style=\"width:${width}%\"><\/div>\r\n                    <\/div>\r\n                  <\/div>\r\n                <\/div>\r\n              `;\r\n            }).join('')}\r\n          <\/div>\r\n\r\n          <div class=\"stat-line\">\r\n            <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gamingwithdaopa.ellatha.com\/media\/evefrontier\/icons\/shield-recharge-time.png\" width=\"32\" height=\"32\" alt=\"Shield recharge time\">\r\n            <label>Shield recharge time<\/label>\r\n            <span>${fmtNum(getValue(['Shield recharge time']))} s<\/span>\r\n          <\/div>\r\n\r\n          <h3 class=\"section-title\">Heat and Capacitor<\/h3>\r\n          <div class=\"stat-line\">\r\n            <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gamingwithdaopa.ellatha.com\/media\/evefrontier\/icons\/capacitor.png\" width=\"32\" height=\"32\" alt=\"Capacitor\">\r\n            <label>Capacitor<\/label>\r\n            <span>${fmtNum(getValue(['Capacitor']))} GJ<\/span>\r\n          <\/div>\r\n          <div class=\"stat-line\">\r\n            <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gamingwithdaopa.ellatha.com\/media\/evefrontier\/icons\/capacitor-recharge.png\" width=\"32\" height=\"32\" alt=\"Capacitor Recharge\">\r\n            <label>Capacitor Recharge<\/label>\r\n            <span style=\"color:var(--accent-2)\">${fmtNum(getValue(['Capacitor Recharge']))} GJ\/s<\/span>\r\n          <\/div>\r\n          <div class=\"stat-line\">\r\n            <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gamingwithdaopa.ellatha.com\/media\/evefrontier\/icons\/specific-heat.png\" width=\"32\" height=\"32\" alt=\"Specific Heat\">\r\n            <label>Specific Heat<\/label>\r\n            <span>${fmtNum(getValue(['Specific Heat']))} C<\/span>\r\n          <\/div>\r\n          <div class=\"stat-line\">\r\n            <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gamingwithdaopa.ellatha.com\/media\/evefrontier\/icons\/conductance.png\" width=\"32\" height=\"32\" alt=\"Conductance\">\r\n            <label>Conductance<\/label>\r\n            <span>${fmtNum(getValue(['Conductance']))} K<\/span>\r\n          <\/div>\r\n\r\n          <h3 class=\"section-title\">Targeting<\/h3>\r\n          <div class=\"stat-line\">\r\n            <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gamingwithdaopa.ellatha.com\/media\/evefrontier\/icons\/max-target-range.png\" width=\"32\" height=\"32\" alt=\"Maximum Targeting Range\">\r\n            <label>Maximum Targeting Range<\/label>\r\n            <span>${fmtNum(getValue(['Maximum Targeting Range']) \/ 1000)} km<\/span>\r\n          <\/div>\r\n          <div class=\"stat-line\">\r\n            <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gamingwithdaopa.ellatha.com\/media\/evefrontier\/icons\/maximum-locked-targets.png\" width=\"32\" height=\"32\" alt=\"Maximum Locked Targets\">\r\n            <label>Maximum Locked Targets<\/label>\r\n            <span>${fmtNum(getValue(['Maximum Locked Targets']))}<\/span>\r\n          <\/div>\r\n          <div class=\"stat-line\">\r\n            <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gamingwithdaopa.ellatha.com\/media\/evefrontier\/icons\/signature-radius.png\" width=\"32\" height=\"32\" alt=\"Signature Radius\">\r\n            <label>Signature Radius<\/label>\r\n            <span>${fmtNum(getValue(['Signature Radius']))} m<\/span>\r\n          <\/div>\r\n          <div class=\"stat-line\">\r\n            <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gamingwithdaopa.ellatha.com\/media\/evefrontier\/icons\/scan-resolution.png\" width=\"32\" height=\"32\" alt=\"Scan Resolution\">\r\n            <label>Scan Resolution<\/label>\r\n            <span>${fmtNum(getValue(['Scan Resolution']))} mm<\/span>\r\n          <\/div>\r\n\r\n          <div class=\"sensor-row\">\r\n            ${sensorTypes.map(sen => {\r\n              const v = fmtNum(getValue([sen.key]) ?? '\u2014');\r\n              return `\r\n                <span class=\"sensor\">\r\n                  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gamingwithdaopa.ellatha.com\/media\/evefrontier\/icons\/${sen.icon}\" width=\"32\" height=\"32\" alt=\"${sen.type}\">\r\n                  ${v} points\r\n                <\/span>\r\n              `;\r\n            }).join('')}\r\n          <\/div>\r\n\r\n          <h3 class=\"section-title\">Propulsion<\/h3>\r\n          <div class=\"stat-line\">\r\n            <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gamingwithdaopa.ellatha.com\/media\/evefrontier\/icons\/maximum-velocity.png\" width=\"32\" height=\"32\" alt=\"Maximum Velocity\">\r\n            <label>Maximum Velocity<\/label>\r\n            <span>${fmtNum(getValue(['Maximum Velocity']))} m\/sec<\/span>\r\n          <\/div>\r\n          <div class=\"stat-line\">\r\n            <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gamingwithdaopa.ellatha.com\/media\/evefrontier\/icons\/ship-warp-speed.png\" width=\"32\" height=\"32\" alt=\"Ship Warp Speed\">\r\n            <label>Ship Warp Speed<\/label>\r\n            <span>${warpStr}<\/span>\r\n          <\/div>\r\n\r\n          <div style=\"height:8px\"><\/div>\r\n\r\n          <div class=\"bp\">\r\n            <h3><i class=\"fa fa-cogs\"><\/i> Blueprint & Build<\/h3>\r\n            <div style=\"display:flex; gap:10px; flex-wrap:wrap\">\r\n              ${bp.blueprintTypeID!=null? `<span class=\"tag\">Blueprint ID: <span class=\"mono\">${bp.blueprintTypeID}<\/span><\/span>`:''}\r\n              ${bp.time!=null? `<span class=\"tag\">Build Time: ${secsToHMS(bp.time)}<\/span>`:''}\r\n              ${ship.basePrice!=null? `<span class=\"tag\">Base Price: ${fmtNum(ship.basePrice)} ISK<\/span>`:''}\r\n            <\/div>\r\n            <div style=\"height:8px\"><\/div>\r\n            ${mats.length\r\n              ? `<div class=\"materials\">\r\n                  <div class=\"faint\">Material<\/div><div class=\"faint\" style=\"text-align:right\">Qty<\/div>\r\n                  ${mats.map(m=>`\r\n                    <div>${m.name ?? m.typeID ?? 'Unknown'}<\/div>\r\n                    <div style=\"text-align:right\">${fmtNum(m.quantity ?? 0)}<\/div>\r\n                  `).join('')}\r\n                <\/div>`\r\n              : `<div class=\"faint\">No materials listed for this hull.<\/div>`\r\n            }\r\n          <\/div>\r\n\r\n          <div style=\"height:10px\"><\/div>\r\n\r\n          <div class=\"bp\">\r\n            <h3><i class=\"fa fa-wrench\"><\/i> Slots & Hardpoints<\/h3>\r\n            <div class=\"materials\">\r\n              ${\r\n                ['Low Slots','Medium Slots','High Slots','Launcher Hardpoints','Turret Hardpoints']\r\n                  .map(key=>{\r\n                    const v = get(s, key + '.value', null);\r\n                    return `<div>${key}<\/div><div style=\"text-align:right\">${v!=null? fmtNum(v) : '\u2014'}<\/div>`;\r\n                  }).join('')\r\n              }\r\n            <\/div>\r\n          <\/div>\r\n        `;\r\n\r\n        const btnAdd = document.getElementById('btnAddCompare');\r\n        if (btnAdd){\r\n          btnAdd.addEventListener('click', ()=> addToCompare(typeID));\r\n        }\r\n\r\n        \/\/ refresh active highlight\r\n        for (const el of document.querySelectorAll('.item')) el.classList.remove('active');\r\n        const activeBtn = Array.from(document.querySelectorAll('.item')).find(b => {\r\n          return b.innerHTML.includes(String(typeID));\r\n        });\r\n        if (activeBtn) activeBtn.classList.add('active');\r\n\r\n        els.detail.parentElement.scrollTo({top:0, behavior:'smooth'});\r\n      }\r\n\r\n      \/** Compare helpers **\/\r\n      function addToCompare(typeID){\r\n        if (!compareList.includes(typeID)){\r\n          if (compareList.length >= 3){\r\n            alert('You can compare up to 3 ships.');\r\n            return;\r\n          }\r\n          compareList.push(typeID);\r\n          renderCompare();\r\n        }\r\n      }\r\n\r\n      function removeFromCompare(typeID){\r\n        compareList = compareList.filter(id=>id!==typeID);\r\n        renderCompare();\r\n      }\r\n\r\n      function renderCompare(){\r\n        if (!compareList.length){\r\n          els.compareWrap.style.display = 'none';\r\n          els.compareTable.innerHTML = '';\r\n          return;\r\n        }\r\n        els.compareWrap.style.display = 'block';\r\n\r\n        const compared = compareList.map(id => ships.find(s=>s.typeID===id)).filter(Boolean);\r\n\r\n        let html = '<thead><tr><th class=\"col-attr\">Attribute<\/th>';\r\n        for (const s of compared){\r\n          const cIcon = getIconHTML(s);\r\n          html += `<th>\r\n            <div style=\"display:flex; align-items:center; justify-content:space-between; gap:8px\">\r\n              <div style=\"display:flex; align-items:center; gap:8px;\">\r\n                ${cIcon}\r\n                <span style=\"font-weight:600;\">${s.name || '\u2014'}<\/span>\r\n              <\/div>\r\n              <span class=\"remove-btn\" title=\"Remove\" data-typeid=\"${s.typeID}\"><i class=\"fa fa-times\"><\/i><\/span>\r\n            <\/div>\r\n            <div class=\"faint mono\">typeID: ${s.typeID}<\/div>\r\n          <\/th>`;\r\n        }\r\n        html += '<\/tr><\/thead>';\r\n\r\n        const rows = [\r\n          { label:'Name', get:(s)=> s.name || '\u2014' },\r\n          { label:'Group', get:(s)=> s.group || (s.groupID!=null? 'Group '+s.groupID : '\u2014') },\r\n          { label:'Mass (kg)', get:(s)=> fmtNum(s.mass) },\r\n          { label:'Volume (m\u00b3)', get:(s)=> fmtNum(s.volume) },\r\n          { label:'Capacity (m\u00b3)', get:(s)=> fmtNum(s.capacity) },\r\n          { label:'Max Velocity', get:(s)=> {\r\n              const v = prefer(s.stats || {}, ['Maximum Velocity','Max Velocity','Velocity']);\r\n              return v ? (fmtNum(v.value) + ' ' + (v.unit||'')) : '\u2014';\r\n            } },\r\n          { label:'Signature Radius', get:(s)=> {\r\n              const v = prefer(s.stats || {}, ['Signature Radius']);\r\n              return v ? (fmtNum(v.value) + ' ' + (v.unit||'')) : '\u2014';\r\n            } },\r\n          { label:'Powergrid (MW)', get:(s)=> {\r\n              const v = prefer(s.stats || {}, ['Powergrid Output','Power Grid Output']);\r\n              return v ? fmtNum(v.value) : '\u2014';\r\n            } },\r\n          { label:'CPU (tf)', get:(s)=> {\r\n              const v = prefer(s.stats || {}, ['CPU Output','CPU']);\r\n              return v ? fmtNum(v.value) : '\u2014';\r\n            } },\r\n          { label:'Max Locked Targets', get:(s)=> {\r\n              const v = prefer(s.stats || {}, ['Maximum Locked Targets','Max Locked Targets']);\r\n              return v ? fmtNum(v.value) : '\u2014';\r\n            } },\r\n          { label:'Warp Speed', get:(s)=> {\r\n              const v = prefer(s.stats || {}, ['Warp Speed Multiplier','Warp Speed']);\r\n              return v ? (fmtNum(v.value) + ' ' + (v.unit||'')) : '\u2014';\r\n            } },\r\n          { label:'Slots (L\/M\/H)', get:(s)=> {\r\n              const L = get(s,'stats.Low Slots.value',null);\r\n              const M = get(s,'stats.Medium Slots.value',null);\r\n              const H = get(s,'stats.High Slots.value',null);\r\n              return [L,M,H].map(v=>v??'\u2014').join('\/');\r\n            } },\r\n          { label:'Hardpoints (Launcher\/Turret)', get:(s)=> {\r\n              const La = get(s,'stats.Launcher Hardpoints.value',null);\r\n              const Tu = get(s,'stats.Turret Hardpoints.value',null);\r\n              return [La,Tu].map(v=>v??'\u2014').join('\/');\r\n            } },\r\n          { label:'Base Price (ISK)', get:(s)=> s.basePrice!=null? fmtNum(s.basePrice) : '\u2014' },\r\n          { label:'Build Time', get:(s)=> s.build && s.build.time!=null ? secsToHMS(s.build.time) : '\u2014' },\r\n        ];\r\n\r\n        html += '<tbody>';\r\n        for (const r of rows){\r\n          html += `<tr><td class=\"col-attr\">${r.label}<\/td>`;\r\n          for (const s of compared){\r\n            html += `<td>${r.get(s)}<\/td>`;\r\n          }\r\n          html += '<\/tr>';\r\n        }\r\n        html += '<\/tbody>';\r\n\r\n        els.compareTable.innerHTML = html;\r\n\r\n        els.compareTable.querySelectorAll('.remove-btn').forEach(btn=>{\r\n          btn.addEventListener('click', ()=>{\r\n            const id = Number(btn.getAttribute('data-typeid'));\r\n            removeFromCompare(id);\r\n          });\r\n        });\r\n      }\r\n\r\n      \/** Events **\/\r\n      els.search.addEventListener('input', () => renderList());\r\n      els.sortBtn.addEventListener('click', ()=>{\r\n        sortAsc = !sortAsc;\r\n        els.sortBtn.innerHTML = sortAsc\r\n          ? '<i class=\"fa fa-sort-alpha-asc\" aria-hidden=\"true\"><\/i>'\r\n          : '<i class=\"fa fa-sort-alpha-desc\" aria-hidden=\"true\"><\/i>';\r\n        renderList();\r\n      });\r\n      els.compareReset.addEventListener('click', ()=>{\r\n        compareList = [];\r\n        renderCompare();\r\n      });\r\n\r\n      \/\/ Deep link support\r\n      window.addEventListener('hashchange', ()=>{\r\n        const m = location.hash.match(\/typeID-(\\d+)\/);\r\n        if(m) selectShip(Number(m[1]));\r\n      });\r\n\r\n      \/\/ Kick off\r\n      load().then(()=>{\r\n        if (ships.length){ selectShip(ships[0].typeID); }\r\n        const m = location.hash.match(\/typeID-(\\d+)\/);\r\n        if(m) selectShip(Number(m[1]));\r\n      });\r\n    })();\r\n  <\/script>\r\n<\/div>\r\n","protected":false},"excerpt":{"rendered":"<p>Plunge into the uncharted void of EVE Frontier Cycle 5 with our definitive Ship Database! Select any hull to uncover its stats, blueprint requirements, module slots, and hardpoint configurations \u2014 now with beautiful ship icons. Compare ships to craft strategies for scavenging, combat, or base-building. Select a ship Use the left sidebar to browse all [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":80,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[],"class_list":["post-46","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tools"],"yoast_head":"<!-- Meta Tags -->\r\n<title>EVE Frontier Ship Database Explorer<\/title>\r\n<meta name=\"description\" content=\"Plunge into the uncharted void of EVE Frontier Cycle 5 with our definitive Ship Database! Select any hull to uncover its stats, blueprint requirements,\" \/>\r\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\r\n<link rel=\"canonical\" href=\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/\" \/>\r\n<meta property=\"og:locale\" content=\"en_US\" \/>\r\n<meta property=\"og:type\" content=\"article\" \/>\r\n<meta property=\"og:title\" content=\"EVE Frontier Ship Database Explorer\" \/>\r\n<meta property=\"og:description\" content=\"Plunge into the uncharted void of EVE Frontier Cycle 5 with our definitive Ship Database! Select any hull to uncover its stats, blueprint requirements,\" \/>\r\n<meta property=\"og:url\" content=\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/\" \/>\r\n<meta property=\"og:site_name\" content=\"EVE Frontier\" \/>\r\n<meta property=\"article:publisher\" content=\"facebook.com\/gamingwithdaopa\/\" \/>\r\n<meta property=\"article:author\" content=\"facebook.com\/gamingwithdaopa\/\" \/>\r\n<meta property=\"article:published_time\" content=\"2025-08-22T17:40:08+00:00\" \/>\r\n<meta property=\"article:modified_time\" content=\"2026-06-04T01:53:24+00:00\" \/>\r\n<meta property=\"og:image\" content=\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-content\/uploads\/sites\/40\/2025\/08\/eve-frontier-ship-database.jpg\" \/>\r\n\t<meta property=\"og:image:width\" content=\"400\" \/>\r\n\t<meta property=\"og:image:height\" content=\"263\" \/>\r\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\r\n<meta name=\"author\" content=\"daopa\" \/>\r\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\r\n<meta name=\"twitter:creator\" content=\"@gamingwithdaopa\" \/>\r\n<meta name=\"twitter:site\" content=\"@gamingwithdaopa\" \/>\r\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"daopa\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"1 minute\" \/>\r\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/\"},\"author\":{\"name\":\"daopa\",\"@id\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/#\/schema\/person\/fb03a927907d90f409fac550ba375638\"},\"headline\":\"EVE Frontier Ship Database Explorer\",\"datePublished\":\"2025-08-22T17:40:08+00:00\",\"dateModified\":\"2026-06-04T01:53:24+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/\"},\"wordCount\":110,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/#\/schema\/person\/fb03a927907d90f409fac550ba375638\"},\"image\":{\"@id\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-content\/uploads\/sites\/40\/2025\/08\/eve-frontier-ship-database.jpg\",\"articleSection\":[\"Tools\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/\",\"url\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/\",\"name\":\"EVE Frontier Ship Database Explorer\",\"isPartOf\":{\"@id\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-content\/uploads\/sites\/40\/2025\/08\/eve-frontier-ship-database.jpg\",\"datePublished\":\"2025-08-22T17:40:08+00:00\",\"dateModified\":\"2026-06-04T01:53:24+00:00\",\"description\":\"Plunge into the uncharted void of EVE Frontier Cycle 5 with our definitive Ship Database! Select any hull to uncover its stats, blueprint requirements,\",\"breadcrumb\":{\"@id\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/#primaryimage\",\"url\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-content\/uploads\/sites\/40\/2025\/08\/eve-frontier-ship-database.jpg\",\"contentUrl\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-content\/uploads\/sites\/40\/2025\/08\/eve-frontier-ship-database.jpg\",\"width\":400,\"height\":263,\"caption\":\"eve frontier ship database\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"EVE Frontier Ship Database Explorer\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/#website\",\"url\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/\",\"name\":\"EVE Frontier\",\"description\":\"DaOpa&#039;s EVE Frontier Fansite - Guides, tools, databases, and lists to empower the EVE Frontier community in exploring the stars.\",\"publisher\":{\"@id\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/#\/schema\/person\/fb03a927907d90f409fac550ba375638\"},\"alternateName\":\"evefrontier\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/#\/schema\/person\/fb03a927907d90f409fac550ba375638\",\"name\":\"daopa\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-content\/uploads\/sites\/40\/2025\/08\/90-90-Logo.png\",\"contentUrl\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-content\/uploads\/sites\/40\/2025\/08\/90-90-Logo.png\",\"width\":90,\"height\":90,\"caption\":\"daopa\"},\"logo\":{\"@id\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/#\/schema\/person\/image\/\"},\"description\":\"DaOpa has been variety streamer since 2009 with game focuses on primarily MMOs, Sandbox, RPG and FPS genres. For inquires comment in the comments sections. This channel is syndicated across various micro niche gaming related blogs operated by DaOpa. He creates fansites, guides, tools for gamers\",\"sameAs\":[\"https:\/\/gamingwithdaopa.ellatha.com\",\"facebook.com\/gamingwithdaopa\/\",\"https:\/\/x.com\/gamingwithdaopa\",\"youtube.com\/@daopa\"],\"url\":\"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/author\/daopa\/\"}]}<\/script>","yoast_head_json":{"title":"EVE Frontier Ship Database Explorer","description":"Plunge into the uncharted void of EVE Frontier Cycle 5 with our definitive Ship Database! Select any hull to uncover its stats, blueprint requirements,","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:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/","og_locale":"en_US","og_type":"article","og_title":"EVE Frontier Ship Database Explorer","og_description":"Plunge into the uncharted void of EVE Frontier Cycle 5 with our definitive Ship Database! Select any hull to uncover its stats, blueprint requirements,","og_url":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/","og_site_name":"EVE Frontier","article_publisher":"facebook.com\/gamingwithdaopa\/","article_author":"facebook.com\/gamingwithdaopa\/","article_published_time":"2025-08-22T17:40:08+00:00","article_modified_time":"2026-06-04T01:53:24+00:00","og_image":[{"width":400,"height":263,"url":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-content\/uploads\/sites\/40\/2025\/08\/eve-frontier-ship-database.jpg","type":"image\/jpeg"}],"author":"daopa","twitter_card":"summary_large_image","twitter_creator":"@gamingwithdaopa","twitter_site":"@gamingwithdaopa","twitter_misc":{"Written by":"daopa","Est. reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/#article","isPartOf":{"@id":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/"},"author":{"name":"daopa","@id":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/#\/schema\/person\/fb03a927907d90f409fac550ba375638"},"headline":"EVE Frontier Ship Database Explorer","datePublished":"2025-08-22T17:40:08+00:00","dateModified":"2026-06-04T01:53:24+00:00","mainEntityOfPage":{"@id":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/"},"wordCount":110,"commentCount":1,"publisher":{"@id":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/#\/schema\/person\/fb03a927907d90f409fac550ba375638"},"image":{"@id":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/#primaryimage"},"thumbnailUrl":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-content\/uploads\/sites\/40\/2025\/08\/eve-frontier-ship-database.jpg","articleSection":["Tools"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/","url":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/","name":"EVE Frontier Ship Database Explorer","isPartOf":{"@id":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/#website"},"primaryImageOfPage":{"@id":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/#primaryimage"},"image":{"@id":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/#primaryimage"},"thumbnailUrl":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-content\/uploads\/sites\/40\/2025\/08\/eve-frontier-ship-database.jpg","datePublished":"2025-08-22T17:40:08+00:00","dateModified":"2026-06-04T01:53:24+00:00","description":"Plunge into the uncharted void of EVE Frontier Cycle 5 with our definitive Ship Database! Select any hull to uncover its stats, blueprint requirements,","breadcrumb":{"@id":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/#primaryimage","url":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-content\/uploads\/sites\/40\/2025\/08\/eve-frontier-ship-database.jpg","contentUrl":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-content\/uploads\/sites\/40\/2025\/08\/eve-frontier-ship-database.jpg","width":400,"height":263,"caption":"eve frontier ship database"},{"@type":"BreadcrumbList","@id":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/ship-database\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/"},{"@type":"ListItem","position":2,"name":"EVE Frontier Ship Database Explorer"}]},{"@type":"WebSite","@id":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/#website","url":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/","name":"EVE Frontier","description":"DaOpa&#039;s EVE Frontier Fansite - Guides, tools, databases, and lists to empower the EVE Frontier community in exploring the stars.","publisher":{"@id":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/#\/schema\/person\/fb03a927907d90f409fac550ba375638"},"alternateName":"evefrontier","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/#\/schema\/person\/fb03a927907d90f409fac550ba375638","name":"daopa","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/#\/schema\/person\/image\/","url":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-content\/uploads\/sites\/40\/2025\/08\/90-90-Logo.png","contentUrl":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-content\/uploads\/sites\/40\/2025\/08\/90-90-Logo.png","width":90,"height":90,"caption":"daopa"},"logo":{"@id":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/#\/schema\/person\/image\/"},"description":"DaOpa has been variety streamer since 2009 with game focuses on primarily MMOs, Sandbox, RPG and FPS genres. For inquires comment in the comments sections. This channel is syndicated across various micro niche gaming related blogs operated by DaOpa. He creates fansites, guides, tools for gamers","sameAs":["https:\/\/gamingwithdaopa.ellatha.com","facebook.com\/gamingwithdaopa\/","https:\/\/x.com\/gamingwithdaopa","youtube.com\/@daopa"],"url":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/author\/daopa\/"}]}},"_links":{"self":[{"href":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-json\/wp\/v2\/posts\/46","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-json\/wp\/v2\/comments?post=46"}],"version-history":[{"count":4,"href":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-json\/wp\/v2\/posts\/46\/revisions"}],"predecessor-version":[{"id":221,"href":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-json\/wp\/v2\/posts\/46\/revisions\/221"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-json\/wp\/v2\/media\/80"}],"wp:attachment":[{"href":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-json\/wp\/v2\/media?parent=46"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-json\/wp\/v2\/categories?post=46"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gamingwithdaopa.ellatha.com\/evefrontier\/wp-json\/wp\/v2\/tags?post=46"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}