@8wave/ai-elements 0.98.0 → 0.99.0-beta.2

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 (178) hide show
  1. package/README.md +24 -5
  2. package/{dist-vue/_chunks/PkStreamingMarkdown-DEhbK-3c.js → dist/_chunks/PkStreamingMarkdown-6Xx9n1ue.js} +379 -362
  3. package/dist/_chunks/PkStreamingMarkdown-6Xx9n1ue.js.map +1 -0
  4. package/dist/_chunks/{PkToolRequestGeolocation-BJ9NJZIg.js → PkToolRequestGeolocation-B73evGBg.js} +2 -2
  5. package/dist/_chunks/{PkToolRequestGeolocation-BJ9NJZIg.js.map → PkToolRequestGeolocation-B73evGBg.js.map} +1 -1
  6. package/dist/_chunks/{PkToolRequestOAuthConnection-DdvJ6n1K.js → PkToolRequestOAuthConnection-BWP5dsK_.js} +3 -3
  7. package/dist/_chunks/{PkToolRequestOAuthConnection-DdvJ6n1K.js.map → PkToolRequestOAuthConnection-BWP5dsK_.js.map} +1 -1
  8. package/dist/_chunks/{PkToolShowArtifact-BaGEr7O9.js → PkToolShowArtifact-bYYaMGxq.js} +7 -7
  9. package/dist/_chunks/{PkToolShowArtifact-BaGEr7O9.js.map → PkToolShowArtifact-bYYaMGxq.js.map} +1 -1
  10. package/dist/_chunks/{PkToolShowCalendarEvent-BYnhl2er.js → PkToolShowCalendarEvent-DdEWaTj-.js} +4 -4
  11. package/dist/_chunks/{PkToolShowCalendarEvent-BYnhl2er.js.map → PkToolShowCalendarEvent-DdEWaTj-.js.map} +1 -1
  12. package/dist/_chunks/{PkToolShowComparison-DahL5vHr.js → PkToolShowComparison-Dcar7HPW.js} +4 -4
  13. package/dist/_chunks/{PkToolShowComparison-DahL5vHr.js.map → PkToolShowComparison-Dcar7HPW.js.map} +1 -1
  14. package/dist/_chunks/{PkToolShowContactForm-upUNZtId.js → PkToolShowContactForm-DtjVW-n6.js} +13 -13
  15. package/dist/_chunks/{PkToolShowContactForm-upUNZtId.js.map → PkToolShowContactForm-DtjVW-n6.js.map} +1 -1
  16. package/dist/_chunks/{PkToolShowDiagram-Jq_4KWiK.js → PkToolShowDiagram-X35nsoIY.js} +8 -8
  17. package/dist/_chunks/{PkToolShowDiagram-Jq_4KWiK.js.map → PkToolShowDiagram-X35nsoIY.js.map} +1 -1
  18. package/dist/_chunks/{PkToolShowEmail-CtmpDS1B.js → PkToolShowEmail-jVoK8qEh.js} +4 -4
  19. package/dist/_chunks/{PkToolShowEmail-CtmpDS1B.js.map → PkToolShowEmail-jVoK8qEh.js.map} +1 -1
  20. package/dist/_chunks/{PkToolShowForm-BNV4Ja6g.js → PkToolShowForm-BP8asXtz.js} +123 -97
  21. package/dist/_chunks/PkToolShowForm-BP8asXtz.js.map +1 -0
  22. package/dist/_chunks/{PkToolShowImageGallery-mLq2p3aH.js → PkToolShowImageGallery-WQL3T4Hr.js} +2 -2
  23. package/dist/_chunks/{PkToolShowImageGallery-mLq2p3aH.js.map → PkToolShowImageGallery-WQL3T4Hr.js.map} +1 -1
  24. package/dist/_chunks/{PkToolShowLocation-SbgTbuGu.js → PkToolShowLocation-w2t7lKpb.js} +4 -4
  25. package/dist/_chunks/{PkToolShowLocation-SbgTbuGu.js.map → PkToolShowLocation-w2t7lKpb.js.map} +1 -1
  26. package/dist/_chunks/{PkToolShowMessage-CAVpDTzd.js → PkToolShowMessage-BPo7WPim.js} +4 -4
  27. package/dist/_chunks/{PkToolShowMessage-CAVpDTzd.js.map → PkToolShowMessage-BPo7WPim.js.map} +1 -1
  28. package/dist/_chunks/{PkToolShowProductList-puiPFItN.js → PkToolShowProductList-BbY4ni7Y.js} +2 -2
  29. package/dist/_chunks/{PkToolShowProductList-puiPFItN.js.map → PkToolShowProductList-BbY4ni7Y.js.map} +1 -1
  30. package/dist/_chunks/{PkToolShowQrCode-CctXvRyG.js → PkToolShowQrCode-CN0ms27N.js} +4 -4
  31. package/dist/_chunks/{PkToolShowQrCode-CctXvRyG.js.map → PkToolShowQrCode-CN0ms27N.js.map} +1 -1
  32. package/dist/_chunks/{PkToolShowSources-DwB6VXrK.js → PkToolShowSources-D2tBcx7n.js} +18 -18
  33. package/dist/_chunks/{PkToolShowSources-DwB6VXrK.js.map → PkToolShowSources-D2tBcx7n.js.map} +1 -1
  34. package/dist/_chunks/{PkToolShowSuggestedReply-QEcIhSxa.js → PkToolShowSuggestedReply-Cdh_elSh.js} +2 -2
  35. package/dist/_chunks/{PkToolShowSuggestedReply-QEcIhSxa.js.map → PkToolShowSuggestedReply-Cdh_elSh.js.map} +1 -1
  36. package/dist/_chunks/{PkToolShowVideo-DoLoI8_N.js → PkToolShowVideo-D3aU5FMO.js} +2 -2
  37. package/dist/_chunks/{PkToolShowVideo-DoLoI8_N.js.map → PkToolShowVideo-D3aU5FMO.js.map} +1 -1
  38. package/dist/_chunks/{PkToolShowWeather-C2rPCQ_K.js → PkToolShowWeather-CzanXIJp.js} +3 -3
  39. package/dist/_chunks/{PkToolShowWeather-C2rPCQ_K.js.map → PkToolShowWeather-CzanXIJp.js.map} +1 -1
  40. package/dist/_chunks/{PkToolShowWebPages-BBJYzF8V.js → PkToolShowWebPages-DkMJrWmT.js} +2 -2
  41. package/dist/_chunks/{PkToolShowWebPages-BBJYzF8V.js.map → PkToolShowWebPages-DkMJrWmT.js.map} +1 -1
  42. package/dist/_chunks/{VvCheckbox.es-D5d8k9yP.js → VvCheckbox.es-CRhIKQNR.js} +2 -2
  43. package/dist/_chunks/{VvCheckbox.es-D5d8k9yP.js.map → VvCheckbox.es-CRhIKQNR.js.map} +1 -1
  44. package/dist/_chunks/{VvCheckboxGroup.es-DVnsOjX0.js → VvCheckboxGroup.es-gOy2kM1Y.js} +5 -5
  45. package/dist/_chunks/{VvCheckboxGroup.es-DVnsOjX0.js.map → VvCheckboxGroup.es-gOy2kM1Y.js.map} +1 -1
  46. package/dist/_chunks/{VvCombobox.es-CFA-K-cQ.js → VvCombobox.es-BOwH3LmO.js} +9 -9
  47. package/dist/_chunks/VvCombobox.es-BOwH3LmO.js.map +1 -0
  48. package/dist/_chunks/{VvInputText.es-csEQ-bSG.js → VvInputText.es-D8nXroKO.js} +536 -513
  49. package/dist/_chunks/VvInputText.es-D8nXroKO.js.map +1 -0
  50. package/dist/_chunks/{VvRadio.es-BpymhC73.js → VvRadio.es-Djy5J33A.js} +2 -2
  51. package/dist/_chunks/{VvRadio.es-BpymhC73.js.map → VvRadio.es-Djy5J33A.js.map} +1 -1
  52. package/dist/_chunks/{VvRadioGroup.es-CSNzOJKx.js → VvRadioGroup.es-DQq3JYCR.js} +5 -5
  53. package/dist/_chunks/VvRadioGroup.es-DQq3JYCR.js.map +1 -0
  54. package/dist/_chunks/{VvSelect.es-CjKMd0nH.js → VvSelect.es-CE4x1ww0.js} +4 -4
  55. package/dist/_chunks/{VvSelect.es-CjKMd0nH.js.map → VvSelect.es-CE4x1ww0.js.map} +1 -1
  56. package/dist/_chunks/VvTextarea.es-BU2vqdEQ.js +1129 -0
  57. package/dist/_chunks/VvTextarea.es-BU2vqdEQ.js.map +1 -0
  58. package/dist/_chunks/{dist-BNET2z7b.js → dist-CvMCBce7.js} +39 -21
  59. package/dist/_chunks/dist-CvMCBce7.js.map +1 -0
  60. package/dist/_chunks/dot-prop-CObyt75F.js +141 -0
  61. package/dist/_chunks/dot-prop-CObyt75F.js.map +1 -0
  62. package/dist/_chunks/{floating-ui.vue-CIKvCpTA.js → floating-ui.vue-BacoFpVq.js} +278 -305
  63. package/dist/_chunks/floating-ui.vue-BacoFpVq.js.map +1 -0
  64. package/dist/_chunks/{index.es-u1dF1xg2.js → index.es-DpqfagWZ.js} +12 -12
  65. package/dist/_chunks/{index.es-u1dF1xg2.js.map → index.es-DpqfagWZ.js.map} +1 -1
  66. package/dist/_chunks/{index.es-BYny0uhz.js → index.es-_oXVRjHy.js} +2352 -2329
  67. package/dist/_chunks/index.es-_oXVRjHy.js.map +1 -0
  68. package/dist/ai-elements.es.js +4818 -5765
  69. package/dist/ai-elements.es.js.map +1 -1
  70. package/dist-vue/PkChatbot.js +1 -1
  71. package/dist-vue/PkChatbotAuth.js +1 -1
  72. package/dist-vue/PkChatbotEmptyState.js +1 -1
  73. package/dist-vue/PkChatbotFeedbackForm.js +1 -1
  74. package/dist-vue/PkChatbotInput.js +1 -1
  75. package/dist-vue/PkChatbotMessages.js +1 -1
  76. package/dist-vue/PkChatbotStepToolDetail.js +1 -1
  77. package/dist-vue/PkChatbotSteps.js +1 -1
  78. package/dist-vue/PkChatbotViewChat.js +1 -1
  79. package/dist-vue/PkChatbotViewConversations.js +1 -1
  80. package/dist-vue/PkChatbotViewFiles.js +1 -1
  81. package/dist-vue/PkChatbotViewProfile.js +1 -1
  82. package/dist-vue/_chunks/PkChatbot-Bf5uY3cO.js +236 -0
  83. package/dist-vue/_chunks/{PkChatbot-DHkhT0Jf.js.map → PkChatbot-Bf5uY3cO.js.map} +1 -1
  84. package/dist-vue/_chunks/{PkChatbotAuth-C_L2xWuD.js → PkChatbotAuth-BGn2MDYD.js} +2 -2
  85. package/dist-vue/_chunks/{PkChatbotAuth-C_L2xWuD.js.map → PkChatbotAuth-BGn2MDYD.js.map} +1 -1
  86. package/dist-vue/_chunks/{PkChatbotEmptyState-BGOC6vxr.js → PkChatbotEmptyState-CPqLqXek.js} +2 -2
  87. package/dist-vue/_chunks/{PkChatbotEmptyState-BGOC6vxr.js.map → PkChatbotEmptyState-CPqLqXek.js.map} +1 -1
  88. package/dist-vue/_chunks/{PkChatbotFeedbackForm-BSe40qlc.js → PkChatbotFeedbackForm-C_y__RH8.js} +2 -2
  89. package/dist-vue/_chunks/{PkChatbotFeedbackForm-BSe40qlc.js.map → PkChatbotFeedbackForm-C_y__RH8.js.map} +1 -1
  90. package/dist-vue/_chunks/{PkChatbotInput-DTazYlPd.js → PkChatbotInput-jvb0vuak.js} +2 -2
  91. package/dist-vue/_chunks/{PkChatbotInput-DTazYlPd.js.map → PkChatbotInput-jvb0vuak.js.map} +1 -1
  92. package/dist-vue/_chunks/PkChatbotMessages-B3G12zah.js +752 -0
  93. package/dist-vue/_chunks/PkChatbotMessages-B3G12zah.js.map +1 -0
  94. package/dist-vue/_chunks/{PkChatbotStepToolDetail-ldThv0t5.js → PkChatbotStepToolDetail-BVI72gyx.js} +2 -2
  95. package/dist-vue/_chunks/{PkChatbotStepToolDetail-ldThv0t5.js.map → PkChatbotStepToolDetail-BVI72gyx.js.map} +1 -1
  96. package/dist-vue/_chunks/PkChatbotSteps-BdU6YC_N.js +172 -0
  97. package/dist-vue/_chunks/{PkChatbotSteps-BpqdFhsG.js.map → PkChatbotSteps-BdU6YC_N.js.map} +1 -1
  98. package/dist-vue/_chunks/{PkChatbotViewChat-C08TsXiL.js → PkChatbotViewChat-c0Ecpzoc.js} +68 -68
  99. package/dist-vue/_chunks/PkChatbotViewChat-c0Ecpzoc.js.map +1 -0
  100. package/dist-vue/_chunks/{PkChatbotViewConversations-BQZi5kSC.js → PkChatbotViewConversations-BfhRCA_1.js} +2 -2
  101. package/dist-vue/_chunks/{PkChatbotViewConversations-BQZi5kSC.js.map → PkChatbotViewConversations-BfhRCA_1.js.map} +1 -1
  102. package/dist-vue/_chunks/{PkChatbotViewFiles-TLKE_tRw.js → PkChatbotViewFiles-BipRoidH.js} +2 -2
  103. package/dist-vue/_chunks/{PkChatbotViewFiles-TLKE_tRw.js.map → PkChatbotViewFiles-BipRoidH.js.map} +1 -1
  104. package/dist-vue/_chunks/{PkChatbotViewProfile-B6ANZY96.js → PkChatbotViewProfile-DuLwYpGZ.js} +2 -2
  105. package/dist-vue/_chunks/{PkChatbotViewProfile-B6ANZY96.js.map → PkChatbotViewProfile-DuLwYpGZ.js.map} +1 -1
  106. package/{dist/_chunks/PkStreamingMarkdown-Djw604Ny.js → dist-vue/_chunks/PkStreamingMarkdown-CjBMQ18U.js} +344 -347
  107. package/dist-vue/_chunks/PkStreamingMarkdown-CjBMQ18U.js.map +1 -0
  108. package/dist-vue/_chunks/{PkToolShowArtifact-CTBwt4DN.js → PkToolShowArtifact-COwSXmF4.js} +2 -2
  109. package/dist-vue/_chunks/{PkToolShowArtifact-CTBwt4DN.js.map → PkToolShowArtifact-COwSXmF4.js.map} +1 -1
  110. package/dist-vue/_chunks/{PkToolShowContactForm-B6-MsExL.js → PkToolShowContactForm-DRRtCCxB.js} +10 -10
  111. package/dist-vue/_chunks/{PkToolShowContactForm-B6-MsExL.js.map → PkToolShowContactForm-DRRtCCxB.js.map} +1 -1
  112. package/dist-vue/_chunks/{PkToolShowForm-C-mWyeka.js → PkToolShowForm-j7Ha-0X3.js} +128 -102
  113. package/dist-vue/_chunks/PkToolShowForm-j7Ha-0X3.js.map +1 -0
  114. package/dist-vue/_chunks/{PkToolShowSources-CFh-i60o.js → PkToolShowSources-BVLw4W5l.js} +43 -43
  115. package/dist-vue/_chunks/{PkToolShowSources-CFh-i60o.js.map → PkToolShowSources-BVLw4W5l.js.map} +1 -1
  116. package/dist-vue/_chunks/{createChatbotApiClient-BOBdBxmf.js → createChatbotApiClient-IH6wBh4s.js} +148 -160
  117. package/dist-vue/_chunks/createChatbotApiClient-IH6wBh4s.js.map +1 -0
  118. package/dist-vue/_chunks/{index.es-XfWQ82pb.js → index.es-Bk1O0p8N.js} +166 -156
  119. package/dist-vue/_chunks/index.es-Bk1O0p8N.js.map +1 -0
  120. package/dist-vue/_chunks/{useChatbotStore-BJ-EDmND.js → useChatbotStore-C3uKi2FS.js} +114 -106
  121. package/dist-vue/_chunks/useChatbotStore-C3uKi2FS.js.map +1 -0
  122. package/dist-vue/_chunks/{utils-BMa8jwJS.js → utils-Cru8TJxe.js} +48 -30
  123. package/dist-vue/_chunks/utils-Cru8TJxe.js.map +1 -0
  124. package/dist-vue/api.js +1 -1
  125. package/dist-vue/composables.js +3 -3
  126. package/dist-vue/index.js +3732 -3213
  127. package/dist-vue/index.js.map +1 -1
  128. package/dist-vue/locales.js +43 -7
  129. package/dist-vue/packages/components/src/PkCheckboxField.d.ts +45 -0
  130. package/dist-vue/packages/components/src/PkEditorRepeater.d.ts +2 -2
  131. package/dist-vue/packages/components/src/{chat/PkToolRequestConfirm.d.ts → PkOfflineScreen.d.ts} +10 -3
  132. package/dist-vue/packages/components/src/PkPwaNotices.d.ts +19 -0
  133. package/dist-vue/packages/components/src/chat/PkAgentSettingsPanel.d.ts +18 -3
  134. package/dist-vue/packages/components/src/chat/PkChatbotMessages.d.ts +24 -2
  135. package/dist-vue/packages/components/src/chat/PkToolApprovalBadge.d.ts +4 -0
  136. package/dist-vue/packages/components/src/chat/PkToolApprovalCard.d.ts +35 -0
  137. package/dist-vue/packages/components/src/chat/PkToolApprovalPreviewMessage.d.ts +11 -0
  138. package/dist-vue/packages/components/src/chat/index.d.ts +2 -1
  139. package/dist-vue/packages/components/src/chat/toolApprovalPreviews.d.ts +12 -0
  140. package/dist-vue/packages/components/src/chat/toolComponentMap.d.ts +5 -3
  141. package/dist-vue/packages/components/src/chat/useChatScroll.d.ts +6 -0
  142. package/dist-vue/packages/components/src/chat/utils.d.ts +13 -0
  143. package/dist-vue/packages/components/src/index.d.ts +4 -1
  144. package/dist-vue/packages/composable/src/chatbot/useChatbotStore.d.ts +70 -1
  145. package/dist-vue/packages/composable/src/index.d.ts +1 -0
  146. package/dist-vue/packages/composable/src/useConnectivity.d.ts +28 -0
  147. package/dist-vue/packages/models/src/schema/Agent.d.ts +129 -0
  148. package/dist-vue/packages/models/src/schema/ReasoningChat.d.ts +30 -0
  149. package/dist-vue/packages/models/src/schema/SubAgent.d.ts +30 -0
  150. package/dist-vue/style.css +1 -1
  151. package/package.json +3 -3
  152. package/dist/_chunks/PkStreamingMarkdown-Djw604Ny.js.map +0 -1
  153. package/dist/_chunks/PkToolRequestConfirm-FQ9nDFXy.js +0 -48
  154. package/dist/_chunks/PkToolRequestConfirm-FQ9nDFXy.js.map +0 -1
  155. package/dist/_chunks/PkToolShowForm-BNV4Ja6g.js.map +0 -1
  156. package/dist/_chunks/VvCombobox.es-CFA-K-cQ.js.map +0 -1
  157. package/dist/_chunks/VvInputText.es-csEQ-bSG.js.map +0 -1
  158. package/dist/_chunks/VvRadioGroup.es-CSNzOJKx.js.map +0 -1
  159. package/dist/_chunks/VvTextarea.es-eEyRRpuT.js +0 -1109
  160. package/dist/_chunks/VvTextarea.es-eEyRRpuT.js.map +0 -1
  161. package/dist/_chunks/dist-BNET2z7b.js.map +0 -1
  162. package/dist/_chunks/dot-prop-BXrC9bAX.js +0 -131
  163. package/dist/_chunks/dot-prop-BXrC9bAX.js.map +0 -1
  164. package/dist/_chunks/floating-ui.vue-CIKvCpTA.js.map +0 -1
  165. package/dist/_chunks/index.es-BYny0uhz.js.map +0 -1
  166. package/dist-vue/_chunks/PkChatbot-DHkhT0Jf.js +0 -236
  167. package/dist-vue/_chunks/PkChatbotMessages-B4qfTNOJ.js +0 -630
  168. package/dist-vue/_chunks/PkChatbotMessages-B4qfTNOJ.js.map +0 -1
  169. package/dist-vue/_chunks/PkChatbotSteps-BpqdFhsG.js +0 -172
  170. package/dist-vue/_chunks/PkChatbotViewChat-C08TsXiL.js.map +0 -1
  171. package/dist-vue/_chunks/PkStreamingMarkdown-DEhbK-3c.js.map +0 -1
  172. package/dist-vue/_chunks/PkToolRequestConfirm-CQNa3seA.js +0 -48
  173. package/dist-vue/_chunks/PkToolRequestConfirm-CQNa3seA.js.map +0 -1
  174. package/dist-vue/_chunks/PkToolShowForm-C-mWyeka.js.map +0 -1
  175. package/dist-vue/_chunks/createChatbotApiClient-BOBdBxmf.js.map +0 -1
  176. package/dist-vue/_chunks/index.es-XfWQ82pb.js.map +0 -1
  177. package/dist-vue/_chunks/useChatbotStore-BJ-EDmND.js.map +0 -1
  178. package/dist-vue/_chunks/utils-BMa8jwJS.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"PkToolRequestOAuthConnection-DdvJ6n1K.js","names":[],"sources":["../../../../packages/components/src/chat/PkToolRequestOAuthConnection.vue","../../../../packages/components/src/chat/PkToolRequestOAuthConnection.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, onUnmounted, ref, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n\n const props = defineProps<{\n part: unknown\n resolveConnection?: (\n serverName: string,\n ) => Promise<{ mcpServerId: string; authorizeUrl: string }>\n }>()\n\n const emit = defineEmits<{\n connected: [mcpServerId: string]\n }>()\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n const toolPart = computed(() => {\n return props.part as {\n state?: string\n toolCallId?: string\n input?: { serverName: string }\n }\n })\n\n const state = computed(() => toolPart.value.state ?? 'unknown')\n const serverName = computed(() => toolPart.value.input?.serverName)\n\n const connectionData = ref<{\n mcpServerId: string\n authorizeUrl: string\n } | null>(null)\n const isResolving = ref(false)\n const oauthCompleted = ref(false)\n const oauthError = ref<string | null>(null)\n\n async function resolveConnectionData() {\n if (\n !serverName.value ||\n !props.resolveConnection ||\n connectionData.value ||\n isResolving.value\n ) {\n return\n }\n isResolving.value = true\n try {\n connectionData.value = await props.resolveConnection(\n serverName.value,\n )\n } catch (err) {\n oauthError.value =\n err instanceof Error ? err.message : 'Failed to resolve OAuth'\n } finally {\n isResolving.value = false\n }\n }\n\n watch(\n () => state.value === 'input-available' && serverName.value,\n (ready) => {\n if (ready) {\n resolveConnectionData()\n }\n },\n { immediate: true },\n )\n\n function onMessage(event: MessageEvent) {\n if (event.data?.type !== 'mcp-oauth-complete') {\n return\n }\n if (event.data.mcpServerId !== connectionData.value?.mcpServerId) {\n return\n }\n window.removeEventListener('message', onMessage)\n if (event.data.success) {\n oauthCompleted.value = true\n emit('connected', event.data.mcpServerId)\n } else {\n oauthError.value = event.data.error ?? 'Unknown error'\n }\n }\n\n function openAuthWindow() {\n if (!connectionData.value?.authorizeUrl) {\n return\n }\n oauthError.value = null\n window.addEventListener('message', onMessage)\n const popup = window.open(\n connectionData.value.authorizeUrl,\n 'mcp_oauth',\n 'width=600,height=700,menubar=no,toolbar=no',\n )\n if (!popup) {\n oauthError.value = $t('auth.popupBlocked')\n }\n }\n\n onUnmounted(() => {\n window.removeEventListener('message', onMessage)\n })\n</script>\n\n<template>\n <div class=\"w-full overflow-hidden bg-surface-1 p-sm rounded-xl text-12\">\n <!-- Loading state -->\n <template v-if=\"isResolving\">\n <div class=\"flex items-center gap-8 text-word-3\">\n <VvIcon name=\"line-md:loading-loop\" />\n <span class=\"text-10\">{{\n $t('messagePart.requestOAuthConnection')\n }}</span>\n </div>\n </template>\n\n <!-- Connected successfully -->\n <template v-else-if=\"oauthCompleted\">\n <div class=\"flex items-center gap-8 text-word-3\">\n <VvIcon name=\"ri:check-line\" />\n <strong class=\"text-10\">\n {{\n $t('messagePart.requestOAuthConnectionSuccess', {\n name: serverName,\n })\n }}\n </strong>\n </div>\n </template>\n\n <!-- OAuth error -->\n <template v-else-if=\"oauthError\">\n <div class=\"flex flex-col gap-xs\">\n <div class=\"flex items-center gap-8 text-word-3\">\n <VvIcon name=\"ri:close-line\" class=\"text-danger\" />\n <strong class=\"text-10\">\n {{ oauthError }}\n </strong>\n </div>\n <VvButton\n v-if=\"connectionData\"\n modifiers=\"primary-small\"\n icon=\"ri:external-link-line\"\n :label=\"\n $t('messagePart.requestOAuthConnectionButton', {\n name: serverName,\n })\n \"\n @click=\"openAuthWindow\" />\n </div>\n </template>\n\n <!-- Call ready — show connect button -->\n <template v-else-if=\"connectionData\">\n <div class=\"flex items-center gap-6 text-word-3 mb-xs\">\n <span>\n {{\n $t('messagePart.requestOAuthConnectionPrompt', {\n name: serverName,\n })\n }}\n </span>\n </div>\n <VvButton\n modifiers=\"primary-small\"\n icon=\"ri:external-link-line\"\n :label=\"\n $t('messagePart.requestOAuthConnectionButton', {\n name: serverName,\n })\n \"\n @click=\"openAuthWindow\" />\n </template>\n <!-- Fallback for unknown state -->\n <template v-else>\n <div class=\"flex items-center gap-8 text-word-3\">\n <VvIcon name=\"ri:link-m\" />\n <span class=\"text-10\">\n {{\n $t('messagePart.requestOAuthConnectionInfo', {\n name: serverName,\n })\n }}\n </span>\n </div>\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, onUnmounted, ref, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n\n const props = defineProps<{\n part: unknown\n resolveConnection?: (\n serverName: string,\n ) => Promise<{ mcpServerId: string; authorizeUrl: string }>\n }>()\n\n const emit = defineEmits<{\n connected: [mcpServerId: string]\n }>()\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n const toolPart = computed(() => {\n return props.part as {\n state?: string\n toolCallId?: string\n input?: { serverName: string }\n }\n })\n\n const state = computed(() => toolPart.value.state ?? 'unknown')\n const serverName = computed(() => toolPart.value.input?.serverName)\n\n const connectionData = ref<{\n mcpServerId: string\n authorizeUrl: string\n } | null>(null)\n const isResolving = ref(false)\n const oauthCompleted = ref(false)\n const oauthError = ref<string | null>(null)\n\n async function resolveConnectionData() {\n if (\n !serverName.value ||\n !props.resolveConnection ||\n connectionData.value ||\n isResolving.value\n ) {\n return\n }\n isResolving.value = true\n try {\n connectionData.value = await props.resolveConnection(\n serverName.value,\n )\n } catch (err) {\n oauthError.value =\n err instanceof Error ? err.message : 'Failed to resolve OAuth'\n } finally {\n isResolving.value = false\n }\n }\n\n watch(\n () => state.value === 'input-available' && serverName.value,\n (ready) => {\n if (ready) {\n resolveConnectionData()\n }\n },\n { immediate: true },\n )\n\n function onMessage(event: MessageEvent) {\n if (event.data?.type !== 'mcp-oauth-complete') {\n return\n }\n if (event.data.mcpServerId !== connectionData.value?.mcpServerId) {\n return\n }\n window.removeEventListener('message', onMessage)\n if (event.data.success) {\n oauthCompleted.value = true\n emit('connected', event.data.mcpServerId)\n } else {\n oauthError.value = event.data.error ?? 'Unknown error'\n }\n }\n\n function openAuthWindow() {\n if (!connectionData.value?.authorizeUrl) {\n return\n }\n oauthError.value = null\n window.addEventListener('message', onMessage)\n const popup = window.open(\n connectionData.value.authorizeUrl,\n 'mcp_oauth',\n 'width=600,height=700,menubar=no,toolbar=no',\n )\n if (!popup) {\n oauthError.value = $t('auth.popupBlocked')\n }\n }\n\n onUnmounted(() => {\n window.removeEventListener('message', onMessage)\n })\n</script>\n\n<template>\n <div class=\"w-full overflow-hidden bg-surface-1 p-sm rounded-xl text-12\">\n <!-- Loading state -->\n <template v-if=\"isResolving\">\n <div class=\"flex items-center gap-8 text-word-3\">\n <VvIcon name=\"line-md:loading-loop\" />\n <span class=\"text-10\">{{\n $t('messagePart.requestOAuthConnection')\n }}</span>\n </div>\n </template>\n\n <!-- Connected successfully -->\n <template v-else-if=\"oauthCompleted\">\n <div class=\"flex items-center gap-8 text-word-3\">\n <VvIcon name=\"ri:check-line\" />\n <strong class=\"text-10\">\n {{\n $t('messagePart.requestOAuthConnectionSuccess', {\n name: serverName,\n })\n }}\n </strong>\n </div>\n </template>\n\n <!-- OAuth error -->\n <template v-else-if=\"oauthError\">\n <div class=\"flex flex-col gap-xs\">\n <div class=\"flex items-center gap-8 text-word-3\">\n <VvIcon name=\"ri:close-line\" class=\"text-danger\" />\n <strong class=\"text-10\">\n {{ oauthError }}\n </strong>\n </div>\n <VvButton\n v-if=\"connectionData\"\n modifiers=\"primary-small\"\n icon=\"ri:external-link-line\"\n :label=\"\n $t('messagePart.requestOAuthConnectionButton', {\n name: serverName,\n })\n \"\n @click=\"openAuthWindow\" />\n </div>\n </template>\n\n <!-- Call ready — show connect button -->\n <template v-else-if=\"connectionData\">\n <div class=\"flex items-center gap-6 text-word-3 mb-xs\">\n <span>\n {{\n $t('messagePart.requestOAuthConnectionPrompt', {\n name: serverName,\n })\n }}\n </span>\n </div>\n <VvButton\n modifiers=\"primary-small\"\n icon=\"ri:external-link-line\"\n :label=\"\n $t('messagePart.requestOAuthConnectionButton', {\n name: serverName,\n })\n \"\n @click=\"openAuthWindow\" />\n </template>\n <!-- Fallback for unknown state -->\n <template v-else>\n <div class=\"flex items-center gap-8 text-word-3\">\n <VvIcon name=\"ri:link-m\" />\n <span class=\"text-10\">\n {{\n $t('messagePart.requestOAuthConnectionInfo', {\n name: serverName,\n })\n }}\n </span>\n </div>\n </template>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"PkToolRequestOAuthConnection-BWP5dsK_.js","names":[],"sources":["../../../../packages/components/src/chat/PkToolRequestOAuthConnection.vue","../../../../packages/components/src/chat/PkToolRequestOAuthConnection.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, onUnmounted, ref, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n\n const props = defineProps<{\n part: unknown\n resolveConnection?: (\n serverName: string,\n ) => Promise<{ mcpServerId: string; authorizeUrl: string }>\n }>()\n\n const emit = defineEmits<{\n connected: [mcpServerId: string]\n }>()\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n const toolPart = computed(() => {\n return props.part as {\n state?: string\n toolCallId?: string\n input?: { serverName: string }\n }\n })\n\n const state = computed(() => toolPart.value.state ?? 'unknown')\n const serverName = computed(() => toolPart.value.input?.serverName)\n\n const connectionData = ref<{\n mcpServerId: string\n authorizeUrl: string\n } | null>(null)\n const isResolving = ref(false)\n const oauthCompleted = ref(false)\n const oauthError = ref<string | null>(null)\n\n async function resolveConnectionData() {\n if (\n !serverName.value ||\n !props.resolveConnection ||\n connectionData.value ||\n isResolving.value\n ) {\n return\n }\n isResolving.value = true\n try {\n connectionData.value = await props.resolveConnection(\n serverName.value,\n )\n } catch (err) {\n oauthError.value =\n err instanceof Error ? err.message : 'Failed to resolve OAuth'\n } finally {\n isResolving.value = false\n }\n }\n\n watch(\n () => state.value === 'input-available' && serverName.value,\n (ready) => {\n if (ready) {\n resolveConnectionData()\n }\n },\n { immediate: true },\n )\n\n function onMessage(event: MessageEvent) {\n if (event.data?.type !== 'mcp-oauth-complete') {\n return\n }\n if (event.data.mcpServerId !== connectionData.value?.mcpServerId) {\n return\n }\n window.removeEventListener('message', onMessage)\n if (event.data.success) {\n oauthCompleted.value = true\n emit('connected', event.data.mcpServerId)\n } else {\n oauthError.value = event.data.error ?? 'Unknown error'\n }\n }\n\n function openAuthWindow() {\n if (!connectionData.value?.authorizeUrl) {\n return\n }\n oauthError.value = null\n window.addEventListener('message', onMessage)\n const popup = window.open(\n connectionData.value.authorizeUrl,\n 'mcp_oauth',\n 'width=600,height=700,menubar=no,toolbar=no',\n )\n if (!popup) {\n oauthError.value = $t('auth.popupBlocked')\n }\n }\n\n onUnmounted(() => {\n window.removeEventListener('message', onMessage)\n })\n</script>\n\n<template>\n <div class=\"w-full overflow-hidden bg-surface-1 p-sm rounded-xl text-12\">\n <!-- Loading state -->\n <template v-if=\"isResolving\">\n <div class=\"flex items-center gap-8 text-word-3\">\n <VvIcon name=\"line-md:loading-loop\" />\n <span class=\"text-10\">{{\n $t('messagePart.requestOAuthConnection')\n }}</span>\n </div>\n </template>\n\n <!-- Connected successfully -->\n <template v-else-if=\"oauthCompleted\">\n <div class=\"flex items-center gap-8 text-word-3\">\n <VvIcon name=\"ri:check-line\" />\n <strong class=\"text-10\">\n {{\n $t('messagePart.requestOAuthConnectionSuccess', {\n name: serverName,\n })\n }}\n </strong>\n </div>\n </template>\n\n <!-- OAuth error -->\n <template v-else-if=\"oauthError\">\n <div class=\"flex flex-col gap-xs\">\n <div class=\"flex items-center gap-8 text-word-3\">\n <VvIcon name=\"ri:close-line\" class=\"text-danger\" />\n <strong class=\"text-10\">\n {{ oauthError }}\n </strong>\n </div>\n <VvButton\n v-if=\"connectionData\"\n modifiers=\"primary-small\"\n icon=\"ri:external-link-line\"\n :label=\"\n $t('messagePart.requestOAuthConnectionButton', {\n name: serverName,\n })\n \"\n @click=\"openAuthWindow\" />\n </div>\n </template>\n\n <!-- Call ready — show connect button -->\n <template v-else-if=\"connectionData\">\n <div class=\"flex items-center gap-6 text-word-3 mb-xs\">\n <span>\n {{\n $t('messagePart.requestOAuthConnectionPrompt', {\n name: serverName,\n })\n }}\n </span>\n </div>\n <VvButton\n modifiers=\"primary-small\"\n icon=\"ri:external-link-line\"\n :label=\"\n $t('messagePart.requestOAuthConnectionButton', {\n name: serverName,\n })\n \"\n @click=\"openAuthWindow\" />\n </template>\n <!-- Fallback for unknown state -->\n <template v-else>\n <div class=\"flex items-center gap-8 text-word-3\">\n <VvIcon name=\"ri:link-m\" />\n <span class=\"text-10\">\n {{\n $t('messagePart.requestOAuthConnectionInfo', {\n name: serverName,\n })\n }}\n </span>\n </div>\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, onUnmounted, ref, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n\n const props = defineProps<{\n part: unknown\n resolveConnection?: (\n serverName: string,\n ) => Promise<{ mcpServerId: string; authorizeUrl: string }>\n }>()\n\n const emit = defineEmits<{\n connected: [mcpServerId: string]\n }>()\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n const toolPart = computed(() => {\n return props.part as {\n state?: string\n toolCallId?: string\n input?: { serverName: string }\n }\n })\n\n const state = computed(() => toolPart.value.state ?? 'unknown')\n const serverName = computed(() => toolPart.value.input?.serverName)\n\n const connectionData = ref<{\n mcpServerId: string\n authorizeUrl: string\n } | null>(null)\n const isResolving = ref(false)\n const oauthCompleted = ref(false)\n const oauthError = ref<string | null>(null)\n\n async function resolveConnectionData() {\n if (\n !serverName.value ||\n !props.resolveConnection ||\n connectionData.value ||\n isResolving.value\n ) {\n return\n }\n isResolving.value = true\n try {\n connectionData.value = await props.resolveConnection(\n serverName.value,\n )\n } catch (err) {\n oauthError.value =\n err instanceof Error ? err.message : 'Failed to resolve OAuth'\n } finally {\n isResolving.value = false\n }\n }\n\n watch(\n () => state.value === 'input-available' && serverName.value,\n (ready) => {\n if (ready) {\n resolveConnectionData()\n }\n },\n { immediate: true },\n )\n\n function onMessage(event: MessageEvent) {\n if (event.data?.type !== 'mcp-oauth-complete') {\n return\n }\n if (event.data.mcpServerId !== connectionData.value?.mcpServerId) {\n return\n }\n window.removeEventListener('message', onMessage)\n if (event.data.success) {\n oauthCompleted.value = true\n emit('connected', event.data.mcpServerId)\n } else {\n oauthError.value = event.data.error ?? 'Unknown error'\n }\n }\n\n function openAuthWindow() {\n if (!connectionData.value?.authorizeUrl) {\n return\n }\n oauthError.value = null\n window.addEventListener('message', onMessage)\n const popup = window.open(\n connectionData.value.authorizeUrl,\n 'mcp_oauth',\n 'width=600,height=700,menubar=no,toolbar=no',\n )\n if (!popup) {\n oauthError.value = $t('auth.popupBlocked')\n }\n }\n\n onUnmounted(() => {\n window.removeEventListener('message', onMessage)\n })\n</script>\n\n<template>\n <div class=\"w-full overflow-hidden bg-surface-1 p-sm rounded-xl text-12\">\n <!-- Loading state -->\n <template v-if=\"isResolving\">\n <div class=\"flex items-center gap-8 text-word-3\">\n <VvIcon name=\"line-md:loading-loop\" />\n <span class=\"text-10\">{{\n $t('messagePart.requestOAuthConnection')\n }}</span>\n </div>\n </template>\n\n <!-- Connected successfully -->\n <template v-else-if=\"oauthCompleted\">\n <div class=\"flex items-center gap-8 text-word-3\">\n <VvIcon name=\"ri:check-line\" />\n <strong class=\"text-10\">\n {{\n $t('messagePart.requestOAuthConnectionSuccess', {\n name: serverName,\n })\n }}\n </strong>\n </div>\n </template>\n\n <!-- OAuth error -->\n <template v-else-if=\"oauthError\">\n <div class=\"flex flex-col gap-xs\">\n <div class=\"flex items-center gap-8 text-word-3\">\n <VvIcon name=\"ri:close-line\" class=\"text-danger\" />\n <strong class=\"text-10\">\n {{ oauthError }}\n </strong>\n </div>\n <VvButton\n v-if=\"connectionData\"\n modifiers=\"primary-small\"\n icon=\"ri:external-link-line\"\n :label=\"\n $t('messagePart.requestOAuthConnectionButton', {\n name: serverName,\n })\n \"\n @click=\"openAuthWindow\" />\n </div>\n </template>\n\n <!-- Call ready — show connect button -->\n <template v-else-if=\"connectionData\">\n <div class=\"flex items-center gap-6 text-word-3 mb-xs\">\n <span>\n {{\n $t('messagePart.requestOAuthConnectionPrompt', {\n name: serverName,\n })\n }}\n </span>\n </div>\n <VvButton\n modifiers=\"primary-small\"\n icon=\"ri:external-link-line\"\n :label=\"\n $t('messagePart.requestOAuthConnectionButton', {\n name: serverName,\n })\n \"\n @click=\"openAuthWindow\" />\n </template>\n <!-- Fallback for unknown state -->\n <template v-else>\n <div class=\"flex items-center gap-8 text-word-3\">\n <VvIcon name=\"ri:link-m\" />\n <span class=\"text-10\">\n {{\n $t('messagePart.requestOAuthConnectionInfo', {\n name: serverName,\n })\n }}\n </span>\n </div>\n </template>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { A as e, C as t, Ht as n, Q as r, S as i, T as a, _ as o, at as s, b as c, g as l, kt as u, mt as d, qt as f, v as p, xt as m, z as h } from "./vue.runtime.esm-bundler-DbhD_IvR.js";
2
- import { i as g } from "./dist-BNET2z7b.js";
3
- import { p as _ } from "./index.es-BYny0uhz.js";
4
- import { t as v } from "./PkStreamingMarkdown-Djw604Ny.js";
2
+ import { t as g } from "./PkStreamingMarkdown-6Xx9n1ue.js";
3
+ import { i as _ } from "./dist-CvMCBce7.js";
4
+ import { d as v } from "./index.es-_oXVRjHy.js";
5
5
  e(), u(), s();
6
6
  var y = ["innerHTML"], b = /* @__PURE__ */ a({
7
7
  inheritAttrs: !1,
@@ -41,7 +41,7 @@ var x = { class: "border border-surface-3 rounded-xl w-full overflow-hidden" },
41
41
  __name: "PkToolShowArtifact",
42
42
  props: { part: { type: null } },
43
43
  setup(e) {
44
- let { copy: r, copied: i } = g(), a = e, s = l(() => a.part), u = l(() => s.value.input?.artifactType && {
44
+ let { copy: r, copied: i } = _(), a = e, s = l(() => a.part), u = l(() => s.value.input?.artifactType && {
45
45
  code: "Code",
46
46
  document: "Document",
47
47
  markdown: "Markdown",
@@ -60,7 +60,7 @@ var x = { class: "border border-surface-3 rounded-xl w-full overflow-hidden" },
60
60
  sql: "sql"
61
61
  }[s.value.input.artifactType] || "plaintext");
62
62
  return (e, a) => {
63
- let l = _;
63
+ let l = v;
64
64
  return h(), c("div", x, [o("div", S, [o("div", C, [o("span", null, f(s.value?.input?.title), 1), o("span", w, f(u.value) + f(d.value), 1)]), t(l, {
65
65
  icon: m(i) ? "ri:check-line" : "ri:file-copy-line",
66
66
  label: m(i) ? e.$t("action.copied") : e.$t("action.copy"),
@@ -76,7 +76,7 @@ var x = { class: "border border-surface-3 rounded-xl w-full overflow-hidden" },
76
76
  key: 0,
77
77
  code: s.value?.input?.content,
78
78
  language: D.value
79
- }, null, 8, ["code", "language"])) : E.value ? (h(), p(v, {
79
+ }, null, 8, ["code", "language"])) : E.value ? (h(), p(g, {
80
80
  key: 1,
81
81
  markdown: s.value?.input?.content,
82
82
  class: "wysiwyg text-word-2"
@@ -90,4 +90,4 @@ var x = { class: "border border-surface-3 rounded-xl w-full overflow-hidden" },
90
90
  //#endregion
91
91
  export { E as default };
92
92
 
93
- //# sourceMappingURL=PkToolShowArtifact-BaGEr7O9.js.map
93
+ //# sourceMappingURL=PkToolShowArtifact-bYYaMGxq.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PkToolShowArtifact-BaGEr7O9.js","names":["$attrs","$t"],"sources":["../../../../packages/components/src/chat/PkCode.vue","../../../../packages/components/src/chat/PkCode.vue","../../../../packages/components/src/chat/PkToolShowArtifact.vue","../../../../packages/components/src/chat/PkToolShowArtifact.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, ref, watch } from 'vue'\n\n defineOptions({\n inheritAttrs: false,\n })\n\n const props = defineProps<{\n code: unknown\n language: string\n line?: boolean\n }>()\n\n const highlightedHtml = ref('')\n\n const hasCode = computed(() => {\n if (typeof props.code === 'string') {\n return props.code\n }\n return JSON.stringify(props.code, null, 2)\n })\n\n async function highlight() {\n const hljs = (await import('highlight.js/lib/common')).default\n try {\n const result = props.language\n ? hljs.highlight(hasCode.value, { language: props.language })\n : hljs.highlightAuto(hasCode.value)\n highlightedHtml.value = result.value\n } catch {\n highlightedHtml.value = hasCode.value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n }\n }\n\n watch(hasCode, highlight, { immediate: true })\n</script>\n\n<template>\n <pre\n :class=\"\n $attrs.class\n ? $attrs.class\n : 'font-mono leading-snug text-smaller bg-surface-1'\n \">\n <code :class=\"['hljs', line ? 'whitespace-pre-line' : 'whitespace-pre', language]\" v-html=\"highlightedHtml\"></code>\n </pre>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, watch } from 'vue'\n\n defineOptions({\n inheritAttrs: false,\n })\n\n const props = defineProps<{\n code: unknown\n language: string\n line?: boolean\n }>()\n\n const highlightedHtml = ref('')\n\n const hasCode = computed(() => {\n if (typeof props.code === 'string') {\n return props.code\n }\n return JSON.stringify(props.code, null, 2)\n })\n\n async function highlight() {\n const hljs = (await import('highlight.js/lib/common')).default\n try {\n const result = props.language\n ? hljs.highlight(hasCode.value, { language: props.language })\n : hljs.highlightAuto(hasCode.value)\n highlightedHtml.value = result.value\n } catch {\n highlightedHtml.value = hasCode.value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n }\n }\n\n watch(hasCode, highlight, { immediate: true })\n</script>\n\n<template>\n <pre\n :class=\"\n $attrs.class\n ? $attrs.class\n : 'font-mono leading-snug text-smaller bg-surface-1'\n \">\n <code :class=\"['hljs', line ? 'whitespace-pre-line' : 'whitespace-pre', language]\" v-html=\"highlightedHtml\"></code>\n </pre>\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import PkCode from './PkCode.vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const { copy, copied } = useClipboard()\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title: string\n content: string\n artifactType: string\n language?: string\n }\n }\n return part\n })\n\n const artifactTypeLabel = computed(() => {\n const labels: Record<string, string> = {\n code: 'Code',\n document: 'Document',\n markdown: 'Markdown',\n json: 'JSON',\n xml: 'XML',\n csv: 'CSV',\n html: 'HTML',\n yaml: 'YAML',\n sql: 'SQL',\n text: 'Text',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'Artifact'\n }\n return labels[toolPart.value.input.artifactType] || 'Artifact'\n })\n\n const languageLabel = computed(() => {\n if (!toolPart.value.input?.language) {\n return ''\n }\n return ` (${toolPart.value.input.language})`\n })\n\n const isCodeType = computed(() => {\n return (\n toolPart.value.input?.artifactType === 'code' ||\n toolPart.value.input?.artifactType === 'json' ||\n toolPart.value.input?.artifactType === 'xml' ||\n toolPart.value.input?.artifactType === 'yaml' ||\n toolPart.value.input?.artifactType === 'html' ||\n toolPart.value.input?.artifactType === 'sql'\n )\n })\n\n const isMarkdownType = computed(() => {\n return toolPart.value.input?.artifactType === 'markdown'\n })\n\n const codeLanguage = computed(() => {\n if (toolPart.value.input?.language) {\n return toolPart.value.input.language\n }\n // Map artifact types to highlight.js languages\n const languageMap: Record<string, string> = {\n json: 'json',\n xml: 'xml',\n yaml: 'yaml',\n html: 'html',\n sql: 'sql',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'plaintext'\n }\n return languageMap[toolPart.value.input.artifactType] || 'plaintext'\n })\n</script>\n\n<template>\n <div class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\n <div\n class=\"px-sm py-6 font-bold bg-surface-1 text-12 border-b border-surface-3 text-word-3 flex justify-between items-center\">\n <div class=\"flex flex-col items-start gap-4\">\n <span>{{ toolPart?.input?.title }}</span>\n <span class=\"text-10 opacity-60 font-normal\">\n {{ artifactTypeLabel }}{{ languageLabel }}\n </span>\n </div>\n <VvButton\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n modifiers=\"action-quiet-small\"\n :title=\"$t('action.copy')\"\n class=\"shrink-0\"\n @click=\"copy(toolPart?.input?.content || '')\" />\n </div>\n <div class=\"px-sm py-10 bg-surface\">\n <PkCode\n v-if=\"isCodeType\"\n :code=\"toolPart?.input?.content\"\n :language=\"codeLanguage\" />\n <PkStreamingMarkdown\n v-else-if=\"isMarkdownType\"\n :markdown=\"toolPart?.input?.content\"\n class=\"wysiwyg text-word-2\" />\n <pre\n v-else\n class=\"text-word-2 whitespace-pre-wrap break-words\"\n :class=\"{\n italic:\n toolPart?.input?.artifactType === 'document' ||\n toolPart?.input?.artifactType === 'text',\n }\"\n >{{ toolPart?.input?.content }}</pre>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import PkCode from './PkCode.vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const { copy, copied } = useClipboard()\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title: string\n content: string\n artifactType: string\n language?: string\n }\n }\n return part\n })\n\n const artifactTypeLabel = computed(() => {\n const labels: Record<string, string> = {\n code: 'Code',\n document: 'Document',\n markdown: 'Markdown',\n json: 'JSON',\n xml: 'XML',\n csv: 'CSV',\n html: 'HTML',\n yaml: 'YAML',\n sql: 'SQL',\n text: 'Text',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'Artifact'\n }\n return labels[toolPart.value.input.artifactType] || 'Artifact'\n })\n\n const languageLabel = computed(() => {\n if (!toolPart.value.input?.language) {\n return ''\n }\n return ` (${toolPart.value.input.language})`\n })\n\n const isCodeType = computed(() => {\n return (\n toolPart.value.input?.artifactType === 'code' ||\n toolPart.value.input?.artifactType === 'json' ||\n toolPart.value.input?.artifactType === 'xml' ||\n toolPart.value.input?.artifactType === 'yaml' ||\n toolPart.value.input?.artifactType === 'html' ||\n toolPart.value.input?.artifactType === 'sql'\n )\n })\n\n const isMarkdownType = computed(() => {\n return toolPart.value.input?.artifactType === 'markdown'\n })\n\n const codeLanguage = computed(() => {\n if (toolPart.value.input?.language) {\n return toolPart.value.input.language\n }\n // Map artifact types to highlight.js languages\n const languageMap: Record<string, string> = {\n json: 'json',\n xml: 'xml',\n yaml: 'yaml',\n html: 'html',\n sql: 'sql',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'plaintext'\n }\n return languageMap[toolPart.value.input.artifactType] || 'plaintext'\n })\n</script>\n\n<template>\n <div class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\n <div\n class=\"px-sm py-6 font-bold bg-surface-1 text-12 border-b border-surface-3 text-word-3 flex justify-between items-center\">\n <div class=\"flex flex-col items-start gap-4\">\n <span>{{ toolPart?.input?.title }}</span>\n <span class=\"text-10 opacity-60 font-normal\">\n {{ artifactTypeLabel }}{{ languageLabel }}\n </span>\n </div>\n <VvButton\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n modifiers=\"action-quiet-small\"\n :title=\"$t('action.copy')\"\n class=\"shrink-0\"\n @click=\"copy(toolPart?.input?.content || '')\" />\n </div>\n <div class=\"px-sm py-10 bg-surface\">\n <PkCode\n v-if=\"isCodeType\"\n :code=\"toolPart?.input?.content\"\n :language=\"codeLanguage\" />\n <PkStreamingMarkdown\n v-else-if=\"isMarkdownType\"\n :markdown=\"toolPart?.input?.content\"\n class=\"wysiwyg text-word-2\" />\n <pre\n v-else\n class=\"text-word-2 whitespace-pre-wrap break-words\"\n :class=\"{\n italic:\n toolPart?.input?.artifactType === 'document' ||\n toolPart?.input?.artifactType === 'text',\n }\"\n >{{ toolPart?.input?.content }}</pre>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"PkToolShowArtifact-bYYaMGxq.js","names":["$attrs","$t"],"sources":["../../../../packages/components/src/chat/PkCode.vue","../../../../packages/components/src/chat/PkCode.vue","../../../../packages/components/src/chat/PkToolShowArtifact.vue","../../../../packages/components/src/chat/PkToolShowArtifact.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, ref, watch } from 'vue'\n\n defineOptions({\n inheritAttrs: false,\n })\n\n const props = defineProps<{\n code: unknown\n language: string\n line?: boolean\n }>()\n\n const highlightedHtml = ref('')\n\n const hasCode = computed(() => {\n if (typeof props.code === 'string') {\n return props.code\n }\n return JSON.stringify(props.code, null, 2)\n })\n\n async function highlight() {\n const hljs = (await import('highlight.js/lib/common')).default\n try {\n const result = props.language\n ? hljs.highlight(hasCode.value, { language: props.language })\n : hljs.highlightAuto(hasCode.value)\n highlightedHtml.value = result.value\n } catch {\n highlightedHtml.value = hasCode.value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n }\n }\n\n watch(hasCode, highlight, { immediate: true })\n</script>\n\n<template>\n <pre\n :class=\"\n $attrs.class\n ? $attrs.class\n : 'font-mono leading-snug text-smaller bg-surface-1'\n \">\n <code :class=\"['hljs', line ? 'whitespace-pre-line' : 'whitespace-pre', language]\" v-html=\"highlightedHtml\"></code>\n </pre>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, watch } from 'vue'\n\n defineOptions({\n inheritAttrs: false,\n })\n\n const props = defineProps<{\n code: unknown\n language: string\n line?: boolean\n }>()\n\n const highlightedHtml = ref('')\n\n const hasCode = computed(() => {\n if (typeof props.code === 'string') {\n return props.code\n }\n return JSON.stringify(props.code, null, 2)\n })\n\n async function highlight() {\n const hljs = (await import('highlight.js/lib/common')).default\n try {\n const result = props.language\n ? hljs.highlight(hasCode.value, { language: props.language })\n : hljs.highlightAuto(hasCode.value)\n highlightedHtml.value = result.value\n } catch {\n highlightedHtml.value = hasCode.value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n }\n }\n\n watch(hasCode, highlight, { immediate: true })\n</script>\n\n<template>\n <pre\n :class=\"\n $attrs.class\n ? $attrs.class\n : 'font-mono leading-snug text-smaller bg-surface-1'\n \">\n <code :class=\"['hljs', line ? 'whitespace-pre-line' : 'whitespace-pre', language]\" v-html=\"highlightedHtml\"></code>\n </pre>\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import PkCode from './PkCode.vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const { copy, copied } = useClipboard()\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title: string\n content: string\n artifactType: string\n language?: string\n }\n }\n return part\n })\n\n const artifactTypeLabel = computed(() => {\n const labels: Record<string, string> = {\n code: 'Code',\n document: 'Document',\n markdown: 'Markdown',\n json: 'JSON',\n xml: 'XML',\n csv: 'CSV',\n html: 'HTML',\n yaml: 'YAML',\n sql: 'SQL',\n text: 'Text',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'Artifact'\n }\n return labels[toolPart.value.input.artifactType] || 'Artifact'\n })\n\n const languageLabel = computed(() => {\n if (!toolPart.value.input?.language) {\n return ''\n }\n return ` (${toolPart.value.input.language})`\n })\n\n const isCodeType = computed(() => {\n return (\n toolPart.value.input?.artifactType === 'code' ||\n toolPart.value.input?.artifactType === 'json' ||\n toolPart.value.input?.artifactType === 'xml' ||\n toolPart.value.input?.artifactType === 'yaml' ||\n toolPart.value.input?.artifactType === 'html' ||\n toolPart.value.input?.artifactType === 'sql'\n )\n })\n\n const isMarkdownType = computed(() => {\n return toolPart.value.input?.artifactType === 'markdown'\n })\n\n const codeLanguage = computed(() => {\n if (toolPart.value.input?.language) {\n return toolPart.value.input.language\n }\n // Map artifact types to highlight.js languages\n const languageMap: Record<string, string> = {\n json: 'json',\n xml: 'xml',\n yaml: 'yaml',\n html: 'html',\n sql: 'sql',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'plaintext'\n }\n return languageMap[toolPart.value.input.artifactType] || 'plaintext'\n })\n</script>\n\n<template>\n <div class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\n <div\n class=\"px-sm py-6 font-bold bg-surface-1 text-12 border-b border-surface-3 text-word-3 flex justify-between items-center\">\n <div class=\"flex flex-col items-start gap-4\">\n <span>{{ toolPart?.input?.title }}</span>\n <span class=\"text-10 opacity-60 font-normal\">\n {{ artifactTypeLabel }}{{ languageLabel }}\n </span>\n </div>\n <VvButton\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n modifiers=\"action-quiet-small\"\n :title=\"$t('action.copy')\"\n class=\"shrink-0\"\n @click=\"copy(toolPart?.input?.content || '')\" />\n </div>\n <div class=\"px-sm py-10 bg-surface\">\n <PkCode\n v-if=\"isCodeType\"\n :code=\"toolPart?.input?.content\"\n :language=\"codeLanguage\" />\n <PkStreamingMarkdown\n v-else-if=\"isMarkdownType\"\n :markdown=\"toolPart?.input?.content\"\n class=\"wysiwyg text-word-2\" />\n <pre\n v-else\n class=\"text-word-2 whitespace-pre-wrap break-words\"\n :class=\"{\n italic:\n toolPart?.input?.artifactType === 'document' ||\n toolPart?.input?.artifactType === 'text',\n }\"\n >{{ toolPart?.input?.content }}</pre>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import PkCode from './PkCode.vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const { copy, copied } = useClipboard()\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title: string\n content: string\n artifactType: string\n language?: string\n }\n }\n return part\n })\n\n const artifactTypeLabel = computed(() => {\n const labels: Record<string, string> = {\n code: 'Code',\n document: 'Document',\n markdown: 'Markdown',\n json: 'JSON',\n xml: 'XML',\n csv: 'CSV',\n html: 'HTML',\n yaml: 'YAML',\n sql: 'SQL',\n text: 'Text',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'Artifact'\n }\n return labels[toolPart.value.input.artifactType] || 'Artifact'\n })\n\n const languageLabel = computed(() => {\n if (!toolPart.value.input?.language) {\n return ''\n }\n return ` (${toolPart.value.input.language})`\n })\n\n const isCodeType = computed(() => {\n return (\n toolPart.value.input?.artifactType === 'code' ||\n toolPart.value.input?.artifactType === 'json' ||\n toolPart.value.input?.artifactType === 'xml' ||\n toolPart.value.input?.artifactType === 'yaml' ||\n toolPart.value.input?.artifactType === 'html' ||\n toolPart.value.input?.artifactType === 'sql'\n )\n })\n\n const isMarkdownType = computed(() => {\n return toolPart.value.input?.artifactType === 'markdown'\n })\n\n const codeLanguage = computed(() => {\n if (toolPart.value.input?.language) {\n return toolPart.value.input.language\n }\n // Map artifact types to highlight.js languages\n const languageMap: Record<string, string> = {\n json: 'json',\n xml: 'xml',\n yaml: 'yaml',\n html: 'html',\n sql: 'sql',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'plaintext'\n }\n return languageMap[toolPart.value.input.artifactType] || 'plaintext'\n })\n</script>\n\n<template>\n <div class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\n <div\n class=\"px-sm py-6 font-bold bg-surface-1 text-12 border-b border-surface-3 text-word-3 flex justify-between items-center\">\n <div class=\"flex flex-col items-start gap-4\">\n <span>{{ toolPart?.input?.title }}</span>\n <span class=\"text-10 opacity-60 font-normal\">\n {{ artifactTypeLabel }}{{ languageLabel }}\n </span>\n </div>\n <VvButton\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n modifiers=\"action-quiet-small\"\n :title=\"$t('action.copy')\"\n class=\"shrink-0\"\n @click=\"copy(toolPart?.input?.content || '')\" />\n </div>\n <div class=\"px-sm py-10 bg-surface\">\n <PkCode\n v-if=\"isCodeType\"\n :code=\"toolPart?.input?.content\"\n :language=\"codeLanguage\" />\n <PkStreamingMarkdown\n v-else-if=\"isMarkdownType\"\n :markdown=\"toolPart?.input?.content\"\n class=\"wysiwyg text-word-2\" />\n <pre\n v-else\n class=\"text-word-2 whitespace-pre-wrap break-words\"\n :class=\"{\n italic:\n toolPart?.input?.artifactType === 'document' ||\n toolPart?.input?.artifactType === 'text',\n }\"\n >{{ toolPart?.input?.content }}</pre>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
@@ -2,8 +2,8 @@ import { A as e, C as t, D as n, S as r, T as i, Ut as a, _ as o, at as s, b as
2
2
  import { r as g } from "./vue-i18n-kZs9Hfey.js";
3
3
  import "./src-BGqVtumX.js";
4
4
  import { n as _ } from "./url-validation-uLMZ5-AU.js";
5
- import { i as v } from "./dist-BNET2z7b.js";
6
- import { d as y, l as b, n as x, p as S, u as C } from "./index.es-BYny0uhz.js";
5
+ import { i as v } from "./dist-CvMCBce7.js";
6
+ import { d as y, f as b, i as x, l as S, t as C } from "./index.es-_oXVRjHy.js";
7
7
  e(), d(), s();
8
8
  var w = {
9
9
  key: 0,
@@ -71,7 +71,7 @@ var w = {
71
71
  e.location && t.push(e.location), e.additionalInfo && t.push(e.additionalInfo), s(t.join("\n"));
72
72
  };
73
73
  return (e, i) => {
74
- let s = b, u = S, g = C, v = y, z = x;
74
+ let s = b, u = y, g = C, v = S, z = x;
75
75
  return B.value?.input ? (h(), c("div", w, [o("div", T, [
76
76
  t(s, {
77
77
  name: "ri:calendar-event-line",
@@ -144,4 +144,4 @@ var w = {
144
144
  //#endregion
145
145
  export { z as default };
146
146
 
147
- //# sourceMappingURL=PkToolShowCalendarEvent-BYnhl2er.js.map
147
+ //# sourceMappingURL=PkToolShowCalendarEvent-DdEWaTj-.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PkToolShowCalendarEvent-BYnhl2er.js","names":["$t"],"sources":["../../../../packages/components/src/chat/PkToolShowCalendarEvent.vue","../../../../packages/components/src/chat/PkToolShowCalendarEvent.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useClipboard } from '@vueuse/core'\n import { isSameSite } from 'utils'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n const { d } = useI18n()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title: string\n startDate: string\n endDate: string\n location?: string\n additionalInfo?: string\n allDay?: boolean\n }\n }\n return part\n })\n\n const dateDisplay = computed(() => {\n const input = toolPart.value.input\n if (!input) {\n return ''\n }\n const { startDate, endDate, allDay } = input\n const start = new Date(startDate)\n const end = new Date(endDate)\n const startDay = startDate.slice(0, 10)\n const endDay = endDate.slice(0, 10)\n if (allDay) {\n if (startDay === endDay) {\n return d(start, 'date-medium')\n }\n return `${d(start, 'date-medium')} - ${d(end, 'date-medium')}`\n }\n if (startDay === endDay) {\n return `${d(start, 'date-time-medium')} - ${d(end, 'time')}`\n }\n return `${d(start, 'date-time-medium')} - ${d(end, 'date-time-medium')}`\n })\n\n const calendarStart = computed(() =>\n toolPart.value.input ? new Date(toolPart.value.input.startDate) : null,\n )\n\n const calendarDay = computed(\n () => calendarStart.value?.getDate().toString() ?? '',\n )\n\n const calendarMonth = computed(() =>\n calendarStart.value ? d(calendarStart.value, 'month-short') : '',\n )\n\n // Floating time: remove dashes/colons without converting to UTC\n const toIcsDateTime = (iso: string) =>\n iso.replace(/[-:]/g, '').replace(/\\.\\d{3}$/, '')\n\n const escapeIcs = (str: string) =>\n str\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/;/g, '\\\\;')\n .replace(/,/g, '\\\\,')\n .replace(/\\n/g, '\\\\n')\n\n const generateIcs = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const { title, startDate, endDate, location, additionalInfo } = input\n const ics = [\n 'BEGIN:VCALENDAR',\n 'VERSION:2.0',\n 'PRODID:-//8wave//8bot//EN',\n 'BEGIN:VEVENT',\n `DTSTART:${toIcsDateTime(startDate)}`,\n `DTEND:${toIcsDateTime(endDate)}`,\n `SUMMARY:${escapeIcs(title)}`,\n location ? `LOCATION:${escapeIcs(location)}` : '',\n additionalInfo ? `DESCRIPTION:${escapeIcs(additionalInfo)}` : '',\n `DTSTAMP:${new Date()\n .toISOString()\n .replace(/[-:]/g, '')\n .replace(/\\.\\d{3}/, '')}`,\n `UID:${crypto.randomUUID()}@8bot.ai`,\n 'END:VEVENT',\n 'END:VCALENDAR',\n ]\n .filter(Boolean)\n .join('\\r\\n')\n\n const blob = new Blob([ics], { type: 'text/calendar;charset=utf-8' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = `${title.replace(/[^a-zA-Z0-9\\s-]/g, '')}.ics`\n a.click()\n URL.revokeObjectURL(url)\n }\n\n const openGoogleCalendar = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const { title, startDate, endDate, location, additionalInfo } = input\n const start = toIcsDateTime(startDate)\n const end = toIcsDateTime(endDate)\n const params = new URLSearchParams({\n action: 'TEMPLATE',\n text: title,\n dates: `${start}/${end}`,\n })\n if (location) {\n params.set('location', location)\n }\n if (additionalInfo) {\n params.set('details', additionalInfo)\n }\n window.open(\n `https://calendar.google.com/calendar/render?${params.toString()}`,\n '_blank',\n )\n }\n\n const openOutlook = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const { title, startDate, endDate, location, additionalInfo } = input\n const params = new URLSearchParams({\n subject: title,\n startdt: startDate,\n enddt: endDate,\n })\n if (location) {\n params.set('location', location)\n }\n if (additionalInfo) {\n params.set('body', additionalInfo)\n }\n window.open(\n `https://outlook.office.com/calendar/0/action/compose?${params.toString()}`,\n '_blank',\n )\n }\n\n const copyEvent = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const lines = [input.title, dateDisplay.value]\n if (input.location) {\n lines.push(input.location)\n }\n if (input.additionalInfo) {\n lines.push(input.additionalInfo)\n }\n copy(lines.join('\\n'))\n }\n</script>\n\n<template>\n <div\n v-if=\"toolPart?.input\"\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\">\n <VvIcon name=\"ri:calendar-event-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{ $t('label.calendarEvent') }}</strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copyEvent\" />\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n strategy: 'fixed',\n }\">\n <VvButton\n icon=\"ri:calendar-line\"\n modifiers=\"action-quiet-small\"\n :label=\"$t('action.addToCalendar')\" />\n <template #items>\n <VvDropdownAction @click=\"openGoogleCalendar\">\n <VvIcon name=\"ri:google-line\" />\n Google Calendar\n </VvDropdownAction>\n <VvDropdownAction @click=\"openOutlook\">\n <VvIcon name=\"ri:microsoft-line\" />\n Outlook\n </VvDropdownAction>\n <VvDropdownAction @click=\"generateIcs\">\n <VvIcon name=\"ri:download-line\" />\n {{ $t('action.downloadIcs') }}\n </VvDropdownAction>\n </template>\n </VvDropdown>\n </VvButtonGroup>\n </div>\n <div class=\"p-sm flex gap-sm items-start\">\n <div\n class=\"shrink-0 w-44 rounded-xl overflow-hidden border border-surface-3 text-center select-none\">\n <div\n class=\"bg-brand px-8 py-2 text-white text-10 font-bold uppercase tracking-wide\">\n {{ calendarMonth }}\n </div>\n <div\n class=\"bg-surface-1 py-4 text-word-1 text-24 font-bold leading-none\">\n {{ calendarDay }}\n </div>\n </div>\n <div class=\"flex flex-col gap-4 min-w-0\">\n <p class=\"font-semibold text-word-1 text-14\">\n {{ toolPart.input.title }}\n </p>\n <div class=\"flex items-center gap-8 text-12 text-word-3\">\n <VvIcon name=\"ri:time-line\" class=\"text-14 shrink-0\" />\n <time :datetime=\"toolPart.input.startDate\">{{\n dateDisplay\n }}</time>\n </div>\n <div\n v-if=\"toolPart.input.location\"\n class=\"flex items-center gap-8 text-12 text-word-3\">\n <VvIcon name=\"ri:map-pin-line\" class=\"text-14 shrink-0\" />\n <a\n v-if=\"toolPart.input.location.startsWith('http')\"\n :href=\"toolPart.input.location\"\n :target=\"\n isSameSite(toolPart.input.location)\n ? undefined\n : '_blank'\n \"\n :rel=\"\n isSameSite(toolPart.input.location)\n ? undefined\n : 'noopener noreferrer'\n \"\n class=\"underline truncate\">\n {{ toolPart.input.location }}\n </a>\n <span v-else>{{ toolPart.input.location }}</span>\n </div>\n <div\n v-if=\"toolPart.input.additionalInfo\"\n class=\"flex items-start gap-8 text-12 text-word-3\">\n <VvIcon\n name=\"ri:sticky-note-line\"\n class=\"text-14 shrink-0 mt-1\" />\n <span>{{ toolPart.input.additionalInfo }}</span>\n </div>\n </div>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useClipboard } from '@vueuse/core'\n import { isSameSite } from 'utils'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n const { d } = useI18n()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title: string\n startDate: string\n endDate: string\n location?: string\n additionalInfo?: string\n allDay?: boolean\n }\n }\n return part\n })\n\n const dateDisplay = computed(() => {\n const input = toolPart.value.input\n if (!input) {\n return ''\n }\n const { startDate, endDate, allDay } = input\n const start = new Date(startDate)\n const end = new Date(endDate)\n const startDay = startDate.slice(0, 10)\n const endDay = endDate.slice(0, 10)\n if (allDay) {\n if (startDay === endDay) {\n return d(start, 'date-medium')\n }\n return `${d(start, 'date-medium')} - ${d(end, 'date-medium')}`\n }\n if (startDay === endDay) {\n return `${d(start, 'date-time-medium')} - ${d(end, 'time')}`\n }\n return `${d(start, 'date-time-medium')} - ${d(end, 'date-time-medium')}`\n })\n\n const calendarStart = computed(() =>\n toolPart.value.input ? new Date(toolPart.value.input.startDate) : null,\n )\n\n const calendarDay = computed(\n () => calendarStart.value?.getDate().toString() ?? '',\n )\n\n const calendarMonth = computed(() =>\n calendarStart.value ? d(calendarStart.value, 'month-short') : '',\n )\n\n // Floating time: remove dashes/colons without converting to UTC\n const toIcsDateTime = (iso: string) =>\n iso.replace(/[-:]/g, '').replace(/\\.\\d{3}$/, '')\n\n const escapeIcs = (str: string) =>\n str\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/;/g, '\\\\;')\n .replace(/,/g, '\\\\,')\n .replace(/\\n/g, '\\\\n')\n\n const generateIcs = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const { title, startDate, endDate, location, additionalInfo } = input\n const ics = [\n 'BEGIN:VCALENDAR',\n 'VERSION:2.0',\n 'PRODID:-//8wave//8bot//EN',\n 'BEGIN:VEVENT',\n `DTSTART:${toIcsDateTime(startDate)}`,\n `DTEND:${toIcsDateTime(endDate)}`,\n `SUMMARY:${escapeIcs(title)}`,\n location ? `LOCATION:${escapeIcs(location)}` : '',\n additionalInfo ? `DESCRIPTION:${escapeIcs(additionalInfo)}` : '',\n `DTSTAMP:${new Date()\n .toISOString()\n .replace(/[-:]/g, '')\n .replace(/\\.\\d{3}/, '')}`,\n `UID:${crypto.randomUUID()}@8bot.ai`,\n 'END:VEVENT',\n 'END:VCALENDAR',\n ]\n .filter(Boolean)\n .join('\\r\\n')\n\n const blob = new Blob([ics], { type: 'text/calendar;charset=utf-8' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = `${title.replace(/[^a-zA-Z0-9\\s-]/g, '')}.ics`\n a.click()\n URL.revokeObjectURL(url)\n }\n\n const openGoogleCalendar = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const { title, startDate, endDate, location, additionalInfo } = input\n const start = toIcsDateTime(startDate)\n const end = toIcsDateTime(endDate)\n const params = new URLSearchParams({\n action: 'TEMPLATE',\n text: title,\n dates: `${start}/${end}`,\n })\n if (location) {\n params.set('location', location)\n }\n if (additionalInfo) {\n params.set('details', additionalInfo)\n }\n window.open(\n `https://calendar.google.com/calendar/render?${params.toString()}`,\n '_blank',\n )\n }\n\n const openOutlook = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const { title, startDate, endDate, location, additionalInfo } = input\n const params = new URLSearchParams({\n subject: title,\n startdt: startDate,\n enddt: endDate,\n })\n if (location) {\n params.set('location', location)\n }\n if (additionalInfo) {\n params.set('body', additionalInfo)\n }\n window.open(\n `https://outlook.office.com/calendar/0/action/compose?${params.toString()}`,\n '_blank',\n )\n }\n\n const copyEvent = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const lines = [input.title, dateDisplay.value]\n if (input.location) {\n lines.push(input.location)\n }\n if (input.additionalInfo) {\n lines.push(input.additionalInfo)\n }\n copy(lines.join('\\n'))\n }\n</script>\n\n<template>\n <div\n v-if=\"toolPart?.input\"\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\">\n <VvIcon name=\"ri:calendar-event-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{ $t('label.calendarEvent') }}</strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copyEvent\" />\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n strategy: 'fixed',\n }\">\n <VvButton\n icon=\"ri:calendar-line\"\n modifiers=\"action-quiet-small\"\n :label=\"$t('action.addToCalendar')\" />\n <template #items>\n <VvDropdownAction @click=\"openGoogleCalendar\">\n <VvIcon name=\"ri:google-line\" />\n Google Calendar\n </VvDropdownAction>\n <VvDropdownAction @click=\"openOutlook\">\n <VvIcon name=\"ri:microsoft-line\" />\n Outlook\n </VvDropdownAction>\n <VvDropdownAction @click=\"generateIcs\">\n <VvIcon name=\"ri:download-line\" />\n {{ $t('action.downloadIcs') }}\n </VvDropdownAction>\n </template>\n </VvDropdown>\n </VvButtonGroup>\n </div>\n <div class=\"p-sm flex gap-sm items-start\">\n <div\n class=\"shrink-0 w-44 rounded-xl overflow-hidden border border-surface-3 text-center select-none\">\n <div\n class=\"bg-brand px-8 py-2 text-white text-10 font-bold uppercase tracking-wide\">\n {{ calendarMonth }}\n </div>\n <div\n class=\"bg-surface-1 py-4 text-word-1 text-24 font-bold leading-none\">\n {{ calendarDay }}\n </div>\n </div>\n <div class=\"flex flex-col gap-4 min-w-0\">\n <p class=\"font-semibold text-word-1 text-14\">\n {{ toolPart.input.title }}\n </p>\n <div class=\"flex items-center gap-8 text-12 text-word-3\">\n <VvIcon name=\"ri:time-line\" class=\"text-14 shrink-0\" />\n <time :datetime=\"toolPart.input.startDate\">{{\n dateDisplay\n }}</time>\n </div>\n <div\n v-if=\"toolPart.input.location\"\n class=\"flex items-center gap-8 text-12 text-word-3\">\n <VvIcon name=\"ri:map-pin-line\" class=\"text-14 shrink-0\" />\n <a\n v-if=\"toolPart.input.location.startsWith('http')\"\n :href=\"toolPart.input.location\"\n :target=\"\n isSameSite(toolPart.input.location)\n ? undefined\n : '_blank'\n \"\n :rel=\"\n isSameSite(toolPart.input.location)\n ? undefined\n : 'noopener noreferrer'\n \"\n class=\"underline truncate\">\n {{ toolPart.input.location }}\n </a>\n <span v-else>{{ toolPart.input.location }}</span>\n </div>\n <div\n v-if=\"toolPart.input.additionalInfo\"\n class=\"flex items-start gap-8 text-12 text-word-3\">\n <VvIcon\n name=\"ri:sticky-note-line\"\n class=\"text-14 shrink-0 mt-1\" />\n <span>{{ toolPart.input.additionalInfo }}</span>\n </div>\n </div>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"PkToolShowCalendarEvent-DdEWaTj-.js","names":["$t"],"sources":["../../../../packages/components/src/chat/PkToolShowCalendarEvent.vue","../../../../packages/components/src/chat/PkToolShowCalendarEvent.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useClipboard } from '@vueuse/core'\n import { isSameSite } from 'utils'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n const { d } = useI18n()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title: string\n startDate: string\n endDate: string\n location?: string\n additionalInfo?: string\n allDay?: boolean\n }\n }\n return part\n })\n\n const dateDisplay = computed(() => {\n const input = toolPart.value.input\n if (!input) {\n return ''\n }\n const { startDate, endDate, allDay } = input\n const start = new Date(startDate)\n const end = new Date(endDate)\n const startDay = startDate.slice(0, 10)\n const endDay = endDate.slice(0, 10)\n if (allDay) {\n if (startDay === endDay) {\n return d(start, 'date-medium')\n }\n return `${d(start, 'date-medium')} - ${d(end, 'date-medium')}`\n }\n if (startDay === endDay) {\n return `${d(start, 'date-time-medium')} - ${d(end, 'time')}`\n }\n return `${d(start, 'date-time-medium')} - ${d(end, 'date-time-medium')}`\n })\n\n const calendarStart = computed(() =>\n toolPart.value.input ? new Date(toolPart.value.input.startDate) : null,\n )\n\n const calendarDay = computed(\n () => calendarStart.value?.getDate().toString() ?? '',\n )\n\n const calendarMonth = computed(() =>\n calendarStart.value ? d(calendarStart.value, 'month-short') : '',\n )\n\n // Floating time: remove dashes/colons without converting to UTC\n const toIcsDateTime = (iso: string) =>\n iso.replace(/[-:]/g, '').replace(/\\.\\d{3}$/, '')\n\n const escapeIcs = (str: string) =>\n str\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/;/g, '\\\\;')\n .replace(/,/g, '\\\\,')\n .replace(/\\n/g, '\\\\n')\n\n const generateIcs = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const { title, startDate, endDate, location, additionalInfo } = input\n const ics = [\n 'BEGIN:VCALENDAR',\n 'VERSION:2.0',\n 'PRODID:-//8wave//8bot//EN',\n 'BEGIN:VEVENT',\n `DTSTART:${toIcsDateTime(startDate)}`,\n `DTEND:${toIcsDateTime(endDate)}`,\n `SUMMARY:${escapeIcs(title)}`,\n location ? `LOCATION:${escapeIcs(location)}` : '',\n additionalInfo ? `DESCRIPTION:${escapeIcs(additionalInfo)}` : '',\n `DTSTAMP:${new Date()\n .toISOString()\n .replace(/[-:]/g, '')\n .replace(/\\.\\d{3}/, '')}`,\n `UID:${crypto.randomUUID()}@8bot.ai`,\n 'END:VEVENT',\n 'END:VCALENDAR',\n ]\n .filter(Boolean)\n .join('\\r\\n')\n\n const blob = new Blob([ics], { type: 'text/calendar;charset=utf-8' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = `${title.replace(/[^a-zA-Z0-9\\s-]/g, '')}.ics`\n a.click()\n URL.revokeObjectURL(url)\n }\n\n const openGoogleCalendar = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const { title, startDate, endDate, location, additionalInfo } = input\n const start = toIcsDateTime(startDate)\n const end = toIcsDateTime(endDate)\n const params = new URLSearchParams({\n action: 'TEMPLATE',\n text: title,\n dates: `${start}/${end}`,\n })\n if (location) {\n params.set('location', location)\n }\n if (additionalInfo) {\n params.set('details', additionalInfo)\n }\n window.open(\n `https://calendar.google.com/calendar/render?${params.toString()}`,\n '_blank',\n )\n }\n\n const openOutlook = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const { title, startDate, endDate, location, additionalInfo } = input\n const params = new URLSearchParams({\n subject: title,\n startdt: startDate,\n enddt: endDate,\n })\n if (location) {\n params.set('location', location)\n }\n if (additionalInfo) {\n params.set('body', additionalInfo)\n }\n window.open(\n `https://outlook.office.com/calendar/0/action/compose?${params.toString()}`,\n '_blank',\n )\n }\n\n const copyEvent = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const lines = [input.title, dateDisplay.value]\n if (input.location) {\n lines.push(input.location)\n }\n if (input.additionalInfo) {\n lines.push(input.additionalInfo)\n }\n copy(lines.join('\\n'))\n }\n</script>\n\n<template>\n <div\n v-if=\"toolPart?.input\"\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\">\n <VvIcon name=\"ri:calendar-event-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{ $t('label.calendarEvent') }}</strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copyEvent\" />\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n strategy: 'fixed',\n }\">\n <VvButton\n icon=\"ri:calendar-line\"\n modifiers=\"action-quiet-small\"\n :label=\"$t('action.addToCalendar')\" />\n <template #items>\n <VvDropdownAction @click=\"openGoogleCalendar\">\n <VvIcon name=\"ri:google-line\" />\n Google Calendar\n </VvDropdownAction>\n <VvDropdownAction @click=\"openOutlook\">\n <VvIcon name=\"ri:microsoft-line\" />\n Outlook\n </VvDropdownAction>\n <VvDropdownAction @click=\"generateIcs\">\n <VvIcon name=\"ri:download-line\" />\n {{ $t('action.downloadIcs') }}\n </VvDropdownAction>\n </template>\n </VvDropdown>\n </VvButtonGroup>\n </div>\n <div class=\"p-sm flex gap-sm items-start\">\n <div\n class=\"shrink-0 w-44 rounded-xl overflow-hidden border border-surface-3 text-center select-none\">\n <div\n class=\"bg-brand px-8 py-2 text-white text-10 font-bold uppercase tracking-wide\">\n {{ calendarMonth }}\n </div>\n <div\n class=\"bg-surface-1 py-4 text-word-1 text-24 font-bold leading-none\">\n {{ calendarDay }}\n </div>\n </div>\n <div class=\"flex flex-col gap-4 min-w-0\">\n <p class=\"font-semibold text-word-1 text-14\">\n {{ toolPart.input.title }}\n </p>\n <div class=\"flex items-center gap-8 text-12 text-word-3\">\n <VvIcon name=\"ri:time-line\" class=\"text-14 shrink-0\" />\n <time :datetime=\"toolPart.input.startDate\">{{\n dateDisplay\n }}</time>\n </div>\n <div\n v-if=\"toolPart.input.location\"\n class=\"flex items-center gap-8 text-12 text-word-3\">\n <VvIcon name=\"ri:map-pin-line\" class=\"text-14 shrink-0\" />\n <a\n v-if=\"toolPart.input.location.startsWith('http')\"\n :href=\"toolPart.input.location\"\n :target=\"\n isSameSite(toolPart.input.location)\n ? undefined\n : '_blank'\n \"\n :rel=\"\n isSameSite(toolPart.input.location)\n ? undefined\n : 'noopener noreferrer'\n \"\n class=\"underline truncate\">\n {{ toolPart.input.location }}\n </a>\n <span v-else>{{ toolPart.input.location }}</span>\n </div>\n <div\n v-if=\"toolPart.input.additionalInfo\"\n class=\"flex items-start gap-8 text-12 text-word-3\">\n <VvIcon\n name=\"ri:sticky-note-line\"\n class=\"text-14 shrink-0 mt-1\" />\n <span>{{ toolPart.input.additionalInfo }}</span>\n </div>\n </div>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useClipboard } from '@vueuse/core'\n import { isSameSite } from 'utils'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n const { d } = useI18n()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title: string\n startDate: string\n endDate: string\n location?: string\n additionalInfo?: string\n allDay?: boolean\n }\n }\n return part\n })\n\n const dateDisplay = computed(() => {\n const input = toolPart.value.input\n if (!input) {\n return ''\n }\n const { startDate, endDate, allDay } = input\n const start = new Date(startDate)\n const end = new Date(endDate)\n const startDay = startDate.slice(0, 10)\n const endDay = endDate.slice(0, 10)\n if (allDay) {\n if (startDay === endDay) {\n return d(start, 'date-medium')\n }\n return `${d(start, 'date-medium')} - ${d(end, 'date-medium')}`\n }\n if (startDay === endDay) {\n return `${d(start, 'date-time-medium')} - ${d(end, 'time')}`\n }\n return `${d(start, 'date-time-medium')} - ${d(end, 'date-time-medium')}`\n })\n\n const calendarStart = computed(() =>\n toolPart.value.input ? new Date(toolPart.value.input.startDate) : null,\n )\n\n const calendarDay = computed(\n () => calendarStart.value?.getDate().toString() ?? '',\n )\n\n const calendarMonth = computed(() =>\n calendarStart.value ? d(calendarStart.value, 'month-short') : '',\n )\n\n // Floating time: remove dashes/colons without converting to UTC\n const toIcsDateTime = (iso: string) =>\n iso.replace(/[-:]/g, '').replace(/\\.\\d{3}$/, '')\n\n const escapeIcs = (str: string) =>\n str\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/;/g, '\\\\;')\n .replace(/,/g, '\\\\,')\n .replace(/\\n/g, '\\\\n')\n\n const generateIcs = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const { title, startDate, endDate, location, additionalInfo } = input\n const ics = [\n 'BEGIN:VCALENDAR',\n 'VERSION:2.0',\n 'PRODID:-//8wave//8bot//EN',\n 'BEGIN:VEVENT',\n `DTSTART:${toIcsDateTime(startDate)}`,\n `DTEND:${toIcsDateTime(endDate)}`,\n `SUMMARY:${escapeIcs(title)}`,\n location ? `LOCATION:${escapeIcs(location)}` : '',\n additionalInfo ? `DESCRIPTION:${escapeIcs(additionalInfo)}` : '',\n `DTSTAMP:${new Date()\n .toISOString()\n .replace(/[-:]/g, '')\n .replace(/\\.\\d{3}/, '')}`,\n `UID:${crypto.randomUUID()}@8bot.ai`,\n 'END:VEVENT',\n 'END:VCALENDAR',\n ]\n .filter(Boolean)\n .join('\\r\\n')\n\n const blob = new Blob([ics], { type: 'text/calendar;charset=utf-8' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = `${title.replace(/[^a-zA-Z0-9\\s-]/g, '')}.ics`\n a.click()\n URL.revokeObjectURL(url)\n }\n\n const openGoogleCalendar = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const { title, startDate, endDate, location, additionalInfo } = input\n const start = toIcsDateTime(startDate)\n const end = toIcsDateTime(endDate)\n const params = new URLSearchParams({\n action: 'TEMPLATE',\n text: title,\n dates: `${start}/${end}`,\n })\n if (location) {\n params.set('location', location)\n }\n if (additionalInfo) {\n params.set('details', additionalInfo)\n }\n window.open(\n `https://calendar.google.com/calendar/render?${params.toString()}`,\n '_blank',\n )\n }\n\n const openOutlook = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const { title, startDate, endDate, location, additionalInfo } = input\n const params = new URLSearchParams({\n subject: title,\n startdt: startDate,\n enddt: endDate,\n })\n if (location) {\n params.set('location', location)\n }\n if (additionalInfo) {\n params.set('body', additionalInfo)\n }\n window.open(\n `https://outlook.office.com/calendar/0/action/compose?${params.toString()}`,\n '_blank',\n )\n }\n\n const copyEvent = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const lines = [input.title, dateDisplay.value]\n if (input.location) {\n lines.push(input.location)\n }\n if (input.additionalInfo) {\n lines.push(input.additionalInfo)\n }\n copy(lines.join('\\n'))\n }\n</script>\n\n<template>\n <div\n v-if=\"toolPart?.input\"\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\">\n <VvIcon name=\"ri:calendar-event-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{ $t('label.calendarEvent') }}</strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copyEvent\" />\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n strategy: 'fixed',\n }\">\n <VvButton\n icon=\"ri:calendar-line\"\n modifiers=\"action-quiet-small\"\n :label=\"$t('action.addToCalendar')\" />\n <template #items>\n <VvDropdownAction @click=\"openGoogleCalendar\">\n <VvIcon name=\"ri:google-line\" />\n Google Calendar\n </VvDropdownAction>\n <VvDropdownAction @click=\"openOutlook\">\n <VvIcon name=\"ri:microsoft-line\" />\n Outlook\n </VvDropdownAction>\n <VvDropdownAction @click=\"generateIcs\">\n <VvIcon name=\"ri:download-line\" />\n {{ $t('action.downloadIcs') }}\n </VvDropdownAction>\n </template>\n </VvDropdown>\n </VvButtonGroup>\n </div>\n <div class=\"p-sm flex gap-sm items-start\">\n <div\n class=\"shrink-0 w-44 rounded-xl overflow-hidden border border-surface-3 text-center select-none\">\n <div\n class=\"bg-brand px-8 py-2 text-white text-10 font-bold uppercase tracking-wide\">\n {{ calendarMonth }}\n </div>\n <div\n class=\"bg-surface-1 py-4 text-word-1 text-24 font-bold leading-none\">\n {{ calendarDay }}\n </div>\n </div>\n <div class=\"flex flex-col gap-4 min-w-0\">\n <p class=\"font-semibold text-word-1 text-14\">\n {{ toolPart.input.title }}\n </p>\n <div class=\"flex items-center gap-8 text-12 text-word-3\">\n <VvIcon name=\"ri:time-line\" class=\"text-14 shrink-0\" />\n <time :datetime=\"toolPart.input.startDate\">{{\n dateDisplay\n }}</time>\n </div>\n <div\n v-if=\"toolPart.input.location\"\n class=\"flex items-center gap-8 text-12 text-word-3\">\n <VvIcon name=\"ri:map-pin-line\" class=\"text-14 shrink-0\" />\n <a\n v-if=\"toolPart.input.location.startsWith('http')\"\n :href=\"toolPart.input.location\"\n :target=\"\n isSameSite(toolPart.input.location)\n ? undefined\n : '_blank'\n \"\n :rel=\"\n isSameSite(toolPart.input.location)\n ? undefined\n : 'noopener noreferrer'\n \"\n class=\"underline truncate\">\n {{ toolPart.input.location }}\n </a>\n <span v-else>{{ toolPart.input.location }}</span>\n </div>\n <div\n v-if=\"toolPart.input.additionalInfo\"\n class=\"flex items-start gap-8 text-12 text-word-3\">\n <VvIcon\n name=\"ri:sticky-note-line\"\n class=\"text-14 shrink-0 mt-1\" />\n <span>{{ toolPart.input.additionalInfo }}</span>\n </div>\n </div>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;EAMI,IAAM,IAAQ,GAIR,EAAE,SAAM,cAAW,EAAa,GAChC,EAAE,SAAM,EAAQ,GAEhB,IAAW,QACA,EAAM,IAWtB,GAEK,IAAc,QAAe;GAC/B,IAAM,IAAQ,EAAS,MAAM;GAC7B,IAAI,CAAC,GACD,OAAO;GAEX,IAAM,EAAE,cAAW,YAAS,cAAW,GACjC,IAAQ,IAAI,KAAK,CAAS,GAC1B,IAAM,IAAI,KAAK,CAAO,GACtB,IAAW,EAAU,MAAM,GAAG,EAAE,GAChC,IAAS,EAAQ,MAAM,GAAG,EAAE;GAUlC,OATI,IACI,MAAa,IACN,EAAE,GAAO,aAAa,IAE1B,GAAG,EAAE,GAAO,aAAa,EAAE,KAAK,EAAE,GAAK,aAAa,MAE3D,MAAa,IACN,GAAG,EAAE,GAAO,kBAAkB,EAAE,KAAK,EAAE,GAAK,MAAM,MAEtD,GAAG,EAAE,GAAO,kBAAkB,EAAE,KAAK,EAAE,GAAK,kBAAkB;EACzE,CAAC,GAEK,IAAgB,QAClB,EAAS,MAAM,QAAQ,IAAI,KAAK,EAAS,MAAM,MAAM,SAAS,IAAI,IACtE,GAEM,IAAc,QACV,EAAc,OAAO,QAAQ,CAAC,CAAC,SAAS,KAAK,EACvD,GAEM,IAAgB,QAClB,EAAc,QAAQ,EAAE,EAAc,OAAO,aAAa,IAAI,EAClE,GAGM,KAAiB,MACnB,EAAI,QAAQ,SAAS,EAAE,CAAC,CAAC,QAAQ,YAAY,EAAE,GAE7C,KAAa,MACf,EACK,QAAQ,OAAO,MAAM,CAAA,CACrB,QAAQ,MAAM,KAAK,CAAA,CACnB,QAAQ,MAAM,KAAK,CAAA,CACnB,QAAQ,OAAO,KAAK,GAEvB,UAAoB;GACtB,IAAM,IAAQ,EAAS,MAAM;GAC7B,IAAI,CAAC,GACD;GAEJ,IAAM,EAAE,UAAO,cAAW,YAAS,aAAU,sBAAmB,GAC1D,IAAM;IACR;IACA;IACA;IACA;IACA,WAAW,EAAc,CAAS;IAClC,SAAS,EAAc,CAAO;IAC9B,WAAW,EAAU,CAAK;IAC1B,IAAW,YAAY,EAAU,CAAQ,MAAM;IAC/C,IAAiB,eAAe,EAAU,CAAc,MAAM;IAC9D,4BAAW,IAAI,KAAK,EAAA,CACf,YAAY,CAAA,CACZ,QAAQ,SAAS,EAAE,CAAA,CACnB,QAAQ,WAAW,EAAE;IAC1B,OAAO,OAAO,WAAW,EAAE;IAC3B;IACA;GACJ,CAAA,CACK,OAAO,OAAO,CAAA,CACd,KAAK,MAAM,GAEV,IAAO,IAAI,KAAK,CAAC,CAAG,GAAG,EAAE,MAAM,8BAA8B,CAAC,GAC9D,IAAM,IAAI,gBAAgB,CAAI,GAC9B,IAAI,SAAS,cAAc,GAAG;GAIpC,AAHA,EAAE,OAAO,GACT,EAAE,WAAW,GAAG,EAAM,QAAQ,oBAAoB,EAAE,EAAE,OACtD,EAAE,MAAM,GACR,IAAI,gBAAgB,CAAG;EAC3B,GAEM,UAA2B;GAC7B,IAAM,IAAQ,EAAS,MAAM;GAC7B,IAAI,CAAC,GACD;GAEJ,IAAM,EAAE,UAAO,cAAW,YAAS,aAAU,sBAAmB,GAC1D,IAAQ,EAAc,CAAS,GAC/B,IAAM,EAAc,CAAO,GAC3B,IAAS,IAAI,gBAAgB;IAC/B,QAAQ;IACR,MAAM;IACN,OAAO,GAAG,EAAM,GAAG;GACvB,CAAC;GAOD,AANI,KACA,EAAO,IAAI,YAAY,CAAQ,GAE/B,KACA,EAAO,IAAI,WAAW,CAAc,GAExC,OAAO,KACH,+CAA+C,EAAO,SAAS,KAC/D,QACJ;EACJ,GAEM,UAAoB;GACtB,IAAM,IAAQ,EAAS,MAAM;GAC7B,IAAI,CAAC,GACD;GAEJ,IAAM,EAAE,UAAO,cAAW,YAAS,aAAU,sBAAmB,GAC1D,IAAS,IAAI,gBAAgB;IAC/B,SAAS;IACT,SAAS;IACT,OAAO;GACX,CAAC;GAOD,AANI,KACA,EAAO,IAAI,YAAY,CAAQ,GAE/B,KACA,EAAO,IAAI,QAAQ,CAAc,GAErC,OAAO,KACH,wDAAwD,EAAO,SAAS,KACxE,QACJ;EACJ,GAEM,UAAkB;GACpB,IAAM,IAAQ,EAAS,MAAM;GAC7B,IAAI,CAAC,GACD;GAEJ,IAAM,IAAQ,CAAC,EAAM,OAAO,EAAY,KAAK;GAO7C,AANI,EAAM,YACN,EAAM,KAAK,EAAM,QAAQ,GAEzB,EAAM,kBACN,EAAM,KAAK,EAAM,cAAc,GAEnC,EAAK,EAAM,KAAK,IAAI,CAAC;EACzB;;;UAKU,EAAA,OAAU,SAAA,EAAA,GADpB,EAgGM,OAhGN,GAgGM,CA7FF,EAsCM,OAtCN,GAsCM;IApCF,EAAwD,GAAA;KAAhD,MAAK;KAAyB,OAAM;;IAC5C,EAAkE,UAAlE,GAAkE,EAArCA,EAAAA,GAAE,qBAAA,CAAA,GAAA,CAAA;IAC/B,EAiCgB,GAAA;KAjCD,WAAU;KAAU,OAAM;;sBAKZ,CAJzB,EAIyB,GAAA;MAHrB,WAAU;MACT,MAAM,EAAA,CAAA,IAAM,kBAAA;MACZ,OAAO,EAAA,CAAA,IAASA,EAAAA,GAAE,eAAA,IAAoBA,EAAAA,GAAE,aAAA;MACxC,SAAO;qCACZ,EA0Ba,GAAA,EAAA,EAzBD;;;;;;MAMP,CAAA,GAAA;MAKU,OAAK,QAIO;OAHnB,EAGmB,GAAA,EAHA,SAAO,EAAkB,GAAA;yBACR,CAAhC,EAAgC,GAAA,EAAxB,MAAK,iBAAgB,CAAA,GAAA,AAAA,EAAA,OAAA,EAAG,qBAEpC,EAAA,CAAA,CAAA;;;OACA,EAGmB,GAAA,EAHA,SAAO,EAAW,GAAA;yBACE,CAAnC,EAAmC,GAAA,EAA3B,MAAK,oBAAmB,CAAA,GAAA,AAAA,EAAA,OAAA,EAAG,aAEvC,EAAA,CAAA,CAAA;;;OACA,EAGmB,GAAA,EAHA,SAAO,EAAW,GAAA;yBACC,CAAlC,EAAkC,GAAA,EAA1B,MAAK,mBAAkB,CAAA,GAAA,EAAG,MAClC,EAAGA,EAAAA,GAAE,oBAAA,CAAA,GAAA,CAAA,CAAA,CAAA;;;;uBAZ6B,CAH1C,EAG0C,GAAA;OAFtC,MAAK;OACL,WAAU;OACT,OAAOA,EAAAA,GAAE,sBAAA;;;;;;OAkB1B,EAqDM,OArDN,GAqDM,CApDF,EAUM,OAVN,GAUM,CARF,EAGM,OAHN,GAGM,EADC,EAAA,KAAa,GAAA,CAAA,GAEpB,EAGM,OAHN,GAGM,EADC,EAAA,KAAW,GAAA,CAAA,CAAA,CAAA,GAGtB,EAwCM,OAxCN,GAwCM;IAvCF,EAEI,KAFJ,GAEI,EADG,EAAA,MAAS,MAAM,KAAK,GAAA,CAAA;IAE3B,EAKM,OALN,GAKM,CAJF,EAAuD,GAAA;KAA/C,MAAK;KAAe,OAAM;QAClC,EAES,QAAA,EAFF,UAAU,EAAA,MAAS,MAAM,UAAA,GAAA,EAC5B,EAAA,KAAW,GAAA,GAAA,CAAA,CAAA,CAAA;IAIT,EAAA,MAAS,MAAM,YAAA,EAAA,GADzB,EAqBM,OArBN,GAqBM,CAlBF,EAA0D,GAAA;KAAlD,MAAK;KAAkB,OAAM;QAE3B,EAAA,MAAS,MAAM,SAAS,WAAU,MAAA,KAAA,EAAA,GAD5C,EAeI,KAAA;;KAbC,MAAM,EAAA,MAAS,MAAM;KACrB,QAAqC,EAAA,CAAA,CAAU,CAAC,EAAA,MAAS,MAAM,QAAQ,IAAoC,KAAA,IAAA;KAK3G,KAAkC,EAAA,CAAA,CAAU,CAAC,EAAA,MAAS,MAAM,QAAQ,IAAoC,KAAA,IAAA;KAKzG,OAAM;SACH,EAAA,MAAS,MAAM,QAAQ,GAAA,GAAA,CAAA,MAAA,EAAA,GAE9B,EAAiD,QAAA,GAAA,EAAjC,EAAA,MAAS,MAAM,QAAQ,GAAA,CAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA;IAGjC,EAAA,MAAS,MAAM,kBAAA,EAAA,GADzB,EAOM,OAPN,GAOM,CAJF,EAEoC,GAAA;KADhC,MAAK;KACL,OAAM;QACV,EAAgD,QAAA,MAAA,EAAvC,EAAA,MAAS,MAAM,cAAc,GAAA,CAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA"}
@@ -1,6 +1,6 @@
1
1
  import { A as e, C as t, Ht as n, S as r, T as i, V as a, _ as o, at as s, b as c, et as l, g as u, kt as d, p as f, qt as p, xt as m, y as h, z as g } from "./vue.runtime.esm-bundler-DbhD_IvR.js";
2
- import { i as _ } from "./dist-BNET2z7b.js";
3
- import { l as v, n as y, p as b } from "./index.es-BYny0uhz.js";
2
+ import { i as _ } from "./dist-CvMCBce7.js";
3
+ import { d as v, f as y, i as b } from "./index.es-_oXVRjHy.js";
4
4
  e(), d(), s();
5
5
  var x = {
6
6
  key: 0,
@@ -22,7 +22,7 @@ var x = {
22
22
  s([t, ...n].join("\n"));
23
23
  };
24
24
  return (e, i) => {
25
- let s = v, u = b, _ = y;
25
+ let s = y, u = v, _ = b;
26
26
  return D.value?.input?.items?.length ? (g(), c("div", x, [o("div", S, [
27
27
  t(s, {
28
28
  name: "ri:scales-line",
@@ -63,4 +63,4 @@ var x = {
63
63
  //#endregion
64
64
  export { D as default };
65
65
 
66
- //# sourceMappingURL=PkToolShowComparison-DahL5vHr.js.map
66
+ //# sourceMappingURL=PkToolShowComparison-Dcar7HPW.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PkToolShowComparison-DahL5vHr.js","names":["$t"],"sources":["../../../../packages/components/src/chat/PkToolShowComparison.vue","../../../../packages/components/src/chat/PkToolShowComparison.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title?: string\n items: Array<{\n name: string\n values: Record<string, string>\n highlighted?: boolean\n }>\n }\n }\n return part\n })\n\n const features = computed(() => {\n const items = toolPart.value.input?.items\n if (!items || items.length === 0) {\n return []\n }\n return Object.keys(items[0].values)\n })\n\n const copyTable = () => {\n const items = toolPart.value.input?.items\n if (!items) {\n return\n }\n const header = ['', ...items.map((i) => i.name)].join('\\t')\n const rows = features.value.map((f) =>\n [f.replace(/_/g, ' '), ...items.map((i) => i.values[f] ?? '')].join(\n '\\t',\n ),\n )\n copy([header, ...rows].join('\\n'))\n }\n</script>\n\n<template>\n <div\n v-if=\"toolPart?.input?.items?.length\"\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\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\">\n <VvIcon name=\"ri:scales-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{\n toolPart.input.title ?? $t('label.comparison')\n }}</strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copyTable\" />\n </VvButtonGroup>\n </div>\n <div class=\"overflow-x-auto\">\n <table class=\"w-full text-12 border-collapse\">\n <thead>\n <tr>\n <th\n class=\"text-left text-word-3 font-medium p-8 border-b border-surface-3 min-w-32\"></th>\n <th\n v-for=\"item in toolPart.input.items\"\n :key=\"item.name\"\n class=\"text-center font-semibold text-word-1 p-8 border-b border-surface-3 min-w-24\"\n :class=\"\n item.highlighted\n ? 'bg-primary/5 border-primary/20'\n : ''\n \">\n {{ item.name }}\n <span v-if=\"item.highlighted\" class=\"ml-4\">⭐</span>\n </th>\n </tr>\n </thead>\n <tbody>\n <tr\n v-for=\"(feature, fIdx) in features\"\n :key=\"feature\"\n :class=\"{ 'bg-surface-1': fIdx % 2 !== 0 }\">\n <td\n class=\"text-word-3 font-medium p-8 whitespace-nowrap\"\n :class=\"{\n 'border-b border-surface-3':\n fIdx !== features.length - 1,\n }\">\n {{ feature.replace(/_/g, ' ') }}\n </td>\n <td\n v-for=\"item in toolPart.input.items\"\n :key=\"item.name\"\n class=\"text-center p-8\"\n :class=\"{\n 'border-b border-surface-3':\n fIdx !== features.length - 1,\n 'bg-surface-info': item.highlighted,\n 'text-success': item.values[feature] === '✓',\n 'text-danger':\n item.values[feature] === '\\u2717',\n 'text-word-2':\n item.values[feature] !== '✓' &&\n item.values[feature] !== '\\u2717',\n }\">\n {{ item.values[feature] ?? '-' }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title?: string\n items: Array<{\n name: string\n values: Record<string, string>\n highlighted?: boolean\n }>\n }\n }\n return part\n })\n\n const features = computed(() => {\n const items = toolPart.value.input?.items\n if (!items || items.length === 0) {\n return []\n }\n return Object.keys(items[0].values)\n })\n\n const copyTable = () => {\n const items = toolPart.value.input?.items\n if (!items) {\n return\n }\n const header = ['', ...items.map((i) => i.name)].join('\\t')\n const rows = features.value.map((f) =>\n [f.replace(/_/g, ' '), ...items.map((i) => i.values[f] ?? '')].join(\n '\\t',\n ),\n )\n copy([header, ...rows].join('\\n'))\n }\n</script>\n\n<template>\n <div\n v-if=\"toolPart?.input?.items?.length\"\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\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\">\n <VvIcon name=\"ri:scales-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{\n toolPart.input.title ?? $t('label.comparison')\n }}</strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copyTable\" />\n </VvButtonGroup>\n </div>\n <div class=\"overflow-x-auto\">\n <table class=\"w-full text-12 border-collapse\">\n <thead>\n <tr>\n <th\n class=\"text-left text-word-3 font-medium p-8 border-b border-surface-3 min-w-32\"></th>\n <th\n v-for=\"item in toolPart.input.items\"\n :key=\"item.name\"\n class=\"text-center font-semibold text-word-1 p-8 border-b border-surface-3 min-w-24\"\n :class=\"\n item.highlighted\n ? 'bg-primary/5 border-primary/20'\n : ''\n \">\n {{ item.name }}\n <span v-if=\"item.highlighted\" class=\"ml-4\">⭐</span>\n </th>\n </tr>\n </thead>\n <tbody>\n <tr\n v-for=\"(feature, fIdx) in features\"\n :key=\"feature\"\n :class=\"{ 'bg-surface-1': fIdx % 2 !== 0 }\">\n <td\n class=\"text-word-3 font-medium p-8 whitespace-nowrap\"\n :class=\"{\n 'border-b border-surface-3':\n fIdx !== features.length - 1,\n }\">\n {{ feature.replace(/_/g, ' ') }}\n </td>\n <td\n v-for=\"item in toolPart.input.items\"\n :key=\"item.name\"\n class=\"text-center p-8\"\n :class=\"{\n 'border-b border-surface-3':\n fIdx !== features.length - 1,\n 'bg-surface-info': item.highlighted,\n 'text-success': item.values[feature] === '✓',\n 'text-danger':\n item.values[feature] === '\\u2717',\n 'text-word-2':\n item.values[feature] !== '✓' &&\n item.values[feature] !== '\\u2717',\n }\">\n {{ item.values[feature] ?? '-' }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;EAII,IAAM,IAAQ,GAIR,EAAE,SAAM,cAAW,EAAa,GAEhC,IAAW,QACA,EAAM,IAWtB,GAEK,IAAW,QAAe;GAC5B,IAAM,IAAQ,EAAS,MAAM,OAAO;GAIpC,OAHI,CAAC,KAAS,EAAM,WAAW,IACpB,CAAC,IAEL,OAAO,KAAK,EAAM,EAAE,CAAC,MAAM;EACtC,CAAC,GAEK,UAAkB;GACpB,IAAM,IAAQ,EAAS,MAAM,OAAO;GACpC,IAAI,CAAC,GACD;GAEJ,IAAM,IAAS,CAAC,IAAI,GAAG,EAAM,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,GAAI,GACpD,IAAO,EAAS,MAAM,KAAK,MAC7B,CAAC,EAAE,QAAQ,MAAM,GAAG,GAAG,GAAG,EAAM,KAAK,MAAM,EAAE,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC,KAC3D,GACJ,CACJ;GACA,EAAK,CAAC,GAAQ,GAAG,CAAI,CAAC,CAAC,KAAK,IAAI,CAAC;EACrC;;;UAKU,EAAA,OAAU,OAAO,OAAO,UAAA,EAAA,GADlC,EAuEM,OAvEN,GAuEM,CApEF,EAaM,OAbN,GAaM;IAXF,EAAgD,GAAA;KAAxC,MAAK;KAAiB,OAAM;;IACpC,EAEW,UAFX,GAEW,EADP,EAAA,MAAS,MAAM,SAASA,EAAAA,GAAE,kBAAA,CAAA,GAAA,CAAA;IAE9B,EAMgB,GAAA;KAND,WAAU;KAAU,OAAM;;sBAKZ,CAJzB,EAIyB,GAAA;MAHrB,WAAU;MACT,MAAM,EAAA,CAAA,IAAM,kBAAA;MACZ,OAAO,EAAA,CAAA,IAASA,EAAAA,GAAE,eAAA,IAAoBA,EAAAA,GAAE,aAAA;MACxC,SAAO;;;;OAGpB,EAqDM,OArDN,GAqDM,CApDF,EAmDQ,SAnDR,GAmDQ,CAlDJ,EAiBQ,SAAA,MAAA,CAhBJ,EAeK,MAAA,MAAA,CAAA,AAAA,EAAA,OAdD,EAC0F,MAAA,EAAtF,OAAM,2EAA0E,GAAA,MAAA,EAAA,IAAA,EAAA,EAAA,GACpF,EAWK,GAAA,MAAA,EAVc,EAAA,MAAS,MAAM,QAAvB,YADX,EAWK,MAAA;IATA,KAAK,EAAK;IACX,OAAK,EAAA,CAAC,gFACmC,EAAK,cAAA,mCAAA,EAAA,CAAA;WAK3C,EAAK,IAAI,IAAG,KACf,CAAA,GAAY,EAAK,eAAA,EAAA,GAAjB,EAAmD,QAAnD,GAA2C,GAAC,KAAA,EAAA,IAAA,EAAA,CAAA,GAAA,CAAA,gBAIxD,EA+BQ,SAAA,MAAA,EAAA,EAAA,EAAA,GA9BJ,EA6BK,GAAA,MAAA,EA5ByB,EAAA,QAAlB,GAAS,YADrB,EA6BK,MAAA;IA3BA,KAAK;IACL,OAAK,EAAA,EAAA,gBAAoB,IAAI,KAAA,EAAA,CAAA;OAC9B,EAOK,MAAA,EAND,OAAK,EAAA,CAAC,iDAA+C,EAAA,6BACsD,MAAS,EAAA,MAAS,SAAM,EAAA,CAAA,CAAA,EAAA,GAAA,EAIhI,EAAQ,QAAO,MAAA,GAAA,CAAA,GAAA,CAAA,IAAA,EAAA,EAAA,GAEtB,EAgBK,GAAA,MAAA,EAfc,EAAA,MAAS,MAAM,QAAvB,YADX,EAgBK,MAAA;IAdA,KAAK,EAAK;IACX,OAAK,EAAA,CAAC,mBAAiB;kCACoF,MAAS,EAAA,MAAS,SAAM;wBAAyD,EAAK;qBAA6D,EAAK,OAAO,OAAO;oBAA8F,EAAK,OAAO,OAAO;oBAAmG,EAAK,OAAO,OAAO,OAAiD,EAAK,OAAO,OAAO;;QAWzjB,EAAK,OAAO,MAAO,GAAA,GAAA,CAAA"}
1
+ {"version":3,"file":"PkToolShowComparison-Dcar7HPW.js","names":["$t"],"sources":["../../../../packages/components/src/chat/PkToolShowComparison.vue","../../../../packages/components/src/chat/PkToolShowComparison.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title?: string\n items: Array<{\n name: string\n values: Record<string, string>\n highlighted?: boolean\n }>\n }\n }\n return part\n })\n\n const features = computed(() => {\n const items = toolPart.value.input?.items\n if (!items || items.length === 0) {\n return []\n }\n return Object.keys(items[0].values)\n })\n\n const copyTable = () => {\n const items = toolPart.value.input?.items\n if (!items) {\n return\n }\n const header = ['', ...items.map((i) => i.name)].join('\\t')\n const rows = features.value.map((f) =>\n [f.replace(/_/g, ' '), ...items.map((i) => i.values[f] ?? '')].join(\n '\\t',\n ),\n )\n copy([header, ...rows].join('\\n'))\n }\n</script>\n\n<template>\n <div\n v-if=\"toolPart?.input?.items?.length\"\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\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\">\n <VvIcon name=\"ri:scales-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{\n toolPart.input.title ?? $t('label.comparison')\n }}</strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copyTable\" />\n </VvButtonGroup>\n </div>\n <div class=\"overflow-x-auto\">\n <table class=\"w-full text-12 border-collapse\">\n <thead>\n <tr>\n <th\n class=\"text-left text-word-3 font-medium p-8 border-b border-surface-3 min-w-32\"></th>\n <th\n v-for=\"item in toolPart.input.items\"\n :key=\"item.name\"\n class=\"text-center font-semibold text-word-1 p-8 border-b border-surface-3 min-w-24\"\n :class=\"\n item.highlighted\n ? 'bg-primary/5 border-primary/20'\n : ''\n \">\n {{ item.name }}\n <span v-if=\"item.highlighted\" class=\"ml-4\">⭐</span>\n </th>\n </tr>\n </thead>\n <tbody>\n <tr\n v-for=\"(feature, fIdx) in features\"\n :key=\"feature\"\n :class=\"{ 'bg-surface-1': fIdx % 2 !== 0 }\">\n <td\n class=\"text-word-3 font-medium p-8 whitespace-nowrap\"\n :class=\"{\n 'border-b border-surface-3':\n fIdx !== features.length - 1,\n }\">\n {{ feature.replace(/_/g, ' ') }}\n </td>\n <td\n v-for=\"item in toolPart.input.items\"\n :key=\"item.name\"\n class=\"text-center p-8\"\n :class=\"{\n 'border-b border-surface-3':\n fIdx !== features.length - 1,\n 'bg-surface-info': item.highlighted,\n 'text-success': item.values[feature] === '✓',\n 'text-danger':\n item.values[feature] === '\\u2717',\n 'text-word-2':\n item.values[feature] !== '✓' &&\n item.values[feature] !== '\\u2717',\n }\">\n {{ item.values[feature] ?? '-' }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title?: string\n items: Array<{\n name: string\n values: Record<string, string>\n highlighted?: boolean\n }>\n }\n }\n return part\n })\n\n const features = computed(() => {\n const items = toolPart.value.input?.items\n if (!items || items.length === 0) {\n return []\n }\n return Object.keys(items[0].values)\n })\n\n const copyTable = () => {\n const items = toolPart.value.input?.items\n if (!items) {\n return\n }\n const header = ['', ...items.map((i) => i.name)].join('\\t')\n const rows = features.value.map((f) =>\n [f.replace(/_/g, ' '), ...items.map((i) => i.values[f] ?? '')].join(\n '\\t',\n ),\n )\n copy([header, ...rows].join('\\n'))\n }\n</script>\n\n<template>\n <div\n v-if=\"toolPart?.input?.items?.length\"\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\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\">\n <VvIcon name=\"ri:scales-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{\n toolPart.input.title ?? $t('label.comparison')\n }}</strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copyTable\" />\n </VvButtonGroup>\n </div>\n <div class=\"overflow-x-auto\">\n <table class=\"w-full text-12 border-collapse\">\n <thead>\n <tr>\n <th\n class=\"text-left text-word-3 font-medium p-8 border-b border-surface-3 min-w-32\"></th>\n <th\n v-for=\"item in toolPart.input.items\"\n :key=\"item.name\"\n class=\"text-center font-semibold text-word-1 p-8 border-b border-surface-3 min-w-24\"\n :class=\"\n item.highlighted\n ? 'bg-primary/5 border-primary/20'\n : ''\n \">\n {{ item.name }}\n <span v-if=\"item.highlighted\" class=\"ml-4\">⭐</span>\n </th>\n </tr>\n </thead>\n <tbody>\n <tr\n v-for=\"(feature, fIdx) in features\"\n :key=\"feature\"\n :class=\"{ 'bg-surface-1': fIdx % 2 !== 0 }\">\n <td\n class=\"text-word-3 font-medium p-8 whitespace-nowrap\"\n :class=\"{\n 'border-b border-surface-3':\n fIdx !== features.length - 1,\n }\">\n {{ feature.replace(/_/g, ' ') }}\n </td>\n <td\n v-for=\"item in toolPart.input.items\"\n :key=\"item.name\"\n class=\"text-center p-8\"\n :class=\"{\n 'border-b border-surface-3':\n fIdx !== features.length - 1,\n 'bg-surface-info': item.highlighted,\n 'text-success': item.values[feature] === '✓',\n 'text-danger':\n item.values[feature] === '\\u2717',\n 'text-word-2':\n item.values[feature] !== '✓' &&\n item.values[feature] !== '\\u2717',\n }\">\n {{ item.values[feature] ?? '-' }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;EAII,IAAM,IAAQ,GAIR,EAAE,SAAM,cAAW,EAAa,GAEhC,IAAW,QACA,EAAM,IAWtB,GAEK,IAAW,QAAe;GAC5B,IAAM,IAAQ,EAAS,MAAM,OAAO;GAIpC,OAHI,CAAC,KAAS,EAAM,WAAW,IACpB,CAAC,IAEL,OAAO,KAAK,EAAM,EAAE,CAAC,MAAM;EACtC,CAAC,GAEK,UAAkB;GACpB,IAAM,IAAQ,EAAS,MAAM,OAAO;GACpC,IAAI,CAAC,GACD;GAEJ,IAAM,IAAS,CAAC,IAAI,GAAG,EAAM,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,GAAI,GACpD,IAAO,EAAS,MAAM,KAAK,MAC7B,CAAC,EAAE,QAAQ,MAAM,GAAG,GAAG,GAAG,EAAM,KAAK,MAAM,EAAE,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC,KAC3D,GACJ,CACJ;GACA,EAAK,CAAC,GAAQ,GAAG,CAAI,CAAC,CAAC,KAAK,IAAI,CAAC;EACrC;;;UAKU,EAAA,OAAU,OAAO,OAAO,UAAA,EAAA,GADlC,EAuEM,OAvEN,GAuEM,CApEF,EAaM,OAbN,GAaM;IAXF,EAAgD,GAAA;KAAxC,MAAK;KAAiB,OAAM;;IACpC,EAEW,UAFX,GAEW,EADP,EAAA,MAAS,MAAM,SAASA,EAAAA,GAAE,kBAAA,CAAA,GAAA,CAAA;IAE9B,EAMgB,GAAA;KAND,WAAU;KAAU,OAAM;;sBAKZ,CAJzB,EAIyB,GAAA;MAHrB,WAAU;MACT,MAAM,EAAA,CAAA,IAAM,kBAAA;MACZ,OAAO,EAAA,CAAA,IAASA,EAAAA,GAAE,eAAA,IAAoBA,EAAAA,GAAE,aAAA;MACxC,SAAO;;;;OAGpB,EAqDM,OArDN,GAqDM,CApDF,EAmDQ,SAnDR,GAmDQ,CAlDJ,EAiBQ,SAAA,MAAA,CAhBJ,EAeK,MAAA,MAAA,CAAA,AAAA,EAAA,OAdD,EAC0F,MAAA,EAAtF,OAAM,2EAA0E,GAAA,MAAA,EAAA,IAAA,EAAA,EAAA,GACpF,EAWK,GAAA,MAAA,EAVc,EAAA,MAAS,MAAM,QAAvB,YADX,EAWK,MAAA;IATA,KAAK,EAAK;IACX,OAAK,EAAA,CAAC,gFACmC,EAAK,cAAA,mCAAA,EAAA,CAAA;WAK3C,EAAK,IAAI,IAAG,KACf,CAAA,GAAY,EAAK,eAAA,EAAA,GAAjB,EAAmD,QAAnD,GAA2C,GAAC,KAAA,EAAA,IAAA,EAAA,CAAA,GAAA,CAAA,gBAIxD,EA+BQ,SAAA,MAAA,EAAA,EAAA,EAAA,GA9BJ,EA6BK,GAAA,MAAA,EA5ByB,EAAA,QAAlB,GAAS,YADrB,EA6BK,MAAA;IA3BA,KAAK;IACL,OAAK,EAAA,EAAA,gBAAoB,IAAI,KAAA,EAAA,CAAA;OAC9B,EAOK,MAAA,EAND,OAAK,EAAA,CAAC,iDAA+C,EAAA,6BACsD,MAAS,EAAA,MAAS,SAAM,EAAA,CAAA,CAAA,EAAA,GAAA,EAIhI,EAAQ,QAAO,MAAA,GAAA,CAAA,GAAA,CAAA,IAAA,EAAA,EAAA,GAEtB,EAgBK,GAAA,MAAA,EAfc,EAAA,MAAS,MAAM,QAAvB,YADX,EAgBK,MAAA;IAdA,KAAK,EAAK;IACX,OAAK,EAAA,CAAC,mBAAiB;kCACoF,MAAS,EAAA,MAAS,SAAM;wBAAyD,EAAK;qBAA6D,EAAK,OAAO,OAAO;oBAA8F,EAAK,OAAO,OAAO;oBAAmG,EAAK,OAAO,OAAO,OAAiD,EAAK,OAAO,OAAO;;QAWzjB,EAAK,OAAO,MAAO,GAAA,GAAA,CAAA"}
@@ -1,9 +1,9 @@
1
1
  import { A as e, C as t, Q as n, T as r, _ as i, at as a, b as o, et as s, g as c, i as l, kt as u, lt as d, n as f, qt as p, xt as m, z as h } from "./vue.runtime.esm-bundler-DbhD_IvR.js";
2
2
  import { r as g } from "./vue-i18n-kZs9Hfey.js";
3
- import { l as _, p as v } from "./index.es-BYny0uhz.js";
4
- import { g as y, u as b, v as x } from "./schemas-DnUKIqgi.js";
5
- import { n as S, r as C, t as w } from "./index.es-u1dF1xg2.js";
6
- import { t as T } from "./PkStreamingMarkdown-Djw604Ny.js";
3
+ import { t as _ } from "./PkStreamingMarkdown-6Xx9n1ue.js";
4
+ import { d as v, f as y } from "./index.es-_oXVRjHy.js";
5
+ import { g as b, u as x, v as S } from "./schemas-DnUKIqgi.js";
6
+ import { n as C, r as w, t as T } from "./index.es-DpqfagWZ.js";
7
7
  e(), a(), u(), l();
8
8
  var E = { class: "border border-surface-3 rounded-xl w-full overflow-hidden bg-surface" }, D = { 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" }, O = { class: "font-bold" }, k = {
9
9
  key: 0,
@@ -23,11 +23,11 @@ var E = { class: "border border-surface-3 rounded-xl w-full overflow-hidden bg-s
23
23
  },
24
24
  emits: ["submit"],
25
25
  setup(e, { emit: r }) {
26
- let { t: a } = g({ useScope: "global" }), l = e, u = c(() => l.part), I = c(() => u.value.input), L = C(c(() => `${u.value.toolCallId}-${u.value.type}-submitted`), !1), R = y({
27
- name: x().min(1).max(255).default(""),
28
- email: b().max(255).default(""),
29
- phone: x().max(50).regex(/^[+0-9\s\-.()]*$/, a("validation.invalidPhoneNumber")).optional()
30
- }), z = r, { VvForm: B, VvFormField: V, formData: H } = w(R, { lazyLoad: !0 });
26
+ let { t: a } = g({ useScope: "global" }), l = e, u = c(() => l.part), I = c(() => u.value.input), L = w(c(() => `${u.value.toolCallId}-${u.value.type}-submitted`), !1), R = b({
27
+ name: S().min(1).max(255).default(""),
28
+ email: x().max(255).default(""),
29
+ phone: S().max(50).regex(/^[+0-9\s\-.()]*$/, a("validation.invalidPhoneNumber")).optional()
30
+ }), z = r, { VvForm: B, VvFormField: V, formData: H } = T(R, { lazyLoad: !0 });
31
31
  n(I, (e) => {
32
32
  H.value = {
33
33
  name: e?.name || "",
@@ -42,9 +42,9 @@ var E = { class: "border border-surface-3 rounded-xl w-full overflow-hidden bg-s
42
42
  ...e,
43
43
  metadata: I.value?.conversationContext
44
44
  });
45
- }, G = S(() => l.privacyPolicyNotice, "message.defaultPrivacyPolicyNotice");
45
+ }, G = C(() => l.privacyPolicyNotice, "message.defaultPrivacyPolicyNotice");
46
46
  return (n, r) => {
47
- let c = _, l = v;
47
+ let c = y, l = v;
48
48
  return h(), o("div", E, [i("div", D, [t(c, {
49
49
  name: "ri:send-plane-2-line",
50
50
  class: "text-16"
@@ -89,7 +89,7 @@ var E = { class: "border border-surface-3 rounded-xl w-full overflow-hidden bg-s
89
89
  i("div", A, [i("div", j, [t(c, {
90
90
  name: "ri:shield-check-line",
91
91
  class: "text-16 shrink-0"
92
- }), t(T, {
92
+ }), t(_, {
93
93
  markdown: m(G),
94
94
  class: "wysiwyg"
95
95
  }, null, 8, ["markdown"])]), t(l, {
@@ -116,4 +116,4 @@ var E = { class: "border border-surface-3 rounded-xl w-full overflow-hidden bg-s
116
116
  //#endregion
117
117
  export { I as default };
118
118
 
119
- //# sourceMappingURL=PkToolShowContactForm-upUNZtId.js.map
119
+ //# sourceMappingURL=PkToolShowContactForm-DtjVW-n6.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PkToolShowContactForm-upUNZtId.js","names":[],"sources":["../../../../packages/components/src/chat/PkToolShowContactForm.vue","../../../../packages/components/src/chat/PkToolShowContactForm.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useForm } from '@volverjs/form-vue'\n import * as z from 'zod'\n import { useSafeLocalStorage, useLocalizedString } from 'composables'\n import type { LocalizedString } from 'models'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n const props = defineProps<{\n part: unknown\n submitted?: boolean\n loading?: boolean\n error?: string\n readonly?: boolean\n privacyPolicyNotice?: LocalizedString\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n type: string\n toolCallId: string\n input?: {\n name: string\n email: string\n phone?: string\n conversationContext?: Record<string, unknown>\n }\n }\n return part\n })\n\n const input = computed(() => toolPart.value.input)\n\n const localSubmitted = useSafeLocalStorage<boolean>(\n computed(\n () =>\n `${toolPart.value.toolCallId}-${toolPart.value.type}-submitted`,\n ),\n false,\n )\n\n const LeadFormSchema = z.object({\n name: z.string().min(1).max(255).default(''),\n email: z.email().max(255).default(''),\n phone: z\n .string()\n .max(50)\n .regex(/^[+0-9\\s\\-.()]*$/, $t('validation.invalidPhoneNumber'))\n .optional(),\n })\n\n const emit = defineEmits<{\n submit: [data: Record<string, unknown>]\n }>()\n\n const { VvForm, VvFormField, formData } = useForm(LeadFormSchema, {\n lazyLoad: true,\n })\n\n // Pre-populate form with input values\n watch(\n input,\n (newInput) => {\n formData.value = {\n name: newInput?.name || '',\n email: newInput?.email || '',\n phone: newInput?.phone || '',\n }\n },\n { immediate: true },\n )\n\n watch(\n () => props.submitted,\n (submitted) => {\n if (submitted) {\n localSubmitted.value = true\n }\n },\n { immediate: true },\n )\n\n const isSubmitted = computed(() => {\n return props.submitted || localSubmitted.value\n })\n\n const submitLead = async (data: Record<string, unknown>): Promise<void> => {\n emit('submit', { ...data, metadata: input.value?.conversationContext })\n }\n\n const privacyNotice = useLocalizedString(\n () => props.privacyPolicyNotice,\n 'message.defaultPrivacyPolicyNotice',\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:send-plane-2-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{ $t('label.contactUs') }}</strong>\n </div>\n\n <Transition mode=\"out-in\">\n <div v-if=\"!isSubmitted\" class=\"p-sm\">\n <VvForm v-model=\"formData\" :readonly @submit=\"submitLead\">\n <VvFormField\n name=\"name\"\n type=\"text\"\n :label=\"$t('label.name')\"\n :placeholder=\"$t('placeholder.name')\"\n icon=\"ri:user-line\"\n modifiers=\"compact no-label\"\n class=\"mb-md\" />\n <VvFormField\n name=\"email\"\n type=\"email\"\n :label=\"$t('label.email')\"\n :placeholder=\"$t('placeholder.email')\"\n icon=\"ri:mail-line\"\n modifiers=\"compact no-label\"\n class=\"mb-md\" />\n <VvFormField\n name=\"phone\"\n type=\"tel\"\n :label=\"$t('label.phone')\"\n :placeholder=\"$t('placeholder.phone')\"\n icon=\"ri:phone-line\"\n class=\"mb-md\"\n modifiers=\"compact no-label\" />\n\n <div class=\"flex justify-between items-center gap-16 mt-xs\">\n <div\n class=\"text-smaller text-word-3 flex items-center gap-8\">\n <VvIcon\n name=\"ri:shield-check-line\"\n class=\"text-16 shrink-0\" />\n <PkStreamingMarkdown\n :markdown=\"privacyNotice\"\n class=\"wysiwyg\" />\n </div>\n <VvButton\n type=\"submit\"\n modifiers=\"primary\"\n :loading\n :disabled=\"loading || readonly\"\n icon-position=\"right\"\n class=\"shrink-0\"\n :label=\"$t('action.submit')\" />\n </div>\n </VvForm>\n </div>\n <div v-else class=\"p-sm\">\n <div class=\"flex items-center gap-sm\">\n <VvIcon\n name=\"ri:mail-check-line\"\n class=\"text-24 text-success\" />\n <div>\n <strong class=\"font-semibold block text-success\">\n {{ $t('message.leadSubmittedTitle') }}\n </strong>\n <p class=\"text-word-3\">\n {{ $t('message.leadSubmittedMessage') }}\n </p>\n </div>\n </div>\n </div>\n </Transition>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useForm } from '@volverjs/form-vue'\n import * as z from 'zod'\n import { useSafeLocalStorage, useLocalizedString } from 'composables'\n import type { LocalizedString } from 'models'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n const props = defineProps<{\n part: unknown\n submitted?: boolean\n loading?: boolean\n error?: string\n readonly?: boolean\n privacyPolicyNotice?: LocalizedString\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n type: string\n toolCallId: string\n input?: {\n name: string\n email: string\n phone?: string\n conversationContext?: Record<string, unknown>\n }\n }\n return part\n })\n\n const input = computed(() => toolPart.value.input)\n\n const localSubmitted = useSafeLocalStorage<boolean>(\n computed(\n () =>\n `${toolPart.value.toolCallId}-${toolPart.value.type}-submitted`,\n ),\n false,\n )\n\n const LeadFormSchema = z.object({\n name: z.string().min(1).max(255).default(''),\n email: z.email().max(255).default(''),\n phone: z\n .string()\n .max(50)\n .regex(/^[+0-9\\s\\-.()]*$/, $t('validation.invalidPhoneNumber'))\n .optional(),\n })\n\n const emit = defineEmits<{\n submit: [data: Record<string, unknown>]\n }>()\n\n const { VvForm, VvFormField, formData } = useForm(LeadFormSchema, {\n lazyLoad: true,\n })\n\n // Pre-populate form with input values\n watch(\n input,\n (newInput) => {\n formData.value = {\n name: newInput?.name || '',\n email: newInput?.email || '',\n phone: newInput?.phone || '',\n }\n },\n { immediate: true },\n )\n\n watch(\n () => props.submitted,\n (submitted) => {\n if (submitted) {\n localSubmitted.value = true\n }\n },\n { immediate: true },\n )\n\n const isSubmitted = computed(() => {\n return props.submitted || localSubmitted.value\n })\n\n const submitLead = async (data: Record<string, unknown>): Promise<void> => {\n emit('submit', { ...data, metadata: input.value?.conversationContext })\n }\n\n const privacyNotice = useLocalizedString(\n () => props.privacyPolicyNotice,\n 'message.defaultPrivacyPolicyNotice',\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:send-plane-2-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{ $t('label.contactUs') }}</strong>\n </div>\n\n <Transition mode=\"out-in\">\n <div v-if=\"!isSubmitted\" class=\"p-sm\">\n <VvForm v-model=\"formData\" :readonly @submit=\"submitLead\">\n <VvFormField\n name=\"name\"\n type=\"text\"\n :label=\"$t('label.name')\"\n :placeholder=\"$t('placeholder.name')\"\n icon=\"ri:user-line\"\n modifiers=\"compact no-label\"\n class=\"mb-md\" />\n <VvFormField\n name=\"email\"\n type=\"email\"\n :label=\"$t('label.email')\"\n :placeholder=\"$t('placeholder.email')\"\n icon=\"ri:mail-line\"\n modifiers=\"compact no-label\"\n class=\"mb-md\" />\n <VvFormField\n name=\"phone\"\n type=\"tel\"\n :label=\"$t('label.phone')\"\n :placeholder=\"$t('placeholder.phone')\"\n icon=\"ri:phone-line\"\n class=\"mb-md\"\n modifiers=\"compact no-label\" />\n\n <div class=\"flex justify-between items-center gap-16 mt-xs\">\n <div\n class=\"text-smaller text-word-3 flex items-center gap-8\">\n <VvIcon\n name=\"ri:shield-check-line\"\n class=\"text-16 shrink-0\" />\n <PkStreamingMarkdown\n :markdown=\"privacyNotice\"\n class=\"wysiwyg\" />\n </div>\n <VvButton\n type=\"submit\"\n modifiers=\"primary\"\n :loading\n :disabled=\"loading || readonly\"\n icon-position=\"right\"\n class=\"shrink-0\"\n :label=\"$t('action.submit')\" />\n </div>\n </VvForm>\n </div>\n <div v-else class=\"p-sm\">\n <div class=\"flex items-center gap-sm\">\n <VvIcon\n name=\"ri:mail-check-line\"\n class=\"text-24 text-success\" />\n <div>\n <strong class=\"font-semibold block text-success\">\n {{ $t('message.leadSubmittedTitle') }}\n </strong>\n <p class=\"text-word-3\">\n {{ $t('message.leadSubmittedMessage') }}\n </p>\n </div>\n </div>\n </div>\n </Transition>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"PkToolShowContactForm-DtjVW-n6.js","names":[],"sources":["../../../../packages/components/src/chat/PkToolShowContactForm.vue","../../../../packages/components/src/chat/PkToolShowContactForm.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useForm } from '@volverjs/form-vue'\n import * as z from 'zod'\n import { useSafeLocalStorage, useLocalizedString } from 'composables'\n import type { LocalizedString } from 'models'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n const props = defineProps<{\n part: unknown\n submitted?: boolean\n loading?: boolean\n error?: string\n readonly?: boolean\n privacyPolicyNotice?: LocalizedString\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n type: string\n toolCallId: string\n input?: {\n name: string\n email: string\n phone?: string\n conversationContext?: Record<string, unknown>\n }\n }\n return part\n })\n\n const input = computed(() => toolPart.value.input)\n\n const localSubmitted = useSafeLocalStorage<boolean>(\n computed(\n () =>\n `${toolPart.value.toolCallId}-${toolPart.value.type}-submitted`,\n ),\n false,\n )\n\n const LeadFormSchema = z.object({\n name: z.string().min(1).max(255).default(''),\n email: z.email().max(255).default(''),\n phone: z\n .string()\n .max(50)\n .regex(/^[+0-9\\s\\-.()]*$/, $t('validation.invalidPhoneNumber'))\n .optional(),\n })\n\n const emit = defineEmits<{\n submit: [data: Record<string, unknown>]\n }>()\n\n const { VvForm, VvFormField, formData } = useForm(LeadFormSchema, {\n lazyLoad: true,\n })\n\n // Pre-populate form with input values\n watch(\n input,\n (newInput) => {\n formData.value = {\n name: newInput?.name || '',\n email: newInput?.email || '',\n phone: newInput?.phone || '',\n }\n },\n { immediate: true },\n )\n\n watch(\n () => props.submitted,\n (submitted) => {\n if (submitted) {\n localSubmitted.value = true\n }\n },\n { immediate: true },\n )\n\n const isSubmitted = computed(() => {\n return props.submitted || localSubmitted.value\n })\n\n const submitLead = async (data: Record<string, unknown>): Promise<void> => {\n emit('submit', { ...data, metadata: input.value?.conversationContext })\n }\n\n const privacyNotice = useLocalizedString(\n () => props.privacyPolicyNotice,\n 'message.defaultPrivacyPolicyNotice',\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:send-plane-2-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{ $t('label.contactUs') }}</strong>\n </div>\n\n <Transition mode=\"out-in\">\n <div v-if=\"!isSubmitted\" class=\"p-sm\">\n <VvForm v-model=\"formData\" :readonly @submit=\"submitLead\">\n <VvFormField\n name=\"name\"\n type=\"text\"\n :label=\"$t('label.name')\"\n :placeholder=\"$t('placeholder.name')\"\n icon=\"ri:user-line\"\n modifiers=\"compact no-label\"\n class=\"mb-md\" />\n <VvFormField\n name=\"email\"\n type=\"email\"\n :label=\"$t('label.email')\"\n :placeholder=\"$t('placeholder.email')\"\n icon=\"ri:mail-line\"\n modifiers=\"compact no-label\"\n class=\"mb-md\" />\n <VvFormField\n name=\"phone\"\n type=\"tel\"\n :label=\"$t('label.phone')\"\n :placeholder=\"$t('placeholder.phone')\"\n icon=\"ri:phone-line\"\n class=\"mb-md\"\n modifiers=\"compact no-label\" />\n\n <div class=\"flex justify-between items-center gap-16 mt-xs\">\n <div\n class=\"text-smaller text-word-3 flex items-center gap-8\">\n <VvIcon\n name=\"ri:shield-check-line\"\n class=\"text-16 shrink-0\" />\n <PkStreamingMarkdown\n :markdown=\"privacyNotice\"\n class=\"wysiwyg\" />\n </div>\n <VvButton\n type=\"submit\"\n modifiers=\"primary\"\n :loading\n :disabled=\"loading || readonly\"\n icon-position=\"right\"\n class=\"shrink-0\"\n :label=\"$t('action.submit')\" />\n </div>\n </VvForm>\n </div>\n <div v-else class=\"p-sm\">\n <div class=\"flex items-center gap-sm\">\n <VvIcon\n name=\"ri:mail-check-line\"\n class=\"text-24 text-success\" />\n <div>\n <strong class=\"font-semibold block text-success\">\n {{ $t('message.leadSubmittedTitle') }}\n </strong>\n <p class=\"text-word-3\">\n {{ $t('message.leadSubmittedMessage') }}\n </p>\n </div>\n </div>\n </div>\n </Transition>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useForm } from '@volverjs/form-vue'\n import * as z from 'zod'\n import { useSafeLocalStorage, useLocalizedString } from 'composables'\n import type { LocalizedString } from 'models'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n const props = defineProps<{\n part: unknown\n submitted?: boolean\n loading?: boolean\n error?: string\n readonly?: boolean\n privacyPolicyNotice?: LocalizedString\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n type: string\n toolCallId: string\n input?: {\n name: string\n email: string\n phone?: string\n conversationContext?: Record<string, unknown>\n }\n }\n return part\n })\n\n const input = computed(() => toolPart.value.input)\n\n const localSubmitted = useSafeLocalStorage<boolean>(\n computed(\n () =>\n `${toolPart.value.toolCallId}-${toolPart.value.type}-submitted`,\n ),\n false,\n )\n\n const LeadFormSchema = z.object({\n name: z.string().min(1).max(255).default(''),\n email: z.email().max(255).default(''),\n phone: z\n .string()\n .max(50)\n .regex(/^[+0-9\\s\\-.()]*$/, $t('validation.invalidPhoneNumber'))\n .optional(),\n })\n\n const emit = defineEmits<{\n submit: [data: Record<string, unknown>]\n }>()\n\n const { VvForm, VvFormField, formData } = useForm(LeadFormSchema, {\n lazyLoad: true,\n })\n\n // Pre-populate form with input values\n watch(\n input,\n (newInput) => {\n formData.value = {\n name: newInput?.name || '',\n email: newInput?.email || '',\n phone: newInput?.phone || '',\n }\n },\n { immediate: true },\n )\n\n watch(\n () => props.submitted,\n (submitted) => {\n if (submitted) {\n localSubmitted.value = true\n }\n },\n { immediate: true },\n )\n\n const isSubmitted = computed(() => {\n return props.submitted || localSubmitted.value\n })\n\n const submitLead = async (data: Record<string, unknown>): Promise<void> => {\n emit('submit', { ...data, metadata: input.value?.conversationContext })\n }\n\n const privacyNotice = useLocalizedString(\n () => props.privacyPolicyNotice,\n 'message.defaultPrivacyPolicyNotice',\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:send-plane-2-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{ $t('label.contactUs') }}</strong>\n </div>\n\n <Transition mode=\"out-in\">\n <div v-if=\"!isSubmitted\" class=\"p-sm\">\n <VvForm v-model=\"formData\" :readonly @submit=\"submitLead\">\n <VvFormField\n name=\"name\"\n type=\"text\"\n :label=\"$t('label.name')\"\n :placeholder=\"$t('placeholder.name')\"\n icon=\"ri:user-line\"\n modifiers=\"compact no-label\"\n class=\"mb-md\" />\n <VvFormField\n name=\"email\"\n type=\"email\"\n :label=\"$t('label.email')\"\n :placeholder=\"$t('placeholder.email')\"\n icon=\"ri:mail-line\"\n modifiers=\"compact no-label\"\n class=\"mb-md\" />\n <VvFormField\n name=\"phone\"\n type=\"tel\"\n :label=\"$t('label.phone')\"\n :placeholder=\"$t('placeholder.phone')\"\n icon=\"ri:phone-line\"\n class=\"mb-md\"\n modifiers=\"compact no-label\" />\n\n <div class=\"flex justify-between items-center gap-16 mt-xs\">\n <div\n class=\"text-smaller text-word-3 flex items-center gap-8\">\n <VvIcon\n name=\"ri:shield-check-line\"\n class=\"text-16 shrink-0\" />\n <PkStreamingMarkdown\n :markdown=\"privacyNotice\"\n class=\"wysiwyg\" />\n </div>\n <VvButton\n type=\"submit\"\n modifiers=\"primary\"\n :loading\n :disabled=\"loading || readonly\"\n icon-position=\"right\"\n class=\"shrink-0\"\n :label=\"$t('action.submit')\" />\n </div>\n </VvForm>\n </div>\n <div v-else class=\"p-sm\">\n <div class=\"flex items-center gap-sm\">\n <VvIcon\n name=\"ri:mail-check-line\"\n class=\"text-24 text-success\" />\n <div>\n <strong class=\"font-semibold block text-success\">\n {{ $t('message.leadSubmittedTitle') }}\n </strong>\n <p class=\"text-word-3\">\n {{ $t('message.leadSubmittedMessage') }}\n </p>\n </div>\n </div>\n </div>\n </Transition>\n </div>\n</template>\n"],"mappings":"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"}