@flamingo-stack/openframe-frontend-core 0.0.295 → 0.0.296-snapshot.20260621021605

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 (291) hide show
  1. package/README.md +9 -0
  2. package/dist/{chunk-7RIYT7ZH.js → chunk-2QG57XOJ.js} +1067 -205
  3. package/dist/chunk-2QG57XOJ.js.map +1 -0
  4. package/dist/{chunk-7KXD7CWD.js → chunk-3JIQVE7T.js} +9 -15
  5. package/dist/{chunk-7KXD7CWD.js.map → chunk-3JIQVE7T.js.map} +1 -1
  6. package/dist/{chunk-FT4FCV7L.cjs → chunk-4PSQS3SW.cjs} +7 -9
  7. package/dist/chunk-4PSQS3SW.cjs.map +1 -0
  8. package/dist/{chunk-OOKKGOPQ.js → chunk-4TLE6VLU.js} +30 -24
  9. package/dist/chunk-4TLE6VLU.js.map +1 -0
  10. package/dist/{chunk-6IBA2MQV.cjs → chunk-53FUMSZ5.cjs} +40 -46
  11. package/dist/chunk-53FUMSZ5.cjs.map +1 -0
  12. package/dist/{chunk-D3LEFMOA.cjs → chunk-54KNMC2R.cjs} +3 -3
  13. package/dist/{chunk-D3LEFMOA.cjs.map → chunk-54KNMC2R.cjs.map} +1 -1
  14. package/dist/{chunk-EYEW6PTA.cjs → chunk-6C526VNN.cjs} +358 -118
  15. package/dist/chunk-6C526VNN.cjs.map +1 -0
  16. package/dist/{chunk-5O6N3BKR.cjs → chunk-7OVGB2DQ.cjs} +19 -25
  17. package/dist/chunk-7OVGB2DQ.cjs.map +1 -0
  18. package/dist/{chunk-6GCI7JOE.js → chunk-AD6C23QY.js} +8 -7
  19. package/dist/{chunk-6GCI7JOE.js.map → chunk-AD6C23QY.js.map} +1 -1
  20. package/dist/chunk-F5OB2YAL.cjs +144 -0
  21. package/dist/chunk-F5OB2YAL.cjs.map +1 -0
  22. package/dist/chunk-FBWXMMRB.cjs +2 -0
  23. package/dist/chunk-FBWXMMRB.cjs.map +1 -0
  24. package/dist/{chunk-YIGPRLQY.cjs → chunk-FCDQNTDG.cjs} +21 -20
  25. package/dist/chunk-FCDQNTDG.cjs.map +1 -0
  26. package/dist/{chunk-XXI7BNB6.cjs → chunk-FQOTC3UU.cjs} +321 -18
  27. package/dist/chunk-FQOTC3UU.cjs.map +1 -0
  28. package/dist/{chunk-INDQMNP6.cjs → chunk-GUTS7HGA.cjs} +11658 -2146
  29. package/dist/chunk-GUTS7HGA.cjs.map +1 -0
  30. package/dist/chunk-GZ4C3XW6.js +2 -0
  31. package/dist/chunk-GZ4C3XW6.js.map +1 -0
  32. package/dist/{chunk-HOVJGXF7.js → chunk-IL47XWV5.js} +8 -14
  33. package/dist/{chunk-HOVJGXF7.js.map → chunk-IL47XWV5.js.map} +1 -1
  34. package/dist/{chunk-LCNMR277.js → chunk-IZ7JSBFP.js} +1 -1
  35. package/dist/chunk-IZ7JSBFP.js.map +1 -0
  36. package/dist/{chunk-5IJ46KAV.js → chunk-JALO4TAZ.js} +360 -57
  37. package/dist/chunk-JALO4TAZ.js.map +1 -0
  38. package/dist/{chunk-AQOWFSMB.cjs → chunk-L6PSSIUQ.cjs} +1 -1
  39. package/dist/chunk-L6PSSIUQ.cjs.map +1 -0
  40. package/dist/{chunk-J3RDKZ32.js → chunk-L7ULJKG7.js} +6 -10
  41. package/dist/{chunk-J3RDKZ32.js.map → chunk-L7ULJKG7.js.map} +1 -1
  42. package/dist/{chunk-6BZEAPNT.js → chunk-PC746XCO.js} +15120 -5608
  43. package/dist/chunk-PC746XCO.js.map +1 -0
  44. package/dist/{chunk-3ZXUQQL4.js → chunk-PI4WSYQV.js} +2 -2
  45. package/dist/{chunk-E4XABBSU.js → chunk-PWQUAVA3.js} +338 -98
  46. package/dist/chunk-PWQUAVA3.js.map +1 -0
  47. package/dist/chunk-SA2WPJVO.js +144 -0
  48. package/dist/chunk-SA2WPJVO.js.map +1 -0
  49. package/dist/{chunk-ETACGX2A.cjs → chunk-UNVE2SDJ.cjs} +37 -31
  50. package/dist/chunk-UNVE2SDJ.cjs.map +1 -0
  51. package/dist/{chunk-5E2HOSSH.cjs → chunk-WMSTJAZT.cjs} +913 -51
  52. package/dist/chunk-WMSTJAZT.cjs.map +1 -0
  53. package/dist/{chunk-EJXHZX2E.js → chunk-X4DOXQRT.js} +4 -6
  54. package/dist/{chunk-EJXHZX2E.js.map → chunk-X4DOXQRT.js.map} +1 -1
  55. package/dist/{chunk-A2YL7QRX.cjs → chunk-YBYI62OE.cjs} +33 -37
  56. package/dist/chunk-YBYI62OE.cjs.map +1 -0
  57. package/dist/components/case-studies/index.cjs +126 -0
  58. package/dist/components/case-studies/index.cjs.map +1 -0
  59. package/dist/components/case-studies/index.d.ts +2 -0
  60. package/dist/components/case-studies/index.d.ts.map +1 -0
  61. package/dist/components/case-studies/index.js +126 -0
  62. package/dist/components/case-studies/index.js.map +1 -0
  63. package/dist/components/case-studies/share-experience-section.d.ts +48 -0
  64. package/dist/components/case-studies/share-experience-section.d.ts.map +1 -0
  65. package/dist/components/chat/chat-container.d.ts.map +1 -1
  66. package/dist/components/chat/error-message-display.d.ts.map +1 -1
  67. package/dist/components/chat/index.cjs +8 -18
  68. package/dist/components/chat/index.cjs.map +1 -1
  69. package/dist/components/chat/index.js +75 -85
  70. package/dist/components/chat/types/component.types.d.ts +2 -0
  71. package/dist/components/chat/types/component.types.d.ts.map +1 -1
  72. package/dist/components/contact/index.cjs +8 -15
  73. package/dist/components/contact/index.cjs.map +1 -1
  74. package/dist/components/contact/index.js +7 -14
  75. package/dist/components/docs/doc-viewer.d.ts +39 -2
  76. package/dist/components/docs/doc-viewer.d.ts.map +1 -1
  77. package/dist/components/docs/docs-hub-page.d.ts +46 -0
  78. package/dist/components/docs/docs-hub-page.d.ts.map +1 -0
  79. package/dist/components/docs/index.cjs +17 -9
  80. package/dist/components/docs/index.cjs.map +1 -1
  81. package/dist/components/docs/index.d.ts +4 -0
  82. package/dist/components/docs/index.d.ts.map +1 -1
  83. package/dist/components/docs/index.js +16 -8
  84. package/dist/components/docs/skeletons.d.ts +32 -0
  85. package/dist/components/docs/skeletons.d.ts.map +1 -0
  86. package/dist/components/docs/use-docs-resolve-link.d.ts +20 -0
  87. package/dist/components/docs/use-docs-resolve-link.d.ts.map +1 -0
  88. package/dist/components/docs/use-document-tree.d.ts.map +1 -1
  89. package/dist/components/embeds/embed-container.d.ts +37 -0
  90. package/dist/components/embeds/embed-container.d.ts.map +1 -0
  91. package/dist/components/embeds/embed-iframe.d.ts.map +1 -1
  92. package/dist/components/embeds/file-download-card.d.ts +18 -0
  93. package/dist/components/embeds/file-download-card.d.ts.map +1 -0
  94. package/dist/components/embeds/index.cjs +38 -15
  95. package/dist/components/embeds/index.cjs.map +1 -1
  96. package/dist/components/embeds/index.d.ts +8 -0
  97. package/dist/components/embeds/index.d.ts.map +1 -1
  98. package/dist/components/embeds/index.js +40 -17
  99. package/dist/components/embeds/linkedin-embed-client.d.ts +8 -0
  100. package/dist/components/embeds/linkedin-embed-client.d.ts.map +1 -0
  101. package/dist/components/embeds/markdown-image.d.ts +5 -0
  102. package/dist/components/embeds/markdown-image.d.ts.map +1 -0
  103. package/dist/components/embeds/reddit-embed-client.d.ts +7 -0
  104. package/dist/components/embeds/reddit-embed-client.d.ts.map +1 -0
  105. package/dist/components/embeds/rich-markdown-runtime.d.ts +46 -0
  106. package/dist/components/embeds/rich-markdown-runtime.d.ts.map +1 -0
  107. package/dist/components/embeds/twitter-embed-client.d.ts +8 -0
  108. package/dist/components/embeds/twitter-embed-client.d.ts.map +1 -0
  109. package/dist/components/faq/index.cjs +9 -16
  110. package/dist/components/faq/index.cjs.map +1 -1
  111. package/dist/components/faq/index.js +8 -15
  112. package/dist/components/features/index.cjs +8 -16
  113. package/dist/components/features/index.cjs.map +1 -1
  114. package/dist/components/features/index.js +24 -32
  115. package/dist/components/features/notifications/notification-drawer.d.ts.map +1 -1
  116. package/dist/components/features/notifications/notifications-context.d.ts +5 -1
  117. package/dist/components/features/notifications/notifications-context.d.ts.map +1 -1
  118. package/dist/components/index.cjs +257 -452
  119. package/dist/components/index.cjs.map +1 -1
  120. package/dist/components/index.js +781 -976
  121. package/dist/components/index.js.map +1 -1
  122. package/dist/components/layout/page-header.d.ts +78 -0
  123. package/dist/components/layout/page-header.d.ts.map +1 -0
  124. package/dist/components/layout/page-layout.d.ts +10 -1
  125. package/dist/components/layout/page-layout.d.ts.map +1 -1
  126. package/dist/components/layout/page-with-header.d.ts +67 -0
  127. package/dist/components/layout/page-with-header.d.ts.map +1 -0
  128. package/dist/components/layout/title-block.d.ts +17 -1
  129. package/dist/components/layout/title-block.d.ts.map +1 -1
  130. package/dist/components/navigation/index.cjs +7 -15
  131. package/dist/components/navigation/index.cjs.map +1 -1
  132. package/dist/components/navigation/index.js +9 -17
  133. package/dist/components/onboarding-guides/index.cjs +35 -36
  134. package/dist/components/onboarding-guides/index.cjs.map +1 -1
  135. package/dist/components/onboarding-guides/index.js +13 -14
  136. package/dist/components/onboarding-guides/index.js.map +1 -1
  137. package/dist/components/onboarding-guides/onboarding-guide-detail-view.d.ts +1 -1
  138. package/dist/components/onboarding-guides/onboarding-guide-detail-view.d.ts.map +1 -1
  139. package/dist/components/related-content/index.cjs +9 -16
  140. package/dist/components/related-content/index.cjs.map +1 -1
  141. package/dist/components/related-content/index.js +8 -15
  142. package/dist/components/shared/dev-section/dev-section-page.d.ts +9 -0
  143. package/dist/components/shared/dev-section/dev-section-page.d.ts.map +1 -1
  144. package/dist/components/shared/dev-section/dev-section-view.d.ts.map +1 -1
  145. package/dist/components/shared/dev-section/index.d.ts +1 -1
  146. package/dist/components/shared/dev-section/index.d.ts.map +1 -1
  147. package/dist/components/shared/doc-search/use-doc-search.d.ts.map +1 -1
  148. package/dist/components/shared/legal-document/legal-document-page.d.ts.map +1 -1
  149. package/dist/components/shared/product-release/release-detail-page.d.ts.map +1 -1
  150. package/dist/components/tickets/index.cjs +100 -112
  151. package/dist/components/tickets/index.cjs.map +1 -1
  152. package/dist/components/tickets/index.js +20 -32
  153. package/dist/components/tickets/index.js.map +1 -1
  154. package/dist/components/ui/button/split-button.d.ts.map +1 -1
  155. package/dist/components/ui/file-manager/index.cjs +50 -52
  156. package/dist/components/ui/file-manager/index.cjs.map +1 -1
  157. package/dist/components/ui/file-manager/index.js +4 -6
  158. package/dist/components/ui/file-manager/index.js.map +1 -1
  159. package/dist/components/ui/index.cjs +13 -19
  160. package/dist/components/ui/index.cjs.map +1 -1
  161. package/dist/components/ui/index.d.ts +2 -0
  162. package/dist/components/ui/index.d.ts.map +1 -1
  163. package/dist/components/ui/index.js +133 -139
  164. package/dist/components/ui/release-changelog-section.d.ts +6 -2
  165. package/dist/components/ui/release-changelog-section.d.ts.map +1 -1
  166. package/dist/components/ui/rich-markdown-renderer.d.ts +34 -0
  167. package/dist/components/ui/rich-markdown-renderer.d.ts.map +1 -0
  168. package/dist/components/ui/simple-markdown-renderer.d.ts +2 -8
  169. package/dist/components/ui/simple-markdown-renderer.d.ts.map +1 -1
  170. package/dist/contexts/chat-runtime-context.d.ts +14 -0
  171. package/dist/contexts/chat-runtime-context.d.ts.map +1 -1
  172. package/dist/contexts/index.cjs +3 -3
  173. package/dist/contexts/index.js +5 -5
  174. package/dist/embed-shims/index.cjs +3 -3
  175. package/dist/embed-shims/index.cjs.map +1 -1
  176. package/dist/embed-shims/index.js +4 -4
  177. package/dist/hooks/index.cjs +4 -9
  178. package/dist/hooks/index.cjs.map +1 -1
  179. package/dist/hooks/index.js +6 -11
  180. package/dist/index.cjs +14 -20
  181. package/dist/index.cjs.map +1 -1
  182. package/dist/index.js +362 -368
  183. package/dist/types/doc-source.d.ts +31 -1
  184. package/dist/types/doc-source.d.ts.map +1 -1
  185. package/dist/utils/index.cjs +4 -0
  186. package/dist/utils/index.cjs.map +1 -1
  187. package/dist/utils/index.d.ts +1 -0
  188. package/dist/utils/index.d.ts.map +1 -1
  189. package/dist/utils/index.js +4 -1
  190. package/dist/utils/index.js.map +1 -1
  191. package/dist/utils/page-header-constants.d.ts +15 -0
  192. package/dist/utils/page-header-constants.d.ts.map +1 -0
  193. package/dist/utils/social-embed-cache.d.ts +29 -0
  194. package/dist/utils/social-embed-cache.d.ts.map +1 -0
  195. package/package.json +7 -1
  196. package/src/components/case-studies/index.ts +4 -0
  197. package/src/components/case-studies/share-experience-section.tsx +185 -0
  198. package/src/components/chat/chat-container.tsx +5 -7
  199. package/src/components/chat/embeddable-chat.tsx +1 -1
  200. package/src/components/chat/error-message-display.tsx +49 -31
  201. package/src/components/chat/types/component.types.ts +2 -0
  202. package/src/components/docs/doc-viewer.tsx +111 -19
  203. package/src/components/docs/docs-hub-page.tsx +149 -0
  204. package/src/components/docs/index.ts +17 -0
  205. package/src/components/docs/skeletons.tsx +138 -0
  206. package/src/components/docs/use-docs-resolve-link.ts +52 -0
  207. package/src/components/docs/use-document-tree.ts +21 -0
  208. package/src/components/embeds/embed-container.tsx +80 -0
  209. package/src/components/embeds/embed-iframe.tsx +7 -9
  210. package/src/components/embeds/file-download-card.tsx +54 -0
  211. package/src/components/embeds/index.ts +30 -0
  212. package/src/components/embeds/linkedin-embed-client.tsx +100 -0
  213. package/src/components/embeds/markdown-image.tsx +88 -0
  214. package/src/components/embeds/og-link-preview.tsx +13 -13
  215. package/src/components/embeds/reddit-embed-client.tsx +550 -0
  216. package/src/components/embeds/rich-markdown-runtime.tsx +79 -0
  217. package/src/components/embeds/twitter-embed-client.tsx +308 -0
  218. package/src/components/features/notifications/notification-drawer.tsx +18 -7
  219. package/src/components/features/notifications/notifications-context.tsx +7 -0
  220. package/src/components/layout/page-header.tsx +182 -0
  221. package/src/components/layout/page-layout.tsx +14 -1
  222. package/src/components/layout/page-with-header.tsx +110 -0
  223. package/src/components/layout/title-block.tsx +40 -62
  224. package/src/components/onboarding-guides/onboarding-guide-detail-view.tsx +3 -3
  225. package/src/components/shared/dev-section/dev-section-page.tsx +9 -1
  226. package/src/components/shared/dev-section/dev-section-view.tsx +14 -9
  227. package/src/components/shared/dev-section/index.ts +1 -1
  228. package/src/components/shared/doc-search/use-doc-search.ts +7 -3
  229. package/src/components/shared/legal-document/legal-document-page.tsx +2 -2
  230. package/src/components/shared/product-release/release-detail-page.tsx +6 -4
  231. package/src/components/ui/button/split-button.tsx +5 -2
  232. package/src/components/ui/index.ts +2 -0
  233. package/src/components/ui/release-changelog-section.tsx +7 -2
  234. package/src/components/ui/rich-markdown-renderer.tsx +1203 -0
  235. package/src/components/ui/simple-markdown-renderer.tsx +7 -11
  236. package/src/contexts/chat-runtime-context.tsx +14 -0
  237. package/src/stories/NotificationDrawer.stories.tsx +2 -0
  238. package/src/types/doc-source.ts +33 -1
  239. package/src/utils/index.ts +1 -0
  240. package/src/utils/page-header-constants.ts +15 -0
  241. package/src/utils/social-embed-cache.ts +391 -0
  242. package/dist/chunk-26PKDALD.js +0 -2379
  243. package/dist/chunk-26PKDALD.js.map +0 -1
  244. package/dist/chunk-3MCHAFHB.js +0 -89
  245. package/dist/chunk-3MCHAFHB.js.map +0 -1
  246. package/dist/chunk-3XIB4VKS.cjs +0 -619
  247. package/dist/chunk-3XIB4VKS.cjs.map +0 -1
  248. package/dist/chunk-4W7NYJ3B.cjs +0 -3009
  249. package/dist/chunk-4W7NYJ3B.cjs.map +0 -1
  250. package/dist/chunk-5E2HOSSH.cjs.map +0 -1
  251. package/dist/chunk-5IJ46KAV.js.map +0 -1
  252. package/dist/chunk-5O6N3BKR.cjs.map +0 -1
  253. package/dist/chunk-6BZEAPNT.js.map +0 -1
  254. package/dist/chunk-6IBA2MQV.cjs.map +0 -1
  255. package/dist/chunk-6JINAOI7.cjs +0 -311
  256. package/dist/chunk-6JINAOI7.cjs.map +0 -1
  257. package/dist/chunk-7RIYT7ZH.js.map +0 -1
  258. package/dist/chunk-A2YL7QRX.cjs.map +0 -1
  259. package/dist/chunk-AQOWFSMB.cjs.map +0 -1
  260. package/dist/chunk-E4XABBSU.js.map +0 -1
  261. package/dist/chunk-ETACGX2A.cjs.map +0 -1
  262. package/dist/chunk-EYEW6PTA.cjs.map +0 -1
  263. package/dist/chunk-FQJK446R.js +0 -1606
  264. package/dist/chunk-FQJK446R.js.map +0 -1
  265. package/dist/chunk-FT4FCV7L.cjs.map +0 -1
  266. package/dist/chunk-INDQMNP6.cjs.map +0 -1
  267. package/dist/chunk-J54Z3OCR.cjs +0 -1606
  268. package/dist/chunk-J54Z3OCR.cjs.map +0 -1
  269. package/dist/chunk-KXCRGTRN.cjs +0 -2379
  270. package/dist/chunk-KXCRGTRN.cjs.map +0 -1
  271. package/dist/chunk-LCNMR277.js.map +0 -1
  272. package/dist/chunk-LFGGF7OT.cjs +0 -449
  273. package/dist/chunk-LFGGF7OT.cjs.map +0 -1
  274. package/dist/chunk-M2OCXTNT.js +0 -311
  275. package/dist/chunk-M2OCXTNT.js.map +0 -1
  276. package/dist/chunk-NSPOYUBH.js +0 -3009
  277. package/dist/chunk-NSPOYUBH.js.map +0 -1
  278. package/dist/chunk-OOKKGOPQ.js.map +0 -1
  279. package/dist/chunk-OQ6X7ZOC.js +0 -449
  280. package/dist/chunk-OQ6X7ZOC.js.map +0 -1
  281. package/dist/chunk-POKKCWKF.js +0 -354
  282. package/dist/chunk-POKKCWKF.js.map +0 -1
  283. package/dist/chunk-TFSYSWPS.cjs +0 -89
  284. package/dist/chunk-TFSYSWPS.cjs.map +0 -1
  285. package/dist/chunk-XXI7BNB6.cjs.map +0 -1
  286. package/dist/chunk-YD43AKI5.js +0 -619
  287. package/dist/chunk-YD43AKI5.js.map +0 -1
  288. package/dist/chunk-YETA25JW.cjs +0 -354
  289. package/dist/chunk-YETA25JW.cjs.map +0 -1
  290. package/dist/chunk-YIGPRLQY.cjs.map +0 -1
  291. /package/dist/{chunk-3ZXUQQL4.js.map → chunk-PI4WSYQV.js.map} +0 -0
