mdzilla 0.0.3 → 0.0.5

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.
@@ -0,0 +1,1882 @@
1
+ import { mkdir, readFile, readdir, stat, writeFile } from "node:fs/promises";
2
+ import { basename, dirname, extname, join } from "node:path";
3
+ import { parseMeta, renderToMarkdown, renderToText } from "md4x";
4
+ import { existsSync } from "node:fs";
5
+ import { tmpdir } from "node:os";
6
+ import { init, parseMeta as parseMeta$1, renderToHtml, renderToText as renderToText$1 } from "md4x/napi";
7
+ import { highlightText } from "@speed-highlight/core";
8
+ //#region web/.output/server/index.mjs
9
+ globalThis.__nitro_main__ = import.meta.url;
10
+ var __defProp = Object.defineProperty;
11
+ var __esmMin = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
12
+ var __exportAll = (all, no_symbols) => {
13
+ let target = {};
14
+ for (var name in all) __defProp(target, name, {
15
+ get: all[name],
16
+ enumerable: true
17
+ });
18
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
19
+ return target;
20
+ };
21
+ var services = {};
22
+ globalThis.__nitro_vite_envs__ = services;
23
+ var NullProtoObj;
24
+ var init_dist = __esmMin((() => {
25
+ NullProtoObj = /* @__PURE__ */ (() => {
26
+ const e = function() {};
27
+ return e.prototype = Object.create(null), Object.freeze(e.prototype), e;
28
+ })();
29
+ }));
30
+ var FastURL, FastResponse;
31
+ var init_generic = __esmMin((() => {
32
+ FastURL = URL;
33
+ FastResponse = Response;
34
+ }));
35
+ function sanitizeStatusMessage(statusMessage = "") {
36
+ return statusMessage.replace(DISALLOWED_STATUS_CHARS, "");
37
+ }
38
+ function sanitizeStatusCode(statusCode, defaultStatusCode = 200) {
39
+ if (!statusCode) return defaultStatusCode;
40
+ if (typeof statusCode === "string") statusCode = +statusCode;
41
+ if (statusCode < 100 || statusCode > 599) return defaultStatusCode;
42
+ return statusCode;
43
+ }
44
+ function isJSONSerializable(value, _type) {
45
+ if (value === null || value === void 0) return true;
46
+ if (_type !== "object") return _type === "boolean" || _type === "number" || _type === "string";
47
+ if (typeof value.toJSON === "function") return true;
48
+ if (Array.isArray(value)) return true;
49
+ if (typeof value.pipe === "function" || typeof value.pipeTo === "function") return false;
50
+ if (value instanceof NullProtoObj) return true;
51
+ const proto = Object.getPrototypeOf(value);
52
+ return proto === Object.prototype || proto === null;
53
+ }
54
+ function toResponse(val, event, config = {}) {
55
+ if (typeof val?.then === "function") return (val.catch?.((error) => error) || Promise.resolve(val)).then((resolvedVal) => toResponse(resolvedVal, event, config));
56
+ const response = prepareResponse(val, event, config);
57
+ if (typeof response?.then === "function") return toResponse(response, event, config);
58
+ const { onResponse } = config;
59
+ return onResponse ? Promise.resolve(onResponse(response, event)).then(() => response) : response;
60
+ }
61
+ function prepareResponse(val, event, config, nested) {
62
+ if (val === kHandled) return new FastResponse(null);
63
+ if (val === kNotFound) val = new HTTPError({
64
+ status: 404,
65
+ message: `Cannot find any route matching [${event.req.method}] ${event.url}`
66
+ });
67
+ if (val && val instanceof Error) {
68
+ const isHTTPError = HTTPError.isError(val);
69
+ const error = isHTTPError ? val : new HTTPError(val);
70
+ if (!isHTTPError) {
71
+ error.unhandled = true;
72
+ if (val?.stack) error.stack = val.stack;
73
+ }
74
+ if (error.unhandled && !config.silent) console.error(error);
75
+ const { onError } = config;
76
+ return onError && !nested ? Promise.resolve(onError(error, event)).catch((error) => error).then((newVal) => prepareResponse(newVal ?? val, event, config, true)) : errorResponse(error, config.debug);
77
+ }
78
+ const preparedRes = event[kEventRes];
79
+ const preparedHeaders = preparedRes?.[kEventResHeaders];
80
+ event[kEventRes] = void 0;
81
+ if (!(val instanceof Response)) {
82
+ const res = prepareResponseBody(val, event, config);
83
+ const status = res.status || preparedRes?.status;
84
+ return new FastResponse(nullBody(event.req.method, status) ? null : res.body, {
85
+ status,
86
+ statusText: res.statusText || preparedRes?.statusText,
87
+ headers: res.headers && preparedHeaders ? mergeHeaders$1(res.headers, preparedHeaders) : res.headers || preparedHeaders
88
+ });
89
+ }
90
+ if (!preparedHeaders || nested || !val.ok) return val;
91
+ try {
92
+ mergeHeaders$1(val.headers, preparedHeaders, val.headers);
93
+ return val;
94
+ } catch {
95
+ return new FastResponse(nullBody(event.req.method, val.status) ? null : val.body, {
96
+ status: val.status,
97
+ statusText: val.statusText,
98
+ headers: mergeHeaders$1(val.headers, preparedHeaders)
99
+ });
100
+ }
101
+ }
102
+ function mergeHeaders$1(base, overrides, target = new Headers(base)) {
103
+ for (const [name, value] of overrides) if (name === "set-cookie") target.append(name, value);
104
+ else target.set(name, value);
105
+ return target;
106
+ }
107
+ function prepareResponseBody(val, event, config) {
108
+ if (val === null || val === void 0) return {
109
+ body: "",
110
+ headers: emptyHeaders
111
+ };
112
+ const valType = typeof val;
113
+ if (valType === "string") return { body: val };
114
+ if (val instanceof Uint8Array) {
115
+ event.res.headers.set("content-length", val.byteLength.toString());
116
+ return { body: val };
117
+ }
118
+ if (val instanceof HTTPResponse || val?.constructor?.name === "HTTPResponse") return val;
119
+ if (isJSONSerializable(val, valType)) return {
120
+ body: JSON.stringify(val, void 0, config.debug ? 2 : void 0),
121
+ headers: jsonHeaders
122
+ };
123
+ if (valType === "bigint") return {
124
+ body: val.toString(),
125
+ headers: jsonHeaders
126
+ };
127
+ if (val instanceof Blob) {
128
+ const headers = new Headers({
129
+ "content-type": val.type,
130
+ "content-length": val.size.toString()
131
+ });
132
+ let filename = val.name;
133
+ if (filename) {
134
+ filename = encodeURIComponent(filename);
135
+ headers.set("content-disposition", `filename="${filename}"; filename*=UTF-8''${filename}`);
136
+ }
137
+ return {
138
+ body: val.stream(),
139
+ headers
140
+ };
141
+ }
142
+ if (valType === "symbol") return { body: val.toString() };
143
+ if (valType === "function") return { body: `${val.name}()` };
144
+ return { body: val };
145
+ }
146
+ function nullBody(method, status) {
147
+ return method === "HEAD" || status === 100 || status === 101 || status === 102 || status === 204 || status === 205 || status === 304;
148
+ }
149
+ function errorResponse(error, debug) {
150
+ return new FastResponse(JSON.stringify({
151
+ ...error.toJSON(),
152
+ stack: debug && error.stack ? error.stack.split("\n").map((l) => l.trim()) : void 0
153
+ }, void 0, debug ? 2 : void 0), {
154
+ status: error.status,
155
+ statusText: error.statusText,
156
+ headers: error.headers ? mergeHeaders$1(jsonHeaders, error.headers) : new Headers(jsonHeaders)
157
+ });
158
+ }
159
+ function callMiddleware(event, middleware, handler, index = 0) {
160
+ if (index === middleware.length) return handler(event);
161
+ const fn = middleware[index];
162
+ let nextCalled;
163
+ let nextResult;
164
+ const next = () => {
165
+ if (nextCalled) return nextResult;
166
+ nextCalled = true;
167
+ nextResult = callMiddleware(event, middleware, handler, index + 1);
168
+ return nextResult;
169
+ };
170
+ const ret = fn(event, next);
171
+ return isUnhandledResponse(ret) ? next() : typeof ret?.then === "function" ? ret.then((resolved) => isUnhandledResponse(resolved) ? next() : resolved) : ret;
172
+ }
173
+ function isUnhandledResponse(val) {
174
+ return val === void 0 || val === kNotFound;
175
+ }
176
+ function parseQuery(input) {
177
+ const params = new NullProtoObj();
178
+ if (!input || input === "?") return params;
179
+ const inputLength = input.length;
180
+ let key = "";
181
+ let value = "";
182
+ let startingIndex = -1;
183
+ let equalityIndex = -1;
184
+ let shouldDecodeKey = false;
185
+ let shouldDecodeValue = false;
186
+ let keyHasPlus = false;
187
+ let valueHasPlus = false;
188
+ let hasBothKeyValuePair = false;
189
+ let c = 0;
190
+ for (let i = 0; i < inputLength + 1; i++) {
191
+ c = i === inputLength ? 38 : input.charCodeAt(i);
192
+ switch (c) {
193
+ case 38:
194
+ hasBothKeyValuePair = equalityIndex > startingIndex;
195
+ if (!hasBothKeyValuePair) equalityIndex = i;
196
+ key = input.slice(startingIndex + 1, equalityIndex);
197
+ if (hasBothKeyValuePair || key.length > 0) {
198
+ if (keyHasPlus) key = key.replace(plusRegex, " ");
199
+ if (shouldDecodeKey) try {
200
+ key = decodeURIComponent(key);
201
+ } catch {}
202
+ if (hasBothKeyValuePair) {
203
+ value = input.slice(equalityIndex + 1, i);
204
+ if (valueHasPlus) value = value.replace(plusRegex, " ");
205
+ if (shouldDecodeValue) try {
206
+ value = decodeURIComponent(value);
207
+ } catch {}
208
+ }
209
+ const currentValue = params[key];
210
+ if (currentValue === void 0) params[key] = value;
211
+ else if (Array.isArray(currentValue)) currentValue.push(value);
212
+ else params[key] = [currentValue, value];
213
+ }
214
+ value = "";
215
+ startingIndex = i;
216
+ equalityIndex = i;
217
+ shouldDecodeKey = false;
218
+ shouldDecodeValue = false;
219
+ keyHasPlus = false;
220
+ valueHasPlus = false;
221
+ break;
222
+ case 61:
223
+ if (equalityIndex <= startingIndex) equalityIndex = i;
224
+ else shouldDecodeValue = true;
225
+ break;
226
+ case 43:
227
+ if (equalityIndex > startingIndex) valueHasPlus = true;
228
+ else keyHasPlus = true;
229
+ break;
230
+ case 37:
231
+ if (equalityIndex > startingIndex) shouldDecodeValue = true;
232
+ else shouldDecodeKey = true;
233
+ break;
234
+ }
235
+ }
236
+ return params;
237
+ }
238
+ function getQuery(event) {
239
+ return parseQuery((event.url || new URL(event.req.url)).search.slice(1));
240
+ }
241
+ function defineHandler(input) {
242
+ if (typeof input === "function") return handlerWithFetch(input);
243
+ const handler = input.handler || (input.fetch ? function _fetchHandler(event) {
244
+ return input.fetch(event.req);
245
+ } : NoHandler);
246
+ return Object.assign(handlerWithFetch(input.middleware?.length ? function _handlerMiddleware(event) {
247
+ return callMiddleware(event, input.middleware, handler);
248
+ } : handler), input);
249
+ }
250
+ function handlerWithFetch(handler) {
251
+ if ("fetch" in handler) return handler;
252
+ return Object.assign(handler, { fetch: (req) => {
253
+ if (typeof req === "string") req = new URL(req, "http://_");
254
+ if (req instanceof URL) req = new Request(req);
255
+ const event = new H3Event(req);
256
+ try {
257
+ return Promise.resolve(toResponse(handler(event), event));
258
+ } catch (error) {
259
+ return Promise.resolve(toResponse(error, event));
260
+ }
261
+ } });
262
+ }
263
+ function defineLazyEventHandler(loader) {
264
+ let handler;
265
+ let promise;
266
+ return defineHandler(function lazyHandler(event) {
267
+ return handler ? handler(event) : (promise ??= Promise.resolve(loader()).then(function resolveLazyHandler(r) {
268
+ handler = toEventHandler(r) || toEventHandler(r.default);
269
+ if (typeof handler !== "function") throw new TypeError("Invalid lazy handler", { cause: { resolved: r } });
270
+ return handler;
271
+ })).then((r) => r(event));
272
+ });
273
+ }
274
+ function toEventHandler(handler) {
275
+ if (typeof handler === "function") return handler;
276
+ if (typeof handler?.handler === "function") return handler.handler;
277
+ if (typeof handler?.fetch === "function") return function _fetchHandler(event) {
278
+ return handler.fetch(event.req);
279
+ };
280
+ }
281
+ var kEventNS, kEventRes, kEventResHeaders, H3Event, H3EventResponse, DISALLOWED_STATUS_CHARS, HTTPError, kNotFound, kHandled, HTTPResponse, frozen, FrozenHeaders, emptyHeaders, jsonHeaders, plusRegex, NoHandler, H3Core;
282
+ var init_h3_ByfIX5Jk = __esmMin((() => {
283
+ init_dist();
284
+ init_generic();
285
+ kEventNS = "h3.internal.event.";
286
+ kEventRes = /* @__PURE__ */ Symbol.for(`${kEventNS}res`);
287
+ kEventResHeaders = /* @__PURE__ */ Symbol.for(`${kEventNS}res.headers`);
288
+ H3Event = class {
289
+ app;
290
+ req;
291
+ url;
292
+ context;
293
+ static __is_event__ = true;
294
+ constructor(req, context, app) {
295
+ this.context = context || req.context || new NullProtoObj();
296
+ this.req = req;
297
+ this.app = app;
298
+ const _url = req._url;
299
+ this.url = _url && _url instanceof URL ? _url : new FastURL(req.url);
300
+ }
301
+ get res() {
302
+ return this[kEventRes] ||= new H3EventResponse();
303
+ }
304
+ get runtime() {
305
+ return this.req.runtime;
306
+ }
307
+ waitUntil(promise) {
308
+ this.req.waitUntil?.(promise);
309
+ }
310
+ toString() {
311
+ return `[${this.req.method}] ${this.req.url}`;
312
+ }
313
+ toJSON() {
314
+ return this.toString();
315
+ }
316
+ get node() {
317
+ return this.req.runtime?.node;
318
+ }
319
+ get headers() {
320
+ return this.req.headers;
321
+ }
322
+ get path() {
323
+ return this.url.pathname + this.url.search;
324
+ }
325
+ get method() {
326
+ return this.req.method;
327
+ }
328
+ };
329
+ H3EventResponse = class {
330
+ status;
331
+ statusText;
332
+ get headers() {
333
+ return this[kEventResHeaders] ||= new Headers();
334
+ }
335
+ };
336
+ DISALLOWED_STATUS_CHARS = /[^\u0009\u0020-\u007E]/g;
337
+ HTTPError = class HTTPError extends Error {
338
+ get name() {
339
+ return "HTTPError";
340
+ }
341
+ status;
342
+ statusText;
343
+ headers;
344
+ cause;
345
+ data;
346
+ body;
347
+ unhandled;
348
+ static isError(input) {
349
+ return input instanceof Error && input?.name === "HTTPError";
350
+ }
351
+ static status(status, statusText, details) {
352
+ return new HTTPError({
353
+ ...details,
354
+ statusText,
355
+ status
356
+ });
357
+ }
358
+ constructor(arg1, arg2) {
359
+ let messageInput;
360
+ let details;
361
+ if (typeof arg1 === "string") {
362
+ messageInput = arg1;
363
+ details = arg2;
364
+ } else details = arg1;
365
+ const status = sanitizeStatusCode(details?.status || (details?.cause)?.status || details?.status || details?.statusCode, 500);
366
+ const statusText = sanitizeStatusMessage(details?.statusText || (details?.cause)?.statusText || details?.statusText || details?.statusMessage);
367
+ const message = messageInput || details?.message || (details?.cause)?.message || details?.statusText || details?.statusMessage || [
368
+ "HTTPError",
369
+ status,
370
+ statusText
371
+ ].filter(Boolean).join(" ");
372
+ super(message, { cause: details });
373
+ this.cause = details;
374
+ this.status = status;
375
+ this.statusText = statusText || void 0;
376
+ const rawHeaders = details?.headers || (details?.cause)?.headers;
377
+ this.headers = rawHeaders ? new Headers(rawHeaders) : void 0;
378
+ this.unhandled = details?.unhandled ?? (details?.cause)?.unhandled ?? void 0;
379
+ this.data = details?.data;
380
+ this.body = details?.body;
381
+ }
382
+ get statusCode() {
383
+ return this.status;
384
+ }
385
+ get statusMessage() {
386
+ return this.statusText;
387
+ }
388
+ toJSON() {
389
+ const unhandled = this.unhandled;
390
+ return {
391
+ status: this.status,
392
+ statusText: this.statusText,
393
+ unhandled,
394
+ message: unhandled ? "HTTPError" : this.message,
395
+ data: unhandled ? void 0 : this.data,
396
+ ...unhandled ? void 0 : this.body
397
+ };
398
+ }
399
+ };
400
+ kNotFound = /* @__PURE__ */ Symbol.for("h3.notFound");
401
+ kHandled = /* @__PURE__ */ Symbol.for("h3.handled");
402
+ HTTPResponse = class {
403
+ #headers;
404
+ #init;
405
+ body;
406
+ constructor(body, init) {
407
+ this.body = body;
408
+ this.#init = init;
409
+ }
410
+ get status() {
411
+ return this.#init?.status || 200;
412
+ }
413
+ get statusText() {
414
+ return this.#init?.statusText || "OK";
415
+ }
416
+ get headers() {
417
+ return this.#headers ||= new Headers(this.#init?.headers);
418
+ }
419
+ };
420
+ frozen = (name) => (...args) => {
421
+ throw new Error(`Headers are frozen (${name} ${args.join(", ")})`);
422
+ };
423
+ FrozenHeaders = class extends Headers {
424
+ set = frozen("set");
425
+ append = frozen("append");
426
+ delete = frozen("delete");
427
+ };
428
+ emptyHeaders = /* @__PURE__ */ new FrozenHeaders({ "content-length": "0" });
429
+ jsonHeaders = /* @__PURE__ */ new FrozenHeaders({ "content-type": "application/json;charset=UTF-8" });
430
+ plusRegex = /\+/g;
431
+ NoHandler = () => kNotFound;
432
+ H3Core = class {
433
+ config;
434
+ "~middleware";
435
+ "~routes" = [];
436
+ constructor(config = {}) {
437
+ this["~middleware"] = [];
438
+ this.config = config;
439
+ this.fetch = this.fetch.bind(this);
440
+ this.handler = this.handler.bind(this);
441
+ }
442
+ fetch(request) {
443
+ return this["~request"](request);
444
+ }
445
+ handler(event) {
446
+ const route = this["~findRoute"](event);
447
+ if (route) {
448
+ event.context.params = route.params;
449
+ event.context.matchedRoute = route.data;
450
+ }
451
+ const routeHandler = route?.data.handler || NoHandler;
452
+ const middleware = this["~getMiddleware"](event, route);
453
+ return middleware.length > 0 ? callMiddleware(event, middleware, routeHandler) : routeHandler(event);
454
+ }
455
+ "~request"(request, context) {
456
+ const event = new H3Event(request, context, this);
457
+ let handlerRes;
458
+ try {
459
+ if (this.config.onRequest) {
460
+ const hookRes = this.config.onRequest(event);
461
+ handlerRes = typeof hookRes?.then === "function" ? hookRes.then(() => this.handler(event)) : this.handler(event);
462
+ } else handlerRes = this.handler(event);
463
+ } catch (error) {
464
+ handlerRes = Promise.reject(error);
465
+ }
466
+ return toResponse(handlerRes, event, this.config);
467
+ }
468
+ "~findRoute"(_event) {}
469
+ "~addRoute"(_route) {
470
+ this["~routes"].push(_route);
471
+ }
472
+ "~getMiddleware"(_event, route) {
473
+ const routeMiddleware = route?.data.middleware;
474
+ const globalMiddleware = this["~middleware"];
475
+ return routeMiddleware ? [...globalMiddleware, ...routeMiddleware] : globalMiddleware;
476
+ }
477
+ };
478
+ new TextEncoder();
479
+ }));
480
+ var init_node = __esmMin((() => {
481
+ init_h3_ByfIX5Jk();
482
+ }));
483
+ init_generic();
484
+ var errorHandler = (error, event) => {
485
+ const res = defaultHandler(error, event);
486
+ return new FastResponse(typeof res.body === "string" ? res.body : JSON.stringify(res.body, null, 2), res);
487
+ };
488
+ function defaultHandler(error, event, opts) {
489
+ const isSensitive = error.unhandled;
490
+ const status = error.status || 500;
491
+ const url = event.url || new URL(event.req.url);
492
+ if (status === 404) {
493
+ const baseURL = "/";
494
+ if (/^\/[^/]/.test(baseURL) && !url.pathname.startsWith(baseURL)) return {
495
+ status: 302,
496
+ statusText: "Found",
497
+ headers: { location: `${baseURL}${url.pathname.slice(1)}${url.search}` },
498
+ body: `Redirecting...`
499
+ };
500
+ }
501
+ if (isSensitive && !opts?.silent) {
502
+ const tags = [error.unhandled && "[unhandled]"].filter(Boolean).join(" ");
503
+ console.error(`[request error] ${tags} [${event.req.method}] ${url}\n`, error);
504
+ }
505
+ const headers = {
506
+ "content-type": "application/json",
507
+ "x-content-type-options": "nosniff",
508
+ "x-frame-options": "DENY",
509
+ "referrer-policy": "no-referrer",
510
+ "content-security-policy": "script-src 'none'; frame-ancestors 'none';"
511
+ };
512
+ if (status === 404 || !event.res.headers.has("cache-control")) headers["cache-control"] = "no-cache";
513
+ const body = {
514
+ error: true,
515
+ url: url.href,
516
+ status,
517
+ statusText: error.statusText,
518
+ message: isSensitive ? "Server Error" : error.message,
519
+ data: isSensitive ? void 0 : error.data
520
+ };
521
+ return {
522
+ status,
523
+ statusText: error.statusText,
524
+ headers,
525
+ body
526
+ };
527
+ }
528
+ var errorHandlers = [errorHandler];
529
+ async function error_handler_default(error, event) {
530
+ for (const handler of errorHandlers) try {
531
+ const response = await handler(error, event, { defaultHandler });
532
+ if (response) return response;
533
+ } catch (error) {
534
+ console.error(error);
535
+ }
536
+ }
537
+ String.fromCharCode;
538
+ var ENC_SLASH_RE = /%2f/gi;
539
+ function decode(text = "") {
540
+ try {
541
+ return decodeURIComponent("" + text);
542
+ } catch {
543
+ return "" + text;
544
+ }
545
+ }
546
+ function decodePath(text) {
547
+ return decode(text.replace(ENC_SLASH_RE, "%252F"));
548
+ }
549
+ var TRAILING_SLASH_RE = /\/$|\/\?|\/#/;
550
+ var JOIN_LEADING_SLASH_RE = /^\.?\//;
551
+ function hasTrailingSlash(input = "", respectQueryAndFragment) {
552
+ if (!respectQueryAndFragment) return input.endsWith("/");
553
+ return TRAILING_SLASH_RE.test(input);
554
+ }
555
+ function withoutTrailingSlash(input = "", respectQueryAndFragment) {
556
+ if (!respectQueryAndFragment) return (hasTrailingSlash(input) ? input.slice(0, -1) : input) || "/";
557
+ if (!hasTrailingSlash(input, true)) return input || "/";
558
+ let path = input;
559
+ let fragment = "";
560
+ const fragmentIndex = input.indexOf("#");
561
+ if (fragmentIndex !== -1) {
562
+ path = input.slice(0, fragmentIndex);
563
+ fragment = input.slice(fragmentIndex);
564
+ }
565
+ const [s0, ...s] = path.split("?");
566
+ return ((s0.endsWith("/") ? s0.slice(0, -1) : s0) || "/") + (s.length > 0 ? `?${s.join("?")}` : "") + fragment;
567
+ }
568
+ function withTrailingSlash(input = "", respectQueryAndFragment) {
569
+ if (!respectQueryAndFragment) return input.endsWith("/") ? input : input + "/";
570
+ if (hasTrailingSlash(input, true)) return input || "/";
571
+ let path = input;
572
+ let fragment = "";
573
+ const fragmentIndex = input.indexOf("#");
574
+ if (fragmentIndex !== -1) {
575
+ path = input.slice(0, fragmentIndex);
576
+ fragment = input.slice(fragmentIndex);
577
+ if (!path) return fragment;
578
+ }
579
+ const [s0, ...s] = path.split("?");
580
+ return s0 + "/" + (s.length > 0 ? `?${s.join("?")}` : "") + fragment;
581
+ }
582
+ function hasLeadingSlash(input = "") {
583
+ return input.startsWith("/");
584
+ }
585
+ function withLeadingSlash(input = "") {
586
+ return hasLeadingSlash(input) ? input : "/" + input;
587
+ }
588
+ function isNonEmptyURL(url) {
589
+ return url && url !== "/";
590
+ }
591
+ function joinURL(base, ...input) {
592
+ let url = base || "";
593
+ for (const segment of input.filter((url2) => isNonEmptyURL(url2))) if (url) {
594
+ const _segment = segment.replace(JOIN_LEADING_SLASH_RE, "");
595
+ url = withTrailingSlash(url) + _segment;
596
+ } else url = segment;
597
+ return url;
598
+ }
599
+ var headers = ((m) => function headersRouteRule(event) {
600
+ for (const [key, value] of Object.entries(m.options || {})) event.res.headers.set(key, value);
601
+ });
602
+ var public_assets_data_default = {
603
+ "/assets/index-BC9qhYL0.js": {
604
+ "type": "text/javascript; charset=utf-8",
605
+ "etag": "\"2c32-P9M3yJbjRmzrrPeoaEqQI2KbS4E\"",
606
+ "mtime": "2026-03-09T15:30:42.528Z",
607
+ "size": 11314,
608
+ "path": "../public/assets/index-BC9qhYL0.js",
609
+ "data": "KGZ1bmN0aW9uKCl7bGV0IGU9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChgbGlua2ApLnJlbExpc3Q7aWYoZSYmZS5zdXBwb3J0cyYmZS5zdXBwb3J0cyhgbW9kdWxlcHJlbG9hZGApKXJldHVybjtmb3IobGV0IGUgb2YgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChgbGlua1tyZWw9Im1vZHVsZXByZWxvYWQiXWApKW4oZSk7bmV3IE11dGF0aW9uT2JzZXJ2ZXIoZT0+e2ZvcihsZXQgdCBvZiBlKWlmKHQudHlwZT09PWBjaGlsZExpc3RgKWZvcihsZXQgZSBvZiB0LmFkZGVkTm9kZXMpZS50YWdOYW1lPT09YExJTktgJiZlLnJlbD09PWBtb2R1bGVwcmVsb2FkYCYmbihlKX0pLm9ic2VydmUoZG9jdW1lbnQse2NoaWxkTGlzdDohMCxzdWJ0cmVlOiEwfSk7ZnVuY3Rpb24gdChlKXtsZXQgdD17fTtyZXR1cm4gZS5pbnRlZ3JpdHkmJih0LmludGVncml0eT1lLmludGVncml0eSksZS5yZWZlcnJlclBvbGljeSYmKHQucmVmZXJyZXJQb2xpY3k9ZS5yZWZlcnJlclBvbGljeSksZS5jcm9zc09yaWdpbj09PWB1c2UtY3JlZGVudGlhbHNgP3QuY3JlZGVudGlhbHM9YGluY2x1ZGVgOmUuY3Jvc3NPcmlnaW49PT1gYW5vbnltb3VzYD90LmNyZWRlbnRpYWxzPWBvbWl0YDp0LmNyZWRlbnRpYWxzPWBzYW1lLW9yaWdpbmAsdH1mdW5jdGlvbiBuKGUpe2lmKGUuZXApcmV0dXJuO2UuZXA9ITA7bGV0IG49dChlKTtmZXRjaChlLmhyZWYsbil9fSkoKTt2YXIgZT1kb2N1bWVudC5nZXRFbGVtZW50QnlJZChgaWNvbi1zdW5gKSx0PWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGBpY29uLW1vb25gKTtmdW5jdGlvbiBuKCl7bGV0IG49bG9jYWxTdG9yYWdlLmdldEl0ZW0oYHRoZW1lYCkscj1uPT09YGRhcmtgfHwhbiYmd2luZG93Lm1hdGNoTWVkaWEoYChwcmVmZXJzLWNvbG9yLXNjaGVtZTogZGFyaylgKS5tYXRjaGVzO2RvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGFzc0xpc3QudG9nZ2xlKGBkYXJrYCxyKSxlLmNsYXNzTGlzdC50b2dnbGUoYGhpZGRlbmAsIXIpLHQuY2xhc3NMaXN0LnRvZ2dsZShgaGlkZGVuYCxyKX1mdW5jdGlvbiByKCl7bigpLHdpbmRvdy5tYXRjaE1lZGlhKGAocHJlZmVycy1jb2xvci1zY2hlbWU6IGRhcmspYCkuYWRkRXZlbnRMaXN0ZW5lcihgY2hhbmdlYCwoKT0+e2xvY2FsU3RvcmFnZS5nZXRJdGVtKGB0aGVtZWApfHxuKCl9KSxkb2N1bWVudC5nZXRFbGVtZW50QnlJZChgdGhlbWUtdG9nZ2xlYCkuYWRkRXZlbnRMaXN0ZW5lcihgY2xpY2tgLCgpPT57bGV0IGU9ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyhgZGFya2ApO2xvY2FsU3RvcmFnZS5zZXRJdGVtKGB0aGVtZWAsZT9gbGlnaHRgOmBkYXJrYCksbigpfSl9ZnVuY3Rpb24gaShlLHQpe3JldHVybiBlLnBhdGg9PT10PyEwOmUuY2hpbGRyZW4/LnNvbWUoZT0+aShlLHQpKT8/ITF9ZnVuY3Rpb24gYShlLHQpe3JldHVybiBlLm1hcChlPT57bGV0IG49ZS5jaGlsZHJlbiYmZS5jaGlsZHJlbi5sZW5ndGg+MCxyPW4/YShlLmNoaWxkcmVuLHQrMSk6YGAsaT0xMit0KjEyO3JldHVybmAKICAgICAgICA8bGk+CiAgICAgICAgICAke2UucGFnZSE9PSExJiYhKG4mJmUuY2hpbGRyZW4/LlswXT8ucGF0aD09PWUucGF0aCk/YDxhIGhyZWY9IiR7ZS5wYXRofSIKICAgICAgICAgICAgY2xhc3M9Im5hdi1saW5rIGJsb2NrIHB5LTEuNSB0ZXh0LXNtICR7bj9gZm9udC1tZWRpdW0gdGV4dC1ncmF5LTkwMCBkYXJrOnRleHQtZ3JheS0xMDBgOmB0ZXh0LWdyYXktNjAwIGRhcms6dGV4dC1ncmF5LTQwMGB9IGhvdmVyOmJnLWdyYXktMTAwIGhvdmVyOnRleHQtZ3JheS05MDAgZGFyazpob3ZlcjpiZy1ncmF5LTgwMCBkYXJrOmhvdmVyOnRleHQtZ3JheS0xMDAgcm91bmRlZC1tZCB0cmFuc2l0aW9uLWNvbG9ycyIKICAgICAgICAgICAgc3R5bGU9InBhZGRpbmctbGVmdDogJHtpfXB4OyBwYWRkaW5nLXJpZ2h0OiAxMnB4IgogICAgICAgICAgICBkYXRhLXBhdGg9IiR7ZS5wYXRofSI+CiAgICAgICAgICAgICR7ZS50aXRsZX0KICAgICAgICAgIDwvYT5gOmA8c3BhbgogICAgICAgICAgICBjbGFzcz0iYmxvY2sgcHktMS41IHRleHQtc20gZm9udC1tZWRpdW0gdGV4dC1ncmF5LTkwMCBkYXJrOnRleHQtZ3JheS0xMDAgY3Vyc29yLWRlZmF1bHQiCiAgICAgICAgICAgIHN0eWxlPSJwYWRkaW5nLWxlZnQ6ICR7aX1weDsgcGFkZGluZy1yaWdodDogMTJweCI+CiAgICAgICAgICAgICR7ZS50aXRsZX0KICAgICAgICAgIDwvc3Bhbj5gfQogICAgICAgICAgJHtyP2A8dWwgY2xhc3M9Im10LTAuNSI+JHtyfTwvdWw+YDpgYH0KICAgICAgICA8L2xpPmB9KS5qb2luKGBgKX1mdW5jdGlvbiBvKGUsdCl7bGV0IG49ZS5zb21lKGU9PmkoZSx0KSkscj0hMDtyZXR1cm4gZS5tYXAoZT0+e2lmKCEoZS5jaGlsZHJlbiYmZS5jaGlsZHJlbi5sZW5ndGg+MCkpcmV0dXJuYDxsaT4ke2UucGFnZT09PSExP2A8c3BhbiBjbGFzcz0iYmxvY2sgcHktMS41IHB4LTMgdGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWdyYXktOTAwIGRhcms6dGV4dC1ncmF5LTEwMCBjdXJzb3ItZGVmYXVsdCI+CiAgICAgICAgICAgICAgICAke2UudGl0bGV9CiAgICAgICAgICAgICAgPC9zcGFuPmA6YDxhIGhyZWY9IiR7ZS5wYXRofSIKICAgICAgICAgICAgICAgIGNsYXNzPSJuYXYtbGluayBibG9jayBweS0xLjUgcHgtMyB0ZXh0LXNtIGZvbnQtbWVkaXVtIHRleHQtZ3JheS05MDAgZGFyazp0ZXh0LWdyYXktMTAwIGhvdmVyOmJnLWdyYXktMTAwIGRhcms6aG92ZXI6YmctZ3JheS04MDAgcm91bmRlZC1tZCB0cmFuc2l0aW9uLWNvbG9ycyIKICAgICAgICAgICAgICAgIGRhdGEtcGF0aD0iJHtlLnBhdGh9Ij4KICAgICAgICAgICAgICAgICR7ZS50aXRsZX0KICAgICAgICAgICAgICA8L2E+YH08L2xpPmA7bGV0IG89aShlLHQpfHwhbiYmcjtyPSExO2xldCBzPWUucGFnZSE9PSExJiZlLmNoaWxkcmVuPy5bMF0/LnBhdGghPT1lLnBhdGgsYz1gPHN2ZyBjbGFzcz0ibmF2LWNoZXZyb24gdy00IGgtNCB0ZXh0LWdyYXktNDAwIHRyYW5zaXRpb24tdHJhbnNmb3JtICR7bz9gcm90YXRlLTkwYDpgYH0iIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0iY3VycmVudENvbG9yIj48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik03LjIxIDE0Ljc3YS43NS43NSAwIDAxLjAyLTEuMDZMMTEuMTY4IDEwIDcuMjMgNi4yOWEuNzUuNzUgMCAxMTEuMDQtMS4wOGw0LjUgNC4yNWEuNzUuNzUgMCAwMTAgMS4wOGwtNC41IDQuMjVhLjc1Ljc1IDAgMDEtMS4wNi0uMDJ6IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz5gLGw9cz9gPGEgaHJlZj0iJHtlLnBhdGh9IgogICAgICAgICAgICBjbGFzcz0ibmF2LWxpbmsgZmxleC0xIHB5LTEuNSB0ZXh0LXNtIGZvbnQtbWVkaXVtIHRleHQtZ3JheS05MDAgZGFyazp0ZXh0LWdyYXktMTAwIGhvdmVyOnRleHQtZ3JheS02MDAgZGFyazpob3Zlcjp0ZXh0LWdyYXktMzAwIHRyYW5zaXRpb24tY29sb3JzIgogICAgICAgICAgICBkYXRhLXBhdGg9IiR7ZS5wYXRofSI+CiAgICAgICAgICAgICR7ZS50aXRsZX0KICAgICAgICAgIDwvYT5gOmA8c3BhbiBjbGFzcz0iZmxleC0xIHB5LTEuNSB0ZXh0LXNtIGZvbnQtbWVkaXVtIHRleHQtZ3JheS05MDAgZGFyazp0ZXh0LWdyYXktMTAwIj4KICAgICAgICAgICAgJHtlLnRpdGxlfQogICAgICAgICAgPC9zcGFuPmAsdT1hKGUuY2hpbGRyZW4sMSk7cmV0dXJuYAogICAgICAgIDxsaSBkYXRhLXNlY3Rpb249IiR7ZS5wYXRofSI+CiAgICAgICAgICA8ZGl2IGNsYXNzPSJmbGV4IGl0ZW1zLWNlbnRlciBweC0zIHJvdW5kZWQtbWQgaG92ZXI6YmctZ3JheS0xMDAgZGFyazpob3ZlcjpiZy1ncmF5LTgwMCB0cmFuc2l0aW9uLWNvbG9ycyBjdXJzb3ItcG9pbnRlciI+CiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9Im5hdi10b2dnbGUgcC0wLjUgLW1sLTEgbXItMSIgZGF0YS1zZWN0aW9uPSIke2UucGF0aH0iIGFyaWEtbGFiZWw9IlRvZ2dsZSBzZWN0aW9uIj4KICAgICAgICAgICAgICAke2N9CiAgICAgICAgICAgIDwvYnV0dG9uPgogICAgICAgICAgICAke2x9CiAgICAgICAgICA8L2Rpdj4KICAgICAgICAgIDx1bCBjbGFzcz0ibmF2LXNlY3Rpb24gbXQtMC41ICR7bz9gYDpgaGlkZGVuYH0iIGRhdGEtc2VjdGlvbj0iJHtlLnBhdGh9Ij4KICAgICAgICAgICAgJHt1fQogICAgICAgICAgPC91bD4KICAgICAgICA8L2xpPmB9KS5qb2luKGBgKX1mdW5jdGlvbiBzKGUpe2ZvcihsZXQgdCBvZiBlKXtpZih0LnBhZ2UhPT0hMSlyZXR1cm4gdC5wYXRoO2lmKHQuY2hpbGRyZW4pe2xldCBlPXModC5jaGlsZHJlbik7aWYoZSlyZXR1cm4gZX19fXZhciBjPVtdO2Z1bmN0aW9uIGwoZSx0KXtjPXQ7bGV0IG49bG9jYXRpb24ucGF0aG5hbWU7ZS5pbm5lckhUTUw9dC5sZW5ndGg/YDx1bCBjbGFzcz0ic3BhY2UteS0wLjUiPiR7byh0LG4pfTwvdWw+YDpgPHAgY2xhc3M9InB4LTMgcHktMiB0ZXh0LXNtIHRleHQtZ3JheS00MDAiPk5vIHBhZ2VzIGxvYWRlZDwvcD5gLGUuYWRkRXZlbnRMaXN0ZW5lcihgY2xpY2tgLHQ9PntsZXQgbj10LnRhcmdldCxyPW4uY2xvc2VzdChgLm5hdi10b2dnbGVgKTtpZihyKXt1KGUsci5kYXRhc2V0LnNlY3Rpb24pO3JldHVybn1sZXQgaT1uLmNsb3Nlc3QoYGxpW2RhdGEtc2VjdGlvbl1gKTtpJiYhbi5jbG9zZXN0KGAubmF2LWxpbmtgKSYmdShlLGkuZGF0YXNldC5zZWN0aW9uKX0pfWZ1bmN0aW9uIHUoZSx0KXtsZXQgbj1lLnF1ZXJ5U2VsZWN0b3IoYHVsLm5hdi1zZWN0aW9uW2RhdGEtc2VjdGlvbj0iJHt0fSJdYCk7biYmKG4uY2xhc3NMaXN0LmNvbnRhaW5zKGBoaWRkZW5gKT8oZS5xdWVyeVNlbGVjdG9yQWxsKGB1bC5uYXYtc2VjdGlvbmApLmZvckVhY2goZT0+e2UuY2xhc3NMaXN0LmFkZChgaGlkZGVuYCl9KSxlLnF1ZXJ5U2VsZWN0b3JBbGwoYC5uYXYtY2hldnJvbmApLmZvckVhY2goZT0+e2UuY2xhc3NMaXN0LnJlbW92ZShgcm90YXRlLTkwYCl9KSxuLmNsYXNzTGlzdC5yZW1vdmUoYGhpZGRlbmApLGUucXVlcnlTZWxlY3RvcihgLm5hdi10b2dnbGVbZGF0YS1zZWN0aW9uPSIke3R9Il0gLm5hdi1jaGV2cm9uYCk/LmNsYXNzTGlzdC5hZGQoYHJvdGF0ZS05MGApKToobi5jbGFzc0xpc3QuYWRkKGBoaWRkZW5gKSxlLnF1ZXJ5U2VsZWN0b3IoYC5uYXYtdG9nZ2xlW2RhdGEtc2VjdGlvbj0iJHt0fSJdIC5uYXYtY2hldnJvbmApPy5jbGFzc0xpc3QucmVtb3ZlKGByb3RhdGUtOTBgKSkpfWZ1bmN0aW9uIGQoZSx0KXtlLnF1ZXJ5U2VsZWN0b3JBbGwoYC5uYXYtbGlua2ApLmZvckVhY2goZT0+e2xldCBuPWUuZ2V0QXR0cmlidXRlKGBkYXRhLXBhdGhgKT09PXQ7ZS5jbGFzc0xpc3QudG9nZ2xlKGBuYXYtYWN0aXZlYCxuKSxlLmNsYXNzTGlzdC50b2dnbGUoYGZvbnQtbWVkaXVtYCxuKX0pO2xldCBuPWMuZmluZChlPT5pKGUsdCkpO24/LmNoaWxkcmVuPy5sZW5ndGgmJihlLnF1ZXJ5U2VsZWN0b3JBbGwoYHVsLm5hdi1zZWN0aW9uYCkuZm9yRWFjaChlPT57ZS5jbGFzc0xpc3QuYWRkKGBoaWRkZW5gKX0pLGUucXVlcnlTZWxlY3RvckFsbChgLm5hdi1jaGV2cm9uYCkuZm9yRWFjaChlPT57ZS5jbGFzc0xpc3QucmVtb3ZlKGByb3RhdGUtOTBgKX0pLGUucXVlcnlTZWxlY3RvcihgdWwubmF2LXNlY3Rpb25bZGF0YS1zZWN0aW9uPSIke24ucGF0aH0iXWApPy5jbGFzc0xpc3QucmVtb3ZlKGBoaWRkZW5gKSxlLnF1ZXJ5U2VsZWN0b3IoYC5uYXYtdG9nZ2xlW2RhdGEtc2VjdGlvbj0iJHtuLnBhdGh9Il0gLm5hdi1jaGV2cm9uYCk/LmNsYXNzTGlzdC5hZGQoYHJvdGF0ZS05MGApKX1mdW5jdGlvbiBmKGUsdCl7ZS5pbm5lckhUTUw9YDxhcnRpY2xlIGNsYXNzPSJwcm9zZSBwcm9zZS1ncmF5IG1heC13LW5vbmUiPiR7dH08L2FydGljbGU+YDtmb3IobGV0IHQgb2YgZS5xdWVyeVNlbGVjdG9yQWxsKGBhW2hyZWZdYCkpe2xldCBuPXQuZ2V0QXR0cmlidXRlKGBocmVmYCk7bi5zdGFydHNXaXRoKGAvYCk/dC5hZGRFdmVudExpc3RlbmVyKGBjbGlja2AsZT0+e2UucHJldmVudERlZmF1bHQoKSxoaXN0b3J5LnB1c2hTdGF0ZShudWxsLGBgLG4pLHdpbmRvdy5kaXNwYXRjaEV2ZW50KG5ldyBQb3BTdGF0ZUV2ZW50KGBwb3BzdGF0ZWApKX0pOm4uc3RhcnRzV2l0aChgI2ApP3QuYWRkRXZlbnRMaXN0ZW5lcihgY2xpY2tgLHQ9Pnt0LnByZXZlbnREZWZhdWx0KCk7bGV0IHI9bi5zbGljZSgxKSxpPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHIpfHxlLnF1ZXJ5U2VsZWN0b3IoYFtpZD0iJHtDU1MuZXNjYXBlKHIpfSJdYCk7aSYmKGkuc2Nyb2xsSW50b1ZpZXcoe2JlaGF2aW9yOmBzbW9vdGhgfSksaGlzdG9yeS5yZXBsYWNlU3RhdGUobnVsbCxgYCxuKSl9KTovXmh0dHBzPzpcL1wvLy50ZXN0KG4pJiYodC50YXJnZXQ9YF9ibGFua2AsdC5yZWw9YG5vb3BlbmVyIG5vcmVmZXJyZXJgKX19YXN5bmMgZnVuY3Rpb24gcChlLHQpe2YoZSxgPHAgY2xhc3M9InRleHQtZ3JheS00MDAiPkxvYWRpbmcuLi48L3A+YCk7bGV0IG49YXdhaXQoYXdhaXQgZmV0Y2goYC9hcGkvcGFnZT9wYXRoPSR7ZW5jb2RlVVJJQ29tcG9uZW50KHQpfWApKS5qc29uKCk7aWYobi5lcnJvcilmKGUsYDxwIGNsYXNzPSJ0ZXh0LXJlZC01MDAiPiR7bi5lcnJvcn08L3A+YCk7ZWxzZXtmKGUsbi5odG1sKTtsZXQgdD1sb2NhdGlvbi5oYXNoLnNsaWNlKDEpO2lmKHQpe2xldCBuPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHQpfHxlLnF1ZXJ5U2VsZWN0b3IoYFtpZD0iJHtDU1MuZXNjYXBlKHQpfSJdYCk7biYmbi5zY3JvbGxJbnRvVmlldyh7YmVoYXZpb3I6YHNtb290aGB9KX19fXZhciBtPVtdO2Z1bmN0aW9uIGgoZSl7bT1lfWZ1bmN0aW9uIGcoKXtsZXQgZT1kb2N1bWVudC5nZXRFbGVtZW50QnlJZChgc2VhcmNoLXRyaWdnZXJgKSx0PWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGBzZWFyY2gtbW9kYWxgKSxuPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGBzZWFyY2gtYmFja2Ryb3BgKSxyPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGBzZWFyY2gtaW5wdXRgKSxpPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGBzZWFyY2gtcmVzdWx0c2ApLGEsbz0tMSxzPVtdO2UuYWRkRXZlbnRMaXN0ZW5lcihgY2xpY2tgLGMpLGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoYGtleWRvd25gLGU9PnsoZS5tZXRhS2V5fHxlLmN0cmxLZXkpJiZlLmtleT09PWBrYCYmKGUucHJldmVudERlZmF1bHQoKSxjKCkpfSksbi5hZGRFdmVudExpc3RlbmVyKGBjbGlja2AsbCksci5hZGRFdmVudExpc3RlbmVyKGBpbnB1dGAsKCk9PntjbGVhclRpbWVvdXQoYSk7bGV0IGU9ci52YWx1ZS50cmltKCk7aWYoZS5sZW5ndGg8Mil7bz0tMSxzPVtdLHAoKTtyZXR1cm59YT1zZXRUaW1lb3V0KCgpPT51KGUpLDIwMCl9KSxyLmFkZEV2ZW50TGlzdGVuZXIoYGtleWRvd25gLGU9PntlLmtleT09PWBBcnJvd0Rvd25gPyhlLnByZXZlbnREZWZhdWx0KCksZihvKzEpKTplLmtleT09PWBBcnJvd1VwYD8oZS5wcmV2ZW50RGVmYXVsdCgpLGYoby0xKSk6ZS5rZXk9PT1gRW50ZXJgJiZvPj0wPyhlLnByZXZlbnREZWZhdWx0KCksaChzW29dLnBhdGgpKTplLmtleT09PWBFc2NhcGVgJiZsKCl9KTtmdW5jdGlvbiBjKCl7dC5jbGFzc0xpc3QucmVtb3ZlKGBoaWRkZW5gKSxyLnZhbHVlPWBgLG89LTEscz1bXSxwKCkscmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpPT5yLmZvY3VzKCkpfWZ1bmN0aW9uIGwoKXt0LmNsYXNzTGlzdC5hZGQoYGhpZGRlbmApLHIudmFsdWU9YGAscz1bXSxvPS0xfWFzeW5jIGZ1bmN0aW9uIHUoZSl7cz0oYXdhaXQoYXdhaXQgZmV0Y2goYC9hcGkvc2VhcmNoP3E9JHtlbmNvZGVVUklDb21wb25lbnQoZSl9YCkpLmpzb24oKSkucmVzdWx0cyxvPXMubGVuZ3RoPjA/MDotMSxkKCl9ZnVuY3Rpb24gZCgpe2lmKHMubGVuZ3RoPT09MCl7aS5pbm5lckhUTUw9YDxwIGNsYXNzPSJweC00IHB5LTggdGV4dC1zbSB0ZXh0LWdyYXktNDAwIHRleHQtY2VudGVyIj5ObyByZXN1bHRzIGZvdW5kPC9wPmA7cmV0dXJufWkuaW5uZXJIVE1MPXMubWFwKChlLHQpPT5gCiAgICAgIDxhIGhyZWY9IiR7ZS5wYXRofSIgY2xhc3M9InNlYXJjaC1pdGVtIGZsZXggaXRlbXMtc3RhcnQgZ2FwLTMgcHgtNCBweS0zIGJvcmRlci1iIGJvcmRlci1ncmF5LTEwMCBkYXJrOmJvcmRlci1ncmF5LTgwMCBob3ZlcjpiZy1ncmF5LTUwIGRhcms6aG92ZXI6YmctZ3JheS04MDAgdHJhbnNpdGlvbi1jb2xvcnMgJHt0PT09bz9gYmctZ3JheS01MCBkYXJrOmJnLWdyYXktODAwYDpgYH0iIGRhdGEtaW5kZXg9IiR7dH0iPgogICAgICAgIDxzdmcgY2xhc3M9InNpemUtNCBtdC0wLjUgc2hyaW5rLTAgdGV4dC1ncmF5LTQwMCIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDI0IDI0IiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiPgogICAgICAgICAgPHBhdGggc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNMTkuNSAxNC4yNXYtMi42MjVhMy4zNzUgMy4zNzUgMCAwIDAtMy4zNzUtMy4zNzVoLTEuNUExLjEyNSAxLjEyNSAwIDAgMSAxMy41IDcuMTI1di0xLjVhMy4zNzUgMy4zNzUgMCAwIDAtMy4zNzUtMy4zNzVIOC4yNW0yLjI1IDBINS42MjVjLS42MjEgMC0xLjEyNS41MDQtMS4xMjUgMS4xMjV2MTcuMjVjMCAuNjIxLjUwNCAxLjEyNSAxLjEyNSAxLjEyNWgxMi43NWMuNjIxIDAgMS4xMjUtLjUwNCAxLjEyNS0xLjEyNVYxMS4yNWE5IDkgMCAwIDAtOS05WiIgLz4KICAgICAgICA8L3N2Zz4KICAgICAgICA8ZGl2IGNsYXNzPSJtaW4tdy0wIj4KICAgICAgICAgIDxkaXYgY2xhc3M9InRleHQtc20gZm9udC1tZWRpdW0gdGV4dC1ncmF5LTkwMCBkYXJrOnRleHQtZ3JheS0xMDAiPiR7dihlLnRpdGxlKX08L2Rpdj4KICAgICAgICAgICR7ZS5zbmlwcGV0c1swXT9gPGRpdiBjbGFzcz0idGV4dC14cyB0ZXh0LWdyYXktNTAwIGRhcms6dGV4dC1ncmF5LTQwMCBtdC0wLjUgbGluZS1jbGFtcC0yIj4ke3YoZS5zbmlwcGV0c1swXSl9PC9kaXY+YDpgYH0KICAgICAgICA8L2Rpdj4KICAgICAgPC9hPmApLmpvaW4oYGApLGkucXVlcnlTZWxlY3RvckFsbChgLnNlYXJjaC1pdGVtYCkuZm9yRWFjaChlPT57ZS5hZGRFdmVudExpc3RlbmVyKGBjbGlja2AsKCk9PmwoKSl9KX1mdW5jdGlvbiBmKGUpe3MubGVuZ3RoIT09MCYmKG89TWF0aC5tYXgoMCxNYXRoLm1pbihlLHMubGVuZ3RoLTEpKSxkKCksaS5xdWVyeVNlbGVjdG9yKGBbZGF0YS1pbmRleD0iJHtvfSJdYCk/LnNjcm9sbEludG9WaWV3KHtibG9jazpgbmVhcmVzdGB9KSl9ZnVuY3Rpb24gcCgpe2xldCBlPV8obSk7aWYoZS5sZW5ndGg9PT0wKXtpLmlubmVySFRNTD1gPHAgY2xhc3M9InB4LTQgcHktOCB0ZXh0LXNtIHRleHQtZ3JheS00MDAgdGV4dC1jZW50ZXIiPlR5cGUgdG8gc2VhcmNo4oCmPC9wPmA7cmV0dXJufXM9ZS5tYXAoZT0+KHtwYXRoOmUucGF0aCx0aXRsZTplLnRpdGxlLHNuaXBwZXRzOltdfSkpLG89LTEsaS5pbm5lckhUTUw9cy5tYXAoKGUsdCk9PmAKICAgICAgPGEgaHJlZj0iJHtlLnBhdGh9IiBjbGFzcz0ic2VhcmNoLWl0ZW0gZmxleCBpdGVtcy1zdGFydCBnYXAtMyBweC00IHB5LTMgYm9yZGVyLWIgYm9yZGVyLWdyYXktMTAwIGRhcms6Ym9yZGVyLWdyYXktODAwIGhvdmVyOmJnLWdyYXktNTAgZGFyazpob3ZlcjpiZy1ncmF5LTgwMCB0cmFuc2l0aW9uLWNvbG9ycyIgZGF0YS1pbmRleD0iJHt0fSI+CiAgICAgICAgPHN2ZyBjbGFzcz0ic2l6ZS00IG10LTAuNSBzaHJpbmstMCB0ZXh0LWdyYXktNDAwIiBmaWxsPSJub25lIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2U9ImN1cnJlbnRDb2xvciI+CiAgICAgICAgICA8cGF0aCBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGQ9Ik0xOS41IDE0LjI1di0yLjYyNWEzLjM3NSAzLjM3NSAwIDAgMC0zLjM3NS0zLjM3NWgtMS41QTEuMTI1IDEuMTI1IDAgMCAxIDEzLjUgNy4xMjV2LTEuNWEzLjM3NSAzLjM3NSAwIDAgMC0zLjM3NS0zLjM3NUg4LjI1bTIuMjUgMEg1LjYyNWMtLjYyMSAwLTEuMTI1LjUwNC0xLjEyNSAxLjEyNXYxNy4yNWMwIC42MjEuNTA0IDEuMTI1IDEuMTI1IDEuMTI1aDEyLjc1Yy42MjEgMCAxLjEyNS0uNTA0IDEuMTI1LTEuMTI1VjExLjI1YTkgOSAwIDAgMC05LTlaIiAvPgogICAgICAgIDwvc3ZnPgogICAgICAgIDxkaXYgY2xhc3M9Im1pbi13LTAiPgogICAgICAgICAgPGRpdiBjbGFzcz0idGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWdyYXktOTAwIGRhcms6dGV4dC1ncmF5LTEwMCI+JHt2KGUudGl0bGUpfTwvZGl2PgogICAgICAgIDwvZGl2PgogICAgICA8L2E+YCkuam9pbihgYCksaS5xdWVyeVNlbGVjdG9yQWxsKGAuc2VhcmNoLWl0ZW1gKS5mb3JFYWNoKGU9PntlLmFkZEV2ZW50TGlzdGVuZXIoYGNsaWNrYCx0PT57dC5wcmV2ZW50RGVmYXVsdCgpO2xldCBuPU51bWJlcihlLmRhdGFzZXQuaW5kZXgpO2goc1tuXS5wYXRoKX0pfSl9ZnVuY3Rpb24gaChlKXtsb2NhdGlvbi5oYXNoPWUsbCgpfX1mdW5jdGlvbiBfKGUpe2xldCB0PVtdO2ZvcihsZXQgbiBvZiBlKW4ucGFnZSE9PSExJiZ0LnB1c2goe3BhdGg6bi5wYXRoLHRpdGxlOm4udGl0bGV9KSxuLmNoaWxkcmVuJiZ0LnB1c2goLi4uXyhuLmNoaWxkcmVuKSk7cmV0dXJuIHR9ZnVuY3Rpb24gdihlKXtyZXR1cm4gZS5yZXBsYWNlKC8mL2csYCZhbXA7YCkucmVwbGFjZSgvPC9nLGAmbHQ7YCkucmVwbGFjZSgvPi9nLGAmZ3Q7YCkucmVwbGFjZSgvIi9nLGAmcXVvdDtgKX12YXIgeT1kb2N1bWVudC5nZXRFbGVtZW50QnlJZChgc2lkZWJhcmApLGI9ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYGNvbnRlbnRgKTtyKCksZygpO2Z1bmN0aW9uIHgoZSl7aGlzdG9yeS5wdXNoU3RhdGUobnVsbCxgYCxlKSxTKCl9YXN5bmMgZnVuY3Rpb24gUygpe2xldCBlPWxvY2F0aW9uLnBhdGhuYW1lO2lmKGU9PT1gL2Ape2YoYixgPHAgY2xhc3M9InRleHQtZ3JheS00MDAiPlNlbGVjdCBhIHBhZ2UgZnJvbSB0aGUgc2lkZWJhci48L3A+YCk7cmV0dXJufWQoeSxlKSxhd2FpdCBwKGIsZSl9YXN5bmMgZnVuY3Rpb24gQygpe2YoYixgPHAgY2xhc3M9InRleHQtZ3JheS00MDAiPkxvYWRpbmcuLi48L3A+YCk7bGV0IGU9KGF3YWl0KGF3YWl0IGZldGNoKGAvYXBpL21ldGFgKSkuanNvbigpKS50b2M7aWYobCh5LGUpLGgoZSkseS5hZGRFdmVudExpc3RlbmVyKGBjbGlja2AsZT0+e2xldCB0PWUudGFyZ2V0LmNsb3Nlc3QoYGEubmF2LWxpbmtgKTt0JiYoZS5wcmV2ZW50RGVmYXVsdCgpLHgodC5nZXRBdHRyaWJ1dGUoYGRhdGEtcGF0aGApKSl9KSx3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihgcG9wc3RhdGVgLFMpLGxvY2F0aW9uLnBhdGhuYW1lPT09YC9gKXtsZXQgdD1zKGUpO2lmKHQpe3godCk7cmV0dXJufX1TKCl9QygpOw=="
610
+ },
611
+ "/assets/logo-BLkVGWak.svg": {
612
+ "type": "image/svg+xml",
613
+ "etag": "\"557-HYXN/qI1kFu3DGsCSw4J8HIDoeU\"",
614
+ "mtime": "2026-03-09T15:30:42.529Z",
615
+ "size": 1367,
616
+ "path": "../public/assets/logo-BLkVGWak.svg",
617
+ "data": "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMDAgMjAwIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+CiAgPCEtLSBCb2R5OiByb3VuZGVkIHJlY3RhbmdsZSAoZG9jdW1lbnQgc2hhcGUpIC0tPgogIDxyZWN0IHg9IjQwIiB5PSIzMCIgd2lkdGg9IjEyMCIgaGVpZ2h0PSIxNTAiIHJ4PSIxOCIgcnk9IjE4IiBmaWxsPSIjMkIyRDQyIi8+CgogIDwhLS0gRG9jdW1lbnQgbGluZXMgKG1hcmtkb3duIGZlZWwpIC0tPgogIDxyZWN0IHg9IjYyIiB5PSI3MCIgd2lkdGg9IjUwIiBoZWlnaHQ9IjYiIHJ4PSIzIiBmaWxsPSIjOEQ5OUFFIi8+CiAgPHJlY3QgeD0iNjIiIHk9Ijg2IiB3aWR0aD0iNzYiIGhlaWdodD0iNiIgcng9IjMiIGZpbGw9IiM4RDk5QUUiLz4KICA8cmVjdCB4PSI2MiIgeT0iMTAyIiB3aWR0aD0iNjIiIGhlaWdodD0iNiIgcng9IjMiIGZpbGw9IiM4RDk5QUUiLz4KICA8cmVjdCB4PSI2MiIgeT0iMTE4IiB3aWR0aD0iNzAiIGhlaWdodD0iNiIgcng9IjMiIGZpbGw9IiM4RDk5QUUiLz4KICA8cmVjdCB4PSI2MiIgeT0iMTM0IiB3aWR0aD0iNDAiIGhlaWdodD0iNiIgcng9IjMiIGZpbGw9IiM4RDk5QUUiLz4KCiAgPCEtLSBIZWFkaW5nIGhhc2ggbWFyayAobWFya2Rvd24gIykgLS0+CiAgPHRleHQgeD0iNjIiIHk9IjYwIiBmb250LWZhbWlseT0ibW9ub3NwYWNlIiBmb250LXdlaWdodD0iYm9sZCIgZm9udC1zaXplPSIxOCIgZmlsbD0iI0VERjJGNCI+IzwvdGV4dD4KCiAgPCEtLSBFeWVzIC0tPgogIDxjaXJjbGUgY3g9Ijc4IiBjeT0iMTcyIiByPSI1IiBmaWxsPSIjRUYyMzNDIi8+CiAgPGNpcmNsZSBjeD0iMTIyIiBjeT0iMTcyIiByPSI1IiBmaWxsPSIjRUYyMzNDIi8+CgogIDwhLS0gVGVldGggKHppbGxhIGJpdGUgb24gYm90dG9tKSAtLT4KICA8cG9seWdvbiBwb2ludHM9IjY4LDE4MCA3NCwxOTIgODAsMTgwIiBmaWxsPSIjRURGMkY0Ii8+CiAgPHBvbHlnb24gcG9pbnRzPSI4OCwxODAgOTQsMTkyIDEwMCwxODAiIGZpbGw9IiNFREYyRjQiLz4KICA8cG9seWdvbiBwb2ludHM9IjEwOCwxODAgMTE0LDE5MiAxMjAsMTgwIiBmaWxsPSIjRURGMkY0Ii8+CiAgPHBvbHlnb24gcG9pbnRzPSIxMjgsMTgwIDEzNCwxOTIgMTQwLDE4MCIgZmlsbD0iI0VERjJGNCIvPgoKICA8IS0tIFNwaWtlcyBvbiB0b3AgKHppbGxhIGhvcm5zKSAtLT4KICA8cG9seWdvbiBwb2ludHM9IjcwLDMwIDc4LDEwIDg2LDMwIiBmaWxsPSIjMkIyRDQyIi8+CiAgPHBvbHlnb24gcG9pbnRzPSI5MiwzMCAxMDAsNiAxMDgsMzAiIGZpbGw9IiMyQjJENDIiLz4KICA8cG9seWdvbiBwb2ludHM9IjExNCwzMCAxMjIsMTAgMTMwLDMwIiBmaWxsPSIjMkIyRDQyIi8+Cjwvc3ZnPgo="
618
+ }
619
+ };
620
+ function readAsset(id) {
621
+ if (!public_assets_data_default[id]) return;
622
+ if (public_assets_data_default[id]._data) return public_assets_data_default[id]._data;
623
+ if (!public_assets_data_default[id].data) return public_assets_data_default[id].data;
624
+ public_assets_data_default[id]._data = Uint8Array.from(atob(public_assets_data_default[id].data), (c) => c.charCodeAt(0));
625
+ return public_assets_data_default[id]._data;
626
+ }
627
+ var publicAssetBases = {};
628
+ function isPublicAssetURL(id = "") {
629
+ if (public_assets_data_default[id]) return true;
630
+ for (const base in publicAssetBases) if (id.startsWith(base)) return true;
631
+ return false;
632
+ }
633
+ function getAsset(id) {
634
+ return public_assets_data_default[id];
635
+ }
636
+ init_node();
637
+ var METHODS = new Set(["HEAD", "GET"]);
638
+ var EncodingMap = {
639
+ gzip: ".gz",
640
+ br: ".br",
641
+ zstd: ".zst"
642
+ };
643
+ var static_default = defineHandler((event) => {
644
+ if (event.req.method && !METHODS.has(event.req.method)) return;
645
+ let id = decodePath(withLeadingSlash(withoutTrailingSlash(event.url.pathname)));
646
+ let asset;
647
+ const encodings = [...(event.req.headers.get("accept-encoding") || "").split(",").map((e) => EncodingMap[e.trim()]).filter(Boolean).sort(), ""];
648
+ if (encodings.length > 1) event.res.headers.append("Vary", "Accept-Encoding");
649
+ for (const encoding of encodings) for (const _id of [id + encoding, joinURL(id, "index.html" + encoding)]) {
650
+ const _asset = getAsset(_id);
651
+ if (_asset) {
652
+ asset = _asset;
653
+ id = _id;
654
+ break;
655
+ }
656
+ }
657
+ if (!asset) {
658
+ if (isPublicAssetURL(id)) {
659
+ event.res.headers.delete("Cache-Control");
660
+ throw new HTTPError({ status: 404 });
661
+ }
662
+ return;
663
+ }
664
+ if (event.req.headers.get("if-none-match") === asset.etag) {
665
+ event.res.status = 304;
666
+ event.res.statusText = "Not Modified";
667
+ return "";
668
+ }
669
+ const ifModifiedSinceH = event.req.headers.get("if-modified-since");
670
+ const mtimeDate = new Date(asset.mtime);
671
+ if (ifModifiedSinceH && asset.mtime && new Date(ifModifiedSinceH) >= mtimeDate) {
672
+ event.res.status = 304;
673
+ event.res.statusText = "Not Modified";
674
+ return "";
675
+ }
676
+ if (asset.type) event.res.headers.set("Content-Type", asset.type);
677
+ if (asset.etag && !event.res.headers.has("ETag")) event.res.headers.set("ETag", asset.etag);
678
+ if (asset.mtime && !event.res.headers.has("Last-Modified")) event.res.headers.set("Last-Modified", mtimeDate.toUTCString());
679
+ if (asset.encoding && !event.res.headers.has("Content-Encoding")) event.res.headers.set("Content-Encoding", asset.encoding);
680
+ if (asset.size > 0 && !event.res.headers.has("Content-Length")) event.res.headers.set("Content-Length", asset.size.toString());
681
+ return readAsset(id);
682
+ });
683
+ var init_h3 = __esmMin((() => {
684
+ init_node();
685
+ }));
686
+ function flattenTree(entries, depth, fileMap) {
687
+ const result = [];
688
+ for (const entry of entries) {
689
+ result.push({
690
+ entry,
691
+ depth,
692
+ filePath: fileMap.get(entry.path)
693
+ });
694
+ if (entry.children) result.push(...flattenTree(entry.children, depth + 1, fileMap));
695
+ }
696
+ return result;
697
+ }
698
+ /**
699
+ * Fuzzy match: checks if all characters of `query` appear in `target` in order.
700
+ * Returns a score (lower is better) or -1 if no match.
701
+ */
702
+ function fuzzyMatch(query, target) {
703
+ const q = query.toLowerCase();
704
+ const t = target.toLowerCase();
705
+ if (q.length === 0) return 0;
706
+ if (q.length > t.length) return -1;
707
+ let score = 0;
708
+ let qi = 0;
709
+ let prevMatchIdx = -1;
710
+ for (let ti = 0; ti < t.length && qi < q.length; ti++) if (t[ti] === q[qi]) {
711
+ if (prevMatchIdx === ti - 1) score -= 5;
712
+ if (ti === 0 || "/\\-_. ".includes(t[ti - 1])) score -= 10;
713
+ if (prevMatchIdx >= 0) score += ti - prevMatchIdx - 1;
714
+ prevMatchIdx = ti;
715
+ qi++;
716
+ }
717
+ if (qi < q.length) return -1;
718
+ score += t.length * .1;
719
+ return score;
720
+ }
721
+ /**
722
+ * Fuzzy filter + sort a list of items.
723
+ * Returns items that match, sorted by best score (lowest first).
724
+ */
725
+ function fuzzyFilter(items, query, getText) {
726
+ if (!query) return items;
727
+ const scored = [];
728
+ for (const item of items) {
729
+ let best = Infinity;
730
+ for (const text of getText(item)) {
731
+ const s = fuzzyMatch(query, text);
732
+ if (s >= 0 && s < best) best = s;
733
+ }
734
+ if (best < Infinity) scored.push({
735
+ item,
736
+ score: best
737
+ });
738
+ }
739
+ scored.sort((a, b) => a.score - b.score);
740
+ return scored.map((s) => s.item);
741
+ }
742
+ var DocsManager;
743
+ var init_manager = __esmMin((() => {
744
+ DocsManager = class {
745
+ source;
746
+ tree = [];
747
+ flat = [];
748
+ _fileMap = /* @__PURE__ */ new Map();
749
+ _contentCache = /* @__PURE__ */ new Map();
750
+ constructor(source) {
751
+ this.source = source;
752
+ }
753
+ async load() {
754
+ const { tree, fileMap } = await this.source.load();
755
+ this.tree = tree;
756
+ this._fileMap = fileMap;
757
+ this.flat = flattenTree(this.tree, 0, this._fileMap);
758
+ this._contentCache.clear();
759
+ }
760
+ async reload() {
761
+ return this.load();
762
+ }
763
+ /** Get raw file content for a flat entry (cached). */
764
+ async getContent(entry) {
765
+ if (!entry.filePath || entry.entry.page === false) return void 0;
766
+ const cached = this._contentCache.get(entry.filePath);
767
+ if (cached !== void 0) return cached;
768
+ const raw = await this.source.readContent(entry.filePath);
769
+ this._contentCache.set(entry.filePath, raw);
770
+ return raw;
771
+ }
772
+ /** Invalidate cached content for a specific file path. */
773
+ invalidate(filePath) {
774
+ this._contentCache.delete(filePath);
775
+ }
776
+ /** Fuzzy filter flat entries by query string. */
777
+ filter(query) {
778
+ return fuzzyFilter(this.flat, query, ({ entry }) => [entry.title, entry.path]);
779
+ }
780
+ /** Flat entries that are navigable pages (excludes directory stubs). */
781
+ get pages() {
782
+ return this.flat.filter((f) => f.entry.page !== false);
783
+ }
784
+ /** Find a flat entry by path (exact or with trailing slash). */
785
+ findByPath(path) {
786
+ return this.flat.find((f) => f.entry.page !== false && (f.entry.path === path || f.entry.path === path + "/"));
787
+ }
788
+ /**
789
+ * Resolve a page path to its content, trying:
790
+ * 1. Exact match in the navigation tree
791
+ * 2. Stripped common prefix (e.g., /docs/guide/... → /guide/...)
792
+ * 3. Direct source fetch (for HTTP sources with uncrawled paths)
793
+ */
794
+ async resolvePage(path) {
795
+ const normalized = path.startsWith("/") ? path : "/" + path;
796
+ const entry = this.findByPath(normalized);
797
+ if (entry) {
798
+ const raw = await this.getContent(entry);
799
+ if (raw) return {
800
+ entry,
801
+ raw
802
+ };
803
+ }
804
+ const prefixed = normalized.match(/^\/[^/]+(\/.+)$/);
805
+ if (prefixed) {
806
+ const stripped = this.findByPath(prefixed[1]);
807
+ if (stripped) {
808
+ const raw = await this.getContent(stripped);
809
+ if (raw) return {
810
+ entry: stripped,
811
+ raw
812
+ };
813
+ }
814
+ }
815
+ const raw = await this.source.readContent(normalized).catch(() => void 0);
816
+ if (raw) return { raw };
817
+ return {};
818
+ }
819
+ /** Return indices of matching flat entries (case-insensitive substring). */
820
+ matchIndices(query) {
821
+ if (!query) return [];
822
+ const lower = query.toLowerCase();
823
+ const matched = /* @__PURE__ */ new Set();
824
+ for (let i = 0; i < this.flat.length; i++) {
825
+ const { entry } = this.flat[i];
826
+ if (entry.title.toLowerCase().includes(lower) || entry.path.toLowerCase().includes(lower)) {
827
+ matched.add(i);
828
+ const parentDepth = this.flat[i].depth;
829
+ for (let j = i + 1; j < this.flat.length; j++) {
830
+ if (this.flat[j].depth <= parentDepth) break;
831
+ matched.add(j);
832
+ }
833
+ }
834
+ }
835
+ return [...matched].sort((a, b) => a - b);
836
+ }
837
+ };
838
+ }));
839
+ var DocsSource;
840
+ var init__base = __esmMin((() => {
841
+ DocsSource = class {};
842
+ }));
843
+ /**
844
+ * Parse a numbered filename/dirname like "1.guide" or "3.middleware.md"
845
+ * into { order, slug }. Also strips `.draft` suffix.
846
+ */
847
+ function parseNumberedName(name) {
848
+ let base = name.endsWith(".md") ? name.slice(0, -3) : name;
849
+ const draft = base.endsWith(".draft");
850
+ if (draft) base = base.slice(0, -6);
851
+ const match = base.match(/^(\d+)\.(.+)$/);
852
+ if (match) return {
853
+ order: Number(match[1]),
854
+ slug: match[2],
855
+ draft
856
+ };
857
+ return {
858
+ order: Infinity,
859
+ slug: base,
860
+ draft
861
+ };
862
+ }
863
+ /**
864
+ * Convert a slug like "getting-started" to "Getting Started".
865
+ */
866
+ function humanizeSlug(slug) {
867
+ return slug.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
868
+ }
869
+ /**
870
+ * Read and parse a .navigation.yml file as simple key: value pairs.
871
+ */
872
+ async function readNavigation(dirPath) {
873
+ try {
874
+ const { headings: _headings, ...rest } = parseMeta(`---\n${await readFile(join(dirPath, ".navigation.yml"), "utf8")}\n---\n`);
875
+ return rest;
876
+ } catch {
877
+ return {};
878
+ }
879
+ }
880
+ /**
881
+ * Extract navigation overrides from frontmatter `navigation` field.
882
+ * Returns merged meta with navigation fields taking priority.
883
+ */
884
+ function applyNavigationOverride(meta) {
885
+ const nav = meta.navigation;
886
+ if (nav === false) return {
887
+ ...meta,
888
+ navigation: false
889
+ };
890
+ if (typeof nav === "object" && nav !== null) {
891
+ const { navigation: _nav, ...rest } = meta;
892
+ return {
893
+ ...rest,
894
+ ...nav
895
+ };
896
+ }
897
+ return meta;
898
+ }
899
+ /**
900
+ * Extract extra meta fields (non-known keys) from a record.
901
+ */
902
+ function extraMeta(record) {
903
+ const extra = {};
904
+ let hasExtra = false;
905
+ for (const [key, value] of Object.entries(record)) if (!_knownKeys.has(key) && key !== "navigation") {
906
+ extra[key] = value;
907
+ hasExtra = true;
908
+ }
909
+ return hasExtra ? extra : void 0;
910
+ }
911
+ /**
912
+ * Scan a docs directory and build a navigation tree
913
+ * using md4x parseMeta for extracting markdown metadata.
914
+ */
915
+ async function scanNav(dirPath, options) {
916
+ return _scanNav(dirPath, "/", options || {});
917
+ }
918
+ async function _scanNav(dirPath, parentPath, options) {
919
+ const dirEntries = await readdir(dirPath);
920
+ const entries = [];
921
+ for (const entry of dirEntries) {
922
+ if (entry.startsWith(".") || entry.startsWith("_") || entry === "package.json" || entry === "pnpm-lock.yaml" || entry === "pnpm-workspace.yaml") continue;
923
+ const fullPath = join(dirPath, entry);
924
+ let stats;
925
+ try {
926
+ stats = await stat(fullPath);
927
+ } catch {
928
+ continue;
929
+ }
930
+ if (stats.isDirectory()) {
931
+ const { order, slug } = parseNumberedName(entry);
932
+ const nav = await readNavigation(fullPath);
933
+ if (nav.navigation === false) continue;
934
+ const children = await _scanNav(fullPath, parentPath === "/" ? `/${slug}` : `${parentPath}/${slug}`, options);
935
+ const hasIndex = children.some((c) => c.slug === "");
936
+ const navEntry = {
937
+ slug,
938
+ path: parentPath === "/" ? `/${slug}` : `${parentPath}/${slug}`,
939
+ title: nav.title || humanizeSlug(slug),
940
+ order,
941
+ ...nav.icon ? { icon: nav.icon } : {},
942
+ ...nav.description ? { description: nav.description } : {},
943
+ ...!hasIndex ? { page: false } : {},
944
+ ...children.length > 0 ? { children } : {}
945
+ };
946
+ entries.push(navEntry);
947
+ } else if (extname(entry) === ".md") {
948
+ const { order, slug, draft } = parseNumberedName(basename(entry));
949
+ if (draft && !options.drafts) continue;
950
+ const meta = applyNavigationOverride(parseMeta(await readFile(fullPath, "utf8")));
951
+ if (meta.navigation === false) continue;
952
+ const resolvedOrder = typeof meta.order === "number" ? meta.order : order;
953
+ const resolvedSlug = slug === "index" ? "" : slug;
954
+ const title = meta.title || humanizeSlug(slug) || "index";
955
+ const entryPath = resolvedSlug === "" ? parentPath === "/" ? "/" : parentPath : parentPath === "/" ? `/${resolvedSlug}` : `${parentPath}/${resolvedSlug}`;
956
+ const extra = extraMeta(meta);
957
+ const navEntry = {
958
+ slug: resolvedSlug,
959
+ path: entryPath,
960
+ title,
961
+ order: resolvedOrder,
962
+ ...meta.icon ? { icon: meta.icon } : {},
963
+ ...meta.description ? { description: meta.description } : {},
964
+ ...draft ? { draft: true } : {},
965
+ ...extra
966
+ };
967
+ entries.push(navEntry);
968
+ }
969
+ }
970
+ entries.sort((a, b) => a.order - b.order || a.slug.localeCompare(b.slug));
971
+ return entries;
972
+ }
973
+ var _knownKeys;
974
+ var init_nav = __esmMin((() => {
975
+ _knownKeys = new Set([
976
+ "slug",
977
+ "path",
978
+ "title",
979
+ "order",
980
+ "icon",
981
+ "description",
982
+ "page",
983
+ "children",
984
+ "headings"
985
+ ]);
986
+ }));
987
+ function parseSlug(name) {
988
+ const base = name.endsWith(".draft") ? name.slice(0, -6) : name;
989
+ const match = base.match(/^(\d+)\.(.+)$/);
990
+ return match ? match[2] : base;
991
+ }
992
+ async function buildFileMap(parentPath, dirPath) {
993
+ const map = /* @__PURE__ */ new Map();
994
+ const entries = await readdir(dirPath, { withFileTypes: true });
995
+ for (const entry of entries) {
996
+ if (entry.name.startsWith(".") || entry.name.startsWith("_")) continue;
997
+ const fullPath = join(dirPath, entry.name);
998
+ if (entry.isDirectory()) {
999
+ const slug = parseSlug(entry.name);
1000
+ const childMap = await buildFileMap(parentPath === "/" ? `/${slug}` : `${parentPath}/${slug}`, fullPath);
1001
+ for (const [k, v] of childMap) map.set(k, v);
1002
+ } else if (extname(entry.name) === ".md") {
1003
+ const slug = parseSlug(entry.name.replace(/\.md$/, ""));
1004
+ const resolvedSlug = slug === "index" ? "" : slug;
1005
+ const entryPath = resolvedSlug === "" ? parentPath === "/" ? "/" : parentPath : parentPath === "/" ? `/${resolvedSlug}` : `${parentPath}/${resolvedSlug}`;
1006
+ map.set(entryPath, fullPath);
1007
+ }
1008
+ }
1009
+ return map;
1010
+ }
1011
+ /**
1012
+ * Read `_navigation.json` manifest (exported by mdzilla) and apply its
1013
+ * ordering to the scanned nav tree. Only reorders; does not add/remove entries.
1014
+ */
1015
+ async function applyNavManifest(tree, dir) {
1016
+ let manifest;
1017
+ try {
1018
+ manifest = JSON.parse(await readFile(join(dir, "_navigation.json"), "utf8"));
1019
+ } catch {
1020
+ return;
1021
+ }
1022
+ reorderTree(tree, manifest);
1023
+ }
1024
+ /** Recursively reorder tree entries to match manifest ordering. */
1025
+ function reorderTree(entries, manifest) {
1026
+ const pathIndex = new Map(manifest.map((m, i) => [m.path, i]));
1027
+ entries.sort((a, b) => {
1028
+ return (pathIndex.get(a.path) ?? Infinity) - (pathIndex.get(b.path) ?? Infinity);
1029
+ });
1030
+ for (const entry of entries) if (entry.children?.length) {
1031
+ const manifestEntry = manifest.find((m) => m.path === entry.path);
1032
+ if (manifestEntry?.children) reorderTree(entry.children, manifestEntry.children);
1033
+ }
1034
+ }
1035
+ var DocsSourceFS;
1036
+ var init_fs = __esmMin((() => {
1037
+ init_nav();
1038
+ init__base();
1039
+ DocsSourceFS = class extends DocsSource {
1040
+ dir;
1041
+ constructor(dir) {
1042
+ super();
1043
+ this.dir = dir;
1044
+ }
1045
+ async load() {
1046
+ const tree = await scanNav(this.dir);
1047
+ await applyNavManifest(tree, this.dir);
1048
+ return {
1049
+ tree,
1050
+ fileMap: await buildFileMap("/", this.dir)
1051
+ };
1052
+ }
1053
+ async readContent(filePath) {
1054
+ return readFile(filePath, "utf8");
1055
+ }
1056
+ };
1057
+ }));
1058
+ var DocsSourceGit;
1059
+ var init_git = __esmMin((() => {
1060
+ init__base();
1061
+ init_fs();
1062
+ DocsSourceGit = class extends DocsSource {
1063
+ src;
1064
+ options;
1065
+ _fs;
1066
+ constructor(src, options = {}) {
1067
+ super();
1068
+ this.src = src;
1069
+ this.options = options;
1070
+ }
1071
+ async load() {
1072
+ const source = this.options.subdir ? `${this.src}/${this.options.subdir}` : this.src;
1073
+ const id = source.replace(/[/#:]/g, "_");
1074
+ const dir = join(tmpdir(), "mdzilla", "gh", id);
1075
+ const { downloadTemplate } = await import("giget");
1076
+ await downloadTemplate(source, {
1077
+ dir,
1078
+ auth: this.options.auth,
1079
+ force: true,
1080
+ install: false
1081
+ });
1082
+ let docsDir = dir;
1083
+ for (const sub of ["docs/content", "docs"]) {
1084
+ const candidate = join(dir, sub);
1085
+ if (existsSync(candidate)) {
1086
+ docsDir = candidate;
1087
+ break;
1088
+ }
1089
+ }
1090
+ this._fs = new DocsSourceFS(docsDir);
1091
+ return this._fs.load();
1092
+ }
1093
+ async readContent(filePath) {
1094
+ if (!this._fs) throw new Error("DocsSourceGit: call load() before readContent()");
1095
+ return this._fs.readContent(filePath);
1096
+ }
1097
+ };
1098
+ }));
1099
+ /**
1100
+ * Parse an npm package spec: `[@scope/]name[@version][/subdir]`
1101
+ */
1102
+ function parseNpmSpec(input) {
1103
+ let rest = input;
1104
+ let subdir = "";
1105
+ if (rest.startsWith("@")) {
1106
+ const secondSlash = rest.indexOf("/", rest.indexOf("/") + 1);
1107
+ if (secondSlash > 0) {
1108
+ subdir = rest.slice(secondSlash);
1109
+ rest = rest.slice(0, secondSlash);
1110
+ }
1111
+ } else {
1112
+ const firstSlash = rest.indexOf("/");
1113
+ if (firstSlash > 0) {
1114
+ subdir = rest.slice(firstSlash);
1115
+ rest = rest.slice(0, firstSlash);
1116
+ }
1117
+ }
1118
+ const versionSep = rest.startsWith("@") ? rest.indexOf("@", 1) : rest.indexOf("@");
1119
+ const hasVersion = versionSep > 0;
1120
+ return {
1121
+ name: hasVersion ? rest.slice(0, versionSep) : rest,
1122
+ version: hasVersion ? rest.slice(versionSep + 1) : "latest",
1123
+ subdir
1124
+ };
1125
+ }
1126
+ /**
1127
+ * Fetch package metadata from the npm registry.
1128
+ * When `version` is provided, fetches that specific version.
1129
+ * Otherwise fetches the full package document.
1130
+ */
1131
+ async function fetchNpmInfo(name, version) {
1132
+ const registryURL = version ? `https://registry.npmjs.org/${name}/${version}` : `https://registry.npmjs.org/${name}`;
1133
+ const res = await fetch(registryURL);
1134
+ if (!res.ok) throw new Error(`Failed to fetch package info for ${name}${version ? `@${version}` : ""}: ${res.status} ${res.statusText}`);
1135
+ return res.json();
1136
+ }
1137
+ /**
1138
+ * Detect npmjs.com URLs and extract the package name.
1139
+ * Supports: npmjs.com/\<pkg\>, npmjs.com/package/\<pkg\>, www.npmjs.com/package/\<pkg\>
1140
+ * Also handles scoped packages: npmjs.com/package/@scope/name
1141
+ */
1142
+ function parseNpmURL(url) {
1143
+ let parsed;
1144
+ try {
1145
+ parsed = new URL(url);
1146
+ } catch {
1147
+ return;
1148
+ }
1149
+ if (parsed.hostname !== "www.npmjs.com" && parsed.hostname !== "npmjs.com") return;
1150
+ const pkgMatch = parsed.pathname.match(/^\/package\/((?:@[^/]+\/)?[^/]+)\/?$/);
1151
+ if (pkgMatch) return pkgMatch[1];
1152
+ const shortMatch = parsed.pathname.match(/^\/((?:@[^/]+\/)?[^/]+)\/?$/);
1153
+ if (shortMatch && !/^(package|settings|signup|login|org|search)$/.test(shortMatch[1])) return shortMatch[1];
1154
+ }
1155
+ var init__npm = __esmMin((() => {}));
1156
+ /** Check if a response is HTML by content-type or content sniffing */
1157
+ function _isHTML(contentType, body) {
1158
+ if (contentType.includes("text/html") || contentType.includes("application/xhtml")) return true;
1159
+ const trimmed = body.trimStart();
1160
+ return trimmed.startsWith("<!") || trimmed.startsWith("<html");
1161
+ }
1162
+ /** Extract a readable title from a URL */
1163
+ function _titleFromURL(url) {
1164
+ try {
1165
+ return new URL(url).hostname;
1166
+ } catch {
1167
+ return url;
1168
+ }
1169
+ }
1170
+ /**
1171
+ * Parse llms.txt content into a nav tree.
1172
+ * Format: `# Title`, `> Description`, `## Section`, `- [Title](url): description`
1173
+ */
1174
+ function _parseLlmsTxt(text, origin, fileMap, contentCache) {
1175
+ const lines = text.split("\n");
1176
+ const tree = [];
1177
+ let siteTitle = "";
1178
+ let siteDescription = "";
1179
+ let currentSection;
1180
+ let order = 0;
1181
+ let childOrder = 0;
1182
+ for (const line of lines) {
1183
+ const trimmed = line.trim();
1184
+ if (!siteTitle && trimmed.startsWith("# ") && !trimmed.startsWith("## ")) {
1185
+ siteTitle = trimmed.slice(2).trim();
1186
+ continue;
1187
+ }
1188
+ if (!siteDescription && trimmed.startsWith("> ")) {
1189
+ siteDescription = trimmed.slice(2).trim();
1190
+ continue;
1191
+ }
1192
+ if (trimmed.startsWith("## ")) {
1193
+ currentSection = {
1194
+ slug: _slugify(trimmed.slice(3).trim()),
1195
+ path: `/_section/${order}`,
1196
+ title: trimmed.slice(3).trim(),
1197
+ order: order++,
1198
+ page: false,
1199
+ children: []
1200
+ };
1201
+ childOrder = 0;
1202
+ tree.push(currentSection);
1203
+ continue;
1204
+ }
1205
+ const linkMatch = trimmed.match(/^-\s*\[([^\]]+)]\(([^)]+)\)(?::\s*(.+))?$/);
1206
+ if (linkMatch) {
1207
+ const title = linkMatch[1];
1208
+ const href = linkMatch[2];
1209
+ const description = linkMatch[3]?.trim();
1210
+ let resolved;
1211
+ try {
1212
+ resolved = new URL(href, origin);
1213
+ if (resolved.origin !== origin) continue;
1214
+ } catch {
1215
+ continue;
1216
+ }
1217
+ const path = resolved.pathname.replace(/\/+$/, "") || "/";
1218
+ const entry = {
1219
+ slug: path.split("/").pop() || path,
1220
+ path,
1221
+ title,
1222
+ order: childOrder++,
1223
+ ...description ? { description } : {}
1224
+ };
1225
+ fileMap.set(path, path);
1226
+ if (currentSection) currentSection.children.push(entry);
1227
+ else tree.push(entry);
1228
+ continue;
1229
+ }
1230
+ }
1231
+ if (tree.length === 0) return [];
1232
+ const root = {
1233
+ slug: "",
1234
+ path: "/",
1235
+ title: siteTitle || _titleFromURL(origin),
1236
+ order: 0,
1237
+ ...siteDescription ? { description: siteDescription } : {},
1238
+ ...tree.length > 0 ? { children: tree } : {}
1239
+ };
1240
+ fileMap.set("/", "/");
1241
+ contentCache.set("/", text);
1242
+ return [root];
1243
+ }
1244
+ function _slugify(text) {
1245
+ return text.toLowerCase().replace(/[^a-z\d]+/g, "-").replace(/^-|-$/g, "");
1246
+ }
1247
+ /** Extract internal links from markdown content to build nav children */
1248
+ function _extractLinks(markdown, baseURL) {
1249
+ const seen = /* @__PURE__ */ new Set();
1250
+ const entries = [];
1251
+ const tocPaths = /* @__PURE__ */ new Set();
1252
+ let order = 0;
1253
+ const linkRe = /\[([^\]]+)]\(([^)]+)\)/g;
1254
+ let match;
1255
+ while ((match = linkRe.exec(markdown)) !== null) {
1256
+ const title = match[1];
1257
+ const href = match[2];
1258
+ const resolved = _resolveHref(href, baseURL);
1259
+ if (!resolved) continue;
1260
+ let path = resolved.pathname.replace(/\/+$/, "") || "/";
1261
+ const isToc = /\/index\.md$/i.test(path) || path.endsWith("/index");
1262
+ path = path.replace(/\/index\.md$/i, "").replace(/\/index$/, "").replace(/\.md$/i, "");
1263
+ path = path || "/";
1264
+ if (path === "/") continue;
1265
+ if (seen.has(path)) continue;
1266
+ seen.add(path);
1267
+ if (isToc) tocPaths.add(path);
1268
+ const slug = path.split("/").pop() || path;
1269
+ entries.push({
1270
+ slug,
1271
+ path,
1272
+ title,
1273
+ order: order++
1274
+ });
1275
+ }
1276
+ return {
1277
+ entries,
1278
+ tocPaths
1279
+ };
1280
+ }
1281
+ /** Resolve an href relative to a base URL, returning null for external links */
1282
+ function _resolveHref(href, baseURL) {
1283
+ try {
1284
+ const base = new URL(baseURL);
1285
+ const resolved = new URL(href, baseURL);
1286
+ if (resolved.origin !== base.origin) return void 0;
1287
+ if (href.startsWith("#")) return void 0;
1288
+ if (/\.(png|jpg|jpeg|gif|svg|css|js|ico|woff2?)$/i.test(resolved.pathname)) return void 0;
1289
+ return resolved;
1290
+ } catch {
1291
+ return;
1292
+ }
1293
+ }
1294
+ var DocsSourceHTTP;
1295
+ var init_http = __esmMin((() => {
1296
+ init__base();
1297
+ init__npm();
1298
+ DocsSourceHTTP = class extends DocsSource {
1299
+ url;
1300
+ options;
1301
+ _contentCache = /* @__PURE__ */ new Map();
1302
+ _tree = [];
1303
+ _fileMap = /* @__PURE__ */ new Map();
1304
+ _npmPackage;
1305
+ constructor(url, options = {}) {
1306
+ super();
1307
+ this.url = url.replace(/\/+$/, "");
1308
+ this._npmPackage = parseNpmURL(this.url);
1309
+ this.options = options;
1310
+ }
1311
+ async load() {
1312
+ if (this._npmPackage) return this._loadNpm(this._npmPackage);
1313
+ const llmsTree = await this._tryLlmsTxt();
1314
+ if (llmsTree) {
1315
+ this._tree = llmsTree;
1316
+ return {
1317
+ tree: this._tree,
1318
+ fileMap: this._fileMap
1319
+ };
1320
+ }
1321
+ const markdown = await this._fetch(this.url);
1322
+ this._contentCache.set("/", markdown);
1323
+ const rootEntry = {
1324
+ slug: "",
1325
+ path: "/",
1326
+ title: parseMeta(markdown).title || _titleFromURL(this.url),
1327
+ order: 0
1328
+ };
1329
+ const { entries: children, tocPaths } = _extractLinks(markdown, this.url);
1330
+ if (children.length > 0) {
1331
+ rootEntry.children = children;
1332
+ for (const child of children) this._fileMap.set(child.path, child.path);
1333
+ }
1334
+ this._tree = [rootEntry];
1335
+ this._fileMap.set("/", "/");
1336
+ if (tocPaths.size > 0) await this._crawlTocPages(children, tocPaths);
1337
+ return {
1338
+ tree: this._tree,
1339
+ fileMap: this._fileMap
1340
+ };
1341
+ }
1342
+ /** Try fetching /llms.txt and parse it into a nav tree */
1343
+ async _tryLlmsTxt() {
1344
+ let origin;
1345
+ try {
1346
+ origin = new URL(this.url).origin;
1347
+ } catch {
1348
+ return;
1349
+ }
1350
+ let text;
1351
+ try {
1352
+ const res = await fetch(`${origin}/llms.txt`, { headers: {
1353
+ accept: "text/plain",
1354
+ ...this.options.headers
1355
+ } });
1356
+ if (!res.ok) return void 0;
1357
+ text = await res.text();
1358
+ } catch {
1359
+ return;
1360
+ }
1361
+ if (!text.trimStart().startsWith("#")) return void 0;
1362
+ return _parseLlmsTxt(text, origin, this._fileMap, this._contentCache);
1363
+ }
1364
+ async readContent(filePath) {
1365
+ const cached = this._contentCache.get(filePath);
1366
+ if (cached !== void 0) return cached;
1367
+ const origin = new URL(this.url).origin;
1368
+ const url = filePath === "/" ? this.url : `${origin}${filePath}`;
1369
+ const markdown = await this._fetch(url);
1370
+ this._contentCache.set(filePath, markdown);
1371
+ return markdown;
1372
+ }
1373
+ /** Crawl index.md pages and attach their links as children */
1374
+ async _crawlTocPages(entries, tocPaths, depth = 0) {
1375
+ if (depth > 3) return;
1376
+ const origin = new URL(this.url).origin;
1377
+ await Promise.all(entries.map(async (entry) => {
1378
+ if (!tocPaths.has(entry.path)) return;
1379
+ const url = `${origin}${entry.path}`;
1380
+ const markdown = await this._fetch(url);
1381
+ this._contentCache.set(entry.path, markdown);
1382
+ const { entries: children, tocPaths: subTocPaths } = _extractLinks(markdown, url);
1383
+ if (children.length > 0) {
1384
+ entry.children = children;
1385
+ for (const child of children) this._fileMap.set(child.path, child.path);
1386
+ if (subTocPaths.size > 0) await this._crawlTocPages(children, subTocPaths, depth + 1);
1387
+ }
1388
+ }));
1389
+ }
1390
+ /** Load an npm package README from the registry */
1391
+ async _loadNpm(pkg) {
1392
+ let markdown;
1393
+ try {
1394
+ const data = await fetchNpmInfo(pkg);
1395
+ markdown = data.readme || `# ${data.name || pkg}\n\n${data.description || "No README available."}`;
1396
+ } catch (err) {
1397
+ markdown = `# Fetch Error\n\nFailed to fetch package \`${pkg}\`\n\n> ${err instanceof Error ? err.message : String(err)}`;
1398
+ }
1399
+ this._contentCache.set("/", markdown);
1400
+ this._fileMap.set("/", "/");
1401
+ this._tree = [{
1402
+ slug: "",
1403
+ path: "/",
1404
+ title: parseMeta(markdown).title || pkg,
1405
+ order: 0
1406
+ }];
1407
+ return {
1408
+ tree: this._tree,
1409
+ fileMap: this._fileMap
1410
+ };
1411
+ }
1412
+ async _fetch(url) {
1413
+ let res;
1414
+ try {
1415
+ res = await fetch(url, { headers: {
1416
+ accept: "text/markdown, text/plain;q=0.9, text/html;q=0.8",
1417
+ ...this.options.headers
1418
+ } });
1419
+ } catch (err) {
1420
+ return `# Fetch Error\n\nFailed to fetch \`${url}\`\n\n> ${err instanceof Error ? err.message : String(err)}`;
1421
+ }
1422
+ if (!res.ok) return `# ${res.status} ${res.statusText}\n\nFailed to fetch \`${url}\``;
1423
+ const contentType = res.headers.get("content-type") || "";
1424
+ const text = await res.text();
1425
+ if (_isHTML(contentType, text)) {
1426
+ const { htmlToMarkdown } = await import("mdream");
1427
+ return htmlToMarkdown(text, { origin: url });
1428
+ }
1429
+ return text;
1430
+ }
1431
+ };
1432
+ }));
1433
+ async function npmProvider(input) {
1434
+ const { name, version, subdir } = parseNpmSpec(input);
1435
+ const info = await fetchNpmInfo(name, version);
1436
+ return {
1437
+ name: info.name,
1438
+ version: info.version,
1439
+ subdir,
1440
+ tar: info.dist.tarball
1441
+ };
1442
+ }
1443
+ var DocsSourceNpm;
1444
+ var init_npm = __esmMin((() => {
1445
+ init__base();
1446
+ init_fs();
1447
+ init__npm();
1448
+ DocsSourceNpm = class extends DocsSource {
1449
+ src;
1450
+ options;
1451
+ _fs;
1452
+ constructor(src, options = {}) {
1453
+ super();
1454
+ this.src = src;
1455
+ this.options = options;
1456
+ }
1457
+ async load() {
1458
+ const pkg = this.src.startsWith("npm:") ? this.src : `npm:${this.src}`;
1459
+ const source = this.options.subdir ? `${pkg}/${this.options.subdir}` : pkg;
1460
+ const id = source.replace(/[/#:@]/g, "_");
1461
+ const dir = join(tmpdir(), "mdzilla", "npm", id);
1462
+ const { downloadTemplate } = await import("giget");
1463
+ await downloadTemplate(source, {
1464
+ dir,
1465
+ force: true,
1466
+ install: false,
1467
+ providers: { npm: npmProvider },
1468
+ registry: false
1469
+ });
1470
+ let docsDir = dir;
1471
+ for (const sub of ["docs/content", "docs"]) {
1472
+ const candidate = join(dir, sub);
1473
+ if (existsSync(candidate)) {
1474
+ docsDir = candidate;
1475
+ break;
1476
+ }
1477
+ }
1478
+ this._fs = new DocsSourceFS(docsDir);
1479
+ return this._fs.load();
1480
+ }
1481
+ async readContent(filePath) {
1482
+ if (!this._fs) throw new Error("DocsSourceNpm: call load() before readContent()");
1483
+ return this._fs.readContent(filePath);
1484
+ }
1485
+ };
1486
+ }));
1487
+ var init_source = __esmMin((() => {
1488
+ init__base();
1489
+ init_fs();
1490
+ init_git();
1491
+ init_http();
1492
+ init_npm();
1493
+ }));
1494
+ /**
1495
+ * Export documentation entries to a local filesystem directory as flat `.md` files.
1496
+ *
1497
+ * Each entry is written to `<dir>/<path>.md` (or `<dir>/<path>/index.md` for directory
1498
+ * index pages). Navigation order is preserved via `order` frontmatter in pages and
1499
+ * `.navigation.yml` files in directories.
1500
+ *
1501
+ * A `README.md` table of contents is generated at the root of the output directory.
1502
+ */
1503
+ async function exportDocsToFS(manager, dir, options = {}) {
1504
+ const rootEntry = manager.flat.find((f) => f.entry.path === "/");
1505
+ const tocLines = [`# ${options.title ?? rootEntry?.entry.title ?? "Table of Contents"}`, ""];
1506
+ const writtenFiles = /* @__PURE__ */ new Set();
1507
+ const dirPaths = /* @__PURE__ */ new Set();
1508
+ collectDirPaths(manager.tree, dirPaths);
1509
+ for (const flat of manager.flat) {
1510
+ if (options.filter ? !options.filter(flat) : flat.entry.page === false) continue;
1511
+ if (IGNORED_PATHS.has(flat.entry.path)) continue;
1512
+ let content = await manager.getContent(flat);
1513
+ if (content === void 0) continue;
1514
+ const cleanContent = options.plainText ? renderToText(content) : renderToMarkdown(content);
1515
+ const filePath = flat.entry.path === "/" || dirPaths.has(flat.entry.path) ? flat.entry.path === "/" ? "/index.md" : `${flat.entry.path}/index.md` : flat.entry.path.endsWith(".md") ? flat.entry.path : `${flat.entry.path}.md`;
1516
+ const dest = join(dir, filePath);
1517
+ await mkdir(dirname(dest), { recursive: true });
1518
+ await writeFile(dest, cleanContent, "utf8");
1519
+ writtenFiles.add(filePath.slice(1));
1520
+ const indent = " ".repeat(flat.depth);
1521
+ const desc = flat.entry.description ? `: ${flat.entry.description}` : "";
1522
+ tocLines.push(`${indent}- [${flat.entry.title}](.${filePath})${desc}`);
1523
+ }
1524
+ let tocFile = options.tocFile ?? "README.md";
1525
+ if (writtenFiles.has(tocFile)) tocFile = `_${tocFile}`;
1526
+ await writeFile(join(dir, tocFile), tocLines.join("\n") + "\n", "utf8");
1527
+ await writeFile(join(dir, "_navigation.json"), JSON.stringify(manager.tree, null, 2) + "\n", "utf8");
1528
+ }
1529
+ /** Collect all paths that are directories (have children in the tree). */
1530
+ function collectDirPaths(entries, set) {
1531
+ for (const entry of entries) if (entry.children?.length) {
1532
+ set.add(entry.path);
1533
+ collectDirPaths(entry.children, set);
1534
+ }
1535
+ }
1536
+ var IGNORED_PATHS;
1537
+ var init_exporter = __esmMin((() => {
1538
+ IGNORED_PATHS = new Set(["/llms.txt", "/llms-full.txt"]);
1539
+ }));
1540
+ var src_exports = /* @__PURE__ */ __exportAll({
1541
+ DocsManager: () => DocsManager,
1542
+ DocsSource: () => DocsSource,
1543
+ DocsSourceFS: () => DocsSourceFS,
1544
+ DocsSourceGit: () => DocsSourceGit,
1545
+ DocsSourceHTTP: () => DocsSourceHTTP,
1546
+ DocsSourceNpm: () => DocsSourceNpm,
1547
+ exportDocsToFS: () => exportDocsToFS
1548
+ });
1549
+ var init_src = __esmMin((() => {
1550
+ init_manager();
1551
+ init_source();
1552
+ init_exporter();
1553
+ }));
1554
+ async function useDocs(initOpts) {
1555
+ if (_docs) return _docs;
1556
+ if (!_docs) {
1557
+ const { DocsManager, DocsSourceGit } = await Promise.resolve().then(() => (init_src(), src_exports));
1558
+ _docs = new DocsManager(initOpts?.source || new DocsSourceGit("gh:nitrojs/nitro/docs", { subdir: "docs" }));
1559
+ await _docs.load();
1560
+ }
1561
+ return _docs;
1562
+ }
1563
+ var _docs;
1564
+ var init_docs = __esmMin((() => {}));
1565
+ var meta_exports = /* @__PURE__ */ __exportAll({ default: () => meta_default });
1566
+ var meta_default;
1567
+ var init_meta = __esmMin((() => {
1568
+ init_h3();
1569
+ init_docs();
1570
+ meta_default = defineHandler(async () => {
1571
+ return {
1572
+ title: "Nitro",
1573
+ toc: (await useDocs()).tree
1574
+ };
1575
+ });
1576
+ }));
1577
+ var page_exports = /* @__PURE__ */ __exportAll({ default: () => page_default });
1578
+ async function highlightCodeBlocks(html) {
1579
+ const codeBlockRe = /<pre><code class="language-(\w+)">([\s\S]*?)<\/code><\/pre>/g;
1580
+ const replacements = [];
1581
+ for (const m of html.matchAll(codeBlockRe)) {
1582
+ const [match, lang, encoded] = m;
1583
+ const text = decodeHtmlEntities(encoded);
1584
+ replacements.push(highlightText(text, lang, false).then((highlighted) => ({
1585
+ match,
1586
+ result: `<pre><code class="language-${lang}">${highlighted}</code></pre>`
1587
+ })).catch(() => ({
1588
+ match,
1589
+ result: match
1590
+ })));
1591
+ }
1592
+ let result = html;
1593
+ for (const { match, result: replacement } of await Promise.all(replacements)) result = result.replace(match, replacement);
1594
+ return result;
1595
+ }
1596
+ function addHeadingAnchors(html) {
1597
+ return html.replace(/<(h[1-6])>(.*?)<\/\1>/g, (_match, tag, content) => {
1598
+ const id = content.replace(/<[^>]+>/g, "").trim().toLowerCase().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-");
1599
+ return `<${tag} id="${id}"><a href="#${id}">#</a>${content}</${tag}>`;
1600
+ });
1601
+ }
1602
+ function decodeHtmlEntities(text) {
1603
+ return text.replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, "\"").replace(/&#39;/g, "'");
1604
+ }
1605
+ var page_default;
1606
+ var init_page = __esmMin((async () => {
1607
+ init_h3();
1608
+ init_docs();
1609
+ await init();
1610
+ page_default = defineHandler(async (event) => {
1611
+ const { path } = getQuery(event);
1612
+ if (!path) return { error: "Missing ?path= query parameter" };
1613
+ const result = await (await useDocs()).resolvePage(path);
1614
+ if (!result.raw) return {
1615
+ error: "Page not found",
1616
+ path
1617
+ };
1618
+ return {
1619
+ path,
1620
+ html: addHeadingAnchors(await highlightCodeBlocks(renderToHtml(result.raw)))
1621
+ };
1622
+ });
1623
+ }));
1624
+ var search_exports = /* @__PURE__ */ __exportAll({ default: () => search_default });
1625
+ /** Extract short text snippets around matching terms. */
1626
+ function extractSnippets(content, terms, opts = {}) {
1627
+ const { maxSnippets = 3, radius = 80 } = opts;
1628
+ const lower = content.toLowerCase();
1629
+ const positions = [];
1630
+ for (const term of terms) {
1631
+ let idx = lower.indexOf(term);
1632
+ while (idx !== -1 && positions.length < maxSnippets * 2) {
1633
+ positions.push(idx);
1634
+ idx = lower.indexOf(term, idx + term.length);
1635
+ }
1636
+ }
1637
+ positions.sort((a, b) => a - b);
1638
+ const snippets = [];
1639
+ let prevEnd = -1;
1640
+ for (const pos of positions) {
1641
+ if (snippets.length >= maxSnippets) break;
1642
+ const start = Math.max(0, pos - radius);
1643
+ const end = Math.min(content.length, pos + radius);
1644
+ if (start <= prevEnd) continue;
1645
+ prevEnd = end;
1646
+ let snippet = content.slice(start, end).trim().replaceAll(/\s+/g, " ");
1647
+ if (start > 0) snippet = "…" + snippet;
1648
+ if (end < content.length) snippet = snippet + "…";
1649
+ snippets.push(snippet);
1650
+ }
1651
+ return snippets;
1652
+ }
1653
+ var search_default;
1654
+ var init_search = __esmMin((() => {
1655
+ init_h3();
1656
+ init_docs();
1657
+ search_default = defineHandler(async (event) => {
1658
+ const { q, limit } = getQuery(event);
1659
+ if (!q || q.length < 2) return { results: [] };
1660
+ const docs = await useDocs();
1661
+ const maxResults = Math.min(Number(limit) || 20, 50);
1662
+ const query = q.toLowerCase();
1663
+ const terms = query.split(/\s+/).filter(Boolean);
1664
+ const scored = [];
1665
+ const titleMatched = /* @__PURE__ */ new Set();
1666
+ for (const flat of docs.pages) {
1667
+ const title = flat.entry.title;
1668
+ const titleLower = title.toLowerCase();
1669
+ if (!terms.every((t) => titleLower.includes(t))) continue;
1670
+ titleMatched.add(flat.entry.path);
1671
+ scored.push({
1672
+ path: flat.entry.path,
1673
+ title,
1674
+ score: titleLower === query ? 0 : 100,
1675
+ snippets: []
1676
+ });
1677
+ }
1678
+ for (const flat of docs.pages) {
1679
+ if (titleMatched.has(flat.entry.path)) continue;
1680
+ const raw = await docs.getContent(flat);
1681
+ if (!raw) continue;
1682
+ const contentLower = raw.toLowerCase();
1683
+ if (!terms.every((t) => contentLower.includes(t))) continue;
1684
+ let score = 300;
1685
+ let matchedHeading;
1686
+ const meta = parseMeta$1(raw);
1687
+ for (const h of meta.headings || []) {
1688
+ const hLower = h.text.toLowerCase();
1689
+ if (terms.every((t) => hLower.includes(t))) {
1690
+ score = hLower === query ? 150 : 200;
1691
+ matchedHeading = h.text;
1692
+ break;
1693
+ }
1694
+ }
1695
+ const snippets = extractSnippets(renderToText$1(raw), terms);
1696
+ scored.push({
1697
+ path: flat.entry.path,
1698
+ title: flat.entry.title,
1699
+ heading: matchedHeading,
1700
+ snippets,
1701
+ score
1702
+ });
1703
+ }
1704
+ for (const result of scored) {
1705
+ if (result.snippets.length > 0) continue;
1706
+ const flat = docs.pages.find((f) => f.entry.path === result.path);
1707
+ if (!flat) continue;
1708
+ const raw = await docs.getContent(flat);
1709
+ if (!raw) continue;
1710
+ result.snippets = extractSnippets(renderToText$1(raw), terms);
1711
+ }
1712
+ scored.sort((a, b) => a.score - b.score);
1713
+ return { results: scored.slice(0, maxResults).map(({ score: _, ...r }) => r) };
1714
+ });
1715
+ }));
1716
+ var rendererTemplate;
1717
+ var init_renderer_template$1 = __esmMin((() => {
1718
+ init_node();
1719
+ rendererTemplate = () => new HTTPResponse("<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <link rel=\"icon\" type=\"image/svg+xml\" href=\"/assets/logo-BLkVGWak.svg\" />\n <title></title>\n <style>/*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-300:oklch(80.8% .114 19.571);--color-red-500:oklch(63.7% .237 25.331);--color-red-800:oklch(44.4% .177 26.899);--color-red-900:oklch(39.6% .141 25.723);--color-yellow-50:oklch(98.7% .026 102.212);--color-yellow-300:oklch(90.5% .182 98.111);--color-yellow-500:oklch(79.5% .184 86.047);--color-yellow-800:oklch(47.6% .114 61.907);--color-yellow-900:oklch(42.1% .095 57.708);--color-green-50:oklch(98.2% .018 155.826);--color-green-300:oklch(87.1% .15 154.449);--color-green-500:oklch(72.3% .219 149.579);--color-green-800:oklch(44.8% .119 151.328);--color-green-900:oklch(39.3% .095 152.535);--color-blue-50:oklch(97% .014 254.604);--color-blue-300:oklch(80.9% .105 251.813);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-800:oklch(42.4% .199 265.638);--color-blue-900:oklch(37.9% .146 265.522);--color-purple-50:oklch(97.7% .014 308.299);--color-purple-300:oklch(82.7% .119 306.383);--color-purple-500:oklch(62.7% .265 303.9);--color-purple-800:oklch(43.8% .218 303.724);--color-purple-900:oklch(38.1% .176 304.987);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-gray-950:oklch(13% .028 261.692);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-lg:32rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-medium:500;--radius-md:.375rem;--radius-xl:.75rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.inset-0{inset:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.z-50{z-index:50}.mt-0\\.5{margin-top:calc(var(--spacing) * .5)}.mr-1{margin-right:calc(var(--spacing) * 1)}.-ml-1{margin-left:calc(var(--spacing) * -1)}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.flex{display:flex}.hidden{display:none}.inline{display:inline}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.h-4{height:calc(var(--spacing) * 4)}.h-8{height:calc(var(--spacing) * 8)}.h-screen{height:100vh}.max-h-80{max-height:calc(var(--spacing) * 80)}.w-4{width:calc(var(--spacing) * 4)}.w-56{width:calc(var(--spacing) * 56)}.w-64{width:calc(var(--spacing) * 64)}.w-full{width:100%}.max-w-lg{max-width:var(--container-lg)}.max-w-none{max-width:none}.min-w-0{min-width:calc(var(--spacing) * 0)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.rotate-90{rotate:90deg}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.flex-col{flex-direction:column}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}:where(.space-y-0\\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * .5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * .5) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-gray-100{border-color:var(--color-gray-100)}.border-gray-200{border-color:var(--color-gray-200)}.bg-black\\/50{background-color:#00000080}@supports (color:color-mix(in lab, red, red)){.bg-black\\/50{background-color:color-mix(in oklab, var(--color-black) 50%, transparent)}}.bg-gray-50{background-color:var(--color-gray-50)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.p-0\\.5{padding:calc(var(--spacing) * .5)}.p-1\\.5{padding:calc(var(--spacing) * 1.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-8{padding:calc(var(--spacing) * 8)}.px-1\\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-0\\.5{padding-block:calc(var(--spacing) * .5)}.py-1\\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-8{padding-block:calc(var(--spacing) * 8)}.pt-\\[15vh\\]{padding-top:15vh}.text-center{text-align:center}.text-left{text-align:left}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-900{color:var(--color-gray-900)}.text-red-500{color:var(--color-red-500)}.placeholder-gray-400::placeholder{color:var(--color-gray-400)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media (hover:hover){.hover\\:border-gray-300:hover{border-color:var(--color-gray-300)}.hover\\:bg-gray-50:hover{background-color:var(--color-gray-50)}.hover\\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\\:text-gray-500:hover{color:var(--color-gray-500)}.hover\\:text-gray-600:hover{color:var(--color-gray-600)}.hover\\:text-gray-900:hover{color:var(--color-gray-900)}}.focus\\:outline-none:focus{--tw-outline-style:none;outline-style:none}@media (min-width:40rem){.sm\\:inline{display:inline}}.dark\\:border-gray-700:where(.dark,.dark *){border-color:var(--color-gray-700)}.dark\\:border-gray-800:where(.dark,.dark *){border-color:var(--color-gray-800)}.dark\\:bg-gray-800:where(.dark,.dark *){background-color:var(--color-gray-800)}.dark\\:bg-gray-900:where(.dark,.dark *){background-color:var(--color-gray-900)}.dark\\:bg-gray-950:where(.dark,.dark *){background-color:var(--color-gray-950)}.dark\\:text-gray-100:where(.dark,.dark *){color:var(--color-gray-100)}.dark\\:text-gray-200:where(.dark,.dark *){color:var(--color-gray-200)}.dark\\:text-gray-400:where(.dark,.dark *){color:var(--color-gray-400)}.dark\\:text-gray-500:where(.dark,.dark *),.dark\\:placeholder-gray-500:where(.dark,.dark *)::placeholder{color:var(--color-gray-500)}@media (hover:hover){.dark\\:hover\\:border-gray-600:where(.dark,.dark *):hover{border-color:var(--color-gray-600)}.dark\\:hover\\:bg-gray-800:where(.dark,.dark *):hover{background-color:var(--color-gray-800)}.dark\\:hover\\:text-gray-100:where(.dark,.dark *):hover{color:var(--color-gray-100)}.dark\\:hover\\:text-gray-300:where(.dark,.dark *):hover{color:var(--color-gray-300)}.dark\\:hover\\:text-gray-400:where(.dark,.dark *):hover{color:var(--color-gray-400)}}}#search-results::-webkit-scrollbar{width:6px}#search-results::-webkit-scrollbar-thumb{background:var(--color-gray-300);border-radius:3px}.dark #search-results::-webkit-scrollbar-thumb{background:var(--color-gray-600)}.line-clamp-2{-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.nav-active{background:var(--color-gray-100)}.dark .nav-active{background:var(--color-gray-800)}.prose{color:var(--color-gray-700);line-height:1.75}.prose h1,.prose h2,.prose h3,.prose h4,.prose h5,.prose h6{color:var(--color-gray-900);margin-top:2em;margin-bottom:.75em;font-weight:700;line-height:1.3;position:relative}:is(.prose h1,.prose h2,.prose h3,.prose h4,.prose h5,.prose h6)>a[href^=\\#]{color:var(--color-gray-300);opacity:0;padding-right:.25em;font-weight:400;text-decoration:none;transition:opacity .15s;position:absolute;right:100%}:is(.prose h1,.prose h2,.prose h3,.prose h4,.prose h5,.prose h6):hover>a[href^=\\#]{opacity:1}.prose h1{margin-top:0;font-size:2.25em}.prose h2{border-bottom:1px solid var(--color-gray-200);padding-bottom:.3em;font-size:1.5em}.prose h3{font-size:1.25em}.prose h4{font-size:1.1em}.prose p{margin-top:1.25em;margin-bottom:1.25em}.prose a{color:var(--color-blue-600);text-underline-offset:2px;text-decoration:underline}.prose a:hover{color:var(--color-blue-500)}.prose strong{color:var(--color-gray-900);font-weight:600}.prose code{color:var(--color-gray-800);background:var(--color-gray-100);border-radius:.25em;padding:.2em .4em;font-size:.875em}.prose pre{border:1px solid var(--color-gray-200);background:#f6f8fa;border-radius:.5em;margin-top:1.5em;margin-bottom:1.5em;padding:1em;overflow-x:auto}.prose pre code{background:0 0;border-radius:0;padding:0;font-size:.875em}.prose blockquote{border-left:3px solid var(--color-gray-300);color:var(--color-gray-500);margin-top:1.5em;margin-bottom:1.5em;padding-left:1em;font-style:italic}.prose blockquote.alert{border-left-width:4px;border-radius:.5em;padding:.75em 1em;font-style:normal}.prose blockquote.alert>p:first-child{margin-top:0}.prose blockquote.alert>p:last-child{margin-bottom:0}.prose blockquote.alert-tip{border-left-color:var(--color-green-500);background:#f0fdf499}@supports (color:color-mix(in lab, red, red)){.prose blockquote.alert-tip{background:color-mix(in srgb, var(--color-green-50) 60%, transparent)}}.prose blockquote.alert-tip{color:var(--color-green-800)}.prose blockquote.alert-note{border-left-color:var(--color-blue-500);background:#eff6ff99}@supports (color:color-mix(in lab, red, red)){.prose blockquote.alert-note{background:color-mix(in srgb, var(--color-blue-50) 60%, transparent)}}.prose blockquote.alert-note{color:var(--color-blue-800)}.prose blockquote.alert-important{border-left-color:var(--color-purple-500);background:#faf5ff99}@supports (color:color-mix(in lab, red, red)){.prose blockquote.alert-important{background:color-mix(in srgb, var(--color-purple-50) 60%, transparent)}}.prose blockquote.alert-important{color:var(--color-purple-800)}.prose blockquote.alert-warning{border-left-color:var(--color-yellow-500);background:#fefce899}@supports (color:color-mix(in lab, red, red)){.prose blockquote.alert-warning{background:color-mix(in srgb, var(--color-yellow-50) 60%, transparent)}}.prose blockquote.alert-warning{color:var(--color-yellow-800)}.prose blockquote.alert-caution{border-left-color:var(--color-red-500);background:#fef2f299}@supports (color:color-mix(in lab, red, red)){.prose blockquote.alert-caution{background:color-mix(in srgb, var(--color-red-50) 60%, transparent)}}.prose blockquote.alert-caution{color:var(--color-red-800)}.prose ul{margin-top:1.25em;margin-bottom:1.25em;padding-left:1.5em;list-style:outside}.prose ol{margin-top:1.25em;margin-bottom:1.25em;padding-left:1.5em;list-style:decimal}.prose li{margin-top:.5em;margin-bottom:.5em}.prose li>ul,.prose li>ol{margin-top:.25em;margin-bottom:.25em}.prose hr{border:none;border-top:1px solid var(--color-gray-200);margin-top:2em;margin-bottom:2em}.prose table{border-collapse:collapse;width:100%;margin-top:1.5em;margin-bottom:1.5em;font-size:.875em}.prose th,.prose td{border:1px solid var(--color-gray-200);text-align:left;padding:.5em .75em}.prose th{background:var(--color-gray-50);color:var(--color-gray-900);font-weight:600}.prose img,.prose video{border-radius:.5em;max-width:100%;margin-top:1.5em;margin-bottom:1.5em}.dark .prose{color:var(--color-gray-200)}.dark .prose h1,.dark .prose h2,.dark .prose h3,.dark .prose h4,.dark .prose h5,.dark .prose h6{color:var(--color-gray-50)}:is(.dark .prose h1,.dark .prose h2,.dark .prose h3,.dark .prose h4,.dark .prose h5,.dark .prose h6)>a[href^=\\#]{color:var(--color-gray-600)}.dark .prose h2{border-bottom-color:var(--color-gray-700)}.dark .prose a{color:var(--color-blue-400)}.dark .prose a:hover{color:var(--color-blue-300)}.dark .prose strong{color:var(--color-gray-50)}.dark .prose code{color:var(--color-gray-100);background:var(--color-gray-800)}.dark .prose pre{border-color:var(--color-gray-700);background:#161b22}.dark .prose pre code{color:var(--color-gray-100);background:0 0}.dark .prose blockquote{border-left-color:var(--color-gray-600);color:var(--color-gray-400)}.dark .prose blockquote.alert-tip{background:#0d542b4d}@supports (color:color-mix(in lab, red, red)){.dark .prose blockquote.alert-tip{background:color-mix(in srgb, var(--color-green-900) 30%, transparent)}}.dark .prose blockquote.alert-tip{color:var(--color-green-300);border-left-color:var(--color-green-500)}.dark .prose blockquote.alert-note{background:#1c398e4d}@supports (color:color-mix(in lab, red, red)){.dark .prose blockquote.alert-note{background:color-mix(in srgb, var(--color-blue-900) 30%, transparent)}}.dark .prose blockquote.alert-note{color:var(--color-blue-300);border-left-color:var(--color-blue-500)}.dark .prose blockquote.alert-important{background:#59168b4d}@supports (color:color-mix(in lab, red, red)){.dark .prose blockquote.alert-important{background:color-mix(in srgb, var(--color-purple-900) 30%, transparent)}}.dark .prose blockquote.alert-important{color:var(--color-purple-300);border-left-color:var(--color-purple-500)}.dark .prose blockquote.alert-warning{background:#733e0a4d}@supports (color:color-mix(in lab, red, red)){.dark .prose blockquote.alert-warning{background:color-mix(in srgb, var(--color-yellow-900) 30%, transparent)}}.dark .prose blockquote.alert-warning{color:var(--color-yellow-300);border-left-color:var(--color-yellow-500)}.dark .prose blockquote.alert-caution{background:#82181a4d}@supports (color:color-mix(in lab, red, red)){.dark .prose blockquote.alert-caution{background:color-mix(in srgb, var(--color-red-900) 30%, transparent)}}.dark .prose blockquote.alert-caution{color:var(--color-red-300);border-left-color:var(--color-red-500)}.dark .prose hr{border-top-color:var(--color-gray-700)}.dark .prose th,.dark .prose td{border-color:var(--color-gray-700)}.dark .prose th{background:var(--color-gray-800);color:var(--color-gray-50)}.shj-syn-cmnt{color:#6e7781;font-style:italic}.shj-syn-err,.shj-syn-kwd{color:#cf222e}.shj-syn-class{color:#953800}.shj-syn-type,.shj-syn-oper,.shj-syn-num,.shj-syn-section,.shj-syn-var,.shj-syn-bool{color:#0550ae}.shj-syn-str{color:#0a3069}.shj-syn-func{color:#8250df}.shj-syn-insert{color:#116329}.shj-syn-deleted{color:#cf222e}.shj-syn-esc{color:#0550ae}.dark .shj-syn-cmnt{color:#8b949e}.dark .shj-syn-err,.dark .shj-syn-kwd{color:#ff7b72}.dark .shj-syn-class{color:#ffa657}.dark .shj-syn-type,.dark .shj-syn-oper,.dark .shj-syn-num,.dark .shj-syn-section,.dark .shj-syn-var,.dark .shj-syn-bool{color:#79c0ff}.dark .shj-syn-str{color:#a5d6ff}.dark .shj-syn-func{color:#d2a8ff}.dark .shj-syn-insert{color:#98c379}.dark .shj-syn-deleted{color:#ff7b72}.dark .shj-syn-esc{color:#79c0ff}@property --tw-space-y-reverse{syntax:\"*\";inherits:false;initial-value:0}@property --tw-border-style{syntax:\"*\";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:\"*\";inherits:false}@property --tw-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:\"*\";inherits:false}@property --tw-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:\"*\";inherits:false}@property --tw-inset-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:\"*\";inherits:false}@property --tw-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:\"*\";inherits:false}@property --tw-inset-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:\"*\";inherits:false}@property --tw-ring-offset-width{syntax:\"<length>\";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:\"*\";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}</style>\n <script type=\"module\" crossorigin src=\"/assets/index-BC9qhYL0.js\"><\/script>\n </head>\n <body class=\"h-screen flex flex-col bg-white text-gray-900 dark:bg-gray-950 dark:text-gray-200\">\n <!-- Header -->\n <header\n class=\"flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-gray-800\"\n >\n <img src=\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMDAgMjAwIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+CiAgPCEtLSBCb2R5OiByb3VuZGVkIHJlY3RhbmdsZSAoZG9jdW1lbnQgc2hhcGUpIC0tPgogIDxyZWN0IHg9IjQwIiB5PSIzMCIgd2lkdGg9IjEyMCIgaGVpZ2h0PSIxNTAiIHJ4PSIxOCIgcnk9IjE4IiBmaWxsPSIjMkIyRDQyIi8+CgogIDwhLS0gRG9jdW1lbnQgbGluZXMgKG1hcmtkb3duIGZlZWwpIC0tPgogIDxyZWN0IHg9IjYyIiB5PSI3MCIgd2lkdGg9IjUwIiBoZWlnaHQ9IjYiIHJ4PSIzIiBmaWxsPSIjOEQ5OUFFIi8+CiAgPHJlY3QgeD0iNjIiIHk9Ijg2IiB3aWR0aD0iNzYiIGhlaWdodD0iNiIgcng9IjMiIGZpbGw9IiM4RDk5QUUiLz4KICA8cmVjdCB4PSI2MiIgeT0iMTAyIiB3aWR0aD0iNjIiIGhlaWdodD0iNiIgcng9IjMiIGZpbGw9IiM4RDk5QUUiLz4KICA8cmVjdCB4PSI2MiIgeT0iMTE4IiB3aWR0aD0iNzAiIGhlaWdodD0iNiIgcng9IjMiIGZpbGw9IiM4RDk5QUUiLz4KICA8cmVjdCB4PSI2MiIgeT0iMTM0IiB3aWR0aD0iNDAiIGhlaWdodD0iNiIgcng9IjMiIGZpbGw9IiM4RDk5QUUiLz4KCiAgPCEtLSBIZWFkaW5nIGhhc2ggbWFyayAobWFya2Rvd24gIykgLS0+CiAgPHRleHQgeD0iNjIiIHk9IjYwIiBmb250LWZhbWlseT0ibW9ub3NwYWNlIiBmb250LXdlaWdodD0iYm9sZCIgZm9udC1zaXplPSIxOCIgZmlsbD0iI0VERjJGNCI+IzwvdGV4dD4KCiAgPCEtLSBFeWVzIC0tPgogIDxjaXJjbGUgY3g9Ijc4IiBjeT0iMTcyIiByPSI1IiBmaWxsPSIjRUYyMzNDIi8+CiAgPGNpcmNsZSBjeD0iMTIyIiBjeT0iMTcyIiByPSI1IiBmaWxsPSIjRUYyMzNDIi8+CgogIDwhLS0gVGVldGggKHppbGxhIGJpdGUgb24gYm90dG9tKSAtLT4KICA8cG9seWdvbiBwb2ludHM9IjY4LDE4MCA3NCwxOTIgODAsMTgwIiBmaWxsPSIjRURGMkY0Ii8+CiAgPHBvbHlnb24gcG9pbnRzPSI4OCwxODAgOTQsMTkyIDEwMCwxODAiIGZpbGw9IiNFREYyRjQiLz4KICA8cG9seWdvbiBwb2ludHM9IjEwOCwxODAgMTE0LDE5MiAxMjAsMTgwIiBmaWxsPSIjRURGMkY0Ii8+CiAgPHBvbHlnb24gcG9pbnRzPSIxMjgsMTgwIDEzNCwxOTIgMTQwLDE4MCIgZmlsbD0iI0VERjJGNCIvPgoKICA8IS0tIFNwaWtlcyBvbiB0b3AgKHppbGxhIGhvcm5zKSAtLT4KICA8cG9seWdvbiBwb2ludHM9IjcwLDMwIDc4LDEwIDg2LDMwIiBmaWxsPSIjMkIyRDQyIi8+CiAgPHBvbHlnb24gcG9pbnRzPSI5MiwzMCAxMDAsNiAxMDgsMzAiIGZpbGw9IiMyQjJENDIiLz4KICA8cG9seWdvbiBwb2ludHM9IjExNCwzMCAxMjIsMTAgMTMwLDMwIiBmaWxsPSIjMkIyRDQyIi8+Cjwvc3ZnPgo=\" alt=\"mdzilla\" class=\"h-8\" />\n <div class=\"flex items-center gap-3\">\n <button\n id=\"search-trigger\"\n type=\"button\"\n class=\"flex items-center gap-2 w-56 px-3 py-1.5 text-sm border rounded-md bg-white text-gray-400 border-gray-200 hover:border-gray-300 hover:text-gray-500 dark:bg-gray-900 dark:text-gray-500 dark:border-gray-700 dark:hover:border-gray-600 dark:hover:text-gray-400 transition-colors cursor-pointer\"\n >\n <svg\n class=\"size-4 shrink-0\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n d=\"m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z\"\n />\n </svg>\n <span class=\"flex-1 text-left\">Search…</span>\n <kbd\n class=\"hidden sm:inline text-xs text-gray-400 dark:text-gray-500 border border-gray-200 dark:border-gray-700 rounded px-1.5 py-0.5\"\n >⌘K</kbd\n >\n </button>\n <button\n id=\"theme-toggle\"\n type=\"button\"\n class=\"p-1.5 rounded-md text-gray-500 hover:text-gray-900 hover:bg-gray-100 dark:text-gray-400 dark:hover:text-gray-100 dark:hover:bg-gray-800 transition-colors\"\n title=\"Toggle theme\"\n >\n <svg\n id=\"icon-sun\"\n class=\"hidden size-5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n d=\"M12 3v2.25m6.364.386-1.591 1.591M21 12h-2.25m-.386 6.364-1.591-1.591M12 18.75V21m-4.773-4.227-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0Z\"\n />\n </svg>\n <svg\n id=\"icon-moon\"\n class=\"hidden size-5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n d=\"M21.752 15.002A9.72 9.72 0 0 1 18 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 0 0 3 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 0 0 9.002-5.998Z\"\n />\n </svg>\n </button>\n </div>\n </header>\n\n <!-- Main layout -->\n <div class=\"flex flex-1 overflow-hidden\">\n <!-- Sidebar -->\n <nav\n id=\"sidebar\"\n class=\"w-64 shrink-0 overflow-y-auto border-r border-gray-200 dark:border-gray-800 p-3\"\n ></nav>\n\n <!-- Content -->\n <main id=\"content\" class=\"flex-1 overflow-y-auto p-8\"></main>\n </div>\n\n <!-- Search modal -->\n <div id=\"search-modal\" class=\"hidden fixed inset-0 z-50\">\n <div id=\"search-backdrop\" class=\"absolute inset-0 bg-black/50\"></div>\n <div class=\"relative flex justify-center pt-[15vh] px-4\">\n <div\n class=\"w-full max-w-lg bg-white dark:bg-gray-900 rounded-xl border border-gray-200 dark:border-gray-700 shadow-2xl overflow-hidden\"\n >\n <div\n class=\"flex items-center gap-3 px-4 py-3 border-b border-gray-200 dark:border-gray-700\"\n >\n <svg\n class=\"size-5 text-gray-400 shrink-0\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n d=\"m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z\"\n />\n </svg>\n <input\n id=\"search-input\"\n type=\"text\"\n placeholder=\"Search documentation…\"\n class=\"flex-1 bg-transparent text-sm text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500 focus:outline-none\"\n />\n <kbd\n class=\"text-xs text-gray-400 dark:text-gray-500 border border-gray-200 dark:border-gray-700 rounded px-1.5 py-0.5\"\n >esc</kbd\n >\n </div>\n <div id=\"search-results\" class=\"max-h-80 overflow-y-auto\">\n <p class=\"px-4 py-8 text-sm text-gray-400 text-center\">Type to search…</p>\n </div>\n </div>\n </div>\n </div>\n\n </body>\n</html>\n", { headers: { "content-type": "text/html; charset=utf-8" } });
1720
+ }));
1721
+ var renderer_template_exports = /* @__PURE__ */ __exportAll({ default: () => renderIndexHTML });
1722
+ function renderIndexHTML(event) {
1723
+ return rendererTemplate(event.req);
1724
+ }
1725
+ var init_renderer_template = __esmMin((() => {
1726
+ init_renderer_template$1();
1727
+ }));
1728
+ init_node();
1729
+ var findRouteRules = /* @__PURE__ */ (() => {
1730
+ const $0 = [{
1731
+ name: "headers",
1732
+ route: "/assets/**",
1733
+ handler: headers,
1734
+ options: { "cache-control": "public, max-age=31536000, immutable" }
1735
+ }];
1736
+ return (m, p) => {
1737
+ let r = [];
1738
+ if (p.charCodeAt(p.length - 1) === 47) p = p.slice(0, -1) || "/";
1739
+ let s = p.split("/");
1740
+ if (s.length > 1) {
1741
+ if (s[1] === "assets") r.unshift({
1742
+ data: $0,
1743
+ params: { "_": s.slice(2).join("/") }
1744
+ });
1745
+ }
1746
+ return r;
1747
+ };
1748
+ })();
1749
+ var _lazy_uz2lcy = defineLazyEventHandler(() => Promise.resolve().then(() => (init_meta(), meta_exports)));
1750
+ var _lazy_VBrP_m = defineLazyEventHandler(() => init_page().then(() => page_exports));
1751
+ var _lazy_hRSBx2 = defineLazyEventHandler(() => Promise.resolve().then(() => (init_search(), search_exports)));
1752
+ var _lazy_KzK1H2 = defineLazyEventHandler(() => Promise.resolve().then(() => (init_renderer_template(), renderer_template_exports)));
1753
+ var findRoute = /* @__PURE__ */ (() => {
1754
+ const $0 = {
1755
+ route: "/api/meta",
1756
+ handler: _lazy_uz2lcy
1757
+ }, $1 = {
1758
+ route: "/api/page",
1759
+ handler: _lazy_VBrP_m
1760
+ }, $2 = {
1761
+ route: "/api/search",
1762
+ handler: _lazy_hRSBx2
1763
+ }, $3 = {
1764
+ route: "/**",
1765
+ handler: _lazy_KzK1H2
1766
+ };
1767
+ return (m, p) => {
1768
+ if (p.charCodeAt(p.length - 1) === 47) p = p.slice(0, -1) || "/";
1769
+ if (p === "/api/meta") return { data: $0 };
1770
+ else if (p === "/api/page") return { data: $1 };
1771
+ else if (p === "/api/search") return { data: $2 };
1772
+ let s = p.split("/");
1773
+ s.length;
1774
+ return {
1775
+ data: $3,
1776
+ params: { "_": s.slice(1).join("/") }
1777
+ };
1778
+ };
1779
+ })();
1780
+ var globalMiddleware = [toEventHandler(static_default)].filter(Boolean);
1781
+ init_node();
1782
+ var APP_ID = "default";
1783
+ function useNitroApp() {
1784
+ let instance = useNitroApp._instance;
1785
+ if (instance) return instance;
1786
+ instance = useNitroApp._instance = createNitroApp();
1787
+ globalThis.__nitro__ = globalThis.__nitro__ || {};
1788
+ globalThis.__nitro__[APP_ID] = instance;
1789
+ return instance;
1790
+ }
1791
+ function createNitroApp() {
1792
+ const hooks = void 0;
1793
+ const captureError = (error, errorCtx) => {
1794
+ if (errorCtx?.event) {
1795
+ const errors = errorCtx.event.req.context?.nitro?.errors;
1796
+ if (errors) errors.push({
1797
+ error,
1798
+ context: errorCtx
1799
+ });
1800
+ }
1801
+ };
1802
+ const h3App = createH3App({ onError(error, event) {
1803
+ return error_handler_default(error, event);
1804
+ } });
1805
+ let appHandler = (req) => {
1806
+ req.context ||= {};
1807
+ req.context.nitro = req.context.nitro || { errors: [] };
1808
+ return h3App.fetch(req);
1809
+ };
1810
+ return {
1811
+ fetch: appHandler,
1812
+ h3: h3App,
1813
+ hooks,
1814
+ captureError
1815
+ };
1816
+ }
1817
+ function createH3App(config) {
1818
+ const h3App = new H3Core(config);
1819
+ h3App["~findRoute"] = (event) => findRoute(event.req.method, event.url.pathname);
1820
+ h3App["~middleware"].push(...globalMiddleware);
1821
+ h3App["~getMiddleware"] = (event, route) => {
1822
+ const pathname = event.url.pathname;
1823
+ const method = event.req.method;
1824
+ const middleware = [];
1825
+ {
1826
+ const routeRules = getRouteRules(method, pathname);
1827
+ event.context.routeRules = routeRules?.routeRules;
1828
+ if (routeRules?.routeRuleMiddleware.length) middleware.push(...routeRules.routeRuleMiddleware);
1829
+ }
1830
+ middleware.push(...h3App["~middleware"]);
1831
+ if (route?.data?.middleware?.length) middleware.push(...route.data.middleware);
1832
+ return middleware;
1833
+ };
1834
+ return h3App;
1835
+ }
1836
+ function getRouteRules(method, pathname) {
1837
+ const m = findRouteRules(method, pathname);
1838
+ if (!m?.length) return { routeRuleMiddleware: [] };
1839
+ const routeRules = {};
1840
+ for (const layer of m) for (const rule of layer.data) {
1841
+ const currentRule = routeRules[rule.name];
1842
+ if (currentRule) {
1843
+ if (rule.options === false) {
1844
+ delete routeRules[rule.name];
1845
+ continue;
1846
+ }
1847
+ if (typeof currentRule.options === "object" && typeof rule.options === "object") currentRule.options = {
1848
+ ...currentRule.options,
1849
+ ...rule.options
1850
+ };
1851
+ else currentRule.options = rule.options;
1852
+ currentRule.route = rule.route;
1853
+ currentRule.params = {
1854
+ ...currentRule.params,
1855
+ ...layer.params
1856
+ };
1857
+ } else if (rule.options !== false) routeRules[rule.name] = {
1858
+ ...rule,
1859
+ params: layer.params
1860
+ };
1861
+ }
1862
+ const middleware = [];
1863
+ for (const rule of Object.values(routeRules)) {
1864
+ if (rule.options === false || !rule.handler) continue;
1865
+ middleware.push(rule.handler(rule));
1866
+ }
1867
+ return {
1868
+ routeRules,
1869
+ routeRuleMiddleware: middleware
1870
+ };
1871
+ }
1872
+ init_docs();
1873
+ async function createDocsServer(initOpts) {
1874
+ const nitroApp = useNitroApp();
1875
+ const docs = await useDocs(initOpts);
1876
+ return {
1877
+ fetch: nitroApp.fetch,
1878
+ docs
1879
+ };
1880
+ }
1881
+ //#endregion
1882
+ export { createDocsServer };