@stacksjs/stx 0.2.318 → 0.2.320

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 (159) hide show
  1. package/dist/builtins/image-delivery.d.ts +14 -0
  2. package/dist/builtins/image-delivery.js +121 -11
  3. package/dist/builtins/image-placeholder.d.ts +5 -0
  4. package/dist/builtins/image-placeholder.js +10 -3
  5. package/dist/builtins/stx-image.js +19 -6
  6. package/dist/chunk-08809py9.js +2 -0
  7. package/dist/{chunk-yzb20ane.js → chunk-19yw8p2h.js} +1 -1
  8. package/dist/{chunk-r3220h2n.js → chunk-1zckawsv.js} +1 -1
  9. package/dist/chunk-273pkk23.js +2 -0
  10. package/dist/{chunk-egr5663e.js → chunk-273xtqav.js} +3 -3
  11. package/dist/{chunk-spzbfqjn.js → chunk-2cey22m2.js} +254 -254
  12. package/dist/{chunk-jg2gbd58.js → chunk-2f0kykg4.js} +1 -1
  13. package/dist/{chunk-ksqba0cq.js → chunk-2q30mata.js} +1 -1
  14. package/dist/{chunk-ybct46zd.js → chunk-2rca15ge.js} +1 -1
  15. package/dist/chunk-2zpf8z9f.js +2 -0
  16. package/dist/{chunk-8q8gj45z.js → chunk-3745eg0d.js} +1 -1
  17. package/dist/chunk-3m34hq6t.js +2 -0
  18. package/dist/{chunk-bbq82jww.js → chunk-3meekwv6.js} +2 -2
  19. package/dist/chunk-3rajeek7.js +2 -0
  20. package/dist/{chunk-3pv0qj5f.js → chunk-456x7xb4.js} +1 -1
  21. package/dist/{chunk-zr1r73p3.js → chunk-45e1wffb.js} +1 -1
  22. package/dist/{chunk-322qz0cj.js → chunk-49129rm8.js} +1 -1
  23. package/dist/{chunk-604qr43v.js → chunk-5mg4ddbx.js} +1 -1
  24. package/dist/chunk-5wep1h8r.js +2 -0
  25. package/dist/chunk-61bmp7rb.js +2 -0
  26. package/dist/chunk-6py5b6p4.js +2 -0
  27. package/dist/{chunk-b73h0vd8.js → chunk-73wmd3vp.js} +1 -1
  28. package/dist/{chunk-ajhrz96a.js → chunk-7vbwm0fg.js} +1 -1
  29. package/dist/{chunk-xcsf7my7.js → chunk-7z2wtxxj.js} +1 -1
  30. package/dist/{chunk-pknc4efv.js → chunk-8s9x1kcg.js} +1 -1
  31. package/dist/chunk-9ef162n1.js +2 -0
  32. package/dist/{chunk-ttny9g8k.js → chunk-9enf3e5m.js} +1 -1
  33. package/dist/{chunk-yzy6e4je.js → chunk-9znajpe5.js} +10 -10
  34. package/dist/{chunk-gpesxpwq.js → chunk-a9az6pen.js} +2 -2
  35. package/dist/chunk-abefheag.js +2 -0
  36. package/dist/{chunk-snmtft92.js → chunk-aqzs1rqe.js} +1 -1
  37. package/dist/{chunk-w6ncyp18.js → chunk-aspvxqzg.js} +1 -1
  38. package/dist/{chunk-b8cteeha.js → chunk-b70m51nc.js} +1 -1
  39. package/dist/{chunk-at84gyvf.js → chunk-b810yw1a.js} +1 -1
  40. package/dist/{chunk-5g39e9ra.js → chunk-b8hj1ena.js} +1 -1
  41. package/dist/chunk-bbad74mr.js +2 -0
  42. package/dist/chunk-bjy23bjm.js +2 -0
  43. package/dist/{chunk-0saq3nwy.js → chunk-brfcence.js} +1 -1
  44. package/dist/chunk-bx9mxc6z.js +2 -0
  45. package/dist/{chunk-gcavh7hk.js → chunk-c84gtc0v.js} +1 -1
  46. package/dist/{chunk-51gea48g.js → chunk-c9m4a26z.js} +1 -1
  47. package/dist/{chunk-y4dd2n2n.js → chunk-ctdmn0az.js} +1 -1
  48. package/dist/{chunk-szkq9s8n.js → chunk-cy6rz73m.js} +1 -1
  49. package/dist/{chunk-85p4dmft.js → chunk-daxm49bn.js} +1 -1
  50. package/dist/{chunk-18p8dqya.js → chunk-dc6z4asx.js} +1 -1
  51. package/dist/chunk-dfewnpk4.js +2 -0
  52. package/dist/{chunk-0mnv8pf5.js → chunk-dt03j5ff.js} +1 -1
  53. package/dist/{chunk-px0hqf1q.js → chunk-ebk6h629.js} +1 -1
  54. package/dist/{chunk-wm86mmgq.js → chunk-f1hfbnxv.js} +1 -1
  55. package/dist/chunk-f1yazmb2.js +2 -0
  56. package/dist/{chunk-n43zq50e.js → chunk-fbb6eaw3.js} +1 -1
  57. package/dist/chunk-fchtzkft.js +2 -0
  58. package/dist/{chunk-acctstj3.js → chunk-fe0pxn8d.js} +1 -1
  59. package/dist/{chunk-ka5wtqmw.js → chunk-fkvg0m44.js} +1 -1
  60. package/dist/{chunk-397rqs12.js → chunk-fvhg6b2b.js} +1 -1
  61. package/dist/{chunk-7c1qq9zq.js → chunk-g786azs5.js} +1 -1
  62. package/dist/chunk-ghvqy1n9.js +2 -0
  63. package/dist/{chunk-nnv8wytm.js → chunk-gvjkh5mv.js} +1 -1
  64. package/dist/chunk-gvyaeytx.js +3 -0
  65. package/dist/{chunk-tqayztkh.js → chunk-hbvxhwvt.js} +1 -1
  66. package/dist/{chunk-s3pvp8qv.js → chunk-hrxdza7v.js} +1 -1
  67. package/dist/chunk-hxk2wkmr.js +2 -0
  68. package/dist/{chunk-tph7b269.js → chunk-j03sjtfs.js} +1 -1
  69. package/dist/{chunk-4ee1aaet.js → chunk-j2d5v745.js} +1 -1
  70. package/dist/{chunk-ry1key0g.js → chunk-j6f8bq12.js} +1 -1
  71. package/dist/chunk-j9vkpac1.js +2 -0
  72. package/dist/{chunk-t5kwx6fa.js → chunk-jk6xwdfb.js} +1 -1
  73. package/dist/{chunk-5qseeh5t.js → chunk-jx6qn384.js} +1 -1
  74. package/dist/chunk-k0rrma2q.js +2 -0
  75. package/dist/{chunk-1ztjv7a4.js → chunk-k1jq596t.js} +1 -1
  76. package/dist/{chunk-wb24hk90.js → chunk-k29v4m21.js} +1 -1
  77. package/dist/{chunk-a50hb40e.js → chunk-k4417q3k.js} +1 -1
  78. package/dist/chunk-k4tbashh.js +2 -0
  79. package/dist/{chunk-s2kxa1tb.js → chunk-k9qd0v7e.js} +1 -1
  80. package/dist/{chunk-jd9nv63q.js → chunk-kbf0xkp1.js} +1 -1
  81. package/dist/{chunk-tzhcjtkr.js → chunk-kep0d46b.js} +1 -1
  82. package/dist/{chunk-djf1p5cy.js → chunk-kpj1tk19.js} +1 -1
  83. package/dist/{chunk-msmhta0w.js → chunk-kz7rzjfd.js} +1 -1
  84. package/dist/{chunk-zdzd2jb4.js → chunk-n9bmagzv.js} +1 -1
  85. package/dist/{chunk-2kv2gnzc.js → chunk-naxteb5j.js} +1 -1
  86. package/dist/{chunk-4hk5ewgp.js → chunk-nevmgfc7.js} +1 -1
  87. package/dist/{chunk-vhan24as.js → chunk-nsavhgg0.js} +1 -1
  88. package/dist/chunk-nwsnjyhg.js +2 -0
  89. package/dist/{chunk-wkcnyv6m.js → chunk-nyfqbqd2.js} +2 -2
  90. package/dist/chunk-pgbhyh3z.js +2 -0
  91. package/dist/{chunk-64ttktzc.js → chunk-pj9zybjf.js} +1 -1
  92. package/dist/chunk-pnp60knr.js +2 -0
  93. package/dist/{chunk-0gbptqh2.js → chunk-pytndzd2.js} +1 -1
  94. package/dist/{chunk-3by4c2g9.js → chunk-qc63mkgk.js} +1 -1
  95. package/dist/{chunk-f044qmn3.js → chunk-qs9bq14j.js} +1 -1
  96. package/dist/chunk-qvc2ddqn.js +2 -0
  97. package/dist/{chunk-6c1ebjat.js → chunk-rhk3w1hf.js} +1 -1
  98. package/dist/{chunk-v02j99gh.js → chunk-rra7n04f.js} +2 -2
  99. package/dist/{chunk-ycgtkfbm.js → chunk-rsjbw0qt.js} +1 -1
  100. package/dist/{chunk-9ebfmdyb.js → chunk-rwcnfdj5.js} +1 -1
  101. package/dist/{chunk-jdcn0ms1.js → chunk-s17bnxws.js} +2 -2
  102. package/dist/chunk-s4c6vvs3.js +2 -0
  103. package/dist/{chunk-prry9kgy.js → chunk-sh9m91w0.js} +1 -1
  104. package/dist/{chunk-aqrp68m6.js → chunk-sqwqyxzx.js} +1 -1
  105. package/dist/{chunk-wwghzbbg.js → chunk-szyc050e.js} +1 -1
  106. package/dist/{chunk-7yzyn9k7.js → chunk-tvvqcwa5.js} +1 -1
  107. package/dist/chunk-v4m87pv6.js +2 -0
  108. package/dist/chunk-v6kvq7ww.js +2 -0
  109. package/dist/chunk-vawmst0v.js +2 -0
  110. package/dist/{chunk-bnq0p4r4.js → chunk-vc506z79.js} +1 -1
  111. package/dist/{chunk-jryjwara.js → chunk-vvds14af.js} +1 -1
  112. package/dist/{chunk-raxr83fs.js → chunk-ws1s0ar4.js} +2 -2
  113. package/dist/chunk-x89acpn9.js +2 -0
  114. package/dist/{chunk-s5wwa0t4.js → chunk-xsd936j5.js} +2 -2
  115. package/dist/chunk-y2htmh35.js +2 -0
  116. package/dist/{chunk-kexk6z9s.js → chunk-y3m051g6.js} +1 -1
  117. package/dist/{chunk-zebypbks.js → chunk-z57k43ad.js} +2 -2
  118. package/dist/cli.js +14 -14
  119. package/dist/craft-entry.js +1 -1
  120. package/dist/craft.js +1 -1
  121. package/dist/database.js +1 -1
  122. package/dist/includes.d.ts +2 -0
  123. package/dist/includes.js +9 -2
  124. package/dist/pwa.js +2 -2
  125. package/dist/ssg.js +2 -2
  126. package/dist/visual-testing.js +1 -1
  127. package/package.json +5 -5
  128. package/dist/chunk-0ggq64sc.js +0 -2
  129. package/dist/chunk-1ppaw4xs.js +0 -2
  130. package/dist/chunk-455m2k1y.js +0 -2
  131. package/dist/chunk-65hqene1.js +0 -2
  132. package/dist/chunk-6vt9ddra.js +0 -2
  133. package/dist/chunk-6xmx6stb.js +0 -2
  134. package/dist/chunk-8618n28z.js +0 -2
  135. package/dist/chunk-8avktqwz.js +0 -2
  136. package/dist/chunk-8z11nkyk.js +0 -2
  137. package/dist/chunk-95jjdgmb.js +0 -2
  138. package/dist/chunk-9aw5d4rr.js +0 -2
  139. package/dist/chunk-9g14542g.js +0 -2
  140. package/dist/chunk-9h4fkwtj.js +0 -2
  141. package/dist/chunk-bxvqqejm.js +0 -2
  142. package/dist/chunk-bzmxbz48.js +0 -2
  143. package/dist/chunk-f9qrz82p.js +0 -2
  144. package/dist/chunk-g8vf2fc7.js +0 -2
  145. package/dist/chunk-h63vszd3.js +0 -2
  146. package/dist/chunk-h78pksyp.js +0 -2
  147. package/dist/chunk-hxf6zg80.js +0 -2
  148. package/dist/chunk-jr79tvvs.js +0 -2
  149. package/dist/chunk-jwnbwemq.js +0 -3
  150. package/dist/chunk-mvj75wef.js +0 -2
  151. package/dist/chunk-n0t2at1c.js +0 -2
  152. package/dist/chunk-v1j4myd8.js +0 -2
  153. package/dist/chunk-v33qvj8y.js +0 -2
  154. package/dist/chunk-vnh668fb.js +0 -2
  155. package/dist/chunk-vpbw6g2t.js +0 -2
  156. package/dist/chunk-w33gx25k.js +0 -2
  157. package/dist/chunk-w3dfvxar.js +0 -2
  158. package/dist/chunk-wcp0dt2c.js +0 -2
  159. package/dist/chunk-z82sc99z.js +0 -2
