@farm.js/core 0.1.0-beta.11 → 0.1.0-beta.14

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.
Files changed (238) hide show
  1. package/dist/chunk-53MVSX3R.mjs +168 -0
  2. package/dist/chunk-53MVSX3R.mjs.map +1 -0
  3. package/dist/{chunk-AW6I64AP.mjs → chunk-6ZXIQSXE.mjs} +16 -1
  4. package/dist/chunk-6ZXIQSXE.mjs.map +1 -0
  5. package/dist/chunk-7ZVN3YZI.mjs +333 -0
  6. package/dist/chunk-7ZVN3YZI.mjs.map +1 -0
  7. package/dist/{chunk-5EVQFRL2.mjs → chunk-ARCGE2VT.mjs} +2 -2
  8. package/dist/chunk-ARCGE2VT.mjs.map +1 -0
  9. package/dist/{chunk-7N62DNSO.mjs → chunk-H3TE3LOV.mjs} +2 -2
  10. package/dist/{chunk-QTZZ2ISQ.mjs → chunk-KLA67WKG.mjs} +1 -1
  11. package/dist/chunk-KLA67WKG.mjs.map +1 -0
  12. package/dist/{chunk-K5ZTUF22.mjs → chunk-L2PE36GQ.mjs} +7 -3
  13. package/dist/chunk-L2PE36GQ.mjs.map +1 -0
  14. package/dist/{chunk-4LND3PXF.mjs → chunk-OPHK6OJN.mjs} +513 -48
  15. package/dist/chunk-OPHK6OJN.mjs.map +1 -0
  16. package/dist/{chunk-77BOAQHI.mjs → chunk-PNFQQSRA.mjs} +754 -156
  17. package/dist/chunk-PNFQQSRA.mjs.map +1 -0
  18. package/dist/chunk-USLFXFFH.mjs +46 -0
  19. package/dist/chunk-USLFXFFH.mjs.map +1 -0
  20. package/dist/{chunk-4677KXB7.mjs → chunk-VUL55IAX.mjs} +368 -103
  21. package/dist/chunk-VUL55IAX.mjs.map +1 -0
  22. package/dist/client.cjs.map +1 -1
  23. package/dist/client.mjs +1 -1
  24. package/dist/{devtools-A22KUJZT.mjs → devtools-GAZ7F3KL.mjs} +4 -3
  25. package/dist/{devtools-A22KUJZT.mjs.map → devtools-GAZ7F3KL.mjs.map} +1 -1
  26. package/dist/docs.cjs +622 -124
  27. package/dist/docs.cjs.map +1 -1
  28. package/dist/docs.mjs +5 -3
  29. package/dist/font.cjs +19 -2
  30. package/dist/font.cjs.map +1 -1
  31. package/dist/font.mjs +7 -3
  32. package/dist/index.cjs +2235 -689
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.mjs +27 -19
  35. package/dist/index.mjs.map +1 -1
  36. package/dist/internal/build-runtime.cjs +2062 -525
  37. package/dist/internal/build-runtime.cjs.map +1 -1
  38. package/dist/internal/build-runtime.mjs +13 -10
  39. package/dist/internal/client-runtime.cjs +169 -2
  40. package/dist/internal/client-runtime.cjs.map +1 -1
  41. package/dist/internal/client-runtime.mjs +170 -2
  42. package/dist/internal/client-runtime.mjs.map +1 -1
  43. package/dist/internal/config-runtime.cjs +22 -0
  44. package/dist/internal/config-runtime.cjs.map +1 -1
  45. package/dist/internal/config-runtime.mjs +3 -2
  46. package/dist/internal/metadata-image-runtime.cjs +199 -0
  47. package/dist/internal/metadata-image-runtime.cjs.map +1 -0
  48. package/dist/internal/metadata-image-runtime.mjs +8 -0
  49. package/dist/internal/metadata-image-runtime.mjs.map +1 -0
  50. package/dist/internal/production-runtime.cjs +310 -0
  51. package/dist/internal/production-runtime.cjs.map +1 -1
  52. package/dist/internal/production-runtime.mjs +10 -0
  53. package/dist/internal/production-runtime.mjs.map +1 -1
  54. package/dist/navigation.cjs.map +1 -1
  55. package/dist/navigation.mjs +2 -2
  56. package/dist/plugin.cjs +1550 -348
  57. package/dist/plugin.cjs.map +1 -1
  58. package/dist/plugin.mjs +9 -5
  59. package/dist/server.cjs +1663 -419
  60. package/dist/server.cjs.map +1 -1
  61. package/dist/server.mjs +17 -19
  62. package/dist/server.mjs.map +1 -1
  63. package/dist/version.cjs +1 -1
  64. package/dist/version.cjs.map +1 -1
  65. package/dist/version.mjs +1 -1
  66. package/dist/vite.cjs +1604 -358
  67. package/dist/vite.cjs.map +1 -1
  68. package/dist/vite.mjs +9 -5
  69. package/package.json +10 -1
  70. package/types/client.d.ts +115 -4
  71. package/dist/after.d.mts +0 -25
  72. package/dist/after.d.ts +0 -25
  73. package/dist/agent-runtime.d.mts +0 -94
  74. package/dist/agent-runtime.d.ts +0 -94
  75. package/dist/api/route-manager.d.mts +0 -66
  76. package/dist/api/route-manager.d.ts +0 -66
  77. package/dist/api/runtime.d.mts +0 -3
  78. package/dist/api/runtime.d.ts +0 -3
  79. package/dist/api.d.mts +0 -48
  80. package/dist/api.d.ts +0 -48
  81. package/dist/app-BNE2FoZ4.d.mts +0 -302
  82. package/dist/app-DRGUmJ3s.d.ts +0 -302
  83. package/dist/app-markdown.d.mts +0 -22
  84. package/dist/app-markdown.d.ts +0 -22
  85. package/dist/cache.d.mts +0 -192
  86. package/dist/cache.d.ts +0 -192
  87. package/dist/chunk-4677KXB7.mjs.map +0 -1
  88. package/dist/chunk-4LND3PXF.mjs.map +0 -1
  89. package/dist/chunk-5EVQFRL2.mjs.map +0 -1
  90. package/dist/chunk-77BOAQHI.mjs.map +0 -1
  91. package/dist/chunk-AW6I64AP.mjs.map +0 -1
  92. package/dist/chunk-K5ZTUF22.mjs.map +0 -1
  93. package/dist/chunk-QM746KUO.mjs +0 -56
  94. package/dist/chunk-QM746KUO.mjs.map +0 -1
  95. package/dist/chunk-QTZZ2ISQ.mjs.map +0 -1
  96. package/dist/client-BT1mFQas.d.mts +0 -447
  97. package/dist/client-Nn0q4eO4.d.ts +0 -447
  98. package/dist/client-cache-CIlyBlmx.d.ts +0 -6
  99. package/dist/client-cache-D-EZ7XVW.d.mts +0 -6
  100. package/dist/client-plugins-Bc5jHcNr.d.ts +0 -1927
  101. package/dist/client-plugins-jsk-ZLzJ.d.mts +0 -1927
  102. package/dist/client-plugins.d.mts +0 -22
  103. package/dist/client-plugins.d.ts +0 -22
  104. package/dist/client.d.mts +0 -447
  105. package/dist/client.d.ts +0 -447
  106. package/dist/config.d.mts +0 -29
  107. package/dist/config.d.ts +0 -29
  108. package/dist/cron.d.mts +0 -78
  109. package/dist/cron.d.ts +0 -78
  110. package/dist/deferred.d.mts +0 -42
  111. package/dist/deferred.d.ts +0 -42
  112. package/dist/deployment.d.mts +0 -34
  113. package/dist/deployment.d.ts +0 -34
  114. package/dist/docs.d.mts +0 -69
  115. package/dist/docs.d.ts +0 -69
  116. package/dist/env-types.d.mts +0 -12
  117. package/dist/env-types.d.ts +0 -12
  118. package/dist/env.d.mts +0 -45
  119. package/dist/env.d.ts +0 -45
  120. package/dist/environment/vite.d.mts +0 -22
  121. package/dist/environment/vite.d.ts +0 -22
  122. package/dist/environment.d.mts +0 -18
  123. package/dist/environment.d.ts +0 -18
  124. package/dist/font.d.mts +0 -70
  125. package/dist/font.d.ts +0 -70
  126. package/dist/headers.d.mts +0 -22
  127. package/dist/headers.d.ts +0 -22
  128. package/dist/i18n/client.d.mts +0 -32
  129. package/dist/i18n/client.d.ts +0 -32
  130. package/dist/i18n/index.d.mts +0 -20
  131. package/dist/i18n/index.d.ts +0 -20
  132. package/dist/i18n/server.d.mts +0 -30
  133. package/dist/i18n/server.d.ts +0 -30
  134. package/dist/image/server.d.mts +0 -37
  135. package/dist/image/server.d.ts +0 -37
  136. package/dist/image/sharp.d.mts +0 -7
  137. package/dist/image/sharp.d.ts +0 -7
  138. package/dist/image-config-Duob7wER.d.mts +0 -50
  139. package/dist/image-config-Duob7wER.d.ts +0 -50
  140. package/dist/image.d.mts +0 -39
  141. package/dist/image.d.ts +0 -39
  142. package/dist/index.d.mts +0 -455
  143. package/dist/index.d.ts +0 -455
  144. package/dist/integration-api-CHT2OKAf.d.mts +0 -93
  145. package/dist/integration-api-CHT2OKAf.d.ts +0 -93
  146. package/dist/integrations.d.mts +0 -22
  147. package/dist/integrations.d.ts +0 -22
  148. package/dist/internal/build-runtime.d.mts +0 -39
  149. package/dist/internal/build-runtime.d.ts +0 -39
  150. package/dist/internal/client-runtime.d.mts +0 -2
  151. package/dist/internal/client-runtime.d.ts +0 -2
  152. package/dist/internal/config-runtime.d.mts +0 -39
  153. package/dist/internal/config-runtime.d.ts +0 -39
  154. package/dist/internal/production-node-env.d.mts +0 -12
  155. package/dist/internal/production-node-env.d.ts +0 -12
  156. package/dist/internal/production-runtime.d.mts +0 -41
  157. package/dist/internal/production-runtime.d.ts +0 -41
  158. package/dist/markdown.d.mts +0 -60
  159. package/dist/markdown.d.ts +0 -60
  160. package/dist/metadata-7ffpT3jr.d.mts +0 -22
  161. package/dist/metadata-JHn-8eht.d.ts +0 -22
  162. package/dist/middleware.d.mts +0 -164
  163. package/dist/middleware.d.ts +0 -164
  164. package/dist/navigation-errors-Dvwpzaer.d.mts +0 -13
  165. package/dist/navigation-errors-Dvwpzaer.d.ts +0 -13
  166. package/dist/navigation.d.mts +0 -14
  167. package/dist/navigation.d.ts +0 -14
  168. package/dist/observability.d.mts +0 -335
  169. package/dist/observability.d.ts +0 -335
  170. package/dist/params-BALtrRim.d.ts +0 -15
  171. package/dist/params-ry-lxqmy.d.mts +0 -15
  172. package/dist/plugin-BJDf43dc.d.mts +0 -165
  173. package/dist/plugin-BJDf43dc.d.ts +0 -165
  174. package/dist/plugin.d.mts +0 -22
  175. package/dist/plugin.d.ts +0 -22
  176. package/dist/production-runtime-9KG7GuvW.d.ts +0 -79
  177. package/dist/production-runtime-B-fweKts.d.mts +0 -79
  178. package/dist/production-runtime-C_B79w2P.d.mts +0 -28
  179. package/dist/production-runtime-DDEM1D2q.d.ts +0 -28
  180. package/dist/query/client.d.mts +0 -61
  181. package/dist/query/client.d.ts +0 -61
  182. package/dist/query/index.d.mts +0 -90
  183. package/dist/query/index.d.ts +0 -90
  184. package/dist/query/parsers.d.mts +0 -25
  185. package/dist/query/parsers.d.ts +0 -25
  186. package/dist/query/server.d.mts +0 -55
  187. package/dist/query/server.d.ts +0 -55
  188. package/dist/request-Dsq4kGW0.d.mts +0 -6
  189. package/dist/request-udtobOLv.d.ts +0 -6
  190. package/dist/request.d.mts +0 -2
  191. package/dist/request.d.ts +0 -2
  192. package/dist/resolver-DJqjLMg_.d.mts +0 -14
  193. package/dist/resolver-IH4RmPEl.d.ts +0 -14
  194. package/dist/route-runtime-DoOHzCAD.d.mts +0 -38
  195. package/dist/route-runtime-DoOHzCAD.d.ts +0 -38
  196. package/dist/router.d.mts +0 -36
  197. package/dist/router.d.ts +0 -36
  198. package/dist/routes.d.mts +0 -224
  199. package/dist/routes.d.ts +0 -224
  200. package/dist/runtime-9nQjVM7X.d.mts +0 -206
  201. package/dist/runtime-Cxpq6xZN.d.mts +0 -27
  202. package/dist/runtime-DgeS2skB.d.ts +0 -206
  203. package/dist/runtime-bv63eUiO.d.ts +0 -27
  204. package/dist/server-action-security.d.mts +0 -43
  205. package/dist/server-action-security.d.ts +0 -43
  206. package/dist/server-fn-client.d.mts +0 -32
  207. package/dist/server-fn-client.d.ts +0 -32
  208. package/dist/server-fn.d.mts +0 -93
  209. package/dist/server-fn.d.ts +0 -93
  210. package/dist/server-plugins.d.mts +0 -55
  211. package/dist/server-plugins.d.ts +0 -55
  212. package/dist/server-query-client.d.mts +0 -50
  213. package/dist/server-query-client.d.ts +0 -50
  214. package/dist/server-query.d.mts +0 -36
  215. package/dist/server-query.d.ts +0 -36
  216. package/dist/server.d.mts +0 -48
  217. package/dist/server.d.ts +0 -48
  218. package/dist/storage.d.mts +0 -52
  219. package/dist/storage.d.ts +0 -52
  220. package/dist/testing.d.mts +0 -101
  221. package/dist/testing.d.ts +0 -101
  222. package/dist/transport-BmbGTXA5.d.mts +0 -49
  223. package/dist/transport-BmbGTXA5.d.ts +0 -49
  224. package/dist/types-BMxWr97v.d.mts +0 -81
  225. package/dist/types-BMxWr97v.d.ts +0 -81
  226. package/dist/types-C9N-nk5R.d.mts +0 -53
  227. package/dist/types-C9N-nk5R.d.ts +0 -53
  228. package/dist/types-D1A6-XvH.d.mts +0 -73
  229. package/dist/types-D1A6-XvH.d.ts +0 -73
  230. package/dist/utils-CA0z0c-2.d.ts +0 -23
  231. package/dist/utils-mYVkSOt2.d.mts +0 -23
  232. package/dist/version.d.mts +0 -3
  233. package/dist/version.d.ts +0 -3
  234. package/dist/vite.d.mts +0 -22
  235. package/dist/vite.d.ts +0 -22
  236. package/dist/workflows.d.mts +0 -110
  237. package/dist/workflows.d.ts +0 -110
  238. /package/dist/{chunk-7N62DNSO.mjs.map → chunk-H3TE3LOV.mjs.map} +0 -0
