@8wave/ai-elements 0.119.0-beta.26 → 0.119.0-beta.30

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 (231) hide show
  1. package/dist/_chunks/{Agent-D8YrsP52.js → Agent-Gdgpd3LA.js} +66 -66
  2. package/dist/_chunks/Agent-Gdgpd3LA.js.map +1 -0
  3. package/dist/_chunks/{PkChatbotFilePreview-DAhN8TyL.js → PkChatbotFilePreview-DiuzVVKH.js} +2 -2
  4. package/dist/_chunks/{PkChatbotFilePreview-DAhN8TyL.js.map → PkChatbotFilePreview-DiuzVVKH.js.map} +1 -1
  5. package/dist/_chunks/{PkStreamingMarkdown-Bry3y6Ru.js → PkStreamingMarkdown-DKyHYHUN.js} +890 -853
  6. package/dist/_chunks/{PkStreamingMarkdown-Bry3y6Ru.js.map → PkStreamingMarkdown-DKyHYHUN.js.map} +1 -1
  7. package/dist/_chunks/{PkToolEditSpreadsheet-5vHzEy4P.js → PkToolEditSpreadsheet-CfJ3BWMe.js} +3 -3
  8. package/dist/_chunks/{PkToolEditSpreadsheet-5vHzEy4P.js.map → PkToolEditSpreadsheet-CfJ3BWMe.js.map} +1 -1
  9. package/dist/_chunks/{PkToolRequestGeolocation-Cj8hTfNF.js → PkToolRequestGeolocation-PxhQxMP1.js} +2 -2
  10. package/dist/_chunks/{PkToolRequestGeolocation-Cj8hTfNF.js.map → PkToolRequestGeolocation-PxhQxMP1.js.map} +1 -1
  11. package/dist/_chunks/{PkToolRequestOAuthConnection-BWxR1hV4.js → PkToolRequestOAuthConnection-klmrRZWz.js} +6 -5
  12. package/dist/_chunks/PkToolRequestOAuthConnection-klmrRZWz.js.map +1 -0
  13. package/dist/_chunks/{PkToolShowArtifact-CfJLe8vD.js → PkToolShowArtifact-ChDm6ZEK.js} +3 -3
  14. package/dist/_chunks/PkToolShowArtifact-ChDm6ZEK.js.map +1 -0
  15. package/dist/_chunks/{PkToolShowCalendarEvent-Bp_yv8S7.js → PkToolShowCalendarEvent-CRVtR3oP.js} +5 -4
  16. package/dist/_chunks/PkToolShowCalendarEvent-CRVtR3oP.js.map +1 -0
  17. package/dist/_chunks/{PkToolShowComparison-Bvd4f4tJ.js → PkToolShowComparison-DLC22e1W.js} +4 -3
  18. package/dist/_chunks/PkToolShowComparison-DLC22e1W.js.map +1 -0
  19. package/dist/_chunks/{PkToolShowContactForm--9XOVqNB.js → PkToolShowContactForm-CfCy-b8w.js} +6 -6
  20. package/dist/_chunks/PkToolShowContactForm-CfCy-b8w.js.map +1 -0
  21. package/dist/_chunks/{PkToolShowDiagram-C-pNbC9n.js → PkToolShowDiagram-JpRMa4Jj.js} +11 -10
  22. package/dist/_chunks/PkToolShowDiagram-JpRMa4Jj.js.map +1 -0
  23. package/dist/_chunks/{PkToolShowEmail-BKel_O29.js → PkToolShowEmail-C7mUCqGL.js} +4 -3
  24. package/dist/_chunks/PkToolShowEmail-C7mUCqGL.js.map +1 -0
  25. package/dist/_chunks/{PkToolShowForm-CGAc1O6K.js → PkToolShowForm-DnIwTGl4.js} +6 -5
  26. package/dist/_chunks/PkToolShowForm-DnIwTGl4.js.map +1 -0
  27. package/dist/_chunks/{PkToolShowImageGallery-CIhIrIcY.js → PkToolShowImageGallery-Ab8fJ9jY.js} +4 -4
  28. package/dist/_chunks/{PkToolShowImageGallery-CIhIrIcY.js.map → PkToolShowImageGallery-Ab8fJ9jY.js.map} +1 -1
  29. package/dist/_chunks/{PkToolShowLocation-78C7jFiV.js → PkToolShowLocation-D5d6bbP-.js} +5 -4
  30. package/dist/_chunks/PkToolShowLocation-D5d6bbP-.js.map +1 -0
  31. package/dist/_chunks/{PkToolShowMessage-BScy-w4J.js → PkToolShowMessage-vw4XS4TR.js} +4 -3
  32. package/dist/_chunks/PkToolShowMessage-vw4XS4TR.js.map +1 -0
  33. package/dist/_chunks/{PkToolShowProductList-BjWKnbyD.js → PkToolShowProductList-DztzZVDd.js} +2 -2
  34. package/dist/_chunks/{PkToolShowProductList-BjWKnbyD.js.map → PkToolShowProductList-DztzZVDd.js.map} +1 -1
  35. package/dist/_chunks/{PkToolShowQrCode-B70jPHDw.js → PkToolShowQrCode-BhcAUXSZ.js} +4 -3
  36. package/dist/_chunks/PkToolShowQrCode-BhcAUXSZ.js.map +1 -0
  37. package/dist/_chunks/{PkToolShowSources-BJ-XFrLD.js → PkToolShowSources-Bvg3f3GC.js} +52 -51
  38. package/dist/_chunks/PkToolShowSources-Bvg3f3GC.js.map +1 -0
  39. package/dist/_chunks/{PkToolShowSuggestedReply-0KahUIlw.js → PkToolShowSuggestedReply-BISQY1ce.js} +2 -2
  40. package/dist/_chunks/{PkToolShowSuggestedReply-0KahUIlw.js.map → PkToolShowSuggestedReply-BISQY1ce.js.map} +1 -1
  41. package/dist/_chunks/{PkToolShowVideo-_V_d-PDr.js → PkToolShowVideo-DdoYLl7R.js} +3 -3
  42. package/dist/_chunks/{PkToolShowVideo-_V_d-PDr.js.map → PkToolShowVideo-DdoYLl7R.js.map} +1 -1
  43. package/dist/_chunks/{PkToolShowWeather-DfLsFayn.js → PkToolShowWeather-CnpPZCLm.js} +2 -2
  44. package/dist/_chunks/{PkToolShowWeather-DfLsFayn.js.map → PkToolShowWeather-CnpPZCLm.js.map} +1 -1
  45. package/dist/_chunks/{PkToolShowWebPages-D55VEPjK.js → PkToolShowWebPages-BooCEJrs.js} +3 -3
  46. package/dist/_chunks/{PkToolShowWebPages-D55VEPjK.js.map → PkToolShowWebPages-BooCEJrs.js.map} +1 -1
  47. package/dist/_chunks/VvButtonLocalized-DV-zbH9b.js +21 -0
  48. package/dist/_chunks/VvButtonLocalized-DV-zbH9b.js.map +1 -0
  49. package/dist/_chunks/{chatImagePolicy-DXkhb-N_.js → chatImagePolicy-CfJt8_9Z.js} +3 -3
  50. package/dist/_chunks/{chatImagePolicy-DXkhb-N_.js.map → chatImagePolicy-CfJt8_9Z.js.map} +1 -1
  51. package/dist/_chunks/{index.es-BrsciU25.js → index.es-oI6RqNZW.js} +2 -2
  52. package/dist/_chunks/{index.es-BrsciU25.js.map → index.es-oI6RqNZW.js.map} +1 -1
  53. package/dist/_chunks/{markdown-DpoAzJSk.js → markdown-BbaLt57-.js} +8 -8
  54. package/dist/_chunks/{markdown-DpoAzJSk.js.map → markdown-BbaLt57-.js.map} +1 -1
  55. package/dist/_chunks/{src-Dt4rhhPN.js → src-DL9TKN-Z.js} +2 -2
  56. package/dist/_chunks/src-DL9TKN-Z.js.map +1 -0
  57. package/dist/_chunks/text-BHCGblDQ.js +6 -0
  58. package/dist/_chunks/text-BHCGblDQ.js.map +1 -0
  59. package/dist/_chunks/{useLightbox-pPBe746W.js → useLightbox-1KKLemEE.js} +2 -2
  60. package/dist/_chunks/{useLightbox-pPBe746W.js.map → useLightbox-1KKLemEE.js.map} +1 -1
  61. package/dist/ai-elements.es.js +2792 -2529
  62. package/dist/ai-elements.es.js.map +1 -1
  63. package/dist-vue/PkChatbot.js +1 -1
  64. package/dist-vue/PkChatbotAudioTranscript.js +1 -1
  65. package/dist-vue/PkChatbotAuth.js +1 -1
  66. package/dist-vue/PkChatbotEmptyState.js +1 -1
  67. package/dist-vue/PkChatbotError.js +1 -1
  68. package/dist-vue/PkChatbotFeedbackForm.js +1 -1
  69. package/dist-vue/PkChatbotFilePreview.js +1 -1
  70. package/dist-vue/PkChatbotInput.js +1 -1
  71. package/dist-vue/PkChatbotMessages.js +1 -1
  72. package/dist-vue/PkChatbotStepPayload.js +1 -1
  73. package/dist-vue/PkChatbotStepToolDetail.js +1 -1
  74. package/dist-vue/PkChatbotSteps.js +1 -1
  75. package/dist-vue/PkChatbotViewChat.js +1 -1
  76. package/dist-vue/PkChatbotViewConversations.js +1 -1
  77. package/dist-vue/PkChatbotViewFiles.js +1 -1
  78. package/dist-vue/PkChatbotViewProfile.js +1 -1
  79. package/dist-vue/PkChatbotWakeupBar.js +1 -1
  80. package/dist-vue/_chunks/{Agent-dGF8mkG9.js → Agent-DU1WWaHR.js} +87 -87
  81. package/dist-vue/_chunks/Agent-DU1WWaHR.js.map +1 -0
  82. package/dist-vue/_chunks/{Document-CV-RJu_p.js → Document-Cto-Qws0.js} +2 -2
  83. package/dist-vue/_chunks/{Document-CV-RJu_p.js.map → Document-Cto-Qws0.js.map} +1 -1
  84. package/dist-vue/_chunks/{PkChatbot-536vsOfp.js → PkChatbot-C18mnGJ9.js} +86 -85
  85. package/dist-vue/_chunks/PkChatbot-C18mnGJ9.js.map +1 -0
  86. package/dist-vue/_chunks/{PkChatbotAudioTranscript-BUxBHanA.js → PkChatbotAudioTranscript-0rvrhSRQ.js} +2 -2
  87. package/dist-vue/_chunks/{PkChatbotAudioTranscript-BUxBHanA.js.map → PkChatbotAudioTranscript-0rvrhSRQ.js.map} +1 -1
  88. package/dist-vue/_chunks/{PkChatbotAuth-BMLLTSwK.js → PkChatbotAuth-BVZzjbK9.js} +4 -3
  89. package/dist-vue/_chunks/PkChatbotAuth-BVZzjbK9.js.map +1 -0
  90. package/dist-vue/_chunks/{PkChatbotEmptyState-Toj4CqXV.js → PkChatbotEmptyState-BKiyP0Ga.js} +2 -2
  91. package/dist-vue/_chunks/{PkChatbotEmptyState-Toj4CqXV.js.map → PkChatbotEmptyState-BKiyP0Ga.js.map} +1 -1
  92. package/dist-vue/_chunks/{PkChatbotError-CRGbK09-.js → PkChatbotError-BV5ga7hk.js} +4 -3
  93. package/dist-vue/_chunks/PkChatbotError-BV5ga7hk.js.map +1 -0
  94. package/dist-vue/_chunks/{PkChatbotFeedbackForm-CMFXjoKR.js → PkChatbotFeedbackForm-B5cYsWBr.js} +8 -7
  95. package/dist-vue/_chunks/PkChatbotFeedbackForm-B5cYsWBr.js.map +1 -0
  96. package/dist-vue/_chunks/{PkChatbotFilePreview-DIP8KLkS.js → PkChatbotFilePreview-D5H-RIk2.js} +2 -2
  97. package/dist-vue/_chunks/{PkChatbotFilePreview-DIP8KLkS.js.map → PkChatbotFilePreview-D5H-RIk2.js.map} +1 -1
  98. package/dist-vue/_chunks/{PkChatbotInput-BfZqRpQ2.js → PkChatbotInput-GvgsYsUw.js} +8 -7
  99. package/dist-vue/_chunks/PkChatbotInput-GvgsYsUw.js.map +1 -0
  100. package/dist-vue/_chunks/PkChatbotMessages-CDLsj7qw.js +876 -0
  101. package/dist-vue/_chunks/PkChatbotMessages-CDLsj7qw.js.map +1 -0
  102. package/dist-vue/_chunks/{PkChatbotStepPayload-D0eoPBQ8.js → PkChatbotStepPayload-Dm-HCHcG.js} +2 -2
  103. package/dist-vue/_chunks/{PkChatbotStepPayload-D0eoPBQ8.js.map → PkChatbotStepPayload-Dm-HCHcG.js.map} +1 -1
  104. package/dist-vue/_chunks/{PkChatbotStepToolDetail-CMx4cw1D.js → PkChatbotStepToolDetail-Bpd_cZEO.js} +16 -16
  105. package/dist-vue/_chunks/{PkChatbotStepToolDetail-CMx4cw1D.js.map → PkChatbotStepToolDetail-Bpd_cZEO.js.map} +1 -1
  106. package/dist-vue/_chunks/{PkChatbotSteps-DeZQhGRU.js → PkChatbotSteps-C4qBM3_t.js} +40 -40
  107. package/dist-vue/_chunks/{PkChatbotSteps-DeZQhGRU.js.map → PkChatbotSteps-C4qBM3_t.js.map} +1 -1
  108. package/dist-vue/_chunks/{PkChatbotViewChat-CVT6OUIv.js → PkChatbotViewChat-By2TY72m.js} +13 -13
  109. package/dist-vue/_chunks/{PkChatbotViewChat-CVT6OUIv.js.map → PkChatbotViewChat-By2TY72m.js.map} +1 -1
  110. package/dist-vue/_chunks/PkChatbotViewConversations-CU5NfEO4.js +199 -0
  111. package/dist-vue/_chunks/PkChatbotViewConversations-CU5NfEO4.js.map +1 -0
  112. package/dist-vue/_chunks/{PkChatbotViewFiles-CA20TBFY.js → PkChatbotViewFiles-CD-UZPT5.js} +18 -17
  113. package/dist-vue/_chunks/PkChatbotViewFiles-CD-UZPT5.js.map +1 -0
  114. package/dist-vue/_chunks/{PkChatbotViewProfile-CyzRxE3D.js → PkChatbotViewProfile-DPlb_Wca.js} +11 -10
  115. package/dist-vue/_chunks/PkChatbotViewProfile-DPlb_Wca.js.map +1 -0
  116. package/dist-vue/_chunks/{PkChatbotWakeupBar-jBti21FQ.js → PkChatbotWakeupBar-Cjgarxnw.js} +3 -2
  117. package/dist-vue/_chunks/PkChatbotWakeupBar-Cjgarxnw.js.map +1 -0
  118. package/dist-vue/_chunks/{PkStreamingMarkdown-C55Fi0Pd.js → PkStreamingMarkdown-CsHzdW69.js} +24 -24
  119. package/dist-vue/_chunks/{PkStreamingMarkdown-C55Fi0Pd.js.map → PkStreamingMarkdown-CsHzdW69.js.map} +1 -1
  120. package/dist-vue/_chunks/{PkSvgViewer-Ts3gQ1hB.js → PkSvgViewer-D6DJ2jVO.js} +7 -6
  121. package/dist-vue/_chunks/PkSvgViewer-D6DJ2jVO.js.map +1 -0
  122. package/dist-vue/_chunks/{PkToolEditSpreadsheet-HAskd6d3.js → PkToolEditSpreadsheet-D8Zp9gzW.js} +3 -3
  123. package/dist-vue/_chunks/{PkToolEditSpreadsheet-HAskd6d3.js.map → PkToolEditSpreadsheet-D8Zp9gzW.js.map} +1 -1
  124. package/dist-vue/_chunks/{PkToolRequestGeolocation-BE22qwxB.js → PkToolRequestGeolocation-JZYgc-2X.js} +2 -2
  125. package/dist-vue/_chunks/{PkToolRequestGeolocation-BE22qwxB.js.map → PkToolRequestGeolocation-JZYgc-2X.js.map} +1 -1
  126. package/dist-vue/_chunks/{PkToolRequestOAuthConnection-GfSalEJG.js → PkToolRequestOAuthConnection-DosWR9I4.js} +11 -10
  127. package/dist-vue/_chunks/PkToolRequestOAuthConnection-DosWR9I4.js.map +1 -0
  128. package/dist-vue/_chunks/{PkToolShowArtifact-z1qTnFkA.js → PkToolShowArtifact-BVofKJ7b.js} +5 -5
  129. package/dist-vue/_chunks/PkToolShowArtifact-BVofKJ7b.js.map +1 -0
  130. package/dist-vue/_chunks/{PkToolShowCalendarEvent-Dv_rss26.js → PkToolShowCalendarEvent-u9O_Sl3-.js} +8 -7
  131. package/dist-vue/_chunks/PkToolShowCalendarEvent-u9O_Sl3-.js.map +1 -0
  132. package/dist-vue/_chunks/{PkToolShowComparison-DQs3E6-k.js → PkToolShowComparison-c2e239T4.js} +3 -2
  133. package/dist-vue/_chunks/PkToolShowComparison-c2e239T4.js.map +1 -0
  134. package/dist-vue/_chunks/{PkToolShowContactForm-Y0lrHXhr.js → PkToolShowContactForm-BzdIFTnC.js} +13 -13
  135. package/dist-vue/_chunks/PkToolShowContactForm-BzdIFTnC.js.map +1 -0
  136. package/dist-vue/_chunks/{PkToolShowDiagram-7WxDObZ6.js → PkToolShowDiagram-CaoB4k6y.js} +11 -10
  137. package/dist-vue/_chunks/PkToolShowDiagram-CaoB4k6y.js.map +1 -0
  138. package/dist-vue/_chunks/{PkToolShowEmail-C591LR5N.js → PkToolShowEmail-CUgZN0J5.js} +8 -7
  139. package/dist-vue/_chunks/PkToolShowEmail-CUgZN0J5.js.map +1 -0
  140. package/dist-vue/_chunks/{PkToolShowForm-CZFWZub7.js → PkToolShowForm-vYuaPtu0.js} +14 -13
  141. package/dist-vue/_chunks/PkToolShowForm-vYuaPtu0.js.map +1 -0
  142. package/dist-vue/_chunks/{PkToolShowImageGallery-CkfXP_lD.js → PkToolShowImageGallery-ooygXk7j.js} +4 -4
  143. package/dist-vue/_chunks/{PkToolShowImageGallery-CkfXP_lD.js.map → PkToolShowImageGallery-ooygXk7j.js.map} +1 -1
  144. package/dist-vue/_chunks/{PkToolShowLocation-Dyz6h_0n.js → PkToolShowLocation-DVMpFdRk.js} +14 -13
  145. package/dist-vue/_chunks/PkToolShowLocation-DVMpFdRk.js.map +1 -0
  146. package/dist-vue/_chunks/{PkToolShowMessage-CbXERPHI.js → PkToolShowMessage-ATTN5Hac.js} +8 -7
  147. package/dist-vue/_chunks/PkToolShowMessage-ATTN5Hac.js.map +1 -0
  148. package/dist-vue/_chunks/{PkToolShowProductList-De-PtmD-.js → PkToolShowProductList-D-HJ9a_h.js} +2 -2
  149. package/dist-vue/_chunks/{PkToolShowProductList-De-PtmD-.js.map → PkToolShowProductList-D-HJ9a_h.js.map} +1 -1
  150. package/dist-vue/_chunks/{PkToolShowQrCode-DEAvfLFu.js → PkToolShowQrCode-D_5VUtEB.js} +3 -2
  151. package/dist-vue/_chunks/PkToolShowQrCode-D_5VUtEB.js.map +1 -0
  152. package/dist-vue/_chunks/{PkToolShowSources-CSN7S0zo.js → PkToolShowSources-DJ35l3Z3.js} +58 -57
  153. package/dist-vue/_chunks/PkToolShowSources-DJ35l3Z3.js.map +1 -0
  154. package/dist-vue/_chunks/{PkToolShowSuggestedReply-DjutyiEi.js → PkToolShowSuggestedReply-I6FBos-F.js} +2 -2
  155. package/dist-vue/_chunks/{PkToolShowSuggestedReply-DjutyiEi.js.map → PkToolShowSuggestedReply-I6FBos-F.js.map} +1 -1
  156. package/dist-vue/_chunks/{PkToolShowVideo-B_Q93E2y.js → PkToolShowVideo-xcg1gdIE.js} +3 -3
  157. package/dist-vue/_chunks/{PkToolShowVideo-B_Q93E2y.js.map → PkToolShowVideo-xcg1gdIE.js.map} +1 -1
  158. package/dist-vue/_chunks/{PkToolShowWeather-BOuNrvY2.js → PkToolShowWeather-DJxKxVp_.js} +2 -2
  159. package/dist-vue/_chunks/{PkToolShowWeather-BOuNrvY2.js.map → PkToolShowWeather-DJxKxVp_.js.map} +1 -1
  160. package/dist-vue/_chunks/{PkToolShowWebPages-D3CdjJUc.js → PkToolShowWebPages-BuaRjavD.js} +3 -3
  161. package/dist-vue/_chunks/{PkToolShowWebPages-D3CdjJUc.js.map → PkToolShowWebPages-BuaRjavD.js.map} +1 -1
  162. package/dist-vue/_chunks/VvButtonLocalized-BuzLsXp3.js +20 -0
  163. package/dist-vue/_chunks/VvButtonLocalized-BuzLsXp3.js.map +1 -0
  164. package/dist-vue/_chunks/{createChatbotApiClient-DSLxswr4.js → createChatbotApiClient-G3Tt1I67.js} +18 -18
  165. package/dist-vue/_chunks/{createChatbotApiClient-DSLxswr4.js.map → createChatbotApiClient-G3Tt1I67.js.map} +1 -1
  166. package/dist-vue/_chunks/{mcpOAuthReport-BeZDTl87.js → mcpOAuthReport-3A9v_gW_.js} +2 -2
  167. package/dist-vue/_chunks/{mcpOAuthReport-BeZDTl87.js.map → mcpOAuthReport-3A9v_gW_.js.map} +1 -1
  168. package/dist-vue/_chunks/{src-DCfvejyT.js → src-DpkuiHam.js} +2 -2
  169. package/dist-vue/_chunks/src-DpkuiHam.js.map +1 -0
  170. package/dist-vue/_chunks/{useChatbotStore-rtl-oKqU.js → useChatbotStore-C1sgxgD1.js} +5 -5
  171. package/dist-vue/_chunks/{useChatbotStore-rtl-oKqU.js.map → useChatbotStore-C1sgxgD1.js.map} +1 -1
  172. package/dist-vue/_chunks/{useSafeLocalStorage-OwzVTZud.js → useSafeLocalStorage-DLIc8pkn.js} +2 -2
  173. package/dist-vue/_chunks/{useSafeLocalStorage-OwzVTZud.js.map → useSafeLocalStorage-DLIc8pkn.js.map} +1 -1
  174. package/dist-vue/_chunks/{utils-CwIMEuAv.js → utils-DsnEcdW3.js} +143 -79
  175. package/dist-vue/_chunks/utils-DsnEcdW3.js.map +1 -0
  176. package/dist-vue/api.js +1 -1
  177. package/dist-vue/composables.js +279 -27
  178. package/dist-vue/composables.js.map +1 -1
  179. package/dist-vue/index.js +3909 -3881
  180. package/dist-vue/index.js.map +1 -1
  181. package/dist-vue/locales.js +42 -6
  182. package/dist-vue/packages/components/src/PkEditorMarkdown.d.ts +3 -2
  183. package/dist-vue/packages/components/src/VvButtonLocalized.d.ts +11 -0
  184. package/dist-vue/packages/components/src/chat/index.d.ts +1 -0
  185. package/dist-vue/packages/components/src/chat/utils.d.ts +30 -0
  186. package/dist-vue/packages/components/src/index.d.ts +1 -0
  187. package/package.json +1 -1
  188. package/dist/_chunks/Agent-D8YrsP52.js.map +0 -1
  189. package/dist/_chunks/PkToolRequestOAuthConnection-BWxR1hV4.js.map +0 -1
  190. package/dist/_chunks/PkToolShowArtifact-CfJLe8vD.js.map +0 -1
  191. package/dist/_chunks/PkToolShowCalendarEvent-Bp_yv8S7.js.map +0 -1
  192. package/dist/_chunks/PkToolShowComparison-Bvd4f4tJ.js.map +0 -1
  193. package/dist/_chunks/PkToolShowContactForm--9XOVqNB.js.map +0 -1
  194. package/dist/_chunks/PkToolShowDiagram-C-pNbC9n.js.map +0 -1
  195. package/dist/_chunks/PkToolShowEmail-BKel_O29.js.map +0 -1
  196. package/dist/_chunks/PkToolShowForm-CGAc1O6K.js.map +0 -1
  197. package/dist/_chunks/PkToolShowLocation-78C7jFiV.js.map +0 -1
  198. package/dist/_chunks/PkToolShowMessage-BScy-w4J.js.map +0 -1
  199. package/dist/_chunks/PkToolShowQrCode-B70jPHDw.js.map +0 -1
  200. package/dist/_chunks/PkToolShowSources-BJ-XFrLD.js.map +0 -1
  201. package/dist/_chunks/src-Dt4rhhPN.js.map +0 -1
  202. package/dist/_chunks/text-DbSEK8si.js +0 -6
  203. package/dist/_chunks/text-DbSEK8si.js.map +0 -1
  204. package/dist-vue/_chunks/Agent-dGF8mkG9.js.map +0 -1
  205. package/dist-vue/_chunks/PkChatbot-536vsOfp.js.map +0 -1
  206. package/dist-vue/_chunks/PkChatbotAuth-BMLLTSwK.js.map +0 -1
  207. package/dist-vue/_chunks/PkChatbotError-CRGbK09-.js.map +0 -1
  208. package/dist-vue/_chunks/PkChatbotFeedbackForm-CMFXjoKR.js.map +0 -1
  209. package/dist-vue/_chunks/PkChatbotInput-BfZqRpQ2.js.map +0 -1
  210. package/dist-vue/_chunks/PkChatbotMessages-CnI3e9wF.js +0 -869
  211. package/dist-vue/_chunks/PkChatbotMessages-CnI3e9wF.js.map +0 -1
  212. package/dist-vue/_chunks/PkChatbotViewConversations-DHeFtAfN.js +0 -197
  213. package/dist-vue/_chunks/PkChatbotViewConversations-DHeFtAfN.js.map +0 -1
  214. package/dist-vue/_chunks/PkChatbotViewFiles-CA20TBFY.js.map +0 -1
  215. package/dist-vue/_chunks/PkChatbotViewProfile-CyzRxE3D.js.map +0 -1
  216. package/dist-vue/_chunks/PkChatbotWakeupBar-jBti21FQ.js.map +0 -1
  217. package/dist-vue/_chunks/PkSvgViewer-Ts3gQ1hB.js.map +0 -1
  218. package/dist-vue/_chunks/PkToolRequestOAuthConnection-GfSalEJG.js.map +0 -1
  219. package/dist-vue/_chunks/PkToolShowArtifact-z1qTnFkA.js.map +0 -1
  220. package/dist-vue/_chunks/PkToolShowCalendarEvent-Dv_rss26.js.map +0 -1
  221. package/dist-vue/_chunks/PkToolShowComparison-DQs3E6-k.js.map +0 -1
  222. package/dist-vue/_chunks/PkToolShowContactForm-Y0lrHXhr.js.map +0 -1
  223. package/dist-vue/_chunks/PkToolShowDiagram-7WxDObZ6.js.map +0 -1
  224. package/dist-vue/_chunks/PkToolShowEmail-C591LR5N.js.map +0 -1
  225. package/dist-vue/_chunks/PkToolShowForm-CZFWZub7.js.map +0 -1
  226. package/dist-vue/_chunks/PkToolShowLocation-Dyz6h_0n.js.map +0 -1
  227. package/dist-vue/_chunks/PkToolShowMessage-CbXERPHI.js.map +0 -1
  228. package/dist-vue/_chunks/PkToolShowQrCode-DEAvfLFu.js.map +0 -1
  229. package/dist-vue/_chunks/PkToolShowSources-CSN7S0zo.js.map +0 -1
  230. package/dist-vue/_chunks/src-DCfvejyT.js.map +0 -1
  231. package/dist-vue/_chunks/utils-CwIMEuAv.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"PkChatbotAudioTranscript-BUxBHanA.js","names":["__unplugin_components_0","_openBlock","_createElementBlock","_createElementVNode","_createVNode","_toDisplayString","_unref","_createCommentVNode","_sfc_main","formatClock","total","seconds","hours","minutes","rest","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","PkChatbotAudioTranscript_default","defineComponent","props","__props","$t","useI18n","isOpen","ref","text","computed","duration","missing","_component_VvIcon","VvIcon","openBlock","createElementBlock","createElementVNode","createVNode","toDisplayString","unref","_cache","createCommentVNode"],"sources":["../../../../packages/utils/src/text-metrics.ts","../../../../packages/components/src/chat/PkChatbotAudioTranscript.vue","../../../../packages/components/src/chat/PkChatbotAudioTranscript.vue"],"sourcesContent":["/**\n * Utility functions for calculating text metrics\n * Shared across document converters and scrapers\n */\n\n/**\n * Count words in markdown/plain text\n * Removes markdown syntax and counts actual words\n */\nexport function countWords(text: string): number {\n const plainText = text\n .replace(/[#*_~`[\\]()]/g, '') // Remove markdown characters\n .replace(/\\n+/g, ' ') // Replace newlines with spaces\n .trim()\n\n if (!plainText) {\n return 0\n }\n\n return plainText.split(/\\s+/).filter((word) => word.length > 0).length\n}\n\n/**\n * Count characters (excluding markdown syntax and whitespace)\n */\nexport function countCharacters(text: string): number {\n return text.replace(/[#*_~`[\\]()]/g, '').replace(/\\s/g, '').length\n}\n\n/**\n * Count paragraphs (separated by double newline)\n */\nexport function countParagraphs(text: string): number {\n return text.split(/\\n\\n+/).filter((p) => p.trim().length > 0).length\n}\n\n/**\n * Count lines (non-empty lines)\n */\nexport function countLines(text: string): number {\n return text.split('\\n').filter((line) => line.trim().length > 0).length\n}\n\n/**\n * Estimate reading time in minutes\n * @param wordCount - Number of words\n * @param wordsPerMinute - Average reading speed (default: 200)\n * @returns Estimated reading time in minutes (minimum 1)\n */\nexport function estimateReadingTime(\n wordCount: number,\n wordsPerMinute = 200,\n): number {\n const minutes = Math.ceil(wordCount / wordsPerMinute)\n return Math.max(1, minutes) // Minimum 1 minute\n}\n\n/**\n * A duration as a player shows it: `m:ss`, or `h:mm:ss` from an hour up.\n * @param seconds - The duration, rounded to the second\n */\nexport function formatClock(seconds: number): string {\n const total = Math.max(0, Math.round(seconds))\n const hours = Math.floor(total / 3600)\n const minutes = String(Math.floor((total % 3600) / 60)).padStart(\n hours ? 2 : 1,\n '0',\n )\n const rest = String(total % 60).padStart(2, '0')\n return hours ? `${hours}:${minutes}:${rest}` : `${minutes}:${rest}`\n}\n","<script lang=\"ts\" setup>\n import { computed, ref } from 'vue'\n import { useI18n } from 'vue-i18n'\n import type { ChatAudioTranscript } from 'models'\n import { formatClock } from 'utils'\n\n const props = defineProps<{\n /** Where the recording plays from. */\n url: string\n /** What the turn heard, once it has (spec `audio-file-transcription.md`, D4). */\n transcript?: ChatAudioTranscript\n /** The turn is still transcribing it: the answer waits on it. */\n pending?: boolean\n }>()\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n /** Arrives open: it is what the turn heard, and its height is bounded. */\n const isOpen = ref(true)\n\n const text = computed(() =>\n props.transcript?.status === 'ready'\n ? props.transcript.text?.trim()\n : undefined,\n )\n\n const duration = computed(() =>\n props.transcript?.durationSeconds\n ? formatClock(props.transcript.durationSeconds)\n : undefined,\n )\n\n /** Why there is no transcript to open, when there is none. */\n const missing = computed(() => {\n switch (props.transcript?.status) {\n case 'no-speech':\n return $t('messagePart.audioTranscriptNoSpeech')\n case 'failed':\n return $t('messagePart.audioTranscriptFailed')\n case 'off':\n return $t('messagePart.audioTranscriptOff')\n default:\n return undefined\n }\n })\n</script>\n\n<template>\n <div class=\"pk-chatbot-audio\">\n <audio\n class=\"pk-chatbot-audio__player\"\n :src=\"url\"\n controls\n preload=\"none\" />\n <!-- The same box as the steps of an answer (`PkChatbotSteps`): a\n header row that opens a body of bounded height. -->\n <div\n v-if=\"pending && !transcript\"\n class=\"pk-chatbot-audio__box\"\n role=\"status\">\n <div class=\"pk-chatbot-audio__header\">\n <VvIcon name=\"loading-loop\" class=\"shrink-0\" />\n <span class=\"pk-chatbot-audio__title\">\n {{ $t('messagePart.audioTranscribing') }}\n </span>\n </div>\n </div>\n <div v-else-if=\"text\" class=\"pk-chatbot-audio__box\">\n <button\n type=\"button\"\n class=\"pk-chatbot-audio__header pk-chatbot-audio__header--toggle\"\n :aria-expanded=\"isOpen\"\n @click=\"isOpen = !isOpen\">\n <VvIcon name=\"ri:file-text-line\" class=\"shrink-0\" />\n <span class=\"pk-chatbot-audio__title\">\n {{ $t('messagePart.audioTranscript') }}\n </span>\n <span v-if=\"duration\" class=\"pk-chatbot-audio__meta\">\n {{ duration }}\n </span>\n <VvIcon\n :name=\"\n isOpen ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\n \"\n class=\"pk-chatbot-audio__chevron shrink-0 ml-auto\" />\n </button>\n <div v-if=\"isOpen\" class=\"pk-chatbot-audio__body light-scrollbar\">\n {{ text }}\n </div>\n </div>\n <div v-else-if=\"missing\" class=\"pk-chatbot-audio__box\">\n <div class=\"pk-chatbot-audio__header\">\n <VvIcon name=\"ri:file-text-line\" class=\"shrink-0\" />\n <span>{{ missing }}</span>\n </div>\n </div>\n </div>\n</template>\n\n<style lang=\"scss\">\n // On the side of the message it belongs to, as wide as a transcript reads\n // well.\n .pk-chatbot-audio {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: var(--spacing-8);\n width: 100%;\n max-width: 28rem;\n min-width: 0;\n\n // As wide as the file card above.\n &__player {\n width: 100%;\n max-width: 280px;\n }\n\n // The frame and the rows of `.pk-chatbot-steps`, so a transcript reads\n // as one more thing the turn did.\n &__box {\n width: 100%;\n border: var(--spacing-px) solid var(--color-surface-3);\n border-radius: var(--rounded-lg);\n background-color: var(--color-surface-1);\n font-size: var(--text-12);\n color: var(--color-word-3);\n overflow: hidden;\n }\n\n &__header {\n display: flex;\n align-items: center;\n gap: var(--spacing-8);\n width: 100%;\n min-height: var(--spacing-40);\n padding: var(--spacing-8) var(--spacing-sm);\n text-align: left;\n\n &--toggle {\n cursor: pointer;\n transition: background-color 0.2s ease;\n\n &:hover {\n background-color: var(--color-surface-2);\n }\n }\n }\n\n &__title {\n font-weight: 600;\n color: var(--color-word-2);\n flex-grow: 1;\n }\n\n &__meta {\n color: var(--color-word-4);\n font-variant-numeric: tabular-nums;\n }\n\n &__chevron {\n font-size: var(--text-16);\n }\n\n // The paragraphs and their [hh:mm:ss] stamps are the transcript's\n // own; a long meeting scrolls inside, as a finished reasoning does.\n &__body {\n max-height: var(--spacing-256);\n overflow: auto;\n padding: var(--spacing-8) var(--spacing-sm);\n border-top: var(--spacing-px) solid var(--color-surface-3);\n background-color: var(--color-surface);\n color: var(--color-word-2);\n line-height: 1.6;\n white-space: pre-line;\n overflow-wrap: anywhere;\n }\n }\n</style>\n","<script lang=\"ts\" setup>\n import { computed, ref } from 'vue'\n import { useI18n } from 'vue-i18n'\n import type { ChatAudioTranscript } from 'models'\n import { formatClock } from 'utils'\n\n const props = defineProps<{\n /** Where the recording plays from. */\n url: string\n /** What the turn heard, once it has (spec `audio-file-transcription.md`, D4). */\n transcript?: ChatAudioTranscript\n /** The turn is still transcribing it: the answer waits on it. */\n pending?: boolean\n }>()\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n /** Arrives open: it is what the turn heard, and its height is bounded. */\n const isOpen = ref(true)\n\n const text = computed(() =>\n props.transcript?.status === 'ready'\n ? props.transcript.text?.trim()\n : undefined,\n )\n\n const duration = computed(() =>\n props.transcript?.durationSeconds\n ? formatClock(props.transcript.durationSeconds)\n : undefined,\n )\n\n /** Why there is no transcript to open, when there is none. */\n const missing = computed(() => {\n switch (props.transcript?.status) {\n case 'no-speech':\n return $t('messagePart.audioTranscriptNoSpeech')\n case 'failed':\n return $t('messagePart.audioTranscriptFailed')\n case 'off':\n return $t('messagePart.audioTranscriptOff')\n default:\n return undefined\n }\n })\n</script>\n\n<template>\n <div class=\"pk-chatbot-audio\">\n <audio\n class=\"pk-chatbot-audio__player\"\n :src=\"url\"\n controls\n preload=\"none\" />\n <!-- The same box as the steps of an answer (`PkChatbotSteps`): a\n header row that opens a body of bounded height. -->\n <div\n v-if=\"pending && !transcript\"\n class=\"pk-chatbot-audio__box\"\n role=\"status\">\n <div class=\"pk-chatbot-audio__header\">\n <VvIcon name=\"loading-loop\" class=\"shrink-0\" />\n <span class=\"pk-chatbot-audio__title\">\n {{ $t('messagePart.audioTranscribing') }}\n </span>\n </div>\n </div>\n <div v-else-if=\"text\" class=\"pk-chatbot-audio__box\">\n <button\n type=\"button\"\n class=\"pk-chatbot-audio__header pk-chatbot-audio__header--toggle\"\n :aria-expanded=\"isOpen\"\n @click=\"isOpen = !isOpen\">\n <VvIcon name=\"ri:file-text-line\" class=\"shrink-0\" />\n <span class=\"pk-chatbot-audio__title\">\n {{ $t('messagePart.audioTranscript') }}\n </span>\n <span v-if=\"duration\" class=\"pk-chatbot-audio__meta\">\n {{ duration }}\n </span>\n <VvIcon\n :name=\"\n isOpen ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\n \"\n class=\"pk-chatbot-audio__chevron shrink-0 ml-auto\" />\n </button>\n <div v-if=\"isOpen\" class=\"pk-chatbot-audio__body light-scrollbar\">\n {{ text }}\n </div>\n </div>\n <div v-else-if=\"missing\" class=\"pk-chatbot-audio__box\">\n <div class=\"pk-chatbot-audio__header\">\n <VvIcon name=\"ri:file-text-line\" class=\"shrink-0\" />\n <span>{{ missing }}</span>\n </div>\n </div>\n </div>\n</template>\n\n<style lang=\"scss\">\n // On the side of the message it belongs to, as wide as a transcript reads\n // well.\n .pk-chatbot-audio {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: var(--spacing-8);\n width: 100%;\n max-width: 28rem;\n min-width: 0;\n\n // As wide as the file card above.\n &__player {\n width: 100%;\n max-width: 280px;\n }\n\n // The frame and the rows of `.pk-chatbot-steps`, so a transcript reads\n // as one more thing the turn did.\n &__box {\n width: 100%;\n border: var(--spacing-px) solid var(--color-surface-3);\n border-radius: var(--rounded-lg);\n background-color: var(--color-surface-1);\n font-size: var(--text-12);\n color: var(--color-word-3);\n overflow: hidden;\n }\n\n &__header {\n display: flex;\n align-items: center;\n gap: var(--spacing-8);\n width: 100%;\n min-height: var(--spacing-40);\n padding: var(--spacing-8) var(--spacing-sm);\n text-align: left;\n\n &--toggle {\n cursor: pointer;\n transition: background-color 0.2s ease;\n\n &:hover {\n background-color: var(--color-surface-2);\n }\n }\n }\n\n &__title {\n font-weight: 600;\n color: var(--color-word-2);\n flex-grow: 1;\n }\n\n &__meta {\n color: var(--color-word-4);\n font-variant-numeric: tabular-nums;\n }\n\n &__chevron {\n font-size: var(--text-16);\n }\n\n // The paragraphs and their [hh:mm:ss] stamps are the transcript's\n // own; a long meeting scrolls inside, as a finished reasoning does.\n &__body {\n max-height: var(--spacing-256);\n overflow: auto;\n padding: var(--spacing-8) var(--spacing-sm);\n border-top: var(--spacing-px) solid var(--color-surface-3);\n background-color: var(--color-surface);\n color: var(--color-word-2);\n line-height: 1.6;\n white-space: pre-line;\n overflow-wrap: anywhere;\n }\n }\n</style>\n"],"mappings":";;;;;AA6DA,SAAgBS,EAAY,GAAyB;CACjD,IAAMC,IAAQ,KAAK,IAAI,GAAG,KAAK,MAAMC,CAAO,CAAC,GACvCC,IAAQ,KAAK,MAAMF,IAAQ,IAAI,GAC/BG,IAAU,OAAO,KAAK,MAAOH,IAAQ,OAAQ,EAAE,CAAC,CAAC,CAAC,SACpDE,IAAQ,IAAI,GACZ,GACJ,GACME,IAAO,OAAOJ,IAAQ,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG;CAC/C,OAAOE,IAAQ,GAAGA,EAAM,GAAGC,EAAQ,GAAGC,MAAS,GAAGD,EAAQ,GAAGC;AACjE;;;;;;;;;;;;;;;;;;;;;;;;;;;EChEI,IAAMe,IAAQC,GASR,EAAE,GAAGC,MAAOC,EAAQ,EAAE,UAAU,SAAS,CAAC,GAG1CC,IAASC,EAAI,EAAI,GAEjBC,IAAOC,QACTP,EAAM,YAAY,WAAW,UACvBA,EAAM,WAAW,MAAM,KAAK,IAC5B,KAAA,CACV,GAEMQ,IAAWD,QACbP,EAAM,YAAY,kBACZpB,EAAYoB,EAAM,WAAW,eAAe,IAC5C,KAAA,CACV,GAGMS,IAAUF,QAAe;GAC3B,QAAQP,EAAM,YAAY,QAA1B;IACI,KAAK,aACD,OAAOE,EAAG,qCAAqC;IACnD,KAAK,UACD,OAAOA,EAAG,mCAAmC;IACjD,KAAK,OACD,OAAOA,EAAG,gCAAgC;IAC9C,SACI;GACR;EACJ,CAAC;;;GAID,OAAA9B,EAAA,GAAAC,EAgDM,OAhDNa,GAgDM,CA/CFZ,EAIqB,SAAA;IAHjB,OAAM;IACL,KAAK2B,EAAA;IACN,UAAA;IACA,SAAQ;GAIF,GAAA,MAAA,GAAAd,CAAA,GAAAc,EAAA,WAAO,CAAKA,EAAA,cADtB7B,EAAA,GAAAC,EAUM,OAVNe,GAUM,CANFd,EAKM,OALNe,GAKM,CAJFd,EAA+CmC,GAAA;IAAvC,MAAK;IAAe,OAAM;GAClCpC,CAAAA,GAAAA,EAEO,QAFPgB,GAEOd,EADAC,EAAAyB,CAAA,CAAE,CAAA,+BAAA,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAIDI,EAAA,SAAhBlC,EAAA,GAAAC,EAsBM,OAtBNkB,GAsBM,CArBFjB,EAiBS,UAAA;IAhBL,MAAK;IACL,OAAM;IACL,iBAAe8B,EAAA;IACf,SAAK,AAAAc,EAAA,QAAA,MAAE,EAAA,QAAM,CAAId,EAAA;;IAClB7B,EAAoDmC,GAAA;KAA5C,MAAK;KAAoB,OAAM;;IACvCpC,EAEO,QAFPmB,GAEOjB,EADAC,EAAAyB,CAAA,CAAE,CAAA,6BAAA,CAAA,GAAA,CAAA;IAEGM,EAAA,SAAZpC,EAAA,GAAAC,EAEO,QAFPqB,GAEOlB,EADAgC,EAAA,KAAQ,GAAA,CAAA,KAAAW,EAAA,IAAA,EAAA;IAEf5C,EAIyDmC,GAAA;KAHpD,MAA+BN,EAAA,QAAM,uBAAA;KAGtC,OAAM;;GAEH,GAAA,GAAAZ,CAAA,GAAAY,EAAA,SAAXhC,EAAA,GAAAC,EAEM,OAFNsB,GAEMnB,EADC8B,EAAA,KAAI,GAAA,CAAA,KAAAa,EAAA,IAAA,EAAA,CAAA,CAAA,KAGCV,EAAA,SAAhBrC,EAAA,GAAAC,EAKM,OALNuB,GAKM,CAJFtB,EAGM,OAHNuB,GAGM,CAFFtB,EAAoDmC,GAAA;IAA5C,MAAK;IAAoB,OAAM;GACvCpC,CAAAA,GAAAA,EAA0B,QAAA,MAAAE,EAAjBiC,EAAA,KAAO,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAAU,EAAA,IAAA,EAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"PkChatbotAudioTranscript-0rvrhSRQ.js","names":["__unplugin_components_0","_openBlock","_createElementBlock","_createElementVNode","_createVNode","_toDisplayString","_unref","_createCommentVNode","_sfc_main","formatClock","total","seconds","hours","minutes","rest","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","PkChatbotAudioTranscript_default","defineComponent","props","__props","$t","useI18n","isOpen","ref","text","computed","duration","missing","_component_VvIcon","VvIcon","openBlock","createElementBlock","createElementVNode","createVNode","toDisplayString","unref","_cache","createCommentVNode"],"sources":["../../../../packages/utils/src/text-metrics.ts","../../../../packages/components/src/chat/PkChatbotAudioTranscript.vue","../../../../packages/components/src/chat/PkChatbotAudioTranscript.vue"],"sourcesContent":["/**\n * Utility functions for calculating text metrics\n * Shared across document converters and scrapers\n */\n\n/**\n * Count words in markdown/plain text\n * Removes markdown syntax and counts actual words\n */\nexport function countWords(text: string): number {\n const plainText = text\n .replace(/[#*_~`[\\]()]/g, '') // Remove markdown characters\n .replace(/\\n+/g, ' ') // Replace newlines with spaces\n .trim()\n\n if (!plainText) {\n return 0\n }\n\n return plainText.split(/\\s+/).filter((word) => word.length > 0).length\n}\n\n/**\n * Count characters (excluding markdown syntax and whitespace)\n */\nexport function countCharacters(text: string): number {\n return text.replace(/[#*_~`[\\]()]/g, '').replace(/\\s/g, '').length\n}\n\n/**\n * Count paragraphs (separated by double newline)\n */\nexport function countParagraphs(text: string): number {\n return text.split(/\\n\\n+/).filter((p) => p.trim().length > 0).length\n}\n\n/**\n * Count lines (non-empty lines)\n */\nexport function countLines(text: string): number {\n return text.split('\\n').filter((line) => line.trim().length > 0).length\n}\n\n/**\n * Estimate reading time in minutes\n * @param wordCount - Number of words\n * @param wordsPerMinute - Average reading speed (default: 200)\n * @returns Estimated reading time in minutes (minimum 1)\n */\nexport function estimateReadingTime(\n wordCount: number,\n wordsPerMinute = 200,\n): number {\n const minutes = Math.ceil(wordCount / wordsPerMinute)\n return Math.max(1, minutes) // Minimum 1 minute\n}\n\n/**\n * A duration as a player shows it: `m:ss`, or `h:mm:ss` from an hour up.\n * @param seconds - The duration, rounded to the second\n */\nexport function formatClock(seconds: number): string {\n const total = Math.max(0, Math.round(seconds))\n const hours = Math.floor(total / 3600)\n const minutes = String(Math.floor((total % 3600) / 60)).padStart(\n hours ? 2 : 1,\n '0',\n )\n const rest = String(total % 60).padStart(2, '0')\n return hours ? `${hours}:${minutes}:${rest}` : `${minutes}:${rest}`\n}\n","<script lang=\"ts\" setup>\n import { computed, ref } from 'vue'\n import { useI18n } from 'vue-i18n'\n import type { ChatAudioTranscript } from 'models'\n import { formatClock } from 'utils'\n\n const props = defineProps<{\n /** Where the recording plays from. */\n url: string\n /** What the turn heard, once it has (spec `audio-file-transcription.md`, D4). */\n transcript?: ChatAudioTranscript\n /** The turn is still transcribing it: the answer waits on it. */\n pending?: boolean\n }>()\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n /** Arrives open: it is what the turn heard, and its height is bounded. */\n const isOpen = ref(true)\n\n const text = computed(() =>\n props.transcript?.status === 'ready'\n ? props.transcript.text?.trim()\n : undefined,\n )\n\n const duration = computed(() =>\n props.transcript?.durationSeconds\n ? formatClock(props.transcript.durationSeconds)\n : undefined,\n )\n\n /** Why there is no transcript to open, when there is none. */\n const missing = computed(() => {\n switch (props.transcript?.status) {\n case 'no-speech':\n return $t('messagePart.audioTranscriptNoSpeech')\n case 'failed':\n return $t('messagePart.audioTranscriptFailed')\n case 'off':\n return $t('messagePart.audioTranscriptOff')\n default:\n return undefined\n }\n })\n</script>\n\n<template>\n <div class=\"pk-chatbot-audio\">\n <audio\n class=\"pk-chatbot-audio__player\"\n :src=\"url\"\n controls\n preload=\"none\" />\n <!-- The same box as the steps of an answer (`PkChatbotSteps`): a\n header row that opens a body of bounded height. -->\n <div\n v-if=\"pending && !transcript\"\n class=\"pk-chatbot-audio__box\"\n role=\"status\">\n <div class=\"pk-chatbot-audio__header\">\n <VvIcon name=\"loading-loop\" class=\"shrink-0\" />\n <span class=\"pk-chatbot-audio__title\">\n {{ $t('messagePart.audioTranscribing') }}\n </span>\n </div>\n </div>\n <div v-else-if=\"text\" class=\"pk-chatbot-audio__box\">\n <button\n type=\"button\"\n class=\"pk-chatbot-audio__header pk-chatbot-audio__header--toggle\"\n :aria-expanded=\"isOpen\"\n @click=\"isOpen = !isOpen\">\n <VvIcon name=\"ri:file-text-line\" class=\"shrink-0\" />\n <span class=\"pk-chatbot-audio__title\">\n {{ $t('messagePart.audioTranscript') }}\n </span>\n <span v-if=\"duration\" class=\"pk-chatbot-audio__meta\">\n {{ duration }}\n </span>\n <VvIcon\n :name=\"\n isOpen ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\n \"\n class=\"pk-chatbot-audio__chevron shrink-0 ml-auto\" />\n </button>\n <div v-if=\"isOpen\" class=\"pk-chatbot-audio__body light-scrollbar\">\n {{ text }}\n </div>\n </div>\n <div v-else-if=\"missing\" class=\"pk-chatbot-audio__box\">\n <div class=\"pk-chatbot-audio__header\">\n <VvIcon name=\"ri:file-text-line\" class=\"shrink-0\" />\n <span>{{ missing }}</span>\n </div>\n </div>\n </div>\n</template>\n\n<style lang=\"scss\">\n // On the side of the message it belongs to, as wide as a transcript reads\n // well.\n .pk-chatbot-audio {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: var(--spacing-8);\n width: 100%;\n max-width: 28rem;\n min-width: 0;\n\n // As wide as the file card above.\n &__player {\n width: 100%;\n max-width: 280px;\n }\n\n // The frame and the rows of `.pk-chatbot-steps`, so a transcript reads\n // as one more thing the turn did.\n &__box {\n width: 100%;\n border: var(--spacing-px) solid var(--color-surface-3);\n border-radius: var(--rounded-lg);\n background-color: var(--color-surface-1);\n font-size: var(--text-12);\n color: var(--color-word-3);\n overflow: hidden;\n }\n\n &__header {\n display: flex;\n align-items: center;\n gap: var(--spacing-8);\n width: 100%;\n min-height: var(--spacing-40);\n padding: var(--spacing-8) var(--spacing-sm);\n text-align: left;\n\n &--toggle {\n cursor: pointer;\n transition: background-color 0.2s ease;\n\n &:hover {\n background-color: var(--color-surface-2);\n }\n }\n }\n\n &__title {\n font-weight: 600;\n color: var(--color-word-2);\n flex-grow: 1;\n }\n\n &__meta {\n color: var(--color-word-4);\n font-variant-numeric: tabular-nums;\n }\n\n &__chevron {\n font-size: var(--text-16);\n }\n\n // The paragraphs and their [hh:mm:ss] stamps are the transcript's\n // own; a long meeting scrolls inside, as a finished reasoning does.\n &__body {\n max-height: var(--spacing-256);\n overflow: auto;\n padding: var(--spacing-8) var(--spacing-sm);\n border-top: var(--spacing-px) solid var(--color-surface-3);\n background-color: var(--color-surface);\n color: var(--color-word-2);\n line-height: 1.6;\n white-space: pre-line;\n overflow-wrap: anywhere;\n }\n }\n</style>\n","<script lang=\"ts\" setup>\n import { computed, ref } from 'vue'\n import { useI18n } from 'vue-i18n'\n import type { ChatAudioTranscript } from 'models'\n import { formatClock } from 'utils'\n\n const props = defineProps<{\n /** Where the recording plays from. */\n url: string\n /** What the turn heard, once it has (spec `audio-file-transcription.md`, D4). */\n transcript?: ChatAudioTranscript\n /** The turn is still transcribing it: the answer waits on it. */\n pending?: boolean\n }>()\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n /** Arrives open: it is what the turn heard, and its height is bounded. */\n const isOpen = ref(true)\n\n const text = computed(() =>\n props.transcript?.status === 'ready'\n ? props.transcript.text?.trim()\n : undefined,\n )\n\n const duration = computed(() =>\n props.transcript?.durationSeconds\n ? formatClock(props.transcript.durationSeconds)\n : undefined,\n )\n\n /** Why there is no transcript to open, when there is none. */\n const missing = computed(() => {\n switch (props.transcript?.status) {\n case 'no-speech':\n return $t('messagePart.audioTranscriptNoSpeech')\n case 'failed':\n return $t('messagePart.audioTranscriptFailed')\n case 'off':\n return $t('messagePart.audioTranscriptOff')\n default:\n return undefined\n }\n })\n</script>\n\n<template>\n <div class=\"pk-chatbot-audio\">\n <audio\n class=\"pk-chatbot-audio__player\"\n :src=\"url\"\n controls\n preload=\"none\" />\n <!-- The same box as the steps of an answer (`PkChatbotSteps`): a\n header row that opens a body of bounded height. -->\n <div\n v-if=\"pending && !transcript\"\n class=\"pk-chatbot-audio__box\"\n role=\"status\">\n <div class=\"pk-chatbot-audio__header\">\n <VvIcon name=\"loading-loop\" class=\"shrink-0\" />\n <span class=\"pk-chatbot-audio__title\">\n {{ $t('messagePart.audioTranscribing') }}\n </span>\n </div>\n </div>\n <div v-else-if=\"text\" class=\"pk-chatbot-audio__box\">\n <button\n type=\"button\"\n class=\"pk-chatbot-audio__header pk-chatbot-audio__header--toggle\"\n :aria-expanded=\"isOpen\"\n @click=\"isOpen = !isOpen\">\n <VvIcon name=\"ri:file-text-line\" class=\"shrink-0\" />\n <span class=\"pk-chatbot-audio__title\">\n {{ $t('messagePart.audioTranscript') }}\n </span>\n <span v-if=\"duration\" class=\"pk-chatbot-audio__meta\">\n {{ duration }}\n </span>\n <VvIcon\n :name=\"\n isOpen ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\n \"\n class=\"pk-chatbot-audio__chevron shrink-0 ml-auto\" />\n </button>\n <div v-if=\"isOpen\" class=\"pk-chatbot-audio__body light-scrollbar\">\n {{ text }}\n </div>\n </div>\n <div v-else-if=\"missing\" class=\"pk-chatbot-audio__box\">\n <div class=\"pk-chatbot-audio__header\">\n <VvIcon name=\"ri:file-text-line\" class=\"shrink-0\" />\n <span>{{ missing }}</span>\n </div>\n </div>\n </div>\n</template>\n\n<style lang=\"scss\">\n // On the side of the message it belongs to, as wide as a transcript reads\n // well.\n .pk-chatbot-audio {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: var(--spacing-8);\n width: 100%;\n max-width: 28rem;\n min-width: 0;\n\n // As wide as the file card above.\n &__player {\n width: 100%;\n max-width: 280px;\n }\n\n // The frame and the rows of `.pk-chatbot-steps`, so a transcript reads\n // as one more thing the turn did.\n &__box {\n width: 100%;\n border: var(--spacing-px) solid var(--color-surface-3);\n border-radius: var(--rounded-lg);\n background-color: var(--color-surface-1);\n font-size: var(--text-12);\n color: var(--color-word-3);\n overflow: hidden;\n }\n\n &__header {\n display: flex;\n align-items: center;\n gap: var(--spacing-8);\n width: 100%;\n min-height: var(--spacing-40);\n padding: var(--spacing-8) var(--spacing-sm);\n text-align: left;\n\n &--toggle {\n cursor: pointer;\n transition: background-color 0.2s ease;\n\n &:hover {\n background-color: var(--color-surface-2);\n }\n }\n }\n\n &__title {\n font-weight: 600;\n color: var(--color-word-2);\n flex-grow: 1;\n }\n\n &__meta {\n color: var(--color-word-4);\n font-variant-numeric: tabular-nums;\n }\n\n &__chevron {\n font-size: var(--text-16);\n }\n\n // The paragraphs and their [hh:mm:ss] stamps are the transcript's\n // own; a long meeting scrolls inside, as a finished reasoning does.\n &__body {\n max-height: var(--spacing-256);\n overflow: auto;\n padding: var(--spacing-8) var(--spacing-sm);\n border-top: var(--spacing-px) solid var(--color-surface-3);\n background-color: var(--color-surface);\n color: var(--color-word-2);\n line-height: 1.6;\n white-space: pre-line;\n overflow-wrap: anywhere;\n }\n }\n</style>\n"],"mappings":";;;;;AA6DA,SAAgBS,EAAY,GAAyB;CACjD,IAAMC,IAAQ,KAAK,IAAI,GAAG,KAAK,MAAMC,CAAO,CAAC,GACvCC,IAAQ,KAAK,MAAMF,IAAQ,IAAI,GAC/BG,IAAU,OAAO,KAAK,MAAOH,IAAQ,OAAQ,EAAE,CAAC,CAAC,CAAC,SACpDE,IAAQ,IAAI,GACZ,GACJ,GACME,IAAO,OAAOJ,IAAQ,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG;CAC/C,OAAOE,IAAQ,GAAGA,EAAM,GAAGC,EAAQ,GAAGC,MAAS,GAAGD,EAAQ,GAAGC;AACjE;;;;;;;;;;;;;;;;;;;;;;;;;;;EChEI,IAAMe,IAAQC,GASR,EAAE,GAAGC,MAAOC,EAAQ,EAAE,UAAU,SAAS,CAAC,GAG1CC,IAASC,EAAI,EAAI,GAEjBC,IAAOC,QACTP,EAAM,YAAY,WAAW,UACvBA,EAAM,WAAW,MAAM,KAAK,IAC5B,KAAA,CACV,GAEMQ,IAAWD,QACbP,EAAM,YAAY,kBACZpB,EAAYoB,EAAM,WAAW,eAAe,IAC5C,KAAA,CACV,GAGMS,IAAUF,QAAe;GAC3B,QAAQP,EAAM,YAAY,QAA1B;IACI,KAAK,aACD,OAAOE,EAAG,qCAAqC;IACnD,KAAK,UACD,OAAOA,EAAG,mCAAmC;IACjD,KAAK,OACD,OAAOA,EAAG,gCAAgC;IAC9C,SACI;GACR;EACJ,CAAC;;;GAID,OAAA9B,EAAA,GAAAC,EAgDM,OAhDNa,GAgDM,CA/CFZ,EAIqB,SAAA;IAHjB,OAAM;IACL,KAAK2B,EAAA;IACN,UAAA;IACA,SAAQ;GAIF,GAAA,MAAA,GAAAd,CAAA,GAAAc,EAAA,WAAO,CAAKA,EAAA,cADtB7B,EAAA,GAAAC,EAUM,OAVNe,GAUM,CANFd,EAKM,OALNe,GAKM,CAJFd,EAA+CmC,GAAA;IAAvC,MAAK;IAAe,OAAM;GAClCpC,CAAAA,GAAAA,EAEO,QAFPgB,GAEOd,EADAC,EAAAyB,CAAA,CAAE,CAAA,+BAAA,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAIDI,EAAA,SAAhBlC,EAAA,GAAAC,EAsBM,OAtBNkB,GAsBM,CArBFjB,EAiBS,UAAA;IAhBL,MAAK;IACL,OAAM;IACL,iBAAe8B,EAAA;IACf,SAAK,AAAAc,EAAA,QAAA,MAAE,EAAA,QAAM,CAAId,EAAA;;IAClB7B,EAAoDmC,GAAA;KAA5C,MAAK;KAAoB,OAAM;;IACvCpC,EAEO,QAFPmB,GAEOjB,EADAC,EAAAyB,CAAA,CAAE,CAAA,6BAAA,CAAA,GAAA,CAAA;IAEGM,EAAA,SAAZpC,EAAA,GAAAC,EAEO,QAFPqB,GAEOlB,EADAgC,EAAA,KAAQ,GAAA,CAAA,KAAAW,EAAA,IAAA,EAAA;IAEf5C,EAIyDmC,GAAA;KAHpD,MAA+BN,EAAA,QAAM,uBAAA;KAGtC,OAAM;;GAEH,GAAA,GAAAZ,CAAA,GAAAY,EAAA,SAAXhC,EAAA,GAAAC,EAEM,OAFNsB,GAEMnB,EADC8B,EAAA,KAAI,GAAA,CAAA,KAAAa,EAAA,IAAA,EAAA,CAAA,CAAA,KAGCV,EAAA,SAAhBrC,EAAA,GAAAC,EAKM,OALNuB,GAKM,CAJFtB,EAGM,OAHNuB,GAGM,CAFFtB,EAAoDmC,GAAA;IAA5C,MAAK;IAAoB,OAAM;GACvCpC,CAAAA,GAAAA,EAA0B,QAAA,MAAAE,EAAjBiC,EAAA,KAAO,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAAU,EAAA,IAAA,EAAA,CAAA,CAAA"}
@@ -1,8 +1,9 @@
1
1
  import { S as e, d as t, r as n, s as r, v as i } from "./schemas-Bu1lick6.js";
2
2
  import { n as a, o } from "./Media-C6RS-s98.js";
3
+ import { t as ee } from "./VvButtonLocalized-BuzLsXp3.js";
3
4
  import { t as s } from "./useImageFallback-5vQIO0pC.js";
4
5
  import { t as c } from "./index.es-C1u3kP7i.js";
5
- import { VvAlert as ee, VvButton as te, VvButtonGroup as ne, VvIcon as re } from "@volverjs/ui-vue/components";
6
+ import { VvAlert as te, VvButtonGroup as ne, VvIcon as re } from "@volverjs/ui-vue/components";
6
7
  import { Fragment as l, Transition as ie, computed as u, createBlock as d, createCommentVNode as f, createElementBlock as p, createElementVNode as m, createTextVNode as h, createVNode as g, defineComponent as _, mergeModels as v, openBlock as y, ref as b, resolveDynamicComponent as ae, toDisplayString as x, unref as S, useModel as C, watch as w, withCtx as T } from "vue";
7
8
  import { useI18n as oe } from "vue-i18n";
8
9
  //#region ../../packages/models/src/schema/User.ts
@@ -150,7 +151,7 @@ var se = O.extend({
150
151
  });
151
152
  }
152
153
  return (e, t) => {
153
- let r = re, i = te, a = ee, s = ne;
154
+ let r = re, i = ee, a = te, s = ne;
154
155
  return y(), p("div", ce, [m("div", le, [g(ie, {
155
156
  name: "pk-flip",
156
157
  mode: "out-in",
@@ -418,4 +419,4 @@ var se = O.extend({
418
419
  //#endregion
419
420
  export { H as t };
420
421
 
421
- //# sourceMappingURL=PkChatbotAuth-BMLLTSwK.js.map
422
+ //# sourceMappingURL=PkChatbotAuth-BVZzjbK9.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PkChatbotAuth-BVZzjbK9.js","names":["z.enum","z.string","z.object","z.boolean","z.coerce.date","z.email","_useModel","z.object","z.email","z.boolean","useForm","z.string","__unplugin_components_0","__unplugin_components_1","__unplugin_components_2","__unplugin_components_3","_openBlock","_createElementBlock","_createElementVNode","_createVNode","_Transition","_withCtx","_toDisplayString","_unref","_createCommentVNode","_createBlock","_resolveDynamicComponent","_Fragment","_createTextVNode","_sfc_main","string","email","_enum","boolean","object","MediaSchema","VvButtonLocalized","useImageFallback","Se","RoleSchema","PasswordSchema","date","PasswordChangeSchema","data","SignUpSchema","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","PkChatbotAuth_default","defineComponent","\"errorMessage\"","\"errorMessageModifiers\"","\"success\"","\"successModifiers\"","__emit","$t","useI18n","props","__props","errorMessage","useModel","success","emit","mode","ref","backToSignIn","showSocialButtons","computed","signInSchema","resetSchema","VvSignInForm","VvSignInField","VvSignUpForm","VvSignUpField","clearSignUp","VvResetForm","VvResetField","clearReset","value","successCard","focusSuccessCard","onSignIn","onSignUp","onReset","handleSocial","provider","isTwoFactorStep","twoFactorKind","VvTwoFactorForm","VvTwoFactorField","clearTwoFactor","methods","switchTwoFactorKind","kind","twoFactorDescription","onVerifyTwoFactor","_component_VvIcon","VvIcon","_component_VvButton","_component_VvAlert","VvAlert","_component_VvButtonGroup","VvButtonGroup","openBlock","createElementBlock","createElementVNode","createVNode","Transition","withCtx","toDisplayString","unref","canShowImage","_cache","onImageError","createCommentVNode","createBlock","resolveDynamicComponent","Fragment","createTextVNode"],"sources":["../../../../packages/models/src/schema/User.ts","../../../../packages/components/src/chat/PkChatbotAuth.vue","../../../../packages/components/src/chat/PkChatbotAuth.vue"],"sourcesContent":["import * as z from 'zod'\nimport { MediaSchema } from './Media'\n\nconst RoleSchema = z.enum(['user', 'admin'])\n\n/** Shortest password better-auth accepts, see `packages/auth`. */\nexport const PASSWORD_MIN_LENGTH = 8\n\n/**\n * Longest password better-auth accepts. Since better-auth 1.7.6 a longer one\n * is refused on sign-in too (`PASSWORD_TOO_LONG`), so every form checks it\n * before sending and shows the translated validation error instead.\n */\nexport const PASSWORD_MAX_LENGTH = 64\n\n/** A password as better-auth accepts it, for every form that sends one. */\nexport const PasswordSchema = z\n .string()\n .min(PASSWORD_MIN_LENGTH)\n .max(PASSWORD_MAX_LENGTH)\n\nexport const UserSchema = z.object({\n id: z.string(),\n name: z.string(),\n email: z.string(),\n emailVerified: z.boolean(),\n image: z.string().nullable(),\n media: MediaSchema.optional().nullable(),\n createdAt: z.coerce.date(),\n updatedAt: z.coerce.date(),\n banned: z.boolean().nullable(),\n banReason: z.string().nullable(),\n banExpires: z.coerce.date().nullable(),\n isAnonymous: z.boolean().nullable(),\n role: RoleSchema,\n twoFactorEnabled: z.boolean().optional(),\n})\n\nexport type User = z.infer<typeof UserSchema>\n\n/**\n * Trimmed user shape for org-scoped lookups (avatars, chat logs, member\n * lists). Served by GET /:audience/users/:id, which only resolves users\n * visible to the caller's active organization.\n */\nexport const UserPreviewSchema = z.object({\n id: z.string(),\n name: z.string(),\n email: z.string().nullable(),\n image: z.string().nullable(),\n isAnonymous: z.boolean().nullable(),\n banned: z.boolean().nullable(),\n})\n\nexport type UserPreview = z.infer<typeof UserPreviewSchema>\n\nexport const PasswordChangeSchema = z\n .object({\n password: PasswordSchema,\n passwordConfirmation: PasswordSchema,\n })\n .refine((data) => data.password === data.passwordConfirmation, {\n params: {\n i18n: 'errors.passwordsDoNotMatch',\n },\n path: ['passwordConfirmation'],\n })\n\nexport type PasswordChange = z.infer<typeof PasswordChangeSchema>\n\nexport const PasswordChangeWithCurrentSchema = PasswordChangeSchema.extend({\n currentPassword: PasswordSchema,\n})\n\nexport type PasswordChangeWithCurrent = z.infer<\n typeof PasswordChangeWithCurrentSchema\n>\n\nexport const UserCreateSchema = PasswordChangeSchema.extend({\n name: z.string().min(1),\n email: z.email(),\n media: MediaSchema.optional(),\n role: RoleSchema.optional().default('user'),\n})\n\nexport type UserCreate = z.infer<typeof UserCreateSchema>\n\nexport const UserUpdateSchema = z.object({\n id: z.string(),\n name: z.string(),\n email: z.string(),\n emailVerified: z.boolean().optional(),\n image: z.string().nullish(),\n role: RoleSchema,\n media: MediaSchema.optional().nullable(),\n banned: z.boolean().nullish(),\n banReason: z.string().nullish(),\n banExpires: z.string().nullish(),\n isAnonymous: z.boolean().nullish(),\n})\n\nexport type UserUpdate = z.infer<typeof UserUpdateSchema>\n\nexport const SignUpSchema = PasswordChangeSchema.extend({\n name: z.string().min(1),\n email: z.email(),\n rememberMe: z.boolean().optional(),\n})\n\nexport type SignUp = z.infer<typeof SignUpSchema>\n","<script setup lang=\"ts\">\n import { computed, ref, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useForm } from '@volverjs/form-vue'\n import * as z from 'zod'\n import { PasswordSchema, SignUpSchema } from 'models'\n import type { AgentBranding, AuthMethods } from 'models'\n import { useImageFallback } from 'composables'\n\n const { t: $t } = useI18n({\n useScope: 'global',\n })\n\n const props = withDefaults(\n defineProps<{\n branding?: AgentBranding\n authMethods?: AuthMethods\n loading?: boolean\n /**\n * Set while an email sign-in waits for its second factor: the\n * methods the account has (`totp`, `otp`). The code step replaces\n * the forms until it is answered or cancelled.\n */\n twoFactorMethods?: string[]\n }>(),\n {\n branding: undefined,\n authMethods: undefined,\n loading: false,\n twoFactorMethods: undefined,\n },\n )\n\n // A deleted agent logo would leave a broken glyph above the sign-in form:\n // drop the whole block instead, the agent name below already identifies it.\n const { canShowImage, onImageError } = useImageFallback()\n\n const errorMessage = defineModel<string | undefined>('errorMessage', {\n default: undefined,\n })\n /**\n * Non-error feedback (e.g. \"check your inbox\" after sign-up / reset).\n * When set, a dedicated success screen replaces the form.\n */\n const success = defineModel<{ title: string; message: string } | undefined>(\n 'success',\n { default: undefined },\n )\n\n const emit = defineEmits<{\n (\n e: 'sign-in',\n payload: {\n email: string\n password: string\n rememberMe: boolean\n },\n ): void\n (\n e: 'sign-up',\n payload: { email: string; password: string; name: string },\n ): void\n (e: 'request-reset', payload: { email: string }): void\n (e: 'social', provider: 'google' | 'microsoft'): void\n (\n e: 'verify-two-factor',\n payload: { kind: 'totp' | 'otp' | 'backup'; code: string },\n ): void\n (e: 'send-two-factor-code'): void\n (e: 'cancel-two-factor'): void\n (e: 'update:errorMessage', message?: string): void\n (e: 'update:success', value?: { title: string; message: string }): void\n }>()\n\n type Mode = 'sign-in' | 'sign-up' | 'reset'\n const mode = ref<Mode>('sign-in')\n watch(mode, () => {\n errorMessage.value = undefined\n success.value = undefined\n })\n\n /** Returns to the sign-in form, clearing any success feedback. */\n function backToSignIn() {\n success.value = undefined\n mode.value = 'sign-in'\n }\n\n const showSocialButtons = computed(\n () => props.authMethods?.google || props.authMethods?.microsoft,\n )\n\n const signInSchema = z.object({\n email: z.email(),\n password: PasswordSchema,\n rememberMe: z.boolean().default(false),\n })\n\n const resetSchema = z.object({\n email: z.email(),\n })\n\n const { VvForm: VvSignInForm, VvFormField: VvSignInField } = useForm(\n signInSchema,\n { lazyLoad: true },\n )\n const {\n VvForm: VvSignUpForm,\n VvFormField: VvSignUpField,\n clear: clearSignUp,\n } = useForm(SignUpSchema, { lazyLoad: true })\n const {\n VvForm: VvResetForm,\n VvFormField: VvResetField,\n clear: clearReset,\n } = useForm(resetSchema, { lazyLoad: true })\n\n // Empty the sign-up / reset forms once their submission succeeds so a\n // later \"back to sign in\" doesn't reveal stale input.\n watch(success, (value) => {\n if (value) {\n clearSignUp()\n clearReset()\n }\n })\n\n // Move focus to the success card once the flip animation has finished\n // (the out-in transition mounts it only after the form leaves), so\n // screen-reader/keyboard users are announced the result.\n const successCard = ref<HTMLElement>()\n function focusSuccessCard() {\n if (success.value) {\n successCard.value?.focus()\n }\n }\n\n function onSignIn(data: {\n email: string\n password: string\n rememberMe?: boolean\n }) {\n emit('sign-in', {\n email: data.email,\n password: data.password,\n rememberMe: data.rememberMe ?? false,\n })\n }\n\n function onSignUp(data: { name: string; email: string; password: string }) {\n emit('sign-up', {\n name: data.name.trim(),\n email: data.email,\n password: data.password,\n })\n }\n\n function onReset(data: { email: string }) {\n emit('request-reset', { email: data.email })\n }\n\n function handleSocial(provider: 'google' | 'microsoft') {\n emit('social', provider)\n }\n\n // Two-step verification (docs/specs/released/two-factor-authentication.md)\n type TwoFactorKind = 'totp' | 'otp' | 'backup'\n const isTwoFactorStep = computed(() => !!props.twoFactorMethods?.length)\n const twoFactorKind = ref<TwoFactorKind>('totp')\n const {\n VvForm: VvTwoFactorForm,\n VvFormField: VvTwoFactorField,\n clear: clearTwoFactor,\n } = useForm(z.object({ code: z.string().trim().min(6).max(32) }), {\n lazyLoad: true,\n })\n // A new challenge starts from the factor the account has, and the email\n // one sends its code straight away.\n watch(\n () => props.twoFactorMethods,\n (methods) => {\n if (!methods?.length) {\n return\n }\n twoFactorKind.value = methods.includes('totp') ? 'totp' : 'otp'\n clearTwoFactor()\n if (twoFactorKind.value === 'otp') {\n emit('send-two-factor-code')\n }\n },\n { immediate: true },\n )\n function switchTwoFactorKind(kind: TwoFactorKind) {\n twoFactorKind.value = kind\n errorMessage.value = undefined\n clearTwoFactor()\n }\n const twoFactorDescription = computed(() => {\n if (twoFactorKind.value === 'backup') {\n return $t('twoFactor.challengeBackup')\n }\n return twoFactorKind.value === 'otp'\n ? $t('twoFactor.challengeEmailSent')\n : $t('twoFactor.challengeApp')\n })\n function onVerifyTwoFactor(data: { code: string }) {\n emit('verify-two-factor', {\n kind: twoFactorKind.value,\n code: data.code.trim(),\n })\n }\n</script>\n\n<template>\n <div\n class=\"pk-chatbot-auth flex flex-col items-center justify-center w-full min-h-full p-lg overflow-y-auto\">\n <div class=\"pk-chatbot-auth__flip w-full max-w-384 mx-auto my-auto\">\n <Transition\n name=\"pk-flip\"\n mode=\"out-in\"\n @after-enter=\"focusSuccessCard\">\n <!-- Success screen (sign-up / reset feedback) -->\n <div\n v-if=\"success\"\n ref=\"successCard\"\n key=\"success\"\n tabindex=\"-1\"\n class=\"pk-chatbot-auth__flip-card outline-none flex flex-col text-center leading-normal\">\n <div\n class=\"pk-chatbot-auth__success-icon w-64 h-64 border border-surface-3 rounded-full bg-surface flex items-center justify-center overflow-hidden bg-surface mx-auto mb-md\">\n <VvIcon\n name=\"ri:mail-check-line\"\n aria-hidden=\"true\"\n class=\"text-success w-32 h-32\" />\n </div>\n <h1 class=\"font-bold text-18 mb-xs\">\n {{ success.title }}\n </h1>\n <p class=\"mb-lg text-16 text-word-3\">\n {{ success.message }}\n </p>\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n icon=\"chevron-left\"\n :label=\"$t('action.backToSignIn')\"\n @click=\"backToSignIn\" />\n </div>\n\n <!-- Sign-in / sign-up / reset forms -->\n <div\n v-else\n key=\"form\"\n class=\"pk-chatbot-auth__flip-card flex flex-col\">\n <!-- Form Container -->\n <div class=\"flex flex-col\">\n <!-- Relative Header Logo -->\n <div\n v-if=\"canShowImage(branding?.interface.logo)\"\n class=\"flex justify-center mb-md\">\n <img\n :src=\"branding?.interface.logo\"\n :alt=\"branding?.name\"\n class=\"w-64 h-64 border border-surface-3 rounded-full overflow-hidden bg-surface object-contain\"\n @error=\"\n onImageError(branding?.interface.logo)\n \" />\n </div>\n\n <div class=\"text-center leading-normal mb-lg\">\n <h1\n v-if=\"branding?.name\"\n class=\"font-bold text-20 m-0\">\n {{ branding.name }}\n </h1>\n <component\n :is=\"branding?.name ? 'h2' : 'h1'\"\n class=\"text-word-3 mb-0\">\n <template v-if=\"isTwoFactorStep\">\n {{ $t('twoFactor.challengeTitle') }}\n </template>\n <template v-else-if=\"mode === 'sign-in'\">\n {{ $t('auth.signInTitle') }}\n </template>\n <template v-else-if=\"mode === 'sign-up'\">\n {{ $t('auth.signUpTitle') }}\n </template>\n <template v-else-if=\"mode === 'reset'\">\n {{ $t('auth.resetTitle') }}\n </template>\n </component>\n </div>\n\n <!-- Error message -->\n <VvAlert\n v-if=\"errorMessage\"\n modifiers=\"danger\"\n class=\"mb-md\"\n :content=\"errorMessage\" />\n\n <!-- Two-step verification -->\n <template v-if=\"isTwoFactorStep\">\n <p\n class=\"text-14 text-word-3 text-center leading-normal mb-md\">\n {{ twoFactorDescription }}\n </p>\n <VvTwoFactorForm\n class=\"flex flex-col\"\n :readonly=\"loading\"\n @submit=\"onVerifyTwoFactor\">\n <VvTwoFactorField\n name=\"code\"\n type=\"text\"\n :autocomplete=\"\n twoFactorKind === 'backup'\n ? 'off'\n : 'one-time-code'\n \"\n :label=\"\n twoFactorKind === 'backup'\n ? $t('twoFactor.backupCode')\n : $t('twoFactor.code')\n \"\n floating />\n <VvButton\n type=\"submit\"\n modifiers=\"primary\"\n :loading=\"loading\"\n :disabled=\"loading\"\n :label=\"$t('twoFactor.verify')\" />\n </VvTwoFactorForm>\n <div class=\"flex justify-center mt-md\">\n <VvButton\n v-if=\"twoFactorKind === 'totp'\"\n type=\"button\"\n modifiers=\"link\"\n :label=\"$t('twoFactor.useBackupCode')\"\n @click=\"switchTwoFactorKind('backup')\" />\n <VvButton\n v-else-if=\"twoFactorKind === 'backup'\"\n type=\"button\"\n modifiers=\"link\"\n :label=\"$t('twoFactor.useApp')\"\n @click=\"switchTwoFactorKind('totp')\" />\n <VvButton\n v-else\n type=\"button\"\n modifiers=\"link\"\n :disabled=\"loading\"\n :label=\"$t('twoFactor.sendAgain')\"\n @click=\"emit('send-two-factor-code')\" />\n </div>\n </template>\n\n <!-- Sign In -->\n <VvSignInForm\n v-else-if=\"mode === 'sign-in'\"\n class=\"flex flex-col\"\n :readonly=\"loading\"\n @submit=\"onSignIn\">\n <div class=\"mb-md\">\n <VvSignInField\n name=\"email\"\n type=\"email\"\n autocomplete=\"username\"\n :label=\"$t('label.email')\"\n floating />\n <VvSignInField\n name=\"password\"\n type=\"password\"\n autocomplete=\"current-password\"\n :label=\"$t('label.password')\"\n floating />\n <div class=\"mb-md\">\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n :label=\"$t('action.forgetPassword')\"\n @click=\"mode = 'reset'\" />\n </div>\n <VvSignInField\n name=\"rememberMe\"\n type=\"checkbox\"\n :label=\"$t('label.rememberMe')\"\n switch />\n </div>\n <VvButton\n type=\"submit\"\n modifiers=\"primary\"\n :loading=\"loading\"\n :disabled=\"loading\"\n :label=\"$t('action.signIn')\" />\n </VvSignInForm>\n\n <!-- Sign Up -->\n <VvSignUpForm\n v-else-if=\"mode === 'sign-up'\"\n class=\"flex flex-col\"\n :readonly=\"loading\"\n @submit=\"onSignUp\">\n <div class=\"mb-md\">\n <VvSignUpField\n name=\"name\"\n type=\"text\"\n autocomplete=\"name\"\n :label=\"$t('label.name')\"\n floating />\n <VvSignUpField\n name=\"email\"\n type=\"email\"\n autocomplete=\"username\"\n :label=\"$t('label.email')\"\n floating />\n <VvSignUpField\n name=\"password\"\n type=\"password\"\n autocomplete=\"new-password\"\n :label=\"$t('label.password')\"\n floating />\n <VvSignUpField\n name=\"passwordConfirmation\"\n type=\"password\"\n autocomplete=\"new-password\"\n :label=\"$t('label.confirmPassword')\"\n floating />\n </div>\n <VvButton\n type=\"submit\"\n modifiers=\"primary\"\n :loading=\"loading\"\n :disabled=\"loading\"\n :label=\"$t('action.continue')\" />\n </VvSignUpForm>\n\n <!-- Reset Password -->\n <VvResetForm\n v-else-if=\"mode === 'reset'\"\n class=\"flex flex-col\"\n :readonly=\"loading\"\n @submit=\"onReset\">\n <VvResetField\n name=\"email\"\n type=\"email\"\n autocomplete=\"username\"\n :label=\"$t('label.email')\"\n floating />\n <VvButtonGroup modifiers=\"vertical\">\n <VvButton\n type=\"submit\"\n modifiers=\"primary\"\n :loading=\"loading\"\n :disabled=\"loading\"\n :label=\"$t('action.submit')\" />\n </VvButtonGroup>\n </VvResetForm>\n\n <!-- Social providers (shared by sign-in and sign-up) -->\n <template\n v-if=\"\n !isTwoFactorStep &&\n (mode === 'sign-in' || mode === 'sign-up') &&\n showSocialButtons\n \">\n <div class=\"vv-separator mt-xs py-xs\">\n <span>{{ $t('label.or') }}</span>\n </div>\n <VvButtonGroup\n modifiers=\"vertical\"\n class=\"gap-xs mt-xs\">\n <VvButton\n v-if=\"authMethods?.google\"\n type=\"button\"\n modifiers=\"secondary\"\n icon=\"logos:google-icon\"\n :disabled=\"loading\"\n :label=\"\n $t('action.signInWithSocialProvider', {\n provider: 'Google',\n })\n \"\n @click=\"handleSocial('google')\" />\n <VvButton\n v-if=\"authMethods?.microsoft\"\n type=\"button\"\n modifiers=\"secondary\"\n icon=\"logos:microsoft-icon\"\n :disabled=\"loading\"\n :label=\"\n $t('action.signInWithSocialProvider', {\n provider: 'Microsoft',\n })\n \"\n @click=\"handleSocial('microsoft')\" />\n </VvButtonGroup>\n </template>\n </div>\n\n <!-- Footer below Form -->\n <div class=\"pt-lg text-center text-word-3\">\n <template v-if=\"isTwoFactorStep\">\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n icon=\"chevron-left\"\n :label=\"$t('action.backToSignIn')\"\n @click=\"emit('cancel-two-factor')\" />\n </template>\n <template v-else-if=\"mode === 'sign-in'\">\n {{ $t('auth.noAccount') }}\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n class=\"font-semibold\"\n :label=\"$t('action.signUp')\"\n @click=\"mode = 'sign-up'\" />\n </template>\n <template v-else-if=\"mode === 'sign-up'\">\n {{ $t('auth.haveAccount') }}\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n class=\"font-semibold\"\n :label=\"$t('action.signIn')\"\n @click=\"mode = 'sign-in'\" />\n </template>\n <template v-else>\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n icon=\"chevron-left\"\n :label=\"$t('action.backToSignIn')\"\n @click=\"mode = 'sign-in'\" />\n </template>\n </div>\n </div>\n </Transition>\n </div>\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot-auth {\n // Flip-card reveal between the form and the success screen, mirroring\n // the classic login in apps/frontend.\n &__flip {\n display: grid;\n transform-style: preserve-3d;\n perspective: 1000px;\n }\n\n &__flip-card {\n grid-area: 1 / 1;\n backface-visibility: hidden;\n transform-style: preserve-3d;\n }\n\n // Subtle pop on the success check icon once the card has flipped in.\n &__success-icon {\n animation: pk-chatbot-auth-check-pop 0.4s ease-out 0.3s backwards;\n }\n }\n\n .pk-flip-enter-active {\n animation: pk-chatbot-auth-flip-in 0.6s ease-out;\n }\n\n .pk-flip-leave-active {\n animation: pk-chatbot-auth-flip-out 0.6s ease-in;\n }\n\n @keyframes pk-chatbot-auth-flip-in {\n 0% {\n transform: rotateY(-180deg);\n opacity: 0;\n }\n\n 100% {\n transform: rotateY(0deg);\n opacity: 1;\n }\n }\n\n @keyframes pk-chatbot-auth-flip-out {\n 0% {\n transform: rotateY(0deg);\n opacity: 1;\n }\n\n 100% {\n transform: rotateY(180deg);\n opacity: 0;\n }\n }\n\n @keyframes pk-chatbot-auth-check-pop {\n 0% {\n transform: scale(0);\n opacity: 0;\n }\n\n 60% {\n transform: scale(1.15);\n }\n\n 100% {\n transform: scale(1);\n opacity: 1;\n }\n }\n</style>\n","<script setup lang=\"ts\">\n import { computed, ref, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useForm } from '@volverjs/form-vue'\n import * as z from 'zod'\n import { PasswordSchema, SignUpSchema } from 'models'\n import type { AgentBranding, AuthMethods } from 'models'\n import { useImageFallback } from 'composables'\n\n const { t: $t } = useI18n({\n useScope: 'global',\n })\n\n const props = withDefaults(\n defineProps<{\n branding?: AgentBranding\n authMethods?: AuthMethods\n loading?: boolean\n /**\n * Set while an email sign-in waits for its second factor: the\n * methods the account has (`totp`, `otp`). The code step replaces\n * the forms until it is answered or cancelled.\n */\n twoFactorMethods?: string[]\n }>(),\n {\n branding: undefined,\n authMethods: undefined,\n loading: false,\n twoFactorMethods: undefined,\n },\n )\n\n // A deleted agent logo would leave a broken glyph above the sign-in form:\n // drop the whole block instead, the agent name below already identifies it.\n const { canShowImage, onImageError } = useImageFallback()\n\n const errorMessage = defineModel<string | undefined>('errorMessage', {\n default: undefined,\n })\n /**\n * Non-error feedback (e.g. \"check your inbox\" after sign-up / reset).\n * When set, a dedicated success screen replaces the form.\n */\n const success = defineModel<{ title: string; message: string } | undefined>(\n 'success',\n { default: undefined },\n )\n\n const emit = defineEmits<{\n (\n e: 'sign-in',\n payload: {\n email: string\n password: string\n rememberMe: boolean\n },\n ): void\n (\n e: 'sign-up',\n payload: { email: string; password: string; name: string },\n ): void\n (e: 'request-reset', payload: { email: string }): void\n (e: 'social', provider: 'google' | 'microsoft'): void\n (\n e: 'verify-two-factor',\n payload: { kind: 'totp' | 'otp' | 'backup'; code: string },\n ): void\n (e: 'send-two-factor-code'): void\n (e: 'cancel-two-factor'): void\n (e: 'update:errorMessage', message?: string): void\n (e: 'update:success', value?: { title: string; message: string }): void\n }>()\n\n type Mode = 'sign-in' | 'sign-up' | 'reset'\n const mode = ref<Mode>('sign-in')\n watch(mode, () => {\n errorMessage.value = undefined\n success.value = undefined\n })\n\n /** Returns to the sign-in form, clearing any success feedback. */\n function backToSignIn() {\n success.value = undefined\n mode.value = 'sign-in'\n }\n\n const showSocialButtons = computed(\n () => props.authMethods?.google || props.authMethods?.microsoft,\n )\n\n const signInSchema = z.object({\n email: z.email(),\n password: PasswordSchema,\n rememberMe: z.boolean().default(false),\n })\n\n const resetSchema = z.object({\n email: z.email(),\n })\n\n const { VvForm: VvSignInForm, VvFormField: VvSignInField } = useForm(\n signInSchema,\n { lazyLoad: true },\n )\n const {\n VvForm: VvSignUpForm,\n VvFormField: VvSignUpField,\n clear: clearSignUp,\n } = useForm(SignUpSchema, { lazyLoad: true })\n const {\n VvForm: VvResetForm,\n VvFormField: VvResetField,\n clear: clearReset,\n } = useForm(resetSchema, { lazyLoad: true })\n\n // Empty the sign-up / reset forms once their submission succeeds so a\n // later \"back to sign in\" doesn't reveal stale input.\n watch(success, (value) => {\n if (value) {\n clearSignUp()\n clearReset()\n }\n })\n\n // Move focus to the success card once the flip animation has finished\n // (the out-in transition mounts it only after the form leaves), so\n // screen-reader/keyboard users are announced the result.\n const successCard = ref<HTMLElement>()\n function focusSuccessCard() {\n if (success.value) {\n successCard.value?.focus()\n }\n }\n\n function onSignIn(data: {\n email: string\n password: string\n rememberMe?: boolean\n }) {\n emit('sign-in', {\n email: data.email,\n password: data.password,\n rememberMe: data.rememberMe ?? false,\n })\n }\n\n function onSignUp(data: { name: string; email: string; password: string }) {\n emit('sign-up', {\n name: data.name.trim(),\n email: data.email,\n password: data.password,\n })\n }\n\n function onReset(data: { email: string }) {\n emit('request-reset', { email: data.email })\n }\n\n function handleSocial(provider: 'google' | 'microsoft') {\n emit('social', provider)\n }\n\n // Two-step verification (docs/specs/released/two-factor-authentication.md)\n type TwoFactorKind = 'totp' | 'otp' | 'backup'\n const isTwoFactorStep = computed(() => !!props.twoFactorMethods?.length)\n const twoFactorKind = ref<TwoFactorKind>('totp')\n const {\n VvForm: VvTwoFactorForm,\n VvFormField: VvTwoFactorField,\n clear: clearTwoFactor,\n } = useForm(z.object({ code: z.string().trim().min(6).max(32) }), {\n lazyLoad: true,\n })\n // A new challenge starts from the factor the account has, and the email\n // one sends its code straight away.\n watch(\n () => props.twoFactorMethods,\n (methods) => {\n if (!methods?.length) {\n return\n }\n twoFactorKind.value = methods.includes('totp') ? 'totp' : 'otp'\n clearTwoFactor()\n if (twoFactorKind.value === 'otp') {\n emit('send-two-factor-code')\n }\n },\n { immediate: true },\n )\n function switchTwoFactorKind(kind: TwoFactorKind) {\n twoFactorKind.value = kind\n errorMessage.value = undefined\n clearTwoFactor()\n }\n const twoFactorDescription = computed(() => {\n if (twoFactorKind.value === 'backup') {\n return $t('twoFactor.challengeBackup')\n }\n return twoFactorKind.value === 'otp'\n ? $t('twoFactor.challengeEmailSent')\n : $t('twoFactor.challengeApp')\n })\n function onVerifyTwoFactor(data: { code: string }) {\n emit('verify-two-factor', {\n kind: twoFactorKind.value,\n code: data.code.trim(),\n })\n }\n</script>\n\n<template>\n <div\n class=\"pk-chatbot-auth flex flex-col items-center justify-center w-full min-h-full p-lg overflow-y-auto\">\n <div class=\"pk-chatbot-auth__flip w-full max-w-384 mx-auto my-auto\">\n <Transition\n name=\"pk-flip\"\n mode=\"out-in\"\n @after-enter=\"focusSuccessCard\">\n <!-- Success screen (sign-up / reset feedback) -->\n <div\n v-if=\"success\"\n ref=\"successCard\"\n key=\"success\"\n tabindex=\"-1\"\n class=\"pk-chatbot-auth__flip-card outline-none flex flex-col text-center leading-normal\">\n <div\n class=\"pk-chatbot-auth__success-icon w-64 h-64 border border-surface-3 rounded-full bg-surface flex items-center justify-center overflow-hidden bg-surface mx-auto mb-md\">\n <VvIcon\n name=\"ri:mail-check-line\"\n aria-hidden=\"true\"\n class=\"text-success w-32 h-32\" />\n </div>\n <h1 class=\"font-bold text-18 mb-xs\">\n {{ success.title }}\n </h1>\n <p class=\"mb-lg text-16 text-word-3\">\n {{ success.message }}\n </p>\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n icon=\"chevron-left\"\n :label=\"$t('action.backToSignIn')\"\n @click=\"backToSignIn\" />\n </div>\n\n <!-- Sign-in / sign-up / reset forms -->\n <div\n v-else\n key=\"form\"\n class=\"pk-chatbot-auth__flip-card flex flex-col\">\n <!-- Form Container -->\n <div class=\"flex flex-col\">\n <!-- Relative Header Logo -->\n <div\n v-if=\"canShowImage(branding?.interface.logo)\"\n class=\"flex justify-center mb-md\">\n <img\n :src=\"branding?.interface.logo\"\n :alt=\"branding?.name\"\n class=\"w-64 h-64 border border-surface-3 rounded-full overflow-hidden bg-surface object-contain\"\n @error=\"\n onImageError(branding?.interface.logo)\n \" />\n </div>\n\n <div class=\"text-center leading-normal mb-lg\">\n <h1\n v-if=\"branding?.name\"\n class=\"font-bold text-20 m-0\">\n {{ branding.name }}\n </h1>\n <component\n :is=\"branding?.name ? 'h2' : 'h1'\"\n class=\"text-word-3 mb-0\">\n <template v-if=\"isTwoFactorStep\">\n {{ $t('twoFactor.challengeTitle') }}\n </template>\n <template v-else-if=\"mode === 'sign-in'\">\n {{ $t('auth.signInTitle') }}\n </template>\n <template v-else-if=\"mode === 'sign-up'\">\n {{ $t('auth.signUpTitle') }}\n </template>\n <template v-else-if=\"mode === 'reset'\">\n {{ $t('auth.resetTitle') }}\n </template>\n </component>\n </div>\n\n <!-- Error message -->\n <VvAlert\n v-if=\"errorMessage\"\n modifiers=\"danger\"\n class=\"mb-md\"\n :content=\"errorMessage\" />\n\n <!-- Two-step verification -->\n <template v-if=\"isTwoFactorStep\">\n <p\n class=\"text-14 text-word-3 text-center leading-normal mb-md\">\n {{ twoFactorDescription }}\n </p>\n <VvTwoFactorForm\n class=\"flex flex-col\"\n :readonly=\"loading\"\n @submit=\"onVerifyTwoFactor\">\n <VvTwoFactorField\n name=\"code\"\n type=\"text\"\n :autocomplete=\"\n twoFactorKind === 'backup'\n ? 'off'\n : 'one-time-code'\n \"\n :label=\"\n twoFactorKind === 'backup'\n ? $t('twoFactor.backupCode')\n : $t('twoFactor.code')\n \"\n floating />\n <VvButton\n type=\"submit\"\n modifiers=\"primary\"\n :loading=\"loading\"\n :disabled=\"loading\"\n :label=\"$t('twoFactor.verify')\" />\n </VvTwoFactorForm>\n <div class=\"flex justify-center mt-md\">\n <VvButton\n v-if=\"twoFactorKind === 'totp'\"\n type=\"button\"\n modifiers=\"link\"\n :label=\"$t('twoFactor.useBackupCode')\"\n @click=\"switchTwoFactorKind('backup')\" />\n <VvButton\n v-else-if=\"twoFactorKind === 'backup'\"\n type=\"button\"\n modifiers=\"link\"\n :label=\"$t('twoFactor.useApp')\"\n @click=\"switchTwoFactorKind('totp')\" />\n <VvButton\n v-else\n type=\"button\"\n modifiers=\"link\"\n :disabled=\"loading\"\n :label=\"$t('twoFactor.sendAgain')\"\n @click=\"emit('send-two-factor-code')\" />\n </div>\n </template>\n\n <!-- Sign In -->\n <VvSignInForm\n v-else-if=\"mode === 'sign-in'\"\n class=\"flex flex-col\"\n :readonly=\"loading\"\n @submit=\"onSignIn\">\n <div class=\"mb-md\">\n <VvSignInField\n name=\"email\"\n type=\"email\"\n autocomplete=\"username\"\n :label=\"$t('label.email')\"\n floating />\n <VvSignInField\n name=\"password\"\n type=\"password\"\n autocomplete=\"current-password\"\n :label=\"$t('label.password')\"\n floating />\n <div class=\"mb-md\">\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n :label=\"$t('action.forgetPassword')\"\n @click=\"mode = 'reset'\" />\n </div>\n <VvSignInField\n name=\"rememberMe\"\n type=\"checkbox\"\n :label=\"$t('label.rememberMe')\"\n switch />\n </div>\n <VvButton\n type=\"submit\"\n modifiers=\"primary\"\n :loading=\"loading\"\n :disabled=\"loading\"\n :label=\"$t('action.signIn')\" />\n </VvSignInForm>\n\n <!-- Sign Up -->\n <VvSignUpForm\n v-else-if=\"mode === 'sign-up'\"\n class=\"flex flex-col\"\n :readonly=\"loading\"\n @submit=\"onSignUp\">\n <div class=\"mb-md\">\n <VvSignUpField\n name=\"name\"\n type=\"text\"\n autocomplete=\"name\"\n :label=\"$t('label.name')\"\n floating />\n <VvSignUpField\n name=\"email\"\n type=\"email\"\n autocomplete=\"username\"\n :label=\"$t('label.email')\"\n floating />\n <VvSignUpField\n name=\"password\"\n type=\"password\"\n autocomplete=\"new-password\"\n :label=\"$t('label.password')\"\n floating />\n <VvSignUpField\n name=\"passwordConfirmation\"\n type=\"password\"\n autocomplete=\"new-password\"\n :label=\"$t('label.confirmPassword')\"\n floating />\n </div>\n <VvButton\n type=\"submit\"\n modifiers=\"primary\"\n :loading=\"loading\"\n :disabled=\"loading\"\n :label=\"$t('action.continue')\" />\n </VvSignUpForm>\n\n <!-- Reset Password -->\n <VvResetForm\n v-else-if=\"mode === 'reset'\"\n class=\"flex flex-col\"\n :readonly=\"loading\"\n @submit=\"onReset\">\n <VvResetField\n name=\"email\"\n type=\"email\"\n autocomplete=\"username\"\n :label=\"$t('label.email')\"\n floating />\n <VvButtonGroup modifiers=\"vertical\">\n <VvButton\n type=\"submit\"\n modifiers=\"primary\"\n :loading=\"loading\"\n :disabled=\"loading\"\n :label=\"$t('action.submit')\" />\n </VvButtonGroup>\n </VvResetForm>\n\n <!-- Social providers (shared by sign-in and sign-up) -->\n <template\n v-if=\"\n !isTwoFactorStep &&\n (mode === 'sign-in' || mode === 'sign-up') &&\n showSocialButtons\n \">\n <div class=\"vv-separator mt-xs py-xs\">\n <span>{{ $t('label.or') }}</span>\n </div>\n <VvButtonGroup\n modifiers=\"vertical\"\n class=\"gap-xs mt-xs\">\n <VvButton\n v-if=\"authMethods?.google\"\n type=\"button\"\n modifiers=\"secondary\"\n icon=\"logos:google-icon\"\n :disabled=\"loading\"\n :label=\"\n $t('action.signInWithSocialProvider', {\n provider: 'Google',\n })\n \"\n @click=\"handleSocial('google')\" />\n <VvButton\n v-if=\"authMethods?.microsoft\"\n type=\"button\"\n modifiers=\"secondary\"\n icon=\"logos:microsoft-icon\"\n :disabled=\"loading\"\n :label=\"\n $t('action.signInWithSocialProvider', {\n provider: 'Microsoft',\n })\n \"\n @click=\"handleSocial('microsoft')\" />\n </VvButtonGroup>\n </template>\n </div>\n\n <!-- Footer below Form -->\n <div class=\"pt-lg text-center text-word-3\">\n <template v-if=\"isTwoFactorStep\">\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n icon=\"chevron-left\"\n :label=\"$t('action.backToSignIn')\"\n @click=\"emit('cancel-two-factor')\" />\n </template>\n <template v-else-if=\"mode === 'sign-in'\">\n {{ $t('auth.noAccount') }}\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n class=\"font-semibold\"\n :label=\"$t('action.signUp')\"\n @click=\"mode = 'sign-up'\" />\n </template>\n <template v-else-if=\"mode === 'sign-up'\">\n {{ $t('auth.haveAccount') }}\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n class=\"font-semibold\"\n :label=\"$t('action.signIn')\"\n @click=\"mode = 'sign-in'\" />\n </template>\n <template v-else>\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n icon=\"chevron-left\"\n :label=\"$t('action.backToSignIn')\"\n @click=\"mode = 'sign-in'\" />\n </template>\n </div>\n </div>\n </Transition>\n </div>\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot-auth {\n // Flip-card reveal between the form and the success screen, mirroring\n // the classic login in apps/frontend.\n &__flip {\n display: grid;\n transform-style: preserve-3d;\n perspective: 1000px;\n }\n\n &__flip-card {\n grid-area: 1 / 1;\n backface-visibility: hidden;\n transform-style: preserve-3d;\n }\n\n // Subtle pop on the success check icon once the card has flipped in.\n &__success-icon {\n animation: pk-chatbot-auth-check-pop 0.4s ease-out 0.3s backwards;\n }\n }\n\n .pk-flip-enter-active {\n animation: pk-chatbot-auth-flip-in 0.6s ease-out;\n }\n\n .pk-flip-leave-active {\n animation: pk-chatbot-auth-flip-out 0.6s ease-in;\n }\n\n @keyframes pk-chatbot-auth-flip-in {\n 0% {\n transform: rotateY(-180deg);\n opacity: 0;\n }\n\n 100% {\n transform: rotateY(0deg);\n opacity: 1;\n }\n }\n\n @keyframes pk-chatbot-auth-flip-out {\n 0% {\n transform: rotateY(0deg);\n opacity: 1;\n }\n\n 100% {\n transform: rotateY(180deg);\n opacity: 0;\n }\n }\n\n @keyframes pk-chatbot-auth-check-pop {\n 0% {\n transform: scale(0);\n opacity: 0;\n }\n\n 60% {\n transform: scale(1.15);\n }\n\n 100% {\n transform: scale(1);\n opacity: 1;\n }\n }\n</style>\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { t as e } from "./PkStreamingMarkdown-C55Fi0Pd.js";
1
+ import { t as e } from "./PkStreamingMarkdown-CsHzdW69.js";
2
2
  import { t } from "./PkAvatar-BTqu8tn9.js";
3
3
  import { createBlock as n, createCommentVNode as r, createElementBlock as i, defineComponent as a, openBlock as o } from "vue";
4
4
  //#region ../../packages/components/src/chat/PkChatbotEmptyState.vue?vue&type=script&setup=true&lang.ts
@@ -27,4 +27,4 @@ var s = { class: "pk-chatbot-empty-state" }, c = /* @__PURE__ */ a({
27
27
  //#endregion
28
28
  export { c as t };
29
29
 
30
- //# sourceMappingURL=PkChatbotEmptyState-Toj4CqXV.js.map
30
+ //# sourceMappingURL=PkChatbotEmptyState-BKiyP0Ga.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PkChatbotEmptyState-Toj4CqXV.js","names":["_openBlock","_createElementBlock","_createBlock","PkAvatar","_createCommentVNode","PkStreamingMarkdown","_sfc_main","PkStreamingMarkdown_default","_hoisted_1","PkChatbotEmptyState_default","defineComponent","openBlock","createElementBlock","__props","createBlock","PkAvatar_default","createCommentVNode"],"sources":["../../../../packages/components/src/chat/PkChatbotEmptyState.vue","../../../../packages/components/src/chat/PkChatbotEmptyState.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import PkAvatar from './PkAvatar.vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n defineProps<{\n greeting?: string\n /** Agent avatar shown above the greeting where the input chip is hidden (mobile) */\n logo?: string | null\n name?: string\n }>()\n</script>\n\n<template>\n <div class=\"pk-chatbot-empty-state\">\n <PkAvatar\n v-if=\"logo || name\"\n class=\"pk-chatbot-empty-state__avatar\"\n modifiers=\"surface\"\n :img-src=\"logo\"\n :name=\"name\" />\n <PkStreamingMarkdown\n v-if=\"greeting\"\n :markdown=\"greeting\"\n :animation=\"null\"\n class=\"wysiwyg pk-chatbot-empty-state__greeting\" />\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot-empty-state {\n // Above the fullscreen ambient glow\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--spacing-sm);\n padding: var(--spacing-md);\n text-align: center;\n\n // Let the greeting wrap on a couple of lines (Gemini-like). Keyed on\n // the chat's own width (`--phone`, measured in PkChatbot): a narrow\n // preview frame on a desktop screen wraps like a phone\n .pk-chatbot--phone & {\n padding-inline: var(--spacing-56);\n }\n\n &__avatar {\n width: var(--spacing-64);\n height: var(--spacing-64);\n font-size: var(--text-20);\n border-radius: var(--rounded-full);\n\n // The agent identity lives in the input chip when that is\n // visible: the chip hides itself at `--tight`, so keying the\n // avatar on the absence of that modifier shows exactly one of\n // the two\n .pk-chatbot:not(.pk-chatbot--tight) & {\n display: none;\n }\n }\n\n &__greeting {\n font-size: var(--text-28);\n font-weight: var(--font-light);\n color: var(--color-word-1);\n text-wrap: balance;\n\n // Render the greeting markdown inline as a single heading line\n :first-child {\n margin-top: 0;\n }\n\n :last-child {\n margin-bottom: 0;\n }\n }\n\n // Enters fading in from below, in sync with the glow ignition\n &__avatar,\n &__greeting {\n animation: pk-chatbot-greeting-enter 600ms var(--ease-out) both;\n\n @media (prefers-reduced-motion: reduce) {\n animation: none;\n }\n }\n }\n\n @keyframes pk-chatbot-greeting-enter {\n from {\n opacity: 0;\n transform: translateY(var(--spacing-16));\n }\n }\n</style>\n","<script setup lang=\"ts\">\n import PkAvatar from './PkAvatar.vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n defineProps<{\n greeting?: string\n /** Agent avatar shown above the greeting where the input chip is hidden (mobile) */\n logo?: string | null\n name?: string\n }>()\n</script>\n\n<template>\n <div class=\"pk-chatbot-empty-state\">\n <PkAvatar\n v-if=\"logo || name\"\n class=\"pk-chatbot-empty-state__avatar\"\n modifiers=\"surface\"\n :img-src=\"logo\"\n :name=\"name\" />\n <PkStreamingMarkdown\n v-if=\"greeting\"\n :markdown=\"greeting\"\n :animation=\"null\"\n class=\"wysiwyg pk-chatbot-empty-state__greeting\" />\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot-empty-state {\n // Above the fullscreen ambient glow\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--spacing-sm);\n padding: var(--spacing-md);\n text-align: center;\n\n // Let the greeting wrap on a couple of lines (Gemini-like). Keyed on\n // the chat's own width (`--phone`, measured in PkChatbot): a narrow\n // preview frame on a desktop screen wraps like a phone\n .pk-chatbot--phone & {\n padding-inline: var(--spacing-56);\n }\n\n &__avatar {\n width: var(--spacing-64);\n height: var(--spacing-64);\n font-size: var(--text-20);\n border-radius: var(--rounded-full);\n\n // The agent identity lives in the input chip when that is\n // visible: the chip hides itself at `--tight`, so keying the\n // avatar on the absence of that modifier shows exactly one of\n // the two\n .pk-chatbot:not(.pk-chatbot--tight) & {\n display: none;\n }\n }\n\n &__greeting {\n font-size: var(--text-28);\n font-weight: var(--font-light);\n color: var(--color-word-1);\n text-wrap: balance;\n\n // Render the greeting markdown inline as a single heading line\n :first-child {\n margin-top: 0;\n }\n\n :last-child {\n margin-bottom: 0;\n }\n }\n\n // Enters fading in from below, in sync with the glow ignition\n &__avatar,\n &__greeting {\n animation: pk-chatbot-greeting-enter 600ms var(--ease-out) both;\n\n @media (prefers-reduced-motion: reduce) {\n animation: none;\n }\n }\n }\n\n @keyframes pk-chatbot-greeting-enter {\n from {\n opacity: 0;\n transform: translateY(var(--spacing-16));\n }\n }\n</style>\n"],"mappings":";;;;;;;;;;;;oBAaIA,EAAA,GAAAC,EAYM,OAZNO,GAYM,CAVQK,EAAA,QAAQA,EAAA,QADlBb,EAAA,GAAAE,EAKmBC,GAAA;;GAHf,OAAM;GACN,WAAU;GACT,WAASU,EAAA;GACT,MAAMA,EAAA;EAED,GAAA,MAAA,GAAA,CAAA,WAAA,MAAA,CAAA,KAAAG,EAAA,IAAA,EAAA,GAAAH,EAAA,YADVb,EAAA,GAAAE,EAIuDG,GAAA;;GAFlD,UAAUQ,EAAA;GACV,WAAW;GACZ,OAAM"}
1
+ {"version":3,"file":"PkChatbotEmptyState-BKiyP0Ga.js","names":["_openBlock","_createElementBlock","_createBlock","PkAvatar","_createCommentVNode","PkStreamingMarkdown","_sfc_main","PkStreamingMarkdown_default","_hoisted_1","PkChatbotEmptyState_default","defineComponent","openBlock","createElementBlock","__props","createBlock","PkAvatar_default","createCommentVNode"],"sources":["../../../../packages/components/src/chat/PkChatbotEmptyState.vue","../../../../packages/components/src/chat/PkChatbotEmptyState.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import PkAvatar from './PkAvatar.vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n defineProps<{\n greeting?: string\n /** Agent avatar shown above the greeting where the input chip is hidden (mobile) */\n logo?: string | null\n name?: string\n }>()\n</script>\n\n<template>\n <div class=\"pk-chatbot-empty-state\">\n <PkAvatar\n v-if=\"logo || name\"\n class=\"pk-chatbot-empty-state__avatar\"\n modifiers=\"surface\"\n :img-src=\"logo\"\n :name=\"name\" />\n <PkStreamingMarkdown\n v-if=\"greeting\"\n :markdown=\"greeting\"\n :animation=\"null\"\n class=\"wysiwyg pk-chatbot-empty-state__greeting\" />\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot-empty-state {\n // Above the fullscreen ambient glow\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--spacing-sm);\n padding: var(--spacing-md);\n text-align: center;\n\n // Let the greeting wrap on a couple of lines (Gemini-like). Keyed on\n // the chat's own width (`--phone`, measured in PkChatbot): a narrow\n // preview frame on a desktop screen wraps like a phone\n .pk-chatbot--phone & {\n padding-inline: var(--spacing-56);\n }\n\n &__avatar {\n width: var(--spacing-64);\n height: var(--spacing-64);\n font-size: var(--text-20);\n border-radius: var(--rounded-full);\n\n // The agent identity lives in the input chip when that is\n // visible: the chip hides itself at `--tight`, so keying the\n // avatar on the absence of that modifier shows exactly one of\n // the two\n .pk-chatbot:not(.pk-chatbot--tight) & {\n display: none;\n }\n }\n\n &__greeting {\n font-size: var(--text-28);\n font-weight: var(--font-light);\n color: var(--color-word-1);\n text-wrap: balance;\n\n // Render the greeting markdown inline as a single heading line\n :first-child {\n margin-top: 0;\n }\n\n :last-child {\n margin-bottom: 0;\n }\n }\n\n // Enters fading in from below, in sync with the glow ignition\n &__avatar,\n &__greeting {\n animation: pk-chatbot-greeting-enter 600ms var(--ease-out) both;\n\n @media (prefers-reduced-motion: reduce) {\n animation: none;\n }\n }\n }\n\n @keyframes pk-chatbot-greeting-enter {\n from {\n opacity: 0;\n transform: translateY(var(--spacing-16));\n }\n }\n</style>\n","<script setup lang=\"ts\">\n import PkAvatar from './PkAvatar.vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n defineProps<{\n greeting?: string\n /** Agent avatar shown above the greeting where the input chip is hidden (mobile) */\n logo?: string | null\n name?: string\n }>()\n</script>\n\n<template>\n <div class=\"pk-chatbot-empty-state\">\n <PkAvatar\n v-if=\"logo || name\"\n class=\"pk-chatbot-empty-state__avatar\"\n modifiers=\"surface\"\n :img-src=\"logo\"\n :name=\"name\" />\n <PkStreamingMarkdown\n v-if=\"greeting\"\n :markdown=\"greeting\"\n :animation=\"null\"\n class=\"wysiwyg pk-chatbot-empty-state__greeting\" />\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot-empty-state {\n // Above the fullscreen ambient glow\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--spacing-sm);\n padding: var(--spacing-md);\n text-align: center;\n\n // Let the greeting wrap on a couple of lines (Gemini-like). Keyed on\n // the chat's own width (`--phone`, measured in PkChatbot): a narrow\n // preview frame on a desktop screen wraps like a phone\n .pk-chatbot--phone & {\n padding-inline: var(--spacing-56);\n }\n\n &__avatar {\n width: var(--spacing-64);\n height: var(--spacing-64);\n font-size: var(--text-20);\n border-radius: var(--rounded-full);\n\n // The agent identity lives in the input chip when that is\n // visible: the chip hides itself at `--tight`, so keying the\n // avatar on the absence of that modifier shows exactly one of\n // the two\n .pk-chatbot:not(.pk-chatbot--tight) & {\n display: none;\n }\n }\n\n &__greeting {\n font-size: var(--text-28);\n font-weight: var(--font-light);\n color: var(--color-word-1);\n text-wrap: balance;\n\n // Render the greeting markdown inline as a single heading line\n :first-child {\n margin-top: 0;\n }\n\n :last-child {\n margin-bottom: 0;\n }\n }\n\n // Enters fading in from below, in sync with the glow ignition\n &__avatar,\n &__greeting {\n animation: pk-chatbot-greeting-enter 600ms var(--ease-out) both;\n\n @media (prefers-reduced-motion: reduce) {\n animation: none;\n }\n }\n }\n\n @keyframes pk-chatbot-greeting-enter {\n from {\n opacity: 0;\n transform: translateY(var(--spacing-16));\n }\n }\n</style>\n"],"mappings":";;;;;;;;;;;;oBAaIA,EAAA,GAAAC,EAYM,OAZNO,GAYM,CAVQK,EAAA,QAAQA,EAAA,QADlBb,EAAA,GAAAE,EAKmBC,GAAA;;GAHf,OAAM;GACN,WAAU;GACT,WAASU,EAAA;GACT,MAAMA,EAAA;EAED,GAAA,MAAA,GAAA,CAAA,WAAA,MAAA,CAAA,KAAAG,EAAA,IAAA,EAAA,GAAAH,EAAA,YADVb,EAAA,GAAAE,EAIuDG,GAAA;;GAFlD,UAAUQ,EAAA;GACV,WAAW;GACZ,OAAM"}
@@ -1,5 +1,6 @@
1
1
  import { n as e, r as t } from "./StreamError-D1AtGgS3.js";
2
- import { VvAlert as n, VvButton as r } from "@volverjs/ui-vue/components";
2
+ import { t as n } from "./VvButtonLocalized-BuzLsXp3.js";
3
+ import { VvAlert as r } from "@volverjs/ui-vue/components";
3
4
  import { computed as i, createBlock as a, createCommentVNode as o, createSlots as s, createTextVNode as c, defineComponent as l, onBeforeUnmount as u, openBlock as d, ref as f, toDisplayString as p, toValue as m, unref as h, watch as g, withCtx as _ } from "vue";
4
5
  import { useI18n as v } from "vue-i18n";
5
6
  //#region ../../packages/composable/src/useChatbotError.ts
@@ -51,7 +52,7 @@ var S = /* @__PURE__ */ l({
51
52
  }, { immediate: !0 }), u(() => {
52
53
  L.value && clearTimeout(L.value);
53
54
  }), (e, t) => {
54
- let i = r, l = n;
55
+ let i = n, l = r;
55
56
  return d(), a(l, {
56
57
  modifiers: h(N) ? "warning" : "danger",
57
58
  class: "rounded-lg"
@@ -82,4 +83,4 @@ var S = /* @__PURE__ */ l({
82
83
  //#endregion
83
84
  export { S as t };
84
85
 
85
- //# sourceMappingURL=PkChatbotError-CRGbK09-.js.map
86
+ //# sourceMappingURL=PkChatbotError-BV5ga7hk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PkChatbotError-BV5ga7hk.js","names":["matchesStreamCode","$emit","__unplugin_components_0","__unplugin_components_1","_openBlock","_createBlock","_unref","_createSlots","_withCtx","_createTextVNode","_toDisplayString","_createCommentVNode","_sfc_main","matchesStreamErrorCode","parseStreamError","VvButtonLocalized","matchesCode","error","code","getStreamErrorPayload","useChatbotError","isContextWindowError","computed","toValue","isNotFoundError","isRateLimitError","isOriginNotAllowedError","isCreditExhaustedError","isConversationBlockedError","isBadRequestError","isInternalServerError","isGatewayConfigError","isGatewayDisabledError","isModelUnavailableError","PkChatbotError_default","defineComponent","__emit","props","__props","emit","$t","useI18n","isOutOfUserReach","errorMessage","payload","retryCountdown","ref","retryTimer","watch","isRefreshableError","tick","onBeforeUnmount","_component_VvButton","_component_VvAlert","VvAlert","openBlock","createBlock","unref","createSlots","withCtx","createTextVNode","toDisplayString","_cache","_ctx","createCommentVNode"],"sources":["../../../../packages/composable/src/useChatbotError.ts","../../../../packages/components/src/chat/PkChatbotError.vue","../../../../packages/components/src/chat/PkChatbotError.vue"],"sourcesContent":["import { computed, toValue, type MaybeRefOrGetter } from 'vue'\nimport {\n matchesStreamErrorCode as matchesStreamCode,\n parseStreamError,\n type StreamErrorPayload,\n} from 'models'\n\nexport type { StreamErrorPayload }\n\ntype ErrorCode =\n | 'context_length_exceeded'\n | 'entity-not-found'\n | 'rate-limit-exceeded'\n | 'origin-not-allowed'\n | 'credit-exhausted'\n | 'conversation-blocked'\n | 'bad request'\n | 'internal-server-error'\n | 'gateway-disabled'\n | 'model-unavailable'\n\nfunction matchesCode(error: Error | undefined, code: ErrorCode): boolean {\n return error?.message?.toLowerCase().includes(code) ?? false\n}\n\nexport function getStreamErrorPayload(\n error: Error | undefined,\n): StreamErrorPayload | undefined {\n return parseStreamError(error?.message)?.payload\n}\n\nexport function useChatbotError(error: MaybeRefOrGetter<Error | undefined>) {\n const isContextWindowError = computed(() =>\n matchesCode(toValue(error), 'context_length_exceeded'),\n )\n const isNotFoundError = computed(() =>\n matchesCode(toValue(error), 'entity-not-found'),\n )\n const isRateLimitError = computed(() =>\n matchesCode(toValue(error), 'rate-limit-exceeded'),\n )\n const isOriginNotAllowedError = computed(() =>\n matchesCode(toValue(error), 'origin-not-allowed'),\n )\n const isCreditExhaustedError = computed(() =>\n matchesCode(toValue(error), 'credit-exhausted'),\n )\n const isConversationBlockedError = computed(() =>\n matchesCode(toValue(error), 'conversation-blocked'),\n )\n const isBadRequestError = computed(() =>\n matchesCode(toValue(error), 'bad request'),\n )\n const isInternalServerError = computed(() =>\n matchesCode(toValue(error), 'internal-server-error'),\n )\n const isGatewayConfigError = computed(() =>\n matchesStreamCode(toValue(error)?.message, 'GATEWAY_CONFIG'),\n )\n /**\n * The organization does not use the platform gateway and this agent's\n * model is one of its. A decision, not a hiccup: retrying in ten seconds\n * gets the same answer.\n */\n const isGatewayDisabledError = computed(() =>\n matchesCode(toValue(error), 'gateway-disabled'),\n )\n /**\n * The agent's model is on the organization's endpoint, which is off, gone\n * or no longer serves it. It lasts until somebody changes the endpoint or\n * the agent, so it is not retried either.\n */\n const isModelUnavailableError = computed(() =>\n matchesCode(toValue(error), 'model-unavailable'),\n )\n\n /** Errors that trigger an automatic retry countdown */\n const isRefreshableError = computed(\n () =>\n !isContextWindowError.value &&\n !isNotFoundError.value &&\n !isOriginNotAllowedError.value &&\n !isCreditExhaustedError.value &&\n !isConversationBlockedError.value &&\n !isBadRequestError.value &&\n !isInternalServerError.value &&\n !isGatewayConfigError.value &&\n !isGatewayDisabledError.value &&\n !isModelUnavailableError.value,\n )\n\n return {\n isContextWindowError,\n isNotFoundError,\n isRateLimitError,\n isOriginNotAllowedError,\n isCreditExhaustedError,\n isConversationBlockedError,\n isBadRequestError,\n isInternalServerError,\n isGatewayConfigError,\n isGatewayDisabledError,\n isModelUnavailableError,\n isRefreshableError,\n }\n}\n","<script lang=\"ts\" setup>\n import { computed, onBeforeUnmount, ref, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useChatbotError, getStreamErrorPayload } from 'composables'\n\n const props = defineProps<{\n error?: Error\n }>()\n\n const emit = defineEmits<{\n (e: 'retry'): void\n (e: 'reset'): void\n }>()\n\n const { t: $t } = useI18n({\n useScope: 'global',\n })\n\n const {\n isContextWindowError,\n isNotFoundError,\n isRateLimitError,\n isOriginNotAllowedError,\n isCreditExhaustedError,\n isConversationBlockedError,\n isBadRequestError,\n isInternalServerError,\n isGatewayConfigError,\n isGatewayDisabledError,\n isModelUnavailableError,\n isRefreshableError,\n } = useChatbotError(() => props.error)\n\n /**\n * Nothing the user of the chat can do about: a new conversation meets the\n * same answer, so the alert offers no button, as for exhausted credit.\n */\n const isOutOfUserReach = computed(\n () =>\n isOriginNotAllowedError.value ||\n isCreditExhaustedError.value ||\n isGatewayConfigError.value ||\n isGatewayDisabledError.value ||\n isModelUnavailableError.value,\n )\n\n const errorMessage = computed(() => {\n if (isGatewayConfigError.value) {\n const payload = getStreamErrorPayload(props.error)\n if (payload?.reason === 'disallowPromptTraining') {\n return $t('message.chatErrorGatewayPromptTraining', {\n model: payload.model,\n })\n }\n if (payload?.reason === 'zeroDataRetention') {\n return $t('message.chatErrorGatewayZdr', {\n model: payload.model,\n })\n }\n return $t('message.chatErrorGeneric')\n }\n if (isContextWindowError.value) {\n return $t('message.chatErrorContextWindow')\n }\n if (isNotFoundError.value) {\n return $t('message.chatErrorNotFound')\n }\n if (isRateLimitError.value) {\n return $t('message.chatErrorRateLimit', {\n seconds: retryCountdown.value,\n })\n }\n if (isOriginNotAllowedError.value) {\n return $t('message.chatErrorOriginNotAllowed')\n }\n if (isCreditExhaustedError.value) {\n return $t('message.chatErrorCreditExhausted')\n }\n if (isGatewayDisabledError.value) {\n return $t('message.chatErrorGatewayDisabled')\n }\n if (isModelUnavailableError.value) {\n return $t('message.chatErrorModelUnavailable')\n }\n if (isConversationBlockedError.value) {\n return $t('message.chatErrorConversationBlocked')\n }\n if (isBadRequestError.value) {\n return $t('message.chatErrorBadRequest')\n }\n if (isInternalServerError.value) {\n return $t('message.chatErrorInternalServer')\n }\n return $t('message.chatErrorGeneric', { seconds: retryCountdown.value })\n })\n\n const retryCountdown = ref<number>(0)\n const retryTimer = ref<ReturnType<typeof setTimeout>>()\n\n watch(\n () => props.error,\n (error) => {\n if (retryTimer.value) {\n clearTimeout(retryTimer.value)\n }\n\n if (error && isRefreshableError.value) {\n retryCountdown.value = 10\n const tick = () => {\n retryCountdown.value--\n if (retryCountdown.value <= 0) {\n emit('retry')\n return\n }\n retryTimer.value = setTimeout(tick, 1000)\n }\n retryTimer.value = setTimeout(tick, 1000)\n } else {\n retryCountdown.value = 0\n }\n },\n { immediate: true },\n )\n\n onBeforeUnmount(() => {\n if (retryTimer.value) {\n clearTimeout(retryTimer.value)\n }\n })\n</script>\n\n<template>\n <VvAlert\n :modifiers=\"isRefreshableError ? 'warning' : 'danger'\"\n class=\"rounded-lg\">\n <!-- The modifier already paints the alert and picks its icon: tinting\n the content again, with a 32px glyph nothing else in the chat\n matches, said the same thing three times (DESIGN.md). -->\n {{ errorMessage }}\n <template v-if=\"isRefreshableError || !isOutOfUserReach\" #footer>\n <VvButton\n v-if=\"isRefreshableError\"\n icon=\"ri:reset-right-line\"\n modifiers=\"action\"\n class=\"text-12\"\n :label=\"$t('action.retryNow')\"\n @click=\"$emit('retry')\" />\n <VvButton\n v-else-if=\"!isOutOfUserReach\"\n icon=\"reload\"\n modifiers=\"action\"\n :label=\"$t('label.newChat')\"\n @click=\"$emit('reset')\" />\n </template>\n </VvAlert>\n</template>\n","<script lang=\"ts\" setup>\n import { computed, onBeforeUnmount, ref, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useChatbotError, getStreamErrorPayload } from 'composables'\n\n const props = defineProps<{\n error?: Error\n }>()\n\n const emit = defineEmits<{\n (e: 'retry'): void\n (e: 'reset'): void\n }>()\n\n const { t: $t } = useI18n({\n useScope: 'global',\n })\n\n const {\n isContextWindowError,\n isNotFoundError,\n isRateLimitError,\n isOriginNotAllowedError,\n isCreditExhaustedError,\n isConversationBlockedError,\n isBadRequestError,\n isInternalServerError,\n isGatewayConfigError,\n isGatewayDisabledError,\n isModelUnavailableError,\n isRefreshableError,\n } = useChatbotError(() => props.error)\n\n /**\n * Nothing the user of the chat can do about: a new conversation meets the\n * same answer, so the alert offers no button, as for exhausted credit.\n */\n const isOutOfUserReach = computed(\n () =>\n isOriginNotAllowedError.value ||\n isCreditExhaustedError.value ||\n isGatewayConfigError.value ||\n isGatewayDisabledError.value ||\n isModelUnavailableError.value,\n )\n\n const errorMessage = computed(() => {\n if (isGatewayConfigError.value) {\n const payload = getStreamErrorPayload(props.error)\n if (payload?.reason === 'disallowPromptTraining') {\n return $t('message.chatErrorGatewayPromptTraining', {\n model: payload.model,\n })\n }\n if (payload?.reason === 'zeroDataRetention') {\n return $t('message.chatErrorGatewayZdr', {\n model: payload.model,\n })\n }\n return $t('message.chatErrorGeneric')\n }\n if (isContextWindowError.value) {\n return $t('message.chatErrorContextWindow')\n }\n if (isNotFoundError.value) {\n return $t('message.chatErrorNotFound')\n }\n if (isRateLimitError.value) {\n return $t('message.chatErrorRateLimit', {\n seconds: retryCountdown.value,\n })\n }\n if (isOriginNotAllowedError.value) {\n return $t('message.chatErrorOriginNotAllowed')\n }\n if (isCreditExhaustedError.value) {\n return $t('message.chatErrorCreditExhausted')\n }\n if (isGatewayDisabledError.value) {\n return $t('message.chatErrorGatewayDisabled')\n }\n if (isModelUnavailableError.value) {\n return $t('message.chatErrorModelUnavailable')\n }\n if (isConversationBlockedError.value) {\n return $t('message.chatErrorConversationBlocked')\n }\n if (isBadRequestError.value) {\n return $t('message.chatErrorBadRequest')\n }\n if (isInternalServerError.value) {\n return $t('message.chatErrorInternalServer')\n }\n return $t('message.chatErrorGeneric', { seconds: retryCountdown.value })\n })\n\n const retryCountdown = ref<number>(0)\n const retryTimer = ref<ReturnType<typeof setTimeout>>()\n\n watch(\n () => props.error,\n (error) => {\n if (retryTimer.value) {\n clearTimeout(retryTimer.value)\n }\n\n if (error && isRefreshableError.value) {\n retryCountdown.value = 10\n const tick = () => {\n retryCountdown.value--\n if (retryCountdown.value <= 0) {\n emit('retry')\n return\n }\n retryTimer.value = setTimeout(tick, 1000)\n }\n retryTimer.value = setTimeout(tick, 1000)\n } else {\n retryCountdown.value = 0\n }\n },\n { immediate: true },\n )\n\n onBeforeUnmount(() => {\n if (retryTimer.value) {\n clearTimeout(retryTimer.value)\n }\n })\n</script>\n\n<template>\n <VvAlert\n :modifiers=\"isRefreshableError ? 'warning' : 'danger'\"\n class=\"rounded-lg\">\n <!-- The modifier already paints the alert and picks its icon: tinting\n the content again, with a 32px glyph nothing else in the chat\n matches, said the same thing three times (DESIGN.md). -->\n {{ errorMessage }}\n <template v-if=\"isRefreshableError || !isOutOfUserReach\" #footer>\n <VvButton\n v-if=\"isRefreshableError\"\n icon=\"ri:reset-right-line\"\n modifiers=\"action\"\n class=\"text-12\"\n :label=\"$t('action.retryNow')\"\n @click=\"$emit('retry')\" />\n <VvButton\n v-else-if=\"!isOutOfUserReach\"\n icon=\"reload\"\n modifiers=\"action\"\n :label=\"$t('label.newChat')\"\n @click=\"$emit('reset')\" />\n </template>\n </VvAlert>\n</template>\n"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { S as e, v as t } from "./schemas-Bu1lick6.js";
2
- import { t as n } from "./index.es-C1u3kP7i.js";
3
- import { VvAlert as r, VvButton as i, VvButtonGroup as a, VvIcon as o } from "@volverjs/ui-vue/components";
2
+ import { t as n } from "./VvButtonLocalized-BuzLsXp3.js";
3
+ import { t as r } from "./index.es-C1u3kP7i.js";
4
+ import { VvAlert as i, VvButtonGroup as a, VvIcon as o } from "@volverjs/ui-vue/components";
4
5
  import { Transition as s, createBlock as c, createCommentVNode as l, createElementBlock as u, createElementVNode as d, createVNode as f, defineComponent as p, isRef as m, openBlock as h, toDisplayString as g, unref as _, withCtx as v, withModifiers as y } from "vue";
5
6
  import { useI18n as b } from "vue-i18n";
6
7
  //#region ../../packages/components/src/chat/PkChatbotFeedbackForm.vue?vue&type=script&setup=true&lang.ts
@@ -16,13 +17,13 @@ var x = { class: "border border-surface-3 rounded-xl w-full overflow-hidden bg-s
16
17
  },
17
18
  emits: ["submit", "close"],
18
19
  setup(p, { emit: j }) {
19
- let { t: M } = b({ useScope: "global" }), N = j, P = t({ comment: e().min(1).default("") }), { VvForm: F, VvFormField: I, formData: L } = n(P, { lazyLoad: !0 }), R = (e) => {
20
+ let { t: M } = b({ useScope: "global" }), N = j, P = t({ comment: e().min(1).default("") }), { VvForm: F, VvFormField: I, formData: L } = r(P, { lazyLoad: !0 }), R = (e) => {
20
21
  N("submit", e.comment);
21
22
  };
22
23
  return (e, t) => {
23
- let n = o, b = i, j = r, N = a;
24
+ let r = o, b = n, j = i, N = a;
24
25
  return h(), u("div", x, [d("div", S, [
25
- f(n, {
26
+ f(r, {
26
27
  name: "ri:feedback-line",
27
28
  class: "text-16"
28
29
  }),
@@ -35,7 +36,7 @@ var x = { class: "border border-surface-3 rounded-xl w-full overflow-hidden bg-s
35
36
  onClick: t[0] ||= y((t) => e.$emit("close"), ["stop"])
36
37
  }, null, 8, ["title"])
37
38
  ]), f(s, { mode: "out-in" }, {
38
- default: v(() => [p.submitted ? (h(), u("div", D, [d("div", O, [f(n, {
39
+ default: v(() => [p.submitted ? (h(), u("div", D, [d("div", O, [f(r, {
39
40
  name: "ri:check-line",
40
41
  class: "text-16 text-success"
41
42
  }), d("div", null, [d("strong", k, g(_(M)("message.feedbackSubmittedTitle")), 1), d("p", A, g(_(M)("message.feedbackSubmittedMessage")), 1)])])])) : (h(), u("div", w, [f(_(F), {
@@ -89,4 +90,4 @@ var x = { class: "border border-surface-3 rounded-xl w-full overflow-hidden bg-s
89
90
  //#endregion
90
91
  export { j as t };
91
92
 
92
- //# sourceMappingURL=PkChatbotFeedbackForm-CMFXjoKR.js.map
93
+ //# sourceMappingURL=PkChatbotFeedbackForm-B5cYsWBr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PkChatbotFeedbackForm-B5cYsWBr.js","names":["$emit","z.object","z.string","useForm","__unplugin_components_0","__unplugin_components_1","__unplugin_components_2","__unplugin_components_3","_openBlock","_createElementBlock","_createElementVNode","_createVNode","_toDisplayString","_unref","_withModifiers","_Transition","_withCtx","_isRef","_createBlock","_createCommentVNode","_sfc_main","string","object","VvButtonLocalized","Se","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","PkChatbotFeedbackForm_default","defineComponent","__emit","$t","useI18n","emit","FeedbackFormSchema","onSubmit","data","_component_VvIcon","VvIcon","_component_VvButton","_component_VvAlert","VvAlert","_component_VvButtonGroup","VvButtonGroup","openBlock","createElementBlock","createElementVNode","createVNode","toDisplayString","unref","_cache","withModifiers","_ctx","Transition","withCtx","__props","VvForm","formData","isRef","$event","createBlock","createCommentVNode","VvFormField"],"sources":["../../../../packages/components/src/chat/PkChatbotFeedbackForm.vue","../../../../packages/components/src/chat/PkChatbotFeedbackForm.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { useI18n } from 'vue-i18n'\n import { useForm } from '@volverjs/form-vue'\n import * as z from 'zod'\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n defineProps<{\n submitted?: boolean\n loading?: boolean\n error?: string\n }>()\n\n const emit = defineEmits<{\n submit: [comment: string]\n close: []\n }>()\n\n const FeedbackFormSchema = z.object({\n comment: z.string().min(1).default(''),\n })\n\n const { VvForm, VvFormField, formData } = useForm(FeedbackFormSchema, {\n lazyLoad: true,\n })\n\n const onSubmit = (data: { comment: string }) => {\n emit('submit', data.comment)\n }\n</script>\n\n<template>\n <div\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden bg-surface\">\n <div\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8 min-h-40\">\n <VvIcon name=\"ri:feedback-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{ $t('action.feedback') }}</strong>\n <VvButton\n icon=\"ri:close-line\"\n modifiers=\"action-quiet-small\"\n :title=\"$t('action.close')\"\n class=\"ml-auto\"\n @click.stop=\"$emit('close')\" />\n </div>\n <Transition mode=\"out-in\">\n <div v-if=\"!submitted\">\n <VvForm v-model=\"formData\" @submit=\"onSubmit\">\n <div class=\"p-sm\">\n <VvAlert\n v-if=\"error\"\n modifiers=\"danger\"\n class=\"mb-sm\"\n :content=\"error\" />\n <VvFormField\n name=\"comment\"\n type=\"textarea\"\n rows=\"3\"\n :label=\"$t('label.comment')\"\n :placeholder=\"$t('placeholder.comment')\"\n modifiers=\"compact no-label\"\n class=\"mb-0\" />\n </div>\n <div\n class=\"flex justify-end border-t border-surface-3 px-sm py-10\">\n <VvButtonGroup>\n <VvButton\n type=\"button\"\n modifiers=\"action-quiet\"\n icon=\"ri:close-line\"\n icon-position=\"right\"\n :label=\"$t('action.close')\"\n @click=\"$emit('close')\" />\n <VvButton\n type=\"submit\"\n modifiers=\"action-primary\"\n icon=\"ri:send-plane-2-line\"\n icon-position=\"right\"\n :loading\n :disabled=\"loading\"\n :label=\"$t('action.submit')\" />\n </VvButtonGroup>\n </div>\n </VvForm>\n </div>\n <div v-else class=\"p-sm\">\n <!-- One confirmation row across every tool card: a green\n check, the title in weight, the body quiet. The check is\n the outcome, so it alone carries the colour (DESIGN.md). -->\n <div class=\"flex items-center gap-sm\">\n <VvIcon name=\"ri:check-line\" class=\"text-16 text-success\" />\n <div>\n <strong class=\"font-medium block text-word-1\">\n {{ $t('message.feedbackSubmittedTitle') }}\n </strong>\n <p class=\"text-word-3\">\n {{ $t('message.feedbackSubmittedMessage') }}\n </p>\n </div>\n </div>\n </div>\n </Transition>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { useI18n } from 'vue-i18n'\n import { useForm } from '@volverjs/form-vue'\n import * as z from 'zod'\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n defineProps<{\n submitted?: boolean\n loading?: boolean\n error?: string\n }>()\n\n const emit = defineEmits<{\n submit: [comment: string]\n close: []\n }>()\n\n const FeedbackFormSchema = z.object({\n comment: z.string().min(1).default(''),\n })\n\n const { VvForm, VvFormField, formData } = useForm(FeedbackFormSchema, {\n lazyLoad: true,\n })\n\n const onSubmit = (data: { comment: string }) => {\n emit('submit', data.comment)\n }\n</script>\n\n<template>\n <div\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden bg-surface\">\n <div\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8 min-h-40\">\n <VvIcon name=\"ri:feedback-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{ $t('action.feedback') }}</strong>\n <VvButton\n icon=\"ri:close-line\"\n modifiers=\"action-quiet-small\"\n :title=\"$t('action.close')\"\n class=\"ml-auto\"\n @click.stop=\"$emit('close')\" />\n </div>\n <Transition mode=\"out-in\">\n <div v-if=\"!submitted\">\n <VvForm v-model=\"formData\" @submit=\"onSubmit\">\n <div class=\"p-sm\">\n <VvAlert\n v-if=\"error\"\n modifiers=\"danger\"\n class=\"mb-sm\"\n :content=\"error\" />\n <VvFormField\n name=\"comment\"\n type=\"textarea\"\n rows=\"3\"\n :label=\"$t('label.comment')\"\n :placeholder=\"$t('placeholder.comment')\"\n modifiers=\"compact no-label\"\n class=\"mb-0\" />\n </div>\n <div\n class=\"flex justify-end border-t border-surface-3 px-sm py-10\">\n <VvButtonGroup>\n <VvButton\n type=\"button\"\n modifiers=\"action-quiet\"\n icon=\"ri:close-line\"\n icon-position=\"right\"\n :label=\"$t('action.close')\"\n @click=\"$emit('close')\" />\n <VvButton\n type=\"submit\"\n modifiers=\"action-primary\"\n icon=\"ri:send-plane-2-line\"\n icon-position=\"right\"\n :loading\n :disabled=\"loading\"\n :label=\"$t('action.submit')\" />\n </VvButtonGroup>\n </div>\n </VvForm>\n </div>\n <div v-else class=\"p-sm\">\n <!-- One confirmation row across every tool card: a green\n check, the title in weight, the body quiet. The check is\n the outcome, so it alone carries the colour (DESIGN.md). -->\n <div class=\"flex items-center gap-sm\">\n <VvIcon name=\"ri:check-line\" class=\"text-16 text-success\" />\n <div>\n <strong class=\"font-medium block text-word-1\">\n {{ $t('message.feedbackSubmittedTitle') }}\n </strong>\n <p class=\"text-word-3\">\n {{ $t('message.feedbackSubmittedMessage') }}\n </p>\n </div>\n </div>\n </div>\n </Transition>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { n as e } from "./cdn-css-JUUNhyQ6.js";
2
- import "./src-DCfvejyT.js";
2
+ import "./src-DpkuiHam.js";
3
3
  import { VvIcon as t } from "@volverjs/ui-vue/components";
4
4
  import { Fragment as n, computed as r, createBlock as i, createCommentVNode as a, createElementBlock as o, createElementVNode as s, createTextVNode as c, createVNode as l, defineComponent as u, normalizeClass as d, normalizeStyle as f, onBeforeUnmount as p, onMounted as m, openBlock as h, ref as g, shallowRef as _, toDisplayString as v, vShow as y, withDirectives as b, withModifiers as x } from "vue";
5
5
  //#region ../../packages/components/src/composables/useLightbox.ts
@@ -364,4 +364,4 @@ var ee = [
364
364
  //#endregion
365
365
  export { T as n, w as r, q as t };
366
366
 
367
- //# sourceMappingURL=PkChatbotFilePreview-DIP8KLkS.js.map
367
+ //# sourceMappingURL=PkChatbotFilePreview-D5H-RIk2.js.map