@@ -1,6 +1,20 @@
1
1
  import type { ImageDeliveryManifest } from 'ts-images/delivery';
2
+ /**
3
+ * Whether a WebP header declares an alpha channel.
4
+ *
5
+ * A simple `VP8 ` frame cannot hold one at all; `VP8X` says so in its flags and
6
+ * `VP8L` in the `alpha_is_used` bit after the dimensions.
7
+ */
8
+ export declare function webpHeaderHasAlpha(header: Uint8Array): boolean;
2
9
  /** Return build-time delivery metadata for one public image URL. */
3
10
  export declare function getImageDelivery(src: string): ImageDeliveryManifest | undefined;
11
+ /**
12
+ * Whether the delivered image at `src` has transparent pixels.
13
+ *
14
+ * Anything painted behind such an image shows through it for as long as it is
15
+ * there, so a placeholder has to stay out of it entirely.
16
+ */
17
+ export declare function isTransparentImage(src: string): boolean;
4
18
  /** Clear process-global delivery state between builds and tests. */
5
19
  export declare function clearImageDeliveryCatalog(): void;
6
20
  /**
@@ -1,10 +1,11 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
- import { generateThumbHash } from "ts-images";
4
+ import { decode, generateThumbHash } from "ts-images";
5
5
  import { createImageDeliveryCatalog } from "ts-images/delivery";
6
- const RASTER_EXTENSIONS = new Set([".avif", ".jpeg", ".jpg", ".png", ".webp"]), DEFAULT_WIDTHS = [320, 640, 960, 1280, 1920], DELIVERY_URL = "/_stx/images";
7
- let deliveryCatalog = new Map;
6
+ const RASTER_EXTENSIONS = new Set([".avif", ".jpeg", ".jpg", ".png", ".webp"]), DEFAULT_WIDTHS = [320, 640, 960, 1280, 1920], DELIVERY_URL = "/_stx/images", ALPHA_NAMESPACE = `stx:${DELIVERY_URL}:alpha-1`;
7
+ let deliveryCatalog = new Map, transparentSources = new Set;
8
+ const warnedOpaqueWebp = new Set;
8
9
  function publicUrl(relativePath) {
9
10
  return `/${relativePath.split(path.sep).map(encodeURIComponent).join("/")}`;
10
11
  }
@@ -12,10 +13,10 @@ function catalogName(relativePath) {
12
13
  const extension = path.extname(relativePath), readable = relativePath.slice(0, -extension.length).replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, ""), pathHash = createHash("sha256").update(relativePath).digest("hex").slice(0, 8);
13
14
  return `${readable || "image"}-${pathHash}`;
14
15
  }
15
- function deliveryStorage(outDir) {
16
+ function deliveryStorage(outDir, cacheNamespace = `stx:${DELIVERY_URL}`) {
16
17
  const url = (key) => `${DELIVERY_URL}/${key.split("/").map(encodeURIComponent).join("/")}`;
17
18
  return {
18
- cacheNamespace: `stx:${DELIVERY_URL}`,
19
+ cacheNamespace,
19
20
  async stat(key) {
20
21
  const file = path.join(outDir, key);
21
22
  try {
@@ -52,13 +53,114 @@ async function collectRasterImages(root, directory = root) {
52
53
  }
53
54
  return files;
54
55
  }
55
- function deliveryEntries(files) {
56
+ function deliveryEntries(files, alphaStorage) {
56
57
  return files.map((file) => ({
57
58
  key: publicUrl(file.relativePath),
58
59
  input: file.absolutePath,
59
- name: catalogName(file.relativePath)
60
+ name: catalogName(file.relativePath),
61
+ ...mayHaveAlpha(file.absolutePath) ? { options: { storage: alphaStorage } } : {}
60
62
  }));
61
63
  }
64
+ function readAt(fd, position, length) {
65
+ const buffer = Buffer.alloc(length), read = fs.readSync(fd, buffer, 0, length, position);
66
+ return buffer.subarray(0, read);
67
+ }
68
+ export function webpHeaderHasAlpha(header) {
69
+ if (header.length < 25)
70
+ return !1;
71
+ const text = (start, end) => String.fromCharCode(...header.subarray(start, end));
72
+ if (text(0, 4) !== "RIFF" || text(8, 12) !== "WEBP")
73
+ return !1;
74
+ const chunk = text(12, 16);
75
+ if (chunk === "VP8X")
76
+ return (header[20] & 16) !== 0;
77
+ if (chunk === "VP8L")
78
+ return ((header[21] | header[22] << 8 | header[23] << 16 | header[24] << 24) >>> 28 & 1) === 1;
79
+ return !1;
80
+ }
81
+ function mayHaveAlpha(file) {
82
+ let fd;
83
+ try {
84
+ fd = fs.openSync(file, "r");
85
+ const head = readAt(fd, 0, 33);
86
+ if (head.length >= 26 && head[0] === 137 && head.toString("latin1", 1, 4) === "PNG") {
87
+ const colorType = head[25];
88
+ if (colorType === 4 || colorType === 6)
89
+ return !0;
90
+ let offset = 8;
91
+ for (let i = 0;i < 64; i++) {
92
+ const chunk = readAt(fd, offset, 8);
93
+ if (chunk.length < 8)
94
+ return !1;
95
+ const type = chunk.toString("latin1", 4, 8);
96
+ if (type === "tRNS")
97
+ return !0;
98
+ if (type === "IDAT" || type === "IEND")
99
+ return !1;
100
+ offset += 12 + chunk.readUInt32BE(0);
101
+ }
102
+ return !1;
103
+ }
104
+ if (head.length >= 25 && head.toString("latin1", 0, 4) === "RIFF")
105
+ return webpHeaderHasAlpha(head);
106
+ return !1;
107
+ } catch {
108
+ return !1;
109
+ } finally {
110
+ if (fd !== void 0)
111
+ fs.closeSync(fd);
112
+ }
113
+ }
114
+ function hasVisibleAlpha(rgba) {
115
+ for (let i = 3;i < rgba.length; i += 4)
116
+ if (rgba[i] !== 255)
117
+ return !0;
118
+ return !1;
119
+ }
120
+ async function findTransparent(entries) {
121
+ const candidates = Object.entries(entries).filter(([, manifest]) => manifest.fallback.format === "png"), transparent = new Set, concurrency = 8;
122
+ for (let offset = 0;offset < candidates.length; offset += concurrency)
123
+ await Promise.all(candidates.slice(offset, offset + concurrency).map(async ([key, manifest]) => {
124
+ const smallest = manifest.variants.filter((variant) => variant.format === "png").sort((a, b) => a.width - b.width)[0];
125
+ try {
126
+ const image = await decode(new Uint8Array(await fs.promises.readFile(smallest?.path ?? manifest.fallback.path)));
127
+ if (hasVisibleAlpha(image.data))
128
+ transparent.add(key);
129
+ } catch {
130
+ transparent.add(key);
131
+ }
132
+ }));
133
+ return transparent;
134
+ }
135
+ function dropOpaqueWebp(entries, transparent) {
136
+ const dropped = [];
137
+ for (const key of transparent) {
138
+ const manifest = entries[key], webp = manifest?.variants.filter((variant) => variant.format === "webp") ?? [];
139
+ if (!manifest || webp.length === 0)
140
+ continue;
141
+ if (!webp.some((variant) => {
142
+ let fd;
143
+ try {
144
+ fd = fs.openSync(variant.path, "r");
145
+ return !webpHeaderHasAlpha(readAt(fd, 0, 32));
146
+ } catch {
147
+ return !0;
148
+ } finally {
149
+ if (fd !== void 0)
150
+ fs.closeSync(fd);
151
+ }
152
+ }))
153
+ continue;
154
+ manifest.variants = manifest.variants.filter((variant) => variant.format !== "webp");
155
+ delete manifest.sources.webp;
156
+ dropped.push(key);
157
+ if (!warnedOpaqueWebp.has(key)) {
158
+ warnedOpaqueWebp.add(key);
159
+ console.warn(`[stx-images] ${key} is transparent but its WebP variants have no alpha channel; serving PNG instead. Upgrade @stacksjs/ts-webp to 0.1.6 or later.`);
160
+ }
161
+ }
162
+ return dropped;
163
+ }
62
164
  async function decodableFiles(files) {
63
165
  const supported = [], concurrency = 8;
64
166
  for (let offset = 0;offset < files.length; offset += concurrency) {
@@ -116,8 +218,13 @@ export function getImageDelivery(src) {
116
218
  const key = normalizeLookupSource(src);
117
219
  return key ? deliveryCatalog.get(key) : void 0;
118
220
  }
221
+ export function isTransparentImage(src) {
222
+ const key = normalizeLookupSource(src);
223
+ return key ? transparentSources.has(key) : !1;
224
+ }
119
225
  export function clearImageDeliveryCatalog() {
120
226
  deliveryCatalog = new Map;
227
+ transparentSources = new Set;
121
228
  }
122
229
  export async function prepareImageDelivery(publicDir, outputDir) {
123
230
  if (!publicDir || !fs.existsSync(publicDir)) {
@@ -140,7 +247,7 @@ export async function prepareImageDelivery(publicDir, outputDir) {
140
247
  clearImageDeliveryCatalog();
141
248
  return { count: 0, fingerprint: "" };
142
249
  }
143
- const catalogOptions = {
250
+ const alphaStorage = deliveryStorage(path.join(outputDir, "_stx", "images"), ALPHA_NAMESPACE), catalogOptions = {
144
251
  outDir: path.join(outputDir, "_stx", "images"),
145
252
  storage: deliveryStorage(path.join(outputDir, "_stx", "images")),
146
253
  baseUrl: DELIVERY_URL,
@@ -156,7 +263,7 @@ export async function prepareImageDelivery(publicDir, outputDir) {
156
263
  try {
157
264
  catalog = await createImageDeliveryCatalog({
158
265
  ...catalogOptions,
159
- entries: deliveryEntries(files)
266
+ entries: deliveryEntries(files, alphaStorage)
160
267
  });
161
268
  } catch (error) {
162
269
  optimizedFiles = await decodableFiles(files);
@@ -181,9 +288,12 @@ export async function prepareImageDelivery(publicDir, outputDir) {
181
288
  }
182
289
  catalog = await createImageDeliveryCatalog({
183
290
  ...catalogOptions,
184
- entries: deliveryEntries(optimizedFiles)
291
+ entries: deliveryEntries(optimizedFiles, alphaStorage)
185
292
  });
186
293
  }
294
+ const transparent = await findTransparent(catalog.entries), droppedWebp = dropOpaqueWebp(catalog.entries, transparent);
187
295
  deliveryCatalog = new Map(Object.entries(catalog.entries));
188
- return { count: optimizedFiles.length, fingerprint: catalog.fingerprint };
296
+ transparentSources = transparent;
297
+ const fingerprint = transparent.size === 0 && droppedWebp.length === 0 ? catalog.fingerprint : createHash("sha256").update(catalog.fingerprint).update(JSON.stringify({ transparent: [...transparent].sort(), droppedWebp: droppedWebp.sort() })).digest("hex");
298
+ return { count: optimizedFiles.length, fingerprint };
189
299
  }
@@ -27,6 +27,11 @@ export interface ImagePlaceholder {
27
27
  dataUrl: string;
28
28
  /** `#rrggbb` average, painted under the mesh and used alone as a fallback. */
