gemi 0.185.0 → 0.186.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai/client/index.d.ts +1 -1
- package/dist/ai/client/index.d.ts.map +1 -1
- package/dist/ai/client/index.js +20 -4
- package/dist/ai/client/index.js.map +1 -1
- package/dist/ai/useChat.d.ts +29 -3
- package/dist/ai/useChat.d.ts.map +1 -1
- package/dist/bin/gemi.js +2 -2
- package/dist/bin/gemi.js.map +2 -2
- package/dist/{chunk-e38xa29v.js → chunk-2c2n3v4k.js} +1 -1
- package/dist/{chunk-0rkastve.js → chunk-5y6e8kpe.js} +2 -2
- package/dist/{chunk-0rkastve.js.map → chunk-5y6e8kpe.js.map} +3 -3
- package/dist/{chunk-tbss13e8.js → chunk-p4bbsa4x.js} +2 -2
- package/dist/{chunk-tbss13e8.js.map → chunk-p4bbsa4x.js.map} +1 -1
- package/dist/{chunk-ykpc18d1.js → chunk-tckf3g8x.js} +1 -1
- package/dist/{chunk-4q505by7.js → chunk-vvwhk2sb.js} +1 -1
- package/dist/facades/index.js +1 -1
- package/dist/http/index.js +1 -1
- package/dist/i18n/index.js +1 -1
- package/dist/internal/staticNavigationRuntime.d.ts +2 -2
- package/dist/internal/staticNavigationRuntime.d.ts.map +1 -1
- package/dist/kernel/index.js +1 -1
- package/dist/server/index.js +1 -1
- package/dist/services/index.js +1 -1
- package/dist/testing/index.js +1 -1
- package/dist/testing/index.js.map +1 -1
- package/package.json +1 -1
- /package/dist/{chunk-e38xa29v.js.map → chunk-2c2n3v4k.js.map} +0 -0
- /package/dist/{chunk-ykpc18d1.js.map → chunk-tckf3g8x.js.map} +0 -0
- /package/dist/{chunk-4q505by7.js.map → chunk-vvwhk2sb.js.map} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{Dc as B9,Qc as P9,Yb as E9,ac as K3,bc as b9,fc as F9,kc as e,xc as N9,xd as I9}from"./chunk-a1r1r1z7.js";import{Ed as i3,Gd as B3,Jd as i9,Kd as l9,Ld as J$,Nd as O$}from"./chunk-xmjzyzn6.js";import{Qd as h9,Vd as m9,Xd as u9,ce as x,de as d9,ee as c9,ge as p9,he as L$}from"./chunk-87nekrjj.js";import{ke as P}from"./chunk-q19cs1qf.js";import{$g as A$,Ag as g3,Bg as f3,Ce as R9,Df as Z3,Eg as w3,Fg as $$,Ge as x$,Gg as G3,Hg as Z$,Ig as z$,Je as U$,Jf as H3,Jg as v3,Kf as u3,Kg as a,Lf as k,Ng as q$,Of as V$,Og as L3,Pf as Y$,Pg as p3,Qf as K$,Sf as w,Te as F$,Ue as l3,Ug as Q$,Vg as H$,Ye as J3,Ze as X3,dg as e3,og as a3,pf as d3,qg as n,ug as r3,vg as r9,wg as e9,ye as l,ze as X$}from"./chunk-0rkastve.js";import{Ki as J9,Oi as P3,Pi as F3,Qi as z3,ei as p,gi as m,vi as o3}from"./chunk-zenfs4e2.js";import{Wi as s9}from"./chunk-q6rse2fh.js";import{fj as g}from"./chunk-spmxhsze.js";import{lj as c3}from"./chunk-7bz43qbt.js";import{oj as N$,pj as n3,sj as N3,tj as t3,wj as P$}from"./chunk-a1414jdv.js";import{Kj as t9,Pj as o9}from"./chunk-vhyabcw9.js";import{dk as g9,fk as u}from"./chunk-vv8vjjez.js";import{gk as A}from"./chunk-ecv4mtgh.js";import{mk as D$}from"./chunk-wtdmwmm7.js";import{al as s3}from"./chunk-96r16t57.js";import{hl as U3,kl as y}from"./chunk-nadkwh8a.js";import{tl as m3}from"./chunk-m906xc76.js";import{Fl as a9}from"./chunk-0ahecas6.js";var T$="mcp",k$=/^[\x21\x23-\x5B\x5D-\x7E]+$/;class O extends e{status;constructor($,Z){super($);this.status=Z;this.name="McpToolError"}}class v extends Error{reason;constructor($,Z){super($);this.reason=Z;this.name="McpCallRefusedError"}}var $9=/^[A-Za-z0-9_-]{1,64}$/,M$=/:([A-Za-z_][A-Za-z0-9_]*)([?*+]?)/g,Z9=4000,M=1e5,R$=/^(text\/|application\/([\w.+-]*\+)?(json|xml))/i,L9=new WeakMap;function V6($){return L9.get($)}class i{router;dispatcher;static token="router.mcp";plans=new Map;scopeTools=new Map;files;featureOn;constructor($,Z,z={}){this.router=$;this.dispatcher=Z;this.files=w$(z.files),this.featureOn=z.featureOn??X3;for(let[G,W]of Object.entries($.routes??{}))this.plans.set(G,E$(W)?this.planNative(G,W):this.plan(G,W));this.resolveScopes()}list($,Z){if(D3($),$.kind==="local")return this.descriptors(Z);let z=[];for(let[G,W]of this.plans){if(!W.remote||!this.grants($.principal,G))continue;if(Y9(W.remote,Z))z.push(W.remote)}return z}async available($,Z){let z=[];for(let G of this.list($,Z))if(await this.isOn(G))z.push(G);return z}descriptors($){let Z=[];for(let{descriptor:z}of this.plans.values())if(Y9(z,$))Z.push(z);return Z}get maxFileBytes(){return this.files.maxBytes}scopes(){return[...this.scopeTools].map(([$,{description:Z}])=>({name:$,description:Z}))}scopesFor($){return[...this.scopeTools].filter(([,{tools:Z}])=>Z.has($)).map(([Z])=>Z)}async execute($,Z,z,G,W={}){D3($);let X=this.plans.get(Z);if(X&&!await this.isOn(X.descriptor)){if($.kind==="remote")throw new v(`There is no tool named "${Z}".`,"unknown-tool");throw new O(`There is no tool named "${Z}".`,404)}if($.kind==="remote"){if(!X?.remote||!this.grants($.principal,Z))throw new v(`There is no tool named "${Z}".`,"unknown-tool");if(X.descriptor.requiresApproval&&W.approved!==!0&&!W3(X))throw new v(`"${Z}" needs the user's approval, and this call does not have it.`,"approval-required");G=void 0}if(!X)throw Error(`McpRegistry: there is no tool named "${Z}".`);if(X.kind==="tool")return await this.executeNative(X,$,z,G,W);let Y=X,K=$.kind==="remote"?Y.remote:Y.descriptor,Q=K.inputSchema.safeParse(z);if(Q.ok===!1)throw new O(`Invalid arguments for "${Z}": ${Q.errors.join(", ")}`);let V=Q.value,H={caller:$,req:$.req,tool:K,input:V,ctx:G},U=await this.fillPath(Y,H),{path:I}=this.dispatcher.getRouteHandlerAndParams(new Request(`http://gemi.internal/api${U}`));if(I!==K.url)throw new O(`"${Z}" has nothing at ${U}.`,404);let J={};for(let _ of Y.jsonKeys)if(V[_]!==void 0)J[_]=V[_];let F,B="";if(Y.fileFields.length>0)F=await this.formData(Y,J,H);else if(K.method==="GET")B=l$(J);else if(Y.jsonKeys.length>0)F=J;let T=this.router.credentials?await this.bind(Y,"the credentials",()=>this.router.credentials(H)):void 0,j={...T?{credentials:T}:{},...W.signal?{signal:W.signal}:{},...W.progress?{progress:W.progress}:{},...$.kind==="remote"?{identity:{user:$.principal.user,grant:{via:$.principal.via,id:$.principal.id,scopes:$.principal.scopes,...$.principal.clientId?{clientId:$.principal.clientId}:{}}}}:{}},C;try{let _=B?`${U}?${B}`:U;C=Object.keys(j).length>0?await this.dispatcher.dispatchAs($.req,K.method,_,F,j):await this.dispatcher.dispatchAs($.req,K.method,_,F)}catch(_){throw console.error(`[gemi/mcp] Dispatching "${Z}" failed:`,_),new O(`"${Z}" failed on the server.`,500)}if(!Y.result&&!K.outputSchema)return await U9(Z,C);return await this.project(Y,H,C)}async isOn($){return $.feature===void 0||await this.featureOn($.feature)===!0}plan($,Z){if(!$9.test($))throw Error(`McpRouter: "${$}" is not a valid tool name. A routes key is the tool's name as a model and an MCP client see it, used verbatim \u2014 letters, digits, "_" and "-", at most 64.`);let z=`McpRouter: "${$}" (${Z?.method} ${Z?.url})`;if(!(Z instanceof Object)||Z.__internal_brand!=="McpRoute")throw Error(`McpRouter: "${$}" is not a route or a tool. Declare it with this.fromApiRoute(...) or this.fromTool(...).`);let{method:G,url:W,meta:X}=Z;if(X.feature!==void 0&&(typeof X.feature!=="string"||X.feature===""))throw Error(`${z}: feature must be a feature key from app/features.`);if(W.startsWith("/__gemi__"))throw Error(`${z} is a framework route, not an app route.`);let Y=this.dispatcher.flatRoutes[W]?.[G];if(!Y)throw Error(`${z} names no route of this app. Expose a route by the path and verb it is mounted at.`);let K=[...W.matchAll(M$)].map(([,N,S])=>({name:N,modifier:S})),Q=X.params??{};for(let N of K)if(!(N.name in Q))throw Error(`${z}: the path param "${N.name}" must be bound or declared "input".`);for(let[N,S]of Object.entries(Q)){if(!K.some((h)=>h.name===N))throw Error(`${z}: "${N}" in params is not a param of the url.`);if(Q9(S))u$(z,`params.${N}`,S);else K9(z,`params.${N}`,S)}let V=[],H;if(X.input){if(H=X.input.toJSONSchema(),H.type!=="object"||!H.properties)throw Error(`${z}: input must be an s.object(...), the fields of the request body.`);V=Object.keys(H.properties)}let U=Object.entries(X.files??{}).map(([N,S])=>({name:N,binder:S}));for(let N of U)K9(z,`files.${N.name}`,N.binder);if(X.result!==void 0&&typeof X.result!=="function")throw Error(`${z}: result must be a function.`);if(X.output!==void 0&&typeof X.output?.safeParse!=="function")throw Error(`${z}: output must be a schema, built with s.`);if(X.title!==void 0&&(typeof X.title!=="string"||X.title===""))throw Error(`${z}: title must be a non-empty string.`);let I=V9(z,G,X.annotations);if(U.length>0&&G==="GET")throw Error(`${z}: a GET has no body to carry a file.`);let J={},F=(N,S)=>{if(N in J)throw Error(`${z}: "${N}" is the input key of two params or files, and the model can only send one.`);J[N]=S},B=new Map,T=new Map;for(let N of K){let S=Q[N.name];if(S==="input"){let h=p.string().describe(`The ":${N.name}" segment of the url.`);F(N.name,N.modifier==="?"||N.modifier==="*"?h.optional():h)}else if(Q9(S)){let h=S.as??N.name;F(h,S.input),T.set(N.name,{key:h,param:S})}else B.set(N.name,S)}let j={};for(let N of U)if(N.binder==="input")F(N.name,p.string().describe("The id of an attachment the user uploaded or a tool produced (gemi_att_\u2026), whose file is sent as this field.")),j[N.name]=this.remoteFileSchema();let C=[...Object.keys(J),...U.map((N)=>N.name)];for(let N of new Set(C))if(V.includes(N))throw Error(`${z}: "${N}" is both an input field and a param or file, and the model can only send one.`);let _=Object.freeze({kind:"route",name:$,description:X.description,method:G,url:W,inputSchema:H9(X.input,H,p.object(J)),...X.output?{outputSchema:X.output}:{},...X.title?{title:X.title}:{},annotations:I,tags:Object.freeze([...X.tags??[]]),requiresApproval:X.requiresApproval===!0,...X.feature!==void 0?{feature:X.feature}:{},...Y.source?{source:Y.source}:{}}),r=!U.every((N)=>N.binder==="input")?null:U.length===0?_:Object.freeze({..._,inputSchema:H9(X.input,H,p.object(p$(J,Object.keys(j))),j)});return{kind:"route",descriptor:_,remote:r,params:K,paramBinders:B,modelParams:T,fileFields:U,jsonKeys:V,...X.result?{result:X.result}:{}}}remoteFileSchema(){let{maxBytes:$,fetch:Z}=this.files,z={name:{type:"string",description:"The file's name, like report.pdf."},mimeType:{type:"string",description:"The file's media type, like application/pdf."},data:{type:"string",contentEncoding:"base64",description:`The file's bytes, base64-encoded (RFC 4648, standard alphabet). At most ${$} bytes decoded.`}};if(Z)z.url={type:"string",format:"uri",description:"An https URL the server downloads the file from, instead of data."};let G={type:"object",description:Z?"A file, sent as base64 in data or fetched from url: exactly one of the two.":"A file, sent as base64 in data.",properties:z,required:["name","mimeType"],additionalProperties:!1},W=Object.keys(z),X=(Y)=>{if(typeof Y!=="object"||Y===null||Array.isArray(Y))return{ok:!1,errors:["a file must be an object"]};let K=[],Q={};for(let V of Object.keys(Y))if(!W.includes(V))K.push(`a file has no field "${V}"`);for(let V of W){let H=Y[V];if(H===void 0||H===null){if(V==="name"||V==="mimeType")K.push(`a file needs "${V}"`);continue}if(typeof H!=="string")K.push(`a file's "${V}" must be a string`);else Q[V]=H}return K.length>0?{ok:!1,errors:K}:{ok:!0,value:Q}};return{toJSONSchema:()=>G,safeParse:X,parse(Y){let K=X(Y);if(K.ok===!1)throw Error(K.errors.join(", "));return K.value}}}planNative($,Z){if(!$9.test($))throw Error(`McpRouter: "${$}" is not a valid tool name. A routes key is the tool's name as a model and an MCP client see it, used verbatim \u2014 letters, digits, "_" and "-", at most 64.`);let z=`McpRouter: "${$}" (a native tool)`,{tool:G,meta:W={}}=Z;if(!(G instanceof Object)||typeof G.name!=="string")throw Error(`${z} is not an AgentTool. Pass one built with AgentTool.create(...).`);if(G.answeredBy==="client"||typeof G.execute!=="function")throw Error(`${z}: "${G.name}" is answered by the client, and only a tool the server runs can be called through the registry.`);if(typeof G.inputSchema==="function")throw Error(`${z}: "${G.name}" resolves its input schema per run, and the registry lists one schema to every caller. Give it a fixed inputSchema.`);if(typeof G.inputSchema?.safeParse!=="function")throw Error(`${z}: its inputSchema must be a schema, built with s.`);if(typeof W!=="object"||W===null)throw Error(`${z}: the meta must be an object.`);if(W.description!==void 0&&(typeof W.description!=="string"||W.description.trim()===""))throw Error(`${z}: description must be a non-empty string.`);if(W.title!==void 0&&(typeof W.title!=="string"||W.title===""))throw Error(`${z}: title must be a non-empty string.`);if(W.tags!==void 0&&(!Array.isArray(W.tags)||W.tags.some((Q)=>typeof Q!=="string")))throw Error(`${z}: tags must be an array of strings.`);if(W.requiresApproval===!1&&G.requiresApproval)throw Error(`${z}: "${G.name}" requires approval, and requiresApproval: false would run it without asking. Leave it out, or register a tool that does not ask.`);let X=W.remote;if(X!==void 0){if(typeof X!=="object"||X===null||typeof X.context!=="function")throw Error(`${z}: remote must be { context(call) }, building the AgentContext a remote call runs with.`);if(X.progress!==void 0&&typeof X.progress!=="function")throw Error(`${z}: remote.progress must be a function.`)}let Y=W.description??G.description;if(typeof Y!=="string"||Y.trim()==="")throw Error(`${z} needs a description: the tool's own, or the meta's.`);let K=Object.freeze({kind:"tool",name:$,description:Y,inputSchema:G.inputSchema,...G.outputSchema?{outputSchema:G.outputSchema}:{},...W.title?{title:W.title}:{},annotations:V9(z,void 0,W.annotations),tags:Object.freeze([...W.tags??[]]),requiresApproval:G.requiresApproval||W.requiresApproval===!0});return{kind:"tool",descriptor:K,remote:X?K:null,tool:G,meta:W}}async approvalRequired($,Z,z,G={}){let W=this.plans.get(Z);if(!W)return!0;if(!W3(W))return W.descriptor.requiresApproval;let X=W;if($.kind!=="remote"||!X.meta.remote)return!0;let Y=X.descriptor.inputSchema.safeParse(z);if(Y.ok===!1)return!0;let K={caller:$,req:$.req,tool:X.descriptor,input:Y.value},Q;try{Q=await this.bind(X,"the remote context",()=>X.meta.remote.context(K))}catch{return!0}if(typeof Q!=="object"||Q===null)return!0;let V=G.signal??new AbortController().signal;return X9(X,Y.value,W9(G9(X,Q,V)))}nativeApproval($){let Z=this.plans.get($);if(Z?.kind!=="tool")throw Error(`McpRegistry: there is no native tool named "${$}".`);return W3(Z)??Z.descriptor.requiresApproval}nativeTool($){let Z=this.plans.get($);if(Z?.kind!=="tool")throw Error(`McpRegistry: there is no native tool named "${$}".`);return Z.tool}startNative($,Z,z,G){let W=this.plans.get(Z);if(W?.kind!=="tool")throw Error(`McpRegistry: there is no native tool named "${Z}".`);if($===void 0)return W.tool.execute(z,G);if(D3($),$.kind!=="local")throw Error("McpRegistry: startNative is for a local caller. A remote call goes through execute().");let X=W.descriptor.inputSchema.safeParse(z);if(X.ok===!1)throw new O(`Invalid arguments for "${Z}": ${X.errors.join(", ")}`);return this.runNative(W,{caller:$,req:$.req,tool:W.descriptor,input:X.value},G)}runNative($,Z,z){let G={...z};return L9.set(G,{...Z,ctx:G}),$.tool.execute(Z.input,G)}async executeNative($,Z,z,G,W){let{name:X}=$.descriptor,Y=$.descriptor.inputSchema.safeParse(z);if(Y.ok===!1)throw new O(`Invalid arguments for "${X}": ${Y.errors.join(", ")}`);let K={caller:Z,req:Z.req,tool:$.descriptor,input:Y.value},Q=(_,_3)=>{if(!W.progress)return;let r;try{r=$.meta.remote?.progress?$.meta.remote.progress(_,_3):y$(_,_3)}catch(N){console.error(`[gemi/mcp] The progress mapping of "${X}" failed:`,N);return}if(r)W.progress(r)};if(Z.kind==="local"){if(!G)throw Error(`McpRegistry: "${X}" is a native tool, which runs with the tool context of an agent call, and none was passed to execute().`);return await z9(this.runNative($,{...K,ctx:G},G),Q)}let V=$.meta.remote,H=await this.bind($,"the remote context",()=>V.context(K));if(typeof H!=="object"||H===null)throw console.error(`[gemi/mcp] The remote context of "${X}" is not an object:`,H),new O(`"${X}" failed on the server.`,500);let U=$.tool.timeoutMs,I=[...W.signal?[W.signal]:[],...U!==void 0?[AbortSignal.timeout(U)]:[]],J=I.length===0?new AbortController().signal:I.length===1?I[0]:AbortSignal.any(I),F=G9($,H,J);if(!W.approved&&W3($)&&await X9($,K.input,W9(F)))throw new v(`"${X}" needs the user's approval, and this call does not have it.`,"approval-required");let B;try{B=await z9(this.runNative($,{...K,ctx:F},F),Q,J)}catch(_){if(J.aborted&&_===J.reason){if(W.signal?.aborted)throw new O(`"${X}" was cancelled.`,499);throw new O(`"${X}" did not finish within ${U} ms.`,504)}if(_ instanceof O)throw _;if(_ instanceof e||_ instanceof v)throw new O(_.message);throw console.error(`[gemi/mcp] "${X}" failed for a remote caller:`,_),new O(`"${X}" failed on the server.`,500)}let T=(_)=>{return console.error(`[gemi/mcp] "${X}" ${_}`),new O(`"${X}" failed on the server.`,500)};if(N9(B))throw T("answered a job handle, and a remote call has no background jobs.");let j=B;if($.descriptor.outputSchema){let _=$.descriptor.outputSchema.safeParse(j);if(_.ok===!1)throw T(`answered what its output schema refuses: ${_.errors.join(", ")}`);j=_.value}if(j===void 0)return null;if(typeof j==="string")return j.length>M?`${j.slice(0,M)}\u2026 [cut at ${M} of ${j.length} characters]`:j;let C=JSON.stringify(j);if(C!==void 0&&C.length>M)return`${C.slice(0,M)}\u2026 [cut at ${M} of ${C.length} characters]`;return j}async fillPath($,Z){let{input:z,req:G}=Z,W=$.descriptor.url;for(let X of $.params){let Y=$.paramBinders.get(X.name),K=$.modelParams.get(X.name),Q;if(Y||K){if(Q=K?await this.bind($,`the param "${X.name}"`,()=>K.param.bind(z[K.key],G,Z),{refusals:!0}):await this.bind($,`the param "${X.name}"`,()=>Y(G,Z)),Q===void 0||Q===null||Q==="")throw console.error(`[gemi/mcp] The ${K?"resolver":"binder"} for "${X.name}" of "${$.descriptor.name}" returned ${JSON.stringify(Q)}.`),new O(`"${$.descriptor.name}" failed on the server.`,500)}else Q=z[X.name];let V=`:${X.name}${X.modifier}`;if(Q===void 0||Q===null||Q===""){if(X.modifier!=="?"&&X.modifier!=="*")throw new O(`"${X.name}" of "${$.descriptor.name}" must not be empty.`);W=W.replace(`/${V}`,"");continue}W=W.replace(V,i$($.descriptor.name,X,String(Q)))}return W}async formData($,Z,z){let{input:G,ctx:W}=z,X=$.descriptor.name;if(z.caller.kind==="remote"){let K=new FormData;for(let[Q,V]of Object.entries(Z))O3(K,Q,V);for(let Q of $.fileFields)K.append(Q.name,await this.remoteFile(X,Q.name,G[Q.name]));return K}if(!W)throw Error(`McpRegistry: "${X}" sends a file, which is resolved through the tool context's attachments, and none was passed to execute().`);let Y=new FormData;for(let[K,Q]of Object.entries(Z))O3(Y,K,Q);for(let K of $.fileFields){let Q=K.binder==="input"?G[K.name]:await this.bind($,`the file "${K.name}"`,()=>K.binder(W,z));if(typeof Q!=="string"||Q==="")throw new O(`"${X}" needs a file for "${K.name}", and this turn has none. Ask the user to attach one.`);Y.append(K.name,await W.attachments.file(Q))}return Y}async remoteFile($,Z,z){let G=(H)=>new O(`"${Z}" of "${$}" ${H}`,400),W=z,{maxBytes:X,fetch:Y}=this.files;if(!v$(W.name))throw G("needs a name of 1 to 255 characters, without control characters or slashes.");if(!g$.test(W.mimeType))throw G(`has a mimeType that is not a media type: "${W.mimeType.slice(0,100)}".`);let K=typeof W.data==="string",Q=typeof W.url==="string";if(K===Q)throw G(Y?"needs exactly one of data or url.":"needs its bytes, base64, in data.");if(K){let H=W.data.replace(/\s+/g,"");if(Math.floor(H.length*3/4)-m$(H)>X)throw G(`is larger than the ${X} bytes a file may be.`);if(H.length%4!==0||!h$.test(H))throw G("has data that is not base64 (RFC 4648, standard alphabet, padded).");return new File([Buffer.from(H,"base64")],W.name,{type:W.mimeType})}if(!Y)throw G("cannot be fetched from a URL here. Send its bytes, base64, in data.");let V;try{V=new URL(W.url)}catch{throw G("has a url that is not a URL.")}if(V.protocol!=="https:")throw G("can only be fetched from an https URL.");try{let H=await J9(V.href,{...Y,maxSize:Math.min(Y.maxSize??X,X),redirect:"follow"});if(!H.ok)throw G(`could not be fetched: ${V.host} answered ${H.status}.`);let U=await H.arrayBuffer();return new File([U],W.name,{type:W.mimeType})}catch(H){if(H instanceof O)throw H;throw G(`could not be fetched from ${V.host}: ${H instanceof Error?H.message:"failed"}.`)}}grants($,Z){for(let z of $.scopes??[])if(this.scopeTools.get(z)?.tools.has(Z))return!0;return!1}resolveScopes(){let $=this.router.scopes;if($===void 0){this.scopeTools.set(T$,{description:"Use this app's tools as you",tools:new Set(this.plans.keys())});return}if(typeof $!=="object"||$===null)throw Error("McpRouter: scopes must be an object of scope names.");let Z=new Set([...this.plans.values()].flatMap(({descriptor:z})=>z.tags));for(let[z,G]of Object.entries($)){let W=`McpRouter: scope "${z}"`;if(!k$.test(z))throw Error(`${W} is not a valid OAuth scope: printable ASCII, no spaces or quotes.`);if(typeof G?.description!=="string"||G.description==="")throw Error(`${W} needs a description: it is what a consent screen shows.`);let X=new Set;for(let Y of G.tags??[]){if(!Z.has(Y))throw Error(`${W} names the tag "${Y}", which no tool has.`);for(let[K,{descriptor:Q}]of this.plans)if(Q.tags.includes(Y))X.add(K)}for(let Y of G.names??[]){if(!this.plans.has(Y))throw Error(`${W} names "${Y}", which is no tool.`);X.add(Y)}if(X.size===0)throw Error(`${W} reaches no tool. Give it tags or names.`);this.scopeTools.set(z,{description:G.description,tools:X})}}async project($,Z,z){let{name:G,outputSchema:W}=$.descriptor;if(z.status<200||z.status>=300)return await U9(G,z);let X=(U,I)=>{if(I===void 0)console.error(`[gemi/mcp] "${G}" ${U}`);else console.error(`[gemi/mcp] "${G}" ${U}`,I);return new O(`"${G}" failed on the server.`,500)},Y=z.headers.get("Content-Type"),K=await z.text(),Q=null;if(K!=="")try{Q=JSON.parse(K)}catch{throw X(`answered ${Y??"a body with no content-type"} that is not JSON, and its result or output needs JSON.`)}let V=Q;if($.result)try{V=await $.result(Q,Z)}catch(U){throw X("failed in its result projection:",U)}if(W){let U=W.safeParse(V);if(U.ok===!1)throw X(`answered what its output schema refuses: ${U.errors.join(", ")}`);V=U.value}if(V===void 0)return null;let H=JSON.stringify(V);if(H!==void 0&&H.length>M)return`${H.slice(0,M)}\u2026 [cut at ${M} of ${H.length} characters]`;return V}async bind($,Z,z,G={}){try{return await z()}catch(W){if(G.refusals&&W instanceof e)throw W;throw console.error(`[gemi/mcp] Binding ${Z} of "${$.descriptor.name}" failed:`,W),new O(`"${$.descriptor.name}" failed on the server.`,500)}}}function E$($){return $ instanceof Object&&$.__internal_brand==="McpTool"}function b$($){return typeof $==="object"&&$!==null&&typeof $.next==="function"&&Symbol.asyncIterator in $}async function z9($,Z,z){let G;if(z)G=new Promise((X,Y)=>{if(z.aborted)Y(z.reason);else z.addEventListener("abort",()=>Y(z.reason),{once:!0})}),G.catch(()=>{});let W=(X)=>G?Promise.race([X,G]):X;if(!b$($))return await W(Promise.resolve($));try{let X=0,Y=await W($.next());while(!Y.done)Z(Y.value,++X),Y=await W($.next());return Y.value}catch(X){throw $.return(void 0).catch(()=>{}),X}}function y$($,Z){if(typeof $==="string")return{progress:Z,message:$};if(typeof $==="object"&&$!==null){let{progress:z,total:G,message:W}=$;if(typeof z==="number"&&Number.isFinite(z))return{progress:z,...typeof G==="number"?{total:G}:{},...typeof W==="string"?{message:W}:{}};if(typeof W==="string")return{progress:Z,message:W}}return{progress:Z}}function G9($,Z,z){let G=$.descriptor.name,W=`mcp_${crypto.randomUUID()}`,X=`mcp_call_${crypto.randomUUID()}`,Y=(Q)=>async()=>{throw new e(`"${G}" was called by a remote MCP client, which has no ${Q}.`,{retryable:!1})},K={put:Y("attachment store"),get:Y("attachment store"),read:Y("attachment store"),file:Y("attachment store")};return{context:Z,body:{},runId:W,toolCallId:X,signal:z,step:1,depth:0,resumed:!1,attachments:K,turn:Object.freeze({attachments:Object.freeze([])}),runAgent:Y("agent run to nest a sub-agent in"),generateImage:Y("attachment store to put an image in"),editImage:Y("attachment store to put an image in"),generate:(Q)=>I9({...Q,signal:Q.signal?AbortSignal.any([z,Q.signal]):z},{origin:{mcp:G,runId:W,toolCallId:X}}),jobs:B9({jobs:void 0,threadId:void 0,runId:W,toolCallId:X,toolName:G,depth:0,async:$.tool.async,attachments:null}),memory:P9(),meter:F9().meter}}function W3($){if($.kind!=="tool"||$.meta.requiresApproval===!0)return;return $.tool.approvalPredicate}function W9($){return{context:$.context,body:$.body,runId:$.runId,threadId:$.threadId,toolCallId:$.toolCallId,step:$.step,depth:$.depth,signal:$.signal}}async function X9($,Z,z){try{return await $.tool.approvalPredicate(Z,z)!==!1}catch(G){return console.error(`[gemi/mcp] The requiresApproval of "${$.descriptor.name}" threw, so the call asks the user:`,G),!0}}function D3($){if($?.kind==="local"&&$.req)return;if($?.kind==="remote"&&$.req&&$.principal?.user&&typeof $.principal.id==="string"&&Array.isArray($.principal.scopes))return;throw Error('McpRegistry: a caller is { kind: "local", req } or { kind: "remote", req, principal }, with the principal a caller resolver verified.')}function Y9($,Z){if(Z?.names&&!Z.names.includes($.name))return!1;if(Z?.tags&&!$.tags.some((z)=>Z.tags.includes(z)))return!1;return!0}var f$=10485760;function w$($){let Z=$?.maxBytes??f$;if(!Number.isSafeInteger(Z)||Z<=0)throw Error("McpRegistry: files.maxBytes must be a positive whole number of bytes.");let z=$?.fetchUrls===!0?{}:typeof $?.fetchUrls==="object"&&$.fetchUrls!==null?$.fetchUrls:null;return{maxBytes:Z,fetch:z}}function v$($){if($.length===0||$.length>255)return!1;for(let Z of $){let z=Z.codePointAt(0);if(z<32||z===127||Z==="/"||Z==="\\")return!1}return!0}var g$=/^[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}\/[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}(\s*;.{0,200})?$/,h$=/^[A-Za-z0-9+/]*={0,2}$/;function m$($){return $.endsWith("==")?2:$.endsWith("=")?1:0}function K9($,Z,z){if(z!=="input"&&typeof z!=="function")throw Error(`${$}: ${Z} must be a function or "input".`)}function Q9($){return $ instanceof Object&&$.__internal_brand==="McpModelParam"}function u$($,Z,z){if(z.as!==void 0&&(typeof z.as!=="string"||z.as===""))throw Error(`${$}: ${Z}.as must be a non-empty string.`);let G=z.input;if(typeof G?.safeParse!=="function"||typeof G.toJSONSchema!=="function")throw Error(`${$}: ${Z}.input must be a schema, built with s.`);if(typeof z.bind!=="function")throw Error(`${$}: ${Z}.bind must be a function.`)}var d$=new Set(["readOnlyHint","destructiveHint","idempotentHint","openWorldHint"]);function c$($){switch($){case"GET":return{readOnlyHint:!0};case"DELETE":return{destructiveHint:!0};case"PUT":return{idempotentHint:!0};default:return{}}}function V9($,Z,z){if(z!==void 0&&(typeof z!=="object"||z===null))throw Error(`${$}: annotations must be an object of hints.`);let G=Z?c$(Z):{};for(let[W,X]of Object.entries(z??{})){if(!d$.has(W))throw Error(`${$}: "${W}" is not a tool annotation. Use readOnlyHint, destructiveHint, idempotentHint or openWorldHint.`);if(X===void 0)continue;if(typeof X!=="boolean")throw Error(`${$}: annotations.${W} must be true or false.`);G[W]=X}if(G.readOnlyHint===!0&&(G.destructiveHint||G.idempotentHint))throw Error(`${$} is read-only${z?.readOnlyHint?"":` (a ${Z})`} and also ${G.destructiveHint?"destructive":"idempotent"}, which only a tool that is not read-only can be. Set readOnlyHint: false if it changes something.`);return Object.freeze(G)}function H9($,Z,z,G={}){let W=z.toJSONSchema(),X=Object.fromEntries(Object.entries(G).map(([Q,V])=>[Q,V.toJSONSchema()])),Y={...Z??{},type:"object",properties:{...Z?.properties??{},...W.properties,...X},required:[...Z?.required??[],...W.required??[],...Object.keys(G)],additionalProperties:!1},K=(Q)=>{if(typeof Q!=="object"||Q===null||Array.isArray(Q))return{ok:!1,errors:["expected an object"]};let V=[],H={};if($){let I=$.safeParse(Q);if(I.ok===!1)V.push(...I.errors);else H={...I.value}}let U=z.safeParse(Q);if(U.ok===!1)V.push(...U.errors);else H={...H,...U.value};for(let[I,J]of Object.entries(G)){let F=Q[I];if(F===void 0){V.push(`"${I}" is required`);continue}let B=J.safeParse(F);if(B.ok===!1)V.push(...B.errors.map((T)=>`${I}: ${T}`));else H[I]=B.value}return V.length>0?{ok:!1,errors:V}:{ok:!0,value:H}};return{toJSONSchema:()=>Y,safeParse:K,parse(Q){let V=K(Q);if(V.ok===!1)throw Error(V.errors.join(", "));return V.value}}}function p$($,Z){return Object.fromEntries(Object.entries($).filter(([z])=>!Z.includes(z)))}function i$($,Z,z){let G=Z.modifier==="*"||Z.modifier==="+"?z.split("/"):[z];if(G.some((W)=>W==="."||W===".."))throw new O(`"${z}" is not a valid value for "${Z.name}" of "${$}".`);return G.map(encodeURIComponent).join("/")}function O3($,Z,z){if(z===void 0||z===null)return;if(Array.isArray(z)){for(let G of z)O3($,Z,G);return}$.append(Z,typeof z==="object"?JSON.stringify(z):String(z))}function l$($){let Z=new URLSearchParams,z=(G,W)=>{if(W===void 0||W===null)return;if(Array.isArray(W)){for(let X of W)z(G,X);return}Z.append(G,typeof W==="object"?JSON.stringify(W):String(W))};for(let[G,W]of Object.entries($))z(G,W);return Z.toString()}async function U9($,Z){if(Z.status>=200&&Z.status<300){let G=Z.headers.get("Content-Type");if(G&&!R$.test(G)){let X=(await Z.arrayBuffer()).byteLength;return`"${$}" answered with ${X} bytes of ${G}, which is not shown.`}let W=await Z.text();if(W==="")return null;if(W.length>M)return`${W.slice(0,M)}\u2026 [cut at ${M} of ${W.length} characters]`;try{return JSON.parse(W)}catch{return W}}let z=await Z.text();if(Z.status>=400&&Z.status<500){let G=z.length>Z9?`${z.slice(0,Z9)}\u2026`:z;throw new O(`"${$}" was refused with ${Z.status}${G?`: ${G}`:"."}`,Z.status)}if(Z.status<500)console.error(`[gemi/mcp] "${$}" answered ${Z.status}${Z.headers.get("Location")?` to ${Z.headers.get("Location")}`:""}, which a tool call cannot follow.`);throw new O(`"${$}" failed on the server.`,Z.status)}import{createHash as n$,randomBytes as s$,timingSafeEqual as t$}from"crypto";function j3($){let Z=$.headers.get("authorization");if(!Z)return null;let z=/^Bearer[ ]+([\x21-\x7e]+)$/i.exec(Z.trim());return z?z[1]:null}class o${options;name="api-key";constructor($){this.options=$;if(typeof $?.prefix!=="string"||!/^[A-Za-z0-9_-]{3,32}$/.test($.prefix))throw Error('McpApiKeyResolver: prefix is required: 3 to 32 letters, digits, _ or -, like "myapp_mcp_".');if(typeof $.verify!=="function")throw Error("McpApiKeyResolver: verify must be a function that looks a key up.")}static generate($){return`${$}${s$(32).toString("base64url")}`}static hash($){return n$("sha256").update($).digest("hex")}static hashesMatch($,Z){let z=Buffer.from($),G=Buffer.from(Z);return z.length===G.length&&t$(z,G)}async resolve($){let Z=j3($);if(!Z?.startsWith(this.options.prefix))return null;let z=await this.options.verify(Z,$);if(!z)return{ok:!1,error:"invalid_token",description:"The API key is not valid."};if(!z.user||typeof z.id!=="string"||z.id===""||!Array.isArray(z.scopes))throw Error("McpApiKeyResolver: verify must answer { user, id, scopes } for a key it knows, or null.");return{ok:!0,principal:{user:z.user,via:this.name,id:z.id,scopes:[...z.scopes]}}}}import{createHash as y9,randomBytes as j9}from"crypto";async function A3($,Z){let z=a$();if(!z)return null;let G=await z.consume($,Z);return G.allowed?null:Math.max(1,Math.ceil(G.retryAfter/1000))}function a$(){try{let $=y();return $.bound(l)?$.make(l):null}catch{return null}}var x3=["2026-07-28"],Y3=["2025-11-25","2025-06-18","2025-03-26"],C3=[...x3,...Y3],S3="io.modelcontextprotocol/protocolVersion",q3="io.modelcontextprotocol/clientCapabilities";var T3="io.modelcontextprotocol/serverInfo",D={ParseError:-32700,InvalidRequest:-32600,MethodNotFound:-32601,InvalidParams:-32602,InternalError:-32603,HeaderMismatch:-32020,MissingRequiredClientCapability:-32021,UnsupportedProtocolVersion:-32022};class L extends Error{code;data;status;constructor($,Z,z,G=200){super(Z);this.code=$;this.data=z;this.status=G;this.name="JsonRpcError"}}function R($,Z){return{jsonrpc:"2.0",id:$,error:{code:Z.code,message:Z.message,...Z.data!==void 0?{data:Z.data}:{}}}}function _9($){if(Array.isArray($))throw new L(D.InvalidRequest,"Batched requests are not supported.",void 0,400);if(typeof $!=="object"||$===null||$.jsonrpc!=="2.0")throw new L(D.InvalidRequest,"Not a JSON-RPC 2.0 message.",void 0,400);let Z=$,z=Z.id,G=typeof z==="string"||typeof z==="number"&&Number.isFinite(z);if(typeof Z.method==="string"){if(Z.params!==void 0&&(typeof Z.params!=="object"||Z.params===null||Array.isArray(Z.params)))throw new L(D.InvalidRequest,"params must be an object.",void 0,400);if(z===void 0)return{kind:"notification",message:Z};if(!G)throw new L(D.InvalidRequest,"id must be a string or a number.",void 0,400);return{kind:"request",message:Z}}if(G&&(("result"in Z)||("error"in Z)))return{kind:"response",message:Z};throw new L(D.InvalidRequest,"Not a JSON-RPC request, notification or response.",void 0,400)}function k3($,Z){let z=$.outputSchema?.toJSONSchema(),G={...$.annotations,...$.title&&!Z?{title:$.title}:{}};return{name:$.name,...$.title?{title:$.title}:{},description:$.description,inputSchema:$.inputSchema.toJSONSchema(),...z&&(Z||z.type==="object")?{outputSchema:z}:{},...Object.keys(G).length>0?{annotations:G}:{}}}function q($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function D9($){let Z=/^=\?base64\?([A-Za-z0-9+/]*={0,2})\?=$/.exec($);if(!Z)return $;try{let z=Buffer.from(Z[1],"base64");return new TextDecoder("utf-8",{fatal:!0}).decode(z)}catch{return null}}import{createHmac as r$,timingSafeEqual as e$}from"crypto";function M3($,Z,z){let G=Buffer.from(JSON.stringify(z)).toString("base64url");return`${Z}.${G}.${O9($,Z,G).toString("base64url")}`}function R3($,Z,z,G=Date.now()){if(typeof z!=="string"||z.length>8192)return null;let W=z.split(".");if(W.length!==3||W[0]!==Z)return null;let[,X,Y]=W,K=Buffer.from(Y,"base64url"),Q=O9($,Z,X);if(K.length!==Q.length||!e$(K,Q))return null;let V;try{V=JSON.parse(Buffer.from(X,"base64url").toString("utf8"))}catch{return null}if(typeof V!=="object"||V===null)return null;if(typeof V.exp!=="number"||V.exp<=G)return null;return V}function O9($,Z,z){return r$("sha256",K3($)).update(`${Z}.${z}`).digest()}var E3="gemi.mcp.request-state.v1",A9="gemi.mcp.session.v1",$2=86400000,x9=600000,C9="gemi_approval",b3=2000,Z2={limit:600,window:60},z2={limit:30,window:60};class $3{registry;static token="router.mcp.http";endpoint;resolvers;context;allowedOrigins;rateLimit;maxBodyBytes;serverInfo;instructions;nonces;approvalTimeoutMs;onCall;feature;featureOn;pending=new Map;inflight=new Map;constructor($,Z,z={}){this.registry=$;if(typeof Z.url!=="string")throw Error(`route.mcp.remote.url is required: the endpoint's canonical URL, like "https://example.com/mcp".`);this.endpoint=X2(Z.url);let G=Z.resolvers??[];if(!Array.isArray(G)||G.length===0)throw Error("route.mcp.remote is enabled without a caller resolver. Configure route.mcp.remote.resolvers \u2014 an McpOAuthServer, an McpApiKeyResolver, or your own \u2014 or leave the endpoint off. Without one every request would be refused, or answered as nobody.");for(let W of G)if(typeof W?.resolve!=="function"||typeof W.name!=="string"||W.name==="")throw Error("route.mcp.remote.resolvers: each resolver needs a name and a resolve().");if(this.resolvers=G,K3(E3),this.context={resource:this.resource,registry:$},this.allowedOrigins=new Set((Z.allowedOrigins??[]).map((W)=>{if(new URL(W).origin!==W)throw Error(`route.mcp.remote.allowedOrigins: "${W}" is not an origin (scheme://host[:port]).`);return W})),this.allowedOrigins.add(this.endpoint.origin),this.rateLimit=Z.rateLimit===!1?!1:Z.rateLimit??Z2,this.maxBodyBytes=Z.maxBodyBytes??Math.ceil($.maxFileBytes*1.4)+1048576,this.serverInfo={name:Z.server?.name??"gemi",version:Z.server?.version??"1.0.0"},this.instructions=Z.server?.instructions,this.nonces=Z.nonces??new E9,this.approvalTimeoutMs=Z.approvalTimeoutMs??x9,Z.onCall!==void 0&&typeof Z.onCall!=="function")throw Error("route.mcp.remote.onCall must be a function.");if(this.onCall=Z.onCall,Z.feature!==void 0){if(typeof Z.feature!=="string"||Z.feature==="")throw Error("route.mcp.remote.feature must be a feature key from app/features.");this.feature=Z.feature}this.featureOn=z.featureOn??X3;for(let W of G)W.boot?.(this.context)}get resource(){return this.endpoint.href.replace(/\/$/,"")}async handle($){let Z=new URL($.url);if(Z.host!==this.endpoint.host)return null;if(this.feature!==void 0){if(!this.ownsPath(Z.pathname))return null;if(await this.featureOn(this.feature)!==!0)return null}for(let W of this.resolvers){let X=await W.handle?.($,this.context);if(X)return X}if(Z.pathname!==this.endpoint.pathname)return null;let z=$.headers.get("origin");if(z!==null&&!this.allowedOrigins.has(z))return f(R(null,new L(D.InvalidRequest,"Origin not allowed.")),403);let G=z?W2(z):{};if($.method==="OPTIONS")return new Response(null,{status:204,headers:{...G,"Access-Control-Allow-Methods":"POST","Access-Control-Allow-Headers":"Authorization, Content-Type, Accept, MCP-Protocol-Version, Mcp-Session-Id, Mcp-Method, Mcp-Name, Last-Event-ID","Access-Control-Max-Age":"600"}});if($.method!=="POST")return S9(new Response(null,{status:405,headers:{Allow:"POST, OPTIONS"}}),G);return S9(await this.post($),G)}ownsPath($){let Z=this.endpoint.pathname.replace(/\/$/,"");return $===this.endpoint.pathname||$===Z||$.startsWith(`${Z}/`)||$.startsWith("/.well-known/")}async post($){let Z=null;for(let Y of this.resolvers){let K=await Y.resolve($,this.context);if(K===null)continue;if(K.ok===!1)return await this.failedAttempt($)??this.unauthorized(K.description);Z={...K.principal,via:Y.name};break}if(!Z)return(j3($)!==null?await this.failedAttempt($):null)??this.unauthorized();let z=await this.spend(Z);if(z)return z;let G=$.headers.get("content-type")??"";if(!/^application\/json\s*(;|$)/i.test(G))return new Response("Content-Type must be application/json.",{status:415});let W;try{W=JSON.parse(await G2($,this.maxBodyBytes))}catch(Y){if(Y instanceof V3)return f(R(null,new L(D.InvalidRequest,`The request is larger than ${this.maxBodyBytes} bytes.`)),413);return f(R(null,new L(D.ParseError,"Parse error.")),400)}let X=new m($,{},"api",this.endpoint.pathname);return await g.run(X,async()=>{try{return await this.dispatch($,X,Z,W)}catch(Y){if(Y instanceof L){let K=q(W)&&(typeof W.id==="string"||typeof W.id==="number")?W.id:null;return f(R(K,Y),Y.status)}return console.error("[gemi/mcp] The MCP endpoint failed:",Y),f(R(null,new L(D.InternalError,"Internal error.")),500)}},{user:Z.user})}async dispatch($,Z,z,G){let W=_9(G),X={kind:"remote",req:Z,principal:z};if(W.kind==="response"){let F=this.session($,z),B=this.pending.get(String(W.message.id));if(B&&B.session===F.id)this.pending.delete(String(W.message.id)),B.resolve(W.message);return new Response(null,{status:202})}let{message:Y}=W,K=Y.params??{},Q=q(K._meta)?K._meta:{};if(typeof Q[S3]==="string"){if(this.checkModernHeaders($,Y,Q[S3]),W.kind==="notification")return new Response(null,{status:202});return await this.respond(Y,async(F,B)=>this.modern({principal:z,caller:X,message:Y,params:K,era:{modern:!0},stream:F,signal:B}),T9(K),$.signal)}if(Y.method==="initialize"){if(W.kind!=="request")throw new L(D.InvalidRequest,"initialize is a request.",void 0,400);return this.initialize(W.message,K,z)}let V=this.session($,z),H=$.headers.get("mcp-protocol-version");if(H!==null&&H!==V.state.v)throw new L(D.InvalidRequest,`MCP-Protocol-Version ${H} is not the session's ${V.state.v}.`,void 0,400);if(W.kind==="notification"){if(Y.method==="notifications/cancelled"){let F=K.requestId;this.inflight.get(`${V.id}:${String(F)}`)?.abort()}return new Response(null,{status:202})}let U=`${V.id}:${String(Y.id)}`,I=new AbortController;this.inflight.set(U,I);let J=AbortSignal.any([I.signal,$.signal]);try{return await this.respond(Y,async(F,B)=>this.legacy({principal:z,caller:X,message:Y,params:K,era:{modern:!1,session:V.state,sessionId:V.id},stream:F,signal:B}),T9(K)||K2(this.registry,Y,V.state),J,()=>this.inflight.delete(U))}catch(F){throw this.inflight.delete(U),F}}async modern($){switch($.message.method){case"server/discover":return this.complete({supportedVersions:C3,capabilities:{tools:{}},...this.instructions?{instructions:this.instructions}:{},ttlMs:60000,cacheScope:"private"});case"tools/list":return this.complete({tools:(await this.registry.available($.caller)).map((Z)=>k3(Z,!0)),ttlMs:60000,cacheScope:"private"});case"tools/call":return await this.callTool($);default:throw new L(D.MethodNotFound,`Method not found: ${$.message.method}`,void 0,404)}}async legacy($){switch($.message.method){case"ping":return{};case"tools/list":return{tools:(await this.registry.available($.caller)).map((Z)=>k3(Z,!1))};case"tools/call":return await this.callTool($);default:throw new L(D.MethodNotFound,`Method not found: ${$.message.method}`)}}complete($){return{resultType:"complete",...$,_meta:{[T3]:this.serverInfo}}}initialize($,Z,z){let G=Z.protocolVersion,W=Y3.includes(G)?G:Y3[0],X=q(Z.capabilities)?Z.capabilities:{},Y={v:W,e:q9(X.elicitation),p:Q3(z),exp:Date.now()+$2},K=M3(A9,"gms1",Y);return f({jsonrpc:"2.0",id:$.id,result:{protocolVersion:W,capabilities:{tools:{listChanged:!1}},serverInfo:this.serverInfo,...this.instructions?{instructions:this.instructions}:{}}},200,{"Mcp-Session-Id":K})}session($,Z){let z=$.headers.get("mcp-session-id");if(!z)throw new L(D.InvalidRequest,"Missing Mcp-Session-Id. Send initialize first, or a request carrying io.modelcontextprotocol/protocolVersion in _meta.",void 0,400);let G=R3(A9,"gms1",z);if(!G||G.p!==Q3(Z))throw new L(D.InvalidRequest,"Session not found.",void 0,404);return{id:z,state:G}}checkModernHeaders($,Z,z){if(!x3.includes(z))throw new L(D.UnsupportedProtocolVersion,"Unsupported protocol version",{supported:C3,requested:z},400);let G=(Y)=>new L(D.HeaderMismatch,`Header mismatch: ${Y}`,void 0,400);if($.headers.get("mcp-protocol-version")!==z)throw G("MCP-Protocol-Version does not match the protocol version in _meta.");if($.headers.get("mcp-method")!==Z.method)throw G("Mcp-Method does not match the method.");let W=Z.params??{},X=Z.method==="tools/call"||Z.method==="prompts/get"?W.name:Z.method==="resources/read"?W.uri:void 0;if(X!==void 0){let Y=$.headers.get("mcp-name");if(Y===null||D9(Y)!==X)throw G("Mcp-Name does not match the request's name.")}}async callTool($){let Z=$.params.name;if(typeof Z!=="string")throw new L(D.InvalidParams,"tools/call needs a tool name.");let z=$.params.arguments??{};if(!this.onCall)return await this.runTool($,Z,z,{approved:!1});let G=performance.now(),W={approved:!1};try{let X=await this.runTool($,Z,z,W);if(!W.pending)await this.report($,Z,z,W,G);return X}catch(X){if(!W.outcome){if(W.outcome="error",W.message=X instanceof L?X.message:"Internal error.",!(X instanceof L))W.error=X}throw await this.report($,Z,z,W,G),X}}async report($,Z,z,G,W){let{principal:X}=$;try{await this.onCall({user:X.user,via:X.via,credentialId:X.id,clientId:X.clientId??null,scopes:X.scopes,tool:Z,arguments:z,outcome:G.outcome??"ok",...G.reason!==void 0?{reason:G.reason}:{},...G.message!==void 0?{message:G.message}:{},...G.status!==void 0?{status:G.status}:{},...G.error!==void 0?{error:G.error}:{},approved:G.approved,durationMs:Math.round((performance.now()-W)*1000)/1000,req:$.caller.req})}catch(Y){console.error(`[gemi/mcp] route.mcp.remote.onCall failed for "${Z}":`,Y)}}async runTool($,Z,z,G){let{caller:W,principal:X}=$,Y=(J,F)=>{G.outcome="denied",G.reason=J,G.message=F},K=(J,F,B)=>{if(G.outcome="error",G.message=J,F!==void 0)G.status=F;if(B!==void 0)G.error=B},Q=(await this.registry.available(W,{names:[Z]}))[0];if(!Q)throw Y("unknown-tool",`Unknown tool: ${Z}`),new L(D.InvalidParams,`Unknown tool: ${Z}`);if(Q.requiresApproval){let J=Q.inputSchema.safeParse(z);if(J.ok===!1){let B=`Invalid arguments for "${Z}": ${J.errors.join(", ")}`;return K(B),this.toolResult($,{content:[{type:"text",text:B}],isError:!0})}if($.era.modern&&q($.params.inputResponses)&&$.params.requestState!==void 0||await this.registry.approvalRequired(W,Z,z,{signal:$.signal})){let B=await this.approval($,Q,z,Y,G);if(B.kind==="answer")return B.result;G.approved=!0}}let V=Q2($),H;try{H=await this.registry.execute(W,Z,z,void 0,{approved:G.approved,signal:$.signal,...V?{progress:V}:{}})}catch(J){if(J instanceof O){if(J.status===401||J.status===403)Y("forbidden",J.message),G.status=J.status;else K(J.message,J.status);return this.toolResult($,{content:[{type:"text",text:J.message}],isError:!0})}if(J instanceof v){let B=J.reason==="unknown-tool"?`Unknown tool: ${Z}`:J.message;throw Y(J.reason,B),new L(D.InvalidParams,B)}console.error(`[gemi/mcp] "${Z}" failed for ${X.via}:${X.id}:`,J);let F=`"${Z}" failed on the server.`;return K(F,void 0,J),this.toolResult($,{content:[{type:"text",text:F}],isError:!0})}let U=typeof H==="string"?H:JSON.stringify(H??null),I=Q.outputSchema&&($.era.modern||q(H))?{structuredContent:H}:{};return G.outcome="ok",this.toolResult($,{content:[{type:"text",text:U}],...I,isError:!1})}toolResult($,Z){return $.era.modern?this.complete(Z):Z}async approval($,Z,z,G,W){let X=V2(Z,z),Y=(I,J="approval-declined")=>{return G(J,I),{kind:"answer",result:this.toolResult($,{content:[{type:"text",text:I}],isError:!0})}},K=(I,J)=>{return G(I,J.message),J};if($.era.modern){let I=q($.params._meta)?$.params._meta:{},J=q(I[q3])?I[q3]:{},F=q($.params.inputResponses)?$.params.inputResponses:null,B=$.params.requestState,T=Y2(z);if(F&&B!==void 0){let C=R3(E3,"grs1",B);if(!C||C.p!==Q3($.principal)||C.t!==Z.name||C.a!==T)throw K("approval-invalid",new L(D.InvalidParams,"requestState is not valid for this call."));if(!await this.spendNonce(C.n,C.exp))throw K("approval-replayed",new L(D.InvalidParams,"requestState has already been used."));return k9(F[C9])?{kind:"approved"}:Y(`The user did not approve "${Z.name}", and it did not run.`)}if(!q9(J.elicitation))throw K("approval-unavailable",new L(D.MissingRequiredClientCapability,`"${Z.name}" needs the user's approval, and this client cannot ask for it (elicitation).`,{requiredCapabilities:{elicitation:{form:{}}}},400));let j={p:Q3($.principal),t:Z.name,a:T,n:j9(16).toString("base64url"),exp:Date.now()+x9};return W.pending=!0,{kind:"answer",result:{resultType:"input_required",inputRequests:{[C9]:{method:"elicitation/create",params:{mode:"form",...X}}},requestState:M3(E3,"grs1",j),_meta:{[T3]:this.serverInfo}}}}let Q=$.era;if(!Q.session.e||!$.stream)return Y(`"${Z.name}" needs the user's approval, and this client cannot ask for it (elicitation). It did not run.`,"approval-unavailable");let V=`gemi-approval-${j9(12).toString("base64url")}`,H=Q.sessionId,U=await new Promise((I)=>{let J=setTimeout(()=>{this.pending.delete(V),I(null)},this.approvalTimeoutMs),F=(B)=>{clearTimeout(J),I(B)};this.pending.set(V,{session:H,resolve:F}),$.signal.addEventListener("abort",()=>{this.pending.delete(V),F(null)}),$.stream.send({jsonrpc:"2.0",id:V,method:"elicitation/create",params:Q.session.v==="2025-11-25"?{mode:"form",...X}:X})});return U&&!U.error&&k9(U.result)?{kind:"approved"}:Y(`The user did not approve "${Z.name}", and it did not run.`)}async spendNonce($,Z){try{return await this.nonces.consume($,Z)}catch(z){return console.error("[gemi/mcp] Spending an approval failed:",z),!1}}async respond($,Z,z,G,W){if(!z)try{let Q=await Z(null,G);return f({jsonrpc:"2.0",id:$.id,result:Q},200)}finally{W?.()}let X=new AbortController,Y=AbortSignal.any([X.signal,G]),K=new f9(()=>X.abort());return(async()=>{try{let Q=await Z(K,Y);K.send({jsonrpc:"2.0",id:$.id,result:Q})}catch(Q){if(Q instanceof L)K.send(R($.id,Q));else console.error("[gemi/mcp] The MCP endpoint failed:",Q),K.send(R($.id,new L(D.InternalError,"Internal error.")))}finally{W?.(),K.close()}})(),new Response(K.readable,{status:200,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-store","X-Accel-Buffering":"no"}})}unauthorized($){let Z=this.resolvers.map((G)=>G.challenge?.(this.context)).find(Boolean)??'Bearer realm="mcp"',z=$?`${Z}, error="invalid_token", error_description="${$.replace(/["\\]/g,"")}"`:Z;return f(R(null,new L(D.InvalidRequest,"Unauthorized.")),401,{"WWW-Authenticate":z})}async failedAttempt($){let Z=R9(new m($,{},"api",this.endpoint.pathname)),z=await A3(`mcp-auth-failed:${Z}`,z2);return z===null?null:M9(z)}async spend($){if(!this.rateLimit)return null;let Z=await A3(`mcp-endpoint:${$.via}:${$.id}`,this.rateLimit);return Z===null?null:M9(Z)}}class f9{readable;controller;closed=!1;encoder=new TextEncoder;constructor($){this.readable=new ReadableStream({start:(Z)=>{this.controller=Z},cancel:()=>{this.closed=!0,$()}})}send($){if(this.closed)return;this.controller.enqueue(this.encoder.encode(`event: message
|
|
2
|
+
import{Dc as B9,Qc as P9,Yb as E9,ac as K3,bc as b9,fc as F9,kc as e,xc as N9,xd as I9}from"./chunk-a1r1r1z7.js";import{Ed as i3,Gd as B3,Jd as i9,Kd as l9,Ld as J$,Nd as O$}from"./chunk-xmjzyzn6.js";import{Qd as h9,Vd as m9,Xd as u9,ce as x,de as d9,ee as c9,ge as p9,he as L$}from"./chunk-87nekrjj.js";import{ke as P}from"./chunk-q19cs1qf.js";import{$g as A$,Ag as g3,Bg as f3,Ce as R9,Df as Z3,Eg as w3,Fg as $$,Ge as x$,Gg as G3,Hg as Z$,Ig as z$,Je as U$,Jf as H3,Jg as v3,Kf as u3,Kg as a,Lf as k,Ng as q$,Of as V$,Og as L3,Pf as Y$,Pg as p3,Qf as K$,Sf as w,Te as F$,Ue as l3,Ug as Q$,Vg as H$,Ye as J3,Ze as X3,dg as e3,og as a3,pf as d3,qg as n,ug as r3,vg as r9,wg as e9,ye as l,ze as X$}from"./chunk-5y6e8kpe.js";import{Ki as J9,Oi as P3,Pi as F3,Qi as z3,ei as p,gi as m,vi as o3}from"./chunk-zenfs4e2.js";import{Wi as s9}from"./chunk-q6rse2fh.js";import{fj as g}from"./chunk-spmxhsze.js";import{lj as c3}from"./chunk-7bz43qbt.js";import{oj as N$,pj as n3,sj as N3,tj as t3,wj as P$}from"./chunk-a1414jdv.js";import{Kj as t9,Pj as o9}from"./chunk-vhyabcw9.js";import{dk as g9,fk as u}from"./chunk-vv8vjjez.js";import{gk as A}from"./chunk-ecv4mtgh.js";import{mk as D$}from"./chunk-wtdmwmm7.js";import{al as s3}from"./chunk-96r16t57.js";import{hl as U3,kl as y}from"./chunk-nadkwh8a.js";import{tl as m3}from"./chunk-m906xc76.js";import{Fl as a9}from"./chunk-0ahecas6.js";var T$="mcp",k$=/^[\x21\x23-\x5B\x5D-\x7E]+$/;class O extends e{status;constructor($,Z){super($);this.status=Z;this.name="McpToolError"}}class v extends Error{reason;constructor($,Z){super($);this.reason=Z;this.name="McpCallRefusedError"}}var $9=/^[A-Za-z0-9_-]{1,64}$/,M$=/:([A-Za-z_][A-Za-z0-9_]*)([?*+]?)/g,Z9=4000,M=1e5,R$=/^(text\/|application\/([\w.+-]*\+)?(json|xml))/i,L9=new WeakMap;function V6($){return L9.get($)}class i{router;dispatcher;static token="router.mcp";plans=new Map;scopeTools=new Map;files;featureOn;constructor($,Z,z={}){this.router=$;this.dispatcher=Z;this.files=w$(z.files),this.featureOn=z.featureOn??X3;for(let[G,W]of Object.entries($.routes??{}))this.plans.set(G,E$(W)?this.planNative(G,W):this.plan(G,W));this.resolveScopes()}list($,Z){if(D3($),$.kind==="local")return this.descriptors(Z);let z=[];for(let[G,W]of this.plans){if(!W.remote||!this.grants($.principal,G))continue;if(Y9(W.remote,Z))z.push(W.remote)}return z}async available($,Z){let z=[];for(let G of this.list($,Z))if(await this.isOn(G))z.push(G);return z}descriptors($){let Z=[];for(let{descriptor:z}of this.plans.values())if(Y9(z,$))Z.push(z);return Z}get maxFileBytes(){return this.files.maxBytes}scopes(){return[...this.scopeTools].map(([$,{description:Z}])=>({name:$,description:Z}))}scopesFor($){return[...this.scopeTools].filter(([,{tools:Z}])=>Z.has($)).map(([Z])=>Z)}async execute($,Z,z,G,W={}){D3($);let X=this.plans.get(Z);if(X&&!await this.isOn(X.descriptor)){if($.kind==="remote")throw new v(`There is no tool named "${Z}".`,"unknown-tool");throw new O(`There is no tool named "${Z}".`,404)}if($.kind==="remote"){if(!X?.remote||!this.grants($.principal,Z))throw new v(`There is no tool named "${Z}".`,"unknown-tool");if(X.descriptor.requiresApproval&&W.approved!==!0&&!W3(X))throw new v(`"${Z}" needs the user's approval, and this call does not have it.`,"approval-required");G=void 0}if(!X)throw Error(`McpRegistry: there is no tool named "${Z}".`);if(X.kind==="tool")return await this.executeNative(X,$,z,G,W);let Y=X,K=$.kind==="remote"?Y.remote:Y.descriptor,Q=K.inputSchema.safeParse(z);if(Q.ok===!1)throw new O(`Invalid arguments for "${Z}": ${Q.errors.join(", ")}`);let V=Q.value,H={caller:$,req:$.req,tool:K,input:V,ctx:G},U=await this.fillPath(Y,H),{path:I}=this.dispatcher.getRouteHandlerAndParams(new Request(`http://gemi.internal/api${U}`));if(I!==K.url)throw new O(`"${Z}" has nothing at ${U}.`,404);let J={};for(let _ of Y.jsonKeys)if(V[_]!==void 0)J[_]=V[_];let F,B="";if(Y.fileFields.length>0)F=await this.formData(Y,J,H);else if(K.method==="GET")B=l$(J);else if(Y.jsonKeys.length>0)F=J;let T=this.router.credentials?await this.bind(Y,"the credentials",()=>this.router.credentials(H)):void 0,j={...T?{credentials:T}:{},...W.signal?{signal:W.signal}:{},...W.progress?{progress:W.progress}:{},...$.kind==="remote"?{identity:{user:$.principal.user,grant:{via:$.principal.via,id:$.principal.id,scopes:$.principal.scopes,...$.principal.clientId?{clientId:$.principal.clientId}:{}}}}:{}},C;try{let _=B?`${U}?${B}`:U;C=Object.keys(j).length>0?await this.dispatcher.dispatchAs($.req,K.method,_,F,j):await this.dispatcher.dispatchAs($.req,K.method,_,F)}catch(_){throw console.error(`[gemi/mcp] Dispatching "${Z}" failed:`,_),new O(`"${Z}" failed on the server.`,500)}if(!Y.result&&!K.outputSchema)return await U9(Z,C);return await this.project(Y,H,C)}async isOn($){return $.feature===void 0||await this.featureOn($.feature)===!0}plan($,Z){if(!$9.test($))throw Error(`McpRouter: "${$}" is not a valid tool name. A routes key is the tool's name as a model and an MCP client see it, used verbatim \u2014 letters, digits, "_" and "-", at most 64.`);let z=`McpRouter: "${$}" (${Z?.method} ${Z?.url})`;if(!(Z instanceof Object)||Z.__internal_brand!=="McpRoute")throw Error(`McpRouter: "${$}" is not a route or a tool. Declare it with this.fromApiRoute(...) or this.fromTool(...).`);let{method:G,url:W,meta:X}=Z;if(X.feature!==void 0&&(typeof X.feature!=="string"||X.feature===""))throw Error(`${z}: feature must be a feature key from app/features.`);if(W.startsWith("/__gemi__"))throw Error(`${z} is a framework route, not an app route.`);let Y=this.dispatcher.flatRoutes[W]?.[G];if(!Y)throw Error(`${z} names no route of this app. Expose a route by the path and verb it is mounted at.`);let K=[...W.matchAll(M$)].map(([,N,S])=>({name:N,modifier:S})),Q=X.params??{};for(let N of K)if(!(N.name in Q))throw Error(`${z}: the path param "${N.name}" must be bound or declared "input".`);for(let[N,S]of Object.entries(Q)){if(!K.some((h)=>h.name===N))throw Error(`${z}: "${N}" in params is not a param of the url.`);if(Q9(S))u$(z,`params.${N}`,S);else K9(z,`params.${N}`,S)}let V=[],H;if(X.input){if(H=X.input.toJSONSchema(),H.type!=="object"||!H.properties)throw Error(`${z}: input must be an s.object(...), the fields of the request body.`);V=Object.keys(H.properties)}let U=Object.entries(X.files??{}).map(([N,S])=>({name:N,binder:S}));for(let N of U)K9(z,`files.${N.name}`,N.binder);if(X.result!==void 0&&typeof X.result!=="function")throw Error(`${z}: result must be a function.`);if(X.output!==void 0&&typeof X.output?.safeParse!=="function")throw Error(`${z}: output must be a schema, built with s.`);if(X.title!==void 0&&(typeof X.title!=="string"||X.title===""))throw Error(`${z}: title must be a non-empty string.`);let I=V9(z,G,X.annotations);if(U.length>0&&G==="GET")throw Error(`${z}: a GET has no body to carry a file.`);let J={},F=(N,S)=>{if(N in J)throw Error(`${z}: "${N}" is the input key of two params or files, and the model can only send one.`);J[N]=S},B=new Map,T=new Map;for(let N of K){let S=Q[N.name];if(S==="input"){let h=p.string().describe(`The ":${N.name}" segment of the url.`);F(N.name,N.modifier==="?"||N.modifier==="*"?h.optional():h)}else if(Q9(S)){let h=S.as??N.name;F(h,S.input),T.set(N.name,{key:h,param:S})}else B.set(N.name,S)}let j={};for(let N of U)if(N.binder==="input")F(N.name,p.string().describe("The id of an attachment the user uploaded or a tool produced (gemi_att_\u2026), whose file is sent as this field.")),j[N.name]=this.remoteFileSchema();let C=[...Object.keys(J),...U.map((N)=>N.name)];for(let N of new Set(C))if(V.includes(N))throw Error(`${z}: "${N}" is both an input field and a param or file, and the model can only send one.`);let _=Object.freeze({kind:"route",name:$,description:X.description,method:G,url:W,inputSchema:H9(X.input,H,p.object(J)),...X.output?{outputSchema:X.output}:{},...X.title?{title:X.title}:{},annotations:I,tags:Object.freeze([...X.tags??[]]),requiresApproval:X.requiresApproval===!0,...X.feature!==void 0?{feature:X.feature}:{},...Y.source?{source:Y.source}:{}}),r=!U.every((N)=>N.binder==="input")?null:U.length===0?_:Object.freeze({..._,inputSchema:H9(X.input,H,p.object(p$(J,Object.keys(j))),j)});return{kind:"route",descriptor:_,remote:r,params:K,paramBinders:B,modelParams:T,fileFields:U,jsonKeys:V,...X.result?{result:X.result}:{}}}remoteFileSchema(){let{maxBytes:$,fetch:Z}=this.files,z={name:{type:"string",description:"The file's name, like report.pdf."},mimeType:{type:"string",description:"The file's media type, like application/pdf."},data:{type:"string",contentEncoding:"base64",description:`The file's bytes, base64-encoded (RFC 4648, standard alphabet). At most ${$} bytes decoded.`}};if(Z)z.url={type:"string",format:"uri",description:"An https URL the server downloads the file from, instead of data."};let G={type:"object",description:Z?"A file, sent as base64 in data or fetched from url: exactly one of the two.":"A file, sent as base64 in data.",properties:z,required:["name","mimeType"],additionalProperties:!1},W=Object.keys(z),X=(Y)=>{if(typeof Y!=="object"||Y===null||Array.isArray(Y))return{ok:!1,errors:["a file must be an object"]};let K=[],Q={};for(let V of Object.keys(Y))if(!W.includes(V))K.push(`a file has no field "${V}"`);for(let V of W){let H=Y[V];if(H===void 0||H===null){if(V==="name"||V==="mimeType")K.push(`a file needs "${V}"`);continue}if(typeof H!=="string")K.push(`a file's "${V}" must be a string`);else Q[V]=H}return K.length>0?{ok:!1,errors:K}:{ok:!0,value:Q}};return{toJSONSchema:()=>G,safeParse:X,parse(Y){let K=X(Y);if(K.ok===!1)throw Error(K.errors.join(", "));return K.value}}}planNative($,Z){if(!$9.test($))throw Error(`McpRouter: "${$}" is not a valid tool name. A routes key is the tool's name as a model and an MCP client see it, used verbatim \u2014 letters, digits, "_" and "-", at most 64.`);let z=`McpRouter: "${$}" (a native tool)`,{tool:G,meta:W={}}=Z;if(!(G instanceof Object)||typeof G.name!=="string")throw Error(`${z} is not an AgentTool. Pass one built with AgentTool.create(...).`);if(G.answeredBy==="client"||typeof G.execute!=="function")throw Error(`${z}: "${G.name}" is answered by the client, and only a tool the server runs can be called through the registry.`);if(typeof G.inputSchema==="function")throw Error(`${z}: "${G.name}" resolves its input schema per run, and the registry lists one schema to every caller. Give it a fixed inputSchema.`);if(typeof G.inputSchema?.safeParse!=="function")throw Error(`${z}: its inputSchema must be a schema, built with s.`);if(typeof W!=="object"||W===null)throw Error(`${z}: the meta must be an object.`);if(W.description!==void 0&&(typeof W.description!=="string"||W.description.trim()===""))throw Error(`${z}: description must be a non-empty string.`);if(W.title!==void 0&&(typeof W.title!=="string"||W.title===""))throw Error(`${z}: title must be a non-empty string.`);if(W.tags!==void 0&&(!Array.isArray(W.tags)||W.tags.some((Q)=>typeof Q!=="string")))throw Error(`${z}: tags must be an array of strings.`);if(W.requiresApproval===!1&&G.requiresApproval)throw Error(`${z}: "${G.name}" requires approval, and requiresApproval: false would run it without asking. Leave it out, or register a tool that does not ask.`);let X=W.remote;if(X!==void 0){if(typeof X!=="object"||X===null||typeof X.context!=="function")throw Error(`${z}: remote must be { context(call) }, building the AgentContext a remote call runs with.`);if(X.progress!==void 0&&typeof X.progress!=="function")throw Error(`${z}: remote.progress must be a function.`)}let Y=W.description??G.description;if(typeof Y!=="string"||Y.trim()==="")throw Error(`${z} needs a description: the tool's own, or the meta's.`);let K=Object.freeze({kind:"tool",name:$,description:Y,inputSchema:G.inputSchema,...G.outputSchema?{outputSchema:G.outputSchema}:{},...W.title?{title:W.title}:{},annotations:V9(z,void 0,W.annotations),tags:Object.freeze([...W.tags??[]]),requiresApproval:G.requiresApproval||W.requiresApproval===!0});return{kind:"tool",descriptor:K,remote:X?K:null,tool:G,meta:W}}async approvalRequired($,Z,z,G={}){let W=this.plans.get(Z);if(!W)return!0;if(!W3(W))return W.descriptor.requiresApproval;let X=W;if($.kind!=="remote"||!X.meta.remote)return!0;let Y=X.descriptor.inputSchema.safeParse(z);if(Y.ok===!1)return!0;let K={caller:$,req:$.req,tool:X.descriptor,input:Y.value},Q;try{Q=await this.bind(X,"the remote context",()=>X.meta.remote.context(K))}catch{return!0}if(typeof Q!=="object"||Q===null)return!0;let V=G.signal??new AbortController().signal;return X9(X,Y.value,W9(G9(X,Q,V)))}nativeApproval($){let Z=this.plans.get($);if(Z?.kind!=="tool")throw Error(`McpRegistry: there is no native tool named "${$}".`);return W3(Z)??Z.descriptor.requiresApproval}nativeTool($){let Z=this.plans.get($);if(Z?.kind!=="tool")throw Error(`McpRegistry: there is no native tool named "${$}".`);return Z.tool}startNative($,Z,z,G){let W=this.plans.get(Z);if(W?.kind!=="tool")throw Error(`McpRegistry: there is no native tool named "${Z}".`);if($===void 0)return W.tool.execute(z,G);if(D3($),$.kind!=="local")throw Error("McpRegistry: startNative is for a local caller. A remote call goes through execute().");let X=W.descriptor.inputSchema.safeParse(z);if(X.ok===!1)throw new O(`Invalid arguments for "${Z}": ${X.errors.join(", ")}`);return this.runNative(W,{caller:$,req:$.req,tool:W.descriptor,input:X.value},G)}runNative($,Z,z){let G={...z};return L9.set(G,{...Z,ctx:G}),$.tool.execute(Z.input,G)}async executeNative($,Z,z,G,W){let{name:X}=$.descriptor,Y=$.descriptor.inputSchema.safeParse(z);if(Y.ok===!1)throw new O(`Invalid arguments for "${X}": ${Y.errors.join(", ")}`);let K={caller:Z,req:Z.req,tool:$.descriptor,input:Y.value},Q=(_,_3)=>{if(!W.progress)return;let r;try{r=$.meta.remote?.progress?$.meta.remote.progress(_,_3):y$(_,_3)}catch(N){console.error(`[gemi/mcp] The progress mapping of "${X}" failed:`,N);return}if(r)W.progress(r)};if(Z.kind==="local"){if(!G)throw Error(`McpRegistry: "${X}" is a native tool, which runs with the tool context of an agent call, and none was passed to execute().`);return await z9(this.runNative($,{...K,ctx:G},G),Q)}let V=$.meta.remote,H=await this.bind($,"the remote context",()=>V.context(K));if(typeof H!=="object"||H===null)throw console.error(`[gemi/mcp] The remote context of "${X}" is not an object:`,H),new O(`"${X}" failed on the server.`,500);let U=$.tool.timeoutMs,I=[...W.signal?[W.signal]:[],...U!==void 0?[AbortSignal.timeout(U)]:[]],J=I.length===0?new AbortController().signal:I.length===1?I[0]:AbortSignal.any(I),F=G9($,H,J);if(!W.approved&&W3($)&&await X9($,K.input,W9(F)))throw new v(`"${X}" needs the user's approval, and this call does not have it.`,"approval-required");let B;try{B=await z9(this.runNative($,{...K,ctx:F},F),Q,J)}catch(_){if(J.aborted&&_===J.reason){if(W.signal?.aborted)throw new O(`"${X}" was cancelled.`,499);throw new O(`"${X}" did not finish within ${U} ms.`,504)}if(_ instanceof O)throw _;if(_ instanceof e||_ instanceof v)throw new O(_.message);throw console.error(`[gemi/mcp] "${X}" failed for a remote caller:`,_),new O(`"${X}" failed on the server.`,500)}let T=(_)=>{return console.error(`[gemi/mcp] "${X}" ${_}`),new O(`"${X}" failed on the server.`,500)};if(N9(B))throw T("answered a job handle, and a remote call has no background jobs.");let j=B;if($.descriptor.outputSchema){let _=$.descriptor.outputSchema.safeParse(j);if(_.ok===!1)throw T(`answered what its output schema refuses: ${_.errors.join(", ")}`);j=_.value}if(j===void 0)return null;if(typeof j==="string")return j.length>M?`${j.slice(0,M)}\u2026 [cut at ${M} of ${j.length} characters]`:j;let C=JSON.stringify(j);if(C!==void 0&&C.length>M)return`${C.slice(0,M)}\u2026 [cut at ${M} of ${C.length} characters]`;return j}async fillPath($,Z){let{input:z,req:G}=Z,W=$.descriptor.url;for(let X of $.params){let Y=$.paramBinders.get(X.name),K=$.modelParams.get(X.name),Q;if(Y||K){if(Q=K?await this.bind($,`the param "${X.name}"`,()=>K.param.bind(z[K.key],G,Z),{refusals:!0}):await this.bind($,`the param "${X.name}"`,()=>Y(G,Z)),Q===void 0||Q===null||Q==="")throw console.error(`[gemi/mcp] The ${K?"resolver":"binder"} for "${X.name}" of "${$.descriptor.name}" returned ${JSON.stringify(Q)}.`),new O(`"${$.descriptor.name}" failed on the server.`,500)}else Q=z[X.name];let V=`:${X.name}${X.modifier}`;if(Q===void 0||Q===null||Q===""){if(X.modifier!=="?"&&X.modifier!=="*")throw new O(`"${X.name}" of "${$.descriptor.name}" must not be empty.`);W=W.replace(`/${V}`,"");continue}W=W.replace(V,i$($.descriptor.name,X,String(Q)))}return W}async formData($,Z,z){let{input:G,ctx:W}=z,X=$.descriptor.name;if(z.caller.kind==="remote"){let K=new FormData;for(let[Q,V]of Object.entries(Z))O3(K,Q,V);for(let Q of $.fileFields)K.append(Q.name,await this.remoteFile(X,Q.name,G[Q.name]));return K}if(!W)throw Error(`McpRegistry: "${X}" sends a file, which is resolved through the tool context's attachments, and none was passed to execute().`);let Y=new FormData;for(let[K,Q]of Object.entries(Z))O3(Y,K,Q);for(let K of $.fileFields){let Q=K.binder==="input"?G[K.name]:await this.bind($,`the file "${K.name}"`,()=>K.binder(W,z));if(typeof Q!=="string"||Q==="")throw new O(`"${X}" needs a file for "${K.name}", and this turn has none. Ask the user to attach one.`);Y.append(K.name,await W.attachments.file(Q))}return Y}async remoteFile($,Z,z){let G=(H)=>new O(`"${Z}" of "${$}" ${H}`,400),W=z,{maxBytes:X,fetch:Y}=this.files;if(!v$(W.name))throw G("needs a name of 1 to 255 characters, without control characters or slashes.");if(!g$.test(W.mimeType))throw G(`has a mimeType that is not a media type: "${W.mimeType.slice(0,100)}".`);let K=typeof W.data==="string",Q=typeof W.url==="string";if(K===Q)throw G(Y?"needs exactly one of data or url.":"needs its bytes, base64, in data.");if(K){let H=W.data.replace(/\s+/g,"");if(Math.floor(H.length*3/4)-m$(H)>X)throw G(`is larger than the ${X} bytes a file may be.`);if(H.length%4!==0||!h$.test(H))throw G("has data that is not base64 (RFC 4648, standard alphabet, padded).");return new File([Buffer.from(H,"base64")],W.name,{type:W.mimeType})}if(!Y)throw G("cannot be fetched from a URL here. Send its bytes, base64, in data.");let V;try{V=new URL(W.url)}catch{throw G("has a url that is not a URL.")}if(V.protocol!=="https:")throw G("can only be fetched from an https URL.");try{let H=await J9(V.href,{...Y,maxSize:Math.min(Y.maxSize??X,X),redirect:"follow"});if(!H.ok)throw G(`could not be fetched: ${V.host} answered ${H.status}.`);let U=await H.arrayBuffer();return new File([U],W.name,{type:W.mimeType})}catch(H){if(H instanceof O)throw H;throw G(`could not be fetched from ${V.host}: ${H instanceof Error?H.message:"failed"}.`)}}grants($,Z){for(let z of $.scopes??[])if(this.scopeTools.get(z)?.tools.has(Z))return!0;return!1}resolveScopes(){let $=this.router.scopes;if($===void 0){this.scopeTools.set(T$,{description:"Use this app's tools as you",tools:new Set(this.plans.keys())});return}if(typeof $!=="object"||$===null)throw Error("McpRouter: scopes must be an object of scope names.");let Z=new Set([...this.plans.values()].flatMap(({descriptor:z})=>z.tags));for(let[z,G]of Object.entries($)){let W=`McpRouter: scope "${z}"`;if(!k$.test(z))throw Error(`${W} is not a valid OAuth scope: printable ASCII, no spaces or quotes.`);if(typeof G?.description!=="string"||G.description==="")throw Error(`${W} needs a description: it is what a consent screen shows.`);let X=new Set;for(let Y of G.tags??[]){if(!Z.has(Y))throw Error(`${W} names the tag "${Y}", which no tool has.`);for(let[K,{descriptor:Q}]of this.plans)if(Q.tags.includes(Y))X.add(K)}for(let Y of G.names??[]){if(!this.plans.has(Y))throw Error(`${W} names "${Y}", which is no tool.`);X.add(Y)}if(X.size===0)throw Error(`${W} reaches no tool. Give it tags or names.`);this.scopeTools.set(z,{description:G.description,tools:X})}}async project($,Z,z){let{name:G,outputSchema:W}=$.descriptor;if(z.status<200||z.status>=300)return await U9(G,z);let X=(U,I)=>{if(I===void 0)console.error(`[gemi/mcp] "${G}" ${U}`);else console.error(`[gemi/mcp] "${G}" ${U}`,I);return new O(`"${G}" failed on the server.`,500)},Y=z.headers.get("Content-Type"),K=await z.text(),Q=null;if(K!=="")try{Q=JSON.parse(K)}catch{throw X(`answered ${Y??"a body with no content-type"} that is not JSON, and its result or output needs JSON.`)}let V=Q;if($.result)try{V=await $.result(Q,Z)}catch(U){throw X("failed in its result projection:",U)}if(W){let U=W.safeParse(V);if(U.ok===!1)throw X(`answered what its output schema refuses: ${U.errors.join(", ")}`);V=U.value}if(V===void 0)return null;let H=JSON.stringify(V);if(H!==void 0&&H.length>M)return`${H.slice(0,M)}\u2026 [cut at ${M} of ${H.length} characters]`;return V}async bind($,Z,z,G={}){try{return await z()}catch(W){if(G.refusals&&W instanceof e)throw W;throw console.error(`[gemi/mcp] Binding ${Z} of "${$.descriptor.name}" failed:`,W),new O(`"${$.descriptor.name}" failed on the server.`,500)}}}function E$($){return $ instanceof Object&&$.__internal_brand==="McpTool"}function b$($){return typeof $==="object"&&$!==null&&typeof $.next==="function"&&Symbol.asyncIterator in $}async function z9($,Z,z){let G;if(z)G=new Promise((X,Y)=>{if(z.aborted)Y(z.reason);else z.addEventListener("abort",()=>Y(z.reason),{once:!0})}),G.catch(()=>{});let W=(X)=>G?Promise.race([X,G]):X;if(!b$($))return await W(Promise.resolve($));try{let X=0,Y=await W($.next());while(!Y.done)Z(Y.value,++X),Y=await W($.next());return Y.value}catch(X){throw $.return(void 0).catch(()=>{}),X}}function y$($,Z){if(typeof $==="string")return{progress:Z,message:$};if(typeof $==="object"&&$!==null){let{progress:z,total:G,message:W}=$;if(typeof z==="number"&&Number.isFinite(z))return{progress:z,...typeof G==="number"?{total:G}:{},...typeof W==="string"?{message:W}:{}};if(typeof W==="string")return{progress:Z,message:W}}return{progress:Z}}function G9($,Z,z){let G=$.descriptor.name,W=`mcp_${crypto.randomUUID()}`,X=`mcp_call_${crypto.randomUUID()}`,Y=(Q)=>async()=>{throw new e(`"${G}" was called by a remote MCP client, which has no ${Q}.`,{retryable:!1})},K={put:Y("attachment store"),get:Y("attachment store"),read:Y("attachment store"),file:Y("attachment store")};return{context:Z,body:{},runId:W,toolCallId:X,signal:z,step:1,depth:0,resumed:!1,attachments:K,turn:Object.freeze({attachments:Object.freeze([])}),runAgent:Y("agent run to nest a sub-agent in"),generateImage:Y("attachment store to put an image in"),editImage:Y("attachment store to put an image in"),generate:(Q)=>I9({...Q,signal:Q.signal?AbortSignal.any([z,Q.signal]):z},{origin:{mcp:G,runId:W,toolCallId:X}}),jobs:B9({jobs:void 0,threadId:void 0,runId:W,toolCallId:X,toolName:G,depth:0,async:$.tool.async,attachments:null}),memory:P9(),meter:F9().meter}}function W3($){if($.kind!=="tool"||$.meta.requiresApproval===!0)return;return $.tool.approvalPredicate}function W9($){return{context:$.context,body:$.body,runId:$.runId,threadId:$.threadId,toolCallId:$.toolCallId,step:$.step,depth:$.depth,signal:$.signal}}async function X9($,Z,z){try{return await $.tool.approvalPredicate(Z,z)!==!1}catch(G){return console.error(`[gemi/mcp] The requiresApproval of "${$.descriptor.name}" threw, so the call asks the user:`,G),!0}}function D3($){if($?.kind==="local"&&$.req)return;if($?.kind==="remote"&&$.req&&$.principal?.user&&typeof $.principal.id==="string"&&Array.isArray($.principal.scopes))return;throw Error('McpRegistry: a caller is { kind: "local", req } or { kind: "remote", req, principal }, with the principal a caller resolver verified.')}function Y9($,Z){if(Z?.names&&!Z.names.includes($.name))return!1;if(Z?.tags&&!$.tags.some((z)=>Z.tags.includes(z)))return!1;return!0}var f$=10485760;function w$($){let Z=$?.maxBytes??f$;if(!Number.isSafeInteger(Z)||Z<=0)throw Error("McpRegistry: files.maxBytes must be a positive whole number of bytes.");let z=$?.fetchUrls===!0?{}:typeof $?.fetchUrls==="object"&&$.fetchUrls!==null?$.fetchUrls:null;return{maxBytes:Z,fetch:z}}function v$($){if($.length===0||$.length>255)return!1;for(let Z of $){let z=Z.codePointAt(0);if(z<32||z===127||Z==="/"||Z==="\\")return!1}return!0}var g$=/^[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}\/[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}(\s*;.{0,200})?$/,h$=/^[A-Za-z0-9+/]*={0,2}$/;function m$($){return $.endsWith("==")?2:$.endsWith("=")?1:0}function K9($,Z,z){if(z!=="input"&&typeof z!=="function")throw Error(`${$}: ${Z} must be a function or "input".`)}function Q9($){return $ instanceof Object&&$.__internal_brand==="McpModelParam"}function u$($,Z,z){if(z.as!==void 0&&(typeof z.as!=="string"||z.as===""))throw Error(`${$}: ${Z}.as must be a non-empty string.`);let G=z.input;if(typeof G?.safeParse!=="function"||typeof G.toJSONSchema!=="function")throw Error(`${$}: ${Z}.input must be a schema, built with s.`);if(typeof z.bind!=="function")throw Error(`${$}: ${Z}.bind must be a function.`)}var d$=new Set(["readOnlyHint","destructiveHint","idempotentHint","openWorldHint"]);function c$($){switch($){case"GET":return{readOnlyHint:!0};case"DELETE":return{destructiveHint:!0};case"PUT":return{idempotentHint:!0};default:return{}}}function V9($,Z,z){if(z!==void 0&&(typeof z!=="object"||z===null))throw Error(`${$}: annotations must be an object of hints.`);let G=Z?c$(Z):{};for(let[W,X]of Object.entries(z??{})){if(!d$.has(W))throw Error(`${$}: "${W}" is not a tool annotation. Use readOnlyHint, destructiveHint, idempotentHint or openWorldHint.`);if(X===void 0)continue;if(typeof X!=="boolean")throw Error(`${$}: annotations.${W} must be true or false.`);G[W]=X}if(G.readOnlyHint===!0&&(G.destructiveHint||G.idempotentHint))throw Error(`${$} is read-only${z?.readOnlyHint?"":` (a ${Z})`} and also ${G.destructiveHint?"destructive":"idempotent"}, which only a tool that is not read-only can be. Set readOnlyHint: false if it changes something.`);return Object.freeze(G)}function H9($,Z,z,G={}){let W=z.toJSONSchema(),X=Object.fromEntries(Object.entries(G).map(([Q,V])=>[Q,V.toJSONSchema()])),Y={...Z??{},type:"object",properties:{...Z?.properties??{},...W.properties,...X},required:[...Z?.required??[],...W.required??[],...Object.keys(G)],additionalProperties:!1},K=(Q)=>{if(typeof Q!=="object"||Q===null||Array.isArray(Q))return{ok:!1,errors:["expected an object"]};let V=[],H={};if($){let I=$.safeParse(Q);if(I.ok===!1)V.push(...I.errors);else H={...I.value}}let U=z.safeParse(Q);if(U.ok===!1)V.push(...U.errors);else H={...H,...U.value};for(let[I,J]of Object.entries(G)){let F=Q[I];if(F===void 0){V.push(`"${I}" is required`);continue}let B=J.safeParse(F);if(B.ok===!1)V.push(...B.errors.map((T)=>`${I}: ${T}`));else H[I]=B.value}return V.length>0?{ok:!1,errors:V}:{ok:!0,value:H}};return{toJSONSchema:()=>Y,safeParse:K,parse(Q){let V=K(Q);if(V.ok===!1)throw Error(V.errors.join(", "));return V.value}}}function p$($,Z){return Object.fromEntries(Object.entries($).filter(([z])=>!Z.includes(z)))}function i$($,Z,z){let G=Z.modifier==="*"||Z.modifier==="+"?z.split("/"):[z];if(G.some((W)=>W==="."||W===".."))throw new O(`"${z}" is not a valid value for "${Z.name}" of "${$}".`);return G.map(encodeURIComponent).join("/")}function O3($,Z,z){if(z===void 0||z===null)return;if(Array.isArray(z)){for(let G of z)O3($,Z,G);return}$.append(Z,typeof z==="object"?JSON.stringify(z):String(z))}function l$($){let Z=new URLSearchParams,z=(G,W)=>{if(W===void 0||W===null)return;if(Array.isArray(W)){for(let X of W)z(G,X);return}Z.append(G,typeof W==="object"?JSON.stringify(W):String(W))};for(let[G,W]of Object.entries($))z(G,W);return Z.toString()}async function U9($,Z){if(Z.status>=200&&Z.status<300){let G=Z.headers.get("Content-Type");if(G&&!R$.test(G)){let X=(await Z.arrayBuffer()).byteLength;return`"${$}" answered with ${X} bytes of ${G}, which is not shown.`}let W=await Z.text();if(W==="")return null;if(W.length>M)return`${W.slice(0,M)}\u2026 [cut at ${M} of ${W.length} characters]`;try{return JSON.parse(W)}catch{return W}}let z=await Z.text();if(Z.status>=400&&Z.status<500){let G=z.length>Z9?`${z.slice(0,Z9)}\u2026`:z;throw new O(`"${$}" was refused with ${Z.status}${G?`: ${G}`:"."}`,Z.status)}if(Z.status<500)console.error(`[gemi/mcp] "${$}" answered ${Z.status}${Z.headers.get("Location")?` to ${Z.headers.get("Location")}`:""}, which a tool call cannot follow.`);throw new O(`"${$}" failed on the server.`,Z.status)}import{createHash as n$,randomBytes as s$,timingSafeEqual as t$}from"crypto";function j3($){let Z=$.headers.get("authorization");if(!Z)return null;let z=/^Bearer[ ]+([\x21-\x7e]+)$/i.exec(Z.trim());return z?z[1]:null}class o${options;name="api-key";constructor($){this.options=$;if(typeof $?.prefix!=="string"||!/^[A-Za-z0-9_-]{3,32}$/.test($.prefix))throw Error('McpApiKeyResolver: prefix is required: 3 to 32 letters, digits, _ or -, like "myapp_mcp_".');if(typeof $.verify!=="function")throw Error("McpApiKeyResolver: verify must be a function that looks a key up.")}static generate($){return`${$}${s$(32).toString("base64url")}`}static hash($){return n$("sha256").update($).digest("hex")}static hashesMatch($,Z){let z=Buffer.from($),G=Buffer.from(Z);return z.length===G.length&&t$(z,G)}async resolve($){let Z=j3($);if(!Z?.startsWith(this.options.prefix))return null;let z=await this.options.verify(Z,$);if(!z)return{ok:!1,error:"invalid_token",description:"The API key is not valid."};if(!z.user||typeof z.id!=="string"||z.id===""||!Array.isArray(z.scopes))throw Error("McpApiKeyResolver: verify must answer { user, id, scopes } for a key it knows, or null.");return{ok:!0,principal:{user:z.user,via:this.name,id:z.id,scopes:[...z.scopes]}}}}import{createHash as y9,randomBytes as j9}from"crypto";async function A3($,Z){let z=a$();if(!z)return null;let G=await z.consume($,Z);return G.allowed?null:Math.max(1,Math.ceil(G.retryAfter/1000))}function a$(){try{let $=y();return $.bound(l)?$.make(l):null}catch{return null}}var x3=["2026-07-28"],Y3=["2025-11-25","2025-06-18","2025-03-26"],C3=[...x3,...Y3],S3="io.modelcontextprotocol/protocolVersion",q3="io.modelcontextprotocol/clientCapabilities";var T3="io.modelcontextprotocol/serverInfo",D={ParseError:-32700,InvalidRequest:-32600,MethodNotFound:-32601,InvalidParams:-32602,InternalError:-32603,HeaderMismatch:-32020,MissingRequiredClientCapability:-32021,UnsupportedProtocolVersion:-32022};class L extends Error{code;data;status;constructor($,Z,z,G=200){super(Z);this.code=$;this.data=z;this.status=G;this.name="JsonRpcError"}}function R($,Z){return{jsonrpc:"2.0",id:$,error:{code:Z.code,message:Z.message,...Z.data!==void 0?{data:Z.data}:{}}}}function _9($){if(Array.isArray($))throw new L(D.InvalidRequest,"Batched requests are not supported.",void 0,400);if(typeof $!=="object"||$===null||$.jsonrpc!=="2.0")throw new L(D.InvalidRequest,"Not a JSON-RPC 2.0 message.",void 0,400);let Z=$,z=Z.id,G=typeof z==="string"||typeof z==="number"&&Number.isFinite(z);if(typeof Z.method==="string"){if(Z.params!==void 0&&(typeof Z.params!=="object"||Z.params===null||Array.isArray(Z.params)))throw new L(D.InvalidRequest,"params must be an object.",void 0,400);if(z===void 0)return{kind:"notification",message:Z};if(!G)throw new L(D.InvalidRequest,"id must be a string or a number.",void 0,400);return{kind:"request",message:Z}}if(G&&(("result"in Z)||("error"in Z)))return{kind:"response",message:Z};throw new L(D.InvalidRequest,"Not a JSON-RPC request, notification or response.",void 0,400)}function k3($,Z){let z=$.outputSchema?.toJSONSchema(),G={...$.annotations,...$.title&&!Z?{title:$.title}:{}};return{name:$.name,...$.title?{title:$.title}:{},description:$.description,inputSchema:$.inputSchema.toJSONSchema(),...z&&(Z||z.type==="object")?{outputSchema:z}:{},...Object.keys(G).length>0?{annotations:G}:{}}}function q($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function D9($){let Z=/^=\?base64\?([A-Za-z0-9+/]*={0,2})\?=$/.exec($);if(!Z)return $;try{let z=Buffer.from(Z[1],"base64");return new TextDecoder("utf-8",{fatal:!0}).decode(z)}catch{return null}}import{createHmac as r$,timingSafeEqual as e$}from"crypto";function M3($,Z,z){let G=Buffer.from(JSON.stringify(z)).toString("base64url");return`${Z}.${G}.${O9($,Z,G).toString("base64url")}`}function R3($,Z,z,G=Date.now()){if(typeof z!=="string"||z.length>8192)return null;let W=z.split(".");if(W.length!==3||W[0]!==Z)return null;let[,X,Y]=W,K=Buffer.from(Y,"base64url"),Q=O9($,Z,X);if(K.length!==Q.length||!e$(K,Q))return null;let V;try{V=JSON.parse(Buffer.from(X,"base64url").toString("utf8"))}catch{return null}if(typeof V!=="object"||V===null)return null;if(typeof V.exp!=="number"||V.exp<=G)return null;return V}function O9($,Z,z){return r$("sha256",K3($)).update(`${Z}.${z}`).digest()}var E3="gemi.mcp.request-state.v1",A9="gemi.mcp.session.v1",$2=86400000,x9=600000,C9="gemi_approval",b3=2000,Z2={limit:600,window:60},z2={limit:30,window:60};class $3{registry;static token="router.mcp.http";endpoint;resolvers;context;allowedOrigins;rateLimit;maxBodyBytes;serverInfo;instructions;nonces;approvalTimeoutMs;onCall;feature;featureOn;pending=new Map;inflight=new Map;constructor($,Z,z={}){this.registry=$;if(typeof Z.url!=="string")throw Error(`route.mcp.remote.url is required: the endpoint's canonical URL, like "https://example.com/mcp".`);this.endpoint=X2(Z.url);let G=Z.resolvers??[];if(!Array.isArray(G)||G.length===0)throw Error("route.mcp.remote is enabled without a caller resolver. Configure route.mcp.remote.resolvers \u2014 an McpOAuthServer, an McpApiKeyResolver, or your own \u2014 or leave the endpoint off. Without one every request would be refused, or answered as nobody.");for(let W of G)if(typeof W?.resolve!=="function"||typeof W.name!=="string"||W.name==="")throw Error("route.mcp.remote.resolvers: each resolver needs a name and a resolve().");if(this.resolvers=G,K3(E3),this.context={resource:this.resource,registry:$},this.allowedOrigins=new Set((Z.allowedOrigins??[]).map((W)=>{if(new URL(W).origin!==W)throw Error(`route.mcp.remote.allowedOrigins: "${W}" is not an origin (scheme://host[:port]).`);return W})),this.allowedOrigins.add(this.endpoint.origin),this.rateLimit=Z.rateLimit===!1?!1:Z.rateLimit??Z2,this.maxBodyBytes=Z.maxBodyBytes??Math.ceil($.maxFileBytes*1.4)+1048576,this.serverInfo={name:Z.server?.name??"gemi",version:Z.server?.version??"1.0.0"},this.instructions=Z.server?.instructions,this.nonces=Z.nonces??new E9,this.approvalTimeoutMs=Z.approvalTimeoutMs??x9,Z.onCall!==void 0&&typeof Z.onCall!=="function")throw Error("route.mcp.remote.onCall must be a function.");if(this.onCall=Z.onCall,Z.feature!==void 0){if(typeof Z.feature!=="string"||Z.feature==="")throw Error("route.mcp.remote.feature must be a feature key from app/features.");this.feature=Z.feature}this.featureOn=z.featureOn??X3;for(let W of G)W.boot?.(this.context)}get resource(){return this.endpoint.href.replace(/\/$/,"")}async handle($){let Z=new URL($.url);if(Z.host!==this.endpoint.host)return null;if(this.feature!==void 0){if(!this.ownsPath(Z.pathname))return null;if(await this.featureOn(this.feature)!==!0)return null}for(let W of this.resolvers){let X=await W.handle?.($,this.context);if(X)return X}if(Z.pathname!==this.endpoint.pathname)return null;let z=$.headers.get("origin");if(z!==null&&!this.allowedOrigins.has(z))return f(R(null,new L(D.InvalidRequest,"Origin not allowed.")),403);let G=z?W2(z):{};if($.method==="OPTIONS")return new Response(null,{status:204,headers:{...G,"Access-Control-Allow-Methods":"POST","Access-Control-Allow-Headers":"Authorization, Content-Type, Accept, MCP-Protocol-Version, Mcp-Session-Id, Mcp-Method, Mcp-Name, Last-Event-ID","Access-Control-Max-Age":"600"}});if($.method!=="POST")return S9(new Response(null,{status:405,headers:{Allow:"POST, OPTIONS"}}),G);return S9(await this.post($),G)}ownsPath($){let Z=this.endpoint.pathname.replace(/\/$/,"");return $===this.endpoint.pathname||$===Z||$.startsWith(`${Z}/`)||$.startsWith("/.well-known/")}async post($){let Z=null;for(let Y of this.resolvers){let K=await Y.resolve($,this.context);if(K===null)continue;if(K.ok===!1)return await this.failedAttempt($)??this.unauthorized(K.description);Z={...K.principal,via:Y.name};break}if(!Z)return(j3($)!==null?await this.failedAttempt($):null)??this.unauthorized();let z=await this.spend(Z);if(z)return z;let G=$.headers.get("content-type")??"";if(!/^application\/json\s*(;|$)/i.test(G))return new Response("Content-Type must be application/json.",{status:415});let W;try{W=JSON.parse(await G2($,this.maxBodyBytes))}catch(Y){if(Y instanceof V3)return f(R(null,new L(D.InvalidRequest,`The request is larger than ${this.maxBodyBytes} bytes.`)),413);return f(R(null,new L(D.ParseError,"Parse error.")),400)}let X=new m($,{},"api",this.endpoint.pathname);return await g.run(X,async()=>{try{return await this.dispatch($,X,Z,W)}catch(Y){if(Y instanceof L){let K=q(W)&&(typeof W.id==="string"||typeof W.id==="number")?W.id:null;return f(R(K,Y),Y.status)}return console.error("[gemi/mcp] The MCP endpoint failed:",Y),f(R(null,new L(D.InternalError,"Internal error.")),500)}},{user:Z.user})}async dispatch($,Z,z,G){let W=_9(G),X={kind:"remote",req:Z,principal:z};if(W.kind==="response"){let F=this.session($,z),B=this.pending.get(String(W.message.id));if(B&&B.session===F.id)this.pending.delete(String(W.message.id)),B.resolve(W.message);return new Response(null,{status:202})}let{message:Y}=W,K=Y.params??{},Q=q(K._meta)?K._meta:{};if(typeof Q[S3]==="string"){if(this.checkModernHeaders($,Y,Q[S3]),W.kind==="notification")return new Response(null,{status:202});return await this.respond(Y,async(F,B)=>this.modern({principal:z,caller:X,message:Y,params:K,era:{modern:!0},stream:F,signal:B}),T9(K),$.signal)}if(Y.method==="initialize"){if(W.kind!=="request")throw new L(D.InvalidRequest,"initialize is a request.",void 0,400);return this.initialize(W.message,K,z)}let V=this.session($,z),H=$.headers.get("mcp-protocol-version");if(H!==null&&H!==V.state.v)throw new L(D.InvalidRequest,`MCP-Protocol-Version ${H} is not the session's ${V.state.v}.`,void 0,400);if(W.kind==="notification"){if(Y.method==="notifications/cancelled"){let F=K.requestId;this.inflight.get(`${V.id}:${String(F)}`)?.abort()}return new Response(null,{status:202})}let U=`${V.id}:${String(Y.id)}`,I=new AbortController;this.inflight.set(U,I);let J=AbortSignal.any([I.signal,$.signal]);try{return await this.respond(Y,async(F,B)=>this.legacy({principal:z,caller:X,message:Y,params:K,era:{modern:!1,session:V.state,sessionId:V.id},stream:F,signal:B}),T9(K)||K2(this.registry,Y,V.state),J,()=>this.inflight.delete(U))}catch(F){throw this.inflight.delete(U),F}}async modern($){switch($.message.method){case"server/discover":return this.complete({supportedVersions:C3,capabilities:{tools:{}},...this.instructions?{instructions:this.instructions}:{},ttlMs:60000,cacheScope:"private"});case"tools/list":return this.complete({tools:(await this.registry.available($.caller)).map((Z)=>k3(Z,!0)),ttlMs:60000,cacheScope:"private"});case"tools/call":return await this.callTool($);default:throw new L(D.MethodNotFound,`Method not found: ${$.message.method}`,void 0,404)}}async legacy($){switch($.message.method){case"ping":return{};case"tools/list":return{tools:(await this.registry.available($.caller)).map((Z)=>k3(Z,!1))};case"tools/call":return await this.callTool($);default:throw new L(D.MethodNotFound,`Method not found: ${$.message.method}`)}}complete($){return{resultType:"complete",...$,_meta:{[T3]:this.serverInfo}}}initialize($,Z,z){let G=Z.protocolVersion,W=Y3.includes(G)?G:Y3[0],X=q(Z.capabilities)?Z.capabilities:{},Y={v:W,e:q9(X.elicitation),p:Q3(z),exp:Date.now()+$2},K=M3(A9,"gms1",Y);return f({jsonrpc:"2.0",id:$.id,result:{protocolVersion:W,capabilities:{tools:{listChanged:!1}},serverInfo:this.serverInfo,...this.instructions?{instructions:this.instructions}:{}}},200,{"Mcp-Session-Id":K})}session($,Z){let z=$.headers.get("mcp-session-id");if(!z)throw new L(D.InvalidRequest,"Missing Mcp-Session-Id. Send initialize first, or a request carrying io.modelcontextprotocol/protocolVersion in _meta.",void 0,400);let G=R3(A9,"gms1",z);if(!G||G.p!==Q3(Z))throw new L(D.InvalidRequest,"Session not found.",void 0,404);return{id:z,state:G}}checkModernHeaders($,Z,z){if(!x3.includes(z))throw new L(D.UnsupportedProtocolVersion,"Unsupported protocol version",{supported:C3,requested:z},400);let G=(Y)=>new L(D.HeaderMismatch,`Header mismatch: ${Y}`,void 0,400);if($.headers.get("mcp-protocol-version")!==z)throw G("MCP-Protocol-Version does not match the protocol version in _meta.");if($.headers.get("mcp-method")!==Z.method)throw G("Mcp-Method does not match the method.");let W=Z.params??{},X=Z.method==="tools/call"||Z.method==="prompts/get"?W.name:Z.method==="resources/read"?W.uri:void 0;if(X!==void 0){let Y=$.headers.get("mcp-name");if(Y===null||D9(Y)!==X)throw G("Mcp-Name does not match the request's name.")}}async callTool($){let Z=$.params.name;if(typeof Z!=="string")throw new L(D.InvalidParams,"tools/call needs a tool name.");let z=$.params.arguments??{};if(!this.onCall)return await this.runTool($,Z,z,{approved:!1});let G=performance.now(),W={approved:!1};try{let X=await this.runTool($,Z,z,W);if(!W.pending)await this.report($,Z,z,W,G);return X}catch(X){if(!W.outcome){if(W.outcome="error",W.message=X instanceof L?X.message:"Internal error.",!(X instanceof L))W.error=X}throw await this.report($,Z,z,W,G),X}}async report($,Z,z,G,W){let{principal:X}=$;try{await this.onCall({user:X.user,via:X.via,credentialId:X.id,clientId:X.clientId??null,scopes:X.scopes,tool:Z,arguments:z,outcome:G.outcome??"ok",...G.reason!==void 0?{reason:G.reason}:{},...G.message!==void 0?{message:G.message}:{},...G.status!==void 0?{status:G.status}:{},...G.error!==void 0?{error:G.error}:{},approved:G.approved,durationMs:Math.round((performance.now()-W)*1000)/1000,req:$.caller.req})}catch(Y){console.error(`[gemi/mcp] route.mcp.remote.onCall failed for "${Z}":`,Y)}}async runTool($,Z,z,G){let{caller:W,principal:X}=$,Y=(J,F)=>{G.outcome="denied",G.reason=J,G.message=F},K=(J,F,B)=>{if(G.outcome="error",G.message=J,F!==void 0)G.status=F;if(B!==void 0)G.error=B},Q=(await this.registry.available(W,{names:[Z]}))[0];if(!Q)throw Y("unknown-tool",`Unknown tool: ${Z}`),new L(D.InvalidParams,`Unknown tool: ${Z}`);if(Q.requiresApproval){let J=Q.inputSchema.safeParse(z);if(J.ok===!1){let B=`Invalid arguments for "${Z}": ${J.errors.join(", ")}`;return K(B),this.toolResult($,{content:[{type:"text",text:B}],isError:!0})}if($.era.modern&&q($.params.inputResponses)&&$.params.requestState!==void 0||await this.registry.approvalRequired(W,Z,z,{signal:$.signal})){let B=await this.approval($,Q,z,Y,G);if(B.kind==="answer")return B.result;G.approved=!0}}let V=Q2($),H;try{H=await this.registry.execute(W,Z,z,void 0,{approved:G.approved,signal:$.signal,...V?{progress:V}:{}})}catch(J){if(J instanceof O){if(J.status===401||J.status===403)Y("forbidden",J.message),G.status=J.status;else K(J.message,J.status);return this.toolResult($,{content:[{type:"text",text:J.message}],isError:!0})}if(J instanceof v){let B=J.reason==="unknown-tool"?`Unknown tool: ${Z}`:J.message;throw Y(J.reason,B),new L(D.InvalidParams,B)}console.error(`[gemi/mcp] "${Z}" failed for ${X.via}:${X.id}:`,J);let F=`"${Z}" failed on the server.`;return K(F,void 0,J),this.toolResult($,{content:[{type:"text",text:F}],isError:!0})}let U=typeof H==="string"?H:JSON.stringify(H??null),I=Q.outputSchema&&($.era.modern||q(H))?{structuredContent:H}:{};return G.outcome="ok",this.toolResult($,{content:[{type:"text",text:U}],...I,isError:!1})}toolResult($,Z){return $.era.modern?this.complete(Z):Z}async approval($,Z,z,G,W){let X=V2(Z,z),Y=(I,J="approval-declined")=>{return G(J,I),{kind:"answer",result:this.toolResult($,{content:[{type:"text",text:I}],isError:!0})}},K=(I,J)=>{return G(I,J.message),J};if($.era.modern){let I=q($.params._meta)?$.params._meta:{},J=q(I[q3])?I[q3]:{},F=q($.params.inputResponses)?$.params.inputResponses:null,B=$.params.requestState,T=Y2(z);if(F&&B!==void 0){let C=R3(E3,"grs1",B);if(!C||C.p!==Q3($.principal)||C.t!==Z.name||C.a!==T)throw K("approval-invalid",new L(D.InvalidParams,"requestState is not valid for this call."));if(!await this.spendNonce(C.n,C.exp))throw K("approval-replayed",new L(D.InvalidParams,"requestState has already been used."));return k9(F[C9])?{kind:"approved"}:Y(`The user did not approve "${Z.name}", and it did not run.`)}if(!q9(J.elicitation))throw K("approval-unavailable",new L(D.MissingRequiredClientCapability,`"${Z.name}" needs the user's approval, and this client cannot ask for it (elicitation).`,{requiredCapabilities:{elicitation:{form:{}}}},400));let j={p:Q3($.principal),t:Z.name,a:T,n:j9(16).toString("base64url"),exp:Date.now()+x9};return W.pending=!0,{kind:"answer",result:{resultType:"input_required",inputRequests:{[C9]:{method:"elicitation/create",params:{mode:"form",...X}}},requestState:M3(E3,"grs1",j),_meta:{[T3]:this.serverInfo}}}}let Q=$.era;if(!Q.session.e||!$.stream)return Y(`"${Z.name}" needs the user's approval, and this client cannot ask for it (elicitation). It did not run.`,"approval-unavailable");let V=`gemi-approval-${j9(12).toString("base64url")}`,H=Q.sessionId,U=await new Promise((I)=>{let J=setTimeout(()=>{this.pending.delete(V),I(null)},this.approvalTimeoutMs),F=(B)=>{clearTimeout(J),I(B)};this.pending.set(V,{session:H,resolve:F}),$.signal.addEventListener("abort",()=>{this.pending.delete(V),F(null)}),$.stream.send({jsonrpc:"2.0",id:V,method:"elicitation/create",params:Q.session.v==="2025-11-25"?{mode:"form",...X}:X})});return U&&!U.error&&k9(U.result)?{kind:"approved"}:Y(`The user did not approve "${Z.name}", and it did not run.`)}async spendNonce($,Z){try{return await this.nonces.consume($,Z)}catch(z){return console.error("[gemi/mcp] Spending an approval failed:",z),!1}}async respond($,Z,z,G,W){if(!z)try{let Q=await Z(null,G);return f({jsonrpc:"2.0",id:$.id,result:Q},200)}finally{W?.()}let X=new AbortController,Y=AbortSignal.any([X.signal,G]),K=new f9(()=>X.abort());return(async()=>{try{let Q=await Z(K,Y);K.send({jsonrpc:"2.0",id:$.id,result:Q})}catch(Q){if(Q instanceof L)K.send(R($.id,Q));else console.error("[gemi/mcp] The MCP endpoint failed:",Q),K.send(R($.id,new L(D.InternalError,"Internal error.")))}finally{W?.(),K.close()}})(),new Response(K.readable,{status:200,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-store","X-Accel-Buffering":"no"}})}unauthorized($){let Z=this.resolvers.map((G)=>G.challenge?.(this.context)).find(Boolean)??'Bearer realm="mcp"',z=$?`${Z}, error="invalid_token", error_description="${$.replace(/["\\]/g,"")}"`:Z;return f(R(null,new L(D.InvalidRequest,"Unauthorized.")),401,{"WWW-Authenticate":z})}async failedAttempt($){let Z=R9(new m($,{},"api",this.endpoint.pathname)),z=await A3(`mcp-auth-failed:${Z}`,z2);return z===null?null:M9(z)}async spend($){if(!this.rateLimit)return null;let Z=await A3(`mcp-endpoint:${$.via}:${$.id}`,this.rateLimit);return Z===null?null:M9(Z)}}class f9{readable;controller;closed=!1;encoder=new TextEncoder;constructor($){this.readable=new ReadableStream({start:(Z)=>{this.controller=Z},cancel:()=>{this.closed=!0,$()}})}send($){if(this.closed)return;this.controller.enqueue(this.encoder.encode(`event: message
|
|
3
3
|
data: ${JSON.stringify($)}
|
|
4
4
|
|
|
5
5
|
`))}close(){if(this.closed)return;this.closed=!0,this.controller.close()}}class V3 extends Error{}async function G2($,Z){let z=Number($.headers.get("content-length"));if(Number.isFinite(z)&&z>Z)throw new V3;if(!$.body)return"";let G=$.body.getReader(),W=[],X=0;for(;;){let{done:Y,value:K}=await G.read();if(Y)break;if(X+=K.byteLength,X>Z)throw await G.cancel(),new V3;W.push(K)}return Buffer.concat(W).toString("utf8")}function f($,Z,z={}){return new Response(JSON.stringify($),{status:Z,headers:{"Content-Type":"application/json","Cache-Control":"no-store",...z}})}function S9($,Z){for(let[z,G]of Object.entries(Z))$.headers.set(z,G);return $}function W2($){return{"Access-Control-Allow-Origin":$,"Access-Control-Expose-Headers":"Mcp-Session-Id, WWW-Authenticate",Vary:"Origin"}}function X2($){let Z;try{Z=new URL($)}catch{throw Error(`route.mcp.remote.url: "${$}" is not a URL.`)}let z=Z.hostname==="localhost"||Z.hostname==="127.0.0.1"||Z.hostname==="[::1]";if(Z.protocol!=="https:"&&!(Z.protocol==="http:"&&z))throw Error("route.mcp.remote.url must be https (http only on localhost): tokens travel to it.");if(Z.search||Z.hash||Z.username||Z.password)throw Error("route.mcp.remote.url must have no query, fragment or credentials.");if(Z.pathname==="/"||Z.pathname.endsWith("/"))throw Error('route.mcp.remote.url needs a path of its own, like "/mcp", without a trailing slash.');return Z}function Q3($){return y9("sha256").update(`${$.via}\x00${$.id}\x00${$.user?.id}`).digest("base64url").slice(0,32)}function Y2($){return y9("sha256").update(b9($??{})).digest("base64url")}function q9($){if(!q($))return!1;if(Object.keys($).length===0)return!0;return"form"in $}function T9($){let Z=q($._meta)?$._meta:{};return typeof Z.progressToken==="string"||typeof Z.progressToken==="number"}function K2($,Z,z){if(Z.method!=="tools/call"||!z.e)return!1;let G=Z.params?.name;return typeof G==="string"&&$.descriptors({names:[G]})[0]?.requiresApproval===!0}function Q2($){let z=(q($.params._meta)?$.params._meta:{}).progressToken;if(!$.stream||typeof z!=="string"&&typeof z!=="number")return;let G=-1/0;return(W)=>{if(typeof W?.progress!=="number"||!Number.isFinite(W.progress)||W.progress<=G)return;G=W.progress,$.stream.send({jsonrpc:"2.0",method:"notifications/progress",params:{progressToken:z,progress:W.progress,...typeof W.total==="number"?{total:W.total}:{},...typeof W.message==="string"?{message:W.message.slice(0,1000)}:{}}})}}function V2($,Z){let z=JSON.stringify(Z??{},null,1),G=z.length>b3?`${z.slice(0,b3)}\u2026 (${z.length-b3} more characters not shown)`:z;return{message:`Allow "${$.title??$.name}" to run? ${$.description}
|
|
@@ -18,7 +18,7 @@ if(!e)return;
|
|
|
18
18
|
if(e==='system')e=window.matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light';
|
|
19
19
|
c.remove(e==='dark'?'light':'dark');c.add(e);d.style.colorScheme=e}catch(x){}}(${$})`}var pD=Object.defineProperty,x=($,Z)=>pD($,"name",{value:Z,configurable:!0}),rZ=class{type=3;name="";prefix="";value="";suffix="";modifier=3;constructor($,Z,J,W,Y,j){this.type=$,this.name=Z,this.prefix=J,this.value=W,this.suffix=Y,this.modifier=j}hasCustomName(){return this.name!==""&&typeof this.name!="number"}};x(rZ,"Part");var cD=/[$_\p{ID_Start}]/u,dD=/[$_\u200C\u200D\p{ID_Continue}]/u,$Y=".*";function cQ($,Z){return(Z?/^[\x00-\xFF]*$/:/^[\x00-\x7F]*$/).test($)}x(cQ,"isASCII");function WY($,Z=!1){let J=[],W=0;for(;W<$.length;){let Y=$[W],j=x(function(z){if(!Z)throw TypeError(z);J.push({type:"INVALID_CHAR",index:W,value:$[W++]})},"ErrorOrInvalid");if(Y==="*"){J.push({type:"ASTERISK",index:W,value:$[W++]});continue}if(Y==="+"||Y==="?"){J.push({type:"OTHER_MODIFIER",index:W,value:$[W++]});continue}if(Y==="\\"){J.push({type:"ESCAPED_CHAR",index:W++,value:$[W++]});continue}if(Y==="{"){J.push({type:"OPEN",index:W,value:$[W++]});continue}if(Y==="}"){J.push({type:"CLOSE",index:W,value:$[W++]});continue}if(Y===":"){let z="",X=W+1;for(;X<$.length;){let Q=$.substr(X,1);if(X===W+1&&cD.test(Q)||X!==W+1&&dD.test(Q)){z+=$[X++];continue}break}if(!z){j(`Missing parameter name at ${W}`);continue}J.push({type:"NAME",index:W,value:z}),W=X;continue}if(Y==="("){let z=1,X="",Q=W+1,G=!1;if($[Q]==="?"){j(`Pattern cannot start with "?" at ${Q}`);continue}for(;Q<$.length;){if(!cQ($[Q],!1)){j(`Invalid character '${$[Q]}' at ${Q}.`),G=!0;break}if($[Q]==="\\"){X+=$[Q++]+$[Q++];continue}if($[Q]===")"){if(z--,z===0){Q++;break}}else if($[Q]==="("&&(z++,$[Q+1]!=="?")){j(`Capturing groups are not allowed at ${Q}`),G=!0;break}X+=$[Q++]}if(G)continue;if(z){j(`Unbalanced pattern at ${W}`);continue}if(!X){j(`Missing pattern at ${W}`);continue}J.push({type:"REGEX",index:W,value:X}),W=Q;continue}J.push({type:"CHAR",index:W,value:$[W++]})}return J.push({type:"END",index:W,value:""}),J}x(WY,"lexer");function YY($,Z={}){let J=WY($);Z.delimiter??="/#?",Z.prefixes??="./";let W=`[^${d0(Z.delimiter)}]+?`,Y=[],j=0,z=0,X="",Q=new Set,G=x((H)=>{if(z<J.length&&J[z].type===H)return J[z++].value},"tryConsume"),B=x(()=>G("OTHER_MODIFIER")??G("ASTERISK"),"tryConsumeModifier"),V=x((H)=>{let I=G(H);if(I!==void 0)return I;let{type:b,index:S}=J[z];throw TypeError(`Unexpected ${b} at ${S}, expected ${H}`)},"mustConsume"),K=x(()=>{let H="",I;for(;I=G("CHAR")??G("ESCAPED_CHAR");)H+=I;return H},"consumeText"),F=x((H)=>H,"DefaultEncodePart"),D=Z.encodePart||F,U="",O=x((H)=>{U+=H},"appendToPendingFixedValue"),L=x(()=>{U.length&&(Y.push(new rZ(3,"","",D(U),"",3)),U="")},"maybeAddPartFromPendingFixedValue"),P=x((H,I,b,S,R)=>{let f=3;switch(R){case"?":f=1;break;case"*":f=0;break;case"+":f=2;break}if(!I&&!b&&f===3){O(H);return}if(L(),!I&&!b){if(!H)return;Y.push(new rZ(3,"","",D(H),"",f));return}let N;b?b==="*"?N=$Y:N=b:N=W;let v=2;N===W?(v=1,N=""):N===$Y&&(v=0,N="");let _;if(I?_=I:b&&(_=j++),Q.has(_))throw TypeError(`Duplicate name '${_}'.`);Q.add(_),Y.push(new rZ(v,_,D(H),N,D(S),f))},"addPart");for(;z<J.length;){let H=G("CHAR"),I=G("NAME"),b=G("REGEX");if(!I&&!b&&(b=G("ASTERISK")),I||b){let R=H??"";Z.prefixes.indexOf(R)===-1&&(O(R),R=""),L();let f=B();P(R,I,b,"",f);continue}let S=H??G("ESCAPED_CHAR");if(S){O(S);continue}if(G("OPEN")){let R=K(),f=G("NAME"),N=G("REGEX");!f&&!N&&(N=G("ASTERISK"));let v=K();V("CLOSE");let _=B();P(R,f,N,v,_);continue}L(),V("END")}return Y}x(YY,"parse");function d0($){return $.replace(/([.+*?^${}()[\]|/\\])/g,"\\$1")}x(d0,"escapeString");function ZY($){return $&&$.ignoreCase?"ui":"u"}x(ZY,"flags");function dQ($,Z,J){return jY(YY($,J),Z,J)}x(dQ,"stringToRegexp");function JZ($){switch($){case 0:return"*";case 1:return"?";case 2:return"+";case 3:return""}}x(JZ,"modifierToString");function jY($,Z,J={}){J.delimiter??="/#?",J.prefixes??="./",J.sensitive??=!1,J.strict??=!1,J.end??=!0,J.start??=!0,J.endsWith="";let W=J.start?"^":"";for(let X of $){if(X.type===3){X.modifier===3?W+=d0(X.value):W+=`(?:${d0(X.value)})${JZ(X.modifier)}`;continue}Z&&Z.push(X.name);let Q=`[^${d0(J.delimiter)}]+?`,G=X.value;if(X.type===1?G=Q:X.type===0&&(G=$Y),!X.prefix.length&&!X.suffix.length){X.modifier===3||X.modifier===1?W+=`(${G})${JZ(X.modifier)}`:W+=`((?:${G})${JZ(X.modifier)})`;continue}if(X.modifier===3||X.modifier===1){W+=`(?:${d0(X.prefix)}(${G})${d0(X.suffix)})`,W+=JZ(X.modifier);continue}W+=`(?:${d0(X.prefix)}`,W+=`((?:${G})(?:`,W+=d0(X.suffix),W+=d0(X.prefix),W+=`(?:${G}))*)${d0(X.suffix)})`,X.modifier===0&&(W+="?")}let Y=`[${d0(J.endsWith)}]|$`,j=`[${d0(J.delimiter)}]`;if(J.end)return J.strict||(W+=`${j}?`),J.endsWith.length?W+=`(?=${Y})`:W+="$",new RegExp(W,ZY(J));J.strict||(W+=`(?:${j}(?=${Y}))?`);let z=!1;if($.length){let X=$[$.length-1];X.type===3&&X.modifier===3&&(z=J.delimiter.indexOf(X)>-1)}return z||(W+=`(?=${j}|${Y})`),new RegExp(W,ZY(J))}x(jY,"partsToRegexp");var I$={delimiter:"",prefixes:"",sensitive:!0,strict:!0},uD={delimiter:".",prefixes:"",sensitive:!0,strict:!0},lD={delimiter:"/",prefixes:"/",sensitive:!0,strict:!0};function uQ($,Z){return $.length?$[0]==="/"?!0:!Z||$.length<2?!1:($[0]=="\\"||$[0]=="{")&&$[1]=="/":!1}x(uQ,"isAbsolutePathname");function zY($,Z){return $.startsWith(Z)?$.substring(Z.length,$.length):$}x(zY,"maybeStripPrefix");function lQ($,Z){return $.endsWith(Z)?$.substr(0,$.length-Z.length):$}x(lQ,"maybeStripSuffix");function XY($){return!$||$.length<2?!1:$[0]==="["||($[0]==="\\"||$[0]==="{")&&$[1]==="["}x(XY,"treatAsIPv6Hostname");var iQ=["ftp","file","http","https","ws","wss"];function QY($){if(!$)return!0;for(let Z of iQ)if($.test(Z))return!0;return!1}x(QY,"isSpecialScheme");function sQ($,Z){if($=zY($,"#"),Z||$==="")return $;let J=new URL("https://example.com");return J.hash=$,J.hash?J.hash.substring(1,J.hash.length):""}x(sQ,"canonicalizeHash");function nQ($,Z){if($=zY($,"?"),Z||$==="")return $;let J=new URL("https://example.com");return J.search=$,J.search?J.search.substring(1,J.search.length):""}x(nQ,"canonicalizeSearch");function oQ($,Z){return Z||$===""?$:XY($)?BY($):KY($)}x(oQ,"canonicalizeHostname");function aQ($,Z){if(Z||$==="")return $;let J=new URL("https://example.com");return J.password=$,J.password}x(aQ,"canonicalizePassword");function rQ($,Z){if(Z||$==="")return $;let J=new URL("https://example.com");return J.username=$,J.username}x(rQ,"canonicalizeUsername");function tQ($,Z,J){if(J||$==="")return $;if(Z&&!iQ.includes(Z))return new URL(`${Z}:${$}`).pathname;let W=$[0]=="/";return $=new URL(W?$:"/-"+$,"https://example.com").pathname,W||($=$.substring(2,$.length)),$}x(tQ,"canonicalizePathname");function eQ($,Z,J){return GY(Z)===$&&($=""),J||$===""?$:VY($)}x(eQ,"canonicalizePort");function $G($,Z){return $=lQ($,":"),Z||$===""?$:r4($)}x($G,"canonicalizeProtocol");function GY($){switch($){case"ws":case"http":return"80";case"wws":case"https":return"443";case"ftp":return"21";default:return""}}x(GY,"defaultPortForProtocol");function r4($){if($==="")return $;if(/^[-+.A-Za-z0-9]*$/.test($))return $.toLowerCase();throw TypeError(`Invalid protocol '${$}'.`)}x(r4,"protocolEncodeCallback");function ZG($){if($==="")return $;let Z=new URL("https://example.com");return Z.username=$,Z.username}x(ZG,"usernameEncodeCallback");function JG($){if($==="")return $;let Z=new URL("https://example.com");return Z.password=$,Z.password}x(JG,"passwordEncodeCallback");function KY($){if($==="")return $;if(/[\t\n\r #%/:<>?@[\]^\\|]/g.test($))throw TypeError(`Invalid hostname '${$}'`);let Z=new URL("https://example.com");return Z.hostname=$,Z.hostname}x(KY,"hostnameEncodeCallback");function BY($){if($==="")return $;if(/[^0-9a-fA-F[\]:]/g.test($))throw TypeError(`Invalid IPv6 hostname '${$}'`);return $.toLowerCase()}x(BY,"ipv6HostnameEncodeCallback");function VY($){if($===""||/^[0-9]*$/.test($)&&parseInt($)<=65535)return $;throw TypeError(`Invalid port '${$}'.`)}x(VY,"portEncodeCallback");function WG($){if($==="")return $;let Z=new URL("https://example.com");return Z.pathname=$[0]!=="/"?"/-"+$:$,$[0]!=="/"?Z.pathname.substring(2,Z.pathname.length):Z.pathname}x(WG,"standardURLPathnameEncodeCallback");function YG($){return $===""?$:new URL(`data:${$}`).pathname}x(YG,"pathURLPathnameEncodeCallback");function jG($){if($==="")return $;let Z=new URL("https://example.com");return Z.search=$,Z.search.substring(1,Z.search.length)}x(jG,"searchEncodeCallback");function zG($){if($==="")return $;let Z=new URL("https://example.com");return Z.hash=$,Z.hash.substring(1,Z.hash.length)}x(zG,"hashEncodeCallback");var XG=class{#j;#W=[];#Z={};#$=0;#Y=1;#G=0;#X=0;#F=0;#U=0;#D=!1;constructor($){this.#j=$}get result(){return this.#Z}parse(){for(this.#W=WY(this.#j,!0);this.#$<this.#W.length;this.#$+=this.#Y){if(this.#Y=1,this.#W[this.#$].type==="END"){if(this.#X===0){this.#H(),this.#K()?this.#J(9,1):this.#B()?this.#J(8,1):this.#J(7,0);continue}else if(this.#X===2){this.#V(5);continue}this.#J(10,0);break}if(this.#F>0)if(this.#C())this.#F-=1;else continue;if(this.#x()){this.#F+=1;continue}switch(this.#X){case 0:this.#T()&&this.#V(1);break;case 1:if(this.#T()){this.#E();let $=7,Z=1;this.#N()?($=2,Z=3):this.#D&&($=2),this.#J($,Z)}break;case 2:this.#L()?this.#V(3):(this.#M()||this.#B()||this.#K())&&this.#V(5);break;case 3:this.#_()?this.#J(4,1):this.#L()&&this.#J(5,1);break;case 4:this.#L()&&this.#J(5,1);break;case 5:this.#A()?this.#U+=1:this.#S()&&(this.#U-=1),this.#I()&&!this.#U?this.#J(6,1):this.#M()?this.#J(7,0):this.#B()?this.#J(8,1):this.#K()&&this.#J(9,1);break;case 6:this.#M()?this.#J(7,0):this.#B()?this.#J(8,1):this.#K()&&this.#J(9,1);break;case 7:this.#B()?this.#J(8,1):this.#K()&&this.#J(9,1);break;case 8:this.#K()&&this.#J(9,1);break;case 9:break;case 10:break}}this.#Z.hostname!==void 0&&this.#Z.port===void 0&&(this.#Z.port="")}#J($,Z){switch(this.#X){case 0:break;case 1:this.#Z.protocol=this.#Q();break;case 2:break;case 3:this.#Z.username=this.#Q();break;case 4:this.#Z.password=this.#Q();break;case 5:this.#Z.hostname=this.#Q();break;case 6:this.#Z.port=this.#Q();break;case 7:this.#Z.pathname=this.#Q();break;case 8:this.#Z.search=this.#Q();break;case 9:this.#Z.hash=this.#Q();break;case 10:break}this.#X!==0&&$!==10&&([1,2,3,4].includes(this.#X)&&[6,7,8,9].includes($)&&(this.#Z.hostname??=""),[1,2,3,4,5,6].includes(this.#X)&&[8,9].includes($)&&(this.#Z.pathname??=this.#D?"/":""),[1,2,3,4,5,6,7].includes(this.#X)&&$===9&&(this.#Z.search??="")),this.#P($,Z)}#P($,Z){this.#X=$,this.#G=this.#$+Z,this.#$+=Z,this.#Y=0}#H(){this.#$=this.#G,this.#Y=0}#V($){this.#H(),this.#X=$}#O($){return $<0&&($=this.#W.length-$),$<this.#W.length?this.#W[$]:this.#W[this.#W.length-1]}#z($,Z){let J=this.#O($);return J.value===Z&&(J.type==="CHAR"||J.type==="ESCAPED_CHAR"||J.type==="INVALID_CHAR")}#T(){return this.#z(this.#$,":")}#N(){return this.#z(this.#$+1,"/")&&this.#z(this.#$+2,"/")}#L(){return this.#z(this.#$,"@")}#_(){return this.#z(this.#$,":")}#I(){return this.#z(this.#$,":")}#M(){return this.#z(this.#$,"/")}#B(){if(this.#z(this.#$,"?"))return!0;if(this.#W[this.#$].value!=="?")return!1;let $=this.#O(this.#$-1);return $.type!=="NAME"&&$.type!=="REGEX"&&$.type!=="CLOSE"&&$.type!=="ASTERISK"}#K(){return this.#z(this.#$,"#")}#x(){return this.#W[this.#$].type=="OPEN"}#C(){return this.#W[this.#$].type=="CLOSE"}#A(){return this.#z(this.#$,"[")}#S(){return this.#z(this.#$,"]")}#Q(){let $=this.#W[this.#$],Z=this.#O(this.#G).index;return this.#j.substring(Z,$.index)}#E(){let $={};Object.assign($,I$),$.encodePart=r4;let Z=dQ(this.#Q(),void 0,$);this.#D=QY(Z)}};x(XG,"Parser");var eW=["protocol","username","password","hostname","port","pathname","search","hash"],_$="*";function JY($,Z){if(typeof $!="string")throw TypeError("parameter 1 is not of type 'string'.");let J=new URL($,Z);return{protocol:J.protocol.substring(0,J.protocol.length-1),username:J.username,password:J.password,hostname:J.hostname,port:J.port,pathname:J.pathname,search:J.search!==""?J.search.substring(1,J.search.length):void 0,hash:J.hash!==""?J.hash.substring(1,J.hash.length):void 0}}x(JY,"extractValues");function N1($,Z){return Z?aZ($):$}x(N1,"processBaseURLString");function oZ($,Z,J){let W;if(typeof Z.baseURL=="string")try{W=new URL(Z.baseURL),Z.protocol===void 0&&($.protocol=N1(W.protocol.substring(0,W.protocol.length-1),J)),!J&&Z.protocol===void 0&&Z.hostname===void 0&&Z.port===void 0&&Z.username===void 0&&($.username=N1(W.username,J)),!J&&Z.protocol===void 0&&Z.hostname===void 0&&Z.port===void 0&&Z.username===void 0&&Z.password===void 0&&($.password=N1(W.password,J)),Z.protocol===void 0&&Z.hostname===void 0&&($.hostname=N1(W.hostname,J)),Z.protocol===void 0&&Z.hostname===void 0&&Z.port===void 0&&($.port=N1(W.port,J)),Z.protocol===void 0&&Z.hostname===void 0&&Z.port===void 0&&Z.pathname===void 0&&($.pathname=N1(W.pathname,J)),Z.protocol===void 0&&Z.hostname===void 0&&Z.port===void 0&&Z.pathname===void 0&&Z.search===void 0&&($.search=N1(W.search.substring(1,W.search.length),J)),Z.protocol===void 0&&Z.hostname===void 0&&Z.port===void 0&&Z.pathname===void 0&&Z.search===void 0&&Z.hash===void 0&&($.hash=N1(W.hash.substring(1,W.hash.length),J))}catch{throw TypeError(`invalid baseURL '${Z.baseURL}'.`)}if(typeof Z.protocol=="string"&&($.protocol=$G(Z.protocol,J)),typeof Z.username=="string"&&($.username=rQ(Z.username,J)),typeof Z.password=="string"&&($.password=aQ(Z.password,J)),typeof Z.hostname=="string"&&($.hostname=oQ(Z.hostname,J)),typeof Z.port=="string"&&($.port=eQ(Z.port,$.protocol,J)),typeof Z.pathname=="string"){if($.pathname=Z.pathname,W&&!uQ($.pathname,J)){let Y=W.pathname.lastIndexOf("/");Y>=0&&($.pathname=N1(W.pathname.substring(0,Y+1),J)+$.pathname)}$.pathname=tQ($.pathname,$.protocol,J)}return typeof Z.search=="string"&&($.search=nQ(Z.search,J)),typeof Z.hash=="string"&&($.hash=sQ(Z.hash,J)),$}x(oZ,"applyInit");function aZ($){return $.replace(/([+*?:{}()\\])/g,"\\$1")}x(aZ,"escapePatternString");function QG($){return $.replace(/([.+*?^${}()[\]|/\\])/g,"\\$1")}x(QG,"escapeRegexpString");function GG($,Z){Z.delimiter??="/#?",Z.prefixes??="./",Z.sensitive??=!1,Z.strict??=!1,Z.end??=!0,Z.start??=!0,Z.endsWith="";let J=".*",W=`[^${QG(Z.delimiter)}]+?`,Y=/[$_\u200C\u200D\p{ID_Continue}]/u,j="";for(let z=0;z<$.length;++z){let X=$[z];if(X.type===3){if(X.modifier===3){j+=aZ(X.value);continue}j+=`{${aZ(X.value)}}${JZ(X.modifier)}`;continue}let Q=X.hasCustomName(),G=!!X.suffix.length||!!X.prefix.length&&(X.prefix.length!==1||!Z.prefixes.includes(X.prefix)),B=z>0?$[z-1]:null,V=z<$.length-1?$[z+1]:null;if(!G&&Q&&X.type===1&&X.modifier===3&&V&&!V.prefix.length&&!V.suffix.length)if(V.type===3){let K=V.value.length>0?V.value[0]:"";G=Y.test(K)}else G=!V.hasCustomName();if(!G&&!X.prefix.length&&B&&B.type===3){let K=B.value[B.value.length-1];G=Z.prefixes.includes(K)}G&&(j+="{"),j+=aZ(X.prefix),Q&&(j+=`:${X.name}`),X.type===2?j+=`(${X.value})`:X.type===1?Q||(j+=`(${W})`):X.type===0&&(!Q&&(!B||B.type===3||B.modifier!==3||G||X.prefix!=="")?j+="*":j+=`(${J})`),X.type===1&&Q&&X.suffix.length&&Y.test(X.suffix[0])&&(j+="\\"),j+=aZ(X.suffix),G&&(j+="}"),X.modifier!==3&&(j+=JZ(X.modifier))}return j}x(GG,"partsToPattern");var FY=class{#j;#W={};#Z={};#$={};#Y={};#G=!1;constructor($={},Z,J){try{let W;if(typeof Z=="string"?W=Z:J=Z,typeof $=="string"){let X=new XG($);if(X.parse(),$=X.result,W===void 0&&typeof $.protocol!="string")throw TypeError("A base URL must be provided for a relative constructor string.");$.baseURL=W}else{if(!$||typeof $!="object")throw TypeError("parameter 1 is not of type 'string' and cannot convert to dictionary.");if(W)throw TypeError("parameter 1 is not of type 'string'.")}typeof J>"u"&&(J={ignoreCase:!1});let Y={ignoreCase:J.ignoreCase===!0},j={pathname:_$,protocol:_$,username:_$,password:_$,hostname:_$,port:_$,search:_$,hash:_$};this.#j=oZ(j,$,!0),GY(this.#j.protocol)===this.#j.port&&(this.#j.port="");let z;for(z of eW){if(!(z in this.#j))continue;let X={},Q=this.#j[z];switch(this.#Z[z]=[],z){case"protocol":Object.assign(X,I$),X.encodePart=r4;break;case"username":Object.assign(X,I$),X.encodePart=ZG;break;case"password":Object.assign(X,I$),X.encodePart=JG;break;case"hostname":Object.assign(X,uD),XY(Q)?X.encodePart=BY:X.encodePart=KY;break;case"port":Object.assign(X,I$),X.encodePart=VY;break;case"pathname":QY(this.#W.protocol)?(Object.assign(X,lD,Y),X.encodePart=WG):(Object.assign(X,I$,Y),X.encodePart=YG);break;case"search":Object.assign(X,I$,Y),X.encodePart=jG;break;case"hash":Object.assign(X,I$,Y),X.encodePart=zG;break}try{this.#Y[z]=YY(Q,X),this.#W[z]=jY(this.#Y[z],this.#Z[z],X),this.#$[z]=GG(this.#Y[z],X),this.#G=this.#G||this.#Y[z].some((G)=>G.type===2)}catch{throw TypeError(`invalid ${z} pattern '${this.#j[z]}'.`)}}}catch(W){throw TypeError(`Failed to construct 'URLPattern': ${W.message}`)}}get[Symbol.toStringTag](){return"URLPattern"}test($={},Z){let J={pathname:"",protocol:"",username:"",password:"",hostname:"",port:"",search:"",hash:""};if(typeof $!="string"&&Z)throw TypeError("parameter 1 is not of type 'string'.");if(typeof $>"u")return!1;try{typeof $=="object"?J=oZ(J,$,!1):J=oZ(J,JY($,Z),!1)}catch{return!1}let W;for(W of eW)if(!this.#W[W].exec(J[W]))return!1;return!0}exec($={},Z){let J={pathname:"",protocol:"",username:"",password:"",hostname:"",port:"",search:"",hash:""};if(typeof $!="string"&&Z)throw TypeError("parameter 1 is not of type 'string'.");if(typeof $>"u")return;try{typeof $=="object"?J=oZ(J,$,!1):J=oZ(J,JY($,Z),!1)}catch{return null}let W={};Z?W.inputs=[$,Z]:W.inputs=[$];let Y;for(Y of eW){let j=this.#W[Y].exec(J[Y]);if(!j)return null;let z={};for(let[X,Q]of this.#Z[Y].entries())if(typeof Q=="string"||typeof Q=="number"){let G=j[X+1];z[Q]=G}W[Y]={input:J[Y]??"",groups:z}}return W}static compareComponent($,Z,J){let W=x((X,Q)=>{for(let G of["type","modifier","prefix","value","suffix"]){if(X[G]<Q[G])return-1;if(X[G]===Q[G])continue;return 1}return 0},"comparePart"),Y=new rZ(3,"","","","",3),j=new rZ(0,"","","","",3),z=x((X,Q)=>{let G=0;for(;G<Math.min(X.length,Q.length);++G){let B=W(X[G],Q[G]);if(B)return B}return X.length===Q.length?0:W(X[G]??Y,Q[G]??Y)},"comparePartList");return!Z.#$[$]&&!J.#$[$]?0:Z.#$[$]&&!J.#$[$]?z(Z.#Y[$],[j]):!Z.#$[$]&&J.#$[$]?z([j],J.#Y[$]):z(Z.#Y[$],J.#Y[$])}get protocol(){return this.#$.protocol}get username(){return this.#$.username}get password(){return this.#$.password}get hostname(){return this.#$.hostname}get port(){return this.#$.port}get pathname(){return this.#$.pathname}get search(){return this.#$.search}get hash(){return this.#$.hash}get hasRegExpGroups(){return this.#G}};x(FY,"URLPattern");function o3($,Z){for(let[J,W]of Object.entries($)){let Y=new FY({pathname:J});if(Y.test({pathname:Z}))return{routePath:J,params:Y.exec({pathname:Z})?.pathname.groups??{},route:W}}return null}var WZ={startIndex:0,carriedViews:[]};function KG($,Z){let J=U0($.path,Z);return J.includes("*")?null:J}function iD($,Z){if(!$)return WZ;if($.search!==Z.search)return WZ;let J=Math.min($.segments.length,Z.segments.length-1),W=0;while(W<J){let Y=$.segments[W],j=Z.segments[W];if(j.alwaysRun)break;if(Y.viewPath!==j.viewPath)break;let z=KG(Y,$.params),X=KG(j,Z.params);if(z===null||X===null||z!==X)break;W++}if(W===0)return WZ;return{startIndex:W,carriedViews:Z.segments.slice(0,W).map(({viewPath:Y})=>Y)}}function sD($,Z){let[,J,...W]=$.split("/");if(!Z.includes(J))return $;let Y=`/${W.join("/")}`;return Y==="/"?"/":Y.replace(/\/$/,"")}function BG($){let{flatViewRoutes:Z,supportedLocales:J,from:W,origin:Y,to:j}=$;if(!W)return WZ;let z;try{z=new URL(W,Y)}catch{return WZ}if(z.origin!==Y)return WZ;let X=o3(Z,sD(z.pathname,J));if(!X)return WZ;return iD({segments:X.route.segments,params:X.params,search:z.search},j)}var UY="x-gemi-from";import{createElement as l1,Fragment as fG}from"react";function nD($){return $.replace(/\([^)]*\)/g,"").replace(/\/\//g,"/")}function t4($){let Z={};for(let[J,W]of Object.entries($))if("run"in W){let Y=W.viewPath;if("children"in W){Z[J]=[Y];let j=new W.children,z=t4(j.routes);for(let[X,Q]of Object.entries(z)){let G=J==="/"?X:`${J}${X}`,B=X==="/"&&J!=="/"?J:G;Z[B]=[Y,...Q]}if(Z[J].length===1)delete Z[J]}else Z[J]=[Y]}else{let Y=new W,j=t4(Y.routes);for(let[z,X]of Object.entries(j)){let Q=J==="/"?z:`${J}${z}`,G=z==="/"&&J!=="/"?J:Q;Z[G]=X}}return Object.fromEntries(Object.entries(Z).map(([J,W])=>[nD(J),W]))}function e4($,Z){let[J,W]=Z,Y=$.find(([j])=>j===J);if(!Y){$.push([J,[...W]]);return}for(let j of W)e4(Y[1],j)}function $8($){let Z=[];for(let[J,W]of Object.entries($))if("run"in W){let Y=W.viewPath;if(Y==="__")continue;if(Y==="REDIRECT")continue;if(Y==="FILE")continue;if("children"in W){let j=new W.children,z=$8(j.routes);e4(Z,[Y,z])}else e4(Z,[Y,[]])}else{let Y=new W,j=$8(Y.routes);for(let z of j)e4(Z,z)}return Z}function DY($){let Z=[];for(let[J,W]of $)Z.push(J,...DY(W).flat());return Array.from(new Set(Z))}function VG($,Z){let[,J,...W]=$.split("/");if(J===void 0||!Z.includes(J))return{locale:null,pathname:$||"/"};return{locale:J,pathname:`/${W.join("/")}`}}class x$ extends m{static getFacadeAccessor(){return c}static getSupportedLocales(){return this.getFacadeRoot().supportedLocales}static getDefaultLocale(){return this.getFacadeRoot().defaultLocale}static locale(){let $=this.getFacadeRoot(),Z=T.getStore();if(Z)return Z.locale??$.detectLocale(Z.req);return $.defaultLocale}static timeZone(){return this.getFacadeRoot().detectTimeZone(T.getStore()?.req)}static formatter($={}){return this.getFacadeRoot().formatter($.locale??x$.locale(),$.timeZone??x$.timeZone())}static setLocale($=x$.locale(),Z={}){let J=this.getFacadeRoot(),W=$;if(!J.supportedLocales.includes($))W=J.defaultLocale;let Y=T.getStore();if(Z.cookie!==!1)Y.setCookie("i18n-locale",W,{expires:new Date(Date.now()+31536000000),secure:!1,httpOnly:!1});return Y.setLocale(W),W}}class OY{id;static token="kernel.id";constructor($=crypto.randomUUID()){this.id=$}}function FG($){return Object.fromEntries(Object.entries($).filter(([,Z])=>{return Z!==null&&Z!==void 0}))}var oD=50;class tZ{fetcher;entries=new Map;settleListener=null;failListener=null;shellAt=null;settledBacklog=[];shipped=new Set;requestStartedAt=performance.now();renderStartedAt=null;discoveryHintsMuted=!1;constructor($){this.fetcher=$}elapsed(){return Math.round(performance.now()-this.requestStartedAt)}keyFor($,Z){return[$,Z].filter((J)=>J.length>0).join("?")}markRenderStart(){if(this.renderStartedAt===null)this.renderStartedAt=performance.now()}markShell(){if(this.shellAt===null)this.shellAt=this.elapsed()}summarize($){let Z=this.elapsed();return{shellAt:this.shellAt??Z,settledAt:Z,aborted:$,queries:Array.from(this.entries.values(),(J)=>({path:J.path,variantKey:J.variantKey,startedAt:J.startedAt,settledAt:J.settledAt,status:J.status,source:J.source}))}}onQueryFail($){this.failListener=$}muteDiscoveryHints(){this.discoveryHintsMuted=!0}maybeLogLateDiscovery($){if(!$.lateBy||this.discoveryHintsMuted)return;if($.status!=="resolved")return;if(Bun.env.NODE_ENV==="production")return;let Z="";try{let Y=JSON.stringify($.data)?.length??0;Z=Y>=1024?`${(Y/1024).toFixed(1)} kB`:`${Y} B`}catch{Z="an unserializable payload"}let J=($.settledAt??0)-$.startedAt,W=$.variantKey?`, { search: ${JSON.stringify(Object.fromEntries(new URLSearchParams($.variantKey)))} }`:"";console.warn(`[gemi] useQuery("${$.patternPath}") was discovered ${$.lateBy}ms into the `+`server render \u2014 under a suspended segment, so its fetch (${J}ms, resolved ${Z}) could not overlap the others. It still streamed. If the query belongs on this route, \`Query.prefetch("${$.patternPath}"${W})\` in the view `+"handler starts it at request time \u2014 but note prefetched data is also re-fetched and "+`streamed into every client-side navigation payload for the route, even when the client already holds it, so weigh that bandwidth against the ${Z}. If the data is only needed conditionally (a closed popover, a hidden tab), \`{ lazy: true }\` + \`trigger()\` avoids running it here at all. \`Query.noPrefetch()\` in the handler marks the omission intentional and silences this hint for the route.`)}read($,Z){return this.entries.get(this.keyFor($,Z))}ensure($,Z={},J="render"){let W=Z.params??{},Y=new URLSearchParams(FG(Z.search??{}));Y.delete("json"),Y.sort();let j=U0($,W),z=Y.toString(),X=this.keyFor(j,z),Q=this.entries.get(X);if(Q)return Q;let G;if(J==="render"&&this.renderStartedAt!==null){let F=Math.round(performance.now()-this.renderStartedAt);if(F>oD)G=F}let B,V=new Promise((F)=>{B=F}),K={path:j,patternPath:$,variantKey:z,lateBy:G,status:"pending",promise:V,source:J,startedAt:this.elapsed()};return this.entries.set(X,K),this.fetcher($,W,Y).then((F)=>{K.status="resolved",K.data=F},(F)=>{K.status="rejected",K.error=F}).then(()=>{if(K.settledAt=this.elapsed(),this.maybeLogLateDiscovery(K),K.status==="rejected"&&this.failListener)this.failListener(K);if(this.settleListener)this.settleListener(K);else this.settledBacklog.push(K);B()}),K}async allSettled(){let $=0;while($!==this.entries.size)$=this.entries.size,await Promise.all(Array.from(this.entries.values(),(Z)=>Z.promise))}snapshotResolved(){let $={};for(let[Z,J]of this.entries){if(J.status!=="resolved")continue;this.shipped.add(Z),$[J.path]??={},$[J.path][J.variantKey]=J.data}return $}onSettle($){this.settleListener=(J)=>{if(this.shipped.has(this.keyFor(J.path,J.variantKey)))return;$(J)};let Z=this.settledBacklog;this.settledBacklog=[];for(let J of Z)this.settleListener(J)}}class u1 extends Error{path;variantKey;status;body;retryAfter;constructor($,Z,J,W,Y){super(typeof W?.message==="string"?W.message:`Request to /api${$} failed with status ${J}`);this.path=$;this.variantKey=Z;this.status=J;this.body=W;this.retryAfter=Y;this.name="QueryError"}}function eZ(){let $=JSON.stringify({error:W$("permission","Forbidden",403)});return new Response($,{status:403,headers:{"Content-Type":"application/json","Content-Length":String(Buffer.byteLength($)),"Cache-Control":"no-store"}})}function LY(){return{status:403,error:{message:"Forbidden"}}}function a3($){let Z=$3.getStore(),J=T.getStore();return(W,Y,j)=>{let z=new URL($.url).origin,X=[U0(W,Y),j.toString()].filter((V)=>V.length>0).join("?"),Q=new Request(`${z}/${X}`,{headers:$.headers,signal:$.signal}),G=Z8($);if(G)Z3(Q,G);let B=new C(Q,Y);return $3.run(Z,()=>T.run(B,async()=>{let V=J?.locale;if(V&&M(c).isLocaleAware)T.getStore().setLocale(V);try{let K=M(Q1).dispatchers(G).api,F=await K.runRouteMiddleware(W,B)??await K.getRouteData(W);if(t1(F)){if(!F.ok)throw new u1(U0(W,Y),j.toString(),F.status,F.body);return F.body}if(F instanceof Response){let D=await F.json().catch(()=>null);if(!F.ok)throw new u1(U0(W,Y),j.toString(),F.status,D);return D}return F}catch(K){if(K instanceof u1)throw K;let F=new u1(U0(W,Y),j.toString(),500,{message:K instanceof Error?K.message:String(K)});throw F.cause=K,F}}))}}var aD=new Set(["script","style","template","title"]),rD=/\shidden([\s=/]|$)/i,tD=/"[^"]*"|'[^']*'/g;function eD($){let Z=0,J=0,W=0,Y=0;while(Y<$.length){let j=$.indexOf("<",Y),z=j===-1?$.length:j;if(z>Y){let V=$.slice(Y,z).replace(/\s+/g,"").length;if(W>0)J+=V;else Z+=V}if(j===-1)break;if($.startsWith("<!--",j)){let V=$.indexOf("-->",j+4);Y=V===-1?$.length:V+3;continue}let X=$.indexOf(">",j);if(X===-1)break;let Q=$.slice(j+1,X);Y=X+1;let G=/^\/?([a-zA-Z][a-zA-Z0-9-]*)/.exec(Q)?.[1]?.toLowerCase();if(!G)continue;let B=Q.startsWith("/");if(!B&&aD.has(G)&&!Q.endsWith("/")){let V=$.indexOf(`</${G}`,Y);Y=V===-1?$.length:V;continue}if(G!=="div")continue;if(B){if(W>0)W-=1}else if(W>0)W+=1;else if(rD.test(Q.replace(tD,'""')))W=1}return{shellChars:Z,deferredChars:J}}var $O=1000,ZO=64;function JO($){return $>=1000?`${($/1000).toFixed(1)} kB`:`${$} chars`}function WO($,Z){if(Z.deferredChars<$O)return null;if(Z.shellChars>=ZO)return null;return`[gemi] GET ${$} streams ${JO(Z.deferredChars)} of its `+`content behind reveal scripts \u2014 a no-JS visitor sees ~${Z.shellChars} chars. If this is a public/content route, add "no-stream" to its middleware.`}function UG($=console.warn){let Z=new Set;return{shouldObserve(J){return!Z.has(J)},report(J,W){if(Z.has(J))return;let Y=WO(J,W);if(!Y)return;Z.add(J),$(Y)}}}function DG(){let $=new TextDecoder,Z="";return{onChunk(J){Z+=$.decode(J,{stream:!0})},measure(){return Z+=$.decode(),eD(Z)}}}function OG($,Z,J=1e4,W){let Y=new TextEncoder,j=()=>{};return new ReadableStream({start(z){let X=!1,Q=(B)=>{if(X)return;X=!0,clearTimeout(G);try{z.close()}catch{}W?.({aborted:B})};j=Q,z.enqueue(Y.encode(`${JSON.stringify($)}
|
|
20
20
|
`)),Z.onSettle((B)=>{if(X||B.status!=="resolved")return;z.enqueue(Y.encode(`${JSON.stringify([B.path,B.variantKey,B.data])}
|
|
21
|
-
`))});let G=setTimeout(()=>Q(!0),J);Z.allSettled().then(()=>Q(!1),()=>Q(!1))},cancel(){j(!1)}})}import{Fragment as OI,createContext as BO,createElement as LI,lazy as MI,use as HI,useContext as TI}from"react";import{createContext as YO}from"react";var jO=YO(null);import{createContext as QO,useContext as VI}from"react";import{useContext as XI}from"react";import{createContext as zO}from"react";import{jsx as YI}from"react/jsx-runtime";var XO=zO({});var GO="gemi.islandI18n",KO=globalThis[Symbol.for(GO)]??=QO(null);function LG($,Z={}){let J=new Set,W={islands:[],render:$,instances:new WeakMap,count:0,i18n:{},localeAware:Boolean(Z.currentLocale),i18nUsed:!1,dictionaries:[],sink:{use(Y,j,z){let X=`${Y} ${j}`;if(J.has(X))return;J.add(X),W.dictionaries.push([Y,j,z])},onUse(){}}};for(let Y of["currentLocale","defaultLocale","timeZone"])Object.defineProperty(W.i18n,Y,{enumerable:!0,get(){return W.i18nUsed=!0,Z[Y]}});return W}function MG($){if(!$.i18nUsed&&!$.localeAware)return;let{currentLocale:Z,defaultLocale:J,timeZone:W}=$.i18n;return{...Z?{currentLocale:Z}:{},...J?{defaultLocale:J}:{},...W?{timeZone:W}:{},...$.dictionaries.length>0?{dictionaries:$.dictionaries}:{}}}var r3="gemi-slot",HG="data-slot",TG="data-gemi-slot";var VO=Symbol.for("gemi.staticRender"),PG=globalThis[VO]??=BO(null);import{createHash as CG}from"crypto";var MY='var r=document,i=window,a=history;i.__gemi_nav?.d();var
|
|
21
|
+
`))});let G=setTimeout(()=>Q(!0),J);Z.allSettled().then(()=>Q(!1),()=>Q(!1))},cancel(){j(!1)}})}import{Fragment as OI,createContext as BO,createElement as LI,lazy as MI,use as HI,useContext as TI}from"react";import{createContext as YO}from"react";var jO=YO(null);import{createContext as QO,useContext as VI}from"react";import{useContext as XI}from"react";import{createContext as zO}from"react";import{jsx as YI}from"react/jsx-runtime";var XO=zO({});var GO="gemi.islandI18n",KO=globalThis[Symbol.for(GO)]??=QO(null);function LG($,Z={}){let J=new Set,W={islands:[],render:$,instances:new WeakMap,count:0,i18n:{},localeAware:Boolean(Z.currentLocale),i18nUsed:!1,dictionaries:[],sink:{use(Y,j,z){let X=`${Y} ${j}`;if(J.has(X))return;J.add(X),W.dictionaries.push([Y,j,z])},onUse(){}}};for(let Y of["currentLocale","defaultLocale","timeZone"])Object.defineProperty(W.i18n,Y,{enumerable:!0,get(){return W.i18nUsed=!0,Z[Y]}});return W}function MG($){if(!$.i18nUsed&&!$.localeAware)return;let{currentLocale:Z,defaultLocale:J,timeZone:W}=$.i18n;return{...Z?{currentLocale:Z}:{},...J?{defaultLocale:J}:{},...W?{timeZone:W}:{},...$.dictionaries.length>0?{dictionaries:$.dictionaries}:{}}}var r3="gemi-slot",HG="data-slot",TG="data-gemi-slot";var VO=Symbol.for("gemi.staticRender"),PG=globalThis[VO]??=BO(null);import{createHash as CG}from"crypto";var MY='var r=document,i=window,a=history;i.__gemi_nav?.d();var C=new AbortController,h=(t,e,n,s)=>t.addEventListener(e,n,{signal:C.signal,...s}),q=i.__gemi_nav={d:()=>C.abort()},y=(t,e)=>{if(!t.g)t.g=1,import(e.s).then((n)=>{if(t.isConnected)t.r=n.h(t,n.m[e.e])}).catch((n)=>console.error(n))},L=(t)=>{let e=t.getElementById("gemi-islands");return e?JSON.parse(e.textContent):{i:[]}},D=(t,e)=>{for(let n of t.querySelectorAll("gemi-island")){let s=e.i[n.dataset.island];if(!s||n.o)continue;if(s.l=="eager")y(n,s);else if(s.l=="idle"||!i.IntersectionObserver||!n.children.length)(i.requestIdleCallback||setTimeout)(()=>y(n,s));else{let l=new IntersectionObserver((m)=>{if(m.some((d)=>d.isIntersecting))l.disconnect(),y(n,s)});for(let m of n.children)l.observe(m)}}},R=\'meta[name="gemi-static"]\',A="style:not([data-gemi-fonts])",T=A+",link[rel=stylesheet]",K=`head>${A},body>${A},link[rel=stylesheet]`,I=\'meta[name]:not([name=viewport]),meta[property],link[rel~=canonical],link[rel~=alternate],link[rel~=icon],link[rel=preload][as=font],style[data-gemi-fonts],script[type="application/ld+json"]\',w=(t)=>t.querySelector(R)?.content,O=(t)=>[...t.querySelectorAll(K)].map((e)=>e.outerHTML).join(),c=(t)=>t.href.split("#")[0],N=O(r),p=r.createElement("div");p.setAttribute("aria-live","polite");p.style.cssText="position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap";r.body.append(p);var _=(t)=>{q.p={url:location.href,title:r.title,initial:t},r.dispatchEvent(new CustomEvent("gemi:page-load",{detail:q.p}))},f=new Map,k=(t)=>{let e=f.get(t);if(!e||Date.now()-e[0]>30000){let n=fetch(t,{headers:{accept:"text/html","x-gemi-navigate":"1"},signal:AbortSignal.timeout(1e4)}).then((s)=>{if(!s.ok||!/^text\\/html/.test(s.headers.get("content-type"))||new URL(s.url||t).origin!=location.origin)throw s;return s.text().then((l)=>[s.url||t,l])});e=[Date.now(),n],n.catch(()=>f.get(t)==e&&f.delete(t))}if(f.delete(t),f.set(t,e),f.size>10)f.delete(f.keys().next().value);return e[1]},M=(t)=>{let e=t.target.closest?.("a[href]"),n=e?.getAttribute("target");if(!e||n&&n!="_self"||e.hasAttribute("download")||/(^|\\s)external(\\s|$)/i.test(e.getAttribute("rel"))||e.closest("[data-gemi-reload]"))return;let s=new URL(e.getAttribute("href"),r.baseURI);if(s.origin==location.origin&&!(s.href.includes("#")&&c(s)==c(location)))return s},v={},U=()=>Math.random().toString(36).slice(2),E=()=>a.state?.g||a.replaceState({...a.state,g:U()},""),P=c(location),b=0,Y=(t)=>{if(!t.hasAttribute("tabindex"))t.setAttribute("tabindex","-1"),t.addEventListener("blur",()=>t.removeAttribute("tabindex"),{once:!0});t.focus({preventScroll:!0})},j=(t)=>{let e=r.body,n=t.body,s=L(t),l=r.documentElement;r.title=t.title;for(let o of["lang","dir"]){let u=t.documentElement.getAttribute(o);if(u==null)l.removeAttribute(o);else l.setAttribute(o,u)}for(let o of r.head.querySelectorAll(I))o.remove();let m=new Set([...r.querySelectorAll("link[rel=modulepreload]")].map((o)=>o.getAttribute("href")));r.head.append(...t.head.querySelectorAll(I),...[...t.head.querySelectorAll("link[rel=modulepreload]")].filter((o)=>!m.has(o.getAttribute("href"))));let d=new Map([...e.querySelectorAll("[data-gemi-persist]")].map((o)=>[o.dataset.gemiPersist,o])),g=[...n.querySelectorAll("[data-gemi-persist]")].map((o)=>[o,d.get(o.dataset.gemiPersist)]).filter((o)=>o[1]);for(let o of[...e.querySelectorAll("gemi-island")].reverse())if(o.o=1,!g.some((u)=>u[1].contains(o)))try{o.r?.unmount()}catch(u){console.error(u)}for(let[o,u]of g)o.replaceWith(u);for(let o of[...e.childNodes])if(!o.matches?.(T))o.remove();for(let o of[...n.children])if(o.matches(T))o.remove();for(let o of[...e.attributes])e.removeAttribute(o.name);for(let o of n.attributes)e.setAttribute(o.name,o.value);e.append(...n.childNodes,p),D(e,s)},H=async(t,e)=>{let n=++b,s=!e&&v[a.state?.g];a.scrollRestoration="manual";try{let[l,m]=await k(c(t));if(n!=b)return;let d=new DOMParser().parseFromString(m,"text/html");if(w(d)==null||w(d)!=w(r)||O(d)!=N)throw 0;if(e){let o=new URL(l);o.hash=t.hash,a.pushState({g:U()},"",o.href)}P=c(location),j(d);let g=e&&t.hash&&r.getElementById(decodeURIComponent(t.hash.slice(1)));if(g)g.scrollIntoView({behavior:"instant"});else i.scrollTo({left:s?.[0]||0,top:s?.[1]||0,behavior:"instant"});if(e)Y(g||r.querySelector("h1")||r.querySelector("main")||r.body);p.textContent=r.title,_(!1)}catch{if(n!=b)return;if(e)location.assign(t.href);else location.reload()}};h(r,"click",(t)=>{if(t.defaultPrevented||t.button||t.metaKey||t.ctrlKey||t.shiftKey||t.altKey)return;let e=M(t);if(e&&r.dispatchEvent(new CustomEvent("gemi:before-navigate",{cancelable:!0,detail:{url:e.href}})))t.preventDefault(),E(),v[a.state.g]=[i.scrollX,i.scrollY],H(e,1)});h(i,"popstate",()=>{if(b++,c(location)==P){let t=v[a.state?.g];if(t)i.scrollTo({left:t[0],top:t[1],behavior:"instant"})}else if(a.state?.g)H(new URL(location.href),0);else location.reload()});h(i,"hashchange",E);h(i,"scroll",()=>a.state?.g&&(v[a.state.g]=[i.scrollX,i.scrollY]),{passive:!0});var S,x=(t)=>{if(r.querySelector(R)?.dataset.prefetch=="none"||navigator.connection?.saveData)return;let e=M(t);if(e&&c(e)!=c(location))k(c(e))};h(r,"pointerover",(t)=>{clearTimeout(S),S=setTimeout(()=>x(t),65)});h(r,"pointerout",()=>clearTimeout(S));h(r,"focusin",x);h(r,"touchstart",x,{passive:!0});E();D(r,L(r));_(!0);';import{createHash as FO}from"crypto";import{existsSync as _G,readFileSync as UO}from"fs";import{join as NY}from"path";var IG=".script",DO=[".ts",".js"],OO="document-scripts.json",xG="data-gemi-script",LO=/^[A-Za-z0-9_-]+(\/[A-Za-z0-9_-]+)*$/;function MO($){if(typeof $!=="string"||!LO.test($))throw Error(`A static view's \`script\` is a path under app/views without the ".script.ts" suffix, e.g. "site/clicks". Got ${JSON.stringify($)}.`)}function HO($,Z){for(let J of DO){let W=NY($,"views",`${Z}${IG}${J}`);if(_G(W))return W}return null}async function NG($){let Z=await Bun.build({entrypoints:[$],target:"browser",format:"iife",minify:!0,throw:!1});if(!Z.success||!Z.outputs[0]){let W=Z.logs.map((Y)=>String(Y)).join(`
|
|
22
22
|
`);throw Error(`The document script ${$} does not bundle.
|
|
23
23
|
${W}`)}let J=(await Z.outputs[0].text()).trim();if(/<\/script|<!--/i.test(J))throw Error(`The document script ${$} contains "</script" or "<!--", which would end the inline <script> it is put in. Write it "<\\/script" or build the string from parts.`);return J}function TO($){return`'sha256-${FO("sha256").update($).digest("base64")}'`}var HY,TY=new Map;function PO(){if(HY===void 0){let $=NY(PY(),"dist","server",OO);HY=_G($)?JSON.parse(UO($,"utf8")):null}return HY??null}async function _Y($){MO($);let Z=Bun.env.NODE_ENV==="production";if(Z){let j=PO()?.[$];if(j!==void 0)return j;let z=TY.get($);if(z)return z}let J=NY(PY(),"app"),W=HO(J,$);if(!W)throw Error(`The document script "${$}" was not found. It is a file at app/views/${$}${IG}.ts (or .js).`);if(!Z)return NG(W);let Y=NG(W);return TY.set($,Y),Y.catch(()=>TY.delete($)),Y}async function EI($){return TO(await _Y($))}var NO="gemi-islands",_O="gemi-island-i18n",vI=`'sha256-${CG("sha256").update(CY).digest("base64")}'`;function IY($,Z,J,W){if(!J)return $;let Y=W?$.lastIndexOf(Z):$.indexOf(Z);return Y===-1?$+J:$.slice(0,Y)+J+$.slice(Y)}var xY=($)=>$.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<"),gI=`'sha256-${CG("sha256").update(MY).digest("base64")}'`,IO='await import("/refresh.js").catch(()=>{});await import("/@vite/client").catch(()=>{});',xO="gemi-static";function AG($,Z,J,W,Y,j){let z=new Set,X=[];if(J)X=Z.islands.map((U)=>{let O=U.module?J(U.module):void 0;if(!O)return console.error(`[gemi] island ${U.module??"(unknown module)"}: no client build entry. Declare it as island(() => import("./Component")) so gemi's Vite plugin builds it.`),null;if(U.load==="eager"){for(let L of O.preload)z.add(L);if(U.preloadDynamic)for(let L of O.dynamicPreload??[])z.add(L)}return{s:O.src,e:U.export,l:U.load}});let Q=X.some((U)=>U!==null),G=j?`<script type="module" ${xG}="${xY(j.name)}">${j.source}</script>`:"";if(!Q&&!Y)return IY($,"</head>",G,!1);let V=(Y?`<meta name="${xO}" content="${xY(Y.identity)}"${Y.prefetch==="none"?' data-prefetch="none"':""}/>`:"")+[...z].map((U)=>`<link rel="modulepreload" href="${xY(U)}"/>`).join("")+G,K=Y?MY:CY,F=Q?MG(Z):void 0,D=(Q?`<script type="application/json" id="${NO}">${r0({i:X})}</script>`:"")+(F?`<script type="application/json" id="${_O}">${r0(F)}</script>`:"")+`<script type="module">${W?IO+K:K}</script>`;return IY(IY($,"</head>",V,!1),"</body>",D,!0)}function CO($,Z){let J=/<(\/?)template\b[^>]*>/gi;J.lastIndex=Z;let W=0;for(let Y=J.exec($);Y;Y=J.exec($))if(W+=Y[1]?-1:1,W===0)return J.lastIndex;return-1}function SG($){let Z=`<template ${TG}="`;for(let J=$.lastIndexOf(Z);J!==-1;J=$.lastIndexOf(Z)){let W=CO($,J);if(W===-1)break;let Y=J+Z.length,j=$.slice(Y,$.indexOf('"',Y)),z=$.indexOf(">",Y)+1,X=$.slice(z,W-11);$=$.slice(0,J)+$.slice(W);let Q=`<${r3} ${HG}="${j}" style="display:contents"></${r3}>`;$=$.split(Q).join(`<${r3} style="display:contents">${X}</${r3}>`)}return $}function AY($){if(!$)return{locale:!0,session:!0,csrf:!0};return{locale:!1,session:$.session===!0,csrf:$.csrf===!0}}function RG($,Z){if($.getSetCookie().length>0){if(Z.cacheControl&&Bun.env.NODE_ENV!=="production")console.warn(`[gemi] A static view with cacheControl "${Z.cacheControl}" set a cookie, so it was sent "private, no-store" instead. Static pages are cacheable only when nothing on them sets a cookie.`);$.set("Cache-Control","private, no-store");return}if(Z.cacheControl&&!$.has("Cache-Control"))$.set("Cache-Control",Z.cacheControl)}function AO($){let Z=$.headers.get("Cache-Control")?.toLowerCase()??"";return/(^|[\s,])(public|s-maxage)\b/.test(Z)}var EG=new Set,SO=new Set(["public","private","s-maxage","proxy-revalidate"]);function SY($,Z){let J=$.get("Cache-Control");if(!J||$.getSetCookie().length===0)return;if(!/(^|[\s,])(public|s-maxage)\b/i.test(J))return;let Y=["private",...J.split(",").map((j)=>j.trim()).filter((j)=>{let z=j.split("=")[0].trim().toLowerCase();return z!==""&&!SO.has(z)})].join(", ");if(Bun.env.NODE_ENV!=="production"&&!EG.has(Z)){EG.add(Z);let j=[...new Set($.getSetCookie().map((z)=>z.split("=")[0]))];console.warn(`[gemi] The view "${Z??""}" sets cookies (${j.join(", ")}) on a response with Cache-Control "${J}", so it was sent "${Y}" instead: a shared cache would hand those cookies to every visitor. To let a CDN cache the page, make it a static view with .static({ cacheControl }).`)}$.set("Cache-Control",Y)}var bG=new Set;function kG($,Z){if(!AO($)||$.headers.getSetCookie().length===0)return $;if(Bun.env.NODE_ENV!=="production"&&!bG.has(Z))bG.add(Z),console.warn(`[gemi] The file route "${Z??""}" set a cookie on a response with Cache-Control "${$.headers.get("Cache-Control")}", so the cookie was not sent: a shared cache would hand it to every visitor. Make the response private, or set the cookie elsewhere.`);try{return $.headers.delete("Set-Cookie"),$}catch{let J=new Headers($.headers);return J.delete("Set-Cookie"),new Response($.body,{status:$.status,statusText:$.statusText,headers:J})}}var EO=async()=>(await import("./chunk-hq710s2a.js")).default,EY,t3=async(...$)=>{return EY??=import("react-dom/server.browser").catch((Z)=>{throw EY=void 0,Z}),(await EY).renderToReadableStream(...$)},wG=1e4,qG="no-locale",bO="no-theme";async function RO($,Z,J){let W=`${J==="italic"?"italic,":""}wght@${J==="italic"?"1,":""}${Z}`,z=(await(await fetch(`https://fonts.googleapis.com/css2?family=${$}:${W}&display=swap`,{headers:{"User-Agent":"Mozilla/5.0 Firefox/1.0"}})).text()).match(/url\(([^)]+)\)/)?.[1];return await fetch(z).then((X)=>X.arrayBuffer())}var wY="/assets";function kO($){return $===wY||$.startsWith(`${wY}/`)}function fO($){let Z=$.filter(kO);if(Z.length>0){let J=Z.length>1;throw Error(`View route path${J?"s":""} ${Z.map((W)=>`"${W}"`).join(", ")} use${J?"":"s"} the reserved "${wY}" prefix. The client build output is served from there before the router runs, so the route would never match. Mount it somewhere else, or set \`assetRoutes: true\` on these views' config (route.view or a route.domains group's view).`)}}function wO($){let Z=M(Q1).resolver;return{...$.domain,root:Z.root,origin:Z.publicOrigin($.rawRequest)}}function bY($){let{status:Z=400,error:J,body:W,...Y}=$;return new Response(W??J?.message,{...Y,status:Z})}function qO($){let{status:Z=400,data:J,directive:W,headers:Y}=$;return new Response(JSON.stringify({data:J,directive:W}),{headers:Y,status:Z})}class e3{static token="router.view";flatViewRoutes={};routeManifest={};clientRouteManifest={};componentTree=[];flatComponentTree=[];requiredViews={};staticRoutes=[];root=null;shellReporter=UG();preloadCache=new WeakMap;hooks;partialRendering;localeRouting;detectLocale;theme;defaultMeta;notFound;publicFiles;assetRoutes;translate;constructor($,Z={}){let J=vQ();if(this.partialRendering=$.partialRendering??J.partialRendering,this.localeRouting=$.localeRouting??J.localeRouting,this.detectLocale=$.detectLocale,this.detectLocale&&this.localeRouting!=="off")throw Error('`view.detectLocale` needs `view.localeRouting: "off"`: on locale-routed views the URL, the `i18n-locale` cookie and `Accept-Language` decide the locale. A `route.domains` group that inherits it and keeps locale routing can set `detectLocale: undefined`.');this.theme=$.theme??J.theme,this.defaultMeta=$.meta,this.notFound=$.notFound,this.publicFiles=$.publicFiles??J.publicFiles,this.assetRoutes=$.assetRoutes??J.assetRoutes,this.translate=$.translate,this.hooks={onNotFound:$.onNotFound??J.onNotFound,onRequestStart:$.onRequestStart??J.onRequestStart,onRequestEnd:$.onRequestEnd??J.onRequestEnd,onRequestFail:$.onRequestFail??J.onRequestFail,onStreamComplete:$.onStreamComplete??J.onStreamComplete};let W={"/":$.rootRouter,"/auth":EQ(Z)};if(this.requiredViews=Object.fromEntries(AQ(Z).map(({view:Y,requiredBy:j})=>[Y,j])),this.flatViewRoutes=a4(W),!this.assetRoutes)fO(Object.keys(this.flatViewRoutes));this.routeManifest=t4(W),this.clientRouteManifest=Object.fromEntries(Object.entries(this.routeManifest).filter(([,Y])=>Y.at(-1)!=="FILE")),this.componentTree=$8(W),this.flatComponentTree=DY(this.componentTree),this.staticRoutes=Object.entries(this.flatViewRoutes).filter(([,Y])=>Y.static).map(([Y])=>Y);for(let Y of this.staticRoutes){let j=this.flatViewRoutes[Y].static?.layout;if(j&&!this.flatComponentTree.includes(j))this.flatComponentTree.push(j)}if(this.notFound){for(let Y of[this.notFound.view,this.notFound.static?.layout])if(Y&&!this.flatComponentTree.includes(Y))this.flatComponentTree.push(Y)}this.root=$.root}async passesFeatureGates($){let Z=M(j$);for(let J of $)if(!await Z.enabled(J))return!1;return!0}async onRequestEnd($,Z={}){if(Z.mintSession!==!1)J8();return await this.hooks.onRequestEnd($)}completeStream($,Z){let J=(W)=>{YZ.error(W?.message??'Error in "onStreamComplete" event handler',{err:JSON.stringify(W)})};try{Promise.resolve(this.hooks.onStreamComplete($,Z)).catch(J)}catch(W){J(W)}}modulePreloadLinks($){let{clientEntry:Z,modulePreloadManifest:J,views:W,routeKey:Y}=$,j=()=>{let Q=new Set(Z?.preload??[]);for(let G of W)for(let B of J?.[G]??[])Q.add(B);return[...Q].map((G)=>l1("link",{key:`modulepreload:${G}`,rel:"modulepreload",href:G}))};if(!J)return j();let z=this.preloadCache.get(J);if(!z||z.clientEntry!==Z)z={clientEntry:Z,byRoute:new Map},this.preloadCache.set(J,z);let X=z.byRoute.get(Y);if(!X)X=j(),z.byRoute.set(Y,X);return X}async renderStatic($){let{req:Z,runInRequestScope:J,staticView:W,currentViews:Y,data:j,serverQueries:z,headers:X}=$,Q;if(W.layout){if(Q=$.viewImportMap[W.layout],!Q)throw Error(`The static layout "${W.layout}" was not found. It is a view path: a file at app/views/${W.layout}.tsx whose default export renders the document.`)}let G=await $.getStyles(Y,{static:!0,layout:W.layout});z.markRenderStart();let B=fY(),V=new AbortController,K=setTimeout(()=>V.abort(),wG),F=(U)=>{if(Bun.env.NODE_ENV!=="production")console.error(U)},D=LG(async(U,O)=>{let L=await t3(U,{signal:V.signal,identifierPrefix:O,progressiveChunkSize:Number.MAX_SAFE_INTEGER,onError:F});return await L.allReady.catch(()=>{}),await new Response(L).text()},{currentLocale:j?.i18n?.currentLocale,defaultLocale:j?.i18n?.defaultLocale,timeZone:j?.i18n?.timeZone});try{let U,O=typeof W.script==="function"?await J(()=>W.script(Z)):W.script;if(O)U={name:O,source:await _Y(O)};let L;if(W.navigation){let I=W.navigation===!0?{}:W.navigation,b=I.version?String(await J(()=>I.version(Z))):"";L={identity:[W.layout??"",$.buildId??"",U?.name??"",b].join("|"),prefetch:I.prefetch==="none"?"none":"intent"}}let P=await t3(l1(PG.Provider,{value:D,children:l1(fG,{children:[...G,l1(this.root,{data:j,viewImportMap:$.viewImportMap,viewModules:$.viewModules,serverQueries:z,dictionarySink:B,rootLayout:Q,key:"root"})]})}),{signal:V.signal,progressiveChunkSize:Number.MAX_SAFE_INTEGER,onError:F});await P.allReady.catch(()=>{});let H=SG(await new Response(P).text());return new Response(AG(H,D,$.resolveIsland,Bun.env.NODE_ENV!=="production",L,U),{status:$.status,headers:X})}finally{clearTimeout(K),J(()=>this.completeStream(Z,z.summarize(V.signal.aborted)))}}async render($){let{req:Z,runInRequestScope:J,csrfTokenHMAC:W,currentPathName:Y,headers:j,i18n:z,params:X,pathname:Q,serverQueries:G,userAgent:B,noStream:V,noTheme:K,url:F,user:D,viewData:U,breadcrumbs:O,urlLocaleSegment:L,meta:P,isOgRequest:H,appId:I,features:b,staticView:S}=$,R=this.theme===!1||K||S?null:{cookie:this.theme.cookie??tW,default:this.theme.default??null,value:yO(Z,this.theme.cookie??tW)},f=L?VG(Q,[L]).pathname:Q,N={kind:"view",data:{meta:P,pageData:{[f]:U},__csrf:W.toString("base64"),prefetchedData:{},i18n:z,auth:{user:D},routeManifest:this.clientRouteManifest,breadcrumbs:O,router:{urlLocaleSegment:L,pathname:Y,params:X,currentPath:Q,searchParams:F.search,is404:!Y?!0:!1,domain:Z.domain?wO(Z):null},appId:I,features:b,theme:R,componentTree:[["404",[]],...this.componentTree],...this.staticRoutes.length>0?{staticRoutes:this.staticRoutes}:{}},head:{}},v=this.root,_=this.routeManifest[Y];return async(k)=>{let{bootstrapModules:M0=[],loaders:Y3,getStyles:s1,viewImportMap:C1,cssManifest:i,ogMap:y,viewModules:r,clientEntry:A1,modulePreloadManifest:j3,assetBase:QZ,resolveIsland:o0,buildId:G1}=k,C$=A1?[]:M0,n1=(p)=>[p,`window.loaders=${Y3}`,...A1?[`import(${JSON.stringify(A1.module)}).catch(function(e){setTimeout(function(){throw e})})`]:[]].join(";");if(H){let p=null,u0=null;for(let A of _??[])if(typeof y[A]==="function")u0=A,p=y[A];if(!p)return new Response("Not found",{status:404});let z3=Object.values(N.data.pageData)[0];try{await t3(l1(p,z3[u0]),{onError:()=>{}})}catch(A){let{fonts:e,...r1}=A.satoriOptions,J6=await Promise.all(e.map((W6)=>{return RO(W6.name,W6.weight,W6.style).then((dK)=>({...W6,data:dK}))})),B5=new Headers(j);B5.set("Content-Type","image/png");let[mK,hK]=await Promise.all([EO(),n4("Rendering an OG image")]),pK=await mK(A.jsx,{...r1,fonts:J6}),cK=await hK(Buffer.from(pK)).png({compressionLevel:0,effort:10}).toBuffer();return new Response(new Uint8Array(cK),{headers:B5})}return new Response("data")}if(S&&Y)return await this.renderStatic({req:Z,runInRequestScope:J,staticView:S,currentViews:_,data:N.data,serverQueries:G,headers:j,getStyles:s1,viewImportMap:C1,viewModules:r,resolveIsland:o0,buildId:G1,status:200});if(S&&!Y&&this.notFound){let p=this.notFound.view;if(!C1[p])throw Error(`The not-found view "${p}" (route.view.notFound) was not found. It is a view path: a file at app/views/${p}.tsx.`);return await this.renderStatic({req:Z,runInRequestScope:J,staticView:S,currentViews:[p],data:N.data,serverQueries:G,headers:j,getStyles:s1,viewImportMap:{...C1,"404":C1[p]},viewModules:r&&{...r,"404":r[p]},resolveIsland:o0,buildId:G1,status:$.refusedStatus??404})}if(N.data.cssManifest=i,N.data.modulePreloadManifest=j3??{},QZ&&QZ!=="/")N.data.assetBase=QZ;if(G1&&G1!=="dev")N.data.buildId=G1;let t=this.modulePreloadLinks({clientEntry:A1,modulePreloadManifest:j3,views:_??["404"],routeKey:Y??"404"}),H8=await s1(_??["404"]);N.data.prefetchedData=G.snapshotResolved(),G.markRenderStart();let A$=new AbortController,o1=setTimeout(()=>A$.abort(),wG),a1=I6(B)||V,GZ=Bun.env.NODE_ENV!=="production"&&!a1&&Y&&this.shellReporter.shouldObserve(Y)?DG():null,S$=fY();try{let p=await t3(l1(fG,{children:[...t,...H8,...R?[l1("script",{key:"theme-script",dangerouslySetInnerHTML:{__html:pQ(r0({cookie:R.cookie,default:R.default}))}})]:[],l1(v,{data:N.data,viewImportMap:C1,viewModules:r,serverQueries:G,dictionarySink:S$,key:"root"})]}),{bootstrapScriptContent:n1(`window.__GEMI_DATA__ = ${r0(N.data)}`),bootstrapModules:C$,signal:A$.signal,...a1?{progressiveChunkSize:Number.MAX_SAFE_INTEGER}:{},onError(u0){if(Bun.env.NODE_ENV!=="production")console.error(u0)}});if(p.allReady.catch(()=>{}).finally(()=>clearTimeout(o1)),a1)await p.allReady.catch(()=>{});return new Response(Y7(p,G,{onShell:a1?void 0:()=>G.markShell(),onChunk:GZ?.onChunk,onClose:()=>J(()=>{if(this.completeStream(Z,G.summarize(A$.signal.aborted)),GZ)this.shellReporter.report(Y,GZ.measure())})},S$),{status:!Y?$.refusedStatus??404:200,headers:j})}catch(p){if(clearTimeout(o1),Bun.env.NODE_ENV==="production")throw J(()=>this.completeStream(Z,G.summarize(A$.signal.aborted))),p;let u0=await t3(l1("div"),{bootstrapScriptContent:n1(`window.error= ${r0(p.message)}; window.stack_trace=${r0(p.stack)};window.__GEMI_DATA__ = ${r0(N.data)}`),bootstrapModules:Bun.env.NODE_ENV==="development"?["/render-error.js",...C$]:C$});return new Response(Y7(u0,G,{onClose:()=>J(()=>this.completeStream(Z,G.summarize(A$.signal.aborted)))}),{status:!Y?$.refusedStatus??404:200,headers:j})}}}viewRefusalStatus($,Z,J){if(b$(Z))return 404;if(Z?.kind===Z$){let W=Z.payload?.view?.status;return W===403||W===404?W:null}if(J$(Z)){if(!J.has(Z))this.hooks.onRequestFail($,Z);return console.error(Z),403}if(Z instanceof u1&&(Z.status===403||Z.status===404))return Z.status;return null}async handleViewRequest($,Z){let J=new URL($.url),W=J.pathname.endsWith(".json"),Y=J.pathname.endsWith(".og"),j=J.pathname.replace(".json","").replace(".og",""),[,z,...X]=j.split("/"),Q=j,G=null,B=null,V=M(c),K=o3(this.flatViewRoutes,j),F=V.isLocaleAware&&this.localeRouting==="prefix"&&!K?.route.middleware.includes(qG);if(F&&V.supportedLocales.includes(z))Q=`/${X.join("/")}`,G=z,B=z;if(($.method==="GET"||$.method==="HEAD")&&!W&&!Y&&K===null&&J.pathname.endsWith("/")&&!J.pathname.startsWith("//")){let _=J.pathname.replace(/\/+$/,""),k=F&&V.supportedLocales.includes(_.slice(1));if(_&&!k)return new Response("",{status:301,headers:{Location:`${_}${J.search}`}})}if(F&&!Y&&B===null&&!(B===null&&K!==null)){let _=RY(z,V.supportedLocales,V.defaultLocale);if(_){let k=X.length?`/${X.join("/")}`:"";return new Response("",{status:302,headers:{"Cache-Control":"private, no-cache, no-store, max-age=0, must-revalidate",Location:`/${_}${k}${W?".json":""}${J.search}`}})}}if(F&&!Y){let _=M(c).detectLocale(new C($,{},"view",Q));if(B===null&&_!==V.defaultLocale){let k=J.pathname==="/"?"":J.pathname;return new Response("",{status:302,headers:{"Cache-Control":"private, no-cache, no-store, max-age=0, must-revalidate",Location:`/${_}${k}${J.search}`}})}}Q=Q.replace("//","/");let U=[],O=[],L=null,P={},H=null,I=!1,b=!1,S=[],R,f=!1,N=!1;try{let _=o3(this.flatViewRoutes,Q);if(B&&_?.route.middleware.includes(qG))_=null;if(_){if(f=!0,L=_.routePath,P=_.params,U=_.route.exec,O=_.route.middleware,S=_.route.features,I=O.includes("no-stream"),b=O.includes(bO),R=_.route.static,N=_.route.segments.at(-1)?.viewPath==="FILE",W&&this.partialRendering){let k=$.headers.get(UY),M0=BG({flatViewRoutes:this.flatViewRoutes,supportedLocales:M(c).supportedLocales,from:k,origin:J.origin,to:{segments:_.route.segments,params:P,search:J.search}});if(M0.startIndex>0)U=U.slice(M0.startIndex),H={from:k,carriedViews:M0.carriedViews}}}}catch(_){throw _}if(R&&W)return new Response("Not found",{status:404});let v=new C($,P,"view",L);return this.hooks.onRequestStart(v),await T.run(v,async()=>{let _=null,k=T.getStore(),M0=$3.getStore(),Y3=(y)=>$3.run(M0,()=>T.runWith(k,y));k.serverQueries=new tZ(a3($));let s1=new Set;k.serverQueries.onQueryFail((y)=>{s1.add(y.error);try{Y3(()=>Promise.resolve(this.hooks.onRequestFail(i,y.error)).catch(()=>{}))}catch{}});let C1=AY(N?{}:R??(L===null&&!W?this.notFound?.static:void 0));if(B){let y=B.replaceAll("/","");x$.setLocale(y,{cookie:C1.locale})}else if(V.isLocaleAware&&!F)k.setLocale(V.defaultLocale);else x$.setLocale(void 0,{cookie:C1.locale});let i=k.req;if(C1.session)J8();try{let y=null;if(this.detectLocale&&!F&&M(c).isLocaleAware){let{supportedLocales:A,defaultLocale:e}=M(c),r1=await this.detectLocale(i,{supportedLocales:A,defaultLocale:e}),J6=typeof r1==="string"?RY(r1,A,e):null;if(J6)k.setLocale(J6)}try{await M($$).runMiddleware(O)}catch(A){if(y=this.viewRefusalStatus(i,A,s1),y===null)throw A}if(y!==null||S.length>0&&!await this.passesFeatureGates(S))L=null,U=[],i.routePath="";let r=M(c),A1=r.isEnabled,j3=r.isLocaleAware,QZ=new C($,i.params),o0={defaultLocale:r.defaultLocale,timeZone:r.detectTimeZone(QZ)};if(j3){let A=null;if(B)A=B.replaceAll("/",""),k.setLocale(A);else if(!F)A=k.locale??r.defaultLocale;else A=r.detectLocale(QZ),k.setLocale(A);let e=A1?r.getPageTranslations(A,i.routePath):{};o0={...o0,supportedLocales:r.supportedLocales,currentLocale:A,dictionary:{[A]:e},defaultLocale:r.defaultLocale,...F?{}:{localeRouting:"off"}}}await kY(o0.currentLocale??"");let G1;try{G1=await Promise.all(U.map((A)=>A(i)))}catch(A){if(y=this.viewRefusalStatus(i,A,s1),y===null)throw A;L=null,U=[],i.routePath="",G1=[]}let C$=void 0;if(L===null){if(C$=await this.hooks.onNotFound(i,{status:y??404}),j3&&!F&&k.locale&&k.locale!==o0.currentLocale){let A=k.locale;o0={...o0,currentLocale:A,dictionary:{[A]:A1?r.getPageTranslations(A,i.routePath):{}}},await kY(A)}}if(this.defaultMeta&&!k.metadata.hasAllDefaultFields)k.metadata.applyDefaults(typeof this.defaultMeta==="function"?await this.defaultMeta(i):this.defaultMeta);if(this.translate!==void 0)k.metadata.applyTranslateDefault(this.translate);let{cookies:n1,headers:t}=k;if(y!==null)t.set("Cache-Control","no-store");_={data:G1,cookies:n1,headers:t,user:k.user,prefetchedData:k.serverQueries.snapshotResolved(),currentPathName:L,params:i.params,urlLocaleSegment:G,meta:k.renderMeta(),appId:M(OY).id,features:await M(j$).forClient()};let{params:H8,user:A$}=_,o1={},a1={};for(let A of G1??[]){let[e,r1]=Object.entries(A)?.[0]??[];if(!e||!r1)continue;a1[`${e}:${L}`]=r1.breadcrumb,o1[e]=r1}let GZ=L===null&&this.notFound&&!W?this.notFound.static:void 0;if(GZ&&C$)o1["404"]=C$;let S$=o1.FILE;if(S$){try{await this.onRequestEnd(i,{mintSession:!1})}catch(e){YZ.error(e?.message??'Error in "onRequestEnd" event handler',{err:JSON.stringify(e)})}let A;if(S$ instanceof Response)A=Y8(S$,t,n1);else{for(let e of n1)t.append("Set-Cookie",e.toString());A=await k8(S$,t)}return kG(A,L)}if(W){t.set("Content-Type","application/x-ndjson; charset=utf-8"),t.append("Vary",UY),n1.forEach((e)=>t.append("Set-Cookie",e.toString())),SY(t,L),await this.hooks.onRequestEnd(i);let A={meta:H&&!k.metadata.touched?null:_.meta,data:{[Q]:o1},breadcrumbs:a1,prefetchedData:k.serverQueries.snapshotResolved(),i18n:o0,features:_.features,is404:!L,appId:_.appId,partial:H};return new Response(OG(A,k.serverQueries,void 0,({aborted:e})=>Y3(()=>this.completeStream(i,k.serverQueries.summarize(e)))),{headers:t})}t.set("Content-Type","text/html; charset=utf-8");let p=L?R:GZ,u0=Boolean(p),z3=AY(p);if(!I&&!u0)t.append("Vary","User-Agent");if(!u0||z3.session)J8();for(let A of n1)t.append("Set-Cookie",A.toString());if(!u0||z3.csrf){let A=Bun.CSRF.generate(process.env.SECRET);t.append("Set-Cookie",`csrf_token=${A}; HttpOnly; Secure; SameSite=Strict; Expires=${new Date(Date.now()+86400000).toUTCString()}`)}try{await this.onRequestEnd(i,{mintSession:!u0||z3.session})}catch(A){YZ.error(A?.message??'Error in "onRequestEnd" event handler',{err:JSON.stringify(A)})}if(u0&&(L||!f))RG(t,p);return SY(t,L),await this.render({req:i,runInRequestScope:Y3,csrfTokenHMAC:Buffer.from(""),currentPathName:L,headers:t,i18n:o0,params:H8,pathname:J.pathname,serverQueries:k.serverQueries,userAgent:$.headers.get("user-agent"),noStream:I,noTheme:b,url:J,user:A$,viewData:o1,breadcrumbs:a1,urlLocaleSegment:G,meta:_.meta,appId:_.appId,features:_.features,isOgRequest:Y,staticView:p,refusedStatus:y??void 0})}catch(y){if(y.kind===Z$){let r=W?qO(y.payload.viewData??y.payload.api):bY(y.payload.view);for(let A1 of k.cookies)r.headers.append("Set-Cookie",A1.toString());return r}if(!s1.has(y))this.hooks.onRequestFail(i,y);if(J$(y))return console.error(y),W?eZ():bY(LY());if(y instanceof u1&&y.status===403)return W?eZ():bY(LY());throw y}},Z)}}function yO($,Z){let J=$.cookies?.get(Z);return hQ(J)?J:null}function qY(){let $=JSON.stringify({error:W$("not_found","Not found",404)});return new Response($,{status:404,headers:{"Content-Type":"application/json","Content-Length":String(Buffer.byteLength($)),"Cache-Control":"no-store"}})}class mG extends C0{routes={"/api-routes":this.get(()=>{let $=M(j8).flatRoutes,Z=[];for(let[J,W]of Object.entries($))for(let[Y,j]of Object.entries(W)){let{exec:z,middleware:X}=j;Z.push({path:J,method:Y,middleware:X})}return Z}),"/view-routes":this.get(()=>{let $=M(e3).flatViewRoutes,Z=[];for(let[J,{middleware:W,viewPath:Y}]of Object.entries($))Z.push({path:J,method:"GET",viewPath:Y,middleware:W});return Z})}}var vO=new Set([e1,"cookie","content-type","content-length","transfer-encoding","connection","host","user-agent","forwarded"]),gO=/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/,mO=/^[\x21\x23-\x2B\x2D-\x3A\x3C-\x5B\x5D-\x7E]*$/;function hO($,Z,J,W){for(let[Y,j]of Object.entries(J.headers??{})){if(j===void 0||j===null)continue;let z=Y.toLowerCase();if(vO.has(z)||z.startsWith("x-forwarded-"))throw Error(`dispatchAs: credentials may not set the "${Y}" header. The access token stays the initiator's, and the request's framing is dispatchAs's own.`);if(W&&z==="authorization")throw Error(`dispatchAs: credentials may not set "Authorization" on a call dispatched as an identity. The caller's token is for the MCP endpoint and is never passed on.`);$.set(Y,j)}for(let[Y,j]of Object.entries(J.cookies??{})){if(j===void 0||j===null)continue;if(Y===e1)throw Error(`dispatchAs: credentials may not set the "${e1}" cookie. The access token stays the initiator's.`);if(!gO.test(Y)||!mO.test(j))throw Error(`dispatchAs: "${Y}" is not a cookie a Cookie header can carry.`);Z.push(`${Y}=${j}`)}}function pO($,Z){let J=$.body.getReader(),W=!1,Y=()=>{if(W)return;W=!0;try{Z()}catch(z){console.error(z)}},j=new ReadableStream({async pull(z){let X;try{X=await J.read()}catch(Q){Y(),z.error(Q);return}if(X.done){Y();try{z.close()}catch{}return}try{z.enqueue(X.value)}catch{}},async cancel(z){try{await J.cancel(z)}finally{Y()}}},{highWaterMark:0});return new Response(j,{status:$.status,statusText:$.statusText,headers:$.headers})}function yG($){let{status:Z=400,data:J,headers:W}=$,Y=new Headers({"Content-Type":"application/json",...W});if(!Y.has("Cache-Control"))Y.set("Cache-Control","no-store");return new Response(JSON.stringify(J),{status:Z,headers:Y})}function Y8($,Z,J){let W=[];Z?.forEach((z,X)=>W.push([X,z]));let Y=[...typeof Z?.getSetCookie==="function"?Z.getSetCookie():[],...Array.from(J??[])];if(W.length===0&&Y.length===0)return $;let j=(z)=>{for(let[X,Q]of W){if(X.toLowerCase()==="set-cookie")continue;if(!z.has(X))z.set(X,Q)}for(let X of Y)z.append("Set-Cookie",X)};try{return j($.headers),$}catch{let z=new Headers($.headers);return j(z),new Response($.body,{status:$.status,statusText:$.statusText,headers:z})}}function cO(){return Bun.env.NODE_ENV==="development"}class j8{static token="router.api";flatRoutes={};onRequestStart;onRequestEnd;onRequestFail;constructor($){let Z=yQ();this.onRequestStart=$.onRequestStart??Z.onRequestStart,this.onRequestEnd=$.onRequestEnd??Z.onRequestEnd,this.onRequestFail=$.onRequestFail??Z.onRequestFail,this.flatRoutes=oW({"/":$.rootRouter,"/auth":dW,"/__gemi__/services/i18n":uW,"/__gemi__/services/image":sW,...cO()?{"/__gemi__/services/logs":nW,"/__gemi__/debug":mG}:{}})}getRouteHandlerAndParams($){let Z=new URL($.url),J=gG(Z.pathname),W={},Y;for(let[j]of Object.entries(this.flatRoutes))try{let z=new URLPattern({pathname:j});if(z.test({pathname:J})){Y=j,W=z.exec({pathname:J})?.pathname.groups;break}}catch(z){console.error(z)}return{params:W,path:Y}}async runRouteMiddleware($,Z){let W=this.flatRoutes[$][Z.rawRequest.method].middleware;try{await M($$).runMiddleware(W)}catch(Y){if(Y.kind===Z$)return yG(Y.payload.api);else{if(b$(Y))return qY();if(this.onRequestFail(Z,Y),console.error(Y),J$(Y))return eZ();throw Y}}}async getRouteData($){let Z=this.flatRoutes[$],J=T.getStore(),W=Z[J.req.rawRequest.method].exec??(()=>Promise.resolve({})),Y={};try{Y=await W()}catch(j){if(j.kind===Z$)return yG(j.payload.api);if(b$(j))return qY();if(this.onRequestFail(J.req,j),console.error(j),J$(j))return eZ();throw j}return Y}isFrameworkRoute($){return $.startsWith("/__gemi__")}async endRequest($,Z,J){let W=async()=>{try{if(!this.isFrameworkRoute(J))await this.onRequestEnd(Z)}catch(Y){YZ.error(Y?.message??'Error in "onRequestEnd" event handler',{err:JSON.stringify(Y)})}finally{$.destroy()}};if(!$.hasPendingWork()){await W();return}$.whenIdle().then(W).catch((Y)=>{console.error(Y)})}isOpenEndedBody($,Z){return $.method!=="HEAD"&&!Z.headers.has("Content-Length")&&Z.body!==null}async handleApiRequest($,Z){let{params:J,path:W}=this.getRouteHandlerAndParams($),Y=this.flatRoutes[W];if(!Y||!Y[$.method])return new Response(JSON.stringify({error:W$("not_found","Not found",404)}),{status:404});let j=new C($,J,"api",W);if(!this.isFrameworkRoute(W))this.onRequestStart(j);return await T.run(j,async()=>{let z=T.getStore(),X=!1,Q=async()=>{X=!0,await this.endRequest(z,j,W)};try{let G=M(c);if(G.isEnabled){let U=G.detectLocale(j);z.setLocale(U)}z.setRequest(j),M($$).applyDefaultBodyLimit($);let B=await this.runRouteMiddleware(W,j);if(B instanceof Response){let U=Y8(B,z.headers,z.cookies);return await Q(),U}let V=await this.getRouteData(W),K=z.headers,F=z.cookies;if(V instanceof Response){let U=Y8(V,K,F);if(this.isOpenEndedBody($,U)){let O=pO(U,()=>this.endRequest(z,j,W));return X=!0,O}return await Q(),U}let D=(t1(V)?V:K1.json(V)).toResponse(K,F);return await Q(),D}catch(G){if(!X)try{await Q()}catch(B){console.error(B)}throw G}},Z)}async dispatchAs($,Z,J,W,Y){let j=new URL($.rawRequest.url).origin,z=new URL(`${j}/api${J}`),X=`/api${J.split(/[?#]/)[0]}`;if(!J.startsWith("/")||z.origin!==j||z.pathname!==X||z.hash!==""||z.pathname.startsWith("/api/__gemi__")||z.pathname==="/api/auth"||z.pathname.startsWith("/api/auth/"))throw Error(`dispatchAs: "${J}" is not an app api path. Pass the route's own path, without "/api", with every param encoded.`);let Q=Y?.identity;if(Q!==void 0&&(typeof Q!=="object"||!Q?.user))throw Error("dispatchAs: identity needs the user to dispatch as.");let G=new Headers,B=[],V=Q?null:$.cookies.get(e1);if(V)B.push(`${e1}=${V}`);if(Y?.credentials)hO(G,B,Y.credentials,Q!==void 0);if(B.length>0)G.set("Cookie",B.join("; "));let K=Q?null:$.headers.get(e1);if(K)G.set(e1,K);let F=$.headers.get("User-Agent");if(F)G.set("User-Agent",F);let D;if(W instanceof FormData)D=W;else if(W!==void 0)G.set("Content-Type","application/json"),D=JSON.stringify(W);let U=new Request(z,{method:Z,headers:G,body:D,...Y?.signal?{signal:Y.signal}:{}});if(vG(U,DZ($),Q?.grant,Y?.progress),$.domain)Z3(U,$.domain);let O=Q?{user:Q.user}:void 0;return T.exit(()=>K6.exit(()=>this.handleApiRequest(U,O)))}}import{timingSafeEqual as dO}from"crypto";var Q8="",gY="*",uO=60000,lO=1e4,z8=/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/,X8=16,yY=/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/,vY="x-forwarded-host";function pG($){return $.startsWith(":")}function $6($,Z){if($===null)return!1;let J=Buffer.from($,"utf8"),W=Buffer.from(Z,"utf8");return J.length===W.length&&dO(J,W)}function iO($){if(!$)return[];if($===!0)return[{header:vY,clientIpHeader:null,secret:null}];let Z=Array.isArray($)?$:[$],J=Array.isArray($)?null:vY;return Z.map((W)=>({header:W.hostHeader?.toLowerCase()??J,clientIpHeader:W.clientIpHeader?.toLowerCase()??null,secret:W.secret?{header:W.secret.header.toLowerCase(),value:W.secret.value}:null}))}function sO($){if(!$||$===!0)return;if(!Array.isArray($)){hG($,"route.domains.trustProxy",vY);return}if($.length===0)throw Error("`route.domains.trustProxy` is an empty list. List at least one proxy, or leave `trustProxy` out.");let Z=new Map;$.forEach((J,W)=>{let Y=`route.domains.trustProxy[${W}]`;if(typeof J!=="object"||J===null||Array.isArray(J))throw Error(`\`${Y}\` must be an object: { hostHeader?, clientIpHeader?, secret }. \`true\` is only accepted on its own.`);if(!J.secret)throw Error(`\`${Y}.secret\` is required: in a list, each proxy proves itself with a secret of its own.`);if(J.hostHeader===void 0&&J.clientIpHeader===void 0)throw Error(`\`${Y}\` names neither \`hostHeader\` nor \`clientIpHeader\`, so it would trust nothing.`);hG(J,Y,null);let j=Z.get(J.secret.value);if(j!==void 0)throw Error(`\`${Y}.secret.value\` is the same as \`route.domains.trustProxy[${j}].secret.value\`. Give each proxy a secret of its own.`);Z.set(J.secret.value,W)})}function hG($,Z,J){let{hostHeader:W,clientIpHeader:Y,secret:j}=$;if(W!==void 0&&(typeof W!=="string"||!yY.test(W)))throw Error(`\`${Z}.hostHeader\` must be a single header name, e.g. "x-forwarded-host". Got ${JSON.stringify(W)}.`);let z=(W??J)?.toLowerCase()??null;if(Y!==void 0){if(typeof Y!=="string"||!yY.test(Y))throw Error(`\`${Z}.clientIpHeader\` must be a single header name, e.g. "x-client-ip". Got ${JSON.stringify(Y)}.`);if(!j)throw Error(`\`${Z}.clientIpHeader\` needs \`secret\`: without proof the proxy sent it, any client that reaches the app directly picks its own address.`);if(Y.toLowerCase()===z)throw Error(`\`${Z}.clientIpHeader\` names the same header as \`hostHeader\`.`);if(typeof j.header==="string"&&Y.toLowerCase()===j.header.toLowerCase())throw Error(`\`${Z}.clientIpHeader\` names the same header as \`secret.header\`.`)}if(!j)return;if(typeof j.header!=="string"||!yY.test(j.header))throw Error(`\`${Z}.secret.header\` must be a header name. Got "${j.header}".`);if(j.header.toLowerCase()===z)throw Error(`\`${Z}.secret.header\` names the same header as \`hostHeader\`; the secret needs a header of its own.`);if(typeof j.value!=="string"||j.value.length<X8)throw Error(`\`${Z}.secret.value\` must be at least ${X8} characters. A guessable one lets any client name its own host.`)}function _1($){if(!$)return null;try{return new URL(`http://${$.trim()}`).hostname.toLowerCase().replace(/\.$/,"")||null}catch{return null}}function nO($){try{let Z=new URL(`http://${$.trim()}`),J=Z.hostname.toLowerCase().replace(/\.$/,"");return J?Z.port?`${J}:${Z.port}`:J:null}catch{return null}}function cG($){if($===void 0)return[];if($===!0)return!0;if(!Array.isArray($))throw Error(`\`route.domains.devHosts\` must be a list of hostnames (or \`true\`). Got ${JSON.stringify($)}.`);return $.map((Z,J)=>{let W=typeof Z==="string"?Z.trim().toLowerCase():"",Y=W.startsWith(".")?W.slice(1):W;if(!Y||!Y.split(".").every((j)=>z8.test(j)))throw Error(`\`route.domains.devHosts[${J}]\` must be a bare hostname, e.g. "app.acme.test", or ".acme.test" for the domain and its subdomains \u2014 no scheme, port, path or "*". Got ${JSON.stringify(Z)}.`);return W})}function oO($){let Z=_1($.root),J=$.root?.trim().toLowerCase().replace(/\.$/,"");if(!Z||Z!==J||!Z.split(".").every((j)=>z8.test(j)))throw Error(`\`route.domains.root\` must be a bare hostname, e.g. "example.com" \u2014 no scheme, port or path. Got "${$.root}".`);if($.custom&&($.custom.cacheTtlMs??0)<0)throw Error(`\`route.domains.custom.cacheTtlMs\` is ${$.custom.cacheTtlMs}; it cannot be negative. Use 0 to disable the cache.`);if($.ask&&$.ask.secret.length<X8)throw Error(`\`route.domains.ask.secret\` must be at least ${X8} characters. A guessable one is worse than leaving \`ask\` out.`);sO($.trustProxy),cG($.devHosts);let W=new Set,Y=null;for(let j of $.groups??[]){let{subdomain:z}=j;if(W.has(z))throw Error(`\`route.domains\` declares the subdomain "${z}" twice.`);if(W.add(z),pG(z)){if(!/^:[A-Za-z_][A-Za-z0-9_]*$/.test(z))throw Error(`"${z}" is not a valid param subdomain. It must be a single \`:name\` label.`);if(Y)throw Error(`\`route.domains\` declares two param subdomains, "${Y.subdomain}" and "${z}"; a host could match either.`);Y=j;continue}if(j.exists)throw Error(`The subdomain "${z}" is fixed, so \`exists\` has no param to check. It only applies to a \`:param\` subdomain.`);if(!z.split(".").every((X)=>z8.test(X)))throw Error(`"${z}" is not a valid subdomain.`)}if($.custom&&!W.has($.custom.group))throw Error(`\`route.domains.custom.group\` is "${$.custom.group}", but no group declares that subdomain.`);if($.ask&&Y&&!Y.exists)throw Error(`\`route.domains.ask\` is set, so "${Y.subdomain}" needs an \`exists\` to say which tenants are real. Without one every host under the root would be approved for a certificate.`)}class mY{root;devHosts;hostTrusts;fixed=new Map;param=null;custom;cacheTtlMs;cache=new Map;inFlight=new Map;askSecret;proxySecretHeaders;constructor($){oO($),this.root=_1($.root),this.devHosts=cG($.devHosts),this.hostTrusts=iO($.trustProxy);for(let Z of $.groups??[])if(pG(Z.subdomain))this.param={...Z,name:Z.subdomain.slice(1)};else this.fixed.set(Z.subdomain.toLowerCase(),Z);this.custom=$.custom??null,this.cacheTtlMs=this.custom?.cacheTtlMs??uO,this.askSecret=$.ask?.secret??null,this.proxySecretHeaders=Array.from(new Set(this.hostTrusts.flatMap((Z)=>Z.secret?[Z.secret.header]:[])))}trustOf($){let Z=null;for(let J of this.hostTrusts)if((!J.secret||$6($.headers.get(J.secret.header),J.secret.value))&&!Z)Z=J;return Z}forwardedHost($){let Z=this.trustOf($)?.header;if(!Z)return null;return $.headers.get(Z)?.split(",")[0]?.trim()||null}trustedClientIp($){let Z=this.trustOf($);if(!Z?.clientIpHeader||!Z.secret)return null;let J=$.headers.get(Z.clientIpHeader)?.split(",")[0];return J===void 0?null:k$(J)}applyClientIp($){let Z=this.trustedClientIp($);if(!Z)return;$.headers.set("x-forwarded-for",Z),$.headers.delete("x-real-ip")}hostOf($){return _1(this.forwardedHost($))??_1(new URL($.url).host)}publicOrigin($){let Z=new URL($.url),J=$.headers.get("x-forwarded-proto")?.split(",")[0]?.trim(),W=J==="http"||J==="https"?J:Z.protocol.replace(/:$/,""),Y=this.forwardedHost($),j=Y&&_1(Y)?nO(Y):null;return`${W}://${j??Z.host}`}async resolve($){let Z=this.hostOf($);if(!Z)return null;let J=await this.match(Z,$);if(J)return J;if(this.custom?.fallback&&!this.isUnderRoot(Z))return{host:Z,group:gY,params:{},custom:!0};return null}async allows($,Z){let J=_1($);return J?await this.match(J,Z)!==null:!1}isUnderRoot($){return $===this.root||$.endsWith(`.${this.root}`)}async match($,Z){if($===this.root)return{host:$,group:Q8,params:{},custom:!1};if($.endsWith(`.${this.root}`)){let W=$.slice(0,-(this.root.length+1)),Y=this.fixed.get(W);if(Y)return{host:$,group:Y.subdomain,params:{},custom:!1};if(this.param&&z8.test(W)){let j={[this.param.name]:W};if(this.param.exists&&!await this.param.exists(j,Z))return null;return{host:$,group:this.param.subdomain,params:j,custom:!1}}return null}if(!this.custom)return null;let J=await this.resolveCustom($);return J?{host:$,group:this.custom.group,params:J,custom:!0}:null}async resolveCustom($){let Z=Date.now(),J=this.cache.get($);if(J&&J.expiresAt>Z)return this.cache.delete($),this.cache.set($,J),J.value;let W=this.inFlight.get($);if(W)return W;let Y=(async()=>await this.custom.resolve($)??null)();this.inFlight.set($,Y);let j;try{j=await Y}finally{this.inFlight.delete($)}if(this.cacheTtlMs>0){if(this.cache.size>=lO)this.cache.delete(this.cache.keys().next().value);this.cache.delete($),this.cache.set($,{value:j,expiresAt:Date.now()+this.cacheTtlMs})}return j}forget($){if($===void 0)this.cache.clear();else{let Z=_1($);if(Z)this.cache.delete(Z)}}}var aO={kind:"none"};function QC($){let Z=($??"").trim().toLowerCase();if(Z===""||Z==="false"||Z==="off"||Z==="0")return aO;if(Z==="true")return{kind:"all"};if(/^[1-9]\d*$/.test(Z))return{kind:"hops",hops:Number(Z)};throw Error(`GEMI_TRUST_PROXY must be "false", "true" or the number of proxies in front of the app (e.g. 1). Got ${JSON.stringify($)}.`)}function GC($,Z,J){if(J.kind==="all"){if(!$.get("x-forwarded-for")&&Z)$.set("x-forwarded-for",Z);return}$.delete("x-real-ip");let W=Z;if(J.kind==="hops"){let Y=($.get("x-forwarded-for")??"").split(",").map((X)=>X.trim()).filter(Boolean),j=Y.length-J.hops,z=j>=0?Y[j]:Y[0];W=(z===void 0?null:k$(z))??Z}if(W)$.set("x-forwarded-for",W);else $.delete("x-forwarded-for")}var dG=/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/,uG=16;function KC($){let Z=$.GEMI_CLIENT_IP_HEADER?.trim()??"",J=$.GEMI_PROXY_SECRET_HEADER?.trim()??"",W=$.GEMI_PROXY_SECRET??"";if(Z===""&&J===""&&W==="")return null;if(Z===""||J===""||W==="")throw Error("GEMI_CLIENT_IP_HEADER, GEMI_PROXY_SECRET_HEADER and GEMI_PROXY_SECRET go together: the client-IP header is only believed on a request that carries the proxy's secret. Set all three, or none.");if(!dG.test(Z))throw Error(`GEMI_CLIENT_IP_HEADER must be a single header name, e.g. "x-azure-clientip". Got ${JSON.stringify(Z)}.`);if(!dG.test(J))throw Error(`GEMI_PROXY_SECRET_HEADER must be a single header name, e.g. "x-azure-fdid". Got ${JSON.stringify(J)}.`);if(Z.toLowerCase()===J.toLowerCase())throw Error("GEMI_CLIENT_IP_HEADER and GEMI_PROXY_SECRET_HEADER name the same header.");if(W.length<uG)throw Error(`GEMI_PROXY_SECRET must be at least ${uG} characters. A guessable one lets any client name its own address.`);return{header:Z.toLowerCase(),secretHeader:J.toLowerCase(),secret:W}}function lG($,Z){if(!$6($.get(Z.secretHeader),Z.secret))return null;let J=$.get(Z.header)?.split(",")[0];return J===void 0?null:k$(J)}var rO="/__gemi__/domains/ask";class Q1{static token="router.domains";resolver;acceptsCustomDomains;clientIpTrust;groups=new Map;staticFilesVary=!1;constructor($,Z){this.groups.set(Q8,$),this.clientIpTrust=Z.clientIpTrust??null;let{domains:J}=Z;if(this.acceptsCustomDomains=Boolean(J?.custom),!J){this.resolver=null;return}this.resolver=new mY(J);let W=(Y)=>({api:Y.api?new j8({...Z.api,...Y.api}):$.api,view:Y.view?new e3({...Z.view,...Y.view},Z.auth):$.view});for(let Y of J.groups??[])this.groups.set(Y.subdomain,W(Y));if(J.custom?.fallback)this.groups.set(gY,W(J.custom.fallback));this.staticFilesVary=this.viewDispatchers().some((Y)=>Y.publicFiles!==$.view.publicFiles||Y.assetRoutes!==$.view.assetRoutes)}async staticFiles($){let Z=(this.staticFilesVary?await this.route($):null)?.view??this.dispatchers(null).view;return{publicFiles:Z.publicFiles,assetRoutes:Z.assetRoutes}}applyClientIp($){let Z=this.clientIpTrust;if(Z)hY($,Z.secretHeader);let J=this.resolver?.trustedClientIp($)??(Z?lG($.headers,Z):null);if(!J)return;$.headers.set("x-forwarded-for",J),$.headers.delete("x-real-ip")}async route($){if(!this.resolver)return this.dispatchers(null);for(let J of this.resolver.proxySecretHeaders)hY($,J);let Z=Z8($)??await this.resolver.resolve($);if(!Z)return null;return Z3($,Z),this.dispatchers(Z)}async ask($){if(!this.resolver?.askSecret||$.method!=="GET")return null;let Z=new URL($.url);if(Z.pathname!==rO)return null;if(!$6(Z.searchParams.get("secret"),this.resolver.askSecret))return null;let J=Z.searchParams.get("domain"),W=J?await this.resolver.allows(J,$):!1;return new Response(null,{status:W?200:404})}dispatchers($){return this.groups.get($?.group??Q8)}viewDispatchers(){return Array.from(new Set(Array.from(this.groups.values(),($)=>$.view)))}viewGroups(){let $=new Set,Z=[];for(let[J,W]of this.groups){if($.has(W.view))continue;$.add(W.view),Z.push({group:J,view:W.view})}return Z}}function J3($){let Z=new Date($??0).getTime();return Number.isFinite(Z)?Z:0}var iG=600000;function sG($,Z){return[T6($,Z),T6($,Z-1)]}class E{static token="auth";config;provider;constructor($={},Z=new G7){fj($.oauthProviders),this.config={...P1(wj($),$),emailCode:W7($.emailCode),passwordLimits:J7($.passwordLimits)},this.provider=Z}async oauthProvider($){return await TZ(this.config.oauthProviders,$)}async oauthProviderNames(){return await oj(this.config.oauthProviders)}get userProvider(){return this.provider}accessTokenCookieOptions($,Z){return{expires:Z,secure:this.publicOrigin($).startsWith("https://"),httpOnly:!0,domain:this.cookieDomain($)}}publicOrigin($){let Z=M().bound(Q1)?M(Q1).resolver:null;return Z?Z.publicOrigin($.rawRequest):new URL($.rawRequest.url).origin}cookieDomain($){let Z=this.config.cookieDomain;if(!Z)return;let J=Z==="root"?M(Q1).resolver?.root:_1(Z);if(!J)throw Error('`auth.cookieDomain` is "root", but `route.domains` is not configured.');let W=$.domain?.host??_1(new URL($.rawRequest.url).host);return W===J||W?.endsWith(`.${J}`)?J:void 0}async getSession($,Z){if(!$)return null;if(!n8($))return this.config.migrateLegacySession?this.convertLegacySession($,Z,this.config.migrateLegacySession):null;let J=await this.userProvider.findSession({token:$,userAgent:Z});if(!J?.user)return null;let W=Date.now(),Y=J3(J.expiresAt),j=J3(J.absoluteExpiresAt);if(Y<=W||j<=W)return await this.userProvider.deleteSession({token:$}),null;let X=await this.slideSession(J,W);return X.user.extension=await this.config.extendSession(X.user),X}async convertLegacySession($,Z,J){let W=T.getStore()?.req;if(!W)return null;let Y=Date.now(),j=Math.floor(Y/iG),z=null,X=await this.userProvider.findSession({token:$,userAgent:Z});if(X?.user){if(!await J(X,{token:$,req:W,userAgent:Z}))return null;let G=T6($,j),B=X.user.id;if(await this.userProvider.withLegacySessionLock($,async()=>{if(!await this.userProvider.claimLegacySession({token:$}))return!1;return await this.userProvider.createSessionV2({token:G,userId:B,userAgent:Z,...this.freshLifetime(Y)}),!0}))z=G}if(!z){for(let G of sG($,j))if((await this.userProvider.findSession({token:G,userAgent:Z}))?.user){z=G;break}}if(!z)return null;let Q=await this.getSession(z,Z);if(Q)W.ctx().setCookie("access_token",z,this.accessTokenCookieOptions(W,new Date(Q.expiresAt)));return Q}async revokeSession($,Z){if(!$)return await this.userProvider.deleteSession({token:$}),null;if(n8($)||!this.config.migrateLegacySession){let Y=await this.userProvider.findSession({token:$,userAgent:Z});return await this.userProvider.deleteSession({token:$}),Y}let J=Math.floor(Date.now()/iG),W=sG($,J);return this.userProvider.withLegacySessionLock($,async()=>{let Y=await this.userProvider.findSession({token:$,userAgent:Z});for(let j of W){if(Y?.user)break;Y=await this.userProvider.findSession({token:j,userAgent:Z})}await this.userProvider.deleteSession({token:$});for(let j of W)await this.userProvider.deleteSession({token:j});return Y})}requestCarryingCookie($){let Z=T.getStore()?.req;return Z?.cookies.get("access_token")===$?Z:null}async slideSession($,Z){let J=this.config.sessionExpiresInHours*3600000;if(new Date($.expiresAt).getTime()-Z>=J/2)return $;let W=new Date(Math.min(Z+J,new Date($.absoluteExpiresAt).getTime())),Y=await this.userProvider.updateSession({token:$.token,expiresAt:W}),j=this.requestCarryingCookie($.token);if(j)j.ctx().setCookie("access_token",$.token,this.accessTokenCookieOptions(j,W));if(!Y)return $;return{...$,expiresAt:Y.expiresAt??W}}freshLifetime($){return{expiresAt:new Date($+this.config.sessionExpiresInHours*3600000),absoluteExpiresAt:new Date($+this.config.sessionAbsoluteExpiresInHours*3600000)}}async generateMagicLink($){}async upsertSession($){await this.userProvider.findSession({token:"",userAgent:""})}async authenticate($){try{let Z=await this.userProvider.findUserByEmailAddress($,!1);if(!Z)throw Error(`User not found with email: ${$}`);let J=await this.createOrUpdateSession({email:$,id:Z.id}),W=new C;if(W.ctx().setCookie("access_token",J.token,this.accessTokenCookieOptions(W,J.expiresAt)),J?.user)J.user.extension=await this.config.extendSession(J.user);return J}catch(Z){console.log(Z)}}async createOrUpdateSessionV2($){let Z=await this.createOrUpdateSession($),J=null;if(Z?.user)J=await this.config.extendSession(Z.user),Z.user.extension=J;return Z}async createOrUpdateSession($){let Z=new C,J=$.id??(await this.userProvider.findUserByEmailAddress($.email,!1))?.id;if(!J)throw new R$;let W=Bun.env.NODE_ENV==="development"?"local":Z.headers.get("User-Agent"),Y=Nj(J),j=await this.userProvider.createSessionV2({token:Y,userId:J,userAgent:W,...this.freshLifetime(Date.now())}),z=null;try{z=await this.userProvider.findSession({token:Y,userAgent:W??""})}catch(X){console.error("Reading the new session back failed:",X)}return z?.user?z:j}async createMagicLinkToken($){let Z=await this.userProvider.findUserByEmailAddress($,!1);if(Z){let{pin:J,token:W}=await this.issueOneTimeCode($,6);return{user:Z,email:$,pin:J,token:W}}return{}}async issueOneTimeCode($,Z){let{activeCodes:J,expiresInMinutes:W,linkExpiresInMinutes:Y}=this.config.emailCode,j=await this.config.generateMagicLinkToken($),z=await this.config.generateCode($),X=typeof z==="string"&&z!==""?z:Sj(Z),Q=P6("link",$,j),G=P6("pin",$,X);if(J===1)await this.userProvider.deleteMagicLinkToken($);else{let B=Math.max(W,Y)*60000,K=(await this.userProvider.listMagicLinkTokensByEmail($,J-1)).filter((F)=>J3(F.createdAt)+B>Date.now()&&F.pin!==G&&F.token!==Q);await this.userProvider.deleteMagicLinkTokensExcept($,K.map((F)=>F.id))}return await this.userProvider.createMagicLinkToken({email:$,token:Q,pin:G}),{email:$,pin:X,token:j}}async oneTimeCodeRows($){let{activeCodes:Z}=this.config.emailCode;if(Z===1){let J=await this.userProvider.findMagicLinkTokenByEmail($);return J?[J]:[]}return await this.userProvider.listMagicLinkTokensByEmail($,Z)}async claimOneTimeCode($,Z){if(!await this.userProvider.claimMagicLinkToken(Z))return!1;if(this.config.emailCode.activeCodes>1)await this.userProvider.deleteMagicLinkToken($);return!0}async verifyOneTimeCode($,Z,J={}){let{expiresInMinutes:W,maxAttempts:Y}=this.config.emailCode,j=await this.oneTimeCodeRows($);if(j.length===0)return HZ("pin",$,null,Z),{status:"invalid"};let z=j.filter((G)=>J3(G.createdAt)+W*60000>Date.now());if(z.length===0)return HZ("pin",$,null,Z),{status:"expired"};let X=!0;for(let G of z)if(!await Rj(G.id,J3(G.createdAt),Y,W))X=!1;if(!X){if(this.config.emailCode.activeCodes===1)await this.userProvider.claimMagicLinkToken(z[0].id);else await this.userProvider.deleteMagicLinkToken($);return{status:"too_many_attempts"}}let Q=null;for(let G of z)if(HZ("pin",$,G.pin,Z))Q??=G;if(!Q)return{status:"invalid"};if(J.claim!==!1&&!await this.claimOneTimeCode($,Q.id))return{status:"invalid"};return{status:"ok",row:Q}}async verifyMagicLinkToken($,Z){let J=await this.oneTimeCodeRows($);if(J.length===0)return HZ("link",$,void 0,Z),!1;let W=null;for(let j of J)if(HZ("link",$,j.token,Z))W??=j;if(!W)return!1;if(J3(W.createdAt)+this.config.emailCode.linkExpiresInMinutes*60000<=Date.now())return!1;return await this.claimOneTimeCode($,W.id)}}class q0 extends m{static getFacadeAccessor(){return E}static async user(){let $=await q0.userOrNull();if($)return $;throw new R$({redirectTo:V6(T.getStore()?.req,this.getFacadeRoot().config.signInPath)})}static async userOrNull(){let $=T.getStore();if($?.user)return $.user;let Z=await X6(this.getFacadeRoot(),$?.req);if(Z)$?.setUser(Z);return Z}static intendedUrl($){let Z=T.getStore()?.req;return V1(Z?.search.get(B1),$??this.getFacadeRoot().config.redirectPath)}static async guard($){let Z=await q0.user();if(!await $(Z))throw new OZ}static async guardSafe($){let Z=await q0.user();try{return await $(Z)}catch(J){return!1}}static async authenticate($){return await this.getFacadeRoot().authenticate($)}static async oauthProviders(){return await this.getFacadeRoot().oauthProviderNames()}static async createMagicLink($){return await this.getFacadeRoot().createMagicLinkToken($)}}class G8{static ensure($,Z={}){let J=T.getStore();if(J.req.kind==="api")throw Error("Query.prefetch() cannot be called from an API request");return J.serverQueries??=new tZ(a3(J.req.rawRequest)),J.serverQueries.ensure($,Z,"prefetch")}static async instant($,...Z){let J=G8.ensure($,Z[0]);if(await J.promise,J.status==="rejected")throw J.error;return J.data}static prefetch($,...Z){G8.ensure($,Z[0])}static noPrefetch(){let $=T.getStore();if($.req.kind==="api")throw Error("Query.noPrefetch() cannot be called from an API request");$.serverQueries??=new tZ(a3($.req.rawRequest)),$.serverQueries.muteDiscoveryHints()}}function tO($){return(Array.isArray($)?$:String($).split("/")).map((J)=>encodeURIComponent(String(J))).join("/")}function pY($,Z={}){let J=$.replace(/\/:(\w+)([*?]?)/g,(W,Y,j)=>{let z=Object.hasOwn(Z,Y)?Z[Y]:void 0;if(z===void 0||z===""){if(j)return"";throw Error(`\`${$}\` needs a value for :${Y}.`)}return`/${j==="*"?tO(z):encodeURIComponent(String(z))}`});return`${K8}${J==="/"?"":J}`||K8}var nG=new Map;function oG($,Z){let J=nG.get($);if(!J)J=new URLPattern({pathname:`${K8}${$==="/"?"":$}`}),nG.set($,J);let W;try{W=new URL(Z,"http://localhost").pathname}catch{return null}let Y=J.exec({pathname:W})?.pathname.groups;if(!Y)return null;let j={};for(let[z,X]of Object.entries(Y)){if(X===void 0)continue;try{j[z]=decodeURIComponent(X)}catch{return null}}return j}function aG($,Z,J="/"){let W=new URL($.origin),Y=Z.host?Z.host:Z.subdomain?`${Z.subdomain}.${$.root}`:$.root,j=new URL(J.startsWith("/")?J:`/${J}`,W),z=eO(Y);if(!z)throw Error(`"${Y}" is not a hostname, so there is no URL for it. Give a bare host, optionally with a port \u2014 no scheme, path or credentials.`);if(j.hostname=z.hostname,z.port)j.port=z.port;return j.toString()}function eO($){try{let Z=new URL(`http://${$.trim()}`);return Z.host===$.trim().toLowerCase()&&Z.pathname==="/"?{hostname:Z.hostname,port:Z.port}:null}catch{return null}}class rG{static origin($){return cY($)}static absolute($,...Z){return`${ZZ()}${U0(String($),Z[0]??{})}`}static relative($,...Z){return U0(String($),Z[0]??{})}static forDomain($,Z,...J){let W=M(Q1).resolver;if(!W)throw Error("`Url.forDomain` needs `route.domains` to be configured.");let Y=T.getStore()?.req?.rawRequest,j=Y?W.publicOrigin(Y):ZZ();if(!j)throw Error("`Url.forDomain` outside a request needs `HOST_NAME` (or `APP_URL`) for the protocol.");return aG({root:W.root,origin:j},$,U0(String(Z),J[0]??{}))}static api($,...Z){return pY(String($),Z[0]??{})}static apiAbsolute($,...Z){return`${cY()}${pY(String($),Z[0]??{})}`}static matchApi($,Z){return oG(String($),Z)}}class tG{name="Meta";static description($){T.getStore().metadata.description($)}static title($){T.getStore().metadata.title($)}static openGraph($){T.getStore().metadata.openGraph($)}static htmlAttributes($){T.getStore().metadata.htmlAttributes($)}static canonical($){T.getStore().metadata.canonical($)}static alternates($){T.getStore().metadata.alternates($)}static tags($){T.getStore().metadata.tags($)}static robots($){T.getStore().metadata.robots($)}static translate($=!0){T.getStore().metadata.translate($)}static fonts($){T.getStore().metadata.fonts($)}}var $L={set($,Z,J){T.getStore().setCookie($,Z,J)},setIfAbsent($,Z,J){if(T.getStore().req.cookies.has($))return!1;return T.getStore().setCookie($,Z,J),!0},delete($,Z){T.getStore().deleteCookie($,Z)}};class i1 extends m{static getFacadeAccessor(){return jZ}static get client(){return this.getFacadeRoot().client}static get($){return i1.client.get($)}static set($,Z){return i1.client.set($,Z)}static del(...$){return i1.client.del(...$)}static exists($){return i1.client.exists($)}static incr($){return i1.client.incr($)}static expire($,Z){return i1.client.expire($,Z)}static ttl($){return i1.client.ttl($)}}function XA($){return $}function eG(){return{store:"memory",ttl:null}}class dY{entries=new Map;maxEntries;now;constructor($={}){let Z=$.maxEntries??1e4;if(!Number.isInteger(Z)||Z<1)throw TypeError(`MemoryCacheStore maxEntries is a whole number of 1 or more; got ${Z}.`);this.maxEntries=Z,this.now=$.now??Date.now}get size(){return this.entries.size}async get($){let Z=this.live($);if(!Z)return null;return this.entries.delete($),this.entries.set($,Z),Z.value}async set($,Z,J){this.entries.delete($),this.entries.set($,{value:Z,expiresAt:J===null?null:this.now()+J});while(this.entries.size>this.maxEntries)this.entries.delete(this.entries.keys().next().value)}async delete($){let Z=this.live($)!==void 0;return this.entries.delete($),Z}async flush(){this.entries.clear()}live($){let Z=this.entries.get($);if(!Z)return;if(Z.expiresAt!==null&&Z.expiresAt<=this.now()){this.entries.delete($);return}return Z}}var ZL="500";class uY{prefix;injectedClient;constructor($={}){this.injectedClient=$.client,this.prefix=$.prefix??"gemi:cache:"}async get($){let Z=await this.client.send("GET",[this.prefix+$]);return Z===null||Z===void 0?null:String(Z)}async set($,Z,J){let W=[this.prefix+$,Z];if(J!==null)W.push("PX",String(Math.max(1,Math.round(J))));await this.client.send("SET",W)}async delete($){return Number(await this.client.send("DEL",[this.prefix+$]))>0}async flush(){if(this.prefix==="")throw Error("RedisCacheStore refuses to flush with an empty prefix: that would delete every key in the database.");let $=this.client,Z=`${JL(this.prefix)}*`,J="0";do{let W=await $.send("SCAN",[J,"MATCH",Z,"COUNT",ZL]),[Y,j]=Array.isArray(W)?W:["0",[]];if(J=String(Y),Array.isArray(j)&&j.length>0)await $.send("UNLINK",j.map(String))}while(J!=="0")}get client(){if(this.injectedClient)return this.injectedClient;let $=M(),Z=$.bound(jZ)?$.make(jZ).client:void 0;if(!Z)throw Error("RedisCacheStore could not reach the Redis client. Register RedisServiceProvider on your application, or pass a client: new RedisCacheStore({ client }).");return Z}}function JL($){return $.replace(/[*?[\]\\^-]/g,(Z)=>`\\${Z}`)}var WL="k:",$K="tag:",YL="t:";class lY{async get($){let Z=await this.manager.read(await this.storeKey($));return Z.found?Z.value:void 0}async has($){return(await this.manager.read(await this.storeKey($))).found}async set($,Z,J){await this.manager.write(await this.storeKey($),Z,J)}async delete($){return this.manager.store.delete(await this.storeKey($))}async pull($){let Z=await this.storeKey($),J=await this.manager.read(Z);if(!J.found)return;return await this.manager.store.delete(Z),J.value}async remember($,Z,J){let[W,Y]=typeof Z==="function"?[void 0,Z]:[Z,J];if(typeof Y!=="function")throw TypeError("Cache.remember needs a function that computes the value.");return this.manager.rememberAt(await this.storeKey($),W,Y)}}class iY extends lY{options;static token="cache";config;builtStore;inflight=new Map;constructor($={},Z={}){super();this.options=Z;if(this.config=P1(eG(),$),this.config.ttl!==null&&this.config.ttl!==void 0)zZ(this.config.ttl)}get manager(){return this}get store(){return this.builtStore??=this.buildStore()}tags(...$){let Z=[...new Set($.flat())].sort();if(Z.length===0)throw TypeError("Cache.tags needs at least one tag.");for(let J of Z)if(typeof J!=="string"||J==="")throw TypeError(`A cache tag is a non-empty string; got ${JSON.stringify(J)}.`);return new JK(this,Z)}async flush(){await this.store.flush()}async storeKey($){return WL+WK($)}async read($){let Z=await this.store.get($);if(Z===null)return{found:!1};try{return{found:!0,value:JSON.parse(Z)}}catch{return{found:!1}}}async write($,Z,J){if(Z===void 0)throw TypeError("Cache.set cannot store undefined: get() returns undefined for a miss. Store null instead.");let W=this.ttlMs(J);if(W===0){await this.store.delete($);return}let Y=JSON.stringify(Z);if(Y===void 0)throw TypeError(`Cache.set cannot store a ${typeof Z}: it has no JSON form.`);await this.store.set($,Y,W)}async rememberAt($,Z,J){let W=await this.read($);if(W.found)return W.value;let Y=this.inflight.get($);if(Y)return Y;let j=(async()=>{try{let z=await J();if(z!==void 0)await this.write($,z,Z);return z}finally{this.inflight.delete($)}})();return this.inflight.set($,j),j}async tagVersions($){return Promise.all($.map(async(Z)=>{let J=$K+Z,W=await this.store.get(J);if(W!==null)return W;let Y=ZK();return await this.store.set(J,Y,null),Y}))}async flushTags($){await Promise.all($.map((Z)=>this.store.set($K+Z,ZK(),null)))}ttlMs($){let Z=$===void 0?this.config.ttl:$;return Z===null||Z===void 0?null:zZ(Z)}buildStore(){let{store:$}=this.config;if($===void 0||$==="memory")return new dY(this.config.memory);if($==="redis"){let Z=this.options.application;return new uY({...this.config.redis,client:Z?{send:(J,W)=>Z.make(jZ).client.send(J,W)}:void 0})}if(typeof $==="function"){let Z=this.options.application;if(!Z)throw Error("A cache store factory needs the application: build CacheManager with { application }.");return $(Z)}if($&&typeof $==="object")return $;throw Error(`Unknown cache store ${JSON.stringify($)} in app/config/cache.ts: use "memory", "redis", a CacheStore, or a function returning one.`)}}class JK extends lY{manager;tagNames;constructor($,Z){super();this.manager=$;this.tagNames=Z}async flush(){await this.manager.flushTags([...this.tagNames])}async storeKey($){WK($);let Z=await this.manager.tagVersions([...this.tagNames]);return`${YL}${Z.join(",")}:${$}`}}function WK($){if(typeof $!=="string"||$==="")throw TypeError(`A cache key is a non-empty string; got ${JSON.stringify($)}.`);return $}function ZK(){let $=new Uint8Array(9);return crypto.getRandomValues($),Array.from($,(Z)=>Z.toString(16).padStart(2,"0")).join("")}class YK extends m{static getFacadeAccessor(){return iY}static get($){return this.getFacadeRoot().get($)}static has($){return this.getFacadeRoot().has($)}static set($,Z,J){return this.getFacadeRoot().set($,Z,J)}static delete($){return this.getFacadeRoot().delete($)}static pull($){return this.getFacadeRoot().pull($)}static remember($,Z,J){let W=this.getFacadeRoot();return typeof Z==="function"?W.remember($,Z):W.remember($,Z,J)}static tags(...$){return this.getFacadeRoot().tags(...$)}static flush(){return this.getFacadeRoot().flush()}}class jK extends m{static getFacadeAccessor(){return F1}static consume($,Z={}){return this.getFacadeRoot().consume($,Z)}static enforce($,Z={},J){return this.getFacadeRoot().enforce($,Z,J)}}class XK extends m{static getFacadeAccessor(){return zK}static run($,Z,J){return this.getFacadeRoot().run($,Z,J)}static acquire($,Z={}){return this.getFacadeRoot().acquire($,Z)}}class GK extends m{static getFacadeAccessor(){return QK}static encrypt($){return this.getFacadeRoot().encrypt($)}static decrypt($){return this.getFacadeRoot().decrypt($)}static needsReencryption($){return this.getFacadeRoot().needsReencryption($)}}class KK extends m{static getFacadeAccessor(){return n3}static for($,Z,J){return this.getFacadeRoot().for($,Z,J)}static list($,Z){return this.getFacadeRoot().list($,Z)}static save($,Z,J){return this.getFacadeRoot().save($,Z,J)}static fake($={}){return this.getFacadeRoot().fake($)}static restore(){this.getFacadeRoot().restore()}}function qA($){return $}function BK(){return{driver:"memory",pollInterval:30000,maxSubscriptions:1e4,batchSize:100,keepaliveInterval:5000}}function B8($){let Z=new URLSearchParams;for(let[J,W]of $)Z.append(J,String(W));return Z.toString()}function sY($){let Z=new Map;if(!$)return Z;let J;try{J=new URLSearchParams($)}catch{return Z}for(let[W,Y]of J){let j=Number(Y);if(Y!==""&&Number.isSafeInteger(j)&&j>=0)Z.set(W,j)}return Z}var{SQL:jL}=globalThis.Bun;function zL(){return Bun.semver.satisfies(Bun.version,">=1.4.0")}var XL=async($)=>{let Z=new jL($,{max:1,idleTimeout:0,maxLifetime:0});return{listen:(J,W,Y)=>Z.listen(J,W,Y),close:()=>Z.close({timeout:1})}},QL=async($)=>{let Z;try{Z=(await import("./chunk-gtdf51jz.js")).default}catch(W){throw Error("The change feed's database driver needs a Postgres client that can LISTEN: Bun 1.4 or later, or the `postgres` package (bun add postgres).",{cause:W})}let J=Z($,{max:1,idle_timeout:0,max_lifetime:null,fetch_types:!1,onnotice:()=>{}});return{listen:(W,Y,j)=>J.listen(W,Y,j),close:()=>J.end({timeout:1}).catch(()=>{})}},VK=($)=>zL()?XL($):QL($);var GL=/^[A-Za-z_][A-Za-z0-9_]*$/;class nY{headsTable;entriesTable;notifyChannel;sql;dialect;connection;url;retain;listener;sqliteTurn=Promise.resolve();constructor($,Z={}){if($.dialect!=="postgres"&&$.dialect!=="sqlite")throw Error(`The change feed's database driver supports Postgres and SQLite, not ${$.dialect}.`);let J=Z.headsTable??"gemi_change_heads",W=Z.entriesTable??"gemi_changes",Y=Z.notifyChannel??"gemi_changes";for(let z of[J,W,Y])if(!GL.test(z))throw Error(`"${z}" is not a plain identifier. Use letters, digits and underscores.`);let j=Z.retain??1000;if(!Number.isInteger(j)||j<1)throw Error(`The change feed's retain must be a whole number, 1 or more; got ${j}.`);this.headsTable=J,this.entriesTable=W,this.notifyChannel=Y,this.sql=$.sql,this.dialect=$.dialect,this.connection=$.name,this.url=$.url,this.retain=j,this.listener=Z.listener??VK}async createTable(){for(let $ of KL(this.headsTable,this.entriesTable))await this.sql.unsafe($)}joinsTransaction(){return this.transaction()!==void 0}publish($,Z){let J=this.transaction();if(!J){let Y=()=>this.sql.begin((z)=>this.append(z,$,Z));if(this.dialect!=="sqlite")return Y();let j=this.sqliteTurn.then(Y);return this.sqliteTurn=j.catch(()=>{}),j}let W=this.append(J,$,Z);return FK(W),W}async append($,Z,J){let W=$.unsafe(`"${this.headsTable}"`),Y=$.unsafe(`"${this.entriesTable}"`),[j]=await $`
|
|
24
24
|
INSERT INTO ${W} (channel, seq) VALUES (${Z}, 1)
|
|
@@ -114,4 +114,4 @@ data: ${JSON.stringify(Z)}
|
|
|
114
114
|
"deadline_at" BIGINT${W}
|
|
115
115
|
)`,`CREATE INDEX IF NOT EXISTS "${Z}_subject_created_at_idx" ON "${Z}"("subject", "created_at")`,`CREATE INDEX IF NOT EXISTS "${Z}_status_deadline_at_idx" ON "${Z}"("status", "deadline_at")`]}var SK=191,EK=30000;class O8 extends Error{id;constructor($){super(`No run has the id ${$}.`);this.id=$;this.name="RunNotFoundError"}}class L8 extends Error{code;data;constructor($,Z={}){super($,Z.cause===void 0?void 0:{cause:Z.cause});this.name="RunFailure",this.code=Z.code,this.data=Z.data}}class X5{options;static token="runs";store;config;ownFeed=null;constructor($={},Z={}){this.options=Z;this.config=P1(xK(),$),this.store=ML(this.config.store,Z.application)}get feed(){if(this.options.feed)return this.options.feed;if(this.options.application)return this.options.application.make(W3);return this.ownFeed??=new W3,this.ownFeed}channel($){return`gemi:run:${$}`}async create($){kK("kind",$.kind);let Z=$.id??`run_${crypto.randomUUID().replaceAll("-","")}`;kK("id",Z);let J=await this.store.create({id:Z,kind:$.kind,subject:$.subject??null,owner:$.owner??null,meta:$.meta??null,status:$.start?"running":"pending",deadlineMs:$.deadline===void 0||$.deadline===null?null:zZ($.deadline)});return await this.publish(J),J}async get($){return await this.store.get($)}list($={}){return this.store.list($)}start($){return this.change($,["pending"],{status:"running"})}async progress($,Z){return LL(Z),this.change($,I1,{status:"running",progress:Z})}complete($,Z){return this.change($,I1,{status:"completed",result:Z===void 0?null:Z})}fail($,Z){return this.change($,I1,{status:"failed",error:RK(Z)})}cancel($,Z){return this.change($,I1,{status:"cancelled",error:{message:Z??"The run was cancelled.",code:"cancelled"}})}async execute($,Z){let J=this.feed.subscribe(this.channel($));try{await J.ready();let W=await this.start($)??await this.store.get($);if(!W)throw new O8($);if(x1(W.status))return W;let Y=new AbortController,j=this.watch($,W,J,Y),z={id:$,record:W,signal:Y.signal,progress:async(Q)=>{if(Y.signal.aborted)return;await this.progress($,Q)}},X;try{let Q=await Z(z);X=await this.complete($,Q)}catch(Q){if(!(Q instanceof L8)&&!Y.signal.aborted)console.error(`[gemi] Run ${$} failed.`,Q);X=await this.change($,I1,{status:"failed",error:Q instanceof L8?RK(Q):{message:"The run failed.",code:"error"}})}finally{Y.abort(),J.close(),await j}return X??await this.store.get($)??W}finally{J.close()}}async wait($,Z={}){let{signal:J}=Z;J?.throwIfAborted();let W=Z.timeout===void 0?1/0:Date.now()+zZ(Z.timeout),Y=this.feed.subscribe(this.channel($),{signal:J});try{await Y.ready();let j=await this.store.get($);if(!j)throw new O8($);let z=null;for(;;){if(x1(j.status))return j;J?.throwIfAborted();let X=await this.untilDeadline(j);if(X!==null&&X<=0){j=await this.expire($)??await this.store.get($)??j;continue}let Q=W-Date.now();if(Q<=0)return j;if(z??=Y.isClosed?new Promise(()=>{}):Y.next(),await bK(z,Math.min(Q,X??1/0,EK),J))z=null;j=await this.store.get($)??j}}finally{Y.close()}}async*subscribe($,Z={}){let J=this.feed.subscribe(this.channel($),{signal:Z.signal});try{await J.ready();let W=await this.store.get($);if(!W)throw new O8($);if(yield W,x1(W.status))return;for await(let Y of J){let j=OL(Y,$)??await this.store.get($);if(!j||j.version<=W.version)continue;if(W=j,yield W,x1(W.status))return}}finally{J.close()}}stream($,Z,J={}){return this.feed.stream($,this.channel(Z),J)}cursor($){return this.feed.cursor(this.channel($))}async sweep(){let $=await this.now(),Z=0;for(let J of await this.store.overdue($,this.config.sweepLimit))if(await this.expire(J.id))Z++;return Z}async prune($){let Z=zZ($);return await this.store.prune?.(Z)??0}async close(){await this.ownFeed?.close(),this.ownFeed=null}now(){return this.store.now?this.store.now():Promise.resolve(Date.now())}async untilDeadline($){if($.deadlineAt===null)return null;return $.deadlineAt-await this.now()}async expire($){let Z=await this.store.get($);if(!Z||x1(Z.status))return null;let J=await this.untilDeadline(Z);if(J===null||J>0)return null;return this.change($,I1,{status:"timed_out",error:{message:"The run passed its deadline.",code:"deadline"}})}async watch($,Z,J,W){let Y=new Promise((z)=>{if(W.signal.aborted)z("ended");W.signal.addEventListener("abort",()=>z("ended"),{once:!0})}),j=null;try{for(;;){if(W.signal.aborted)return;if(x1(Z.status)){W.abort();return}let z=await this.untilDeadline(Z);if(z!==null&&z<=0){Z=await this.expire($)??await this.store.get($)??Z;continue}j??=J.next();let X=await Promise.race([Y,bK(j,Math.min(z??1/0,EK))]);if(X==="ended")return;if(X)j=null;Z=await this.store.get($)??Z}}catch(z){console.error(`[gemi] Run ${$}: could not follow the run for a cancel.`,z)}}async change($,Z,J){let W=await this.store.transition($,Z,J);if(W)await this.publish(W);return W}async publish($){try{await this.feed.publish(this.channel($.id),$)}catch(Z){console.error(`[gemi] Run ${$.id}: could not publish its change.`,Z)}}}function bK($,Z,J){return new Promise((W,Y)=>{let j=Number.isFinite(Z)?setTimeout(()=>Q(!1),Math.max(0,Z)):null,z=()=>{X(),Y(J.reason)},X=()=>{if(j)clearTimeout(j);J?.removeEventListener("abort",z)},Q=(G)=>{X(),W(G)};J?.addEventListener("abort",z,{once:!0}),$.then(()=>Q(!0),()=>Q(!0))})}function OL($,Z){if($.type!=="change")return null;let J=$.data;if(!J||typeof J!=="object"||J.id!==Z||typeof J.version!=="number")return null;return J}function RK($){if(typeof $==="string")return{message:$};if($ instanceof L8)return{message:$.message,...$.code!==void 0?{code:$.code}:{},...$.data!==void 0?{data:$.data}:{}};if($ instanceof Error)return{message:$.message};return $}function kK($,Z){if(typeof Z!=="string"||Z===""||Z.length>SK)throw TypeError(`A run's ${$} is a string of 1 to ${SK} characters; got ${JSON.stringify(Z)}.`)}function LL($){let{fraction:Z}=$;if(Z!==void 0&&!(Number.isFinite(Z)&&Z>=0&&Z<=1))throw RangeError(`A run's progress fraction is between 0 and 1; got ${Z}.`)}function ML($,Z){if($==="memory")return new J5;if($==="database"||typeof $==="function"){if(!Z&&($==="database"||$.length>0))throw Error("The runs store needs the application it belongs to, and this RunManager was built without one. Pass { application }.");if($==="database"){let J=Z.make(f1).connection();return new z5(J)}return $(Z)}if(typeof $==="string")throw Error(`Unknown runs store "${$}". The runs slice's store is "memory", "database", a RunStore, or a function returning one.`);return $}class fK extends m{static getFacadeAccessor(){return X5}static create($){return this.getFacadeRoot().create($)}static get($){return this.getFacadeRoot().get($)}static list($){return this.getFacadeRoot().list($)}static start($){return this.getFacadeRoot().start($)}static progress($,Z){return this.getFacadeRoot().progress($,Z)}static complete($,Z){return this.getFacadeRoot().complete($,Z)}static fail($,Z){return this.getFacadeRoot().fail($,Z)}static cancel($,Z){return this.getFacadeRoot().cancel($,Z)}static execute($,Z){return this.getFacadeRoot().execute($,Z)}static wait($,Z){return this.getFacadeRoot().wait($,Z)}static subscribe($,Z){return this.getFacadeRoot().subscribe($,Z)}static stream($,Z,J){return this.getFacadeRoot().stream($,Z,J)}static cursor($){return this.getFacadeRoot().cursor($)}static channel($){return this.getFacadeRoot().channel($)}static sweep(){return this.getFacadeRoot().sweep()}static prune($){return this.getFacadeRoot().prune($)}}class wK extends m{static getFacadeAccessor(){return j$}static enabled($){return this.getFacadeRoot().enabled($)}static all(){return this.getFacadeRoot().forClient()}static explain($){return this.getFacadeRoot().explain($)}static for($){return this.getFacadeRoot().for($)}static list(){return this.getFacadeRoot().list()}static set($,Z,J){return this.getFacadeRoot().set($,Z,J)}static refresh(){return this.getFacadeRoot().refresh()}static invalidate(){return this.getFacadeRoot().invalidate()}}class K5{value;constructor($){this.value=$}}var HL=/^[A-Za-z_][A-Za-z0-9_$]*$/;function TL($){let Z=["SET TRANSACTION READ ONLY"],J=[["statementTimeoutMs","statement_timeout"],["lockTimeoutMs","lock_timeout"],["idleInTransactionTimeoutMs","idle_in_transaction_session_timeout"]];for(let[W,Y]of J){let j=$[W];if(j===void 0)continue;if(typeof j!=="number"||!Number.isInteger(j)||j<=0)throw TypeError(`DB.readOnly: ${W} must be a positive whole number of milliseconds, got ${String(j)}.`);Z.push(`SET LOCAL ${Y} = ${j}`)}if($.role!==void 0){if(typeof $.role!=="string"||!HL.test($.role))throw TypeError(`DB.readOnly: the role "${String($.role)}" is not a plain identifier. Use letters, digits, _ and $.`);Z.push(`SET LOCAL ROLE "${$.role}"`)}return Z}class M8{bound;constructor($){this.bound=$}get name(){return this.bound??k1()}get sql(){return this.connection().sql}get dialect(){return this.connection().dialect}async query($){return await this.run($,"query")}async execute($){let Z=await this.run($,"execute");return Number(Z?.count??0)}async transaction($){let Z=this.name,J=this.connection(Z);return G5(J.sql,(W)=>Q5(Z,()=>$(W)),{slowTransactionThreshold:J.config.slowTransactionThreshold,connection:Z})}async readOnly($,Z){let J=typeof $==="function"?{}:$,W=typeof $==="function"?$:Z;if(typeof W!=="function")throw TypeError("DB.readOnly needs a callback: readOnly(options, async (tx) => ...).");let Y=TL(J??{}),j=this.name,z=this.connection(j);if(z.dialect!=="postgres")throw Error(`DB.readOnly is supported on Postgres only, and the "${j}" connection is ${z.dialect}.`);if(l0()!==void 0)throw Error("DB.readOnly cannot run inside a transaction: SET TRANSACTION READ ONLY has to be the first statement of its own transaction. Call it outside the transaction.");try{await G5(z.sql,async(X)=>{for(let G of Y)await X.unsafe(G);let Q=await Q5(j,()=>W(X));throw new K5(Q)},{slowTransactionThreshold:z.config.slowTransactionThreshold,connection:j})}catch(X){if(X instanceof K5)return X.value;throw X}throw Error("DB.readOnly: the transaction committed, which it never should.")}async schema(){let $=this.connection(),{introspect:Z}=await import("./chunk-2rpz1p8g.js");return Z(this.handle()??$.sql,$.dialect)}run($,Z){let J=this.connection(),{text:W,values:Y}=vK($,yK(J.dialect),Z);return(this.handle()??J.sql).unsafe(W,Y)}handle(){let $=l0();if($===void 0)return;return k1()===this.name?$:void 0}connection($=this.name){return qK($),M(f1).connection($)}}var XZ=new M8;class gK extends m{static getFacadeAccessor(){return f1}static connection($){return new M8($)}static get sql(){return XZ.sql}static get dialect(){return XZ.dialect}static query($){return XZ.query($)}static execute($){return XZ.execute($)}static transaction($){return XZ.transaction($)}static readOnly($,Z){return XZ.readOnly($,Z)}static schema(){return XZ.schema()}static close(){return this.getFacadeRoot().close()}}export{K1 as le,lK as me,a0 as ne,X3 as oe,_8 as pe,BZ as qe,G3 as re,C0 as se,X6 as te,s8 as ue,n8 as ve,Nj as we,Y$ as xe,F1 as ye,k$ as ze,J0 as Ae,$j as Be,DZ as Ce,_j as De,Ij as Ee,a8 as Fe,r8 as Ge,P6 as He,HZ as Ie,zV as Je,mT as Ke,wj as Le,pj as Me,j7 as Ne,cj as Oe,dj as Pe,UV as Qe,uj as Re,z7 as Se,LV as Te,MV as Ue,X7 as Ve,lj as We,ij as Xe,j$ as Ye,sj as Ze,NV as _e,G7 as $e,w8 as af,F6 as bf,S1 as cf,k8 as df,E1 as ef,x$ as ff,G8 as gf,rG as hf,tG as if,$L as jf,i1 as kf,XA as lf,eG as mf,dY as nf,uY as of,iY as pf,JK as qf,YK as rf,jK as sf,XK as tf,GK as uf,KK as vf,qA as wf,BK as xf,B8 as yf,sY as zf,nY as Af,oY as Bf,V8 as Cf,W3 as Df,NK as Ef,_K as Ff,u as Gf,K3 as Hf,g4 as If,IP as Jf,xP as Kf,CP as Lf,bP as Mf,$Q as Nf,qW as Of,WQ as Pf,qP as Qf,zQ as Rf,c0 as Sf,u3 as Tf,XQ as Uf,IK as Vf,US as Wf,Z5 as Xf,I1 as Yf,x1 as Zf,J5 as _f,z5 as $f,DL as ag,O8 as bg,L8 as cg,X5 as dg,fK as eg,wK as fg,M8 as gg,gK as hg,vW as ig,HD as jg,lW as kg,iW as lg,sN as mg,bQ as ng,wQ as og,Q6 as pg,$$ as qg,Q_ as rg,yQ as sg,vQ as tg,OY as ug,eZ as vg,LY as wg,EI as xg,vI as yg,gI as zg,AO as Ag,SY as Bg,wY as Cg,kO as Dg,bY as Eg,qO as Fg,e3 as Gg,qY as Hg,yG as Ig,Y8 as Jg,j8 as Kg,QC as Lg,GC as Mg,KC as Ng,Q1 as Og,E as Pg,q0 as Qg,G6 as Rg,y5 as Sg,zB as Tg,f5 as Ug,g5 as Vg,E8 as Wg,B6 as Xg,b8 as Yg,m5 as Zg,FB as _g,UB as $g,l5 as ah,s5 as bh,o5 as ch,Jj as dh,Wj as eh,Yj as fh,g8 as gh,TB as hh,z0 as ih,Dj as jh,LZ as kh,Tj as lh};
|
|
116
116
|
|
|
117
|
-
//# debugId=
|
|
117
|
+
//# debugId=DD6E631F0CFFC3BB64756E2164756E21
|