@aphrody/m3-showcase 3.3.4

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 (674) hide show
  1. package/README.md +47 -0
  2. package/dist/Album-20-x0fyhqxj.png +0 -0
  3. package/dist/Album-txdjxr6p.png +0 -0
  4. package/dist/Album_Light-bnvn9x43.png +0 -0
  5. package/dist/Alias-20-jpvzp7sd.png +0 -0
  6. package/dist/Alias-fbqj79wp.png +0 -0
  7. package/dist/Alias_Light-hv5b8k7t.png +0 -0
  8. package/dist/AmazonS3-x58haer2.png +0 -0
  9. package/dist/AndroidPhotos-cj9z6mnt.png +0 -0
  10. package/dist/AppleFiles-g4g8431e.png +0 -0
  11. package/dist/ApplePhotos-f2nesvx1.png +0 -0
  12. package/dist/Application-ft1as292.png +0 -0
  13. package/dist/Application_Light-h2p2z3de.png +0 -0
  14. package/dist/Archive-20-y262mxsm.png +0 -0
  15. package/dist/Archive-vmmq3f0p.png +0 -0
  16. package/dist/Archive_Light-fqxdt82g.png +0 -0
  17. package/dist/Audio-20-345hqxr8.png +0 -0
  18. package/dist/Audio-3w697yx9.png +0 -0
  19. package/dist/Audio_Light-4pb6z10h.png +0 -0
  20. package/dist/BackBlaze-6m4qpkyc.png +0 -0
  21. package/dist/Ball-d0bcgqha.png +0 -0
  22. package/dist/Book-20-etd4fzhm.png +0 -0
  23. package/dist/Book-ekfqxh7a.png +0 -0
  24. package/dist/BookBlue-17k9z7dy.png +0 -0
  25. package/dist/Book_Light-0n5wsr76.png +0 -0
  26. package/dist/Box-rd26c0g6.png +0 -0
  27. package/dist/CloudSync-wxh5ez5h.png +0 -0
  28. package/dist/CloudSync_Light-nb09rvv4.png +0 -0
  29. package/dist/Code-20-ybgq5j59.png +0 -0
  30. package/dist/Collection-20-7g9nzzcf.png +0 -0
  31. package/dist/Collection-52f2j9wx.png +0 -0
  32. package/dist/CollectionSparkle-nj38wazp.png +0 -0
  33. package/dist/CollectionSparkle_Light-hp1jptvv.png +0 -0
  34. package/dist/Collection_Light-z7p3knd7.png +0 -0
  35. package/dist/Compute-ghst3emj.png +0 -0
  36. package/dist/Config-20-vqd0vqeb.png +0 -0
  37. package/dist/DAV-mr5nm7zs.png +0 -0
  38. package/dist/Database-20-0q97pw36.png +0 -0
  39. package/dist/Database-rcxjw7yv.png +0 -0
  40. package/dist/Database_Light-1dxfaj96.png +0 -0
  41. package/dist/DeleteLocation-3hw52syq.png +0 -0
  42. package/dist/Devices-t2f2k803.png +0 -0
  43. package/dist/Document-20-0f78jpbp.png +0 -0
  44. package/dist/Document-kgsdt3nq.png +0 -0
  45. package/dist/Document_Light-ht9avf71.png +0 -0
  46. package/dist/Document_doc-wqd2zqp2.png +0 -0
  47. package/dist/Document_doc_Light-4ppbm2he.png +0 -0
  48. package/dist/Document_memory-6vymqjra.png +0 -0
  49. package/dist/Document_pdf-7b1zt469.png +0 -0
  50. package/dist/Document_pdf_Light-42j6dt8z.png +0 -0
  51. package/dist/Document_srt-symqv91r.png +0 -0
  52. package/dist/Document_xls-j5tbzav2.png +0 -0
  53. package/dist/Document_xls_Light-w6kbrvem.png +0 -0
  54. package/dist/Document_xmp-7xqx4tm8.png +0 -0
  55. package/dist/Dotfile-20-w53rabv6.png +0 -0
  56. package/dist/Drive-7wb1bf5w.png +0 -0
  57. package/dist/Drive-AmazonS3_Light-z6j2s9xm.png +0 -0
  58. package/dist/Drive-BackBlaze_Light-tr4wfkey.png +0 -0
  59. package/dist/Drive-DAV_Light-kse85f46.png +0 -0
  60. package/dist/Drive-Darker-mss4n9ws.png +0 -0
  61. package/dist/Drive-Dropbox_Light-48naz6gc.png +0 -0
  62. package/dist/Drive-GoogleDrive_Light-t4d4180c.png +0 -0
  63. package/dist/Drive-Mega-z6k8n821.png +0 -0
  64. package/dist/Drive-Mega_Light-nk0qskfb.png +0 -0
  65. package/dist/Drive-OneDrive-sx649zqw.png +0 -0
  66. package/dist/Drive-OneDrive_Light-2n556kpe.png +0 -0
  67. package/dist/Drive-OpenStack-tcs5rge7.png +0 -0
  68. package/dist/Drive-OpenStack_Light-05qnc2gy.png +0 -0
  69. package/dist/Drive-PCloud_Light-d0h9kbwp.png +0 -0
  70. package/dist/Drive-box_Light-0cb17zc1.png +0 -0
  71. package/dist/Drive_Light-dcjdmxm9.png +0 -0
  72. package/dist/Dropbox-q4nkmy9v.png +0 -0
  73. package/dist/Encrypted-20-m8ax3zxz.png +0 -0
  74. package/dist/Encrypted-ddrf9wk4.png +0 -0
  75. package/dist/Encrypted_Light-n1mjh529.png +0 -0
  76. package/dist/Entity-a4438mse.png +0 -0
  77. package/dist/Entity_Light-acxm9r2c.png +0 -0
  78. package/dist/Executable-20-fp7e8r9j.png +0 -0
  79. package/dist/Executable_Light_old-6xd6fa1z.png +0 -0
  80. package/dist/Executable_old-cyj158kz.png +0 -0
  81. package/dist/Face_Light-pjctyrvt.png +0 -0
  82. package/dist/Folder-20-r5505wvj.png +0 -0
  83. package/dist/Folder-kc594khj.png +0 -0
  84. package/dist/Folder-tag-xmp-ff4bgkr4.png +0 -0
  85. package/dist/FolderGrey-2vy13evc.png +0 -0
  86. package/dist/FolderGrey_Light-7z31xy56.png +0 -0
  87. package/dist/FolderNoSpace-d65fr1rz.png +0 -0
  88. package/dist/FolderNoSpace_Light-r5fc4pfj.png +0 -0
  89. package/dist/Folder_Light-rrg0jy36.png +0 -0
  90. package/dist/Font-20-r5n0z7f9.png +0 -0
  91. package/dist/Game-ts1kdw4e.png +0 -0
  92. package/dist/Game_Light-4d6ty5nz.png +0 -0
  93. package/dist/Globe-b379ffpd.png +0 -0
  94. package/dist/GlobeAlt-2mjbsvpp.png +0 -0
  95. package/dist/Globe_Light-2r9sdhb0.png +0 -0
  96. package/dist/GoogleDrive-1swewbzf.png +0 -0
  97. package/dist/GoogleSansFlex-latin-23tdmmt1.woff2 +0 -0
  98. package/dist/HDD-e85re2j5.png +0 -0
  99. package/dist/HDD_Light-pfbhb5wg.png +0 -0
  100. package/dist/Heart-3nx0yjvz.png +0 -0
  101. package/dist/Heart_Light-msf9zhq6.png +0 -0
  102. package/dist/Home-waerfpg1.png +0 -0
  103. package/dist/Home_Light-mdswjrcg.png +0 -0
  104. package/dist/Image-20-7vvqrhrb.png +0 -0
  105. package/dist/Image-fz5c8462.png +0 -0
  106. package/dist/Image_Light-rp0w5n3r.png +0 -0
  107. package/dist/Indexed-nxd6ctrt.png +0 -0
  108. package/dist/Key-20-z5nhfv0c.png +0 -0
  109. package/dist/Key-4en80vnn.png +0 -0
  110. package/dist/Key_Light-h3pc5e2c.png +0 -0
  111. package/dist/Keys-9jknyggw.png +0 -0
  112. package/dist/Keys_Light-5w8kcsmz.png +0 -0
  113. package/dist/Laptop-9gwskqny.png +0 -0
  114. package/dist/Laptop_Light-pwtbqbkp.png +0 -0
  115. package/dist/Link-20-f7hh1tcv.png +0 -0
  116. package/dist/Link-w9y1yad0.png +0 -0
  117. package/dist/Link_Light-4dy9pa5j.png +0 -0
  118. package/dist/Location-7vx0yx6r.png +0 -0
  119. package/dist/LocationManaged-w1n71jx5.png +0 -0
  120. package/dist/LocationReplica-4c6ncswq.png +0 -0
  121. package/dist/Lock-mnveqyfm.png +0 -0
  122. package/dist/Lock_Light-xwnbzkjz.png +0 -0
  123. package/dist/Mega-h4j4t3sb.png +0 -0
  124. package/dist/Mesh-20-rkky209q.png +0 -0
  125. package/dist/Mesh-efjcay8j.png +0 -0
  126. package/dist/Mesh_Light-t9yyzb3y.png +0 -0
  127. package/dist/MiniSilverBox-g8dfw0cp.png +0 -0
  128. package/dist/Mobile-Android-wy5kr3bj.png +0 -0
  129. package/dist/Mobile-jpsv7vp8.png +0 -0
  130. package/dist/Mobile_Light-2rwnn5bx.png +0 -0
  131. package/dist/MoveLocation-kft0z94v.png +0 -0
  132. package/dist/MoveLocation_Light-c23j5x59.png +0 -0
  133. package/dist/Movie-nxat82kv.png +0 -0
  134. package/dist/Movie_Light-eh1hmsr5.png +0 -0
  135. package/dist/NewLocation-2hfv9dwq.png +0 -0
  136. package/dist/Node-wykht7k0.png +0 -0
  137. package/dist/Node_Light-maewxhk1.png +0 -0
  138. package/dist/OneDrive-e4jvssjp.png +0 -0
  139. package/dist/OpenStack-pqp01jfd.png +0 -0
  140. package/dist/PC-eyfa7ewm.png +0 -0
  141. package/dist/PCloud-p0n6g1hq.png +0 -0
  142. package/dist/Package-20-grg5wkse.png +0 -0
  143. package/dist/Package-d7ex1fnn.png +0 -0
  144. package/dist/Package_Light-yj2cvgyw.png +0 -0
  145. package/dist/SD-h17wvz4z.png +0 -0
  146. package/dist/SD_Light-y3mmqh6b.png +0 -0
  147. package/dist/Scrapbook-f92c8p1x.png +0 -0
  148. package/dist/Scrapbook_Light-50pjr0q7.png +0 -0
  149. package/dist/Screenshot-20-z4tfe78m.png +0 -0
  150. package/dist/Screenshot-9nd23fde.png +0 -0
  151. package/dist/ScreenshotAlt-en1yt2gv.png +0 -0
  152. package/dist/Screenshot_Light-hnbah84r.png +0 -0
  153. package/dist/Search-7x8c5z1s.png +0 -0
  154. package/dist/SearchAlt-dmxzk2jb.png +0 -0
  155. package/dist/Search_Light-n23xd2ws.png +0 -0
  156. package/dist/Server-hqsf8851.png +0 -0
  157. package/dist/Server_Light-3x01jqz4.png +0 -0
  158. package/dist/SilverBox-0mk6sxrh.png +0 -0
  159. package/dist/Spacedrop-1-d230z0az.png +0 -0
  160. package/dist/Spacedrop-r1t67bcq.png +0 -0
  161. package/dist/Spacedrop_Light-dj5tgtep.png +0 -0
  162. package/dist/Storage-4x2q4nx6.png +0 -0
  163. package/dist/Sync-531te7fq.png +0 -0
  164. package/dist/Sync_Light-754vfxyr.png +0 -0
  165. package/dist/Tablet-ze6ermb7.png +0 -0
  166. package/dist/Tablet_Light-32skyk12.png +0 -0
  167. package/dist/Tags-bfapk266.png +0 -0
  168. package/dist/Tags_Light-7s00envw.png +0 -0
  169. package/dist/Terminal-t1yjx33x.png +0 -0
  170. package/dist/Terminal_Light-4s5azdgr.png +0 -0
  171. package/dist/Text-20-pt0zjg62.png +0 -0
  172. package/dist/Text-6fgmf4b2.png +0 -0
  173. package/dist/TextAlt_Light-w9kbgvm8.png +0 -0
  174. package/dist/Text_Light-c2k3w31k.png +0 -0
  175. package/dist/Text_txt-xhvv80ys.png +0 -0
  176. package/dist/TexturedMesh-ysk831xz.png +0 -0
  177. package/dist/TexturedMesh_Light-4twy5k6k.png +0 -0
  178. package/dist/Trash-hzscccvk.png +0 -0
  179. package/dist/Trash_Light-78nc56tp.png +0 -0
  180. package/dist/Undefined-pkbecmq4.png +0 -0
  181. package/dist/Undefined_Light-jxesg2zv.png +0 -0
  182. package/dist/Unknown-20-07efh8ya.png +0 -0
  183. package/dist/Video-20-q7yg9p4w.png +0 -0
  184. package/dist/Video-370fzqyw.png +0 -0
  185. package/dist/Video_Light-00vhrp0m.png +0 -0
  186. package/dist/WebPageArchive-20-wn0v4x27.png +0 -0
  187. package/dist/Widget-20-9t860nnc.png +0 -0
  188. package/dist/Widget-k1p15mg9.png +0 -0
  189. package/dist/Widget_Light-5md790ar.png +0 -0
  190. package/dist/ace-ph0rt669.svg +1 -0
  191. package/dist/acemanifest-je939qnz.svg +1 -0
  192. package/dist/adoc-kfbf89h8.svg +1 -0
  193. package/dist/adonis-pn6tbmnq.svg +1 -0
  194. package/dist/adonisconfig-5wfnycbk.svg +1 -0
  195. package/dist/afdesign-5nzbppfa.svg +1 -0
  196. package/dist/afphoto-p941z6q7.svg +1 -0
  197. package/dist/afpub-3232tcp9.svg +1 -0
  198. package/dist/ai-vvwvj03w.svg +1 -0
  199. package/dist/air-e3h8cfx1.svg +1 -0
  200. package/dist/angular-fyg22v82.svg +1 -0
  201. package/dist/angular-kzcwnjdt.svg +1 -0
  202. package/dist/anim-15kqy432.svg +1 -0
  203. package/dist/astro-wdcxh4zx.svg +1 -0
  204. package/dist/astroconfig-73qsx73n.svg +1 -0
  205. package/dist/atomizer-42xe88w7.svg +1 -0
  206. package/dist/audio-xy5qb7t1.svg +1 -0
  207. package/dist/audiomp3-s01feh78.svg +1 -0
  208. package/dist/audioogg-bcake0v6.svg +1 -0
  209. package/dist/audiowav-px37pxve.svg +1 -0
  210. package/dist/audiowv-bq8tbfdv.svg +1 -0
  211. package/dist/azure-veqzyzqq.svg +1 -0
  212. package/dist/babel-vxcfp57a.svg +1 -0
  213. package/dist/ballerina-faxx9p3b.svg +1 -0
  214. package/dist/ballerinaconfig-tmd09kkg.svg +1 -0
  215. package/dist/bat-vjr63aqs.svg +1 -0
  216. package/dist/bazel-4e01p5gp.svg +1 -0
  217. package/dist/bazelignore-wzgc7h2d.svg +1 -0
  218. package/dist/bicep-dae0dh59.svg +1 -0
  219. package/dist/bicepconfig-v64442sp.svg +1 -0
  220. package/dist/bicepparam-ts4jjq60.svg +1 -0
  221. package/dist/binary-dz3thnjq.svg +1 -0
  222. package/dist/biome-gbahcmjy.svg +1 -0
  223. package/dist/blade-je22xc2d.svg +1 -0
  224. package/dist/brotli-1m7qfk77.svg +1 -0
  225. package/dist/browserslist-005php91.svg +1 -0
  226. package/dist/bruno-h4bh0s2c.svg +1 -0
  227. package/dist/bsconfig-gmwc0r2r.svg +1 -0
  228. package/dist/buck-gtasjqw1.svg +1 -0
  229. package/dist/bun-6y6y7t4s.svg +1 -0
  230. package/dist/bun-zxmcandz.svg +1 -0
  231. package/dist/bundler-qhs5a5xb.svg +1 -0
  232. package/dist/bunlock-74b62xbm.svg +1 -0
  233. package/dist/c-k2se7t6q.svg +1 -0
  234. package/dist/c-v9cxtxe1.svg +1 -0
  235. package/dist/cargo-ma5bwyg5.svg +1 -0
  236. package/dist/cargolock-ak0tnv5y.svg +1 -0
  237. package/dist/cert-z62mqtqq.svg +1 -0
  238. package/dist/cheader-mgw2nf38.svg +1 -0
  239. package/dist/chunk-08yjrfs5.js +2 -0
  240. package/dist/chunk-2pmrsdd5.js +2 -0
  241. package/dist/chunk-3995cv9k.js +1 -0
  242. package/dist/chunk-58a3eq49.js +2 -0
  243. package/dist/chunk-616szvb9.js +2 -0
  244. package/dist/chunk-6638b8v6.js +1 -0
  245. package/dist/chunk-6ej2n64j.js +1 -0
  246. package/dist/chunk-7tt0cawd.js +10 -0
  247. package/dist/chunk-9gxv4c5g.js +1 -0
  248. package/dist/chunk-9na12mjw.js +1 -0
  249. package/dist/chunk-b7mpjcry.js +1 -0
  250. package/dist/chunk-c1g6tshf.js +2 -0
  251. package/dist/chunk-d50zvrb1.css +1 -0
  252. package/dist/chunk-d6c35fm0.js +2 -0
  253. package/dist/chunk-ehpz56xv.js +2 -0
  254. package/dist/chunk-ewtr6sjm.js +9 -0
  255. package/dist/chunk-g9rnrhvz.js +2 -0
  256. package/dist/chunk-gv83r4qx.js +262 -0
  257. package/dist/chunk-j46wg1ym.js +156 -0
  258. package/dist/chunk-kapsksxf.js +1 -0
  259. package/dist/chunk-m98tyb4g.js +6 -0
  260. package/dist/chunk-nn0prq25.js +2 -0
  261. package/dist/chunk-nsgjb3bx.js +2 -0
  262. package/dist/chunk-p8r6wjkz.js +3 -0
  263. package/dist/chunk-rdnm87fw.js +1 -0
  264. package/dist/chunk-re36kkra.js +1 -0
  265. package/dist/chunk-vm9edd26.js +2 -0
  266. package/dist/chunk-x2hztqk0.css +1 -0
  267. package/dist/chunk-yyxb5zbq.js +2 -0
  268. package/dist/civet-5bbs33v3.svg +1 -0
  269. package/dist/claude-jscxahsf.svg +1 -0
  270. package/dist/cli-4f5nfe5s.svg +1 -0
  271. package/dist/clojure-0h7h9znc.svg +1 -0
  272. package/dist/cmake-q8ryfre0.svg +1 -0
  273. package/dist/cmake-qwe6x8nx.svg +1 -0
  274. package/dist/codeworkspace-326020b4.svg +1 -0
  275. package/dist/coffeescript-ec1bytnk.svg +1 -0
  276. package/dist/commitlint-93j0tfvp.svg +1 -0
  277. package/dist/compodoc-36b7gn70.svg +1 -0
  278. package/dist/composer-vv2tvxkr.svg +1 -0
  279. package/dist/composerlock-nf0232yh.svg +1 -0
  280. package/dist/conan-dggdfcr9.svg +1 -0
  281. package/dist/conf-5756g97p.svg +1 -0
  282. package/dist/copilot-1phy76q3.svg +1 -0
  283. package/dist/cpp-4yvddm6j.svg +1 -0
  284. package/dist/cpp-pbznrtpp.svg +1 -0
  285. package/dist/crystal-x20aj00e.svg +1 -0
  286. package/dist/csharp-0p3hstq8.svg +1 -0
  287. package/dist/csharp-cpmfe8y0.svg +1 -0
  288. package/dist/cshtml-xb5gtb0r.svg +1 -0
  289. package/dist/csproj-ftptw15a.svg +1 -0
  290. package/dist/css-tqps22nw.svg +1 -0
  291. package/dist/css-ycr1qc5f.svg +1 -0
  292. package/dist/cssmap-3gnm34f6.svg +1 -0
  293. package/dist/csv-gg0axfar.svg +1 -0
  294. package/dist/cucumber-m06dfkm5.svg +1 -0
  295. package/dist/cursor-jw7n7tpq.svg +1 -0
  296. package/dist/cypress-xsm2fq1p.svg +1 -0
  297. package/dist/cypressjs-hapzyfm1.svg +1 -0
  298. package/dist/cypressts-jey9ahc7.svg +1 -0
  299. package/dist/d-4x2njcan.svg +1 -0
  300. package/dist/dartlang-7dwdwv03.svg +1 -0
  301. package/dist/dartlang-mra7r0f8.svg +1 -0
  302. package/dist/delphiproject-7snmvsdx.svg +1 -0
  303. package/dist/diff-hekg2jpm.svg +1 -0
  304. package/dist/docker-8q58y2kc.svg +1 -0
  305. package/dist/dockerdebug-8zhgj7bd.svg +1 -0
  306. package/dist/dockerignore-488safx9.svg +1 -0
  307. package/dist/drawio-6qm0rhkv.svg +1 -0
  308. package/dist/drizzle-5bct2tg6.svg +1 -0
  309. package/dist/dsstore-pmhpmkdr.svg +1 -0
  310. package/dist/dune-r4xhac56.svg +1 -0
  311. package/dist/duneproject-3b99jndq.svg +1 -0
  312. package/dist/edge-0jwced3c.svg +1 -0
  313. package/dist/editorconfig-hee1zp1h.svg +1 -0
  314. package/dist/eex-q1bkj66x.svg +1 -0
  315. package/dist/elixir-48ge02m5.svg +1 -0
  316. package/dist/elm-97mh5wye.svg +1 -0
  317. package/dist/env-ysamxkcd.svg +1 -0
  318. package/dist/eraser-7mejjgrg.svg +1 -0
  319. package/dist/erb-f28j5x6b.svg +1 -0
  320. package/dist/erlang-3ebtbtfw.svg +1 -0
  321. package/dist/esbuild-wptxye5y.svg +1 -0
  322. package/dist/eslint-mrbexpc5.svg +1 -0
  323. package/dist/eslintignore-k65wpbsr.svg +1 -0
  324. package/dist/excalidraw-28avfa1h.svg +1 -0
  325. package/dist/exs-5w2cfpaf.svg +1 -0
  326. package/dist/exx-s897xhz3.svg +1 -0
  327. package/dist/farm-m80hxnfy.svg +1 -0
  328. package/dist/favicon-djc6sne4.svg +1 -0
  329. package/dist/figma-krwq889b.svg +1 -0
  330. package/dist/file-hetj1tjc.svg +1 -0
  331. package/dist/file_light-jx35pv2m.svg +1 -0
  332. package/dist/flakelock-2nsqn4gw.svg +1 -0
  333. package/dist/flutter-277q83en.svg +1 -0
  334. package/dist/flutterlock-h0nywsvt.svg +1 -0
  335. package/dist/flutterpackage-cpgnfwtt.svg +1 -0
  336. package/dist/folder-2xmsfyxp.svg +1 -0
  337. package/dist/folder_open-wk4ndx1f.svg +1 -0
  338. package/dist/fonteot-a8xmqj3j.svg +1 -0
  339. package/dist/fontotf-f01hg174.svg +1 -0
  340. package/dist/fontttf-pcr3rt21.svg +1 -0
  341. package/dist/fontwoff-v1gdka62.svg +1 -0
  342. package/dist/fontwoff2-1w1r47x8.svg +1 -0
  343. package/dist/freemarker-s9m714ah.svg +1 -0
  344. package/dist/fsharp-89mjndn4.svg +1 -0
  345. package/dist/gbl-v20qxsgx.svg +1 -0
  346. package/dist/git-wc9x7c5e.svg +1 -0
  347. package/dist/gitlab-bhcvbetz.svg +1 -0
  348. package/dist/gleam-h2ze8vtz.svg +1 -0
  349. package/dist/gleamconfig-6sq0xy19.svg +1 -0
  350. package/dist/go-15qaph9s.svg +1 -0
  351. package/dist/go-j2dk6r7k.svg +1 -0
  352. package/dist/go_package-5nc95prx.svg +1 -0
  353. package/dist/godot-v7nnsyvc.svg +1 -0
  354. package/dist/gradle-khh2bn3v.svg +1 -0
  355. package/dist/gradlebat-631878b0.svg +1 -0
  356. package/dist/gradlekotlin-f8netdbt.svg +1 -0
  357. package/dist/grain-tztem5b9.svg +1 -0
  358. package/dist/graphql-egmdpvzr.svg +1 -0
  359. package/dist/groovy-c0sstajm.svg +1 -0
  360. package/dist/grunt-56ssa3fr.svg +1 -0
  361. package/dist/gulp-j7wc27hd.svg +1 -0
  362. package/dist/h-4xbbejcs.svg +1 -0
  363. package/dist/haml-6pyt136a.svg +1 -0
  364. package/dist/handlebars-1v8g0n32.svg +1 -0
  365. package/dist/hardhat-1k6gym6f.svg +1 -0
  366. package/dist/hash-xd1ymkyp.svg +1 -0
  367. package/dist/hashicorp-vty9d6de.svg +1 -0
  368. package/dist/haskell-ncbxh3wk.svg +1 -0
  369. package/dist/haxe-j5nqdw5z.svg +1 -0
  370. package/dist/haxeml-bn7wtpx1.svg +1 -0
  371. package/dist/hpp-rpxcfk6j.svg +1 -0
  372. package/dist/htaccess-s4rrm1re.svg +1 -0
  373. package/dist/html-3vbw2fxn.svg +1 -0
  374. package/dist/html-v1z6sanr.svg +1 -0
  375. package/dist/http-9bfh1zqw.svg +1 -0
  376. package/dist/identifier-6gsrr6st.svg +1 -0
  377. package/dist/image-pstdg0vj.svg +1 -0
  378. package/dist/imagegif-any2rrn3.svg +1 -0
  379. package/dist/imageico-cng69rft.svg +1 -0
  380. package/dist/imagejpg-rtx9yy9y.svg +1 -0
  381. package/dist/imagepng-j6f306v1.svg +1 -0
  382. package/dist/imagewebp-q1mcm8np.svg +1 -0
  383. package/dist/imba-xxn1q1r2.svg +1 -0
  384. package/dist/index.html +16 -0
  385. package/dist/info-qssn7jw5.svg +1 -0
  386. package/dist/instructions-3068x11a.svg +1 -0
  387. package/dist/ipynb-qm8fb1p1.svg +1 -0
  388. package/dist/jar-src0eb7a.svg +1 -0
  389. package/dist/java-126v951r.svg +1 -0
  390. package/dist/java-hhh3k9xf.svg +1 -0
  391. package/dist/jenkins-ap6tzby2.svg +1 -0
  392. package/dist/jest-xrtp7hh0.svg +1 -0
  393. package/dist/jinja-v9kggcps.svg +1 -0
  394. package/dist/js-qsntbmzx.svg +1 -0
  395. package/dist/js-r0b86hmj.svg +1 -0
  396. package/dist/jsmap-1ns6yn3z.svg +1 -0
  397. package/dist/json-1jhmg3gf.svg +1 -0
  398. package/dist/jsp-7n103tna.svg +1 -0
  399. package/dist/julia-nba7etbq.svg +1 -0
  400. package/dist/karma-zcbeze4p.svg +1 -0
  401. package/dist/keep-tw8xf3gf.svg +1 -0
  402. package/dist/key-hd2nnhmr.svg +1 -0
  403. package/dist/knex-87w40q0j.svg +1 -0
  404. package/dist/knip-kzsz2w4s.svg +1 -0
  405. package/dist/kotlin-360tzrt1.svg +1 -0
  406. package/dist/kotlin-hbykz1k8.svg +1 -0
  407. package/dist/kotlins-4zz4rshm.svg +1 -0
  408. package/dist/krita-wx5qyrx7.svg +1 -0
  409. package/dist/latex-jwrpzd2b.svg +1 -0
  410. package/dist/launch-8wsjpmd3.svg +1 -0
  411. package/dist/lazarusproject-gma2fvya.svg +1 -0
  412. package/dist/less-p4zwh19p.svg +1 -0
  413. package/dist/license-qamq8mp3.svg +1 -0
  414. package/dist/light_editorconfig-k28g3f4k.svg +1 -0
  415. package/dist/liquid-wtexakya.svg +1 -0
  416. package/dist/llvm-cfgd7591.svg +1 -0
  417. package/dist/lock-wv5q3nef.svg +1 -0
  418. package/dist/log-ykdkwnpq.svg +1 -0
  419. package/dist/lua-aynthw24.svg +1 -0
  420. package/dist/m-va54fte8.svg +1 -0
  421. package/dist/m3-bun.manifest.json +3785 -0
  422. package/dist/makefile-kkcgz3sb.svg +1 -0
  423. package/dist/manifest-ede4t0vc.svg +1 -0
  424. package/dist/markdown-x7kezf76.svg +1 -0
  425. package/dist/markdownx-y5mf21hn.svg +1 -0
  426. package/dist/maven-djc7vb1b.svg +1 -0
  427. package/dist/mermaid-4bpjjghk.svg +1 -0
  428. package/dist/mesh-q798mf4t.svg +1 -0
  429. package/dist/mgcb-cfmfr63b.svg +1 -0
  430. package/dist/mint-b732cej4.svg +1 -0
  431. package/dist/mix-41smb4q2.svg +1 -0
  432. package/dist/mixlock-z0cvwpkq.svg +1 -0
  433. package/dist/mjml-4kzxtz0b.svg +1 -0
  434. package/dist/mkdocs-5t1davz8.svg +1 -0
  435. package/dist/mockoon-5pw3ckhf.svg +1 -0
  436. package/dist/motoko-yv95035d.svg +1 -0
  437. package/dist/mov-r3cjb3vr.svg +1 -0
  438. package/dist/mp4-31hded8m.svg +1 -0
  439. package/dist/mtl-01f1f06m.svg +1 -0
  440. package/dist/mustache-1s62ewsg.svg +1 -0
  441. package/dist/nelua-97199e3p.svg +1 -0
  442. package/dist/neon-gcp7rsp5.svg +1 -0
  443. package/dist/nestjs-sme3dmgk.svg +1 -0
  444. package/dist/nestjscontroller-2ceskrfc.svg +1 -0
  445. package/dist/nestjsdecorator-52k9dwm2.svg +1 -0
  446. package/dist/nestjsdto-xf36my7y.svg +1 -0
  447. package/dist/nestjsentity-q17fyvm1.svg +1 -0
  448. package/dist/nestjsfilter-qytmtqzj.svg +1 -0
  449. package/dist/nestjsguard-4pyb34xe.svg +1 -0
  450. package/dist/nestjsinterceptor-7s690j87.svg +1 -0
  451. package/dist/nestjsmodule-zeyz5633.svg +1 -0
  452. package/dist/nestjsrepository-kz26s1jf.svg +1 -0
  453. package/dist/nestjsresolver-8qdvexrk.svg +1 -0
  454. package/dist/nestjsservice-kp3b933m.svg +1 -0
  455. package/dist/nestscheduler-60p4j2tg.svg +1 -0
  456. package/dist/netlify-bbgdw42s.svg +1 -0
  457. package/dist/nextconfig-gr1sd69d.svg +1 -0
  458. package/dist/nextron-sf3ag316.svg +1 -0
  459. package/dist/nginx-73stz0yt.svg +1 -0
  460. package/dist/nim-gqnvnkc5.svg +1 -0
  461. package/dist/nix-t1m4qhc8.svg +1 -0
  462. package/dist/njk-dfv3nrxr.svg +1 -0
  463. package/dist/node-w3gp0xxn.svg +1 -0
  464. package/dist/nodemon-q41mkhvz.svg +1 -0
  465. package/dist/npm-rt8ga6qx.svg +1 -0
  466. package/dist/npmlock-8p4sp377.svg +1 -0
  467. package/dist/nuxt-13qdp31g.svg +1 -0
  468. package/dist/nvidia-fysz92ep.svg +1 -0
  469. package/dist/nvim-h3ynkfqg.svg +1 -0
  470. package/dist/nvm-ser6majj.svg +1 -0
  471. package/dist/nx-av0cw2sw.svg +1 -0
  472. package/dist/obj-thakg863.svg +1 -0
  473. package/dist/ocaml-maevkwa7.svg +1 -0
  474. package/dist/ocamli-w0gc5jq8.svg +1 -0
  475. package/dist/ocamll-h2wysvh1.svg +1 -0
  476. package/dist/ocamly-ppj6pfy3.svg +1 -0
  477. package/dist/odin-x7qb7b6x.svg +1 -0
  478. package/dist/opengl-h6pbxg3n.svg +1 -0
  479. package/dist/oxlint-7qwxtp86.svg +1 -0
  480. package/dist/panda-9qqa1nn4.svg +1 -0
  481. package/dist/parcel-gzckrwpy.svg +1 -0
  482. package/dist/pascal-kj6crs4h.svg +1 -0
  483. package/dist/pdf-wk39v1nv.svg +1 -0
  484. package/dist/perl-11dgrnh8.svg +1 -0
  485. package/dist/perlm-7xrwgd93.svg +1 -0
  486. package/dist/pfx-ggdb4v6p.svg +1 -0
  487. package/dist/photoshop-m3gw1xv7.svg +1 -0
  488. package/dist/php-jgyt96zk.svg +1 -0
  489. package/dist/php-jx84j7ns.svg +1 -0
  490. package/dist/plantuml-04ncqrmc.svg +1 -0
  491. package/dist/playright-dfc8tvme.svg +1 -0
  492. package/dist/plop-n71aee6w.svg +1 -0
  493. package/dist/pnpm-jvkts1qb.svg +1 -0
  494. package/dist/pnpmlock-2kqbdtn7.svg +1 -0
  495. package/dist/poetry-yjeeyvtr.svg +1 -0
  496. package/dist/poetrylock-da30xbws.svg +1 -0
  497. package/dist/postcssconfig-yyvnwr01.svg +1 -0
  498. package/dist/powershell-hf358xbb.svg +1 -0
  499. package/dist/powershelldata-nggemhrs.svg +1 -0
  500. package/dist/powershellmodule-v5wz6sed.svg +1 -0
  501. package/dist/precommit-wmfmt8tq.svg +1 -0
  502. package/dist/prettier-nyc1v0qk.svg +1 -0
  503. package/dist/prettierignore-hx4x759w.svg +1 -0
  504. package/dist/prisma-te242v0q.svg +1 -0
  505. package/dist/prolog-twb6h758.svg +1 -0
  506. package/dist/prompt-eg8c0gqa.svg +1 -0
  507. package/dist/properties-c39zkae1.svg +1 -0
  508. package/dist/proto-rsvsx4xb.svg +1 -0
  509. package/dist/pug-rqxd67km.svg +1 -0
  510. package/dist/pvk-bc4g1qms.svg +1 -0
  511. package/dist/py-0g79s39m.svg +1 -0
  512. package/dist/pyproject-5s59g4en.svg +1 -0
  513. package/dist/python-ds482k8k.svg +1 -0
  514. package/dist/qt-y3kxpf67.svg +1 -0
  515. package/dist/quarkus-xrq4b999.svg +1 -0
  516. package/dist/quasar-hvna6b7f.svg +1 -0
  517. package/dist/r-n1bnfab8.svg +1 -0
  518. package/dist/racket-vx5e6n1d.svg +1 -0
  519. package/dist/raku-4ydzc5wj.svg +1 -0
  520. package/dist/razor-cbqpr6vt.svg +1 -0
  521. package/dist/rb-mfkwkq7e.svg +1 -0
  522. package/dist/reactjs-qjyhk3rf.svg +1 -0
  523. package/dist/reactts-p0hf29yr.svg +1 -0
  524. package/dist/readme-3qcyy95y.svg +1 -0
  525. package/dist/redis-ya1xyn4v.svg +1 -0
  526. package/dist/rego-tr1y9cqm.svg +1 -0
  527. package/dist/remix-61pbjda4.svg +1 -0
  528. package/dist/rescript-9c3xnepn.svg +1 -0
  529. package/dist/rescriptinterface-6ne0a2rf.svg +1 -0
  530. package/dist/restructuredtext-7k21mjx4.svg +1 -0
  531. package/dist/rjson-3s2edhhr.svg +1 -0
  532. package/dist/robots-geh7c3pq.svg +1 -0
  533. package/dist/rollup-0dxydzr9.svg +1 -0
  534. package/dist/rome-1gxetp8g.svg +1 -0
  535. package/dist/ron-ft34rzr3.svg +1 -0
  536. package/dist/root_folder-rhwm7290.svg +1 -0
  537. package/dist/root_folder_light-ngkg5m4x.svg +1 -0
  538. package/dist/root_folder_light_open-c6nhg6sy.svg +1 -0
  539. package/dist/root_folder_open-genv0ps7.svg +1 -0
  540. package/dist/rs-60bcevwn.svg +1 -0
  541. package/dist/ruby-7j5zzh38.svg +1 -0
  542. package/dist/rust-a9528zdg.svg +1 -0
  543. package/dist/rustfmt-c8evpzd7.svg +1 -0
  544. package/dist/sails-5ecccxrg.svg +1 -0
  545. package/dist/salesforce-4d89045j.svg +1 -0
  546. package/dist/sass-g9qbr3x4.svg +1 -0
  547. package/dist/scala-8gnn0ekc.svg +1 -0
  548. package/dist/scss-g9qbr3x4.svg +1 -0
  549. package/dist/sentinel-g8py3peh.svg +1 -0
  550. package/dist/sequelize-qvzwnjhv.svg +1 -0
  551. package/dist/sh-bkp0n5vb.svg +1 -0
  552. package/dist/shaderlab-gkww43v2.svg +1 -0
  553. package/dist/shell-kc0a9zjq.svg +1 -0
  554. package/dist/silq-mczpsqmz.svg +1 -0
  555. package/dist/slim-8j9jf3zt.svg +1 -0
  556. package/dist/sln-nketqakm.svg +1 -0
  557. package/dist/smarty-w1zxys1s.svg +1 -0
  558. package/dist/sol-adyfjwzz.svg +1 -0
  559. package/dist/spc-kk30w5m6.svg +1 -0
  560. package/dist/sql-3c4gcy7a.svg +1 -0
  561. package/dist/sqlite-cppkxr0a.svg +1 -0
  562. package/dist/storybook-885ssp75.svg +1 -0
  563. package/dist/stylelint-z7s6yhc9.svg +1 -0
  564. package/dist/stylelintignore-xwnh8sx1.svg +1 -0
  565. package/dist/stylus-qz53ytkd.svg +1 -0
  566. package/dist/suo-3fvnz3bx.svg +1 -0
  567. package/dist/svelte-jp3x9gw7.svg +1 -0
  568. package/dist/svelteconfig-m0n00zjj.svg +1 -0
  569. package/dist/svg-8dyqf96t.svg +1 -0
  570. package/dist/swift-8g870v6j.svg +1 -0
  571. package/dist/symfony-q77kcepw.svg +1 -0
  572. package/dist/tailwind-3es9cgbd.svg +1 -0
  573. package/dist/tauri-xnj526kw.svg +1 -0
  574. package/dist/taze-e3ykqs0k.svg +1 -0
  575. package/dist/terrafile-gqn1tysh.svg +1 -0
  576. package/dist/terraform-jy4fbwsr.svg +1 -0
  577. package/dist/terraformvars-05qje1sw.svg +1 -0
  578. package/dist/terraformversion-gq2tkwmn.svg +1 -0
  579. package/dist/testjs-sqgjsb8h.svg +1 -0
  580. package/dist/testts-19m1sf26.svg +1 -0
  581. package/dist/tmpl-enggw2gc.svg +1 -0
  582. package/dist/todo-ccw0mpg2.svg +1 -0
  583. package/dist/toml-rmx5hba4.svg +1 -0
  584. package/dist/toolversions-s7fttfyp.svg +1 -0
  585. package/dist/tox-a4j4yvmb.svg +1 -0
  586. package/dist/travis-gr3jtpx2.svg +1 -0
  587. package/dist/tres-qt3kk1t0.svg +1 -0
  588. package/dist/ts-7amn21ms.svg +1 -0
  589. package/dist/tscn-g1jthb4m.svg +1 -0
  590. package/dist/tsconfig-r1s750bq.svg +1 -0
  591. package/dist/tsx-a3rsjrrz.svg +1 -0
  592. package/dist/turbo-dcmj75tc.svg +1 -0
  593. package/dist/twig-3xgrb919.svg +1 -0
  594. package/dist/txt-y0t8b72p.svg +1 -0
  595. package/dist/typescript-kd5g4jkg.svg +1 -0
  596. package/dist/typescriptdef-y43343m6.svg +1 -0
  597. package/dist/ui-pxvg5zj2.svg +1 -0
  598. package/dist/unocss-b0f5fthj.svg +1 -0
  599. package/dist/user-q7tk1k2d.svg +1 -0
  600. package/dist/v-c25jfygk.svg +1 -0
  601. package/dist/vanillaextract-3w6vds6m.svg +1 -0
  602. package/dist/vb-87ckj7t3.svg +1 -0
  603. package/dist/vercel-hfxjvaj9.svg +1 -0
  604. package/dist/version-zd7hfmf1.svg +1 -0
  605. package/dist/vhd-xaw7zbny.svg +1 -0
  606. package/dist/vhdl-s308rb5a.svg +1 -0
  607. package/dist/video-z6khth5y.svg +1 -0
  608. package/dist/vite-5g5xkmpk.svg +1 -0
  609. package/dist/viteenv-jbmx0tb0.svg +1 -0
  610. package/dist/vitest-5267dzt2.svg +1 -0
  611. package/dist/vmod-8jftapdc.svg +1 -0
  612. package/dist/vscode-8tvcs7ae.svg +1 -0
  613. package/dist/vue-j5sjdz4b.svg +1 -0
  614. package/dist/vue-x9h2d0d2.svg +1 -0
  615. package/dist/vueconfig-726zh8dd.svg +1 -0
  616. package/dist/wasm-vgmg9kv4.svg +1 -0
  617. package/dist/webpack-hfwce90m.svg +1 -0
  618. package/dist/wgsl-68923cz5.svg +1 -0
  619. package/dist/windi-c9m8en7k.svg +1 -0
  620. package/dist/wren-7ep5ph5r.svg +1 -0
  621. package/dist/xmake-mc60ax7m.svg +1 -0
  622. package/dist/xml-feq1fbt4.svg +1 -0
  623. package/dist/yaml-n43aw0fx.svg +1 -0
  624. package/dist/yang-mtcxs2mg.svg +1 -0
  625. package/dist/yarn-k4k6e35h.svg +1 -0
  626. package/dist/yarnerror-5jkesx9j.svg +1 -0
  627. package/dist/yarnignore-ryh8jd5p.svg +1 -0
  628. package/dist/yarnlock-9zvhbg04.svg +1 -0
  629. package/dist/yin-f931bzgj.svg +1 -0
  630. package/dist/zig-nx2e65ns.svg +1 -0
  631. package/dist/zip-7hqmj0b0.svg +1 -0
  632. package/m3.config.ts +32 -0
  633. package/package.json +60 -0
  634. package/scripts/browser-contract.ts +400 -0
  635. package/scripts/icons.ts +56 -0
  636. package/scripts/inventory.ts +86 -0
  637. package/scripts/shots.ts +154 -0
  638. package/scripts/tauri.ts +401 -0
  639. package/src/App.tsx +40 -0
  640. package/src/adaptive/dpad.ts +223 -0
  641. package/src/adaptive/window.ts +133 -0
  642. package/src/api/index.ts +332 -0
  643. package/src/components/ui.tsx +89 -0
  644. package/src/env.d.ts +5 -0
  645. package/src/favicon.svg +1 -0
  646. package/src/generated/inventory.json +426 -0
  647. package/src/index.html +16 -0
  648. package/src/inventory.ts +19 -0
  649. package/src/main.tsx +6 -0
  650. package/src/pages/Adaptive.tsx +128 -0
  651. package/src/pages/Ai.tsx +174 -0
  652. package/src/pages/Brands.tsx +156 -0
  653. package/src/pages/Components.tsx +91 -0
  654. package/src/pages/Design.tsx +163 -0
  655. package/src/pages/Explorer.tsx +125 -0
  656. package/src/pages/Forms.tsx +128 -0
  657. package/src/pages/Icons.tsx +138 -0
  658. package/src/pages/Motion.tsx +157 -0
  659. package/src/pages/Next.tsx +107 -0
  660. package/src/pages/Overview.tsx +105 -0
  661. package/src/pages/Primitives.tsx +138 -0
  662. package/src/pages/Reader.tsx +101 -0
  663. package/src/pages/System.tsx +283 -0
  664. package/src/pages/Theme.tsx +146 -0
  665. package/src/pages/index.ts +25 -0
  666. package/src/router.ts +22 -0
  667. package/src/shell/Shell.tsx +383 -0
  668. package/src/shell/nav.ts +198 -0
  669. package/src/styles.css +61 -0
  670. package/test/contracts.test.ts +87 -0
  671. package/test/host-contract.test.ts +183 -0
  672. package/test/runtime-api.test.ts +138 -0
  673. package/test-dom/dpad.test.ts +78 -0
  674. package/tsconfig.json +11 -0
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@aphrody/m3-showcase",
3
+ "version": "3.3.4",
4
+ "description": "Adaptive Aphrody M3 web showcase with mobile, desktop and TV layouts, a Bun UI/API executable and a prepared canonical Tauri desktop shell.",
5
+ "license": "Apache-2.0",
6
+ "type": "module",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "scripts": {
11
+ "inventory": "bun scripts/inventory.ts",
12
+ "dev": "bun scripts/inventory.ts && m3-bun dev",
13
+ "build": "bun scripts/inventory.ts && m3-bun build",
14
+ "serve": "m3-bun serve",
15
+ "compile": "bun scripts/inventory.ts && m3-bun compile",
16
+ "package": "m3-bun package",
17
+ "deploy": "m3-bun deploy all",
18
+ "smoke": "m3-bun smoke",
19
+ "typecheck": "tsc -p tsconfig.json --noEmit",
20
+ "test": "bun test ./test && bun run test:dom",
21
+ "icons": "bun scripts/icons.ts",
22
+ "tauri": "bun scripts/tauri.ts",
23
+ "test:dom": "bun test --preload @aphrody/m3-config/test/dom ./test-dom"
24
+ },
25
+ "dependencies": {
26
+ "@aphrody/ag-ui": "1.0.1",
27
+ "@aphrody/assets": "0.1.0",
28
+ "@aphrody/canvas": "1.0.9-aphrody.3",
29
+ "@aphrody/eslint-plugin-m3": "3.3.3",
30
+ "@aphrody/identity": "0.1.0",
31
+ "@aphrody/m3": "3.3.4",
32
+ "@aphrody/m3-ai": "3.3.4",
33
+ "@aphrody/m3-baseui": "3.3.4",
34
+ "@aphrody/m3-bun": "3.3.4",
35
+ "@aphrody/m3-codemods": "3.3.4",
36
+ "@aphrody/m3-design": "3.3.4",
37
+ "@aphrody/m3-explorer": "3.3.4",
38
+ "@aphrody/m3-fonts": "3.3.4",
39
+ "@aphrody/m3-forms": "3.3.4",
40
+ "@aphrody/m3-front": "3.3.4",
41
+ "@aphrody/m3-icons": "3.3.4",
42
+ "@aphrody/m3-mcp": "3.3.4",
43
+ "@aphrody/m3-motion": "3.3.4",
44
+ "@aphrody/m3-next": "3.3.4",
45
+ "@aphrody/m3-os-themes": "3.3.4",
46
+ "@aphrody/m3-primitives": "3.3.4",
47
+ "@aphrody/m3-react": "3.3.4",
48
+ "@aphrody/m3-reader": "3.3.4",
49
+ "@aphrody/m3-tailwind": "3.3.4",
50
+ "@aphrody/m3-theme": "3.3.4",
51
+ "@aphrody/m3-tokens": "3.3.4",
52
+ "@aphrody/material-design-icons": "1.0.0",
53
+ "@aphrody/scaffold": "1.0.0-canary",
54
+ "@modelcontextprotocol/sdk": "^1.31.0",
55
+ "react-hook-form": "^7.89.0"
56
+ },
57
+ "engines": {
58
+ "bun": ">=1.4.2"
59
+ }
60
+ }
@@ -0,0 +1,400 @@
1
+ #!/usr/bin/env bun
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ // Chromium interaction checks against an existing local production server; no snapshots or installations.
4
+ import assert from "node:assert/strict";
5
+ import { mkdir } from "node:fs/promises";
6
+ import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
7
+ import { fileURLToPath } from "node:url";
8
+ import { chromium, type Page } from "playwright-core";
9
+ import { PAGES } from "../src/pages/index.ts";
10
+ import { CHROMIUM_ARGS } from "./shots.ts";
11
+
12
+ const RUNS = fileURLToPath(new URL("../../../../.coord/runs/m3-prod/", import.meta.url));
13
+ interface Check {
14
+ name: string;
15
+ passed: boolean;
16
+ durationMs: number;
17
+ error?: string;
18
+ }
19
+ export interface BrowserContractReport {
20
+ url: string;
21
+ timestamp: string;
22
+ browser: string;
23
+ checks: Check[];
24
+ navigation: { route: string; tag: string; href: string | null }[];
25
+ inputUndefined?: { type: string; attribute: string | null };
26
+ consoleErrors: string[];
27
+ httpFailures: string[];
28
+ externalRequests: string[];
29
+ }
30
+
31
+ /** Artifacts are restricted to the integrating agent's existing qualification directory. */
32
+ export function outputPath(value = resolve(RUNS, "browser-contract.json")): string {
33
+ const target = resolve(value);
34
+ const within = relative(RUNS, target);
35
+ if (
36
+ !within ||
37
+ within === ".." ||
38
+ within.startsWith(".." + sep) ||
39
+ isAbsolute(within) ||
40
+ !target.endsWith(".json")
41
+ )
42
+ throw new TypeError("Output must be a JSON file under " + RUNS);
43
+ return target;
44
+ }
45
+ function localUrl(value: string): string {
46
+ const url = new URL(value);
47
+ if (
48
+ !["http:", "https:"].includes(url.protocol) ||
49
+ !["localhost", "127.0.0.1", "[::1]"].includes(url.hostname) ||
50
+ url.username ||
51
+ url.password
52
+ )
53
+ throw new TypeError("Use a local HTTP server URL.");
54
+ return url.origin;
55
+ }
56
+ async function ready(page: Page, route: string): Promise<void> {
57
+ await page.waitForFunction(
58
+ (id) => document.querySelector('[data-testid="main"]')?.getAttribute("data-route") === id,
59
+ route,
60
+ );
61
+ await page.locator("main h1").waitFor();
62
+ assert.equal(await page.locator("h1").count(), 1, "Each page must have one document heading");
63
+ assert.doesNotMatch(await page.locator("main h1").innerText(), /Unable to load/i);
64
+ }
65
+ async function destination(page: Page, route: string): Promise<void> {
66
+ await page.getByTestId("nav-" + route).click();
67
+ await ready(page, route);
68
+ assert.equal(new URL(page.url()).hash, "#/" + route);
69
+ }
70
+ async function containsText(page: Page, selector: string, text: string): Promise<void> {
71
+ await page.waitForFunction(
72
+ ({ selector: query, text: expectedText }) =>
73
+ document.querySelector(query)?.textContent?.includes(expectedText),
74
+ { selector, text },
75
+ );
76
+ }
77
+ async function scheme(page: Page, expected: "light" | "dark"): Promise<void> {
78
+ await page.waitForFunction(
79
+ (value) => getComputedStyle(document.documentElement).colorScheme === value,
80
+ expected,
81
+ );
82
+ }
83
+ async function layout(page: Page, expected: string): Promise<void> {
84
+ await page.waitForFunction(
85
+ (value) =>
86
+ document.querySelector('[data-testid="shell"]')?.getAttribute("data-layout") === value,
87
+ expected,
88
+ );
89
+ }
90
+
91
+ export async function browserContract(baseUrl: string): Promise<BrowserContractReport> {
92
+ const url = localUrl(baseUrl);
93
+ const browser = await chromium.launch({ headless: true, args: CHROMIUM_ARGS });
94
+ const report: BrowserContractReport = {
95
+ url,
96
+ timestamp: new Date().toISOString(),
97
+ browser: browser.version(),
98
+ checks: [],
99
+ navigation: [],
100
+ consoleErrors: [],
101
+ httpFailures: [],
102
+ externalRequests: [],
103
+ };
104
+ const context = await browser.newContext({
105
+ viewport: { width: 1280, height: 800 },
106
+ colorScheme: "light",
107
+ reducedMotion: "reduce",
108
+ locale: "en-US",
109
+ timezoneId: "UTC",
110
+ });
111
+ const page = await context.newPage();
112
+ page.setDefaultTimeout(8_000);
113
+ page.setDefaultNavigationTimeout(20_000);
114
+ async function check(name: string, action: () => Promise<void>): Promise<void> {
115
+ const start = performance.now();
116
+ try {
117
+ await action();
118
+ report.checks.push({ name, passed: true, durationMs: Math.round(performance.now() - start) });
119
+ console.log("PASS " + name);
120
+ } catch (error) {
121
+ const message = error instanceof Error ? error.message : String(error);
122
+ report.checks.push({
123
+ name,
124
+ passed: false,
125
+ durationMs: Math.round(performance.now() - start),
126
+ error: message.slice(0, 4000),
127
+ });
128
+ console.error("FAIL " + name + ": " + message.split("\n")[0]);
129
+ }
130
+ }
131
+ page.on("console", (message) => {
132
+ if (message.type() === "error") report.consoleErrors.push(message.text());
133
+ });
134
+ page.on("pageerror", (error) => report.consoleErrors.push(error.message));
135
+ page.on("response", (response) => {
136
+ if (response.status() >= 400)
137
+ report.httpFailures.push(response.status() + " " + response.url());
138
+ });
139
+ await context.route("**/*", async (route) => {
140
+ const requestUrl = new URL(route.request().url());
141
+ if (requestUrl.origin === url || ["data:", "blob:"].includes(requestUrl.protocol))
142
+ await route.continue();
143
+ else {
144
+ report.externalRequests.push(requestUrl.origin);
145
+ await route.abort();
146
+ }
147
+ });
148
+ try {
149
+ await page.goto(url + "/#/overview", { waitUntil: "networkidle" });
150
+ await ready(page, "overview");
151
+ await check("Chromium input type fallback", async () => {
152
+ report.inputUndefined = await page.evaluate(() => {
153
+ const input = document.createElement("input");
154
+ input.type = undefined as unknown as string;
155
+ return { type: input.type, attribute: input.getAttribute("type") };
156
+ });
157
+ assert.deepEqual(report.inputUndefined, { type: "text", attribute: "undefined" });
158
+ });
159
+ for (const route of Object.keys(PAGES)) {
160
+ // eslint-disable-next-line no-await-in-loop -- Navigation runs sequentially in one real browser history.
161
+ await check("Navigate and announce " + route, async () => {
162
+ const control = page.getByTestId("nav-" + route);
163
+ report.navigation.push({
164
+ route,
165
+ tag: await control.evaluate((element) => element.tagName),
166
+ href: await control.getAttribute("href"),
167
+ });
168
+ await destination(page, route);
169
+ assert.equal(await control.getAttribute("aria-current"), "page");
170
+ if (route !== "overview") assert.match(await page.title(), new RegExp(route, "i"));
171
+ });
172
+ }
173
+ await check("Destinations expose native deep links", async () => {
174
+ assert.equal(report.navigation.length, 15);
175
+ for (const control of report.navigation) {
176
+ assert.equal(control.tag, "A", control.route + " must be a navigation link");
177
+ assert.equal(control.href, "#/" + control.route);
178
+ }
179
+ });
180
+ await check("Skip link focuses content and preserves the route", async () => {
181
+ const before = page.url();
182
+ await page.getByRole("link", { name: "Skip to content", exact: true }).focus();
183
+ await page.keyboard.press("Enter");
184
+ assert.equal(page.url(), before);
185
+ assert.equal(await page.evaluate(() => document.activeElement?.id), "main");
186
+ });
187
+ await check("Light and dark choices persist across reload", async () => {
188
+ await destination(page, "theme");
189
+ await page.evaluate(() => localStorage.clear());
190
+ await page.reload({ waitUntil: "networkidle" });
191
+ await ready(page, "theme");
192
+ await page.getByRole("combobox", { name: "Colour mode", exact: true }).selectOption("dark");
193
+ await scheme(page, "dark");
194
+ await page.reload({ waitUntil: "networkidle" });
195
+ await ready(page, "theme");
196
+ await scheme(page, "dark");
197
+ assert.equal(
198
+ await page.getByRole("combobox", { name: "Colour mode", exact: true }).inputValue(),
199
+ "dark",
200
+ );
201
+ await page.getByRole("combobox", { name: "Colour mode", exact: true }).selectOption("light");
202
+ await scheme(page, "light");
203
+ await page.reload({ waitUntil: "networkidle" });
204
+ await ready(page, "theme");
205
+ await scheme(page, "light");
206
+ assert.equal(
207
+ await page.getByRole("combobox", { name: "Colour mode", exact: true }).inputValue(),
208
+ "light",
209
+ );
210
+ });
211
+ await check("Live layout overrides persist and auto follows the viewport", async () => {
212
+ await destination(page, "adaptive");
213
+ await page.getByTestId("layout-mobile").click();
214
+ await layout(page, "mobile");
215
+ assert.equal(await page.getByTestId("bottom-bar").count(), 1);
216
+ await page.getByTestId("layout-tv").click();
217
+ await layout(page, "tv");
218
+ await page.reload({ waitUntil: "networkidle" });
219
+ await ready(page, "adaptive");
220
+ await layout(page, "tv");
221
+ assert.equal(await page.getByTestId("drawer").count(), 1);
222
+ await page.getByTestId("layout-auto").click();
223
+ await layout(page, "desktop");
224
+ await page.setViewportSize({ width: 390, height: 844 });
225
+ await layout(page, "mobile");
226
+ await page.setViewportSize({ width: 1280, height: 800 });
227
+ await layout(page, "desktop");
228
+ });
229
+ await check("TV arrows move spatial focus and Enter activates a tile", async () => {
230
+ await destination(page, "adaptive");
231
+ await page.getByTestId("layout-tv").click();
232
+ await layout(page, "tv");
233
+ await page.locator('[data-tile="tile 1"]').focus();
234
+ await page.keyboard.press("ArrowRight");
235
+ assert.equal(
236
+ await page.evaluate(() => document.activeElement?.getAttribute("data-tile")),
237
+ "tile 2",
238
+ );
239
+ await page.keyboard.press("Enter");
240
+ await containsText(page, '[data-testid="dpad-focus"]', "tile 2 (activated)");
241
+ await page.keyboard.press("ArrowDown");
242
+ assert.equal(
243
+ await page.evaluate(() => document.activeElement?.getAttribute("data-tile")),
244
+ "tile 8",
245
+ );
246
+ await page.getByTestId("layout-auto").click();
247
+ await layout(page, "desktop");
248
+ });
249
+ await check("TV Back returns to the previous destination", async () => {
250
+ await destination(page, "overview");
251
+ await destination(page, "adaptive");
252
+ await page.getByTestId("layout-tv").click();
253
+ await layout(page, "tv");
254
+ await page.getByTestId("nav-adaptive").focus();
255
+ await page.keyboard.press("Escape");
256
+ await ready(page, "overview");
257
+ await destination(page, "adaptive");
258
+ await page.getByTestId("layout-auto").click();
259
+ await layout(page, "desktop");
260
+ });
261
+ await check("Forms validate, preview valid values and reset", async () => {
262
+ await destination(page, "forms");
263
+ await page.getByRole("button", { name: "Preview profile", exact: true }).click();
264
+ await page.getByText("Enter a name with at least two characters.", { exact: true }).waitFor();
265
+ await page.getByRole("textbox", { name: /Display name/ }).fill("Ada");
266
+ await page.getByRole("textbox", { name: /Email address/ }).fill("ada@example.invalid");
267
+ await page.getByLabel("These are local sample values").check();
268
+ await page.getByRole("button", { name: "Preview profile", exact: true }).click();
269
+ await containsText(page, "main [role=status]", "Valid preview ready.");
270
+ assert.match(await page.locator("aside").innerText(), /Ada/);
271
+ await page.getByRole("button", { name: "Reset form", exact: true }).click();
272
+ assert.equal(await page.getByRole("textbox", { name: /Display name/ }).inputValue(), "");
273
+ assert.equal(await page.getByLabel("These are local sample values").isChecked(), false);
274
+ await containsText(page, "main [role=status]", "No profile has been saved.");
275
+ });
276
+ await check(
277
+ "Explorer selects and opens with keyboard, changes star, filters and grids",
278
+ async () => {
279
+ await destination(page, "explorer");
280
+ const row = page.getByRole("row").filter({ hasText: "Material notes.md" });
281
+ await row.focus();
282
+ await page.keyboard.press("Space");
283
+ await containsText(page, "main [role=status]", "Selected Material notes.md");
284
+ assert.equal(await row.getAttribute("aria-selected"), "true");
285
+ await page.keyboard.press("Enter");
286
+ await containsText(page, "main [role=status]", "Opened local preview: Material notes.md");
287
+ await row.getByRole("button", { name: "Unstar", exact: true }).click();
288
+ assert.equal(await row.getByRole("button", { name: "Star", exact: true }).count(), 1);
289
+ const explorer = page.getByRole("region", { name: "Google Drive File List", exact: true });
290
+ await explorer.getByRole("button", { name: /^People/ }).click();
291
+ assert.equal(await explorer.locator("tbody tr").count(), 2);
292
+ await explorer.getByRole("button", { name: "Grid view", exact: true }).click();
293
+ assert.equal(await explorer.locator("table").count(), 0);
294
+ assert.equal(
295
+ await explorer.getByRole("button", { name: "Design studies", exact: true }).count(),
296
+ 1,
297
+ );
298
+ assert.equal(
299
+ await explorer.getByRole("button", { name: "Colour palette.json", exact: true }).count(),
300
+ 1,
301
+ );
302
+ },
303
+ );
304
+ await check("Reader changes page and reading mode with local artwork", async () => {
305
+ await destination(page, "reader");
306
+ await containsText(page, "main [role=status]", "Illustration page: 1");
307
+ await page.getByRole("button", { name: "Page suivante", exact: true }).click();
308
+ await containsText(page, "main [role=status]", "Illustration page: 2");
309
+ await page.getByRole("button", { name: "Page précédente", exact: true }).click();
310
+ await containsText(page, "main [role=status]", "Illustration page: 1");
311
+ await page
312
+ .getByRole("button", { name: "Mode de lecture vertical (webtoon)", exact: true })
313
+ .click();
314
+ const vertical = page.locator('main [aria-label$="lecture verticale"]');
315
+ await vertical.waitFor();
316
+ assert.equal(await vertical.getAttribute("tabindex"), "0");
317
+ await page.getByRole("button", { name: "Annotated pages", exact: true }).click();
318
+ assert.equal(
319
+ await page
320
+ .getByRole("button", { name: "Annotated pages", exact: true })
321
+ .getAttribute("aria-pressed"),
322
+ "true",
323
+ );
324
+ await page.getByText("Local demonstration page 1.", { exact: false }).first().waitFor();
325
+ assert.equal((await page.locator('main img[src^="data:image/svg+xml"]').count()) > 0, true);
326
+ });
327
+ await check("Design generates inspectable CSS, tokens and React source", async () => {
328
+ await destination(page, "design");
329
+ await page
330
+ .getByRole("textbox", { name: "Describe the interface", exact: true })
331
+ .fill("A minimal dashboard for developers, with a list-detail layout.");
332
+ await page.getByRole("button", { name: "Generate design", exact: true }).click();
333
+ await containsText(page, "main [role=status]", "Design generated locally.");
334
+ const files = page.getByRole("combobox", { name: "File", exact: true });
335
+ assert.equal(await files.locator("option").count(), 3);
336
+ assert.match(await page.locator("main").innerText(), /--md-sys-color-primary/);
337
+ await files.selectOption("src/index.tsx");
338
+ assert.match(await page.locator("main").innerText(), /@aphrody[/]/);
339
+ });
340
+ await check("AI fixture renders events and Stop restores the composer", async () => {
341
+ await destination(page, "ai");
342
+ await page
343
+ .getByRole("textbox", { name: "Draft for the local protocol fixture", exact: true })
344
+ .fill("Inspect the package inventory.");
345
+ await page.getByRole("button", { name: "Send", exact: true }).click();
346
+ await page
347
+ .getByText(/Local protocol fixture: your draft contains/)
348
+ .first()
349
+ .waitFor();
350
+ await page
351
+ .getByRole("status")
352
+ .filter({ hasText: /^Ready$/ })
353
+ .waitFor();
354
+ await page.getByRole("button", { name: "Send", exact: true }).click();
355
+ await page.getByRole("button", { name: "Stop", exact: true }).click();
356
+ await containsText(page, "main [role=status]", "Stream stopped.");
357
+ await page.getByRole("button", { name: "Stop", exact: true }).waitFor({ state: "detached" });
358
+ assert.equal(await page.getByRole("button", { name: "Stop", exact: true }).count(), 0);
359
+ assert.equal(await page.getByRole("button", { name: "Send", exact: true }).isEnabled(), true);
360
+ });
361
+ await check(
362
+ "Local rendering has no console errors, HTTP failures or external requests",
363
+ async () => {
364
+ assert.deepEqual(report.consoleErrors, []);
365
+ assert.deepEqual(report.httpFailures, []);
366
+ assert.deepEqual(report.externalRequests, []);
367
+ },
368
+ );
369
+ } finally {
370
+ await context.close();
371
+ await browser.close();
372
+ }
373
+ return report;
374
+ }
375
+
376
+ if (import.meta.main) {
377
+ const args = process.argv.slice(2);
378
+ if (args.includes("--help")) {
379
+ console.log(
380
+ "bun apps/showcase/scripts/browser-contract.ts [--url http://127.0.0.1:3312] [--out " +
381
+ resolve(RUNS, "browser-contract.json") +
382
+ "]",
383
+ );
384
+ } else {
385
+ const value = (flag: string) => {
386
+ const index = args.indexOf(flag);
387
+ if (index < 0) return undefined;
388
+ const next = args[index + 1];
389
+ if (!next || next.startsWith("--")) throw new TypeError("Missing value for " + flag);
390
+ return next;
391
+ };
392
+ const out = outputPath(value("--out"));
393
+ const report = await browserContract(value("--url") ?? "http://127.0.0.1:3312");
394
+ await mkdir(dirname(out), { recursive: true });
395
+ await Bun.write(out, JSON.stringify(report, null, 2) + "\n");
396
+ const failures = report.checks.filter((check) => !check.passed);
397
+ console.log(report.checks.length + " checks, " + failures.length + " failures; " + out);
398
+ if (failures.length) process.exitCode = 1;
399
+ }
400
+ }
@@ -0,0 +1,56 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import { resolve } from "node:path";
3
+
4
+ export const SHOWCASE_ROOT = resolve(import.meta.dir, "..");
5
+ export const APHRODY_ROOT = resolve(SHOWCASE_ROOT, "../../..");
6
+ export const TAURI_ROOT = resolve(APHRODY_ROOT, "crates/ui/m3-showcase");
7
+ /** Canonical Aphrody artwork stays in its protected identity owner; generated icons are ignored. */
8
+ export const ICON_SOURCE = resolve(
9
+ SHOWCASE_ROOT,
10
+ "../../../crates/ui/identity/assets/brand/icon.svg",
11
+ );
12
+
13
+ export function iconCommand(root = TAURI_ROOT, executable = Bun.which("tauri")): string[] {
14
+ if (!executable)
15
+ throw new Error(
16
+ "The installed Tauri CLI is missing. Qualify the declared Aphrody/Yolo toolchain before generating icons.",
17
+ );
18
+ return [
19
+ executable,
20
+ "icon",
21
+ ICON_SOURCE,
22
+ "--output",
23
+ resolve(root, "icons"),
24
+ "--ios-color",
25
+ "#6750a4",
26
+ ];
27
+ }
28
+
29
+ export async function generateIcons(args: string[] = [], root = TAURI_ROOT): Promise<void> {
30
+ if (!(await Bun.file(ICON_SOURCE).exists()))
31
+ throw new Error(`Canonical Aphrody icon is missing: ${ICON_SOURCE}`);
32
+ const command = iconCommand(root);
33
+ if (args.includes("--plan")) {
34
+ console.log(
35
+ JSON.stringify({ command, source: ICON_SOURCE, output: resolve(root, "icons") }, null, 2),
36
+ );
37
+ return;
38
+ }
39
+ const process = Bun.spawn(command, {
40
+ cwd: root,
41
+ stdin: "inherit",
42
+ stdout: "inherit",
43
+ stderr: "inherit",
44
+ });
45
+ const code = await process.exited;
46
+ if (code !== 0) throw new Error(`Tauri icon generation failed with exit ${code}`);
47
+ }
48
+
49
+ if (import.meta.main) {
50
+ try {
51
+ await generateIcons(Bun.argv.slice(2));
52
+ } catch (error) {
53
+ console.error(error instanceof Error ? error.message : error);
54
+ process.exitCode = 1;
55
+ }
56
+ }
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env bun
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ // Writes src/generated/inventory.json: every package and app of the monorepo (name, version, description, entry
4
+ // points, location, whether it is in the Bun workspace). The showcase serves it from its own API (`/api/packages`)
5
+ // and its pages read the same data. A test checks the committed file is current: run `bun run inventory` after a
6
+ // version or description change.
7
+ import { existsSync, readdirSync, readFileSync } from "node:fs";
8
+ import { dirname, join, resolve } from "node:path";
9
+
10
+ const here = dirname(import.meta.path);
11
+ export const ROOT = resolve(here, "../../..");
12
+ export const OUT = join(here, "../src/generated/inventory.json");
13
+
14
+ export interface InventoryEntry {
15
+ name: string;
16
+ version: string;
17
+ description: string;
18
+ /** Path relative to the repository. */
19
+ dir: string;
20
+ kind: "package" | "app";
21
+ /** In the Bun workspace (installed and linked) or a host-bound member outside it. */
22
+ workspace: boolean;
23
+ private: boolean;
24
+ /** Number of `exports` entries (0 when the package declares `main` only). */
25
+ exports: number;
26
+ bin: string[];
27
+ }
28
+
29
+ function workspaceExclusions(root: string): Set<string> {
30
+ const manifest = JSON.parse(readFileSync(join(root, "package.json"), "utf8")) as {
31
+ workspaces?: { packages?: string[] };
32
+ };
33
+ return new Set(
34
+ (manifest.workspaces?.packages ?? []).filter((g) => g.startsWith("!")).map((g) => g.slice(1)),
35
+ );
36
+ }
37
+
38
+ /** The inventory, sorted by name. */
39
+ export function collect(root: string = ROOT): InventoryEntry[] {
40
+ const excluded = workspaceExclusions(root);
41
+ const entries: InventoryEntry[] = [];
42
+ for (const [kind, base] of [
43
+ ["package", "packages"],
44
+ ["app", "apps"],
45
+ ] as const) {
46
+ const dir = join(root, base);
47
+ if (!existsSync(dir)) continue;
48
+ for (const name of readdirSync(dir).toSorted()) {
49
+ const file = join(dir, name, "package.json");
50
+ if (!existsSync(file)) continue;
51
+ const manifest = JSON.parse(readFileSync(file, "utf8")) as {
52
+ name: string;
53
+ version?: string;
54
+ description?: string;
55
+ private?: boolean;
56
+ exports?: Record<string, unknown> | string;
57
+ bin?: string | Record<string, string>;
58
+ };
59
+ const rel = `${base}/${name}`;
60
+ const exported = manifest.exports;
61
+ entries.push({
62
+ name: manifest.name,
63
+ version: manifest.version ?? "0.0.0",
64
+ description: (manifest.description ?? "").replace(/\s+/g, " ").trim().slice(0, 220),
65
+ dir: rel,
66
+ kind,
67
+ workspace: !excluded.has(rel),
68
+ private: manifest.private === true,
69
+ exports:
70
+ typeof exported === "object" && exported
71
+ ? Object.keys(exported).length
72
+ : exported
73
+ ? 1
74
+ : 0,
75
+ bin: typeof manifest.bin === "string" ? [manifest.name] : Object.keys(manifest.bin ?? {}),
76
+ });
77
+ }
78
+ }
79
+ return entries.toSorted((a, b) => a.name.localeCompare(b.name));
80
+ }
81
+
82
+ if (import.meta.main) {
83
+ const entries = collect();
84
+ await Bun.write(OUT, `${JSON.stringify(entries, null, 2)}\n`);
85
+ console.log(`inventory: ${entries.length} packages and apps -> ${OUT}`);
86
+ }