29
29
  color: string;
30
+ /**
31
+ * The image has transparent pixels. A placeholder painted behind it would
32
+ * show through for as long as it stayed, so the component renders none.
33
+ */
34
+ transparent?: boolean;
30
35
  }
31
36
  /**
32
37
  * The placeholder for `src`, or undefined when there is none.
@@ -19,6 +19,12 @@ export function setImagePlaceholder(urlPath, placeholder) {
19
19
  placeholders.set(urlPath, placeholder);
20
20
  warmed = !0;
21
21
  }
22
+ function hasTransparency(rgba) {
23
+ for (let i = 3;i < rgba.length; i += 4)
24
+ if (rgba[i] < 255)
25
+ return !0;
26
+ return !1;
27
+ }
22
28
  function averageColor(rgba) {
23
29
  let r = 0, g = 0, b = 0, n = 0;
24
30
  for (let i = 0;i < rgba.length; i += 4) {
@@ -111,8 +117,8 @@ export async function warmImagePlaceholders(publicDir, options = {}) {
111
117
  if (stat.size > maxBytes)
112
118
  return;
113
119
  const cached = cache[urlPath];
114
- if (cached && cached.mtimeMs === stat.mtimeMs && cached.size === stat.size) {
115
- placeholders.set(urlPath, { dataUrl: cached.dataUrl, color: cached.color });
120
+ if (cached && cached.mtimeMs === stat.mtimeMs && cached.size === stat.size && typeof cached.transparent === "boolean") {
121
+ placeholders.set(urlPath, { dataUrl: cached.dataUrl, color: cached.color, transparent: cached.transparent });
116
122
  return;
117
123
  }
118
124
  try {
@@ -121,7 +127,8 @@ export async function warmImagePlaceholders(publicDir, options = {}) {
121
127
  return;
122
128
  const { rgba, w, h } = tsImages.thumbHashToRGBA(hash), placeholder = {
123
129
  dataUrl: svgDataUrl(meshSvg(rgba, w, h)),
124
- color: averageColor(rgba)
130
+ color: averageColor(rgba),
131
+ transparent: hasTransparency(rgba)
125
132
  };
126
133
  placeholders.set(urlPath, placeholder);
127
134
  cache[urlPath] = { mtimeMs: stat.mtimeMs, size: stat.size, ...placeholder };
@@ -1,5 +1,5 @@
1
1
  import { forwardResolvedAttrs, forwardStaticAttrs } from "./attrs.js";
2
- import { getImageDelivery } from "./image-delivery.js";
2
+ import { getImageDelivery, isTransparentImage } from "./image-delivery.js";
3
3
  import { getImagePlaceholder } from "./image-placeholder.js";
4
4
  const DEFAULT_BREAKPOINTS = {
5
5
  sm: 640,
@@ -99,6 +99,9 @@ function transformSrc(src, width, height, provider, format) {
99
99
  }
100
100
  return src;
101
101
  }
102
+ function placeholderCleanup(properties) {
103
+ return `var s=this.style;${properties.map((property) => `s.${property}=''`).join(";")}`;
104
+ }
102
105
  function generateBlurPlaceholder(width, height, color = "#e5e7eb") {
103
106
  const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}"><rect width="100%" height="100%" fill="${color}"/></svg>`;
104
107
  return `data:image/svg+xml;base64,${btoa(svg)}`;
@@ -107,7 +110,7 @@ export const StxImageBuiltin = {
107
110
  name: "StxImage",
108
111
  aliases: ["Image", "stx-image", "stx-img"],
109
112
  render(props, _slotContent, _ctx) {
110
- const src = resolveProp(props, "src") || "", delivery = getImageDelivery(src), alt = resolveProp(props, "alt") || "", width = resolveProp(props, "width") || (delivery ? String(delivery.source.width) : void 0), height = resolveProp(props, "height") || (delivery ? String(delivery.source.height) : void 0), sizes = resolveProp(props, "sizes"), srcset = resolveProp(props, "srcset"), densities = resolveProp(props, "densities"), format = resolveProp(props, "format"), placeholder = resolveProp(props, "placeholder") || (delivery ? "thumbhash" : void 0), placeholderColor = resolveProp(props, "placeholderColor") || "#e5e7eb", provider = resolveProp(props, "provider"), className = resolveProp(props, "class") || resolveProp(props, "className") || "", style = resolveProp(props, "style") || "", quality = resolveProp(props, "quality"), lazy = resolveBoolProp(props, "lazy", !0), preload = resolveBoolProp(props, "preload", !1), priority = resolveBoolProp(props, "priority", !1), explicitLoading = resolveProp(props, "loading"), decoding = resolveProp(props, "decoding") || "async", usePicture = !!delivery || resolveBoolProp(props, "picture", !1) || !!format, numWidth = width ? Number.parseInt(width) : void 0, numHeight = height ? Number.parseInt(height) : void 0;
113
+ const src = resolveProp(props, "src") || "", delivery = getImageDelivery(src), alt = resolveProp(props, "alt") || "", width = resolveProp(props, "width") || (delivery ? String(delivery.source.width) : void 0), height = resolveProp(props, "height") || (delivery ? String(delivery.source.height) : void 0), sizes = resolveProp(props, "sizes"), srcset = resolveProp(props, "srcset"), densities = resolveProp(props, "densities"), format = resolveProp(props, "format"), transparent = isTransparentImage(src) || getImagePlaceholder(src)?.transparent === !0, placeholder = resolveProp(props, "placeholder") || (delivery && !transparent ? "thumbhash" : void 0), placeholderColor = resolveProp(props, "placeholderColor") || "#e5e7eb", provider = resolveProp(props, "provider"), className = resolveProp(props, "class") || resolveProp(props, "className") || "", style = resolveProp(props, "style") || "", quality = resolveProp(props, "quality"), lazy = resolveBoolProp(props, "lazy", !0), preload = resolveBoolProp(props, "preload", !1), priority = resolveBoolProp(props, "priority", !1), explicitLoading = resolveProp(props, "loading"), decoding = resolveProp(props, "decoding") || "async", usePicture = !!delivery || resolveBoolProp(props, "picture", !1) || !!format, numWidth = width ? Number.parseInt(width) : void 0, numHeight = height ? Number.parseInt(height) : void 0;
111
114
  let finalSrcset = srcset || "", finalSizes = "";
112
115
  if (delivery) {
113
116
  finalSrcset = delivery.sources[delivery.fallback.format] || "";
@@ -125,25 +128,30 @@ export const StxImageBuiltin = {
125
128
  styles.push(style);
126
129
  if (numWidth && numHeight)
127
130
  styles.push(`aspect-ratio:${numWidth}/${numHeight}`);
128
- if (placeholder === "blur" || placeholder === "color" || placeholder === "thumbhash") {
131
+ const placeholderProperties = [], derivedPlaceholder = placeholder === "blur" || placeholder === "color" || placeholder === "thumbhash";
132
+ if (derivedPlaceholder && !transparent) {
129
133
  const derived = delivery?.placeholder ? { dataUrl: delivery.placeholder.dataUrl, color: placeholderColor } : getImagePlaceholder(src);
130
- if (derived && placeholder === "color")
134
+ if (derived && placeholder === "color") {
131
135
  styles.push(`background-color:${derived.color}`);
132
- else if (derived) {
136
+ placeholderProperties.push("backgroundColor");
137
+ } else if (derived) {
133
138
  styles.push(`background-color:${derived.color}`);
134
139
  styles.push(`background-image:url(${derived.dataUrl})`);
135
140
  styles.push("background-size:cover");
136
141
  styles.push("background-repeat:no-repeat");
142
+ placeholderProperties.push("backgroundColor", "backgroundImage");
137
143
  } else {
138
144
  const placeholderUrl = generateBlurPlaceholder(numWidth || 16, numHeight || 9, placeholderColor);
139
145
  styles.push(`background-image:url(${placeholderUrl})`);
140
146
  styles.push("background-size:cover");
141
147
  styles.push("background-repeat:no-repeat");
148
+ placeholderProperties.push("backgroundImage");
142
149
  }
143
- } else if (placeholder && placeholder !== "empty" && placeholder !== "none") {
150
+ } else if (!derivedPlaceholder && placeholder && placeholder !== "empty" && placeholder !== "none") {
144
151
  styles.push(`background-image:url(${escapeAttr(placeholder)})`);
145
152
  styles.push("background-size:cover");
146
153
  styles.push("background-repeat:no-repeat");
154
+ placeholderProperties.push("backgroundImage");
147
155
  }
148
156
  const finalSrc = delivery?.fallback.url || transformSrc(src, numWidth, numHeight, provider, format), imgAttrs = [];
149
157
  imgAttrs.push(`src="${escapeAttr(finalSrc)}"`);
@@ -189,6 +197,11 @@ export const StxImageBuiltin = {
189
197
  "loading",
190
198
  "decoding"
191
199
  ]);
200
+ if (placeholderProperties.length > 0) {
201
+ const authorOnload = typeof props.static.onload === "string" ? props.static.onload : "", handler = placeholderCleanup(placeholderProperties) + (authorOnload ? `;${authorOnload}` : "");
202
+ imgAttrs.push(`onload="${escapeAttr(handler)}"`);
203
+ consumedStatic.add("onload");
204
+ }
192
205
  imgAttrs.push(...forwardStaticAttrs(props, consumedStatic));
193
206
  imgAttrs.push(...forwardResolvedAttrs(props, consumedStatic));
194
207
  const imgTag = `<img ${imgAttrs.join(" ")} />`;
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{tu as a,uu as b}from"./chunk-nyfqbqd2.js";import"./chunk-dc6z4asx.js";import"./chunk-vvds14af.js";export{a as prepareRuntimeConfig,b as generateRuntimeConfigTypes};
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{Ui as O,Vi as w,Wi as Z}from"./chunk-xwxdwqn9.js";import{gl as R,nl as U,tl as T}from"./chunk-s2kxa1tb.js";import{Io as W,fm as M,hq as k,yr as C}from"./chunk-spzbfqjn.js";import{Pu as E,Qu as L}from"./chunk-xcsf7my7.js";import{Uu as B}from"./chunk-ttny9g8k.js";import $ from"path";var Y=new Map;function b(Q,z){for(let J of Q.matchAll(/\b(?:const|let|var|function|class)\s+([A-Z_a-z$][\w$]*)/g))if(J[1])z.add(J[1]);for(let J of Q.matchAll(/\b(?:const|let|var)\s*\{([^{}]*)\}\s*=/g))for(let H of(J[1]??"").split(",")){let K=((H.includes(":")?H.split(":").pop():H)??"").replace(/=.*$/s,"").replace(/^\s*\.\.\./,"").trim();if(/^[A-Z_a-z$][\w$]*$/.test(K))z.add(K)}for(let J of Q.matchAll(/\b(?:const|let|var)\s*\[([^\]]*)\]\s*=/g))for(let H of(J[1]??"").split(",")){let V=H.replace(/=.*$/s,"").replace(/^\s*\.\.\./,"").trim();if(/^[A-Z_a-z$][\w$]*$/.test(V))z.add(V)}}async function l(Q){let z;if(Q)z=$.resolve(Q);else{let q=await C();z=$.resolve(q.root||process.cwd(),q.storesDir||"stores")}let J=new Bun.Glob("*.ts"),H=[];try{for await(let q of J.scan({cwd:z,absolute:!0})){let y=$.basename(q,".ts");if(["index","types"].includes(y))continue;if(q.includes(".d.ts"))continue;H.push(q)}}catch{return Z(Y,z,"",""),null}let V=()=>[...new Set([...H,...H.flatMap((q)=>R(q))])],K=O(V()),P=w(Y,z,K);if(P!==void 0)return P||null;if(H.length===0)return Z(Y,z,K,""),null;let A=[];for(let q of H){let y=await Bun.file(q).text();A.push({file:q,hasUseStore:/useStore\s*\(/.test(y)})}A.sort((q,y)=>{if(q.hasUseStore===y.hasUseStore)return 0;return q.hasUseStore?1:-1});let N=A.map((q)=>q.file),G=[],X=new Set,F=k({loader:"ts",target:"browser",define:M()});for(let q of N)try{let y=await Bun.file(q).text(),I=$.basename(q,".ts");if(b(y,X),U(y))y=await T(y,q,{projectRoot:process.cwd(),externalizeUserModules:!1});y=W(y),y=E(y),y=L(y),y=y.replace(/^export\s+(default\s+)?/gm,""),y=F.transformSync(y),G.push(`// Store: ${I}
2
+ import{Ui as O,Vi as w,Wi as Z}from"./chunk-xwxdwqn9.js";import{gl as R,nl as U,tl as T}from"./chunk-k9qd0v7e.js";import{Io as W,fm as M,iq as k,zr as C}from"./chunk-2cey22m2.js";import{Su as E,Tu as L}from"./chunk-7z2wtxxj.js";import{Xu as B}from"./chunk-9enf3e5m.js";import $ from"path";var Y=new Map;function b(Q,z){for(let J of Q.matchAll(/\b(?:const|let|var|function|class)\s+([A-Z_a-z$][\w$]*)/g))if(J[1])z.add(J[1]);for(let J of Q.matchAll(/\b(?:const|let|var)\s*\{([^{}]*)\}\s*=/g))for(let H of(J[1]??"").split(",")){let K=((H.includes(":")?H.split(":").pop():H)??"").replace(/=.*$/s,"").replace(/^\s*\.\.\./,"").trim();if(/^[A-Z_a-z$][\w$]*$/.test(K))z.add(K)}for(let J of Q.matchAll(/\b(?:const|let|var)\s*\[([^\]]*)\]\s*=/g))for(let H of(J[1]??"").split(",")){let V=H.replace(/=.*$/s,"").replace(/^\s*\.\.\./,"").trim();if(/^[A-Z_a-z$][\w$]*$/.test(V))z.add(V)}}async function l(Q){let z;if(Q)z=$.resolve(Q);else{let q=await C();z=$.resolve(q.root||process.cwd(),q.storesDir||"stores")}let J=new Bun.Glob("*.ts"),H=[];try{for await(let q of J.scan({cwd:z,absolute:!0})){let y=$.basename(q,".ts");if(["index","types"].includes(y))continue;if(q.includes(".d.ts"))continue;H.push(q)}}catch{return Z(Y,z,"",""),null}let V=()=>[...new Set([...H,...H.flatMap((q)=>R(q))])],K=O(V()),P=w(Y,z,K);if(P!==void 0)return P||null;if(H.length===0)return Z(Y,z,K,""),null;let A=[];for(let q of H){let y=await Bun.file(q).text();A.push({file:q,hasUseStore:/useStore\s*\(/.test(y)})}A.sort((q,y)=>{if(q.hasUseStore===y.hasUseStore)return 0;return q.hasUseStore?1:-1});let N=A.map((q)=>q.file),G=[],X=new Set,F=k({loader:"ts",target:"browser",define:M()});for(let q of N)try{let y=await Bun.file(q).text(),I=$.basename(q,".ts");if(b(y,X),U(y))y=await T(y,q,{projectRoot:process.cwd(),externalizeUserModules:!1});y=W(y),y=E(y),y=L(y),y=y.replace(/^export\s+(default\s+)?/gm,""),y=F.transformSync(y),G.push(`// Store: ${I}
3
3
  ${y.trim()}`)}catch(y){console.warn(`[stx] Failed to load store ${q}:`,y)}if(G.length===0)return Z(Y,z,K,""),null;let j=G.join(`
4
4
 
5
5
  `),x=`;(function(){
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{Hg as I}from"./chunk-dvvx1wny.js";import{yr as H}from"./chunk-spzbfqjn.js";import{ew as G}from"./chunk-jryjwara.js";import L from"path";async function Q(k={}){let J=performance.now(),A=k.root||process.cwd(),j=await H(A),B=k.ssr?.routeRules??j.routeRules??{};if(I(B),!j.ssr&&Object.keys(B).length)throw Error("routeRules require ssr: true and the production server; flat SSG output cannot apply request/cache policies");if(!j.ssr&&(k.ssr?.serverApi??j.serverApi))throw Error("serverApi requires ssr: true; flat SSG output cannot execute API endpoints");let q=j.ssr?"ssr":"ssg";console.log(`[stx build] Mode: ${q.toUpperCase()}${j.ssr?" (ssr: true in stx.config.ts)":" (default \u2014 ssr is false)"}`);let D,E;if(q==="ssg"){let{generateStaticSite:z}=await import("./ssg.js");D=await z({pagesDir:L.join(j.root||".",j.pagesDir||j.build?.pagesDir||"pages"),publicDir:j.publicDir||j.build?.publicDir||"public",outputDir:j.build?.outputDir||"dist",generate404:j.build?.generate404??!0,minify:j.build?.minify??!0,cleanOutput:j.build?.cleanOutput??!0,router:j.router,...k.ssg})}else{let{buildForProduction:z}=await import("./chunk-g8vf2fc7.js");E=await z({root:A,outputDir:".output",debug:k.debug,...k.ssr})}let K=Math.round(performance.now()-J);return{mode:q,ssg:D,ssr:E,duration:K}}
2
+ import{Hg as I}from"./chunk-dvvx1wny.js";import{zr as H}from"./chunk-2cey22m2.js";import{hw as G}from"./chunk-vvds14af.js";import L from"path";async function Q(k={}){let J=performance.now(),A=k.root||process.cwd(),j=await H(A),B=k.ssr?.routeRules??j.routeRules??{};if(I(B),!j.ssr&&Object.keys(B).length)throw Error("routeRules require ssr: true and the production server; flat SSG output cannot apply request/cache policies");if(!j.ssr&&(k.ssr?.serverApi??j.serverApi))throw Error("serverApi requires ssr: true; flat SSG output cannot execute API endpoints");let q=j.ssr?"ssr":"ssg";console.log(`[stx build] Mode: ${q.toUpperCase()}${j.ssr?" (ssr: true in stx.config.ts)":" (default \u2014 ssr is false)"}`);let D,E;if(q==="ssg"){let{generateStaticSite:z}=await import("./ssg.js");D=await z({pagesDir:L.join(j.root||".",j.pagesDir||j.build?.pagesDir||"pages"),publicDir:j.publicDir||j.build?.publicDir||"public",outputDir:j.build?.outputDir||"dist",generate404:j.build?.generate404??!0,minify:j.build?.minify??!0,cleanOutput:j.build?.cleanOutput??!0,router:j.router,...k.ssg})}else{let{buildForProduction:z}=await import("./chunk-273pkk23.js");E=await z({root:A,outputDir:".output",debug:k.debug,...k.ssr})}let K=Math.round(performance.now()-J);return{mode:q,ssg:D,ssr:E,duration:K}}
3
3
  export{Q as Ue};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{Wf as a}from"./chunk-rhk3w1hf.js";import"./chunk-8s9x1kcg.js";import"./chunk-a9az6pen.js";import"./chunk-dvvx1wny.js";import"./chunk-j03sjtfs.js";import"./chunk-t41aaehf.js";import"./chunk-09zjty4k.js";import"./chunk-z57k43ad.js";import"./chunk-2cey22m2.js";import"./chunk-ws1s0ar4.js";import"./chunk-b810yw1a.js";import"./chunk-fvhg6b2b.js";import"./chunk-sqwqyxzx.js";import"./chunk-273xtqav.js";import"./chunk-gvyaeytx.js";import"./chunk-j6f8bq12.js";import"./chunk-j2d5v745.js";import"./chunk-nyfqbqd2.js";import"./chunk-dc6z4asx.js";import"./chunk-pj9zybjf.js";import"./chunk-7z2wtxxj.js";import"./chunk-naxteb5j.js";import"./chunk-9enf3e5m.js";import"./chunk-3meekwv6.js";import"./chunk-rwcnfdj5.js";import"./chunk-vvds14af.js";export{a as buildForProduction};
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{ou as uJ}from"./chunk-4ee1aaet.js";import{ew as gJ}from"./chunk-jryjwara.js";import z from"path";import{hasLocalConfig as yJ}from"bunfig";var wJ={fg:{light:"gray-900",dark:"gray-100",description:"Primary text"},"fg-strong":{light:"gray-700",dark:"gray-300",description:"Labels, secondary headings"},"fg-muted":{light:"gray-600",dark:"gray-400",description:"Supporting text"},"fg-soft":{light:"gray-500",dark:"gray-400",description:"De-emphasised text"},"fg-subtle":{light:"gray-400",dark:"gray-500",description:"Placeholders, disabled text"},surface:{light:"gray-50",dark:"gray-800",description:"Page and panel background"},"surface-raised":{light:"gray-100",dark:"gray-700",description:"Cards, popovers"},"surface-sunken":{light:"gray-200",dark:"gray-700",description:"Wells, track backgrounds"},line:{light:"gray-200",dark:"gray-700",description:"Default border, divider"},"line-strong":{light:"gray-300",dark:"gray-600",description:"Input border, focus ring track"},accent:{light:"indigo-600",dark:"indigo-400",description:"Primary action, selected state"},info:{light:"blue-600",dark:"blue-400",description:"Informational emphasis, links"},danger:{light:"red-600",dark:"red-400",description:"Errors, destructive actions"},success:{light:"green-600",dark:"green-400",description:"Confirmation"},warning:{light:"yellow-500",dark:"yellow-400",description:"Caution"},"accent-solid":{light:"indigo-600",dark:"indigo-500",description:"Primary button fill"},"info-solid":{light:"blue-600",dark:"blue-500",description:"Informational fill"},"danger-solid":{light:"red-600",dark:"red-500",description:"Destructive button fill"},"success-solid":{light:"green-600",dark:"green-500",description:"Confirmation fill"}};function p(J){return`--stx-${J}`}function m(J,Q){let Z=Q.lastIndexOf("-");if(Z===-1)return typeof J[Q]==="string"?J[Q]:void 0;let $=J[Q.slice(0,Z)];if(!$||typeof $!=="object")return;let U=$[Q.slice(Z+1)];return typeof U==="string"?U:void 0}function BJ(J){let Q={};for(let[Z,$]of Object.entries(wJ)){let U=m(J,$.light);if(U===void 0)continue;Q[Z]=`var(${p(Z)}, ${U})`}return Q}function HJ(J){let Q=[],Z=[];for(let[$,U]of Object.entries(wJ)){let F=m(J,U.light),W=m(J,U.dark);if(F===void 0)continue;if(Q.push(` ${p($)}: ${F};`),W!==void 0)Z.push(` ${p($)}: ${W};`)}if(Q.length===0)return"";return["/* stx role tokens \u2014 override any of these to re-theme by meaning. */",":root {",...Q,"}",".dark {",...Z,"}",""].join(`
2
+ import{ru as uJ}from"./chunk-j2d5v745.js";import{hw as gJ}from"./chunk-vvds14af.js";import z from"path";import{hasLocalConfig as yJ}from"bunfig";var wJ={fg:{light:"gray-900",dark:"gray-100",description:"Primary text"},"fg-strong":{light:"gray-700",dark:"gray-300",description:"Labels, secondary headings"},"fg-muted":{light:"gray-600",dark:"gray-400",description:"Supporting text"},"fg-soft":{light:"gray-500",dark:"gray-400",description:"De-emphasised text"},"fg-subtle":{light:"gray-400",dark:"gray-500",description:"Placeholders, disabled text"},surface:{light:"gray-50",dark:"gray-800",description:"Page and panel background"},"surface-raised":{light:"gray-100",dark:"gray-700",description:"Cards, popovers"},"surface-sunken":{light:"gray-200",dark:"gray-700",description:"Wells, track backgrounds"},line:{light:"gray-200",dark:"gray-700",description:"Default border, divider"},"line-strong":{light:"gray-300",dark:"gray-600",description:"Input border, focus ring track"},accent:{light:"indigo-600",dark:"indigo-400",description:"Primary action, selected state"},info:{light:"blue-600",dark:"blue-400",description:"Informational emphasis, links"},danger:{light:"red-600",dark:"red-400",description:"Errors, destructive actions"},success:{light:"green-600",dark:"green-400",description:"Confirmation"},warning:{light:"yellow-500",dark:"yellow-400",description:"Caution"},"accent-solid":{light:"indigo-600",dark:"indigo-500",description:"Primary button fill"},"info-solid":{light:"blue-600",dark:"blue-500",description:"Informational fill"},"danger-solid":{light:"red-600",dark:"red-500",description:"Destructive button fill"},"success-solid":{light:"green-600",dark:"green-500",description:"Confirmation fill"}};function p(J){return`--stx-${J}`}function m(J,Q){let Z=Q.lastIndexOf("-");if(Z===-1)return typeof J[Q]==="string"?J[Q]:void 0;let $=J[Q.slice(0,Z)];if(!$||typeof $!=="object")return;let U=$[Q.slice(Z+1)];return typeof U==="string"?U:void 0}function BJ(J){let Q={};for(let[Z,$]of Object.entries(wJ)){let U=m(J,$.light);if(U===void 0)continue;Q[Z]=`var(${p(Z)}, ${U})`}return Q}function HJ(J){let Q=[],Z=[];for(let[$,U]of Object.entries(wJ)){let F=m(J,U.light),W=m(J,U.dark);if(F===void 0)continue;if(Q.push(` ${p($)}: ${F};`),W!==void 0)Z.push(` ${p($)}: ${W};`)}if(Q.length===0)return"";return["/* stx role tokens \u2014 override any of these to re-theme by meaning. */",":root {",...Q,"}",".dark {",...Z,"}",""].join(`
3
3
  `)}function OJ(J){return typeof J==="object"&&J!==null&&!Array.isArray(J)}function h(J,Q){let Z={...J};for(let[$,U]of Object.entries(Q))Z[$]=OJ(U)&&OJ(Z[$])?h(Z[$],U):U;return Z}function LJ(J={},Q={}){let Z=J.theme||{},$=Q.theme||{},{extend:U,...F}=$,{extend:W,...j}=Z,V=j.colors||{};j.colors={...V,...BJ(V)};let X=h(j,F),q=h(W||{},U||{});if(Object.keys(q).length>0)X.extend=q;let G=[...J.safelist||[],...Q.safelist||[]],w={...J.shortcuts||{},...Q.shortcuts||{}},K=[...J.preflights||[],...Q.preflights||[]];return{config:{...J,...Q,theme:X,safelist:G,shortcuts:w,...K.length>0?{preflights:K}:{},content:[],output:""},safelist:G,shortcuts:w,includePreflight:Q.preflight!==!1,minify:Q.minify===!0,tokenCSS:HJ(V)}}var x=/<script\b[^>]*>/iy,c=/<\/script\s*>/ig,S=/<style\b[^>]*>/iy,o=/<\/style\s*>/ig;function KJ(J,Q,Z,$){Z.lastIndex=Q;let U=Z.exec(J);if(!U||U.index!==Q)return-1;$.lastIndex=Z.lastIndex;let F=$.exec(J);if(!F)return-1;return F.index+F[0].length}function l(J,Q){return KJ(J,Q,x,c)}function IJ(J,Q){return KJ(J,Q,S,o)}function iJ(J,Q){if(!J.startsWith("<!--",Q))return-1;let Z=J.indexOf("-->",Q+4);if(Z===-1)return-1;return Z+3}function DJ(J,Q){if(J.startsWith("<!--",Q)){let U=iJ(J,Q);return U===-1?J.length:U}if(x.lastIndex=Q,x.exec(J)?.index===Q){c.lastIndex=x.lastIndex;let U=c.exec(J);return U?U.index+U[0].length:J.length}if(S.lastIndex=Q,S.exec(J)?.index===Q){o.lastIndex=S.lastIndex;let U=o.exec(J);return U?U.index+U[0].length:J.length}return-1}function rJ(J,Q){let Z=[],$=0,U=J.length,F=!1,W=null;while($<U){let j=J[$];if(F){if(W){if(j===W)W=null}else if(j==='"'||j==="'")W=j;else if(j===">")F=!1;$++;continue}if(j!=="<"){let G=J.indexOf("<",$+1);if(G===-1)break;$=G;continue}let V=Q(J,$);if(V>$){Z.push({start:$,end:V,token:J.slice($,V)}),$=V;continue}let X=DJ(J,$);if(X>$){$=X;continue}let q=J.charCodeAt($+1);if(q>=65&&q<=90||q>=97&&q<=122)F=!0;$++}return Z}function vQ(J){let Q=0,Z=0,$=0,U=!1,F=null;while($<J.length){if(U){let G=J[$];if(F){if(G===F)F=null}else if(G==='"'||G==="'")F=G;else if(G===">")U=!1;$++;continue}let W=J.indexOf("<",$),j=W===-1?J.length:W;while($<j){let G=J[$++];if(G==="{")Q++;else if(G==="}")Z++;if(Q>=2&&Z>=2)return!0}if(W===-1)break;let V=DJ(J,W);if(V>W){$=V;continue}let X=J.charCodeAt(W+1),q=X===47?J.charCodeAt(W+2):X;if(q>=65&&q<=90||q>=97&&q<=122)U=!0;$=W+1}return!1}function NJ(J,Q){while(J.size>=Q){let Z=J.keys().next();if(Z.done)return;J.delete(Z.value)}}var nJ=65536,cJ=12,i=new Map;function a(J,Q,Z,$){let U=$!==void 0&&J.length>=nJ,F=U?`${$}\x00${J}`:"";if(U){let q=i.get(F);if(q)return{output:q.output,tokens:q.tokens.slice()}}let W=rJ(J,Q);if(W.length===0)return{output:J,tokens:[]};let j=W.map((q)=>q.token),V="",X=0;for(let q=0;q<W.length;q++){let G=W[q];V+=J.slice(X,G.start),V+=Z(G.token,q),X=G.end}if(V+=J.slice(X),U)return NJ(i,cJ),i.set(F,{output:V,tokens:j}),{output:V,tokens:j.slice()};return{output:V,tokens:j}}var oJ=65536,lJ=4,r=new Map;function n(J,Q,Z){return{output:Q,scripts:Z,restore:($)=>$===Q?J:aJ($,Z)}}function RQ(J){let Q=J.length>=oJ;if(Q){let U=r.get(J);if(U)return n(J,U.output,U.scripts.slice())}let{output:Z,tokens:$}=a(J,l,(U,F)=>`\x00STX_SCRIPT_${F}\x00`);if(Q)return NJ(r,lJ),r.set(J,{output:Z,scripts:$}),n(J,Z,$.slice());return n(J,Z,$)}function aJ(J,Q){if(Q.length===0)return J;return J.replace(/\x00STX_SCRIPT_(\d+)\x00/g,(Z,$)=>Q[+$]??"")}function MJ(J,Q=""){let Z=`${J}${Q}`,$=0;for(let U=0;U<Z.length;U++){let F=Z.charCodeAt(U);$=($<<5)-$+F,$=$&$}return`stx-${Math.abs($).toString(36)}`}function PJ(J,Q,Z={}){let{prefix:$="",preserveHost:U=!0,scopeKeyframes:F=!0,scopeCustomProperties:W=!1}=Z;if(!J.trim())return"";let j=s(J),V=[],X=new Map;if(F)for(let q of j){let G=q.selector.match(/@keyframes\s+([a-z_-][a-z0-9_-]*)/i);if(G){let w=G[1],K=`${Q}_${w}`;X.set(w,K)}}for(let q of j){let G=AJ(q,Q,$,U,X,W);V.push(G)}return V.join(`
4
4
 
5
5
  `)}function s(J){let Q=[],Z=J.replace(/\/\*[\s\S]*?\*\//g,""),$=0,U="",F=!1,W="";for(let j=0;j<Z.length;j++){let V=Z[j];if(V==="@"&&$===0)F=!0;if(V==="{")$++;else if(V==="}"){if($--,$===0){if(F){W+=V;let X=W.match(/@([a-z-]+)\s*([^{]*)\{([\s\S]*)\}/i);if(X){let[,q,G,w]=X;if(q==="keyframes")Q.push({selector:`@keyframes ${G.trim()}`,declarations:w.trim()});else if(q==="media"||q==="supports"||q==="container"){let K=s(w);Q.push({selector:`@${q} ${G.trim()}`,declarations:K.map((M)=>`${M.selector} { ${M.declarations} }`).join(`
@@ -17,7 +17,7 @@ catch (e) {
17
17
  }
18
18
  throw e;
19
19
  }
20
- `),U.set(X,q)}return q(...j)}catch{return}}};if(this.pool.length<this.maxPoolSize)this.pool.push({func:W,context:Q.slice()});return W}clear(){this.pool.length=0,this.fnCache.clear()}}var CQ=new bJ;class kJ{metrics=new Map;budgets=new Map;violations=[];maxViolations=100;violationHandlers=[];enabled=!0;setEnabled(J){this.enabled=J}isEnabled(){return this.enabled}setBudget(J,Q){this.budgets.set(J,{warnThreshold:0.8,action:"warn",...Q})}setBudgets(J){for(let[Q,Z]of Object.entries(J))this.setBudget(Q,Z)}removeBudget(J){this.budgets.delete(J)}getBudgets(){let J={};for(let[Q,Z]of this.budgets.entries())J[Q]=Z;return J}onViolation(J){this.violationHandlers.push(J)}offViolation(J){let Q=this.violationHandlers.indexOf(J);if(Q!==-1)this.violationHandlers.splice(Q,1)}time(J,Q){if(!this.enabled)return Q();let Z=performance.now(),$=Q(),U=performance.now()-Z;return this.recordTime(J,U),this.checkBudget(J,U),$}async timeAsync(J,Q){if(!this.enabled)return Q();let Z=performance.now(),$=await Q(),U=performance.now()-Z;return this.recordTime(J,U),this.checkBudget(J,U),$}checkBudget(J,Q){let Z=this.budgets.get(J);if(!Z)return;let $=Q/Z.maxTime*100,U=Z.warnThreshold!==void 0?Q>=Z.maxTime*Z.warnThreshold&&Q<Z.maxTime:!1,F=Q>=Z.maxTime;if(!U&&!F)return;let W={label:J,actualTime:Q,budgetTime:Z.maxTime,exceedancePercent:$,timestamp:new Date,isWarning:U};this.violations.push(W);while(this.violations.length>this.maxViolations)this.violations.shift();for(let V of this.violationHandlers)try{V(W)}catch{}let j=U?`[Performance Warning] "${J}" took ${Q.toFixed(2)}ms (${$.toFixed(1)}% of ${Z.maxTime}ms budget)`:`[Performance Budget Exceeded] "${J}" took ${Q.toFixed(2)}ms (exceeded ${Z.maxTime}ms budget by ${($-100).toFixed(1)}%)`;switch(Z.action){case"log":console.log(j);break;case"warn":console.warn(j);break;case"error":console.error(j);break;case"throw":if(F)throw Error(j);else console.warn(j);break}}recordTime(J,Q){let Z=this.metrics.get(J);if(Z)Z.count++,Z.totalTime+=Q,Z.maxTime=Math.max(Z.maxTime,Q),Z.minTime=Math.min(Z.minTime,Q);else this.metrics.set(J,{count:1,totalTime:Q,maxTime:Q,minTime:Q})}getStats(J){if(J){let Z=this.metrics.get(J);if(!Z)return{};let $=this.budgets.get(J);return{count:Z.count,avgTime:Z.totalTime/Z.count,totalTime:Z.totalTime,maxTime:Z.maxTime,minTime:Z.minTime,budget:$?.maxTime,budgetUtilization:$?Z.totalTime/Z.count/$.maxTime*100:void 0}}let Q={};for(let[Z,$]of this.metrics.entries()){let U=this.budgets.get(Z);Q[Z]={count:$.count,avgTime:$.totalTime/$.count,totalTime:$.totalTime,maxTime:$.maxTime,minTime:$.minTime,budget:U?.maxTime,budgetUtilization:U?$.totalTime/$.count/U.maxTime*100:void 0}}return Q}getViolations(J){if(J)return this.violations.filter((Q)=>Q.label===J);return[...this.violations]}getViolationStats(){let J={},Q=0,Z=0;for(let $ of this.violations)if(J[$.label]=(J[$.label]||0)+1,$.isWarning)Q++;else Z++;return{total:this.violations.length,byLabel:J,warnings:Q,errors:Z}}clear(){this.metrics.clear()}clearViolations(){this.violations.length=0}clearBudgets(){this.budgets.clear()}reset(){this.clear(),this.clearViolations(),this.clearBudgets(),this.violationHandlers.length=0}}var $J=null;function WQ(){if(!$J)$J=new kJ;return $J}var gQ=new Proxy({},{get(J,Q){return WQ()[Q]}});var xJ=[];function SJ(J){let Q=new ZJ(J);return xJ.push(Q),Q}function mQ(){for(let J of xJ)J.clear()}function UJ(J,...Q){return`${Q.map((Z)=>String(Z??"")).join("\x00")}\x00${J.length}\x00${Bun.hash(J)}`}function hQ(J){let Q=[];for(let Z of new Set(J))try{Q.push({path:Z,mtimeMs:EJ.statSync(Z).mtimeMs})}catch{}return Q}function iQ(J){for(let Q of J)try{if(EJ.statSync(Q.path).mtimeMs!==Q.mtimeMs)return!1}catch{return!1}return!0}var O=null,WJ=!1,H=null,T="",A=!1,dJ=256,D=new Map,L=new Map,N=null,b=null;function y(J){return Bun.hash(J).toString(16).padStart(16,"0").slice(0,16)}function FJ(J,Q){if(D.has(J))D.delete(J);else if(D.size>=dJ)D.delete(D.keys().next().value);D.set(J,Q)}function VQ(J){let Q=y(J);if(L.has(Q))L.delete(Q);else if(L.size>=dJ)L.delete(L.keys().next().value);return L.set(Q,J),Q}function eQ(J){let Q=L.get(J);if(Q===void 0)return;return L.delete(J),L.set(J,Q),Q}async function XQ(J){if(!N)return null;try{let Q=Bun.file(z.join(N,`cw-${y(J)}.css`));if(!await Q.exists())return null;return await Q.text()}catch{return null}}async function jQ(J,Q){if(!N)return;try{if(!fs.existsSync(N))fs.mkdirSync(N,{recursive:!0});await Bun.write(z.join(N,`cw-${y(J)}.css`),Q)}catch{}}async function fJ(J){try{let Q=await import(J);if(Q&&Q.CSSGenerator)return{CSSGenerator:Q.CSSGenerator,config:Q.config,build:Q.build,defaultConfig:Q.defaultConfig,extractClasses:Q.extractClasses}}catch{}return null}var qQ=[["@stacksjs","ts-css","dist","engine","index.js"],["@stacksjs","ts-css","src","engine","index.ts"]],GQ=["@stacksjs/ts-css/engine","@stacksjs/ts-css/dist/engine/index.js"];function zQ(){let J=[],Q=process.cwd();while(Q!==z.dirname(Q)){for(let Z of["node_modules","pantry"])for(let $ of qQ)J.push(z.join(Q,Z,...$));Q=z.dirname(Q)}return J}function YQ(){let J=[],Q=process.env.HOME||process.env.USERPROFILE||"",Z=[Q&&z.join(Q,"Code","Tools","ts-css"),Q&&z.join(Q,"Code","Tools","crosswind"),Q&&z.join(Q,"repos","stacks-org","ts-css"),Q&&z.join(Q,"repos","stacks-org","crosswind"),z.join(process.cwd(),"..","ts-css"),z.join(process.cwd(),"..","crosswind")].filter(Boolean);for(let $ of Z)J.push(z.join($,"packages","toolkit","dist","engine","index.js")),J.push(z.join($,"packages","toolkit","src","engine","index.ts"));if(Q)J.push(z.join(Q,"Code","Tools","stx","node_modules","@stacksjs","ts-css","dist","engine","index.js"));return J}async function pJ(){if(WJ)return O;WJ=!0;try{let J=async(U)=>{for(let F of U){if(!await Bun.file(F).exists())continue;let W=await fJ(F);if(W){if(!process.env.STACKS_DEV_QUIET)console.log(`${Y.green}[ts-css]${Y.reset} CSS engine loaded from ${z.dirname(z.dirname(F))}`);return W}}return null};if(process.env.CROSSWIND_SRC){let U=z.resolve(process.env.CROSSWIND_SRC),F=await J([U]);if(!F)throw Error(`CROSSWIND_SRC did not resolve to a Css module: ${U}`);return O=F,O}let Q=await J(zQ());if(Q)return O=Q,O;let Z=GQ;for(let U of Z){let F=await fJ(U);if(F){if(O=F,!process.env.STACKS_DEV_QUIET)console.log(`${Y.green}[ts-css]${Y.reset} CSS engine loaded`);return O}}let $=await J(YQ());if($)return O=$,O;throw Error("Css CSSGenerator not found in any location")}catch{return console.warn(`${Y.yellow}[ts-css] CSS engine not available, Tailwind styles will not be generated${Y.reset}`),console.warn(`${Y.yellow}Run 'bun add @stacksjs/ts-css' to enable CSS generation${Y.reset}`),null}}function J0(){VJ.clear(),O=null,WJ=!1,H=null,T="",D.clear(),L.clear(),b=null}var CJ=!1;async function mJ(J){try{let Q=yJ({name:"css",cwd:J})?"css":yJ({name:"crosswind",cwd:J})?"crosswind":null;if(!Q)return null;if(Q==="crosswind"&&!process.env.STACKS_DEV_QUIET&&!CJ)CJ=!0,console.warn(`${Y.yellow}[ts-css]${Y.reset} Reading the CSS config from a \`crosswind\` file. Rename it to \`css\` (e.g. config/css.ts) \u2014 the old name is deprecated.`);let{loadConfigWithResult:Z}=await import("bunfig"),$=await Z({name:Q,cwd:J,defaultConfig:{},checkEnv:!1,verbose:!1});if(!$?.path||!$.config||Object.keys($.config).length===0)return null;let U=z.relative(J,$.path);if(!process.env.STACKS_DEV_QUIET)console.log(`${Y.green}[ts-css]${Y.reset} Loaded config from ${U||$.path}`);return $.config}catch(Q){if(Q instanceof Error&&Q.name==="ConfigNotFoundError")return null;return console.warn(`${Y.yellow}[ts-css]${Y.reset} Failed to load css config:`,Q instanceof Error?Q.message:Q),null}}async function wQ(J){let Q=null;try{let{loadStxConfig:Z}=await import("./chunk-w3dfvxar.js"),$=await Z(J);if($.css)if(typeof $.css==="string"){let U=z.isAbsolute($.css)?$.css:z.resolve(J,$.css);if(await Bun.file(U).exists()){let F=await import(U);Q=F.default||F,console.log(`${Y.green}[ts-css]${Y.reset} Loaded config from stx.config.ts \u2192 ${$.css}`)}}else{if(Q={...$.css,content:$.css.content||[],preflight:$.css.preflight??!0,minify:$.css.minify??!1},$.css.config){let U=z.isAbsolute($.css.config)?$.css.config:z.resolve(J,$.css.config);if(await Bun.file(U).exists()){let F=await import(U);Q={...F.default||F,...Q}}}console.log(`${Y.green}[ts-css]${Y.reset} Using inline CSS config from stx.config.ts`)}}catch{}return Q||await mJ(J)}function BQ(J){try{let Q=new WeakSet;return y(JSON.stringify(J??{},(Z,$)=>{if(typeof $==="function")return`[fn]${String($)}`;if(typeof $==="object"&&$!==null){if(Q.has($))return"[circular]";Q.add($)}return $})??"")}catch{return"unhashable"}}async function HQ(J){if(A)return T;A=!0;try{let Q=await pJ();if(!Q||!Q.build)return A=!1,"";if(!H)H=await mJ(J);if(!H)return A=!1,"";let Z=Q.defaultConfig?.theme||{},$=H.theme||{},U={...Q.defaultConfig,...H,theme:{...Z,...$,extend:{...Z.extend||{},...$.extend||{}}}},F=performance.now(),W=await Q.build(U),j=performance.now()-F;if(T=W.css,console.log(`${Y.cyan}[ts-css]${Y.reset} Built ${W.classes.size} classes in ${j.toFixed(1)}ms`),U.output){let V=z.isAbsolute(U.output)?U.output:z.join(J,U.output),X=z.dirname(V);if(!fs.existsSync(X))fs.mkdirSync(X,{recursive:!0});await Bun.write(V,W.css)}return A=!1,W.css}catch(Q){return console.error(`${Y.red}[ts-css]${Y.reset} Build error:`,Q),A=!1,T}}async function Q0(J){H=null,await HQ(J)}function $0(){return T}function OQ(J){let Q=new Set,Z=/class\s*=\s*["']([^"']+)["']/gi,$=Z.exec(J);while($!==null){for(let W of $[1].split(/\s+/))if(W.trim())Q.add(W.trim());$=Z.exec(J)}let U=/(?:x-class|:class)\s*=\s*"([^"]+)"/gi,F=U.exec(J);while(F!==null){let W=F[1].match(/'([^']+)'/g);if(W){for(let j of W)for(let V of j.slice(1,-1).split(/\s+/))if(V.trim())Q.add(V.trim())}F=U.exec(J)}return Q}var VJ=SJ(64);async function LQ(J,Q){let Z=VJ.get(UJ(J,Q,b));if(Z!==void 0)return Z;let $=await KQ(J,Q);if($)VJ.set(UJ(J,Q,b),$);return $}async function KQ(J,Q){try{let Z=await pJ();if(!Z)return"";let $=typeof Z.extractClasses==="function"?Z.extractClasses(J):OQ(J);if($.size===0)return"";let U=Q?z.resolve(Q):process.cwd();if(!N)N=uJ(U,"cache");let F=[...$].sort().join(" "),W=`${b||"default"}::${F}`,j=D.get(W);if(j!==void 0)return FJ(W,j),j;let V=await XQ(W);if(V!==null)return FJ(W,V),V;if(!H)H=await wQ(U),b=BQ(H);let X=Z.defaultConfig||Z.config,q=H||{},G=LJ(X,q),{safelist:w,includePreflight:K,minify:M,tokenCSS:hJ}=G,XJ=G.config,_=new Z.CSSGenerator(XJ);for(let B of w)_.generate(B);for(let B of $)_.generate(B);let I=_.toCSS(K,M),jJ=XJ.shortcuts||q.shortcuts||{};for(let[B,f]of Object.entries(jJ)){if(!$.has(B)&&!w.includes(B))continue;let C=f.split(/\s+/).filter(Boolean);for(let R of C)_.generate(R)}I=_.toCSS(K,M);let v=I.split(`
20
+ `),U.set(X,q)}return q(...j)}catch{return}}};if(this.pool.length<this.maxPoolSize)this.pool.push({func:W,context:Q.slice()});return W}clear(){this.pool.length=0,this.fnCache.clear()}}var CQ=new bJ;class kJ{metrics=new Map;budgets=new Map;violations=[];maxViolations=100;violationHandlers=[];enabled=!0;setEnabled(J){this.enabled=J}isEnabled(){return this.enabled}setBudget(J,Q){this.budgets.set(J,{warnThreshold:0.8,action:"warn",...Q})}setBudgets(J){for(let[Q,Z]of Object.entries(J))this.setBudget(Q,Z)}removeBudget(J){this.budgets.delete(J)}getBudgets(){let J={};for(let[Q,Z]of this.budgets.entries())J[Q]=Z;return J}onViolation(J){this.violationHandlers.push(J)}offViolation(J){let Q=this.violationHandlers.indexOf(J);if(Q!==-1)this.violationHandlers.splice(Q,1)}time(J,Q){if(!this.enabled)return Q();let Z=performance.now(),$=Q(),U=performance.now()-Z;return this.recordTime(J,U),this.checkBudget(J,U),$}async timeAsync(J,Q){if(!this.enabled)return Q();let Z=performance.now(),$=await Q(),U=performance.now()-Z;return this.recordTime(J,U),this.checkBudget(J,U),$}checkBudget(J,Q){let Z=this.budgets.get(J);if(!Z)return;let $=Q/Z.maxTime*100,U=Z.warnThreshold!==void 0?Q>=Z.maxTime*Z.warnThreshold&&Q<Z.maxTime:!1,F=Q>=Z.maxTime;if(!U&&!F)return;let W={label:J,actualTime:Q,budgetTime:Z.maxTime,exceedancePercent:$,timestamp:new Date,isWarning:U};this.violations.push(W);while(this.violations.length>this.maxViolations)this.violations.shift();for(let V of this.violationHandlers)try{V(W)}catch{}let j=U?`[Performance Warning] "${J}" took ${Q.toFixed(2)}ms (${$.toFixed(1)}% of ${Z.maxTime}ms budget)`:`[Performance Budget Exceeded] "${J}" took ${Q.toFixed(2)}ms (exceeded ${Z.maxTime}ms budget by ${($-100).toFixed(1)}%)`;switch(Z.action){case"log":console.log(j);break;case"warn":console.warn(j);break;case"error":console.error(j);break;case"throw":if(F)throw Error(j);else console.warn(j);break}}recordTime(J,Q){let Z=this.metrics.get(J);if(Z)Z.count++,Z.totalTime+=Q,Z.maxTime=Math.max(Z.maxTime,Q),Z.minTime=Math.min(Z.minTime,Q);else this.metrics.set(J,{count:1,totalTime:Q,maxTime:Q,minTime:Q})}getStats(J){if(J){let Z=this.metrics.get(J);if(!Z)return{};let $=this.budgets.get(J);return{count:Z.count,avgTime:Z.totalTime/Z.count,totalTime:Z.totalTime,maxTime:Z.maxTime,minTime:Z.minTime,budget:$?.maxTime,budgetUtilization:$?Z.totalTime/Z.count/$.maxTime*100:void 0}}let Q={};for(let[Z,$]of this.metrics.entries()){let U=this.budgets.get(Z);Q[Z]={count:$.count,avgTime:$.totalTime/$.count,totalTime:$.totalTime,maxTime:$.maxTime,minTime:$.minTime,budget:U?.maxTime,budgetUtilization:U?$.totalTime/$.count/U.maxTime*100:void 0}}return Q}getViolations(J){if(J)return this.violations.filter((Q)=>Q.label===J);return[...this.violations]}getViolationStats(){let J={},Q=0,Z=0;for(let $ of this.violations)if(J[$.label]=(J[$.label]||0)+1,$.isWarning)Q++;else Z++;return{total:this.violations.length,byLabel:J,warnings:Q,errors:Z}}clear(){this.metrics.clear()}clearViolations(){this.violations.length=0}clearBudgets(){this.budgets.clear()}reset(){this.clear(),this.clearViolations(),this.clearBudgets(),this.violationHandlers.length=0}}var $J=null;function WQ(){if(!$J)$J=new kJ;return $J}var gQ=new Proxy({},{get(J,Q){return WQ()[Q]}});var xJ=[];function SJ(J){let Q=new ZJ(J);return xJ.push(Q),Q}function mQ(){for(let J of xJ)J.clear()}function UJ(J,...Q){return`${Q.map((Z)=>String(Z??"")).join("\x00")}\x00${J.length}\x00${Bun.hash(J)}`}function hQ(J){let Q=[];for(let Z of new Set(J))try{Q.push({path:Z,mtimeMs:EJ.statSync(Z).mtimeMs})}catch{}return Q}function iQ(J){for(let Q of J)try{if(EJ.statSync(Q.path).mtimeMs!==Q.mtimeMs)return!1}catch{return!1}return!0}var O=null,WJ=!1,H=null,T="",A=!1,dJ=256,D=new Map,L=new Map,N=null,b=null;function y(J){return Bun.hash(J).toString(16).padStart(16,"0").slice(0,16)}function FJ(J,Q){if(D.has(J))D.delete(J);else if(D.size>=dJ)D.delete(D.keys().next().value);D.set(J,Q)}function VQ(J){let Q=y(J);if(L.has(Q))L.delete(Q);else if(L.size>=dJ)L.delete(L.keys().next().value);return L.set(Q,J),Q}function eQ(J){let Q=L.get(J);if(Q===void 0)return;return L.delete(J),L.set(J,Q),Q}async function XQ(J){if(!N)return null;try{let Q=Bun.file(z.join(N,`cw-${y(J)}.css`));if(!await Q.exists())return null;return await Q.text()}catch{return null}}async function jQ(J,Q){if(!N)return;try{if(!fs.existsSync(N))fs.mkdirSync(N,{recursive:!0});await Bun.write(z.join(N,`cw-${y(J)}.css`),Q)}catch{}}async function fJ(J){try{let Q=await import(J);if(Q&&Q.CSSGenerator)return{CSSGenerator:Q.CSSGenerator,config:Q.config,build:Q.build,defaultConfig:Q.defaultConfig,extractClasses:Q.extractClasses}}catch{}return null}var qQ=[["@stacksjs","ts-css","dist","engine","index.js"],["@stacksjs","ts-css","src","engine","index.ts"]],GQ=["@stacksjs/ts-css/engine","@stacksjs/ts-css/dist/engine/index.js"];function zQ(){let J=[],Q=process.cwd();while(Q!==z.dirname(Q)){for(let Z of["node_modules","pantry"])for(let $ of qQ)J.push(z.join(Q,Z,...$));Q=z.dirname(Q)}return J}function YQ(){let J=[],Q=process.env.HOME||process.env.USERPROFILE||"",Z=[Q&&z.join(Q,"Code","Tools","ts-css"),Q&&z.join(Q,"Code","Tools","crosswind"),Q&&z.join(Q,"repos","stacks-org","ts-css"),Q&&z.join(Q,"repos","stacks-org","crosswind"),z.join(process.cwd(),"..","ts-css"),z.join(process.cwd(),"..","crosswind")].filter(Boolean);for(let $ of Z)J.push(z.join($,"packages","toolkit","dist","engine","index.js")),J.push(z.join($,"packages","toolkit","src","engine","index.ts"));if(Q)J.push(z.join(Q,"Code","Tools","stx","node_modules","@stacksjs","ts-css","dist","engine","index.js"));return J}async function pJ(){if(WJ)return O;WJ=!0;try{let J=async(U)=>{for(let F of U){if(!await Bun.file(F).exists())continue;let W=await fJ(F);if(W){if(!process.env.STACKS_DEV_QUIET)console.log(`${Y.green}[ts-css]${Y.reset} CSS engine loaded from ${z.dirname(z.dirname(F))}`);return W}}return null};if(process.env.CROSSWIND_SRC){let U=z.resolve(process.env.CROSSWIND_SRC),F=await J([U]);if(!F)throw Error(`CROSSWIND_SRC did not resolve to a Css module: ${U}`);return O=F,O}let Q=await J(zQ());if(Q)return O=Q,O;let Z=GQ;for(let U of Z){let F=await fJ(U);if(F){if(O=F,!process.env.STACKS_DEV_QUIET)console.log(`${Y.green}[ts-css]${Y.reset} CSS engine loaded`);return O}}let $=await J(YQ());if($)return O=$,O;throw Error("Css CSSGenerator not found in any location")}catch{return console.warn(`${Y.yellow}[ts-css] CSS engine not available, Tailwind styles will not be generated${Y.reset}`),console.warn(`${Y.yellow}Run 'bun add @stacksjs/ts-css' to enable CSS generation${Y.reset}`),null}}function J0(){VJ.clear(),O=null,WJ=!1,H=null,T="",D.clear(),L.clear(),b=null}var CJ=!1;async function mJ(J){try{let Q=yJ({name:"css",cwd:J})?"css":yJ({name:"crosswind",cwd:J})?"crosswind":null;if(!Q)return null;if(Q==="crosswind"&&!process.env.STACKS_DEV_QUIET&&!CJ)CJ=!0,console.warn(`${Y.yellow}[ts-css]${Y.reset} Reading the CSS config from a \`crosswind\` file. Rename it to \`css\` (e.g. config/css.ts) \u2014 the old name is deprecated.`);let{loadConfigWithResult:Z}=await import("bunfig"),$=await Z({name:Q,cwd:J,defaultConfig:{},checkEnv:!1,verbose:!1});if(!$?.path||!$.config||Object.keys($.config).length===0)return null;let U=z.relative(J,$.path);if(!process.env.STACKS_DEV_QUIET)console.log(`${Y.green}[ts-css]${Y.reset} Loaded config from ${U||$.path}`);return $.config}catch(Q){if(Q instanceof Error&&Q.name==="ConfigNotFoundError")return null;return console.warn(`${Y.yellow}[ts-css]${Y.reset} Failed to load css config:`,Q instanceof Error?Q.message:Q),null}}async function wQ(J){let Q=null;try{let{loadStxConfig:Z}=await import("./chunk-v6kvq7ww.js"),$=await Z(J);if($.css)if(typeof $.css==="string"){let U=z.isAbsolute($.css)?$.css:z.resolve(J,$.css);if(await Bun.file(U).exists()){let F=await import(U);Q=F.default||F,console.log(`${Y.green}[ts-css]${Y.reset} Loaded config from stx.config.ts \u2192 ${$.css}`)}}else{if(Q={...$.css,content:$.css.content||[],preflight:$.css.preflight??!0,minify:$.css.minify??!1},$.css.config){let U=z.isAbsolute($.css.config)?$.css.config:z.resolve(J,$.css.config);if(await Bun.file(U).exists()){let F=await import(U);Q={...F.default||F,...Q}}}console.log(`${Y.green}[ts-css]${Y.reset} Using inline CSS config from stx.config.ts`)}}catch{}return Q||await mJ(J)}function BQ(J){try{let Q=new WeakSet;return y(JSON.stringify(J??{},(Z,$)=>{if(typeof $==="function")return`[fn]${String($)}`;if(typeof $==="object"&&$!==null){if(Q.has($))return"[circular]";Q.add($)}return $})??"")}catch{return"unhashable"}}async function HQ(J){if(A)return T;A=!0;try{let Q=await pJ();if(!Q||!Q.build)return A=!1,"";if(!H)H=await mJ(J);if(!H)return A=!1,"";let Z=Q.defaultConfig?.theme||{},$=H.theme||{},U={...Q.defaultConfig,...H,theme:{...Z,...$,extend:{...Z.extend||{},...$.extend||{}}}},F=performance.now(),W=await Q.build(U),j=performance.now()-F;if(T=W.css,console.log(`${Y.cyan}[ts-css]${Y.reset} Built ${W.classes.size} classes in ${j.toFixed(1)}ms`),U.output){let V=z.isAbsolute(U.output)?U.output:z.join(J,U.output),X=z.dirname(V);if(!fs.existsSync(X))fs.mkdirSync(X,{recursive:!0});await Bun.write(V,W.css)}return A=!1,W.css}catch(Q){return console.error(`${Y.red}[ts-css]${Y.reset} Build error:`,Q),A=!1,T}}async function Q0(J){H=null,await HQ(J)}function $0(){return T}function OQ(J){let Q=new Set,Z=/class\s*=\s*["']([^"']+)["']/gi,$=Z.exec(J);while($!==null){for(let W of $[1].split(/\s+/))if(W.trim())Q.add(W.trim());$=Z.exec(J)}let U=/(?:x-class|:class)\s*=\s*"([^"]+)"/gi,F=U.exec(J);while(F!==null){let W=F[1].match(/'([^']+)'/g);if(W){for(let j of W)for(let V of j.slice(1,-1).split(/\s+/))if(V.trim())Q.add(V.trim())}F=U.exec(J)}return Q}var VJ=SJ(64);async function LQ(J,Q){let Z=VJ.get(UJ(J,Q,b));if(Z!==void 0)return Z;let $=await KQ(J,Q);if($)VJ.set(UJ(J,Q,b),$);return $}async function KQ(J,Q){try{let Z=await pJ();if(!Z)return"";let $=typeof Z.extractClasses==="function"?Z.extractClasses(J):OQ(J);if($.size===0)return"";let U=Q?z.resolve(Q):process.cwd();if(!N)N=uJ(U,"cache");let F=[...$].sort().join(" "),W=`${b||"default"}::${F}`,j=D.get(W);if(j!==void 0)return FJ(W,j),j;let V=await XQ(W);if(V!==null)return FJ(W,V),V;if(!H)H=await wQ(U),b=BQ(H);let X=Z.defaultConfig||Z.config,q=H||{},G=LJ(X,q),{safelist:w,includePreflight:K,minify:M,tokenCSS:hJ}=G,XJ=G.config,_=new Z.CSSGenerator(XJ);for(let B of w)_.generate(B);for(let B of $)_.generate(B);let I=_.toCSS(K,M),jJ=XJ.shortcuts||q.shortcuts||{};for(let[B,f]of Object.entries(jJ)){if(!$.has(B)&&!w.includes(B))continue;let C=f.split(/\s+/).filter(Boolean);for(let R of C)_.generate(R)}I=_.toCSS(K,M);let v=I.split(`
21
21
  `);for(let[B,f]of Object.entries(jJ)){if(!$.has(B)&&!w.includes(B))continue;let C=f.split(/\s+/).filter(Boolean),R=[],g=[];for(let u of C){let qJ=u.startsWith("dark:"),GJ=`.${(qJ?u.slice(5):u).replace(/\//g,"\\/").replace(/:/g,"\\:").replace(/\./g,"\\.").replace(/\[/g,"\\[").replace(/\]/g,"\\]").replace(/%/g,"\\%")}`;for(let k=0;k<v.length;k++){let zJ=v[k].trim();if(zJ===`${GJ} {`||zJ.startsWith(`${GJ} {`)){let E=k,YJ="";while(E<v.length){if(YJ+=v[E],v[E].includes("}"))break;E++}let d=YJ.match(/\{([^}]+)\}/);if(d)if(qJ)g.push(d[1].trim());else R.push(d[1].trim());break}}}if(R.length)I+=`
22
22
  .${B} { ${R.join(" ")} }`;if(g.length)I+=`
23
23
  @media (prefers-color-scheme: dark) { .dark .${B} { ${g.join(" ")} } }`}return I=hJ+I,FJ(W,I),jQ(W,I),I}catch(Z){return console.warn("Failed to generate Css CSS:",Z),""}}async function Z0(J,Q,Z=!1,$=!1){let U=await LQ(J,Q);if(!U)return $?QJ(J):J;let F=Z?`<link data-css="generated" rel="stylesheet" href="/_stx/css.${VQ(U)}.css">`:`<style data-css="generated">
@@ -29,4 +29,4 @@ ${F}`);return F+J}function IQ(J,Q){let Z=JJ(J).map((V)=>({...V,replacement:""}))
29
29
  ${Q}`});else Z.push({start:0,end:0,replacement:Q})}}Z.sort((V,X)=>V.start-X.start||V.end-X.end);for(let V=1;V<Z.length;V++)if(Z[V].start<Z[V-1].end)return DQ(QJ(J),Q);let F=Array(Z.length*2+1),W=0,j=0;for(let V of Z)F[j++]=J.slice(W,V.start),F[j++]=V.replacement,W=V.end;return F[j]=J.slice(W),F.join("")}function DQ(J,Q){let Z=/(?:<style\b[^>]*\bdata-css=(?:"generated"|'generated')[^>]*>[\s\S]*?<\/style>|<link\b[^>]*\bdata-css=(?:"generated"|'generated')[^>]*>)/g;if(Z.test(J)){let $=!1;return J.replace(Z,()=>{if($)return"";return $=!0,Q})}if(J.includes("</head>"))return J.replace("</head>",`${Q}
30
30
  </head>`);if(J.includes("<body"))return J.replace(/<body([^>]*)>/,`<body$1>
31
31
  ${Q}`);return Q+J}
