PageSourceSearch

https://www.r0y.xyz/assets/OilCommoditiesTerminalWidget-DvAw4P8c.js

js r0y.xyz collected 2026-10-04 22:00:52 UTC 21,853 bytes, 35 lines download raw bytes

1import{r as w,j as a,__tla as re}from"./vendor-BvzV4098.js";import{f as P,__tla as oe}from"./econLiveData-ObD-Miqf.js";import{W as ce,u as de,__tla as he}from"./widgetDataNav-Bpr3bh_v.js";import{__tla as xe}from"./fetchEconData-CGEl_7n0.js";import{__tla as pe}from"./index-DkXTyYOv.js";import{__tla as fe}from"./jspdf-CfiETrc0.js";import{__tla as me}from"./framer-motion-C706ZmUs.js";import"./html2canvas-B0tyYwQk.js";import"./r0yEconNormalize-bUJfz_MD.js";let A,ve=Promise.all([(()=>{try{return re}catch{}})(),(()=>{try{return oe}catch{}})(),(()=>{try{return he}catch{}})(),(()=>{try{return xe}catch{}})(),(()=>{try{return pe}catch{}})(),(()=>{try{return fe}catch{}})(),(()=>{try{return me}catch{}})()]).then(async()=>{const V=[["1990-07","1991-03"],["2001-03","2001-11"],["2007-12","2009-06"],["2020-02","2020-04"]],z=[["1990-08","Gulf War"],["2008-06","2008 peak"],["2014-11","Shale glut"],["2020-04","COVID"],["2022-06","Ukraine"]];function L(n){const o=n.slice(0,10);return o.length>=7?o.slice(0,7):o}function _(n){const o=n.filter(r=>Number.isFinite(r.value)&&r.value>0).sort((r,e)=>r.date.localeCompare(e.date)),d=new Map;for(const r of o){const e=L(r.date),l=d.get(e);(!l||r.date>=l.date)&&d.set(e,r)}const h=new Map;for(const[r,e]of d)h.set(r,e.value);return h}function H(n){const o=[];for(let e=1;e<n.length;e++)o.push({d:n[e].d,r:n[e].nom/n[e-1].nom-1});const d=12,h=o.map((e,l)=>{if(l<d)return null;let i=0,c=0;for(let x=l-d+1;x<=l;x++)c+=o[x].r;c/=d;for(let x=l-d+1;x<=l;x++)i+=(o[x].r-c)**2;return Math.sqrt(i/d)*Math.sqrt(12)*100}),r=Math.sqrt(o.reduce((e,l)=>
1e+l.r*l.r,0)/o.length)*Math.sqrt(12)*100;return{rets:o,rollingVol:h,annVol:r}}function U(n,o,d,h){const r=[...n.keys()].sort().filter(t=>t>="1986-01");if(r.length<24)return null;const e=r[r.length-1],l=h.get(e);if(!l)return null;const i=r.map(t=>{const T=n.get(t),j=h.get(t),N=j&&j>0?T*(l/j):null;return{d:t,nom:T,real:N}}),c=r.filter(t=>o.has(t)).map(t=>({d:t,p:o.get(t)})),x=[...d.keys()].sort().map(t=>({d:t,p:d.get(t)})),u={};c.forEach(t=>{u[t.d]=t.p});const g={};x.forEach(t=>{g[t.d]=t.p});const k=i.filter(t=>t.real!=null),b=k[k.length-1]??i[i.length-1],v=[...k].sort((t,T)=>T.real-t.real)[0]??b,{rets:s,rollingVol:y,annVol:p}=H(i);return{wti:i,brent:c,gas:x,bMap:u,gMap:g,cpiBase:e,rets:s,rollingVol:y,annVol:p,latest:i[i.length-1],latestReal:b,hiReal:v,asOf:e}}async function X(){const[n,o,d,h]=await Promise.all([P("DCOILWTICO",2e3),P("DCOILBRENTEU",2e3),P("DHHNGSP",2e3).catch(()=>[]),P("cpi",2e3)]),r=_(n),e=_(o),l=_(d),i=_(h);return U(r,e,l,i)}function D(n){return n.wti.filter(o=>o.real!=null)}function G(){const n=[],o=[],d=[];let h=18.95,r=18.5,e=2.5;for(let s=1986;s<=2026;s++)for(let y=1;y<=12;y++){const p=`${s}
1-${String(y).padStart(2,"0")}`,t=(s-1986)/40;h+=Math.sin(t*Math.PI*3)*2+Math.sin(y*.5)*1.5+(s>=2008&&s<2010?5:0),h=Math.max(10,Math.min(140,h)),r=h*(1.02+Math.sin(t)*.05),s>=1997&&(e=2+Math.sin(t*2)*1.5+(s>=2022?2:0),e=Math.max(1.5,Math.min(10,e)),d.push({d:p,p:e})),(s>=1987||y>=5)&&o.push({d:p,p:r});const T=h*(2.8+t*.4);n.push({d:p,nom:h,real:T})}const l={};o.forEach(s=>{l[s.d]=s.p});const i={};d.forEach(s=>{i[s.d]=s.p});const c=n.filter(s=>s.real!=null),x=n[n.length-1],u=c[c.length-1],g=[...c].sort((s,y)=>y.real-s.real)[0],{rets:k,rollingVol:b,annVol:v}=H(n);return{wti:n,brent:o,gas:d,bMap:l,gMap:i,cpiBase:x.d,rets:k,rollingVol:b,annVol:v,latest:x,latestReal:u,hiReal:g,asOf:x.d}}const B="ui-monospace,Menlo,monospace";function I(n){const o=Math.min(window.devicePixelRatio,2),d=n.clientWidth,h=n.clientHeight;(n.width!==d*o||n.height!==h*o)&&(n.width=d*o,n.height=h*o);const r=n.getContext("2d");return r.setTransform(o,0,0,o,0,0),{W:d,H:h,ctx:r}}function $(n,o,d,h,r){n.fillStyle="rgba(255,255,255,0.045)",V.forEach(([e,l])=>{const i=d.findIndex(g=>g.d>=e),c=d.findIndex(g=>g.d>=l);if(i<0)return;const x=o(i),u=o(c<0?d.length-1:c);n.fillRect(x,h,u-x,r-h)})}function O(n,o,d,h,r,e=5){n.fillStyle="#6c6c76",n.textAlign="center",n.textBaseline="top";for(let l=1990;l<=2025;l+=e){const i=d.findIndex(c=>c.d.slice(0,4)===String(l));i>=0&&n.fillText(String(l),o(i),r-h+5)}}function q(n,o,d){const{W:h,H:r,ctx:e}=I(n);e.clearRect(0,0,h,r);const l=40,i=14,c=16,x=22,u=o.wti,g=D(o),k=u.length,b=Math.max(...u.map(t=>Math.max(t.nom,t.real??0)))*1.05,v=t=>l+(h-l-i)*t/(k-1),s=t=>c+(r-c-x)*(1-t/b);$(e,v,u,c,r-x),e.font="9px "+B,e.strokeStyle="rgba(255,255,255,0.05)",e.fillStyle="#6c6c76",e.textAlign="right",e.textBaseline="middle";for(let t=0;t<=b;t+=40)e.beginPath(),e.moveTo(l,s(t)),e.lineTo(h-i,s(t)),e.stroke(),e.fillText("$"+t,l-5,s(t));z.forEach(([t,T])=>{const j=u.findIndex(m=>m.d===t);if(j<0)return;const N=v(j);e.strokeStyle="rgba(255,255,255,0.1)",e.beginPath(),e.moveTo(N,c),e.lineTo(N,r-x),e.stroke(),e.fillStyle="#6c6c76",e.save(),e.translate(N,c+3),e.textAlign="left",e.textBaseline="middle",e.font="8px "+B,e.fillText(T,3,0),e.restore()}),e.fillStyle="rgba(251,146,60,0.07)",e.beginPath();let y=!1;g.forEach(t=>{const T=u.indexOf(t),j=v(T),N=s(t.real);y?e.lineTo(j,N):(e.moveTo(j,r-x),e.lineTo(j,N),y=!0)}),e.lineTo(v(u.indexOf(g[g.length-1])),r-x),e.closePath(),e.fill(),e.strokeStyle="#fb923c",e.lineWidth=1.5,e.beginPath(),g.forEach((t,T)=>{const j=u.indexOf(t),N=v(j),m=s(t.real);T?e.lineTo(N,m):e.moveTo(N,m)}),e.stroke(),e.strokeStyle="#84cc16",e.lineWidth=1.4,e.beginPath(),u.forEach((t,T)=>{const j=v(T),N=s(t.nom);T?e.lineTo(j,N):e.moveTo(j,N)}),e.stroke();const p=o.cpiBase.slice(0,4);if(e.fillStyle="#84cc16",e.textAlign="left",e.fillText("nominal",l+4,r-x-10),e.fillStyle="#fb923c",e.fillText("real ("+p+"$)",l+52,r-x-10),O(e,v,u,x,r),d>=0&&d<k){const t=v(d);e.strokeStyle="rgba(255,255,255,0.4)",e.beginPath(),e.moveTo(t,c),e.lineTo(t,r-x),e.stroke()}return{X:v,N:k,D:u,mode:"ov"}}function Y(n,o,d){const h=d.bMap,r=d.wti.filter(m=>h[m.d]!=null),{W:e,H:l,ctx:i}=I(n);i.clearRect(0,0,e,l);const c=40,x=14,u=16,g=22,k=r.length,b=Math.max(...r.map(m=>Math.max(m.nom,h[m.d])))*1.05,v=m=>c+(e-c-x)*m/(k-1),s=m=>u+(l-u-g)*(1-m/b);$(i,v,r,u,l-g),i.font="9px "+B,i.strokeStyle="rgba(255,255,255,0.05)",i.fillStyle="#6c6c76",i.textAlign="right",i.textBaseline="middle";for(let m=0;m<=b;m+=40)i.beginPath(),i.moveTo(c,s(m)),i.lineTo(e-x,s(m)),i.stroke(),i.fillText("$"+m,c-5,s(m));i.strokeStyle="#22d3ee",i.lineWidth=1.4,i.beginPath(),r.forEach((m,f)=>{const S=v(f),M=s(h[m.d]);f?i.lineTo(S,M):i.moveTo(S,M)}),i.stroke(),i.strokeStyle="#84cc16",i.lineWidth=1.4,i.beginPath(),r.forEach((m,f)=>{const S=v(f),M=s(m.nom);f?i.lineTo(S,M):i.moveTo(S,M)}),i.stroke(),i.fillStyle="#84cc16",i.textAlign="left",i.fillText("WTI",c+4,u+6),i.fillStyle="#22d3ee",i.fillText("Brent",c+40,u+6),O(i,v,r,g,l);const y=I(o),p=y.ctx;p.clearRect(0,0,y.W,y.H);const t=r.map(m=>m.nom-h[m.d]),T=Math.max(...t.map(Math.abs))*1.1,j=m=>c+(y.W-c-x)*m/(k-1),N=m=>8+(y.H-26)*(1-(m+T)/(2*T));return p.strokeStyle="rgba(255,255,255,0.05)",[-T/2,0,T/2].forEach(m=>
1{p.beginPath(),p.moveTo(c,N(m)),p.lineTo(y.W-x,N(m)),p.stroke(),p.fillStyle="#6c6c76",p.font="8px "+B,p.textAlign="right",p.textBaseline="middle",p.fillText((m>0?"+":"")+m.toFixed(0),c-5,N(m))}),p.beginPath(),t.forEach((m,f)=>{const S=j(f),M=N(m);f?p.lineTo(S,M):p.moveTo(S,M)}),p.lineTo(j(k-1),N(0)),p.lineTo(j(0),N(0)),p.closePath(),p.fillStyle="rgba(132,204,22,0.12)",p.fill(),p.strokeStyle="#84cc16",p.lineWidth=1.2,p.beginPath(),t.forEach((m,f)=>{const S=j(f),M=N(m);f?p.lineTo(S,M):p.moveTo(S,M)}),p.stroke(),{X:v,N:k,D:r,mode:"sp"}}function K(n,o,d){const h=d.rets,r=d.rollingVol,e=d.annVol,{W:l,H:i,ctx:c}=I(n);c.clearRect(0,0,l,i);const x=42,u=14,g=18,k=24,b=new Array(41).fill(0);h.forEach(f=>{const S=Math.max(0,Math.min(40,Math.round(f.r*100)+20));b[S]++});const v=Math.max(...b),s=f=>x+(l-x-u)*f/41,y=f=>g+(i-g-k)*(1-f/v);c.font="9px "+B,b.forEach((f,S)=>{const M=S-20;c.fillStyle=M>=0?"#22c55e":"#ef4444",c.globalAlpha=.6,c.fillRect(s(S)+.5,y(f),(l-x-u)/41-1,i-k-y(f)),c.globalAlpha=1}),c.strokeStyle="rgba(255,255,255,0.25)",c.beginPath(),c.moveTo(s(20),g),c.lineTo(s(20),i-k),c.stroke(),c.fillStyle="#6c6c76",c.textAlign="center",c.textBaseline="top";for(let f=-20;f<=20;f+=10)c.fillText((f>0?"+":"")+f+"%",s(f+20),i-k+5);c.textAlign="left",c.fillStyle="#43434c",c.fillText("Monthly return distribution \xB7 ann. vol "+e.toFixed(0)+"%",x+4,g-14);const p=I(o),t=p.ctx;t.clearRect(0,0,p.W,p.H);const T=Math.max(...r.filter(f=>f!=null))*1.1,j=f=>x+(p.W-x-u)*f/(h.length-1),N=f=>8+(p.H-26)*(1-f/T);t.strokeStyle="rgba(255,255,255,0.05)",[0,T/2,T].forEach(f=>{t.beginPath(),t.moveTo(x,N(f)),t.lineTo(p.W-u,N(f)),t.stroke(),t.fillStyle="#6c6c76",t.font="8px "+B,t.textAlign="right",t.textBaseline="middle",t.fillText(f.toFixed(0)+"%",x-5,N(f))}),t.strokeStyle="#fb923c",t.lineWidth=1.2,t.beginPath();let m=!1;r.forEach((f,S)=>{if(f==null)return;const M=j(S),F=N(f);m?t.lineTo(M,F):(t.moveTo(M,F),m=!0)}),t.stroke(),t.fillStyle="#6c6c76",t.textAlign="center",t.textBaseline="top";for(let f=1990;f<=2025;f+=10){const S=h.findIndex(M=>M.d.slice(0,4)===String(f));S>=0&&t.fillText(String(f),j(S),p.H-14)}return{}}function J(n,o){const d=o.gMap,h=o.wti.filter(s=>d[s.d]!=null).map(s=>({d:s.d,ratio:s.nom/d[s.d]})),{W:r,H:e,ctx:l}=I(n);l.clearRect(0,0,r,e);const i=40,c=14,x=18,u=22,g=h.length,k=Math.max(...h.map(s=>s.ratio))*1.05,b=s=>i+(r-i-c)*s/(g-1),v=s=>x+(e-x-u)*(1-s/k);$(l,b,h,x,e-u),l.font="9px "+B,l.strokeStyle="rgba(255,255,255,0.05)",l.fillStyle="#6c6c76",l.textAlign="right",l.textBaseline="middle";for(let s=0;s<=k;s+=10)l.beginPath(),l.moveTo(i,v(s)),l.lineTo(r-c,v(s)),l.stroke(),l.fillText(s+"\xD7",i-5,v(s));l.strokeStyle="#22c55e",l.setLineDash([5,4]),l.beginPath(),l.moveTo(i,v(5.8)),l.lineTo(r-c,v(5.8)),l.stroke(),l.setLineDash([]),l.fillStyle="#22c55e",l.textAlign="left",l.fillText("energy parity 5.8\xD7 (per BTU)",i+4,v(5.8)-8),l.fillStyle="rgba(168,85,247,0.1)",l.beginPath(),l.moveTo(b(0),e-u),h.forEach((s,y)=>l.lineTo(b(y),v(s.ratio))),l.lineTo(b(g-1),e-u),l.closePath(),l.fill(),l.strokeStyle="#a855f7",l.lineWidth=1.6,l.beginPath(),h.forEach((s,y)=>{const p=b(y),t=v(s.ratio);y?l.lineTo(p,t):l.moveTo(p,t)}),l.stroke(),l.fillStyle="#ededee",l.textAlign="left",l.textBaseline="top",l.fillText("WTI ($/bbl) \xF7 Henry Hub ($/MMBtu) \xB7 high = oil rich vs gas",i+4,x+2),l.fillStyle="#6c6c76",l.textAlign="center",l.textBaseline="top";for(let s=2e3;s<=2025;s+=5){const y=h.findIndex(p=>p.d.slice(0,4)===String(s));y>=0&&l.fillText(String(s),b(y),e-u+5)}return{X:b,N:g,D:h,mode:"ratio"}}const Q={overview:"WTI nominal vs real + events",spread:"WTI vs Brent + spread",returns:"Return distribution + vol",ratio:"Oil-to-gas price ratio"},Z={overview:"WTI crude nominal vs inflation-adjusted (current dollars), with major supply shocks and NBER recessions marked.",spread:"WTI and Brent benchmarks with the WTI\u2212Brent spread below \u2014 the spread blew out after 2011 when US shale flooded inland markets.",returns:"Distribution of monthly WTI returns (fat-tailed) and rolling 12-month annualized volatility \u2014 oil is among the most volatile macro assets.",ratio:"WTI per barrel divided by Henry Hub gas per MMBtu. Far above the ~5.8\xD7 energy-parity line means oil is expensive relative to gas per unit of energy."};function ee(n,o,d,h,r){return n==="overview"?q(o,h,r):n==="spread"?Y(o,d,h):n==="returns"?(K(o,d,h),{}):J(o,h)}const te=[{id:"DCOILWTICO",provider:"FRED",description:"Cushing OK WTI Spot Price FOB (Dollars per Barrel)",endpoint:"/econ-fetch?alias=DCOILWTICO",cadence:"Daily"},{id:"DCOILBRENTEU",provider:"FRED",description:"Europe Brent Spot Price FOB (Dollars per Barrel)",endpoint:"/econ-fetch?alias=DCOILBRENTEU",cadence:"Daily"},{id:"DHHNGSP",provider:"FRED",description:"Henry Hub Natural Gas Spot Price (Dollars per Million Btu)",endpoint:"/econ-fetch?alias=DHHNGSP",cadence:"Daily"},{id:"CPIAUCSL",provider:"BLS / FRED",description:"CPI-U for inflation-adjusted WTI in current dollars",endpoint:"/econ-fetch?alias=cpi",cadence:"Monthly"}],le=`
2  .oil-vt { --bg:#09090b;--panel:#0c0c0f;--line:rgba(255,255,255,0.07);--line-2:rgba(255,255,255,0.13);--text:#ededee;--muted:#6c6c76;--muted-2:#43434c;--wti:#84cc16;--brent:#22d3ee;--real:#fb923c;--gas:#a855f7;--up:#22c55e;--down:#ef4444;--mono:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
3    box-sizing:border-box;height:100%;min-height:420px;background:var(--bg);color:var(--text);font-family:var(--mono);-webkit-font-smoothing:antialiased;overflow:hidden;display:flex;flex-direction:column;
4  }
5  .oil-vt *{box-sizing:border-box}
6  .oil-vt header{display:flex;align-items:center;gap:16px;padding:10px 18px;border-bottom:1px solid var(--line);flex-shrink:0}
7  .oil-vt .ttl{display:flex;flex-direction:column;gap:2px}
8  .oil-vt .ttl h1{font-size:11px;font-weight:600;letter-spacing:.2em;text-transform:uppercase;margin:0}
9  .oil-vt .ttl .s{font-size:8px;letter-spacing:.13em;text-transform:uppercase;color:var(--muted)}
10  .oil-vt .tabs{display:flex;gap:2px}
11  .oil-vt .tabs button{background:transparent;color:var(--muted);border:1px solid transparent;border-radius:3px;
11cursor:pointer;font-family:var(--mono);font-size:9px;letter-spacing:.06em;text-transform:uppercase;padding:7px 11px}
12  .oil-vt .tabs button:hover{color:var(--text)}
13  .oil-vt .tabs button.on{background:rgba(255,255,255,0.06);color:var(--text);border-color:var(--line-2)}
14  .oil-vt .spacer{flex:1}
15  .oil-vt .hstats{display:flex;gap:16px}
16  .oil-vt .hstats .b{display:flex;flex-direction:column;align-items:flex-end;gap:1px}
17  .oil-vt .hstats .l{font-size:7px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
18  .oil-vt .hstats .n{font-size:15px;font-weight:600;font-variant-numeric:tabular-nums}
19  .oil-vt .body{flex:1;display:flex;min-height:0}
20  .oil-vt .main{flex:1;display:flex;flex-direction:column;min-width:0}
21  .oil-vt .canvaswrap{flex:1;position:relative;min-height:0}
22  .oil-vt canvas{display:block;width:100%;height:100%}
23  .oil-vt .sub{height:120px;border-top:1px solid var(--line);position:relative;flex-shrink:0}
24  .oil-vt .sub.hide{display:none}
25  .oil-vt .lbl{position:absolute;top:9px;left:14px;font-size:8px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);z-index:2;pointer-events:none}
26  .oil-vt aside{width:242px;border-left:1px solid var(--line);padding:14px;overflow-y:auto;flex:0 0 auto}
27  .oil-vt .sect{font-size:8px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);margin:2px 0 10px}
28  .oil-vt .sect:not(:first-child){margin-top:16px}
29  .oil-vt .line{display:flex;justify-content:space-between;padding:6px 0;border-top:1px solid var(--line);font-size:10.5px}
30  .oil-vt .line .k{color:var(--muted)}
31  .oil-vt .line .v{font-variant-numeric:tabular-nums;font-weight:600}
32  .oil-vt .foot{padding:7px 18px;border-top:1px solid var(--line);font-size:8px;color:var(--muted-2);flex-shrink:0}
33  .oil-vt .tip{position:fixed;pointer-events:none;z-index:20;background:#000;border:1px solid var(--line-2);border-radius:2px;padding:7px 10px;font-size:10px;white-space:nowrap;line-height:1.6}
34  .oil-vt .tip b{color:#fff}
35`,ne=[{id:"overview",label:"Overview"},{id:"spread",label:"WTI\u2013Brent"},{id:"returns",label:"Returns & vol"},{id:"ratio",label:"Oil/Gas ratio"}],C={spread:"WTI \u2212 Brent spread ($/bbl)",returns:"Rolling 12-month annualized volatility"};function ie({data:n}){var u,g,k;const o=n.latest,d=n.bMap,h=n.gMap[o.d]??((u=n.gas[n.gas.length-1])==null?void 0:u.p)??0,r=d[o.d]!=null?o.nom-d[o.d]:null,e=D(n),l=[...e].sort((b,v)=>b.real-v.real)[0],i=[...n.rets].sort((b,v)=>v.r-b.r)[0],c=[...n.rets].sort((b,v)=>b.r-v.r)[0],x=n.rollingVol[n.rollingVol.length-1];return a.jsxs(a.Fragment,{children:[a.jsx("div",{className:"sect",children:"Spot"}),a.jsxs("div",{className:"line",children:[a.jsx("span",{className:"k",children:"WTI"}),a.jsxs("span",{className:"v",children:["$",o.nom.toFixed(2)]})]}),a.jsxs("div",{className:"line",children:[a.jsx("span",{className:"k",children:"Brent"}),a.jsxs("span",{className:"v",children:["$",(d[o.d]??0).toFixed(2)]})]}),a.jsxs("div",{className:"line",children:[a.jsx("span",{className:"k",children:"WTI\u2212Brent"}),a.jsx("span",{className:"v",children:r!=null?(r>=0?"+":"")+r.toFixed(2):"\u2014"})]}),a.jsxs("div",{className:"line",children:[a.jsx("span",{className:"k",children:"Henry Hub gas"}),a.jsxs("span",{className:"v",children:["$",h.toFixed(2)]})]}),a.jsxs("div",{className:"line",children:[a.jsx("span",{className:"k",children:"Oil/gas ratio"}),a.jsxs("span",{className:"v",children:[(o.nom/h).toFixed(1),"\xD7"]})]}),a.jsxs("div",{className:"sect",children:["Real (in ",n.cpiBase.slice(0,4)," $)"]}),a.jsxs("div",{className:"line",children:[a.jsx("span",{className:"k",children:"WTI real"}),a.jsxs("span",{className:"v",children:["$",((g=n.latestReal.real)==null?void 0:g.toFixed(0))??"\u2014"]})]}),a.jsxs("div",{className:"line",children:[a.jsx("span",{className:"k",children:"Real all-time high"}),a.jsxs("span",{className:"v",children:["$",(k=n.hiReal.real)==null?void 0:k.toFixed(0)," (",n.hiReal.d.slice(0,4),")"]})]}),l&&a.jsxs("div",{className:"line",children:[a.jsx("span",{className:"k",children:"Real low"}),a.jsxs("span",{className:"v",children:["$",l.real.toFixed(0)," (",l.d.slice(0,4),")"]})]}),a.jsxs("div",{className:"line",children:[a.jsx("span",{className:"k",children:"Real average"}),a.jsxs("span",{className:"v",children:["$",(e.reduce((b,v)=>b+v.real,0)/e.length).toFixed(0)]})]}),a.jsx("div",{className:"sect",children:"Risk"}),a.jsxs("div",{className:"line",children:[a.jsx("span",{className:"k",children:"Ann. volatility"}),a.jsxs("span",{className:"v",children:[n.annVol.toFixed(0),"%"]})]}),a.jsxs("div",{className:"line",children:[a.jsx("span",{className:"k",children:"Rolling 12m vol"}),a.jsxs("span",{className:"v",children:[(x??0).toFixed(0),"%"]})]}),i&&a.jsxs("div",{className:"line",children:[a.jsx("span",{className:"k",children:"Best month"}),a.jsxs("span",{className:"v",style:{color:"var(--up)"},children:["+",(i.r*100).toFixed(0),"% (",i.d.slice(0,7),")"]})]}),c&&a.jsxs("div",{className:"line",children:[a.jsx("span",{className:"k",children:"Worst month"}),a.jsxs("span",{className:"v",style:{color:"var(--down)"},children:[(c.r*100).toFixed(0),"% (",c.d.slice(0,7),")"]})]})]})}function ae(){const[n,o]=w.useState(G()),[d,h]=w.useState(!1),r=w.useCallback(async()=>{try{const e=await X();e&&(o(e),h(!0))}catch{}},[]);return w.useEffect(()=>{r()},[r]),de(r,{debounceMs:8e3}),{data:n,live:d}}A=function(){var p;const{data:n,live:o}=ae(),[d,h]=w.useState("overview"),[r,e]=w.useState(-1),[l,i]=w.useState(null),c=w.useRef(null),x=w.useRef(null),u=w.useRef({}),g=n.latest,k=n.rollingVol[n.rollingVol.length-1]??n.annVol,b=n.asOf.slice(0,4),v=d==="spread"||d==="returns",s=w.useCallback(()=>{const t=c.current,T=x.current;!t||!T||(u.current=ee(d,t,T,n,r))},[d,n,r]);w.useEffect(()=>{s()},[s]),w.useEffect(()=>{const t=()=>s();return window.addEventListener("resize",t),()=>window.removeEventListener("resize",t)},[s]);const y=t=>{const T=u.current,j=T.mode;if(!j||j!=="ov"&&j!=="sp"&&j!=="ratio"){i(null);return}const N=T.X,m=T.N,f=T.D;if(!N||!m||!f)return;const S=c.current,M=S.getBoundingClientRect(),F=t.clientX-M.left,E=Math.round((F-40)/(S.clientWidth-54)*(m-1));if(E<0||E>=m){e(-1),i(null);return}e(E);const se=n.bMap;if(j==="ratio"){const R=f[E];i({x:t.clientX+13,y:t.clientY+13,html:`<b>${R.d}</b><br>ratio <b>${R.ratio.toFixed(1)}\xD7</b>`});return}const W=f[E];if(j==="sp"){const R=se[W.d];i({x:t.clientX+13,y:t.clientY+13,html:`<b>${W.d}</b><br>WTI <b style="color:var(--wti)">$${W.nom.toFixed(2)}</b><br>Brent <b style="color:var(--brent)">$${R.toFixed(2)}</b><br>spread ${W.nom-R>=0?"+":""}${(W.nom-R).toFixed(2)}`});return}i({x:t.clientX+13,y:t.clientY+13,html:`<b>${W.d}</b><br>nominal <b style="color:var(--wti)">$${W.nom.toFixed(2)}</b>`+(W.real!=null?`<br>real <b style="color:var(--real)">$${W.real.toFixed(2)}</b>`:"")})};return a.jsxs(ce,{title:"Oil & Commodities Terminal",subtitle:"WTI \xB7 Brent \xB7 Henry Hub \xB7 real prices \xB7 FRED energy series",asOf:n.asOf,sources:te,children:[a.jsx("style",{children:le}),a.jsxs("div",{className:"oil-vt",children:[a.jsxs("header",{children:[a.jsxs("div",{className:"ttl",children:[a.jsx("h1",{children:"Oil & Commodities Terminal"}),a.jsxs("div",{className:"s",children:["WTI \xB7 Brent \xB7 Henry Hub \xB7 1986\u2013",b," \xB7 ",o?"real data":"cached"]})]}),a.jsx("div",{className:"tabs",children:ne.map(t=>a.jsx("button",{type:"button",className:d===t.id?"on":"",onClick:()=>
35{h(t.id),e(-1),i(null)},children:t.label},t.id))}),a.jsx("div",{className:"spacer"}),a.jsxs("div",{className:"hstats",children:[a.jsxs("div",{className:"b",children:[a.jsx("span",{className:"l",children:"WTI"}),a.jsxs("span",{className:"n",style:{color:"var(--wti)"},children:["$",g.nom.toFixed(0)]})]}),a.jsxs("div",{className:"b",children:[a.jsx("span",{className:"l",children:"Brent"}),a.jsx("span",{className:"n",style:{color:"var(--brent)"},children:n.bMap[g.d]?"$"+n.bMap[g.d].toFixed(0):"\u2014"})]}),a.jsxs("div",{className:"b",children:[a.jsx("span",{className:"l",children:"Real ATH"}),a.jsxs("span",{className:"n",children:["$",((p=n.hiReal.real)==null?void 0:p.toFixed(0))??"\u2014"]})]}),a.jsxs("div",{className:"b",children:[a.jsx("span",{className:"l",children:"12m vol"}),a.jsxs("span",{className:"n",children:[k.toFixed(0),"%"]})]})]})]}),a.jsxs("div",{className:"body",children:[a.jsxs("div",{className:"main",children:[a.jsxs("div",{className:"canvaswrap",children:[a.jsx("div",{className:"lbl",children:Q[d]}),a.jsx("canvas",{ref:c,onMouseMove:y,onMouseLeave:()=>{e(-1),i(null)}})]}),a.jsxs("div",{className:`sub${v?"":" hide"}`,children:[v&&C[d]?a.jsx("div",{className:"lbl",children:C[d]}):null,a.jsx("canvas",{ref:x})]})]}),a.jsx("aside",{children:a.jsx(ie,{data:n})})]}),a.jsx("div",{className:"foot",children:Z[d]}),l?a.jsx("div",{className:"tip",style:{left:l.x,top:l.y,display:"block"},dangerouslySetInnerHTML:{__html:l.html}}):null]})]})}});export{ve as __tla,A as default};

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.