1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[41050],{18085:(e,t,r)=>{r.d(t,{A:()=>s});let s=(0,r(71847).A)("Send",[["path",{d:"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z",key:"1ffxy3"}],["path",{d:"m21.854 2.147-10.94 10.939",key:"12cjpa"}]])},33789:(e,t,r)=>{r.d(t,{p:()=>o});var s=r(95155),a=r(12115),n=r(25016);let o=a.forwardRef((e,t)=>{let{className:r,type:a,...o}=e;return(0,s.jsx)("input",{type:a,className:(0,n.cn)("flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",r),ref:t,...o})});o.displayName="Input"},41050:(e,t,r)=>{r.r(t),r.d(t,{default:()=>b});var s=r(95155),a=r(12115),n=r(38580),o=r(97003),i=r(33789),c=r(1524),l=r(30814),d=r(56154),m=r(80534),u=r(65229),h=r(35299),x=r(18085);function p(e){let{className:t="w-6 h-6"}=e;return(0,s.jsxs)("svg",{viewBox:"0 0 48 48",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:t,children:[(0,s.jsx)("circle",{cx:"24",cy:"24",r:"22",stroke:"currentColor",strokeWidth:"3",fill:"none"}),(0,s.jsx)("path",{d:"M30 16.5C28.2 14.9 25.8 14 23.5 14C18.3 14 14 18.5 14 24C14 29.5 18.3 34 23.5 34C25.8 34 28.2 33.1 30 31.5",stroke:"currentColor",strokeWidth:"3",strokeLinecap:"round"}),(0,s.jsx)("circle",{cx:"35",cy:"24",r:"2.5",fill:"currentColor"})]})}function f(e){let{matches:t,userStats:r,userName:f="Player",onClose:g,initialMessage:b}=e,[y,w]=(0,a.useState)([{id:"welcome",content:"Hi ".concat(f,"! \uD83D\uDC4B I'm your AI squash coach. I've analyzed your ").concat(t.length," uploaded matches and I'm here to help you improve. Ask me anything about your performance, specific matches, or get personalized training advice!"),role:"assistant",timestamp:new Date}]),[j,v]=(0,a.useState)(""),[N,k]=(0,a.useState)(!1),D=(0,a.useRef)(null),C=(0,a.useRef)(null),M=(0,a.useRef)(!1);(0,a.useEffect)(()=>{b&&!M.current&&(M.current=!0,v(b),setTimeout(()=>{v("");let e={id:Date.now().toString(),content:b,role:"user",timestamp:new Date};w(t=>[...t,e]),k(!0),(async()=>{try{let e=await fetch("/api/chat",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:b,context:""})});if(!e.ok)throw Error();let t=await e.json();w(e=>[...e,{id:Date.now().toString(),content:t.message||"I couldn't generate a response.",role:"assistant",timestamp:new Date}])}catch(e){w(e=>[...e,{id:Date.now().toString(),content:"Sorry, I couldn't connect. Please try again.",role:"assistant",timestamp:new Date}])}finally{k(!1)}})()},100))},[]),(0,a.useEffect)(()=>{D.current&&(D.current.scrollTop=D.current.scrollHeight)},[y]);let S=async()=>{if(!j.trim()||N)return;(0,n.ck)(void 0,j.trim());let e={id:Date.now().toString(),content:j.trim(),role:"user",timestamp:new Date};w(t=>[...t,e]),v(""),k(!0);try{let s=await fetch("/api/chat",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({messages:y.map(e=>({role:e.role,content:e.content})).concat([{role:"user",content:e.content}]),matchContext:(()=>{if(!t||0===t.length)return"";let e=t.slice(0,10),r="Total Matches: ".concat(t.length,"\n\n");return r+="Recent Matches:\n",e.forEach((e,t)=>{let s="".concat(t+1,". ").concat("practice"===e.matchType?"Practice Session":"vs ".concat(e.opponent)),a=e.result?" - Result: ".concat(e.result):"",n=e.date?" - Date: ".concat(new Date(e.date).toLocaleDateString()):"",o=e.duration?" - Duration: ".concat(Math.round(e.duration/60),"min"):"";if(r+="".concat(s).concat(a).concat(n).concat(o,"\n"),e.analysisData){let t=e.analysisData;t.shotDistribution&&(r+=" Shot Distribution: Cross Court ".concat(Math.round(t.shotDistribution.crossCourt),"%, Straight Drive ").concat(Math.round(t.shotDistribution.straightDrive),"%, Drop ").concat(Math.round(t.shotDistribution.drop),"%\n")),t.speedMetrics&&(r+=" Avg Speed: ".concat(Math.round(t.speedMetrics.averageSpeed)," km/h\n"))}r+="\n"}),r})(),userStats:(()=>
1{if(!r)return"";let e="Overall Performance Stats:\n";if(r.shotDistribution&&(e+="Shot Distribution: Cross Court ".concat(Math.round(r.shotDistribution.crossCourt),"%, Straight Drive ").concat(Math.round(r.shotDistribution.straightDrive),"%, Drop ").concat(Math.round(r.shotDistribution.drop),"%, Boast ").concat(Math.round(r.shotDistribution.boast),"%\n")),r.speedMetrics&&(e+="Speed: Avg ".concat(Math.round(r.speedMetrics.averageSpeed)," km/h, Max ").concat(Math.round(r.speedMetrics.maxSpeed)," km/h\n")),r.shotQualityMetrics){let t=r.shotQualityMetrics.forehand,s=r.shotQualityMetrics.backhand;e+="Forehand: Technique ".concat(Math.round(t.technique),"%, Consistency ").concat(Math.round(t.consistency),"%\n"),e+="Backhand: Technique ".concat(Math.round(s.technique),"%, Consistency ").concat(Math.round(s.consistency),"%\n")}return e})()})});if(!s.ok)throw Error("Failed to get response");let a=await s.json(),n={id:(Date.now()+1).toString(),content:a.message,role:"assistant",timestamp:new Date};w(e=>[...e,n])}catch(t){console.error("Chat error:",t);
1let e={id:(Date.now()+1).toString(),content:"Sorry, I encountered an error. Please try again.",role:"assistant",timestamp:new Date};w(t=>[...t,e])}finally{var s;k(!1),null==(s=C.current)||s.focus()}},A=[{icon:c.A,text:"Analyze my recent performance",color:"text-blue-600"},{icon:l.A,text:"What should I focus on improving?",color:"text-green-600"},{icon:d.A,text:"Give me training drills",color:"text-yellow-600"},{icon:m.A,text:"Compare my matches",color:"text-purple-600"}];return(0,s.jsxs)("div",{className:"flex flex-col h-full",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between px-4 py-3 bg-gradient-to-r from-primary/15 to-primary/5 border-b border-primary/20",children:[(0,s.jsxs)("div",{className:"flex items-center gap-3",children:[(0,s.jsxs)("div",{className:"relative",children:[(0,s.jsx)("div",{className:"w-10 h-10 bg-gradient-to-br from-primary to-primary/80 rounded-full flex items-center justify-center shadow-lg shadow-primary/20",children:(0,s.jsx)(p,{className:"w-5 h-5 text-primary-foreground"})}),(0,s.jsx)("span",{className:"absolute -top-0.5 -right-0.5 w-3 h-3 bg-green-500 border-2 border-card rounded-full"})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("h3",{className:"text-sm font-bold text-foreground",children:"Core AI Coach"}),(0,s.jsxs)("p",{className:"text-[11px] text-muted-foreground",children:["Trained on your ",t.length," matches"]})]})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"text-[10px] px-2 py-0.5 rounded-full bg-primary/15 text-primary font-medium hidden sm:inline-block",children:"Overall AI"}),g&&(0,s.jsx)("button",{onClick:g,className:"text-muted-foreground hover:text-foreground transition-colors p-1.5 rounded-lg hover:bg-white/10","aria-label":"Close chat",children:(0,s.jsx)(u.A,{className:"h-4 w-4"})})]})]}),(0,s.jsx)("div",{className:"flex-1 p-4 overflow-y-auto",ref:D,children:(0,s.jsxs)("div",{className:"space-y-4",children:[y.map(e=>(0,s.jsxs)("div",{className:"flex gap-2.5 ".concat("user"===e.role?"justify-end":"justify-start"),children:["assistant"===e.role&&(0,s.jsx)("div",{className:"w-7 h-7 bg-gradient-to-br from-primary to-primary/80 rounded-full flex items-center justify-center flex-shrink-0 mt-0.5",children:(0,s.jsx)(p,{className:"w-3.5 h-3.5 text-primary-foreground"})}),(0,s.jsxs)("div",{className:"max-w-[82%] rounded-xl px-3.5 py-2.5 ".concat("user"===e.role?"bg-primary/20 text-foreground":"bg-white/5 text-muted-foreground border border-white/10"),children:[(0,s.jsx)("p",{className:"text-[13px] whitespace-pre-wrap leading-relaxed",children:"assistant"===e.role?e.content.replace(/#{1,6}\s?/g,"").replace(/\*{1,3}([^*]+)\*{1,3}/g,"$1").replace(/`{1,3}([^`]*)`{1,3}/g,"$1").replace(/^[-*+]\s/gm,"").trim():e.content}),(0,s.jsx)("p",{className:"text-[10px] opacity-50 mt-1",children:e.timestamp.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})})]})]},e.id)),N&&(0,s.jsxs)("div",{className:"flex gap-2.5 justify-start",children:[(0,s.jsx)("div",{className:"w-7 h-7 bg-gradient-to-br from-primary to-primary/80 rounded-full flex items-center justify-center flex-shrink-0",children:(0,s.jsx)(p,{className:"w-3.5 h-3.5 text-primary-foreground"})}),(0,s.jsxs)("div",{className:"bg-white/5 rounded-xl px-3.5 py-2.5 border border-white/10 flex items-center gap-2",children:[(0,s.jsx)(h.A,{className:"w-3.5 h-3.5 animate-spin text-primary"}),(0,s.jsx)("span",{className:"text-xs text-muted-foreground",children:"Thinking..."})]})]})]})}),y.length<=1&&(0,s.jsxs)("div",{className:"px-4 pb-3",children:[(0,s.jsx)("p",{className:"text-[11px] text-muted-foreground mb-2 font-medium",children:"Try asking:"}),(0,s.jsx)("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-1.5",children:A.map((e,t)=>(0,s.jsxs)("button",{onClick:()=>v(e.text),className:"flex items-center gap-2 px-3 py-2 text-xs rounded-lg bg-primary/5 border border-primary/15 text-primary hover:bg-primary/10 transition-colors text-left",children:[(0,s.jsx)(e.icon,{className:"w-3.5 h-3.5 flex-shrink-0"}),(0,s.jsx)("span",{className:"line-clamp-1",children:e.text})]},t))})]}),(0,s.jsxs)("div",{className:"p-3 border-t border-border/50",children:[(0,s.jsxs)("div",{className:"flex gap-2",children:[(0,s.jsx)(i.p,{ref:C,value:j,onChange:e=>v(e.target.value),onKeyPress:e=>{"Enter"!==e.key||e.shiftKey||(e.preventDefault(),S())},placeholder:"Ask about your matches, stats, or training...",disabled:N,className:"flex-1 text-sm h-10 rounded-xl bg-background border-border focus-visible:ring-primary/30"}),(0,s.jsx)(o.$,{onClick:S,disabled:!j.trim()||N,size:"icon",className:"flex-shrink-0 h-10 w-10 rounded-xl",children:N?(0,s.jsx)(h.A,{className:"w-4 h-4 animate-spin"}):(0,s.jsx)(x.A,{className:"w-4 h-4"})})]}
1),(0,s.jsx)("p",{className:"text-[10px] text-muted-foreground/60 mt-1.5 text-center",children:"Powered by your match data ⢠Press Enter to send"})]})]})}var g=r(70252);function b(e){let{matches:t,userStats:r,userName:o}=e,[i,c]=(0,a.useState)(!1),[l,d]=(0,a.useState)(),m=(0,g.Le)(),u=()=>{i?((0,n.Tv)(),d(void 0)):(0,n.Xc)(),c(!i)};return(0,s.jsxs)(s.Fragment,{children:[!i&&!m&&(0,s.jsx)("div",{className:"fixed bottom-24 sm:bottom-6 right-4 sm:right-6 z-[110] flex flex-col items-end gap-2",children:(0,s.jsx)("button",{onClick:u,className:"w-12 h-12 sm:w-14 sm:h-14 rounded-full bg-[#0d0d12] border border-white/20 hover:border-white/40 shadow-2xl transition-all duration-300 flex items-center justify-center self-end","aria-label":"AI Coach",children:(0,s.jsx)("div",{className:"w-6 h-6 sm:w-7 sm:h-7 rounded-full bg-white"})})}),i&&(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("div",{className:"fixed inset-0 bg-black/50 backdrop-blur-sm z-[110] transition-opacity animate-in fade-in duration-200",onClick:u}),(0,s.jsx)("div",{className:"fixed inset-x-0 bottom-0 top-0 sm:inset-y-0 sm:left-auto sm:right-0 sm:w-[440px] bg-card border-t sm:border-t-0 sm:border-l border-primary/20 shadow-2xl shadow-primary/10 z-[120] flex flex-col animate-in slide-in-from-bottom sm:slide-in-from-right duration-300",children:(0,s.jsx)("div",{className:"flex-1 min-h-0 overflow-hidden flex flex-col",children:(0,s.jsx)(f,{matches:t,userStats:r,userName:o,onClose:u,initialMessage:l})})})]})]})}},80534:(e,t,r)=>{r.d(t,{A:()=>s});let s=(0,r(71847).A)("ChartColumn",[["path",{d:"M3 3v16a2 2 0 0 0 2 2h16",key:"c24i48"}],["path",{d:"M18 17V9",key:"2bz60n"}],["path",{d:"M13 17V5",key:"1frdt8"}],["path",{d:"M8 17v-3",key:"17ska0"}]])}}]);
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.