1<!doctype html> 2<html lang="en" data-theme="crucible"> 3<head> 4 <meta charset="utf-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1"> 6 <title>Price Check â SolarCrucible/HighStellar Syndicates</title> 7 <meta name="theme-color" content="#231410"> 8 <!-- CMS_PUBLIC_ADSENSE_V1 section=pricecheck --> 9 <meta name="evesyndicates-ad-section" content="pricecheck"> 10
10<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-6238237199007075" crossorigin="anonymous"></script>
10 11 12 13 14 15 16 <link rel="icon" href="/assets/brand/themes/crucible/favicon.png?v=1787613252"> 17 <link rel="preload" as="image" href="/assets/brand/themes/crucible/header.jpg?v=1787613252"> 18 <link rel="stylesheet" href="/assets/style.css?v=1787613252"> 19 <link rel="stylesheet" href="/assets/stellar_navigation.css?v=1787716059"> 20 <link rel="stylesheet" href="/assets/contextual_help.css?v=1787613252"> 21 <style> 22 :root{ --header-bg: url('/assets/brand/themes/crucible/header.jpg?v=1787613252'); --hero-bg: url('/assets/brand/themes/crucible/hero.jpg?v=1787613252'); } 23 24 /* Compact character portrait + location badge (top header, right side) */ 25.userbadge{display:flex; align-items:center; justify-content:flex-end; gap:12px; min-width:0; max-width:720px} 26.userbadge--link{padding:8px 10px; border-radius:18px; text-decoration:none; color:inherit; border:1px solid rgba(255,255,255,.10); background:linear-gradient(180deg, rgba(255,255,255,.10), rgba(255,255,255,.04)); box-shadow:0 12px 24px rgba(0,0,0,.26); transition:transform .15s ease, border-color .15s ease, box-shadow .15s ease, background .15s ease} 27.userbadge--link:hover,.userbadge--link:focus-visible{transform:translateY(-1px); border-color:rgba(255,255,255,.22); background:linear-gradient(180deg, rgba(255,255,255,.14), rgba(255,255,255,.06)); box-shadow:0 16px 30px rgba(0,0,0,.34); outline:none} 28.userbadge__portrait{width:48px; height:48px; border-radius:14px; flex:0 0 auto; 29 border:1px solid rgba(255,255,255,.16); background:rgba(0,0,0,.22); 30 box-shadow: 0 10px 18px rgba(0,0,0,.35); 31} 32.userbadge__meta{min-width:0; text-align:right; line-height:1.08} 33.userbadge__headline,.userbadge__corp,.userbadge__loc{white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:600px; display:block} 34.userbadge__headline{font-size:.86rem; font-weight:900; color:rgba(231,236,255,.98)} 35.userbadge__name{font-weight:1000} 36.userbadge__role{font-weight:800; color:rgba(231,236,255,.78)} 37.userbadge__sep{opacity:.52; margin:0 .2rem} 38.userbadge__corp{font-size:.76rem; color:rgba(231,236,255,.84)} 39.userbadge__loc{font-size:.76rem; color:rgba(231,236,255,.74)} 40.userbadge__sec{font-weight:800} 41@media (max-width: 720px){ .userbadge{max-width:420px} .userbadge__headline,.userbadge__corp,.userbadge__loc{max-width:340px} } 42@media (max-width: 520px){ .userbadge{max-width:255px} .userbadge__headline,.userbadge__corp,.userbadge__loc{max-width:185px} } 43 44 45/* CMS_HEADER_LOGOUT_BUTTON_V1: persistent sign-out action beside the pilot badge. */ 46.cms-header-account{display:flex;align-items:center;justify-content:flex-end;gap:8px;min-width:0;flex:0 1 auto} 47.cms-header-logout{display:inline-flex;align-items:center;justify-content:center;gap:7px;min-height:42px;padding:0 12px;border-radius:13px;border:1px solid rgba(255,112,143,.36);background:linear-gradient(180deg,rgba(93,24,42,.68),rgba(43,11,23,.66));color:rgba(255,239,244,.98);text-decoration:none;font-size:.78rem;font-weight:950;letter-spacing:.02em;white-space:nowrap;box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 10px 24px rgba(0,0,0,.22);transition:transform .15s ease,border-color .15s ease,background .15s ease,box-shadow .15s ease} 48.cms-header-logout:hover,.cms-header-logout:focus-visible{transform:translateY(-1px);border-color:rgba(255,132,157,.70);background:linear-gradient(180deg,rgba(126,32,55,.78),rgba(58,14,29,.76));box-shadow:inset 0 1px 0 rgba(255,255,255,.08),0 13px 28px rgba(0,0,0,.30),0 0 0 1px rgba(255,112,143,.08);outline:none} 49.cms-header-logout__icon{font-size:1rem;line-height:1} 50@media (max-width: 900px){.cms-header-logout{padding:0 10px}.cms-header-logout__label{display:none}} 51@media (max-width: 560px){.cms-header-account{gap:6px}.cms-header-logout{min-width:40px;padding:0 9px}} 52 53/* CEO/COO safe role preview */ 54/* CMS_VIEW_AS_HEADER_LAYER_HOTFIX_V1 55 The Stellar navigation is sticky at z-index 5000. Keep the header in the 56 normal document flow, but raise it while its View As flyout is open and 57 allow the flyout to escape the header bounds instead of being clipped. */ 58.topbar{overflow:visible!important} 59.topbar__inner{z-index:2} 60.topbar:has(.cms-view-as[open]){z-index:5100} 61.cms-view-as{position:relative;display:flex;align-items:center;z-index:1} 62.cms-view-as[open]{z-index:5200} 63.cms-view-as>summary{list-style:none;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:7px;min-height:40px;min-width:86px;padding:0 12px;border-radius:12px;border:1px solid rgba(134,187,255,.35);background:rgba(73,123,190,.13);font-weight:900;font-size:12px;line-height:1.1;letter-spacing:.02em;color:#eaf4ff;white-space:nowrap} 64.cms-view-as>summary::-webkit-details-marker{display:none} 65.cms-view-as[open]>summary{border-color:rgba(134,187,255,.65);background:rgba(73,123,190,.23)} 66.cms-view-as__menu{position:absolute;right:0;top:calc(100% + 8px);z-index:5210;width:250px;padding:12px;border-radius:16px;background:linear-gradient(180deg,rgba(18,28,48,.99),rgba(8,14,27,.99));border:1px solid rgba(255,255,255,.13);box-shadow:0 20px 48px rgba(0,0,0,.5)} 67.cms-view-as__menu-title{font-weight:1000;margin-bottom:4px}.cms-view-as__menu-sub{font-size:11px;opacity:.68;line-height:1.4;margin-bottom:10px}
68.cms-view-as__menu form{display:grid;gap:7px}.cms-view-as__menu button{width:100%;text-align:left;padding:9px 11px;border-radius:10px;border:1px solid rgba(255,255,255,.1);background:rgba(255,255,255,.045);color:#eef5ff;font-weight:850;cursor:pointer}.cms-view-as__menu button:hover{background:rgba(116,177,255,.14);border-color:rgba(116,177,255,.42)} 69 70.cms-vacation-banner{position:relative;z-index:899;background:linear-gradient(90deg,rgba(23,74,110,.98),rgba(34,82,91,.98));border-top:1px solid rgba(125,220,255,.28);border-bottom:1px solid rgba(125,220,255,.32);color:#eafaff} 71.cms-vacation-banner__inner{min-height:52px;display:flex;gap:14px;align-items:center;justify-content:center;flex-wrap:wrap;padding:8px 16px;font-weight:800}.cms-vacation-banner form{margin:0}.cms-vacation-banner button{border:1px solid rgba(255,255,255,.45);background:rgba(255,255,255,.14);color:#fff;padding:8px 13px;border-radius:10px;font-weight:950;cursor:pointer} 72 73.cms-role-preview-banner{position:relative;z-index:900;background:linear-gradient(90deg,rgba(122,75,9,.98),rgba(117,45,19,.98));border-top:1px solid rgba(255,211,118,.38);border-bottom:1px solid rgba(255,211,118,.42);color:#fff4d9} 74.cms-role-preview-banner__inner{min-height:50px;display:flex;gap:14px;align-items:center;justify-content:center;flex-wrap:wrap;padding:8px 16px;font-weight:850}.cms-role-preview-banner strong{color:#fff}.cms-role-preview-banner form{margin:0}.cms-role-preview-banner button{border:1px solid rgba(255,255,255,.4);background:rgba(255,255,255,.13);color:#fff;padding:7px 12px;border-radius:10px;font-weight:950;cursor:pointer} 75@media (max-width:900px){.cms-view-as>summary{padding:0 9px}.cms-view-as__label{display:none}.cms-view-as__menu{right:-56px}} 76 77/* Hall of Fame nav pill */ 78.pill--hof{ 79 position:relative; 80 color:#fff7dc !important; 81 background:linear-gradient(180deg, rgba(255,221,115,.30), rgba(171,118,23,.34)) !important; 82 border:1px solid rgba(255,214,102,.58) !important; 83 box-shadow: inset 0 1px 0 rgba(255,245,200,.28), 0 8px 18px rgba(76,50,6,.24); 84 text-shadow:0 1px 0 rgba(77,45,0,.45); 85} 86.pill--hof:hover, 87.pill--hof:focus-visible{ 88 background:linear-gradient(180deg, rgba(255,230,140,.38), rgba(190,132,28,.42)) !important; 89 border-color:rgba(255,224,132,.72) !important; 90 box-shadow: inset 0 1px 0 rgba(255,249,220,.34), 0 10px 22px rgba(95,63,9,.30), 0 0 0 1px rgba(255,219,112,.12); 91} 92.pill--hof::before{ 93 content:'ð'; 94 margin-right:.4rem; 95} 96 97/* Global page loading overlay */ 98.page-loader{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(6,10,18,.70);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);opacity:0;visibility:hidden;pointer-events:none;transition:opacity .18s ease, visibility .18s ease;z-index:9999;} 99.page-loader.is-visible{opacity:1;visibility:visible;pointer-events:auto;} 100.page-loader__panel{min-width:230px;max-width:min(92vw,420px);padding:18px 20px;border-radius:20px;background:linear-gradient(180deg, rgba(16,24,44,.96), rgba(9,14,27,.96));border:1px solid rgba(255,255,255,.12);box-shadow:0 18px 40px rgba(0,0,0,.45);display:flex;align-items:center;gap:14px;color:#eef3ff;} 101.page-loader__spinner{width:26px;height:26px;border-radius:999px;border:3px solid rgba(255,255,255,.18);border-top-color:#8ec5ff;animation:page-loader-spin .8s linear infinite;flex:0 0 auto;} 102.page-loader__text{font-weight:1000;letter-spacing:.02em;} 103.page-loader__sub{font-size:12px;opacity:.72;margin-top:2px;} 104@keyframes page-loader-spin{to{transform:rotate(360deg)}} 105 </style> 106</head> 107<body> 108 <header class="topbar"> 109 <div class="topbar__bg" aria-hidden="true"></div> 110 <div class="topbar__inner container"> 111 <a class="brandmark" href="/" aria-label="Home"> 112 <img class="brandmark__logo" src="/assets/brand/themes/crucible/logo.png?v=1787613252" alt="SolarCrucible/HighStellar Syndicates"> 113 <div class="brandmark__text"> 114 <div class="brandmark__org">Eve Syndicates</div> 115 <div class="brandmark__app">Corporation Management System</div> 116 </div> 117 </a> 118 119 <div class="cms-header-search" data-stellar-header-search>
120 <span class="cms-header-search__icon" aria-hidden="true">â</span> 121 <input type="search" data-stellar-header-search-input placeholder="Search CMS + EVEâ¦" aria-label="Search the Corporation Management System and EVE help" autocomplete="off" readonly> 122 <kbd>Ctrl K</kbd> 123 </div> 124 <button type="button" class="cms-header-help" data-help-open title="Help for this page" aria-label="Help for this page"><span class="cms-header-help__q" aria-hidden="true">?</span><span class="cms-header-help__label">Help</span></button> 125 126 127 </div> 128 </header> 129 130 131 132 <section class="stellar-nav" data-stellar-nav aria-label="CMS navigation"> 133 <div class="stellar-nav__stars" aria-hidden="true"></div> 134 <div class="container stellar-nav__shell stellar-nav__shell--compact"> 135 <div class="stellar-nav__primary-row"> 136 <nav class="stellar-nav__bar" aria-label="Primary navigation"> 137 <details class="stellar-menu stellar-menu--cyan"> 138 <summary class="stellar-menu__trigger"> 139 <span class="stellar-menu__icon" aria-hidden="true">â</span> 140 <span>Public Portal</span> 141 </summary> 142 <div class="stellar-menu__panel"> 143 <div class="stellar-menu__panel-head"><span>Public Portal</span><small>4 links</small></div> 144 <div class="stellar-menu__sections"><section class="stellar-menu__section"><div class="stellar-menu__grid"> <a class="stellar-card" href="/" data-stellar-launch data-result-type="page" data-search-title="home" data-search="home return to the eve syndicates public portal. landing portal"> 145 <span class="stellar-card__icon" aria-hidden="true">â</span> 146 <span class="stellar-card__body"> 147 <span class="stellar-card__title">Home</span> 148 <span class="stellar-card__desc">Return to the EVE Syndicates public portal.</span> </span> 149 <span class="stellar-card__badges"> 150 </span> 151 </a> 152 <a class="stellar-card is-active" href="/pricecheck.php" data-stellar-launch data-result-type="page" data-search-title="public price check" data-search="public price check paste items and value them without logging in. market appraisal value"> 153 <span class="stellar-card__icon" aria-hidden="true">â</span> 154 <span class="stellar-card__body"> 155 <span class="stellar-card__title">Public Price Check</span> 156 <span class="stellar-card__desc">Paste items and value them without logging in.</span> </span> 157 <span class="stellar-card__badges"> 158 </span> 159 </a> 160 <a class="stellar-card" href="/onboarding/" data-stellar-launch data-result-type="page" data-search-title="apply to this corp" data-search="apply to this corp start the corporation application and onboarding flow. application recruit join"> 161 <span class="stellar-card__icon" aria-hidden="true">â¤</span> 162 <span class="stellar-card__body"> 163 <span class="stellar-card__title">Apply to This Corp</span> 164 <span class="stellar-card__desc">Start the corporation application and onboarding flow.</span> </span> 165 <span class="stellar-card__badges"> 166 </span> 167 </a> 168 <a class="stellar-card" href="/login.php" data-stellar-launch data-result-type="page" data-search-title="member login" data-search="member login access the cms pilot command desk. sign in sso"> 169 <span class="stellar-card__icon" aria-hidden="true">â</span> 170 <span class="stellar-card__body"> 171 <span class="stellar-card__title">Member Login</span> 172 <span class="stellar-card__desc">Access the CMS pilot command desk.</span> </span> 173 <span class="stellar-card__badges"> 174 </span> 175 </a> 176 </div></section></div> </div> 177 </details> 178 </nav> 179 180 <div class="stellar-nav__actions"> 181 <div class="stellar-nav__chips stellar-nav__chips--compact" aria-label="Session status">
182 <span class="stellar-chip stellar-chip--role">Public</span> 183 </div> 184 <button class="stellar-nav__quick" type="button" data-stellar-open-search aria-label="Search CMS"><span>Search</span><kbd>Ctrl K</kbd></button> 185 <button class="stellar-nav__mobile" type="button" data-stellar-open-drawer aria-label="Open navigation"><span></span><span></span><span></span></button> 186 </div> 187 </div> 188 189 </div> 190 191 <div class="stellar-search" data-stellar-search aria-hidden="true"> 192 <div class="stellar-search__backdrop" data-stellar-close-search></div> 193 <div class="stellar-search__panel" role="dialog" aria-modal="true" aria-label="Search CMS"> 194 <div class="stellar-search__head"> 195 <div><strong>Search CMS + EVE</strong><small>CMS pages first, then Help, EVE knowledge, and trusted outside learning resources</small></div> 196 <button type="button" data-stellar-close-search aria-label="Close CMS search">Ã</button> 197 </div> 198 <label class="stellar-search__box"><span>â</span><input type="search" data-stellar-search-input placeholder="Search CMS or ask an EVE topic: scanning, PI, bubbles, haulingâ¦" autocomplete="off"></label> 199 <div class="stellar-search__results" data-stellar-search-results> 200 <div class="stellar-search__prompt" data-stellar-search-prompt> 201 <strong>Search everything from one box.</strong> 202 <span>Try <b>scanning</b>, <b>referral</b>, <b>PI</b>, <b>bubbles</b>, <b>hauling</b>, <b>blueprints</b>, or the name of any CMS feature.</span> 203 <small>Results stay on Eve Syndicates first. Trusted outside EVE learning links are shown afterward.</small> 204 </div> 205 <a class="stellar-card stellar-card--compact" href="/" data-stellar-launch data-result-type="page" data-search-title="home" data-search="home return to the eve syndicates public portal. landing portal public portal"> 206 <span class="stellar-card__icon" aria-hidden="true">â</span> 207 <span class="stellar-card__body"> 208 <span class="stellar-card__title">Home</span> 209 <span class="stellar-card__context">Public Portal</span> </span> 210 <span class="stellar-card__badges"> 211 </span> 212 </a> 213 <a class="stellar-card is-active stellar-card--compact" href="/pricecheck.php" data-stellar-launch data-result-type="page" data-search-title="public price check" data-search="public price check paste items and value them without logging in. market appraisal value public portal"> 214 <span class="stellar-card__icon" aria-hidden="true">â</span> 215 <span class="stellar-card__body"> 216 <span class="stellar-card__title">Public Price Check</span> 217 <span class="stellar-card__context">Public Portal</span> </span> 218 <span class="stellar-card__badges"> 219 </span> 220 </a> 221 <a class="stellar-card stellar-card--compact" href="/onboarding/" data-stellar-launch data-result-type="page" data-search-title="apply to this corp" data-search="apply to this corp start the corporation application and onboarding flow. application recruit join public portal"> 222 <span class="stellar-card__icon" aria-hidden="true">â¤</span> 223 <span class="stellar-card__body"> 224 <span class="stellar-card__title">Apply to This Corp</span> 225 <span class="stellar-card__context">Public Portal</span> </span> 226 <span class="stellar-card__badges"> 227 </span> 228 </a> 229 <a class="stellar-card stellar-card--compact" href="/login.php" data-stellar-launch data-result-type="page" data-search-title="member login" data-search="member login access the cms pilot command desk. sign in sso public portal"> 230 <span class="stellar-card__icon" aria-hidden="true">â</span> 231 <span class="stellar-card__body"> 232 <span class="stellar-card__title">Member Login</span> 233 <span class="stellar-card__context">Public Portal</span> </span>
234 <span class="stellar-card__badges"> 235 </span> 236 </a> 237 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=how-to-use-the-cms-help-system" data-stellar-launch data-result-type="help" data-search-title="how to use the cms help system" data-search="how to use the cms help system click ? help beside a page heading or in the main header. the drawer explains the current screen without making you leave it. help question mark contextual drawer guide instructions new pilot search cms documentation knowledge base start here help guide instructions cms help"> 238 <span class="stellar-card__icon" aria-hidden="true">?</span> 239 <span class="stellar-card__body"> 240 <span class="stellar-card__title">How to Use the CMS Help System</span> 241 <span class="stellar-card__context">CMS Help</span> </span> 242 <span class="stellar-card__badges"> 243 <span class="stellar-card__badge">HELP</span> </span> 244 </a> 245 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=how-to-use-search-cms" data-stellar-launch data-result-type="help" data-search-title="how to use search cms" data-search="how to use search cms press ctrl-k or click search cms, type what you are trying to do, then open the matching page or help result. search ctrl k quick launch command palette find page help article start here help guide instructions cms help"> 246 <span class="stellar-card__icon" aria-hidden="true">?</span> 247 <span class="stellar-card__body"> 248 <span class="stellar-card__title">How to Use Search CMS</span> 249 <span class="stellar-card__context">CMS Help</span> </span> 250 <span class="stellar-card__badges"> 251 <span class="stellar-card__badge">HELP</span> </span> 252 </a> 253 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=start-here-what-the-cms-is-and-why-we-use-it" data-stellar-launch data-result-type="help" data-search-title="start here: what the cms is and why we use it" data-search="start here: what the cms is and why we use it the cms is the corporation's shared operations system for fleets, industry, logistics, training, records, and member workflows. use the menus or search cms to find the task you need. cms start here corporation management system overview new player start here help guide instructions cms help"> 254 <span class="stellar-card__icon" aria-hidden="true">?</span> 255 <span class="stellar-card__body"> 256 <span class="stellar-card__title">Start Here: What the CMS Is and Why We Use It</span> 257 <span class="stellar-card__context">CMS Help</span> </span> 258 <span class="stellar-card__badges"> 259 <span class="stellar-card__badge">HELP</span> </span> 260 </a> 261 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=how-to-use-price-check" data-stellar-launch data-result-type="help" data-search-title="how to use price check" data-search="how to use price check paste the item list into price check, review the amarr-based values and selected percentage, then copy the result you need. price check amarr items valuation buyback isk new player support help guide instructions cms help"> 262 <span class="stellar-card__icon" aria-hidden="true">?</span> 263 <span class="stellar-card__body"> 264 <span class="stellar-card__title">How to Use Price Check</span> 265 <span class="stellar-card__context">CMS Help</span> </span> 266 <span class="stellar-card__badges"> 267 <span class="stellar-card__badge">HELP</span> </span> 268 </a> 269 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=how-to-link-discord" data-stellar-launch data-result-type="help" data-search-title="how to link discord to the cms" data-search="how to link discord to the cms open discord link from your profile/pilot menu and follow the displayed linking steps so the cms can match your pilot to your discord account. discord link account channelbot pilot profile discord setup help guide instructions cms help">
270 <span class="stellar-card__icon" aria-hidden="true">?</span> 271 <span class="stellar-card__body"> 272 <span class="stellar-card__title">How to Link Discord to the CMS</span> 273 <span class="stellar-card__context">CMS Help</span> </span> 274 <span class="stellar-card__badges"> 275 <span class="stellar-card__badge">HELP</span> </span> 276 </a> 277 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=help-page-guide" data-stellar-launch data-result-type="help" data-search-title="reading cms help articles" data-search="reading cms help articles use the quick answer first, then read the full instructions or new pilot guidance only when you need more detail. help article quick answer new pilot guidance related article help center start here help guide instructions cms help"> 278 <span class="stellar-card__icon" aria-hidden="true">?</span> 279 <span class="stellar-card__body"> 280 <span class="stellar-card__title">Reading CMS Help Articles</span> 281 <span class="stellar-card__context">CMS Help</span> </span> 282 <span class="stellar-card__badges"> 283 <span class="stellar-card__badge">HELP</span> </span> 284 </a> 285 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=help-assistant-status-guide" data-stellar-launch data-result-type="help" data-search-title="help assistant & ticket status" data-search="help assistant & ticket status use the normal help center, contextual ? help, or suggest a feature while assistant/ticket features are marked planned or disabled. help assistant ticket planned disabled support helpbot future start here help guide instructions cms help"> 286 <span class="stellar-card__icon" aria-hidden="true">?</span> 287 <span class="stellar-card__body"> 288 <span class="stellar-card__title">Help Assistant & Ticket Status</span> 289 <span class="stellar-card__context">CMS Help</span> </span> 290 <span class="stellar-card__badges"> 291 <span class="stellar-card__badge">HELP</span> </span> 292 </a> 293 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=onboarding-pilot-guide" data-stellar-launch data-result-type="help" data-search-title="corporation onboarding" data-search="corporation onboarding follow the current onboarding status page. complete only the step it asks for next; staff review and background-check steps can take time. onboarding application applicant background check provisional solar crucible status start here help guide instructions cms help"> 294 <span class="stellar-card__icon" aria-hidden="true">?</span> 295 <span class="stellar-card__body"> 296 <span class="stellar-card__title">Corporation Onboarding</span> 297 <span class="stellar-card__context">CMS Help</span> </span> 298 <span class="stellar-card__badges"> 299 <span class="stellar-card__badge">HELP</span> </span> 300 </a> 301 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=pilot-command-desk-guide" data-stellar-launch data-result-type="help" data-search-title="pilot command desk" data-search="pilot command desk start here when you log in. use the top navigation or search cms to jump to the task you need. home pilot command desk cms navigation search ctrl k start here help guide instructions cms help"> 302 <span class="stellar-card__icon" aria-hidden="true">?</span> 303 <span class="stellar-card__body"> 304 <span class="stellar-card__title">Pilot Command Desk</span> 305 <span class="stellar-card__context">CMS Help</span> </span> 306 <span class="stellar-card__badges"> 307 <span class="stellar-card__badge">HELP</span> </span> 308 </a> 309 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=provisional-dashboard-guide" data-stellar-launch data-result-type="help" data-search-title="provisional member dashboard" data-search="provisional member dashboard the provisional dashboard shows the actions and information available during the provisional period. complete checklist items and use the provided links rather than looking for hidden full-member menus. provisional member dashboard checklist discord onboarding probation start here help guide instructions cms help">
310 <span class="stellar-card__icon" aria-hidden="true">?</span> 311 <span class="stellar-card__body"> 312 <span class="stellar-card__title">Provisional Member Dashboard</span> 313 <span class="stellar-card__context">CMS Help</span> </span> 314 <span class="stellar-card__badges"> 315 <span class="stellar-card__badge">HELP</span> </span> 316 </a> 317 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-scanning-dscan-probes" data-stellar-launch data-result-type="eve" data-search-title="eve scanning: d-scan, probe scanner & probes" data-search="eve scanning: d-scan, probe scanner & probes use d-scan to check what is around you without launching probes. use the probe scanner with core probes to locate cosmic signatures such as relic, data, wormhole, and other scannable sites. scanning scan scanner dscan d-scan directional scanner probe probes probing probe scanner core scanner probes combat probes signatures cosmic signatures exploration alt-p eve new player knowledge help guide instructions eve knowledge"> 318 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 319 <span class="stellar-card__body"> 320 <span class="stellar-card__title">EVE Scanning: D-Scan, Probe Scanner & Probes</span> 321 <span class="stellar-card__context">EVE Knowledge</span> </span> 322 <span class="stellar-card__badges"> 323 <span class="stellar-card__badge">EVE GUIDE</span> </span> 324 </a> 325 <a class="stellar-card stellar-card--compact" href="/referrals.php" data-stellar-launch data-result-type="page" data-search-title="open referral page" data-search="open referral page share the official referral link when you want the cms to record who referred a new applicant. recruitment referrals referral recruit applicant link code attribution recruitment page feature open go to cms page"> 326 <span class="stellar-card__icon" aria-hidden="true">â</span> 327 <span class="stellar-card__body"> 328 <span class="stellar-card__title">Open Referral Page</span> 329 <span class="stellar-card__context">CMS Page</span> </span> 330 <span class="stellar-card__badges"> 331 <span class="stellar-card__badge">CMS</span> </span> 332 </a> 333 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=referrals-guide" data-stellar-launch data-result-type="help" data-search-title="recruitment referrals" data-search="recruitment referrals share the official referral link when you want the cms to record who referred a new applicant. referral recruit applicant link code attribution recruitment corporation & membership help guide instructions cms help"> 334 <span class="stellar-card__icon" aria-hidden="true">?</span> 335 <span class="stellar-card__body"> 336 <span class="stellar-card__title">Recruitment Referrals</span> 337 <span class="stellar-card__context">CMS Help</span> </span> 338 <span class="stellar-card__badges"> 339 <span class="stellar-card__badge">HELP</span> </span> 340 </a> 341 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=partner-access-guide" data-stellar-launch data-result-type="help" data-search-title="partner access / branded instance request" data-search="partner access / branded instance request enter the organization and contact details, choose the type of access requested, and submit the form for leadership review. partner access branded instance alliance corporation request allowlist external organization corporation & membership help guide instructions cms help"> 342 <span class="stellar-card__icon" aria-hidden="true">?</span> 343 <span class="stellar-card__body"> 344 <span class="stellar-card__title">Partner Access / Branded Instance Request</span> 345 <span class="stellar-card__context">CMS Help</span> </span> 346 <span class="stellar-card__badges"> 347 <span class="stellar-card__badge">HELP</span> </span> 348 </a> 349 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-exploration-relic-data-sites" data-stellar-launch data-result-type="eve" data-search-title="exploration, relic sites & data sites" data-search="exploration, relic sites & data sites exploration uses probe scanning to find cosmic signatures, then analyzers to hack relic or data containers for loot. it is one of the easiest careers to begin with a small inexpensive frigate. exploration explorer relic data site sites hacking cosmic signature signatures archaeology analyzer data analyzer relic analyzer loot scan scanning eve new player knowledge help guide instructions eve knowledge">
350 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 351 <span class="stellar-card__body"> 352 <span class="stellar-card__title">Exploration, Relic Sites & Data Sites</span> 353 <span class="stellar-card__context">EVE Knowledge</span> </span> 354 <span class="stellar-card__badges"> 355 <span class="stellar-card__badge">EVE GUIDE</span> </span> 356 </a> 357 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-hacking-basics" data-stellar-launch data-result-type="eve" data-search-title="hacking relic and data containers" data-search="hacking relic and data containers after you scan a relic or data site, approach a container, activate the correct analyzer, and complete the hacking minigame by finding and destroying the system core. hacking hack relic analyzer data analyzer virus coherence strength system core minigame exploration containers eve new player knowledge help guide instructions eve knowledge"> 358 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 359 <span class="stellar-card__body"> 360 <span class="stellar-card__title">Hacking Relic and Data Containers</span> 361 <span class="stellar-card__context">EVE Knowledge</span> </span> 362 <span class="stellar-card__badges"> 363 <span class="stellar-card__badge">EVE GUIDE</span> </span> 364 </a> 365 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-overview-local-basics" data-stellar-launch data-result-type="eve" data-search-title="overview, local chat & situational awareness" data-search="overview, local chat & situational awareness your overview shows objects and pilots on grid; local shows who is in the system where local is available. together with d-scan, they are your basic awareness tools. overview local chat situational awareness neutral red blue standings grid pilots danger hostile intel eve new player knowledge help guide instructions eve knowledge"> 366 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 367 <span class="stellar-card__body"> 368 <span class="stellar-card__title">Overview, Local Chat & Situational Awareness</span> 369 <span class="stellar-card__context">EVE Knowledge</span> </span> 370 <span class="stellar-card__badges"> 371 <span class="stellar-card__badge">EVE GUIDE</span> </span> 372 </a> 373 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-bookmarks-safe-spots" data-stellar-launch data-result-type="eve" data-search-title="bookmarks, safe spots & travel marks" data-search="bookmarks, safe spots & travel marks bookmarks save locations in space. they are used for safe spots, gate perches, instant-dock/undock locations, wormhole entrances, tactical positions, and repeated work sites. bookmark bookmarks safe safe spot safespot perch tactical instant dock undock gate travel wormhole marks locations eve new player knowledge help guide instructions eve knowledge"> 374 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 375 <span class="stellar-card__body"> 376 <span class="stellar-card__title">Bookmarks, Safe Spots & Travel Marks</span> 377 <span class="stellar-card__context">EVE Knowledge</span> </span> 378 <span class="stellar-card__badges"> 379 <span class="stellar-card__badge">EVE GUIDE</span> </span> 380 </a> 381 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-security-space-types" data-stellar-launch data-result-type="eve" data-search-title="high-sec, low-sec, null-sec & wormhole space" data-search="high-sec, low-sec, null-sec & wormhole space eve space has different security rules. high-sec has concord response, low-sec has limited empire enforcement, null-sec has no concord protection, and wormholes have their own local-chat and travel risks. highsec high-sec lowsec low-sec nullsec null-sec wormhole wormholes security status concord space types dangerous space eve new player knowledge help guide instructions eve knowledge">
382 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 383 <span class="stellar-card__body"> 384 <span class="stellar-card__title">High-Sec, Low-Sec, Null-Sec & Wormhole Space</span> 385 <span class="stellar-card__context">EVE Knowledge</span> </span> 386 <span class="stellar-card__badges"> 387 <span class="stellar-card__badge">EVE GUIDE</span> </span> 388 </a> 389 <a class="stellar-card stellar-card--compact" href="/university/" data-stellar-launch data-result-type="page" data-search-title="open thesyndicates university" data-search="open thesyndicates university warp disruption bubbles are area effects used mainly in null-sec and wormhole space to stop or alter warps. they are a major reason null-sec travel requires different habits than high-sec travel. warp bubbles & interdiction bubble bubbles warp disruption interdiction interdictor dictor hic drag bubble catch bubble nullsec travel gate camp warp page feature open go to cms page"> 390 <span class="stellar-card__icon" aria-hidden="true">â</span> 391 <span class="stellar-card__body"> 392 <span class="stellar-card__title">Open TheSyndicates University</span> 393 <span class="stellar-card__context">CMS Page</span> </span> 394 <span class="stellar-card__badges"> 395 <span class="stellar-card__badge">CMS</span> </span> 396 </a> 397 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-warp-bubbles-interdiction" data-stellar-launch data-result-type="eve" data-search-title="warp bubbles & interdiction" data-search="warp bubbles & interdiction warp disruption bubbles are area effects used mainly in null-sec and wormhole space to stop or alter warps. they are a major reason null-sec travel requires different habits than high-sec travel. bubble bubbles warp disruption interdiction interdictor dictor hic drag bubble catch bubble nullsec travel gate camp warp eve new player knowledge help guide instructions eve knowledge"> 398 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 399 <span class="stellar-card__body"> 400 <span class="stellar-card__title">Warp Bubbles & Interdiction</span> 401 <span class="stellar-card__context">EVE Knowledge</span> </span> 402 <span class="stellar-card__badges"> 403 <span class="stellar-card__badge">EVE GUIDE</span> </span> 404 </a> 405 <a class="stellar-card stellar-card--compact" href="/fits.php" data-stellar-launch data-result-type="page" data-search-title="open my fits" data-search="open my fits a ship fit is the combination of modules, rigs, ammunition, drones, and charges installed for a specific job. fits work best when they have one clear purpose. ship fittings: high, mid, low slots & rigs fit fitting fittings modules high slot mid slot low slot rigs cpu powergrid calibration ship fit eft pyfa doctrine page feature open go to cms page"> 406 <span class="stellar-card__icon" aria-hidden="true">â</span> 407 <span class="stellar-card__body"> 408 <span class="stellar-card__title">Open My Fits</span> 409 <span class="stellar-card__context">CMS Page</span> </span> 410 <span class="stellar-card__badges"> 411 <span class="stellar-card__badge">CMS</span> </span> 412 </a> 413 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-fittings-basics" data-stellar-launch data-result-type="eve" data-search-title="ship fittings: high, mid, low slots & rigs" data-search="ship fittings: high, mid, low slots & rigs a ship fit is the combination of modules, rigs, ammunition, drones, and charges installed for a specific job. fits work best when they have one clear purpose. fit fitting fittings modules high slot mid slot low slot rigs cpu powergrid calibration ship fit eft pyfa doctrine eve new player knowledge help guide instructions eve knowledge"> 414 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 415 <span class="stellar-card__body">
416 <span class="stellar-card__title">Ship Fittings: High, Mid, Low Slots & Rigs</span> 417 <span class="stellar-card__context">EVE Knowledge</span> </span> 418 <span class="stellar-card__badges"> 419 <span class="stellar-card__badge">EVE GUIDE</span> </span> 420 </a> 421 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-capacitor-modules" data-stellar-launch data-result-type="eve" data-search-title="capacitor, module activation & overheating" data-search="capacitor, module activation & overheating capacitor is your shipâs energy pool for many active modules. if your capacitor reaches zero, modules that require capacitor can shut off and your escape options may disappear. capacitor cap stable module activation cycle overheating heat thermodynamics neut neutralizer energy eve new player knowledge help guide instructions eve knowledge"> 422 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 423 <span class="stellar-card__body"> 424 <span class="stellar-card__title">Capacitor, Module Activation & Overheating</span> 425 <span class="stellar-card__context">EVE Knowledge</span> </span> 426 <span class="stellar-card__badges"> 427 <span class="stellar-card__badge">EVE GUIDE</span> </span> 428 </a> 429 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-tanking-basics" data-stellar-launch data-result-type="eve" data-search-title="shield, armor & hull tanking" data-search="shield, armor & hull tanking tanking is how a fit survives damage. most ships focus primarily on shield or armor rather than trying to maximize every defense layer at once. tank tanking shield armor hull buffer active tank resist resistance repairer booster extender plate damage control ehp eve new player knowledge help guide instructions eve knowledge"> 430 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 431 <span class="stellar-card__body"> 432 <span class="stellar-card__title">Shield, Armor & Hull Tanking</span> 433 <span class="stellar-card__context">EVE Knowledge</span> </span> 434 <span class="stellar-card__badges"> 435 <span class="stellar-card__badge">EVE GUIDE</span> </span> 436 </a> 437 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-drones-basics" data-stellar-launch data-result-type="eve" data-search-title="drones: launching, controlling & recalling" data-search="drones: launching, controlling & recalling drones are small controlled craft launched from a drone bay. they can deal damage, mine, repair, jam, salvage, or perform other specialized roles depending on type. drone drones drone bay bandwidth light medium heavy mining salvage repair ecm recall launch control eve new player knowledge help guide instructions eve knowledge"> 438 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 439 <span class="stellar-card__body"> 440 <span class="stellar-card__title">Drones: Launching, Controlling & Recalling</span> 441 <span class="stellar-card__context">EVE Knowledge</span> </span> 442 <span class="stellar-card__badges"> 443 <span class="stellar-card__badge">EVE GUIDE</span> </span> 444 </a> 445 <a class="stellar-card stellar-card--compact" href="/fleets/" data-stellar-launch data-result-type="page" data-search-title="open corporation fleets" data-search="open corporation fleets mining means locking an asteroid, activating a mining laser or strip miner, and moving the ore into a hold or fleet workflow. the real skill is doing it efficiently without ignoring safety. mining basics: ore, lasers, holds & safety mining mine ore asteroid mining laser strip miner venture barge exhumer yield ore hold survey scanner boosts compression page feature open go to cms page"> 446 <span class="stellar-card__icon" aria-hidden="true">â</span> 447 <span class="stellar-card__body"> 448 <span class="stellar-card__title">Open Corporation Fleets</span>
449 <span class="stellar-card__context">CMS Page</span> </span> 450 <span class="stellar-card__badges"> 451 <span class="stellar-card__badge">CMS</span> </span> 452 </a> 453 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-mining-basics" data-stellar-launch data-result-type="eve" data-search-title="mining basics: ore, lasers, holds & safety" data-search="mining basics: ore, lasers, holds & safety mining means locking an asteroid, activating a mining laser or strip miner, and moving the ore into a hold or fleet workflow. the real skill is doing it efficiently without ignoring safety. mining mine ore asteroid mining laser strip miner venture barge exhumer yield ore hold survey scanner boosts compression eve new player knowledge help guide instructions eve knowledge"> 454 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 455 <span class="stellar-card__body"> 456 <span class="stellar-card__title">Mining Basics: Ore, Lasers, Holds & Safety</span> 457 <span class="stellar-card__context">EVE Knowledge</span> </span> 458 <span class="stellar-card__badges"> 459 <span class="stellar-card__badge">EVE GUIDE</span> </span> 460 </a> 461 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-reprocessing-compression" data-stellar-launch data-result-type="eve" data-search-title="ore compression & reprocessing" data-search="ore compression & reprocessing compression reduces the hauling volume of many resources without turning them into minerals. reprocessing converts ore or other materials into their refined outputs and can lose value if your yield or location is poor. compression compress compressed ore reprocessing refine refining minerals yield efficiency mining hauling eve new player knowledge help guide instructions eve knowledge"> 462 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 463 <span class="stellar-card__body"> 464 <span class="stellar-card__title">Ore Compression & Reprocessing</span> 465 <span class="stellar-card__context">EVE Knowledge</span> </span> 466 <span class="stellar-card__badges"> 467 <span class="stellar-card__badge">EVE GUIDE</span> </span> 468 </a> 469 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-market-orders" data-stellar-launch data-result-type="eve" data-search-title="market: buy orders, sell orders & regional pricing" data-search="market: buy orders, sell orders & regional pricing sell orders offer items at a price; buy orders offer isk for items. eve markets are regional, so price and availability can change dramatically from one trade hub or region to another. market buy order sell order regional market price prices station trade hub amarr jita broker fee tax order eve new player knowledge help guide instructions eve knowledge"> 470 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 471 <span class="stellar-card__body"> 472 <span class="stellar-card__title">Market: Buy Orders, Sell Orders & Regional Pricing</span> 473 <span class="stellar-card__context">EVE Knowledge</span> </span> 474 <span class="stellar-card__badges"> 475 <span class="stellar-card__badge">EVE GUIDE</span> </span> 476 </a> 477 <a class="stellar-card stellar-card--compact" href="/contracts.php" data-stellar-launch data-result-type="page" data-search-title="open contract builder" data-search="open contract builder contracts move items or isk between pilots outside the normal market. courier contracts package cargo for delivery and use collateral to protect the owner if the package is not delivered. contracts & courier contracts contract contracts courier item exchange collateral reward expiration delivery hauling package accept contract corporation page feature open go to cms page"> 478 <span class="stellar-card__icon" aria-hidden="true">â</span> 479 <span class="stellar-card__body">
480 <span class="stellar-card__title">Open Contract Builder</span> 481 <span class="stellar-card__context">CMS Page</span> </span> 482 <span class="stellar-card__badges"> 483 <span class="stellar-card__badge">CMS</span> </span> 484 </a> 485 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-contracts-courier" data-stellar-launch data-result-type="eve" data-search-title="contracts & courier contracts" data-search="contracts & courier contracts contracts move items or isk between pilots outside the normal market. courier contracts package cargo for delivery and use collateral to protect the owner if the package is not delivered. contract contracts courier item exchange collateral reward expiration delivery hauling package accept contract corporation eve new player knowledge help guide instructions eve knowledge"> 486 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 487 <span class="stellar-card__body"> 488 <span class="stellar-card__title">Contracts & Courier Contracts</span> 489 <span class="stellar-card__context">EVE Knowledge</span> </span> 490 <span class="stellar-card__badges"> 491 <span class="stellar-card__badge">EVE GUIDE</span> </span> 492 </a> 493 <a class="stellar-card stellar-card--compact" href="/logistics/" data-stellar-launch data-result-type="page" data-search-title="open logistics command" data-search="open logistics command a hauling job is limited by route, cargo volume, ship capacity, risk, reward, and collateral. the cheapest route is not always the safest route. hauling, cargo volume & collateral hauling haul cargo volume m3 collateral courier freight transport route reward logistics hauler page feature open go to cms page"> 494 <span class="stellar-card__icon" aria-hidden="true">â</span> 495 <span class="stellar-card__body"> 496 <span class="stellar-card__title">Open Logistics Command</span> 497 <span class="stellar-card__context">CMS Page</span> </span> 498 <span class="stellar-card__badges"> 499 <span class="stellar-card__badge">CMS</span> </span> 500 </a> 501 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-hauling-cargo-collateral" data-stellar-launch data-result-type="eve" data-search-title="hauling, cargo volume & collateral" data-search="hauling, cargo volume & collateral a hauling job is limited by route, cargo volume, ship capacity, risk, reward, and collateral. the cheapest route is not always the safest route. hauling haul cargo volume m3 collateral courier freight transport route reward logistics hauler eve new player knowledge help guide instructions eve knowledge"> 502 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 503 <span class="stellar-card__body"> 504 <span class="stellar-card__title">Hauling, Cargo Volume & Collateral</span> 505 <span class="stellar-card__context">EVE Knowledge</span> </span> 506 <span class="stellar-card__badges"> 507 <span class="stellar-card__badge">EVE GUIDE</span> </span> 508 </a> 509 <a class="stellar-card stellar-card--compact" href="/manufacture/" data-stellar-launch data-result-type="page" data-search-title="open manufacturing board" data-search="open manufacturing board manufacturing turns blueprint requirements plus materials into finished items. your real cost includes materials, job fees, time, location, hauling, and any missing intermediate components. industry & manufacturing basics industry manufacturing build job blueprint materials components factory production material efficiency time efficiency me te page feature open go to cms page"> 510 <span class="stellar-card__icon" aria-hidden="true">â</span> 511 <span class="stellar-card__body"> 512 <span class="stellar-card__title">Open Manufacturing Board</span> 513 <span class="stellar-card__context">CMS Page</span> </span> 514 <span class="stellar-card__badges">
515 <span class="stellar-card__badge">CMS</span> </span> 516 </a> 517 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-industry-manufacturing" data-stellar-launch data-result-type="eve" data-search-title="industry & manufacturing basics" data-search="industry & manufacturing basics manufacturing turns blueprint requirements plus materials into finished items. your real cost includes materials, job fees, time, location, hauling, and any missing intermediate components. industry manufacturing build job blueprint materials components factory production material efficiency time efficiency me te eve new player knowledge help guide instructions eve knowledge"> 518 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 519 <span class="stellar-card__body"> 520 <span class="stellar-card__title">Industry & Manufacturing Basics</span> 521 <span class="stellar-card__context">EVE Knowledge</span> </span> 522 <span class="stellar-card__badges"> 523 <span class="stellar-card__badge">EVE GUIDE</span> </span> 524 </a> 525 <a class="stellar-card stellar-card--compact" href="/blueprints/" data-stellar-launch data-result-type="page" data-search-title="open blueprint network" data-search="open blueprint network a blueprint original (bpo) can be researched and reused. a blueprint copy (bpc) has a limited number of runs. me affects material use; te affects manufacturing time. blueprints: bpos, bpcs, me & te blueprint blueprints bpo bpc blueprint original copy copies runs me material efficiency te time efficiency invention page feature open go to cms page"> 526 <span class="stellar-card__icon" aria-hidden="true">â</span> 527 <span class="stellar-card__body"> 528 <span class="stellar-card__title">Open Blueprint Network</span> 529 <span class="stellar-card__context">CMS Page</span> </span> 530 <span class="stellar-card__badges"> 531 <span class="stellar-card__badge">CMS</span> </span> 532 </a> 533 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-blueprints-bpo-bpc" data-stellar-launch data-result-type="eve" data-search-title="blueprints: bpos, bpcs, me & te" data-search="blueprints: bpos, bpcs, me & te a blueprint original (bpo) can be researched and reused. a blueprint copy (bpc) has a limited number of runs. me affects material use; te affects manufacturing time. blueprint blueprints bpo bpc blueprint original copy copies runs me material efficiency te time efficiency invention eve new player knowledge help guide instructions eve knowledge"> 534 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 535 <span class="stellar-card__body"> 536 <span class="stellar-card__title">Blueprints: BPOs, BPCs, ME & TE</span> 537 <span class="stellar-card__context">EVE Knowledge</span> </span> 538 <span class="stellar-card__badges"> 539 <span class="stellar-card__badge">EVE GUIDE</span> </span> 540 </a> 541 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-planetary-industry-pi" data-stellar-launch data-result-type="eve" data-search-title="planetary industry (pi) basics" data-search="planetary industry (pi) basics planetary industry extracts and processes resources on planets through command centers, extractor heads, processors, storage, and launch facilities. pi planetary industry planets command center extractor heads extraction processor processors storage launchpad p0 p1 p2 p3 p4 eve new player knowledge help guide instructions eve knowledge"> 542 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 543 <span class="stellar-card__body"> 544 <span class="stellar-card__title">Planetary Industry (PI) Basics</span> 545 <span class="stellar-card__context">EVE Knowledge</span> </span> 546 <span class="stellar-card__badges"> 547 <span class="stellar-card__badge">EVE GUIDE</span> </span> 548 </a> 549 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-fleets-broadcasts" data-stellar-launch data-result-type="eve" data-search-title="fleets, wings, squads & broadcasts" data-search="fleets, wings, squads & broadcasts joining a fleet gives pilots shared organization, broadcasts, boosts, warp commands, and other coordination tools. fleet discipline matters more as the operation becomes more dangerous. fleet fleets squad wing commander fc broadcasts broadcast shield armor capacitor target warp fleet command boosts roles eve new player knowledge help guide instructions eve knowledge">
550 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 551 <span class="stellar-card__body"> 552 <span class="stellar-card__title">Fleets, Wings, Squads & Broadcasts</span> 553 <span class="stellar-card__context">EVE Knowledge</span> </span> 554 <span class="stellar-card__badges"> 555 <span class="stellar-card__badge">EVE GUIDE</span> </span> 556 </a> 557 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-skill-training-plans" data-stellar-launch data-result-type="eve" data-search-title="skills, skill queue & training plans" data-search="skills, skill queue & training plans skills train in real time. a good plan trains what you need to fly and fit your next useful ship instead of chasing every skill to level v immediately. skills skill training queue skill plan plans sp skillpoints skill points level v support skills training time eve new player knowledge help guide instructions eve knowledge"> 558 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 559 <span class="stellar-card__body"> 560 <span class="stellar-card__title">Skills, Skill Queue & Training Plans</span> 561 <span class="stellar-card__context">EVE Knowledge</span> </span> 562 <span class="stellar-card__badges"> 563 <span class="stellar-card__badge">EVE GUIDE</span> </span> 564 </a> 565 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-ship-loss-insurance" data-stellar-launch data-result-type="eve" data-search-title="ship loss, insurance & replacement" data-search="ship loss, insurance & replacement ships in eve are consumable tools. when a ship explodes, the hull and most fitted assets are gone; some modules or cargo may drop as loot. ship loss losses insurance explode destroyed killmail kill report replacement srp ship replacement afford to lose eve new player knowledge help guide instructions eve knowledge"> 566 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 567 <span class="stellar-card__body"> 568 <span class="stellar-card__title">Ship Loss, Insurance & Replacement</span> 569 <span class="stellar-card__context">EVE Knowledge</span> </span> 570 <span class="stellar-card__badges"> 571 <span class="stellar-card__badge">EVE GUIDE</span> </span> 572 </a> 573 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-wormholes-basics" data-stellar-launch data-result-type="eve" data-search-title="wormholes: connections, polarization & no normal local" data-search="wormholes: connections, polarization & no normal local wormholes are temporary connections with limited mass and lifetime. local chat does not work like normal known-space local, so d-scan and probes become critical. wormhole wormholes wh jspace j-space scanning probes dscan local polarization mass lifetime connection bookmark eve new player knowledge help guide instructions eve knowledge"> 574 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 575 <span class="stellar-card__body"> 576 <span class="stellar-card__title">Wormholes: Connections, Polarization & No Normal Local</span> 577 <span class="stellar-card__context">EVE Knowledge</span> </span> 578 <span class="stellar-card__badges"> 579 <span class="stellar-card__badge">EVE GUIDE</span> </span> 580 </a> 581 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-nullsec-intel-survival" data-stellar-launch data-result-type="eve" data-search-title="null-sec survival, intel & nbsi" data-search="null-sec survival, intel & nbsi null-sec has no concord protection. survival depends on local/intel awareness, standings, safe travel habits, fleet communication, and understanding bubbles and gate threats. nullsec null-sec null space intel nbsi not blue shoot it local standings hostile neutral gate camp bubble alliance womp survival eve new player knowledge help guide instructions eve knowledge">
582 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 583 <span class="stellar-card__body"> 584 <span class="stellar-card__title">Null-Sec Survival, Intel & NBSI</span> 585 <span class="stellar-card__context">EVE Knowledge</span> </span> 586 <span class="stellar-card__badges"> 587 <span class="stellar-card__badge">EVE GUIDE</span> </span> 588 </a> 589 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-terms-acronyms" data-stellar-launch data-result-type="eve" data-search-title="common eve terms & acronyms" data-search="common eve terms & acronyms eve players use a lot of shorthand. if a fleet or guide uses a term you do not recognize, search it here rather than guessing during an operation. terms acronyms glossary fc dps logi tackle scram point mwd ab ewar dscan pi bpo bpc me te nbsi srp cta eve slang eve new player knowledge help guide instructions eve knowledge"> 590 <span class="stellar-card__icon" aria-hidden="true">â¦</span> 591 <span class="stellar-card__body"> 592 <span class="stellar-card__title">Common EVE Terms & Acronyms</span> 593 <span class="stellar-card__context">EVE Knowledge</span> </span> 594 <span class="stellar-card__badges"> 595 <span class="stellar-card__badge">EVE GUIDE</span> </span> 596 </a> 597 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-sso-login-and-background-authorization-basics" data-stellar-launch data-result-type="help" data-search-title="eve sso login and background authorization basics" data-search="eve sso login and background authorization basics use the eve sso button and read the scopes shown by ccp before authorizing. normal login and special background-check authorization are separate flows. eve sso login background authorization scopes ccp token eve sso / login help guide instructions cms help"> 598 <span class="stellar-card__icon" aria-hidden="true">?</span> 599 <span class="stellar-card__body"> 600 <span class="stellar-card__title">EVE SSO Login and Background Authorization Basics</span> 601 <span class="stellar-card__context">CMS Help</span> </span> 602 <span class="stellar-card__badges"> 603 <span class="stellar-card__badge">HELP</span> </span> 604 </a> 605 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=price-check-order-book-immediate-pricing" data-stellar-launch data-result-type="help" data-search-title="using the syndicates price check: order book & immediate pricing" data-search="using the syndicates price check: order book & immediate pricing immediate sell walks current buy-order price levels for your full quantity. immediate buy walks current sell-order levels. a partial fill warning means the selected hub does not currently have enough visible liquidity to fill the entire quantity at any stored order-book level. price check market appraisal immediate sell immediate buy order book liquidity fill percentage jita amarr dodixie rens hek split top buy top sell eve market public tools & market intelligence help guide instructions cms help"> 606 <span class="stellar-card__icon" aria-hidden="true">?</span> 607 <span class="stellar-card__body"> 608 <span class="stellar-card__title">Using The Syndicates Price Check: Order Book & Immediate Pricing</span> 609 <span class="stellar-card__context">CMS Help</span> </span> 610 <span class="stellar-card__badges"> 611 <span class="stellar-card__badge">HELP</span> </span> 612 </a> 613 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=price-check-whole-appraisal-reprocessing" data-stellar-launch data-result-type="help" data-search-title="price check: whole-appraisal reprocessing" data-search="price check: whole-appraisal reprocessing enable reprocess entire appraisal, set efficiency, and click check prices. price check replaces reprocessable source items with their aggregated recovered outputs and appraises those outputs at the selected hub. incomplete portion remainders and non-reprocessable items remain in the final appraisal. price check reprocess reprocessing ore compressed ore minerals appraisal efficiency recovered output remainder public tools & market intelligence help guide instructions cms help">
614 <span class="stellar-card__icon" aria-hidden="true">?</span> 615 <span class="stellar-card__body"> 616 <span class="stellar-card__title">Price Check: Whole-Appraisal Reprocessing</span> 617 <span class="stellar-card__context">CMS Help</span> </span> 618 <span class="stellar-card__badges"> 619 <span class="stellar-card__badge">HELP</span> </span> 620 </a> 621 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=price-check-market-intelligence-trends-warnings" data-stellar-launch data-result-type="help" data-search-title="price check market intelligence, trends & warnings" data-search="price check market intelligence, trends & warnings market intelligence describes measurable market conditions. it does not label ordinary price movement as manipulation. history-based metrics appear only after enough real daily history has accumulated in the eve syndicates market database. price check market intelligence history median trend warning spread depth vwap liquidity price impact unusual price quote confidence jita amarr dodixie rens hek public tools & market intelligence help guide instructions cms help"> 622 <span class="stellar-card__icon" aria-hidden="true">?</span> 623 <span class="stellar-card__body"> 624 <span class="stellar-card__title">Price Check Market Intelligence, Trends & Warnings</span> 625 <span class="stellar-card__context">CMS Help</span> </span> 626 <span class="stellar-card__badges"> 627 <span class="stellar-card__badge">HELP</span> </span> 628 </a> 629 <a class="stellar-card stellar-card--compact" href="/eve-market/" data-stellar-launch data-result-type="page" data-search-title="open eve market intelligence" data-search="open eve market intelligence open eve market intelligence, search an item name or type id, then select a hub. item pages show current buy/sell, quantity-aware immediate prices, history, depth, confidence, and warnings without crowding the main price check results. public eve market item pages eve market item page market search item price jita amarr dodixie rens hek chart history order book depth immediate buy immediate sell page feature open go to cms page"> 630 <span class="stellar-card__icon" aria-hidden="true">â</span> 631 <span class="stellar-card__body"> 632 <span class="stellar-card__title">Open EVE Market Intelligence</span> 633 <span class="stellar-card__context">CMS Page</span> </span> 634 <span class="stellar-card__badges"> 635 <span class="stellar-card__badge">CMS</span> </span> 636 </a> 637 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=public-eve-market-item-pages" data-stellar-launch data-result-type="help" data-search-title="public eve market item pages" data-search="public eve market item pages open eve market intelligence, search an item name or type id, then select a hub. item pages show current buy/sell, quantity-aware immediate prices, history, depth, confidence, and warnings without crowding the main price check results. eve market item page market search item price jita amarr dodixie rens hek chart history order book depth immediate buy immediate sell public tools & market intelligence help guide instructions cms help"> 638 <span class="stellar-card__icon" aria-hidden="true">?</span> 639 <span class="stellar-card__body"> 640 <span class="stellar-card__title">Public EVE Market Item Pages</span> 641 <span class="stellar-card__context">CMS Help</span> </span> 642 <span class="stellar-card__badges"> 643 <span class="stellar-card__badge">HELP</span> </span> 644 </a> 645 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=price-check-guide" data-stellar-launch data-result-type="help" data-search-title="price check" data-search="price check paste the item list, review the resolved items and totals, then adjust the permitted buyback/price options if needed. price check items amarr market buyback percent estimate paste industry help guide instructions cms help">
646 <span class="stellar-card__icon" aria-hidden="true">?</span> 647 <span class="stellar-card__body"> 648 <span class="stellar-card__title">Price Check</span> 649 <span class="stellar-card__context">CMS Help</span> </span> 650 <span class="stellar-card__badges"> 651 <span class="stellar-card__badge">HELP</span> </span> 652 </a> 653 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=how-hauling-and-logistics-work-in-the-cms" data-stellar-launch data-result-type="help" data-search-title="how hauling and logistics work in the cms" data-search="how hauling and logistics work in the cms use logistics command to see what needs action, open the run, and follow the highlighted workflow gate through assignment, contract, pickup, delivery, and payout. hauling logistics workflow courier dispatch payout run hauling / logistics help guide instructions cms help"> 654 <span class="stellar-card__icon" aria-hidden="true">?</span> 655 <span class="stellar-card__body"> 656 <span class="stellar-card__title">How Hauling and Logistics Work in the CMS</span> 657 <span class="stellar-card__context">CMS Help</span> </span> 658 <span class="stellar-card__badges"> 659 <span class="stellar-card__badge">HELP</span> </span> 660 </a> 661 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=how-to-use-the-discord-helpbot" data-stellar-launch data-result-type="help" data-search-title="how to use the discord helpbot" data-search="how to use the discord helpbot use the configured discord helpbot command to search role-safe cms help articles. if the bot feature is unavailable, use search cms or the help center. discord helpbot help search role safe command discord helpbot help guide instructions cms help"> 662 <span class="stellar-card__icon" aria-hidden="true">?</span> 663 <span class="stellar-card__body"> 664 <span class="stellar-card__title">How to Use the Discord HelpBot</span> 665 <span class="stellar-card__context">CMS Help</span> </span> 666 <span class="stellar-card__badges"> 667 <span class="stellar-card__badge">HELP</span> </span> 668 </a> 669 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=university-invite-guide" data-stellar-launch data-result-type="help" data-search-title="university invitation links" data-search="university invitation links a valid university invitation can still take a pilot directly into a course, but published courses no longer require an invitation for active members. university invitation invite token enrollment published course university help guide instructions cms help"> 670 <span class="stellar-card__icon" aria-hidden="true">?</span> 671 <span class="stellar-card__body"> 672 <span class="stellar-card__title">University Invitation Links</span> 673 <span class="stellar-card__context">CMS Help</span> </span> 674 <span class="stellar-card__badges"> 675 <span class="stellar-card__badge">HELP</span> </span> 676 </a> 677 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=record-boards-guide" data-stellar-launch data-result-type="help" data-search-title="hall of fame & record boards" data-search="hall of fame & record boards use the main hall of fame for the overview, then open a specialized board for mining, fleets, pve, pvp, industry, hauling, exploration, systems, or other records. hall of fame records leaderboard mining fleet pve pvp industry hauler exploration hall of shame records & achievements help guide instructions cms help"> 678 <span class="stellar-card__icon" aria-hidden="true">?</span> 679 <span class="stellar-card__body"> 680 <span class="stellar-card__title">Hall of Fame & Record Boards</span> 681 <span class="stellar-card__context">CMS Help</span> </span> 682 <span class="stellar-card__badges"> 683 <span class="stellar-card__badge">HELP</span> </span> 684 </a> 685 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=system-status-guide" data-stellar-launch data-result-type="help" data-search-title="cms system status" data-search="cms system status open system status when a feature looks down before repeatedly retrying actions. it can help distinguish a site-wide problem from a single record problem. status system health outage esi discord mail service troubleshooting troubleshooting help guide instructions cms help">
686 <span class="stellar-card__icon" aria-hidden="true">?</span> 687 <span class="stellar-card__body"> 688 <span class="stellar-card__title">CMS System Status</span> 689 <span class="stellar-card__context">CMS Help</span> </span> 690 <span class="stellar-card__badges"> 691 <span class="stellar-card__badge">HELP</span> </span> 692 </a> 693 <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=where-to-get-help-when-something-breaks" data-stellar-launch data-result-type="help" data-search-title="where to get help when something breaks" data-search="where to get help when something breaks open ? help on the problem page, check system status when an integration may be down, then send a question/bug through the site if the issue remains. troubleshooting help broken bug question system status support troubleshooting help guide instructions cms help"> 694 <span class="stellar-card__icon" aria-hidden="true">?</span> 695 <span class="stellar-card__body"> 696 <span class="stellar-card__title">Where to Get Help When Something Breaks</span> 697 <span class="stellar-card__context">CMS Help</span> </span> 698 <span class="stellar-card__badges"> 699 <span class="stellar-card__badge">HELP</span> </span> 700 </a> 701 <a class="stellar-card stellar-card--compact" href="https://wiki.eveuniversity.org/Directional_scanning" data-stellar-launch data-result-type="external" data-search-title="directional scanning" data-search="directional scanning current guide to d-scan mechanics, range, angle, and practical use. scanning scan dscan d-scan directional scanner hunting safety eve university article eve university" target="_blank" rel="noopener noreferrer"> 702 <span class="stellar-card__icon" aria-hidden="true">â</span> 703 <span class="stellar-card__body"> 704 <span class="stellar-card__title">Directional scanning</span> 705 <span class="stellar-card__context">EVE University</span> </span> 706 <span class="stellar-card__badges"> 707 <span class="stellar-card__badge">WEB</span> </span> 708 </a> 709 <a class="stellar-card stellar-card--compact" href="https://wiki.eveuniversity.org/Probing_In_Simple_Steps" data-stellar-launch data-result-type="external" data-search-title="probing in simple steps" data-search="probing in simple steps beginner steps for core probe launchers, scanner probes, and resolving signatures. scanning probes probing core scanner probe signatures exploration eve university article eve university" target="_blank" rel="noopener noreferrer"> 710 <span class="stellar-card__icon" aria-hidden="true">â</span> 711 <span class="stellar-card__body"> 712 <span class="stellar-card__title">Probing In Simple Steps</span> 713 <span class="stellar-card__context">EVE University</span> </span> 714 <span class="stellar-card__badges"> 715 <span class="stellar-card__badge">WEB</span> </span> 716 </a> 717 <a class="stellar-card stellar-card--compact" href="https://www.eveonline.com/eve-academy/careers/explorer" data-stellar-launch data-result-type="external" data-search-title="explorer - eve academy" data-search="explorer - eve academy official beginner career page for scanning, hacking, ships, and exploration. exploration scanning hacking relic data probes beginner explorer ccp / eve online official guide ccp / eve online" target="_blank" rel="noopener noreferrer"> 718 <span class="stellar-card__icon" aria-hidden="true">â</span> 719 <span class="stellar-card__body"> 720 <span class="stellar-card__title">Explorer - EVE Academy</span> 721 <span class="stellar-card__context">CCP / EVE Online</span> </span> 722 <span class="stellar-card__badges"> 723 <span class="stellar-card__badge">WEB</span> </span> 724 </a> 725 <a class="stellar-card stellar-card--compact" href="https://wiki.eveuniversity.org/Category:Exploration" data-stellar-launch data-result-type="external" data-search-title="exploration articles" data-search="exploration articles collection of exploration, scanning, hacking, and cosmic-signature guides. exploration scanning hacking relic data wormhole signatures eve university resource collection eve university" target="_blank" rel="noopener noreferrer">
726 <span class="stellar-card__icon" aria-hidden="true">â</span> 727 <span class="stellar-card__body"> 728 <span class="stellar-card__title">Exploration articles</span> 729 <span class="stellar-card__context">EVE University</span> </span> 730 <span class="stellar-card__badges"> 731 <span class="stellar-card__badge">WEB</span> </span> 732 </a> 733 <a class="stellar-card stellar-card--compact" href="https://wiki.eveuniversity.org/Mining" data-stellar-launch data-result-type="external" data-search-title="mining" data-search="mining mining overview including ships, resources, and operating considerations. mining ore asteroid barge exhumer venture compression reprocessing eve university article eve university" target="_blank" rel="noopener noreferrer"> 734 <span class="stellar-card__icon" aria-hidden="true">â</span> 735 <span class="stellar-card__body"> 736 <span class="stellar-card__title">Mining</span> 737 <span class="stellar-card__context">EVE University</span> </span> 738 <span class="stellar-card__badges"> 739 <span class="stellar-card__badge">WEB</span> </span> 740 </a> 741 <a class="stellar-card stellar-card--compact" href="https://www.eveonline.com/eve-academy/careers/industrialist" data-stellar-launch data-result-type="external" data-search-title="industrialist - eve academy" data-search="industrialist - eve academy official beginner material for mining, production, trade, and industry careers. industry manufacturing mining market hauling blueprints industrialist ccp / eve online official guide ccp / eve online" target="_blank" rel="noopener noreferrer"> 742 <span class="stellar-card__icon" aria-hidden="true">â</span> 743 <span class="stellar-card__body"> 744 <span class="stellar-card__title">Industrialist - EVE Academy</span> 745 <span class="stellar-card__context">CCP / EVE Online</span> </span> 746 <span class="stellar-card__badges"> 747 <span class="stellar-card__badge">WEB</span> </span> 748 </a> 749 <div class="stellar-search__empty" data-stellar-search-empty hidden>No matching Eve Syndicates page or local guide was found. Try the outside EVE learning searches below.</div> 750 </div> 751 </div> 752 </div> 753 754 <aside class="stellar-drawer" data-stellar-drawer aria-hidden="true"> 755 <div class="stellar-drawer__backdrop" data-stellar-close-drawer></div> 756 <div class="stellar-drawer__panel" role="dialog" aria-modal="true" aria-label="Mobile navigation"> 757 <div class="stellar-drawer__head"><strong>CMS Navigation</strong><button type="button" data-stellar-close-drawer aria-label="Close navigation">Ã</button></div> 758 <button class="stellar-drawer__search" type="button" data-stellar-open-search>â Search CMS + EVE <kbd>Ctrl K</kbd></button> 759 <section class="stellar-drawer__group"><h3>â Public Portal</h3> 760 <a class="stellar-card stellar-card--compact" href="/" data-stellar-launch data-result-type="page" data-search-title="home" data-search="home return to the eve syndicates public portal. landing portal"> 761 <span class="stellar-card__icon" aria-hidden="true">â</span> 762 <span class="stellar-card__body"> 763 <span class="stellar-card__title">Home</span> 764 </span> 765 <span class="stellar-card__badges"> 766 </span> 767 </a> 768 <a class="stellar-card is-active stellar-card--compact" href="/pricecheck.php" data-stellar-launch data-result-type="page" data-search-title="public price check" data-search="public price check paste items and value them without logging in. market appraisal value"> 769 <span class="stellar-card__icon" aria-hidden="true">â</span> 770 <span class="stellar-card__body"> 771 <span class="stellar-card__title">Public Price Check</span> 772 </span> 773 <span class="stellar-card__badges"> 774 </span> 775 </a> 776 <a class="stellar-card stellar-card--compact" href="/onboarding/" data-stellar-launch data-result-type="page" data-search-title="apply to this corp" data-search="apply to this corp start the corporation application and onboarding flow. application recruit join">
777 <span class="stellar-card__icon" aria-hidden="true">â¤</span> 778 <span class="stellar-card__body"> 779 <span class="stellar-card__title">Apply to This Corp</span> 780 </span> 781 <span class="stellar-card__badges"> 782 </span> 783 </a> 784 <a class="stellar-card stellar-card--compact" href="/login.php" data-stellar-launch data-result-type="page" data-search-title="member login" data-search="member login access the cms pilot command desk. sign in sso"> 785 <span class="stellar-card__icon" aria-hidden="true">â</span> 786 <span class="stellar-card__body"> 787 <span class="stellar-card__title">Member Login</span> 788 </span> 789 <span class="stellar-card__badges"> 790 </span> 791 </a> 792 </section> 793 </div> 794 </aside> 795 </section> 796 797 798 <main class="container content"> 799 800 801<style> 802 /* Price Check: "cool slider" */ 803 .pctslider input[type=range]{ 804 width:100%; 805 height:12px; 806 border-radius:999px; 807 border:1px solid var(--border); 808 background:linear-gradient(90deg, rgba(255,90,90,.28), rgba(255,255,255,.08), rgba(90,255,180,.22)); 809 outline:none; 810 } 811 .pctslider input[type=range]::-webkit-slider-thumb{ 812 -webkit-appearance:none; 813 appearance:none; 814 width:18px; 815 height:18px; 816 border-radius:999px; 817 background:var(--accent); 818 border:2px solid rgba(0,0,0,.28); 819 box-shadow:0 6px 16px rgba(0,0,0,.35); 820 cursor:pointer; 821 } 822 .pctslider input[type=range]::-moz-range-thumb{ 823 width:18px; 824 height:18px; 825 border-radius:999px; 826 background:var(--accent); 827 border:2px solid rgba(0,0,0,.28); 828 box-shadow:0 6px 16px rgba(0,0,0,.35); 829 cursor:pointer; 830 } 831 .pctpresets{ display:flex; flex-wrap:wrap; gap:8px; margin-top:10px; } 832 833/* Recent checks badges */ 834.pc-badges{ display:flex; flex-wrap:wrap; gap:8px; } 835.pc-badge{ 836 appearance:none; 837 border:1px solid var(--border); 838 background:rgba(255,255,255,.04); 839 color:var(--text); 840 border-radius:999px; 841 padding:6px 10px; 842 font-size:12px; 843 line-height:1; 844 cursor:pointer; 845 transition:transform .06s ease, background .12s ease, border-color .12s ease; 846} 847.pc-badge:hover{ background:rgba(255,255,255,.07); border-color:rgba(255,255,255,.18); } 848.pc-badge:active{ transform:translateY(1px); } 849.pc-badge strong{ font-weight:700; } 850 851/* Multi-hub totals badges */ 852.hubtotals{ 853 display:grid; 854 grid-template-columns: repeat(5, minmax(0, 1fr)); 855 gap:10px; 856 margin-top:12px; 857} 858@media (max-width: 980px){ 859 .hubtotals{ grid-template-columns: repeat(2, minmax(0, 1fr)); } 860} 861@media (max-width: 560px){ 862 .hubtotals{ grid-template-columns: 1fr; } 863} 864.hubbadge{ 865 border:1px solid var(--border); 866 background:rgba(255,255,255,.04); 867 border-radius:14px; 868 padding:10px 12px; 869 min-height:70px; 870} 871.hubbadge.active{ 872 border-color:rgba(255,255,255,.20); 873 box-shadow:0 0 0 1px rgba(255,255,255,.06) inset; 874} 875.hubbadge .h-title{ 876 display:flex; 877 justify-content:space-between; 878 align-items:baseline; 879 gap:10px; 880 font-weight:800; 881} 882.hubbadge .h-sub{ 883 margin-top:6px; 884 display:flex; 885 justify-content:space-between; 886 gap:10px; 887 font-size:12px; 888 color:var(--muted); 889} 890.hubbadge .h-val{ 891 font-weight:800; 892 color:var(--text); 893} 894.pc-immediate-line{margin-top:5px;display:flex;flex-wrap:wrap;gap:5px 8px;font-size:11px;color:var(--muted)} 895.pc-immediate-pill{display:inline-flex;align-items:center;gap:4px;border:1px solid var(--border);border-radius:999px;padding:3px 7px;background:rgba(255,255,255,.035)} 896.pc-immediate-pill strong{color:var(--text)} 897.pc-immediate-pill.warn{border-color:rgba(243,200,96,.45);color:#ffe29b;background:rgba(243,200,96,.07)} 898.pc-totalblock.immediate{border-color:rgba(92,190,255,.30);background:rgba(92,190,255,.06)} 899.hubbadge .h-sub.immediate{color:var(--text);font-weight:750} 900 901 902 /* Results totals (center + copy) */ 903 .pc-results-head{ display:flex; flex-direction:column; gap:10px; } 904 .pc-totals{ display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:12px; text-align:center; } 905 .pc-totalblock{ display:flex; align-items:baseline; gap:8px; padding:8px 10px; border:1px solid var(--border); background:rgba(255,255,255,.04); border-radius:14px; } 906 .pc-totalblock .lbl{ font-size:12px; letter-spacing:.10em; text-transform:uppercase; font-weight:900; color:var(--muted); } 907 .pc-totalblock .val{ font-size:20px; font-weight:900; color:var(--text); } 908 .pc-copybtn{ padding:4px 8px !important; font-size:11px !important; line-height:1 !important; border-radius:999px !important; } 909 .pc-totals-meta{ flex-basis:100%; margin-top:-4px; } 910 @media (max-width:560px){ .pc-totalblock .val{ font-size:18px; } } 911 .pc-recycle-row>td{padding:0 0 10px !important;border-top:0 !important;background:transparent !important} 912 .pc-recycle{margin:0;width:100%;box-sizing:border-box;border:1px solid rgba(255,255,255,.16);background:rgba(255,255,255,.035);border-radius:10px;padding:8px 10px;transition:border-color .12s ease,background .12s ease} 913 .pc-recycle summary{cursor:pointer;font-size:12px;font-weight:850;color:var(--text);display:flex;gap:8px;align-items:center;justify-content:space-between;flex-wrap:wrap} 914 .pc-recycle-summary-value{font-weight:900;color:var(--muted)} 915 .pc-recycle.positive{border-color:rgba(55,210,125,.55);background:rgba(55,210,125,.10)} 916 .pc-recycle.positive summary,.pc-recycle.positive .pc-recycle-summary-value{color:#bff5da} 917 .pc-recycle.negative{border-color:rgba(245,90,90,.58);background:rgba(245,90,90,.10)} 918 .pc-recycle.negative summary,.pc-recycle.negative .pc-recycle-summary-value{color:#ffd1d1} 919 .pc-recycle-body{padding-top:8px} 920 .pc-recycle-head{display:block} 921 .pc-recycle-note{font-size:11px;color:var(--muted);line-height:1.45} 922 .pc-global-reprocess{margin-top:12px;padding-top:12px;border-top:1px solid var(--border)} 923 .pc-global-reprocess-title{display:flex;align-items:center;justify-content:space-between;gap:10px} 924 .pc-reprocess-toggle{display:flex;align-items:center;gap:8px;margin:0;cursor:pointer;font-weight:800} 925 .pc-reprocess-toggle input{width:16px!important;height:16px!important;min-height:0!important;padding:0!important;margin:0;accent-color:var(--accent)} 926 .pc-global-reprocess-row{display:flex;align-items:center;gap:8px;margin-top:7px} 927 .pc-global-reprocess-row input{width:110px;min-height:38px;padding:7px 10px} 928 .pc-global-reprocess strong{color:var(--text)} 929 .pc-recycle-kpis{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:7px;margin-top:9px} 930 .pc-recycle-kpi{border:1px solid var(--border);background:rgba(0,0,0,.12);border-radius:9px;padding:7px 8px;min-width:0} 931 .pc-recycle-kpi .k{font-size:9px;font-weight:900;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);line-height:1.25} 932 .pc-recycle-kpi .v{font-size:12px;font-weight:900;color:var(--text);margin-top:3px;overflow-wrap:anywhere} 933 .pc-recycle-kpi.positive .v{color:#bff5da} 934 .pc-recycle-kpi.negative .v{color:#ffd1d1} 935 .pc-recycle-tablewrap{overflow:auto;margin-top:9px;border:1px solid var(--border);border-radius:9px} 936 .pc-recycle-table{width:100%;min-width:650px;border-collapse:collapse;font-size:11px} 937 .pc-recycle-table th,.pc-recycle-table td{padding:6px 7px;border-bottom:1px solid rgba(255,255,255,.07);text-align:right;white-space:nowrap} 938 .pc-recycle-table th{font-size:9px;text-transform:uppercase;letter-spacing:.05em;
938color:var(--muted);background:rgba(255,255,255,.025)} 939 .pc-recycle-table th:first-child,.pc-recycle-table td:first-child{text-align:left;white-space:normal;min-width:180px} 940 .pc-recycle-table tbody tr:last-child td{border-bottom:0} 941 .pc-recycle-foot{margin-top:7px;font-size:10px;color:var(--muted);line-height:1.4} 942 @media(max-width:820px){.pc-recycle-kpis{grid-template-columns:repeat(2,minmax(0,1fr))}} 943 @media(max-width:520px){.pc-recycle-kpis{grid-template-columns:1fr}} 944 945 /* Unresolved-item review dialog */ 946 .pc-unresolved-overlay{position:fixed;inset:0;z-index:10050;display:none;align-items:center;justify-content:center;padding:20px;background:rgba(4,9,17,.78);backdrop-filter:blur(3px)} 947 .pc-unresolved-overlay.open{display:flex} 948 .pc-unresolved-dialog{width:min(720px,96vw);max-height:86vh;display:flex;flex-direction:column;border:1px solid rgba(245,90,90,.45);background:var(--panel,#101826);border-radius:16px;box-shadow:0 20px 60px rgba(0,0,0,.52);overflow:hidden} 949 .pc-unresolved-head{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;padding:16px 18px;border-bottom:1px solid var(--border);background:rgba(245,90,90,.08)} 950 .pc-unresolved-head h3{margin:0;font-size:20px} 951 .pc-unresolved-head .hint{margin-top:5px} 952 .pc-unresolved-close{flex:0 0 auto;min-width:40px;min-height:40px;padding:6px 10px!important;font-size:20px!important;line-height:1!important} 953 .pc-unresolved-body{padding:14px 18px;overflow:auto} 954 .pc-unresolved-list{display:grid;gap:8px;margin:0;padding:0;list-style:none} 955 .pc-unresolved-item{border:1px solid rgba(245,90,90,.32);background:rgba(245,90,90,.07);border-radius:10px;padding:10px 12px} 956 .pc-unresolved-item strong{display:block;color:#ffd1d1;overflow-wrap:anywhere} 957 .pc-unresolved-item .hint{margin-top:4px;font-size:11px;overflow-wrap:anywhere} 958 .pc-unresolved-actions{display:flex;justify-content:flex-end;gap:10px;flex-wrap:wrap;padding:14px 18px;border-top:1px solid var(--border);background:rgba(255,255,255,.025)} 959 .pc-unresolved-actions .btn{min-height:42px} 960 @media(max-width:560px){.pc-unresolved-overlay{padding:10px}.pc-unresolved-actions{display:grid;grid-template-columns:1fr}.pc-unresolved-actions .btn{width:100%}} 961 962 963 /* CMS_MARKET_FRESHNESS_PANEL_V1 */ 964 .pc-market-freshness{ 965 display:grid; 966 grid-template-columns:auto 1fr auto auto; 967 align-items:center; 968 gap:12px; 969 padding:11px 13px; 970 border:1px solid var(--border); 971 border-radius:14px; 972 background:rgba(255,255,255,.035); 973 margin-top:12px; 974 } 975 976 .pc-market-dot{ 977 width:11px; 978 height:11px; 979 border-radius:50%; 980 background:#8b96a8; 981 box-shadow:0 0 0 4px rgba(139,150,168,.11); 982 } 983 984 .pc-market-freshness.fresh .pc-market-dot{ 985 background:#4fda8c; 986 box-shadow:0 0 0 4px rgba(79,218,140,.12); 987 } 988 989 .pc-market-freshness.aging .pc-market-dot{ 990 background:#f3c860; 991 box-shadow:0 0 0 4px rgba(243,200,96,.12); 992 } 993 994 .pc-market-freshness.stale .pc-market-dot{ 995 background:#f06767; 996 box-shadow:0 0 0 4px rgba(240,103,103,.12); 997 } 998 999 .pc-market-source{ 1000 font-weight:900; 1001 } 1002 1003 .pc-market-age{ 1004 font-family:var(--mono); 1005 font-weight:900; 1006 white-space:nowrap; 1007 } 1008 1009 .pc-market-state{ 1010 border:1px solid var(--border); 1011 border-radius:999px; 1012 padding:4px 8px; 1013 font-size:10px; 1014 font-weight:900; 1015 letter-spacing:.08em; 1016 } 1017 1018 .pc-market-freshness.fresh .pc-market-state{ 1019 color:#bff5da; 1020 border-color:rgba(79,218,140,.4); 1021 } 1022 1023 .pc-market-freshness.aging .pc-market-state{ 1024 color:#ffe29b; 1025 border-color:rgba(243,200,96,.4); 1026 } 1027 1028 .pc-market-freshness.stale .pc-market-state{ 1029 color:#ffd1d1; 1030 border-color:rgba(240,103,103,.45); 1031 } 1032 1033 @media(max-width:720px){ 1034 .pc-market-freshness{ 1035 grid-template-columns:auto 1fr; 1036 } 1037 1038 .pc-market-age, 1039 .pc-market-state{ 1040 grid-column:2; 1041 justify-self:start; 1042 } 1043 } 1044 1045 1046 1047 /* CMS_PRICECHECK_PHASE2_INTELLIGENCE_CSS */ 1048 .pc-intel-summary{ 1049 display:none; 1050 margin-top:12px; 1051 border:1px solid var(--border); 1052 border-radius:14px; 1053 background:rgba(255,255,255,.035); 1054 padding:11px 13px; 1055 } 1056 .pc-intel-summary.show{display:block} 1057 .pc-intel-summary.warning{border-color:rgba(243,200,96,.42);background:rgba(243,200,96,.06)} 1058 .pc-intel-summary.high{border-color:rgba(240,103,103,.48);background:rgba(240,103,103,.07)} 1059 .pc-intel-summary-head{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap} 1060 .pc-intel-summary-title{font-weight:900} 1061 .pc-intel-summary-bits{display:flex;gap:7px;flex-wrap:wrap;margin-top:8px} 1062 .pc-intel-chip{display:inline-flex;align-items:center;gap:5px;border:1px solid var(--border);border-radius:999px;padding:4px 8px;font-size:10px;font-weight:850;color:var(--muted);background:rgba(255,255,255,.025)} 1063 .pc-intel-chip.high{border-color:rgba(240,103,103,.45);color:#ffd1d1;background:rgba(240,103,103,.07)} 1064 .pc-intel-chip.warning{border-color:rgba(243,200,96,.45);color:#ffe29b;background:rgba(243,200,96,.07)} 1065 .pc-intel-row>td{padding:0 0 10px!important;border-top:0!important;background:transparent!important} 1066 .pc-intel{margin:0;width:100%;box-sizing:border-box;border:1px solid rgba(92,190,255,.23);background:rgba(92,190,255,.035);border-radius:10px;padding:8px 10px} 1067 .pc-intel[open]{background:rgba(92,190,255,.055)} 1068 .pc-intel summary{cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;font-size:12px;font-weight:850;color:var(--text)} 1069 .pc-intel-summary-right{display:flex;align-items:center;gap:6px;flex-wrap:wrap} 1070 .pc-confidence{display:inline-flex;align-items:center;border:1px solid var(--border);border-radius:999px;padding:3px 7px;font-size:10px;font-weight:900;letter-spacing:.03em} 1071 .pc-confidence.high{border-color:rgba(79,218,140,.38);color:#bff5da;background:rgba(79,218,140,.07)} 1072 .pc-confidence.moderate{border-color:rgba(243,200,96,.42);color:#ffe29b;background:rgba(243,200,96,.07)} 1073 .pc-confidence.low{border-color:rgba(240,103,103,.48);color:#ffd1d1;background:rgba(240,103,103,.07)} 1074 .pc-intel-body{padding-top:9px} 1075 .pc-intel-grid{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:7px} 1076 .pc-intel-kpi{border:1px solid var(--border);background:rgba(0,0,0,.13);border-radius:9px;padding:7px 8px;min-width:0} 1077 .pc-intel-kpi .k{font-size:9px;font-weight:900;letter-spacing:.055em;text-transform:uppercase;color:var(--muted);line-height:1.25} 1078 .pc-intel-kpi .v{font-size:12px;font-weight:900;color:var(--text);margin-top:3px;overflow-wrap:anywhere} 1079 .pc-intel-kpi .v.up{color:#bff5da} 1080 .pc-intel-kpi .v.down{color:#ffd1d1} 1081 .pc-intel-secondary{display:grid;grid-template-columns:minmax(220px,.8fr) minmax(300px,1.2fr);gap:10px;margin-top:9px} 1082 .pc-intel-chart,.pc-intel-depth{border:1px solid var(--border);background:rgba(0,0,0,.10);border-radius:9px;padding:8px 9px;min-width:0} 1083 .pc-intel-chart-title,.pc-intel-depth-title{font-size:9px;font-weight:900;letter-spacing:.055em;text-transform:uppercase;color:var(--muted);margin-bottom:5px} 1084 .pc-sparkline{width:100%;height:48px;display:block;color:#a7d7ff} 1085 .pc-sparkline-grid{stroke:currentColor;opacity:.12;stroke-width:1} 1086 .pc-sparkline-line{fill:none;stroke:currentColor;stroke-width:2;vector-effect:non-scaling-stroke} 1087 .pc-intel-depth-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;font-size:10px} 1088 .pc-intel-depth-grid div{display:flex;justify-content:space-between;gap:8px;border-bottom:1px solid rgba(255,255,255,.06);padding:3px 0} 1089 .pc-intel-depth-grid span:first-child{color:var(--muted)} 1090 .pc-intel-depth-grid strong{color:var(--text);text-align:right} 1091 .pc-intel-warnings{display:grid;gap:6px;margin-top:9px} 1092 .pc-intel-warning{border:1px solid var(--border);border-radius:8px;padding:7px 8px;font-size:10px;line-height:1.4} 1093 .pc-intel-warning strong{display:block;margin-bottom:2px} 1094 .pc-intel-warning.warning{border-color:rgba(243,200,96,.42);background:rgba(243,200,96,.06);color:#ffe29b} 1095 .pc-intel-warning.high{border-color:rgba(240,103,103,.48);background:rgba(240,103,103,.07);color:#ffd1d1} 1096 .pc-intel-ok{font-size:10px;color:#bff5da;border:1px solid rgba(79,218,140,.32);background:rgba(79,218,140,.05);border-radius:8px;padding:7px 8px;margin-top:9px} 1097 .pc-intel-history-note{font-size:10px;color:var(--muted);line-height:1.4;margin-top:7px} 1098 @media(max-width:1050px){.pc-intel-grid{grid-template-columns:repeat(3,minmax(0,1fr))}} 1099 @media(max-width:760px){.pc-intel-secondary{grid-template-columns:1fr}.pc-intel-grid{grid-template-columns:repeat(2,minmax(0,1fr))}} 1100 @media(max-width:460px){.pc-intel-grid{grid-template-columns:1fr}} 1101 1102 1103 /* CMS_PUBLIC_REFERRAL_BOTTOM_V1 */ 1104 .pc-results-ad{display:none;width:100%;box-sizing:border-box;margin:10px 0 4px;overflow:hidden}
1105 .pc-results-ad.is-ready{display:block} 1106 .pc-referral-link{display:block;border:1px solid rgba(92,190,255,.18);border-radius:10px;overflow:hidden;box-shadow:0 8px 16px rgba(0,0,0,.16);transition:transform .16s ease, box-shadow .16s ease, border-color .16s ease} 1107 .pc-referral-link:hover{transform:translateY(-1px);box-shadow:0 12px 20px rgba(0,0,0,.22);border-color:rgba(92,190,255,.32)} 1108 .pc-referral-link img{display:block;width:100%;height:auto} 1109 @media(max-width:650px){.pc-results-ad{margin:8px 0 2px}} 1110 1111 /* CMS_PRICECHECK_UXV2_CSS */ 1112 #pcResults{overflow:hidden} 1113 #pcResults .tablewrap{overflow-x:hidden;border-radius:12px} 1114 #pcTable{width:100%;table-layout:auto} 1115 #pcTable th,#pcTable td{padding:10px 9px;vertical-align:middle} 1116 #pcTable th{white-space:nowrap;font-size:11px} 1117 #pcTable td{font-size:12px} 1118 #pcTable .pc-item-cell{min-width:180px;max-width:320px} 1119 #pcTable .pc-num{text-align:right;white-space:nowrap;font-variant-numeric:tabular-nums} 1120 #pcTable .pc-actions-cell{width:1%;white-space:nowrap} 1121 .pc-row-actions{display:flex;gap:6px;justify-content:flex-end;flex-wrap:wrap} 1122 .pc-row-action{padding:5px 8px!important;min-height:0!important;font-size:10px!important;border-radius:8px!important} 1123 .pc-advanced-inline{display:none;margin-top:5px;font-size:10px;line-height:1.45;color:var(--muted)} 1124 #pcResults.pc-advanced-on .pc-advanced-inline{display:block} 1125 1126 .pc-results-head{gap:8px!important} 1127 .pc-results-toolbar{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap} 1128 .pc-results-tools{display:flex;align-items:center;gap:7px;flex-wrap:wrap} 1129 .pc-mode-btn{padding:6px 10px!important;min-height:0!important;font-size:11px!important} 1130 .pc-mode-btn.active{border-color:rgba(92,190,255,.48)!important;background:rgba(92,190,255,.10)!important} 1131 .pc-mode-btn.notice{border-color:rgba(243,200,96,.42)!important} 1132 .pc-mode-btn.high{border-color:rgba(240,103,103,.48)!important} 1133 1134 .pc-totals{display:block!important;text-align:left!important} 1135 .pc-basic-totals{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:9px;width:100%} 1136 .pc-totalhero{border:1px solid var(--border);border-radius:12px;background:rgba(255,255,255,.035);padding:10px 12px;min-width:0} 1137 .pc-totalhero .k{color:var(--muted);font-size:10px;font-weight:900;letter-spacing:.08em;text-transform:uppercase} 1138 .pc-totalhero .v{margin-top:3px;font-size:20px;font-weight:950;color:var(--text);line-height:1.1} 1139 .pc-totalhero .s{margin-top:4px;color:var(--muted);font-size:10px} 1140 .pc-totalhero-head{display:flex;align-items:flex-start;justify-content:space-between;gap:8px} 1141 .pc-basic-meta{grid-column:1/-1;color:var(--muted);font-size:10px;padding:0 2px} 1142 .pc-advanced-totals{display:none;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin-top:8px} 1143 #pcResults.pc-advanced-on .pc-advanced-totals{display:grid} 1144 .pc-advanced-total{border:1px solid var(--border);background:rgba(92,190,255,.035);border-radius:10px;padding:8px 10px} 1145 .pc-advanced-total .k{color:var(--muted);font-size:9px;font-weight:900;letter-spacing:.06em;text-transform:uppercase} 1146 .pc-advanced-total .v{color:var(--text);font-size:14px;font-weight:900;margin-top:2px} 1147 1148 .hubtotals{grid-template-columns:repeat(5,minmax(0,1fr))!important;gap:7px!important;margin-top:10px!important} 1149 .hubbadge{min-height:0!important;padding:8px 9px!important;border-radius:10px!important} 1150 .hubbadge .h-title{font-size:11px} 1151 .hubbadge .h-sub{margin-top:4px!important;font-size:10px!important} 1152 .hubbadge .pc-hub-advanced{display:none} 1153 #pcResults.pc-advanced-on .hubbadge .pc-hub-advanced{display:block} 1154 1155 .pc-intel-summary.show{display:none!important} 1156 #pcResults.pc-health-open .pc-intel-summary.show{display:block!important} 1157 .pc-intel-summary,.pc-intel-summary.warning,.pc-intel-summary.high{border-color:var(--border)!important;background:rgba(255,255,255,.025)!important;padding:9px 10px!important;margin-top:9px!important} 1158 .pc-intel-summary-title{font-size:12px} 1159 1160 .pc-intel-row,.pc-recycle-row{display:none} 1161 .pc-intel-row>td,.pc-recycle-row>td{padding:0 0 8px!important;background:transparent!important;border-top:0!important} 1162 .pc-detail-drawer{border:1px solid rgba(92,190,255,.25);background:rgba(92,190,255,.035);border-radius:10px;padding:10px} 1163 .pc-detail-head{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;margin-bottom:8px} 1164 .pc-detail-title{font-size:12px;font-weight:900} 1165 .pc-detail-sub{color:var(--muted);font-size:10px;margin-top:2px} 1166 .pc-detail-kpis{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:7px} 1167 .pc-detail-kpi{border:1px solid var(--border);background:rgba(0,0,0,.10);border-radius:8px;padding:7px 8px;min-width:0} 1168 .pc-detail-kpi .k{color:var(--muted);font-size:8px;font-weight:900;text-transform:uppercase;letter-spacing:.055em} 1169 .pc-detail-kpi .v{color:var(--text);font-size:11px;font-weight:900;margin-top:2px;overflow-wrap:anywhere} 1170 .pc-detail-grid{display:grid;grid-template-columns:minmax(220px,.8fr) minmax(300px,1.2fr);gap:8px;margin-top:8px} 1171 .pc-detail-panel{border:1px solid var(--border);background:rgba(0,0,0,.08);border-radius:8px;padding:8px} 1172 .pc-detail-panel-title{color:var(--muted);font-size:9px;font-weight:900;text-transform:uppercase;letter-spacing:.055em;margin-bottom:5px} 1173 .pc-detail-depth{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:3px 10px;font-size:10px} 1174 .pc-detail-depth div{display:flex;justify-content:space-between;gap:8px;border-bottom:1px solid rgba(255,255,255,.05);padding:3px 0} 1175 .pc-detail-depth span{color:var(--muted)} 1176 .pc-detail-warnings{display:grid;gap:5px;margin-top:8px} 1177 .pc-detail-warning{border:1px solid rgba(243,200,96,.34);background:rgba(243,200,96,.045);color:#ffe29b;border-radius:7px;padding:6px 8px;font-size:10px;line-height:1.4} 1178 .pc-detail-warning.high{border-color:rgba(240,103,103,.42);background:rgba(240,103,103,.055);color:#ffd1d1} 1179 .pc-detail-warning strong{display:block;margin-bottom:1px} 1180 .pc-detail-ok{margin-top:8px;color:#bff5da;font-size:10px} 1181
1182 @media(max-width:900px){ 1183 .hubtotals{grid-template-columns:repeat(2,minmax(0,1fr))!important} 1184 .pc-detail-kpis{grid-template-columns:repeat(2,minmax(0,1fr))} 1185 .pc-detail-grid{grid-template-columns:1fr} 1186 } 1187 @media(max-width:650px){ 1188 #pcResults .tablewrap{overflow-x:auto} 1189 #pcTable{min-width:760px} 1190 .pc-basic-totals{grid-template-columns:1fr} 1191 .pc-advanced-totals{grid-template-columns:1fr} 1192 .hubtotals{grid-template-columns:1fr!important} 1193 } 1194 1195 1196 /* CMS_PRICECHECK_UXV2_NEGATIVE_CSS */ 1197 .pc-negative, 1198 .pc-detail-kpi .v.down, 1199 .pc-intel-kpi .v.down, 1200 .pc-recycle-kpi.negative .v, 1201 .pc-recycle-summary-value.negative{ 1202 color:#ff7373!important; 1203 font-weight:900!important; 1204 } 1205 .pc-negative{ 1206 text-shadow:0 0 10px rgba(255,90,90,.10); 1207 } 1208 1209 1210 /* CMS_PRICECHECK_UXV2_MARKET_BUTTON_CSS */ 1211 .pc-market-btn{ 1212 display:inline-flex!important; 1213 align-items:center; 1214 justify-content:center; 1215 gap:5px; 1216 min-width:132px; 1217 font-variant-numeric:tabular-nums; 1218 font-weight:900!important; 1219 } 1220 .pc-market-btn .pc-market-confidence{ 1221 font-size:9px; 1222 letter-spacing:.045em; 1223 } 1224 .pc-market-btn .pc-market-spread{ 1225 font-size:9px; 1226 opacity:.9; 1227 } 1228 .pc-market-btn .pc-market-notices{ 1229 display:inline-flex; 1230 align-items:center; 1231 justify-content:center; 1232 min-width:18px; 1233 height:18px; 1234 padding:0 5px; 1235 border-radius:999px; 1236 font-size:9px; 1237 font-weight:950; 1238 border:1px solid currentColor; 1239 } 1240 .pc-market-btn.good{ 1241 border-color:rgba(75,210,150,.52)!important; 1242 background:rgba(75,210,150,.085)!important; 1243 color:#9ff0c9!important; 1244 } 1245 .pc-market-btn.warning{ 1246 border-color:rgba(243,200,96,.60)!important; 1247 background:rgba(243,200,96,.095)!important; 1248 color:#ffe08a!important; 1249 } 1250 .pc-market-btn.high{ 1251 border-color:rgba(240,103,103,.66)!important; 1252 background:rgba(240,103,103,.105)!important; 1253 color:#ff9a9a!important; 1254 } 1255 .pc-market-btn.none{ 1256 border-color:var(--border)!important; 1257 color:var(--muted)!important; 1258 } 1259 .pc-market-btn.high .pc-market-notices{ 1260 background:rgba(240,103,103,.12); 1261 } 1262 .pc-market-btn.warning .pc-market-notices{ 1263 background:rgba(243,200,96,.10); 1264 } 1265 .pc-market-btn.good .pc-market-notices{ 1266 background:rgba(75,210,150,.08); 1267 } 1268 1269 @media(max-width:820px){ 1270 .pc-market-btn{ 1271 min-width:116px; 1272 gap:4px; 1273 } 1274 .pc-market-btn .pc-market-spread{ 1275 display:none; 1276 } 1277 } 1278 1279 1280 /* CMS_PRICECHECK_REPROCESS_MODE_AUTORUN_V1 */ 1281 .pc-reprocess-btn{ 1282 display:none!important; 1283 } 1284 1285</style> 1286 1287 1288<div class="grid" style="gap:14px"> 1289 <div class="card"> 1290 <div style="display:flex; gap:12px; align-items:flex-end; justify-content:space-between; flex-wrap:wrap"> 1291 <div> 1292 <h1 style="margin:0">Price Check</h1> 1293 <div class="hint" style="margin-top:6px"> 1294 Paste an item list <em>or</em> paste directly from EVE inventory/assets, pick a region, and choose a market hub, click Check Prices, and get a clean Buy / Sell appraisal. Advanced pricing, depth, history, and market health stay available on demand. 1295 </div> 1296 </div> 1297 <div class="hint" style="text-align:right"> 1298 Tip: quantities can be <code>1000 Tritanium</code>, <code>30 x Plasma Thruster</code>, <code>Tritanium 1000</code>, <code>Tritanium x1000</code>, or <code>Construction Blocks (23 Units)</code>. 1299 </div> 1300 </div> 1301 1302 <form id="pcForm" style="margin-top:12px"> 1303 <input type="hidden" name="csrf" value="7f97e5cf384ab7d2a7603e8e4a5e01dfa7aa9dc843d1f17e0c9b09d17db49cef"> 1304 1305 <div class="grid" style="grid-template-columns: 1fr; gap:12px"> 1306 <div class="grid" style="grid-template-columns: 1fr; gap:12px" id="pcGrid"> 1307 <div id="pcItemsColumn" style="min-width:0"> 1308 <label>Items</label> 1309 <textarea id="pcItemsTextarea" name="items" rows="10" placeholder="Tritanium 100000\n30 x Plasma Thruster\nConstruction Blocks (23 Units)\n\n(One item per line)" style="font-family:var(--mono); resize:vertical"></textarea> 1310 <div class="hint" style="margin-top:8px">Max: 200 lines per run. Blank lines are ignored.</div> 1311 <div class="grid" style="grid-template-columns: repeat(3, minmax(0, 1fr)); gap:10px; margin-top:12px"> 1312 <button class="btn primary" type="submit" id="pcRun">Check Prices</button> 1313 <a class="btn ghost" href="/eve-market/" id="pcMarketBrowser">Market Browser</a><!-- CMS_PRICECHECK_PHASE3_MARKET_BROWSER_LINK --> 1314 <button class="btn ghost" type="button" id="pcClear">Clear</button> 1315 <button class="btn secondary" type="button" id="pcShare" title="Copy a shareable link with the current items">Copy Share Link</button> 1316 </div> 1317 </div> 1318 1319 <div id="pcSettingsColumn" style="min-width:0"> 1320 <label>Hub</label> 1321 <div class="hint" style="margin-top:6px">Pick which market hub to price against.</div> 1322 <select name="region_id" id="pcHubSelect"> 1323 <option value="10000043" selected>Domain (Amarr)</option> 1324 <option value="10000002" >The Forge (Jita)</option> 1325 <option value="10000032" >Sinq Laison (Dodixie)</option> 1326 <option value="10000030" >Heimatar (Rens)</option> 1327 <option value="10000042" >Metropolis (Hek)</option> 1328 <option value="19000001" >Global PLEX Market (PLEX only)</option> 1329 </select> 1330 1331 1332 <div style="height:10px"></div> 1333 <label style="display:flex; align-items:center; justify-content:space-between; gap:10px">
1334 <span>Price adjustment %</span> 1335 <span class="badge" id="adjBadge">0%</span> 1336 </label> 1337 <div class="pctslider"> 1338 <input type="range" name="adj_pct" id="adjPct" min="-90" max="90" step="0.5" value="0"> 1339 <div class="pctpresets"> 1340 <button class="btn ghost" type="button" data-pct="-10" style="padding:6px 10px; font-size:12px" title="Set to -10%">-10%</button> 1341 <button class="btn ghost" type="button" data-pct="0" style="padding:6px 10px; font-size:12px" title="Set to 0%">0%</button> 1342 <button class="btn ghost" type="button" data-pct="10" style="padding:6px 10px; font-size:12px" title="Set to +10%">+10%</button> 1343 </div> 1344 </div> 1345 <p class="small">Applies a +/â percent to displayed prices and totals for the selected hub.</p> 1346 1347 <div class="pc-global-reprocess"> 1348 <div class="pc-global-reprocess-title"> 1349 <label class="pc-reprocess-toggle" for="pcShowReprocess" title="Appraise the entire pasted list after reprocessing instead of pricing the original ore/items."> 1350 <input id="pcShowReprocess" type="checkbox"> 1351 <span>Reprocess entire appraisal</span> 1352 </label> 1353 <span class="badge" id="pcReprocessEffBadge">72%</span> 1354 </div> 1355 <div class="pc-global-reprocess-row"> 1356 <input id="pcReprocessEff" type="number" min="0" max="100" step="0.1" value="72" inputmode="decimal" aria-describedby="pcReprocessEffHelp"> 1357 <strong>%</strong> 1358 </div> 1359 <div class="hint" id="pcReprocessEffHelp" style="margin-top:6px">When enabled, the entire pasted list is converted into recovered outputs at this efficiency, then those outputs are appraised at the selected hub. Changing this option automatically reruns the appraisal. Complete-portion remainders and non-reprocessable items stay in the final appraisal.</div> 1360 </div> 1361 1362 </div> 1363 </div> 1364 </div> 1365 </form> 1366 </div> 1367 1368 1369 1370 1371 <!-- CMS_MARKET_FRESHNESS_PANEL_V1 --> 1372 <div 1373 id="pcMarketFreshness" 1374 class="pc-market-freshness" 1375 aria-live="polite" 1376 > 1377 <span class="pc-market-dot"></span> 1378 1379 <div> 1380 <div class="pc-market-source"> 1381 EVE Syndicates Market Intelligence 1382 </div> 1383 1384 <div class="hint" id="pcMarketDetail"> 1385 Checking local market ingest⦠1386 </div> 1387 </div> 1388 1389 <div class="pc-market-age" id="pcMarketAge"> 1390 â 1391 </div> 1392 1393 <div class="pc-market-state" id="pcMarketState"> 1394 CHECKING 1395 </div> 1396 </div> 1397 1398<div class="card" id="pcResults" style="display:none"> 1399 <div class="pc-results-head"> 1400 <div> 1401 <div class="pc-results-toolbar"> 1402 <div> 1403 <h2 style="margin:0">Results</h2> 1404 <div class="hint" id="pcMeta" style="margin-top:4px"></div> 1405 </div> 1406 <div class="pc-results-tools" aria-label="Price Check result controls"> 1407 <!-- CMS_PRICECHECK_UXV2_TOOLBAR --> 1408 <button class="btn ghost pc-mode-btn" type="button" id="pcAdvancedToggle" aria-pressed="false">Advanced Pricing</button> 1409 <button class="btn ghost pc-mode-btn" type="button" id="pcHealthToggle" aria-pressed="false">Market Health</button> 1410 </div> 1411 </div> 1412 </div> 1413 <div id="pcTotals" class="pc-totals" aria-live="polite"></div> 1414 </div> 1415 1416 <div id="pcHubTotals" class="hubtotals" style="display:none"></div> 1417 1418 <!-- CMS_PRICECHECK_PHASE2_INTELLIGENCE_SUMMARY --> 1419 <div id="pcIntelSummary" class="pc-intel-summary" aria-live="polite"></div> 1420 1421 <div id="pcMsg" class="notice" style="margin-top:12px; display:none"></div> 1422 1423 <div class="tablewrap" style="margin-top:12px"> 1424 <table class="table" id="pcTable"> 1425 <thead> 1426 <tr> 1427 <th>Item</th> 1428 <th class="pc-num">Qty</th> 1429 <th class="pc-num">Buy</th> 1430 <th class="pc-num">Sell</th> 1431 <th class="pc-num">Buy Total</th> 1432 <th class="pc-num">Sell Total</th> 1433 <th class="pc-actions-cell">Market</th> 1434 </tr> 1435 </thead> 1436 <tbody></tbody> 1437 </table> 1438 </div> 1439 1440 <div class="hint" style="margin-top:12px"> 1441 Pricing source: EVE Syndicates Market Intelligence. If a line errors, it usually means the item name didnât resolve on ESI, or the item has no market data in that region. 1442 </div> 1443 </div> 1444 1445<div class="card" id="pcRecent" style="display:none"> 1446 <div style="display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap"> 1447 <h2 style="margin:0">Recent checks</h2> 1448 <button class="btn ghost" type="button" id="pcRecentClear" style="padding:6px 10px; font-size:12px">Clear history</button> 1449 </div> 1450 <div class="hint" style="margin-top:6px">Stored locally in your browser on this device.</div> 1451 <div class="pc-badges" id="pcRecentBadges" style="margin-top:12px"></div> 1452</div> 1453 1454<!-- CMS_PUBLIC_REFERRAL_BOTTOM_V1: Price Check banner intentionally below results/recent checks --> 1455<div class="pc-results-ad" id="pcResultsAd" aria-label="EVE Online free skill points referral"> 1456 <a class="pc-referral-link" href="https://www.eveonline.com/signup?invc=c2c0373f-cae0-4026-91e7-651973b69340" target="_blank" rel="noopener noreferrer sponsored"> 1457 <img src="/assets/referrals/eve_free_skill_points_slim_banner_2026_09_22.png" alt="Start EVE Online with free skill points â claim the referral bonus"> 1458 </a> 1459</div> 1460 1461</div> 1462 1463<div class="pc-unresolved-overlay" id="pcUnresolvedOverlay" aria-hidden="true"> 1464 <section class="pc-unresolved-dialog" role="dialog" aria-modal="true" aria-labelledby="pcUnresolvedTitle" aria-describedby="pcUnresolvedDesc"> 1465 <div class="pc-unresolved-head"> 1466 <div> 1467 <h3 id="pcUnresolvedTitle">Some pasted items did not resolve</h3> 1468 <div class="hint" id="pcUnresolvedDesc">Review the unresolved lines below. You can remove all of them and immediately run Price Check again, or close this window and edit the pasted list yourself.</div> 1469 </div> 1470 <button class="btn ghost pc-unresolved-close" type="button" id="pcUnresolvedX" aria-label="Close unresolved
1470items dialog">Ã</button> 1471 </div> 1472 <div class="pc-unresolved-body"> 1473 <ul class="pc-unresolved-list" id="pcUnresolvedList"></ul> 1474 </div> 1475 <div class="pc-unresolved-actions"> 1476 <button class="btn ghost" type="button" id="pcUnresolvedManual">Close â Remove Manually</button> 1477 <button class="btn primary" type="button" id="pcUnresolvedRemove">Remove Unresolved & Recheck</button> 1478 </div> 1479 </section> 1480</div> 1481
1482<script> 1483(function(){ 1484 const form = document.getElementById('pcForm'); 1485 const taItems = form ? form.querySelector('textarea[name=\"items\"]') : null; 1486 const btnRun = document.getElementById('pcRun'); 1487 const btnClear = document.getElementById('pcClear'); 1488 const btnShare = document.getElementById('pcShare'); 1489 const results = document.getElementById('pcResults'); 1490 const resultsAd = document.getElementById('pcResultsAd'); 1491 let resultsAdInitialized = false; 1492 function pcInitResultsAd(){ 1493 if (!resultsAd || resultsAdInitialized) return; 1494 resultsAd.classList.add('is-ready'); 1495 resultsAdInitialized = true; 1496 } 1497 const msg = document.getElementById('pcMsg'); 1498 const meta = document.getElementById('pcMeta'); 1499 const totals = document.getElementById('pcTotals'); 1500 const hubTotals = document.getElementById('pcHubTotals'); 1501 const table = document.getElementById('pcTable'); 1502 const recentCard = document.getElementById('pcRecent'); 1503 const recentBadges = document.getElementById('pcRecentBadges'); 1504 const recentClear = document.getElementById('pcRecentClear'); 1505 const adjRange = document.getElementById('adjPct'); 1506 const adjBadge = document.getElementById('adjBadge'); 1507 const adjPresetBtns = document.querySelectorAll('[data-pct]'); 1508 const reprocessEffInput = document.getElementById('pcReprocessEff'); 1509 const reprocessEffBadge = document.getElementById('pcReprocessEffBadge'); 1510 const showReprocessToggle = document.getElementById('pcShowReprocess'); 1511 const unresolvedOverlay = document.getElementById('pcUnresolvedOverlay'); 1512 const unresolvedList = document.getElementById('pcUnresolvedList'); 1513 const unresolvedRemoveBtn = document.getElementById('pcUnresolvedRemove'); 1514 const unresolvedManualBtn = document.getElementById('pcUnresolvedManual'); 1515 const unresolvedXBtn = document.getElementById('pcUnresolvedX'); 1516 let unresolvedRows = []; 1517 let unresolvedReturnFocus = null; 1518 1519 const hubSelect = form ? form.querySelector('#pcHubSelect') : null; 1520 1521 // CMS_MARKET_FRESHNESS_PANEL_V1 1522 const marketFreshness = 1523 document.getElementById('pcMarketFreshness'); 1524 1525 const marketAge = 1526 document.getElementById('pcMarketAge'); 1527 1528 const marketState = 1529 document.getElementById('pcMarketState'); 1530 1531 const marketDetail = 1532 document.getElementById('pcMarketDetail'); 1533 1534 let marketAgeAtFetch = null; 1535 let marketAgeFetchedMs = 0; 1536 let marketFreshAfter = 600; 1537 let marketStaleAfter = 1200; 1538 1539 1540 1541 let lastAppraisal = null; // Current successful appraisal used by Copy Share Link 1542 1543 1544 // Preferred hub (per-browser). Migrate the old DMC/IRS key once. 1545 const HUB_PREF_KEY = 'evesyndicates_pricecheck_preferred_hub_region'; 1546 const HUB_PREF_KEY_LEGACY = 'dmc_irs_pricecheck_preferred_hub_region'; 1547 1548 try { 1549 const urlHasRegion = 1550 (new URL(window.location.href)) 1551 .searchParams 1552 .has('region_id'); 1553 1554 if (!urlHasRegion && hubSelect) { 1555 let saved = 1556 localStorage.getItem(HUB_PREF_KEY); 1557 1558 if (!saved) { 1559 saved = 1560 localStorage.getItem(HUB_PREF_KEY_LEGACY); 1561 1562 if (saved) { 1563 localStorage.setItem( 1564 HUB_PREF_KEY, 1565 saved 1566 ); 1567 } 1568 } 1569 1570 if ( 1571 saved && 1572 String(saved).trim() !== '' 1573 ) { 1574 hubSelect.value = String(saved); 1575 } 1576 } 1577 } catch (_) {} 1578 1579 1580function showHubSavedToast(){ 1581 // Tiny, dependency-free toast 1582 let t = document.getElementById('hubSavedToast'); 1583 if (!t) { 1584 t = document.createElement('div'); 1585 t.id = 'hubSavedToast'; 1586 t.style.position = 'fixed'; 1587 t.style.right = '16px'; 1588 t.style.bottom = '16px'; 1589 t.style.zIndex = '9999'; 1590 t.style.padding = '10px 12px'; 1591 t.style.borderRadius = '12px'; 1592 t.style.background = 'rgba(0,0,0,0.85)'; 1593 t.style.border = '1px solid rgba(255,255,255,0.18)'; 1594 t.style.color = '#fff'; 1595 t.style.fontSize = '13px'; 1596 t.style.maxWidth = '320px'; 1597 t.style.boxShadow = '0 10px 30px rgba(0,0,0,0.35)'; 1598 t.style.opacity = '0'; 1599 t.style.transform = 'translateY(6px)'; 1600 t.style.transition = 'opacity 180ms ease, transform 180ms ease'; 1601 document.body.appendChild(t); 1602 } 1603 t.textContent = 'Hub preference saved for future lookups.'; 1604 requestAnimationFrame(() => { 1605 t.style.opacity = '1'; 1606 t.style.transform = 'translateY(0)'; 1607 }); 1608 clearTimeout(window.__hubToastTimer); 1609 window.__hubToastTimer = setTimeout(() => { 1610 t.style.opacity = '0'; 1611 t.style.transform = 'translateY(6px)'; 1612 }, 2200); 1613} 1614 1615if (hubSelect) { 1616 hubSelect.addEventListener('change', function(){
1617 try { localStorage.setItem(HUB_PREF_KEY, String(hubSelect.value || '')); } catch (_) {} 1618 showHubSavedToast(); 1619 }); 1620 } 1621 1622 1623 function fmtPct(v){ 1624 const n = Math.round(Number(v) * 10) / 10; 1625 const s = String(n).replace(/\.0$/, ''); 1626 return (n>0?'+':'') + s + '%'; 1627 } 1628 1629 function syncAdjUI(){ 1630 if (!adjRange || !adjBadge) return; 1631 const v = clampPct(adjRange.value); 1632 adjRange.value = v; 1633 adjBadge.textContent = fmtPct(v); 1634 } 1635 1636 if (adjRange) adjRange.addEventListener('input', syncAdjUI); 1637 adjPresetBtns.forEach(b => b.addEventListener('click', function(){ 1638 if (!adjRange) return; 1639 adjRange.value = b.getAttribute('data-pct') || '0'; 1640 syncAdjUI(); 1641 })); 1642 1643 // Initialize slider badge 1644 syncAdjUI(); 1645 1646 function clampPct(v){ 1647 let x = Number(v); 1648 if (!isFinite(x)) x = 0; 1649 if (x < -90) x = -90; 1650 if (x > 90) x = 90; 1651 return x; 1652 } 1653 1654 function getAdjPct(){ 1655 try { 1656 const fd = new FormData(form); 1657 return clampPct(fd.get('adj_pct') || 0); 1658 } catch(e){ return 0; } 1659 } 1660 1661 function fmtISK(n){ 1662 if (n === null || typeof n === 'undefined' || Number.isNaN(Number(n))) return 'â'; 1663 return new Intl.NumberFormat(undefined, { maximumFractionDigits: 2 }).format(Number(n)) + ' ISK'; 1664 } 1665 function fmtInt(n){ 1666 if (n === null || typeof n === 'undefined' || Number.isNaN(Number(n))) return 'â'; 1667 return new Intl.NumberFormat(undefined, { maximumFractionDigits: 0 }).format(Number(n)); 1668 } 1669 1670 1671 function fmtM3(n){ 1672 if (n === null || typeof n === 'undefined' || Number.isNaN(Number(n))) return 'â'; 1673 return new Intl.NumberFormat(undefined, { maximumFractionDigits: 2 }).format(Number(n)) + ' m³'; 1674 } 1675 1676 1677// Recent checks (local, per-browser) 1678const RECENT_KEY = 'evesyndicates_pricecheck_recent_v1'; 1679const RECENT_KEY_LEGACY = 'dmc_irs_pricecheck_recent_v1'; 1680const RECENT_MAX = 10; 1681 1682function hubShort(regionId){ 1683 const id = String(regionId || ''); 1684 if (id === '10000002') return 'Jita'; 1685 if (id === '10000043') return 'Amarr'; 1686 if (id === '10000032') return 'Dodixie'; 1687 if (id === '10000030') return 'Rens'; 1688 if (id === '10000042') return 'Hek'; 1689 if (id === '19000001') return 'PLEX'; 1690 return 'Hub ' + id; 1691} 1692 1693 1694// 5-hub comparison badges (major trade hubs) 1695const HUBS_5 = [ 1696 { id: '10000002', label: 'Jita' }, 1697 { id: '10000043', label: 'Amarr' }, 1698 { id: '10000032', label: 'Dodixie' }, 1699 { id: '10000030', label: 'Rens' }, 1700 { id: '10000042', label: 'Hek' }, 1701]; 1702 1703function hubLabel(regionId){ 1704 const id = String(regionId || ''); 1705 const hit = HUBS_5.find(h => h.id === id); 1706 return hit ? hit.label : hubShort(id); 1707} 1708 1709 1710function renderHubBadge(regionId, summary, adjPct, isActive, loadingText, errText){ 1711 if (!hubTotals) return; 1712 1713 const id = String(regionId || ''); 1714 let el = hubTotals.querySelector('[data-hub="'+id+'"]'); 1715 if (!el) { 1716 el = document.createElement('div'); 1717 el.className = 'hubbadge'; 1718 el.dataset.hub = id; 1719 hubTotals.appendChild(el); 1720 } 1721 1722 el.classList.toggle('active', !!isActive); 1723 1724 const factor = 1 + (clampPct(adjPct) / 100); 1725 const d = summary || {}; 1726 const typesOk = Number(d.types_priced || 0); 1727 const typesReq = Number(d.types_requested || 0); 1728 const topBuy = Number(d.buy_total || 0) * factor; 1729 const topSell = Number(d.sell_total || 0) * factor; 1730 const iSell = Number(d.immediate_sell_total || 0) * factor; 1731 const split = Number(d.split_total || 0) * factor; 1732 const iBuy = Number(d.immediate_buy_total || 0) * factor; 1733 const buy = iSell; 1734 const sell = iBuy; 1735 const sellFill = Number(d.immediate_sell_fill_pct || 0); 1736 const buyFill = Number(d.immediate_buy_fill_pct || 0); 1737 const right = errText ? 'â' : (loadingText ? loadingText : String(typesOk) + '/' + String(typesReq)); 1738 1739 el.innerHTML = 1740 '<div class="h-title"><span>'+escapeHtml(hubLabel(id))+'</span><span class="hint">'+escapeHtml(right)+'</span></div>' 1741 + (errText 1742 ? '<div class="hint" style="margin-top:5px">'+escapeHtml(errText)+'</div>' 1743 : ( 1744 '<div class="h-sub"><span>Buy</span><span class="h-val">'+escapeHtml(loadingText ? 'â¦' : fmtISKShort(buy))+'</span></div>' 1745 + '<div class="h-sub"><span>Sell</span><span class="h-val">'+escapeHtml(loadingText ? 'â¦' : fmtISKShort(sell))+'</span></div>' 1746 + '<div class="pc-hub-advanced">' 1747 + '<div class="h-sub immediate"><span>Immediate Sell</span><span>'+escapeHtml(loadingText ? 'â¦' : fmtISKShort(iSell))+'</span></div>' 1748 + '<div class="h-sub"><span>Split</span><span>'+escapeHtml(loadingText ? 'â¦' : fmtISKShort(split))+'</span></div>' 1749 + '<div class="h-sub immediate"><span>Immediate Buy</span><span>'+escapeHtml(loadingText ? 'â¦' : fmtISKShort(iBuy))+'</span></div>' 1750 + (!loadingText && (sellFill < 99.999 || buyFill < 99.999) 1751 ? '<div class="hint" style="margin-top:4px">Fill: sell '+escapeHtml(sellFill.toFixed(1))+'% · buy '+escapeHtml(buyFill.toFixed(1))+'%</div>' 1752 : '') 1753 + '</div>' 1754 ) 1755 ); 1756 1757 if (!errText && !loadingText) { 1758 el.title = hubLabel(id) 1759 + ' · Buy ' + fmtISK(buy) 1760 + ' · Sell ' + fmtISK(sell) 1761 + ' · Immediate Sell ' + fmtISK(iSell) 1762 + ' · Split ' + fmtISK(split) 1763 + ' · Immediate Buy ' + fmtISK(iBuy) 1764 + ' · Top Buy ' + fmtISK(topBuy) 1765 + ' · Top Sell ' + fmtISK(topSell); 1766 } 1767} 1768 1769function loadAllHubTotals(adjPct, mainData){ 1770 if (!hubTotals) return; 1771 hubTotals.style.display = ''; 1772 hubTotals.innerHTML = ''; 1773 const mainRegion = mainData && mainData.region_id ? String(mainData.region_id) : ''; 1774 const comparison = mainData && mainData.hub_comparison ? mainData.hub_comparison : {}; 1775 HUBS_5.forEach(function(h){ 1776 const d = comparison[String(h.id)] || null; 1777 if (!d) {
1778 renderHubBadge(h.id, null, adjPct, h.id === mainRegion, null, 'No local comparison data'); 1779 return; 1780 } 1781 renderHubBadge(h.id, d, adjPct, h.id === mainRegion, null, null); 1782 }); 1783 } 1784 1785function fmtISKShort(n){ 1786 const x = Number(n); 1787 if (!isFinite(x)) return 'â'; 1788 const abs = Math.abs(x); 1789 const units = [ 1790 {v: 1e12, s: 't'}, 1791 {v: 1e9, s: 'b'}, 1792 {v: 1e6, s: 'm'}, 1793 {v: 1e3, s: 'k'}, 1794 ]; 1795 for (const u of units) { 1796 if (abs >= u.v) { 1797 const v = x / u.v; 1798 const txt = (Math.round(v * 100) / 100).toString().replace(/\.0+$/,'').replace(/(\.\d)0$/,'$1'); 1799 return txt + u.s + ' ISK'; 1800 } 1801 } 1802 return fmtISK(x); 1803} 1804 1805function countLines(text){ 1806 return String(text || '') 1807 .split(/\r?\n/) 1808 .map(l => l.trim()) 1809 .filter(Boolean).length; 1810} 1811 1812function loadRecent(){ 1813 try{ 1814 let raw = 1815 localStorage.getItem(RECENT_KEY); 1816 1817 if (!raw) { 1818 raw = 1819 localStorage.getItem(RECENT_KEY_LEGACY); 1820 1821 if (raw) { 1822 localStorage.setItem( 1823 RECENT_KEY, 1824 raw 1825 ); 1826 } 1827 } 1828 1829 const arr = 1830 raw ? JSON.parse(raw) : []; 1831 1832 return Array.isArray(arr) ? arr : []; 1833 1834 }catch(_){ 1835 return []; 1836 } 1837} 1838 1839function saveRecent(arr){ 1840 try{ localStorage.setItem(RECENT_KEY, JSON.stringify(arr)); }catch(_){} 1841} 1842 1843function renderRecent(){ 1844 if (!recentCard || !recentBadges) return; 1845 const list = loadRecent(); 1846 if (!list.length) { 1847 recentCard.style.display = 'none'; 1848 recentBadges.innerHTML = ''; 1849 return; 1850 } 1851 recentCard.style.display = ''; 1852 recentBadges.innerHTML = ''; 1853 list.forEach((it) => { 1854 const btn = document.createElement('button'); 1855 btn.type = 'button'; 1856 btn.className = 'pc-badge'; 1857 const lines = Number(it.lines || 0) || countLines(it.items || ''); 1858 const hub = hubShort(it.region_id); 1859 const total = fmtISKShort(it.total_isk); 1860 btn.innerHTML = '<strong>' + escapeHtml(String(lines)) + '</strong> items ⢠' 1861 + escapeHtml(hub) + ' ⢠' + escapeHtml(total); 1862 1863 const when = it.when ? new Date(it.when) : null; 1864 const whenTxt = when && !isNaN(when.getTime()) ? when.toLocaleString() : ''; 1865 const adj = (it.adj_pct && Number(it.adj_pct)) ? (' ⢠Adjustment ' + (Number(it.adj_pct)>0?'+':'') + it.adj_pct + '%') : ''; 1866 btn.title = (whenTxt ? ('Ran: ' + whenTxt) : 'Recent check') + adj; 1867 1868 btn.addEventListener('click', function(){
1869 try { 1870 // Restore this check into the UI and run it again (no gigantic URL required). 1871 if (taItems) taItems.value = it.items || ''; 1872 const sel = form ? form.querySelector('select[name="region_id"]') : null; 1873 if (sel && it.region_id) sel.value = String(it.region_id); 1874 if (adjRange) { adjRange.value = String(it.adj_pct ?? 0); syncAdjUI(); } 1875 1876 // Keep URL clean. 1877 try { 1878 const u = new URL(window.location.href); 1879 u.search = ''; 1880 history.replaceState(null, '', u.toString()); 1881 } catch(_) {} 1882 1883 run(); 1884 } catch(_) {} 1885 }); 1886 1887 recentBadges.appendChild(btn); 1888 }); 1889} 1890 1891if (recentClear) { 1892 recentClear.addEventListener('click', function(){ 1893 try{ localStorage.removeItem(RECENT_KEY); localStorage.removeItem(RECENT_KEY_LEGACY); }catch(_){} 1894 renderRecent(); 1895 }); 1896} 1897 1898 1899 1900 function marketHumanAge(seconds){ 1901 let s = Math.max(0, Math.floor(Number(seconds) || 0)); 1902 1903 if (s < 60) return s + 's old'; 1904 1905 const m = Math.floor(s / 60); 1906 const rs = s % 60; 1907 1908 if (m < 60) { 1909 return m + 'm ' + rs + 's old'; 1910 } 1911 1912 const h = Math.floor(m / 60); 1913 const rm = m % 60; 1914 1915 return h + 'h ' + rm + 'm old'; 1916 } 1917 1918 function marketExtractAge(m){ 1919 if (!m || typeof m !== 'object') return null; 1920 1921 const direct = [ 1922 m.age_seconds, 1923 m.data_age_seconds, 1924 m.ingest_age_seconds, 1925 m.seconds_old 1926 ]; 1927 1928 for (const v of direct) { 1929 const n = Number(v); 1930 1931 if (Number.isFinite(n) && n >= 0) { 1932 return n; 1933 } 1934 } 1935 1936 const stamps = [ 1937 m.last_success_at, 1938 m.last_success_utc, 1939 m.completed_at, 1940 m.finished_at, 1941 m.updated_at, 1942 m.ingested_at 1943 ]; 1944 1945 for (const stamp of stamps) { 1946 if (!stamp) continue; 1947 1948 const d = new Date(String(stamp)); 1949 1950 if (!Number.isNaN(d.getTime())) { 1951 return Math.max( 1952 0, 1953 (Date.now() - d.getTime()) / 1000 1954 ); 1955 } 1956 } 1957 1958 return null; 1959 } 1960 1961 function marketRenderClock(){ 1962 if (!marketFreshness || !marketAge) return; 1963 1964 if (marketAgeAtFetch === null) { 1965 marketAge.textContent = 'â'; 1966 return; 1967 } 1968 1969 const elapsed = 1970 Math.max( 1971 0, 1972 (Date.now() - marketAgeFetchedMs) / 1000 1973 ); 1974 1975 const age = marketAgeAtFetch + elapsed; 1976 1977 marketAge.textContent = marketHumanAge(age); 1978 1979 marketFreshness.classList.remove( 1980 'fresh', 1981 'aging', 1982 'stale' 1983 ); 1984 1985 let cls = 'fresh'; 1986 let label = 'FRESH'; 1987 1988 if (age > marketStaleAfter) { 1989 cls = 'stale'; 1990 label = 'STALE'; 1991 } else if (age > marketFreshAfter) { 1992 cls = 'aging'; 1993 label = 'AGING'; 1994 } 1995 1996 marketFreshness.classList.add(cls); 1997 1998 if (marketState) { 1999 marketState.textContent = label; 2000 } 2001 } 2002 2003 function renderMarketStatus(m, regionId){ 2004 if (!marketFreshness) return; 2005 2006 const age = marketExtractAge(m); 2007 2008 const freshAfter = 2009 Number(m && m.fresh_after_seconds); 2010 2011 const staleAfter = 2012 Number(m && m.stale_after_seconds); 2013 2014 if ( 2015 Number.isFinite(freshAfter) 2016 && freshAfter > 0 2017 ) { 2018 marketFreshAfter = freshAfter; 2019 } 2020 2021 if ( 2022 Number.isFinite(staleAfter) 2023 && staleAfter > marketFreshAfter 2024 ) { 2025 marketStaleAfter = staleAfter; 2026 } 2027 2028 marketAgeAtFetch = 2029 Number.isFinite(age) 2030 ? age 2031 : null; 2032 2033 marketAgeFetchedMs = Date.now(); 2034 2035 const option = 2036 hubSelect && 2037 hubSelect.options && 2038 hubSelect.selectedIndex >= 0 2039 ? hubSelect.options[hubSelect.selectedIndex] 2040 : null; 2041 2042 const hubLabel = 2043 option 2044 ? option.textContent.trim() 2045 : ('Region ' + String(regionId || '')); 2046 2047 const types = 2048 Number( 2049 m && ( 2050 m.types_priced ?? 2051 m.priced_types ?? 2052 m.type_count 2053 ) 2054 ); 2055 2056 const orders = 2057 Number( 2058 m && ( 2059 m.orders_kept ?? 2060 m.order_count ?? 2061 m.orders 2062 ) 2063 ); 2064 2065 const detail = []; 2066 2067 detail.push(hubLabel); 2068 2069 if (Number.isFinite(types) && types > 0) { 2070 detail.push(
2071 types.toLocaleString('en-US') 2072 + ' priced types' 2073 ); 2074 } 2075 2076 if (Number.isFinite(orders) && orders > 0) { 2077 detail.push( 2078 orders.toLocaleString('en-US') 2079 + ' orders' 2080 ); 2081 } 2082 2083 detail.push('Direct CCP ESI ingest'); 2084 detail.push('automatic refresh enabled'); 2085 2086 if (marketDetail) { 2087 marketDetail.textContent = detail.join(' ⢠'); 2088 } 2089 2090 marketRenderClock(); 2091 } 2092 2093 async function refreshMarketStatus(){ 2094 if (!hubSelect) return; 2095 2096 const regionId = 2097 String(hubSelect.value || '10000043'); 2098 2099 try { 2100 const u = new URL( 2101 '/api/market_status.php', 2102 window.location.origin 2103 ); 2104 2105 u.searchParams.set('region_id', regionId); 2106 2107 const res = await fetch( 2108 u.toString(), 2109 { 2110 credentials:'same-origin', 2111 cache:'no-store' 2112 } 2113 ); 2114 2115 const data = await res.json().catch(() => null); 2116 2117 if ( 2118 res.ok && 2119 data && 2120 data.ok && 2121 data.market 2122 ) { 2123 renderMarketStatus( 2124 data.market, 2125 regionId 2126 ); 2127 } 2128 2129 } catch (_) { 2130 // Keep the last known timer visible. 2131 } 2132 } 2133 2134 function showMsg(html, kind){ 2135 msg.style.display = ''; 2136 msg.className = 'notice' + (kind ? (' ' + kind) : ''); 2137 msg.innerHTML = html; 2138 } 2139 function hideMsg(){ 2140 msg.style.display = 'none'; 2141 msg.innerHTML = ''; 2142 } 2143 2144 function unresolvedIsNameFailure(r){ 2145 if (!r || !r.error) return false; 2146 if (!r.type_id) return true; 2147 return /no matching item types? found/i.test(String(r.error || '')); 2148 } 2149 2150 function unresolvedClose(){ 2151 if (!unresolvedOverlay) return; 2152 unresolvedOverlay.classList.remove('open'); 2153 unresolvedOverlay.setAttribute('aria-hidden', 'true'); 2154 unresolvedRows = []; 2155 const target = unresolvedReturnFocus; 2156 unresolvedReturnFocus = null; 2157 if (target && typeof target.focus === 'function') { try { target.focus(); } catch(_) {} } 2158 } 2159 2160 function unresolvedOpen(rows){ 2161 if (!unresolvedOverlay || !unresolvedList) return; 2162 unresolvedRows = Array.isArray(rows) ? rows.slice() : []; 2163 if (!unresolvedRows.length) return; 2164 unresolvedReturnFocus = document.activeElement; 2165 unresolvedList.innerHTML = ''; 2166 unresolvedRows.forEach(function(r){ 2167 const li = document.createElement('li'); 2168 li.className = 'pc-unresolved-item'; 2169 const label = String(r.input || r.query || r.item_name || 'Unresolved item'); 2170 const lineNo = Number(r.line || 0); 2171 const err = String(r.error || 'No matching EVE item type was found.'); 2172 li.innerHTML = '<strong>' + escapeHtml(label) + '</strong>' 2173 + '<div class="hint">' + (lineNo > 0 ? ('Pasted item #' + escapeHtml(String(lineNo)) + ' · ') : '') + escapeHtml(err) + '</div>'; 2174 unresolvedList.appendChild(li); 2175 }); 2176 if (unresolvedRemoveBtn) { 2177 unresolvedRemoveBtn.textContent = 'Remove ' + unresolvedRows.length + ' Unresolved ' + (unresolvedRows.length === 1 ? 'Item' : 'Items') + ' & Recheck'; 2178 } 2179 unresolvedOverlay.classList.add('open'); 2180 unresolvedOverlay.setAttribute('aria-hidden', 'false'); 2181 setTimeout(function(){ if (unresolvedRemoveBtn) unresolvedRemoveBtn.focus(); }, 0); 2182 } 2183 2184 function unresolvedRemoveFromTextarea(rows){ 2185 if (!taItems) return 0; 2186 const removeParsedIndexes = new Set(); 2187 (rows || []).forEach(function(r){ 2188 const n = Number(r && r.line || 0); 2189 if (Number.isInteger(n) && n > 0) removeParsedIndexes.add(n); 2190 }); 2191 if (!removeParsedIndexes.size) return 0; 2192 2193 const original = String(taItems.value || '').replace(/\r\n/g, '\n').replace(/\r/g, '\n'); 2194 const lines = original.split('\n'); 2195 let parsedIndex = 0; 2196 let removed = 0; 2197 const kept = []; 2198 lines.forEach(function(line){ 2199 // Mirrors Price Check's one-output-row-per-nonblank-input-line behavior. 2200 const probe = String(line || '').replace(/\u00a0/g, ' ').replace(/[\u200B-\u200D\uFEFF]/g, '').trim(); 2201 if (probe !== '') { 2202 parsedIndex += 1; 2203 if (removeParsedIndexes.has(parsedIndex)) { removed += 1; return; } 2204 } 2205 kept.push(line); 2206 }); 2207 taItems.value = kept.join('\n').replace(/^\n+|\n+$/g, ''); 2208 return removed; 2209 } 2210 2211 if (unresolvedManualBtn) unresolvedManualBtn.addEventListener('click', unresolvedClose); 2212 if (unresolvedXBtn) unresolvedXBtn.addEventListener('click', unresolvedClose); 2213 if (unresolvedOverlay) { 2214 unresolvedOverlay.addEventListener('click', function(e){ if (e.target === unresolvedOverlay) unresolvedClose(); }); 2215 } 2216 document.addEventListener('keydown', function(e){ 2217 if (e.key === 'Escape' && unresolvedOverlay && unresolvedOverlay.classList.contains('open')) unresolvedClose(); 2218 }); 2219 if (unresolvedRemoveBtn) { 2220 unresolvedRemoveBtn.addEventListener('click', function(){ 2221 const removed = unresolvedRemoveFromTextarea(unresolvedRows); 2222 unresolvedClose(); 2223 if (!removed) { 2224 showMsg('Could not safely match the unresolved lines back to the pasted list. Remove them manually and run Price Check again.', 'warn'); 2225 results.style.display = ''; 2226 return; 2227 } 2228 if (!taItems || !String(taItems.value || '').trim()) { 2229 clearTable(); 2230 totals.textContent = ''; 2231 meta.textContent = ''; 2232 showMsg('All pasted items were unresolved and have been removed. Paste another item list to continue.', 'w
2232arn'); 2233 results.style.display = ''; 2234 return; 2235 } 2236 run(); 2237 }); 2238 } 2239 2240 function setBusy(isBusy){ 2241 if (btnRun) btnRun.disabled = !!isBusy; 2242 if (btnClear) btnClear.disabled = !!isBusy; 2243 if (btnShare) btnShare.disabled = !!isBusy; 2244 if (showReprocessToggle) showReprocessToggle.disabled = !!isBusy; 2245 if (reprocessEffInput) reprocessEffInput.disabled = !!isBusy; 2246 if (btnRun) btnRun.textContent = isBusy ? 'Checkingâ¦' : 'Check Prices'; 2247 } 2248 2249 function clearTable(){ 2250 const tbody = table.querySelector('tbody'); 2251 tbody.innerHTML = ''; 2252 const intelSummary = document.getElementById('pcIntelSummary'); // CMS_PRICECHECK_PHASE2_CLEAR_SUMMARY 2253 if (intelSummary) { intelSummary.className = 'pc-intel-summary'; intelSummary.innerHTML = ''; } 2254 } 2255 2256 function getReprocessEff(){ 2257 let pct = Number(reprocessEffInput ? reprocessEffInput.value : 72); 2258 if (!Number.isFinite(pct)) pct = 72; 2259 pct = Math.max(0, Math.min(100, pct)); 2260 if (reprocessEffInput && Number(reprocessEffInput.value) !== pct) reprocessEffInput.value = String(pct); 2261 if (reprocessEffBadge) reprocessEffBadge.textContent = pct.toFixed(1).replace(/\.0$/,'') + '%'; 2262 return pct; 2263 } 2264 2265 2266 function syncRecycleVisibility(){ 2267 if (!table) return; 2268 2269 // Whole-appraisal reprocessing replaces the appraisal result itself. 2270 // Legacy per-row Reprocess controls/drawers are never exposed. 2271 table.querySelectorAll('.pc-reprocess-btn').forEach(function(btn){ 2272 btn.style.display = 'none'; 2273 }); 2274 2275 table.querySelectorAll('.pc-recycle-row').forEach(function(row){ 2276 row.style.display = 'none'; 2277 }); 2278 } 2279 2280 function rerenderAllRecycleBoxes(){ 2281 getReprocessEff(); 2282 if (!table) return; 2283 table.querySelectorAll('.pc-recycle').forEach(renderRecycleBox); 2284 syncRecycleVisibility(); 2285 } 2286 2287 if (showReprocessToggle) { 2288 showReprocessToggle.addEventListener('change', function(){ 2289 syncRecycleVisibility(); 2290 2291 // The checkbox is an appraisal MODE, not a per-row display option. 2292 // If there is pasted input, immediately rebuild the entire result set. 2293 if (taItems && taItems.value.trim()) { 2294 lastAppraisal = null; 2295 run(); 2296 } 2297 }); 2298 } 2299 2300 if (reprocessEffInput) { 2301 reprocessEffInput.addEventListener('input', function(){ 2302 getReprocessEff(); 2303 }); 2304 2305 reprocessEffInput.addEventListener('change', function(){ 2306 getReprocessEff(); 2307 syncRecycleVisibility(); 2308 2309 if ( 2310 showReprocessToggle 2311 && showReprocessToggle.checked 2312 && taItems 2313 && taItems.value.trim() 2314 ) { 2315 lastAppraisal = null; 2316 run(); 2317 } 2318 }); 2319 2320 getReprocessEff(); 2321 } 2322 2323 function reprocessSplitPrice(buy, sell){ 2324 buy = Number(buy); sell = Number(sell); 2325 buy = Number.isFinite(buy) && buy > 0 ? buy : 0; 2326 sell = Number.isFinite(sell) && sell > 0 ? sell : 0; 2327 if (buy > 0 && sell > 0) return (buy + sell) / 2; 2328 return buy > 0 ? buy : sell; 2329 } 2330 2331 function recycleHtml(recipe, lineQty){ 2332 if (!recipe || !Array.isArray(recipe.materials) || !recipe.materials.length) return ''; 2333 const portion = Math.max(1, Number(recipe.portion_size || 1)); 2334 const qty = Math.max(1, Number(lineQty || 1)); 2335 const intactBuy = Math.max(0, Number(recipe.amarr_buy_unit || 0)); 2336 const intactSell = Math.max(0, Number(recipe.amarr_sell_unit || 0)); 2337 const intactSplit = Math.max(0, Number(recipe.amarr_split_unit || reprocessSplitPrice(intactBuy, intactSell))); 2338 let html = '<details class="pc-recycle" data-line-qty="' + escapeHtml(String(qty)) + '" data-portion="' + escapeHtml(String(portion)) + '" data-intact-split="' + escapeHtml(String(intactSplit)) + '">'; 2339 html += '<summary><span>â» Recyclable / Reprocessable</span><span class="pc-recycle-summary-value">calculatingâ¦</span></summary>'; 2340 html += '<div class="pc-recycle-body">'; 2341 html += '<div class="pc-recycle-head"><div class="pc-recycle-note">Recovered value uses <strong>Amarr Split</strong> â the midpoint between Amarr max-buy and min-sell. Recovered quantities use the <strong>Reprocess entire appraisal</strong> set above and round down to whole units.</div></div>'; 2342 html += '<div class="pc-recycle-kpis">'; 2343 html += '<div class="pc-recycle-kpi"><div class="k">Intact Value · Split</div><div class="v pc-rp-intact">â</div></div>'; 2344 html += '<div class="pc-recycle-kpi"><div class="k">Recovered Value · Split</div><div class="v pc-rp-recovered-total">â</div></div>'; 2345 html += '<div class="pc-recycle-kpi pc-rp-delta-card"><div class="k">ISK Difference</div><div class="v pc-rp-delta">â</div></div>'; 2346 html += '<div class="pc-recycle-kpi pc-rp-pct-card"><div class="k">% Difference · Reprocessed vs Item</div><div class="v pc-rp-pct">â</div></div>'; 2347 html += '</div>'; 2348 html += '<div class="pc-recycle-tablewrap"><table class="pc-recycle-table"><thead><tr><th>
2348Output Material</th><th>Base Qty / Portion</th><th>Recovered Qty</th><th>Amarr Split / Unit</th><th>Recovered Value · Split</th></tr></thead><tbody>'; 2349 for (const mat of recipe.materials) { 2350 const baseQty = Math.max(0, Number(mat.quantity || 0)); 2351 const split = Math.max(0, Number(mat.amarr_split_unit || reprocessSplitPrice(mat.amarr_buy_unit, mat.amarr_sell_unit))); 2352 html += '<tr class="pc-rp-row" data-base-qty="' + escapeHtml(String(baseQty)) + '" data-split-unit="' + escapeHtml(String(split)) + '">'; 2353 html += '<td><strong>' + escapeHtml(String(mat.name || ('TypeID ' + String(mat.type_id || '')))) + '</strong><div class="hint">TypeID #' + escapeHtml(fmtInt(mat.type_id || 0)) + '</div></td>'; 2354 html += '<td>' + escapeHtml(fmtInt(baseQty)) + '</td><td class="pc-rp-qty">â</td><td class="pc-rp-unit">' + (split > 0 ? escapeHtml(fmtISK(split)) : 'â') + '</td><td class="pc-rp-value">â</td></tr>'; 2355 } 2356 html += '</tbody></table></div>'; 2357 html += '<div class="pc-recycle-foot">Comparison uses only full reprocessing portions. Any remainder stays intact and is excluded from both sides of the comparison. If only one Amarr market side is available, that price is used as the Split fallback.</div>'; 2358 html += '</div></details>'; 2359 return html; 2360 } 2361 2362 function renderRecycleBox(box){ 2363 if (!box) return; 2364 const pct = getReprocessEff(); 2365 2366 const lineQty = Math.max(0, Math.floor(Number(box.dataset.lineQty || 0))); 2367 const portion = Math.max(1, Math.floor(Number(box.dataset.portion || 1))); 2368 const fullPortions = Math.floor(lineQty / portion); 2369 const usedQty = fullPortions * portion; 2370 const remainder = Math.max(0, lineQty - usedQty); 2371 const intactSplitUnit = Math.max(0, Number(box.dataset.intactSplit || 0)); 2372 const intactValue = usedQty * intactSplitUnit; 2373 let recoveredTotal = 0; 2374 let pricedMaterials = 0; 2375 const materialRows = Array.from(box.querySelectorAll('.pc-rp-row')); 2376 const totalMaterials = materialRows.length; 2377 2378 materialRows.forEach(function(row){ 2379 const baseQty = Math.max(0, Number(row.dataset.baseQty || 0)); 2380 const splitUnit = Math.max(0, Number(row.dataset.splitUnit || 0)); 2381 const recoveredQty = Math.floor(baseQty * fullPortions * (pct / 100)); 2382 const recoveredValue = recoveredQty * splitUnit; 2383 if (splitUnit > 0) { recoveredTotal += recoveredValue; pricedMaterials++; } 2384 const q = row.querySelector('.pc-rp-qty'); 2385 const v = row.querySelector('.pc-rp-value'); 2386 if (q) q.textContent = fmtInt(recoveredQty); 2387 if (v) v.textContent = splitUnit > 0 ? fmtISK(recoveredValue) : 'â'; 2388 }); 2389 2390 const pricesComplete = totalMaterials > 0 && pricedMaterials === totalMaterials; 2391 const canCompare = fullPortions > 0 && intactSplitUnit > 0 && pricesComplete; 2392 const delta = recoveredTotal - intactValue; 2393 const pctDiff = canCompare ? (delta / intactValue) * 100 : null; 2394 const intactEl = box.querySelector('.pc-rp-intact'); 2395 const recoveredEl = box.querySelector('.pc-rp-recovered-total'); 2396 const deltaEl = box.querySelector('.pc-rp-delta'); 2397 const pctEl = box.querySelector('.pc-rp-pct'); 2398 const summary = box.querySelector('.pc-recycle-summary-value'); 2399 const deltaCard = box.querySelector('.pc-rp-delta-card'); 2400 const pctCard = box.querySelector('.pc-rp-pct-card'); 2401 2402 if (intactEl) intactEl.textContent = (fullPortions > 0 && intactSplitUnit > 0) ? fmtISK(intactValue) : 'â'; 2403 if (recoveredEl) recoveredEl.textContent = (fullPortions > 0 && pricesComplete) ? fmtISK(recoveredTotal) : 'â'; 2404 if (deltaEl) deltaEl.textContent = canCompare ? ((delta > 0 ? '+' : '') + fmtISK(delta)) : 'â'; 2405 if (pctEl) pctEl.textContent = pctDiff === null ? 'â' : ((pctDiff > 0 ? '+' : '') + pctDiff.toFixed(2) + '%'); 2406 [deltaCard,pctCard].forEach(function(card){ if(card) card.classList.remove('positive','negative'); }); 2407 box.classList.remove('positive','negative'); 2408 if (canCompare && delta > 0) { 2409 if(deltaCard) deltaCard.classList.add('positive'); 2410 if(pctCard) pctCard.classList.add('positive'); 2411 box.classList.add('positive'); 2412 } 2413 if (canCompare && delta < 0) { 2414 if(deltaCard) deltaCard.classList.add('negative'); 2415 if(pctCard) pctCard.classList.add('negative'); 2416 box.classList.add('negative'); 2417 } 2418 2419 if (summary) { 2420 if (fullPortions <= 0) summary.textContent = pct.toFixed(1).replace(/\.0$/,'') + '% · need ' + fmtInt(porti
2420on) + ' per portion'; 2421 else if (pctDiff !== null) summary.textContent = pct.toFixed(1).replace(/\.0$/,'') + '% · ' + (pctDiff > 0 ? '+' : '') + pctDiff.toFixed(2) + '% vs intact' + (remainder > 0 ? ' · ' + fmtInt(remainder) + ' remainder' : ''); 2422 else summary.textContent = pct.toFixed(1).replace(/\.0$/,'') + '% · Amarr Split pricing incomplete'; 2423 } 2424 } 2425 2426 // CMS_PRICECHECK_RECYCLE_ROW_RESTORE_V2 2427 // Exact helper restored from the known-good pre-Split backup. 2428 2429 function buildRecycleRow(r){ 2430 const html = recycleHtml( 2431 r && r.reprocessing ? r.reprocessing : null, 2432 Number((r && r.qty) || 1) 2433 ); 2434 if (!html) return null; 2435 2436 const tr = document.createElement('tr'); 2437 tr.className = 'pc-recycle-row'; 2438 tr.dataset.drawerKind = 'reprocess'; 2439 tr.style.display = 'none'; 2440 2441 const td = document.createElement('td'); 2442 td.colSpan = 7; 2443 td.innerHTML = html; 2444 2445 tr.appendChild(td); 2446 return tr; 2447 } 2448 2449 2450 2451 function buildRow(r, adjPct){ 2452 const tr = document.createElement('tr'); 2453 tr.className = 'pc-price-row'; 2454 2455 const tdItem = document.createElement('td'); 2456 const tdQty = document.createElement('td'); 2457 const tdBuy = document.createElement('td'); 2458 const tdSell = document.createElement('td'); 2459 const tdBuyTotal = document.createElement('td'); 2460 const tdSellTotal = document.createElement('td'); 2461 const tdActions = document.createElement('td'); 2462 2463 tdItem.className = 'pc-item-cell'; 2464 tdQty.className = 'pc-num'; 2465 tdBuy.className = 'pc-num'; 2466 tdSell.className = 'pc-num'; 2467 tdBuyTotal.className = 'pc-num'; 2468 tdSellTotal.className = 'pc-num'; 2469 tdActions.className = 'pc-actions-cell'; 2470 2471 const qty = Math.max(1, Number(r.qty || 1)); 2472 const factor = 1 + (clampPct(adjPct) / 100); 2473 2474 const minSell = 2475 (r.min_sell !== null && typeof r.min_sell !== 'undefined') 2476 ? Number(r.min_sell) 2477 : NaN; 2478 2479 const maxBuy = 2480 (r.max_buy !== null && typeof r.max_buy !== 'undefined') 2481 ? Number(r.max_buy) 2482 : NaN; 2483 2484 if (r.error) { 2485 tdItem.innerHTML = 2486 '<strong>' + escapeHtml(r.name || r.input || 'Unknown') + '</strong>' 2487 + '<div class="hint" style="margin-top:4px">' 2488 + escapeHtml(r.error) 2489 + '</div>'; 2490 2491 tdQty.textContent = fmtInt(qty); 2492 tdBuy.textContent = 'â'; 2493 tdSell.textContent = 'â'; 2494 tdBuyTotal.textContent = 'â'; 2495 tdSellTotal.textContent = 'â'; 2496 tdActions.innerHTML = 2497 '<button type="button" class="btn ghost pc-row-action pc-market-btn high" disabled>' 2498 + '<span class="pc-market-confidence">ERROR</span>' 2499 + '</button>'; 2500 2501 tr.style.opacity = '0.82'; 2502 2503 } else { 2504 const nm = r.item_name || r.name || r.input || ''; 2505 const maxBuyAdj = Number.isFinite(maxBuy) ? maxBuy * factor : NaN; 2506 const minSellAdj = Number.isFinite(minSell) ? minSell * factor : NaN; 2507 const splitAdj = 2508 Number.isFinite(maxBuyAdj) && Number.isFinite(minSellAdj) 2509 ? (maxBuyAdj + minSellAdj) / 2 2510 : NaN; 2511 2512 const iSell = r.immediate_sell && typeof r.immediate_sell === 'object' 2513 ? r.immediate_sell 2514 : null; 2515 2516 const iBuy = r.immediate_buy && typeof r.immediate_buy === 'object' 2517 ? r.immediate_buy 2518 : null; 2519 2520 const iSellAvg = 2521 iSell && Number.isFinite(Number(iSell.average)) 2522 ? Number(iSell.average) * factor 2523 : NaN; 2524 2525 const iBuyAvg = 2526 iBuy && Number.isFinite(Number(iBuy.average)) 2527 ? Number(iBuy.average) * factor 2528 : NaN; 2529 2530 const iSellFill = iSell ? Number(iSell.fill_pct || 0) : 0; 2531 const iBuyFill = iBuy ? Number(iBuy.fill_pct || 0) : 0; 2532 2533 // CMS_PRICECHECK_PHASE3_ITEM_LINK 2534 const marketItemUrl = r.type_id ? ('/eve-market/?type_id=' + encodeURIComponent(r.type_id)) : ''; 2535 tdItem.innerHTML = 2536 (marketItemUrl 2537 ? '<strong><a href="' + marketItemUrl + '" title="Open item market page">' + escapeHtml(nm) + '</a></strong>' 2538 : '<strong>' + escapeHtml(nm) + '</strong>') 2539 + '<div class="pc-advanced-inline">' 2540 + 'Immediate Sell: <strong>' + escapeHtml(fmtISK(iSellAvg)) + '</strong>' 2541 + ' · ' + escapeHtml(iSellFill.toFixed(1)) + '%' 2542 + ' | Split: <strong>' + escapeHtml(fmtISK(splitAdj)) + '</strong>' 2543 + ' | Immediate Buy: <strong>' + escapeHtml(fmtISK(iBuyAvg)) + '</strong>' 2544 + ' · ' + escapeHtml(iBuyFill.toFixed(1)) + '%' 2545 + '</div>'; 2546 2547 const iSellLine = iSell && Number.isFinite(Number(iSell.line_total)) 2548 ? Number(iSell.line_total) * factor 2549 : NaN; 2550 const iBuyLine = iBuy && Number.isFinite(Number(iBuy.line_total)) 2551 ? Number(iBuy.line_total) * factor 2552 : NaN; 2553 2554 // Basic columns are quantity-aware: what this exact line can execute for 2555 // now, not max-buy/min-sell multiplied beyond available order depth. 2556 tdQty.textContent = fmtInt(qty); 2557 tdBuy.textContent = fmtISK(Number.isFinite(iSellAvg) ? iSellAvg : maxBuyAdj); 2558 tdSell.textContent = fmtISK(Number.isFinite(iBuyAvg) ? iBuyAvg : minSellAdj); 2559 tdBuyTotal.textContent = fmtISK(Number.isFinite(iSellLine) ? iSellLine : ((Number.isFinite(maxBuyAdj) ? maxBuyAdj : 0) * qty)); 2560 tdSellTotal.textContent = fmtISK(Number.isFinite(iBuyLine) ? iBuyLine : ((Number.isFinite(minSellAdj) ? minSellAdj : 0) * qty)); 2561 2562 const actions = []; 2563 2564 if (r.market_intelligence && typeof r.market_intelligence === 'object') { 2565 const intel = r.market_intelligence;
2566 const warnings = Array.isArray(intel.warnings) ? intel.warnings : []; 2567 const conf = intel.confidence || {}; 2568 const current = intel.current || {}; 2569 2570 const confidenceLabel = String(conf.label || 'â'); 2571 const confidenceScore = Number(conf.score || 0); 2572 const spread = Number(current.spread_pct); 2573 const warningCount = warnings.length; 2574 2575 const highCount = warnings.filter(function(w){ 2576 return String((w && w.severity) || '').toLowerCase() === 'high'; 2577 }).length; 2578 2579 const warningSeverity = 2580 highCount > 0 || confidenceLabel.toLowerCase() === 'low' 2581 ? 'high' 2582 : ( 2583 warningCount > 0 || confidenceLabel.toLowerCase() === 'moderate' 2584 ? 'warning' 2585 : 'good' 2586 ); 2587 2588 const spreadText = 2589 Number.isFinite(spread) 2590 ? spread.toFixed(1) + '%' 2591 : 'â'; 2592 2593 const noticeText = 2594 highCount > 0 2595 ? String(highCount) + '!' 2596 : String(warningCount); 2597 2598 const titleBits = [ 2599 'Confidence ' + confidenceLabel + ' ' + confidenceScore + '/100', 2600 'Spread ' + spreadText, 2601 warningCount + ' notice' + (warningCount === 1 ? '' : 's') 2602 ]; 2603 2604 if (highCount > 0) { 2605 titleBits.push(highCount + ' high-priority'); 2606 } 2607 2608 actions.push( 2609 '<button type="button"' 2610 + ' class="btn ghost pc-row-action pc-market-btn ' + warningSeverity + '"' 2611 + ' data-pc-action="intel"' 2612 + ' title="' + escapeHtml(titleBits.join(' · ')) + '">' 2613 + '<span class="pc-market-confidence">' + escapeHtml(confidenceLabel.toUpperCase()) + '</span>' 2614 + '<span class="pc-market-spread">' + escapeHtml(spreadText) + '</span>' 2615 + '<span class="pc-market-notices">' + escapeHtml(noticeText) + '</span>' 2616 + '</button>' 2617 ); 2618 } else { 2619 actions.push( 2620 '<button type="button" class="btn ghost pc-row-action pc-market-btn none" disabled>' 2621 + '<span class="pc-market-confidence">NO DATA</span>' 2622 + '</button>' 2623 ); 2624 } 2625 2626 if ( 2627 r.reprocessing 2628 && Array.isArray(r.reprocessing.materials) 2629 && r.reprocessing.materials.length 2630 ) { 2631 actions.push( 2632 '<button type="button"' 2633 + ' class="btn ghost pc-row-action pc-reprocess-btn"' 2634 + ' data-pc-action="reprocess"' 2635 + ' style="display:none">' 2636 + 'â» Reprocess' 2637 + '</button>' 2638 ); 2639 } 2640 2641 tdActions.innerHTML = 2642 '<div class="pc-row-actions">' 2643 + actions.join('') 2644 + '</div>'; 2645 } 2646 2647 tr.appendChild(tdItem); 2648 tr.appendChild(tdQty); 2649 tr.appendChild(tdBuy); 2650 tr.appendChild(tdSell); 2651 tr.appendChild(tdBuyTotal); 2652 tr.appendChild(tdSellTotal); 2653 tr.appendChild(tdActions); 2654 2655 return tr; 2656 } 2657 2658 2659 // CMS_PRICECHECK_PHASE2_INTELLIGENCE_JS 2660 function intelNum(v){ 2661 const n = Number(v); 2662 return Number.isFinite(n) ? n : null; 2663 } 2664 2665 function intelPct(v){ 2666 const n = intelNum(v); 2667 if (n === null) return 'Building'; 2668 const sign = n > 0 ? '+' : ''; 2669 return sign + n.toFixed(Math.abs(n) >= 100 ? 0 : 1) + '%'; 2670 } 2671 2672 function intelPctClass(v){ 2673 const n = intelNum(v); 2674 if (n === null || Math.abs(n) < 0.0001) return ''; 2675 return n > 0 ? 'up' : 'down'; 2676 } 2677 2678 function intelSparkline(series, factor){ 2679 const rows = Array.isArray(series) ? series : []; 2680 const points = rows 2681 .map(function(p){
2682 const v = intelNum(p && p.split); 2683 return v !== null && v > 0 ? {date:String(p.date || ''), value:v * factor} : null; 2684 }) 2685 .filter(Boolean); 2686 2687 if (points.length < 2) { 2688 return '<div class="pc-intel-history-note">Daily history is still building. The chart appears after at least two daily samples exist.</div>'; 2689 } 2690 2691 const vals = points.map(p => p.value); 2692 let lo = Math.min.apply(null, vals); 2693 let hi = Math.max.apply(null, vals); 2694 if (!(hi > lo)) { hi = lo + 1; } 2695 2696 const w = 260; 2697 const h = 48; 2698 const pad = 3; 2699 const coords = points.map(function(p, i){ 2700 const x = pad + ((w - pad * 2) * (i / Math.max(1, points.length - 1))); 2701 const y = pad + ((h - pad * 2) * (1 - ((p.value - lo) / (hi - lo)))); 2702 return x.toFixed(1) + ',' + y.toFixed(1); 2703 }).join(' '); 2704 2705 const title = escapeHtml(points[0].date + ' ââ â ' + points[points.length - 1].date); 2706 2707 return '<svg class="pc-sparkline" viewBox="0 0 '+w+' '+h+'" role="img" aria-label="Split price history '+title+'">' 2708 + '<line class="pc-sparkline-grid" x1="3" y1="24" x2="257" y2="24"></line>' 2709 + '<polyline class="pc-sparkline-line" points="'+coords+'"></polyline>' 2710 + '</svg>' 2711 + '<div class="pc-intel-history-note">' 2712 + escapeHtml(points.length + ' daily samples ââ¬Â¢ ' + points[0].date + ' ââ â ' + points[points.length - 1].date) 2713 + '</div>'; 2714 } 2715 2716 2717 function buildIntelRow(r, adjPct){ 2718 const intel = r && r.market_intelligence; 2719 if (!intel || typeof intel !== 'object') return null; 2720 2721 const tr = document.createElement('tr'); 2722 tr.className = 'pc-intel-row'; 2723 tr.dataset.drawerKind = 'intel'; 2724 tr.style.display = 'none'; 2725 2726 const td = document.createElement('td'); 2727 td.colSpan = 7; 2728 2729 const factor = 1 + (clampPct(adjPct) / 100); 2730 const hist = intel.history || {}; 2731 const depth = intel.depth || {}; 2732 const liq = intel.liquidity || {}; 2733 const conf = intel.confidence || {}; 2734 const warnings = Array.isArray(intel.warnings) ? intel.warnings : []; 2735 2736 const median = intelNum(hist.median_30d); 2737 const spread = intelNum((intel.current || {}).spread_pct);
2738 const sellImpact = intelNum(liq.immediate_sell_impact_pct); 2739 const buyImpact = intelNum(liq.immediate_buy_impact_pct); 2740 const samples = Number(hist.samples || 0); 2741 const daysCovered = Number(hist.days_covered || 0); 2742 const change1 = intelNum(hist.change_1d_pct); 2743 const change7 = intelNum(hist.change_7d_pct); 2744 const change30 = intelNum(hist.change_30d_pct); 2745 const confidenceLabel = String(conf.label || 'â'); 2746 const confidenceScore = Number(conf.score || 0); 2747 2748 const warningHtml = warnings.length 2749 ? '<div class="pc-detail-warnings">' + warnings.map(function(w){ 2750 const sev = (w && w.severity === 'high') ? ' high' : ''; 2751 return '<div class="pc-detail-warning'+sev+'"><strong>' 2752 + escapeHtml(String(w.title || 'Market notice')) 2753 + '</strong>' 2754 + escapeHtml(String(w.message || '')) 2755 + '</div>'; 2756 }).join('') + '</div>' 2757 : '<div class="pc-detail-ok">No material warning thresholds are currently triggered.</div>'; 2758 2759 const historyNote = samples < 2 2760 ? 'History is still building. Longer change windows appear only after enough real daily samples exist.' 2761 : ('History coverage: ' + daysCovered + ' day' + (daysCovered === 1 ? '' : 's') + '.'); 2762 2763 td.innerHTML = 2764 '<section class="pc-detail-drawer">'+ 2765 '<div class="pc-detail-head">'+ 2766 '<div>'+ 2767 '<div class="pc-detail-title">Market Intelligence · '+escapeHtml(String(r.item_name || r.name || r.input || 'Item'))+'</div>'+ 2768 '<div class="pc-detail-sub">Advanced market data is shown only when requested.</div>'+ 2769 '</div>'+ 2770 '<button type="button" class="btn ghost pc-row-action" data-pc-action="close-drawer">Close</button>'+ 2771 '</div>'+ 2772 '<div class="pc-detail-kpis">'+ 2773 '<div class="pc-detail-kpi"><div class="k">Quote Confidence</div><div class="v">'+escapeHtml(confidenceLabel)+' · '+escapeHtml(String(confidenceScore))+'/100</div></div>'+ 2774 '<div class="pc-detail-kpi"><div class="k">Spread</div><div class="v">'+escapeHtml(spread !== null ? spread.toFixed(1)+'%' : 'â')+'</div></div>'+ 2775 '<div class="pc-detail-kpi"><div class="k">30D Median</div><div class="v">'+escapeHtml(median !== null ? fmtISK(median * factor) : 'Building')+'</div></div>'+ 2776 '<div class="pc-detail-kpi"><div class="k">History</div><div class="v">'+escapeHtml(String(samples))+' daily</div></div>'+ 2777 '</div>'+ 2778 '<div class="pc-detail-grid">'+ 2779 '<div class="pc-detail-panel">'+ 2780 '<div class="pc-detail-panel-title">Price History</div>'+ 2781 '<div class="pc-detail-kpis" style="grid-template-columns:repeat(3,minmax(0,1fr));margin-bottom:7px">'+ 2782 '<div class="pc-detail-kpi"><div class="k">1D</div><div class="v '+intelPctClass(change1)+'">'+escapeHtml(intelPct(change1))+'</div></div>'+ 2783 '<div class="pc-detail-kpi"><div class="k">7D</div><div class="v '+intelPctClass(change7)+'">'+escapeHtml(intelPct(change7))+'</div></div>'+ 2784 '<div class="pc-detail-kpi"><div class="k">30D</div><div class="v '+intelPctClass(change30)+'">'+escapeHtml(intelPct(change30))+'</div></div>'+ 2785 '</div>'+ 2786 intelSparkline(hist.series || [], factor)+ 2787 '<div class="pc-intel-history-note">'+escapeHtml(historyNote)+'</div>'+ 2788 '</div>'+ 2789 '<div class="pc-detail-panel">'+ 2790 '<div class="pc-detail-panel-title">Depth & Market Impact</div>'+ 2791 '<div class="pc-detail-depth">'+ 2792 '<div><span>1% Buy VWAP</span><strong>'+escapeHtml(intelNum(depth.buy_vwap_1pct)!==null ? fmtISK(Number(depth.buy_vwap_1pct)*factor) : 'â')+'</strong></div>'+ 2793 '<div><span>1% Buy Depth</span><strong>'+escapeHtml(fmtInt(Number(depth.buy_depth_1pct || 0)))+'</strong></div>'+ 2794 '<div><span>5% Buy VWAP</span><strong>'+escapeHtml(intelNum(depth.buy_vwap_5pct)!==null ? fmtISK(Number(depth.buy_vwap_5pct)*factor) : 'â')+'</strong></div>'+ 2795 '<div><span>5% Buy Depth</span><strong>
2795'+escapeHtml(fmtInt(Number(depth.buy_depth_5pct || 0)))+'</strong></div>'+ 2796 '<div><span>1% Sell VWAP</span><strong>'+escapeHtml(intelNum(depth.sell_vwap_1pct)!==null ? fmtISK(Number(depth.sell_vwap_1pct)*factor) : 'â')+'</strong></div>'+ 2797 '<div><span>1% Sell Depth</span><strong>'+escapeHtml(fmtInt(Number(depth.sell_depth_1pct || 0)))+'</strong></div>'+ 2798 '<div><span>5% Sell VWAP</span><strong>'+escapeHtml(intelNum(depth.sell_vwap_5pct)!==null ? fmtISK(Number(depth.sell_vwap_5pct)*factor) : 'â')+'</strong></div>'+ 2799 '<div><span>5% Sell Depth</span><strong>'+escapeHtml(fmtInt(Number(depth.sell_depth_5pct || 0)))+'</strong></div>'+ 2800 '<div><span>Immediate Sell Impact</span><strong>'+escapeHtml(sellImpact !== null ? sellImpact.toFixed(1)+'%' : 'â')+'</strong></div>'+ 2801 '<div><span>Immediate Buy Impact</span><strong>'+escapeHtml(buyImpact !== null ? buyImpact.toFixed(1)+'%' : 'â')+'</strong></div>'+ 2802 '</div>'+ 2803 '</div>'+ 2804 '</div>'+ 2805 warningHtml+ 2806 '<div class="pc-intel-history-note">Warnings describe measurable market conditions; they are not claims of manipulation.</div>'+ 2807 '</section>'; 2808 2809 tr.appendChild(td); 2810 return tr; 2811 } 2812 2813 2814 function renderIntelSummary(data){ 2815 const el = document.getElementById('pcIntelSummary'); 2816 const btn = document.getElementById('pcHealthToggle'); 2817 if (!el) return; 2818 2819 const summary = data && data.intelligence_summary ? data.intelligence_summary : null; 2820 if (!summary || !Number(summary.items_analyzed || 0)) { 2821 el.className = 'pc-intel-summary'; 2822 el.innerHTML = ''; 2823 if (btn) { 2824 btn.textContent = 'Market Health'; 2825 btn.classList.remove('notice', 'high'); 2826 } 2827 return; 2828 } 2829 2830 const analyzed = Number(summary.items_analyzed || 0); 2831 const warnings = Number(summary.warnings || 0); 2832 const high = Number(summary.high_warnings || 0); 2833 const ready7 = Number(summary.history_7d_ready_items || 0); 2834 const ready30 = Number(summary.history_30d_ready_items || 0); 2835 const conf = summary.confidence || {}; 2836 2837 el.className = 'pc-intel-summary show'; 2838 el.innerHTML = 2839 '<div class="pc-intel-summary-head">' 2840 + '<div><div class="pc-intel-summary-title">Market Health</div><div class="hint">Summary only â open an item Details drawer for depth, history, and notices.</div></div>' 2841 + '</div>' 2842 + '<div class="pc-intel-summary-bits">' 2843 + '<span class="pc-intel-chip">'+escapeHtml(String(analyzed))+' analyzed</span>' 2844 + '<span class="pc-intel-chip">Confidence '+escapeHtml(String(conf.High || 0))+' high · '+escapeHtml(String(conf.Moderate || 0))+' moderate · '+escapeHtml(String(conf.Low || 0))+' low</span>' 2845 + '<span class="pc-intel-chip'+(high ? ' high' : (warnings ? ' warning' : ''))+'">'+escapeHtml(String(warnings))+' notice'+(warnings===1?'':'s')+'</span>' 2846 + '<span class="pc-intel-chip">7D ready '+escapeHtml(String(ready7))+'</span>' 2847 + '<span class="pc-intel-chip">30D ready '+escapeHtml(String(ready30))+'</span>' 2848 + '</div>'; 2849 2850 if (btn) { 2851 btn.textContent = warnings ? ('Market Health · ' + warnings) : 'Market Health'; 2852 btn.classList.toggle('notice', warnings > 0 && high < 1); 2853 btn.classList.toggle('high', high > 0); 2854 } 2855 } 2856 2857 2858 // CMS_PRICECHECK_UXV2_JS 2859 const pcAdvancedToggle = document.getElementById('pcAdvancedToggle'); 2860 const pcHealthToggle = document.getElementById('pcHealthToggle'); 2861 2862 function pcSetAdvanced(on){ 2863 if (!results) return; 2864 results.classList.toggle('pc-advanced-on', !!on); 2865 if (pcAdvancedToggle) { 2866 pcAdvancedToggle.classList.toggle('active', !!on); 2867 pcAdvancedToggle.setAttribute('aria-pressed', on ? 'true' : 'false'); 2868 pcAdvancedToggle.textContent = on ? 'Basic Pricing' : 'Advanced Pricing'; 2869 } 2870 } 2871 2872 function pcSetHealth(open){ 2873 if (!results) return; 2874 results.classList.toggle('pc-health-open', !!open); 2875 if (pcHealthToggle) { 2876 pcHealthToggle.classList.toggle('active', !!open); 2877 pcHealthToggle.setAttribute('aria-pressed', open ? 'true' : 'false'); 2878 } 2879 } 2880 2881 pcSetAdvanced(false); 2882 pcSetHealth(false); 2883 2884 if (pcAdvancedToggle) { 2885 pcAdvancedToggle.addEventListener('click', function(){ 2886 pcSetAdvanced(!results.classList.contains('pc-advanced-on')); 2887 }); 2888 } 2889 2890 if (pcHealthToggle) { 2891 pcHealthToggle.addEventListener('click', function(){ 2892 pcSetHealth(!results.classList.contains('pc-health-open')); 2893 }); 2894 } 2895 2896 function pcCloseAllDrawers(exceptRow){ 2897 if (!table) return; 2898 table.querySelectorAll('.pc-intel-row, .pc-recycle-row').forEach(function(row){ 2899 if (row !== exceptRow) row.style.display = 'none'; 2900 });
2901 table.querySelectorAll('.pc-price-row').forEach(function(row){ 2902 row.classList.remove('pc-row-open'); 2903 }); 2904 } 2905 2906 function pcFindDrawer(priceRow, kind){ 2907 let row = priceRow ? priceRow.nextElementSibling : null; 2908 while (row && !row.classList.contains('pc-price-row')) { 2909 if (row.dataset && row.dataset.drawerKind === kind) return row; 2910 row = row.nextElementSibling; 2911 } 2912 return null; 2913 } 2914 2915 if (table && !table.dataset.uxv2Bound) { 2916 table.dataset.uxv2Bound = '1'; 2917 table.addEventListener('click', function(e){ 2918 const btn = e.target.closest('[data-pc-action]'); 2919 if (!btn) return; 2920 const action = String(btn.dataset.pcAction || ''); 2921 2922 if (action === 'close-drawer') { 2923 const drawerRow = btn.closest('tr'); 2924 if (drawerRow) { 2925 drawerRow.style.display = 'none'; 2926 2927 let prev = drawerRow.previousElementSibling; 2928 while (prev && !prev.classList.contains('pc-price-row')) { 2929 prev = prev.previousElementSibling; 2930 } 2931 if (prev) prev.classList.remove('pc-row-open'); 2932 } 2933 return; 2934 } 2935 2936 const priceRow = btn.closest('.pc-price-row'); 2937 if (!priceRow) return; 2938 2939 if (action === 'intel' || action === 'reprocess') { 2940 const target = pcFindDrawer(priceRow, action === 'intel' ? 'intel' : 'reprocess'); 2941 if (!target) return; 2942 const opening = target.style.display === 'none' || !target.style.display; 2943 pcCloseAllDrawers(opening ? target : null); 2944 target.style.display = opening ? 'table-row' : 'none'; // CMS_PRICECHECK_UXV2_DRAWER_FIX 2945 priceRow.classList.toggle('pc-row-open', opening); 2946 2947 if (opening && action === 'reprocess') { 2948 const details = target.querySelector('details.pc-recycle'); 2949 if (details) { 2950 details.open = true;
2951 try { renderRecycleBox(details); } catch(_) {} 2952 } 2953 } 2954 2955 if (opening) { 2956 try { pcApplyNegativeColors(target); } catch(_) {} 2957 target.scrollIntoView({block:'nearest', behavior:'smooth'}); 2958 } 2959 } 2960 }); 2961 } 2962 2963 2964 // CMS_PRICECHECK_UXV2_NEGATIVE_JS 2965 function pcApplyNegativeColors(root){ 2966 const scope = root || document; 2967 2968 const selector = [ 2969 '.pc-num', 2970 '.pc-totalhero .v', 2971 '.pc-advanced-total .v', 2972 '.pc-detail-kpi .v', 2973 '.pc-detail-depth strong', 2974 '.pc-intel-kpi .v', 2975 '.pc-recycle-kpi .v', 2976 '.pc-recycle-summary-value', 2977 '.pc-advanced-inline strong', 2978 '.hubbadge .h-val', 2979 '.hubbadge .pc-hub-advanced span:last-child' 2980 ].join(','); 2981 2982 scope.querySelectorAll(selector).forEach(function(el){ 2983 const text = String(el.textContent || '') 2984 .replace(/\u2212/g, '-') 2985 .trim(); 2986 2987 const negative = 2988 /^-\s*(?:[$â¬Â£Â¥]\s*)?[\d,.]+/.test(text) 2989 || /^-\s*[\d,.]+\s*(?:ISK|%|m³|B|M|K)?\b/i.test(text); 2990 2991 el.classList.toggle('pc-negative', negative); 2992 }); 2993 } 2994 2995 function escapeHtml(s){ 2996 return String(s) 2997 .replaceAll('&', '&') 2998 .replaceAll('<', '<') 2999 .replaceAll('>', '>') 3000 .replaceAll('"', '"') 3001 .replaceAll("'", '''); 3002 } 3003 3004 3005 async function copyToClipboard(text){ 3006 const t = String(text || ''); 3007 if (!t) return false; 3008 try { 3009 await navigator.clipboard.writeText(t); 3010 return true; 3011 } catch (e) { 3012 try { 3013 const ta = document.createElement('textarea'); 3014 ta.value = t; 3015 ta.setAttribute('readonly', ''); 3016 ta.style.position = 'fixed'; 3017 ta.style.left = '-9999px'; 3018 document.body.appendChild(ta); 3019 ta.select(); 3020 ta.setSelectionRange(0, ta.value.length); 3021 const ok = document.execCommand('copy'); 3022 document.body.removeChild(ta); 3023 return !!ok; 3024 } catch(_) { 3025 return false; 3026 } 3027 } 3028 } 3029 3030 function flashCopied(btn){ 3031 if (!btn) return; 3032 const old = btn.textContent; 3033 btn.textContent = 'â'; 3034 btn.disabled = true; 3035 setTimeout(()=>{ btn.textContent = old; btn.disabled = false; }, 900); 3036 } 3037 3038 if (totals && !totals.dataset.copyBound) { 3039 totals.dataset.copyBound = '1'; 3040 totals.addEventListener('click', async function(e){ 3041 const b = e.target && e.target.closest ? e.target.closest('button[data-copy]') : null; 3042 if (!b) return; 3043 const which = b.getAttribute('data-copy') || ''; 3044 let spanId = 'pcBuyTotal'; 3045 if (which === 'immediate-sell') spanId = 'pcImmediateSellTotal'; 3046 if (which === 'split') spanId = 'pcSplitTotal'; 3047 if (which === 'immediate-buy') spanId = 'pcImmediateBuyTotal'; 3048 if (which === 'sell') spanId = 'pcSellTotal'; 3049 const span = document.getElementById(spanId); 3050 const val = span ? span.textContent.trim() : ''; 3051 const ok = await copyToClipboard(val); 3052 flashCopied(b); 3053 if (!ok) { 3054 showMsg('Could not copy automatically. Your browser may block clipboard access here.', 'warn'); 3055 results.style.display = ''; 3056 setTimeout(()=>{ hideMsg(); }, 1600); 3057 } 3058 }); 3059 } 3060 3061 async function run(){ 3062 hideMsg(); 3063 clearTable(); 3064 3065 const fd = new FormData(form); 3066 const items = (fd.get('items') || '').toString(); 3067 const regionId = (fd.get('region_id') || '10000043').toString(); 3068 const csrf = (fd.get('csrf') || '').toString(); 3069 const reprocessRequested = !!(showReprocessToggle && showReprocessToggle.checked); 3070 const reprocessEfficiency = getReprocessEff(); // CMS_PRICECHECK_REPROCESS_APPRAISAL_UI_V1 3071 3072 if (!items.trim()) { 3073 showMsg('Paste at least one item name.', 'warn'); 3074 results.style.display = ''; 3075 return; 3076 } 3077 3078 results.style.display = ''; 3079 meta.textContent = ''; 3080 totals.textContent = ''; 3081 showMsg(reprocessRequested ? 'Working⦠reprocessing the entire appraisal and pricing recovered outputs.' : 'Working⦠resolving names + fetching market stats.', ''); 3082 3083 setBusy(true); 3084 3085 try { 3086 const body = new URLSearchParams({ 3087 items: items, 3088 region_id: regionId, 3089 csrf: csrf, 3090 }); 3091 3092 if (reprocessRequested) { 3093 body.set('reprocess_mode', '1');
3094 body.set('reprocess_efficiency', String(reprocessEfficiency)); 3095 } 3096 3097 const res = await fetch('/api/pricecheck.php', { 3098 method: 'POST', 3099 headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, 3100 body: body.toString(), 3101 credentials: 'same-origin' 3102 }); 3103 3104 const data = await res.json().catch(()=>null); 3105 if (!res.ok || !data || !data.ok) { 3106 const emsg = (data && data.error) ? data.error : ('HTTP ' + res.status); 3107 showMsg('<strong>Error:</strong> ' + escapeHtml(emsg), 'danger'); 3108 return; 3109 } 3110 3111 hideMsg(); 3112 3113 if (data.market) { 3114 renderMarketStatus( 3115 data.market, 3116 regionId 3117 ); 3118 } 3119 3120 const adjPct = getAdjPct(); 3121 3122 const regionName = data.region_name || ('Region ' + regionId); 3123 const ts = data.ts || ''; 3124 meta.textContent = regionName 3125 + (adjPct ? (' ⢠Buyback ' + (adjPct>0?'+':'') + adjPct + '%') : '') 3126 + (ts ? (' ⢠' + ts.replace('T',' ').replace('Z',' UTC')) : ''); 3127 3128 const reprocessMeta = data.reprocessing_mode && data.reprocessing_mode.active 3129 ? data.reprocessing_mode 3130 : null; 3131 3132 if (reprocessMeta && meta) { 3133 meta.textContent += 3134 ' ⢠⻠Reprocessed ' + Number(reprocessMeta.efficiency_pct || reprocessEfficiency).toFixed(1).replace(/\.0$/, '') + '%' 3135 + ' ⢠' + String(reprocessMeta.source_lines || 0) + ' source lines â ' 3136 + String(reprocessMeta.final_types || 0) + ' final item types'; 3137 } 3138 3139 const t = data.totals || {}; 3140 const factor = 1 + (adjPct / 100); 3141 3142 const buyRaw = Number(t.buy_total || 0); 3143 const sellRaw = Number(t.sell_total || 0); 3144 3145 const splitRaw = 3146 Number.isFinite(Number(t.split_total)) 3147 ? Number(t.split_total) 3148 : ((buyRaw + sellRaw) / 2); 3149 3150 const immediateSellRaw = Number(t.immediate_sell_total || 0); 3151 const immediateBuyRaw = Number(t.immediate_buy_total || 0); 3152 const buyAdj = buyRaw * factor; 3153 const immediateSellAdj = immediateSellRaw * factor; 3154 const splitAdj = splitRaw * factor; 3155 const immediateBuyAdj = immediateBuyRaw * factor; 3156 const sellAdj = sellRaw * factor; 3157 3158 // Headline values use quantity-aware executable depth. Top-of-book values 3159 // remain available in the API and advanced item intelligence. 3160 const buyDisplayAdj = immediateSellAdj; 3161 const sellDisplayAdj = immediateBuyAdj; 3162 const buyTxt = fmtISK(buyDisplayAdj); 3163 const immediateSellTxt = fmtISK(immediateSellAdj); 3164 const splitTxt = fmtISK(splitAdj); 3165 const immediateBuyTxt = fmtISK(immediateBuyAdj); 3166 const sellTxt = fmtISK(sellDisplayAdj); 3167 3168 const metaBits = []; 3169 3170 if (reprocessMeta) { 3171 metaBits.push( 3172 'â» Reprocessed appraisal ' + escapeHtml(String(Number(reprocessMeta.efficiency_pct || reprocessEfficiency).toFixed(1).replace(/\.0$/, ''))) + '%' 3173 ); 3174 3175 if (Number(reprocessMeta.remainder_qty || 0) > 0) { 3176 metaBits.push( 3177 escapeHtml(fmtInt(Number(reprocessMeta.remainder_qty || 0))) + ' remainder units retained' 3178 ); 3179 } 3180 3181 if (Number(reprocessMeta.unprocessed_qty || 0) > 0) { 3182 metaBits.push( 3183 escapeHtml(fmtInt(Number(reprocessMeta.unprocessed_qty || 0))) + ' non-reprocessable units retained' 3184 ); 3185 } 3186 } 3187 3188 if (adjPct) { 3189 metaBits.push( 3190 'Buyback ' 3191 + (adjPct > 0 ? '+' : '') 3192 + escapeHtml(String(adjPct)) 3193 + '%' 3194 ); 3195 } 3196 3197 const immediateSellFill = Number(t.immediate_sell_fill_pct || 0); 3198 const immediateBuyFill = Number(t.immediate_buy_fill_pct || 0); 3199 if (immediateSellFill < 99.999) { 3200 metaBits.push('âš Immediate Sell liquidity ' + escapeHtml(immediateSellFill.toFixed(1)) + '% filled'); 3201 } 3202 if (immediateBuyFill < 99.999) { 3203 metaBits.push('âš Immediate Buy liquidity ' + escapeHtml(immediateBuyFill.toFixed(1)) + '% filled'); 3204 } 3205 3206 metaBits.push( 3207 escapeHtml(String(t.lines_ok || 0)) 3208 + '/' 3209 + escapeHtml(String(t.lines || 0)) 3210 + ' lines ok' 3211 ); 3212 3213 totals.innerHTML = 3214 '<div class="pc-basic-totals">' + 3215 '<div class="pc-totalhero">' + 3216 '<div class="pc-totalhero-head">' + 3217 '<div><div class="k">Buy Value</div><div class="v" id="pcBuyTotal">
3217' + escapeHtml(buyTxt) + '</div></div>' + 3218 '<button type="button" class="btn ghost pc-copybtn" data-copy="buy" title="Copy buy total">â§</button>' + 3219 '</div>' + 3220 '<div class="s">Executable buy-order depth for this exact quantity</div>' + 3221 '</div>' + 3222 '<div class="pc-totalhero">' + 3223 '<div class="pc-totalhero-head">' + 3224 '<div><div class="k">Sell Value</div><div class="v" id="pcSellTotal">' + escapeHtml(sellTxt) + '</div></div>' + 3225 '<button type="button" class="btn ghost pc-copybtn" data-copy="sell" title="Copy sell total">â§</button>' + 3226 '</div>' + 3227 '<div class="s">Sell-order depth required to buy this exact quantity</div>' + 3228 '</div>' + 3229 '<div class="pc-basic-meta">' + metaBits.join(' <span class="hint">â¢</span> ') + '</div>' + 3230 '</div>' + 3231 '<div class="pc-advanced-totals">' + 3232 '<div class="pc-advanced-total"><div class="k">Immediate Sell</div><div class="v"><span id="pcImmediateSellTotal">' + escapeHtml(immediateSellTxt) + '</span> <button type="button" class="btn ghost pc-copybtn" data-copy="immediate-sell" title="Copy immediate-sell total">â§</button></div></div>' + 3233 '<div class="pc-advanced-total"><div class="k">Split</div><div class="v"><span id="pcSplitTotal">' + escapeHtml(splitTxt) + '</span> <button type="button" class="btn ghost pc-copybtn" data-copy="split" title="Copy split total">â§</button></div></div>' + 3234 '<div class="pc-advanced-total"><div class="k">Immediate Buy</div><div class="v"><span id="pcImmediateBuyTotal">' + escapeHtml(immediateBuyTxt) + '</span> <button type="button" class="btn ghost pc-copybtn" data-copy="immediate-buy" title="Copy immediate-buy total">â§</button></div></div>' + 3235 '</div>'; 3236 3237 // Snapshot exactly what this appraisal displayed so a short share link can 3238 // produce a rich Discord appraisal preview without repricing inside Discord. 3239 const appraisalPreview = (data.items || []) 3240 .filter(r => !r.error) 3241 .slice(0, 12) 3242 .map(r => { 3243 const nm = r.item_name || r.name || r.input || 'Unknown'; 3244 const qty = Number(r.qty || 1); 3245 return String(nm) + ' - ' + qty.toLocaleString('en-US'); 3246 }); 3247 3248 lastAppraisal = { 3249 signature: [ 3250 String(items).trim(), 3251 String(regionId), 3252 String(adjPct), 3253 reprocessRequested ? ('reprocess:' + String(reprocessEfficiency)) : 'raw' 3254 ].join('|'), 3255 3256 region_name: regionName, 3257 buy_total: buyDisplayAdj, 3258 split_total: splitAdj, 3259 sell_total: sellDisplayAdj, 3260 lines: Number(t.lines || 0), 3261 lines_ok: Number(t.lines_ok || 0), 3262 preview: appraisalPreview, 3263 reprocess_mode: reprocessRequested, 3264 reprocess_efficiency: reprocessRequested ? reprocessEfficiency : null 3265 }; 3266 3267 const tbody = table.querySelector('tbody'); 3268 3269 3270 // 5-hub totals badges from this same local appraisal request 3271 try { loadAllHubTotals(adjPct, data); } catch(_) {} 3272 try { renderIntelSummary(data); } catch(_) {} // CMS_PRICECHECK_PHASE2_RENDER_SUMMARY 3273 3274// CMS_PRICECHECK_REPROCESS_APPRAISAL_RESULTS_V1 3275(data.items || []).forEach(function(r){ 3276 tbody.appendChild(buildRow(r, adjPct)); 3277 const intelRow = buildIntelRow(r, adjPct); // CMS_PRICECHECK_PHASE2_ITEM_ROW 3278 if (intelRow) tbody.appendChild(intelRow); 3279 const recycleRow = buildRecycleRow(r); 3280 if (recycleRow) tbody.appendChild(recycleRow); 3281 }); 3282 rerenderAllRecycleBoxes(); 3283 try { pcApplyNegativeColors(results); } catch(_) {} 3284 try { pcInitResultsAd(); } catch(_) {} // CMS_PUBLIC_REFERRAL_BOTTOM_INIT_V1 3285 3286 const unresolved = (data.items || []).filter(unresolvedIsNameFailure); 3287 if (unresolved.length) unresolvedOpen(unresolved); 3288 3289 3290// Save this run into "recent checks" (local to this browser) 3291try{ 3292 const itemsText = items; 3293 const lines = Number(t.lines || 0) || countLines(itemsText); 3294 const entry = { 3295 when: new Date().toISOString(), 3296 items: itemsText, 3297 lines: lines, 3298 region_id: regionId, 3299 region_name: regionName, 3300 adj_pct: adjPct, 3301 total_isk: splitAdj 3302 }; 3303 3304 let list = loadRecent(); 3305 const sig = (String(entry.region_id) + '|' + String(entry.adj_pct) + '|' + String(entry.items).trim()); 3306 list = list.filter(x => (String(x.region_id) + '|' + String(x.adj_pct) + '|' + String(x.items).trim()) !== sig); 3307 list.unshift(entry); 3308 if (list.length > RECENT_MAX) list = list.slice(0, RECENT_MAX); 3309 saveRecent(list); 3310 renderRecent(); 3311}catch(_){} 3312 3313 // We do NOT auto-stuff the current state into the URL. 3314 // Share links are created only via the "Copy Share Link" button. 3315 3316 // CMS_PRICECHECK_RUN_RETURNS_APPRAISAL_V2 3317 return lastAppraisal; 3318 3319 } catch (e) { 3320 showMsg('<strong>Error:</strong> ' + escapeHtml(e && e.message ? e.message : e), 'danger'); 3321 } finally { 3322 setBusy(false); 3323 } 3324 } 3325 3326 form && form.addEventListener('submit', function(e){ 3327 e.preventDefault(); 3328 run(); 3329 }); 3330 3331 btnClear && btnClear.addEventListener('click', function(){ 3332 // Reset for a fresh run (do not re-fill from any defaults baked into the HTML). 3333 if (taItems) taItems.value = ''; 3334 if (adjRange) { adjRange.value = '0'; syncAdjUI(); } 3335 hideMsg(); 3336 clearTable(); 3337 lastAppraisal = null; 3338 if (hubTotals) { hubTotals.style.display = 'none'; hubTotals.innerHTML = ''; } 3339 results.style.display = 'none'; 3340 try { 3341 const u = new URL(window.location.href); 3342 u.searchParams.delete('items'); 3343 u.searchParams.delete('item'); 3344 u.searchParams.delete('adj_pct'); 3345 u.searchParams.delete('share'); 3346 history.replaceState(null, '', u.toString()); 3347 } catch(e) {} 3348 }); 3349 3350 // When coming back to this page via browser back/forward or normal navigation, 3351 // start clean unless this is an explicit share link. 3352 window.addEventListener('pageshow', function(){ 3353 try { 3354 const u = new URL(window.location.href); 3355 const isShare = u.searchParams.has('items') || u.searchParams.has('item') || u.searchParams.has('share'); 3356 if (!isShare) { 3357 if (taItems) taItems.value = ''; 3358 if (adjRange) { adjRange.value = '0'; syncAdjUI(); } 3359 hideMsg(); 3360 clearTable(); 3361 if (hubTotals) { hubTotals.style.display = 'none'; hubTotals.innerHTML = ''; } 3362 results.style.display = 'none'; 3363 // Keep the URL clean as well. 3364 u.searchParams.delete('adj_pct'); 3365 u.searchParams.delete('items'); 3366 u.searchParams.delete('item'); 3367 u.searchParams.delete('share'); 3368 history.replaceState(null, '', u.toString()); 3369 } 3370 } catch(_) {} 3371 }); 3372 3373 btnShare && btnShare.addEventListener('click', async function(){ 3374 try { 3375 const fd = new FormData(form); 3376 3377 const items = (fd.get('items') || '').toString(); 3378 const regionId = (fd.get('region_id') || '10000043').toString(); 3379 const csrf = (fd.get('csrf') || '').toString(); 3380 const adjPct = String(getAdjPct()); 3381 3382 if (!items.trim()) { 3383 showMsg('Nothing to share yet â paste some items first.', 'w
3383arn'); 3384 return; 3385 } 3386 3387 const wantedSignature = [ 3388 String(items).trim(), 3389 String(regionId), 3390 String(Number(adjPct)), 3391 (showReprocessToggle && showReprocessToggle.checked) ? ('reprocess:' + String(getReprocessEff())) : 'raw' 3392 ].join('|'); 3393 3394 let snap = lastAppraisal; 3395 3396 // If items/hub/adjustment changed since the previous appraisal, refresh it 3397 // automatically before creating the share link. 3398 if (!snap || snap.signature !== wantedSignature) { 3399 showMsg('Refreshing appraisal before creating the share linkâ¦', ''); 3400 snap = await run(); 3401 3402 if (!snap) { 3403 showMsg('Price Check must complete successfully before the appraisal can be shared.', 'warn'); 3404 return; 3405 } 3406 } 3407 3408 const body = new URLSearchParams({ 3409 items: items, 3410 region_id: regionId, 3411 adj_pct: adjPct, 3412 reprocess_mode: (showReprocessToggle && showReprocessToggle.checked) ? '1' : '0', 3413 reprocess_efficiency: String(getReprocessEff()), 3414 csrf: csrf, 3415 3416 region_name: String(snap.region_name || ''), 3417 buy_total: String(snap.buy_total || 0), 3418 split_total: String(snap.split_total || 0), 3419 sell_total: String(snap.sell_total || 0), 3420 lines: String(snap.lines || 0), 3421 lines_ok: String(snap.lines_ok || 0), 3422 preview_json: JSON.stringify(snap.preview || []) 3423 }); 3424 3425 const res = await fetch('/api/sharelink.php', { 3426 method: 'POST', 3427 headers: { 3428 'Content-Type': 'application/x-www-form-urlencoded' 3429 }, 3430 body: body.toString(), 3431 credentials: 'same-origin' 3432 }); 3433 3434 const data = await res.json().catch(() => null); 3435 3436 if (!res.ok || !data || !data.ok || !data.code) { 3437 const emsg = 3438 (data && data.error) 3439 ? data.error 3440 : ('HTTP ' + res.status); 3441 3442 showMsg('<strong>Error:</strong> ' + escapeHtml(emsg), 'danger'); 3443 return; 3444 } 3445 3446 const u = new URL(window.location.href); 3447 3448 u.searchParams.delete('items'); 3449 u.searchParams.delete('item'); 3450 u.searchParams.delete('region_id'); 3451 u.searchParams.delete('adj_pct'); 3452 3453 u.searchParams.set('share', data.code); 3454 3455 const copied = await copyToClipboard(u.toString()); 3456 3457 if (copied) { 3458 showMsg( 3459 '<strong>Appraisal link copied.</strong> Discord will show the Split value and item preview.', 3460 'ok' 3461 ); 3462 } else { 3463 showMsg( 3464 'Appraisal created, but the browser blocked automatic clipboard access. Copy the URL from the address bar.', 3465 'warn' 3466 ); 3467 } 3468 3469 results.style.display = ''; 3470 3471 setTimeout(() => { 3472 hideMsg(); 3473 }, 2600); 3474 3475 } catch (e) { 3476 showMsg( 3477 'Could not create the appraisal link: ' 3478 + escapeHtml(e && e.message ? e.message : String(e)), 3479 'warn' 3480 ); 3481 3482 results.style.display = ''; 3483 } 3484 }); 3485 3486 // Make EVE clipboard paste Just Workâ¢. 3487 // EVE often copies as TSV (tab-separated) with extra columns; normalize to "Item Qty" lines. 3488 function parseQtyClipboard(s){ 3489 const cleaned = String(s || '').replace(/[\u00A0\t ,\.]/g, '').trim(); 3490 if (!/^\d+$/.test(cleaned)) return null; 3491 let n = parseInt(cleaned, 10); 3492 if (!Number.isFinite(n) || n < 1) return null; 3493 if (n > 2000000000) n = 2000000000; 3494 return n; 3495 } 3496 3497 function normalizeClipboard(text){ 3498 const t = String(text || ''); 3499 if (!t.includes('\t')) return t; 3500 const lines = t.replace(/\r\n/g, '\n').replace(/\r/g, '\n').split('\n'); 3501 const out = []; 3502 for (const ln of lines) { 3503 const raw = (ln || '').trim(); 3504 if (!raw) continue; 3505 if (raw.includes('\t')) { 3506 const fields = raw.split(/\t+/).map(v => (v||'').trim()).filter(Boolean); 3507 if (fields.length >= 2) { 3508 let qty = null, qtyIdx = -1; 3509 for (let i=0; i<fields.length; i++) { 3510 const f = fields[i]; 3511 if (/^[\d\s,.\u00A0]+$/.test(f)) { 3512 const q = parseQtyClipboard(f); 3513 if (q !== null) { qty = q; qtyIdx = i; break; } 3514 } 3515 } 3516 if (qty !== null) { 3517 let name = null; 3518 for (let i=0; i<fields.length; i++) { 3519 if (i === qtyIdx) continue; 3520 const f = fields[i]; 3521 if (/^(type|item|name|quantity|qty)$/i.test(f)) continue; 3522 if (!/^[\d\s,.\u00A0]+$/.test(f)) { name = f; break; } 3523 } 3524 if (!name) name = (qtyIdx === 0 && fields[1]) ? fields[1] : fields[0]; 3525 out.push(name + ' ' + String(qty)); 3526 continue; 3527 } 3528 } 3529 } 3530 out.push(raw.replace(/\s+/g, ' ')); 3531 } 3532 return out.join('\n'); 3533 } 3534 3535 if (taItems && !taItems.dataset.evePasteBound) { 3536 taItems.dataset.evePasteBound = '1'; 3537 taItems.addEventListener('paste', function(e){
3538 try { 3539 const clip = e.clipboardData && e.clipboardData.getData ? e.clipboardData.getData('text/plain') : ''; 3540 if (clip && clip.includes('\t')) { 3541 const norm = normalizeClipboard(clip); 3542 if (norm && norm !== clip) { 3543 e.preventDefault(); 3544 e.stopPropagation(); 3545 const start = taItems.selectionStart || 0; 3546 const end = taItems.selectionEnd || 0; 3547 taItems.setRangeText(norm, start, end, 'end'); 3548 } 3549 } 3550 } catch(err) { 3551 // If anything weird happens, let the browser do its default paste. 3552 } 3553 }); 3554 } 3555 3556 // Auto-run if prefilled by querystring. 3557 (function(){ 3558 try{ 3559 const ta = form.querySelector('textarea[name="items"]'); 3560 if (ta && ta.value && ta.value.trim().length > 0) { 3561 run(); 3562 } 3563 }catch(e){} 3564 })(); 3565 3566 // Responsive layout tweak: side-by-side on wide screens. 3567 (function(){ 3568 const grid = document.getElementById('pcGrid'); 3569 if (!grid) return; 3570 function apply(){ 3571 const itemsCol = document.getElementById('pcItemsColumn'); 3572 const itemsTa = document.getElementById('pcItemsTextarea'); 3573 if (window.innerWidth >= 900) { 3574 grid.style.gridTemplateColumns = '2fr 1fr'; 3575 grid.style.alignItems = 'stretch'; 3576 if (itemsCol) { 3577 itemsCol.style.display = 'flex'; 3578 itemsCol.style.flexDirection = 'column'; 3579 itemsCol.style.minHeight = '100%'; 3580 } 3581 if (itemsTa) { 3582 itemsTa.style.flex = '1 1 auto'; 3583 itemsTa.style.minHeight = '0'; 3584 itemsTa.style.height = 'auto'; 3585 } 3586 } else { 3587 grid.style.gridTemplateColumns = '1fr'; 3588 grid.style.alignItems = 'start'; 3589 if (itemsCol) { 3590 itemsCol.style.display = 'block'; 3591 itemsCol.style.minHeight = ''; 3592 } 3593 if (itemsTa) { 3594 itemsTa.style.flex = ''; 3595 itemsTa.style.minHeight = '180px'; 3596 itemsTa.style.height = ''; 3597 } 3598 } 3599 } 3600 apply(); 3601 window.addEventListener('resize', apply, {passive:true}); 3602 })(); 3603 3604 // Render recent checks badges 3605 renderRecent(); 3606 3607 // Market-data accuracy clock. 3608 refreshMarketStatus(); 3609 3610 setInterval( 3611 marketRenderClock, 3612 1000 3613 ); 3614 3615 setInterval( 3616 refreshMarketStatus, 3617 60000 3618 ); 3619 3620 if (hubSelect) { 3621 hubSelect.addEventListener( 3622 'change', 3623 refreshMarketStatus 3624 ); 3625 } 3626 3627})(); 3628</script>
3628 3629 3630 </main> 3631 3632 <div class="ctx-help-root" data-contextual-help-root data-help-api="/api/contextual_help.php" aria-hidden="true"> 3633 <div class="ctx-help-backdrop" data-help-backdrop></div> 3634 <aside class="ctx-help-drawer" data-help-drawer role="dialog" aria-modal="true" aria-label="Contextual Help"> 3635 <div class="ctx-help-head"> 3636 <div><div class="ctx-help-head__eyebrow">CMS Help</div><h2 data-help-title>Help for this page</h2></div> 3637 <button type="button" class="ctx-help-close" data-help-close aria-label="Close help">Ã</button> 3638 </div> 3639 <div class="ctx-help-toolbar"> 3640 <span class="small muted">Page-specific guidance without leaving your workflow.</span> 3641 <label class="ctx-help-guidance"><input type="checkbox" data-help-guidance-toggle> New Pilot Guidance</label> 3642 </div> 3643 <div class="ctx-help-body" data-help-body><div class="ctx-help-loading"><span class="ctx-help-spinner" aria-hidden="true"></span><span>Loading helpâ¦</span></div></div> 3644 </aside> 3645 </div> 3646 3647 <div id="pageLoader" class="page-loader" aria-hidden="true"> 3648 <div class="page-loader__panel" role="status" aria-live="polite"> 3649 <div class="page-loader__spinner" aria-hidden="true"></div> 3650 <div> 3651 <div class="page-loader__text" id="pageLoaderText">Loadingâ¦</div> 3652 <div class="page-loader__sub">Please wait while the page finishes loading.</div> 3653 </div> 3654 </div> 3655 </div> 3656 3657 <footer class="footer"> 3658 <div class="container footer__inner"> 3659 <div class="footer__title">SolarCrucible/HighStellar Syndicates</div> 3660 <div class="footer__text">Requests are not contracts. Each request may be accepted, rejected, or reprioritized based on capacity and materials.</div> 3661 3662 <style> 3663 .suggestionBox{margin-top:18px} 3664 .suggestionBox details{border:1px solid rgba(255,255,255,.08); border-radius:16px; background:rgba(0,0,0,.35); box-shadow:0 10px 26px rgba(0,0,0,.25)} 3665 .suggestionBox summary{cursor:pointer; list-style:none; display:flex; align-items:center; justify-content:space-between; gap:12px; padding:14px 16px} 3666 .suggestionBox summary::-webkit-details-marker{display:none} 3667 .suggestionBox .sumTitle{display:flex; align-items:center; gap:10px; font-weight:800} 3668 .suggestionBox .sumHint{opacity:.75; font-size:.9rem} 3669 .suggestionBox .inner{padding:0 16px 16px} 3670 .suggestionBox .row{display:flex; gap:10px; flex-wrap:wrap} 3671 .suggestionBox .row > div{flex:1;
3671 min-width:200px} 3672 .suggestionBox .ok{margin-top:10px; color:#a7f3d0} 3673 .suggestionBox .err{margin-top:10px; color:#fca5a5} 3674</style> 3675 3676<div class="suggestionBox"> 3677 <details class="card" id="sugg_bd8d3df3c5"> 3678 <summary> 3679 <div class="sumTitle"> 3680 <span class="badge">Feedback</span> 3681 <span>Suggestion box</span> 3682 </div> 3683 <div class="sumHint">ideas ⢠bugs ⢠questions</div> 3684 </summary> 3685 3686 <div class="inner"> 3687 <form class="suggestionForm" data-box="sugg_bd8d3df3c5"> 3688 <input type="hidden" name="csrf" value="7f97e5cf384ab7d2a7603e8e4a5e01dfa7aa9dc843d1f17e0c9b09d17db49cef"> 3689 <!-- 3690 We keep the DB kind enum as feature/problem/question, but expose broader topics to users. 3691 Topic is mapped server-side (and mirrored client-side) to one of the three kinds. 3692 --> 3693 <input type="hidden" name="kind" value="feature"> 3694 <input type="hidden" name="page_key" value="Footer"> 3695 <input type="hidden" name="page_url" value="/pricecheck.php"> 3696 <div class="row"> 3697 <div> 3698 <label>Topic</label> 3699 <select name="topic"> 3700 <option value="suggestion">Suggestion</option> 3701 <option value="improvement">Improvement</option> 3702 <option value="bug">Bug</option> 3703 <option value="help">Question / help</option> 3704 <option value="new_feature">New feature</option> 3705 </select> 3706 </div> 3707 <div> 3708 <label>Title <span class="muted small">(optional)</span></label> 3709 <input type="text" name="title" placeholder="Short summary (optional)"> 3710 </div> 3711 </div> 3712 3713 <div style="margin-top:12px"> 3714 <label>Details</label> 3715 <textarea name="message" rows="6" placeholder="What happened / what should it do? Include item names, steps, etc." required></textarea> 3716 <div class="muted small" style="margin-top:6px">This sends feedback about <b>the site</b>.</div> 3717 </div> 3718 3719 <div class="row" style="margin-top:12px"> 3720 <div> 3721 <label>Character name <span class="muted small">(optional)</span></label> 3722 <input type="text" name="name" value="" placeholder="Your in-game name"> 3723 </div> 3724 <div> 3725 <label>Email <span class="muted small">(optional)</span></label> 3726 <input type="email" name="email" value="" placeholder="So we can reply (optional)"> 3727 </div> 3728 </div> 3729 3730 <div style="display:flex; gap:10px; flex-wrap:wrap; align-items:center; margin-top:14px"> 3731 <button class="btn primary" type="submit">Send</button> 3732 <span class="muted small">Goes to admins under <b>Feature Suggestions</b>.</span> 3733 </div> 3734 3735 <div class="ok small" style="display:none"></div> 3736 <div class="err small" style="display:none"></div> 3737 </form> 3738 </div> 3739 </details> 3740</div> 3741
3742<script> 3743(function(){ 3744 if (window.__dmcSuggestInit) return; 3745 window.__dmcSuggestInit = true; 3746 3747 function mapTopicToKind(topic){ 3748 topic = (topic || '').toLowerCase(); 3749 if (topic === 'bug') return 'problem'; 3750 if (topic === 'help') return 'question'; 3751 // suggestion / improvement / new_feature -> feature 3752 return 'feature'; 3753 } 3754 3755 async function postForm(form){ 3756 const okEl = form.querySelector('.ok'); 3757 const errEl = form.querySelector('.err'); 3758 okEl.style.display = 'none'; errEl.style.display = 'none'; 3759 okEl.textContent = ''; errEl.textContent = ''; 3760 3761 const btn = form.querySelector('button[type="submit"]'); 3762 if (btn) { btn.disabled = true; btn.textContent = 'Sendingâ¦'; } 3763 3764 try{ 3765 // Mirror server-side mapping so "kind" is always present/consistent. 3766 const topicEl = form.querySelector('select[name="topic"]'); 3767 const kindEl = form.querySelector('input[name="kind"]'); 3768 if (topicEl && kindEl) kindEl.value = mapTopicToKind(topicEl.value); 3769 3770 const fd = new FormData(form); 3771 const res = await fetch('/api/suggest.php', { method:'POST', body:fd, credentials:'same-origin' }); 3772 const data = await res.json().catch(()=>null); 3773 3774 if (!res.ok || !data || data.ok !== true){ 3775 const msg = (data && data.error) ? data.error : ('Request failed ('+res.status+').'); 3776 errEl.textContent = msg; 3777 errEl.style.display = 'block'; 3778 } else { 3779 okEl.textContent = 'Sent. Thanks â the admins will see it.'; 3780 okEl.style.display = 'block'; 3781 form.reset(); 3782 } 3783 }catch(e){ 3784 errEl.textContent = 'Network error. Try again.'; 3785 errEl.style.display = 'block'; 3786 }finally{ 3787 if (btn) { btn.disabled = false; btn.textContent = 'Send'; } 3788 } 3789 } 3790 3791 document.addEventListener('submit', function(e){ 3792 const form = e.target; 3793 if (!form || !form.classList || !form.classList.contains('suggestionForm')) return; 3794 e.preventDefault(); 3795 postForm(form); 3796 }, true); 3797})(); 3798</script>
3798 3799 3800 <div class="footer__links small"> 3801 <a href="/admin/login.php">Staff Login</a> 3802 </div> 3803 </div> 3804 </footer> 3805 3806
3806<script> 3807 // Keep scroll position on refresh/redirect (e.g. after saving a checkbox or form). 3808 // Key is based on path + querystring EXCEPT transient params like "msg". 3809 (function(){ 3810 try{ 3811 function normalizedKey(){ 3812 var u = new URL(window.location.href); 3813 u.searchParams.delete('msg'); 3814 // Keep other filters/search intact. 3815 var qs = u.searchParams.toString(); 3816 return 'scroll:' + u.pathname + (qs ? ('?' + qs) : ''); 3817 } 3818 3819 var key = normalizedKey(); 3820 var saved = sessionStorage.getItem(key); 3821 if (saved !== null && saved !== '') { 3822 var y = parseInt(saved, 10); 3823 if (!isNaN(y)) { 3824 // Restore a couple frames later to beat layout shifts. 3825 requestAnimationFrame(function(){ 3826 requestAnimationFrame(function(){ window.scrollTo(0, y); }); 3827 }); 3828 } 3829 } 3830 3831 var lastWrite = 0; 3832 function saveNow(){ 3833 // Normalize key again in case a redirect added msg, etc. 3834 try { key = normalizedKey(); } catch(e) {} 3835 sessionStorage.setItem(key, String(window.scrollY || 0)); 3836 } 3837 3838 window.addEventListener('scroll', function(){ 3839 var now = Date.now(); 3840 if (now - lastWrite < 250) return; 3841 lastWrite = now; 3842 saveNow(); 3843 }, {passive:true}); 3844 3845 window.addEventListener('beforeunload', function(){ 3846 try { saveNow(); } catch(e) {} 3847 }); 3848 }catch(e){ /* no-op */ } 3849 })(); 3850 3851 // Dropdown behavior: only one open at a time, click-away closes, ESC closes. 3852 (function(){ 3853 function closeAll(except){ 3854 document.querySelectorAll('details.dd').forEach(function(d){ 3855 if (except && d === except) return; 3856 d.open = false; 3857 }); 3858 } 3859 document.querySelectorAll('details.dd').forEach(function(d){ 3860 d.addEventListener('toggle', function(){ 3861 if (d.open) closeAll(d); 3862 }); 3863 }); 3864 document.addEventListener('click', function(e){ 3865 if (!e.target.closest || !e.target.closest('details.dd')) closeAll(null); 3866 }); 3867 document.addEventListener('keydown', function(e){ 3868 if (e.key === 'Escape') closeAll(null); 3869 }); 3870 })(); 3871 </script>
3871 3872 3873
3873<script src="/assets/stellar_navigation.js?v=1790823250"></script>
3873 3874 3875
3875<script src="/assets/contextual_help.js?v=1787613252"></script>
3875 3876 3877
3877<script src="/assets/localtime.js?v=1787613252"></script>
3877 3878 3879 3880<!-- CMS_HOF_LIFETIME_NAV_JS -->
3881<script src="/assets/hof_lifetime_nav.js"></script>
3881 3882</body> 3883</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.