32
- export{ZJ as ut,fQ as vt,gQ as wt,SJ as xt,mQ as yt,UJ as zt,hQ as At,iQ as Bt,l as Ct,IJ as Dt,iJ as Et,rJ as Ft,vQ as Gt,NJ as Ht,a as It,RQ as Jt,aJ as Kt,h as Lt,LJ as Mt,JJ as Nt,QJ as Ot,xQ as Pt,Y as Qt,eQ as Rt,pJ as St,J0 as Tt,mJ as Ut,wQ as Vt,BQ as Wt,HQ as Xt,Q0 as Yt,$0 as Zt,OQ as _t,LQ as $t,Z0 as au};
32
+ export{ZJ as vt,fQ as wt,gQ as xt,SJ as yt,mQ as zt,UJ as At,hQ as Bt,iQ as Ct,l as Dt,IJ as Et,iJ as Ft,rJ as Gt,vQ as Ht,NJ as It,a as Jt,RQ as Kt,aJ as Lt,h as Mt,LJ as Nt,JJ as Ot,QJ as Pt,xQ as Qt,Y as Rt,eQ as St,pJ as Tt,J0 as Ut,mJ as Vt,wQ as Wt,BQ as Xt,HQ as Yt,Q0 as Zt,$0 as _t,OQ as $t,LQ as au,Z0 as bu};