@@ -4,7 +4,11 @@ import {
4
4
  } from "./chunk-V7RBCSDJ.mjs";
5
5
  import {
6
6
  resolveDocsConfig
7
- } from "./chunk-K5ZTUF22.mjs";
7
+ } from "./chunk-L2PE36GQ.mjs";
8
+ import {
9
+ resolveFarmDocsFontAssets,
10
+ toFarmDocsPublicFontAssets
11
+ } from "./chunk-USLFXFFH.mjs";
8
12
  import {
9
13
  __name
10
14
  } from "./chunk-CGILA3WO.mjs";
@@ -224,8 +228,8 @@ var farmDocsPixelBorderCss = String.raw`
224
228
  --scrollbar-thumb-hover: var(--color-fd-ring);
225
229
  --scrollbar-track: transparent;
226
230
  --radius: 0px;
227
- --font-geist-sans: "Geist Sans";
228
- --font-geist-mono: "Geist Mono";
231
+ --font-geist-sans: ui-sans-serif, system-ui, sans-serif;
232
+ --font-geist-mono: ui-monospace, monospace;
229
233
  }
230
234
 
231
235
  .dark {
@@ -238,28 +242,6 @@ body,
238
242
  background-color: var(--color-fd-background) !important;
239
243
  }
240
244
 
241
- @font-face {
242
- font-family: "Geist Sans";
243
- font-display: block;
244
- font-style: normal;
245
- font-weight: 100 900;
246
- src:
247
- local("Geist Sans"),
248
- url("/assets/Geist-Variable-CrgPqtmy.woff2") format("woff2"),
249
- url("/node_modules/geist/dist/fonts/geist-sans/Geist-Variable.woff2") format("woff2");
250
- }
251
-
252
- @font-face {
253
- font-family: "Geist Mono";
254
- font-display: block;
255
- font-style: normal;
256
- font-weight: 100 900;
257
- src:
258
- local("Geist Mono"),
259
- url("/assets/GeistMono-Variable-BNLlm6Cd.woff2") format("woff2"),
260
- url("/node_modules/geist/dist/fonts/geist-mono/GeistMono-Variable.woff2") format("woff2");
261
- }
262
-
263
245
  * {
264
246
  scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
265
247
  scrollbar-width: thin;
@@ -1448,22 +1430,421 @@ code:not(pre code) {
1448
1430
  }
1449
1431
  `;
1450
1432
 
