mirror of
https://github.com/wahyd4/links.git
synced 2026-08-09 05:06:16 +10:00
13 lines
68 KiB
JavaScript
13 lines
68 KiB
JavaScript
import{r as i,j as l,c as Qt}from"./client-DS0SU7Jy.js";/**
|
||
* react-router v7.15.1
|
||
*
|
||
* Copyright (c) Remix Software Inc.
|
||
*
|
||
* This source code is licensed under the MIT license found in the
|
||
* LICENSE.md file in the root directory of this source tree.
|
||
*
|
||
* @license MIT
|
||
*/var ft="popstate";function mt(e){return typeof e=="object"&&e!=null&&"pathname"in e&&"search"in e&&"hash"in e&&"state"in e&&"key"in e}function Zt(e={}){function t(r,a){var d;let s=(d=a.state)==null?void 0:d.masked,{pathname:o,search:c,hash:u}=s||r.location;return Ge("",{pathname:o,search:c,hash:u},a.state&&a.state.usr||null,a.state&&a.state.key||"default",s?{pathname:r.location.pathname,search:r.location.search,hash:r.location.hash}:void 0)}function n(r,a){return typeof a=="string"?a:we(a)}return tn(t,n,null,e)}function M(e,t){if(e===!1||e===null||typeof e>"u")throw new Error(t)}function K(e,t){if(!e){typeof console<"u"&&console.warn(t);try{throw new Error(t)}catch{}}}function en(){return Math.random().toString(36).substring(2,10)}function pt(e,t){return{usr:e.state,key:e.key,idx:t,masked:e.mask?{pathname:e.pathname,search:e.search,hash:e.hash}:void 0}}function Ge(e,t,n=null,r,a){return{pathname:typeof e=="string"?e:e.pathname,search:"",hash:"",...typeof t=="string"?ue(t):t,state:n,key:t&&t.key||r||en(),mask:a}}function we({pathname:e="/",search:t="",hash:n=""}){return t&&t!=="?"&&(e+=t.charAt(0)==="?"?t:"?"+t),n&&n!=="#"&&(e+=n.charAt(0)==="#"?n:"#"+n),e}function ue(e){let t={};if(e){let n=e.indexOf("#");n>=0&&(t.hash=e.substring(n),e=e.substring(0,n));let r=e.indexOf("?");r>=0&&(t.search=e.substring(r),e=e.substring(0,r)),e&&(t.pathname=e)}return t}function tn(e,t,n,r={}){let{window:a=document.defaultView,v5Compat:s=!1}=r,o=a.history,c="POP",u=null,d=f();d==null&&(d=0,o.replaceState({...o.state,idx:d},""));function f(){return(o.state||{idx:null}).idx}function h(){c="POP";let m=f(),g=m==null?null:m-d;d=m,u&&u({action:c,location:b.location,delta:g})}function p(m,g){c="PUSH";let w=mt(m)?m:Ge(b.location,m,g);d=f()+1;let x=pt(w,d),P=b.createHref(w.mask||w);try{o.pushState(x,"",P)}catch(E){if(E instanceof DOMException&&E.name==="DataCloneError")throw E;a.location.assign(P)}s&&u&&u({action:c,location:b.location,delta:1})}function y(m,g){c="REPLACE";let w=mt(m)?m:Ge(b.location,m,g);d=f();let x=pt(w,d),P=b.createHref(w.mask||w);o.replaceState(x,"",P),s&&u&&u({action:c,location:b.location,delta:0})}function v(m){return nn(m)}let b={get action(){return c},get location(){return e(a,o)},listen(m){if(u)throw new Error("A history only accepts one active listener");return a.addEventListener(ft,h),u=m,()=>{a.removeEventListener(ft,h),u=null}},createHref(m){return t(a,m)},createURL:v,encodeLocation(m){let g=v(m);return{pathname:g.pathname,search:g.search,hash:g.hash}},push:p,replace:y,go(m){return o.go(m)}};return b}function nn(e,t=!1){let n="http://localhost";typeof window<"u"&&(n=window.location.origin!=="null"?window.location.origin:window.location.href),M(n,"No window.location.(origin|href) available to create URL");let r=typeof e=="string"?e:we(e);return r=r.replace(/ $/,"%20"),!t&&r.startsWith("//")&&(r=n+r),new URL(r,n)}function Nt(e,t,n="/"){return rn(e,t,n,!1)}function rn(e,t,n,r,a){let s=typeof t=="string"?ue(t):t,o=ee(s.pathname||"/",n);if(o==null)return null;let c=an(e),u=null,d=yn(o);for(let f=0;u==null&&f<c.length;++f)u=pn(c[f],d,r);return u}function an(e){let t=jt(e);return sn(t),t}function jt(e,t=[],n=[],r="",a=!1){let s=(o,c,u=a,d)=>{let f={relativePath:d===void 0?o.path||"":d,caseSensitive:o.caseSensitive===!0,childrenIndex:c,route:o};if(f.relativePath.startsWith("/")){if(!f.relativePath.startsWith(r)&&u)return;M(f.relativePath.startsWith(r),`Absolute route path "${f.relativePath}" nested under path "${r}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),f.relativePath=f.relativePath.slice(r.length)}let h=V([r,f.relativePath]),p=n.concat(f);o.children&&o.children.length>0&&(M(o.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${h}".`),jt(o.children,t,p,h,u)),!(o.path==null&&!o.index)&&t.push({path:h,score:fn(h,o.index),routesMeta:p})};return e.forEach((o,c)=>{var u;if(o.path===""||!((u=o.path)!=null&&u.includes("?")))s(o,c);else for(let d of Tt(o.path))s(o,c,!0,d)}),t}function Tt(e){let t=e.split("/");if(t.length===0)return[];let[n,...r]=t,a=n.endsWith("?"),s=n.replace(/\?$/,"");if(r.length===0)return a?[s,""]:[s];let o=Tt(r.join("/")),c=[];return c.push(...o.map(u=>u===""?s:[s,u].join("/"))),a&&c.push(...o),c.map(u=>e.startsWith("/")&&u===""?"/":u)}function sn(e){e.sort((t,n)=>t.score!==n.score?n.score-t.score:mn(t.routesMeta.map(r=>r.childrenIndex),n.routesMeta.map(r=>r.childrenIndex)))}var on=/^:[\w-]+$/,ln=3,un=2,cn=1,dn=10,hn=-2,gt=e=>e==="*";function fn(e,t){let n=e.split("/"),r=n.length;return n.some(gt)&&(r+=hn),t&&(r+=un),n.filter(a=>!gt(a)).reduce((a,s)=>a+(on.test(s)?ln:s===""?cn:dn),r)}function mn(e,t){return e.length===t.length&&e.slice(0,-1).every((r,a)=>r===t[a])?e[e.length-1]-t[t.length-1]:0}function pn(e,t,n=!1){let{routesMeta:r}=e,a={},s="/",o=[];for(let c=0;c<r.length;++c){let u=r[c],d=c===r.length-1,f=s==="/"?t:t.slice(s.length)||"/",h=Le({path:u.relativePath,caseSensitive:u.caseSensitive,end:d},f),p=u.route;if(!h&&d&&n&&!r[r.length-1].route.index&&(h=Le({path:u.relativePath,caseSensitive:u.caseSensitive,end:!1},f)),!h)return null;Object.assign(a,h.params),o.push({params:a,pathname:V([s,h.pathname]),pathnameBase:xn(V([s,h.pathnameBase])),route:p}),h.pathnameBase!=="/"&&(s=V([s,h.pathnameBase]))}return o}function Le(e,t){typeof e=="string"&&(e={path:e,caseSensitive:!1,end:!0});let[n,r]=gn(e.path,e.caseSensitive,e.end),a=t.match(n);if(!a)return null;let s=a[0],o=s.replace(/(.)\/+$/,"$1"),c=a.slice(1);return{params:r.reduce((d,{paramName:f,isOptional:h},p)=>{if(f==="*"){let v=c[p]||"";o=s.slice(0,s.length-v.length).replace(/(.)\/+$/,"$1")}const y=c[p];return h&&!y?d[f]=void 0:d[f]=(y||"").replace(/%2F/g,"/"),d},{}),pathname:s,pathnameBase:o,pattern:e}}function gn(e,t=!1,n=!0){K(e==="*"||!e.endsWith("*")||e.endsWith("/*"),`Route path "${e}" will be treated as if it were "${e.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${e.replace(/\*$/,"/*")}".`);let r=[],a="^"+e.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(o,c,u,d,f)=>{if(r.push({paramName:c,isOptional:u!=null}),u){let h=f.charAt(d+o.length);return h&&h!=="/"?"/([^\\/]*)":"(?:/([^\\/]*))?"}return"/([^\\/]+)"}).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return e.endsWith("*")?(r.push({paramName:"*"}),a+=e==="*"||e==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):n?a+="\\/*$":e!==""&&e!=="/"&&(a+="(?:(?=\\/|$))"),[new RegExp(a,t?void 0:"i"),r]}function yn(e){try{return e.split("/").map(t=>decodeURIComponent(t).replace(/\//g,"%2F")).join("/")}catch(t){return K(!1,`The URL path "${e}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${t}).`),e}}function ee(e,t){if(t==="/")return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let n=t.endsWith("/")?t.length-1:t.length,r=e.charAt(n);return r&&r!=="/"?null:e.slice(n)||"/"}var vn=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;function bn(e,t="/"){let{pathname:n,search:r="",hash:a=""}=typeof e=="string"?ue(e):e,s;return n?(n=Pt(n),n.startsWith("/")?s=yt(n.substring(1),"/"):s=yt(n,t)):s=t,{pathname:s,search:En(r),hash:Rn(a)}}function yt(e,t){let n=_e(t).split("/");return e.split("/").forEach(a=>{a===".."?n.length>1&&n.pop():a!=="."&&n.push(a)}),n.length>1?n.join("/"):"/"}function Ve(e,t,n,r){return`Cannot include a '${e}' character in a manually specified \`to.${t}\` field [${JSON.stringify(r)}]. Please separate it out to the \`to.${n}\` field. Alternatively you may provide the full path as a string in <Link to="..."> and the router will parse it for you.`}function wn(e){return e.filter((t,n)=>n===0||t.route.path&&t.route.path.length>0)}function Mt(e){let t=wn(e);return t.map((n,r)=>r===t.length-1?n.pathname:n.pathnameBase)}function tt(e,t,n,r=!1){let a;typeof e=="string"?a=ue(e):(a={...e},M(!a.pathname||!a.pathname.includes("?"),Ve("?","pathname","search",a)),M(!a.pathname||!a.pathname.includes("#"),Ve("#","pathname","hash",a)),M(!a.search||!a.search.includes("#"),Ve("#","search","hash",a)));let s=e===""||a.pathname==="",o=s?"/":a.pathname,c;if(o==null)c=n;else{let h=t.length-1;if(!r&&o.startsWith("..")){let p=o.split("/");for(;p[0]==="..";)p.shift(),h-=1;a.pathname=p.join("/")}c=h>=0?t[h]:"/"}let u=bn(a,c),d=o&&o!=="/"&&o.endsWith("/"),f=(s||o===".")&&n.endsWith("/");return!u.pathname.endsWith("/")&&(d||f)&&(u.pathname+="/"),u}var Pt=e=>e.replace(/\/\/+/g,"/"),V=e=>Pt(e.join("/")),_e=e=>e.replace(/\/+$/,""),xn=e=>_e(e).replace(/^\/*/,"/"),En=e=>!e||e==="?"?"":e.startsWith("?")?e:"?"+e,Rn=e=>!e||e==="#"?"":e.startsWith("#")?e:"#"+e,Sn=class{constructor(e,t,n,r=!1){this.status=e,this.statusText=t||"",this.internal=r,n instanceof Error?(this.data=n.toString(),this.error=n):this.data=n}};function kn(e){return e!=null&&typeof e.status=="number"&&typeof e.statusText=="string"&&typeof e.internal=="boolean"&&"data"in e}function Cn(e){let t=e.map(n=>n.route.path).filter(Boolean);return V(t)||"/"}var It=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function At(e,t){let n=e;if(typeof n!="string"||!vn.test(n))return{absoluteURL:void 0,isExternal:!1,to:n};let r=n,a=!1;if(It)try{let s=new URL(window.location.href),o=n.startsWith("//")?new URL(s.protocol+n):new URL(n),c=ee(o.pathname,t);o.origin===s.origin&&c!=null?n=c+o.search+o.hash:a=!0}catch{K(!1,`<Link to="${n}"> contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:r,isExternal:a,to:n}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var Lt=["POST","PUT","PATCH","DELETE"];new Set(Lt);var Nn=["GET",...Lt];new Set(Nn);var ce=i.createContext(null);ce.displayName="DataRouter";var Be=i.createContext(null);Be.displayName="DataRouterState";var _t=i.createContext(!1);function jn(){return i.useContext(_t)}var $t=i.createContext({isTransitioning:!1});$t.displayName="ViewTransition";var Tn=i.createContext(new Map);Tn.displayName="Fetchers";var Mn=i.createContext(null);Mn.displayName="Await";var H=i.createContext(null);H.displayName="Navigation";var Ee=i.createContext(null);Ee.displayName="Location";var te=i.createContext({outlet:null,matches:[],isDataRoute:!1});te.displayName="Route";var nt=i.createContext(null);nt.displayName="RouteError";var Bt="REACT_ROUTER_ERROR",Pn="REDIRECT",In="ROUTE_ERROR_RESPONSE";function An(e){if(e.startsWith(`${Bt}:${Pn}:{`))try{let t=JSON.parse(e.slice(28));if(typeof t=="object"&&t&&typeof t.status=="number"&&typeof t.statusText=="string"&&typeof t.location=="string"&&typeof t.reloadDocument=="boolean"&&typeof t.replace=="boolean")return t}catch{}}function Ln(e){if(e.startsWith(`${Bt}:${In}:{`))try{let t=JSON.parse(e.slice(40));if(typeof t=="object"&&t&&typeof t.status=="number"&&typeof t.statusText=="string")return new Sn(t.status,t.statusText,t.data)}catch{}}function _n(e,{relative:t}={}){M(Re(),"useHref() may be used only in the context of a <Router> component.");let{basename:n,navigator:r}=i.useContext(H),{hash:a,pathname:s,search:o}=ke(e,{relative:t}),c=s;return n!=="/"&&(c=s==="/"?n:V([n,s])),r.createHref({pathname:c,search:o,hash:a})}function Re(){return i.useContext(Ee)!=null}function ne(){return M(Re(),"useLocation() may be used only in the context of a <Router> component."),i.useContext(Ee).location}var Ft="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function Ot(e){i.useContext(H).static||i.useLayoutEffect(e)}function Se(){let{isDataRoute:e}=i.useContext(te);return e?Kn():$n()}function $n(){M(Re(),"useNavigate() may be used only in the context of a <Router> component.");let e=i.useContext(ce),{basename:t,navigator:n}=i.useContext(H),{matches:r}=i.useContext(te),{pathname:a}=ne(),s=JSON.stringify(Mt(r)),o=i.useRef(!1);return Ot(()=>{o.current=!0}),i.useCallback((u,d={})=>{if(K(o.current,Ft),!o.current)return;if(typeof u=="number"){n.go(u);return}let f=tt(u,JSON.parse(s),a,d.relative==="path");e==null&&t!=="/"&&(f.pathname=f.pathname==="/"?t:V([t,f.pathname])),(d.replace?n.replace:n.push)(f,d.state,d)},[t,n,s,a,e])}i.createContext(null);function ke(e,{relative:t}={}){let{matches:n}=i.useContext(te),{pathname:r}=ne(),a=JSON.stringify(Mt(n));return i.useMemo(()=>tt(e,JSON.parse(a),r,t==="path"),[e,a,r,t])}function Bn(e,t){return Dt(e,t)}function Dt(e,t,n){var m;M(Re(),"useRoutes() may be used only in the context of a <Router> component.");let{navigator:r}=i.useContext(H),{matches:a}=i.useContext(te),s=a[a.length-1],o=s?s.params:{},c=s?s.pathname:"/",u=s?s.pathnameBase:"/",d=s&&s.route;{let g=d&&d.path||"";zt(c,!d||g.endsWith("*")||g.endsWith("*?"),`You rendered descendant <Routes> (or called \`useRoutes()\`) at "${c}" (under <Route path="${g}">) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render.
|
||
|
||
Please change the parent <Route path="${g}"> to <Route path="${g==="/"?"*":`${g}/*`}">.`)}let f=ne(),h;if(t){let g=typeof t=="string"?ue(t):t;M(u==="/"||((m=g.pathname)==null?void 0:m.startsWith(u)),`When overriding the location using \`<Routes location>\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${u}" but pathname "${g.pathname}" was given in the \`location\` prop.`),h=g}else h=f;let p=h.pathname||"/",y=p;if(u!=="/"){let g=u.replace(/^\//,"").split("/");y="/"+p.replace(/^\//,"").split("/").slice(g.length).join("/")}let v=n&&n.state.matches.length?n.state.matches.map(g=>Object.assign(g,{route:n.manifest[g.route.id]||g.route})):Nt(e,{pathname:y});K(d||v!=null,`No routes matched location "${h.pathname}${h.search}${h.hash}" `),K(v==null||v[v.length-1].route.element!==void 0||v[v.length-1].route.Component!==void 0||v[v.length-1].route.lazy!==void 0,`Matched leaf route at location "${h.pathname}${h.search}${h.hash}" does not have an element or Component. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.`);let b=zn(v&&v.map(g=>Object.assign({},g,{params:Object.assign({},o,g.params),pathname:V([u,r.encodeLocation?r.encodeLocation(g.pathname.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:g.pathname]),pathnameBase:g.pathnameBase==="/"?u:V([u,r.encodeLocation?r.encodeLocation(g.pathnameBase.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:g.pathnameBase])})),a,n);return t&&b?i.createElement(Ee.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",mask:void 0,...h},navigationType:"POP"}},b):b}function Fn(){let e=qn(),t=kn(e)?`${e.status} ${e.statusText}`:e instanceof Error?e.message:JSON.stringify(e),n=e instanceof Error?e.stack:null,r="rgba(200,200,200, 0.5)",a={padding:"0.5rem",backgroundColor:r},s={padding:"2px 4px",backgroundColor:r},o=null;return console.error("Error handled by React Router default ErrorBoundary:",e),o=i.createElement(i.Fragment,null,i.createElement("p",null,"💿 Hey developer 👋"),i.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",i.createElement("code",{style:s},"ErrorBoundary")," or"," ",i.createElement("code",{style:s},"errorElement")," prop on your route.")),i.createElement(i.Fragment,null,i.createElement("h2",null,"Unexpected Application Error!"),i.createElement("h3",{style:{fontStyle:"italic"}},t),n?i.createElement("pre",{style:a},n):null,o)}var On=i.createElement(Fn,null),Ut=class extends i.Component{constructor(e){super(e),this.state={location:e.location,revalidation:e.revalidation,error:e.error}}static getDerivedStateFromError(e){return{error:e}}static getDerivedStateFromProps(e,t){return t.location!==e.location||t.revalidation!=="idle"&&e.revalidation==="idle"?{error:e.error,location:e.location,revalidation:e.revalidation}:{error:e.error!==void 0?e.error:t.error,location:t.location,revalidation:e.revalidation||t.revalidation}}componentDidCatch(e,t){this.props.onError?this.props.onError(e,t):console.error("React Router caught the following error during render",e)}render(){let e=this.state.error;if(this.context&&typeof e=="object"&&e&&"digest"in e&&typeof e.digest=="string"){const n=Ln(e.digest);n&&(e=n)}let t=e!==void 0?i.createElement(te.Provider,{value:this.props.routeContext},i.createElement(nt.Provider,{value:e,children:this.props.component})):this.props.children;return this.context?i.createElement(Dn,{error:e},t):t}};Ut.contextType=_t;var Je=new WeakMap;function Dn({children:e,error:t}){let{basename:n}=i.useContext(H);if(typeof t=="object"&&t&&"digest"in t&&typeof t.digest=="string"){let r=An(t.digest);if(r){let a=Je.get(t);if(a)throw a;let s=At(r.location,n);if(It&&!Je.get(t))if(s.isExternal||r.reloadDocument)window.location.href=s.absoluteURL||s.to;else{const o=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(s.to,{replace:r.replace}));throw Je.set(t,o),o}return i.createElement("meta",{httpEquiv:"refresh",content:`0;url=${s.absoluteURL||s.to}`})}}return e}function Un({routeContext:e,match:t,children:n}){let r=i.useContext(ce);return r&&r.static&&r.staticContext&&(t.route.errorElement||t.route.ErrorBoundary)&&(r.staticContext._deepestRenderedBoundaryId=t.route.id),i.createElement(te.Provider,{value:e},n)}function zn(e,t=[],n){let r=n==null?void 0:n.state;if(e==null){if(!r)return null;if(r.errors)e=r.matches;else if(t.length===0&&!r.initialized&&r.matches.length>0)e=r.matches;else return null}let a=e,s=r==null?void 0:r.errors;if(s!=null){let f=a.findIndex(h=>h.route.id&&(s==null?void 0:s[h.route.id])!==void 0);M(f>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(s).join(",")}`),a=a.slice(0,Math.min(a.length,f+1))}let o=!1,c=-1;if(n&&r){o=r.renderFallback;for(let f=0;f<a.length;f++){let h=a[f];if((h.route.HydrateFallback||h.route.hydrateFallbackElement)&&(c=f),h.route.id){let{loaderData:p,errors:y}=r,v=h.route.loader&&!p.hasOwnProperty(h.route.id)&&(!y||y[h.route.id]===void 0);if(h.route.lazy||v){n.isStatic&&(o=!0),c>=0?a=a.slice(0,c+1):a=[a[0]];break}}}}let u=n==null?void 0:n.onError,d=r&&u?(f,h)=>{var p,y;u(f,{location:r.location,params:((y=(p=r.matches)==null?void 0:p[0])==null?void 0:y.params)??{},pattern:Cn(r.matches),errorInfo:h})}:void 0;return a.reduceRight((f,h,p)=>{let y,v=!1,b=null,m=null;r&&(y=s&&h.route.id?s[h.route.id]:void 0,b=h.route.errorElement||On,o&&(c<0&&p===0?(zt("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),v=!0,m=null):c===p&&(v=!0,m=h.route.hydrateFallbackElement||null)));let g=t.concat(a.slice(0,p+1)),w=()=>{let x;return y?x=b:v?x=m:h.route.Component?x=i.createElement(h.route.Component,null):h.route.element?x=h.route.element:x=f,i.createElement(Un,{match:h,routeContext:{outlet:f,matches:g,isDataRoute:r!=null},children:x})};return r&&(h.route.ErrorBoundary||h.route.errorElement||p===0)?i.createElement(Ut,{location:r.location,revalidation:r.revalidation,component:b,error:y,children:w(),routeContext:{outlet:null,matches:g,isDataRoute:!0},onError:d}):w()},null)}function rt(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function Hn(e){let t=i.useContext(ce);return M(t,rt(e)),t}function Wn(e){let t=i.useContext(Be);return M(t,rt(e)),t}function Vn(e){let t=i.useContext(te);return M(t,rt(e)),t}function at(e){let t=Vn(e),n=t.matches[t.matches.length-1];return M(n.route.id,`${e} can only be used on routes that contain a unique "id"`),n.route.id}function Jn(){return at("useRouteId")}function qn(){var r;let e=i.useContext(nt),t=Wn("useRouteError"),n=at("useRouteError");return e!==void 0?e:(r=t.errors)==null?void 0:r[n]}function Kn(){let{router:e}=Hn("useNavigate"),t=at("useNavigate"),n=i.useRef(!1);return Ot(()=>{n.current=!0}),i.useCallback(async(a,s={})=>{K(n.current,Ft),n.current&&(typeof a=="number"?await e.navigate(a):await e.navigate(a,{fromRouteId:t,...s}))},[e,t])}var vt={};function zt(e,t,n){!t&&!vt[e]&&(vt[e]=!0,K(!1,n))}i.memo(Gn);function Gn({routes:e,manifest:t,future:n,state:r,isStatic:a,onError:s}){return Dt(e,void 0,{manifest:t,state:r,isStatic:a,onError:s})}function Pe(e){M(!1,"A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.")}function Yn({basename:e="/",children:t=null,location:n,navigationType:r="POP",navigator:a,static:s=!1,useTransitions:o}){M(!Re(),"You cannot render a <Router> inside another <Router>. You should never have more than one in your app.");let c=e.replace(/^\/*/,"/"),u=i.useMemo(()=>({basename:c,navigator:a,static:s,useTransitions:o,future:{}}),[c,a,s,o]);typeof n=="string"&&(n=ue(n));let{pathname:d="/",search:f="",hash:h="",state:p=null,key:y="default",mask:v}=n,b=i.useMemo(()=>{let m=ee(d,c);return m==null?null:{location:{pathname:m,search:f,hash:h,state:p,key:y,mask:v},navigationType:r}},[c,d,f,h,p,y,r,v]);return K(b!=null,`<Router basename="${c}"> is not able to match the URL "${d}${f}${h}" because it does not start with the basename, so the <Router> won't render anything.`),b==null?null:i.createElement(H.Provider,{value:u},i.createElement(Ee.Provider,{children:t,value:b}))}function Xn({children:e,location:t}){return Bn(Ye(e),t)}function Ye(e,t=[]){let n=[];return i.Children.forEach(e,(r,a)=>{if(!i.isValidElement(r))return;let s=[...t,a];if(r.type===i.Fragment){n.push.apply(n,Ye(r.props.children,s));return}M(r.type===Pe,`[${typeof r.type=="string"?r.type:r.type.name}] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>`),M(!r.props.index||!r.props.children,"An index route cannot have child routes.");let o={id:r.props.id||s.join("-"),caseSensitive:r.props.caseSensitive,element:r.props.element,Component:r.props.Component,index:r.props.index,path:r.props.path,middleware:r.props.middleware,loader:r.props.loader,action:r.props.action,hydrateFallbackElement:r.props.hydrateFallbackElement,HydrateFallback:r.props.HydrateFallback,errorElement:r.props.errorElement,ErrorBoundary:r.props.ErrorBoundary,hasErrorBoundary:r.props.hasErrorBoundary===!0||r.props.ErrorBoundary!=null||r.props.errorElement!=null,shouldRevalidate:r.props.shouldRevalidate,handle:r.props.handle,lazy:r.props.lazy};r.props.children&&(o.children=Ye(r.props.children,s)),n.push(o)}),n}var Ie="get",Ae="application/x-www-form-urlencoded";function Fe(e){return typeof HTMLElement<"u"&&e instanceof HTMLElement}function Qn(e){return Fe(e)&&e.tagName.toLowerCase()==="button"}function Zn(e){return Fe(e)&&e.tagName.toLowerCase()==="form"}function er(e){return Fe(e)&&e.tagName.toLowerCase()==="input"}function tr(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function nr(e,t){return e.button===0&&(!t||t==="_self")&&!tr(e)}var je=null;function rr(){if(je===null)try{new FormData(document.createElement("form"),0),je=!1}catch{je=!0}return je}var ar=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function qe(e){return e!=null&&!ar.has(e)?(K(!1,`"${e}" is not a valid \`encType\` for \`<Form>\`/\`<fetcher.Form>\` and will default to "${Ae}"`),null):e}function sr(e,t){let n,r,a,s,o;if(Zn(e)){let c=e.getAttribute("action");r=c?ee(c,t):null,n=e.getAttribute("method")||Ie,a=qe(e.getAttribute("enctype"))||Ae,s=new FormData(e)}else if(Qn(e)||er(e)&&(e.type==="submit"||e.type==="image")){let c=e.form;if(c==null)throw new Error('Cannot submit a <button> or <input type="submit"> without a <form>');let u=e.getAttribute("formaction")||c.getAttribute("action");if(r=u?ee(u,t):null,n=e.getAttribute("formmethod")||c.getAttribute("method")||Ie,a=qe(e.getAttribute("formenctype"))||qe(c.getAttribute("enctype"))||Ae,s=new FormData(c,e),!rr()){let{name:d,type:f,value:h}=e;if(f==="image"){let p=d?`${d}.`:"";s.append(`${p}x`,"0"),s.append(`${p}y`,"0")}else d&&s.append(d,h)}}else{if(Fe(e))throw new Error('Cannot submit element that is not <form>, <button>, or <input type="submit|image">');n=Ie,r=null,a=Ae,o=e}return s&&a==="text/plain"&&(o=s,s=void 0),{action:r,method:n.toLowerCase(),encType:a,formData:s,body:o}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");function st(e,t){if(e===!1||e===null||typeof e>"u")throw new Error(t)}function Ht(e,t,n,r){let a=typeof e=="string"?new URL(e,typeof window>"u"?"server://singlefetch/":window.location.origin):e;return n?a.pathname.endsWith("/")?a.pathname=`${a.pathname}_.${r}`:a.pathname=`${a.pathname}.${r}`:a.pathname==="/"?a.pathname=`_root.${r}`:t&&ee(a.pathname,t)==="/"?a.pathname=`${_e(t)}/_root.${r}`:a.pathname=`${_e(a.pathname)}.${r}`,a}async function or(e,t){if(e.id in t)return t[e.id];try{let n=await import(e.module);return t[e.id]=n,n}catch(n){return console.error(`Error loading route module \`${e.module}\`, reloading page...`),console.error(n),window.__reactRouterContext&&window.__reactRouterContext.isSpaMode,window.location.reload(),new Promise(()=>{})}}function ir(e){return e==null?!1:e.href==null?e.rel==="preload"&&typeof e.imageSrcSet=="string"&&typeof e.imageSizes=="string":typeof e.rel=="string"&&typeof e.href=="string"}async function lr(e,t,n){let r=await Promise.all(e.map(async a=>{let s=t.routes[a.route.id];if(s){let o=await or(s,n);return o.links?o.links():[]}return[]}));return hr(r.flat(1).filter(ir).filter(a=>a.rel==="stylesheet"||a.rel==="preload").map(a=>a.rel==="stylesheet"?{...a,rel:"prefetch",as:"style"}:{...a,rel:"prefetch"}))}function bt(e,t,n,r,a,s){let o=(u,d)=>n[d]?u.route.id!==n[d].route.id:!0,c=(u,d)=>{var f;return n[d].pathname!==u.pathname||((f=n[d].route.path)==null?void 0:f.endsWith("*"))&&n[d].params["*"]!==u.params["*"]};return s==="assets"?t.filter((u,d)=>o(u,d)||c(u,d)):s==="data"?t.filter((u,d)=>{var h;let f=r.routes[u.route.id];if(!f||!f.hasLoader)return!1;if(o(u,d)||c(u,d))return!0;if(u.route.shouldRevalidate){let p=u.route.shouldRevalidate({currentUrl:new URL(a.pathname+a.search+a.hash,window.origin),currentParams:((h=n[0])==null?void 0:h.params)||{},nextUrl:new URL(e,window.origin),nextParams:u.params,defaultShouldRevalidate:!0});if(typeof p=="boolean")return p}return!0}):[]}function ur(e,t,{includeHydrateFallback:n}={}){return cr(e.map(r=>{let a=t.routes[r.route.id];if(!a)return[];let s=[a.module];return a.clientActionModule&&(s=s.concat(a.clientActionModule)),a.clientLoaderModule&&(s=s.concat(a.clientLoaderModule)),n&&a.hydrateFallbackModule&&(s=s.concat(a.hydrateFallbackModule)),a.imports&&(s=s.concat(a.imports)),s}).flat(1))}function cr(e){return[...new Set(e)]}function dr(e){let t={},n=Object.keys(e).sort();for(let r of n)t[r]=e[r];return t}function hr(e,t){let n=new Set;return new Set(t),e.reduce((r,a)=>{let s=JSON.stringify(dr(a));return n.has(s)||(n.add(s),r.push({key:s,link:a})),r},[])}function ot(){let e=i.useContext(ce);return st(e,"You must render this element inside a <DataRouterContext.Provider> element"),e}function fr(){let e=i.useContext(Be);return st(e,"You must render this element inside a <DataRouterStateContext.Provider> element"),e}var it=i.createContext(void 0);it.displayName="FrameworkContext";function lt(){let e=i.useContext(it);return st(e,"You must render this element inside a <HydratedRouter> element"),e}function mr(e,t){let n=i.useContext(it),[r,a]=i.useState(!1),[s,o]=i.useState(!1),{onFocus:c,onBlur:u,onMouseEnter:d,onMouseLeave:f,onTouchStart:h}=t,p=i.useRef(null);i.useEffect(()=>{if(e==="render"&&o(!0),e==="viewport"){let b=g=>{g.forEach(w=>{o(w.isIntersecting)})},m=new IntersectionObserver(b,{threshold:.5});return p.current&&m.observe(p.current),()=>{m.disconnect()}}},[e]),i.useEffect(()=>{if(r){let b=setTimeout(()=>{o(!0)},100);return()=>{clearTimeout(b)}}},[r]);let y=()=>{a(!0)},v=()=>{a(!1),o(!1)};return n?e!=="intent"?[s,p,{}]:[s,p,{onFocus:pe(c,y),onBlur:pe(u,v),onMouseEnter:pe(d,y),onMouseLeave:pe(f,v),onTouchStart:pe(h,y)}]:[!1,p,{}]}function pe(e,t){return n=>{e&&e(n),n.defaultPrevented||t(n)}}function pr({page:e,...t}){let n=jn(),{router:r}=ot(),a=i.useMemo(()=>Nt(r.routes,e,r.basename),[r.routes,e,r.basename]);return a?n?i.createElement(yr,{page:e,matches:a,...t}):i.createElement(vr,{page:e,matches:a,...t}):null}function gr(e){let{manifest:t,routeModules:n}=lt(),[r,a]=i.useState([]);return i.useEffect(()=>{let s=!1;return lr(e,t,n).then(o=>{s||a(o)}),()=>{s=!0}},[e,t,n]),r}function yr({page:e,matches:t,...n}){let r=ne(),{future:a}=lt(),{basename:s}=ot(),o=i.useMemo(()=>{if(e===r.pathname+r.search+r.hash)return[];let c=Ht(e,s,a.unstable_trailingSlashAwareDataRequests,"rsc"),u=!1,d=[];for(let f of t)typeof f.route.shouldRevalidate=="function"?u=!0:d.push(f.route.id);return u&&d.length>0&&c.searchParams.set("_routes",d.join(",")),[c.pathname+c.search]},[s,a.unstable_trailingSlashAwareDataRequests,e,r,t]);return i.createElement(i.Fragment,null,o.map(c=>i.createElement("link",{key:c,rel:"prefetch",as:"fetch",href:c,...n})))}function vr({page:e,matches:t,...n}){let r=ne(),{future:a,manifest:s,routeModules:o}=lt(),{basename:c}=ot(),{loaderData:u,matches:d}=fr(),f=i.useMemo(()=>bt(e,t,d,s,r,"data"),[e,t,d,s,r]),h=i.useMemo(()=>bt(e,t,d,s,r,"assets"),[e,t,d,s,r]),p=i.useMemo(()=>{if(e===r.pathname+r.search+r.hash)return[];let b=new Set,m=!1;if(t.forEach(w=>{var P;let x=s.routes[w.route.id];!x||!x.hasLoader||(!f.some(E=>E.route.id===w.route.id)&&w.route.id in u&&((P=o[w.route.id])!=null&&P.shouldRevalidate)||x.hasClientLoader?m=!0:b.add(w.route.id))}),b.size===0)return[];let g=Ht(e,c,a.unstable_trailingSlashAwareDataRequests,"data");return m&&b.size>0&&g.searchParams.set("_routes",t.filter(w=>b.has(w.route.id)).map(w=>w.route.id).join(",")),[g.pathname+g.search]},[c,a.unstable_trailingSlashAwareDataRequests,u,r,s,f,t,e,o]),y=i.useMemo(()=>ur(h,s),[h,s]),v=gr(h);return i.createElement(i.Fragment,null,p.map(b=>i.createElement("link",{key:b,rel:"prefetch",as:"fetch",href:b,...n})),y.map(b=>i.createElement("link",{key:b,rel:"modulepreload",href:b,...n})),v.map(({key:b,link:m})=>i.createElement("link",{key:b,nonce:n.nonce,...m,crossOrigin:m.crossOrigin??n.crossOrigin})))}function br(...e){return t=>{e.forEach(n=>{typeof n=="function"?n(t):n!=null&&(n.current=t)})}}var wr=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";try{wr&&(window.__reactRouterVersion="7.15.1")}catch{}function xr({basename:e,children:t,useTransitions:n,window:r}){let a=i.useRef();a.current==null&&(a.current=Zt({window:r,v5Compat:!0}));let s=a.current,[o,c]=i.useState({action:s.action,location:s.location}),u=i.useCallback(d=>{n===!1?c(d):i.startTransition(()=>c(d))},[n]);return i.useLayoutEffect(()=>s.listen(u),[s,u]),i.createElement(Yn,{basename:e,children:t,location:o.location,navigationType:o.action,navigator:s,useTransitions:n})}var Wt=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,Vt=i.forwardRef(function({onClick:t,discover:n="render",prefetch:r="none",relative:a,reloadDocument:s,replace:o,mask:c,state:u,target:d,to:f,preventScrollReset:h,viewTransition:p,defaultShouldRevalidate:y,...v},b){let{basename:m,navigator:g,useTransitions:w}=i.useContext(H),x=typeof f=="string"&&Wt.test(f),P=At(f,m);f=P.to;let E=_n(f,{relative:a}),D=ne(),J=null;if(c){let W=tt(c,[],D.mask?D.mask.pathname:"/",!0);m!=="/"&&(W.pathname=W.pathname==="/"?m:V([m,W.pathname])),J=g.createHref(W)}let[X,oe,he]=mr(r,v),Ue=kr(f,{replace:o,mask:c,state:u,target:d,preventScrollReset:h,relative:a,viewTransition:p,defaultShouldRevalidate:y,useTransitions:w});function ie(W){t&&t(W),W.defaultPrevented||Ue(W)}let re=!(P.isExternal||s),fe=i.createElement("a",{...v,...he,href:(re?J:void 0)||P.absoluteURL||E,onClick:re?ie:t,ref:br(b,oe),target:d,"data-discover":!x&&n==="render"?"true":void 0});return X&&!x?i.createElement(i.Fragment,null,fe,i.createElement(pr,{page:E})):fe});Vt.displayName="Link";var Er=i.forwardRef(function({"aria-current":t="page",caseSensitive:n=!1,className:r="",end:a=!1,style:s,to:o,viewTransition:c,children:u,...d},f){let h=ke(o,{relative:d.relative}),p=ne(),y=i.useContext(Be),{navigator:v,basename:b}=i.useContext(H),m=y!=null&&Mr(h)&&c===!0,g=v.encodeLocation?v.encodeLocation(h).pathname:h.pathname,w=p.pathname,x=y&&y.navigation&&y.navigation.location?y.navigation.location.pathname:null;n||(w=w.toLowerCase(),x=x?x.toLowerCase():null,g=g.toLowerCase()),x&&b&&(x=ee(x,b)||x);const P=g!=="/"&&g.endsWith("/")?g.length-1:g.length;let E=w===g||!a&&w.startsWith(g)&&w.charAt(P)==="/",D=x!=null&&(x===g||!a&&x.startsWith(g)&&x.charAt(g.length)==="/"),J={isActive:E,isPending:D,isTransitioning:m},X=E?t:void 0,oe;typeof r=="function"?oe=r(J):oe=[r,E?"active":null,D?"pending":null,m?"transitioning":null].filter(Boolean).join(" ");let he=typeof s=="function"?s(J):s;return i.createElement(Vt,{...d,"aria-current":X,className:oe,ref:f,style:he,to:o,viewTransition:c},typeof u=="function"?u(J):u)});Er.displayName="NavLink";var Rr=i.forwardRef(({discover:e="render",fetcherKey:t,navigate:n,reloadDocument:r,replace:a,state:s,method:o=Ie,action:c,onSubmit:u,relative:d,preventScrollReset:f,viewTransition:h,defaultShouldRevalidate:p,...y},v)=>{let{useTransitions:b}=i.useContext(H),m=jr(),g=Tr(c,{relative:d}),w=o.toLowerCase()==="get"?"get":"post",x=typeof c=="string"&&Wt.test(c),P=E=>{if(u&&u(E),E.defaultPrevented)return;E.preventDefault();let D=E.nativeEvent.submitter,J=(D==null?void 0:D.getAttribute("formmethod"))||o,X=()=>m(D||E.currentTarget,{fetcherKey:t,method:J,navigate:n,replace:a,state:s,relative:d,preventScrollReset:f,viewTransition:h,defaultShouldRevalidate:p});b&&n!==!1?i.startTransition(()=>X()):X()};return i.createElement("form",{ref:v,method:w,action:g,onSubmit:r?u:P,...y,"data-discover":!x&&e==="render"?"true":void 0})});Rr.displayName="Form";function Sr(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function Jt(e){let t=i.useContext(ce);return M(t,Sr(e)),t}function kr(e,{target:t,replace:n,mask:r,state:a,preventScrollReset:s,relative:o,viewTransition:c,defaultShouldRevalidate:u,useTransitions:d}={}){let f=Se(),h=ne(),p=ke(e,{relative:o});return i.useCallback(y=>{if(nr(y,t)){y.preventDefault();let v=n!==void 0?n:we(h)===we(p),b=()=>f(e,{replace:v,mask:r,state:a,preventScrollReset:s,relative:o,viewTransition:c,defaultShouldRevalidate:u});d?i.startTransition(()=>b()):b()}},[h,f,p,n,r,a,t,e,s,o,c,u,d])}var Cr=0,Nr=()=>`__${String(++Cr)}__`;function jr(){let{router:e}=Jt("useSubmit"),{basename:t}=i.useContext(H),n=Jn(),r=e.fetch,a=e.navigate;return i.useCallback(async(s,o={})=>{let{action:c,method:u,encType:d,formData:f,body:h}=sr(s,t);if(o.navigate===!1){let p=o.fetcherKey||Nr();await r(p,n,o.action||c,{defaultShouldRevalidate:o.defaultShouldRevalidate,preventScrollReset:o.preventScrollReset,formData:f,body:h,formMethod:o.method||u,formEncType:o.encType||d,flushSync:o.flushSync})}else await a(o.action||c,{defaultShouldRevalidate:o.defaultShouldRevalidate,preventScrollReset:o.preventScrollReset,formData:f,body:h,formMethod:o.method||u,formEncType:o.encType||d,replace:o.replace,state:o.state,fromRouteId:n,flushSync:o.flushSync,viewTransition:o.viewTransition})},[r,a,t,n])}function Tr(e,{relative:t}={}){let{basename:n}=i.useContext(H),r=i.useContext(te);M(r,"useFormAction must be used inside a RouteContext");let[a]=r.matches.slice(-1),s={...ke(e||".",{relative:t})},o=ne();if(e==null){s.search=o.search;let c=new URLSearchParams(s.search),u=c.getAll("index");if(u.some(f=>f==="")){c.delete("index"),u.filter(h=>h).forEach(h=>c.append("index",h));let f=c.toString();s.search=f?`?${f}`:""}}return(!e||e===".")&&a.route.index&&(s.search=s.search?s.search.replace(/^\?/,"?index&"):"?index"),n!=="/"&&(s.pathname=s.pathname==="/"?n:V([n,s.pathname])),we(s)}function Mr(e,{relative:t}={}){let n=i.useContext($t);M(n!=null,"`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`. Did you accidentally import `RouterProvider` from `react-router`?");let{basename:r}=Jt("useViewTransitionState"),a=ke(e,{relative:t});if(!n.isTransitioning)return!1;let s=ee(n.currentLocation.pathname,r)||n.currentLocation.pathname,o=ee(n.nextLocation.pathname,r)||n.nextLocation.pathname;return Le(a.pathname,o)!=null||Le(a.pathname,s)!=null}const L=6,ae=2.6,q=240,Q={LE:[10,13],RE:[29,13],MO:[20,27]};function G(e,t,n){const r=[],a=Math.ceil(n);for(let s=-a;s<=a;s++)for(let o=-a;o<=a;o++)s*s+o*o<=n*n&&r.push([e+s,t+o]);return r}function $(e,t,n,r,a,s=5){const o=[],c=new Set;for(let u=r;u<=a;u+=s){const d=u*Math.PI/180,f=Math.round(e+n*Math.cos(d)),h=Math.round(t+n*Math.sin(d)),p=`${f},${h}`;c.has(p)||(c.add(p),o.push([f,h]))}return o}function Y(e,t,n){const r=[];for(let a=Math.round(e-n);a<=Math.round(e+n);a++)r.push([a,Math.round(t)]);return r}function Xe(e,t,n,r){const a=[],s=new Set,o=Math.round(n);for(let c=-o;c<=o;c++){const u=c/o*Math.PI,d=Math.round(t+r*Math.sin(u)),f=`${e+c},${d}`;s.has(f)||(s.add(f),a.push([e+c,d]))}return a}function Pr(e,t,n,r){const a=[],s=Math.round(n);for(let o=-s;o<=s;o++){const c=o+s;a.push([e+o,Math.round(t+(c%4<2?r:-r))])}return a}function wt(e,t){return[[-1,-2],[1,-2],[-2,-1],[-1,-1],[0,-1],[1,-1],[2,-1],[-2,0],[-1,0],[0,0],[1,0],[2,0],[-1,1],[0,1],[1,1],[0,2]].map(([n,r])=>[e+n,t+r])}function xt(e,t,n,r){const a=[],s=new Set,o=Math.round(r*2*Math.PI*8);for(let c=0;c<=o;c++){const u=c/o*r*2*Math.PI,d=c/o*n,f=Math.round(e+d*Math.cos(u)),h=Math.round(t+d*Math.sin(u)),p=`${f},${h}`;s.has(p)||(s.add(p),a.push([f,h]))}return a}function Ke(e,t){return[[e-1,t-1],[e,t-1],[e+1,t-1],[e,t],[e-1,t+1],[e,t+1],[e+1,t+1]]}function Et(e,t){return[...$(e,t-1,1.5,200,360,30),[e,t+1],[e,t+3]]}function Z(e,t){return{iris:G(e,t,3),pupil:G(e,t,1.5),hl:[[e-1,t-1]],lash:Y(e,t-3,3)}}function z(e,t){return{iris:G(e,t,4),pupil:G(e,t,2),hl:[[e-1,t-1],[e-2,t-2]],lash:Y(e,t-4,4)}}function le(e,t){return{iris:G(e,t,3).filter(([,r])=>r>=t-1&&r<=t+1),pupil:[[e,t]],lash:Y(e,t-1,2)}}function se(e,t){return{iris:G(e,t,3).filter(([,r])=>r>=t),pupil:[[e-1,t],[e,t],[e+1,t]],lash:Y(e,t,3)}}function Te(e,t){return{iris:G(e,t+1,3),pupil:G(e,t+2,1.5),hl:[[e-1,t]],lash:Y(e,t-2,2)}}function Me(e,t,n=2){return{iris:G(e,t,3),pupil:G(e+n,t,1.5),hl:[[e+n-1,t-1]],lash:Y(e,t-3,3)}}function Ir(e,t){return{wink:$(e,t+1,3,200,340,15)}}function ve(e,t){return $(e,t,5,25,155)}function Qe(e,t){return $(e,t,7,15,165)}function Rt(e,t){return Y(e,t,5)}function Ar(e,t){const n=$(e-2,t,4,30,120,10),r=$(e+3,t+2,2.5,270,360,15),a=new Set(n.map(([s,o])=>`${s},${o}`));return[...n,...r.filter(([s,o])=>!a.has(`${s},${o}`))]}function Lr(e,t){const n=$(e-2,t,2,200,340,20),r=$(e+2,t,2,200,340,20),a=Y(e,t+2,3),s=new Set(n.map(([o,c])=>`${o},${c}`));return[...n,...r.filter(([o,c])=>!s.has(`${o},${c}`)),...a]}function _r(e,t,n){const r=Math.abs(Math.sin(n*1.4));if(r<.25)return $(e,t,4,20,160,8);const a=r<.65?1:2,s=$(e,t-a,3.5,190,350,8),o=$(e,t+a,3,10,170,8),c=new Set(s.map(([u,d])=>`${u},${d}`));return[...s,...o.filter(([u,d])=>!c.has(`${u},${d}`))]}const[S,k]=Q.LE,[C,N]=Q.RE,[j,T]=Q.MO,_="#22CCFF",$r=[{id:"idle",label:"😐 待机",color:"#00FFEE",category:"interaction",canBlink:!0,leftEye:Z(S,k),rightEye:Z(C,N),mouth:ve(j,T)},{id:"listening",label:"👂 聆听",color:"#44AAFF",category:"interaction",canBlink:!0,leftEye:z(S,k),rightEye:z(C,N),mouth:$(j,T,3,0,180)},{id:"thinking",label:"🤔 思考",color:"#FFCC00",category:"interaction",canBlink:!0,leftEye:le(S,k),rightEye:Z(C,N),mouth:Xe(j,T,5,1),extras:[{dots:Et(S-1,k-6),color:"#FFCC00",alpha:.75}]},{id:"speaking",label:"💬 说话",color:"#FFFFFF",pupilColor:"#002233",category:"interaction",canBlink:!0,leftEye:Z(S,k),rightEye:Z(C,N),speakingMouth:!0},{id:"happy",label:"😊 开心",color:"#FF44AA",category:"interaction",canBlink:!0,leftEye:{heart:wt(S,k)},rightEye:{heart:wt(C,N)},mouth:Qe(j,T)},{id:"error",label:"😵 错误",color:"#FF4400",category:"interaction",canBlink:!0,leftEye:{spiral:xt(S,k,4,2)},rightEye:{spiral:xt(C,N,4,2)},mouth:Pr(j,T,5,1.5)},{id:"confused",label:"😕 困惑",color:"#BB44FF",category:"interaction",canBlink:!0,leftEye:z(S,k),rightEye:le(C,N),mouth:Xe(j,T,5,1.5),extras:[{dots:Et(C+1,N-6),color:"#BB44FF",alpha:.75}]},{id:"dreaming",label:"💤 做梦",color:"#5566FF",category:"interaction",canBlink:!0,leftEye:se(S,k),rightEye:se(C,N),mouth:ve(j,T),extras:[{dots:Ke(24,10),color:"#5566FF",alpha:.85,zzzIndex:0},{dots:Ke(28,7),color:"#7788FF",alpha:.75,zzzIndex:1},{dots:Ke(32,4),color:"#99AAFF",alpha:.65,zzzIndex:2}]}],qt=[{id:"natural_smile",label:"01 自然微笑",color:_,category:"auto",canBlink:!0,leftEye:Z(S,k),rightEye:Z(C,N),mouth:ve(j,T)},{id:"calm_relax",label:"02 平静放松",color:_,category:"auto",canBlink:!0,leftEye:se(S,k),rightEye:se(C,N),mouth:Rt(j,T)},{id:"curious_observe",label:"03 好奇观察",color:_,category:"auto",canBlink:!0,leftEye:z(S,k),rightEye:z(C,N),mouth:$(j,T,4,30,150,8)},{id:"light_joy",label:"04 轻松愉悦",color:_,category:"auto",canBlink:!0,leftEye:le(S,k),rightEye:le(C,N),mouth:Qe(j,T)},{id:"side_think",label:"05 侧目思考",color:_,category:"auto",canBlink:!0,leftEye:Me(S,k,2),rightEye:Me(C,N,2),mouth:Xe(j,T,4,1)},{id:"warm_friendly",label:"06 温和友善",color:_,category:"auto",canBlink:!0,leftEye:Te(S,k),rightEye:Te(C,N),mouth:ve(j,T)},{id:"quiet_listen",label:"07 静静聆听",color:_,category:"auto",canBlink:!0,leftEye:Z(S,k),rightEye:Z(C,N),mouth:Y(j,T,4)},{id:"focus_gaze",label:"08 专注注视",color:_,category:"auto",canBlink:!0,leftEye:z(S,k),rightEye:z(C,N),mouth:Rt(j,T)},{id:"quiet_wait",label:"09 安静等待",color:_,category:"auto",canBlink:!0,leftEye:se(S,k),rightEye:se(C,N),mouth:$(j,T,4,30,150,8)},{id:"slow_blink",label:"10 慢眨眼",color:_,category:"auto",canBlink:!0,leftEye:le(S,k),rightEye:le(C,N),mouth:ve(j,T)},{id:"look_around",label:"11 左右扫视",color:_,category:"auto",canBlink:!0,leftEye:Me(S,k,-2),rightEye:Me(C,N,-2),mouth:Y(j,T,4)},{id:"playful",label:"12 小小调皮",color:_,category:"auto",canBlink:!1,leftEye:Ir(S,k),rightEye:z(C,N),mouth:Ar(j,T)},{id:"joyful_wait",label:"13 愉悦期待",color:_,category:"auto",canBlink:!0,leftEye:z(S,k),rightEye:z(C,N),mouth:Qe(j,T)},{id:"slight_surprise",label:"14 轻微惊喜",color:_,category:"auto",canBlink:!0,leftEye:z(S,k),rightEye:z(C,N),mouth:$(j,T,3,0,180,10)},{id:"gentle_gaze",label:"15 温柔注视",color:_,category:"auto",canBlink:!0,leftEye:Te(S,k),rightEye:Te(C,N),mouth:$(j,T,4,30,150,8)},{id:"spaceout",label:"16 发呆放空",color:_,category:"auto",canBlink:!0,leftEye:se(S,k),rightEye:se(C,N),mouth:Lr(j,T)}],ut=[...$r,...qt],ge=qt.map(e=>e.id),Ze=Object.fromEntries(ut.map(e=>[e.id,e]));function O(e,t,n,r,a=null){if(!(!t||t.length===0)){if(e.save(),a==null){e.globalAlpha=Math.max(0,Math.min(1,r)),e.shadowBlur=14,e.shadowColor=n,e.fillStyle=n,e.beginPath();for(const[s,o]of t){const c=s*L+L/2,u=o*L+L/2;e.moveTo(c+ae,u),e.arc(c,u,ae,0,Math.PI*2)}e.fill(),e.shadowBlur=0,e.fillStyle="rgba(255,255,255,0.55)",e.beginPath();for(const[s,o]of t){const c=s*L+L/2,u=o*L+L/2;e.moveTo(c+ae*.38,u),e.arc(c,u,ae*.38,0,Math.PI*2)}e.fill()}else{const s=[],o=[];for(const[u,d]of t){const f=(u*7.3+d*13.1)*.31;(Math.sin(a*1.1+f)>0?s:o).push([u,d])}const c=(u,d,f)=>{if(u.length){e.globalAlpha=Math.max(0,Math.min(1,d)),e.shadowBlur=f,e.shadowColor=n,e.fillStyle=n,e.beginPath();for(const[h,p]of u){const y=h*L+L/2,v=p*L+L/2;e.moveTo(y+ae,v),e.arc(y,v,ae,0,Math.PI*2)}e.fill()}};c(o,r*.68,7),c(s,r,20),e.globalAlpha=Math.max(0,Math.min(1,r*.55)),e.shadowBlur=0,e.fillStyle="rgba(255,255,255,0.55)",e.beginPath();for(const[u,d]of t){const f=u*L+L/2,h=d*L+L/2;e.moveTo(f+ae*.38,h),e.arc(f,h,ae*.38,0,Math.PI*2)}e.fill()}e.restore()}}function ye(e,t,n){return n>=1?e:e.map(([r,a])=>[r,t+(a-t)*n])}function Br(e,t){if(e===null)return 1;const n=t-e;return n<120?1-n/120:n<220?0:n<340?(n-220)/120:1}function St(e,t,n,r,a,s,o,c,u){if(!t)return;const d=s||"#001020";t.iris?(O(e,ye(t.iris,r,c),a,o,u),O(e,ye(t.pupil,r,c),d,o,null),t.hl&&O(e,ye(t.hl,r,c),"#ffffff",o*.9,null),t.lash&&O(e,ye(t.lash,r,c),a,o,null)):t.closed!==void 0?(O(e,t.closed,a,o,u),t.lash&&O(e,t.lash,a,o,null)):t.wink?O(e,t.wink,a,o,u):t.heart?O(e,t.heart,a,o,u):t.spiral?O(e,t.spiral,a,o,u):t.star?O(e,t.star,a,o,u):t.pts&&O(e,ye(t.pts,r,c),a,o,u)}function Fr({expressionId:e,scale:t=2}){const n=i.useRef(null),r=i.useRef({currentId:e,previousId:null,transitionStart:null,blinkStart:null,nextBlink:performance.now()+2e3+Math.random()*2e3,t:0,raf:null});return i.useEffect(()=>{const a=r.current;e!==a.currentId&&(a.previousId=a.currentId,a.currentId=e,a.transitionStart=performance.now(),a.blinkStart=null)},[e]),i.useEffect(()=>{const s=n.current.getContext("2d"),o=r.current;function c(d,f,h,p){if(!d)return;St(s,d.leftEye,Q.LE[0],Q.LE[1],d.color,d.pupilColor,f,h,p),St(s,d.rightEye,Q.RE[0],Q.RE[1],d.color,d.pupilColor,f,h,p);const y=d.speakingMouth?_r(Q.MO[0],Q.MO[1],o.t):d.mouth;if(y&&O(s,y,d.color,f,p),d.extras)for(const v of d.extras){let b=f*v.alpha;if(v.zzzIndex!==void 0){const m=o.t-v.zzzIndex*1.2;b*=.35+.65*(Math.sin(m)*.5+.5)}O(s,v.dots,v.color,b,null)}}function u(){const d=performance.now();o.t+=.04,s.clearRect(0,0,q,q),s.fillStyle="#000",s.fillRect(0,0,q,q);let f=1,h=0;if(o.transitionStart!==null){const b=d-o.transitionStart;if(b>=380)o.transitionStart=null,o.previousId=null;else{const m=b/380,g=m<.5?2*m*m:1-(-2*m+2)**2/2;f=g,h=1-g}}const p=Ze[o.currentId];!o.blinkStart&&o.transitionStart===null&&(p!=null&&p.canBlink)&&d>=o.nextBlink&&(o.blinkStart=d,o.nextBlink=d+2500+Math.random()*2500),o.blinkStart!==null&&d-o.blinkStart>=340&&(o.blinkStart=null);const y=Br(o.blinkStart,d);o.previousId&&c(Ze[o.previousId],h,1,null);const v=o.transitionStart===null?o.t:null;c(p,f,y,v),s.save(),s.globalAlpha=.04,s.fillStyle="#000";for(let b=0;b<q;b+=2)s.fillRect(0,b+1,q,1);s.restore(),o.raf=requestAnimationFrame(u)}return o.raf=requestAnimationFrame(u),()=>cancelAnimationFrame(o.raf)},[]),l.jsx("canvas",{ref:n,width:q,height:q,style:{width:q*t,height:q*t,imageRendering:"pixelated",borderRadius:14,boxShadow:"0 0 40px rgba(0,255,200,0.2)",display:"block"}})}function Or({base64:e,mimeType:t="audio/mp3",label:n="🔊"}){const r=e?`data:${t};base64,${e}`:null;return r?l.jsx("audio",{className:"audio-btn",controls:!0,src:r,title:n,preload:"none"}):null}function Dr({role:e,text:t,audioBase64:n,audioMime:r}){const a=e==="user";return l.jsxs("div",{className:`bubble ${a?"bubble-user":"bubble-bot"}`,children:[l.jsx("div",{className:"bubble-label",children:a?"你":"JBOT"}),l.jsx("div",{className:"bubble-text",children:t}),n&&l.jsx(Or,{base64:n,mimeType:r||"audio/mp3"})]})}function Ur({messages:e,voiceStatus:t}){const n=i.useRef(null),r=Se();return i.useEffect(()=>{var a;(a=n.current)==null||a.scrollIntoView({behavior:"smooth"})},[e]),l.jsxs("section",{className:"chat-panel",children:[l.jsxs("div",{className:"chat-header",children:[l.jsx("span",{className:"chat-title",children:"对话"}),l.jsx("button",{className:"history-link",onClick:()=>r("/history"),children:"历史记录 →"})]}),t&&l.jsx("div",{className:`voice-status voice-status-${t.type}`,children:t.text}),l.jsxs("div",{className:"chat-messages",children:[e.length===0?l.jsx("p",{className:"chat-empty",children:"按住 Space 开始说话…"}):e.map(a=>l.jsx(Dr,{role:a.role,text:a.text,audioBase64:a.audioBase64,audioMime:a.audioMime},a.id)),l.jsx("div",{ref:n})]})]})}const Oe="jbot_memory",zr=100;function be(){try{return JSON.parse(localStorage.getItem(Oe)||"[]")}catch{return[]}}function Hr(e){const t=be(),n=e.toLowerCase().trim();if(t.some(a=>a.text.toLowerCase().trim()===n))return null;const r={id:crypto.randomUUID(),text:e.trim(),createdAt:Date.now()};return localStorage.setItem(Oe,JSON.stringify([r,...t].slice(0,zr))),r}function Wr(e){localStorage.setItem(Oe,JSON.stringify(be().filter(t=>t.id!==e)))}function Vr(){localStorage.removeItem(Oe)}function Jr({memories:e,onMemoriesChange:t}){const[n,r]=i.useState(!1),a=o=>{Wr(o),t()},s=()=>{window.confirm("清空所有记忆?")&&(Vr(),t())};return l.jsxs("div",{className:"memory-panel",children:[l.jsxs("button",{className:"memory-toggle",onClick:()=>r(o=>!o),children:[l.jsx("span",{children:"🧠 长期记忆"}),l.jsx("span",{className:"memory-badge",children:e.length}),l.jsx("span",{className:"memory-arrow",children:n?"▲":"▼"})]}),n&&l.jsx("div",{className:"memory-body",children:e.length===0?l.jsx("p",{className:"memory-empty",children:"对话后会自动记住关于你的信息"}):l.jsxs(l.Fragment,{children:[l.jsx("ul",{className:"memory-list",children:e.map(o=>l.jsxs("li",{className:"memory-item",children:[l.jsx("span",{className:"memory-text",children:o.text}),l.jsx("button",{className:"memory-del",onClick:()=>a(o.id),title:"删除",children:"×"})]},o.id))}),l.jsx("button",{className:"memory-clear",onClick:s,children:"清空全部"})]})})]})}const de="/api/jbot";async function qr(e,t=[],n={}){const r=await fetch(`${de}/chat/`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({messages:e,memories:t,settings:n})});if(!r.ok){const a=await r.json().catch(()=>({}));throw new Error(a.error||`HTTP ${r.status}`)}return r.json()}async function Kr(e,t="audio/webm"){const n=await fetch(`${de}/asr/`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({audioBase64:e,format:t})});if(!n.ok){const r=await n.json().catch(()=>({}));throw new Error(r.error||`HTTP ${n.status}`)}return n.json()}async function Gr(e,t){const n=await fetch(`${de}/tts/`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({text:e,voice:t})});if(!n.ok){const r=await n.json().catch(()=>({}));throw new Error(r.error||`HTTP ${n.status}`)}return n.json()}async function Yr(e,t){try{const n=await fetch(`${de}/memory/extract/`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userText:e,botText:t})});if(!n.ok)return[];const{facts:r=[]}=await n.json();return r}catch{return[]}}async function Xr(){try{const e=await fetch(`${de}/api-config/`);return e.ok?e.json():{}}catch{return{}}}async function Qr(e){const t=await fetch(`${de}/api-config/`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!t.ok){const n=await t.json().catch(()=>({}));throw new Error(n.error||`HTTP ${t.status}`)}return t.json()}function Zr(){const[e,t]=i.useState(!1),n=i.useRef(null),r=i.useRef(null),a=i.useRef(null),s=i.useRef([]),o=i.useRef(""),c=i.useCallback(async()=>{var p;if(e)return;s.current=[],o.current="",(p=n.current)!=null&&p.active||(n.current=await navigator.mediaDevices.getUserMedia({audio:!0}));const d=MediaRecorder.isTypeSupported("audio/webm;codecs=opus")?"audio/webm;codecs=opus":"audio/webm",f=new MediaRecorder(n.current,{mimeType:d});f.ondataavailable=y=>{y.data.size>0&&s.current.push(y.data)},f.start(100),r.current=f;const h=window.SpeechRecognition||window.webkitSpeechRecognition;if(h){const y=new h;y.lang="zh-CN",y.interimResults=!0,y.continuous=!0,y.onresult=v=>{let b="";for(const m of v.results)m.isFinal&&(b+=m[0].transcript);b&&(o.current=b)},y.onerror=v=>{console.warn("SpeechRecognition error:",v.error)},y.start(),a.current=y}t(!0)},[e]),u=i.useCallback(()=>new Promise(d=>{var p,y;t(!1);const f=o.current;try{(p=a.current)==null||p.stop()}catch{}a.current=null,(y=n.current)==null||y.getTracks().forEach(v=>v.stop()),n.current=null;const h=r.current;if(!h)return d({transcript:f,audioBase64:null,mimeType:null});h.onstop=async()=>{const v=h.mimeType;if(s.current.length===0)return d({transcript:f,audioBase64:null,mimeType:v});const b=new Blob(s.current,{type:v}),m=new FileReader;m.onloadend=()=>{d({transcript:f,audioBase64:m.result.split(",")[1],mimeType:v})},m.readAsDataURL(b)},h.stop(),r.current=null}),[]);return{isRecording:e,start:c,stop:u}}const De="jbot_history",ea=200;function $e(){try{return JSON.parse(localStorage.getItem(De)||"[]")}catch{return[]}}function ta(e){const t=$e(),n=[{id:crypto.randomUUID(),timestamp:Date.now(),...e},...t];return localStorage.setItem(De,JSON.stringify(n.slice(0,ea))),n[0]}function na(){localStorage.removeItem(De)}function ra(e){localStorage.setItem(De,JSON.stringify($e().filter(t=>t.id!==e)))}const aa=[{id:"zh_female_vv_uranus_bigtts",label:"灵儿",lang:"中文",gender:"女",style:"亲切"},{id:"zh_female_tianmei_conversation_bigtts",label:"甜美",lang:"中文",gender:"女",style:"温柔"},{id:"zh_female_linjing_conversation_bigtts",label:"琳静",lang:"中文",gender:"女",style:"知性"},{id:"zh_female_qingxin_conversation_bigtts",label:"清新",lang:"中文",gender:"女",style:"清新"},{id:"zh_male_m191_uranus_bigtts",label:"豪远",lang:"中文",gender:"男",style:"标准"},{id:"zh_male_haoran_conversation_bigtts",label:"豪然",lang:"中文",gender:"男",style:"稳重"},{id:"zh_male_m372_conversation_bigtts",label:"温和男声",lang:"中文",gender:"男",style:"温和"},{id:"en_female_sarah_jupiter_bigtts",label:"Sarah",lang:"EN",gender:"女",style:"Warm"},{id:"en_male_adam_mars_bigtts",label:"Adam",lang:"EN",gender:"男",style:"Clear"}],Kt="zh_female_vv_uranus_bigtts",ct="jbot_settings",et={robotName:"JBOT",robotPersonality:"你是一个友好、简洁、偶尔幽默的AI机器人助手。回复控制在80字以内。",language:"auto",voiceId:Kt,customVoiceId:"",responseMaxWords:80,switchIntervalMs:1e4};function xe(){try{const e=JSON.parse(localStorage.getItem(ct)||"{}");return{...et,...e}}catch{return{...et}}}function sa(e){const n={...xe(),...e};return localStorage.setItem(ct,JSON.stringify(n)),n}function oa(){return localStorage.removeItem(ct),{...et}}function ia(e=null){var n;const t=e||xe();return((n=t.customVoiceId)==null?void 0:n.trim())||t.voiceId||Kt}const la=ut.filter(e=>e.category==="interaction"),ua=ut.filter(e=>e.category==="auto"),ca={1:"idle",2:"listening",3:"thinking",4:"speaking",5:"happy",6:"error",7:"confused",8:"dreaming",q:"natural_smile",w:"calm_relax",e:"curious_observe",r:"light_joy",t:"side_think",y:"warm_friendly",u:"quiet_listen",i:"focus_gaze"};async function da(e,t="audio/mp3"){return new Promise(n=>{const r=new Audio(`data:${t};base64,${e}`);r.onended=n,r.onerror=n,r.play().catch(n)})}function ha(e){return new Promise(t=>{if(!window.speechSynthesis)return t();const n=new SpeechSynthesisUtterance(e);n.lang="zh-CN",n.rate=1.05,n.onend=t,n.onerror=t,window.speechSynthesis.speak(n)})}function fa({phase:e,onStart:t,onEnd:n}){const r=e==="thinking"||e==="speaking";let a="🎙 按住说话",s="";e==="acquiring"?(a="⏳ 准备中…",s=" vbtn--acquiring"):e==="listening"?(a="🔴 松开发送",s=" vbtn--recording"):e==="thinking"?(a="⚙ 思考中…",s=" vbtn--busy"):e==="speaking"&&(a="🔊 播放中…",s=" vbtn--busy");const o=u=>{u.preventDefault(),r||t()},c=u=>{u.preventDefault(),n()};return l.jsx("div",{className:"vbtn-wrap",children:l.jsx("button",{className:`vbtn${s}`,disabled:r,onMouseDown:o,onMouseUp:c,onMouseLeave:c,onTouchStart:o,onTouchEnd:c,onTouchCancel:c,children:a})})}function ma(){var dt;const e=Se(),[t,n]=i.useState(ge[0]),[r,a]=i.useState(!0),[s,o]=i.useState(1),[c]=i.useState(()=>xe().switchIntervalMs??1e4),u=i.useRef(null),d=i.useRef(!0),f=i.useRef(ge[0]),h=i.useRef(null),p=i.useRef(c);i.useEffect(()=>{d.current=r},[r]),i.useEffect(()=>{f.current=t},[t]);const y=i.useCallback(()=>{clearTimeout(u.current),u.current=null},[]);h.current=()=>{if(y(),!d.current)return;const R=1+(Math.random()-.5)*.3;u.current=setTimeout(()=>{var A;const U=ge.filter(F=>F!==f.current),I=U[Math.floor(Math.random()*U.length)];n(I),(A=h.current)==null||A.call(h)},p.current*R)};const v=i.useCallback(()=>{var R;return(R=h.current)==null?void 0:R.call(h)},[]);i.useEffect(()=>(r?v():y(),y),[r,v,y]);const b=i.useCallback(R=>{y(),n(R),d.current&&v()},[y,v]),{start:m,stop:g}=Zr(),[w,x]=i.useState("idle"),[P,E]=i.useState(null),[D,J]=i.useState([]),[X,oe]=i.useState([]),[he,Ue]=i.useState(()=>be()),ie=i.useRef("idle"),re=i.useRef(!1),fe=i.useCallback(()=>Ue(be()),[]);i.useEffect(()=>{ie.current=w},[w]);const W=(R,U,I,A)=>{const F={id:crypto.randomUUID(),role:R,text:U,audioBase64:I,audioMime:A};return J(We=>[...We.slice(-29),F]),F},ze=i.useCallback(async()=>{if(!(re.current||ie.current!=="idle")){re.current=!0,y(),x("acquiring"),E({type:"acquiring",text:"⏳ 麦克风准备中…"});try{await m()}catch(R){console.warn("[PTT] Mic acquisition failed:",R.message),re.current=!1,x("idle"),E({type:"error",text:"⚠ 麦克风不可用"}),setTimeout(()=>E(null),2500),v();return}n("listening"),x("listening"),E({type:"listening",text:"🎙 请讲话 · 松开结束"})}},[y,m,v]),He=i.useCallback(async()=>{if(!re.current)return;if(re.current=!1,ie.current==="acquiring"){x("idle"),E(null),v();return}if(ie.current!=="listening")return;x("thinking"),n("thinking"),E({type:"thinking",text:"⚙ 识别中…"});const{transcript:R,audioBase64:U,mimeType:I}=await g();let A="";if(U)try{E({type:"thinking",text:"⚙ 识别中…"});const{text:B}=await Kr(U,I||"audio/webm");A=(B==null?void 0:B.trim())||""}catch(B){console.warn("[ASR] Volcengine failed, using browser transcript:",B.message)}if(A||(A=R.trim()),!A){x("idle"),n("idle"),E(null);return}W("user",A,U,I),E({type:"thinking",text:"⚙ 思考中…"});let F="";try{const B=be().map(Xt=>Xt.text),Ce=xe(),Ne=[...X,{role:"user",content:A}],{text:Yt}=await qr(Ne.slice(-10),B,Ce);F=Yt,oe([...Ne,{role:"assistant",content:F}].slice(-20))}catch(B){F=`对话出错: ${B.message}`}n("speaking"),x("speaking"),E({type:"speaking",text:"🔊 播放中…"});const We=ia();let me=null,ht=!1;try{const{audioBase64:B}=await Gr(F,We);me=B}catch(B){console.warn("[TTS] Volcengine unavailable, using browser TTS:",B.message),ht=!0}ht&&E({type:"speaking",text:"🔊 播放中… (浏览器语音)"}),W("bot",F,me,"audio/mp3"),ta({userText:A,botText:F,userAudioBase64:U,userAudioMime:I,botAudioBase64:me,botAudioMime:"audio/mp3"}),Yr(A,F).then(B=>{let Ce=!1;B.forEach(Ne=>{Hr(Ne)&&(Ce=!0)}),Ce&&fe()}).catch(()=>{}),me?await da(me,"audio/mp3"):await ha(F),x("idle"),E(null);const Gt=ge[Math.floor(Math.random()*ge.length)];n(Gt),v()},[g,X,v]);return i.useEffect(()=>{function R(I){if(!(I.target.tagName==="INPUT"||I.target.tagName==="TEXTAREA")){if(I.code==="Space"&&!I.repeat){I.preventDefault(),ze();return}if(ie.current==="idle"){const A=ca[I.key.toLowerCase()];A&&b(A)}}}function U(I){I.code==="Space"&&(I.preventDefault(),He())}return window.addEventListener("keydown",R),window.addEventListener("keyup",U),()=>{window.removeEventListener("keydown",R),window.removeEventListener("keyup",U)}},[ze,He,b]),l.jsxs("div",{className:"app",children:[l.jsxs("header",{className:"hdr",children:[l.jsx("a",{href:"/",className:"hdr-home",title:"返回主页",children:"🏠"}),l.jsxs("h1",{children:["J",l.jsx("span",{className:"accent",children:"BOT"})]}),l.jsx("p",{className:"subtitle",children:"AI Robot Face · 240×240"}),l.jsxs("nav",{className:"hdr-nav",children:[l.jsx("button",{className:"hdr-link",onClick:()=>e("/history"),children:"历史"}),l.jsx("button",{className:"hdr-link",onClick:()=>e("/settings"),children:"设置"})]})]}),l.jsxs("div",{className:"page-body",children:[l.jsxs("aside",{className:"left-col",children:[l.jsxs("section",{className:"screen-wrap",children:[l.jsxs("div",{className:"scale-controls",children:[l.jsx("button",{className:`scale-btn${s===1?" active":""}`,onClick:()=>o(1),children:"1×"}),l.jsx("button",{className:`scale-btn${s===2?" active":""}`,onClick:()=>o(2),children:"2×"})]}),l.jsx("div",{className:"bezel",children:l.jsx(Fr,{expressionId:t,scale:s})}),l.jsx("div",{className:"expr-label",children:(dt=Ze[t])==null?void 0:dt.label})]}),l.jsxs("section",{className:"panel",children:[l.jsxs("div",{className:"panel-section",children:[l.jsxs("h3",{children:["交互状态 ",l.jsx("span",{className:"key-hint",children:"1 – 8"})]}),l.jsx("div",{className:"btn-grid",children:la.map(R=>l.jsx("button",{className:`ebtn${t===R.id?" active":""}`,style:{"--c":R.color},onClick:()=>b(R.id),children:R.label},R.id))})]}),l.jsxs("div",{className:"panel-section",children:[l.jsxs("h3",{children:["微表情 ",l.jsx("span",{className:"key-hint",children:"Q–I · 自动"})]}),l.jsx("div",{className:"btn-grid btn-grid-4",children:ua.map(R=>l.jsx("button",{className:`ebtn${t===R.id?" active":""}`,style:{"--c":R.color},onClick:()=>b(R.id),children:R.label},R.id))})]}),l.jsxs("label",{className:"toggle",children:[l.jsx("input",{type:"checkbox",checked:r,onChange:R=>a(R.target.checked)}),l.jsx("span",{children:"自动轮换微表情"})]})]})]}),l.jsxs("div",{className:"right-col",children:[l.jsx(Jr,{memories:he,onMemoriesChange:fe}),l.jsx(Ur,{messages:D,voiceStatus:P}),l.jsx("div",{className:"right-footer",children:l.jsx(fa,{phase:w,onStart:ze,onEnd:He})})]})]})]})}function kt({base64:e,mimeType:t="audio/mp3"}){return e?l.jsx("audio",{className:"hist-audio",controls:!0,src:`data:${t};base64,${e}`,preload:"none"}):null}function pa({entry:e,onDelete:t}){const r=new Date(e.timestamp).toLocaleString("zh-CN",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"});return l.jsxs("article",{className:"hist-entry",children:[l.jsxs("div",{className:"hist-meta",children:[l.jsx("span",{className:"hist-time",children:r}),l.jsx("button",{className:"hist-del",onClick:()=>t(e.id),title:"删除",children:"✕"})]}),l.jsxs("div",{className:"hist-row hist-row-user",children:[l.jsx("div",{className:"hist-role",children:"你"}),l.jsxs("div",{className:"hist-body",children:[l.jsx("p",{className:"hist-text",children:e.userText||"(语音消息)"}),l.jsx(kt,{base64:e.userAudioBase64,mimeType:e.userAudioMime||"audio/webm"})]})]}),l.jsxs("div",{className:"hist-row hist-row-bot",children:[l.jsx("div",{className:"hist-role",children:"JBOT"}),l.jsxs("div",{className:"hist-body",children:[l.jsx("p",{className:"hist-text",children:e.botText||""}),l.jsx(kt,{base64:e.botAudioBase64,mimeType:"audio/mp3"})]})]})]})}function ga(){const[e,t]=i.useState(()=>$e()),n=Se(),r=s=>{ra(s),t($e())},a=()=>{window.confirm("确认清空所有历史记录?")&&(na(),t([]))};return l.jsxs("div",{className:"hist-page",children:[l.jsxs("div",{className:"hist-toolbar",children:[l.jsx("button",{className:"hist-back",onClick:()=>n("/"),children:"← 返回"}),l.jsx("h1",{className:"hist-heading",children:"历史对话"}),l.jsx("button",{className:"hist-clear",onClick:a,disabled:e.length===0,children:"清空"})]}),e.length===0?l.jsx("p",{className:"hist-empty",children:"暂无历史记录"}):l.jsx("div",{className:"hist-list",children:e.map(s=>l.jsx(pa,{entry:s,onDelete:r},s.id))})]})}const Ct={volcAppId:"",volcAccessToken:"",openrouterApiKey:"",llmModel:"deepseek/deepseek-chat",volcTtsVoice:"zh_female_vv_uranus_bigtts",volcAsrResource:"volc.bigasr.sauc.duration"};function ya(){const e=Se(),[t,n]=i.useState(()=>xe()),[r,a]=i.useState(Ct),[s,o]=i.useState(!0),[c,u]=i.useState(!1),[d,f]=i.useState({});i.useEffect(()=>{Xr().then(m=>{m&&!m.error&&a(g=>({...g,...m}))}).finally(()=>o(!1))},[]);const h=(m,g)=>{n(w=>({...w,[m]:g})),u(!1)},p=(m,g)=>{a(w=>({...w,[m]:g})),u(!1)},y=m=>f(g=>({...g,[m]:!g[m]})),v=async()=>{sa(t);try{await Qr(r),u(!0),setTimeout(()=>u(!1),2e3)}catch(m){alert("API 配置保存失败:"+m.message)}},b=()=>{if(window.confirm("重置所有设置为默认值?")){const m=oa();n(m),a(Ct),u(!1)}};return l.jsxs("div",{className:"settings-page",children:[l.jsxs("div",{className:"settings-toolbar",children:[l.jsx("button",{className:"settings-back",onClick:()=>e("/"),children:"← 返回"}),l.jsx("h1",{className:"settings-heading",children:"全局设置"}),l.jsx("button",{className:"settings-save",onClick:v,children:c?"✓ 已保存":"保存"})]}),l.jsxs("div",{className:"settings-body",children:[l.jsxs("section",{className:"settings-section",children:[l.jsx("h2",{className:"settings-section-title",children:"🔑 API 配置"}),l.jsx("p",{className:"settings-hint-block",children:"配置保存在服务器数据库中。Token 字段显示 *** 表示已配置,留空则保持不变。"}),s?l.jsx("p",{className:"settings-hint-block",children:"加载中…"}):l.jsxs(l.Fragment,{children:[l.jsxs("label",{className:"settings-label",children:["Volcengine App ID",l.jsx("input",{className:"settings-input",value:r.volcAppId,onChange:m=>p("volcAppId",m.target.value),placeholder:"填写火山引擎 App ID"})]}),l.jsxs("label",{className:"settings-label",children:["Volcengine Access Token",l.jsxs("div",{className:"settings-secret-row",children:[l.jsx("input",{className:"settings-input",type:d.volcAccessToken?"text":"password",value:r.volcAccessToken,onChange:m=>p("volcAccessToken",m.target.value),placeholder:"留空则保持不变"}),l.jsx("button",{className:"settings-show-btn",onClick:()=>y("volcAccessToken"),children:d.volcAccessToken?"隐藏":"显示"})]})]}),l.jsxs("label",{className:"settings-label",children:["OpenRouter API Key",l.jsxs("div",{className:"settings-secret-row",children:[l.jsx("input",{className:"settings-input",type:d.openrouterApiKey?"text":"password",value:r.openrouterApiKey,onChange:m=>p("openrouterApiKey",m.target.value),placeholder:"留空则保持不变"}),l.jsx("button",{className:"settings-show-btn",onClick:()=>y("openrouterApiKey"),children:d.openrouterApiKey?"隐藏":"显示"})]})]}),l.jsxs("label",{className:"settings-label",children:["LLM 模型",l.jsx("input",{className:"settings-input",value:r.llmModel,onChange:m=>p("llmModel",m.target.value),placeholder:"deepseek/deepseek-chat"}),l.jsx("span",{className:"settings-hint",children:"OpenRouter 模型 ID,例如 openai/gpt-4o"})]}),l.jsxs("label",{className:"settings-label",children:["ASR Resource ID",l.jsx("input",{className:"settings-input",value:r.volcAsrResource,onChange:m=>p("volcAsrResource",m.target.value),placeholder:"volc.bigasr.sauc.duration"})]})]})]}),l.jsxs("section",{className:"settings-section",children:[l.jsx("h2",{className:"settings-section-title",children:"🤖 机器人身份"}),l.jsxs("label",{className:"settings-label",children:["名字",l.jsx("input",{className:"settings-input",value:t.robotName,onChange:m=>h("robotName",m.target.value),placeholder:"JBOT"})]}),l.jsxs("label",{className:"settings-label",children:["人格描述 ",l.jsx("span",{className:"settings-hint",children:"会注入到每轮对话的系统提示"}),l.jsx("textarea",{className:"settings-textarea",rows:3,value:t.robotPersonality,onChange:m=>h("robotPersonality",m.target.value),placeholder:"你是一个友好、简洁、偶尔幽默的AI机器人助手。回复控制在80字以内。"})]}),l.jsxs("div",{className:"settings-label",children:["微表情切换间隔",l.jsxs("div",{className:"settings-slider-row",children:[l.jsx("input",{type:"range",min:"3",max:"30",step:"1",value:Math.round((t.switchIntervalMs??1e4)/1e3),onChange:m=>h("switchIntervalMs",Number(m.target.value)*1e3),className:"settings-slider"}),l.jsxs("span",{className:"settings-slider-val",children:[Math.round((t.switchIntervalMs??1e4)/1e3)," 秒"]})]})]})]}),l.jsxs("section",{className:"settings-section",children:[l.jsx("h2",{className:"settings-section-title",children:"👤 用户背景"}),l.jsxs("label",{className:"settings-label",children:["关于你 ",l.jsx("span",{className:"settings-hint",children:"机器人会了解你的背景,更好地回答"}),l.jsx("textarea",{className:"settings-textarea",rows:3,value:t.extraContext||"",onChange:m=>h("extraContext",m.target.value),placeholder:"例如:我叫小明,是一名软件工程师,在上海工作,对AI和嵌入式系统感兴趣。"})]})]}),l.jsxs("section",{className:"settings-section",children:[l.jsx("h2",{className:"settings-section-title",children:"🌐 语言"}),l.jsx("div",{className:"settings-radio-group",children:[{value:"auto",label:"自动(跟随用户语言)"},{value:"zh-CN",label:"中文"},{value:"en-US",label:"English"}].map(m=>l.jsxs("label",{className:"settings-radio-label",children:[l.jsx("input",{type:"radio",name:"language",value:m.value,checked:t.language===m.value,onChange:()=>h("language",m.value)}),m.label]},m.value))})]}),l.jsxs("section",{className:"settings-section",children:[l.jsx("h2",{className:"settings-section-title",children:"🔊 语音音色"}),l.jsx("div",{className:"settings-voice-grid",children:aa.map(m=>l.jsxs("button",{className:`settings-voice-btn ${!t.customVoiceId&&t.voiceId===m.id?"active":""}`,onClick:()=>{h("voiceId",m.id),h("customVoiceId","")},children:[l.jsx("span",{className:"voice-btn-label",children:m.label}),l.jsxs("span",{className:"voice-btn-meta",children:[m.lang," · ",m.gender," · ",m.style]})]},m.id))}),l.jsxs("label",{className:"settings-label settings-label-mt",children:["自定义音色 ID ",l.jsx("span",{className:"settings-hint",children:"填写后会覆盖上方选择"}),l.jsx("input",{className:"settings-input",value:t.customVoiceId||"",onChange:m=>h("customVoiceId",m.target.value),placeholder:"例如 zh_female_vv_uranus_bigtts"})]}),l.jsxs("p",{className:"settings-hint-block",children:["完整音色列表见"," ",l.jsx("a",{href:"https://www.volcengine.com/docs/6561/1257544",target:"_blank",rel:"noreferrer",children:"火山引擎 TTS 音色文档"})]})]}),l.jsxs("section",{className:"settings-section settings-section-danger",children:[l.jsx("h2",{className:"settings-section-title",children:"⚠️ 重置"}),l.jsx("button",{className:"settings-reset-btn",onClick:b,children:"重置为默认设置"})]})]})]})}Qt.createRoot(document.getElementById("jbot-root")).render(l.jsx(i.StrictMode,{children:l.jsx(xr,{basename:"/jbot",children:l.jsxs(Xn,{children:[l.jsx(Pe,{path:"/",element:l.jsx(ma,{})}),l.jsx(Pe,{path:"/history",element:l.jsx(ga,{})}),l.jsx(Pe,{path:"/settings",element:l.jsx(ya,{})})]})})}));
|