@@ -1,3009 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }"use client";
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
- var _chunkJ54Z3OCRcjs = require('./chunk-J54Z3OCR.cjs');
21
-
22
-
23
-
24
- var _chunkTFSYSWPScjs = require('./chunk-TFSYSWPS.cjs');
25
-
26
-
27
- var _chunkAQOWFSMBcjs = require('./chunk-AQOWFSMB.cjs');
28
-
29
-
30
- var _chunkXL4V2PYGcjs = require('./chunk-XL4V2PYG.cjs');
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
- var _chunkXXI7BNB6cjs = require('./chunk-XXI7BNB6.cjs');
39
-
40
-
41
-
42
- var _chunkWBR7H6E3cjs = require('./chunk-WBR7H6E3.cjs');
43
-
44
-
45
-
46
- var _chunkFIG2RKZFcjs = require('./chunk-FIG2RKZF.cjs');
47
-
48
-
49
-
50
-
51
-
52
-
53
-
54
- var _chunkZS2SBWBRcjs = require('./chunk-ZS2SBWBR.cjs');
55
-
56
- // src/components/ui/card.tsx
57
- _chunkFIG2RKZFcjs.init_cn.call(void 0, );
58
- var _react = require('react'); var React = _interopRequireWildcard(_react); var React2 = _interopRequireWildcard(_react); var React4 = _interopRequireWildcard(_react); var React6 = _interopRequireWildcard(_react); var React5 = _interopRequireWildcard(_react); var React22 = _interopRequireWildcard(_react);
59
- var _jsxruntime = require('react/jsx-runtime');
60
- var Card = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
61
- "div",
62
- {
63
- ref,
64
- className: _chunkFIG2RKZFcjs.cn.call(void 0,
65
- "rounded-lg border bg-card text-card-foreground shadow-sm",
66
- className
67
- ),
68
- ...props
69
- }
70
- ));
71
- Card.displayName = "Card";
72
- var CardHeader = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
73
- "div",
74
- {
75
- ref,
76
- className: _chunkFIG2RKZFcjs.cn.call(void 0, "flex flex-col space-y-1.5 p-6", className),
77
- ...props
78
- }
79
- ));
80
- CardHeader.displayName = "CardHeader";
81
- var CardTitle = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
82
- "div",
83
- {
84
- ref,
85
- className: _chunkFIG2RKZFcjs.cn.call(void 0,
86
- "text-2xl font-semibold leading-none tracking-tight",
87
- className
88
- ),
89
- ...props
90
- }
91
- ));
92
- CardTitle.displayName = "CardTitle";
93
- var CardDescription = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
94
- "div",
95
- {
96
- ref,
97
- className: _chunkFIG2RKZFcjs.cn.call(void 0, "text-sm text-muted-foreground", className),
98
- ...props
99
- }
100
- ));
101
- CardDescription.displayName = "CardDescription";
102
- var CardContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref, className: _chunkFIG2RKZFcjs.cn.call(void 0, "p-6 pt-0", className), ...props }));
103
- CardContent.displayName = "CardContent";
104
- var CardFooter = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
105
- "div",
106
- {
107
- ref,
108
- className: _chunkFIG2RKZFcjs.cn.call(void 0, "flex items-center p-6 pt-0", className),
109
- ...props
110
- }
111
- ));
112
- CardFooter.displayName = "CardFooter";
113
- function CardHorizontal({ icon, title, description, className = "", borderLeft = true }) {
114
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
115
- "div",
116
- {
117
- className: _chunkFIG2RKZFcjs.cn.call(void 0,
118
- "w-full flex flex-row items-center gap-3 md:gap-4 bg-ods-card p-4 md:p-6 min-h-[80px]",
119
- borderLeft ? "border-l border-ods-border" : "",
120
- className
121
- ),
122
- children: [
123
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-5 h-5 flex-shrink-0", children: icon }),
124
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col min-w-0", children: [
125
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-medium text-sm md:text-sm text-ods-text-primary leading-tight mb-0.5 text-left", children: title }),
126
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-xs md:text-sm text-ods-text-secondary leading-tight text-left", children: description })
127
- ] })
128
- ]
129
- }
130
- );
131
- }
132
-
133
- // src/components/ui/tabs.tsx
134
- _chunkFIG2RKZFcjs.init_cn.call(void 0, );
135
-
136
- var _reacttabs = require('@radix-ui/react-tabs'); var TabsPrimitive = _interopRequireWildcard(_reacttabs);
137
-
138
- var Tabs = TabsPrimitive.Root;
139
- var TabsList = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
140
- TabsPrimitive.List,
141
- {
142
- ref,
143
- className: _chunkFIG2RKZFcjs.cn.call(void 0,
144
- "inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
145
- className
146
- ),
147
- ...props
148
- }
149
- ));
150
- TabsList.displayName = TabsPrimitive.List.displayName;
151
- var TabsTrigger = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
152
- TabsPrimitive.Trigger,
153
- {
154
- ref,
155
- className: _chunkFIG2RKZFcjs.cn.call(void 0,
156
- "inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
157
- className
158
- ),
159
- ...props
160
- }
161
- ));
162
- TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
163
- var TabsContent = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
164
- TabsPrimitive.Content,
165
- {
166
- ref,
167
- className: _chunkFIG2RKZFcjs.cn.call(void 0,
168
- "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
169
- className
170
- ),
171
- ...props
172
- }
173
- ));
174
- TabsContent.displayName = TabsPrimitive.Content.displayName;
175
-
176
- // src/components/ui/status-badge.tsx
177
- _chunkFIG2RKZFcjs.init_cn.call(void 0, );
178
- var _classvarianceauthority = require('class-variance-authority');
179
-
180
- var statusBadgeVariants = _classvarianceauthority.cva.call(void 0,
181
- "inline-flex items-center justify-center rounded font-mono font-medium uppercase tracking-wide",
182
- {
183
- variants: {
184
- variant: {
185
- card: "px-3 py-1.5 text-sm",
186
- button: "px-2 py-0.5 text-[10px] leading-none"
187
- },
188
- colorScheme: {
189
- cyan: "bg-[var(--ods-flamingo-cyan-base)] text-ods-text-on-accent",
190
- pink: "bg-[var(--ods-flamingo-pink-base)] text-ods-text-on-accent",
191
- yellow: "bg-[var(--ods-flamingo-yellow-base)] text-ods-text-on-accent border border-[var(--ods-system-greys-black)]",
192
- green: "bg-[var(--ods-flamingo-green-base)] text-ods-text-on-accent",
193
- purple: "bg-[var(--ods-flamingo-purple-base)] text-ods-text-on-accent",
194
- success: "bg-[var(--ods-attention-green-success-secondary)] text-[var(--ods-attention-green-success)]",
195
- error: "bg-[var(--ods-attention-red-error-secondary)] text-[var(--ods-attention-red-error)]",
196
- warning: "bg-[var(--ods-attention-yellow-warning-secondary)] text-[var(--ods-attention-yellow-warning)]",
197
- default: "bg-ods-bg-secondary text-ods-text-primary",
198
- // Border-only variants (no background) - for task type badges
199
- accentBorder: "bg-transparent border-2 text-ods-accent border-ods-accent",
200
- errorBorder: "bg-transparent border-2 text-[var(--ods-attention-red-error)] border-[var(--ods-attention-red-error)]",
201
- whiteBorder: "bg-transparent border-2 text-ods-text-primary border-ods-text-primary"
202
- }
203
- },
204
- defaultVariants: {
205
- variant: "card",
206
- colorScheme: "default"
207
- }
208
- }
209
- );
210
- function StatusBadge({
211
- text,
212
- variant,
213
- colorScheme,
214
- className,
215
- singleLine,
216
- ...props
217
- }) {
218
- const renderText = () => {
219
- if (singleLine) return text;
220
- if (variant === "button" && text.includes(" ")) {
221
- const words = text.split(" ");
222
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "flex flex-col items-center justify-center text-center gap-0", children: words.map((word, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "block", children: word }, index)) });
223
- }
224
- return text;
225
- };
226
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
227
- "span",
228
- {
229
- className: _chunkFIG2RKZFcjs.cn.call(void 0, statusBadgeVariants({ variant, colorScheme }), className),
230
- ...props,
231
- children: renderText()
232
- }
233
- );
234
- }
235
-
236
- // src/components/ui/simple-markdown-renderer.tsx
237
-
238
- var _reactmarkdown = require('react-markdown'); var _reactmarkdown2 = _interopRequireDefault(_reactmarkdown);
239
- var _remarkgfm = require('remark-gfm'); var _remarkgfm2 = _interopRequireDefault(_remarkgfm);
240
- var _remarkbreaks = require('remark-breaks'); var _remarkbreaks2 = _interopRequireDefault(_remarkbreaks);
241
- var _rehypehighlight = require('rehype-highlight'); var _rehypehighlight2 = _interopRequireDefault(_rehypehighlight);
242
- var _rehyperaw = require('rehype-raw'); var _rehyperaw2 = _interopRequireDefault(_rehyperaw);
243
- var _unistutilvisit = require('unist-util-visit');
244
- _chunkFIG2RKZFcjs.init_cn.call(void 0, );
245
-
246
- var EVENT_HANDLER_ATTR_RE = /^on[a-z]+$/i;
247
- var JAVASCRIPT_URL_RE = /^[\s\x00-\x1f]*javascript:/i;
248
- var DATA_URL_RE = /^[\s\x00-\x1f]*data:/i;
249
- var URL_ATTRS = /* @__PURE__ */ new Set([
250
- "href",
251
- "src",
252
- // `srcset` accepts `javascript:` on legacy browsers — same guard
253
- // as the canonical hast-util-sanitize default schema's attr set.
254
- // Multi-candidate scanning lives in `srcsetHasUnsafeCandidate` below;
255
- // a single-URL check would miss a malicious second candidate like
256
- // `"https://safe.png 1x, javascript:alert(1) 2x"`.
257
- "srcset",
258
- "formaction",
259
- "xlink:href",
260
- "poster",
261
- "data",
262
- "action",
263
- "background"
264
- ]);
265
- function srcsetHasUnsafeCandidate(srcset) {
266
- for (const candidate of srcset.split(",")) {
267
- const url = _nullishCoalesce(candidate.trim().split(/\s+/)[0], () => ( ""));
268
- if (JAVASCRIPT_URL_RE.test(url) || DATA_URL_RE.test(url)) return true;
269
- }
270
- return false;
271
- }
272
- var STRIP_ELEMENTS = /* @__PURE__ */ new Set([
273
- "script",
274
- "style",
275
- "noscript",
276
- "noembed",
277
- "object",
278
- "embed",
279
- "applet",
280
- "base",
281
- "meta"
282
- ]);
283
- function rehypeStripUnsafe() {
284
- return (tree) => {
285
- _unistutilvisit.visit.call(void 0, tree, "element", (node, index, parent) => {
286
- const tag = String(_nullishCoalesce(node.tagName, () => ( ""))).toLowerCase();
287
- if (STRIP_ELEMENTS.has(tag)) {
288
- if (parent && typeof index === "number") {
289
- parent.children.splice(index, 1);
290
- return index;
291
- }
292
- node.children = [];
293
- node.tagName = "span";
294
- node.properties = {};
295
- return;
296
- }
297
- if (!node.properties || typeof node.properties !== "object") return;
298
- for (const key of Object.keys(node.properties)) {
299
- if (EVENT_HANDLER_ATTR_RE.test(key)) {
300
- delete node.properties[key];
301
- continue;
302
- }
303
- if (URL_ATTRS.has(key.toLowerCase())) {
304
- const raw = node.properties[key];
305
- const v = Array.isArray(raw) ? raw[0] : raw;
306
- if (typeof v === "string") {
307
- const unsafe = key.toLowerCase() === "srcset" ? srcsetHasUnsafeCandidate(v) : JAVASCRIPT_URL_RE.test(v) || DATA_URL_RE.test(v);
308
- if (unsafe) {
309
- delete node.properties[key];
310
- continue;
311
- }
312
- }
313
- }
314
- if (tag === "iframe" && key.toLowerCase() === "srcdoc") {
315
- delete node.properties[key];
316
- }
317
- }
318
- });
319
- };
320
- }
321
- function cardAwareUrlTransform(url, key) {
322
- if (key === "href" && typeof url === "string" && (url.startsWith("card://") || url.startsWith("mention://")))
323
- return url;
324
- return _reactmarkdown.defaultUrlTransform.call(void 0, url);
325
- }
326
- var SAFE_HTML_TAGS = /* @__PURE__ */ new Set([
327
- // Block + inline text
328
- "a",
329
- "abbr",
330
- "address",
331
- "article",
332
- "aside",
333
- "b",
334
- "bdi",
335
- "bdo",
336
- "blockquote",
337
- "br",
338
- "caption",
339
- "cite",
340
- "code",
341
- "col",
342
- "colgroup",
343
- "data",
344
- "dd",
345
- "del",
346
- "details",
347
- "dfn",
348
- "div",
349
- "dl",
350
- "dt",
351
- "em",
352
- "figcaption",
353
- "figure",
354
- "footer",
355
- "h1",
356
- "h2",
357
- "h3",
358
- "h4",
359
- "h5",
360
- "h6",
361
- "header",
362
- "hgroup",
363
- "hr",
364
- "i",
365
- "ins",
366
- "kbd",
367
- "li",
368
- "main",
369
- "mark",
370
- "nav",
371
- "ol",
372
- "p",
373
- "pre",
374
- "q",
375
- "rp",
376
- "rt",
377
- "ruby",
378
- "s",
379
- "samp",
380
- "section",
381
- "small",
382
- "span",
383
- "strong",
384
- "sub",
385
- "summary",
386
- "sup",
387
- "table",
388
- "tbody",
389
- "td",
390
- "tfoot",
391
- "th",
392
- "thead",
393
- "time",
394
- "tr",
395
- "u",
396
- "ul",
397
- "var",
398
- "wbr",
399
- // Media
400
- "img",
401
- "picture",
402
- "source",
403
- "audio",
404
- "video",
405
- "iframe",
406
- "track",
407
- // Forms (rehype-raw allows them; mostly harmless for chat output)
408
- "button",
409
- "input",
410
- "label",
411
- "select",
412
- "option",
413
- "optgroup",
414
- "textarea",
415
- "form",
416
- "fieldset",
417
- "legend"
418
- ]);
419
- var TAG_LIKE_REGEX = /<(\/?)([a-zA-Z][a-zA-Z0-9-]{0,63})((?:\s[^>]{0,4096}?)?)(\/?)>/g;
420
- function escapeUnknownHtmlTags(text) {
421
- if (!text || text.indexOf("<") === -1) return text;
422
- const parts = [];
423
- let cursor = 0;
424
- const PROTECTED_SPAN_RE = /```[\s\S]*?```|`[^`\n]+`/g;
425
- let span;
426
- while ((span = PROTECTED_SPAN_RE.exec(text)) !== null) {
427
- if (span.index > cursor) {
428
- parts.push(escapeOutsideFences(text.slice(cursor, span.index)));
429
- }
430
- parts.push(span[0]);
431
- cursor = span.index + span[0].length;
432
- }
433
- if (cursor < text.length) {
434
- parts.push(escapeOutsideFences(text.slice(cursor)));
435
- }
436
- return parts.join("");
437
- }
438
- function escapeOutsideFences(segment) {
439
- return segment.replace(TAG_LIKE_REGEX, (match, slash, tag, rest, selfClose) => {
440
- const lower = tag.toLowerCase();
441
- if (SAFE_HTML_TAGS.has(lower)) return match;
442
- return `&lt;${slash}${tag}${rest}${selfClose}&gt;`;
443
- });
444
- }
445
- var mermaidStyles = `
446
- .mermaid-svg-container svg {
447
- max-width: 100% !important;
448
- height: auto !important;
449
- min-height: 200px;
450
- font-family: 'DM Sans', sans-serif !important;
451
- font-size: 14px !important;
452
- }
453
- @media (min-width: 1520px) {
454
- .mermaid-svg-container svg {
455
- max-width: 900px !important;
456
- max-height: 700px !important;
457
- min-height: 300px;
458
- font-size: 16px !important;
459
- }
460
- }
461
- @media (min-width: 768px) and (max-width: 1519px) {
462
- .mermaid-svg-container svg {
463
- max-width: 700px !important;
464
- max-height: 600px !important;
465
- min-height: 250px;
466
- font-size: 15px !important;
467
- }
468
- }
469
- @media (max-width: 767px) {
470
- .mermaid-svg-container svg {
471
- max-width: 90vw !important;
472
- max-height: 400px !important;
473
- min-height: 200px;
474
- font-size: 13px !important;
475
- }
476
- }
477
- .mermaid-svg-container svg[width] { width: 100% !important; }
478
- .mermaid-svg-container .node rect,
479
- .mermaid-svg-container .node circle,
480
- .mermaid-svg-container .node ellipse,
481
- .mermaid-svg-container .node polygon { stroke-width: 2px !important; }
482
- .mermaid-svg-container .edgePath path { stroke-width: 2px !important; }
483
- @media (min-width: 768px) {
484
- .mermaid-svg-container .node text,
485
- .mermaid-svg-container .edgeLabel text { font-size: 14px !important; }
486
- }
487
- @media (min-width: 1520px) {
488
- .mermaid-svg-container .node text,
489
- .mermaid-svg-container .edgeLabel text { font-size: 16px !important; }
490
- }
491
- `;
492
- var MermaidDiagram = ({ chart }) => {
493
- const [svg, setSvg] = _react.useState.call(void 0, "");
494
- const [error, setError] = _react.useState.call(void 0, "");
495
- const [isLoading, setIsLoading] = _react.useState.call(void 0, true);
496
- const [mounted, setMounted] = _react.useState.call(void 0, false);
497
- _react.useEffect.call(void 0, () => {
498
- setMounted(true);
499
- }, []);
500
- _react.useEffect.call(void 0, () => {
501
- const renderMermaid = async () => {
502
- try {
503
- setIsLoading(true);
504
- const { default: mermaid } = await Promise.resolve().then(() => _interopRequireWildcard(require("mermaid")));
505
- mermaid.initialize({
506
- startOnLoad: false,
507
- theme: "dark",
508
- themeVariables: {
509
- primaryColor: "#FFC008",
510
- primaryTextColor: "#FAFAFA",
511
- primaryBorderColor: "#3A3A3A",
512
- lineColor: "#888888",
513
- secondaryColor: "#212121",
514
- tertiaryColor: "#2A2A2A",
515
- background: "transparent",
516
- mainBkg: "transparent",
517
- secondBkg: "transparent",
518
- tertiaryBkg: "transparent",
519
- cScale0: "#FFC008",
520
- cScale1: "#4ECDC4",
521
- cScale2: "#45B7D1",
522
- cScale3: "#96CEB4",
523
- cScale4: "#FFEAA7",
524
- cScale5: "#DDA0DD",
525
- cScale6: "#98D8C8",
526
- cScale7: "#F7DC6F",
527
- cScale8: "#BB8FCE",
528
- cScale9: "#85C1E9",
529
- taskTextColor: "#FAFAFA",
530
- taskTextOutsideColor: "#FAFAFA",
531
- activeTaskTextColor: "#1A1A1A",
532
- nodeTextColor: "#FAFAFA"
533
- },
534
- flowchart: { useMaxWidth: true, htmlLabels: true, rankSpacing: 50, nodeSpacing: 30, curve: "basis" },
535
- sequence: { useMaxWidth: true, width: 150 },
536
- pie: { useMaxWidth: true, useWidth: void 0 },
537
- fontFamily: "DM Sans, sans-serif",
538
- fontSize: 14,
539
- securityLevel: "loose"
540
- });
541
- const { svg: renderedSvg } = await mermaid.render(`mermaid-${Date.now()}`, chart);
542
- setSvg(renderedSvg);
543
- setIsLoading(false);
544
- } catch (err) {
545
- console.error("Mermaid rendering error:", err);
546
- setError(`Failed to render diagram: ${err instanceof Error ? err.message : "Unknown error"}`);
547
- setIsLoading(false);
548
- }
549
- };
550
- if (mounted) {
551
- renderMermaid();
552
- }
553
- }, [chart, mounted]);
554
- if (error) {
555
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "error-state bg-ods-card border border-ods-border rounded-lg p-6 my-6", children: [
556
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "error-icon flex justify-center mb-4", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkZS2SBWBRcjs.AlertCircleIcon, { className: "w-12 h-12 text-ods-error" }) }),
557
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "error-title text-center font-sans font-semibold text-lg text-ods-error mb-2", children: "Diagram Error" }),
558
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "error-description text-center font-sans text-sm text-ods-text-secondary mb-4 break-words overflow-hidden max-w-full", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "overflow-x-auto", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "pre", { className: "whitespace-pre-wrap break-words text-xs", children: error }) }) })
559
- ] });
560
- }
561
- if (isLoading || !svg) {
562
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "skeleton-code bg-ods-card border border-ods-border rounded-lg p-6 min-h-[120px] flex items-center justify-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "animate-pulse text-ods-text-tertiary font-sans", children: isLoading ? "Loading diagram renderer..." : "Rendering diagram..." }) });
563
- }
564
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "mermaid-container rounded-lg p-4 md:p-6 lg:p-8 my-6 overflow-x-auto bg-ods-card border border-ods-border", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex justify-center items-center w-full min-h-[200px] md:min-h-[250px] lg:min-h-[300px]", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
565
- "div",
566
- {
567
- className: "mermaid-svg-container w-full flex justify-center max-w-full",
568
- style: { fontSize: "14px" },
569
- dangerouslySetInnerHTML: {
570
- __html: svg.replace(
571
- /<svg[^>]*>/,
572
- (match) => match.replace(/width="[^"]*"/, 'width="100%"').replace(/height="[^"]*"/, 'height="auto"')
573
- )
574
- }
575
- }
576
- ) }) });
577
- };
578
- function extractText(node) {
579
- if (typeof node === "string") return node;
580
- if (Array.isArray(node)) return node.map(extractText).join("");
581
- if (_optionalChain([node, 'optionalAccess', _ => _.props, 'optionalAccess', _2 => _2.children])) return extractText(node.props.children);
582
- return "";
583
- }
584
- var TEXT_SIZE_PRESETS = {
585
- default: {
586
- h1: "text-heading-1",
587
- h2: "text-heading-2",
588
- h3: "text-2xl md:text-3xl",
589
- h4: "text-xl",
590
- h5: "text-lg md:text-xl",
591
- h6: "text-base md:text-lg",
592
- p: "md:text-h4 lg:text-h4",
593
- li: "text-base md:text-lg",
594
- blockquote: "text-lg",
595
- code: "text-[14px]",
596
- th: "text-xs md:text-sm",
597
- td: "text-xs md:text-sm"
598
- },
599
- compact: {
600
- h1: "text-heading-2",
601
- h2: "text-heading-3",
602
- h3: "text-xl md:text-2xl",
603
- h4: "text-lg md:text-xl",
604
- h5: "text-base md:text-lg",
605
- h6: "text-sm md:text-base",
606
- p: "text-base md:text-lg",
607
- li: "text-base md:text-lg",
608
- blockquote: "text-base md:text-lg",
609
- code: "text-[13px]",
610
- th: "text-xs md:text-sm",
611
- td: "text-xs md:text-sm"
612
- },
613
- large: {
614
- h1: "text-heading-1",
615
- h2: "text-heading-1",
616
- h3: "text-heading-2",
617
- h4: "text-2xl md:text-3xl",
618
- h5: "text-xl md:text-2xl",
619
- h6: "text-lg md:text-xl",
620
- p: "text-h3",
621
- li: "text-lg md:text-xl",
622
- blockquote: "text-xl md:text-2xl",
623
- code: "text-[16px]",
624
- th: "text-sm md:text-base",
625
- td: "text-sm md:text-base"
626
- }
627
- };
628
- function resolveTextSizeConfig(config) {
629
- const defaultSizes = TEXT_SIZE_PRESETS.default;
630
- if (!config) return defaultSizes;
631
- if (typeof config === "string") return TEXT_SIZE_PRESETS[config];
632
- if ("preset" in config) return { ...TEXT_SIZE_PRESETS[config.preset], ...config.overrides };
633
- return { ...defaultSizes, ...config };
634
- }
635
- var SimpleMarkdownRendererImpl = ({
636
- content,
637
- className = "",
638
- sectionIds,
639
- demoteMarkdownH1ToH2 = false,
640
- brokenLinks = [],
641
- onInternalLinkClick,
642
- currentPath: propCurrentPath,
643
- onResolveLink,
644
- preprocessContent,
645
- componentOverrides,
646
- textSize,
647
- additionalRemarkPlugins
648
- }) => {
649
- const idCountsRef = _react.useRef.call(void 0, {});
650
- const textSizes = _react.useMemo.call(void 0, () => resolveTextSizeConfig(textSize), [textSize]);
651
- const sectionIdMap = _react.useMemo.call(void 0, () => {
652
- const map = /* @__PURE__ */ new Map();
653
- if (sectionIds) {
654
- sectionIds.forEach((section) => {
655
- const cleanTitle = section.title.replace(/[\u{1F300}-\u{1F9FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]/gu, "").trim().toLowerCase();
656
- map.set(section.title.toLowerCase(), section.id);
657
- map.set(cleanTitle, section.id);
658
- map.set(section.title, section.id);
659
- });
660
- }
661
- return map;
662
- }, [sectionIds]);
663
- const generateHeadingId = _react.useCallback.call(void 0, (text, level) => {
664
- if (sectionIds && (level === 1 || level === 2)) {
665
- const variations = [
666
- text,
667
- text.toLowerCase(),
668
- text.replace(/[\u{1F300}-\u{1F9FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]/gu, "").trim(),
669
- text.replace(/[\u{1F300}-\u{1F9FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]/gu, "").trim().toLowerCase()
670
- ];
671
- for (const v of variations) {
672
- const id = sectionIdMap.get(v);
673
- if (id) return id;
674
- }
675
- }
676
- const baseId = text.replace(/[\u{1F300}-\u{1F9FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]/gu, "").trim().toLowerCase().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/^-+|-+$/g, "");
677
- const cleanId = baseId || `section-${Object.keys(idCountsRef.current).length + 1}`;
678
- if (idCountsRef.current[cleanId]) {
679
- idCountsRef.current[cleanId]++;
680
- return `${cleanId}-${idCountsRef.current[cleanId]}`;
681
- }
682
- idCountsRef.current[cleanId] = 1;
683
- return cleanId;
684
- }, [sectionIds, sectionIdMap]);
685
- const processedContent = _react.useMemo.call(void 0,
686
- () => escapeUnknownHtmlTags(preprocessContent ? preprocessContent(content) : content),
687
- [preprocessContent, content]
688
- );
689
- const makeHeading = _react.useCallback.call(void 0,
690
- (Tag, level, headingClassName) => ({ children }) => {
691
- const text = extractText(children);
692
- const effectiveLevel = Tag === "h1" && demoteMarkdownH1ToH2 ? 2 : level;
693
- const id = generateHeadingId(text, effectiveLevel);
694
- const EffectiveTag = Tag === "h1" && demoteMarkdownH1ToH2 ? "h2" : Tag;
695
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, EffectiveTag, { id, className: headingClassName, children });
696
- },
697
- [generateHeadingId, demoteMarkdownH1ToH2]
698
- );
699
- const components = _react.useMemo.call(void 0, () => ({
700
- // --- code ---
701
- code: ({ node, inline, className: codeClassName, children, ...props }) => {
702
- const match = /language-(\w+)/.exec(codeClassName || "");
703
- const language = match ? match[1] : "";
704
- if (!inline && language === "mermaid") {
705
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MermaidDiagram, { chart: String(children).replace(/\n$/, "") });
706
- }
707
- if (!inline && match) {
708
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "code-block-container border rounded-lg my-6 overflow-hidden bg-ods-card border-ods-border", children: [
709
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "code-header border-b px-4 py-2 bg-ods-card border-ods-border", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-sans text-xs uppercase tracking-wide text-ods-text-tertiary", children: language || "code" }) }),
710
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "p-4", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "pre", { className: "overflow-x-auto", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
711
- "code",
712
- {
713
- className: _chunkFIG2RKZFcjs.cn.call(void 0, `language-${language} hljs`, textSizes.code),
714
- style: {
715
- fontFamily: "JetBrains Mono', 'SF Mono', Consolas, monospace",
716
- background: "transparent",
717
- color: "var(--ods-text-primary)"
718
- },
719
- ...props,
720
- children
721
- }
722
- ) }) })
723
- ] });
724
- }
725
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "code", { className: "font-mono text-[0.9em] px-1.5 py-0.5 rounded border bg-ods-card text-ods-text-primary border-ods-border", ...props, children });
726
- },
727
- // --- div (pass-through, overridable for embeds) ---
728
- div: ({ node, className: divClassName, children, ...props }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: divClassName, ...props, children }),
729
- // --- blockquote ---
730
- blockquote: ({ children }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "blockquote", { className: "border-l-4 border-ods-accent ml-0 pl-6 my-8 py-4 rounded-r-lg bg-ods-bg-secondary", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "font-sans leading-relaxed text-ods-text-secondary", textSizes.blockquote), children }) }),
731
- // --- headings ---
732
- h1: makeHeading("h1", 1, _chunkFIG2RKZFcjs.cn.call(void 0, "font-sans font-bold mt-8 mb-4 first:mt-0 text-ods-text-primary", textSizes.h1)),
733
- h2: makeHeading("h2", 2, _chunkFIG2RKZFcjs.cn.call(void 0, "font-sans font-semibold mt-8 mb-4 pb-2 border-b text-ods-text-primary border-ods-border", textSizes.h2)),
734
- h3: makeHeading("h3", 3, _chunkFIG2RKZFcjs.cn.call(void 0, "font-sans font-semibold mt-6 mb-3 text-ods-text-primary", textSizes.h3)),
735
- h4: makeHeading("h4", 4, _chunkFIG2RKZFcjs.cn.call(void 0, "font-sans font-semibold mt-4 mb-2 text-ods-text-primary", textSizes.h4)),
736
- h5: makeHeading("h5", 5, _chunkFIG2RKZFcjs.cn.call(void 0, "font-sans font-semibold mt-3 mb-2 text-ods-text-primary", textSizes.h5)),
737
- h6: makeHeading("h6", 6, _chunkFIG2RKZFcjs.cn.call(void 0, "font-sans font-semibold mt-3 mb-1 text-ods-text-primary", textSizes.h6)),
738
- // --- paragraph ---
739
- p: ({ children }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "leading-relaxed mb-4 first:mt-0 last:mb-0 text-ods-text-primary", textSizes.p), children }),
740
- // --- links ---
741
- a: ({ href, children, className: linkClassName }) => {
742
- const isBroken = brokenLinks.includes(href);
743
- const isInternalDocLink = propCurrentPath !== void 0 && propCurrentPath !== null && href && !href.startsWith("http") && !href.startsWith("#");
744
- if (isBroken) {
745
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "text-ods-accent cursor-not-allowed", children: [
746
- children,
747
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "sup", { className: "ml-1 text-xs font-bold text-ods-attention-red-error", children: "[BROKEN]" })
748
- ] });
749
- }
750
- if (isInternalDocLink && onInternalLinkClick) {
751
- const currentPath = _nullishCoalesce(propCurrentPath, () => ( ""));
752
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
753
- "span",
754
- {
755
- className: "text-ods-accent no-underline relative transition-colors duration-200 hover:after:w-full after:content-[''] after:absolute after:w-0 after:h-0.5 after:-bottom-0.5 after:left-0 after:bg-ods-accent after:transition-all after:duration-300 cursor-pointer",
756
- onClick: async (e) => {
757
- e.preventDefault();
758
- e.stopPropagation();
759
- if (onResolveLink) {
760
- try {
761
- const result = await onResolveLink(href, currentPath);
762
- if (result.type === "folder-no-readme" && result.action === "expand_folder") {
763
- onInternalLinkClick(result.resolvedPath, { expandFolder: true, fromInternalLink: true });
764
- } else if (result.type === "not-found") {
765
- return;
766
- } else if (result.success && result.resolvedPath) {
767
- onInternalLinkClick(result.resolvedPath, { fromInternalLink: true });
768
- }
769
- } catch (error) {
770
- console.error("Error resolving link:", error);
771
- }
772
- } else {
773
- onInternalLinkClick(href, { fromInternalLink: true });
774
- }
775
- },
776
- role: "link",
777
- tabIndex: 0,
778
- onKeyDown: (e) => {
779
- if (e.key === "Enter" || e.key === " ") {
780
- e.currentTarget.click();
781
- }
782
- },
783
- children
784
- }
785
- );
786
- }
787
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
788
- "a",
789
- {
790
- href,
791
- className: `text-ods-accent no-underline relative transition-colors duration-200 hover:after:w-full after:content-[''] after:absolute after:w-0 after:h-0.5 after:-bottom-0.5 after:left-0 after:bg-ods-accent after:transition-all after:duration-300 ${linkClassName || ""}`,
792
- target: _optionalChain([href, 'optionalAccess', _3 => _3.startsWith, 'call', _4 => _4("http")]) ? "_blank" : void 0,
793
- rel: _optionalChain([href, 'optionalAccess', _5 => _5.startsWith, 'call', _6 => _6("http")]) ? "noopener noreferrer" : void 0,
794
- children
795
- }
796
- );
797
- },
798
- // --- images ---
799
- // Inline content image renderer. Used by blog posts, docs, AND chat
800
- // messages (where users may attach screenshots / photos via the +
801
- // attachment button).
802
- //
803
- // Sizing rules (2025-2026 best practice — Claude.ai, ChatGPT,
804
- // iMessage, Slack, Discord inline image patterns):
805
- //
806
- // - CAP max-width at 400px so inline images don't blow out the
807
- // message column on wide panels. Click-to-expand opens a
808
- // full-resolution modal for users who need detail.
809
- // - CAP max-height at 400px so portrait-orientation images
810
- // don't dominate vertical space (a 1000x3000 phone screenshot
811
- // would otherwise push the next message off-screen).
812
- // - Small images render at NATURAL pixel size — a 64x64
813
- // thumbnail stays 64x64, not stretched to fill the column.
814
- // - `object-contain` preserves aspect ratio when both dimensions
815
- // are constrained (long landscape, tall portrait).
816
- //
817
- // Implementation: Next.js `<Image>` — the project's canonical
818
- // image primitive. Gives us:
819
- // - WebP/AVIF format conversion for modern browsers (smaller
820
- // bytes for the same visual quality).
821
- // - Responsive `srcset` via the `sizes` prop (browser picks the
822
- // right variant for the viewport).
823
- // - Automatic lazy-loading (`loading="lazy"` by default, mid-
824
- // page images skipped until they near the viewport).
825
- // - Automatic `decoding="async"` so image decode doesn't block
826
- // paint.
827
- //
828
- // `width={400} height={400}` props are REQUIRED by Next.js
829
- // `<Image>` (non-`fill` mode throws without them) but they're
830
- // effectively a CEILING here, not the display size — the CSS
831
- // overrides (`w-auto h-auto max-w-full max-h-[400px]`) drive
832
- // the actual rendered size. The inline `style={{ width: 'auto',
833
- // height: 'auto' }}` is belt-and-suspenders: Next.js Image sets
834
- // matching HTML `width`/`height` attributes on the rendered
835
- // `<img>` and inline style wins over both HTML attributes AND
836
- // utility classes regardless of CSS-specificity surprises.
837
- //
838
- // Layout reservation trade-off: until image bytes arrive, the
839
- // browser may reserve a placeholder box up to 400x400 (the props'
840
- // intrinsic-ratio hint). Once loaded, the box collapses to the
841
- // natural size if smaller. This is the standard Next.js Image
842
- // behavior across the codebase — accepted for the optimizer +
843
- // responsive-srcset benefits. Chat attachments hosted in side
844
- // panels see this only on first render of a fresh attachment
845
- // (cached re-renders pop in without a perceptible shift).
846
- img: ({ src, alt }) => {
847
- if (!src || typeof src !== "string" || src.trim() === "") return null;
848
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
849
- _chunkXL4V2PYGcjs.next_image_default,
850
- {
851
- src,
852
- alt: _nullishCoalesce(alt, () => ( "No image available")),
853
- width: 400,
854
- height: 400,
855
- sizes: "(max-width: 400px) 100vw, 400px",
856
- className: "max-w-full max-h-[400px] w-auto h-auto rounded-lg object-contain",
857
- style: { width: "auto", height: "auto" }
858
- }
859
- );
860
- },
861
- // --- lists ---
862
- ul: ({ children }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ul", { className: "list-disc list-outside my-4 ml-8 space-y-2 text-ods-text-primary", children }),
863
- ol: ({ children }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ol", { className: "list-decimal list-outside my-4 ml-8 space-y-2 text-ods-text-primary", children }),
864
- li: ({ children }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "leading-relaxed pl-2", textSizes.li), children }),
865
- // --- tables ---
866
- table: ({ children }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "table-container my-6 overflow-x-auto", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "min-w-full border rounded-lg border-ods-border bg-ods-card", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "table", { className: "w-full table-fixed md:table-auto", children }) }) }),
867
- thead: ({ children }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "thead", { className: "bg-ods-bg-secondary", children }),
868
- th: ({ children }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "px-2 md:px-4 py-3 text-left font-semibold text-ods-accent border-r last:border-r-0 break-words border-ods-border", textSizes.th), children }),
869
- td: ({ children }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "px-2 md:px-4 py-3 border-r last:border-r-0 border-b break-words whitespace-normal text-ods-text-primary border-ods-border", textSizes.td), children }),
870
- // --- horizontal rule ---
871
- hr: () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "hr", { className: "border-0 border-t my-8 border-ods-border" }),
872
- // --- merge overrides ---
873
- ...componentOverrides
874
- }), [makeHeading, brokenLinks, propCurrentPath, onInternalLinkClick, onResolveLink, componentOverrides, textSizes]);
875
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: `simple-markdown-renderer ${className}`, children: [
876
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "style", { dangerouslySetInnerHTML: { __html: mermaidStyles } }),
877
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "content-wrapper max-w-none break-words", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "article", { className: "prose prose-lg max-w-none", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
878
- _reactmarkdown2.default,
879
- {
880
- remarkPlugins: [_remarkgfm2.default, _remarkbreaks2.default, ..._nullishCoalesce(additionalRemarkPlugins, () => ( []))],
881
- rehypePlugins: [
882
- // ORDER MATTERS: rehype-raw parses the raw HTML embedded
883
- // in the source markdown into HAST nodes; rehypeStripUnsafe
884
- // then walks the HAST tree and drops XSS vectors (on*
885
- // event handlers, javascript: URLs, script/style/iframe-srcdoc,
886
- // data: URIs). Reversing the order would have nothing to
887
- // sanitize (raw HTML would still be strings).
888
- _rehyperaw2.default,
889
- rehypeStripUnsafe,
890
- [_rehypehighlight2.default, { detect: true, ignoreMissing: true }]
891
- ],
892
- urlTransform: cardAwareUrlTransform,
893
- components,
894
- children: processedContent
895
- }
896
- ) }) })
897
- ] });
898
- };
899
- var SimpleMarkdownRenderer = _react.memo.call(void 0, SimpleMarkdownRendererImpl);
900
-
901
- // src/components/ui/square-avatar.tsx
902
-
903
- _chunkFIG2RKZFcjs.init_cn.call(void 0, );
904
-
905
- var SquareAvatar = React4.memo(React4.forwardRef(
906
- ({ className, src, alt, size = "md", fallback, variant = "square", initialsClassName, ...props }, ref) => {
907
- const sizeClasses = {
908
- sm: "h-8 w-8",
909
- md: "h-10 w-10",
910
- lg: "h-12 w-12",
911
- xl: "h-16 w-16"
912
- };
913
- const sizePx = {
914
- sm: 32,
915
- md: 40,
916
- lg: 48,
917
- xl: 64
918
- };
919
- const variantClasses = {
920
- square: "rounded-md",
921
- round: "rounded-full"
922
- };
923
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
924
- "div",
925
- {
926
- className: _chunkFIG2RKZFcjs.cn.call(void 0,
927
- "relative flex items-center justify-center shrink-0 overflow-hidden border border-ods-border bg-ods-bg",
928
- sizeClasses[size],
929
- variantClasses[variant],
930
- className
931
- ),
932
- ref,
933
- ...props,
934
- children: [
935
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0,
936
- // Initials default to `--color-text-primary` (the old
937
- // `text-ods-text-primary` value) so they stay readable on the default
938
- // `bg-ods-bg` AND on the brand accent fills (`bg-ods-flamingo-pink`
939
- // for the current user, `bg-ods-flamingo-cyan` for Mingo). The color
940
- // resolves through `--ods-avatar-initials` with that fallback, so a
941
- // host themed with a custom avatar fill can override the var with a
942
- // contrast-correct value (e.g. `getReadableTextColor(accent)`) WITHOUT
943
- // regressing any avatar that leaves the var unset. A caller passing
944
- // its own `initialsClassName` text color still wins (tailwind-merge
945
- // keeps the later class).
946
- "flex items-center justify-center text-xs font-medium text-[color:var(--ods-avatar-initials,var(--color-text-primary))]",
947
- initialsClassName,
948
- src && "hidden"
949
- ), children: _chunkJ54Z3OCRcjs.getFirstLastInitials.call(void 0, fallback || alt) || "?" }),
950
- src && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
951
- _chunkXL4V2PYGcjs.next_image_default,
952
- {
953
- className: "absolute inset-0 h-full w-full object-cover",
954
- src,
955
- alt: alt || "",
956
- width: sizePx[size],
957
- height: sizePx[size],
958
- onError: (e) => {
959
- e.currentTarget.style.display = "none";
960
- const el = e.currentTarget.previousElementSibling;
961
- if (el) el.classList.remove("hidden");
962
- }
963
- }
964
- )
965
- ]
966
- }
967
- );
968
- }
969
- ));
970
- SquareAvatar.displayName = "SquareAvatar";
971
-
972
- // src/components/ui/actions-menu.tsx
973
- var _reactdropdownmenu = require('@radix-ui/react-dropdown-menu'); var DropdownMenuPrimitive = _interopRequireWildcard(_reactdropdownmenu);
974
-
975
- // node_modules/@radix-ui/react-use-controllable-state/dist/index.mjs
976
-
977
-
978
- // node_modules/@radix-ui/react-use-layout-effect/dist/index.mjs
979
-
980
- var useLayoutEffect2 = _optionalChain([globalThis, 'optionalAccess', _7 => _7.document]) ? React5.useLayoutEffect : () => {
981
- };
982
-
983
- // node_modules/@radix-ui/react-use-controllable-state/dist/index.mjs
984
-
985
- var useInsertionEffect = React6[" useInsertionEffect ".trim().toString()] || useLayoutEffect2;
986
- function useControllableState({
987
- prop,
988
- defaultProp,
989
- onChange = () => {
990
- },
991
- caller
992
- }) {
993
- const [uncontrolledProp, setUncontrolledProp, onChangeRef] = useUncontrolledState({
994
- defaultProp,
995
- onChange
996
- });
997
- const isControlled = prop !== void 0;
998
- const value = isControlled ? prop : uncontrolledProp;
999
- if (true) {
1000
- const isControlledRef = React6.useRef(prop !== void 0);
1001
- React6.useEffect(() => {
1002
- const wasControlled = isControlledRef.current;
1003
- if (wasControlled !== isControlled) {
1004
- const from = wasControlled ? "controlled" : "uncontrolled";
1005
- const to = isControlled ? "controlled" : "uncontrolled";
1006
- console.warn(
1007
- `${caller} is changing from ${from} to ${to}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`
1008
- );
1009
- }
1010
- isControlledRef.current = isControlled;
1011
- }, [isControlled, caller]);
1012
- }
1013
- const setValue = React6.useCallback(
1014
- (nextValue) => {
1015
- if (isControlled) {
1016
- const value2 = isFunction(nextValue) ? nextValue(prop) : nextValue;
1017
- if (value2 !== prop) {
1018
- _optionalChain([onChangeRef, 'access', _8 => _8.current, 'optionalCall', _9 => _9(value2)]);
1019
- }
1020
- } else {
1021
- setUncontrolledProp(nextValue);
1022
- }
1023
- },
1024
- [isControlled, prop, setUncontrolledProp, onChangeRef]
1025
- );
1026
- return [value, setValue];
1027
- }
1028
- function useUncontrolledState({
1029
- defaultProp,
1030
- onChange
1031
- }) {
1032
- const [value, setValue] = React6.useState(defaultProp);
1033
- const prevValueRef = React6.useRef(value);
1034
- const onChangeRef = React6.useRef(onChange);
1035
- useInsertionEffect(() => {
1036
- onChangeRef.current = onChange;
1037
- }, [onChange]);
1038
- React6.useEffect(() => {
1039
- if (prevValueRef.current !== value) {
1040
- _optionalChain([onChangeRef, 'access', _10 => _10.current, 'optionalCall', _11 => _11(value)]);
1041
- prevValueRef.current = value;
1042
- }
1043
- }, [value, prevValueRef]);
1044
- return [value, setValue, onChangeRef];
1045
- }
1046
- function isFunction(value) {
1047
- return typeof value === "function";
1048
- }
1049
-
1050
- // src/components/ui/actions-menu.tsx
1051
- _chunkWBR7H6E3cjs.init_next_link.call(void 0, );
1052
- var _lucidereact = require('lucide-react');
1053
-
1054
- _chunkFIG2RKZFcjs.init_cn.call(void 0, );
1055
- _chunkXXI7BNB6cjs.init_button2.call(void 0, );
1056
-
1057
- var ROW_CLASSES = "flex flex-1 min-w-0 items-center gap-[var(--spacing-system-xsf)] p-[var(--spacing-system-s)] cursor-pointer transition-colors bg-ods-bg outline-none";
1058
- var WRAPPER_CLASSES = "relative flex items-stretch border-b border-ods-border last:border-b-0";
1059
- var SECONDARY_ACTION_CLASSES = "flex p-[var(--spacing-system-s)] shrink-0 items-center justify-center self-stretch border-l border-ods-border transition-colors hover:bg-ods-bg-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ods-focus [&_svg]:w-4 [&_svg]:h-4 md:[&_svg]:w-6 md:[&_svg]:h-6";
1060
- var SecondaryAction = ({ action }) => {
1061
- const handleClick = _react.useCallback.call(void 0,
1062
- (e) => {
1063
- e.stopPropagation();
1064
- if (action.disabled) {
1065
- e.preventDefault();
1066
- return;
1067
- }
1068
- _optionalChain([action, 'access', _12 => _12.onClick, 'optionalCall', _13 => _13()]);
1069
- },
1070
- [action]
1071
- );
1072
- const classes = _chunkFIG2RKZFcjs.cn.call(void 0,
1073
- SECONDARY_ACTION_CLASSES,
1074
- action.disabled && "cursor-not-allowed opacity-60 pointer-events-none"
1075
- );
1076
- if (action.href) {
1077
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1078
- _chunkWBR7H6E3cjs.next_link_default,
1079
- {
1080
- href: action.href,
1081
- prefetch: false,
1082
- target: action.openInNewTab ? "_blank" : void 0,
1083
- rel: action.openInNewTab ? "noopener noreferrer" : void 0,
1084
- "aria-label": action["aria-label"],
1085
- "aria-disabled": action.disabled || void 0,
1086
- tabIndex: action.disabled ? -1 : void 0,
1087
- className: classes,
1088
- onClick: handleClick,
1089
- children: action.icon
1090
- }
1091
- );
1092
- }
1093
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1094
- "button",
1095
- {
1096
- type: "button",
1097
- "aria-label": action["aria-label"],
1098
- disabled: action.disabled,
1099
- className: classes,
1100
- onClick: handleClick,
1101
- children: action.icon
1102
- }
1103
- );
1104
- };
1105
- var MenuItem = ({ item, onItemClick }) => {
1106
- const activate = _react.useCallback.call(void 0, () => {
1107
- if (item.disabled) return;
1108
- if (item.type === "checkbox") {
1109
- _optionalChain([item, 'access', _14 => _14.onClick, 'optionalCall', _15 => _15()]);
1110
- _optionalChain([onItemClick, 'optionalCall', _16 => _16(item)]);
1111
- return;
1112
- }
1113
- if (item.type === "submenu") return;
1114
- _optionalChain([item, 'access', _17 => _17.onClick, 'optionalCall', _18 => _18()]);
1115
- _optionalChain([onItemClick, 'optionalCall', _19 => _19(item)]);
1116
- }, [item, onItemClick]);
1117
- const handleClick = _react.useCallback.call(void 0,
1118
- (e) => {
1119
- e.stopPropagation();
1120
- e.preventDefault();
1121
- activate();
1122
- },
1123
- [activate]
1124
- );
1125
- const handleKeyDown = _react.useCallback.call(void 0,
1126
- (e) => {
1127
- if (e.key !== "Enter" && e.key !== " ") return;
1128
- e.preventDefault();
1129
- e.stopPropagation();
1130
- activate();
1131
- },
1132
- [activate]
1133
- );
1134
- const handleLinkClick = _react.useCallback.call(void 0,
1135
- (e) => {
1136
- if (item.disabled) {
1137
- e.preventDefault();
1138
- e.stopPropagation();
1139
- return;
1140
- }
1141
- _optionalChain([item, 'access', _20 => _20.onClick, 'optionalCall', _21 => _21()]);
1142
- _optionalChain([onItemClick, 'optionalCall', _22 => _22(item)]);
1143
- },
1144
- [item, onItemClick]
1145
- );
1146
- if (item.type === "separator") {
1147
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "bg-ods-system-greys-soft-grey h-1 w-full" });
1148
- }
1149
- const itemClasses = _chunkFIG2RKZFcjs.cn.call(void 0,
1150
- ROW_CLASSES,
1151
- item.disabled ? "text-ods-text-secondary cursor-not-allowed pointer-events-none opacity-60" : "text-ods-text-primary hover:bg-ods-bg-hover"
1152
- );
1153
- const subTriggerClasses = _chunkFIG2RKZFcjs.cn.call(void 0,
1154
- itemClasses,
1155
- "data-[state=open]:bg-ods-bg-active focus:bg-ods-bg-hover"
1156
- );
1157
- const renderAsLink = !!item.href && item.type !== "submenu" && item.type !== "checkbox";
1158
- const rowContent = /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
1159
- item.icon && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1160
- "div",
1161
- {
1162
- className: _chunkFIG2RKZFcjs.cn.call(void 0,
1163
- "w-4 h-4 md:w-6 md:h-6 flex-shrink-0 flex items-center justify-center",
1164
- item.danger && "text-ods-error",
1165
- item.disabled && "opacity-50"
1166
- ),
1167
- children: item.icon
1168
- }
1169
- ),
1170
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1171
- "span",
1172
- {
1173
- className: _chunkFIG2RKZFcjs.cn.call(void 0,
1174
- "flex-1 text-h4 font-medium leading-6",
1175
- item.disabled ? "text-ods-text-secondary" : item.danger ? "text-ods-error" : "text-ods-text-primary"
1176
- ),
1177
- children: item.label
1178
- }
1179
- ),
1180
- item.type === "checkbox" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1181
- "div",
1182
- {
1183
- className: _chunkFIG2RKZFcjs.cn.call(void 0,
1184
- "w-4 h-4 md:w-6 md:h-6 flex items-center justify-center rounded-md transition-colors",
1185
- item.checked ? "bg-ods-accent" : "border-2 border-ods-border bg-transparent"
1186
- ),
1187
- children: item.checked && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Check, { className: "w-3 h-3 md:w-4 md:h-4 text-ods-text-on-accent", strokeWidth: 3 })
1188
- }
1189
- ),
1190
- item.type === "submenu" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkZS2SBWBRcjs.Chevron02RightIcon, { className: "w-4 h-4 md:w-6 md:h-6 text-ods-text-secondary" })
1191
- ] });
1192
- if (renderAsLink && item.href) {
1193
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: WRAPPER_CLASSES, children: [
1194
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1195
- _chunkWBR7H6E3cjs.next_link_default,
1196
- {
1197
- href: item.href,
1198
- prefetch: false,
1199
- className: itemClasses,
1200
- onClick: handleLinkClick,
1201
- "aria-disabled": item.disabled,
1202
- tabIndex: item.disabled ? -1 : void 0,
1203
- children: rowContent
1204
- }
1205
- ),
1206
- item.iconAction && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SecondaryAction, { action: item.iconAction })
1207
- ] });
1208
- }
1209
- if (item.type === "submenu" && item.submenu) {
1210
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: WRAPPER_CLASSES, children: [
1211
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, DropdownMenuPrimitive.Sub, { children: [
1212
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1213
- DropdownMenuPrimitive.SubTrigger,
1214
- {
1215
- disabled: item.disabled,
1216
- className: subTriggerClasses,
1217
- children: rowContent
1218
- }
1219
- ),
1220
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1221
- DropdownMenuPrimitive.SubContent,
1222
- {
1223
- sideOffset: 4,
1224
- className: "z-[1500] min-w-[256px] max-h-[var(--radix-popper-available-height)] bg-ods-bg border border-ods-border rounded-md shadow-xl overflow-y-auto p-0",
1225
- children: item.submenu.map((subItem, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1226
- MenuItem,
1227
- {
1228
- item: subItem,
1229
- onItemClick
1230
- },
1231
- subItem.id || index
1232
- ))
1233
- }
1234
- ) })
1235
- ] }),
1236
- item.iconAction && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SecondaryAction, { action: item.iconAction })
1237
- ] });
1238
- }
1239
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: WRAPPER_CLASSES, children: [
1240
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1241
- "div",
1242
- {
1243
- role: "menuitem",
1244
- tabIndex: item.disabled ? -1 : 0,
1245
- "aria-disabled": item.disabled,
1246
- className: itemClasses,
1247
- onClick: handleClick,
1248
- onKeyDown: handleKeyDown,
1249
- children: rowContent
1250
- }
1251
- ),
1252
- item.iconAction && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SecondaryAction, { action: item.iconAction })
1253
- ] });
1254
- };
1255
- var GroupSeparator = () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "bg-ods-bg-surface h-[3px] w-full" });
1256
- var ActionsMenu = ({
1257
- groups,
1258
- className = "",
1259
- onItemClick
1260
- }) => {
1261
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1262
- "div",
1263
- {
1264
- className: `relative min-w-[256px] max-h-[var(--radix-popper-available-height)] bg-ods-bg border border-ods-border rounded-md shadow-lg overflow-y-auto ${className}`,
1265
- children: groups.map((group, groupIndex) => {
1266
- const groupKey = group.id || group.items.map((i) => i.id).join("|");
1267
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, React.default.Fragment, { children: [
1268
- group.items.map((item, itemIndex) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1269
- MenuItem,
1270
- {
1271
- item,
1272
- onItemClick
1273
- },
1274
- item.id || `${groupKey}-${itemIndex}`
1275
- )),
1276
- group.separator && groupIndex < groups.length - 1 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, GroupSeparator, {})
1277
- ] }, groupKey);
1278
- })
1279
- }
1280
- );
1281
- };
1282
- var ActionsMenuDropdown = ({
1283
- groups,
1284
- onItemClick,
1285
- className,
1286
- trigger,
1287
- customTrigger,
1288
- triggerAriaLabel = "More actions",
1289
- triggerClassName,
1290
- contentClassName,
1291
- align = "end",
1292
- side = "bottom",
1293
- sideOffset = 6,
1294
- open: openProp,
1295
- onOpenChange,
1296
- onCloseAutoFocus
1297
- }) => {
1298
- const [open = false, setOpen] = useControllableState({
1299
- prop: openProp,
1300
- defaultProp: false,
1301
- onChange: onOpenChange
1302
- });
1303
- const handleItemClick = _react.useCallback.call(void 0,
1304
- (item) => {
1305
- _optionalChain([onItemClick, 'optionalCall', _23 => _23(item)]);
1306
- if (item.type !== "checkbox" && item.type !== "submenu" && item.closeOnSelect !== false) {
1307
- setOpen(false);
1308
- }
1309
- },
1310
- [onItemClick, setOpen]
1311
- );
1312
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkXXI7BNB6cjs.DropdownMenu, { open, onOpenChange: setOpen, modal: false, children: [
1313
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXXI7BNB6cjs.DropdownMenuTrigger, { asChild: true, children: _nullishCoalesce(customTrigger, () => ( /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1314
- _chunkXXI7BNB6cjs.Button,
1315
- {
1316
- variant: "outline",
1317
- size: "icon",
1318
- "aria-label": triggerAriaLabel,
1319
- className: triggerClassName || "bg-ods-card border-ods-border hover:bg-ods-bg-hover flex items-center justify-center focus-visible:ring-0",
1320
- leftIcon: _nullishCoalesce(trigger, () => ( /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkZS2SBWBRcjs.Ellipsis01Icon, { size: 24, className: "text-ods-text-primary" })))
1321
- }
1322
- ))) }),
1323
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1324
- _chunkXXI7BNB6cjs.DropdownMenuContent,
1325
- {
1326
- align,
1327
- side,
1328
- sideOffset,
1329
- onCloseAutoFocus,
1330
- className: _chunkFIG2RKZFcjs.cn.call(void 0,
1331
- "p-0 border-0 bg-transparent shadow-none overflow-visible",
1332
- contentClassName
1333
- ),
1334
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1335
- ActionsMenu,
1336
- {
1337
- groups,
1338
- onItemClick: handleItemClick,
1339
- className
1340
- }
1341
- )
1342
- }
1343
- )
1344
- ] });
1345
- };
1346
-
1347
- // src/components/chat/utils/nav-anchor-props.ts
1348
- function isSameOriginAbsoluteHref(href) {
1349
- if (typeof window === "undefined") return false;
1350
- if (!/^https?:\/\//i.test(href)) return false;
1351
- try {
1352
- return new URL(href).origin === window.location.origin;
1353
- } catch (e2) {
1354
- return false;
1355
- }
1356
- }
1357
- function computeIsNewTab(runtime, href, targetPlatform) {
1358
- if (!href) return false;
1359
- if (runtime.navigation.mode === "embed") return !isSameOriginAbsoluteHref(href);
1360
- return _nullishCoalesce(_optionalChain([runtime, 'access', _24 => _24.navigation, 'access', _25 => _25.decideNewTab, 'optionalCall', _26 => _26({ href, targetPlatform })]), () => ( _chunkJ54Z3OCRcjs.decideNewTab.call(void 0, {
1361
- href,
1362
- targetPlatform,
1363
- currentSource: _nullishCoalesce(runtime.source, () => ( ""))
1364
- })));
1365
- }
1366
- function newTabAnchorAttrs(isNewTab) {
1367
- return isNewTab ? { target: "_blank", rel: "noopener noreferrer" } : {};
1368
- }
1369
- function buildAnchorProps(href, isNewTab) {
1370
- return href ? { href, ...newTabAnchorAttrs(isNewTab) } : void 0;
1371
- }
1372
-
1373
- // src/components/chat/entity-cards/entity-author-card.tsx
1374
- _chunkWBR7H6E3cjs.init_next_link.call(void 0, );
1375
-
1376
- var EMPTY_AUTHOR_PLACEHOLDER = {
1377
- full_name: "\u2014",
1378
- avatar_url: null,
1379
- job_title: "Unknown"
1380
- };
1381
- function EntityMetadataValueCell({
1382
- value,
1383
- label,
1384
- className,
1385
- uppercase = true
1386
- }) {
1387
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: `bg-ods-card p-4 flex flex-col gap-3 ${_nullishCoalesce(className, () => ( ""))}`, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-0", children: [
1388
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-h4 text-ods-text-primary", children: uppercase ? value.toLocaleUpperCase() : value }),
1389
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "font-['DM_Sans'] font-medium text-[14px] leading-[20px] text-ods-text-secondary", children: label })
1390
- ] }) });
1391
- }
1392
- function EntityMetadataAuthorCell({
1393
- author,
1394
- roleLabel = "Author",
1395
- authorHref,
1396
- className
1397
- }) {
1398
- const trimmedName = typeof author.full_name === "string" ? author.full_name.trim() : "";
1399
- const fullName = trimmedName || "Unknown Author";
1400
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: `bg-ods-card p-4 flex items-center gap-3 ${_nullishCoalesce(className, () => ( ""))}`, children: [
1401
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1402
- SquareAvatar,
1403
- {
1404
- src: author.avatar_url || "",
1405
- alt: fullName,
1406
- fallback: _chunkJ54Z3OCRcjs.nameInitials.call(void 0, fullName, ""),
1407
- size: "md",
1408
- variant: "round"
1409
- }
1410
- ),
1411
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-0 flex-1 min-w-0", children: [
1412
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-h3 tracking-[-0.36px] text-ods-text-primary truncate", title: fullName, children: authorHref && trimmedName ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkWBR7H6E3cjs.next_link_default, { href: authorHref, className: "hover:text-ods-accent transition-colors", children: fullName }) : fullName }),
1413
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "font-['DM_Sans'] font-medium text-[14px] leading-[20px] text-ods-text-secondary", children: author.job_title || roleLabel })
1414
- ] })
1415
- ] });
1416
- }
1417
- function EntityAuthorCard({
1418
- author,
1419
- roleLabel = "Author",
1420
- authorHref,
1421
- publishedAt,
1422
- publishedLabel = "Published",
1423
- extraCells,
1424
- renderEmptyAuthor = false,
1425
- className
1426
- }) {
1427
- const hasAuthor = !!_optionalChain([author, 'optionalAccess', _27 => _27.full_name]);
1428
- if (!hasAuthor && !renderEmptyAuthor) return null;
1429
- const effectiveAuthor = hasAuthor ? author : EMPTY_AUTHOR_PLACEHOLDER;
1430
- const formatted = publishedAt ? _chunkJ54Z3OCRcjs.formatDate.call(void 0, publishedAt) : "";
1431
- const dateLabel = formatted === "Invalid Date" ? "" : formatted;
1432
- const showDateCell = !!dateLabel;
1433
- const extras = _nullishCoalesce(extraCells, () => ( []));
1434
- const totalCells = extras.length + (showDateCell ? 1 : 0) + 1;
1435
- const gridColsClass = totalCells >= 4 ? "md:grid-cols-4" : totalCells === 3 ? "md:grid-cols-3" : totalCells === 2 ? "md:grid-cols-2" : "md:grid-cols-1";
1436
- const dividerClass = "border-b md:border-b-0 md:border-r border-ods-border";
1437
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1438
- "div",
1439
- {
1440
- className: `grid grid-cols-1 ${gridColsClass} border border-ods-border rounded-md overflow-hidden w-full ${_nullishCoalesce(className, () => ( ""))}`,
1441
- children: [
1442
- extras.map((cell, i) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1443
- EntityMetadataValueCell,
1444
- {
1445
- value: cell.value,
1446
- label: cell.label,
1447
- uppercase: _nullishCoalesce(cell.uppercase, () => ( true)),
1448
- className: dividerClass
1449
- },
1450
- `${cell.label}-${i}`
1451
- )),
1452
- showDateCell && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1453
- EntityMetadataValueCell,
1454
- {
1455
- value: dateLabel,
1456
- label: publishedLabel,
1457
- uppercase: false,
1458
- className: dividerClass
1459
- }
1460
- ),
1461
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, EntityMetadataAuthorCell, { author: effectiveAuthor, roleLabel, authorHref })
1462
- ]
1463
- }
1464
- );
1465
- }
1466
-
1467
- // src/components/chat/entity-cards/blog-image-placeholder.tsx
1468
-
1469
- function BlogImagePlaceholder({
1470
- imageUrl,
1471
- title,
1472
- className = ""
1473
- }) {
1474
- if (!imageUrl) return null;
1475
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `relative block w-full h-full overflow-hidden bg-ods-bg ${className}`, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1476
- "img",
1477
- {
1478
- src: imageUrl,
1479
- alt: `Cover image for ${title}`,
1480
- className: "block w-full h-full object-contain",
1481
- loading: "lazy",
1482
- onError: (e) => {
1483
- e.currentTarget.style.display = "none";
1484
- }
1485
- }
1486
- ) });
1487
- }
1488
-
1489
- // src/components/features/video.tsx
1490
-
1491
- var _muxplayerreact = require('@mux/mux-player-react'); var _muxplayerreact2 = _interopRequireDefault(_muxplayerreact);
1492
-
1493
- if (typeof window !== "undefined") {
1494
- const w = window;
1495
- if (!_optionalChain([w, 'access', _28 => _28.chrome, 'optionalAccess', _29 => _29.cast])) {
1496
- w.chrome = { ..._nullishCoalesce(w.chrome, () => ( {})), cast: { isAvailable: false } };
1497
- }
1498
- }
1499
- if (typeof window !== "undefined" && typeof console !== "undefined") {
1500
- const w = window;
1501
- if (!w.__MEDIA_CHROME_WARN_PATCHED__) {
1502
- w.__MEDIA_CHROME_WARN_PATCHED__ = true;
1503
- const MEDIA_CHROME_NO_STYLESHEET_PREFIX = "Media Chrome: No style sheet found on style tag of";
1504
- const originalWarn = console.warn.bind(console);
1505
- console.warn = (...args) => {
1506
- if (typeof args[0] === "string" && args[0].startsWith(MEDIA_CHROME_NO_STYLESHEET_PREFIX)) {
1507
- return;
1508
- }
1509
- originalWarn(...args);
1510
- };
1511
- }
1512
- }
1513
- var YT_HOSTS = /* @__PURE__ */ new Set([
1514
- "youtube.com",
1515
- "www.youtube.com",
1516
- "m.youtube.com",
1517
- "youtu.be",
1518
- "youtube-nocookie.com",
1519
- "www.youtube-nocookie.com"
1520
- ]);
1521
- function isYouTubeUrl(url) {
1522
- try {
1523
- return YT_HOSTS.has(new URL(url, "http://placeholder.local").hostname.toLowerCase());
1524
- } catch (e3) {
1525
- return false;
1526
- }
1527
- }
1528
- var YT_PATH_RE = /^\/(?:embed|v|shorts)\/([^/]+)\/?$/;
1529
- var BARE_YT_ID_RE = /^[A-Za-z0-9_-]{11}$/;
1530
- function extractYouTubeId(url) {
1531
- if (!url) return null;
1532
- if (BARE_YT_ID_RE.test(url)) return url;
1533
- let u;
1534
- try {
1535
- u = new URL(url, "http://placeholder.local");
1536
- } catch (e4) {
1537
- return null;
1538
- }
1539
- if (!YT_HOSTS.has(u.hostname.toLowerCase())) return null;
1540
- if (u.hostname.toLowerCase().endsWith("youtu.be")) {
1541
- return _nullishCoalesce(u.pathname.split("/").filter(Boolean)[0], () => ( null));
1542
- }
1543
- const v = u.searchParams.get("v");
1544
- if (v) return v;
1545
- const m = u.pathname.match(YT_PATH_RE);
1546
- return m ? m[1] : null;
1547
- }
1548
- function Video(props) {
1549
- const url = props.url;
1550
- if (!url) return null;
1551
- const effectiveKind = resolveKind(props, url);
1552
- const layout = _nullishCoalesce(props.layout, () => ( "native"));
1553
- const inner = effectiveKind === "youtube" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1554
- YouTubeFacade,
1555
- {
1556
- url,
1557
- title: props.title,
1558
- priority: props.priority,
1559
- className: props.className,
1560
- minimalControls: props.minimalControls
1561
- }
1562
- ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1563
- FilePlayer,
1564
- {
1565
- url,
1566
- poster: props.poster,
1567
- muted: props.muted,
1568
- srtContent: "srtContent" in props ? props.srtContent : null,
1569
- captionsUrl: "captionsUrl" in props ? props.captionsUrl : null,
1570
- className: props.className
1571
- }
1572
- );
1573
- return wrapWithLayout(inner, layout);
1574
- }
1575
- function resolveKind(props, url) {
1576
- if ("kind" in props) {
1577
- if (props.kind === "youtube") return "youtube";
1578
- if (props.kind === "file") return "file";
1579
- }
1580
- if (BARE_YT_ID_RE.test(url)) return "youtube";
1581
- return isYouTubeUrl(url) ? "youtube" : "file";
1582
- }
1583
- function wrapWithLayout(inner, layout) {
1584
- switch (layout) {
1585
- case "centered":
1586
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex justify-center w-full", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-full max-w-3xl aspect-video rounded-lg overflow-hidden border border-ods-border", children: inner }) });
1587
- case "fill":
1588
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "absolute inset-0 w-full h-full", children: inner });
1589
- case "native":
1590
- default:
1591
- return inner;
1592
- }
1593
- }
1594
- function FilePlayer({
1595
- url,
1596
- poster,
1597
- muted,
1598
- srtContent,
1599
- captionsUrl,
1600
- className
1601
- }) {
1602
- if (process.env.NODE_ENV !== "production" && srtContent && !captionsUrl) {
1603
- console.warn(
1604
- "[Video] srtContent supplied without captionsUrl \u2014 captions will not render. Pass captionsUrl (the VTT URL) instead; raw SRT text overlays are no longer supported."
1605
- );
1606
- }
1607
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1608
- _muxplayerreact2.default,
1609
- {
1610
- src: url,
1611
- poster: poster || void 0,
1612
- streamType: "on-demand",
1613
- playsInline: true,
1614
- muted,
1615
- preferCmcd: "header",
1616
- accentColor: "var(--ods-accent, var(--color-accent-primary))",
1617
- className,
1618
- style: { width: "100%", height: "100%" },
1619
- children: captionsUrl ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1620
- "track",
1621
- {
1622
- kind: "captions",
1623
- src: captionsUrl,
1624
- srcLang: "en",
1625
- label: "English",
1626
- default: true
1627
- }
1628
- ) : null
1629
- }
1630
- );
1631
- }
1632
- function YouTubeFacade({
1633
- url,
1634
- title = "YouTube Video",
1635
- priority,
1636
- className,
1637
- minimalControls
1638
- }) {
1639
- const videoId = extractYouTubeId(url);
1640
- if (!videoId) return null;
1641
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, YouTubeFacadeInner, { videoId, title, priority, className, minimalControls });
1642
- }
1643
- var YT_NOCOOKIE_ORIGIN = "https://www.youtube-nocookie.com";
1644
- var YT_STATE_ENDED = 0;
1645
- var YT_STATE_PLAYING = 1;
1646
- var YT_PLAYING_BLUR_DELAY_MS = 1e3;
1647
- function YouTubeFacadeInner({
1648
- videoId,
1649
- title,
1650
- priority,
1651
- className,
1652
- minimalControls
1653
- }) {
1654
- const [activated, setActivated] = _react.useState.call(void 0, false);
1655
- const iframeRef = _react.useRef.call(void 0, null);
1656
- const { embedUrl, posterJpg, posterWebp } = _react.useMemo.call(void 0, () => {
1657
- const params = new URLSearchParams({
1658
- autoplay: "1",
1659
- rel: "0",
1660
- modestbranding: "1",
1661
- playsinline: "1",
1662
- enablejsapi: "1"
1663
- });
1664
- if (typeof window !== "undefined") {
1665
- params.set("origin", window.location.origin);
1666
- }
1667
- if (minimalControls) {
1668
- params.set("controls", "0");
1669
- params.set("fs", "0");
1670
- params.set("iv_load_policy", "3");
1671
- params.set("cc_load_policy", "0");
1672
- params.set("disablekb", "1");
1673
- }
1674
- return {
1675
- embedUrl: `${YT_NOCOOKIE_ORIGIN}/embed/${videoId}?${params.toString()}`,
1676
- posterJpg: `https://i.ytimg.com/vi/${videoId}/mqdefault.jpg`,
1677
- posterWebp: `https://i.ytimg.com/vi_webp/${videoId}/mqdefault.webp`
1678
- };
1679
- }, [videoId, minimalControls]);
1680
- _react.useEffect.call(void 0, () => {
1681
- if (!activated) return;
1682
- const iframe = iframeRef.current;
1683
- if (!iframe) return;
1684
- function subscribe() {
1685
- _optionalChain([iframe, 'optionalAccess', _30 => _30.contentWindow, 'optionalAccess', _31 => _31.postMessage, 'call', _32 => _32(
1686
- '{"event":"listening"}',
1687
- YT_NOCOOKIE_ORIGIN
1688
- )]);
1689
- }
1690
- iframe.addEventListener("load", subscribe);
1691
- subscribe();
1692
- let blurTimer = null;
1693
- function handleMessage(event) {
1694
- if (event.origin !== YT_NOCOOKIE_ORIGIN) return;
1695
- if (typeof event.data !== "string") return;
1696
- let payload = null;
1697
- try {
1698
- payload = JSON.parse(event.data);
1699
- } catch (e5) {
1700
- return;
1701
- }
1702
- if (!payload || payload.event !== "infoDelivery") return;
1703
- const state = _optionalChain([payload, 'access', _33 => _33.info, 'optionalAccess', _34 => _34.playerState]);
1704
- if (typeof state !== "number") return;
1705
- if (state === YT_STATE_PLAYING) {
1706
- if (blurTimer !== null) return;
1707
- blurTimer = setTimeout(() => {
1708
- blurTimer = null;
1709
- _optionalChain([iframeRef, 'access', _35 => _35.current, 'optionalAccess', _36 => _36.blur, 'call', _37 => _37()]);
1710
- }, YT_PLAYING_BLUR_DELAY_MS);
1711
- return;
1712
- }
1713
- if (state === YT_STATE_ENDED) {
1714
- setActivated(false);
1715
- }
1716
- }
1717
- window.addEventListener("message", handleMessage);
1718
- return () => {
1719
- iframe.removeEventListener("load", subscribe);
1720
- window.removeEventListener("message", handleMessage);
1721
- if (blurTimer !== null) clearTimeout(blurTimer);
1722
- };
1723
- }, [activated]);
1724
- const wrapperClass = `relative w-full ${_nullishCoalesce(className, () => ( ""))}`;
1725
- const wrapperStyle = { paddingBottom: "56.25%" };
1726
- if (activated) {
1727
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: wrapperClass, style: wrapperStyle, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1728
- "iframe",
1729
- {
1730
- ref: iframeRef,
1731
- src: embedUrl,
1732
- allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",
1733
- allowFullScreen: true,
1734
- title,
1735
- className: "absolute inset-0 w-full h-full border-0 rounded-lg"
1736
- }
1737
- ) });
1738
- }
1739
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: wrapperClass, style: wrapperStyle, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1740
- "button",
1741
- {
1742
- type: "button",
1743
- "aria-label": `Play: ${title}`,
1744
- onClick: () => setActivated(true),
1745
- className: "group absolute inset-0 p-0 m-0 border border-ods-border rounded-lg overflow-hidden bg-ods-card cursor-pointer",
1746
- children: [
1747
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "picture", { children: [
1748
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "source", { type: "image/webp", srcSet: posterWebp }),
1749
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1750
- "img",
1751
- {
1752
- src: posterJpg,
1753
- alt: title,
1754
- loading: "lazy",
1755
- ..._chunkJ54Z3OCRcjs.fetchPriorityProp.call(void 0, priority),
1756
- decoding: priority ? "sync" : "async",
1757
- className: "absolute inset-0 w-full h-full object-cover"
1758
- }
1759
- )
1760
- ] }),
1761
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "absolute inset-0 flex items-center justify-center bg-ods-bg-inverse bg-opacity-20 transition-opacity duration-200 group-hover:bg-opacity-30", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "flex items-center justify-center w-16 h-16 rounded-full bg-ods-accent text-ods-text-on-accent shadow-lg transition-transform duration-200 group-hover:scale-110", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkZS2SBWBRcjs.PlayIcon, { size: 24, color: "currentColor", className: "ml-1" }) }) })
1762
- ]
1763
- }
1764
- ) });
1765
- }
1766
-
1767
- // src/components/features/video-ratio-tabs.tsx
1768
-
1769
- var TAB_TRIGGER_CLASS = "rounded-none border-b-2 border-transparent data-[state=active]:border-ods-accent data-[state=active]:bg-transparent data-[state=active]:shadow-none px-4 py-2 text-sm text-ods-text-secondary data-[state=active]:text-ods-text-primary";
1770
- var RATIO_GRID_CLASS = {
1771
- portrait: "grid grid-cols-2 md:grid-cols-3 gap-4",
1772
- square: "grid grid-cols-2 md:grid-cols-3 gap-4",
1773
- landscape: "grid grid-cols-1 md:grid-cols-2 gap-4"
1774
- };
1775
- var RATIO_DISPLAY_GRID_CLASS = {
1776
- portrait: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4",
1777
- square: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4",
1778
- landscape: "grid grid-cols-1 md:grid-cols-2 gap-6"
1779
- };
1780
- var RATIO_TAB_CONFIG = [
1781
- { key: "portrait", label: "Portrait 9:16" },
1782
- { key: "square", label: "Square 1:1" },
1783
- { key: "landscape", label: "Landscape 16:9" }
1784
- ];
1785
- function RatioTabs({
1786
- groups,
1787
- defaultTab,
1788
- className = ""
1789
- }) {
1790
- const activeTabs = RATIO_TAB_CONFIG.filter((t) => groups[t.key].count > 0);
1791
- if (activeTabs.length <= 1) {
1792
- const active = activeTabs[0];
1793
- return active ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children: groups[active.key].render() }) : null;
1794
- }
1795
- const firstTab = defaultTab && groups[defaultTab].count > 0 ? defaultTab : activeTabs[0].key;
1796
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Tabs, { defaultValue: firstTab, className: `w-full ${className}`, children: [
1797
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TabsList, { className: "inline-flex justify-start rounded-none bg-transparent h-auto p-0 gap-0 mb-2", children: activeTabs.map((t) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, TabsTrigger, { value: t.key, className: TAB_TRIGGER_CLASS, children: [
1798
- t.label,
1799
- " (",
1800
- groups[t.key].count,
1801
- ")"
1802
- ] }, t.key)) }),
1803
- activeTabs.map((t) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1804
- TabsContent,
1805
- {
1806
- value: t.key,
1807
- forceMount: true,
1808
- className: "data-[state=inactive]:hidden",
1809
- children: groups[t.key].render()
1810
- },
1811
- t.key
1812
- ))
1813
- ] });
1814
- }
1815
- function detectAspectRatio(ratioString, width, height) {
1816
- if (ratioString === "16:9") return "16:9";
1817
- if (ratioString === "1:1") return "1:1";
1818
- if (ratioString === "9:16") return "9:16";
1819
- if (width && height) {
1820
- if (Math.abs(width - height) < Math.min(width, height) * 0.1) return "1:1";
1821
- if (width > height) return "16:9";
1822
- }
1823
- return "9:16";
1824
- }
1825
- function ratioToCategory(ratio) {
1826
- if (ratio === "16:9") return "landscape";
1827
- if (ratio === "1:1") return "square";
1828
- return "portrait";
1829
- }
1830
- function groupByAspectRatio(items, getAspectRatio) {
1831
- const portrait = [];
1832
- const square = [];
1833
- const landscape = [];
1834
- for (const item of items) {
1835
- const cat = ratioToCategory(getAspectRatio(item));
1836
- if (cat === "landscape") landscape.push(item);
1837
- else if (cat === "square") square.push(item);
1838
- else portrait.push(item);
1839
- }
1840
- const filled = [portrait, square, landscape].filter((a) => a.length > 0).length;
1841
- return { portrait, square, landscape, hasMultiple: filled > 1 };
1842
- }
1843
-
1844
- // src/components/features/video-bites-display.tsx
1845
-
1846
-
1847
- var RATIO_TO_CSS_ASPECT = {
1848
- portrait: "9 / 16",
1849
- square: "1 / 1",
1850
- landscape: "16 / 9"
1851
- };
1852
- function LazyBite({ ratio, children }) {
1853
- const { ref, isNear } = _chunkTFSYSWPScjs.useNearViewport.call(void 0, "500px");
1854
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref, style: { aspectRatio: RATIO_TO_CSS_ASPECT[ratio] }, children: isNear ? children : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-full h-full bg-ods-card rounded-md" }) });
1855
- }
1856
- function VideoBitesDisplay({
1857
- bites,
1858
- title = "Video Highlights",
1859
- filterPublished = true,
1860
- showTitle = true
1861
- }) {
1862
- const grouped = _react.useMemo.call(void 0, () => {
1863
- const filtered = filterPublished ? bites.filter((b) => b.published) : bites;
1864
- const sorted = [...filtered].sort((a, b) => {
1865
- if (!a.created_at && !b.created_at) return 0;
1866
- if (!a.created_at) return 1;
1867
- if (!b.created_at) return -1;
1868
- return new Date(b.created_at).getTime() - new Date(a.created_at).getTime();
1869
- });
1870
- return groupByAspectRatio(
1871
- sorted,
1872
- (b) => detectAspectRatio(b.aspect_ratio)
1873
- );
1874
- }, [bites, filterPublished]);
1875
- const totalCount = grouped.portrait.length + grouped.square.length + grouped.landscape.length;
1876
- if (totalCount === 0) return null;
1877
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-6 w-full min-w-0", children: [
1878
- showTitle && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: `${_chunkJ54Z3OCRcjs.SECTION_HEADING_CLASS} break-words`, children: title }),
1879
- grouped.hasMultiple ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1880
- RatioTabs,
1881
- {
1882
- groups: {
1883
- portrait: {
1884
- count: grouped.portrait.length,
1885
- render: () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, BiteGrid, { bites: grouped.portrait, ratio: "portrait" })
1886
- },
1887
- square: {
1888
- count: grouped.square.length,
1889
- render: () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, BiteGrid, { bites: grouped.square, ratio: "square" })
1890
- },
1891
- landscape: {
1892
- count: grouped.landscape.length,
1893
- render: () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, BiteGrid, { bites: grouped.landscape, ratio: "landscape" })
1894
- }
1895
- }
1896
- }
1897
- ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1898
- BiteGrid,
1899
- {
1900
- bites: grouped.portrait.length > 0 ? grouped.portrait : grouped.square.length > 0 ? grouped.square : grouped.landscape,
1901
- ratio: grouped.portrait.length > 0 ? "portrait" : grouped.square.length > 0 ? "square" : "landscape"
1902
- }
1903
- )
1904
- ] });
1905
- }
1906
- function BiteGrid({ bites, ratio }) {
1907
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: RATIO_DISPLAY_GRID_CLASS[ratio], children: bites.map((bite, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, LazyBite, { ratio, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, VideoBiteCard, { url: bite.url, title: bite.title, thumbnailUrl: bite.thumbnail_url }) }, bite.url || index)) });
1908
- }
1909
- function VideoBiteCard({ url, title, thumbnailUrl }) {
1910
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Card, { className: "overflow-hidden border border-ods-border bg-ods-card hover:border-ods-accent transition-colors flex flex-col h-full", children: [
1911
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "relative flex-1 min-h-0", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Video, { url, poster: thumbnailUrl || void 0, layout: "fill" }) }),
1912
- title && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "p-4", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-h4 text-ods-text-primary line-clamp-2", title, children: title }) })
1913
- ] });
1914
- }
1915
-
1916
- // src/components/features/entity-video-section.tsx
1917
-
1918
- function EntityVideoSection({
1919
- mainVideoUrl,
1920
- youtubeUrl,
1921
- highlightVideoUrl,
1922
- highlightVideoThumbnail,
1923
- mainVideoPoster,
1924
- title = "Video",
1925
- videoSummary,
1926
- videoBites,
1927
- bitesTitle = "Video Highlights",
1928
- filterPublishedBites = true,
1929
- MarkdownRenderer,
1930
- srtContent,
1931
- captionsUrl,
1932
- priority = false
1933
- }) {
1934
- const hasFullVideo = !!(youtubeUrl || mainVideoUrl);
1935
- const hasHighlight = !!highlightVideoUrl;
1936
- const hasVideo = hasFullVideo || hasHighlight;
1937
- if (!hasVideo && !videoSummary && (!videoBites || videoBites.length === 0)) {
1938
- return null;
1939
- }
1940
- const fullVideoUrl = youtubeUrl || mainVideoUrl || null;
1941
- const fullVideoKind = youtubeUrl ? "youtube" : "auto";
1942
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
1943
- hasVideo && (hasFullVideo && hasHighlight ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Tabs, { defaultValue: "full-video", className: "w-full", children: [
1944
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, TabsList, { className: "inline-flex justify-start rounded-none bg-transparent h-auto p-0 gap-0", children: [
1945
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1946
- TabsTrigger,
1947
- {
1948
- value: "full-video",
1949
- className: "rounded-none border-b-2 border-transparent data-[state=active]:border-ods-accent data-[state=active]:bg-transparent data-[state=active]:shadow-none px-4 md:px-6 py-3 text-ods-text-secondary data-[state=active]:text-ods-text-primary",
1950
- children: "Full Video"
1951
- }
1952
- ),
1953
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1954
- TabsTrigger,
1955
- {
1956
- value: "highlights",
1957
- className: "rounded-none border-b-2 border-transparent data-[state=active]:border-ods-accent data-[state=active]:bg-transparent data-[state=active]:shadow-none px-4 md:px-6 py-3 text-ods-text-secondary data-[state=active]:text-ods-text-primary",
1958
- children: "Highlights"
1959
- }
1960
- )
1961
- ] }),
1962
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TabsContent, { value: "full-video", className: "mt-4", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1963
- Video,
1964
- {
1965
- kind: fullVideoKind,
1966
- url: fullVideoUrl,
1967
- poster: mainVideoPoster,
1968
- title,
1969
- srtContent,
1970
- captionsUrl,
1971
- layout: "centered",
1972
- priority
1973
- }
1974
- ) }),
1975
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TabsContent, { value: "highlights", className: "mt-4", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1976
- Video,
1977
- {
1978
- url: highlightVideoUrl,
1979
- poster: highlightVideoThumbnail,
1980
- layout: "centered"
1981
- }
1982
- ) })
1983
- ] }) : hasFullVideo ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1984
- Video,
1985
- {
1986
- kind: fullVideoKind,
1987
- url: fullVideoUrl,
1988
- poster: mainVideoPoster,
1989
- title,
1990
- srtContent,
1991
- captionsUrl,
1992
- layout: "centered",
1993
- priority
1994
- }
1995
- ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1996
- Video,
1997
- {
1998
- url: highlightVideoUrl,
1999
- poster: highlightVideoThumbnail,
2000
- layout: "centered",
2001
- priority
2002
- }
2003
- )),
2004
- videoSummary && MarkdownRenderer && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-6 w-full min-w-0", children: [
2005
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: `${_chunkJ54Z3OCRcjs.SECTION_HEADING_CLASS} break-words`, children: "Summary" }),
2006
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-h4 text-ods-text-primary break-words overflow-hidden", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MarkdownRenderer, { content: videoSummary }) })
2007
- ] }),
2008
- videoBites && videoBites.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2009
- VideoBitesDisplay,
2010
- {
2011
- bites: videoBites,
2012
- title: bitesTitle,
2013
- filterPublished: filterPublishedBites
2014
- }
2015
- )
2016
- ] });
2017
- }
2018
-
2019
- // src/components/chat/entity-cards/onboarding-guide-card.tsx
2020
- _chunkWBR7H6E3cjs.init_next_link.call(void 0, );
2021
- _chunkFIG2RKZFcjs.init_cn.call(void 0, );
2022
-
2023
-
2024
- // src/components/chat/entity-cards/use-entity-card-link.ts
2025
-
2026
- function useEntityCardLink({
2027
- href,
2028
- targetPlatform,
2029
- target,
2030
- rel
2031
- }) {
2032
- const runtime = _chunkAQOWFSMBcjs.useChatRuntime.call(void 0, );
2033
- return _react.useMemo.call(void 0, () => {
2034
- if (target !== void 0 || rel !== void 0) {
2035
- const safeRel = _nullishCoalesce(rel, () => ( (target === "_blank" ? "noopener noreferrer" : void 0)));
2036
- return { target, rel: safeRel };
2037
- }
2038
- const newTab = runtime ? computeIsNewTab(runtime, href, _nullishCoalesce(targetPlatform, () => ( null))) : false;
2039
- return newTab ? { target: "_blank", rel: "noopener noreferrer" } : { target: void 0, rel: void 0 };
2040
- }, [target, rel, href, targetPlatform, runtime]);
2041
- }
2042
-
2043
- // src/components/chat/entity-cards/use-entity-card-placeholder.ts
2044
- var NO_OP_BUILDER = () => "";
2045
- function useEntityCardPlaceholder({
2046
- title,
2047
- placeholderUrl,
2048
- siteName = "",
2049
- aspect = "wide"
2050
- }) {
2051
- const runtime = _chunkAQOWFSMBcjs.useChatRuntime.call(void 0, );
2052
- const builder = _nullishCoalesce(_optionalChain([runtime, 'optionalAccess', _38 => _38.resolvePlaceholderUrl]), () => ( NO_OP_BUILDER));
2053
- const enabled = placeholderUrl === void 0 && !!_optionalChain([runtime, 'optionalAccess', _39 => _39.resolvePlaceholderUrl]);
2054
- const derived = _chunkTFSYSWPScjs.useOgPlaceholder.call(void 0, builder, title, siteName, enabled, aspect);
2055
- return placeholderUrl !== void 0 ? placeholderUrl : derived;
2056
- }
2057
-
2058
- // src/components/chat/entity-cards/onboarding-guide-card.tsx
2059
-
2060
- function stripMarkdownPreview(text) {
2061
- return text.replace(/```[\s\S]*?```/g, " ").replace(/^#{1,6}\s+/gm, "").replace(/!?\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/[*_~`>]/g, "").replace(/^\s*[-+]\s+/gm, "").replace(/-{3,}/g, " ").replace(/\s+/g, " ").trim().replace(/^([\s\S]{240})[\s\S]+$/, "$1\u2026");
2062
- }
2063
- var HORIZONTAL_SIZE_TOKENS = {
2064
- default: {
2065
- padding: "p-4",
2066
- step: "w-8 h-8 text-sm",
2067
- title: "text-h5",
2068
- summaryClamp: "line-clamp-2"
2069
- }
2070
- };
2071
- function OnboardingGuideCardSkeleton({ size = "default" }) {
2072
- if (size === "catalog") {
2073
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "bg-ods-system-greys-black border border-ods-border rounded-lg overflow-hidden flex flex-col p-6 gap-4 animate-pulse", children: [
2074
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col md:flex-row gap-4 md:gap-6", children: [
2075
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-full md:w-[256px] aspect-[1200/630] bg-ods-border rounded-lg flex-shrink-0" }),
2076
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1 min-w-0 flex flex-col", children: [
2077
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "min-h-[60px] md:min-h-[72px] flex flex-col gap-1.5 justify-start mb-3", children: [
2078
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-[25px] md:h-[30px] w-3/4 bg-ods-border rounded" }),
2079
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-[25px] md:h-[30px] w-1/2 bg-ods-border rounded" })
2080
- ] }),
2081
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "min-h-[46px] md:min-h-[52px] flex flex-col gap-2 justify-start", children: [
2082
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-3 w-full bg-ods-border/70 rounded" }),
2083
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-3 w-5/6 bg-ods-border/70 rounded" })
2084
- ] })
2085
- ] })
2086
- ] }),
2087
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "grid grid-cols-1 md:grid-cols-3 border border-ods-border rounded-md overflow-hidden w-full", children: [
2088
- [0, 1].map((i) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2089
- "div",
2090
- {
2091
- className: "bg-ods-card p-4 flex flex-col gap-3 border-b md:border-b-0 md:border-r border-ods-border",
2092
- children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-2", children: [
2093
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-6 w-32 bg-ods-bg rounded" }),
2094
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-3 w-20 bg-ods-bg/60 rounded" })
2095
- ] })
2096
- },
2097
- `cell-${i}`
2098
- )),
2099
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "bg-ods-card p-4 flex items-center gap-3", children: [
2100
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-10 w-10 rounded-full bg-ods-bg shrink-0" }),
2101
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-2 flex-1 min-w-0", children: [
2102
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-4 w-3/4 bg-ods-bg rounded" }),
2103
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-3 w-1/2 bg-ods-bg/60 rounded" })
2104
- ] })
2105
- ] })
2106
- ] })
2107
- ] });
2108
- }
2109
- if (size === "sm") {
2110
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: _chunkJ54Z3OCRcjs.COMPACT_CARD_SKELETON_OUTER, children: [
2111
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunkJ54Z3OCRcjs.COMPACT_CARD_SKELETON_IMAGE_SLOT }),
2112
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: _chunkJ54Z3OCRcjs.COMPACT_CARD_TEXT_COL, children: [
2113
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunkJ54Z3OCRcjs.COMPACT_CARD_TITLE_ROW, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "h-3.5 w-3/5 rounded bg-ods-bg" }) }),
2114
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunkJ54Z3OCRcjs.COMPACT_CARD_META_ROW_BOX, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "h-3 w-2/5 rounded bg-ods-bg/70" }) }),
2115
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunkJ54Z3OCRcjs.COMPACT_CARD_META_ROW_BOX, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "h-3 w-11/12 rounded bg-ods-bg/40" }) })
2116
- ] }),
2117
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "flex shrink-0 items-center self-start h-5", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "h-3.5 w-3.5 rounded bg-ods-bg" }) })
2118
- ] });
2119
- }
2120
- const t = HORIZONTAL_SIZE_TOKENS.default;
2121
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2122
- "span",
2123
- {
2124
- className: `flex items-start gap-3 rounded-md border border-ods-border bg-ods-card ${t.padding} animate-pulse`,
2125
- children: [
2126
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `shrink-0 inline-flex items-center justify-center rounded-full bg-ods-bg ${t.step}` }),
2127
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "flex flex-col gap-2 flex-1 min-w-0", children: [
2128
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "block h-4 w-2/3 rounded bg-ods-bg" }),
2129
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "block h-3 w-1/3 rounded bg-ods-bg/70" }),
2130
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "block h-3 w-full rounded bg-ods-bg/40" })
2131
- ] })
2132
- ]
2133
- }
2134
- );
2135
- }
2136
- function OnboardingGuideCard({
2137
- guide,
2138
- href,
2139
- target: targetProp,
2140
- rel: relProp,
2141
- targetPlatform,
2142
- placeholderUrl: placeholderUrlProp,
2143
- size = "default",
2144
- className
2145
- }) {
2146
- const { target, rel } = useEntityCardLink({
2147
- href,
2148
- targetPlatform,
2149
- target: targetProp,
2150
- rel: relProp
2151
- });
2152
- const placeholderUrl = useEntityCardPlaceholder({
2153
- title: guide.title,
2154
- placeholderUrl: placeholderUrlProp,
2155
- aspect: size === "sm" ? "square" : "wide"
2156
- });
2157
- if (size === "catalog") {
2158
- const coverImage = guide.featured_image || guide.main_video_thumbnail || guide.og_image_url || null;
2159
- const hasVideoCover = !!(guide.main_video_thumbnail || guide.highlight_video_thumbnail);
2160
- const stepLabel = typeof guide.step_order === "number" ? String(guide.step_order).padStart(2, "0") : "\u2014";
2161
- const durationLabel = typeof guide.highlight_video_duration_ms === "number" && guide.highlight_video_duration_ms > 0 ? _chunkJ54Z3OCRcjs.formatDurationMMSS.call(void 0, Math.floor(guide.highlight_video_duration_ms / 1e3)) : "";
2162
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2163
- _chunkWBR7H6E3cjs.next_link_default,
2164
- {
2165
- href,
2166
- target,
2167
- rel,
2168
- prefetch: false,
2169
- className: _chunkFIG2RKZFcjs.cn.call(void 0,
2170
- "group block no-underline bg-ods-system-greys-black",
2171
- "border border-ods-border rounded-lg overflow-hidden",
2172
- "transition-all duration-300 ease-out",
2173
- "transform hover:translate-y-[-2px]",
2174
- "hover:border-ods-accent hover:shadow-lg hover:shadow-ods-accent/[0.08]",
2175
- className
2176
- ),
2177
- "aria-label": `Open ${guide.title}`,
2178
- children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col p-6 gap-4", children: [
2179
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col md:flex-row gap-4 md:gap-6", children: [
2180
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-full md:w-[256px] flex-shrink-0", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "relative rounded-lg overflow-hidden w-full aspect-[1200/630] bg-ods-bg", children: [
2181
- coverImage ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2182
- _chunkXL4V2PYGcjs.next_image_default,
2183
- {
2184
- src: coverImage,
2185
- alt: guide.title,
2186
- fill: true,
2187
- sizes: "(max-width: 768px) 100vw, 256px",
2188
- className: "object-cover",
2189
- unoptimized: true
2190
- }
2191
- ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2192
- BlogImagePlaceholder,
2193
- {
2194
- title: guide.title,
2195
- imageUrl: _nullishCoalesce(placeholderUrl, () => ( null)),
2196
- className: "absolute inset-0"
2197
- }
2198
- ),
2199
- hasVideoCover && coverImage && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "absolute inset-0 flex items-center justify-center bg-black/30", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Play, { className: "w-10 h-10 text-white", fill: "white" }) }),
2200
- durationLabel && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "absolute bottom-2 right-2 inline-flex items-center gap-1 px-2 py-1 rounded bg-black/60 text-white text-xs font-medium font-mono", children: [
2201
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Clock, { className: "w-3 h-3" }),
2202
- durationLabel
2203
- ] })
2204
- ] }) }),
2205
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1 min-w-0 flex flex-col", children: [
2206
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "min-h-[60px] md:min-h-[72px] flex items-start mb-3", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "font-['Azeret_Mono'] font-semibold text-xl md:text-2xl text-ods-text-primary leading-tight line-clamp-2", children: guide.title }) }),
2207
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "min-h-[46px] md:min-h-[52px]", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "font-['DM_Sans'] text-sm md:text-base text-ods-text-secondary leading-relaxed line-clamp-2", children: stripMarkdownPreview(guide.video_summary || guide.content || "") }) })
2208
- ] })
2209
- ] }),
2210
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2211
- EntityAuthorCard,
2212
- {
2213
- author: guide.author,
2214
- publishedAt: guide.published_at,
2215
- renderEmptyAuthor: true,
2216
- extraCells: [
2217
- {
2218
- value: `${guide.section} \xB7 Step ${stepLabel}`,
2219
- label: "Section",
2220
- uppercase: false
2221
- }
2222
- ]
2223
- }
2224
- )
2225
- ] })
2226
- }
2227
- );
2228
- }
2229
- if (size === "sm") {
2230
- const coverImage = guide.featured_image || guide.main_video_thumbnail || guide.og_image_url || null;
2231
- const compactCover = coverImage || placeholderUrl || null;
2232
- const hasVideoCover = !guide.featured_image && !!guide.main_video_thumbnail;
2233
- const summary2 = stripMarkdownPreview(guide.video_summary || guide.content || "");
2234
- const author = _optionalChain([guide, 'access', _40 => _40.author, 'optionalAccess', _41 => _41.full_name, 'optionalAccess', _42 => _42.trim, 'call', _43 => _43()]) || "";
2235
- const subtitleParts = [
2236
- `Step ${guide.step_order}`,
2237
- guide.section,
2238
- author
2239
- ].filter((s) => typeof s === "string" && s.length > 0);
2240
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkWBR7H6E3cjs.next_link_default, { href, target, rel, prefetch: false, className: _chunkFIG2RKZFcjs.cn.call(void 0, _chunkJ54Z3OCRcjs.COMPACT_CARD_OUTER, className), children: [
2241
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: _chunkJ54Z3OCRcjs.COMPACT_CARD_IMAGE_SLOT, children: [
2242
- compactCover ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2243
- _chunkXL4V2PYGcjs.next_image_default,
2244
- {
2245
- src: compactCover,
2246
- alt: guide.title,
2247
- fill: true,
2248
- sizes: "56px",
2249
- className: "object-contain",
2250
- unoptimized: true
2251
- }
2252
- ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "flex h-full w-full items-center justify-center text-ods-accent", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.GraduationCap, { className: "w-4 h-4" }) }),
2253
- hasVideoCover && compactCover && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "absolute inset-0 flex items-center justify-center bg-black/30", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Play, { className: "h-4 w-4 text-white", fill: "white" }) })
2254
- ] }),
2255
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: _chunkJ54Z3OCRcjs.COMPACT_CARD_TEXT_COL, children: [
2256
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunkJ54Z3OCRcjs.COMPACT_CARD_TITLE_ROW, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunkFIG2RKZFcjs.cn.call(void 0, _chunkJ54Z3OCRcjs.COMPACT_CARD_TITLE, "font-['Azeret_Mono']"), children: guide.title }) }),
2257
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunkJ54Z3OCRcjs.COMPACT_CARD_META_ROW_BOX, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "truncate text-[11px] leading-4 text-[var(--color-accent-primary)]", children: subtitleParts.join(" \xB7 ") }) }),
2258
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunkJ54Z3OCRcjs.COMPACT_CARD_META_ROW_BOX, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunkJ54Z3OCRcjs.COMPACT_CARD_SUMMARY, children: summary2 || _chunkJ54Z3OCRcjs.COMPACT_CARD_ROW_FILLER }) })
2259
- ] }),
2260
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "flex shrink-0 items-center self-start h-5 text-ods-text-secondary", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ExternalLink, { className: "w-3.5 h-3.5" }) })
2261
- ] });
2262
- }
2263
- const t = HORIZONTAL_SIZE_TOKENS.default;
2264
- const summary = stripMarkdownPreview(guide.video_summary || guide.content || "");
2265
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2266
- _chunkWBR7H6E3cjs.next_link_default,
2267
- {
2268
- href,
2269
- target,
2270
- rel,
2271
- prefetch: false,
2272
- className: _chunkFIG2RKZFcjs.cn.call(void 0,
2273
- `flex items-start gap-3 rounded-md border border-ods-border bg-ods-card hover:border-ods-accent transition-colors ${t.padding}`,
2274
- className
2275
- ),
2276
- children: [
2277
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2278
- "span",
2279
- {
2280
- className: `shrink-0 inline-flex items-center justify-center rounded-full bg-ods-accent/10 text-ods-accent font-semibold ${t.step}`,
2281
- "aria-hidden": "true",
2282
- children: guide.step_order
2283
- }
2284
- ),
2285
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "flex flex-col gap-0.5 flex-1 min-w-0", children: [
2286
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `block ${t.title} text-ods-text-primary truncate`, children: guide.title }),
2287
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "inline-flex items-center gap-1 font-['DM_Sans'] text-[12px] leading-[16px] text-ods-text-secondary", children: [
2288
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.GraduationCap, { className: "h-3 w-3 shrink-0" }),
2289
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "truncate", children: guide.section })
2290
- ] }),
2291
- summary && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `font-['DM_Sans'] text-[14px] leading-[20px] text-ods-text-secondary ${t.summaryClamp}`, children: summary })
2292
- ] })
2293
- ]
2294
- }
2295
- );
2296
- }
2297
-
2298
- // src/components/ui/page-actions.tsx
2299
- _chunkFIG2RKZFcjs.init_cn.call(void 0, );
2300
-
2301
- _chunkXXI7BNB6cjs.init_button2.call(void 0, );
2302
-
2303
- function actionKey(action, idx) {
2304
- return `${_nullishCoalesce(_nullishCoalesce(action.label, () => ( action.ariaLabel)), () => ( "action"))}-${idx}`;
2305
- }
2306
- function actionToMenuItems(action, idx) {
2307
- if (action.submenu && action.submenu.length > 0) {
2308
- if (!action.label) return action.submenu;
2309
- return action.submenu.map((item) => ({
2310
- ...item,
2311
- label: `${action.label} (${item.label})`
2312
- }));
2313
- }
2314
- if (!action.label) return [];
2315
- return [{
2316
- id: `action-${idx}`,
2317
- label: action.label,
2318
- icon: action.icon,
2319
- onClick: action.onClick,
2320
- disabled: action.disabled,
2321
- href: action.href,
2322
- iconAction: action.iconAction ? {
2323
- icon: action.iconAction.icon,
2324
- "aria-label": action.iconAction["aria-label"],
2325
- onClick: action.iconAction.onClick,
2326
- href: action.iconAction.href,
2327
- openInNewTab: action.iconAction.openInNewTab,
2328
- disabled: action.iconAction.disabled
2329
- } : void 0
2330
- }];
2331
- }
2332
- function renderActionButton(action, opts = {}) {
2333
- if (action.iconAction) {
2334
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2335
- _chunkXXI7BNB6cjs.SplitButton,
2336
- {
2337
- variant: _nullishCoalesce(action.variant, () => ( void 0)),
2338
- href: action.href,
2339
- prefetch: action.prefetch,
2340
- openInNewTab: action.openInNewTab,
2341
- onClick: action.onClick,
2342
- disabled: action.disabled,
2343
- mainDisabled: action.mainDisabled,
2344
- leftIcon: action.icon,
2345
- fullWidth: opts.fullWidth,
2346
- iconAction: action.iconAction,
2347
- children: action.label
2348
- }
2349
- );
2350
- }
2351
- if (action.submenu && action.submenu.length > 0) {
2352
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2353
- ActionsMenuDropdown,
2354
- {
2355
- groups: [{ items: action.submenu }],
2356
- customTrigger: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2357
- _chunkXXI7BNB6cjs.Button,
2358
- {
2359
- variant: "outline",
2360
- disabled: action.disabled,
2361
- loading: action.loading,
2362
- leftIcon: action.icon,
2363
- splitIcon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkZS2SBWBRcjs.Chevron02DownIcon, { className: "h-4 w-4" }),
2364
- className: opts.fullWidth ? "flex-1" : void 0,
2365
- children: action.label
2366
- }
2367
- )
2368
- }
2369
- );
2370
- }
2371
- const isIconOnly = opts.iconOnly || !action.label || action.iconOnlyOnDesktop;
2372
- if (isIconOnly) {
2373
- const iconNode = action.iconOnlyOnDesktop ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "inline-flex [&_svg]:!text-ods-text-primary", children: action.icon }) : action.icon;
2374
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2375
- _chunkXXI7BNB6cjs.Button,
2376
- {
2377
- variant: action.variant,
2378
- size: "icon",
2379
- href: action.href,
2380
- prefetch: action.prefetch,
2381
- openInNewTab: action.openInNewTab,
2382
- onClick: action.onClick,
2383
- disabled: action.disabled,
2384
- loading: action.loading,
2385
- leftIcon: iconNode,
2386
- "aria-label": _nullishCoalesce(action.label, () => ( action.ariaLabel))
2387
- }
2388
- );
2389
- }
2390
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2391
- _chunkXXI7BNB6cjs.Button,
2392
- {
2393
- variant: action.variant,
2394
- href: action.href,
2395
- prefetch: action.prefetch,
2396
- openInNewTab: action.openInNewTab,
2397
- onClick: action.onClick,
2398
- disabled: action.disabled,
2399
- loading: action.loading,
2400
- leftIcon: action.icon,
2401
- className: opts.fullWidth ? "flex-1" : void 0,
2402
- children: action.label
2403
- }
2404
- );
2405
- }
2406
- var ACTIONS_GAP = "gap-[var(--spacing-system-xs)]";
2407
- function PageActions({
2408
- variant = "icon-buttons",
2409
- actions,
2410
- menuActions,
2411
- selector,
2412
- className
2413
- }) {
2414
- if (variant === "icon-buttons") {
2415
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, IconButtonsVariant, { actions, menuActions, selector, className });
2416
- }
2417
- if (variant === "menu-primary") {
2418
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MenuPrimaryVariant, { actions, menuActions: menuActions || [], selector, className });
2419
- }
2420
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PrimaryButtonsVariant, { actions, className });
2421
- }
2422
- function IconButtonsVariant({
2423
- actions,
2424
- menuActions,
2425
- selector,
2426
- className
2427
- }) {
2428
- const desktopActions = actions.filter((a) => !a.showOnlyMobile);
2429
- const hasMenuActions = !!menuActions && menuActions.some((g) => g.items.length > 0);
2430
- const isSingleAction = actions.length === 1 && !_optionalChain([actions, 'access', _44 => _44[0], 'access', _45 => _45.submenu, 'optionalAccess', _46 => _46.length]);
2431
- const singleAction = isSingleAction ? actions[0] : null;
2432
- const useSingleActionMobile = isSingleAction && !hasMenuActions;
2433
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
2434
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "hidden md:flex items-center", ACTIONS_GAP, className), children: [
2435
- selector,
2436
- desktopActions.map((action, idx) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, React.default.Fragment, { children: renderActionButton(action) }, actionKey(action, idx))),
2437
- hasMenuActions && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ActionsMenuDropdown, { groups: menuActions })
2438
- ] }),
2439
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "flex md:hidden", className), children: useSingleActionMobile && singleAction ? renderActionButton(singleAction, { iconOnly: true }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2440
- ActionsMenuDropdown,
2441
- {
2442
- groups: [
2443
- { items: actions.flatMap(actionToMenuItems) },
2444
- ..._nullishCoalesce(menuActions, () => ( []))
2445
- ]
2446
- }
2447
- ) })
2448
- ] });
2449
- }
2450
- function PrimaryButtonsVariant({
2451
- actions,
2452
- className
2453
- }) {
2454
- const sortedActions = [...actions].sort((a, b) => {
2455
- if (a.variant === "accent" && b.variant !== "accent") return 1;
2456
- if (a.variant !== "accent" && b.variant === "accent") return -1;
2457
- return 0;
2458
- });
2459
- const desktopActions = sortedActions.filter((a) => !a.showOnlyMobile);
2460
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
2461
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "hidden md:flex items-center", ACTIONS_GAP, className), children: desktopActions.map((action, idx) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, React.default.Fragment, { children: renderActionButton(action) }, `desktop-${actionKey(action, idx)}`)) }),
2462
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MobileBottomActions, { actions: sortedActions })
2463
- ] });
2464
- }
2465
- function MenuPrimaryVariant({
2466
- actions,
2467
- menuActions,
2468
- selector,
2469
- className
2470
- }) {
2471
- const desktopActions = actions.filter((a) => !a.showOnlyMobile);
2472
- const hasMenuActions = menuActions.some((g) => g.items.length > 0);
2473
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
2474
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "hidden md:flex items-center", ACTIONS_GAP, className), children: [
2475
- selector,
2476
- hasMenuActions && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ActionsMenuDropdown, { groups: menuActions }),
2477
- desktopActions.map((action, idx) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, React.default.Fragment, { children: renderActionButton({ ...action, variant: action.variant || "accent" }) }, `desktop-${actionKey(action, idx)}`))
2478
- ] }),
2479
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "flex md:hidden", className), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2480
- ActionsMenuDropdown,
2481
- {
2482
- groups: [
2483
- { items: actions.flatMap(actionToMenuItems) },
2484
- ...menuActions
2485
- ]
2486
- }
2487
- ) })
2488
- ] });
2489
- }
2490
- function MobileBottomActions({ actions }) {
2491
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0,
2492
- "fixed md:hidden bottom-0 left-0 right-0 z-50",
2493
- "bg-ods-card border-t border-ods-border",
2494
- "flex items-start pt-6 pb-6 px-6",
2495
- ACTIONS_GAP
2496
- ), children: actions.map((action, idx) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, React.default.Fragment, { children: renderActionButton(action, { fullWidth: !!action.label }) }, `mobile-${actionKey(action, idx)}`)) });
2497
- }
2498
- function usePageActionsBottomPadding(variant) {
2499
- return variant === "primary-buttons" || variant === "menu-primary" ? "pb-40 md:pb-0" : "";
2500
- }
2501
-
2502
- // src/components/ui/entity-image.tsx
2503
- _chunkFIG2RKZFcjs.init_cn.call(void 0, );
2504
-
2505
-
2506
- function EntityImage({ src, alt, fallbackText, className }) {
2507
- const [imageFailed, setImageFailed] = React.default.useState(false);
2508
- React.default.useEffect(() => {
2509
- setImageFailed(false);
2510
- }, [src]);
2511
- const showFallback = imageFailed || !src;
2512
- const initials = _chunkJ54Z3OCRcjs.getFirstLastInitials.call(void 0, _nullishCoalesce(fallbackText, () => ( alt)));
2513
- if (showFallback) {
2514
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2515
- "div",
2516
- {
2517
- "aria-label": alt,
2518
- className: _chunkFIG2RKZFcjs.cn.call(void 0,
2519
- "size-[52px] md:size-[60px] shrink-0 rounded-md border border-ods-border bg-ods-bg flex items-center justify-center text-ods-text-secondary text-h4 select-none",
2520
- className
2521
- ),
2522
- children: initials || "?"
2523
- }
2524
- );
2525
- }
2526
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2527
- "img",
2528
- {
2529
- src: _nullishCoalesce(src, () => ( void 0)),
2530
- alt: _nullishCoalesce(alt, () => ( "")),
2531
- onError: () => setImageFailed(true),
2532
- className: _chunkFIG2RKZFcjs.cn.call(void 0,
2533
- "size-[52px] md:size-[60px] shrink-0 rounded-md border border-ods-border object-contain",
2534
- className
2535
- )
2536
- }
2537
- );
2538
- }
2539
-
2540
- // src/components/layout/title-block.tsx
2541
- _chunkFIG2RKZFcjs.init_cn.call(void 0, );
2542
-
2543
- // src/components/layout/back-button.tsx
2544
- _chunkFIG2RKZFcjs.init_cn.call(void 0, );
2545
-
2546
- function BackButton({ label = "Back", className, type = "button", ...props }) {
2547
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2548
- "button",
2549
- {
2550
- type,
2551
- className: _chunkFIG2RKZFcjs.cn.call(void 0,
2552
- "group inline-flex items-center justify-center self-start rounded-md",
2553
- "gap-[var(--spacing-system-xsf)] py-[var(--spacing-system-sf)]",
2554
- "text-ods-text-secondary hover:text-ods-text-primary",
2555
- "transition-colors duration-200",
2556
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ods-focus",
2557
- className
2558
- ),
2559
- ...props,
2560
- children: [
2561
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkZS2SBWBRcjs.Chevron02LeftIcon, { className: "size-6 shrink-0" }),
2562
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-h4", children: label })
2563
- ]
2564
- }
2565
- );
2566
- }
2567
-
2568
- // src/components/layout/title-block.tsx
2569
-
2570
- function TitleBlock({
2571
- title,
2572
- subtitle,
2573
- image,
2574
- backButton,
2575
- actions,
2576
- actionsVariant = "icon-buttons",
2577
- menuActions,
2578
- selector,
2579
- variant = "plain",
2580
- className
2581
- }) {
2582
- const hasActions = actions && actions.length > 0;
2583
- const hasMenuActions = !!menuActions && menuActions.some((g) => g.items.length > 0);
2584
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2585
- "div",
2586
- {
2587
- className: _chunkFIG2RKZFcjs.cn.call(void 0,
2588
- "flex items-end justify-between gap-[var(--spacing-system-m)]",
2589
- "md:flex-col md:items-start md:justify-start lg:flex-row lg:items-end lg:justify-between",
2590
- "pt-[var(--spacing-system-l)]",
2591
- variant === "card" ? _chunkFIG2RKZFcjs.cn.call(void 0,
2592
- "bg-ods-card border-b border-ods-border",
2593
- "px-[var(--spacing-system-l)] pb-[var(--spacing-system-l)]",
2594
- "md:bg-transparent md:border-b-0",
2595
- "md:px-0 md:pb-0",
2596
- "md:mb-[var(--spacing-system-l)]"
2597
- ) : "mb-[var(--spacing-system-l)]",
2598
- className
2599
- ),
2600
- children: [
2601
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-[var(--spacing-system-xs)] flex-1 min-w-0", children: [
2602
- backButton && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2603
- BackButton,
2604
- {
2605
- onClick: backButton.onClick,
2606
- label: backButton.label,
2607
- className: "hidden md:inline-flex"
2608
- }
2609
- ),
2610
- image || subtitle ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-[var(--spacing-system-m)] min-w-0 w-full", children: [
2611
- image && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2612
- EntityImage,
2613
- {
2614
- src: image.src,
2615
- alt: image.alt,
2616
- fallbackText: image.alt || title
2617
- }
2618
- ),
2619
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col justify-center min-w-0 flex-1", children: [
2620
- title && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { className: "text-h2 text-ods-text-primary truncate", title, children: title }),
2621
- subtitle && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-h6 text-ods-text-secondary truncate", title: subtitle, children: subtitle })
2622
- ] })
2623
- ] }) : title && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { className: "text-h2 text-ods-text-primary", children: title })
2624
- ] }),
2625
- (hasActions || hasMenuActions || selector) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex gap-2 items-center shrink-0", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2626
- PageActions,
2627
- {
2628
- variant: actionsVariant,
2629
- actions: _nullishCoalesce(actions, () => ( [])),
2630
- menuActions,
2631
- selector
2632
- }
2633
- ) })
2634
- ]
2635
- }
2636
- );
2637
- }
2638
-
2639
- // src/components/layout/page-layout.tsx
2640
- _chunkFIG2RKZFcjs.init_cn.call(void 0, );
2641
-
2642
- function PageLayout({
2643
- children,
2644
- title,
2645
- subtitle,
2646
- image,
2647
- backButton,
2648
- actions,
2649
- actionsVariant = "icon-buttons",
2650
- menuActions,
2651
- selector,
2652
- headerVariant,
2653
- className,
2654
- contentClassName,
2655
- showHeader = true
2656
- }) {
2657
- const hasActions = actions && actions.length > 0;
2658
- const needsBottomPadding = hasActions && actionsVariant === "primary-buttons";
2659
- const hasHeader = showHeader && (title || subtitle || image || backButton || hasActions || selector);
2660
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "flex flex-col w-full", className), children: [
2661
- hasHeader && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2662
- TitleBlock,
2663
- {
2664
- title,
2665
- subtitle,
2666
- image,
2667
- backButton,
2668
- actions,
2669
- actionsVariant,
2670
- menuActions,
2671
- selector,
2672
- variant: headerVariant
2673
- }
2674
- ),
2675
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "flex flex-col flex-1 gap-[var(--spacing-system-l)]", needsBottomPadding && "pb-28 md:pb-0", contentClassName), children })
2676
- ] });
2677
- }
2678
-
2679
- // src/components/layout/article-detail-layout.tsx
2680
- _chunkFIG2RKZFcjs.init_cn.call(void 0, );
2681
-
2682
- function PageShell({ children, schemas, contentClassName }) {
2683
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "main", { className: "bg-ods-bg min-h-screen", children: [
2684
- schemas,
2685
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "page-shell-content max-w-[1920px] mx-auto", contentClassName), children })
2686
- ] });
2687
- }
2688
- function ArticleDetailLayout({ children, schemas, contentClassName }) {
2689
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "main", { className: "bg-ods-bg min-h-screen", children: [
2690
- schemas,
2691
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "max-w-[1280px] mx-auto px-6 md:px-20 py-6 md:py-10", contentClassName), children })
2692
- ] });
2693
- }
2694
-
2695
- // src/components/ui/error-state.tsx
2696
- _chunkXXI7BNB6cjs.init_button2.call(void 0, );
2697
- _chunkFIG2RKZFcjs.init_cn.call(void 0, );
2698
-
2699
-
2700
- function ErrorState({
2701
- title = "Error",
2702
- message,
2703
- variant = "error",
2704
- showIcon = true,
2705
- showRetry = false,
2706
- showHome = false,
2707
- onRetry,
2708
- onHome,
2709
- className,
2710
- containerClassName
2711
- }) {
2712
- const getVariantStyles = () => {
2713
- switch (variant) {
2714
- case "error":
2715
- return {
2716
- bg: "bg-ods-attention-red-error/20",
2717
- border: "border-ods-attention-red-error",
2718
- text: "text-ods-attention-red-error",
2719
- icon: "text-ods-attention-red-error"
2720
- };
2721
- case "warning":
2722
- return {
2723
- bg: "bg-ods-attention-yellow-warning/20",
2724
- border: "border-ods-attention-yellow-warning",
2725
- text: "text-ods-attention-yellow-warning",
2726
- icon: "text-ods-attention-yellow-warning"
2727
- };
2728
- case "info":
2729
- return {
2730
- bg: "bg-ods-bg-surface",
2731
- border: "border-ods-border",
2732
- text: "text-ods-text-secondary",
2733
- icon: "text-ods-text-secondary"
2734
- };
2735
- }
2736
- };
2737
- const styles = getVariantStyles();
2738
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "p-6", containerClassName), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0,
2739
- "rounded-lg p-4 border",
2740
- styles.bg,
2741
- styles.border,
2742
- className
2743
- ), children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-start gap-3", children: [
2744
- showIcon && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.AlertTriangle, { className: _chunkFIG2RKZFcjs.cn.call(void 0, "h-5 w-5 mt-0.5 flex-shrink-0", styles.icon) }),
2745
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1", children: [
2746
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "font-semibold mb-1", styles.text), children: title }),
2747
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "text-sm", styles.text), children: message }),
2748
- (showRetry || showHome) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex gap-2 mt-3", children: [
2749
- showRetry && onRetry && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2750
- _chunkXXI7BNB6cjs.Button,
2751
- {
2752
- onClick: onRetry,
2753
- variant: "outline",
2754
- size: "small-legacy",
2755
- className: "h-8",
2756
- leftIcon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.RefreshCw, { className: "h-4 w-4" }),
2757
- children: "Try Again"
2758
- }
2759
- ),
2760
- showHome && onHome && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2761
- _chunkXXI7BNB6cjs.Button,
2762
- {
2763
- onClick: onHome,
2764
- variant: "outline",
2765
- size: "small-legacy",
2766
- className: "h-8",
2767
- leftIcon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Home, { className: "h-4 w-4" }),
2768
- children: "Go Home"
2769
- }
2770
- )
2771
- ] })
2772
- ] })
2773
- ] }) }) });
2774
- }
2775
- function PageError({ message, onRetry, onHome }) {
2776
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2777
- ErrorState,
2778
- {
2779
- title: "Page Error",
2780
- message,
2781
- variant: "error",
2782
- showRetry: !!onRetry,
2783
- showHome: !!onHome,
2784
- onRetry,
2785
- onHome
2786
- }
2787
- );
2788
- }
2789
- function LoadError({ message, onRetry }) {
2790
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2791
- ErrorState,
2792
- {
2793
- title: "Loading Error",
2794
- message,
2795
- variant: "error",
2796
- showRetry: !!onRetry,
2797
- onRetry
2798
- }
2799
- );
2800
- }
2801
- function NotFoundError({ message = "The requested item was not found", onHome }) {
2802
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2803
- ErrorState,
2804
- {
2805
- title: "Not Found",
2806
- message,
2807
- variant: "warning",
2808
- showHome: !!onHome,
2809
- onHome
2810
- }
2811
- );
2812
- }
2813
-
2814
- // src/components/features/entity-tag-badges.tsx
2815
- var _link = require('next/link'); var _link2 = _interopRequireDefault(_link);
2816
-
2817
- var TAG_BADGE_CLASS = "bg-ods-card border border-ods-border";
2818
- var BADGE_CLASS = TAG_BADGE_CLASS;
2819
- function EntityTagBadges({ tags, basePath, max, className }) {
2820
- const items = (tags || []).filter((t) => !!t && !!t.name);
2821
- if (items.length === 0) return null;
2822
- const visibleLimit = max == null ? items.length : Math.max(0, max);
2823
- const shown = items.slice(0, visibleLimit);
2824
- const overflow = items.length - shown.length;
2825
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: `flex flex-wrap items-center gap-2 w-full ${className || ""}`, children: [
2826
- shown.map((tag) => {
2827
- const key = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(tag.tag_id, () => ( tag.id)), () => ( tag.slug)), () => ( tag.name));
2828
- const label = (tag.name || "").toUpperCase();
2829
- if (basePath && tag.slug) {
2830
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _link2.default, { href: `${basePath}?tags=${tag.slug}`, className: "inline-flex", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2831
- StatusBadge,
2832
- {
2833
- text: label,
2834
- variant: "card",
2835
- className: `${BADGE_CLASS} cursor-pointer transition-colors hover:border-ods-accent`
2836
- }
2837
- ) }, key);
2838
- }
2839
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StatusBadge, { text: label, variant: "card", className: BADGE_CLASS }, key);
2840
- }),
2841
- overflow > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StatusBadge, { text: `+${overflow}`, variant: "card", className: `${BADGE_CLASS} text-ods-text-secondary` })
2842
- ] });
2843
- }
2844
-
2845
- // src/components/features/mux-origins.ts
2846
- var MUX_STREAM_ORIGIN = "https://stream.mux.com";
2847
- var MUX_IMAGE_ORIGIN = "https://image.mux.com";
2848
-
2849
- // src/components/features/use-video-warmup.ts
2850
-
2851
- var _reactdom = require('react-dom'); var _reactdom2 = _interopRequireDefault(_reactdom);
2852
- function useVideoOriginPreconnect({
2853
- supabaseStorageOrigin
2854
- } = {}) {
2855
- const runtime = _chunkAQOWFSMBcjs.useChatRuntime.call(void 0, );
2856
- const resolvedOrigin = _nullishCoalesce(supabaseStorageOrigin, () => ( _optionalChain([runtime, 'optionalAccess', _47 => _47.endpoints, 'access', _48 => _48.supabaseStorageOrigin])));
2857
- try {
2858
- _reactdom2.default.preconnect(MUX_STREAM_ORIGIN, { crossOrigin: "anonymous" });
2859
- _reactdom2.default.preconnect(MUX_IMAGE_ORIGIN, { crossOrigin: "anonymous" });
2860
- if (resolvedOrigin) {
2861
- _reactdom2.default.preconnect(resolvedOrigin, { crossOrigin: "anonymous" });
2862
- }
2863
- } catch (err) {
2864
- if (process.env.NODE_ENV !== "production") {
2865
- console.warn("[useVideoOriginPreconnect] preconnect failed:", err);
2866
- }
2867
- }
2868
- }
2869
- function useVideoWarmup({
2870
- videoUrl,
2871
- supabaseStorageOrigin,
2872
- nearMargin = "1000px"
2873
- } = {}) {
2874
- const runtime = _chunkAQOWFSMBcjs.useChatRuntime.call(void 0, );
2875
- const resolvedOrigin = _nullishCoalesce(supabaseStorageOrigin, () => ( _optionalChain([runtime, 'optionalAccess', _49 => _49.endpoints, 'access', _50 => _50.supabaseStorageOrigin])));
2876
- useVideoOriginPreconnect({ supabaseStorageOrigin: resolvedOrigin });
2877
- const { ref, isNear } = _chunkTFSYSWPScjs.useNearViewport.call(void 0, nearMargin);
2878
- _react.useEffect.call(void 0, () => {
2879
- if (!isNear || !videoUrl || !resolvedOrigin) return;
2880
- const conn = navigator.connection;
2881
- if (_optionalChain([conn, 'optionalAccess', _51 => _51.saveData]) === true) return;
2882
- let videoOrigin;
2883
- try {
2884
- videoOrigin = new URL(videoUrl, "http://placeholder.local").origin;
2885
- } catch (e6) {
2886
- return;
2887
- }
2888
- if (videoOrigin !== resolvedOrigin) return;
2889
- const link = document.createElement("link");
2890
- link.rel = "preload";
2891
- link.as = "video";
2892
- link.href = videoUrl;
2893
- link.crossOrigin = "anonymous";
2894
- if ("fetchPriority" in link) {
2895
- ;
2896
- link.fetchPriority = "low";
2897
- }
2898
- document.head.appendChild(link);
2899
- return () => {
2900
- link.remove();
2901
- };
2902
- }, [isNear, videoUrl, resolvedOrigin]);
2903
- return { ref, isNear };
2904
- }
2905
-
2906
- // src/components/features/captions-url.ts
2907
- function getCaptionsUrl(entityType, entityId, srtContent) {
2908
- if (!srtContent) return void 0;
2909
- const hash = `${srtContent.length}-${srtContent.slice(0, 8).replace(/\s/g, "")}`;
2910
- return `/api/captions/${entityType}/${entityId}?v=${hash}`;
2911
- }
2912
-
2913
- // src/components/ui/filter-pill-row.tsx
2914
- _chunkXXI7BNB6cjs.init_button2.call(void 0, );
2915
-
2916
-
2917
- function FilterPillRow({
2918
- label,
2919
- selectedValue,
2920
- onValueChange,
2921
- options,
2922
- countLabel,
2923
- children
2924
- }) {
2925
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-wrap items-center gap-3 p-4 bg-ods-card border border-ods-border rounded-lg", children: [
2926
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2", children: [
2927
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Filter, { className: "h-4 w-4 text-ods-accent" }),
2928
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-h5 text-ods-text-secondary", children: label })
2929
- ] }),
2930
- children || options.map((opt) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2931
- _chunkXXI7BNB6cjs.Button,
2932
- {
2933
- type: "button",
2934
- variant: selectedValue === opt.value ? "accent" : "outline",
2935
- size: "small-legacy",
2936
- onClick: () => onValueChange(opt.value),
2937
- className: "text-h3",
2938
- children: opt.label
2939
- },
2940
- opt.value
2941
- )),
2942
- countLabel && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "ml-auto text-[12px] font-['DM_Sans'] text-ods-text-secondary shrink-0", children: countLabel })
2943
- ] });
2944
- }
2945
-
2946
-
2947
-
2948
-
2949
-
2950
-
2951
-
2952
-
2953
-
2954
-
2955
-
2956
-
2957
-
2958
-
2959
-
2960
-
2961
-
2962
-
2963
-
2964
-
2965
-
2966
-
2967
-
2968
-
2969
-
2970
-
2971
-
2972
-
2973
-
2974
-
2975
-
2976
-
2977
-
2978
-
2979
-
2980
-
2981
-
2982
-
2983
-
2984
-
2985
-
2986
-
2987
-
2988
-
2989
-
2990
-
2991
-
2992
-
2993
-
2994
-
2995
-
2996
-
2997
-
2998
-
2999
-
3000
-
3001
-
3002
-
3003
-
3004
-
3005
-
3006
-
3007
-
3008
- exports.Card = Card; exports.CardHeader = CardHeader; exports.CardTitle = CardTitle; exports.CardDescription = CardDescription; exports.CardContent = CardContent; exports.CardFooter = CardFooter; exports.CardHorizontal = CardHorizontal; exports.Tabs = Tabs; exports.TabsList = TabsList; exports.TabsTrigger = TabsTrigger; exports.TabsContent = TabsContent; exports.statusBadgeVariants = statusBadgeVariants; exports.StatusBadge = StatusBadge; exports.SimpleMarkdownRenderer = SimpleMarkdownRenderer; exports.SquareAvatar = SquareAvatar; exports.useControllableState = useControllableState; exports.ActionsMenu = ActionsMenu; exports.ActionsMenuDropdown = ActionsMenuDropdown; exports.computeIsNewTab = computeIsNewTab; exports.newTabAnchorAttrs = newTabAnchorAttrs; exports.buildAnchorProps = buildAnchorProps; exports.EMPTY_AUTHOR_PLACEHOLDER = EMPTY_AUTHOR_PLACEHOLDER; exports.EntityMetadataValueCell = EntityMetadataValueCell; exports.EntityMetadataAuthorCell = EntityMetadataAuthorCell; exports.EntityAuthorCard = EntityAuthorCard; exports.BlogImagePlaceholder = BlogImagePlaceholder; exports.extractYouTubeId = extractYouTubeId; exports.Video = Video; exports.RATIO_GRID_CLASS = RATIO_GRID_CLASS; exports.RATIO_DISPLAY_GRID_CLASS = RATIO_DISPLAY_GRID_CLASS; exports.RatioTabs = RatioTabs; exports.detectAspectRatio = detectAspectRatio; exports.ratioToCategory = ratioToCategory; exports.groupByAspectRatio = groupByAspectRatio; exports.VideoBitesDisplay = VideoBitesDisplay; exports.VideoBiteCard = VideoBiteCard; exports.EntityVideoSection = EntityVideoSection; exports.useEntityCardLink = useEntityCardLink; exports.useEntityCardPlaceholder = useEntityCardPlaceholder; exports.OnboardingGuideCardSkeleton = OnboardingGuideCardSkeleton; exports.OnboardingGuideCard = OnboardingGuideCard; exports.PageActions = PageActions; exports.usePageActionsBottomPadding = usePageActionsBottomPadding; exports.BackButton = BackButton; exports.EntityImage = EntityImage; exports.TitleBlock = TitleBlock; exports.PageLayout = PageLayout; exports.PageShell = PageShell; exports.ArticleDetailLayout = ArticleDetailLayout; exports.ErrorState = ErrorState; exports.PageError = PageError; exports.LoadError = LoadError; exports.NotFoundError = NotFoundError; exports.TAG_BADGE_CLASS = TAG_BADGE_CLASS; exports.EntityTagBadges = EntityTagBadges; exports.MUX_STREAM_ORIGIN = MUX_STREAM_ORIGIN; exports.MUX_IMAGE_ORIGIN = MUX_IMAGE_ORIGIN; exports.useVideoOriginPreconnect = useVideoOriginPreconnect; exports.useVideoWarmup = useVideoWarmup; exports.getCaptionsUrl = getCaptionsUrl; exports.FilterPillRow = FilterPillRow;
3009
- //# sourceMappingURL=chunk-4W7NYJ3B.cjs.map