1433
+ // src/docs/social-image.ts
1434
+ import { createHash } from "crypto";
1435
+ var FARM_DOCS_SOCIAL_IMAGE_WIDTH = 1200;
1436
+ var FARM_DOCS_SOCIAL_IMAGE_HEIGHT = 630;
1437
+ var FARM_DOCS_SOCIAL_IMAGE_VERSION = 3;
1438
+ function normalizeEntry(entry) {
1439
+ if (!entry || entry === "/") return "";
1440
+ return `/${entry.replace(/^\/+|\/+$/g, "")}`;
1441
+ }
1442
+ __name(normalizeEntry, "normalizeEntry");
1443
+ function encodeSlugPath(slug) {
1444
+ return slug.split("/").filter(Boolean).map((segment) => encodeURIComponent(segment)).join("/");
1445
+ }
1446
+ __name(encodeSlugPath, "encodeSlugPath");
1447
+ function getSocialImageConfig(docs) {
1448
+ return typeof docs.config.socialImage === "object" && docs.config.socialImage ? docs.config.socialImage : void 0;
1449
+ }
1450
+ __name(getSocialImageConfig, "getSocialImageConfig");
1451
+ function getNavTitle(docs) {
1452
+ if (typeof docs.config.nav !== "object" || !docs.config.nav || !("title" in docs.config.nav)) {
1453
+ return "Farm.js";
1454
+ }
1455
+ return String(docs.config.nav.title || "Farm.js");
1456
+ }
1457
+ __name(getNavTitle, "getNavTitle");
1458
+ function isFalse(value) {
1459
+ return value ? /^(false|no|none|off|disabled)$/i.test(value.trim()) : false;
1460
+ }
1461
+ __name(isFalse, "isFalse");
1462
+ function isExternalOrRootPath(value) {
1463
+ return /^(https?:)?\/\//i.test(value) || value.startsWith("/");
1464
+ }
1465
+ __name(isExternalOrRootPath, "isExternalOrRootPath");
1466
+ function isFarmDocsSocialImageEnabled(page, docs) {
1467
+ if (docs.config.socialImage === false || getSocialImageConfig(docs)?.enabled === false) {
1468
+ return false;
1469
+ }
1470
+ return !isFalse(page.frontmatter.socialImage);
1471
+ }
1472
+ __name(isFarmDocsSocialImageEnabled, "isFarmDocsSocialImageEnabled");
1473
+ function getFarmDocsCustomSocialImage(page) {
1474
+ const value = page.frontmatter.socialImage || page.frontmatter.openGraphImage || page.frontmatter.ogImage;
1475
+ return value && !isFalse(value) && isExternalOrRootPath(value) ? value : void 0;
1476
+ }
1477
+ __name(getFarmDocsCustomSocialImage, "getFarmDocsCustomSocialImage");
1478
+ function resolveIllustration(page) {
1479
+ const explicit = page.frontmatter.socialIllustration?.toLowerCase();
1480
+ if (explicit === "auth" || explicit === "cache" || explicit === "cli" || explicit === "integrations" || explicit === "project" || explicit === "routing" || explicit === "runtime") {
1481
+ return explicit;
1482
+ }
1483
+ const source = `${page.slug} ${page.title} ${page.section || ""}`.toLowerCase();
1484
+ if (/auth|session|security|csrf/.test(source)) return "auth";
1485
+ if (/cache|ppr|render|static|revalid|stream/.test(source)) return "cache";
1486
+ if (/integration|stripe|prisma|better.auth|email|job|workflow/.test(source)) {
1487
+ return "integrations";
1488
+ }
1489
+ if (/cli|test|deploy|preview|upgrade|migration|install/.test(source)) return "cli";
1490
+ if (/project|structure|config|environment|markdown|docs.engine/.test(source)) {
1491
+ return "project";
1492
+ }
1493
+ if (/rout|endpoint|middleware|navigation|server.function|server.action|api/.test(source)) {
1494
+ return "routing";
1495
+ }
1496
+ return "runtime";
1497
+ }
1498
+ __name(resolveIllustration, "resolveIllustration");
1499
+ function createHashValue(value) {
1500
+ return createHash("sha256").update(JSON.stringify(value)).digest("hex").slice(0, 16);
1501
+ }
1502
+ __name(createHashValue, "createHashValue");
1503
+ function resolveBaseUrl(requestUrl, config) {
1504
+ return config?.baseUrl ? new URL(config.baseUrl) : new URL(requestUrl.origin);
1505
+ }
1506
+ __name(resolveBaseUrl, "resolveBaseUrl");
1507
+ function createFarmDocsSocialImageDescriptor(page, docs, requestUrl) {
1508
+ const config = getSocialImageConfig(docs);
1509
+ const siteName = config?.siteName || getNavTitle(docs);
1510
+ const brand = config?.brand || siteName;
1511
+ const title = page.frontmatter.socialTitle || page.title;
1512
+ const description = page.frontmatter.socialDescription || page.description || docs.config.metadata?.description || `Documentation for ${siteName}`;
1513
+ const section = page.frontmatter.section || page.section || "Documentation";
1514
+ const illustration = resolveIllustration(page);
1515
+ const entry = normalizeEntry(docs.entry);
1516
+ const slugPath = encodeSlugPath(page.slug) || "index";
1517
+ const imagePath = `${entry}/_social/${slugPath}/opengraph-image.svg`;
1518
+ const baseUrl = resolveBaseUrl(requestUrl, config);
1519
+ const pageUrl = new URL(page.href, baseUrl).href;
1520
+ const imageAlt = `${title} \u2014 ${siteName} documentation`;
1521
+ const hash = createHashValue({
1522
+ version: FARM_DOCS_SOCIAL_IMAGE_VERSION,
1523
+ title,
1524
+ description,
1525
+ section,
1526
+ siteName,
1527
+ brand,
1528
+ pageHref: page.href,
1529
+ illustration,
1530
+ fonts: config?.fonts
1531
+ });
1532
+ return {
1533
+ title,
1534
+ description,
1535
+ section,
1536
+ siteName,
1537
+ brand,
1538
+ pageHref: page.href,
1539
+ pageUrl,
1540
+ imagePath,
1541
+ imageUrl: new URL(`${imagePath}?v=${hash}`, baseUrl).href,
1542
+ imageAlt,
1543
+ illustration,
1544
+ fonts: config?.fonts,
1545
+ hash
1546
+ };
1547
+ }
1548
+ __name(createFarmDocsSocialImageDescriptor, "createFarmDocsSocialImageDescriptor");
1549
+ function getFarmDocsSocialImageSlug(docs, requestUrl) {
1550
+ const entry = normalizeEntry(docs.entry);
1551
+ const prefix = `${entry}/_social/`;
1552
+ const suffix = "/opengraph-image.svg";
1553
+ if (!requestUrl.pathname.startsWith(prefix) || !requestUrl.pathname.endsWith(suffix)) {
1554
+ return null;
1555
+ }
1556
+ const rawSlug = requestUrl.pathname.slice(prefix.length, -suffix.length);
1557
+ if (!rawSlug) return null;
1558
+ try {
1559
+ const slug = rawSlug.split("/").map((segment) => decodeURIComponent(segment)).join("/");
1560
+ if (slug.split("/").some((segment) => !segment || segment === ".." || segment === ".")) {
1561
+ return null;
1562
+ }
1563
+ return slug === "index" ? "" : slug;
1564
+ } catch {
1565
+ return null;
1566
+ }
1567
+ }
1568
+ __name(getFarmDocsSocialImageSlug, "getFarmDocsSocialImageSlug");
1569
+ function escapeXml(value) {
1570
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
1571
+ }
1572
+ __name(escapeXml, "escapeXml");
1573
+ function truncate(value, length) {
1574
+ if (value.length <= length) return value;
1575
+ return `${value.slice(0, Math.max(0, length - 1)).trimEnd()}\u2026`;
1576
+ }
1577
+ __name(truncate, "truncate");
1578
+ function wrapText(value, maxCharacters, maxLines) {
1579
+ const words = value.trim().split(/\s+/).filter(Boolean);
1580
+ const lines = [];
1581
+ let current = "";
1582
+ let consumedWords = 0;
1583
+ for (const word of words) {
1584
+ const candidate = current ? `${current} ${word}` : word;
1585
+ if (candidate.length <= maxCharacters || !current) {
1586
+ current = candidate;
1587
+ consumedWords += 1;
1588
+ continue;
1589
+ }
1590
+ lines.push(current);
1591
+ if (lines.length === maxLines) break;
1592
+ current = word;
1593
+ consumedWords += 1;
1594
+ }
1595
+ if (current && lines.length < maxLines) lines.push(current);
1596
+ if (consumedWords < words.length && lines.length) {
1597
+ lines[lines.length - 1] = truncate(`${lines[lines.length - 1]}\u2026`, maxCharacters);
1598
+ }
1599
+ return lines;
1600
+ }
1601
+ __name(wrapText, "wrapText");
1602
+ function renderTextLines(lines, x, y, lineHeight, attributes) {
1603
+ return lines.map(
1604
+ (line, index) => `<text x="${x}" y="${y + index * lineHeight}" ${attributes}>${escapeXml(line)}</text>`
1605
+ ).join("");
1606
+ }
1607
+ __name(renderTextLines, "renderTextLines");
1608
+ function renderEmbeddedFont(name, source, weight) {
1609
+ if (!source) return "";
1610
+ return `@font-face{font-family:"${name}";src:url("${escapeXml(source)}") format("woff2");font-style:normal;font-weight:${weight};font-display:block;}`;
1611
+ }
1612
+ __name(renderEmbeddedFont, "renderEmbeddedFont");
1613
+ function renderArrow(x1, y, x2, color = "#8b8b8b") {
1614
+ return `<path d="M${x1} ${y}H${x2 - 9}" fill="none" stroke="${color}"/><path d="m${x2 - 9} ${y - 5} 9 5-9 5" fill="none" stroke="${color}"/>`;
1615
+ }
1616
+ __name(renderArrow, "renderArrow");
1617
+ function renderPanelHeader(label, status) {
1618
+ return `<text x="819" y="171" class="label">${escapeXml(label)}</text><text x="1134" y="171" class="label bright" text-anchor="end">${escapeXml(status)}</text>`;
1619
+ }
1620
+ __name(renderPanelHeader, "renderPanelHeader");
1621
+ function renderRoutingIllustration() {
1622
+ return `${renderPanelHeader("ROUTE BLUEPRINT", "TYPED")}
1623
+ <rect x="819" y="296" width="92" height="54" fill="#a3a3a3"/>
1624
+ <text x="832" y="327" class="diagram-title ink">src/app</text>
1625
+ <path d="M911 323h41M952 232v181M952 232h44M952 323h44M952 413h44" fill="none" stroke="#696969"/>
1626
+ <rect x="996" y="205" width="138" height="54" fill="#0a0a0a" stroke="#414141"/>
1627
+ <text x="1010" y="228" class="diagram-title">/</text><text x="1010" y="246" class="micro">STATIC</text>
1628
+ <rect x="996" y="296" width="138" height="54" fill="#0a0a0a" stroke="#414141"/>
1629
+ <text x="1010" y="319" class="diagram-title">/blog/:slug</text><text x="1010" y="337" class="micro">DYNAMIC</text>
1630
+ <rect x="996" y="386" width="138" height="55" fill="#f0f0f0"/>
1631
+ <text x="1010" y="410" class="diagram-title ink">/docs/:path*</text><text x="1010" y="428" class="micro ink-muted">CATCH-ALL</text>
1632
+ <line x1="819" y1="450" x2="1134" y2="450" stroke="#343434"/>
1633
+ <text x="819" y="475" class="label bright">FILE ROUTES</text><text x="1134" y="475" class="label" text-anchor="end">TYPES INCLUDED</text>`;
1634
+ }
1635
+ __name(renderRoutingIllustration, "renderRoutingIllustration");
1636
+ function renderAuthIllustration() {
1637
+ return `${renderPanelHeader("REQUEST GUARD", "SERVER VERIFIED")}
1638
+ <rect x="819" y="269" width="86" height="54" fill="#0a0a0a" stroke="#454545"/>
1639
+ <text x="837" y="292" class="micro bright">REQUEST</text><text x="837" y="310" class="diagram-title">GET /app</text>
1640
+ ${renderArrow(905, 296, 943)}
1641
+ <rect x="943" y="224" width="104" height="118" fill="#f0f0f0"/>
1642
+ <path d="M974 271v-12a21 21 0 0 1 42 0v12M968 271h54v45h-54z" fill="#050505"/>
1643
+ <circle cx="995" cy="292" r="4" fill="#f0f0f0"/><path d="M995 296v8" stroke="#f0f0f0" stroke-width="3"/>
1644
+ <text x="995" y="332" class="micro ink" text-anchor="middle">auth()</text>
1645
+ ${renderArrow(1047, 296, 1071)}
1646
+ <rect x="1071" y="269" width="63" height="54" fill="#0a0a0a" stroke="#454545"/>
1647
+ <text x="1082" y="292" class="micro bright">ALLOW</text><text x="1082" y="310" class="micro">/app</text>
1648
+ <rect x="819" y="372" width="315" height="38" fill="#090909" stroke="#3d3d3d"/>
1649
+ <rect x="832" y="385" width="11" height="11" fill="#a3a3a3"/>
1650
+ <text x="856" y="395" class="code">session.user / verified</text>
1651
+ <line x1="819" y1="450" x2="1134" y2="450" stroke="#343434"/>
1652
+ <text x="819" y="475" class="label bright">SESSION TYPED</text><text x="1134" y="475" class="label" text-anchor="end">CSRF PROTECTED</text>`;
1653
+ }
1654
+ __name(renderAuthIllustration, "renderAuthIllustration");
1655
+ function renderCacheIllustration() {
1656
+ return `${renderPanelHeader("PAGE / PRODUCT", "CACHE + PPR")}
1657
+ <rect x="819" y="204" width="315" height="54" fill="#f0f0f0"/>
1658
+ <text x="836" y="235" class="diagram-title ink">STATIC SHELL</text><text x="1116" y="235" class="micro ink-muted" text-anchor="end">BUILD</text>
1659
+ <rect x="819" y="271" width="198" height="76" fill="#a3a3a3"/>
1660
+ <text x="836" y="301" class="diagram-title ink">CACHED DATA</text><text x="836" y="326" class="micro ink-muted">tag: products</text>
1661
+ <rect x="1029" y="271" width="105" height="76" fill="#0a0a0a" stroke="#555"/>
1662
+ <text x="1045" y="301" class="diagram-title">LIVE</text><text x="1045" y="326" class="micro">stream</text>
1663
+ <path d="M1081 347v43m-8-9 8 9 8-9" fill="none" stroke="#d4d4d4"/>
1664
+ <line x1="819" y1="450" x2="1134" y2="450" stroke="#343434"/>
1665
+ <text x="819" y="475" class="label bright">STATIC FIRST</text><text x="1134" y="475" class="label" text-anchor="end">DYNAMIC WHERE NEEDED</text>`;
1666
+ }
1667
+ __name(renderCacheIllustration, "renderCacheIllustration");
1668
+ function renderIntegrationsIllustration() {
1669
+ return `${renderPanelHeader("INTEGRATION GRAPH", "ONE PRODUCT")}
1670
+ <path d="M976 309H879V247M976 309H879v87M1030 309h93V247M1030 309h93v87" fill="none" stroke="#4a4a4a"/>
1671
+ <rect x="819" y="214" width="120" height="57" fill="#0a0a0a" stroke="#4b4b4b"/><text x="839" y="247" class="diagram-title">BETTER AUTH</text>
1672
+ <rect x="819" y="368" width="120" height="57" fill="#0a0a0a" stroke="#4b4b4b"/><text x="851" y="401" class="diagram-title">PRISMA</text>
1673
+ <rect x="1061" y="214" width="73" height="57" fill="#0a0a0a" stroke="#4b4b4b"/><text x="1077" y="247" class="diagram-title">STRIPE</text>
1674
+ <rect x="1061" y="368" width="73" height="57" fill="#a3a3a3"/><text x="1075" y="401" class="diagram-title ink">VERCEL</text>
1675
+ <rect x="976" y="277" width="94" height="64" fill="#f0f0f0"/>
1676
+ <text x="994" y="304" class="diagram-title ink">FARM.JS</text><text x="994" y="324" class="micro ink-muted">CORE</text>
1677
+ <line x1="819" y1="450" x2="1134" y2="450" stroke="#343434"/>
1678
+ <text x="819" y="475" class="label bright">BRING YOUR STACK</text><text x="1134" y="475" class="label" text-anchor="end">CONNECTED ONCE</text>`;
1679
+ }
1680
+ __name(renderIntegrationsIllustration, "renderIntegrationsIllustration");
1681
+ function renderCliIllustration() {
1682
+ return `${renderPanelHeader("TERMINAL", "PRODUCTION OUTPUT")}
1683
+ <rect x="819" y="203" width="315" height="213" fill="#050505" stroke="#555"/>
1684
+ <line x1="819" y1="236" x2="1134" y2="236" stroke="#555"/>
1685
+ <circle cx="837" cy="220" r="4" fill="#5d5d5d"/><circle cx="850" cy="220" r="4" fill="#7a7a7a"/><circle cx="863" cy="220" r="4" fill="#a3a3a3"/>
1686
+ <text x="837" y="273" class="code bright"><tspan fill="#7a7a7a">$</tspan> farm build</text>
1687
+ <rect x="837" y="293" width="11" height="11" fill="#a3a3a3"/><path d="m839 298 3 3 6-7" fill="none" stroke="#050505" stroke-width="1.5"/>
1688
+ <text x="861" y="303" class="code">64 routes discovered</text>
1689
+ <rect x="837" y="320" width="11" height="11" fill="#a3a3a3"/><path d="m839 325 3 3 6-7" fill="none" stroke="#050505" stroke-width="1.5"/>
1690
+ <text x="861" y="330" class="code">client + server bundles</text>
1691
+ <rect x="837" y="355" width="126" height="30" fill="#f0f0f0"/><text x="853" y="374" class="micro ink">BUILD COMPLETE</text>
1692
+ <text x="1115" y="374" class="micro" text-anchor="end">/dist</text>
1693
+ <line x1="819" y1="450" x2="1134" y2="450" stroke="#343434"/>
1694
+ <text x="819" y="475" class="label bright">REAL COMMANDS</text><text x="1134" y="475" class="label" text-anchor="end">842MS</text>`;
1695
+ }
1696
+ __name(renderCliIllustration, "renderCliIllustration");
1697
+ function renderProjectIllustration() {
1698
+ return `${renderPanelHeader("PROJECT MAP", "CONVENTION TYPED")}
1699
+ <rect x="819" y="202" width="315" height="216" fill="#050505" stroke="#555"/>
1700
+ <text x="837" y="227" class="diagram-title bright">my-app/</text>
1701
+ <path d="M847 243v143M847 259h23M847 293h23M847 327h23M847 361h23" fill="none" stroke="#666"/>
1702
+ <rect x="870" y="243" width="246" height="33" fill="#0a0a0a" stroke="#444"/><text x="886" y="264" class="code">src/app</text><text x="1098" y="264" class="micro" text-anchor="end">ROUTES</text>
1703
+ <rect x="870" y="277" width="246" height="33" fill="#f0f0f0"/><text x="886" y="298" class="code ink">src/app/page.tsx</text>
1704
+ <rect x="870" y="311" width="246" height="33" fill="#0a0a0a" stroke="#444"/><text x="886" y="332" class="code">src/app/api/users/route.ts</text><text x="1098" y="332" class="micro" text-anchor="end">API</text>
1705
+ <rect x="870" y="345" width="246" height="33" fill="#0a0a0a" stroke="#444"/><text x="886" y="366" class="code">farm.config.ts</text><text x="1098" y="366" class="micro" text-anchor="end">CONFIG</text>
1706
+ <line x1="819" y1="450" x2="1134" y2="450" stroke="#343434"/>
1707
+ <text x="819" y="475" class="label bright">FILES BECOME FEATURES</text><text x="1134" y="475" class="label" text-anchor="end">ONE CONFIG</text>`;
1708
+ }
1709
+ __name(renderProjectIllustration, "renderProjectIllustration");
1710
+ function renderRuntimeIllustration() {
1711
+ return `${renderPanelHeader("PRODUCT ARCHITECTURE", "FULL STACK")}
1712
+ <rect x="819" y="211" width="315" height="55" fill="#f0f0f0"/>
1713
+ <text x="836" y="244" class="diagram-title ink">PRODUCT SURFACE</text><text x="1116" y="244" class="micro ink-muted" text-anchor="end">UI + ROUTES</text>
1714
+ <path d="M976 266v20m0 61v20" stroke="#727272"/>
1715
+ <rect x="855" y="286" width="242" height="61" fill="#a3a3a3"/>
1716
+ <text x="874" y="314" class="diagram-title ink">APPLICATION CORE</text><text x="874" y="334" class="micro ink-muted">APIS \xB7 MIDDLEWARE</text>
1717
+ <rect x="819" y="367" width="315" height="55" fill="#4c4c4c"/>
1718
+ <text x="836" y="400" class="diagram-title bright">CONNECTED STACK</text><text x="1116" y="400" class="micro" text-anchor="end">DATA \xB7 AUTH \xB7 DEPLOY</text>
1719
+ <line x1="819" y1="450" x2="1134" y2="450" stroke="#343434"/>
1720
+ <text x="819" y="475" class="label bright">ONE FRAMEWORK</text><text x="1134" y="475" class="label" text-anchor="end">ONE DEPLOYMENT MODEL</text>`;
1721
+ }
1722
+ __name(renderRuntimeIllustration, "renderRuntimeIllustration");
1723
+ function renderIllustration(type) {
1724
+ switch (type) {
1725
+ case "auth":
1726
+ return renderAuthIllustration();
1727
+ case "cache":
1728
+ return renderCacheIllustration();
1729
+ case "cli":
1730
+ return renderCliIllustration();
1731
+ case "integrations":
1732
+ return renderIntegrationsIllustration();
1733
+ case "project":
1734
+ return renderProjectIllustration();
1735
+ case "routing":
1736
+ return renderRoutingIllustration();
1737
+ default:
1738
+ return renderRuntimeIllustration();
1739
+ }
1740
+ }
1741
+ __name(renderIllustration, "renderIllustration");
1742
+ function renderFarmDocsSocialImageSvg(descriptor) {
1743
+ const titleLines = wrapText(descriptor.title, 22, 2);
1744
+ const longestTitleLine = Math.max(...titleLines.map((line) => line.length));
1745
+ const titleSize = titleLines.length === 1 ? longestTitleLine > 17 ? 62 : 74 : 56;
1746
+ const titleLineHeight = Math.round(titleSize * 0.98);
1747
+ const titleY = titleLines.length === 1 ? 294 : 266;
1748
+ const descriptionY = titleY + (titleLines.length - 1) * titleLineHeight + 59;
1749
+ const descriptionLines = wrapText(descriptor.description, 68, 2);
1750
+ const routeY = Math.max(418, descriptionY + descriptionLines.length * 29 + 24);
1751
+ const section = truncate(descriptor.section.toUpperCase(), 27);
1752
+ const route = truncate(descriptor.pageHref, 42);
1753
+ const footerUrl = truncate(descriptor.pageUrl.replace(/^https?:\/\//, ""), 70);
1754
+ const brand = truncate(descriptor.brand.toUpperCase(), 25);
1755
+ const titleId = `farm-docs-og-${descriptor.hash}`;
1756
+ return `<?xml version="1.0" encoding="UTF-8"?>
1757
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${FARM_DOCS_SOCIAL_IMAGE_WIDTH}" height="${FARM_DOCS_SOCIAL_IMAGE_HEIGHT}" viewBox="0 0 ${FARM_DOCS_SOCIAL_IMAGE_WIDTH} ${FARM_DOCS_SOCIAL_IMAGE_HEIGHT}" role="img" aria-labelledby="${titleId}-title ${titleId}-description">
1758
+ <title id="${titleId}-title">${escapeXml(descriptor.imageAlt)}</title>
1759
+ <desc id="${titleId}-description">${escapeXml(descriptor.description)}</desc>
1760
+ <metadata>${escapeXml(JSON.stringify({ generator: "Farm.js docs", page: descriptor.pageUrl, illustration: descriptor.illustration }))}</metadata>
1761
+ <style type="text/css">
1762
+ ${renderEmbeddedFont("Farm Sans", descriptor.fonts?.sans, "100 900")}
1763
+ ${renderEmbeddedFont("Farm Mono", descriptor.fonts?.mono, "100 900")}
1764
+ ${renderEmbeddedFont("Farm Pixel", descriptor.fonts?.display, "400 700")}
1765
+ .sans{font-family:"Farm Sans","Arial",sans-serif}.mono,.label,.code,.diagram-title,.micro{font-family:"Farm Mono","Menlo","DejaVu Sans Mono",monospace}.pixel{font-family:"Farm Pixel","Farm Mono",monospace}.label{fill:#8b8b8b;font-size:10px;font-weight:600;letter-spacing:1.2px}.code{fill:#8b8b8b;font-size:11px}.diagram-title{fill:#e7e7e7;font-size:11px;font-weight:650}.micro{fill:#777;font-size:8px;letter-spacing:.45px}.bright{fill:#f5f5f4}.ink{fill:#050505}.ink-muted{fill:#4c4c4c}
1766
+ </style>
1767
+ <defs>
1768
+ <pattern id="canvas-grid" width="40" height="40" patternUnits="userSpaceOnUse"><path d="M40 0H0V40" fill="none" stroke="#151515"/></pattern>
1769
+ <pattern id="diagonal" width="12" height="12" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><line x1="0" y1="0" x2="0" y2="12" stroke="#171717" stroke-width="2"/></pattern>
1770
+ <clipPath id="frame-clip"><rect x="28" y="28" width="1144" height="574"/></clipPath>
1771
+ </defs>
1772
+ <rect width="1200" height="630" fill="#050505"/>
1773
+ <rect width="1200" height="630" fill="url(#canvas-grid)"/>
1774
+ <g clip-path="url(#frame-clip)">
1775
+ <rect x="28" y="28" width="1144" height="574" fill="#020202"/>
1776
+ <rect x="782" y="114" width="390" height="411" fill="url(#diagonal)"/>
1777
+ </g>
1778
+ <rect x="28.5" y="28.5" width="1143" height="573" fill="none" stroke="#323232"/>
1779
+ <path d="M28 114.5h1144M28 525.5h1144M781.5 114v411" fill="none" stroke="#303030"/>
1780
+
1781
+ <g transform="translate(71 51)">
1782
+ <rect width="11" height="11" rx="1" fill="#f5f5f4"/><rect x="15" width="28" height="11" rx="1" fill="#f5f5f4"/>
1783
+ <rect y="15" width="11" height="11" rx="1" fill="#9b9b9b"/><rect x="15" y="15" width="28" height="11" rx="1" fill="#9b9b9b"/>
1784
+ <rect y="30" width="11" height="11" rx="1" fill="#5f5f5f"/><rect x="15" y="30" width="20" height="11" rx="1" fill="#5f5f5f"/>
1785
+ <text x="61" y="24" class="mono bright" font-size="24" font-weight="550">FARM<tspan fill="#777">.JS</tspan></text>
1786
+ <text x="61" y="43" class="label">BY FARMING LABS</text>
1787
+ </g>
1788
+ <text x="1134" y="72" class="label" text-anchor="end">${escapeXml(brand)} \xB7 DOCUMENTATION</text>
1789
+
1790
+ <text x="71" y="198" class="mono bright" font-size="13" font-weight="650">DOCS</text>
1791
+ <line x1="117" y1="193" x2="155" y2="193" stroke="#696969"/>
1792
+ <text x="166" y="198" class="mono" fill="#9b9b9b" font-size="13">${escapeXml(section)}</text>
1793
+ ${renderTextLines(titleLines, 71, titleY, titleLineHeight, `class="pixel bright" font-size="${titleSize}" font-weight="500" letter-spacing="-2.4"`)}
1794
+ ${renderTextLines(descriptionLines, 71, descriptionY, 29, 'class="sans" fill="#a3a3a3" font-size="20" font-weight="430" letter-spacing="-.3"')}
1795
+ <rect x="71" y="${routeY}" width="${Math.min(390, 56 + route.length * 8)}" height="36" fill="#050505" stroke="#3c3c3c"/>
1796
+ <text x="85" y="${routeY + 23}" class="mono bright" font-size="11" font-weight="600">GET</text>
1797
+ <text x="119" y="${routeY + 23}" class="mono" fill="#898989" font-size="11">${escapeXml(route)}</text>
1798
+
1799
+ ${renderIllustration(descriptor.illustration)}
1800
+
1801
+ <text x="71" y="570" class="mono bright" font-size="13" font-weight="550">${escapeXml(footerUrl)}</text>
1802
+ <text x="1134" y="570" class="mono" fill="#9b9b9b" font-size="12" text-anchor="end">FARM.JS DOCUMENTATION</text>
1803
+ <path d="M20 20h10M20 20v10M1180 20h-10M1180 20v10M20 610h10M20 610v-10M1180 610h-10M1180 610v-10" fill="none" stroke="#9b9b9b"/>
1804
+ </svg>`;
1805
+ }
1806
+ __name(renderFarmDocsSocialImageSvg, "renderFarmDocsSocialImageSvg");
1807
+ function renderFarmDocsSocialMetadata(descriptor, customImage) {
1808
+ const imageUrl = customImage ? new URL(customImage, descriptor.pageUrl).href : descriptor.imageUrl;
1809
+ const customExtension = customImage?.toLowerCase().split(/[?#]/, 1)[0];
1810
+ const imageType = customExtension?.endsWith(".webp") ? "image/webp" : customExtension?.endsWith(".png") ? "image/png" : customExtension?.match(/\.jpe?g$/) ? "image/jpeg" : "image/svg+xml";
1811
+ const tag = /* @__PURE__ */ __name((property, content, name = false) => `<meta ${name ? "name" : "property"}="${property}" content="${escapeXml(content)}">`, "tag");
1812
+ return [
1813
+ tag("og:type", "article"),
1814
+ tag("og:site_name", descriptor.siteName),
1815
+ tag("og:title", descriptor.title),
1816
+ tag("og:description", descriptor.description),
1817
+ tag("og:url", descriptor.pageUrl),
1818
+ tag("og:image", imageUrl),
1819
+ tag("og:image:type", imageType),
1820
+ ...customImage ? [] : [
1821
+ tag("og:image:width", String(FARM_DOCS_SOCIAL_IMAGE_WIDTH)),
1822
+ tag("og:image:height", String(FARM_DOCS_SOCIAL_IMAGE_HEIGHT))
1823
+ ],
1824
+ tag("og:image:alt", descriptor.imageAlt),
1825
+ tag("twitter:card", "summary_large_image", true),
1826
+ tag("twitter:title", descriptor.title, true),
1827
+ tag("twitter:description", descriptor.description, true),
1828
+ tag("twitter:image", imageUrl, true),
1829
+ tag("twitter:image:alt", descriptor.imageAlt, true)
1830
+ ].join("\n ");
1831
+ }
1832
+ __name(renderFarmDocsSocialMetadata, "renderFarmDocsSocialMetadata");
1833
+
1451
1834
  // src/docs/handler.ts
1452
1835
  var DOCS_FILE_NAMES = ["page.mdx", "page.md", "index.mdx", "index.md"];
1453
1836
  var DOCS_FILE_EXTENSIONS2 = [".mdx", ".md"];
1454
1837
  var FARM_DOCS_FALLBACK_FAVICON = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' fill='black'/%3E%3Cpath d='M7 8h18v3H10v5h12v3H10v5H7z' fill='white'/%3E%3C/svg%3E";
1455
1838
  var FARM_DOCS_FAVICON_FILES = ["favicon.svg", "favicon.ico", "favicon.png"];
1456
- var GEIST_SANS_FONT_URL = "/assets/Geist-Variable-CrgPqtmy.woff2";
1457
- var GEIST_MONO_FONT_URL = "/assets/GeistMono-Variable-BNLlm6Cd.woff2";
1458
1839
  function trimSlashes(value) {
1459
1840
  return value.replace(/^\/+|\/+$/g, "");
1460
1841
  }
1461
1842
  __name(trimSlashes, "trimSlashes");
1462
- function normalizeEntry(entry) {
1843
+ function normalizeEntry2(entry) {
1463
1844
  if (!entry || entry === "/") return "/";
1464
1845
  return `/${trimSlashes(entry)}`;
1465
1846
  }
1466
- __name(normalizeEntry, "normalizeEntry");
1847
+ __name(normalizeEntry2, "normalizeEntry");
1467
1848
  function normalizeSlug(value) {
1468
1849
  return trimSlashes(decodeURIComponent(value)).replace(/\.(mdx?|markdown)$/i, "");
1469
1850
  }
@@ -1528,7 +1909,7 @@ function isFarmDocsRequest(docs, request) {
1528
1909
  if (!docs?.enabled) return false;
1529
1910
  if (request.method !== "GET" && request.method !== "HEAD") return false;
1530
1911
  const pathname = new URL(request.url).pathname;
1531
- const entry = normalizeEntry(docs.entry);
1912
+ const entry = normalizeEntry2(docs.entry);
1532
1913
  if (entry === "/") return true;
1533
1914
  return pathname === entry || pathname === `${entry}.md` || pathname.startsWith(`${entry}/`);
1534
1915
  }
@@ -1548,20 +1929,20 @@ function resolveFarmDocsContentDir(docs, options) {
1548
1929
  __name(resolveFarmDocsContentDir, "resolveFarmDocsContentDir");
1549
1930
  function getFarmDocsRouteTypeEntries(docs) {
1550
1931
  if (!docs?.enabled) return [];
1551
- const entry = normalizeEntry(docs.entry);
1932
+ const entry = normalizeEntry2(docs.entry);
1552
1933
  if (entry === "/") return ["/", "/[...docs]"];
1553
1934
  return [entry, `${entry}/[...docs]`];
1554
1935
  }
1555
1936
  __name(getFarmDocsRouteTypeEntries, "getFarmDocsRouteTypeEntries");
1556
1937
  function getFarmDocsDocumentNavigationMatchers(docs) {
1557
1938
  if (!docs?.enabled) return [];
1558
- const entry = normalizeEntry(docs.entry);
1939
+ const entry = normalizeEntry2(docs.entry);
1559
1940
  return [entry === "/" ? "/(.*)" : `${entry}(.*)`];
1560
1941
  }
1561
1942
  __name(getFarmDocsDocumentNavigationMatchers, "getFarmDocsDocumentNavigationMatchers");
1562
1943
  function getRequestSlug(docs, request) {
1563
1944
  const pathname = new URL(request.url).pathname;
1564
- const entry = normalizeEntry(docs.entry);
1945
+ const entry = normalizeEntry2(docs.entry);
1565
1946
  if (entry === "/") return normalizeSlug(pathname);
1566
1947
  if (pathname === entry || pathname === `${entry}.md`) return "";
1567
1948
  return normalizeSlug(pathname.slice(entry.length));
@@ -1624,6 +2005,7 @@ function loadFarmDocsPage(contentDir, docs, slug) {
1624
2005
  slug,
1625
2006
  title,
1626
2007
  description: frontmatter.description,
2008
+ section: frontmatter.section,
1627
2009
  href,
1628
2010
  sourcePath,
1629
2011
  lastModified: resolveFarmDocsPageLastModified(contentDir, sourcePath, frontmatter),
@@ -1633,7 +2015,7 @@ function loadFarmDocsPage(contentDir, docs, slug) {
1633
2015
  }
1634
2016
  __name(loadFarmDocsPage, "loadFarmDocsPage");
1635
2017
  function createDocsHref(entry, slug) {
1636
- const normalizedEntry = normalizeEntry(entry);
2018
+ const normalizedEntry = normalizeEntry2(entry);
1637
2019
  const normalizedSlug = trimSlashes(slug);
1638
2020
  if (normalizedEntry === "/") return normalizedSlug ? `/${normalizedSlug}` : "/";
1639
2021
  return normalizedSlug ? `${normalizedEntry}/${normalizedSlug}` : normalizedEntry;
@@ -2604,7 +2986,7 @@ function renderPixelBreadcrumb(page, docs) {
2604
2986
  const parentSegments = segments.slice(0, -1);
2605
2987
  const parentSegment = parentSegments[parentSegments.length - 1];
2606
2988
  const currentSegment = segments[segments.length - 1];
2607
- const entry = normalizeEntry(docs.entry);
2989
+ const entry = normalizeEntry2(docs.entry);
2608
2990
  const parentPath = parentSegments.join("/");
2609
2991
  const parentHref = entry === "/" ? `/${parentPath}` : `${entry}/${parentPath}`;
2610
2992
  return `<nav class="fd-breadcrumb" aria-label="Breadcrumb">
@@ -2647,7 +3029,7 @@ ${items.map(
2647
3029
  }
2648
3030
  __name(renderPixelToc, "renderPixelToc");
2649
3031
  function renderDocsRuntimeScript(docs) {
2650
- const docsEntry = JSON.stringify(normalizeEntry(docs.entry));
3032
+ const docsEntry = JSON.stringify(normalizeEntry2(docs.entry));
2651
3033
  return `<script>(()=>{if(window.__farmDocsRuntime)return;window.__farmDocsRuntime=true;document.documentElement.dataset.farmDocsRuntime="true";document.documentElement.dataset.farmDocsRuntimeId=Math.random().toString(36).slice(2);const docsEntry=${docsEntry};let cleanupToc=()=>{};let closeMobileSidebar=()=>{};const normalizePath=(path)=>path.length>1?path.replace(/\\/+$/,""):path;const isDocsPath=(path)=>{const next=normalizePath(path);const entry=normalizePath(docsEntry);if(next.endsWith(".md"))return false;if(entry==="/")return true;return next===entry||next.startsWith(entry+"/")};const initToc=()=>{cleanupToc();const toc=document.getElementById("nd-toc");if(!toc){cleanupToc=()=>{};return}const links=Array.from(toc.querySelectorAll("[data-toc-item]"));const thumb=toc.querySelector("[data-toc-thumb]");const pairs=links.map((link)=>{let id=link.hash.slice(1);try{id=decodeURIComponent(id)}catch{}return{link,heading:document.getElementById(id)}}).filter((item)=>item.heading);const setActive=(active)=>{for(const {link} of pairs)link.dataset.active=link===active.link?"true":"false";if(!thumb)return;const styles=getComputedStyle(active.link);const top=active.link.offsetTop+parseFloat(styles.paddingTop||"0");const bottom=active.link.offsetTop+active.link.clientHeight-parseFloat(styles.paddingBottom||"0");thumb.style.clipPath="polygon(0 "+top+"px,100% "+top+"px,100% "+bottom+"px,0 "+bottom+"px)"};const update=()=>{if(pairs.length===0)return;const offset=Math.min(window.innerHeight*0.3,160);let active=pairs[0];for(const pair of pairs){if(pair.heading.getBoundingClientRect().top<=offset)active=pair;else break}setActive(active)};let frame=0;const schedule=()=>{if(frame)return;frame=requestAnimationFrame(()=>{frame=0;update()})};const onHashChange=()=>setTimeout(schedule,0);window.addEventListener("scroll",schedule,{passive:true});window.addEventListener("resize",schedule);window.addEventListener("hashchange",onHashChange);cleanupToc=()=>{window.removeEventListener("scroll",schedule);window.removeEventListener("resize",schedule);window.removeEventListener("hashchange",onHashChange);if(frame)cancelAnimationFrame(frame);frame=0};update()};const getSidebar=()=>document.getElementById("nd-sidebar");const ensureActiveVisible=()=>{const sidebar=getSidebar();if(!sidebar)return;const active=sidebar.querySelector('a[data-active="true"]');if(!(active instanceof HTMLElement))return;const activeRect=active.getBoundingClientRect();const sidebarRect=sidebar.getBoundingClientRect();if(activeRect.top<sidebarRect.top||activeRect.bottom>sidebarRect.bottom)sidebar.scrollTop+=activeRect.top-sidebarRect.top-(sidebar.clientHeight-activeRect.height)/2};const setSidebarActive=(path)=>{const sidebar=getSidebar();if(!sidebar)return;const current=normalizePath(path);for(const link of Array.from(sidebar.querySelectorAll("a[href]"))){try{link.dataset.active=normalizePath(new URL(link.href,location.href).pathname)===current?"true":"false"}catch{}}ensureActiveVisible()};const initMobileSidebar=()=>{const layout=document.getElementById("nd-docs-layout");const sidebar=getSidebar();const toggle=document.querySelector("[data-sidebar-toggle]");const backdrop=document.querySelector("[data-sidebar-backdrop]");if(!layout||!sidebar||!(toggle instanceof HTMLButtonElement))return;const setOpen=(open)=>{layout.dataset.sidebarOpen=open?"true":"false";document.documentElement.dataset.farmDocsSidebar=open?"open":"closed";toggle.setAttribute("aria-expanded",open?"true":"false");toggle.setAttribute("aria-label",open?"Close menu":"Open menu")};const toggleOpen=()=>setOpen(layout.dataset.sidebarOpen!=="true");closeMobileSidebar=()=>setOpen(false);toggle.addEventListener("click",(event)=>{event.preventDefault();toggleOpen()});backdrop?.addEventListener("click",()=>closeMobileSidebar());document.addEventListener("keydown",(event)=>{if(event.key==="Escape")closeMobileSidebar()});sidebar.addEventListener("click",(event)=>{const target=event.target instanceof Element?event.target.closest("a[href]"):null;if(target)closeMobileSidebar()});closeMobileSidebar()};const initSidebarScroll=()=>{const sidebar=getSidebar();if(!sidebar)return;const key="farmdocs:sidebar-scroll:"+location.origin;const getStorage=()=>{try{return window.sessionStorage}catch{return null}};const readSaved=()=>{try{const raw=getStorage()?.getItem(key);if(!raw)return null;const parsed=JSON.parse(raw);return parsed&&typeof parsed==="object"?parsed:null}catch{return null}};const save=(path=location.pathname)=>{try{getStorage()?.setItem(key,JSON.stringify({path,scrollTop:sidebar.scrollTop}))}catch{}};const saved=readSaved();if(saved?.path===location.pathname&&Number.isFinite(Number(saved.scrollTop)))sidebar.scrollTop=Number(saved.scrollTop);ensureActiveVisible();save();sidebar.addEventListener("scroll",()=>save(),{passive:true});sidebar.addEventListener("click",(event)=>{const target=event.target instanceof Element?event.target.closest("a[href]"):null;if(!target)return;try{save(new URL(target.href,location.href).pathname)}catch{save()}});window.addEventListener("beforeunload",()=>save())};let navigateController=null;const getPageKey=(root)=>{const article=root.getElementById("nd-page");if(!article)return"";return article.querySelector("h1")?.textContent?.trim()||article.textContent?.replace(/\\s+/g," ").trim().slice(0,160)||""};const swapDocsPage=(html,url)=>{const nextDoc=new DOMParser().parseFromString(html,"text/html");const nextArticle=nextDoc.getElementById("nd-page");const currentArticle=document.getElementById("nd-page");if(!nextArticle||!currentArticle)return false;const nextKey=getPageKey(nextDoc);const importedArticle=document.importNode(nextArticle,true);currentArticle.replaceWith(importedArticle);const renderedArticle=document.getElementById("nd-page");if(!renderedArticle||renderedArticle===currentArticle||(nextKey&&getPageKey(document)!==nextKey))return false;const nextToc=nextDoc.getElementById("nd-toc");const currentToc=document.getElementById("nd-toc");if(nextToc&&currentToc)currentToc.replaceWith(document.importNode(nextToc,true));if(nextDoc.title)document.title=nextDoc.title;const nextDescription=nextDoc.querySelector('meta[name="description"]');const currentDescription=document.querySelector('meta[name="description"]');if(nextDescription&&currentDescription)currentDescription.setAttribute("content",nextDescription.getAttribute("content")||"");setSidebarActive(url.pathname);initToc();closeMobileSidebar();return true};const navigateDocs=async(url,{replace=false,scroll=true}={})=>{if(!isDocsPath(url.pathname))return false;if(navigateController)navigateController.abort();const controller=new AbortController();navigateController=controller;document.documentElement.dataset.farmDocsNavigating="true";try{const response=await fetch(url.href,{cache:"no-store",headers:{accept:"text/html","x-farm-docs-navigate":"1"},signal:controller.signal});if(!response.ok||!((response.headers.get("content-type")||"").includes("text/html")))return false;const html=await response.text();if(!swapDocsPage(html,url))return false;if(replace)history.replaceState({farmDocs:true},"",url.href);else history.pushState({farmDocs:true},"",url.href);if(scroll){if(url.hash){let id=url.hash.slice(1);try{id=decodeURIComponent(id)}catch{}document.getElementById(id)?.scrollIntoView({block:"start"})}else window.scrollTo({top:0,left:0})}return true}catch(error){if(error?.name==="AbortError")return true;return false}finally{if(navigateController===controller){delete document.documentElement.dataset.farmDocsNavigating;navigateController=null}}};const initClientNavigation=()=>{document.addEventListener("click",(event)=>{if(event.defaultPrevented||event.button!==0||event.metaKey||event.ctrlKey||event.shiftKey||event.altKey)return;const target=event.target instanceof Element?event.target.closest("a[href]"):null;if(!target||target.target||target.hasAttribute("download"))return;let url;try{url=new URL(target.href,location.href)}catch{return}if(url.origin!==location.origin||!isDocsPath(url.pathname))return;if(normalizePath(url.pathname)===normalizePath(location.pathname)&&url.hash)return;event.preventDefault();navigateDocs(url).then((handled)=>{if(!handled)location.href=url.href})});window.addEventListener("popstate",()=>{navigateDocs(new URL(location.href),{replace:true,scroll:false}).then((handled)=>{if(!handled)location.reload()})})};const init=()=>{initToc();initMobileSidebar();initSidebarScroll();initClientNavigation()};if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",init,{once:true});else init()})();</script>`;
2652
3034
  }
2653
3035
  __name(renderDocsRuntimeScript, "renderDocsRuntimeScript");
@@ -2700,17 +3082,28 @@ ${readCssWithImports(themeCssPath)}`;
2700
3082
  }
2701
3083
  }
2702
3084
  __name(resolvePixelBorderThemeCss, "resolvePixelBorderThemeCss");
2703
- function renderFarmDocsBridgeCss(docs) {
3085
+ function renderFarmDocsBridgeCss(docs, fontAssets, layoutFonts) {
2704
3086
  const sidebarWidth = getThemeLayoutValue(docs, "sidebarWidth", 320);
2705
3087
  const contentWidth = getThemeLayoutValue(docs, "contentWidth", 860);
3088
+ const fontFaces = fontAssets.map(
3089
+ ({ family, url }) => `@font-face { font-family: "${family}"; src: url("${url}") format("woff2"); font-style: normal; font-weight: 100 900; font-display: block; }`
3090
+ ).join("\n");
3091
+ const fontVariables = [
3092
+ fontAssets.some(({ family }) => family === "Geist Sans") ? '--font-geist-sans: "Geist Sans", ui-sans-serif, system-ui, sans-serif;' : "",
3093
+ fontAssets.some(({ family }) => family === "Geist Mono") ? '--font-geist-mono: "Geist Mono", ui-monospace, monospace;' : ""
3094
+ ].filter(Boolean).join(" ");
3095
+ const fontCss = fontFaces ? `${fontFaces}
3096
+ :root { ${fontVariables} }` : "";
3097
+ const layoutFontVariables = [
3098
+ renderFarmDocsLayoutFontVariable("--fd-layout-font-body", layoutFonts?.body),
3099
+ renderFarmDocsLayoutFontVariable("--fd-layout-font-code", layoutFonts?.code)
3100
+ ].filter(Boolean).join(" ");
2706
3101
  return `
2707
- @font-face { font-family: "Geist Sans"; src: local("Geist Sans"), url("${GEIST_SANS_FONT_URL}") format("woff2"), url("/node_modules/geist/dist/fonts/geist-sans/Geist-Variable.woff2") format("woff2"); font-display: block; font-style: normal; font-weight: 100 900; }
2708
- @font-face { font-family: "Geist Mono"; src: local("Geist Mono"), url("${GEIST_MONO_FONT_URL}") format("woff2"), url("/node_modules/geist/dist/fonts/geist-mono/GeistMono-Variable.woff2") format("woff2"); font-display: block; font-style: normal; font-weight: 100 900; }
2709
- :root { color-scheme: dark; --font-geist-sans: "Geist Sans"; --font-geist-mono: "Geist Mono"; --fd-sidebar-width: ${sidebarWidth}px; --fd-content-width: ${contentWidth}px; --fd-toc-width: 240px; --fd-docs-height: 100vh; --fd-docs-row-1: var(--fd-nav-height, 44px); --fd-docs-font-sans: var(--font-geist-sans, "Geist Sans", var(--font-sans, system-ui, -apple-system, sans-serif)); --fd-docs-font-mono: var(--font-geist-mono, "Geist Mono", var(--font-mono, ui-monospace, monospace)); --fd-font-sans: var(--fd-docs-font-sans); --fd-font-mono: var(--fd-docs-font-mono); --fd-pixel-rail-width: 12px; --fd-sidebar-edge: calc(var(--fd-pixel-rail-width) + 18px); --fd-sidebar-guide-x: calc(var(--fd-sidebar-edge) + 16px); --fd-sidebar-link-x: calc(var(--fd-sidebar-guide-x) + 22px); --fd-sidebar-sub-guide-x: calc(var(--fd-sidebar-link-x) + 7px); --fd-sidebar-sub-link-x: calc(var(--fd-sidebar-sub-guide-x) + 28px); --fd-sidebar-branch-gap: 0px; --fd-sidebar-nested-icon-gap: 0px; --fd-sidebar-line-color: color-mix(in srgb, var(--color-fd-border, hsl(0 0% 15%)) 88%, transparent); }
3102
+ :root { color-scheme: dark; --font-geist-sans: ui-sans-serif, system-ui, sans-serif; --font-geist-mono: ui-monospace, monospace; ${layoutFontVariables} --fd-sidebar-width: ${sidebarWidth}px; --fd-content-width: ${contentWidth}px; --fd-toc-width: 240px; --fd-docs-height: 100vh; --fd-docs-row-1: var(--fd-nav-height, 44px); --fd-docs-font-sans: var(--fd-layout-font-body, var(--font-geist-sans, var(--font-sans, system-ui, -apple-system, sans-serif))); --fd-docs-font-mono: var(--fd-layout-font-code, var(--font-geist-mono, var(--font-mono, ui-monospace, monospace))); --fd-font-sans: var(--fd-docs-font-sans); --fd-font-mono: var(--fd-docs-font-mono); --fd-pixel-rail-width: 12px; --fd-sidebar-edge: calc(var(--fd-pixel-rail-width) + 18px); --fd-sidebar-guide-x: calc(var(--fd-sidebar-edge) + 16px); --fd-sidebar-link-x: calc(var(--fd-sidebar-guide-x) + 22px); --fd-sidebar-sub-guide-x: calc(var(--fd-sidebar-link-x) + 7px); --fd-sidebar-sub-link-x: calc(var(--fd-sidebar-sub-guide-x) + 28px); --fd-sidebar-branch-gap: 0px; --fd-sidebar-nested-icon-gap: 0px; --fd-sidebar-line-color: color-mix(in srgb, var(--color-fd-border, hsl(0 0% 15%)) 88%, transparent); }
2710
3103
  * { box-sizing: border-box; }
2711
3104
  html { background: var(--color-fd-background, hsl(0 0% 2%)); scroll-padding-top: calc(var(--fd-nav-height, 44px) + 24px); }
2712
3105
  html[data-farm-docs-sidebar="open"], html[data-farm-docs-sidebar="open"] body { overflow: hidden; }
2713
- body { margin: 0; min-height: 100vh; background: var(--color-fd-background, hsl(0 0% 2%)); color: var(--color-fd-foreground, oklch(0.985 0.001 106.423)); font-family: var(--fd-docs-font-sans); text-rendering: optimizeLegibility; }
3106
+ body { margin: 0; min-height: 100vh; background: var(--color-fd-background, hsl(0 0% 2%)); color: var(--color-fd-foreground, oklch(0.985 0.001 106.423)); font-family: var(--fd-docs-font-sans); font-synthesis: none; text-rendering: optimizeLegibility; }
2714
3107
  ::selection { background: var(--color-fd-foreground, #fff); color: var(--color-fd-background, #000); }
2715
3108
  a { color: inherit; }
2716
3109
  #nd-docs-layout { --fd-sidebar-col: var(--fd-sidebar-width); display: grid; grid-template: "sidebar header header" var(--fd-nav-height, 44px) "sidebar main toc" 1fr / var(--fd-sidebar-width) minmax(0, 1fr) var(--fd-toc-width) !important; min-height: 100vh; border-top: 1px solid var(--color-fd-border, hsl(0 0% 15%)); background: var(--color-fd-background, hsl(0 0% 2%)); }
@@ -2890,15 +3283,51 @@ function renderFarmDocsBridgeCss(docs) {
2890
3283
  .sh__line { min-height: 1.6em; }
2891
3284
  }
2892
3285
  ${farmDocsPixelBorderCss}
3286
+ ${fontCss}
2893
3287
  `;
2894
3288
  }
2895
3289
  __name(renderFarmDocsBridgeCss, "renderFarmDocsBridgeCss");
2896
- function renderPixelDocsHtml(page, pages, docs, themeCss, clientEntry, faviconHref) {
3290
+ function renderFarmDocsLayoutFontVariable(name, font) {
3291
+ const family = font?.style.fontFamily;
3292
+ if (!family || /[;{}<>]/.test(family)) return "";
3293
+ return `${name}: ${family};`;
3294
+ }
3295
+ __name(renderFarmDocsLayoutFontVariable, "renderFarmDocsLayoutFontVariable");
3296
+ function renderFarmDocsFontPreloads(fontAssets) {
3297
+ return fontAssets.map(
3298
+ ({ url }) => `<link rel="preload" href="${escapeAttribute(url)}" as="font" type="font/woff2" crossorigin>`
3299
+ ).join("\n ");
3300
+ }
3301
+ __name(renderFarmDocsFontPreloads, "renderFarmDocsFontPreloads");
3302
+ function renderFarmDocsFontPreloadHeader(fontAssets) {
3303
+ return fontAssets.map(({ url }) => `<${url}>; rel=preload; as=font; type=font/woff2; crossorigin`).join(", ");
3304
+ }
3305
+ __name(renderFarmDocsFontPreloadHeader, "renderFarmDocsFontPreloadHeader");
3306
+ function getFarmLayoutFontPreloads(layoutFonts) {
3307
+ const seen = /* @__PURE__ */ new Set();
3308
+ return [layoutFonts?.body, layoutFonts?.code].flatMap(
3309
+ (font) => (font?.preloads || []).filter(({ href }) => {
3310
+ if (seen.has(href)) return false;
3311
+ seen.add(href);
3312
+ return true;
3313
+ })
3314
+ );
3315
+ }
3316
+ __name(getFarmLayoutFontPreloads, "getFarmLayoutFontPreloads");
3317
+ function renderFarmLayoutFontPreloadHeader(layoutFonts) {
3318
+ return getFarmLayoutFontPreloads(layoutFonts).map(({ href, type }) => `<${href}>; rel=preload; as=font; type=${type}; crossorigin`).join(", ");
3319
+ }
3320
+ __name(renderFarmLayoutFontPreloadHeader, "renderFarmLayoutFontPreloadHeader");
3321
+ function renderPixelDocsHtml(page, pages, docs, themeCss, clientEntry, faviconHref, requestUrl, fontAssets, layoutFonts, fontStylesheetHref) {
2897
3322
  const navTitle = typeof docs.config.nav === "object" && docs.config.nav && "title" in docs.config.nav ? String(docs.config.nav.title || "Docs") : "Docs";
2898
3323
  const description = page.description || docs.config.metadata?.description || "";
2899
3324
  const tocItems = extractTocItems(page.body, getThemeTocDepth(docs));
2900
3325
  const themeName = getThemeName(docs);
2901
3326
  const searchEnabled = isFarmDocsSearchEnabled(docs);
3327
+ const socialMetadata = isFarmDocsSocialImageEnabled(page, docs) ? renderFarmDocsSocialMetadata(
3328
+ createFarmDocsSocialImageDescriptor(page, docs, requestUrl),
3329
+ getFarmDocsCustomSocialImage(page)
3330
+ ) : "";
2902
3331
  return `<!DOCTYPE html>
2903
3332
  <html class="dark" lang="en" data-docs-theme="${escapeAttribute(themeName)}">
2904
3333
  <head>
@@ -2907,11 +3336,12 @@ function renderPixelDocsHtml(page, pages, docs, themeCss, clientEntry, faviconHr
2907
3336
  <meta name="generator" content="@farming-labs/docs via Farm.js">
2908
3337
  <title>${escapeHtml(page.title)}</title>
2909
3338
  ${renderFarmDocsFaviconLink(faviconHref)}
2910
- <link rel="preload" href="${GEIST_SANS_FONT_URL}" as="font" type="font/woff2" crossorigin>
2911
- <link rel="preload" href="${GEIST_MONO_FONT_URL}" as="font" type="font/woff2" crossorigin>
3339
+ ${renderFarmDocsFontPreloads(fontAssets)}
3340
+ ${fontStylesheetHref ? `<link rel="stylesheet" href="${escapeAttribute(fontStylesheetHref)}">` : ""}
2912
3341
  ${description ? `<meta name="description" content="${escapeHtml(description)}">` : ""}
3342
+ ${socialMetadata}
2913
3343
  <style>${themeCss}
2914
- ${renderFarmDocsBridgeCss(docs)}</style>
3344
+ ${renderFarmDocsBridgeCss(docs, fontAssets, layoutFonts)}</style>
2915
3345
  ${searchEnabled ? renderDocsSearchBootstrapScript() : ""}
2916
3346
  </head>
2917
3347
  <body>
@@ -2964,9 +3394,34 @@ ${renderMarkdownHtmlWithTitleMeta(page, docs)}
2964
3394
  __name(renderPixelDocsHtml, "renderPixelDocsHtml");
2965
3395
  function createFarmDocsHandler(docs, options) {
2966
3396
  const faviconHref = resolveFarmDocsFavicon(docs, options);
3397
+ const fontAssets = options.fontAssets ?? toFarmDocsPublicFontAssets(resolveFarmDocsFontAssets(options.root));
3398
+ const fallbackFontPreloadHeader = renderFarmDocsFontPreloadHeader(fontAssets);
2967
3399
  return /* @__PURE__ */ __name(async function handleFarmDocsRequest(request) {
2968
3400
  if (!docs?.enabled || request.method !== "GET" && request.method !== "HEAD") return null;
2969
3401
  const contentDir = resolveFarmDocsContentDir(docs, options);
3402
+ const requestUrl = new URL(request.url);
3403
+ const socialImageSlug = getFarmDocsSocialImageSlug(docs, requestUrl);
3404
+ if (socialImageSlug !== null) {
3405
+ const socialImagePage = loadFarmDocsPage(contentDir, docs, socialImageSlug);
3406
+ if (!socialImagePage || !isFarmDocsSocialImageEnabled(socialImagePage, docs) || getFarmDocsCustomSocialImage(socialImagePage)) {
3407
+ return null;
3408
+ }
3409
+ const descriptor = createFarmDocsSocialImageDescriptor(socialImagePage, docs, requestUrl);
3410
+ if (requestUrl.pathname !== descriptor.imagePath) return null;
3411
+ const etag = `"${descriptor.hash}"`;
3412
+ const immutable = requestUrl.searchParams.get("v") === descriptor.hash;
3413
+ const headers = new Headers({
3414
+ "Content-Type": "image/svg+xml; charset=utf-8",
3415
+ "Cache-Control": immutable ? "public, max-age=31536000, immutable" : "public, max-age=0, must-revalidate",
3416
+ ETag: etag,
3417
+ "X-Content-Type-Options": "nosniff"
3418
+ });
3419
+ if (request.headers.get("if-none-match") === etag) {
3420
+ return new Response(null, { status: 304, headers });
3421
+ }
3422
+ if (request.method === "HEAD") return new Response(null, { status: 200, headers });
3423
+ return new Response(renderFarmDocsSocialImageSvg(descriptor), { status: 200, headers });
3424
+ }
2970
3425
  const publicResponse = createFarmDocsPublicResponse(contentDir, docs, request);
2971
3426
  if (publicResponse) return publicResponse;
2972
3427
  if (!isFarmDocsRequest(docs, request)) return null;
@@ -2989,6 +3444,11 @@ function createFarmDocsHandler(docs, options) {
2989
3444
  }
2990
3445
  );
2991
3446
  }
3447
+ const pathname = new URL(request.url).pathname;
3448
+ const layoutFonts = await options.resolveLayoutFonts?.(pathname);
3449
+ const usesLayoutFonts = Boolean(layoutFonts?.body || layoutFonts?.code);
3450
+ const activeFontAssets = usesLayoutFonts ? [] : fontAssets;
3451
+ const fontPreloadHeader = usesLayoutFonts ? renderFarmLayoutFontPreloadHeader(layoutFonts) : fallbackFontPreloadHeader;
2992
3452
  return new Response(
2993
3453
  renderPixelDocsHtml(
2994
3454
  page,
@@ -2996,13 +3456,18 @@ function createFarmDocsHandler(docs, options) {
2996
3456
  docs,
2997
3457
  resolvePixelBorderThemeCss(options),
2998
3458
  options.clientEntry || "/farm-client.js",
2999
- faviconHref
3459
+ faviconHref,
3460
+ requestUrl,
3461
+ activeFontAssets,
3462
+ layoutFonts,
3463
+ usesLayoutFonts ? options.fontStylesheetHref : void 0
3000
3464
  ),
3001
3465
  {
3002
3466
  status: 200,
3003
3467
  headers: {
3004
3468
  "Content-Type": "text/html; charset=utf-8",
3005
- "Cache-Control": "public, s-maxage=60, stale-while-revalidate=300"
3469
+ "Cache-Control": "public, s-maxage=60, stale-while-revalidate=300",
3470
+ ...fontPreloadHeader ? { Link: fontPreloadHeader } : {}
3006
3471
  }
3007
3472
  }
3008
3473
  );
@@ -3537,4 +4002,4 @@ export {
3537
4002
  createDocsAPI,
3538
4003
  createFarmDocsAPIHandler
3539
4004
  };
3540
- //# sourceMappingURL=chunk-4LND3PXF.mjs.map
4005
+ //# sourceMappingURL=chunk-OPHK6OJN.mjs.map