1(function(){"use strict";let T={},$={},j=[],N=!1,_,x=null,S=null,M=0;const E=(f,t)=>{const d=f.position.x-t.position.x,c=f.position.y-t.position.y,o=f.position.z-t.position.z;return Math.sqrt(d*d+c*c+o*o)},R=new Map,q=()=>{R.clear();for(const f of j)R.has(f.source_system_id)||R.set(f.source_system_id,[]),R.has(f.destination_system_id)||R.set(f.destination_system_id,[]),R.get(f.source_system_id).push(f.destination_system_id),R.get(f.destination_system_id).push(f.source_system_id)};let J=60,z=0,U=999999;const C=(f,t)=>{let d=null,c=null;const o=f.id,r=t.id,s=[[o]],u=new Set([o]);for(;s.length;){const a=s.shift(),p=a[a.length-1];if(p===r){c=a.length-1;let m=0;for(let D=0;D<c;D++){const h=G.get(a[D]),n=G.get(a[D+1]);m+=E(h,n)}d=m;break}for(const m of R.get(p)||[])u.has(m)||(u.add(m),s.push([...a,m]))}const l=E(f,t);let i=!1;if(d===null)if(l<=J)i=!0;else return{gateDistance:null,gateHops:null,shipDistance:1/0,chooseShip:!1};else{const a=c;l<=z&&l<=J&&a>=U&&(i=!0)}return{gateDistance:d,gateHops:c,shipDistance:l,chooseShip:i}},I=(f,t)=>{let d=0,c=0,o=0;const r=f.length;for(let s=0;s<r-1;s++){const u=$[f[s]],l=$[f[s+1]];if(!u||!l)continue;const i=C(u,l);if(i.chooseShip){if(i.shipDistance>J+1e-6)return{shipDistance:1/0,shipJumps:1/0,totalDistance:1/0};d+=i.shipDistance,c+=1,o+=i.shipDistance}else if(i.gateDistance!==null)o+=i.gateDistance;else return{shipDistance:1/0,shipJumps:1/0,totalDistance:1/0}}return{shipDistance:d,shipJumps:c,totalDistance:o}},G=new Map,Y=(f,t,d,c,o)=>{const r=new Set(t.filter(i=>i!==f)),s=[f];let u=!1,l={shipDistance:0,shipJumps:0,totalDistance:0};for(;r.size;){let i=null;const a=s[s.length-1],p=$[a];for(const m of r){const D=$[m];if(!p||!D)continue;const h=C(p,D);if(h.chooseShip){if(h.shipDistance>J+1e-6)continue}else if(h.gateDistance===null)continue;const n=h.chooseShip?{shipDist:h.shipDistance,shipJumps:1,total:h.shipDistance}:{shipDist:0,shipJumps:0,total:h.gateDistance};if(!i){i={name:m,inc:n};continue}const e=i.inc;(n.shipDist<e.shipDist||n.shipDist===e.shipDist&&n.shipJumps<e.shipJumps||n.shipDist===e.shipDist&&n.shipJumps===e.shipJumps&&n.total<e.total)&&(i={name:m,inc:n})}if(i)o&&b({type:"progress",message:`[DEBUG] NN append ${i.name} inc(shipDist=${i.inc.shipDist.toFixed(2)}, shipJumps=${i.inc.shipJumps}, total=${i.inc.total.toFixed(2)})`});else{if(c){let m,D=1/0;for(const n of r){const e=$[n];if(!e||!p)continue;const g=E(p,e);if(g<=J+1e-6){m=n,D=g;break}}if(m){o&&b({type:"progress",message:`[DEBUG] Bridging components via ship jump ${D.toFixed(2)} LY to ${m}`}),s.push(m),r.delete(m);continue}let h=null;if(p)for(const n of r){const e=$[n];if(e){for(let g=0;g<s.length;g++){const y=s[g];if(y===a)continue;const k=$[y];if(!k)continue;const v=C(p,k);if(v.gateDistance===null&&(!v.chooseShip||v.shipDistance>J+1e-6))continue;const w=E(k,e);if(w<=J+1e-6){h={anchor:y,target:n,d:w};break}}if(h)break}}if(h){o&&b({type:"progress",message:`[DEBUG] Revisit bridge via ${h.anchor} -> ship ${h.target} (${h.d.toFixed(2)} LY)`}),s.push(h.anchor),s.push(h.target),r.delete(h.target);continue}else if(o){let n=null;for(const e of r){const g=$[e];if(g){for(let y=0;y<s.length;y++){const k=$[s[y]];if(!k)continue;const v=E(k,g);if(v<=J+1e-6){n={name:e,via:s[y],d:v};break}}if(n)break}}n&&b({type:"progress",message:`[DEBUG] Ordering block: ${n.name} reachable from earlier ${n.via} at ${n.d.toFixed(2)} LY but not from tail ${s[s.length-1]}`})}if(c&&r.size){let n=null;e:for(let e=s.length-2;e>=0;e--){const g=s[e],y=$[g];if(y)for(const k of r){const v=$[k];if(!v)continue;const w=E(y,v);if(w<=J+1e-6){n={backtrackIdx:e,target:k,d:w};break e}}}if(n){const e=s.slice(n.backtrackIdx);for(let g=e.length-2;g>=0;g--){const y=e[g];s[s.length-1]!==y&&s.push(y)}s.push(n.target),r.delete(n.target),o&&b({type:"progress",message:`[DEBUG] Backtrack bridge via anchor ${s[s.length-2]} -> ship ${n.target} (${n.d.toFixed(2)} LY) after duplicating ${e.length-1} nodes`});continue}}}if(d&&s[s.length-1]!==f){const m=$[s[s.length-1]],D=$[f];let h=!1;if(m&&D){const n=C(m,D);n.chooseShip?n.shipDistance<=J+1e-6&&(h=!0):n.gateDistance!==null&&(h=!0)}if(h){o&&b({type:"progress",message:"[DEBUG] Reposition to start to seek new bridging opportunities"}),s.push(f);continue}else{o&&b({type:"progress",message:`[DEBUG] Reposition blocked: tail ${s[s.length-1]} cannot reach start ${f} (direct ${m&&D?E(m,D).toFixed(2):"?"} LY > ${J} and no gate path)`}),u=!0;break}}u=!0;break}i&&(l.shipDistance+=i.inc.shipDist,l.shipJumps+=i.inc.shipJumps,l.totalDistance+=i.inc.total,s.push(i.name),r.delete(i.name))}if(d&&s.push(f),u&&o){const i=[...r],a=i.slice(0,12).join(", ");b({type:"progress",message:`[DEBUG] NN unreachable with ${r.size} remaining (sample: ${a}${i.length>12?" ...":""})`})}return{path:s,unreachable:u||s.filter(i=>i!==f).length<t.filter(i=>i!==f).length}},L=(f,t,d,c)=>{const o=Date.now();let r=f.slice();const s=t?r.length-1:r.length,u=i=>I(i,t);let l=u(r);if(!isFinite(l.shipDistance))return f;for(;Date.now()-o<d;){let i=!1;for(let a=1;a<s-2;a++){for(let p=a+1;p<s-1;p++){const m=r.slice(0,a).concat(r.slice(a,p+1).reverse(),r.slice(p+1));let D=!0;const h=[];a>0&&h.push([a-1,a]),h.push([a,p]),p+1<r.length&&h.push([p,p+1]);for(const[g,y]of h){const k=m[g],v=m[y],w=$[k],B=$[v];if(!w||!B){D=!1;break}const F=C(w,B);if(F.chooseShip){if(F.shipDistance>J+1e-6){D=!1;break}}else if(F.gateDistance===null){D=!1;break}}if(!D){c&&b({type:"progress",message:`[DEBUG] 2-opt reject segment (${a},${p}) infeasible`});continue}const n=u(m);if(!isFinite(n.shipDistance))continue;if(n.shipDistance<l.shipDistance||n.shipDistance===l.shipDistance&&n.shipJumps<l.shipJumps||n.shipDistance===l.shipDistance&&n.shipJumps===l.shipJumps&&n.totalDistance<l.totalDistance){r=m,l=n,i=!0,c&&b({type:"progress",message:`[DEBUG] 2-opt improve (${a},${p}) shipDist=${l.shipDistance.toFixed(2)} shipJumps=${l.shipJumps} total=${l.totalDistance.toFixed(2)}`});break}}if(i)break}if(!i)break}return r},H=(f,t,d,c,o,r)=>{let s=f.slice(),u=I(s,c);for(let l=0;l<t&&!N;l++){const i=d*1e3,a=s.slice();if(a.length>5){const h=1+Math.floor(Math.random()*(a.length-3)),n=h+1+Math.floor(Math.random()*(a.length-h-2));a.splice(h,n-h,...a.slice(h,n).reverse())}const p=L(a,c,i,r),m=I(p,c);(m.shipDistance<u.shipDistance||m.shipDistance===u.shipDistance&&m.shipJumps<u.shipJumps||m.shipDistance===u.shipDistance&&m.shipJumps===u.shipJumps&&m.totalDistance<u.totalDistance)&&(s=p,u=m,r&&o(`[DEBUG] Pass ${l+1} improvement shipDist=${u.shipDistance.toFixed(2)} shipJumps=${u.shipJumps} total=${u.totalDistance.toFixed(2)}`)),o(`Pass ${l+1}/${t}`)}return s},b=f=>{self.postMessage(f)},O=(f,t,d)=>{let c=f.slice();if(c.length>5){const l=1+Math.floor(Math.random()*(c.length-3)),i=l+1+Math.floor(Math.random()*(c.length-l-2));
1c.splice(l,i-l,...c.slice(l,i).reverse())}const o=L(c,t,250,d),r=I(o,t),s=I(f,t);return r.shipDistance<s.shipDistance||r.shipDistance===s.shipDistance&&r.shipJumps<s.shipJumps||r.shipDistance===s.shipDistance&&r.shipJumps===s.shipJumps&&r.totalDistance<s.totalDistance?{path:o,improved:!0,cost:r}:{path:f,improved:!1,cost:s}},V=(f,t,d,c,o,r)=>{x=f.slice(),S=I(x,c),M=Date.now();const s=M,u=t*1e3,l=d>0?d*1e3:0;for(;!N;){const i=Date.now();if(u>0&&i-s>=u){const p=S||I(x,c);b({type:"optimizeDone",reason:"time budget",generation:o,path:x,shipDistance:p.shipDistance,shipJumps:p.shipJumps,totalDistance:p.totalDistance});break}if(l>0&&i-M>=l){const p=S||I(x,c);b({type:"optimizeDone",reason:"stall timeout",generation:o,path:x,shipDistance:p.shipDistance,shipJumps:p.shipJumps,totalDistance:p.totalDistance});break}if(!x){b({type:"optimizeDone",reason:"no champion",generation:o,path:[],shipDistance:1/0,shipJumps:1/0,totalDistance:1/0});break}const a=O(x,c,r);a.improved&&(x=a.path.slice(),S=a.cost,M=Date.now(),b({type:"optimizeResult",path:x.slice(),shipDistance:a.cost.shipDistance,shipJumps:a.cost.shipJumps,totalDistance:a.cost.totalDistance,generation:o}))}if(N){const i=S&&x?S:x?I(x,c):{shipDistance:1/0,shipJumps:1/0,totalDistance:1/0};b({type:"optimizeDone",reason:"stopped",generation:o,path:x||[],shipDistance:i.shipDistance,shipJumps:i.shipJumps,totalDistance:i.totalDistance})}},K=(f,t,d)=>{const c=[];for(const e of f){const g=$[e];g&&c.push(g)}const o=new Map;c.forEach(e=>o.set(e.id,e));const r=new Map;let s=0;for(const e of c){if(r.has(e.id))continue;const g=[e.id];for(r.set(e.id,s);g.length;){const y=g.shift();for(const k of R.get(y)||[])o.has(k)&&!r.has(k)&&(r.set(k,s),g.push(k))}s++}const u=Array.from({length:s},()=>[]);for(const e of c)u[r.get(e.id)].push(e.id);if(u.length<=1)return{reachable:!0,minRequired:0};const l=[];for(let e=0;e<u.length;e++)for(let g=e+1;g<u.length;g++){let y=1/0;for(const k of u[e]){const v=G.get(k);for(const w of u[g]){const B=G.get(w),F=E(v,B);F<y&&(y=F)}}
1l.push({a:e,b:g,d:y})}const i=Array.from({length:u.length},(e,g)=>g),a=e=>i[e]===e?e:i[e]=a(i[e]),p=(e,g)=>{e=a(e),g=a(g),e!==g&&(i[g]=e)};for(const e of l)e.d<=d+1e-9&&p(e.a,e.b);let m=a(0),D=!0;for(let e=1;e<u.length;e++)if(a(e)!==m){D=!1;break}l.sort((e,g)=>e.d-g.d);for(let e=0;e<u.length;e++)i[e]=e;let h=0,n=0;for(const e of l){if(h===u.length-1)break;a(e.a)!==a(e.b)&&(p(e.a,e.b),h++,e.d>n&&(n=e.d))}return{reachable:D,minRequired:n}};self.onmessage=f=>{const t=f.data;if(t.type==="init"){T=t.systems,$={},j=Object.values(t.stargates),G.clear();for(const d of Object.values(T))G.set(d.id,d),$[d.name]=d;q(),N=!1,b({type:"ready"})}else if(t.type==="baseline"){if(_=t.generation,N=!1,J=t.maxShipRange,z=t.shipTradeDistance,U=t.minGateHopsSaved,!$[t.start]){b({type:"baselineResult",path:[t.start]});return}const d=[t.start,...t.systems.filter(p=>p!==t.start)],c=K(d,t.start,J);if(!c.reachable){b({type:"baselineError",reason:`Unreachable systems with current ship range (${J} LY). Minimum required ~${c.minRequired.toFixed(2)} LY`,minRequiredShipRange:c.minRequired,generation:t.generation});return}let{path:o,unreachable:r}=Y(t.start,t.systems,t.returnToStart,c.reachable,!!t.debug);if(r){b({type:"baselineError",reason:"Unreachable systems with current ship range / gate network",generation:t.generation});return}if(t.returnToStart&&o.length>=2){const p=o[0];if(o[o.length-1]===p&&o.length>2){const D=o[o.length-2],h=$[D],n=$[p];if(h&&n){const e=C(h,n);if(!(e.chooseShip&&e.shipDistance<=J+1e-6||!e.chooseShip&&e.gateDistance!==null)){let y;const k=[];for(let v=o.length-2;v>0;v--){const w=o[v];if(w===p)continue;const B=$[w];if(!B||!n)continue;const F=C(B,n);if(F.gateDistance!==null||F.chooseShip&&F.shipDistance<=J+1e-6){y=w;break}const A=E(B,n);k.push(`${w}:${A.toFixed(2)}`)}if(y)o.pop(),o.push(y),o.push(p),t.debug&&b({type:"progress",message:`[DEBUG] Closure salvage: switched closing anchor to ${y}`});else{let v=1/0,w;for(let B=1;B<o.length-1;B++){const F=o[B],A=$[F];if(!A||!n)continue;const P=E(A,n);P<v&&(v=P,w=F)}t.debug&&b({type:"progress",message:`[DEBUG] Closure failure: cannot return to start. Nearest anchor ${w||"??"} at ${isFinite(v)?v.toFixed(2):"â"} LY > max ${J}. Candidates sampled: ${k.slice(0,6).join(", ")}`}),b({type:"baselineError",reason:`Cannot return to start within ship range (${J} LY). Nearest closing jump needs ${(isFinite(v)?v:0).toFixed(2)} LY`,generation:t.generation});return}}}}}let u=L(o,t.returnToStart,250,!!t.debug),l=I(u,t.returnToStart);if(!isFinite(l.shipDistance)){const p=I(o,t.returnToStart);if(isFinite(p.shipDistance))u=o,l=p;else{let m="";for(let D=0;D<o.length-1;D++){const h=o[D],n=o[D+1],e=$[h],g=$[n];if(!e||!g)continue;const y=C(e,g);if(y.gateDistance===null&&(!y.chooseShip||y.shipDistance>J+1e-6)){const k=E(e,g).toFixed(2);m=` Unreachable edge ${h} -> ${n} direct=${k}LY (max ${J}).`;break}}b({type:"progress",message:`[DEBUG] Baseline unreachable diagnostics:${m||" (no edge found??)"}`}),b({type:"baselineError",reason:"Route optimization produced unreachable segment",generation:t.generation});return}}let i=!1,a=0;for(let p=0;p<u.length-1;p++){const m=$[u[p]],D=$[u[p+1]];if(!m||!D)continue;const h=C(m,D);h.chooseShip&&h.shipDistance>J+1e-6&&(i=!0,h.shipDistance>a&&(a=h.shipDistance))}i&&b({type:"progress",message:`Baseline contains ship jump over range (${a.toFixed(2)} > ${J}). Params may require adjustment.`}),b({type:"baselineResult",path:u,shipDistance:l.shipDistance,shipJumps:l.shipJumps,totalDistance:l.totalDistance,generation:t.generation})}else if(t.type==="optimize"){N=!1,J=t.maxShipRange,z=t.shipTradeDistance,U=t.minGateHopsSaved;const d=H(t.path,t.passes,t.timePerPassSec,t.returnToStart,o=>b({type:"progress",message:o}),!!t.debug),c=I(d,t.returnToStart);b({type:"optimizeResult",path:d,shipDistance:c.shipDistance,shipJumps:c.shipJumps,totalDistance:c.totalDistance,generation:t.generation}),b({type:"optimizeDone",reason:"passes complete",generation:t.generation,path:d,shipDistance:c.shipDistance,shipJumps:c.shipJumps,totalDistance:c.totalDistance})}else if(t.type==="optimizeContinuous")_=t.generation,N=!1,J=t.maxShipRange,z
1=t.shipTradeDistance,U=t.minGateHopsSaved,V(t.path,t.maxTimeSec,t.stallTimeoutSec,t.returnToStart,t.generation,!!t.debug);else if(t.type==="updateChampion"){if(_!==void 0&&t.generation!==void 0&&t.generation!==_)return;if(!x){x=t.path.slice(),S=null;return}const d=I(t.path,!0);(!S||d.shipDistance<S.shipDistance||d.shipDistance===S.shipDistance&&d.shipJumps<S.shipJumps||d.shipDistance===S.shipDistance&&d.shipJumps===S.shipJumps&&d.totalDistance<S.totalDistance)&&(x=t.path.slice(),S=d,M=Date.now())}else t.type==="stop"&&(N=!0,b({type:"stopped"}))}})();
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.