gemi 0.120.1 → 0.121.0

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.
@@ -4,6 +4,8 @@ import { type OAuthConnectionProvider, type OAuthTokenSet } from "./OAuthConnect
4
4
  export type ConnectionOwner = {
5
5
  id: string | number;
6
6
  } | string | number;
7
+ /** See `ProviderConnection.status`. */
8
+ export type ConnectionStatus = "connected" | "needs_reconnect";
7
9
  /** What `Connections.fake` answers an API request with. */
8
10
  export type FakeConnectionHandler = (request: Request) => Response | Promise<Response>;
9
11
  export interface ConnectionManagerOptions {
@@ -82,6 +84,12 @@ export declare class ProviderConnection {
82
84
  /** A refresh was refused: the user has to connect again. */
83
85
  get needsReconnect(): boolean;
84
86
  get connectedAt(): Date;
87
+ /**
88
+ * What to show the user: `"needs_reconnect"` when a refresh was refused, or
89
+ * when the access token has expired and there is no refresh token to renew
90
+ * it; `"connected"` otherwise. Read without calling the provider.
91
+ */
92
+ get status(): ConnectionStatus;
85
93
  /** Whether every one of `scopes` was granted. */
86
94
  hasScopes(...scopes: string[]): boolean;
87
95
  /**
@@ -122,6 +130,7 @@ export declare class ProviderConnection {
122
130
  scopes: string[];
123
131
  expiresAt: Date;
124
132
  needsReconnect: boolean;
133
+ status: ConnectionStatus;
125
134
  connectedAt: Date;
126
135
  };
127
136
  private current;
@@ -1 +1 @@
1
- {"version":3,"file":"ConnectionManager.d.ts","sourceRoot":"","sources":["../../../auth/connections/ConnectionManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ConnectionManager.d.ts","sourceRoot":"","sources":["../../../auth/connections/ConnectionManager.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EAGrB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,KAAK,uBAAuB,EAAE,KAAK,aAAa,EAAc,MAAM,2BAA2B,CAAC;AAEzG,0EAA0E;AAC1E,MAAM,MAAM,eAAe,GAAG;IAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAAG,MAAM,GAAG,MAAM,CAAC;AAExE,uCAAuC;AACvC,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,iBAAiB,CAAC;AAE/D,2DAA2D;AAC3D,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEvF,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;IACnD,+EAA+E;IAC/E,KAAK,CAAC,EAAE,eAAe,GAAG,CAAC,MAAM,eAAe,CAAC,CAAC;CACnD;AAED;;;GAGG;AACH,qBAAa,iBAAiB;IAShB,OAAO,CAAC,QAAQ,CAAC,OAAO;IARpC,MAAM,CAAC,KAAK,SAAsB;IAElC,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgD;IAC3E,OAAO,CAAC,KAAK,CAAiD;IAC9D,OAAO,CAAC,SAAS,CAAoC;IACrD,QAAQ,CAAC,YAAY,EAAE,OAAO,EAAE,CAAM;gBAET,OAAO,EAAE,wBAAwB;IAE9D,IAAI,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAEvD;IAED,yCAAyC;IACzC,IAAI,KAAK,IAAI,eAAe,CAW3B;IAED,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,uBAAuB;IAa/C,sFAAsF;IAChF,GAAG,CAAC,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAMtF,qCAAqC;IAC/B,IAAI,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAOhE;;;;OAIG;IACG,IAAI,CACR,IAAI,EAAE,eAAe,EACrB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GACvD,OAAO,CAAC,kBAAkB,CAAC;IAe9B;;;;;OAKG;IACH,IAAI,CAAC,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAM,GAAG,IAAI;IAOhE,qBAAqB;IACrB,OAAO,IAAI,IAAI;IAMf,IAAI,KAAK,IAAI,OAAO,CAEnB;IAID,gBAAgB;IACV,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;IAUjE;;;;;;;;OAQG;IACH,OAAO,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;YAU9C,WAAW;YAkDX,QAAQ;CAcvB;AAED;;;GAGG;AACH,qBAAa,kBAAkB;IAE3B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,MAAM;gBADG,OAAO,EAAE,iBAAiB,EACnC,MAAM,EAAE,gBAAgB;IAGlC,IAAI,QAAQ,IAAI,MAAM,CAErB;IACD,IAAI,MAAM,IAAI,MAAM,CAEnB;IACD,IAAI,iBAAiB,IAAI,MAAM,GAAG,IAAI,CAErC;IACD,uCAAuC;IACvC,IAAI,MAAM,IAAI,SAAS,MAAM,EAAE,CAE9B;IACD,IAAI,SAAS,IAAI,IAAI,GAAG,IAAI,CAE3B;IACD,4DAA4D;IAC5D,IAAI,cAAc,IAAI,OAAO,CAE5B;IACD,IAAI,WAAW,IAAI,IAAI,CAEtB;IAED;;;;OAIG;IACH,IAAI,MAAM,IAAI,gBAAgB,CAO7B;IAED,iDAAiD;IACjD,SAAS,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO;IAIvC;;;;;;;;;;;;OAYG;IACG,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAe3E;;;OAGG;IACG,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;IAIpC,+CAA+C;IACzC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAI9B;;;;;;;OAOG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAY7B,+DAA+D;IACzD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC,MAAM;;;;;;;;;YAgBQ,OAAO;YAUP,WAAW;IAYzB,OAAO,CAAC,UAAU;YA2BJ,IAAI;IA8BlB,OAAO,CAAC,OAAO;CAMhB"}
@@ -1,8 +1,20 @@
1
1
  export interface OAuthConnectionProviderConfig {
2
2
  /** The provider's authorization endpoint: `https://www.figma.com/oauth`. */
3
3
  authorizeUrl: string;
4
- /** The token endpoint, for the code exchange and refreshes. */
4
+ /** The token endpoint, for the code exchange (and refreshes, unless `refreshUrl` says otherwise). */
5
5
  tokenUrl: string;
6
+ /**
7
+ * Where refresh tokens are spent, for a provider with a refresh endpoint of
8
+ * its own: Figma refreshes at `https://api.figma.com/v1/oauth/refresh`.
9
+ * Default `tokenUrl`.
10
+ */
11
+ refreshUrl?: string;
12
+ /**
13
+ * The `grant_type` sent with a refresh. Default `"refresh_token"` (RFC 6749
14
+ * §6). `false` leaves it out, for a refresh endpoint that documents only
15
+ * `refresh_token` (Figma's).
16
+ */
17
+ refreshGrantType?: string | false;
6
18
  /**
7
19
  * The RFC 7009 revocation endpoint. Without one, `revoke()` is refused and
8
20
  * `disconnect()` (which forgets the tokens locally) is the way to remove a
@@ -16,7 +28,7 @@ export interface OAuthConnectionProviderConfig {
16
28
  /** How `scopes` are joined on the authorization URL. Default `" "` (RFC 6749). */
17
29
  scopeSeparator?: string;
18
30
  /**
19
- * How the client authenticates to the token and revocation endpoints:
31
+ * How the client authenticates to the token, refresh and revocation endpoints:
20
32
  * `"body"` sends `client_id` and `client_secret` as form fields (what most
21
33
  * providers document), `"basic"` sends them as HTTP Basic credentials.
22
34
  * Default `"body"`.
@@ -71,6 +83,9 @@ export interface OAuthTokenSet {
71
83
  * figma: new OAuthConnectionProvider({
72
84
  * authorizeUrl: "https://www.figma.com/oauth",
73
85
  * tokenUrl: "https://api.figma.com/v1/oauth/token",
86
+ * refreshUrl: "https://api.figma.com/v1/oauth/refresh",
87
+ * refreshGrantType: false,
88
+ * clientAuth: "basic",
74
89
  * clientId: process.env.FIGMA_CLIENT_ID!,
75
90
  * clientSecret: process.env.FIGMA_CLIENT_SECRET!,
76
91
  * scopes: ["file_content:read"],
@@ -80,7 +95,7 @@ export interface OAuthTokenSet {
80
95
  * ```
81
96
  */
82
97
  export declare class OAuthConnectionProvider {
83
- readonly config: Required<Omit<OAuthConnectionProviderConfig, "revokeUrl" | "redirectUri">> & Pick<OAuthConnectionProviderConfig, "revokeUrl" | "redirectUri">;
98
+ readonly config: Required<Omit<OAuthConnectionProviderConfig, "revokeUrl" | "redirectUri" | "refreshUrl">> & Pick<OAuthConnectionProviderConfig, "revokeUrl" | "redirectUri" | "refreshUrl">;
84
99
  constructor(config: OAuthConnectionProviderConfig);
85
100
  /** The URL to send the browser to. */
86
101
  authorizationUrl(args: {
@@ -95,8 +110,9 @@ export declare class OAuthConnectionProvider {
95
110
  redirectUri: string;
96
111
  }): Promise<OAuthTokenSet>;
97
112
  /**
98
- * Spends `refreshToken` for a new access token. A provider that does not
99
- * rotate refresh tokens answers without one, and the old one is kept.
113
+ * Spends `refreshToken` for a new access token at `refreshUrl` (default
114
+ * `tokenUrl`). A provider that does not rotate refresh tokens (Figma)
115
+ * answers without one, and the old one is kept.
100
116
  */
101
117
  refresh(refreshToken: string, scopes: string[]): Promise<OAuthTokenSet>;
102
118
  /** Revokes `token` at the provider (RFC 7009). */
@@ -1 +1 @@
1
- {"version":3,"file":"OAuthConnectionProvider.d.ts","sourceRoot":"","sources":["../../../auth/connections/OAuthConnectionProvider.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,6BAA6B;IAC5C,4EAA4E;IAC5E,YAAY,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,6BAA6B;IAC7B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,kFAAkF;IAClF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9B,kGAAkG;IAClG,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,kDAAkD;AAClD,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,mEAAmE;IACnE,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;IACvB,gFAAgF;IAChF,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB;;;OAGG;IACH,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,uBAAuB;IAClC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CACvB,IAAI,CAAC,6BAA6B,EAAE,WAAW,GAAG,aAAa,CAAC,CACjE,GACC,IAAI,CAAC,6BAA6B,EAAE,WAAW,GAAG,aAAa,CAAC,CAAC;gBAEvD,MAAM,EAAE,6BAA6B;IA0BjD,sCAAsC;IACtC,gBAAgB,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM;IAkB7F,kDAAkD;IAClD,YAAY,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAUvG;;;OAGG;IACH,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAKvE,kDAAkD;IAC5C,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBlF,OAAO,CAAC,IAAI;YAgBE,YAAY;CA0C3B;AAgBD,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEpD"}
1
+ {"version":3,"file":"OAuthConnectionProvider.d.ts","sourceRoot":"","sources":["../../../auth/connections/OAuthConnectionProvider.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,6BAA6B;IAC5C,4EAA4E;IAC5E,YAAY,EAAE,MAAM,CAAC;IACrB,qGAAqG;IACrG,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAClC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,6BAA6B;IAC7B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,kFAAkF;IAClF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9B,kGAAkG;IAClG,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,kDAAkD;AAClD,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,mEAAmE;IACnE,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;IACvB,gFAAgF;IAChF,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB;;;OAGG;IACH,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,uBAAuB;IAClC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CACvB,IAAI,CAAC,6BAA6B,EAAE,WAAW,GAAG,aAAa,GAAG,YAAY,CAAC,CAChF,GACC,IAAI,CAAC,6BAA6B,EAAE,WAAW,GAAG,aAAa,GAAG,YAAY,CAAC,CAAC;gBAEtE,MAAM,EAAE,6BAA6B;IA6BjD,sCAAsC;IACtC,gBAAgB,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM;IAkB7F,kDAAkD;IAClD,YAAY,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAcvG;;;;OAIG;IACH,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAYvE,kDAAkD;IAC5C,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBlF,OAAO,CAAC,IAAI;YAgBE,YAAY;CA2C3B;AAgBD,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEpD"}
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{S as q,T as KJ,U as OJ}from"./chunk-qphjhpad.js";import{oa as B,sa as L,ta as UJ}from"./chunk-a22h5cby.js";import"./chunk-kk18xqgc.js";import{De as QJ,Ee as A,Vc as a}from"./chunk-b5a5vvkk.js";import"./chunk-65beps2q.js";import"./chunk-m53fgf20.js";import{Ef as o,Ff as n,If as i}from"./chunk-4acpw92g.js";import{Jg as HJ}from"./chunk-cca0grq3.js";import"./chunk-m83zm86m.js";import"./chunk-1xdrs2hx.js";import"./chunk-19dpzp4y.js";import"./chunk-yds7zwc3.js";import"./chunk-meg8rtr6.js";import"./chunk-h43jp8ws.js";import"./chunk-s07v65x6.js";import"./chunk-gc2dz11k.js";import"./chunk-cskqet01.js";import"./chunk-fenc5tpv.js";import"./chunk-nz8z8jr1.js";import"./chunk-4fx8p02c.js";import{Ui as e}from"./chunk-er8acmch.js";import"./chunk-2n3pgfnb.js";import{fj as YJ}from"./chunk-d5f1m3d2.js";import{gj as N}from"./chunk-rhvc1axc.js";import"./chunk-tewhms9w.js";import{createHash as X2}from"crypto";import{join as w,resolve as VJ,sep as zJ}from"path";import{Duplex as TJ}from"stream";import{constants as P,createBrotliCompress as RJ,createGzip as bJ}from"zlib";var kJ=["br","gzip"],SJ=1024,wJ=5,vJ=19,EJ=6;function yJ(J){if(J===void 0)return 1;if(!/^\d+(\.\d{0,3})?$/.test(J.trim()))return 1;let $=Number(J.trim());return Number.isFinite($)?Math.min($,1):1}function gJ(J){if(J===null||J===void 0)return null;let $=new Map;for(let Z of J.split(",")){let[X,...Q]=Z.split(";"),H=X.trim().toLowerCase();if(H==="")continue;let j=1;for(let Y of Q){let K=Y.indexOf("=");if(K===-1)continue;if(Y.slice(0,K).trim().toLowerCase()==="q"){j=yJ(Y.slice(K+1));break}}$.set(H,j)}return $}function b(J,$=kJ){let Z=gJ(J);if(!Z)return null;let X=Z.get("*"),Q=null,H=0;for(let j of $){let Y=Z.get(j)??X??0;if(Y>H)Q=j,H=Y}return Q}function fJ(J,$){if(!J)return!1;return J.split(",").some((Z)=>Z.trim().toLowerCase().split("=")[0].trim()===$)}function mJ(J,$){if(J==="HEAD")return!1;if($.status<200||$.status===204||$.status===206||$.status===304)return!1;if($.headers.has("Content-Range"))return!1;let Z=$.headers.get("Content-Type");if(!Z||!/^\s*text\/html\s*(;|$)/i.test(Z))return!1;if(!$.body)return!1;let X=$.headers.get("Content-Encoding");if(X&&X.trim().toLowerCase()!=="identity")return!1;if(fJ($.headers.get("Cache-Control"),"no-transform"))return!1;let Q=$.headers.get("Content-Length");if(Q!==null&&Number(Q)<SJ)return!1;return!0}function uJ(J){let $=J==="br"?RJ({params:{[P.BROTLI_PARAM_QUALITY]:wJ,[P.BROTLI_PARAM_LGWIN]:vJ},flush:P.BROTLI_OPERATION_FLUSH}):bJ({level:EJ,flush:P.Z_SYNC_FLUSH});return TJ.toWeb($)}function hJ(J){let $=J.get("Vary");if(!$){J.set("Vary","Accept-Encoding");return}let Z=$.split(",").map((X)=>X.trim().toLowerCase());if(Z.includes("*")||Z.includes("accept-encoding"))return;J.append("Vary","Accept-Encoding")}function c(J,$){if(!mJ(J.method,$))return $;let Z=new Headers($.headers);hJ(Z);let X=b(J.headers.get("Accept-Encoding"));if(!X)return new Response($.body,{status:$.status,statusText:$.statusText,headers:Z});let Q;try{Q=uJ(X)}catch{return new Response($.body,{status:$.status,statusText:$.statusText,headers:Z})}return Z.set("Content-Encoding",X),Z.delete("Content-Length"),new Response($.body.pipeThrough(Q),{status:$.status,statusText:$.statusText,headers:Z})}import{readdir as iJ,stat as t}from"fs/promises";import{join as aJ}from"path";import{mkdir as O2,readFile as cJ,stat as V2,writeFile as z2}from"fs/promises";import{dirname as L2,join as pJ}from"path";import{promisify as p}from"util";import{brotliCompress as dJ,constants as I2,gzip as lJ}from"zlib";var oJ=".vite/static-assets.json";var d={br:".br",gzip:".gz"},nJ=["br","gzip"],P2=p(dJ),_2=p(lJ);async function l(J){let $;try{$=await cJ(pJ(J,oJ),"utf8")}catch{return null}let Z;try{Z=JSON.parse($)?.files}catch{return null}if(!Z||typeof Z!=="object")return null;let X={files:{}};for(let[Q,H]of Object.entries(Z)){if(!Array.isArray(H))continue;X.files[Q]=nJ.filter((j)=>H.includes(j))}return X}function k(J){let $=J.toString(),Z=new Bun.CryptoHasher("sha1");return Z.update($),Z.digest("hex")}async function r(J){let $=new Set;async function Z(X,Q){let H;try{H=await iJ(X,{withFileTypes:!0})}catch{return}for(let j of H){if(j.name.startsWith("."))continue;if(Q&&j.name==="assets")continue;let Y=aJ(X,j.name),K=j.isDirectory(),V=j.isFile();if(j.isSymbolicLink())try{let F=await t(Y);K=F.isDirectory(),V=F.isFile()}catch{continue}if(V)$.add(Y);else if(K&&!j.isSymbolicLink())await Z(Y,!1)}}return await Z(J,!0),$}var tJ="public, max-age=31536000, must-revalidate",rJ="public, max-age=31536000, immutable";async function sJ(J,$,Z){if(Z.length===0||J.headers.has("Range"))return null;let X=b(J.headers.get("Accept-Encoding"),Z);if(!X)return null;let Q=$+d[X];try{let H=await t(Q);return H.isFile()?{encoding:X,path:Q,size:H.size}:null}catch{return null}}async function s(J,$,Z={}){let X=Bun.file($),Q=Z.encodings??[],H={"Content-Type":X.type||"application/octet-stream","Cache-Control":Z.immutable?rJ:tJ,"Accept-Ranges":"bytes"};if(Q.length>0)H.Vary="Accept-Encoding";let j=await sJ(J,$,Q);if(j){let V=Bun.file(j.path);return new Response(V.stream(),{headers:{...H,"Content-Encoding":j.encoding,"Content-Length":String(j.size),ETag:`${k(V.lastModified)}-${j.encoding}`}})}let Y=X.size;H.ETag=k(X.lastModified);let K=o(J.headers.get("Range"));if(K){let V=n(K,Y);if(!V)return a(Y);return new Response(X.slice(V.start,V.end+1).stream(),{status:206,headers:{...H,"Content-Range":i(V.start,V.end,Y),"Content-Length":String(V.length)}})}return new Response(X.stream(),{headers:{...H,"Content-Length":String(Y)}})}import{stat as Q2}from"fs/promises";var _="app/client.tsx";function JJ(J,$=B){let Z=J[_]?.file;if(!Z)return;return{module:L(Z,$),preload:M(J,_,$)}}function M(J,$,Z=B){let X=[],Q=new Set,H=(j)=>{if(Q.has(j))return;Q.add(j);let Y=J[j];if(!Y?.file)return;X.push(L(Y.file,Z));for(let K of Y.imports??[])H(K)};return H($),X}function $J(J,$){let Z=[],X=new Set,Q=new Set,H=(j)=>{if(Q.has(j))return;Q.add(j);let Y=J[j];if(!Y)return;for(let K of Y.imports??[])H(K);for(let K of Y.css??[])if(!X.has(K))X.add(K),Z.push(K)};return H($),Z}function ZJ(J,$=B){let Z=new Map;return(X)=>{if(!Z.has(X)){let Q=`${X}${e}`,H=J[Q]?.file;Z.set(X,H?{src:L(H,$),preload:M(J,Q,$)}:void 0)}return Z.get(X)}}function XJ(J,$=30000){let Z=JSON.stringify("gemi:chunk-reload"),X=JSON.stringify(`Failed to fetch dynamically imported module: ${J}`);return`var r=!1;try{var s=window.sessionStorage,m=JSON.parse(s.getItem(${Z})||"null");var d=m?Date.now()-m.at:NaN;if(navigator.onLine!==!1&&!(d>=0&&d<${$})){s.setItem(${Z},JSON.stringify({url:window.location.href,at:Date.now()}));r=!0}}catch(e){}if(r)window.location.reload();else throw new Error(${X});export {}`}var eJ=new RegExp(`^${QJ}/.+\\.m?js$`);function J2(J){return eJ.test(J)}function WJ(J){if(J2(J))return new Response(XJ(J),{headers:{"Content-Type":"application/javascript","Cache-Control":"no-store"}});if(A(J))return new Response("Not found",{status:404});return}var $2=`<!DOCTYPE html>
2
+ import{S as q,T as KJ,U as OJ}from"./chunk-fpc7bfa9.js";import{oa as B,sa as L,ta as UJ}from"./chunk-a22h5cby.js";import"./chunk-kk18xqgc.js";import{De as QJ,Ee as A,Vc as a}from"./chunk-baz7ne68.js";import"./chunk-65beps2q.js";import"./chunk-m53fgf20.js";import{Ef as o,Ff as n,If as i}from"./chunk-4acpw92g.js";import{Jg as HJ}from"./chunk-cca0grq3.js";import"./chunk-m83zm86m.js";import"./chunk-pspthd52.js";import"./chunk-19dpzp4y.js";import"./chunk-yds7zwc3.js";import"./chunk-meg8rtr6.js";import"./chunk-h43jp8ws.js";import"./chunk-s07v65x6.js";import"./chunk-gc2dz11k.js";import"./chunk-cskqet01.js";import"./chunk-fenc5tpv.js";import"./chunk-nz8z8jr1.js";import"./chunk-4fx8p02c.js";import{Ui as e}from"./chunk-er8acmch.js";import"./chunk-2n3pgfnb.js";import{fj as YJ}from"./chunk-d5f1m3d2.js";import{gj as N}from"./chunk-rhvc1axc.js";import"./chunk-tewhms9w.js";import{createHash as X2}from"crypto";import{join as w,resolve as VJ,sep as zJ}from"path";import{Duplex as TJ}from"stream";import{constants as P,createBrotliCompress as RJ,createGzip as bJ}from"zlib";var kJ=["br","gzip"],SJ=1024,wJ=5,vJ=19,EJ=6;function yJ(J){if(J===void 0)return 1;if(!/^\d+(\.\d{0,3})?$/.test(J.trim()))return 1;let $=Number(J.trim());return Number.isFinite($)?Math.min($,1):1}function gJ(J){if(J===null||J===void 0)return null;let $=new Map;for(let Z of J.split(",")){let[X,...Q]=Z.split(";"),H=X.trim().toLowerCase();if(H==="")continue;let j=1;for(let Y of Q){let K=Y.indexOf("=");if(K===-1)continue;if(Y.slice(0,K).trim().toLowerCase()==="q"){j=yJ(Y.slice(K+1));break}}$.set(H,j)}return $}function b(J,$=kJ){let Z=gJ(J);if(!Z)return null;let X=Z.get("*"),Q=null,H=0;for(let j of $){let Y=Z.get(j)??X??0;if(Y>H)Q=j,H=Y}return Q}function fJ(J,$){if(!J)return!1;return J.split(",").some((Z)=>Z.trim().toLowerCase().split("=")[0].trim()===$)}function mJ(J,$){if(J==="HEAD")return!1;if($.status<200||$.status===204||$.status===206||$.status===304)return!1;if($.headers.has("Content-Range"))return!1;let Z=$.headers.get("Content-Type");if(!Z||!/^\s*text\/html\s*(;|$)/i.test(Z))return!1;if(!$.body)return!1;let X=$.headers.get("Content-Encoding");if(X&&X.trim().toLowerCase()!=="identity")return!1;if(fJ($.headers.get("Cache-Control"),"no-transform"))return!1;let Q=$.headers.get("Content-Length");if(Q!==null&&Number(Q)<SJ)return!1;return!0}function uJ(J){let $=J==="br"?RJ({params:{[P.BROTLI_PARAM_QUALITY]:wJ,[P.BROTLI_PARAM_LGWIN]:vJ},flush:P.BROTLI_OPERATION_FLUSH}):bJ({level:EJ,flush:P.Z_SYNC_FLUSH});return TJ.toWeb($)}function hJ(J){let $=J.get("Vary");if(!$){J.set("Vary","Accept-Encoding");return}let Z=$.split(",").map((X)=>X.trim().toLowerCase());if(Z.includes("*")||Z.includes("accept-encoding"))return;J.append("Vary","Accept-Encoding")}function c(J,$){if(!mJ(J.method,$))return $;let Z=new Headers($.headers);hJ(Z);let X=b(J.headers.get("Accept-Encoding"));if(!X)return new Response($.body,{status:$.status,statusText:$.statusText,headers:Z});let Q;try{Q=uJ(X)}catch{return new Response($.body,{status:$.status,statusText:$.statusText,headers:Z})}return Z.set("Content-Encoding",X),Z.delete("Content-Length"),new Response($.body.pipeThrough(Q),{status:$.status,statusText:$.statusText,headers:Z})}import{readdir as iJ,stat as t}from"fs/promises";import{join as aJ}from"path";import{mkdir as O2,readFile as cJ,stat as V2,writeFile as z2}from"fs/promises";import{dirname as L2,join as pJ}from"path";import{promisify as p}from"util";import{brotliCompress as dJ,constants as I2,gzip as lJ}from"zlib";var oJ=".vite/static-assets.json";var d={br:".br",gzip:".gz"},nJ=["br","gzip"],P2=p(dJ),_2=p(lJ);async function l(J){let $;try{$=await cJ(pJ(J,oJ),"utf8")}catch{return null}let Z;try{Z=JSON.parse($)?.files}catch{return null}if(!Z||typeof Z!=="object")return null;let X={files:{}};for(let[Q,H]of Object.entries(Z)){if(!Array.isArray(H))continue;X.files[Q]=nJ.filter((j)=>H.includes(j))}return X}function k(J){let $=J.toString(),Z=new Bun.CryptoHasher("sha1");return Z.update($),Z.digest("hex")}async function r(J){let $=new Set;async function Z(X,Q){let H;try{H=await iJ(X,{withFileTypes:!0})}catch{return}for(let j of H){if(j.name.startsWith("."))continue;if(Q&&j.name==="assets")continue;let Y=aJ(X,j.name),K=j.isDirectory(),V=j.isFile();if(j.isSymbolicLink())try{let F=await t(Y);K=F.isDirectory(),V=F.isFile()}catch{continue}if(V)$.add(Y);else if(K&&!j.isSymbolicLink())await Z(Y,!1)}}return await Z(J,!0),$}var tJ="public, max-age=31536000, must-revalidate",rJ="public, max-age=31536000, immutable";async function sJ(J,$,Z){if(Z.length===0||J.headers.has("Range"))return null;let X=b(J.headers.get("Accept-Encoding"),Z);if(!X)return null;let Q=$+d[X];try{let H=await t(Q);return H.isFile()?{encoding:X,path:Q,size:H.size}:null}catch{return null}}async function s(J,$,Z={}){let X=Bun.file($),Q=Z.encodings??[],H={"Content-Type":X.type||"application/octet-stream","Cache-Control":Z.immutable?rJ:tJ,"Accept-Ranges":"bytes"};if(Q.length>0)H.Vary="Accept-Encoding";let j=await sJ(J,$,Q);if(j){let V=Bun.file(j.path);return new Response(V.stream(),{headers:{...H,"Content-Encoding":j.encoding,"Content-Length":String(j.size),ETag:`${k(V.lastModified)}-${j.encoding}`}})}let Y=X.size;H.ETag=k(X.lastModified);let K=o(J.headers.get("Range"));if(K){let V=n(K,Y);if(!V)return a(Y);return new Response(X.slice(V.start,V.end+1).stream(),{status:206,headers:{...H,"Content-Range":i(V.start,V.end,Y),"Content-Length":String(V.length)}})}return new Response(X.stream(),{headers:{...H,"Content-Length":String(Y)}})}import{stat as Q2}from"fs/promises";var _="app/client.tsx";function JJ(J,$=B){let Z=J[_]?.file;if(!Z)return;return{module:L(Z,$),preload:M(J,_,$)}}function M(J,$,Z=B){let X=[],Q=new Set,H=(j)=>{if(Q.has(j))return;Q.add(j);let Y=J[j];if(!Y?.file)return;X.push(L(Y.file,Z));for(let K of Y.imports??[])H(K)};return H($),X}function $J(J,$){let Z=[],X=new Set,Q=new Set,H=(j)=>{if(Q.has(j))return;Q.add(j);let Y=J[j];if(!Y)return;for(let K of Y.imports??[])H(K);for(let K of Y.css??[])if(!X.has(K))X.add(K),Z.push(K)};return H($),Z}function ZJ(J,$=B){let Z=new Map;return(X)=>{if(!Z.has(X)){let Q=`${X}${e}`,H=J[Q]?.file;Z.set(X,H?{src:L(H,$),preload:M(J,Q,$)}:void 0)}return Z.get(X)}}function XJ(J,$=30000){let Z=JSON.stringify("gemi:chunk-reload"),X=JSON.stringify(`Failed to fetch dynamically imported module: ${J}`);return`var r=!1;try{var s=window.sessionStorage,m=JSON.parse(s.getItem(${Z})||"null");var d=m?Date.now()-m.at:NaN;if(navigator.onLine!==!1&&!(d>=0&&d<${$})){s.setItem(${Z},JSON.stringify({url:window.location.href,at:Date.now()}));r=!0}}catch(e){}if(r)window.location.reload();else throw new Error(${X});export {}`}var eJ=new RegExp(`^${QJ}/.+\\.m?js$`);function J2(J){return eJ.test(J)}function WJ(J){if(J2(J))return new Response(XJ(J),{headers:{"Content-Type":"application/javascript","Cache-Control":"no-store"}});if(A(J))return new Response("Not found",{status:404});return}var $2=`<!DOCTYPE html>
3
3
  <html lang="en">
4
4
  <head>
5
5
  <meta charset="UTF-8" />
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{cf as FF}from"./chunk-65beps2q.js";import{wf as XF}from"./chunk-m53fgf20.js";import{$f as Y8,Ag as qX,Bf as _X,Bg as nX,Cf as G5,Df as Q5,Dg as oX,Ef as b8,Ff as x8,If as S8,Jf as f8,Kf as CZ,Lf as JX,Mf as RX,Nf as dJ,Of as q,Tf as x,Uf as o8,Vf as m$,Wf as v8,Xf as b3,Zf as Z$,_f as h,ng as v3,ug as p$,xf as yZ,yg as Dz,zg as x$}from"./chunk-4acpw92g.js";import{Gg as _Z,Hg as P0,Ig as v1,Jg as B5}from"./chunk-cca0grq3.js";import{Kg as sz,Lg as D8,Mg as H}from"./chunk-m83zm86m.js";import{Pg as Gz,Sg as V3}from"./chunk-1xdrs2hx.js";import{Wg as s5,Zg as hX}from"./chunk-19dpzp4y.js";import{ph as L3,uh as xZ}from"./chunk-yds7zwc3.js";import{Kh as mX}from"./chunk-meg8rtr6.js";import{Lh as P8}from"./chunk-h43jp8ws.js";import{Mh as xX,Nh as T1,Oh as W$,Ph as WF,Qh as YF,Sh as bJ,Th as iX,ai as zF}from"./chunk-s07v65x6.js";import{pi as Y$}from"./chunk-gc2dz11k.js";import{ui as NX,zi as PJ}from"./chunk-cskqet01.js";import{Gi as LX,Li as a}from"./chunk-fenc5tpv.js";import{Mi as HZ,Pi as T}from"./chunk-nz8z8jr1.js";import{Xi as TJ}from"./chunk-er8acmch.js";import{Yi as aX}from"./chunk-2n3pgfnb.js";import{hj as SX}from"./chunk-rhvc1axc.js";import{mj as U8}from"./chunk-tewhms9w.js";function _3($){return typeof $==="function"&&$.prototype!==void 0}function O1($){return typeof $==="string"?[$]:$}function x3($,Z){let j=Z?"attachment":"inline",J=$.replace(/["\\]/g,"").replace(/[^\x20-\x7e]/g,"_");return`${j}; filename="${J}"; filename*=UTF-8''${encodeURIComponent($)}`}function MF($){return"total"in $&&"partial"in $&&"body"in $}function yJ(){return new Response("Not found",{status:404,headers:{"X-Content-Type-Options":"nosniff"}})}function EZ($){return new Response(null,{status:416,headers:{"Accept-Ranges":"bytes","Content-Range":f8($),"Content-Length":"0","Cache-Control":"no-store","X-Content-Type-Options":"nosniff"}})}async function PF($){if($ instanceof Blob)return{body:$,start:0,end:$.size-1,total:$.size,partial:!1,type:$.type,name:$.name,download:!1,status:200,extraHeaders:{}};if(MF($))return{body:$.body,start:$.start,end:$.end,total:$.total,partial:$.partial,type:$.type,name:$.name,download:$.download??!1,etag:$.etag,lastModified:$.lastModified,status:$.status??200,extraHeaders:$.headers??{}};let Z=$.file,j=Z instanceof Blob?Z:null,J=$.total??j?.size??-1;return{body:Z,start:$.start??0,end:$.end??J-1,total:J,partial:$.partial??!1,type:$.type??j?.type??"",name:$.name??Z?.name,download:$.download??!1,etag:$.etag,lastModified:$.lastModified,status:$.status??200,extraHeaders:$.headers??{}}}async function A8($,Z){if($ instanceof Response)return $;if(!$)return yJ();let j=await PF($),{body:J,start:W,end:Y,total:z,partial:X}=j;if(J instanceof Blob&&"exists"in J&&typeof J.exists==="function"){if(!await J.exists())return yJ()}let{range:F}=Z;if(F){if(z<=0)return EZ(Math.max(z,0));if(!X){if(J instanceof Blob){let K=x8(F,z);if(!K)return EZ(z);J=J.slice(K.start,K.end+1),W=K.start,Y=K.end,X=!0}}}let G=Boolean(F)&&X,Q=G?206:j.status,O=new Headers;if(O.set("Accept-Ranges","bytes"),O.set("Content-Type",j.type||"application/octet-stream"),O.set("X-Content-Type-Options","nosniff"),G)O.set("Content-Range",S8(W,Y,z)),O.set("Content-Length",String(Y-W+1));else if(z>=0)O.set("Content-Length",String(z));if(j.name)O.set("Content-Disposition",x3(j.name,j.download));if(j.etag)O.set("ETag",j.etag);if(j.lastModified)O.set("Last-Modified",j.lastModified.toUTCString());for(let[K,D]of Object.entries(j.extraHeaders))O.set(K,D);if((Z.method??"GET").toUpperCase()==="HEAD"){if(J&&"cancel"in J&&typeof J.cancel==="function")await J.cancel();return new Response(null,{status:Q,headers:O})}return new Response(J,{status:Q,headers:O})}class k$ extends P0{limit;constructor($){super("The request body is too large.",{status:413});this.limit=$}}var qJ={b:1,k:1024,kb:1024,m:1048576,mb:1048576,g:1073741824,gb:1073741824};function bZ($){if(typeof $==="number"){if(Number.isFinite($)&&$>=0)return Math.floor($);if($===1/0)return 1/0}else{let Z=$.trim().toLowerCase();if(Z==="none"||Z==="off")return 1/0;let j=/^(\d+(?:\.\d+)?)\s*([a-z]*)$/.exec(Z);if(j&&(j[2]===""||(j[2]in qJ)))return Math.floor(Number(j[1])*(qJ[j[2]]??1))}throw Error(`Invalid body limit ${JSON.stringify($)}. Use a byte count or a size such as "64kb", "1mb" or "none".`)}var RZ=new WeakMap;function mJ($){return RZ.has($)}function pJ($){return RZ.get($)?.limit??null}function hJ($){let Z=RZ.get($);return Z?Z.read>Z.limit:!1}function LF($){let Z=$.headers.get("Content-Length");if(Z===null||!/^\s*\d+\s*$/.test(Z))return null;return Number(Z)}function R8($,Z){let j=LF($);if(j!==null&&j>Z)throw new k$(Z)}function S3($,Z,j={}){let J=RZ.get($);if(J)J.limit=Z;else{let W={limit:Z,read:0,stream:void 0,used:!1};RZ.set($,W),HF($,W)}if(j.checkDeclared!==!1)R8($,Z)}function NF($){return Reflect.get(Object.getPrototypeOf($),"body",$)??null}function E8($,Z){if(Z.stream!==void 0)return Z.stream;let j=NF($);if(!j)return Z.stream=null;let J;return Z.stream=new ReadableStream({async pull(W){J??=j.getReader();let{done:Y,value:z}=await J.read();if(Y){W.close();return}if(Z.read+=z.byteLength,Z.read>Z.limit){let X=new k$(Z.limit);W.error(X),J.cancel(X).catch(()=>{});return}W.enqueue(z)},cancel(W){return J?J.cancel(W):j.cancel(W)}},{highWaterMark:0}),Z.stream}async function w$($,Z){if(R8($,Z.limit),Z.used||Z.stream?.locked)throw TypeError("Body already used");Z.used=!0;let j=E8($,Z);if(!j)return new Uint8Array(0);let J=j.getReader(),W=[],Y=0;for(;;){let{done:F,value:G}=await J.read();if(F)break;W.push(G),Y+=G.byteLength}let z=new Uint8Array(Y),X=0;for(let F of W)z.set(F,X),X+=F.byteLength;return z}function gJ($){return $.headers.get("Content-Type")??""}function HF($,Z){let j=(J,W)=>Object.defineProperty($,J,{configurable:!0,...W});j("body",{get:()=>E8($,Z)}),j("bodyUsed",{get:()=>Z.used||Boolean(Z.stream?.locked)||Reflect.get(Object.getPrototypeOf($),"bodyUsed",$)}),j("bytes",{value:()=>w$($,Z)}),j("arrayBuffer",{value:async()=>{let J=await w$($,Z);return J.buffer.slice(J.byteOffset,J.byteOffset+J.byteLength)}}),j("text",{value:async()=>new TextDecoder().decode(await w$($,Z))}),j("json",{value:async()=>JSON.parse(new TextDecoder().decode(await w$($,Z)))}),j("blob",{value:async()=>new Blob([await w$($,Z)],{type:gJ($)})}),j("formData",{value:async()=>new Response(await w$($,Z),{headers:{"Content-Type":gJ($)}}).formData()}),j("clone",{value:()=>{R8($,Z.limit);let J=E8($,Z),W=null;if(J){let[Y,z]=J.tee();Z.stream=Y,W=z}return new Request($.url,{method:$.method,headers:$.headers,body:W,signal:$.signal,duplex:"half"})}})}function cJ($){return _3($)}class j0{method;handler;methodName;__internal_brand="RouteHandler";middlewares=[];constructor($,Z,j){this.method=$;this.handler=Z;this.methodName=j;this.handler=Z,this.methodName=j,this.method=$}get source(){if(!cJ(this.handler)||typeof this.methodName!=="string")return;return{controller:this.handler,methodName:this.methodName}}__internal_use(){return{run:this.run.bind(this),middlewares:this.middlewares}}run($){if(cJ(this.handler)){let Z=new this.handler;return Z[this.methodName].bind(Z)()}return this.handler()}middleware($){return this.middlewares=O1($),this}}class uJ{url;headers;__internal_brand="ProxyHandler";middlewares=[];constructor($,Z){this.url=$;this.headers=Z}middleware($){return this.middlewares=O1($),this}async run(){let $=new x,Z=$.headers.toJSON();for(let j of dJ($.rawRequest))delete Z[j];try{return await fetch(this.url,{method:$.rawRequest.method,headers:{...Z,...this.headers},body:$.rawRequest.body})}catch(j){if(hJ($.rawRequest))throw new k$(pJ($.rawRequest));throw j}}}class lJ{constructor(...$){return new j0(...$)}}class iJ extends j0{__internal_brand="StreamHandler";async run($){let Z=H.getStore(),j=Z?.req?.rawRequest,J=b8(j?.headers.get("Range"));if(Z)Z.rangeRequest=J;try{let W=await super.run($);return await A8(W,{range:J,method:j?.method})}catch(W){if(W instanceof v8)return EZ(W.total);throw W}finally{if(Z)Z.rangeRequest=null}}}class sJ{constructor(...$){return new iJ(...$)}}class nJ{__internal_brand="ResourceRoutes";first;second;constructor($){this.first={get:new j0("GET",$,"list"),post:new j0("POST",$,"store")},this.second={get:new j0("GET",$,"show"),put:new j0("PUT",$,"update"),delete:new j0("DELETE",$,"delete")}}middleware($){if($.list)this.first.get.middleware($.list);if($.store)this.first.post.middleware($.store);if($.show)this.second.get.middleware($.show);if($.update)this.second.put.middleware($.update);if($.delete)this.second.delete.middleware($.delete);return this}}class A0{static __brand="ApiRouter";routes={};middlewares=[];middleware($){}get($,Z){return new j0("GET",$,Z)}post($,Z){return new j0("POST",$,Z)}put($,Z){return new j0("PUT",$,Z)}patch($,Z){return new j0("PATCH",$,Z)}delete($,Z){return new j0("DELETE",$,Z)}resource($){return new nJ($)}agent($){if($.kind!=="agent-controller")throw TypeError(`this.agent() takes an AgentController class, and got ${CF($)}.`);return _F($,this)}file($,Z){return new lJ("GET",$,Z)}stream($,Z){return new sJ("GET",$,Z)}proxy($,Z={}){return new uJ($,Z)}}function CF($){if(typeof $==="function"&&$.name)return $.name;return typeof $}function _F($,Z){let j={stream:new j0("POST",$,"stream"),attach:new j0("POST",$,"attach"),stop:new j0("POST",$,"stop"),upload:new j0("POST",$,"upload")};return class extends A0{static __internal_brand="AgentRoute";static controller=$;static handlers=j;constructor(){super();this.middlewares=[...Z?.middlewares??[]]}routes={"/":j.stream,"/attach":j.attach,"/stop":j.stop,"/files":j.upload};static middleware(W){if(W.stream)j.stream.middleware(W.stream);if(W.attach)j.attach.middleware(W.attach);if(W.stop)j.stop.middleware(W.stop);if(W.upload)j.upload.middleware(W.upload);return this}}}class w8{as;input;bind;__internal_brand="McpModelParam";constructor($,Z,j){this.as=$;this.input=Z;this.bind=j}}class k8{method;url;meta;__internal_brand="McpRoute";constructor($,Z,j){this.method=$;this.url=Z;this.meta=j}}class oJ{static __brand="McpRouter";routes={};scopes;param($){return new w8($.as,$.input,$.bind)}fromApiRoute($,Z,j){return new k8($,Z,j)}}function G0($,Z){return $.replace(/:([^/]+[*?]?)/g,(j,J)=>{let W=J.endsWith("?")||J.endsWith("*"),Y=W?J.slice(0,-1):J,z=Z[Y];if(z===void 0){if(W)return"";if(import.meta.env.DEV)throw Error(`Missing parameter: ${Y}`);console.error(`Missing parameter: ${Y} in URL: ${$}`)}return String(z)}).replace(/\/\//g,"/").replace(/\/$/,"")}class y8 extends P0{constructor($,Z=307){super("Redirect error");this.name="RedirectError",this.payload={api:{status:200,data:{},directive:{kind:"Redirect",path:$}},view:{status:Z,headers:{"Cache-Control":"private, no-cache, no-store, max-age=0, must-revalidate",Location:$}}}}}class B1{static to($,...Z){let[j={}]=Z,{search:J={},params:W={},permanent:Y,status:z}={params:{},status:307,permanent:!1,...j},X=new URLSearchParams(J).toString();throw new y8([G0($,W)||"/",X.toString()].filter(Boolean).join("?"),z??(Y?301:307))}static external($,Z=307){throw new y8($,Z)}}var aJ=Symbol.for("gemi.HttpResponse");class $${kind;body;status;headers;[aJ]=!0;constructor($,Z,j,J){this.kind=$;this.body=Z;this.status=j;this.headers=J}static json($,Z={}){let j=Z.status??200;return xF(j),new $$("json",$,j,new Headers(Z.headers))}static error($,Z,j={}){if(!Number.isInteger($)||$<400||$>599)throw RangeError(`HttpResponse.error: status must be an integer from 400 to 599, got ${$}.`);return $$.json({error:Z},{...j,status:$})}get ok(){return this.status>=200&&this.status<300}toResponse($,Z){let j=$,J=this.serialize(j);for(let W of Z)j.append("Set-Cookie",W);this.headers.forEach((W,Y)=>{if(Y.toLowerCase()!=="set-cookie")j.set(Y,W)});for(let W of this.headers.getSetCookie())j.append("Set-Cookie",W);if(this.status>=400&&!this.headers.has("Cache-Control"))j.set("Cache-Control","no-store");return new Response(J,{status:this.status,headers:j})}serialize($){switch(this.kind){case"json":return $.set("Content-Type","application/json"),JSON.stringify(this.body)??null}}}function xF($){if(!Number.isInteger($)||$<200||$>599)throw RangeError(`HttpResponse: status must be an integer from 200 to 599, got ${$}.`);if($===204||$===205||$===304)throw RangeError(`HttpResponse.json: a ${$} response has no body.`)}function y$($){return typeof $==="object"&&$!==null&&$[aJ]===!0}function SF($,Z,j={}){return $$.error($,Z,j)}class rJ{kind="redirect";viewPath="REDIRECT";middlewares=[];featureGates=[];handler;constructor($){if(!$)this.handler=()=>({});else if(typeof $==="function")this.handler=$;else{let[Z,j]=$;this.handler=(J)=>{return new Z()[j](J)}}}async run($,Z){let{destination:j,permanent:J=!1,status:W=307}=await this.handler($);if(!j)throw Error(`Redirect destination is required see ${Z}`);return B1.to(j,{permanent:J,status:W}),{}}middleware($){return this.middlewares=O1($),this}feature($){return this.featureGates=[...this.featureGates,$],this}}async function q8($,Z){if($ instanceof Response)return $;let j=$ instanceof Blob,J=j?$:$.file,W=j?$.name:$.name??$.file?.name,Y=(j?$.type:$.type??$.file?.type)||"",z=j?!1:$.download??!1,X=j?200:$.status??200;if(!j)for(let[F,G]of Object.entries($.headers??{}))Z.set(F,G);if(J instanceof Blob&&"exists"in J&&typeof J.exists==="function"){if(!await J.exists())return new Response("Not found",{status:404})}if(Z.set("Content-Type",Y||"application/octet-stream"),J instanceof Blob)Z.set("Content-Length",String(J.size));if(W)Z.set("Content-Disposition",x3(W,z));return new Response(J instanceof Blob?J.stream():J,{status:X,headers:Z})}class tJ{kind="file";viewPath="FILE";middlewares=[];featureGates=[];handler;constructor($){if(!$)this.handler=()=>null;else if(typeof $==="function")this.handler=$;else{let[Z,j]=$;this.handler=(J)=>{return new Z()[j](J)}}}async run($,Z){let j=await this.handler($);if(!j)throw Error(`File route handler must return a file see ${Z}`);return{FILE:j}}middleware($){return this.middlewares=O1($),this}feature($){return this.featureGates=[...this.featureGates,$],this}}function eJ($,Z){if(y$($))throw Error(`The handler of view "${Z}" returned an HttpResponse. HttpResponse is for api routes; a view handler returns its props.`);return $}class $5{viewPath;middlewares=[];featureGates=[];staticOptions=null;handler;constructor($,Z){this.viewPath=$;if(!Z)this.handler=()=>({});else if(typeof Z==="function")this.handler=Z;else{let[j,J]=Z;this.handler=(W)=>{return new j()[J](W)}}}async run($,Z){let j=eJ(await this.handler($),this.viewPath);return{[this.viewPath]:{...j,breadcrumb:{label:j?.breadcrumb??"",href:Z}}}}middleware($){return this.middlewares=O1($),this}static($={}){return this.staticOptions={...$},this}feature($){return this.featureGates=[...this.featureGates,$],this}}class Z5{viewPath;children;middlewares=[];featureGates=[];alwaysRuns=!1;handler=()=>({});constructor($,Z,j){this.viewPath=$;if(typeof Z==="function")this.handler=Z,this.children=class extends D1{routes=j??{}};else if(Array.isArray(Z)){let[J,W]=Z;this.handler=(Y)=>{return new J()[W](Y)},this.children=class extends D1{routes=j??{}}}else this.children=class extends D1{routes=Z},this.handler=()=>({})}async run($,Z){let j=eJ(await this.handler($),this.viewPath);return{[this.viewPath]:{...j,breadcrumb:{label:j?.breadcrumb??"",href:Z}}}}alwaysRun(){return this.alwaysRuns=!0,this}middleware($){return this.middlewares=O1($),this}feature($){return this.featureGates=[...this.featureGates,$],this}}class D1{middlewares=[];featureGates=[];routes={};view($,Z){return new $5($,Z)}file($){return new tJ($)}redirect($){return new rJ($)}layout($,Z,j){return new Z5($,Z,j)}}class o{req;static runsOnRefusal=!1;config={};constructor($){this.req=$}run(...$){return{}}static configure($){let Z=this;return class extends Z{config=$}}}function fF($){return $}function AF(){return{aliases:{},global:[],bodyLimit:null}}var U1="redirect";function V1($,Z="/"){if(typeof $!=="string"||!$.startsWith("/"))return Z;if(/[\u0000-\u001f\u007f\\]/.test($)||$.startsWith("//"))return Z;try{let j=new URL($,"http://gemi.invalid");if(j.origin!=="http://gemi.invalid")return Z;let J=`${j.search}${j.hash}`.replaceAll("/","%2F"),W=`${j.pathname}${J}`.replaceAll(":","%3A");return W.startsWith("//")?Z:W}catch{return Z}}function q$($){let Z=$.headers.get("x-forwarded-proto")?.split(",")[0]?.trim();return Z?Z==="https":new URL($.url).protocol==="https:"}function EF($,Z=!0){let j=new URL($.rawRequest.url),J=j.pathname.replace(/\.(json|og)$/,""),[,W,...Y]=J.split("/");if(T(a).supportedLocales.includes(W))J=`/${Y.join("/")}`;return Z?`${J}${j.search}`:J}function RF($,Z){let j=(J)=>J.replace(/\/+$/,"")||"/";return j($)===j(Z)}function f3($,Z){let j=Z||T(E).config.signInPath,J=/^[a-z][a-z\d+.-]*:/i.test(j);if(J?!/^https?:\/\//i.test(j):!j.startsWith("/"))throw Error(`\`auth.signInPath\` must be a path like "/auth/sign-in", or an http(s) URL for sign-in hosted elsewhere. Got "${j}". A route's own \`"auth:<path>"\` cannot carry a URL, because the alias parser splits it on the colon.`);let W=new URL(j,"http://gemi.invalid");if($?.kind==="view"){let Y=EF($,!J);if(J||!RF(new URL(Y,W).pathname,W.pathname))W.searchParams.set(U1,Y)}return J?W.href:`${W.pathname}${W.search}`}var b1="access_token";function vZ($){return $?.cookies?.get("access_token")||$?.headers?.get("access_token")||null}async function A3($,Z){let j=vZ(Z);if(!j)return null;return(await $.getSession(j,Z.headers.get("User-Agent")))?.user??null}class j5 extends o{async run($){let Z=H.getStore(),j=Z.req;if(Z.user)return{};let J=await A3(T(E),j);if(!J)throw new Z$({redirectTo:f3(j,$)});return Z.setUser(J),{}}}var m8="gemi_same_site",g8="private, no-cache, no-store, max-age=0, must-revalidate";class E3 extends o{run(){let $=H.getStore(),Z=$?.req;if(!Z||$.user)return{};let j=Z.rawRequest;if(Z.kind!=="view"||j.method!=="GET"&&j.method!=="HEAD")return{};let J=new URL(j.url);if(/\.(json|og)$/.test(J.pathname))return{};if(J.searchParams.has(m8))return{};if(vZ(Z))return{};let W=j.headers.get("Sec-Fetch-Site");if(W&&W!=="cross-site")return{};throw J.searchParams.set(m8,"1"),new J5(`${J.pathname}${J.search}`)}}class J5 extends P0{location;constructor($){super("Same-site bounce");this.location=$;this.name="SameSiteBounce";let Z=bF($),j={"Content-Type":"text/html; charset=utf-8","Cache-Control":g8,"Referrer-Policy":"no-referrer","X-Robots-Tag":"noindex"};this.payload={api:{status:401,data:{},headers:{"Cache-Control":g8}},viewData:{status:200,data:{},headers:{"Cache-Control":g8},directive:{kind:"Redirect",path:$}},view:{status:200,headers:j,body:`<!doctype html><html><head><meta charset="utf-8"><meta name="robots" content="noindex"><meta name="referrer" content="no-referrer"><meta http-equiv="refresh" content="0;url=${Z}"><title>Redirecting</title></head><body><p><a href="${Z}">Continue</a></p></body></html>`}}}}function bF($){return $.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}class W5 extends o{async run(...$){let[Z="public",j="864000",...J]=$,W=`${Z}, max-age=${j}${J.length>0?", ":""}${J.join(", ")}`;if($.length===0)W="public, max-age=864000, stale-while-revalidate=300, stale-if-error=600";if($.length===1&&$[0]==="public")W="public, max-age=864000, stale-while-revalidate=300, stale-if-error=600";if($.length===1&&$[0]==="private")W="private, max-age=0, stale-while-revalidate=300, stale-if-error=600";if(this.req.rawRequest.method==="GET")this.req.ctx().setHeaders("Cache-Control",W);return{}}}var Y5={"Access-Control-Allow-Methods":"GET, POST, PUT, DELETE, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization, X-Requested-With","Access-Control-Allow-Credentials":"true"};class z5 extends o{static runsOnRefusal=!0;config={origins:{"":{"Access-Control-Allow-Methods":"GET, HEAD, POST, PUT, DELETE, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization, X-Requested-With","Access-Control-Allow-Credentials":"true"}}};run(){let $=this.req,Z=$.rawRequest.headers.get("Origin");if(Z&&this.config.origins[Z]){$.ctx().setHeaders("Access-Control-Allow-Origin",Z);let j={...Y5,...this.config.origins[Z]};for(let[J,W]of Object.entries(j))$.ctx().setHeaders(J,W)}else if(Z&&this.config.origins["*"]){$.ctx().setHeaders("Access-Control-Allow-Origin","*");let j={...Y5,...this.config.origins["*"]};delete j["Access-Control-Allow-Credentials"];for(let[J,W]of Object.entries(j))$.ctx().setHeaders(J,W)}return{}}}class t0{config;static token="ratelimiter";constructor($){this.config=$}get driver(){return this.config.driver}async consume($,Z={}){let j=Z.limit??this.config.limit,J=Z.window??this.config.window,W=Z.cost??1;if(X5("window",J),X5("limit",j),!Number.isFinite(W)||W<0)throw Error(`Rate limiter cost must be zero or greater, got ${W}`);return await this.config.driver.consume({key:$,limit:j,window:J*1000,cost:W})}}function X5($,Z){if(!Number.isFinite(Z)||Z<=0)throw Error(`Rate limiter ${$} must be greater than zero, got ${Z}`)}class wZ extends P0{constructor($){super("Rate limit exceeded");let Z={"Content-Type":"application/json",...$?O5($):{}};this.payload={api:{status:429,data:{error:v1("rate_limit","Rate limit exceeded",429)},headers:Z},view:{error:{message:"Rate limit exceeded"},status:429,headers:Z}}}}class K5 extends o{async run($,Z){let j=vF();if(!j)return{};let J=await j.consume(this.key(),{limit:F5($)??this.config.limit,window:F5(Z)??this.config.window});if(this.config.headers!==!1){let W=this.req.ctx?.();if(W)for(let[Y,z]of Object.entries(O5(J)))W.setHeaders(Y,z)}if(!J.allowed)throw new wZ(J);return{}}key(){if(this.config.key)return this.config.key(this.req);let $=G5(this.req.rawRequest);if($)return`mcp:${$.via}:${$.id}:${this.req.routePath??"*"}`;return`${g$(this.req)}:${this.req.routePath??"*"}`}}function vF(){try{let $=T();return $.bound(t0)?$.make(t0):null}catch{return null}}function g$($){let Z=Q5($.rawRequest);if(Z!==void 0)return Z;let j=$.headers.get("x-forwarded-for");if(j){let[J]=j.split(",");if(J?.trim())return J.trim()}return $.headers.get("x-real-ip")?.trim()||"unknown"}function O5($){let Z={"X-RateLimit-Limit":String($.limit),"X-RateLimit-Remaining":String($.remaining),"X-RateLimit-Reset":String(Math.ceil($.resetAt/1000))};if(!$.allowed)Z["Retry-After"]=String(Math.max(1,Math.ceil($.retryAfter/1000)));return Z}function F5($){if($===void 0||$===null||$==="")return;let Z=Number($);if(!Number.isFinite(Z)||Z<=0)return;return Z}class D5 extends o{async run(){let $=this.req.cookies.get("csrf_token");if(!$)throw new p8;if(!["POST","PUT","PATCH","DELETE"].includes(this.req.rawRequest.method))return{};if(!Bun.CSRF.verify($,{secret:process.env.SECRET}))throw new p8;return{}}}class p8 extends P0{constructor(){super("Invalid CSRF token");this.name="InvalidCSRFTokenError"}payload={api:{status:403,data:{error:B5("csrf","Invalid CSRF token",403)}},view:{}}}class R3 extends o{run($){let Z=$??this.config.limit;if(Z===void 0||Z==="")throw Error('`body-limit` needs a size, as in "body-limit:64kb".');return S3(this.req.rawRequest,bZ(Z)),{}}}class U5{policiesList={};constructor(){let $=this.register();for(let Z of $){let j=new Z;this.policiesList[Z.name]=j}}register(){return[]}}class V5{all($,Z){return!0}}class h8{options;param;refuse;answers=new WeakMap;constructor($){this.options=$;this.param=$.param,this.refuse=$.refuse??"not_found"}refusal(){return this.refuse==="forbidden"?new m$:new b3}authorize($,Z){if(typeof Z==="number"&&Number.isFinite(Z))Z=String(Z);if(typeof Z!=="string"||Z==="")return Promise.reject(this.refusal());let j=this.answers.get($.rawRequest);if(!j)j=new Map,this.answers.set($.rawRequest,j);let J=j.get(Z);if(!J)J=this.decide($,Z),j.set(Z,J);return J}async allows($,Z){try{return await this.authorize($,Z),!0}catch(j){if(this.isRefusal(j))return!1;throw j}}fromRoute($=new x,Z=this.param){if(Z===void 0)throw Error('This resource policy has no `param`. Give `defineResourcePolicy` one, or name it: `fromRoute(req, "pageId")`, or `alias:pageId` on the middleware.');return this.authorize($,$.params?.[Z])}get middleware(){if(!this.middlewareClass){let $=(Z,j)=>this.fromRoute(Z,j||void 0);this.middlewareClass=class extends o{async run(j){await $(this.req,j)}}}return this.middlewareClass}middlewareClass;forAgent($){return{authorize:async(Z,{threadId:j,body:J})=>{let W;if(j!==void 0){if(W=$.thread?await $.thread(j,Z):null,W===null||W===void 0)throw this.refusal()}if(J!==void 0){let Y=await $.body(J,Z);if(await this.authorize(Z,Y),j!==void 0&&String(W)!==String(Y))throw this.refusal();return}if(j!==void 0)await this.authorize(Z,W)}}}async decide($,Z){let j=await this.options.load(Z,$);if(j===null||j===void 0||!await this.options.allow(j,$))throw this.refusal();return j}isRefusal($){return this.refuse==="forbidden"?$ instanceof m$:$ instanceof b3}}function wF($){return new h8($)}async function w3($,Z,j=!1){if(!$.body)return new Uint8Array;let[J,W]=await nF($.body),z=J.length>=2&&J[0]===31&&J[1]===139?W.pipeThrough(new DecompressionStream("gzip")):W;return sF(z,Z,j,$.url)}async function sF($,Z,j,J){let W=$.getReader(),Y=[],z=0;try{for(;;){let{done:G,value:Q}=await W.read();if(G)break;if(z+Q.byteLength>Z){if(!j)throw new v3(J,Z);Y.push(Q.subarray(0,Z-z)),z=Z;break}Y.push(Q),z+=Q.byteLength}}finally{W.cancel().catch(()=>{})}let X=new Uint8Array(z),F=0;for(let G of Y)X.set(G,F),F+=G.byteLength;return X}async function nF($){let Z=$.getReader(),j=await Z.read(),J=j.done?new Uint8Array:j.value,W=new ReadableStream({start(Y){if(j.done)Y.close();else Y.enqueue(J)},async pull(Y){let z=await Z.read();if(z.done)Y.close();else Y.enqueue(z.value)},cancel(Y){return Z.cancel(Y)}});return[J,W]}function k3($){return new TextDecoder("utf-8").decode($)}var oF={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&apos;"};function j$($){return $.replace(/[&<>"']/g,(Z)=>oF[Z])}var aF={amp:"&",lt:"<",gt:">",quot:'"',apos:"'"};function c8($){if(!$.includes("&"))return $;return $.replace(/&(#x[0-9a-fA-F]{1,6}|#[0-9]{1,7}|[a-zA-Z]{2,4});/g,(Z,j)=>{if(j[0]!=="#")return aF[j]??Z;let J=j[1]==="x"?parseInt(j.slice(2),16):parseInt(j.slice(1),10);return J>0&&J<=1114111?String.fromCodePoint(J):Z})}function d8($){let Z=$.indexOf(":");return(Z===-1?$:$.slice(Z+1)).toLowerCase()}function T5($,Z){let j=$.length,J=0;while(J<j){if(Z.stopped?.())return;let W=$.indexOf("<",J);if(W===-1){Z.text(c8($.slice(J)));return}if(W>J)Z.text(c8($.slice(J,W)));if($.startsWith("<!--",W)){let Y=$.indexOf("-->",W+4);if(Y===-1)return;J=Y+3}else if($.startsWith("<![CDATA[",W)){let Y=$.indexOf("]]>",W+9);if(Y===-1)return;Z.text($.slice(W+9,Y)),J=Y+3}else if($.startsWith("<?",W)){let Y=$.indexOf("?>",W+2);if(Y===-1)return;J=Y+2}else if($.startsWith("<!",W)){let Y=$.indexOf(">",W+2);if(Y===-1)return;let z=$.indexOf("[",W+2);if(z!==-1&&z<Y){let X=$.indexOf("]",z+1);if(X===-1)return;let F=$.indexOf(">",X+1);if(F===-1)return;J=F+1}else J=Y+1}else if($[W+1]==="/"){let Y=$.indexOf(">",W+2);if(Y===-1)return;Z.close(d8($.slice(W+2,Y).trim())),J=Y+1}else{let Y=rF($,W+1);if(Y===-1)return;let z=$.slice(W+1,Y),X=z.endsWith("/");if(X)z=z.slice(0,-1);let F=z.search(/[\s]|$/),G=d8(z.slice(0,F));if(G){if(Z.open(G,tF(z.slice(F)),X),X)Z.close(G)}J=Y+1}}}function rF($,Z){let j=null;for(let J=Z;J<$.length;J++){let W=$[J];if(j){if(W===j)j=null}else if(W==='"'||W==="'")j=W;else if(W===">")return J}return-1}function tF($){let Z={},j=/([^\s=]+)\s*=\s*(?:"([^"]*)"|'([^']*)')/g;for(let J of $.matchAll(j))Z[d8(J[1])]=c8(J[2]??J[3]??"");return Z}class J0 extends Error{url;status;constructor($,Z=null,j=null){super($);this.url=Z;this.status=j;this.name="SitemapError"}}var N5="http://www.sitemaps.org/schemas/sitemap/0.9",eF="http://www.w3.org/1999/xhtml",i8=`<?xml version="1.0" encoding="UTF-8"?>
2
+ import{cf as FF}from"./chunk-65beps2q.js";import{wf as XF}from"./chunk-m53fgf20.js";import{$f as Y8,Ag as qX,Bf as _X,Bg as nX,Cf as G5,Df as Q5,Dg as oX,Ef as b8,Ff as x8,If as S8,Jf as f8,Kf as CZ,Lf as JX,Mf as RX,Nf as dJ,Of as q,Tf as x,Uf as o8,Vf as m$,Wf as v8,Xf as b3,Zf as Z$,_f as h,ng as v3,ug as p$,xf as yZ,yg as Dz,zg as x$}from"./chunk-4acpw92g.js";import{Gg as _Z,Hg as P0,Ig as v1,Jg as B5}from"./chunk-cca0grq3.js";import{Kg as sz,Lg as D8,Mg as H}from"./chunk-m83zm86m.js";import{Pg as Gz,Sg as V3}from"./chunk-pspthd52.js";import{Wg as s5,Zg as hX}from"./chunk-19dpzp4y.js";import{ph as L3,uh as xZ}from"./chunk-yds7zwc3.js";import{Kh as mX}from"./chunk-meg8rtr6.js";import{Lh as P8}from"./chunk-h43jp8ws.js";import{Mh as xX,Nh as T1,Oh as W$,Ph as WF,Qh as YF,Sh as bJ,Th as iX,ai as zF}from"./chunk-s07v65x6.js";import{pi as Y$}from"./chunk-gc2dz11k.js";import{ui as NX,zi as PJ}from"./chunk-cskqet01.js";import{Gi as LX,Li as a}from"./chunk-fenc5tpv.js";import{Mi as HZ,Pi as T}from"./chunk-nz8z8jr1.js";import{Xi as TJ}from"./chunk-er8acmch.js";import{Yi as aX}from"./chunk-2n3pgfnb.js";import{hj as SX}from"./chunk-rhvc1axc.js";import{mj as U8}from"./chunk-tewhms9w.js";function _3($){return typeof $==="function"&&$.prototype!==void 0}function O1($){return typeof $==="string"?[$]:$}function x3($,Z){let j=Z?"attachment":"inline",J=$.replace(/["\\]/g,"").replace(/[^\x20-\x7e]/g,"_");return`${j}; filename="${J}"; filename*=UTF-8''${encodeURIComponent($)}`}function MF($){return"total"in $&&"partial"in $&&"body"in $}function yJ(){return new Response("Not found",{status:404,headers:{"X-Content-Type-Options":"nosniff"}})}function EZ($){return new Response(null,{status:416,headers:{"Accept-Ranges":"bytes","Content-Range":f8($),"Content-Length":"0","Cache-Control":"no-store","X-Content-Type-Options":"nosniff"}})}async function PF($){if($ instanceof Blob)return{body:$,start:0,end:$.size-1,total:$.size,partial:!1,type:$.type,name:$.name,download:!1,status:200,extraHeaders:{}};if(MF($))return{body:$.body,start:$.start,end:$.end,total:$.total,partial:$.partial,type:$.type,name:$.name,download:$.download??!1,etag:$.etag,lastModified:$.lastModified,status:$.status??200,extraHeaders:$.headers??{}};let Z=$.file,j=Z instanceof Blob?Z:null,J=$.total??j?.size??-1;return{body:Z,start:$.start??0,end:$.end??J-1,total:J,partial:$.partial??!1,type:$.type??j?.type??"",name:$.name??Z?.name,download:$.download??!1,etag:$.etag,lastModified:$.lastModified,status:$.status??200,extraHeaders:$.headers??{}}}async function A8($,Z){if($ instanceof Response)return $;if(!$)return yJ();let j=await PF($),{body:J,start:W,end:Y,total:z,partial:X}=j;if(J instanceof Blob&&"exists"in J&&typeof J.exists==="function"){if(!await J.exists())return yJ()}let{range:F}=Z;if(F){if(z<=0)return EZ(Math.max(z,0));if(!X){if(J instanceof Blob){let K=x8(F,z);if(!K)return EZ(z);J=J.slice(K.start,K.end+1),W=K.start,Y=K.end,X=!0}}}let G=Boolean(F)&&X,Q=G?206:j.status,O=new Headers;if(O.set("Accept-Ranges","bytes"),O.set("Content-Type",j.type||"application/octet-stream"),O.set("X-Content-Type-Options","nosniff"),G)O.set("Content-Range",S8(W,Y,z)),O.set("Content-Length",String(Y-W+1));else if(z>=0)O.set("Content-Length",String(z));if(j.name)O.set("Content-Disposition",x3(j.name,j.download));if(j.etag)O.set("ETag",j.etag);if(j.lastModified)O.set("Last-Modified",j.lastModified.toUTCString());for(let[K,D]of Object.entries(j.extraHeaders))O.set(K,D);if((Z.method??"GET").toUpperCase()==="HEAD"){if(J&&"cancel"in J&&typeof J.cancel==="function")await J.cancel();return new Response(null,{status:Q,headers:O})}return new Response(J,{status:Q,headers:O})}class k$ extends P0{limit;constructor($){super("The request body is too large.",{status:413});this.limit=$}}var qJ={b:1,k:1024,kb:1024,m:1048576,mb:1048576,g:1073741824,gb:1073741824};function bZ($){if(typeof $==="number"){if(Number.isFinite($)&&$>=0)return Math.floor($);if($===1/0)return 1/0}else{let Z=$.trim().toLowerCase();if(Z==="none"||Z==="off")return 1/0;let j=/^(\d+(?:\.\d+)?)\s*([a-z]*)$/.exec(Z);if(j&&(j[2]===""||(j[2]in qJ)))return Math.floor(Number(j[1])*(qJ[j[2]]??1))}throw Error(`Invalid body limit ${JSON.stringify($)}. Use a byte count or a size such as "64kb", "1mb" or "none".`)}var RZ=new WeakMap;function mJ($){return RZ.has($)}function pJ($){return RZ.get($)?.limit??null}function hJ($){let Z=RZ.get($);return Z?Z.read>Z.limit:!1}function LF($){let Z=$.headers.get("Content-Length");if(Z===null||!/^\s*\d+\s*$/.test(Z))return null;return Number(Z)}function R8($,Z){let j=LF($);if(j!==null&&j>Z)throw new k$(Z)}function S3($,Z,j={}){let J=RZ.get($);if(J)J.limit=Z;else{let W={limit:Z,read:0,stream:void 0,used:!1};RZ.set($,W),HF($,W)}if(j.checkDeclared!==!1)R8($,Z)}function NF($){return Reflect.get(Object.getPrototypeOf($),"body",$)??null}function E8($,Z){if(Z.stream!==void 0)return Z.stream;let j=NF($);if(!j)return Z.stream=null;let J;return Z.stream=new ReadableStream({async pull(W){J??=j.getReader();let{done:Y,value:z}=await J.read();if(Y){W.close();return}if(Z.read+=z.byteLength,Z.read>Z.limit){let X=new k$(Z.limit);W.error(X),J.cancel(X).catch(()=>{});return}W.enqueue(z)},cancel(W){return J?J.cancel(W):j.cancel(W)}},{highWaterMark:0}),Z.stream}async function w$($,Z){if(R8($,Z.limit),Z.used||Z.stream?.locked)throw TypeError("Body already used");Z.used=!0;let j=E8($,Z);if(!j)return new Uint8Array(0);let J=j.getReader(),W=[],Y=0;for(;;){let{done:F,value:G}=await J.read();if(F)break;W.push(G),Y+=G.byteLength}let z=new Uint8Array(Y),X=0;for(let F of W)z.set(F,X),X+=F.byteLength;return z}function gJ($){return $.headers.get("Content-Type")??""}function HF($,Z){let j=(J,W)=>Object.defineProperty($,J,{configurable:!0,...W});j("body",{get:()=>E8($,Z)}),j("bodyUsed",{get:()=>Z.used||Boolean(Z.stream?.locked)||Reflect.get(Object.getPrototypeOf($),"bodyUsed",$)}),j("bytes",{value:()=>w$($,Z)}),j("arrayBuffer",{value:async()=>{let J=await w$($,Z);return J.buffer.slice(J.byteOffset,J.byteOffset+J.byteLength)}}),j("text",{value:async()=>new TextDecoder().decode(await w$($,Z))}),j("json",{value:async()=>JSON.parse(new TextDecoder().decode(await w$($,Z)))}),j("blob",{value:async()=>new Blob([await w$($,Z)],{type:gJ($)})}),j("formData",{value:async()=>new Response(await w$($,Z),{headers:{"Content-Type":gJ($)}}).formData()}),j("clone",{value:()=>{R8($,Z.limit);let J=E8($,Z),W=null;if(J){let[Y,z]=J.tee();Z.stream=Y,W=z}return new Request($.url,{method:$.method,headers:$.headers,body:W,signal:$.signal,duplex:"half"})}})}function cJ($){return _3($)}class j0{method;handler;methodName;__internal_brand="RouteHandler";middlewares=[];constructor($,Z,j){this.method=$;this.handler=Z;this.methodName=j;this.handler=Z,this.methodName=j,this.method=$}get source(){if(!cJ(this.handler)||typeof this.methodName!=="string")return;return{controller:this.handler,methodName:this.methodName}}__internal_use(){return{run:this.run.bind(this),middlewares:this.middlewares}}run($){if(cJ(this.handler)){let Z=new this.handler;return Z[this.methodName].bind(Z)()}return this.handler()}middleware($){return this.middlewares=O1($),this}}class uJ{url;headers;__internal_brand="ProxyHandler";middlewares=[];constructor($,Z){this.url=$;this.headers=Z}middleware($){return this.middlewares=O1($),this}async run(){let $=new x,Z=$.headers.toJSON();for(let j of dJ($.rawRequest))delete Z[j];try{return await fetch(this.url,{method:$.rawRequest.method,headers:{...Z,...this.headers},body:$.rawRequest.body})}catch(j){if(hJ($.rawRequest))throw new k$(pJ($.rawRequest));throw j}}}class lJ{constructor(...$){return new j0(...$)}}class iJ extends j0{__internal_brand="StreamHandler";async run($){let Z=H.getStore(),j=Z?.req?.rawRequest,J=b8(j?.headers.get("Range"));if(Z)Z.rangeRequest=J;try{let W=await super.run($);return await A8(W,{range:J,method:j?.method})}catch(W){if(W instanceof v8)return EZ(W.total);throw W}finally{if(Z)Z.rangeRequest=null}}}class sJ{constructor(...$){return new iJ(...$)}}class nJ{__internal_brand="ResourceRoutes";first;second;constructor($){this.first={get:new j0("GET",$,"list"),post:new j0("POST",$,"store")},this.second={get:new j0("GET",$,"show"),put:new j0("PUT",$,"update"),delete:new j0("DELETE",$,"delete")}}middleware($){if($.list)this.first.get.middleware($.list);if($.store)this.first.post.middleware($.store);if($.show)this.second.get.middleware($.show);if($.update)this.second.put.middleware($.update);if($.delete)this.second.delete.middleware($.delete);return this}}class A0{static __brand="ApiRouter";routes={};middlewares=[];middleware($){}get($,Z){return new j0("GET",$,Z)}post($,Z){return new j0("POST",$,Z)}put($,Z){return new j0("PUT",$,Z)}patch($,Z){return new j0("PATCH",$,Z)}delete($,Z){return new j0("DELETE",$,Z)}resource($){return new nJ($)}agent($){if($.kind!=="agent-controller")throw TypeError(`this.agent() takes an AgentController class, and got ${CF($)}.`);return _F($,this)}file($,Z){return new lJ("GET",$,Z)}stream($,Z){return new sJ("GET",$,Z)}proxy($,Z={}){return new uJ($,Z)}}function CF($){if(typeof $==="function"&&$.name)return $.name;return typeof $}function _F($,Z){let j={stream:new j0("POST",$,"stream"),attach:new j0("POST",$,"attach"),stop:new j0("POST",$,"stop"),upload:new j0("POST",$,"upload")};return class extends A0{static __internal_brand="AgentRoute";static controller=$;static handlers=j;constructor(){super();this.middlewares=[...Z?.middlewares??[]]}routes={"/":j.stream,"/attach":j.attach,"/stop":j.stop,"/files":j.upload};static middleware(W){if(W.stream)j.stream.middleware(W.stream);if(W.attach)j.attach.middleware(W.attach);if(W.stop)j.stop.middleware(W.stop);if(W.upload)j.upload.middleware(W.upload);return this}}}class w8{as;input;bind;__internal_brand="McpModelParam";constructor($,Z,j){this.as=$;this.input=Z;this.bind=j}}class k8{method;url;meta;__internal_brand="McpRoute";constructor($,Z,j){this.method=$;this.url=Z;this.meta=j}}class oJ{static __brand="McpRouter";routes={};scopes;param($){return new w8($.as,$.input,$.bind)}fromApiRoute($,Z,j){return new k8($,Z,j)}}function G0($,Z){return $.replace(/:([^/]+[*?]?)/g,(j,J)=>{let W=J.endsWith("?")||J.endsWith("*"),Y=W?J.slice(0,-1):J,z=Z[Y];if(z===void 0){if(W)return"";if(import.meta.env.DEV)throw Error(`Missing parameter: ${Y}`);console.error(`Missing parameter: ${Y} in URL: ${$}`)}return String(z)}).replace(/\/\//g,"/").replace(/\/$/,"")}class y8 extends P0{constructor($,Z=307){super("Redirect error");this.name="RedirectError",this.payload={api:{status:200,data:{},directive:{kind:"Redirect",path:$}},view:{status:Z,headers:{"Cache-Control":"private, no-cache, no-store, max-age=0, must-revalidate",Location:$}}}}}class B1{static to($,...Z){let[j={}]=Z,{search:J={},params:W={},permanent:Y,status:z}={params:{},status:307,permanent:!1,...j},X=new URLSearchParams(J).toString();throw new y8([G0($,W)||"/",X.toString()].filter(Boolean).join("?"),z??(Y?301:307))}static external($,Z=307){throw new y8($,Z)}}var aJ=Symbol.for("gemi.HttpResponse");class $${kind;body;status;headers;[aJ]=!0;constructor($,Z,j,J){this.kind=$;this.body=Z;this.status=j;this.headers=J}static json($,Z={}){let j=Z.status??200;return xF(j),new $$("json",$,j,new Headers(Z.headers))}static error($,Z,j={}){if(!Number.isInteger($)||$<400||$>599)throw RangeError(`HttpResponse.error: status must be an integer from 400 to 599, got ${$}.`);return $$.json({error:Z},{...j,status:$})}get ok(){return this.status>=200&&this.status<300}toResponse($,Z){let j=$,J=this.serialize(j);for(let W of Z)j.append("Set-Cookie",W);this.headers.forEach((W,Y)=>{if(Y.toLowerCase()!=="set-cookie")j.set(Y,W)});for(let W of this.headers.getSetCookie())j.append("Set-Cookie",W);if(this.status>=400&&!this.headers.has("Cache-Control"))j.set("Cache-Control","no-store");return new Response(J,{status:this.status,headers:j})}serialize($){switch(this.kind){case"json":return $.set("Content-Type","application/json"),JSON.stringify(this.body)??null}}}function xF($){if(!Number.isInteger($)||$<200||$>599)throw RangeError(`HttpResponse: status must be an integer from 200 to 599, got ${$}.`);if($===204||$===205||$===304)throw RangeError(`HttpResponse.json: a ${$} response has no body.`)}function y$($){return typeof $==="object"&&$!==null&&$[aJ]===!0}function SF($,Z,j={}){return $$.error($,Z,j)}class rJ{kind="redirect";viewPath="REDIRECT";middlewares=[];featureGates=[];handler;constructor($){if(!$)this.handler=()=>({});else if(typeof $==="function")this.handler=$;else{let[Z,j]=$;this.handler=(J)=>{return new Z()[j](J)}}}async run($,Z){let{destination:j,permanent:J=!1,status:W=307}=await this.handler($);if(!j)throw Error(`Redirect destination is required see ${Z}`);return B1.to(j,{permanent:J,status:W}),{}}middleware($){return this.middlewares=O1($),this}feature($){return this.featureGates=[...this.featureGates,$],this}}async function q8($,Z){if($ instanceof Response)return $;let j=$ instanceof Blob,J=j?$:$.file,W=j?$.name:$.name??$.file?.name,Y=(j?$.type:$.type??$.file?.type)||"",z=j?!1:$.download??!1,X=j?200:$.status??200;if(!j)for(let[F,G]of Object.entries($.headers??{}))Z.set(F,G);if(J instanceof Blob&&"exists"in J&&typeof J.exists==="function"){if(!await J.exists())return new Response("Not found",{status:404})}if(Z.set("Content-Type",Y||"application/octet-stream"),J instanceof Blob)Z.set("Content-Length",String(J.size));if(W)Z.set("Content-Disposition",x3(W,z));return new Response(J instanceof Blob?J.stream():J,{status:X,headers:Z})}class tJ{kind="file";viewPath="FILE";middlewares=[];featureGates=[];handler;constructor($){if(!$)this.handler=()=>null;else if(typeof $==="function")this.handler=$;else{let[Z,j]=$;this.handler=(J)=>{return new Z()[j](J)}}}async run($,Z){let j=await this.handler($);if(!j)throw Error(`File route handler must return a file see ${Z}`);return{FILE:j}}middleware($){return this.middlewares=O1($),this}feature($){return this.featureGates=[...this.featureGates,$],this}}function eJ($,Z){if(y$($))throw Error(`The handler of view "${Z}" returned an HttpResponse. HttpResponse is for api routes; a view handler returns its props.`);return $}class $5{viewPath;middlewares=[];featureGates=[];staticOptions=null;handler;constructor($,Z){this.viewPath=$;if(!Z)this.handler=()=>({});else if(typeof Z==="function")this.handler=Z;else{let[j,J]=Z;this.handler=(W)=>{return new j()[J](W)}}}async run($,Z){let j=eJ(await this.handler($),this.viewPath);return{[this.viewPath]:{...j,breadcrumb:{label:j?.breadcrumb??"",href:Z}}}}middleware($){return this.middlewares=O1($),this}static($={}){return this.staticOptions={...$},this}feature($){return this.featureGates=[...this.featureGates,$],this}}class Z5{viewPath;children;middlewares=[];featureGates=[];alwaysRuns=!1;handler=()=>({});constructor($,Z,j){this.viewPath=$;if(typeof Z==="function")this.handler=Z,this.children=class extends D1{routes=j??{}};else if(Array.isArray(Z)){let[J,W]=Z;this.handler=(Y)=>{return new J()[W](Y)},this.children=class extends D1{routes=j??{}}}else this.children=class extends D1{routes=Z},this.handler=()=>({})}async run($,Z){let j=eJ(await this.handler($),this.viewPath);return{[this.viewPath]:{...j,breadcrumb:{label:j?.breadcrumb??"",href:Z}}}}alwaysRun(){return this.alwaysRuns=!0,this}middleware($){return this.middlewares=O1($),this}feature($){return this.featureGates=[...this.featureGates,$],this}}class D1{middlewares=[];featureGates=[];routes={};view($,Z){return new $5($,Z)}file($){return new tJ($)}redirect($){return new rJ($)}layout($,Z,j){return new Z5($,Z,j)}}class o{req;static runsOnRefusal=!1;config={};constructor($){this.req=$}run(...$){return{}}static configure($){let Z=this;return class extends Z{config=$}}}function fF($){return $}function AF(){return{aliases:{},global:[],bodyLimit:null}}var U1="redirect";function V1($,Z="/"){if(typeof $!=="string"||!$.startsWith("/"))return Z;if(/[\u0000-\u001f\u007f\\]/.test($)||$.startsWith("//"))return Z;try{let j=new URL($,"http://gemi.invalid");if(j.origin!=="http://gemi.invalid")return Z;let J=`${j.search}${j.hash}`.replaceAll("/","%2F"),W=`${j.pathname}${J}`.replaceAll(":","%3A");return W.startsWith("//")?Z:W}catch{return Z}}function q$($){let Z=$.headers.get("x-forwarded-proto")?.split(",")[0]?.trim();return Z?Z==="https":new URL($.url).protocol==="https:"}function EF($,Z=!0){let j=new URL($.rawRequest.url),J=j.pathname.replace(/\.(json|og)$/,""),[,W,...Y]=J.split("/");if(T(a).supportedLocales.includes(W))J=`/${Y.join("/")}`;return Z?`${J}${j.search}`:J}function RF($,Z){let j=(J)=>J.replace(/\/+$/,"")||"/";return j($)===j(Z)}function f3($,Z){let j=Z||T(E).config.signInPath,J=/^[a-z][a-z\d+.-]*:/i.test(j);if(J?!/^https?:\/\//i.test(j):!j.startsWith("/"))throw Error(`\`auth.signInPath\` must be a path like "/auth/sign-in", or an http(s) URL for sign-in hosted elsewhere. Got "${j}". A route's own \`"auth:<path>"\` cannot carry a URL, because the alias parser splits it on the colon.`);let W=new URL(j,"http://gemi.invalid");if($?.kind==="view"){let Y=EF($,!J);if(J||!RF(new URL(Y,W).pathname,W.pathname))W.searchParams.set(U1,Y)}return J?W.href:`${W.pathname}${W.search}`}var b1="access_token";function vZ($){return $?.cookies?.get("access_token")||$?.headers?.get("access_token")||null}async function A3($,Z){let j=vZ(Z);if(!j)return null;return(await $.getSession(j,Z.headers.get("User-Agent")))?.user??null}class j5 extends o{async run($){let Z=H.getStore(),j=Z.req;if(Z.user)return{};let J=await A3(T(E),j);if(!J)throw new Z$({redirectTo:f3(j,$)});return Z.setUser(J),{}}}var m8="gemi_same_site",g8="private, no-cache, no-store, max-age=0, must-revalidate";class E3 extends o{run(){let $=H.getStore(),Z=$?.req;if(!Z||$.user)return{};let j=Z.rawRequest;if(Z.kind!=="view"||j.method!=="GET"&&j.method!=="HEAD")return{};let J=new URL(j.url);if(/\.(json|og)$/.test(J.pathname))return{};if(J.searchParams.has(m8))return{};if(vZ(Z))return{};let W=j.headers.get("Sec-Fetch-Site");if(W&&W!=="cross-site")return{};throw J.searchParams.set(m8,"1"),new J5(`${J.pathname}${J.search}`)}}class J5 extends P0{location;constructor($){super("Same-site bounce");this.location=$;this.name="SameSiteBounce";let Z=bF($),j={"Content-Type":"text/html; charset=utf-8","Cache-Control":g8,"Referrer-Policy":"no-referrer","X-Robots-Tag":"noindex"};this.payload={api:{status:401,data:{},headers:{"Cache-Control":g8}},viewData:{status:200,data:{},headers:{"Cache-Control":g8},directive:{kind:"Redirect",path:$}},view:{status:200,headers:j,body:`<!doctype html><html><head><meta charset="utf-8"><meta name="robots" content="noindex"><meta name="referrer" content="no-referrer"><meta http-equiv="refresh" content="0;url=${Z}"><title>Redirecting</title></head><body><p><a href="${Z}">Continue</a></p></body></html>`}}}}function bF($){return $.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}class W5 extends o{async run(...$){let[Z="public",j="864000",...J]=$,W=`${Z}, max-age=${j}${J.length>0?", ":""}${J.join(", ")}`;if($.length===0)W="public, max-age=864000, stale-while-revalidate=300, stale-if-error=600";if($.length===1&&$[0]==="public")W="public, max-age=864000, stale-while-revalidate=300, stale-if-error=600";if($.length===1&&$[0]==="private")W="private, max-age=0, stale-while-revalidate=300, stale-if-error=600";if(this.req.rawRequest.method==="GET")this.req.ctx().setHeaders("Cache-Control",W);return{}}}var Y5={"Access-Control-Allow-Methods":"GET, POST, PUT, DELETE, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization, X-Requested-With","Access-Control-Allow-Credentials":"true"};class z5 extends o{static runsOnRefusal=!0;config={origins:{"":{"Access-Control-Allow-Methods":"GET, HEAD, POST, PUT, DELETE, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization, X-Requested-With","Access-Control-Allow-Credentials":"true"}}};run(){let $=this.req,Z=$.rawRequest.headers.get("Origin");if(Z&&this.config.origins[Z]){$.ctx().setHeaders("Access-Control-Allow-Origin",Z);let j={...Y5,...this.config.origins[Z]};for(let[J,W]of Object.entries(j))$.ctx().setHeaders(J,W)}else if(Z&&this.config.origins["*"]){$.ctx().setHeaders("Access-Control-Allow-Origin","*");let j={...Y5,...this.config.origins["*"]};delete j["Access-Control-Allow-Credentials"];for(let[J,W]of Object.entries(j))$.ctx().setHeaders(J,W)}return{}}}class t0{config;static token="ratelimiter";constructor($){this.config=$}get driver(){return this.config.driver}async consume($,Z={}){let j=Z.limit??this.config.limit,J=Z.window??this.config.window,W=Z.cost??1;if(X5("window",J),X5("limit",j),!Number.isFinite(W)||W<0)throw Error(`Rate limiter cost must be zero or greater, got ${W}`);return await this.config.driver.consume({key:$,limit:j,window:J*1000,cost:W})}}function X5($,Z){if(!Number.isFinite(Z)||Z<=0)throw Error(`Rate limiter ${$} must be greater than zero, got ${Z}`)}class wZ extends P0{constructor($){super("Rate limit exceeded");let Z={"Content-Type":"application/json",...$?O5($):{}};this.payload={api:{status:429,data:{error:v1("rate_limit","Rate limit exceeded",429)},headers:Z},view:{error:{message:"Rate limit exceeded"},status:429,headers:Z}}}}class K5 extends o{async run($,Z){let j=vF();if(!j)return{};let J=await j.consume(this.key(),{limit:F5($)??this.config.limit,window:F5(Z)??this.config.window});if(this.config.headers!==!1){let W=this.req.ctx?.();if(W)for(let[Y,z]of Object.entries(O5(J)))W.setHeaders(Y,z)}if(!J.allowed)throw new wZ(J);return{}}key(){if(this.config.key)return this.config.key(this.req);let $=G5(this.req.rawRequest);if($)return`mcp:${$.via}:${$.id}:${this.req.routePath??"*"}`;return`${g$(this.req)}:${this.req.routePath??"*"}`}}function vF(){try{let $=T();return $.bound(t0)?$.make(t0):null}catch{return null}}function g$($){let Z=Q5($.rawRequest);if(Z!==void 0)return Z;let j=$.headers.get("x-forwarded-for");if(j){let[J]=j.split(",");if(J?.trim())return J.trim()}return $.headers.get("x-real-ip")?.trim()||"unknown"}function O5($){let Z={"X-RateLimit-Limit":String($.limit),"X-RateLimit-Remaining":String($.remaining),"X-RateLimit-Reset":String(Math.ceil($.resetAt/1000))};if(!$.allowed)Z["Retry-After"]=String(Math.max(1,Math.ceil($.retryAfter/1000)));return Z}function F5($){if($===void 0||$===null||$==="")return;let Z=Number($);if(!Number.isFinite(Z)||Z<=0)return;return Z}class D5 extends o{async run(){let $=this.req.cookies.get("csrf_token");if(!$)throw new p8;if(!["POST","PUT","PATCH","DELETE"].includes(this.req.rawRequest.method))return{};if(!Bun.CSRF.verify($,{secret:process.env.SECRET}))throw new p8;return{}}}class p8 extends P0{constructor(){super("Invalid CSRF token");this.name="InvalidCSRFTokenError"}payload={api:{status:403,data:{error:B5("csrf","Invalid CSRF token",403)}},view:{}}}class R3 extends o{run($){let Z=$??this.config.limit;if(Z===void 0||Z==="")throw Error('`body-limit` needs a size, as in "body-limit:64kb".');return S3(this.req.rawRequest,bZ(Z)),{}}}class U5{policiesList={};constructor(){let $=this.register();for(let Z of $){let j=new Z;this.policiesList[Z.name]=j}}register(){return[]}}class V5{all($,Z){return!0}}class h8{options;param;refuse;answers=new WeakMap;constructor($){this.options=$;this.param=$.param,this.refuse=$.refuse??"not_found"}refusal(){return this.refuse==="forbidden"?new m$:new b3}authorize($,Z){if(typeof Z==="number"&&Number.isFinite(Z))Z=String(Z);if(typeof Z!=="string"||Z==="")return Promise.reject(this.refusal());let j=this.answers.get($.rawRequest);if(!j)j=new Map,this.answers.set($.rawRequest,j);let J=j.get(Z);if(!J)J=this.decide($,Z),j.set(Z,J);return J}async allows($,Z){try{return await this.authorize($,Z),!0}catch(j){if(this.isRefusal(j))return!1;throw j}}fromRoute($=new x,Z=this.param){if(Z===void 0)throw Error('This resource policy has no `param`. Give `defineResourcePolicy` one, or name it: `fromRoute(req, "pageId")`, or `alias:pageId` on the middleware.');return this.authorize($,$.params?.[Z])}get middleware(){if(!this.middlewareClass){let $=(Z,j)=>this.fromRoute(Z,j||void 0);this.middlewareClass=class extends o{async run(j){await $(this.req,j)}}}return this.middlewareClass}middlewareClass;forAgent($){return{authorize:async(Z,{threadId:j,body:J})=>{let W;if(j!==void 0){if(W=$.thread?await $.thread(j,Z):null,W===null||W===void 0)throw this.refusal()}if(J!==void 0){let Y=await $.body(J,Z);if(await this.authorize(Z,Y),j!==void 0&&String(W)!==String(Y))throw this.refusal();return}if(j!==void 0)await this.authorize(Z,W)}}}async decide($,Z){let j=await this.options.load(Z,$);if(j===null||j===void 0||!await this.options.allow(j,$))throw this.refusal();return j}isRefusal($){return this.refuse==="forbidden"?$ instanceof m$:$ instanceof b3}}function wF($){return new h8($)}async function w3($,Z,j=!1){if(!$.body)return new Uint8Array;let[J,W]=await nF($.body),z=J.length>=2&&J[0]===31&&J[1]===139?W.pipeThrough(new DecompressionStream("gzip")):W;return sF(z,Z,j,$.url)}async function sF($,Z,j,J){let W=$.getReader(),Y=[],z=0;try{for(;;){let{done:G,value:Q}=await W.read();if(G)break;if(z+Q.byteLength>Z){if(!j)throw new v3(J,Z);Y.push(Q.subarray(0,Z-z)),z=Z;break}Y.push(Q),z+=Q.byteLength}}finally{W.cancel().catch(()=>{})}let X=new Uint8Array(z),F=0;for(let G of Y)X.set(G,F),F+=G.byteLength;return X}async function nF($){let Z=$.getReader(),j=await Z.read(),J=j.done?new Uint8Array:j.value,W=new ReadableStream({start(Y){if(j.done)Y.close();else Y.enqueue(J)},async pull(Y){let z=await Z.read();if(z.done)Y.close();else Y.enqueue(z.value)},cancel(Y){return Z.cancel(Y)}});return[J,W]}function k3($){return new TextDecoder("utf-8").decode($)}var oF={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&apos;"};function j$($){return $.replace(/[&<>"']/g,(Z)=>oF[Z])}var aF={amp:"&",lt:"<",gt:">",quot:'"',apos:"'"};function c8($){if(!$.includes("&"))return $;return $.replace(/&(#x[0-9a-fA-F]{1,6}|#[0-9]{1,7}|[a-zA-Z]{2,4});/g,(Z,j)=>{if(j[0]!=="#")return aF[j]??Z;let J=j[1]==="x"?parseInt(j.slice(2),16):parseInt(j.slice(1),10);return J>0&&J<=1114111?String.fromCodePoint(J):Z})}function d8($){let Z=$.indexOf(":");return(Z===-1?$:$.slice(Z+1)).toLowerCase()}function T5($,Z){let j=$.length,J=0;while(J<j){if(Z.stopped?.())return;let W=$.indexOf("<",J);if(W===-1){Z.text(c8($.slice(J)));return}if(W>J)Z.text(c8($.slice(J,W)));if($.startsWith("<!--",W)){let Y=$.indexOf("-->",W+4);if(Y===-1)return;J=Y+3}else if($.startsWith("<![CDATA[",W)){let Y=$.indexOf("]]>",W+9);if(Y===-1)return;Z.text($.slice(W+9,Y)),J=Y+3}else if($.startsWith("<?",W)){let Y=$.indexOf("?>",W+2);if(Y===-1)return;J=Y+2}else if($.startsWith("<!",W)){let Y=$.indexOf(">",W+2);if(Y===-1)return;let z=$.indexOf("[",W+2);if(z!==-1&&z<Y){let X=$.indexOf("]",z+1);if(X===-1)return;let F=$.indexOf(">",X+1);if(F===-1)return;J=F+1}else J=Y+1}else if($[W+1]==="/"){let Y=$.indexOf(">",W+2);if(Y===-1)return;Z.close(d8($.slice(W+2,Y).trim())),J=Y+1}else{let Y=rF($,W+1);if(Y===-1)return;let z=$.slice(W+1,Y),X=z.endsWith("/");if(X)z=z.slice(0,-1);let F=z.search(/[\s]|$/),G=d8(z.slice(0,F));if(G){if(Z.open(G,tF(z.slice(F)),X),X)Z.close(G)}J=Y+1}}}function rF($,Z){let j=null;for(let J=Z;J<$.length;J++){let W=$[J];if(j){if(W===j)j=null}else if(W==='"'||W==="'")j=W;else if(W===">")return J}return-1}function tF($){let Z={},j=/([^\s=]+)\s*=\s*(?:"([^"]*)"|'([^']*)')/g;for(let J of $.matchAll(j))Z[d8(J[1])]=c8(J[2]??J[3]??"");return Z}class J0 extends Error{url;status;constructor($,Z=null,j=null){super($);this.url=Z;this.status=j;this.name="SitemapError"}}var N5="http://www.sitemaps.org/schemas/sitemap/0.9",eF="http://www.w3.org/1999/xhtml",i8=`<?xml version="1.0" encoding="UTF-8"?>
3
3
  `,I5=`<urlset xmlns="${N5}" xmlns:xhtml="${eF}">
4
4
  `,M5=`</urlset>
5
5
  `,J$=50000,kZ=52428800,P5=2048,$G=new Set(["always","hourly","daily","weekly","monthly","yearly","never"]),ZG=/^\d{4}(-\d{2}(-\d{2}(T\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:\d{2}))?)?)?$/,jG="application/xml; charset=utf-8",L5=new TextEncoder;function s8($,Z){let j;try{j=new URL($)}catch{throw new J0(`Sitemap: ${Z} "${$}" is not an absolute URL.`)}if(j.protocol!=="http:"&&j.protocol!=="https:")throw new J0(`Sitemap: ${Z} "${$}" is not an http(s) URL.`);let J=j.href;if(J.length>P5)throw new J0(`Sitemap: ${Z} is over ${P5} characters: "${J.slice(0,80)}\u2026".`);return J}function H5($,Z){if($ instanceof Date){if(Number.isNaN($.getTime()))throw new J0(`Sitemap: lastmod of ${Z} is an invalid Date.`);return $.toISOString()}if(!ZG.test($))throw new J0(`Sitemap: lastmod "${$}" of ${Z} is not a W3C datetime (e.g. "2026-10-07" or "2026-10-07T12:00:00Z").`);return $}function JG($){let Z=s8($.loc,"loc"),j=`<url><loc>${j$(Z)}</loc>`;if($.lastmod!=null)j+=`<lastmod>${j$(H5($.lastmod,Z))}</lastmod>`;if($.changefreq!=null){if(!$G.has($.changefreq))throw new J0(`Sitemap: changefreq "${$.changefreq}" of ${Z} is not one the protocol knows.`);j+=`<changefreq>${$.changefreq}</changefreq>`}if($.priority!=null){let J=$.priority;if(!Number.isFinite(J)||J<0||J>1)throw new J0(`Sitemap: priority ${J} of ${Z} is not between 0 and 1.`);j+=`<priority>${Number(J.toFixed(4))}</priority>`}for(let J of $.alternates??[]){let W=J.hrefLang?.trim();if(!W)throw new J0(`Sitemap: an alternate of ${Z} has no hrefLang.`);let Y=s8(J.href,`alternate href of ${Z}`);j+=`<xhtml:link rel="alternate" hreflang="${j$(W)}" href="${j$(Y)}"/>`}return`${j}</url>
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{Pb as eZ,Sb as t,Tb as Z3,ac as YZ}from"./chunk-mr94nfp1.js";import{lc as LZ,nc as ZZ,qc as B3,rc as I3,sc as N3,uc as O3}from"./chunk-9rr5h818.js";import{Bc as D3,Dc as K3,Fc as H3,Mc as D,Nc as U3,Oc as Q3,Qc as V3,wc as Y3}from"./chunk-dwedx1jb.js";import{Tc as J}from"./chunk-9xyxbxgk.js";import{He as l,Le as m,Me as zZ,Ne as AZ,Vd as p,de as P3,ee as qZ,id as T3,ie as r,md as v,pd as rZ,se as MZ,td as S3,ue as GZ,ye as kZ}from"./chunk-b5a5vvkk.js";import{Ag as i,Rf as b,Tf as CZ,gg as jZ,ug as gZ,yg as $Z,zg as a}from"./chunk-4acpw92g.js";import{Mg as aZ}from"./chunk-m83zm86m.js";import{Sg as DZ}from"./chunk-1xdrs2hx.js";import{Vg as x3,Wg as OZ,Zg as e,_g as SZ,bh as _3}from"./chunk-19dpzp4y.js";import{Ih as X3,Kh as k}from"./chunk-meg8rtr6.js";import{Lh as _}from"./chunk-h43jp8ws.js";import{Rh as L3}from"./chunk-s07v65x6.js";import{Fi as TZ}from"./chunk-1wnnkde0.js";import{Mi as F3,Pi as g}from"./chunk-nz8z8jr1.js";var R3="mcp",E3=/^[\x21\x23-\x5B\x5D-\x7E]+$/;class L extends YZ{status;constructor(Z,$){super(Z);this.status=$;this.name="McpToolError"}}class d extends Error{reason;constructor(Z,$){super(Z);this.reason=$;this.name="McpCallRefusedError"}}var w3=/^[A-Za-z0-9_-]{1,64}$/,b3=/:([A-Za-z_][A-Za-z0-9_]*)([?*+]?)/g,RZ=4000,y=1e5,y3=/^(text\/|application\/([\w.+-]*\+)?(json|xml))/i;class f{router;dispatcher;static token="router.mcp";plans=new Map;scopeTools=new Map;files;constructor(Z,$,G={}){this.router=Z;this.dispatcher=$;this.files=v3(G.files);for(let[W,z]of Object.entries(Z.routes??{}))this.plans.set(W,this.plan(W,z));this.resolveScopes()}list(Z,$){if(EZ(Z),Z.kind==="local")return this.descriptors($);let G=[];for(let[W,z]of this.plans){if(!z.remote||!this.grants(Z.principal,W))continue;if(wZ(z.remote,$))G.push(z.remote)}return G}descriptors(Z){let $=[];for(let{descriptor:G}of this.plans.values())if(wZ(G,Z))$.push(G);return $}get maxFileBytes(){return this.files.maxBytes}scopes(){return[...this.scopeTools].map(([Z,{description:$}])=>({name:Z,description:$}))}scopesFor(Z){return[...this.scopeTools].filter(([,{tools:$}])=>$.has(Z)).map(([$])=>$)}async execute(Z,$,G,W,z={}){EZ(Z);let X=this.plans.get($);if(Z.kind==="remote"){if(!X?.remote||!this.grants(Z.principal,$))throw new d(`There is no tool named "${$}".`,"unknown-tool");if(X.descriptor.requiresApproval&&z.approved!==!0)throw new d(`"${$}" needs the user's approval, and this call does not have it.`,"approval-required");W=void 0}if(!X)throw Error(`McpRegistry: there is no tool named "${$}".`);let Y=X,K=Z.kind==="remote"?Y.remote:Y.descriptor,U=K.inputSchema.safeParse(G);if(U.ok===!1)throw new L(`Invalid arguments for "${$}": ${U.errors.join(", ")}`);let H=U.value,Q={caller:Z,req:Z.req,tool:K,input:H,ctx:W},V=await this.fillPath(Y,Q),{path:I}=this.dispatcher.getRouteHandlerAndParams(new Request(`http://gemi.internal/api${V}`));if(I!==K.url)throw new L(`"${$}" has nothing at ${V}.`,404);let C={};for(let q of Y.jsonKeys)if(H[q]!==void 0)C[q]=H[q];let P,x="";if(Y.fileFields.length>0)P=await this.formData(Y,C,Q);else if(K.method==="GET")x=t3(C);else if(Y.jsonKeys.length>0)P=C;let j=this.router.credentials?await this.bind(Y,"the credentials",()=>this.router.credentials(Q)):void 0,w={...j?{credentials:j}:{},...z.signal?{signal:z.signal}:{},...z.progress?{progress:z.progress}:{},...Z.kind==="remote"?{identity:{user:Z.principal.user,grant:{via:Z.principal.via,id:Z.principal.id,scopes:Z.principal.scopes,...Z.principal.clientId?{clientId:Z.principal.clientId}:{}}}}:{}},u;try{let q=x?`${V}?${x}`:V;u=Object.keys(w).length>0?await this.dispatcher.dispatchAs(Z.req,K.method,q,P,w):await this.dispatcher.dispatchAs(Z.req,K.method,q,P)}catch(q){throw console.error(`[gemi/mcp] Dispatching "${$}" failed:`,q),new L(`"${$}" failed on the server.`,500)}if(!Y.result&&!K.outputSchema)return await vZ($,u);return await this.project(Y,Q,u)}plan(Z,$){if(!w3.test(Z))throw Error(`McpRouter: "${Z}" 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 G=`McpRouter: "${Z}" (${$?.method} ${$?.url})`;if(!($ instanceof Object)||$.__internal_brand!=="McpRoute")throw Error(`McpRouter: "${Z}" is not a route. Declare it with this.fromApiRoute(...).`);let{method:W,url:z,meta:X}=$;if(z.startsWith("/__gemi__"))throw Error(`${G} is a framework route, not an app route.`);let Y=this.dispatcher.flatRoutes[z]?.[W];if(!Y)throw Error(`${G} names no route of this app. Expose a route by the path and verb it is mounted at.`);let K=[...z.matchAll(b3)].map(([,B,A])=>({name:B,modifier:A})),U=X.params??{};for(let B of K)if(!(B.name in U))throw Error(`${G}: the path param "${B.name}" must be bound or declared "input".`);for(let[B,A]of Object.entries(U)){if(!K.some((M)=>M.name===B))throw Error(`${G}: "${B}" in params is not a param of the url.`);if(yZ(A))d3(G,`params.${B}`,A);else bZ(G,`params.${B}`,A)}let H=[],Q;if(X.input){if(Q=X.input.toJSONSchema(),Q.type!=="object"||!Q.properties)throw Error(`${G}: input must be an s.object(...), the fields of the request body.`);H=Object.keys(Q.properties)}let V=Object.entries(X.files??{}).map(([B,A])=>({name:B,binder:A}));for(let B of V)bZ(G,`files.${B.name}`,B.binder);if(X.result!==void 0&&typeof X.result!=="function")throw Error(`${G}: result must be a function.`);if(X.output!==void 0&&typeof X.output?.safeParse!=="function")throw Error(`${G}: output must be a schema, built with s.`);if(X.title!==void 0&&(typeof X.title!=="string"||X.title===""))throw Error(`${G}: title must be a non-empty string.`);let I=i3(G,W,X.annotations);if(V.length>0&&W==="GET")throw Error(`${G}: a GET has no body to carry a file.`);let C={},P=(B,A)=>{if(B in C)throw Error(`${G}: "${B}" is the input key of two params or files, and the model can only send one.`);C[B]=A},x=new Map,j=new Map;for(let B of K){let A=U[B.name];if(A==="input"){let M=b.string().describe(`The ":${B.name}" segment of the url.`);P(B.name,B.modifier==="?"||B.modifier==="*"?M.optional():M)}else if(yZ(A)){let M=A.as??B.name;P(M,A.input),j.set(B.name,{key:M,param:A})}else x.set(B.name,A)}let w={};for(let B of V)if(B.binder==="input")P(B.name,b.string().describe("The id of an attachment the user uploaded or a tool produced (gemi_att_\u2026), whose file is sent as this field.")),w[B.name]=this.remoteFileSchema();let u=[...Object.keys(C),...V.map((B)=>B.name)];for(let B of new Set(u))if(H.includes(B))throw Error(`${G}: "${B}" is both an input field and a param or file, and the model can only send one.`);let q=Object.freeze({name:Z,description:X.description,method:W,url:z,inputSchema:fZ(X.input,Q,b.object(C)),...X.output?{outputSchema:X.output}:{},...X.title?{title:X.title}:{},annotations:I,tags:Object.freeze([...X.tags??[]]),requiresApproval:X.requiresApproval===!0,...Y.source?{source:Y.source}:{}}),k3=!V.every((B)=>B.binder==="input")?null:V.length===0?q:Object.freeze({...q,inputSchema:fZ(X.input,Q,b.object(l3(C,Object.keys(w))),w)});return{descriptor:q,remote:k3,params:K,paramBinders:x,modelParams:j,fileFields:V,jsonKeys:H,...X.result?{result:X.result}:{}}}remoteFileSchema(){let{maxBytes:Z,fetch:$}=this.files,G={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 ${Z} bytes decoded.`}};if($)G.url={type:"string",format:"uri",description:"An https URL the server downloads the file from, instead of data."};let W={type:"object",description:$?"A file, sent as base64 in data or fetched from url: exactly one of the two.":"A file, sent as base64 in data.",properties:G,required:["name","mimeType"],additionalProperties:!1},z=Object.keys(G),X=(Y)=>{if(typeof Y!=="object"||Y===null||Array.isArray(Y))return{ok:!1,errors:["a file must be an object"]};let K=[],U={};for(let H of Object.keys(Y))if(!z.includes(H))K.push(`a file has no field "${H}"`);for(let H of z){let Q=Y[H];if(Q===void 0||Q===null){if(H==="name"||H==="mimeType")K.push(`a file needs "${H}"`);continue}if(typeof Q!=="string")K.push(`a file's "${H}" must be a string`);else U[H]=Q}return K.length>0?{ok:!1,errors:K}:{ok:!0,value:U}};return{toJSONSchema:()=>W,safeParse:X,parse(Y){let K=X(Y);if(K.ok===!1)throw Error(K.errors.join(", "));return K.value}}}async fillPath(Z,$){let{input:G,req:W}=$,z=Z.descriptor.url;for(let X of Z.params){let Y=Z.paramBinders.get(X.name),K=Z.modelParams.get(X.name),U;if(Y||K){if(U=K?await this.bind(Z,`the param "${X.name}"`,()=>K.param.bind(G[K.key],W,$),{refusals:!0}):await this.bind(Z,`the param "${X.name}"`,()=>Y(W,$)),U===void 0||U===null||U==="")throw console.error(`[gemi/mcp] The ${K?"resolver":"binder"} for "${X.name}" of "${Z.descriptor.name}" returned ${JSON.stringify(U)}.`),new L(`"${Z.descriptor.name}" failed on the server.`,500)}else U=G[X.name];let H=`:${X.name}${X.modifier}`;if(U===void 0||U===null||U===""){if(X.modifier!=="?"&&X.modifier!=="*")throw new L(`"${X.name}" of "${Z.descriptor.name}" must not be empty.`);z=z.replace(`/${H}`,"");continue}z=z.replace(H,n3(Z.descriptor.name,X,String(U)))}return z}async formData(Z,$,G){let{input:W,ctx:z}=G,X=Z.descriptor.name;if(G.caller.kind==="remote"){let K=new FormData;for(let[U,H]of Object.entries($))XZ(K,U,H);for(let U of Z.fileFields)K.append(U.name,await this.remoteFile(X,U.name,W[U.name]));return K}if(!z)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,U]of Object.entries($))XZ(Y,K,U);for(let K of Z.fileFields){let U=K.binder==="input"?W[K.name]:await this.bind(Z,`the file "${K.name}"`,()=>K.binder(z,G));if(typeof U!=="string"||U==="")throw new L(`"${X}" needs a file for "${K.name}", and this turn has none. Ask the user to attach one.`);Y.append(K.name,await z.attachments.file(U))}return Y}async remoteFile(Z,$,G){let W=(Q)=>new L(`"${$}" of "${Z}" ${Q}`,400),z=G,{maxBytes:X,fetch:Y}=this.files;if(!g3(z.name))throw W("needs a name of 1 to 255 characters, without control characters or slashes.");if(!h3.test(z.mimeType))throw W(`has a mimeType that is not a media type: "${z.mimeType.slice(0,100)}".`);let K=typeof z.data==="string",U=typeof z.url==="string";if(K===U)throw W(Y?"needs exactly one of data or url.":"needs its bytes, base64, in data.");if(K){let Q=z.data.replace(/\s+/g,"");if(Math.floor(Q.length*3/4)-u3(Q)>X)throw W(`is larger than the ${X} bytes a file may be.`);if(Q.length%4!==0||!m3.test(Q))throw W("has data that is not base64 (RFC 4648, standard alphabet, padded).");return new File([Buffer.from(Q,"base64")],z.name,{type:z.mimeType})}if(!Y)throw W("cannot be fetched from a URL here. Send its bytes, base64, in data.");let H;try{H=new URL(z.url)}catch{throw W("has a url that is not a URL.")}if(H.protocol!=="https:")throw W("can only be fetched from an https URL.");try{let Q=await gZ(H.href,{...Y,maxSize:Math.min(Y.maxSize??X,X),redirect:"follow"});if(!Q.ok)throw W(`could not be fetched: ${H.host} answered ${Q.status}.`);let V=await Q.arrayBuffer();return new File([V],z.name,{type:z.mimeType})}catch(Q){if(Q instanceof L)throw Q;throw W(`could not be fetched from ${H.host}: ${Q instanceof Error?Q.message:"failed"}.`)}}grants(Z,$){for(let G of Z.scopes??[])if(this.scopeTools.get(G)?.tools.has($))return!0;return!1}resolveScopes(){let Z=this.router.scopes;if(Z===void 0){this.scopeTools.set(R3,{description:"Use this app's tools as you",tools:new Set(this.plans.keys())});return}if(typeof Z!=="object"||Z===null)throw Error("McpRouter: scopes must be an object of scope names.");let $=new Set([...this.plans.values()].flatMap(({descriptor:G})=>G.tags));for(let[G,W]of Object.entries(Z)){let z=`McpRouter: scope "${G}"`;if(!E3.test(G))throw Error(`${z} is not a valid OAuth scope: printable ASCII, no spaces or quotes.`);if(typeof W?.description!=="string"||W.description==="")throw Error(`${z} needs a description: it is what a consent screen shows.`);let X=new Set;for(let Y of W.tags??[]){if(!$.has(Y))throw Error(`${z} names the tag "${Y}", which no tool has.`);for(let[K,{descriptor:U}]of this.plans)if(U.tags.includes(Y))X.add(K)}for(let Y of W.names??[]){if(!this.plans.has(Y))throw Error(`${z} names "${Y}", which is no tool.`);X.add(Y)}if(X.size===0)throw Error(`${z} reaches no tool. Give it tags or names.`);this.scopeTools.set(G,{description:W.description,tools:X})}}async project(Z,$,G){let{name:W,outputSchema:z}=Z.descriptor;if(G.status<200||G.status>=300)return await vZ(W,G);let X=(V,I)=>{if(I===void 0)console.error(`[gemi/mcp] "${W}" ${V}`);else console.error(`[gemi/mcp] "${W}" ${V}`,I);return new L(`"${W}" failed on the server.`,500)},Y=G.headers.get("Content-Type"),K=await G.text(),U=null;if(K!=="")try{U=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 H=U;if(Z.result)try{H=await Z.result(U,$)}catch(V){throw X("failed in its result projection:",V)}if(z){let V=z.safeParse(H);if(V.ok===!1)throw X(`answered what its output schema refuses: ${V.errors.join(", ")}`);H=V.value}if(H===void 0)return null;let Q=JSON.stringify(H);if(Q!==void 0&&Q.length>y)return`${Q.slice(0,y)}\u2026 [cut at ${y} of ${Q.length} characters]`;return H}async bind(Z,$,G,W={}){try{return await G()}catch(z){if(W.refusals&&z instanceof YZ)throw z;throw console.error(`[gemi/mcp] Binding ${$} of "${Z.descriptor.name}" failed:`,z),new L(`"${Z.descriptor.name}" failed on the server.`,500)}}}function EZ(Z){if(Z?.kind==="local"&&Z.req)return;if(Z?.kind==="remote"&&Z.req&&Z.principal?.user&&typeof Z.principal.id==="string"&&Array.isArray(Z.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 wZ(Z,$){if($?.names&&!$.names.includes(Z.name))return!1;if($?.tags&&!Z.tags.some((G)=>$.tags.includes(G)))return!1;return!0}var f3=10485760;function v3(Z){let $=Z?.maxBytes??f3;if(!Number.isSafeInteger($)||$<=0)throw Error("McpRegistry: files.maxBytes must be a positive whole number of bytes.");let G=Z?.fetchUrls===!0?{}:typeof Z?.fetchUrls==="object"&&Z.fetchUrls!==null?Z.fetchUrls:null;return{maxBytes:$,fetch:G}}function g3(Z){if(Z.length===0||Z.length>255)return!1;for(let $ of Z){let G=$.codePointAt(0);if(G<32||G===127||$==="/"||$==="\\")return!1}return!0}var h3=/^[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}\/[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}(\s*;.{0,200})?$/,m3=/^[A-Za-z0-9+/]*={0,2}$/;function u3(Z){return Z.endsWith("==")?2:Z.endsWith("=")?1:0}function bZ(Z,$,G){if(G!=="input"&&typeof G!=="function")throw Error(`${Z}: ${$} must be a function or "input".`)}function yZ(Z){return Z instanceof Object&&Z.__internal_brand==="McpModelParam"}function d3(Z,$,G){if(G.as!==void 0&&(typeof G.as!=="string"||G.as===""))throw Error(`${Z}: ${$}.as must be a non-empty string.`);let W=G.input;if(typeof W?.safeParse!=="function"||typeof W.toJSONSchema!=="function")throw Error(`${Z}: ${$}.input must be a schema, built with s.`);if(typeof G.bind!=="function")throw Error(`${Z}: ${$}.bind must be a function.`)}var c3=new Set(["readOnlyHint","destructiveHint","idempotentHint","openWorldHint"]);function p3(Z){switch(Z){case"GET":return{readOnlyHint:!0};case"DELETE":return{destructiveHint:!0};case"PUT":return{idempotentHint:!0};default:return{}}}function i3(Z,$,G){if(G!==void 0&&(typeof G!=="object"||G===null))throw Error(`${Z}: annotations must be an object of hints.`);let W=p3($);for(let[z,X]of Object.entries(G??{})){if(!c3.has(z))throw Error(`${Z}: "${z}" is not a tool annotation. Use readOnlyHint, destructiveHint, idempotentHint or openWorldHint.`);if(X===void 0)continue;if(typeof X!=="boolean")throw Error(`${Z}: annotations.${z} must be true or false.`);W[z]=X}if(W.readOnlyHint===!0&&(W.destructiveHint||W.idempotentHint))throw Error(`${Z} is read-only${G?.readOnlyHint?"":` (a ${$})`} and also ${W.destructiveHint?"destructive":"idempotent"}, which only a tool that is not read-only can be. Set readOnlyHint: false if it changes something.`);return Object.freeze(W)}function fZ(Z,$,G,W={}){let z=G.toJSONSchema(),X=Object.fromEntries(Object.entries(W).map(([U,H])=>[U,H.toJSONSchema()])),Y={...$??{},type:"object",properties:{...$?.properties??{},...z.properties,...X},required:[...$?.required??[],...z.required??[],...Object.keys(W)],additionalProperties:!1},K=(U)=>{if(typeof U!=="object"||U===null||Array.isArray(U))return{ok:!1,errors:["expected an object"]};let H=[],Q={};if(Z){let I=Z.safeParse(U);if(I.ok===!1)H.push(...I.errors);else Q={...I.value}}let V=G.safeParse(U);if(V.ok===!1)H.push(...V.errors);else Q={...Q,...V.value};for(let[I,C]of Object.entries(W)){let P=U[I];if(P===void 0){H.push(`"${I}" is required`);continue}let x=C.safeParse(P);if(x.ok===!1)H.push(...x.errors.map((j)=>`${I}: ${j}`));else Q[I]=x.value}return H.length>0?{ok:!1,errors:H}:{ok:!0,value:Q}};return{toJSONSchema:()=>Y,safeParse:K,parse(U){let H=K(U);if(H.ok===!1)throw Error(H.errors.join(", "));return H.value}}}function l3(Z,$){return Object.fromEntries(Object.entries(Z).filter(([G])=>!$.includes(G)))}function n3(Z,$,G){let W=$.modifier==="*"||$.modifier==="+"?G.split("/"):[G];if(W.some((z)=>z==="."||z===".."))throw new L(`"${G}" is not a valid value for "${$.name}" of "${Z}".`);return W.map(encodeURIComponent).join("/")}function XZ(Z,$,G){if(G===void 0||G===null)return;if(Array.isArray(G)){for(let W of G)XZ(Z,$,W);return}Z.append($,typeof G==="object"?JSON.stringify(G):String(G))}function t3(Z){let $=new URLSearchParams,G=(W,z)=>{if(z===void 0||z===null)return;if(Array.isArray(z)){for(let X of z)G(W,X);return}$.append(W,typeof z==="object"?JSON.stringify(z):String(z))};for(let[W,z]of Object.entries(Z))G(W,z);return $.toString()}async function vZ(Z,$){if($.status>=200&&$.status<300){let W=$.headers.get("Content-Type");if(W&&!y3.test(W)){let X=(await $.arrayBuffer()).byteLength;return`"${Z}" answered with ${X} bytes of ${W}, which is not shown.`}let z=await $.text();if(z==="")return null;if(z.length>y)return`${z.slice(0,y)}\u2026 [cut at ${y} of ${z.length} characters]`;try{return JSON.parse(z)}catch{return z}}let G=await $.text();if($.status>=400&&$.status<500){let W=G.length>RZ?`${G.slice(0,RZ)}\u2026`:G;throw new L(`"${Z}" was refused with ${$.status}${W?`: ${W}`:"."}`,$.status)}if($.status<500)console.error(`[gemi/mcp] "${Z}" answered ${$.status}${$.headers.get("Location")?` to ${$.headers.get("Location")}`:""}, which a tool call cannot follow.`);throw new L(`"${Z}" failed on the server.`,$.status)}import{createHash as s3,randomBytes as o3,timingSafeEqual as a3}from"crypto";function KZ(Z){let $=Z.headers.get("authorization");if(!$)return null;let G=/^Bearer[ ]+([\x21-\x7e]+)$/i.exec($.trim());return G?G[1]:null}class r3{options;name="api-key";constructor(Z){this.options=Z;if(typeof Z?.prefix!=="string"||!/^[A-Za-z0-9_-]{3,32}$/.test(Z.prefix))throw Error('McpApiKeyResolver: prefix is required: 3 to 32 letters, digits, _ or -, like "myapp_mcp_".');if(typeof Z.verify!=="function")throw Error("McpApiKeyResolver: verify must be a function that looks a key up.")}static generate(Z){return`${Z}${o3(32).toString("base64url")}`}static hash(Z){return s3("sha256").update(Z).digest("hex")}static hashesMatch(Z,$){let G=Buffer.from(Z),W=Buffer.from($);return G.length===W.length&&a3(G,W)}async resolve(Z){let $=KZ(Z);if(!$?.startsWith(this.options.prefix))return null;let G=await this.options.verify($,Z);if(!G)return{ok:!1,error:"invalid_token",description:"The API key is not valid."};if(!G.user||typeof G.id!=="string"||G.id===""||!Array.isArray(G.scopes))throw Error("McpApiKeyResolver: verify must answer { user, id, scopes } for a key it knows, or null.");return{ok:!0,principal:{user:G.user,via:this.name,id:G.id,scopes:[...G.scopes]}}}}import{createHash as $3,randomBytes as dZ}from"crypto";async function HZ(Z,$){let G=e3();if(!G)return null;let W=await G.consume(Z,$);return W.allowed?null:Math.max(1,Math.ceil(W.retryAfter/1000))}function e3(){try{let Z=g();return Z.bound(v)?Z.make(v):null}catch{return null}}var UZ=["2026-07-28"],n=["2025-11-25","2025-06-18","2025-03-26"],QZ=[...UZ,...n],VZ="io.modelcontextprotocol/protocolVersion",BZ="io.modelcontextprotocol/clientCapabilities";var IZ="io.modelcontextprotocol/serverInfo",N={ParseError:-32700,InvalidRequest:-32600,MethodNotFound:-32601,InvalidParams:-32602,InternalError:-32603,HeaderMismatch:-32020,MissingRequiredClientCapability:-32021,UnsupportedProtocolVersion:-32022};class F extends Error{code;data;status;constructor(Z,$,G,W=200){super($);this.code=Z;this.data=G;this.status=W;this.name="JsonRpcError"}}function T(Z,$){return{jsonrpc:"2.0",id:Z,error:{code:$.code,message:$.message,...$.data!==void 0?{data:$.data}:{}}}}function hZ(Z){if(Array.isArray(Z))throw new F(N.InvalidRequest,"Batched requests are not supported.",void 0,400);if(typeof Z!=="object"||Z===null||Z.jsonrpc!=="2.0")throw new F(N.InvalidRequest,"Not a JSON-RPC 2.0 message.",void 0,400);let $=Z,G=$.id,W=typeof G==="string"||typeof G==="number"&&Number.isFinite(G);if(typeof $.method==="string"){if($.params!==void 0&&(typeof $.params!=="object"||$.params===null||Array.isArray($.params)))throw new F(N.InvalidRequest,"params must be an object.",void 0,400);if(G===void 0)return{kind:"notification",message:$};if(!W)throw new F(N.InvalidRequest,"id must be a string or a number.",void 0,400);return{kind:"request",message:$}}if(W&&(("result"in $)||("error"in $)))return{kind:"response",message:$};throw new F(N.InvalidRequest,"Not a JSON-RPC request, notification or response.",void 0,400)}function JZ(Z,$){let G=Z.outputSchema?.toJSONSchema(),W={...Z.annotations,...Z.title&&!$?{title:Z.title}:{}};return{name:Z.name,...Z.title?{title:Z.title}:{},description:Z.description,inputSchema:Z.inputSchema.toJSONSchema(),...G&&($||G.type==="object")?{outputSchema:G}:{},...Object.keys(W).length>0?{annotations:W}:{}}}function O(Z){return typeof Z==="object"&&Z!==null&&!Array.isArray(Z)}function mZ(Z){let $=/^=\?base64\?([A-Za-z0-9+/]*={0,2})\?=$/.exec(Z);if(!$)return Z;try{let G=Buffer.from($[1],"base64");return new TextDecoder("utf-8",{fatal:!0}).decode(G)}catch{return null}}import{createHmac as Z9,timingSafeEqual as $9}from"crypto";function FZ(Z,$,G){let W=Buffer.from(JSON.stringify(G)).toString("base64url");return`${$}.${W}.${uZ(Z,$,W).toString("base64url")}`}function NZ(Z,$,G,W=Date.now()){if(typeof G!=="string"||G.length>8192)return null;let z=G.split(".");if(z.length!==3||z[0]!==$)return null;let[,X,Y]=z,K=Buffer.from(Y,"base64url"),U=uZ(Z,$,X);if(K.length!==U.length||!$9(K,U))return null;let H;try{H=JSON.parse(Buffer.from(X,"base64url").toString("utf8"))}catch{return null}if(typeof H!=="object"||H===null)return null;if(typeof H.exp!=="number"||H.exp<=W)return null;return H}function uZ(Z,$,G){return Z9("sha256",t(Z)).update(`${$}.${G}`).digest()}var xZ="gemi.mcp.request-state.v1",cZ="gemi.mcp.session.v1",G9=86400000,pZ=600000,iZ="gemi_approval",PZ=2000,W9={limit:600,window:60},z9={limit:30,window:60};class c{registry;static token="router.mcp.http";endpoint;resolvers;context;allowedOrigins;rateLimit;maxBodyBytes;serverInfo;instructions;nonces;approvalTimeoutMs;pending=new Map;inflight=new Map;constructor(Z,$){this.registry=Z;if(typeof $.url!=="string")throw Error(`route.mcp.remote.url is required: the endpoint's canonical URL, like "https://example.com/mcp".`);this.endpoint=K9($.url);let G=$.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().");this.resolvers=G,t(xZ),this.context={resource:this.resource,registry:Z},this.allowedOrigins=new Set(($.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=$.rateLimit===!1?!1:$.rateLimit??W9,this.maxBodyBytes=$.maxBodyBytes??Math.ceil(Z.maxFileBytes*1.4)+1048576,this.serverInfo={name:$.server?.name??"gemi",version:$.server?.version??"1.0.0"},this.instructions=$.server?.instructions,this.nonces=$.nonces??new eZ,this.approvalTimeoutMs=$.approvalTimeoutMs??pZ;for(let W of G)W.boot?.(this.context)}get resource(){return this.endpoint.href.replace(/\/$/,"")}async handle(Z){let $=new URL(Z.url);if($.host!==this.endpoint.host)return null;for(let z of this.resolvers){let X=await z.handle?.(Z,this.context);if(X)return X}if($.pathname!==this.endpoint.pathname)return null;let G=Z.headers.get("origin");if(G!==null&&!this.allowedOrigins.has(G))return S(T(null,new F(N.InvalidRequest,"Origin not allowed.")),403);let W=G?Y9(G):{};if(Z.method==="OPTIONS")return new Response(null,{status:204,headers:{...W,"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(Z.method!=="POST")return lZ(new Response(null,{status:405,headers:{Allow:"POST, OPTIONS"}}),W);return lZ(await this.post(Z),W)}async post(Z){let $=null;for(let Y of this.resolvers){let K=await Y.resolve(Z,this.context);if(K===null)continue;if(K.ok===!1)return await this.failedAttempt(Z)??this.unauthorized(K.description);$={...K.principal,via:Y.name};break}if(!$)return(KZ(Z)!==null?await this.failedAttempt(Z):null)??this.unauthorized();let G=await this.spend($);if(G)return G;let W=Z.headers.get("content-type")??"";if(!/^application\/json\s*(;|$)/i.test(W))return new Response("Content-Type must be application/json.",{status:415});let z;try{z=JSON.parse(await X9(Z,this.maxBodyBytes))}catch(Y){if(Y instanceof o)return S(T(null,new F(N.InvalidRequest,`The request is larger than ${this.maxBodyBytes} bytes.`)),413);return S(T(null,new F(N.ParseError,"Parse error.")),400)}let X=new CZ(Z,{},"api",this.endpoint.pathname);return await aZ.run(X,async()=>{try{return await this.dispatch(Z,X,$,z)}catch(Y){if(Y instanceof F){let K=O(z)&&(typeof z.id==="string"||typeof z.id==="number")?z.id:null;return S(T(K,Y),Y.status)}return console.error("[gemi/mcp] The MCP endpoint failed:",Y),S(T(null,new F(N.InternalError,"Internal error.")),500)}},{user:$.user})}async dispatch(Z,$,G,W){let z=hZ(W),X={kind:"remote",req:$,principal:G};if(z.kind==="response"){let P=this.session(Z,G),x=this.pending.get(String(z.message.id));if(x&&x.session===P.id)this.pending.delete(String(z.message.id)),x.resolve(z.message);return new Response(null,{status:202})}let{message:Y}=z,K=Y.params??{},U=O(K._meta)?K._meta:{};if(typeof U[VZ]==="string"){if(this.checkModernHeaders(Z,Y,U[VZ]),z.kind==="notification")return new Response(null,{status:202});return await this.respond(Y,async(P,x)=>this.modern({principal:G,caller:X,message:Y,params:K,era:{modern:!0},stream:P,signal:x}),tZ(K),Z.signal)}if(Y.method==="initialize"){if(z.kind!=="request")throw new F(N.InvalidRequest,"initialize is a request.",void 0,400);return this.initialize(z.message,K,G)}let H=this.session(Z,G),Q=Z.headers.get("mcp-protocol-version");if(Q!==null&&Q!==H.state.v)throw new F(N.InvalidRequest,`MCP-Protocol-Version ${Q} is not the session's ${H.state.v}.`,void 0,400);if(z.kind==="notification"){if(Y.method==="notifications/cancelled"){let P=K.requestId;this.inflight.get(`${H.id}:${String(P)}`)?.abort()}return new Response(null,{status:202})}let V=`${H.id}:${String(Y.id)}`,I=new AbortController;this.inflight.set(V,I);let C=AbortSignal.any([I.signal,Z.signal]);try{return await this.respond(Y,async(P,x)=>this.legacy({principal:G,caller:X,message:Y,params:K,era:{modern:!1,session:H.state,sessionId:H.id},stream:P,signal:x}),tZ(K)||U9(this.registry,Y,H.state),C,()=>this.inflight.delete(V))}catch(P){throw this.inflight.delete(V),P}}async modern(Z){switch(Z.message.method){case"server/discover":return this.complete({supportedVersions:QZ,capabilities:{tools:{}},...this.instructions?{instructions:this.instructions}:{},ttlMs:60000,cacheScope:"private"});case"tools/list":return this.complete({tools:this.registry.list(Z.caller).map(($)=>JZ($,!0)),ttlMs:60000,cacheScope:"private"});case"tools/call":return await this.callTool(Z);default:throw new F(N.MethodNotFound,`Method not found: ${Z.message.method}`,void 0,404)}}async legacy(Z){switch(Z.message.method){case"ping":return{};case"tools/list":return{tools:this.registry.list(Z.caller).map(($)=>JZ($,!1))};case"tools/call":return await this.callTool(Z);default:throw new F(N.MethodNotFound,`Method not found: ${Z.message.method}`)}}complete(Z){return{resultType:"complete",...Z,_meta:{[IZ]:this.serverInfo}}}initialize(Z,$,G){let W=$.protocolVersion,z=n.includes(W)?W:n[0],X=O($.capabilities)?$.capabilities:{},Y={v:z,e:nZ(X.elicitation),p:s(G),exp:Date.now()+G9},K=FZ(cZ,"gms1",Y);return S({jsonrpc:"2.0",id:Z.id,result:{protocolVersion:z,capabilities:{tools:{listChanged:!1}},serverInfo:this.serverInfo,...this.instructions?{instructions:this.instructions}:{}}},200,{"Mcp-Session-Id":K})}session(Z,$){let G=Z.headers.get("mcp-session-id");if(!G)throw new F(N.InvalidRequest,"Missing Mcp-Session-Id. Send initialize first, or a request carrying io.modelcontextprotocol/protocolVersion in _meta.",void 0,400);let W=NZ(cZ,"gms1",G);if(!W||W.p!==s($))throw new F(N.InvalidRequest,"Session not found.",void 0,404);return{id:G,state:W}}checkModernHeaders(Z,$,G){if(!UZ.includes(G))throw new F(N.UnsupportedProtocolVersion,"Unsupported protocol version",{supported:QZ,requested:G},400);let W=(Y)=>new F(N.HeaderMismatch,`Header mismatch: ${Y}`,void 0,400);if(Z.headers.get("mcp-protocol-version")!==G)throw W("MCP-Protocol-Version does not match the protocol version in _meta.");if(Z.headers.get("mcp-method")!==$.method)throw W("Mcp-Method does not match the method.");let z=$.params??{},X=$.method==="tools/call"||$.method==="prompts/get"?z.name:$.method==="resources/read"?z.uri:void 0;if(X!==void 0){let Y=Z.headers.get("mcp-name");if(Y===null||mZ(Y)!==X)throw W("Mcp-Name does not match the request's name.")}}async callTool(Z){let{params:$,caller:G,principal:W}=Z,z=$.name;if(typeof z!=="string")throw new F(N.InvalidParams,"tools/call needs a tool name.");let X=$.arguments??{},Y=this.registry.list(G,{names:[z]})[0];if(!Y)throw new F(N.InvalidParams,`Unknown tool: ${z}`);let K=!1;if(Y.requiresApproval){let I=Y.inputSchema.safeParse(X);if(I.ok===!1)return this.toolResult(Z,{content:[{type:"text",text:`Invalid arguments for "${z}": ${I.errors.join(", ")}`}],isError:!0});let C=await this.approval(Z,Y,X);if(C.kind==="answer")return C.result;K=!0}let U=Q9(Z),H;try{H=await this.registry.execute(G,z,X,void 0,{approved:K,signal:Z.signal,...U?{progress:U}:{}})}catch(I){if(I instanceof L)return this.toolResult(Z,{content:[{type:"text",text:I.message}],isError:!0});if(I instanceof d)throw new F(N.InvalidParams,I.reason==="unknown-tool"?`Unknown tool: ${z}`:I.message);return console.error(`[gemi/mcp] "${z}" failed for ${W.via}:${W.id}:`,I),this.toolResult(Z,{content:[{type:"text",text:`"${z}" failed on the server.`}],isError:!0})}let Q=typeof H==="string"?H:JSON.stringify(H??null),V=Y.outputSchema&&(Z.era.modern||O(H))?{structuredContent:H}:{};return this.toolResult(Z,{content:[{type:"text",text:Q}],...V,isError:!1})}toolResult(Z,$){return Z.era.modern?this.complete($):$}async approval(Z,$,G){let W=V9($,G),z=(H)=>({kind:"answer",result:this.toolResult(Z,{content:[{type:"text",text:H}],isError:!0})});if(Z.era.modern){let H=O(Z.params._meta)?Z.params._meta:{},Q=O(H[BZ])?H[BZ]:{},V=O(Z.params.inputResponses)?Z.params.inputResponses:null,I=Z.params.requestState,C=H9(G);if(V&&I!==void 0){let x=NZ(xZ,"grs1",I);if(!x||x.p!==s(Z.principal)||x.t!==$.name||x.a!==C)throw new F(N.InvalidParams,"requestState is not valid for this call.");if(!await this.spendNonce(x.n,x.exp))throw new F(N.InvalidParams,"requestState has already been used.");return sZ(V[iZ])?{kind:"approved"}:z(`The user did not approve "${$.name}", and it did not run.`)}if(!nZ(Q.elicitation))throw new F(N.MissingRequiredClientCapability,`"${$.name}" needs the user's approval, and this client cannot ask for it (elicitation).`,{requiredCapabilities:{elicitation:{form:{}}}},400);let P={p:s(Z.principal),t:$.name,a:C,n:dZ(16).toString("base64url"),exp:Date.now()+pZ};return{kind:"answer",result:{resultType:"input_required",inputRequests:{[iZ]:{method:"elicitation/create",params:{mode:"form",...W}}},requestState:FZ(xZ,"grs1",P),_meta:{[IZ]:this.serverInfo}}}}let X=Z.era;if(!X.session.e||!Z.stream)return z(`"${$.name}" needs the user's approval, and this client cannot ask for it (elicitation). It did not run.`);let Y=`gemi-approval-${dZ(12).toString("base64url")}`,K=X.sessionId,U=await new Promise((H)=>{let Q=setTimeout(()=>{this.pending.delete(Y),H(null)},this.approvalTimeoutMs),V=(I)=>{clearTimeout(Q),H(I)};this.pending.set(Y,{session:K,resolve:V}),Z.signal.addEventListener("abort",()=>{this.pending.delete(Y),V(null)}),Z.stream.send({jsonrpc:"2.0",id:Y,method:"elicitation/create",params:X.session.v==="2025-11-25"?{mode:"form",...W}:W})});return U&&!U.error&&sZ(U.result)?{kind:"approved"}:z(`The user did not approve "${$.name}", and it did not run.`)}async spendNonce(Z,$){try{return await this.nonces.consume(Z,$)}catch(G){return console.error("[gemi/mcp] Spending an approval failed:",G),!1}}async respond(Z,$,G,W,z){if(!G)try{let U=await $(null,W);return S({jsonrpc:"2.0",id:Z.id,result:U},200)}finally{z?.()}let X=new AbortController,Y=AbortSignal.any([X.signal,W]),K=new G3(()=>X.abort());return(async()=>{try{let U=await $(K,Y);K.send({jsonrpc:"2.0",id:Z.id,result:U})}catch(U){if(U instanceof F)K.send(T(Z.id,U));else console.error("[gemi/mcp] The MCP endpoint failed:",U),K.send(T(Z.id,new F(N.InternalError,"Internal error.")))}finally{z?.(),K.close()}})(),new Response(K.readable,{status:200,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-store","X-Accel-Buffering":"no"}})}unauthorized(Z){let $=this.resolvers.map((W)=>W.challenge?.(this.context)).find(Boolean)??'Bearer realm="mcp"',G=Z?`${$}, error="invalid_token", error_description="${Z.replace(/["\\]/g,"")}"`:$;return S(T(null,new F(N.InvalidRequest,"Unauthorized.")),401,{"WWW-Authenticate":G})}async failedAttempt(Z){let $=rZ(new CZ(Z,{},"api",this.endpoint.pathname)),G=await HZ(`mcp-auth-failed:${$}`,z9);return G===null?null:oZ(G)}async spend(Z){if(!this.rateLimit)return null;let $=await HZ(`mcp-endpoint:${Z.via}:${Z.id}`,this.rateLimit);return $===null?null:oZ($)}}class G3{readable;controller;closed=!1;encoder=new TextEncoder;constructor(Z){this.readable=new ReadableStream({start:($)=>{this.controller=$},cancel:()=>{this.closed=!0,Z()}})}send(Z){if(this.closed)return;this.controller.enqueue(this.encoder.encode(`event: message
2
+ import{Pb as eZ,Sb as t,Tb as Z3,ac as YZ}from"./chunk-mr94nfp1.js";import{lc as LZ,nc as ZZ,qc as B3,rc as I3,sc as N3,uc as O3}from"./chunk-9rr5h818.js";import{Bc as D3,Dc as K3,Fc as H3,Mc as D,Nc as U3,Oc as Q3,Qc as V3,wc as Y3}from"./chunk-dwedx1jb.js";import{Tc as J}from"./chunk-9xyxbxgk.js";import{He as l,Le as m,Me as zZ,Ne as AZ,Vd as p,de as P3,ee as qZ,id as T3,ie as r,md as v,pd as rZ,se as MZ,td as S3,ue as GZ,ye as kZ}from"./chunk-baz7ne68.js";import{Ag as i,Rf as b,Tf as CZ,gg as jZ,ug as gZ,yg as $Z,zg as a}from"./chunk-4acpw92g.js";import{Mg as aZ}from"./chunk-m83zm86m.js";import{Sg as DZ}from"./chunk-pspthd52.js";import{Vg as x3,Wg as OZ,Zg as e,_g as SZ,bh as _3}from"./chunk-19dpzp4y.js";import{Ih as X3,Kh as k}from"./chunk-meg8rtr6.js";import{Lh as _}from"./chunk-h43jp8ws.js";import{Rh as L3}from"./chunk-s07v65x6.js";import{Fi as TZ}from"./chunk-1wnnkde0.js";import{Mi as F3,Pi as g}from"./chunk-nz8z8jr1.js";var R3="mcp",E3=/^[\x21\x23-\x5B\x5D-\x7E]+$/;class L extends YZ{status;constructor(Z,$){super(Z);this.status=$;this.name="McpToolError"}}class d extends Error{reason;constructor(Z,$){super(Z);this.reason=$;this.name="McpCallRefusedError"}}var w3=/^[A-Za-z0-9_-]{1,64}$/,b3=/:([A-Za-z_][A-Za-z0-9_]*)([?*+]?)/g,RZ=4000,y=1e5,y3=/^(text\/|application\/([\w.+-]*\+)?(json|xml))/i;class f{router;dispatcher;static token="router.mcp";plans=new Map;scopeTools=new Map;files;constructor(Z,$,G={}){this.router=Z;this.dispatcher=$;this.files=v3(G.files);for(let[W,z]of Object.entries(Z.routes??{}))this.plans.set(W,this.plan(W,z));this.resolveScopes()}list(Z,$){if(EZ(Z),Z.kind==="local")return this.descriptors($);let G=[];for(let[W,z]of this.plans){if(!z.remote||!this.grants(Z.principal,W))continue;if(wZ(z.remote,$))G.push(z.remote)}return G}descriptors(Z){let $=[];for(let{descriptor:G}of this.plans.values())if(wZ(G,Z))$.push(G);return $}get maxFileBytes(){return this.files.maxBytes}scopes(){return[...this.scopeTools].map(([Z,{description:$}])=>({name:Z,description:$}))}scopesFor(Z){return[...this.scopeTools].filter(([,{tools:$}])=>$.has(Z)).map(([$])=>$)}async execute(Z,$,G,W,z={}){EZ(Z);let X=this.plans.get($);if(Z.kind==="remote"){if(!X?.remote||!this.grants(Z.principal,$))throw new d(`There is no tool named "${$}".`,"unknown-tool");if(X.descriptor.requiresApproval&&z.approved!==!0)throw new d(`"${$}" needs the user's approval, and this call does not have it.`,"approval-required");W=void 0}if(!X)throw Error(`McpRegistry: there is no tool named "${$}".`);let Y=X,K=Z.kind==="remote"?Y.remote:Y.descriptor,U=K.inputSchema.safeParse(G);if(U.ok===!1)throw new L(`Invalid arguments for "${$}": ${U.errors.join(", ")}`);let H=U.value,Q={caller:Z,req:Z.req,tool:K,input:H,ctx:W},V=await this.fillPath(Y,Q),{path:I}=this.dispatcher.getRouteHandlerAndParams(new Request(`http://gemi.internal/api${V}`));if(I!==K.url)throw new L(`"${$}" has nothing at ${V}.`,404);let C={};for(let q of Y.jsonKeys)if(H[q]!==void 0)C[q]=H[q];let P,x="";if(Y.fileFields.length>0)P=await this.formData(Y,C,Q);else if(K.method==="GET")x=t3(C);else if(Y.jsonKeys.length>0)P=C;let j=this.router.credentials?await this.bind(Y,"the credentials",()=>this.router.credentials(Q)):void 0,w={...j?{credentials:j}:{},...z.signal?{signal:z.signal}:{},...z.progress?{progress:z.progress}:{},...Z.kind==="remote"?{identity:{user:Z.principal.user,grant:{via:Z.principal.via,id:Z.principal.id,scopes:Z.principal.scopes,...Z.principal.clientId?{clientId:Z.principal.clientId}:{}}}}:{}},u;try{let q=x?`${V}?${x}`:V;u=Object.keys(w).length>0?await this.dispatcher.dispatchAs(Z.req,K.method,q,P,w):await this.dispatcher.dispatchAs(Z.req,K.method,q,P)}catch(q){throw console.error(`[gemi/mcp] Dispatching "${$}" failed:`,q),new L(`"${$}" failed on the server.`,500)}if(!Y.result&&!K.outputSchema)return await vZ($,u);return await this.project(Y,Q,u)}plan(Z,$){if(!w3.test(Z))throw Error(`McpRouter: "${Z}" 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 G=`McpRouter: "${Z}" (${$?.method} ${$?.url})`;if(!($ instanceof Object)||$.__internal_brand!=="McpRoute")throw Error(`McpRouter: "${Z}" is not a route. Declare it with this.fromApiRoute(...).`);let{method:W,url:z,meta:X}=$;if(z.startsWith("/__gemi__"))throw Error(`${G} is a framework route, not an app route.`);let Y=this.dispatcher.flatRoutes[z]?.[W];if(!Y)throw Error(`${G} names no route of this app. Expose a route by the path and verb it is mounted at.`);let K=[...z.matchAll(b3)].map(([,B,A])=>({name:B,modifier:A})),U=X.params??{};for(let B of K)if(!(B.name in U))throw Error(`${G}: the path param "${B.name}" must be bound or declared "input".`);for(let[B,A]of Object.entries(U)){if(!K.some((M)=>M.name===B))throw Error(`${G}: "${B}" in params is not a param of the url.`);if(yZ(A))d3(G,`params.${B}`,A);else bZ(G,`params.${B}`,A)}let H=[],Q;if(X.input){if(Q=X.input.toJSONSchema(),Q.type!=="object"||!Q.properties)throw Error(`${G}: input must be an s.object(...), the fields of the request body.`);H=Object.keys(Q.properties)}let V=Object.entries(X.files??{}).map(([B,A])=>({name:B,binder:A}));for(let B of V)bZ(G,`files.${B.name}`,B.binder);if(X.result!==void 0&&typeof X.result!=="function")throw Error(`${G}: result must be a function.`);if(X.output!==void 0&&typeof X.output?.safeParse!=="function")throw Error(`${G}: output must be a schema, built with s.`);if(X.title!==void 0&&(typeof X.title!=="string"||X.title===""))throw Error(`${G}: title must be a non-empty string.`);let I=i3(G,W,X.annotations);if(V.length>0&&W==="GET")throw Error(`${G}: a GET has no body to carry a file.`);let C={},P=(B,A)=>{if(B in C)throw Error(`${G}: "${B}" is the input key of two params or files, and the model can only send one.`);C[B]=A},x=new Map,j=new Map;for(let B of K){let A=U[B.name];if(A==="input"){let M=b.string().describe(`The ":${B.name}" segment of the url.`);P(B.name,B.modifier==="?"||B.modifier==="*"?M.optional():M)}else if(yZ(A)){let M=A.as??B.name;P(M,A.input),j.set(B.name,{key:M,param:A})}else x.set(B.name,A)}let w={};for(let B of V)if(B.binder==="input")P(B.name,b.string().describe("The id of an attachment the user uploaded or a tool produced (gemi_att_\u2026), whose file is sent as this field.")),w[B.name]=this.remoteFileSchema();let u=[...Object.keys(C),...V.map((B)=>B.name)];for(let B of new Set(u))if(H.includes(B))throw Error(`${G}: "${B}" is both an input field and a param or file, and the model can only send one.`);let q=Object.freeze({name:Z,description:X.description,method:W,url:z,inputSchema:fZ(X.input,Q,b.object(C)),...X.output?{outputSchema:X.output}:{},...X.title?{title:X.title}:{},annotations:I,tags:Object.freeze([...X.tags??[]]),requiresApproval:X.requiresApproval===!0,...Y.source?{source:Y.source}:{}}),k3=!V.every((B)=>B.binder==="input")?null:V.length===0?q:Object.freeze({...q,inputSchema:fZ(X.input,Q,b.object(l3(C,Object.keys(w))),w)});return{descriptor:q,remote:k3,params:K,paramBinders:x,modelParams:j,fileFields:V,jsonKeys:H,...X.result?{result:X.result}:{}}}remoteFileSchema(){let{maxBytes:Z,fetch:$}=this.files,G={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 ${Z} bytes decoded.`}};if($)G.url={type:"string",format:"uri",description:"An https URL the server downloads the file from, instead of data."};let W={type:"object",description:$?"A file, sent as base64 in data or fetched from url: exactly one of the two.":"A file, sent as base64 in data.",properties:G,required:["name","mimeType"],additionalProperties:!1},z=Object.keys(G),X=(Y)=>{if(typeof Y!=="object"||Y===null||Array.isArray(Y))return{ok:!1,errors:["a file must be an object"]};let K=[],U={};for(let H of Object.keys(Y))if(!z.includes(H))K.push(`a file has no field "${H}"`);for(let H of z){let Q=Y[H];if(Q===void 0||Q===null){if(H==="name"||H==="mimeType")K.push(`a file needs "${H}"`);continue}if(typeof Q!=="string")K.push(`a file's "${H}" must be a string`);else U[H]=Q}return K.length>0?{ok:!1,errors:K}:{ok:!0,value:U}};return{toJSONSchema:()=>W,safeParse:X,parse(Y){let K=X(Y);if(K.ok===!1)throw Error(K.errors.join(", "));return K.value}}}async fillPath(Z,$){let{input:G,req:W}=$,z=Z.descriptor.url;for(let X of Z.params){let Y=Z.paramBinders.get(X.name),K=Z.modelParams.get(X.name),U;if(Y||K){if(U=K?await this.bind(Z,`the param "${X.name}"`,()=>K.param.bind(G[K.key],W,$),{refusals:!0}):await this.bind(Z,`the param "${X.name}"`,()=>Y(W,$)),U===void 0||U===null||U==="")throw console.error(`[gemi/mcp] The ${K?"resolver":"binder"} for "${X.name}" of "${Z.descriptor.name}" returned ${JSON.stringify(U)}.`),new L(`"${Z.descriptor.name}" failed on the server.`,500)}else U=G[X.name];let H=`:${X.name}${X.modifier}`;if(U===void 0||U===null||U===""){if(X.modifier!=="?"&&X.modifier!=="*")throw new L(`"${X.name}" of "${Z.descriptor.name}" must not be empty.`);z=z.replace(`/${H}`,"");continue}z=z.replace(H,n3(Z.descriptor.name,X,String(U)))}return z}async formData(Z,$,G){let{input:W,ctx:z}=G,X=Z.descriptor.name;if(G.caller.kind==="remote"){let K=new FormData;for(let[U,H]of Object.entries($))XZ(K,U,H);for(let U of Z.fileFields)K.append(U.name,await this.remoteFile(X,U.name,W[U.name]));return K}if(!z)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,U]of Object.entries($))XZ(Y,K,U);for(let K of Z.fileFields){let U=K.binder==="input"?W[K.name]:await this.bind(Z,`the file "${K.name}"`,()=>K.binder(z,G));if(typeof U!=="string"||U==="")throw new L(`"${X}" needs a file for "${K.name}", and this turn has none. Ask the user to attach one.`);Y.append(K.name,await z.attachments.file(U))}return Y}async remoteFile(Z,$,G){let W=(Q)=>new L(`"${$}" of "${Z}" ${Q}`,400),z=G,{maxBytes:X,fetch:Y}=this.files;if(!g3(z.name))throw W("needs a name of 1 to 255 characters, without control characters or slashes.");if(!h3.test(z.mimeType))throw W(`has a mimeType that is not a media type: "${z.mimeType.slice(0,100)}".`);let K=typeof z.data==="string",U=typeof z.url==="string";if(K===U)throw W(Y?"needs exactly one of data or url.":"needs its bytes, base64, in data.");if(K){let Q=z.data.replace(/\s+/g,"");if(Math.floor(Q.length*3/4)-u3(Q)>X)throw W(`is larger than the ${X} bytes a file may be.`);if(Q.length%4!==0||!m3.test(Q))throw W("has data that is not base64 (RFC 4648, standard alphabet, padded).");return new File([Buffer.from(Q,"base64")],z.name,{type:z.mimeType})}if(!Y)throw W("cannot be fetched from a URL here. Send its bytes, base64, in data.");let H;try{H=new URL(z.url)}catch{throw W("has a url that is not a URL.")}if(H.protocol!=="https:")throw W("can only be fetched from an https URL.");try{let Q=await gZ(H.href,{...Y,maxSize:Math.min(Y.maxSize??X,X),redirect:"follow"});if(!Q.ok)throw W(`could not be fetched: ${H.host} answered ${Q.status}.`);let V=await Q.arrayBuffer();return new File([V],z.name,{type:z.mimeType})}catch(Q){if(Q instanceof L)throw Q;throw W(`could not be fetched from ${H.host}: ${Q instanceof Error?Q.message:"failed"}.`)}}grants(Z,$){for(let G of Z.scopes??[])if(this.scopeTools.get(G)?.tools.has($))return!0;return!1}resolveScopes(){let Z=this.router.scopes;if(Z===void 0){this.scopeTools.set(R3,{description:"Use this app's tools as you",tools:new Set(this.plans.keys())});return}if(typeof Z!=="object"||Z===null)throw Error("McpRouter: scopes must be an object of scope names.");let $=new Set([...this.plans.values()].flatMap(({descriptor:G})=>G.tags));for(let[G,W]of Object.entries(Z)){let z=`McpRouter: scope "${G}"`;if(!E3.test(G))throw Error(`${z} is not a valid OAuth scope: printable ASCII, no spaces or quotes.`);if(typeof W?.description!=="string"||W.description==="")throw Error(`${z} needs a description: it is what a consent screen shows.`);let X=new Set;for(let Y of W.tags??[]){if(!$.has(Y))throw Error(`${z} names the tag "${Y}", which no tool has.`);for(let[K,{descriptor:U}]of this.plans)if(U.tags.includes(Y))X.add(K)}for(let Y of W.names??[]){if(!this.plans.has(Y))throw Error(`${z} names "${Y}", which is no tool.`);X.add(Y)}if(X.size===0)throw Error(`${z} reaches no tool. Give it tags or names.`);this.scopeTools.set(G,{description:W.description,tools:X})}}async project(Z,$,G){let{name:W,outputSchema:z}=Z.descriptor;if(G.status<200||G.status>=300)return await vZ(W,G);let X=(V,I)=>{if(I===void 0)console.error(`[gemi/mcp] "${W}" ${V}`);else console.error(`[gemi/mcp] "${W}" ${V}`,I);return new L(`"${W}" failed on the server.`,500)},Y=G.headers.get("Content-Type"),K=await G.text(),U=null;if(K!=="")try{U=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 H=U;if(Z.result)try{H=await Z.result(U,$)}catch(V){throw X("failed in its result projection:",V)}if(z){let V=z.safeParse(H);if(V.ok===!1)throw X(`answered what its output schema refuses: ${V.errors.join(", ")}`);H=V.value}if(H===void 0)return null;let Q=JSON.stringify(H);if(Q!==void 0&&Q.length>y)return`${Q.slice(0,y)}\u2026 [cut at ${y} of ${Q.length} characters]`;return H}async bind(Z,$,G,W={}){try{return await G()}catch(z){if(W.refusals&&z instanceof YZ)throw z;throw console.error(`[gemi/mcp] Binding ${$} of "${Z.descriptor.name}" failed:`,z),new L(`"${Z.descriptor.name}" failed on the server.`,500)}}}function EZ(Z){if(Z?.kind==="local"&&Z.req)return;if(Z?.kind==="remote"&&Z.req&&Z.principal?.user&&typeof Z.principal.id==="string"&&Array.isArray(Z.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 wZ(Z,$){if($?.names&&!$.names.includes(Z.name))return!1;if($?.tags&&!Z.tags.some((G)=>$.tags.includes(G)))return!1;return!0}var f3=10485760;function v3(Z){let $=Z?.maxBytes??f3;if(!Number.isSafeInteger($)||$<=0)throw Error("McpRegistry: files.maxBytes must be a positive whole number of bytes.");let G=Z?.fetchUrls===!0?{}:typeof Z?.fetchUrls==="object"&&Z.fetchUrls!==null?Z.fetchUrls:null;return{maxBytes:$,fetch:G}}function g3(Z){if(Z.length===0||Z.length>255)return!1;for(let $ of Z){let G=$.codePointAt(0);if(G<32||G===127||$==="/"||$==="\\")return!1}return!0}var h3=/^[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}\/[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}(\s*;.{0,200})?$/,m3=/^[A-Za-z0-9+/]*={0,2}$/;function u3(Z){return Z.endsWith("==")?2:Z.endsWith("=")?1:0}function bZ(Z,$,G){if(G!=="input"&&typeof G!=="function")throw Error(`${Z}: ${$} must be a function or "input".`)}function yZ(Z){return Z instanceof Object&&Z.__internal_brand==="McpModelParam"}function d3(Z,$,G){if(G.as!==void 0&&(typeof G.as!=="string"||G.as===""))throw Error(`${Z}: ${$}.as must be a non-empty string.`);let W=G.input;if(typeof W?.safeParse!=="function"||typeof W.toJSONSchema!=="function")throw Error(`${Z}: ${$}.input must be a schema, built with s.`);if(typeof G.bind!=="function")throw Error(`${Z}: ${$}.bind must be a function.`)}var c3=new Set(["readOnlyHint","destructiveHint","idempotentHint","openWorldHint"]);function p3(Z){switch(Z){case"GET":return{readOnlyHint:!0};case"DELETE":return{destructiveHint:!0};case"PUT":return{idempotentHint:!0};default:return{}}}function i3(Z,$,G){if(G!==void 0&&(typeof G!=="object"||G===null))throw Error(`${Z}: annotations must be an object of hints.`);let W=p3($);for(let[z,X]of Object.entries(G??{})){if(!c3.has(z))throw Error(`${Z}: "${z}" is not a tool annotation. Use readOnlyHint, destructiveHint, idempotentHint or openWorldHint.`);if(X===void 0)continue;if(typeof X!=="boolean")throw Error(`${Z}: annotations.${z} must be true or false.`);W[z]=X}if(W.readOnlyHint===!0&&(W.destructiveHint||W.idempotentHint))throw Error(`${Z} is read-only${G?.readOnlyHint?"":` (a ${$})`} and also ${W.destructiveHint?"destructive":"idempotent"}, which only a tool that is not read-only can be. Set readOnlyHint: false if it changes something.`);return Object.freeze(W)}function fZ(Z,$,G,W={}){let z=G.toJSONSchema(),X=Object.fromEntries(Object.entries(W).map(([U,H])=>[U,H.toJSONSchema()])),Y={...$??{},type:"object",properties:{...$?.properties??{},...z.properties,...X},required:[...$?.required??[],...z.required??[],...Object.keys(W)],additionalProperties:!1},K=(U)=>{if(typeof U!=="object"||U===null||Array.isArray(U))return{ok:!1,errors:["expected an object"]};let H=[],Q={};if(Z){let I=Z.safeParse(U);if(I.ok===!1)H.push(...I.errors);else Q={...I.value}}let V=G.safeParse(U);if(V.ok===!1)H.push(...V.errors);else Q={...Q,...V.value};for(let[I,C]of Object.entries(W)){let P=U[I];if(P===void 0){H.push(`"${I}" is required`);continue}let x=C.safeParse(P);if(x.ok===!1)H.push(...x.errors.map((j)=>`${I}: ${j}`));else Q[I]=x.value}return H.length>0?{ok:!1,errors:H}:{ok:!0,value:Q}};return{toJSONSchema:()=>Y,safeParse:K,parse(U){let H=K(U);if(H.ok===!1)throw Error(H.errors.join(", "));return H.value}}}function l3(Z,$){return Object.fromEntries(Object.entries(Z).filter(([G])=>!$.includes(G)))}function n3(Z,$,G){let W=$.modifier==="*"||$.modifier==="+"?G.split("/"):[G];if(W.some((z)=>z==="."||z===".."))throw new L(`"${G}" is not a valid value for "${$.name}" of "${Z}".`);return W.map(encodeURIComponent).join("/")}function XZ(Z,$,G){if(G===void 0||G===null)return;if(Array.isArray(G)){for(let W of G)XZ(Z,$,W);return}Z.append($,typeof G==="object"?JSON.stringify(G):String(G))}function t3(Z){let $=new URLSearchParams,G=(W,z)=>{if(z===void 0||z===null)return;if(Array.isArray(z)){for(let X of z)G(W,X);return}$.append(W,typeof z==="object"?JSON.stringify(z):String(z))};for(let[W,z]of Object.entries(Z))G(W,z);return $.toString()}async function vZ(Z,$){if($.status>=200&&$.status<300){let W=$.headers.get("Content-Type");if(W&&!y3.test(W)){let X=(await $.arrayBuffer()).byteLength;return`"${Z}" answered with ${X} bytes of ${W}, which is not shown.`}let z=await $.text();if(z==="")return null;if(z.length>y)return`${z.slice(0,y)}\u2026 [cut at ${y} of ${z.length} characters]`;try{return JSON.parse(z)}catch{return z}}let G=await $.text();if($.status>=400&&$.status<500){let W=G.length>RZ?`${G.slice(0,RZ)}\u2026`:G;throw new L(`"${Z}" was refused with ${$.status}${W?`: ${W}`:"."}`,$.status)}if($.status<500)console.error(`[gemi/mcp] "${Z}" answered ${$.status}${$.headers.get("Location")?` to ${$.headers.get("Location")}`:""}, which a tool call cannot follow.`);throw new L(`"${Z}" failed on the server.`,$.status)}import{createHash as s3,randomBytes as o3,timingSafeEqual as a3}from"crypto";function KZ(Z){let $=Z.headers.get("authorization");if(!$)return null;let G=/^Bearer[ ]+([\x21-\x7e]+)$/i.exec($.trim());return G?G[1]:null}class r3{options;name="api-key";constructor(Z){this.options=Z;if(typeof Z?.prefix!=="string"||!/^[A-Za-z0-9_-]{3,32}$/.test(Z.prefix))throw Error('McpApiKeyResolver: prefix is required: 3 to 32 letters, digits, _ or -, like "myapp_mcp_".');if(typeof Z.verify!=="function")throw Error("McpApiKeyResolver: verify must be a function that looks a key up.")}static generate(Z){return`${Z}${o3(32).toString("base64url")}`}static hash(Z){return s3("sha256").update(Z).digest("hex")}static hashesMatch(Z,$){let G=Buffer.from(Z),W=Buffer.from($);return G.length===W.length&&a3(G,W)}async resolve(Z){let $=KZ(Z);if(!$?.startsWith(this.options.prefix))return null;let G=await this.options.verify($,Z);if(!G)return{ok:!1,error:"invalid_token",description:"The API key is not valid."};if(!G.user||typeof G.id!=="string"||G.id===""||!Array.isArray(G.scopes))throw Error("McpApiKeyResolver: verify must answer { user, id, scopes } for a key it knows, or null.");return{ok:!0,principal:{user:G.user,via:this.name,id:G.id,scopes:[...G.scopes]}}}}import{createHash as $3,randomBytes as dZ}from"crypto";async function HZ(Z,$){let G=e3();if(!G)return null;let W=await G.consume(Z,$);return W.allowed?null:Math.max(1,Math.ceil(W.retryAfter/1000))}function e3(){try{let Z=g();return Z.bound(v)?Z.make(v):null}catch{return null}}var UZ=["2026-07-28"],n=["2025-11-25","2025-06-18","2025-03-26"],QZ=[...UZ,...n],VZ="io.modelcontextprotocol/protocolVersion",BZ="io.modelcontextprotocol/clientCapabilities";var IZ="io.modelcontextprotocol/serverInfo",N={ParseError:-32700,InvalidRequest:-32600,MethodNotFound:-32601,InvalidParams:-32602,InternalError:-32603,HeaderMismatch:-32020,MissingRequiredClientCapability:-32021,UnsupportedProtocolVersion:-32022};class F extends Error{code;data;status;constructor(Z,$,G,W=200){super($);this.code=Z;this.data=G;this.status=W;this.name="JsonRpcError"}}function T(Z,$){return{jsonrpc:"2.0",id:Z,error:{code:$.code,message:$.message,...$.data!==void 0?{data:$.data}:{}}}}function hZ(Z){if(Array.isArray(Z))throw new F(N.InvalidRequest,"Batched requests are not supported.",void 0,400);if(typeof Z!=="object"||Z===null||Z.jsonrpc!=="2.0")throw new F(N.InvalidRequest,"Not a JSON-RPC 2.0 message.",void 0,400);let $=Z,G=$.id,W=typeof G==="string"||typeof G==="number"&&Number.isFinite(G);if(typeof $.method==="string"){if($.params!==void 0&&(typeof $.params!=="object"||$.params===null||Array.isArray($.params)))throw new F(N.InvalidRequest,"params must be an object.",void 0,400);if(G===void 0)return{kind:"notification",message:$};if(!W)throw new F(N.InvalidRequest,"id must be a string or a number.",void 0,400);return{kind:"request",message:$}}if(W&&(("result"in $)||("error"in $)))return{kind:"response",message:$};throw new F(N.InvalidRequest,"Not a JSON-RPC request, notification or response.",void 0,400)}function JZ(Z,$){let G=Z.outputSchema?.toJSONSchema(),W={...Z.annotations,...Z.title&&!$?{title:Z.title}:{}};return{name:Z.name,...Z.title?{title:Z.title}:{},description:Z.description,inputSchema:Z.inputSchema.toJSONSchema(),...G&&($||G.type==="object")?{outputSchema:G}:{},...Object.keys(W).length>0?{annotations:W}:{}}}function O(Z){return typeof Z==="object"&&Z!==null&&!Array.isArray(Z)}function mZ(Z){let $=/^=\?base64\?([A-Za-z0-9+/]*={0,2})\?=$/.exec(Z);if(!$)return Z;try{let G=Buffer.from($[1],"base64");return new TextDecoder("utf-8",{fatal:!0}).decode(G)}catch{return null}}import{createHmac as Z9,timingSafeEqual as $9}from"crypto";function FZ(Z,$,G){let W=Buffer.from(JSON.stringify(G)).toString("base64url");return`${$}.${W}.${uZ(Z,$,W).toString("base64url")}`}function NZ(Z,$,G,W=Date.now()){if(typeof G!=="string"||G.length>8192)return null;let z=G.split(".");if(z.length!==3||z[0]!==$)return null;let[,X,Y]=z,K=Buffer.from(Y,"base64url"),U=uZ(Z,$,X);if(K.length!==U.length||!$9(K,U))return null;let H;try{H=JSON.parse(Buffer.from(X,"base64url").toString("utf8"))}catch{return null}if(typeof H!=="object"||H===null)return null;if(typeof H.exp!=="number"||H.exp<=W)return null;return H}function uZ(Z,$,G){return Z9("sha256",t(Z)).update(`${$}.${G}`).digest()}var xZ="gemi.mcp.request-state.v1",cZ="gemi.mcp.session.v1",G9=86400000,pZ=600000,iZ="gemi_approval",PZ=2000,W9={limit:600,window:60},z9={limit:30,window:60};class c{registry;static token="router.mcp.http";endpoint;resolvers;context;allowedOrigins;rateLimit;maxBodyBytes;serverInfo;instructions;nonces;approvalTimeoutMs;pending=new Map;inflight=new Map;constructor(Z,$){this.registry=Z;if(typeof $.url!=="string")throw Error(`route.mcp.remote.url is required: the endpoint's canonical URL, like "https://example.com/mcp".`);this.endpoint=K9($.url);let G=$.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().");this.resolvers=G,t(xZ),this.context={resource:this.resource,registry:Z},this.allowedOrigins=new Set(($.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=$.rateLimit===!1?!1:$.rateLimit??W9,this.maxBodyBytes=$.maxBodyBytes??Math.ceil(Z.maxFileBytes*1.4)+1048576,this.serverInfo={name:$.server?.name??"gemi",version:$.server?.version??"1.0.0"},this.instructions=$.server?.instructions,this.nonces=$.nonces??new eZ,this.approvalTimeoutMs=$.approvalTimeoutMs??pZ;for(let W of G)W.boot?.(this.context)}get resource(){return this.endpoint.href.replace(/\/$/,"")}async handle(Z){let $=new URL(Z.url);if($.host!==this.endpoint.host)return null;for(let z of this.resolvers){let X=await z.handle?.(Z,this.context);if(X)return X}if($.pathname!==this.endpoint.pathname)return null;let G=Z.headers.get("origin");if(G!==null&&!this.allowedOrigins.has(G))return S(T(null,new F(N.InvalidRequest,"Origin not allowed.")),403);let W=G?Y9(G):{};if(Z.method==="OPTIONS")return new Response(null,{status:204,headers:{...W,"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(Z.method!=="POST")return lZ(new Response(null,{status:405,headers:{Allow:"POST, OPTIONS"}}),W);return lZ(await this.post(Z),W)}async post(Z){let $=null;for(let Y of this.resolvers){let K=await Y.resolve(Z,this.context);if(K===null)continue;if(K.ok===!1)return await this.failedAttempt(Z)??this.unauthorized(K.description);$={...K.principal,via:Y.name};break}if(!$)return(KZ(Z)!==null?await this.failedAttempt(Z):null)??this.unauthorized();let G=await this.spend($);if(G)return G;let W=Z.headers.get("content-type")??"";if(!/^application\/json\s*(;|$)/i.test(W))return new Response("Content-Type must be application/json.",{status:415});let z;try{z=JSON.parse(await X9(Z,this.maxBodyBytes))}catch(Y){if(Y instanceof o)return S(T(null,new F(N.InvalidRequest,`The request is larger than ${this.maxBodyBytes} bytes.`)),413);return S(T(null,new F(N.ParseError,"Parse error.")),400)}let X=new CZ(Z,{},"api",this.endpoint.pathname);return await aZ.run(X,async()=>{try{return await this.dispatch(Z,X,$,z)}catch(Y){if(Y instanceof F){let K=O(z)&&(typeof z.id==="string"||typeof z.id==="number")?z.id:null;return S(T(K,Y),Y.status)}return console.error("[gemi/mcp] The MCP endpoint failed:",Y),S(T(null,new F(N.InternalError,"Internal error.")),500)}},{user:$.user})}async dispatch(Z,$,G,W){let z=hZ(W),X={kind:"remote",req:$,principal:G};if(z.kind==="response"){let P=this.session(Z,G),x=this.pending.get(String(z.message.id));if(x&&x.session===P.id)this.pending.delete(String(z.message.id)),x.resolve(z.message);return new Response(null,{status:202})}let{message:Y}=z,K=Y.params??{},U=O(K._meta)?K._meta:{};if(typeof U[VZ]==="string"){if(this.checkModernHeaders(Z,Y,U[VZ]),z.kind==="notification")return new Response(null,{status:202});return await this.respond(Y,async(P,x)=>this.modern({principal:G,caller:X,message:Y,params:K,era:{modern:!0},stream:P,signal:x}),tZ(K),Z.signal)}if(Y.method==="initialize"){if(z.kind!=="request")throw new F(N.InvalidRequest,"initialize is a request.",void 0,400);return this.initialize(z.message,K,G)}let H=this.session(Z,G),Q=Z.headers.get("mcp-protocol-version");if(Q!==null&&Q!==H.state.v)throw new F(N.InvalidRequest,`MCP-Protocol-Version ${Q} is not the session's ${H.state.v}.`,void 0,400);if(z.kind==="notification"){if(Y.method==="notifications/cancelled"){let P=K.requestId;this.inflight.get(`${H.id}:${String(P)}`)?.abort()}return new Response(null,{status:202})}let V=`${H.id}:${String(Y.id)}`,I=new AbortController;this.inflight.set(V,I);let C=AbortSignal.any([I.signal,Z.signal]);try{return await this.respond(Y,async(P,x)=>this.legacy({principal:G,caller:X,message:Y,params:K,era:{modern:!1,session:H.state,sessionId:H.id},stream:P,signal:x}),tZ(K)||U9(this.registry,Y,H.state),C,()=>this.inflight.delete(V))}catch(P){throw this.inflight.delete(V),P}}async modern(Z){switch(Z.message.method){case"server/discover":return this.complete({supportedVersions:QZ,capabilities:{tools:{}},...this.instructions?{instructions:this.instructions}:{},ttlMs:60000,cacheScope:"private"});case"tools/list":return this.complete({tools:this.registry.list(Z.caller).map(($)=>JZ($,!0)),ttlMs:60000,cacheScope:"private"});case"tools/call":return await this.callTool(Z);default:throw new F(N.MethodNotFound,`Method not found: ${Z.message.method}`,void 0,404)}}async legacy(Z){switch(Z.message.method){case"ping":return{};case"tools/list":return{tools:this.registry.list(Z.caller).map(($)=>JZ($,!1))};case"tools/call":return await this.callTool(Z);default:throw new F(N.MethodNotFound,`Method not found: ${Z.message.method}`)}}complete(Z){return{resultType:"complete",...Z,_meta:{[IZ]:this.serverInfo}}}initialize(Z,$,G){let W=$.protocolVersion,z=n.includes(W)?W:n[0],X=O($.capabilities)?$.capabilities:{},Y={v:z,e:nZ(X.elicitation),p:s(G),exp:Date.now()+G9},K=FZ(cZ,"gms1",Y);return S({jsonrpc:"2.0",id:Z.id,result:{protocolVersion:z,capabilities:{tools:{listChanged:!1}},serverInfo:this.serverInfo,...this.instructions?{instructions:this.instructions}:{}}},200,{"Mcp-Session-Id":K})}session(Z,$){let G=Z.headers.get("mcp-session-id");if(!G)throw new F(N.InvalidRequest,"Missing Mcp-Session-Id. Send initialize first, or a request carrying io.modelcontextprotocol/protocolVersion in _meta.",void 0,400);let W=NZ(cZ,"gms1",G);if(!W||W.p!==s($))throw new F(N.InvalidRequest,"Session not found.",void 0,404);return{id:G,state:W}}checkModernHeaders(Z,$,G){if(!UZ.includes(G))throw new F(N.UnsupportedProtocolVersion,"Unsupported protocol version",{supported:QZ,requested:G},400);let W=(Y)=>new F(N.HeaderMismatch,`Header mismatch: ${Y}`,void 0,400);if(Z.headers.get("mcp-protocol-version")!==G)throw W("MCP-Protocol-Version does not match the protocol version in _meta.");if(Z.headers.get("mcp-method")!==$.method)throw W("Mcp-Method does not match the method.");let z=$.params??{},X=$.method==="tools/call"||$.method==="prompts/get"?z.name:$.method==="resources/read"?z.uri:void 0;if(X!==void 0){let Y=Z.headers.get("mcp-name");if(Y===null||mZ(Y)!==X)throw W("Mcp-Name does not match the request's name.")}}async callTool(Z){let{params:$,caller:G,principal:W}=Z,z=$.name;if(typeof z!=="string")throw new F(N.InvalidParams,"tools/call needs a tool name.");let X=$.arguments??{},Y=this.registry.list(G,{names:[z]})[0];if(!Y)throw new F(N.InvalidParams,`Unknown tool: ${z}`);let K=!1;if(Y.requiresApproval){let I=Y.inputSchema.safeParse(X);if(I.ok===!1)return this.toolResult(Z,{content:[{type:"text",text:`Invalid arguments for "${z}": ${I.errors.join(", ")}`}],isError:!0});let C=await this.approval(Z,Y,X);if(C.kind==="answer")return C.result;K=!0}let U=Q9(Z),H;try{H=await this.registry.execute(G,z,X,void 0,{approved:K,signal:Z.signal,...U?{progress:U}:{}})}catch(I){if(I instanceof L)return this.toolResult(Z,{content:[{type:"text",text:I.message}],isError:!0});if(I instanceof d)throw new F(N.InvalidParams,I.reason==="unknown-tool"?`Unknown tool: ${z}`:I.message);return console.error(`[gemi/mcp] "${z}" failed for ${W.via}:${W.id}:`,I),this.toolResult(Z,{content:[{type:"text",text:`"${z}" failed on the server.`}],isError:!0})}let Q=typeof H==="string"?H:JSON.stringify(H??null),V=Y.outputSchema&&(Z.era.modern||O(H))?{structuredContent:H}:{};return this.toolResult(Z,{content:[{type:"text",text:Q}],...V,isError:!1})}toolResult(Z,$){return Z.era.modern?this.complete($):$}async approval(Z,$,G){let W=V9($,G),z=(H)=>({kind:"answer",result:this.toolResult(Z,{content:[{type:"text",text:H}],isError:!0})});if(Z.era.modern){let H=O(Z.params._meta)?Z.params._meta:{},Q=O(H[BZ])?H[BZ]:{},V=O(Z.params.inputResponses)?Z.params.inputResponses:null,I=Z.params.requestState,C=H9(G);if(V&&I!==void 0){let x=NZ(xZ,"grs1",I);if(!x||x.p!==s(Z.principal)||x.t!==$.name||x.a!==C)throw new F(N.InvalidParams,"requestState is not valid for this call.");if(!await this.spendNonce(x.n,x.exp))throw new F(N.InvalidParams,"requestState has already been used.");return sZ(V[iZ])?{kind:"approved"}:z(`The user did not approve "${$.name}", and it did not run.`)}if(!nZ(Q.elicitation))throw new F(N.MissingRequiredClientCapability,`"${$.name}" needs the user's approval, and this client cannot ask for it (elicitation).`,{requiredCapabilities:{elicitation:{form:{}}}},400);let P={p:s(Z.principal),t:$.name,a:C,n:dZ(16).toString("base64url"),exp:Date.now()+pZ};return{kind:"answer",result:{resultType:"input_required",inputRequests:{[iZ]:{method:"elicitation/create",params:{mode:"form",...W}}},requestState:FZ(xZ,"grs1",P),_meta:{[IZ]:this.serverInfo}}}}let X=Z.era;if(!X.session.e||!Z.stream)return z(`"${$.name}" needs the user's approval, and this client cannot ask for it (elicitation). It did not run.`);let Y=`gemi-approval-${dZ(12).toString("base64url")}`,K=X.sessionId,U=await new Promise((H)=>{let Q=setTimeout(()=>{this.pending.delete(Y),H(null)},this.approvalTimeoutMs),V=(I)=>{clearTimeout(Q),H(I)};this.pending.set(Y,{session:K,resolve:V}),Z.signal.addEventListener("abort",()=>{this.pending.delete(Y),V(null)}),Z.stream.send({jsonrpc:"2.0",id:Y,method:"elicitation/create",params:X.session.v==="2025-11-25"?{mode:"form",...W}:W})});return U&&!U.error&&sZ(U.result)?{kind:"approved"}:z(`The user did not approve "${$.name}", and it did not run.`)}async spendNonce(Z,$){try{return await this.nonces.consume(Z,$)}catch(G){return console.error("[gemi/mcp] Spending an approval failed:",G),!1}}async respond(Z,$,G,W,z){if(!G)try{let U=await $(null,W);return S({jsonrpc:"2.0",id:Z.id,result:U},200)}finally{z?.()}let X=new AbortController,Y=AbortSignal.any([X.signal,W]),K=new G3(()=>X.abort());return(async()=>{try{let U=await $(K,Y);K.send({jsonrpc:"2.0",id:Z.id,result:U})}catch(U){if(U instanceof F)K.send(T(Z.id,U));else console.error("[gemi/mcp] The MCP endpoint failed:",U),K.send(T(Z.id,new F(N.InternalError,"Internal error.")))}finally{z?.(),K.close()}})(),new Response(K.readable,{status:200,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-store","X-Accel-Buffering":"no"}})}unauthorized(Z){let $=this.resolvers.map((W)=>W.challenge?.(this.context)).find(Boolean)??'Bearer realm="mcp"',G=Z?`${$}, error="invalid_token", error_description="${Z.replace(/["\\]/g,"")}"`:$;return S(T(null,new F(N.InvalidRequest,"Unauthorized.")),401,{"WWW-Authenticate":G})}async failedAttempt(Z){let $=rZ(new CZ(Z,{},"api",this.endpoint.pathname)),G=await HZ(`mcp-auth-failed:${$}`,z9);return G===null?null:oZ(G)}async spend(Z){if(!this.rateLimit)return null;let $=await HZ(`mcp-endpoint:${Z.via}:${Z.id}`,this.rateLimit);return $===null?null:oZ($)}}class G3{readable;controller;closed=!1;encoder=new TextEncoder;constructor(Z){this.readable=new ReadableStream({start:($)=>{this.controller=$},cancel:()=>{this.closed=!0,Z()}})}send(Z){if(this.closed)return;this.controller.enqueue(this.encoder.encode(`event: message
3
3
  data: ${JSON.stringify(Z)}
4
4
 
5
5
  `))}close(){if(this.closed)return;this.closed=!0,this.controller.close()}}class o extends Error{}async function X9(Z,$){let G=Number(Z.headers.get("content-length"));if(Number.isFinite(G)&&G>$)throw new o;if(!Z.body)return"";let W=Z.body.getReader(),z=[],X=0;for(;;){let{done:Y,value:K}=await W.read();if(Y)break;if(X+=K.byteLength,X>$)throw await W.cancel(),new o;z.push(K)}return Buffer.concat(z).toString("utf8")}function S(Z,$,G={}){return new Response(JSON.stringify(Z),{status:$,headers:{"Content-Type":"application/json","Cache-Control":"no-store",...G}})}function lZ(Z,$){for(let[G,W]of Object.entries($))Z.headers.set(G,W);return Z}function Y9(Z){return{"Access-Control-Allow-Origin":Z,"Access-Control-Expose-Headers":"Mcp-Session-Id, WWW-Authenticate",Vary:"Origin"}}function K9(Z){let $;try{$=new URL(Z)}catch{throw Error(`route.mcp.remote.url: "${Z}" is not a URL.`)}let G=$.hostname==="localhost"||$.hostname==="127.0.0.1"||$.hostname==="[::1]";if($.protocol!=="https:"&&!($.protocol==="http:"&&G))throw Error("route.mcp.remote.url must be https (http only on localhost): tokens travel to it.");if($.search||$.hash||$.username||$.password)throw Error("route.mcp.remote.url must have no query, fragment or credentials.");if($.pathname==="/"||$.pathname.endsWith("/"))throw Error('route.mcp.remote.url needs a path of its own, like "/mcp", without a trailing slash.');return $}function s(Z){return $3("sha256").update(`${Z.via}\x00${Z.id}\x00${Z.user?.id}`).digest("base64url").slice(0,32)}function H9(Z){return $3("sha256").update(Z3(Z??{})).digest("base64url")}function nZ(Z){if(!O(Z))return!1;if(Object.keys(Z).length===0)return!0;return"form"in Z}function tZ(Z){let $=O(Z._meta)?Z._meta:{};return typeof $.progressToken==="string"||typeof $.progressToken==="number"}function U9(Z,$,G){if($.method!=="tools/call"||!G.e)return!1;let W=$.params?.name;return typeof W==="string"&&Z.descriptors({names:[W]})[0]?.requiresApproval===!0}function Q9(Z){let G=(O(Z.params._meta)?Z.params._meta:{}).progressToken;if(!Z.stream||typeof G!=="string"&&typeof G!=="number")return;let W=-1/0;return(z)=>{if(typeof z?.progress!=="number"||!Number.isFinite(z.progress)||z.progress<=W)return;W=z.progress,Z.stream.send({jsonrpc:"2.0",method:"notifications/progress",params:{progressToken:G,progress:z.progress,...typeof z.total==="number"?{total:z.total}:{},...typeof z.message==="string"?{message:z.message.slice(0,1000)}:{}}})}}function V9(Z,$){let G=JSON.stringify($??{},null,1),W=G.length>PZ?`${G.slice(0,PZ)}\u2026 (${G.length-PZ} more characters not shown)`:G;return{message:`Allow "${Z.title??Z.name}" to run? ${Z.description}
@@ -1,6 +1,6 @@
1
1
  // @bun
2
- import{Ba as y}from"./chunk-kk18xqgc.js";import{createElement as q}from"react";function z(i,n){let p=Object.keys(n).sort((s,g)=>g.length-s.length).map((s)=>s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")),b=new RegExp(p.join("|"),"g");return i.replace(b,(s)=>n[s])}async function L(i,n,p=[],b){let s=[...p.map((t)=>`${i}/views/${t}.tsx`),b?`${i}/views/${b}.tsx`:`${i}/views/RootLayout.tsx`],g=new Set;for(let t of s){let u=n.moduleGraph.getModulesByFile(t);if(u)for(let x of u)g.add(x)}let e=[],l=[],r={};for(let t of g)if(t)for(let u of t.importedModules){if(u.file.includes("module.css"))r[u.file]=u.ssrTransformResult.map.sourcesContent.join("");if(u.file.includes(".css"))l.push(u.file)}for(let t of l){let u=await n.transformRequest(t+"?direct"),x=t.includes("module.css"),k="";if(x)k=z(r[t],u.default);e.push({isDev:!0,id:t,content:x?k:u.code})}return e.map((t,u)=>{return q("style",{key:u,type:"text/css","data-vite-dev-id":t.id,dangerouslySetInnerHTML:{__html:t.content}})})}async function _(i=[]){return i.map((n,p)=>{return q("style",{key:p,id:n?.id,type:"text/css",dangerouslySetInnerHTML:{__html:n.content}})})}import{existsSync as J}from"fs";import{basename as N}from"path";import{networkInterfaces as O}from"os";var v={name:"gemi",version:"0.120.1",private:!1,license:"MIT",author:"Enes Tufekci <enes@gemijs.dev>",repository:{type:"git",url:"git+https://github.com/nstfkc/gemi.git",directory:"packages/gemi"},bin:{gemi:"./dist/bin/gemi.js","gemi-orm-generator":"./dist/bin/orm-generator.js"},files:["dist/**/*","ide/typescript-plugin/package.json","skills/**/*"],module:!0,exports:{"./http":"./http/index.ts","./client":"./client/index.ts","./ai":"./ai/index.ts","./ai/client":"./ai/client/index.ts","./testing":"./testing/index.ts","./app":"./app/index.ts","./facades":"./facades/index.ts","./email":"./email/index.ts","./vite":"./dist/vite/index.mjs","./kernel":"./kernel/index.ts","./services":"./services/index.ts","./i18n":"./i18n/index.ts","./dictionary":"./i18n/dictionaryRuntime.ts","./server":"./server/index.ts","./config":"./config/index.ts","./container":"./container/index.ts","./foundation":"./foundation/index.ts","./database":"./database/index.ts","./orm":"./orm/index.ts","./support":"./support/index.ts","./console/run":"./console/run.ts","./queue/work":"./services/queue/work.ts","./stats/route-table":"./stats/route-table.ts","./ide/typescript-plugin":"./ide/typescript-plugin/index.ts","./bun/preload":"./bun/preload.ts","./bun/plugin":"./bun/plugin.ts","./vitest":"./vitest/index.ts"},scripts:{lint:"oxlint",typecheck:"tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.browser.json && tsc --noEmit -p ide/typescript-plugin/tsconfig.json",build:"NODE_ENV=production bun run build:core && bun run build:bin && bun run build:types && bun run build:client && bun run build:plugin && bun run build:ts-plugin && bun run build:client-types && bun run build:augmentation","build:core":"bun ./scripts/build.ts","build:bin":"bun build --outdir=./dist/bin --target=bun --external=vite --external=react-dom --external=react/jsx-runtime --external=bun --external=sharp --external=@azure/storage-blob --external=typescript --sourcemap ./bin/gemi.ts ./bin/orm-generator.ts && bun ./scripts/prepare-bin.ts","build:client":"rm -rf dist/client dist/testing dist/ai/client dist/chunks && vite build -c vite.client.config.mts","build:plugin":"vite build -c vite.plugin.config.mts","build:ts-plugin":"bun ./scripts/build-ts-plugin.ts","build:types":"tsc -p tsconfig.build.json","build:client-types":"tsc -p tsconfig.browser.json",test:"bun --bun x vitest","test:types":"vitest run --typecheck.only","test:live":"bun --bun x vitest run ai/live","test:packaging":"bun --bun x vitest run --config vitest.packaging.config.ts","build:publish":"bun scripts/build-publish.ts",prepublishOnly:"echo 'Do not publish from this directory \u2014 its exports point at TS source. Run: bun run build:publish, then publish from .publish/' && exit 1","build:augmentation":"bun ./scripts/wire-augmentation.ts"},dependencies:{"@aws-sdk/client-s3":"^3.629.0","@aws-sdk/s3-request-presigner":"^3.629.0","ast-types":"^0.14.2",commander:"^12.1.0",history:"^5.3.0","jsx-email":"2.0.0-rc2.1","magic-string":"^0.30.17",open:"^10.1.0","react-error-boundary":"^6.0.0",recast:"^0.23.9",resend:"^6.12.3",satori:"^0.12.2","temporal-polyfill":"^0.2.5","twitter-api-v2":"^1.20.2","urlpattern-polyfill":"^10.0.0",uuid:"^9.0.1"},devDependencies:{"@babel/parser":"^7.25.4","@prisma/generator-helper":"^6.5.0","@repo/typescript-config":"*","@testing-library/react":"^16.3.2","@types/bun":"^1.3.14","@types/eslint":"^8.56.5","@types/node":"^20.11.24","@types/react":"^19.0.2","@types/react-dom":"^19.0.2",eslint:"^8.57.0",jsdom:"^30.0.1",oxlint:"^1.39.0",postgres:"^3.4.5",react:"19.2.3","react-dom":"19.2.3",typescript:"^5.7.3",vitest:"^4.0.0"},peerDependencies:{"@azure/storage-blob":"^12.28.0",react:">=19","react-dom":">=19",sharp:"^0.34.2",typescript:">=5",vite:"^8.0.0",postgres:"^3.4.0"},peerDependenciesMeta:{"@azure/storage-blob":{optional:!0},typescript:{optional:!0},postgres:{optional:!0}}};var Q=[" \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557\u2588\u2588\u2557","\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551","\u2588\u2588\u2551 \u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2554\u2588\u2588\u2588\u2588\u2554\u2588\u2588\u2551\u2588\u2588\u2551","\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551\u255A\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2551","\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551\u2588\u2588\u2551"," \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D"],W=Boolean(process.stdout.isTTY)&&!process.env.NO_COLOR,c=(i,n)=>W?`\x1B[${i}m${n}\x1B[0m`:n,X=(i)=>c("1",i),d=(i)=>c("2",i),j=(i)=>c("36",i),Y=(i)=>c("32",i),Z=(i)=>c("35",i);function $(){return v.version??"?"}function f(i){for(let n of Object.values(O()))for(let p of n??[])if((p.family==="IPv4"||p.family===4)&&!p.internal)return`http://${p.address}:${i}`;return null}function H(i){return y(i).filter((n)=>J(n)).map((n)=>N(n))}function T(i){let{port:n,rootDir:p}=i,b=`http://localhost:${n}`,s=f(n),g=H(p),e=(r,t)=>` ${Y("\u279C")} ${X(r.padEnd(9))}${t}`,l=["",...Q.map((r)=>Z(r)),"",` ${d("gemi")} ${j(`v${$()}`)}`,"",e("Local:",j(b)),e("Network:",s?j(s):d("unavailable")),e("Env:",g.length?g.join(", "):d("none")),""];console.log(l.join(`
2
+ import{Ba as y}from"./chunk-kk18xqgc.js";import{createElement as q}from"react";function z(i,n){let p=Object.keys(n).sort((s,g)=>g.length-s.length).map((s)=>s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")),b=new RegExp(p.join("|"),"g");return i.replace(b,(s)=>n[s])}async function L(i,n,p=[],b){let s=[...p.map((t)=>`${i}/views/${t}.tsx`),b?`${i}/views/${b}.tsx`:`${i}/views/RootLayout.tsx`],g=new Set;for(let t of s){let u=n.moduleGraph.getModulesByFile(t);if(u)for(let x of u)g.add(x)}let e=[],l=[],r={};for(let t of g)if(t)for(let u of t.importedModules){if(u.file.includes("module.css"))r[u.file]=u.ssrTransformResult.map.sourcesContent.join("");if(u.file.includes(".css"))l.push(u.file)}for(let t of l){let u=await n.transformRequest(t+"?direct"),x=t.includes("module.css"),k="";if(x)k=z(r[t],u.default);e.push({isDev:!0,id:t,content:x?k:u.code})}return e.map((t,u)=>{return q("style",{key:u,type:"text/css","data-vite-dev-id":t.id,dangerouslySetInnerHTML:{__html:t.content}})})}async function _(i=[]){return i.map((n,p)=>{return q("style",{key:p,id:n?.id,type:"text/css",dangerouslySetInnerHTML:{__html:n.content}})})}import{existsSync as J}from"fs";import{basename as N}from"path";import{networkInterfaces as O}from"os";var v={name:"gemi",version:"0.121.0",private:!1,license:"MIT",author:"Enes Tufekci <enes@gemijs.dev>",repository:{type:"git",url:"git+https://github.com/nstfkc/gemi.git",directory:"packages/gemi"},bin:{gemi:"./dist/bin/gemi.js","gemi-orm-generator":"./dist/bin/orm-generator.js"},files:["dist/**/*","ide/typescript-plugin/package.json","skills/**/*"],module:!0,exports:{"./http":"./http/index.ts","./client":"./client/index.ts","./ai":"./ai/index.ts","./ai/client":"./ai/client/index.ts","./testing":"./testing/index.ts","./app":"./app/index.ts","./facades":"./facades/index.ts","./email":"./email/index.ts","./vite":"./dist/vite/index.mjs","./kernel":"./kernel/index.ts","./services":"./services/index.ts","./i18n":"./i18n/index.ts","./dictionary":"./i18n/dictionaryRuntime.ts","./server":"./server/index.ts","./config":"./config/index.ts","./container":"./container/index.ts","./foundation":"./foundation/index.ts","./database":"./database/index.ts","./orm":"./orm/index.ts","./support":"./support/index.ts","./console/run":"./console/run.ts","./queue/work":"./services/queue/work.ts","./stats/route-table":"./stats/route-table.ts","./ide/typescript-plugin":"./ide/typescript-plugin/index.ts","./bun/preload":"./bun/preload.ts","./bun/plugin":"./bun/plugin.ts","./vitest":"./vitest/index.ts"},scripts:{lint:"oxlint",typecheck:"tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.browser.json && tsc --noEmit -p ide/typescript-plugin/tsconfig.json",build:"NODE_ENV=production bun run build:core && bun run build:bin && bun run build:types && bun run build:client && bun run build:plugin && bun run build:ts-plugin && bun run build:client-types && bun run build:augmentation","build:core":"bun ./scripts/build.ts","build:bin":"bun build --outdir=./dist/bin --target=bun --external=vite --external=react-dom --external=react/jsx-runtime --external=bun --external=sharp --external=@azure/storage-blob --external=typescript --sourcemap ./bin/gemi.ts ./bin/orm-generator.ts && bun ./scripts/prepare-bin.ts","build:client":"rm -rf dist/client dist/testing dist/ai/client dist/chunks && vite build -c vite.client.config.mts","build:plugin":"vite build -c vite.plugin.config.mts","build:ts-plugin":"bun ./scripts/build-ts-plugin.ts","build:types":"tsc -p tsconfig.build.json","build:client-types":"tsc -p tsconfig.browser.json",test:"bun --bun x vitest","test:types":"vitest run --typecheck.only","test:live":"bun --bun x vitest run ai/live","test:packaging":"bun --bun x vitest run --config vitest.packaging.config.ts","build:publish":"bun scripts/build-publish.ts",prepublishOnly:"echo 'Do not publish from this directory \u2014 its exports point at TS source. Run: bun run build:publish, then publish from .publish/' && exit 1","build:augmentation":"bun ./scripts/wire-augmentation.ts"},dependencies:{"@aws-sdk/client-s3":"^3.629.0","@aws-sdk/s3-request-presigner":"^3.629.0","ast-types":"^0.14.2",commander:"^12.1.0",history:"^5.3.0","jsx-email":"2.0.0-rc2.1","magic-string":"^0.30.17",open:"^10.1.0","react-error-boundary":"^6.0.0",recast:"^0.23.9",resend:"^6.12.3",satori:"^0.12.2","temporal-polyfill":"^0.2.5","twitter-api-v2":"^1.20.2","urlpattern-polyfill":"^10.0.0",uuid:"^9.0.1"},devDependencies:{"@babel/parser":"^7.25.4","@prisma/generator-helper":"^6.5.0","@repo/typescript-config":"*","@testing-library/react":"^16.3.2","@types/bun":"^1.3.14","@types/eslint":"^8.56.5","@types/node":"^20.11.24","@types/react":"^19.0.2","@types/react-dom":"^19.0.2",eslint:"^8.57.0",jsdom:"^30.0.1",oxlint:"^1.39.0",postgres:"^3.4.5",react:"19.2.3","react-dom":"19.2.3",typescript:"^5.7.3",vitest:"^4.0.0"},peerDependencies:{"@azure/storage-blob":"^12.28.0",react:">=19","react-dom":">=19",sharp:"^0.34.2",typescript:">=5",vite:"^8.0.0",postgres:"^3.4.0"},peerDependenciesMeta:{"@azure/storage-blob":{optional:!0},typescript:{optional:!0},postgres:{optional:!0}}};var Q=[" \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557\u2588\u2588\u2557","\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551","\u2588\u2588\u2551 \u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2554\u2588\u2588\u2588\u2588\u2554\u2588\u2588\u2551\u2588\u2588\u2551","\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551\u255A\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2551","\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551\u2588\u2588\u2551"," \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D"],W=Boolean(process.stdout.isTTY)&&!process.env.NO_COLOR,c=(i,n)=>W?`\x1B[${i}m${n}\x1B[0m`:n,X=(i)=>c("1",i),d=(i)=>c("2",i),j=(i)=>c("36",i),Y=(i)=>c("32",i),Z=(i)=>c("35",i);function $(){return v.version??"?"}function f(i){for(let n of Object.values(O()))for(let p of n??[])if((p.family==="IPv4"||p.family===4)&&!p.internal)return`http://${p.address}:${i}`;return null}function H(i){return y(i).filter((n)=>J(n)).map((n)=>N(n))}function T(i){let{port:n,rootDir:p}=i,b=`http://localhost:${n}`,s=f(n),g=H(p),e=(r,t)=>` ${Y("\u279C")} ${X(r.padEnd(9))}${t}`,l=["",...Q.map((r)=>Z(r)),"",` ${d("gemi")} ${j(`v${$()}`)}`,"",e("Local:",j(b)),e("Network:",s?j(s):d("unavailable")),e("Env:",g.length?g.join(", "):d("none")),""];console.log(l.join(`
3
3
  `))}function I(i=process.env.SERVER_IDLE_TIMEOUT){if(i===void 0||i.trim()==="")return 10;let n=Number(i.trim());if(!Number.isInteger(n)||n<0||n>255)throw Error(`SERVER_IDLE_TIMEOUT must be a whole number of seconds from 0 to 255 (0 disables the timeout), got ${JSON.stringify(i)}.`);return n}
4
4
  export{L as R,_ as S,T,I as U};
5
5
 
6
- //# debugId=FCD4109D0D976AD564756E2164756E21
6
+ //# debugId=A9FDD937DDD46A0664756E2164756E21
@@ -7,6 +7,6 @@
7
7
  "/**\n * Bun's default, and what both servers use when `SERVER_IDLE_TIMEOUT` is unset.\n */\nexport const DEFAULT_SERVER_IDLE_TIMEOUT = 10;\n\n/**\n * The `idleTimeout` (seconds) both `gemi dev` and `gemi start` pass to\n * `Bun.serve`, from `SERVER_IDLE_TIMEOUT` (#787).\n *\n * One reader for both servers, so a long-poll that works under `gemi start`\n * also works under `gemi dev`. Before this, only `httpProd` read the variable\n * and the dev server always ran at Bun's 10 seconds.\n *\n * It is the time a connection may stay silent, a response that has not started\n * included, before Bun closes it; `0` disables it. It does not apply to an\n * upgraded websocket (the HMR relay included), which has its own\n * `websocket.idleTimeout`.\n *\n * Unset or blank means the default. Anything that is not a whole number from 0\n * to 255 (Bun's own limits) fails the boot with the variable's name, instead\n * of Bun's \"expects idleTimeout to be an integer\", which does not say where the\n * value came from.\n */\nexport function serverIdleTimeout(raw: string | undefined = process.env.SERVER_IDLE_TIMEOUT): number {\n if (raw === undefined || raw.trim() === \"\") return DEFAULT_SERVER_IDLE_TIMEOUT;\n\n const seconds = Number(raw.trim());\n if (!Number.isInteger(seconds) || seconds < 0 || seconds > 255) {\n throw new Error(\n `SERVER_IDLE_TIMEOUT must be a whole number of seconds from 0 to 255 ` +\n `(0 disables the timeout), got ${JSON.stringify(raw)}.`,\n );\n }\n return seconds;\n}\n"
8
8
  ],
9
9
  "mappings": ";yCAAA,wBAAS,cAGT,SAAS,CAAc,CAAC,EAAc,EAAwC,CAC5E,IAAM,EAAc,OAAO,KAAK,CAAM,EACnC,KAAK,CAAC,EAAG,IAAM,EAAE,OAAS,EAAE,MAAM,EAClC,IAAI,CAAC,IAAQ,EAAI,QAAQ,sBAAuB,MAAM,CAAC,EAGpD,EAAQ,IAAI,OAAO,EAAY,KAAK,GAAG,EAAG,GAAG,EAEnD,OAAO,EAAK,QAAQ,EAAO,CAAC,IAAU,EAAO,EAAM,EAGrD,eAAsB,CAAe,CACnC,EACA,EACA,EAAyB,CAAC,EAE1B,EACA,CACA,IAAM,EAAQ,CACZ,GAAG,EAAa,IAAI,CAAC,IAAS,GAAG,WAAgB,OAAU,EAC3D,EAAS,GAAG,WAAgB,QAAe,GAAG,wBAChD,EAEM,EAAU,IAAI,IACpB,QAAW,KAAQ,EAAO,CACxB,IAAM,EAAM,EAAK,YAAY,iBAAiB,CAAI,EAClD,GAAI,EACF,QAAW,KAAK,EAAK,EAAQ,IAAI,CAAC,EAItC,IAAM,EAAS,CAAC,EACV,EAAa,CAAC,EACd,EAA2C,CAAC,EAClD,QAAW,KAAO,EAChB,GAAI,EACF,QAAW,KAAY,EAAI,gBAAiB,CAC1C,GAAI,EAAS,KAAK,SAAS,YAAY,EACrC,EAAiB,EAAS,MAAQ,EAAS,mBAAmB,IAAI,eAAe,KAAK,EAAE,EAE1F,GAAI,EAAS,KAAK,SAAS,MAAM,EAC/B,EAAW,KAAK,EAAS,IAAI,EAMrC,QAAW,KAAiB,EAAY,CACtC,IAAM,EAAY,MAAM,EAAK,iBAAiB,EAAgB,SAAS,EAEjE,EAAc,EAAc,SAAS,YAAY,EAEnD,EAAuB,GAE3B,GAAI,EACF,EAAuB,EACrB,EAAiB,GAGhB,EAA6D,OAChE,EAGF,EAAO,KAAK,CACV,MAAO,GACP,GAAI,EACJ,QAAS,EAAc,EAAuB,EAAU,IAC1D,CAAC,EAGH,OAAO,EAAO,IAAI,CAAC,EAAO,IAAM,CAC9B,OAAO,EAAc,QAAS,CAC5B,IAAK,EACL,KAAM,WACN,mBAAoB,EAAM,GAC1B,wBAAyB,CAAE,OAAQ,EAAM,OAAQ,CACnD,CAAC,EACF,EAGH,eAAsB,CAAY,CAAC,EAAS,CAAC,EAAG,CAC9C,OAAO,EAAO,IAAI,CAAC,EAAO,IAAM,CAC9B,OAAO,EAAc,QAAS,CAC5B,IAAK,EACL,GAAI,GAAO,GACX,KAAM,WACN,wBAAyB,CAAE,OAAQ,EAAM,OAAQ,CACnD,CAAC,EACF,EC3FH,qBAAS,WACT,mBAAS,aACT,4BAAS,gyHAKT,IAAM,EAAM,CACV,oKACA,mLACA,yKACA,oKACA,mLACA,yJACF,EAEM,EAAW,QAAQ,QAAQ,OAAO,KAAK,GAAK,CAAC,QAAQ,IAAI,SACzD,EAAQ,CAAC,EAAc,IAC3B,EAAW,QAAQ,KAAQ,WAAgB,EACvC,EAAO,CAAC,IAAc,EAAM,IAAK,CAAC,EAClC,EAAM,CAAC,IAAc,EAAM,IAAK,CAAC,EACjC,EAAO,CAAC,IAAc,EAAM,KAAM,CAAC,EACnC,EAAQ,CAAC,IAAc,EAAM,KAAM,CAAC,EACpC,EAAU,CAAC,IAAc,EAAM,KAAM,CAAC,EAE5C,SAAS,CAAW,EAAW,CAC7B,OAAQ,EAA6B,SAAW,IAGlD,SAAS,CAAU,CAAC,EAAsC,CACxD,QAAW,KAAU,OAAO,OAAO,EAAkB,CAAC,EACpD,QAAW,KAAS,GAAU,CAAC,EAG7B,IADa,EAAM,SAAW,QAAW,EAAM,SAAuB,IAC1D,CAAC,EAAM,SAAU,MAAO,UAAU,EAAM,WAAW,IAGnE,OAAO,KAGT,SAAS,CAAc,CAAC,EAA2B,CACjD,OAAO,EAAS,CAAO,EACpB,OAAO,CAAC,IAAS,EAAW,CAAI,CAAC,EACjC,IAAI,CAAC,IAAS,EAAS,CAAI,CAAC,EAG1B,SAAS,CAAkB,CAAC,EAGhC,CACD,IAAQ,OAAM,WAAY,EACpB,EAAQ,oBAAoB,IAC5B,EAAU,EAAW,CAAI,EACzB,EAAM,EAAe,CAAO,EAE5B,EAAM,CAAC,EAAe,IAC1B,KAAK,EAAM,QAAE,MAAM,EAAK,EAAM,OAAO,CAAC,CAAC,IAAI,IAEvC,EAAM,CACV,GACA,GAAG,EAAI,IAAI,CAAC,IAAS,EAAQ,CAAI,CAAC,EAClC,GACA,KAAK,EAAI,MAAM,KAAK,EAAK,IAAI,EAAY,GAAG,IAC5C,GACA,EAAI,SAAU,EAAK,CAAK,CAAC,EACzB,EAAI,WAAY,EAAU,EAAK,CAAO,EAAI,EAAI,aAAa,CAAC,EAC5D,EAAI,OAAQ,EAAI,OAAS,EAAI,KAAK,IAAI,EAAI,EAAI,MAAM,CAAC,EACrD,EACF,EAEA,QAAQ,IAAI,EAAI,KAAK;AAAA,CAAI,CAAC,EC/CrB,SAAS,CAAiB,CAAC,EAA0B,QAAQ,IAAI,oBAA6B,CACnG,GAAI,IAAQ,QAAa,EAAI,KAAK,IAAM,GAAI,MArBH,IAuBzC,IAAM,EAAU,OAAO,EAAI,KAAK,CAAC,EACjC,GAAI,CAAC,OAAO,UAAU,CAAO,GAAK,EAAU,GAAK,EAAU,IACzD,MAAU,MACR,qGACmC,KAAK,UAAU,CAAG,IACvD,EAEF,OAAO",
10
- "debugId": "FCD4109D0D976AD564756E2164756E21",
10
+ "debugId": "A9FDD937DDD46A0664756E2164756E21",
11
11
  "names": []
12
12
  }