@8wave/ai-elements 0.71.0 → 0.74.0

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 (165) hide show
  1. package/README.md +62 -15
  2. package/dist/_chunks/{PkToolShowArtifact-D-dU41VG.js → PkToolShowArtifact-c_vCWUpQ.js} +2 -2
  3. package/dist/_chunks/{PkToolShowArtifact-D-dU41VG.js.map → PkToolShowArtifact-c_vCWUpQ.js.map} +1 -1
  4. package/dist/_chunks/{PkToolShowCalendarEvent-B33fWbkk.js → PkToolShowCalendarEvent-D2VHu1V3.js} +3 -3
  5. package/dist/_chunks/{PkToolShowCalendarEvent-B33fWbkk.js.map → PkToolShowCalendarEvent-D2VHu1V3.js.map} +1 -1
  6. package/dist/_chunks/{PkToolShowComparison-CcKHsr36.js → PkToolShowComparison-C2ZUH0w4.js} +3 -3
  7. package/dist/_chunks/{PkToolShowComparison-CcKHsr36.js.map → PkToolShowComparison-C2ZUH0w4.js.map} +1 -1
  8. package/dist/_chunks/{PkToolShowContactForm-SmOSbCsp.js → PkToolShowContactForm-6C4uWDtf.js} +3 -3
  9. package/dist/_chunks/{PkToolShowContactForm-SmOSbCsp.js.map → PkToolShowContactForm-6C4uWDtf.js.map} +1 -1
  10. package/dist/_chunks/{PkToolShowEmail-BOivL2p_.js → PkToolShowEmail-BuyCHUU5.js} +3 -3
  11. package/dist/_chunks/{PkToolShowEmail-BOivL2p_.js.map → PkToolShowEmail-BuyCHUU5.js.map} +1 -1
  12. package/dist/_chunks/{PkToolShowImageGallery-Dy0vFEU-.js → PkToolShowImageGallery-ByldZ0nj.js} +2 -2
  13. package/dist/_chunks/{PkToolShowImageGallery-Dy0vFEU-.js.map → PkToolShowImageGallery-ByldZ0nj.js.map} +1 -1
  14. package/dist/_chunks/{PkToolShowLocation-US6u26ra.js → PkToolShowLocation-BCFnC5c7.js} +3 -3
  15. package/dist/_chunks/{PkToolShowLocation-US6u26ra.js.map → PkToolShowLocation-BCFnC5c7.js.map} +1 -1
  16. package/dist/_chunks/{PkToolShowMessage-Cjslxq94.js → PkToolShowMessage-6Bsfi3BC.js} +3 -3
  17. package/dist/_chunks/{PkToolShowMessage-Cjslxq94.js.map → PkToolShowMessage-6Bsfi3BC.js.map} +1 -1
  18. package/dist/_chunks/{PkToolShowMultipleChoice-BEwiJCLu.js → PkToolShowMultipleChoice-BLNTD2lK.js} +3 -3
  19. package/dist/_chunks/{PkToolShowMultipleChoice-BEwiJCLu.js.map → PkToolShowMultipleChoice-BLNTD2lK.js.map} +1 -1
  20. package/dist/_chunks/{PkToolShowProductList-D3Qe8yQM.js → PkToolShowProductList-B4S5_m-f.js} +2 -2
  21. package/dist/_chunks/{PkToolShowProductList-D3Qe8yQM.js.map → PkToolShowProductList-B4S5_m-f.js.map} +1 -1
  22. package/dist/_chunks/{PkToolShowQrCode-B64sdI0N.js → PkToolShowQrCode-BVZlzYDq.js} +3 -3
  23. package/dist/_chunks/{PkToolShowQrCode-B64sdI0N.js.map → PkToolShowQrCode-BVZlzYDq.js.map} +1 -1
  24. package/dist/_chunks/{PkToolShowSources-CK3lqqoU.js → PkToolShowSources-BQo5DRwt.js} +13 -4
  25. package/dist/_chunks/PkToolShowSources-BQo5DRwt.js.map +1 -0
  26. package/dist/_chunks/{PkToolShowSuggestedReply-BGWA08C7.js → PkToolShowSuggestedReply-BxDI6yp_.js} +2 -2
  27. package/dist/_chunks/{PkToolShowSuggestedReply-BGWA08C7.js.map → PkToolShowSuggestedReply-BxDI6yp_.js.map} +1 -1
  28. package/dist/_chunks/{PkToolShowWeather-ClMzD04y.js → PkToolShowWeather-DR6egBIP.js} +3 -3
  29. package/dist/_chunks/{PkToolShowWeather-ClMzD04y.js.map → PkToolShowWeather-DR6egBIP.js.map} +1 -1
  30. package/dist/_chunks/{PkToolShowWebPages-BCqywwEK.js → PkToolShowWebPages-D8RngE-F.js} +2 -2
  31. package/dist/_chunks/{PkToolShowWebPages-BCqywwEK.js.map → PkToolShowWebPages-D8RngE-F.js.map} +1 -1
  32. package/dist/_chunks/{index.es-Z3Hu-QIb.js → index.es-BGFmj59S.js} +2429 -1559
  33. package/dist/_chunks/{index.es-Z3Hu-QIb.js.map → index.es-BGFmj59S.js.map} +1 -1
  34. package/dist/ai-elements.es.js +3026 -3063
  35. package/dist/ai-elements.es.js.map +1 -1
  36. package/dist-vue/PkChatbot.js +1 -1
  37. package/dist-vue/PkChatbotFeedbackForm.js +1 -1
  38. package/dist-vue/PkChatbotFilePreview.js +1 -1
  39. package/dist-vue/PkChatbotInput.js +1 -1
  40. package/dist-vue/PkChatbotMessages.js +1 -1
  41. package/dist-vue/PkChatbotViewChat.js +1 -1
  42. package/dist-vue/PkChatbotViewConversations.js +1 -1
  43. package/dist-vue/PkChatbotViewProfile.js +1 -1
  44. package/dist-vue/_chunks/PkChatbot-woRkjgP5.js +190 -0
  45. package/dist-vue/_chunks/{PkChatbot-CkxgCXC4.js.map → PkChatbot-woRkjgP5.js.map} +1 -1
  46. package/dist-vue/_chunks/{PkChatbotFeedbackForm-CUnS-WyR.js → PkChatbotFeedbackForm-D-lx1URv.js} +2 -2
  47. package/dist-vue/_chunks/{PkChatbotFeedbackForm-CUnS-WyR.js.map → PkChatbotFeedbackForm-D-lx1URv.js.map} +1 -1
  48. package/dist-vue/_chunks/{PkChatbotFilePreview-JSpi3pmN.js → PkChatbotFilePreview-DHzuGtz5.js} +2 -2
  49. package/dist-vue/_chunks/{PkChatbotFilePreview-JSpi3pmN.js.map → PkChatbotFilePreview-DHzuGtz5.js.map} +1 -1
  50. package/dist-vue/_chunks/{PkChatbotInput-ODPhsqZt.js → PkChatbotInput-LHE0HZ9z.js} +3 -3
  51. package/dist-vue/_chunks/{PkChatbotInput-ODPhsqZt.js.map → PkChatbotInput-LHE0HZ9z.js.map} +1 -1
  52. package/dist-vue/_chunks/{PkChatbotMessages-B5EK-qDo.js → PkChatbotMessages-BxTeEm3j.js} +15 -15
  53. package/dist-vue/_chunks/{PkChatbotMessages-B5EK-qDo.js.map → PkChatbotMessages-BxTeEm3j.js.map} +1 -1
  54. package/dist-vue/_chunks/{PkChatbotViewChat-C4haTRtG.js → PkChatbotViewChat-BoEfZeco.js} +9 -9
  55. package/dist-vue/_chunks/{PkChatbotViewChat-C4haTRtG.js.map → PkChatbotViewChat-BoEfZeco.js.map} +1 -1
  56. package/dist-vue/_chunks/PkChatbotViewConversations-DvVc1arX.js +163 -0
  57. package/dist-vue/_chunks/PkChatbotViewConversations-DvVc1arX.js.map +1 -0
  58. package/dist-vue/_chunks/{PkChatbotViewProfile-Cafl_Jf8.js → PkChatbotViewProfile-Dev_6pki.js} +2 -2
  59. package/dist-vue/_chunks/{PkChatbotViewProfile-Cafl_Jf8.js.map → PkChatbotViewProfile-Dev_6pki.js.map} +1 -1
  60. package/dist-vue/_chunks/{PkRelativeTime-jP41qAJ5.js → PkRelativeTime-WZ2aPcp_.js} +1 -1
  61. package/dist-vue/_chunks/{PkRelativeTime-jP41qAJ5.js.map → PkRelativeTime-WZ2aPcp_.js.map} +1 -1
  62. package/dist-vue/_chunks/{PkStreamingMarkdown-CtiMH6FD.js → PkStreamingMarkdown-B4gnJ4hk.js} +1 -1
  63. package/dist-vue/_chunks/{PkStreamingMarkdown-CtiMH6FD.js.map → PkStreamingMarkdown-B4gnJ4hk.js.map} +1 -1
  64. package/dist-vue/_chunks/{PkToolShowArtifact-C2DgB_1z.js → PkToolShowArtifact-EvbUZSOf.js} +2 -2
  65. package/dist-vue/_chunks/{PkToolShowArtifact-C2DgB_1z.js.map → PkToolShowArtifact-EvbUZSOf.js.map} +1 -1
  66. package/dist-vue/_chunks/{PkToolShowContactForm-BzzbXuhh.js → PkToolShowContactForm-CsDOqSJK.js} +3 -3
  67. package/dist-vue/_chunks/{PkToolShowContactForm-BzzbXuhh.js.map → PkToolShowContactForm-CsDOqSJK.js.map} +1 -1
  68. package/dist-vue/_chunks/{PkToolShowImageGallery-DQXrJYop.js → PkToolShowImageGallery-B7Bt6ZGv.js} +2 -2
  69. package/dist-vue/_chunks/{PkToolShowImageGallery-DQXrJYop.js.map → PkToolShowImageGallery-B7Bt6ZGv.js.map} +1 -1
  70. package/dist-vue/_chunks/{PkToolShowLocation-McDIqI8y.js → PkToolShowLocation-DteWf0Cs.js} +1 -1
  71. package/dist-vue/_chunks/{PkToolShowLocation-McDIqI8y.js.map → PkToolShowLocation-DteWf0Cs.js.map} +1 -1
  72. package/dist-vue/_chunks/{PkToolShowMultipleChoice-DW3m6VbJ.js → PkToolShowMultipleChoice-DZXfWtQp.js} +1 -1
  73. package/dist-vue/_chunks/{PkToolShowMultipleChoice-DW3m6VbJ.js.map → PkToolShowMultipleChoice-DZXfWtQp.js.map} +1 -1
  74. package/dist-vue/_chunks/{PkToolShowProductList-BDSJs7bn.js → PkToolShowProductList-CtqWK0x4.js} +2 -2
  75. package/dist-vue/_chunks/{PkToolShowProductList-BDSJs7bn.js.map → PkToolShowProductList-CtqWK0x4.js.map} +1 -1
  76. package/dist-vue/_chunks/{PkToolShowSources-BXeGRm4D.js → PkToolShowSources-ZtXFkIHt.js} +14 -5
  77. package/dist-vue/_chunks/PkToolShowSources-ZtXFkIHt.js.map +1 -0
  78. package/dist-vue/_chunks/{PkToolShowSuggestedReply-Dm3BTWYg.js → PkToolShowSuggestedReply-30m9yWDL.js} +1 -1
  79. package/dist-vue/_chunks/{PkToolShowSuggestedReply-Dm3BTWYg.js.map → PkToolShowSuggestedReply-30m9yWDL.js.map} +1 -1
  80. package/dist-vue/_chunks/{PkToolShowWebPages-DnYVhLVU.js → PkToolShowWebPages-DZIdrdWs.js} +2 -2
  81. package/dist-vue/_chunks/{PkToolShowWebPages-DnYVhLVU.js.map → PkToolShowWebPages-DZIdrdWs.js.map} +1 -1
  82. package/dist-vue/_chunks/{PkUrl-CH4pWBR8.js → PkUrl-CGbSBfuP.js} +1 -1
  83. package/dist-vue/_chunks/{PkUrl-CH4pWBR8.js.map → PkUrl-CGbSBfuP.js.map} +1 -1
  84. package/dist-vue/_chunks/{createChatbotApiClient-OA7JscBS.js → createChatbotApiClient-YJegM3ni.js} +141 -119
  85. package/dist-vue/_chunks/createChatbotApiClient-YJegM3ni.js.map +1 -0
  86. package/dist-vue/_chunks/{dist-Bs6dYy7x.js → dist-21vPGg1O.js} +3 -3
  87. package/dist-vue/_chunks/{dist-Bs6dYy7x.js.map → dist-21vPGg1O.js.map} +1 -1
  88. package/dist-vue/_chunks/{dist-Bb1zRSg4.js → dist-BGXTbYew2.js} +4 -4
  89. package/dist-vue/_chunks/dist-BGXTbYew2.js.map +1 -0
  90. package/dist-vue/_chunks/{dist-BrlD3co0.js → dist-BL9cumqH.js} +2 -2
  91. package/dist-vue/_chunks/{dist-BrlD3co0.js.map → dist-BL9cumqH.js.map} +1 -1
  92. package/dist-vue/_chunks/{dist-B9Pw4_a5.js → dist-BU-VgsYM.js} +3 -3
  93. package/dist-vue/_chunks/{dist-B9Pw4_a5.js.map → dist-BU-VgsYM.js.map} +1 -1
  94. package/dist-vue/_chunks/{dist-D-tjAaHK.js → dist-BU5m1pTR.js} +3 -3
  95. package/dist-vue/_chunks/{dist-D-tjAaHK.js.map → dist-BU5m1pTR.js.map} +1 -1
  96. package/dist-vue/_chunks/{dist-Dn0cKZ5Q.js → dist-BbP2I_Or.js} +2 -2
  97. package/dist-vue/_chunks/{dist-Dn0cKZ5Q.js.map → dist-BbP2I_Or.js.map} +1 -1
  98. package/dist-vue/_chunks/{dist-Cvsv0YEw.js → dist-BvmTki6w.js} +3 -3
  99. package/dist-vue/_chunks/{dist-Cvsv0YEw.js.map → dist-BvmTki6w.js.map} +1 -1
  100. package/dist-vue/_chunks/{dist-QzbLuLIV.js → dist-C3dPzENq.js} +3 -3
  101. package/dist-vue/_chunks/{dist-QzbLuLIV.js.map → dist-C3dPzENq.js.map} +1 -1
  102. package/dist-vue/_chunks/{dist-BMWOJZqC.js → dist-C6AWJq9a.js} +2 -2
  103. package/dist-vue/_chunks/{dist-BMWOJZqC.js.map → dist-C6AWJq9a.js.map} +1 -1
  104. package/dist-vue/_chunks/{dist-BQCdUoYc.js → dist-CGNGkvWf.js} +4 -4
  105. package/dist-vue/_chunks/{dist-BQCdUoYc.js.map → dist-CGNGkvWf.js.map} +1 -1
  106. package/dist-vue/_chunks/{dist-JOgG1zY3.js → dist-CIN_Avbm.js} +1 -1
  107. package/dist-vue/_chunks/{dist-JOgG1zY3.js.map → dist-CIN_Avbm.js.map} +1 -1
  108. package/dist-vue/_chunks/{dist-NKG-Bt-Q.js → dist-CePpgudw.js} +3 -3
  109. package/dist-vue/_chunks/{dist-NKG-Bt-Q.js.map → dist-CePpgudw.js.map} +1 -1
  110. package/dist-vue/_chunks/{dist-C13mHkC-.js → dist-CtMo7ig_.js} +2 -2
  111. package/dist-vue/_chunks/{dist-C13mHkC-.js.map → dist-CtMo7ig_.js.map} +1 -1
  112. package/dist-vue/_chunks/{dist-DucfoJQX.js → dist-CwG072cD.js} +3 -3
  113. package/dist-vue/_chunks/{dist-DucfoJQX.js.map → dist-CwG072cD.js.map} +1 -1
  114. package/dist-vue/_chunks/{dist-_4yQQX_L.js → dist-DFvVVU0-.js} +2 -2
  115. package/dist-vue/_chunks/{dist-_4yQQX_L.js.map → dist-DFvVVU0-.js.map} +1 -1
  116. package/dist-vue/_chunks/{dist-C_tRbeXQ.js → dist-DGz57kzK.js} +2 -2
  117. package/dist-vue/_chunks/{dist-C_tRbeXQ.js.map → dist-DGz57kzK.js.map} +1 -1
  118. package/dist-vue/_chunks/{dist-C2tC3pDh.js → dist-DT30Xa-D.js} +2 -2
  119. package/dist-vue/_chunks/{dist-C2tC3pDh.js.map → dist-DT30Xa-D.js.map} +1 -1
  120. package/dist-vue/_chunks/{dist-DNn7FqmI.js → dist-DoRhRpjL.js} +2 -2
  121. package/dist-vue/_chunks/{dist-DNn7FqmI.js.map → dist-DoRhRpjL.js.map} +1 -1
  122. package/dist-vue/_chunks/{dist-CQmgfFIN.js → dist-GnhLE5-A.js} +4 -4
  123. package/dist-vue/_chunks/{dist-CQmgfFIN.js.map → dist-GnhLE5-A.js.map} +1 -1
  124. package/dist-vue/_chunks/{dist-1ToEz3Zq.js → dist-QzWOn2Kx.js} +3 -3
  125. package/dist-vue/_chunks/{dist-1ToEz3Zq.js.map → dist-QzWOn2Kx.js.map} +1 -1
  126. package/dist-vue/_chunks/{dist-e9UFeG14.js → dist-uYEYs0EJ.js} +2 -2
  127. package/dist-vue/_chunks/{dist-e9UFeG14.js.map → dist-uYEYs0EJ.js.map} +1 -1
  128. package/dist-vue/_chunks/{dist-BpT8aqtS.js → dist-ukeBjdwq.js} +4 -4
  129. package/dist-vue/_chunks/{dist-BpT8aqtS.js.map → dist-ukeBjdwq.js.map} +1 -1
  130. package/dist-vue/_chunks/{dist-BHTSdHeX.js → dist-wLB8N32T.js} +3 -3
  131. package/dist-vue/_chunks/{dist-BHTSdHeX.js.map → dist-wLB8N32T.js.map} +1 -1
  132. package/dist-vue/_chunks/{index.es-BnOT0fHY.js → index.es-CrPSzhoZ.js} +1 -1
  133. package/dist-vue/_chunks/{index.es-BnOT0fHY.js.map → index.es-CrPSzhoZ.js.map} +1 -1
  134. package/dist-vue/_chunks/{useChatbotStore-BNGyIqjI.js → useChatbotStore-DGL81KJa.js} +868 -852
  135. package/dist-vue/_chunks/{useChatbotStore-BNGyIqjI.js.map → useChatbotStore-DGL81KJa.js.map} +1 -1
  136. package/dist-vue/_chunks/{useLightbox-BiZUwsmB.js → useLightbox-1sB7fmFb.js} +1 -1
  137. package/dist-vue/_chunks/{useLightbox-BiZUwsmB.js.map → useLightbox-1sB7fmFb.js.map} +1 -1
  138. package/dist-vue/_chunks/{utils-DO7emdsn.js → utils-BegUBK7s.js} +1 -1
  139. package/dist-vue/_chunks/{utils-DO7emdsn.js.map → utils-BegUBK7s.js.map} +1 -1
  140. package/dist-vue/api.js +1 -1
  141. package/dist-vue/apps/web-component/src/composables/useChatbotAgent.d.ts +3 -1
  142. package/dist-vue/composables.js +3 -3
  143. package/dist-vue/index.js +3780 -3498
  144. package/dist-vue/index.js.map +1 -1
  145. package/dist-vue/locales.js +56 -20
  146. package/dist-vue/packages/components/src/PkEditorPrompt.d.ts +2 -0
  147. package/dist-vue/packages/components/src/chat/PkAgentSettingsPanel.d.ts +6 -3
  148. package/dist-vue/packages/components/src/chat/PkEditorChannels.d.ts +16 -0
  149. package/dist-vue/packages/composable/src/chatbot/api/createChatbotApiClient.d.ts +2 -0
  150. package/dist-vue/packages/composable/src/chatbot/useChatbotStore.d.ts +2 -3553
  151. package/dist-vue/packages/models/src/schema/Agent.d.ts +15 -5
  152. package/dist-vue/packages/models/src/schema/AgentChatStatistics.d.ts +160 -0
  153. package/dist-vue/packages/models/src/schema/Chat.d.ts +6 -0
  154. package/dist-vue/packages/models/src/schema/Document.d.ts +18 -0
  155. package/dist-vue/packages/models/src/schema/ReasoningChat.d.ts +4 -2
  156. package/dist-vue/packages/models/src/schema/SubAgent.d.ts +5 -3
  157. package/dist-vue/style.css +1 -1
  158. package/package.json +2 -2
  159. package/dist/_chunks/PkToolShowSources-CK3lqqoU.js.map +0 -1
  160. package/dist-vue/_chunks/PkChatbot-CkxgCXC4.js +0 -190
  161. package/dist-vue/_chunks/PkChatbotViewConversations--vd3MWYy.js +0 -40
  162. package/dist-vue/_chunks/PkChatbotViewConversations--vd3MWYy.js.map +0 -1
  163. package/dist-vue/_chunks/PkToolShowSources-BXeGRm4D.js.map +0 -1
  164. package/dist-vue/_chunks/createChatbotApiClient-OA7JscBS.js.map +0 -1
  165. package/dist-vue/_chunks/dist-Bb1zRSg4.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"PkToolShowSources-CK3lqqoU.js","names":["core._coercedDate","schemas.ZodDate","$t"],"sources":["../../../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/coerce.js","../../../../packages/models/src/utils.ts","../../../../packages/models/src/schema/constants.ts","../../../../packages/models/src/schema/Media.ts","../../../../packages/models/src/schema/Header.ts","../../../../packages/models/src/schema/Document.ts","../../../../packages/components/src/chat/PkChunkPreview.vue","../../../../packages/components/src/chat/PkChunkPreview.vue","../../../../packages/components/src/chat/PkDocumentHeader.vue","../../../../packages/components/src/chat/PkDocumentHeader.vue","../../../../packages/components/src/chat/PkToolShowSources.vue","../../../../packages/components/src/chat/PkToolShowSources.vue"],"sourcesContent":["import * as core from \"../core/index.js\";\nimport * as schemas from \"./schemas.js\";\nexport function string(params) {\n return core._coercedString(schemas.ZodString, params);\n}\nexport function number(params) {\n return core._coercedNumber(schemas.ZodNumber, params);\n}\nexport function boolean(params) {\n return core._coercedBoolean(schemas.ZodBoolean, params);\n}\nexport function bigint(params) {\n return core._coercedBigint(schemas.ZodBigInt, params);\n}\nexport function date(params) {\n return core._coercedDate(schemas.ZodDate, params);\n}\n","import * as z from 'zod'\n\nexport type QueryStringFilter<T extends string = string> = `filter[${T}]`\nexport type Querystring = {\n 'page[number]'?: number | string\n 'page[size]'?: number | string\n sort?: string[] | string\n [filterKeys: QueryStringFilter]: unknown\n [otherKeys: string]: unknown\n}\n\nexport const makeSortEnum = <const T extends string>(input: T) => {\n return [`${input}`, `-${input}`] as [T, `-${T}`]\n}\n\nexport const makeSortEnums = <const T extends string>(input: readonly T[]) => {\n return input.flatMap((i) => makeSortEnum(i))\n}\n\nexport const zodQs = {\n pagination: (defaultNumber = 1, defaultSize = 10) => {\n return {\n 'page[number]': z\n .number()\n .or(z.string())\n .transform((v) => Number(v))\n .default(defaultNumber),\n 'page[size]': z\n .number()\n .or(z.string())\n .transform((v) => Number(v))\n .default(defaultSize),\n }\n },\n filter: <const T extends string>(input: T) => {\n return { [`filter[${input}]`]: z.string().optional() } as Record<\n `filter[${T}]`,\n z.ZodOptional<z.ZodString | z.ZodArray<z.ZodString>>\n >\n },\n include: <const T extends string>(input: T) => {\n return { [`include[${input}]`]: z.string().optional() } as Record<\n `include[${T}]`,\n z.ZodOptional<z.ZodArray<z.ZodString> | z.ZodString>\n >\n },\n range: <const T extends string>(input: T) => {\n return {\n [`from[${input}]`]: z.string().optional(),\n [`to[${input}]`]: z.string().optional(),\n } as Record<`from[${T}]` | `to[${T}]`, z.ZodOptional<z.ZodString>>\n },\n has: <const T extends string>(input: T) => {\n return { [`has[${input}]`]: z.boolean().optional() } as Record<\n `has[${T}]`,\n z.ZodOptional<z.ZodBoolean>\n >\n },\n fullText: () => {\n return { [`filter[fullText]`]: z.string().optional() }\n },\n ids: () => {\n return { ids: z.union([z.string(), z.array(z.string())]).optional() }\n },\n deleted: () => {\n return { 'filter[isDeleted]': z.boolean().default(false) }\n },\n filters: <const T extends string>(input: readonly T[]) => {\n return input\n .map((i) => zodQs.filter(i))\n .reduce((a, b) => ({ ...a, ...b }))\n },\n sort: <const S extends string>(sort: S[]) => {\n const sortEnums = makeSortEnums(sort) as [S, ...`-${S}`[]]\n return {\n // @ts-expect-error: zod does not support tuple types\n sort: z.enum(sortEnums).optional().default(sortEnums[0]),\n }\n },\n}\n","export enum LanguageModel {\n // OpenAI\n textEmbedding3Small = 'openai/text-embedding-3-small',\n gpt5Nano = 'openai/gpt-5-nano',\n gpt5Mini = 'openai/gpt-5-mini',\n gpt51Thinking = 'openai/gpt-5.1-thinking',\n gpt51Instant = 'openai/gpt-5.1-instant',\n gpt52 = 'openai/gpt-5.2',\n gpt52Chat = 'openai/gpt-5.2-chat',\n gpt54nano = 'openai/gpt-5.4-nano',\n gpt54mini = 'openai/gpt-5.4-mini',\n gpt54 = 'openai/gpt-5.4',\n gpt54Pro = 'openai/gpt-5.4-pro',\n gpt55 = 'openai/gpt-5.5',\n gpt55Pro = 'openai/gpt-5.5-pro',\n // Google Gemini\n gemini25Flash = 'google/gemini-2.5-flash',\n gemini25FlashLite = 'google/gemini-2.5-flash-lite',\n gemini25Pro = 'google/gemini-2.5-pro',\n gemini3Flash = 'google/gemini-3-flash',\n gemini3ProPreview = 'google/gemini-3-pro-preview',\n gemini31FlashLitePreview = 'google/gemini-3.1-flash-lite-preview',\n gemini31ProPreview = 'google/gemini-3.1-pro-preview',\n // Anthropic Claude\n claudeHaiku45 = 'anthropic/claude-haiku-4.5',\n claudeSonnet45 = 'anthropic/claude-sonnet-4.5',\n claudeSonnet46 = 'anthropic/claude-sonnet-4.6',\n claudeOpus46 = 'anthropic/claude-opus-4.6',\n // Deepseek\n deepseek32 = 'deepseek/deepseek-v3.2',\n deepseek32Thinking = 'deepseek/deepseek-v3.2-thinking',\n deepseek4pro = 'deepseek/deepseek-v4-pro',\n deepseek4Flash = 'deepseek/deepseek-v4-flash',\n // Alibaba\n alibabaQwen36Plus = 'alibaba/qwen3.6-plus',\n}\n\nexport const EMBED_MODEL = LanguageModel.textEmbedding3Small\n\nexport enum LanguageModelBrand {\n openai = 'openai',\n google = 'google',\n anthropic = 'anthropic',\n deepseek = 'deepseek',\n}\n\n/**\n * Supported languages for documents and revised answers\n */\nexport enum SupportedLanguage {\n it = 'it',\n en = 'en',\n es = 'es',\n fr = 'fr',\n de = 'de',\n}\n\n/**\n * Language display names (i18n keys)\n */\nexport const LANGUAGE_NAMES: Record<SupportedLanguage, string> = {\n [SupportedLanguage.it]: 'language.italian',\n [SupportedLanguage.en]: 'language.english',\n [SupportedLanguage.es]: 'language.spanish',\n [SupportedLanguage.fr]: 'language.french',\n [SupportedLanguage.de]: 'language.german',\n}\n\n/**\n * Content extraction strategies for URL scraping\n */\nexport enum ExtractionStrategy {\n /** Use Mozilla Readability for content extraction (fast, free, no API calls) */\n READABILITY = 'readability',\n /** Use AI-based extraction (better for complex layouts, requires API calls) */\n AI = 'ai',\n}\n\n/**\n * Browser engine options for URL scraping\n */\nexport enum BrowserEngine {\n /** Use simple HTTP fetch (fast, lightweight, no JavaScript support) */\n FETCH = 'fetch',\n /** Use Puppeteer with headless Chrome (full browser, JavaScript support) */\n PUPPETEER = 'puppeteer',\n}\n","import { z } from 'zod'\n\n// ===== Constants =====\n\nexport const MAX_FILE_SIZE = 100 * 1024 * 1024 // 100MB\n\nexport const MIME_TYPE_REGEX = /^[a-z]+\\/[a-z0-9\\-+.]+$/i\n\nexport const SUPPORTED_IMAGE_TYPES = [\n 'image/jpeg',\n 'image/png',\n 'image/gif',\n 'image/webp',\n 'image/svg+xml',\n] as const\n\nexport const SUPPORTED_DOCUMENT_TYPES = [\n 'application/pdf',\n 'application/msword',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n 'application/vnd.ms-excel',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n 'text/plain',\n 'text/markdown',\n] as const\n\nexport const SUPPORTED_VIDEO_TYPES = [\n 'video/mp4',\n 'video/webm',\n 'video/ogg',\n] as const\n\nexport const SUPPORTED_AUDIO_TYPES = [\n 'audio/mpeg',\n 'audio/wav',\n 'audio/ogg',\n] as const\n\n// ===== Enums =====\n\nexport enum StoragePolicy {\n DEFAULT = 'default',\n COLD = 'cold',\n HOT = 'hot',\n ARCHIVE = 'archive',\n}\n\nexport enum PreviewStatus {\n Pending = 'pending',\n Done = 'done',\n Failed = 'failed',\n}\n\n// ===== Storage Handle Schemas =====\n\nconst AzureBlobStorageHandleSchema = z.object({\n type: z.literal('azure-blob'),\n blobUri: z.url(),\n containerName: z.string().min(1),\n pathRelativeToContainer: z.string().min(1),\n})\n\nconst S3StorageHandleSchema = z.object({\n type: z.literal('s3'),\n bucket: z.string().min(1),\n key: z.string().min(1),\n region: z.string().min(1),\n})\n\nconst StorageHandleSchema = z.discriminatedUnion('type', [\n AzureBlobStorageHandleSchema,\n S3StorageHandleSchema,\n])\n\n// ===== Media Upload Schema =====\n\n/**\n * Media upload information for preparing a file upload\n */\nexport const MediaUploadSchema = z.object({\n /** Media type category (picture, video, audio, etc.) */\n type: z.string().min(1),\n /** Original filename */\n name: z.string().min(1),\n /** MIME type (e.g., 'image/jpeg') */\n mimeType: z.string().regex(MIME_TYPE_REGEX),\n /** File size in bytes (must be positive) */\n bytesCount: z.number().positive(),\n /** File extension with dot (e.g., '.jpg') */\n extension: z\n .string()\n .regex(/^\\.[a-zA-Z0-9]+$/)\n .transform((ext) => ext.toLowerCase()),\n /** Optional custom stored filename */\n storedFileName: z.string().optional(),\n /** Additional metadata key-value pairs */\n metadata: z.record(z.string(), z.string()).default({}),\n /** Storage tags for categorization */\n tags: z.record(z.string(), z.string()).default({}),\n})\nexport type MediaUpload = z.infer<typeof MediaUploadSchema>\n\n// ===== Media Source Schema =====\n\n/**\n * Complete media source information including storage details\n */\nexport const MediaSourceSchema = MediaUploadSchema.extend({\n /** Storage backend configuration */\n storageHandle: StorageHandleSchema,\n /** Storage tier/policy */\n storagePolicy: z.enum(StoragePolicy),\n /** Optional signature data for verification */\n signData: z.string().optional(),\n /** Actual stored filename (required) */\n storedFileName: z.string().min(1),\n})\nexport type MediaSource = z.infer<typeof MediaSourceSchema>\n\n// ===== Media Schema =====\n\n/**\n * Complete media object with source and optional variants\n */\nexport const MediaSchema = z.object({\n /** Display name for the media */\n name: z.string().min(1),\n /** Primary media source */\n src: MediaSourceSchema,\n /** Optional additional sources (e.g., different resolutions) */\n srcSet: z.array(MediaSourceSchema).default([]),\n /** Type-specific metadata (dimensions, duration, etc.) */\n rawOptions: z.custom<RawOptions>().optional(),\n})\nexport type Media = z.infer<typeof MediaSchema>\n\n// ===== Upload Handle Schema =====\n\n/**\n * Upload handle containing SAS URI and metadata for client-side upload\n */\nexport const MediaUploadHandleSchema = z.object({\n /** Media source information */\n src: MediaSourceSchema,\n /** Upload credentials and metadata */\n uploadHandle: z.object({\n /** Shared Access Signature URI for upload */\n uploadSasuri: z.string().url(),\n /** Metadata to attach to the blob */\n metadata: z.record(z.string(), z.string()).default({}),\n /** Tags to attach to the blob */\n tags: z.record(z.string(), z.string()).default({}),\n }),\n})\nexport type MediaUploadHandle = z.infer<typeof MediaUploadHandleSchema>\n\n// ===== Download Handle Schema =====\n\n/**\n * Download handle containing SAS URIs for different access patterns\n */\nexport const MediaDownloadHandleSchema = z.object({\n /** Media source information */\n src: MediaSourceSchema,\n /** Download credentials and URIs */\n downloadHandle: z.object({\n /** SAS URI for file download */\n downloadSasuri: z.string().url(),\n /** SAS URI for inline viewing */\n viewSasuri: z.string().url(),\n /** Optional SAS URI for preview thumbnail */\n previewSasuri: z.string().url().optional(),\n /** Expiration timestamp for the SAS URIs */\n expiresOn: z.string().datetime(),\n /** Storage backend type */\n type: z.string(),\n }),\n})\nexport type MediaDownloadHandle = z.infer<typeof MediaDownloadHandleSchema>\n\n// ===== Media Types =====\n\nexport enum MediaType {\n picture = 'picture',\n video = 'video',\n audio = 'audio',\n office = 'office',\n archive = 'archive',\n binary = 'binary',\n executable = 'executable',\n}\n\n// ===== Raw Options Schemas =====\n\nconst PictureRawOptionsSchema = z.object({\n type: z.literal(MediaType.picture),\n width: z.number().positive(),\n height: z.number().positive(),\n blurhash: z.string().optional(),\n})\n\nconst VideoRawOptionsSchema = z.object({\n type: z.literal(MediaType.video),\n width: z.number().positive(),\n height: z.number().positive(),\n duration: z.number().nonnegative(),\n})\n\nconst AudioRawOptionsSchema = z.object({\n type: z.literal(MediaType.audio),\n duration: z.number().nonnegative(),\n})\n\nconst OfficeRawOptionsSchema = z.object({\n type: z.literal(MediaType.office),\n})\n\nconst ArchiveRawOptionsSchema = z.object({\n type: z.literal(MediaType.archive),\n})\n\nconst BinaryRawOptionsSchema = z.object({\n type: z.literal(MediaType.binary),\n})\n\nconst ExecutableRawOptionsSchema = z.object({\n type: z.literal(MediaType.executable),\n})\n\nexport const RawOptionsSchema = z.discriminatedUnion('type', [\n PictureRawOptionsSchema,\n VideoRawOptionsSchema,\n AudioRawOptionsSchema,\n OfficeRawOptionsSchema,\n ArchiveRawOptionsSchema,\n BinaryRawOptionsSchema,\n ExecutableRawOptionsSchema,\n])\n\n// ===== Raw Options Types =====\n\n// ===== Raw Options Types =====\n\nexport type PictureRawOptions = z.infer<typeof PictureRawOptionsSchema>\nexport type VideoRawOptions = z.infer<typeof VideoRawOptionsSchema>\nexport type AudioRawOptions = z.infer<typeof AudioRawOptionsSchema>\nexport type OfficeRawOptions = z.infer<typeof OfficeRawOptionsSchema>\nexport type ArchiveRawOptions = z.infer<typeof ArchiveRawOptionsSchema>\nexport type BinaryRawOptions = z.infer<typeof BinaryRawOptionsSchema>\nexport type ExecutableRawOptions = z.infer<typeof ExecutableRawOptionsSchema>\n\nexport type RawOptions = z.infer<typeof RawOptionsSchema>\n\n// ===== Uploaded File Type =====\n\nexport type UploadedFile<Source = undefined> = Source extends undefined\n ? {\n name: string\n size: number\n type: string\n url: string\n lastModified?: number\n }\n : {\n name: string\n size: number\n type: string\n url: string\n lastModified?: number\n source: Source\n }\n\n// ===== Helper Functions =====\n\n/**\n * Check if a MIME type is a supported image format\n */\nexport const isSupportedImageType = (mimeType: string): boolean => {\n return mimeType.startsWith('image/')\n}\n\n/**\n * Check if a MIME type supports preview generation\n */\nexport const isSupportedPreviewType = (mimeType: string): boolean => {\n return mimeType.startsWith('image/') || mimeType === 'application/pdf'\n}\n\n/**\n * Determine MediaType from MIME type\n */\nexport const getMediaTypeFromMime = (mimeType: string): MediaType => {\n if (mimeType.startsWith('image/')) return MediaType.picture\n if (mimeType.startsWith('video/')) return MediaType.video\n if (mimeType.startsWith('audio/')) return MediaType.audio\n if (\n mimeType.startsWith('application/pdf') ||\n mimeType.startsWith('application/msword') ||\n mimeType.startsWith('application/vnd.openxmlformats') ||\n mimeType.startsWith('application/vnd.ms-')\n ) {\n return MediaType.office\n }\n if (\n mimeType === 'application/zip' ||\n mimeType === 'application/x-rar-compressed' ||\n mimeType === 'application/x-7z-compressed'\n ) {\n return MediaType.archive\n }\n if (\n mimeType.startsWith('application/x-') &&\n mimeType.includes('executable')\n ) {\n return MediaType.executable\n }\n return MediaType.binary\n}\n\n/**\n * Extract file extension from filename\n */\nexport const getExtensionFromFilename = (filename: string): string => {\n const lastDot = filename.lastIndexOf('.')\n return lastDot === -1 ? '' : filename.slice(lastDot).toLowerCase()\n}\n\n/**\n * Format bytes to human-readable string\n */\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n if (bytes === 0) return '0 Bytes'\n const k = 1024\n const dm = decimals < 0 ? 0 : decimals\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`\n}\n\n// ===== Type Guards =====\n\nexport const isPictureOptions = (\n options: RawOptions,\n): options is PictureRawOptions => {\n return options.type === MediaType.picture\n}\n\nexport const isVideoOptions = (\n options: RawOptions,\n): options is VideoRawOptions => {\n return options.type === MediaType.video\n}\n\nexport const isAudioOptions = (\n options: RawOptions,\n): options is AudioRawOptions => {\n return options.type === MediaType.audio\n}\n\nexport const isOfficeOptions = (\n options: RawOptions,\n): options is OfficeRawOptions => {\n return options.type === MediaType.office\n}\n\nexport const isArchiveOptions = (\n options: RawOptions,\n): options is ArchiveRawOptions => {\n return options.type === MediaType.archive\n}\n\nexport const isBinaryOptions = (\n options: RawOptions,\n): options is BinaryRawOptions => {\n return options.type === MediaType.binary\n}\n\nexport const isExecutableOptions = (\n options: RawOptions,\n): options is ExecutableRawOptions => {\n return options.type === MediaType.executable\n}\n","import * as z from 'zod'\n\nexport const HeaderSchema = z.object({\n key: z.string().optional(),\n value: z.string().optional(),\n})\n\nexport const HeadesSchema = z.array(HeaderSchema).transform((headers) => {\n return headers?.filter(\n (header) => header.key?.trim() && header.value?.trim(),\n ) as Array<{ key: string; value: string }>\n})\n\nexport type Header = z.infer<typeof HeaderSchema>\nexport type Headers = z.infer<typeof HeadesSchema>\n","import * as z from 'zod'\nimport { zodQs } from '../utils'\nimport {\n SupportedLanguage,\n ExtractionStrategy,\n BrowserEngine,\n} from './constants'\nimport { MediaSchema } from './Media'\nimport { HeadesSchema } from './Header'\n\n/**\n * Processing status for document indexing and embedding generation\n */\nexport enum IndexStatus {\n Pending = 'pending',\n Processing = 'processing',\n Success = 'success',\n Failed = 'failed',\n}\n\n// ===== Document Source Types =====\n\n/**\n * Conversion options for document processing\n * Used when creating or reprocessing documents\n */\nexport const ConversionOptionsSchema = z.object({\n extractionStrategy: z.enum(ExtractionStrategy).optional(),\n browserEngine: z.enum(BrowserEngine).optional(),\n headers: HeadesSchema.nullish(),\n aiDescriptionModel: z.string().optional(),\n aiDescriptionPrompt: z.string().max(5000).optional(),\n language: z.string().optional(),\n})\n\nexport type ConversionOptions = z.infer<typeof ConversionOptionsSchema>\n\n/**\n * Metadata structure for document.metadata column\n * Consolidates all metadata from converters and source info\n */\nexport const DocumentMetadataSchema = z\n .object({\n // === Source Info (URL documents only) ===\n source: z\n .object({\n url: z.string(),\n lastScrapedAt: z.string(),\n })\n .optional(),\n\n // === Media Info (File documents only) ===\n media: MediaSchema.optional(),\n\n // === Common Fields (all document types) ===\n title: z.string().optional(),\n author: z.string().optional(),\n description: z.string().optional(),\n summary: z.string().optional(),\n keywords: z.array(z.string()).optional(),\n\n // === PDF Specific ===\n subject: z.string().optional(),\n creator: z.string().optional(), // Original application\n producer: z.string().optional(), // PDF generator software\n creationDate: z.string().optional(),\n modificationDate: z.string().optional(),\n pageCount: z\n .union([z.number(), z.array(z.unknown())])\n .transform((val) => (Array.isArray(val) ? val.length : val))\n .optional(),\n encrypted: z.boolean().optional(),\n\n // === DOCX Specific ===\n characterCount: z.number().optional(),\n lineCount: z.number().optional(),\n\n // === URL Specific ===\n siteName: z.string().optional(),\n canonicalUrl: z.url().optional(),\n imageUrl: z.url().optional(),\n favicon: z.url().optional(),\n type: z.string().optional(), // og:type (article, website, etc.)\n locale: z.string().optional(),\n tags: z.array(z.string()).optional(),\n publishedTime: z.string().optional(),\n modifiedTime: z.string().optional(),\n\n // === Metrics (all document types) ===\n wordCount: z.number().optional(),\n paragraphCount: z.number().optional(),\n readingTime: z.number().optional(), // in minutes\n\n // === Conversion Options (for reprocessing) ===\n conversionOptions: ConversionOptionsSchema.optional(),\n })\n .loose() // Allow additional custom fields\n\nexport type DocumentMetadata = z.infer<typeof DocumentMetadataSchema>\n\n/**\n * Document type enum\n *\n * - 'file': Document created from uploaded file (PDF, DOCX)\n * - 'url': Document created from web scraping\n * - 'revised-answer': Document created from revised AI answer\n * - 'plain-text': Document created from plain text input\n */\nexport enum DocumentType {\n File = 'file',\n Url = 'url',\n RevisedAnswer = 'revised-answer',\n PlainText = 'plain-text',\n}\n\n// ===== Schemas =====\n\n/**\n * Full document schema from database\n * Extended with computed field chunksCount\n */\nconst BaseDocumentSchema = z.object({\n id: z.string(),\n externalId: z.string().nullable(),\n name: z.string(),\n content: z.string(),\n type: z.string(),\n language: z.string(),\n metadata: z.record(z.string(), z.unknown()),\n indexStatus: z.string(),\n processedAt: z.coerce.date().nullable(),\n createdAt: z.coerce.date(),\n createdBy: z.string(),\n updatedAt: z.coerce.date(),\n updatedBy: z.string(),\n deleted: z.boolean(),\n deletedAt: z.coerce.date().nullable(),\n deletedBy: z.string().nullable(),\n organizationId: z.string(),\n})\n\nexport const DocumentSchema = BaseDocumentSchema.extend({\n type: z.enum(DocumentType),\n indexStatus: z.enum(IndexStatus),\n metadata: DocumentMetadataSchema,\n // Add computed field for chunks count (populated by service layer)\n chunksCount: z.number().optional(),\n})\n\n/**\n * Query parameters for listing documents with pagination, sorting, and filters\n */\nexport const DocumentQuerystringSchema = z.object({\n ...zodQs.pagination(),\n ...zodQs.sort(['id', 'updatedAt', 'createdAt', 'name']),\n ...zodQs.filters(['type', 'language', 'agentId', 'indexStatus']),\n ...zodQs.fullText(),\n ...zodQs.ids(),\n 'filter[similarity]': z.string().optional(),\n})\n\n/**\n * Document creation schema for POST /documents endpoint\n *\n * Supports three types:\n * - 'file': Requires media object with uploaded file info\n * - 'url': Requires url string for web scraping\n * - 'revised-answer': Requires content (created from revisedAnswer service)\n */\nexport const DocumentCreateDtoSchema = z\n .object({\n type: z.enum(DocumentType).default(DocumentType.File),\n name: z.string().min(1).max(255).optional(),\n language: z.enum(SupportedLanguage).optional(),\n organizationId: z.string(),\n agentIds: z.array(z.string()).min(1, 'At least one agent is required'),\n media: MediaSchema.optional(),\n url: z.url().optional(),\n content: z.string().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n extractionStrategy: z.enum(ExtractionStrategy).optional(),\n browserEngine: z.enum(BrowserEngine).optional(),\n headers: HeadesSchema.nullish().default([]),\n aiDescriptionModel: z.string().optional(),\n aiDescriptionPrompt: z.string().max(5000).optional(),\n })\n .superRefine((data, ctx) => {\n if (data.type === DocumentType.File && !data.media) {\n ctx.addIssue({\n code: 'custom',\n params: {\n i18n: 'errors.required',\n },\n path: ['media'],\n })\n return\n }\n if (data.type === DocumentType.Url && !data.url) {\n ctx.addIssue({\n code: 'custom',\n params: {\n i18n: 'errors.required',\n },\n path: ['url'],\n })\n }\n if (\n data.type === DocumentType.PlainText &&\n !(data.name || data.language)\n ) {\n if (!data.name) {\n ctx.addIssue({\n code: 'custom',\n params: {\n i18n: 'errors.required',\n },\n path: ['name'],\n })\n }\n if (!data.language) {\n ctx.addIssue({\n code: 'custom',\n params: {\n i18n: 'errors.required',\n },\n path: ['language'],\n })\n }\n }\n })\n\n/**\n * Document update schema for PUT /documents/:id endpoint\n *\n * All fields are optional, but at least one must be provided\n */\nexport const DocumentUpdateDtoSchema = z.object({\n id: z.string(),\n organizationId: z.string(),\n content: z.string().optional(),\n name: z.string().min(1).max(255).optional(),\n language: z.enum(SupportedLanguage).optional(),\n agentIds: z.array(z.string()).min(1).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n})\n\n// ===== Type Exports =====\n\nexport type Document = z.infer<typeof DocumentSchema>\nexport type DocumentQuerystring = z.infer<typeof DocumentQuerystringSchema>\nexport type DocumentCreateDto = z.infer<typeof DocumentCreateDtoSchema>\nexport type DocumentUpdateDto = z.infer<typeof DocumentUpdateDtoSchema>\n\n// ===== Helper Functions =====\n\nexport const getStatusColor = (status: IndexStatus) => {\n switch (status) {\n case IndexStatus.Success:\n return 'success'\n case IndexStatus.Failed:\n return 'danger'\n case IndexStatus.Processing:\n return 'warning'\n default:\n return 'info'\n }\n}\n\nexport const getStatusIcon = (status: IndexStatus) => {\n switch (status) {\n case IndexStatus.Success:\n return 'ri:check-line'\n case IndexStatus.Failed:\n return 'ri:error-warning-line'\n case IndexStatus.Processing:\n return 'ri:hourglass-line'\n default:\n return 'ri:time-line'\n }\n}\n\nexport const getTypeIcon = (type: DocumentType) => {\n switch (type) {\n case DocumentType.File:\n return 'ri:file-line'\n case DocumentType.Url:\n return 'ri:link'\n case DocumentType.RevisedAnswer:\n return 'ri:feedback-line'\n default:\n return 'ri:input-method-line'\n }\n}\n\nexport const getFileIcon = (extension: string) => {\n const ext = (\n extension.startsWith('.') ? extension.slice(1) : extension\n ).toLowerCase()\n switch (ext) {\n case 'pdf':\n return 'ri:file-pdf-2-line'\n case 'doc':\n case 'docx':\n return 'ri:file-word-line'\n case 'xls':\n case 'xlsx':\n return 'ri:file-excel-line'\n case 'ppt':\n case 'pptx':\n return 'ri:file-ppt-line'\n case 'txt':\n return 'ri:file-text-line'\n case 'mp3':\n case 'wav':\n case 'ogg':\n return 'ri:file-music-line'\n case 'mp4':\n case 'avi':\n case 'mkv':\n return 'ri:file-video-line'\n case 'jpg':\n case 'jpeg':\n case 'png':\n case 'gif':\n case 'bmp':\n case 'svg':\n return 'ri:file-image-line'\n case 'zip':\n case 'rar':\n case '7z':\n return 'ri:file-zip-line'\n default:\n return 'ri:file-line'\n }\n}\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { stripMarkdown } from 'utils'\n\n const props = defineProps<{\n content: string\n similarity?: number\n maxSimilarity?: number\n expanded: boolean\n }>()\n\n const similarityPercent = computed(() => {\n if (props.similarity == null) {\n return null\n }\n const max =\n props.maxSimilarity && props.maxSimilarity > 0\n ? props.maxSimilarity\n : 1\n return Math.round((props.similarity / max) * 100)\n })\n</script>\n\n<template>\n <VvIcon name=\"ri:text-snippet\" class=\"shrink-0 text-12 text-word-4\" />\n <span class=\"text-10 text-word-2 truncate flex-1\" :title=\"content\">\n {{ stripMarkdown(content) }}\n </span>\n <span v-if=\"similarityPercent != null\" class=\"text-10 text-word-4 shrink-0\">\n {{ similarityPercent }}%\n </span>\n <VvIcon\n :name=\"expanded ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-14 text-word-4 shrink-0\" />\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { stripMarkdown } from 'utils'\n\n const props = defineProps<{\n content: string\n similarity?: number\n maxSimilarity?: number\n expanded: boolean\n }>()\n\n const similarityPercent = computed(() => {\n if (props.similarity == null) {\n return null\n }\n const max =\n props.maxSimilarity && props.maxSimilarity > 0\n ? props.maxSimilarity\n : 1\n return Math.round((props.similarity / max) * 100)\n })\n</script>\n\n<template>\n <VvIcon name=\"ri:text-snippet\" class=\"shrink-0 text-12 text-word-4\" />\n <span class=\"text-10 text-word-2 truncate flex-1\" :title=\"content\">\n {{ stripMarkdown(content) }}\n </span>\n <span v-if=\"similarityPercent != null\" class=\"text-10 text-word-4 shrink-0\">\n {{ similarityPercent }}%\n </span>\n <VvIcon\n :name=\"expanded ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-14 text-word-4 shrink-0\" />\n</template>\n","<script setup lang=\"ts\">\n import type { DocumentType } from 'models'\n import { getTypeIcon } from 'models'\n import PkUrl from '../PkUrl.vue'\n\n defineProps<{\n type: string\n name: string\n url?: string\n filename?: string\n }>()\n</script>\n\n<template>\n <VvIcon\n :name=\"getTypeIcon(type as DocumentType)\"\n class=\"shrink-0 text-14 text-word-3\" />\n <div class=\"flex flex-col gap-2 min-w-0 flex-1\">\n <strong class=\"font-bold text-12 text-word-1 truncate block\">\n {{ name }}\n </strong>\n <span v-if=\"filename\" class=\"text-10 text-word-4 truncate\">\n {{ filename }}\n </span>\n <span\n v-if=\"url\"\n class=\"text-10 text-word-4 truncate flex items-center gap-4\">\n <VvIcon name=\"ri:link\" class=\"shrink-0 text-10\" />\n <PkUrl :url=\"url\" />\n </span>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import type { DocumentType } from 'models'\n import { getTypeIcon } from 'models'\n import PkUrl from '../PkUrl.vue'\n\n defineProps<{\n type: string\n name: string\n url?: string\n filename?: string\n }>()\n</script>\n\n<template>\n <VvIcon\n :name=\"getTypeIcon(type as DocumentType)\"\n class=\"shrink-0 text-14 text-word-3\" />\n <div class=\"flex flex-col gap-2 min-w-0 flex-1\">\n <strong class=\"font-bold text-12 text-word-1 truncate block\">\n {{ name }}\n </strong>\n <span v-if=\"filename\" class=\"text-10 text-word-4 truncate\">\n {{ filename }}\n </span>\n <span\n v-if=\"url\"\n class=\"text-10 text-word-4 truncate flex items-center gap-4\">\n <VvIcon name=\"ri:link\" class=\"shrink-0 text-10\" />\n <PkUrl :url=\"url\" />\n </span>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, reactive } from 'vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import PkChunkPreview from './PkChunkPreview.vue'\n import PkDocumentHeader from './PkDocumentHeader.vue'\n\n interface SourceItem {\n chunkId: string\n documentId: string\n documentName: string\n documentType: string\n language: string\n content: string\n chunkIndex?: number | null\n similarity?: number\n sourceUrl?: string\n sourceFilename?: string\n sourceDescription?: string\n sourceImageUrl?: string\n }\n\n const props = defineProps<{\n part: unknown\n onExpandContext?: (payload: {\n documentId: string\n chunkIndex: number\n }) => Promise<string>\n onDownload?: (documentId: string) => void\n }>()\n\n const toolPart = computed(() => {\n return props.part as {\n input?: {\n sources: SourceItem[]\n }\n }\n })\n\n const sources = computed(() => toolPart.value.input?.sources || [])\n\n const groupedSources = computed(() => {\n const groups = new Map<\n string,\n { document: SourceItem; chunks: SourceItem[] }\n >()\n for (const source of sources.value) {\n const existing = groups.get(source.documentId)\n if (existing) {\n existing.chunks.push(source)\n } else {\n groups.set(source.documentId, {\n document: source,\n chunks: [source],\n })\n }\n }\n return [...groups.values()]\n })\n\n const maxSimilarity = computed(() => {\n return Math.max(...sources.value.map((s) => s.similarity ?? 0), 0)\n })\n\n const expandedDocuments = reactive(new Set<string>())\n const expandedChunks = reactive(new Set<string>())\n const contextData = reactive(new Map<string, string>())\n const loadingContext = reactive(new Set<string>())\n\n const toggleDocument = (documentId: string) => {\n if (expandedDocuments.has(documentId)) {\n expandedDocuments.delete(documentId)\n } else {\n expandedDocuments.add(documentId)\n }\n }\n\n const toggleChunk = (chunkId: string) => {\n if (expandedChunks.has(chunkId)) {\n expandedChunks.delete(chunkId)\n } else {\n expandedChunks.add(chunkId)\n }\n }\n\n const handleExpandContext = async (source: SourceItem) => {\n if (source.chunkIndex == null || !props.onExpandContext) {\n return\n }\n loadingContext.add(source.chunkId)\n try {\n const content = await props.onExpandContext({\n documentId: source.documentId,\n chunkIndex: source.chunkIndex,\n })\n contextData.set(source.chunkId, content)\n } finally {\n loadingContext.delete(source.chunkId)\n }\n }\n\n const clearContext = (chunkId: string) => {\n contextData.delete(chunkId)\n }\n\n const showMore = ref(false)\n const visibleGroups = computed(() => {\n if (showMore.value) {\n return groupedSources.value\n }\n return groupedSources.value.slice(0, 3)\n })\n const hasMore = computed(() => groupedSources.value.length > 3)\n</script>\n\n<template>\n <div v-if=\"sources.length\" class=\"flex flex-col gap-xs w-full\">\n <div class=\"flex items-center gap-4 text-12 text-word-3 font-semibold\">\n <VvIcon name=\"ri:article-line\" class=\"text-14\" />\n {{ $t('label.sources') }}\n <span class=\"text-word-4 font-normal\">\n ({{ groupedSources.length }})\n </span>\n </div>\n\n <ul class=\"flex flex-col gap-xs\">\n <li\n v-for=\"group in visibleGroups\"\n :key=\"group.document.documentId\"\n class=\"border border-surface-3 rounded-lg overflow-hidden\">\n <!-- Document header -->\n <button\n class=\"flex items-center gap-8 p-8 w-full text-left hover:bg-surface-1 transition-colors cursor-pointer\"\n @click=\"toggleDocument(group.document.documentId)\">\n <PkDocumentHeader\n :type=\"group.document.documentType\"\n :name=\"group.document.documentName\"\n :url=\"group.document.sourceUrl\"\n :filename=\"group.document.sourceFilename\" />\n <div class=\"flex items-center gap-4 shrink-0\">\n <span\n v-if=\"group.chunks.length > 1\"\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2\">\n {{ group.chunks.length }}\n </span>\n <span\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2 uppercase\">\n {{ group.document.language }}\n </span>\n <VvIcon\n :name=\"\n expandedDocuments.has(group.document.documentId)\n ? 'ri:arrow-up-s-line'\n : 'ri:arrow-down-s-line'\n \"\n class=\"text-16 text-word-3\" />\n </div>\n </button>\n\n <!-- Expanded content -->\n <div\n v-if=\"expandedDocuments.has(group.document.documentId)\"\n class=\"border-t border-surface-3\">\n <PkStreamingMarkdown\n v-if=\"group.document.sourceDescription\"\n :markdown=\"group.document.sourceDescription\"\n class=\"px-8 py-4 text-10 text-word-3 bg-surface-1 border-b border-surface-3\" />\n\n <!-- Chunk excerpts -->\n <div\n v-for=\"chunk in group.chunks\"\n :key=\"chunk.chunkId\"\n class=\"border-b border-surface-3 last:border-b-0\">\n <button\n class=\"flex items-center gap-8 px-8 py-6 w-full text-left hover:bg-surface-1 transition-colors cursor-pointer\"\n @click=\"toggleChunk(chunk.chunkId)\">\n <PkChunkPreview\n :content=\"chunk.content\"\n :similarity=\"chunk.similarity\"\n :max-similarity=\"maxSimilarity\"\n :expanded=\"expandedChunks.has(chunk.chunkId)\" />\n </button>\n\n <!-- Expanded chunk content -->\n <div\n v-if=\"expandedChunks.has(chunk.chunkId)\"\n class=\"bg-surface-1 border-t border-surface-3\">\n <div class=\"p-8 text-10 text-word-3\">\n <transition mode=\"out-in\">\n <!-- Context expansion -->\n <PkStreamingMarkdown\n v-if=\"contextData.has(chunk.chunkId)\"\n :markdown=\"\n contextData.get(chunk.chunkId)!\n \"\n class=\"wysiwyg\" />\n\n <!-- Chunk content -->\n <PkStreamingMarkdown\n v-else\n :markdown=\"chunk.content\"\n class=\"wysiwyg\" />\n </transition>\n </div>\n\n <!-- Actions bar -->\n <div\n class=\"flex items-center gap-8 px-8 py-6 border-t border-surface-3 bg-surface\">\n <!-- Expand / collapse context -->\n <button\n v-if=\"\n onExpandContext &&\n chunk.chunkIndex != null &&\n !contextData.has(chunk.chunkId)\n \"\n class=\"text-10 text-word-3 hover:text-word flex items-center gap-4 cursor-pointer\"\n :disabled=\"\n loadingContext.has(chunk.chunkId)\n \"\n @click=\"handleExpandContext(chunk)\">\n <VvIcon\n :name=\"\n loadingContext.has(chunk.chunkId)\n ? 'line-md:loading-loop'\n : 'ri:expand-up-down-line'\n \"\n class=\"text-12\" />\n {{ $t('label.expandContext') }}\n </button>\n <button\n v-else-if=\"contextData.has(chunk.chunkId)\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n @click=\"clearContext(chunk.chunkId)\">\n <VvIcon\n name=\"ri:collapse-vertical-line\"\n class=\"text-12\" />\n {{ $t('label.collapseContext') }}\n </button>\n\n <!-- Open source URL -->\n <a\n v-if=\"chunk.sourceUrl\"\n :href=\"chunk.sourceUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 ml-auto\">\n <VvIcon\n name=\"ri:external-link-line\"\n class=\"text-12\" />\n {{ $t('label.openSource') }}\n </a>\n\n <!-- Download file -->\n <button\n v-if=\"\n onDownload &&\n chunk.documentType === 'file'\n \"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n :class=\"{\n 'ml-auto': !chunk.sourceUrl,\n }\"\n @click=\"onDownload(chunk.documentId)\">\n <VvIcon\n name=\"ri:download-line\"\n class=\"text-12\" />\n {{ $t('label.downloadFile') }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </li>\n </ul>\n\n <!-- Show more -->\n <button\n v-if=\"hasMore\"\n class=\"text-12 text-word-3 cursor-pointer hover:underline flex items-center gap-4 mx-auto\"\n @click=\"showMore = !showMore\">\n <VvIcon\n :name=\"showMore ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-16\" />\n {{\n showMore\n ? $t('action.showLess')\n : $t('action.showMore', {\n count: groupedSources.length - 3,\n })\n }}\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, reactive } from 'vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import PkChunkPreview from './PkChunkPreview.vue'\n import PkDocumentHeader from './PkDocumentHeader.vue'\n\n interface SourceItem {\n chunkId: string\n documentId: string\n documentName: string\n documentType: string\n language: string\n content: string\n chunkIndex?: number | null\n similarity?: number\n sourceUrl?: string\n sourceFilename?: string\n sourceDescription?: string\n sourceImageUrl?: string\n }\n\n const props = defineProps<{\n part: unknown\n onExpandContext?: (payload: {\n documentId: string\n chunkIndex: number\n }) => Promise<string>\n onDownload?: (documentId: string) => void\n }>()\n\n const toolPart = computed(() => {\n return props.part as {\n input?: {\n sources: SourceItem[]\n }\n }\n })\n\n const sources = computed(() => toolPart.value.input?.sources || [])\n\n const groupedSources = computed(() => {\n const groups = new Map<\n string,\n { document: SourceItem; chunks: SourceItem[] }\n >()\n for (const source of sources.value) {\n const existing = groups.get(source.documentId)\n if (existing) {\n existing.chunks.push(source)\n } else {\n groups.set(source.documentId, {\n document: source,\n chunks: [source],\n })\n }\n }\n return [...groups.values()]\n })\n\n const maxSimilarity = computed(() => {\n return Math.max(...sources.value.map((s) => s.similarity ?? 0), 0)\n })\n\n const expandedDocuments = reactive(new Set<string>())\n const expandedChunks = reactive(new Set<string>())\n const contextData = reactive(new Map<string, string>())\n const loadingContext = reactive(new Set<string>())\n\n const toggleDocument = (documentId: string) => {\n if (expandedDocuments.has(documentId)) {\n expandedDocuments.delete(documentId)\n } else {\n expandedDocuments.add(documentId)\n }\n }\n\n const toggleChunk = (chunkId: string) => {\n if (expandedChunks.has(chunkId)) {\n expandedChunks.delete(chunkId)\n } else {\n expandedChunks.add(chunkId)\n }\n }\n\n const handleExpandContext = async (source: SourceItem) => {\n if (source.chunkIndex == null || !props.onExpandContext) {\n return\n }\n loadingContext.add(source.chunkId)\n try {\n const content = await props.onExpandContext({\n documentId: source.documentId,\n chunkIndex: source.chunkIndex,\n })\n contextData.set(source.chunkId, content)\n } finally {\n loadingContext.delete(source.chunkId)\n }\n }\n\n const clearContext = (chunkId: string) => {\n contextData.delete(chunkId)\n }\n\n const showMore = ref(false)\n const visibleGroups = computed(() => {\n if (showMore.value) {\n return groupedSources.value\n }\n return groupedSources.value.slice(0, 3)\n })\n const hasMore = computed(() => groupedSources.value.length > 3)\n</script>\n\n<template>\n <div v-if=\"sources.length\" class=\"flex flex-col gap-xs w-full\">\n <div class=\"flex items-center gap-4 text-12 text-word-3 font-semibold\">\n <VvIcon name=\"ri:article-line\" class=\"text-14\" />\n {{ $t('label.sources') }}\n <span class=\"text-word-4 font-normal\">\n ({{ groupedSources.length }})\n </span>\n </div>\n\n <ul class=\"flex flex-col gap-xs\">\n <li\n v-for=\"group in visibleGroups\"\n :key=\"group.document.documentId\"\n class=\"border border-surface-3 rounded-lg overflow-hidden\">\n <!-- Document header -->\n <button\n class=\"flex items-center gap-8 p-8 w-full text-left hover:bg-surface-1 transition-colors cursor-pointer\"\n @click=\"toggleDocument(group.document.documentId)\">\n <PkDocumentHeader\n :type=\"group.document.documentType\"\n :name=\"group.document.documentName\"\n :url=\"group.document.sourceUrl\"\n :filename=\"group.document.sourceFilename\" />\n <div class=\"flex items-center gap-4 shrink-0\">\n <span\n v-if=\"group.chunks.length > 1\"\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2\">\n {{ group.chunks.length }}\n </span>\n <span\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2 uppercase\">\n {{ group.document.language }}\n </span>\n <VvIcon\n :name=\"\n expandedDocuments.has(group.document.documentId)\n ? 'ri:arrow-up-s-line'\n : 'ri:arrow-down-s-line'\n \"\n class=\"text-16 text-word-3\" />\n </div>\n </button>\n\n <!-- Expanded content -->\n <div\n v-if=\"expandedDocuments.has(group.document.documentId)\"\n class=\"border-t border-surface-3\">\n <PkStreamingMarkdown\n v-if=\"group.document.sourceDescription\"\n :markdown=\"group.document.sourceDescription\"\n class=\"px-8 py-4 text-10 text-word-3 bg-surface-1 border-b border-surface-3\" />\n\n <!-- Chunk excerpts -->\n <div\n v-for=\"chunk in group.chunks\"\n :key=\"chunk.chunkId\"\n class=\"border-b border-surface-3 last:border-b-0\">\n <button\n class=\"flex items-center gap-8 px-8 py-6 w-full text-left hover:bg-surface-1 transition-colors cursor-pointer\"\n @click=\"toggleChunk(chunk.chunkId)\">\n <PkChunkPreview\n :content=\"chunk.content\"\n :similarity=\"chunk.similarity\"\n :max-similarity=\"maxSimilarity\"\n :expanded=\"expandedChunks.has(chunk.chunkId)\" />\n </button>\n\n <!-- Expanded chunk content -->\n <div\n v-if=\"expandedChunks.has(chunk.chunkId)\"\n class=\"bg-surface-1 border-t border-surface-3\">\n <div class=\"p-8 text-10 text-word-3\">\n <transition mode=\"out-in\">\n <!-- Context expansion -->\n <PkStreamingMarkdown\n v-if=\"contextData.has(chunk.chunkId)\"\n :markdown=\"\n contextData.get(chunk.chunkId)!\n \"\n class=\"wysiwyg\" />\n\n <!-- Chunk content -->\n <PkStreamingMarkdown\n v-else\n :markdown=\"chunk.content\"\n class=\"wysiwyg\" />\n </transition>\n </div>\n\n <!-- Actions bar -->\n <div\n class=\"flex items-center gap-8 px-8 py-6 border-t border-surface-3 bg-surface\">\n <!-- Expand / collapse context -->\n <button\n v-if=\"\n onExpandContext &&\n chunk.chunkIndex != null &&\n !contextData.has(chunk.chunkId)\n \"\n class=\"text-10 text-word-3 hover:text-word flex items-center gap-4 cursor-pointer\"\n :disabled=\"\n loadingContext.has(chunk.chunkId)\n \"\n @click=\"handleExpandContext(chunk)\">\n <VvIcon\n :name=\"\n loadingContext.has(chunk.chunkId)\n ? 'line-md:loading-loop'\n : 'ri:expand-up-down-line'\n \"\n class=\"text-12\" />\n {{ $t('label.expandContext') }}\n </button>\n <button\n v-else-if=\"contextData.has(chunk.chunkId)\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n @click=\"clearContext(chunk.chunkId)\">\n <VvIcon\n name=\"ri:collapse-vertical-line\"\n class=\"text-12\" />\n {{ $t('label.collapseContext') }}\n </button>\n\n <!-- Open source URL -->\n <a\n v-if=\"chunk.sourceUrl\"\n :href=\"chunk.sourceUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 ml-auto\">\n <VvIcon\n name=\"ri:external-link-line\"\n class=\"text-12\" />\n {{ $t('label.openSource') }}\n </a>\n\n <!-- Download file -->\n <button\n v-if=\"\n onDownload &&\n chunk.documentType === 'file'\n \"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n :class=\"{\n 'ml-auto': !chunk.sourceUrl,\n }\"\n @click=\"onDownload(chunk.documentId)\">\n <VvIcon\n name=\"ri:download-line\"\n class=\"text-12\" />\n {{ $t('label.downloadFile') }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </li>\n </ul>\n\n <!-- Show more -->\n <button\n v-if=\"hasMore\"\n class=\"text-12 text-word-3 cursor-pointer hover:underline flex items-center gap-4 mx-auto\"\n @click=\"showMore = !showMore\">\n <VvIcon\n :name=\"showMore ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-16\" />\n {{\n showMore\n ? $t('action.showLess')\n : $t('action.showMore', {\n count: groupedSources.length - 3,\n })\n }}\n </button>\n </div>\n</template>\n"],"x_google_ignoreList":[0],"mappings":";;;;;;;;AAcA,SAAgB,EAAK,GAAQ;AACzB,QAAOA,EAAkBC,GAAiB,EAAO;;;;ACJrD,IAAa,KAAwC,MAC1C,CAAC,GAAG,KAAS,IAAI,IAAQ,EAGvB,KAAyC,MAC3C,EAAM,SAAS,MAAM,EAAa,EAAE,CAAC,EAGnC,IAAQ;CACjB,aAAa,IAAgB,GAAG,IAAc,QACnC;EACH,gBAAgB,GACH,CACR,GAAG,GAAU,CAAC,CACd,WAAW,MAAM,OAAO,EAAE,CAAC,CAC3B,QAAQ,EAAc;EAC3B,cAAc,GACD,CACR,GAAG,GAAU,CAAC,CACd,WAAW,MAAM,OAAO,EAAE,CAAC,CAC3B,QAAQ,EAAY;EAC5B;CAEL,SAAiC,OACtB,GAAG,UAAU,EAAM,KAAK,GAAU,CAAC,UAAU,EAAE;CAK1D,UAAkC,OACvB,GAAG,WAAW,EAAM,KAAK,GAAU,CAAC,UAAU,EAAE;CAK3D,QAAgC,OACrB;GACF,QAAQ,EAAM,KAAK,GAAU,CAAC,UAAU;GACxC,MAAM,EAAM,KAAK,GAAU,CAAC,UAAU;EAC1C;CAEL,MAA8B,OACnB,GAAG,OAAO,EAAM,KAAK,GAAW,CAAC,UAAU,EAAE;CAKxD,iBACW,EAAG,oBAAqB,GAAU,CAAC,UAAU,EAAE;CAE1D,YACW,EAAE,KAAK,EAAQ,CAAC,GAAU,EAAE,EAAQ,GAAU,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE;CAEzE,gBACW,EAAE,qBAAqB,GAAW,CAAC,QAAQ,GAAM,EAAE;CAE9D,UAAkC,MACvB,EACF,KAAK,MAAM,EAAM,OAAO,EAAE,CAAC,CAC3B,QAAQ,GAAG,OAAO;EAAE,GAAG;EAAG,GAAG;EAAG,EAAE;CAE3C,OAA+B,MAAc;EACzC,IAAM,IAAY,EAAc,EAAK;AACrC,SAAO,EAEH,MAAM,EAAO,EAAU,CAAC,UAAU,CAAC,QAAQ,EAAU,GAAG,EAC3D;;CAER,EC/EW,IAAL,yBAAA,GAAA;QAEH,EAAA,sBAAsB,iCACtB,EAAA,WAAW,qBACX,EAAA,WAAW,qBACX,EAAA,gBAAgB,2BAChB,EAAA,eAAe,0BACf,EAAA,QAAQ,kBACR,EAAA,YAAY,uBACZ,EAAA,YAAY,uBACZ,EAAA,YAAY,uBACZ,EAAA,QAAQ,kBACR,EAAA,WAAW,sBACX,EAAA,QAAQ,kBACR,EAAA,WAAW,sBAEX,EAAA,gBAAgB,2BAChB,EAAA,oBAAoB,gCACpB,EAAA,cAAc,yBACd,EAAA,eAAe,yBACf,EAAA,oBAAoB,+BACpB,EAAA,2BAA2B,wCAC3B,EAAA,qBAAqB,iCAErB,EAAA,gBAAgB,8BAChB,EAAA,iBAAiB,+BACjB,EAAA,iBAAiB,+BACjB,EAAA,eAAe,6BAEf,EAAA,aAAa,0BACb,EAAA,qBAAqB,mCACrB,EAAA,eAAe,4BACf,EAAA,iBAAiB,8BAEjB,EAAA,oBAAoB;KACvB;AAE0B,EAAc;AAYzC,IAAY,IAAL,yBAAA,GAAA;QACH,EAAA,KAAK,MACL,EAAA,KAAK,MACL,EAAA,KAAK,MACL,EAAA,KAAK,MACL,EAAA,KAAK;KACR;AAMI,EAAkB,IAClB,EAAkB,IAClB,EAAkB,IAClB,EAAkB,IAClB,EAAkB;AAMvB,IAAY,IAAL,yBAAA,GAAA;QAEH,EAAA,cAAc,eAEd,EAAA,KAAK;KACR,EAKW,IAAL,yBAAA,GAAA;QAEH,EAAA,QAAQ,SAER,EAAA,YAAY;KACf,EChFY,IAAkB,4BAkCnB,KAAL,yBAAA,GAAA;QACH,EAAA,UAAU,WACV,EAAA,OAAO,QACP,EAAA,MAAM,OACN,EAAA,UAAU;KACb,EAwBK,KAAsB,EAAqB,QAAQ,CAdpB,EAAS;CAC1C,MAAM,EAAU,aAAa;CAC7B,SAAS,GAAO;CAChB,eAAe,GAAU,CAAC,IAAI,EAAE;CAChC,yBAAyB,GAAU,CAAC,IAAI,EAAE;CAC7C,CAUG,EAR0B,EAAS;CACnC,MAAM,EAAU,KAAK;CACrB,QAAQ,GAAU,CAAC,IAAI,EAAE;CACzB,KAAK,GAAU,CAAC,IAAI,EAAE;CACtB,QAAQ,GAAU,CAAC,IAAI,EAAE;CAC5B,CAIG,CACH,CAAC,EAmCW,IA5BoB,EAAS;CAEtC,MAAM,GAAU,CAAC,IAAI,EAAE;CAEvB,MAAM,GAAU,CAAC,IAAI,EAAE;CAEvB,UAAU,GAAU,CAAC,MAAM,EAAgB;CAE3C,YAAY,GAAU,CAAC,UAAU;CAEjC,WAAW,GACE,CACR,MAAM,mBAAmB,CACzB,WAAW,MAAQ,EAAI,aAAa,CAAC;CAE1C,gBAAgB,GAAU,CAAC,UAAU;CAErC,UAAU,EAAS,GAAU,EAAE,GAAU,CAAC,CAAC,QAAQ,EAAE,CAAC;CAEtD,MAAM,EAAS,GAAU,EAAE,GAAU,CAAC,CAAC,QAAQ,EAAE,CAAC;CACrD,CAQgC,CAAkB,OAAO;CAEtD,eAAe;CAEf,eAAe,EAAO,GAAc;CAEpC,UAAU,GAAU,CAAC,UAAU;CAE/B,gBAAgB,GAAU,CAAC,IAAI,EAAE;CACpC,CAAC,EAQW,IAAc,EAAS;CAEhC,MAAM,GAAU,CAAC,IAAI,EAAE;CAEvB,KAAK;CAEL,QAAQ,EAAQ,EAAkB,CAAC,QAAQ,EAAE,CAAC;CAE9C,YAAY,GAAsB,CAAC,UAAU;CAChD,CAAC;AAQqC,EAAS;CAE5C,KAAK;CAEL,cAAc,EAAS;EAEnB,cAAc,GAAU,CAAC,KAAK;EAE9B,UAAU,EAAS,GAAU,EAAE,GAAU,CAAC,CAAC,QAAQ,EAAE,CAAC;EAEtD,MAAM,EAAS,GAAU,EAAE,GAAU,CAAC,CAAC,QAAQ,EAAE,CAAC;EACrD,CAAC;CACL,CAAC,EAQuC,EAAS;CAE9C,KAAK;CAEL,gBAAgB,EAAS;EAErB,gBAAgB,GAAU,CAAC,KAAK;EAEhC,YAAY,GAAU,CAAC,KAAK;EAE5B,eAAe,GAAU,CAAC,KAAK,CAAC,UAAU;EAE1C,WAAW,GAAU,CAAC,UAAU;EAEhC,MAAM,GAAU;EACnB,CAAC;CACL,CAAC;AAKF,IAAY,IAAL,yBAAA,GAAA;QACH,EAAA,UAAU,WACV,EAAA,QAAQ,SACR,EAAA,QAAQ,SACR,EAAA,SAAS,UACT,EAAA,UAAU,WACV,EAAA,SAAS,UACT,EAAA,aAAa;KAChB;AAuC+B,EAAqB,QAAQ;CAnC7B,EAAS;EACrC,MAAM,EAAU,EAAU,QAAQ;EAClC,OAAO,GAAU,CAAC,UAAU;EAC5B,QAAQ,GAAU,CAAC,UAAU;EAC7B,UAAU,GAAU,CAAC,UAAU;EAClC,CA+BG;CA7B0B,EAAS;EACnC,MAAM,EAAU,EAAU,MAAM;EAChC,OAAO,GAAU,CAAC,UAAU;EAC5B,QAAQ,GAAU,CAAC,UAAU;EAC7B,UAAU,GAAU,CAAC,aAAa;EACrC,CAyBG;CAvB0B,EAAS;EACnC,MAAM,EAAU,EAAU,MAAM;EAChC,UAAU,GAAU,CAAC,aAAa;EACrC,CAqBG;CAnB2B,EAAS,EACpC,MAAM,EAAU,EAAU,OAAO,EACpC,CAkBG;CAhB4B,EAAS,EACrC,MAAM,EAAU,EAAU,QAAQ,EACrC,CAeG;CAb2B,EAAS,EACpC,MAAM,EAAU,EAAU,OAAO,EACpC,CAYG;CAV+B,EAAS,EACxC,MAAM,EAAU,EAAU,WAAW,EACxC,CASG;CACH,CAAC;ACtOF,IAAa,IAAe,EALA,EAAS;CACjC,KAAK,GAAU,CAAC,UAAU;CAC1B,OAAO,GAAU,CAAC,UAAU;CAC/B,CAEmC,CAAa,CAAC,WAAW,MAClD,GAAS,QACX,MAAW,EAAO,KAAK,MAAM,IAAI,EAAO,OAAO,MAAM,CACzD,CACH,ECEU,IAAL,yBAAA,GAAA;QACH,EAAA,UAAU,WACV,EAAA,aAAa,cACb,EAAA,UAAU,WACV,EAAA,SAAS;KACZ,EAQY,IAA0B,EAAS;CAC5C,oBAAoB,EAAO,EAAmB,CAAC,UAAU;CACzD,eAAe,EAAO,EAAc,CAAC,UAAU;CAC/C,SAAS,EAAa,SAAS;CAC/B,oBAAoB,GAAU,CAAC,UAAU;CACzC,qBAAqB,GAAU,CAAC,IAAI,IAAK,CAAC,UAAU;CACpD,UAAU,GAAU,CAAC,UAAU;CAClC,CAAC,EAQW,KAAyB,EAC1B;CAEJ,QAAQ,EACI;EACJ,KAAK,GAAU;EACf,eAAe,GAAU;EAC5B,CAAC,CACD,UAAU;CAGf,OAAO,EAAY,UAAU;CAG7B,OAAO,GAAU,CAAC,UAAU;CAC5B,QAAQ,GAAU,CAAC,UAAU;CAC7B,aAAa,GAAU,CAAC,UAAU;CAClC,SAAS,GAAU,CAAC,UAAU;CAC9B,UAAU,EAAQ,GAAU,CAAC,CAAC,UAAU;CAGxC,SAAS,GAAU,CAAC,UAAU;CAC9B,SAAS,GAAU,CAAC,UAAU;CAC9B,UAAU,GAAU,CAAC,UAAU;CAC/B,cAAc,GAAU,CAAC,UAAU;CACnC,kBAAkB,GAAU,CAAC,UAAU;CACvC,WAAW,EACA,CAAC,GAAU,EAAE,EAAQ,GAAW,CAAC,CAAC,CAAC,CACzC,WAAW,MAAS,MAAM,QAAQ,EAAI,GAAG,EAAI,SAAS,EAAK,CAC3D,UAAU;CACf,WAAW,GAAW,CAAC,UAAU;CAGjC,gBAAgB,GAAU,CAAC,UAAU;CACrC,WAAW,GAAU,CAAC,UAAU;CAGhC,UAAU,GAAU,CAAC,UAAU;CAC/B,cAAc,GAAO,CAAC,UAAU;CAChC,UAAU,GAAO,CAAC,UAAU;CAC5B,SAAS,GAAO,CAAC,UAAU;CAC3B,MAAM,GAAU,CAAC,UAAU;CAC3B,QAAQ,GAAU,CAAC,UAAU;CAC7B,MAAM,EAAQ,GAAU,CAAC,CAAC,UAAU;CACpC,eAAe,GAAU,CAAC,UAAU;CACpC,cAAc,GAAU,CAAC,UAAU;CAGnC,WAAW,GAAU,CAAC,UAAU;CAChC,gBAAgB,GAAU,CAAC,UAAU;CACrC,aAAa,GAAU,CAAC,UAAU;CAGlC,mBAAmB,EAAwB,UAAU;CACxD,CAAC,CACD,OAAO,EAYA,IAAL,yBAAA,GAAA;QACH,EAAA,OAAO,QACP,EAAA,MAAM,OACN,EAAA,gBAAgB,kBAChB,EAAA,YAAY;KACf;AAQ0B,EAAS;CAChC,IAAI,GAAU;CACd,YAAY,GAAU,CAAC,UAAU;CACjC,MAAM,GAAU;CAChB,SAAS,GAAU;CACnB,MAAM,GAAU;CAChB,UAAU,GAAU;CACpB,UAAU,EAAS,GAAU,EAAE,GAAW,CAAC;CAC3C,aAAa,GAAU;CACvB,aAAa,GAAe,CAAC,UAAU;CACvC,WAAW,GAAe;CAC1B,WAAW,GAAU;CACrB,WAAW,GAAe;CAC1B,WAAW,GAAU;CACrB,SAAS,GAAW;CACpB,WAAW,GAAe,CAAC,UAAU;CACrC,WAAW,GAAU,CAAC,UAAU;CAChC,gBAAgB,GAAU;CAC7B,CAE6B,CAAmB,OAAO;CACpD,MAAM,EAAO,EAAa;CAC1B,aAAa,EAAO,EAAY;CAChC,UAAU;CAEV,aAAa,GAAU,CAAC,UAAU;CACrC,CAAC,EAKuC,EAAS;CAC9C,GAAG,EAAM,YAAY;CACrB,GAAG,EAAM,KAAK;EAAC;EAAM;EAAa;EAAa;EAAO,CAAC;CACvD,GAAG,EAAM,QAAQ;EAAC;EAAQ;EAAY;EAAW;EAAc,CAAC;CAChE,GAAG,EAAM,UAAU;CACnB,GAAG,EAAM,KAAK;CACd,sBAAsB,GAAU,CAAC,UAAU;CAC9C,CAAC,EAUqC,EAC3B;CACJ,MAAM,EAAO,EAAa,CAAC,QAAQ,EAAa,KAAK;CACrD,MAAM,GAAU,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI,CAAC,UAAU;CAC3C,UAAU,EAAO,EAAkB,CAAC,UAAU;CAC9C,gBAAgB,GAAU;CAC1B,UAAU,EAAQ,GAAU,CAAC,CAAC,IAAI,GAAG,iCAAiC;CACtE,OAAO,EAAY,UAAU;CAC7B,KAAK,GAAO,CAAC,UAAU;CACvB,SAAS,GAAU,CAAC,UAAU;CAC9B,UAAU,EAAS,GAAU,EAAE,GAAW,CAAC,CAAC,UAAU;CACtD,oBAAoB,EAAO,EAAmB,CAAC,UAAU;CACzD,eAAe,EAAO,EAAc,CAAC,UAAU;CAC/C,SAAS,EAAa,SAAS,CAAC,QAAQ,EAAE,CAAC;CAC3C,oBAAoB,GAAU,CAAC,UAAU;CACzC,qBAAqB,GAAU,CAAC,IAAI,IAAK,CAAC,UAAU;CACvD,CAAC,CACD,aAAa,GAAM,MAAQ;AACxB,KAAI,EAAK,SAAS,EAAa,QAAQ,CAAC,EAAK,OAAO;AAChD,IAAI,SAAS;GACT,MAAM;GACN,QAAQ,EACJ,MAAM,mBACT;GACD,MAAM,CAAC,QAAQ;GAClB,CAAC;AACF;;AAWJ,CATI,EAAK,SAAS,EAAa,OAAO,CAAC,EAAK,OACxC,EAAI,SAAS;EACT,MAAM;EACN,QAAQ,EACJ,MAAM,mBACT;EACD,MAAM,CAAC,MAAM;EAChB,CAAC,EAGF,EAAK,SAAS,EAAa,aAC3B,EAAE,EAAK,QAAQ,EAAK,cAEf,EAAK,QACN,EAAI,SAAS;EACT,MAAM;EACN,QAAQ,EACJ,MAAM,mBACT;EACD,MAAM,CAAC,OAAO;EACjB,CAAC,EAED,EAAK,YACN,EAAI,SAAS;EACT,MAAM;EACN,QAAQ,EACJ,MAAM,mBACT;EACD,MAAM,CAAC,WAAW;EACrB,CAAC;EAGZ,EAOiC,EAAS;CAC5C,IAAI,GAAU;CACd,gBAAgB,GAAU;CAC1B,SAAS,GAAU,CAAC,UAAU;CAC9B,MAAM,GAAU,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI,CAAC,UAAU;CAC3C,UAAU,EAAO,EAAkB,CAAC,UAAU;CAC9C,UAAU,EAAQ,GAAU,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU;CAC/C,UAAU,EAAS,GAAU,EAAE,GAAW,CAAC,CAAC,UAAU;CACzD,CAAC;AAqCF,IAAa,MAAe,MAAuB;AAC/C,SAAQ,GAAR;EACI,KAAK,EAAa,KACd,QAAO;EACX,KAAK,EAAa,IACd,QAAO;EACX,KAAK,EAAa,cACd,QAAO;EACX,QACI,QAAO;;;;;;;;;;;;;;EC9Rf,IAAM,IAAQ,GAOR,IAAoB,QAAe;AACrC,OAAI,EAAM,cAAc,KACpB,QAAO;GAEX,IAAM,IACF,EAAM,iBAAiB,EAAM,gBAAgB,IACvC,EAAM,gBACN;AACV,UAAO,KAAK,MAAO,EAAM,aAAa,IAAO,IAAG;IACnD;;;;IAID,EAAsE,GAAA;KAA9D,MAAK;KAAkB,OAAM;;IACrC,EAEO,QAAA;KAFD,OAAM;KAAuC,OAAO,EAAA;SACnD,EAAA,EAAa,CAAC,EAAA,QAAO,CAAA,EAAA,GAAA,GAAA;IAEhB,EAAA,SAAiB,OAE7B,EAAA,IAAA,GAAA,IAF6B,GAAA,EAA7B,EAEO,QAFP,IAEO,EADA,EAAA,MAAiB,GAAG,MAC3B,EAAA;IACA,EAE2C,GAAA;KADtC,MAAM,EAAA,WAAQ,uBAAA;KACf,OAAM;;;;;;;;;;;;;;;;;;;;;;2BEnBV,EAE2C,GAAA;IADtC,MAAM,EAAA,GAAW,CAAC,EAAA,KAAI;IACvB,OAAM;0BACV,EAaM,OAbN,IAaM;IAZF,EAES,UAFT,IAES,EADF,EAAA,KAAI,EAAA,EAAA;IAEC,EAAA,YAAA,GAAA,EAAZ,EAEO,QAFP,IAEO,EADA,EAAA,SAAQ,EAAA,EAAA,IAAA,EAAA,IAAA,GAAA;IAGL,EAAA,OAAA,GAAA,EADV,EAKO,QALP,IAKO,CAFH,EAAkD,GAAA;KAA1C,MAAK;KAAU,OAAM;QAC7B,EAAoB,IAAA,EAAZ,KAAK,EAAA,KAAG,EAAA,MAAA,GAAA,CAAA,MAAA,CAAA,CAAA,CAAA,IAAA,EAAA,IAAA,GAAA;;;;;;;;;;;;;;;;;;;;;;;;EEPxB,IAAM,IAAQ,GASR,IAAW,QACN,EAAM,KAKhB,EAEK,IAAU,QAAe,EAAS,MAAM,OAAO,WAAW,EAAE,CAAA,EAE5D,IAAiB,QAAe;GAClC,IAAM,oBAAS,IAAI,KAGjB;AACF,QAAK,IAAM,KAAU,EAAQ,OAAO;IAChC,IAAM,IAAW,EAAO,IAAI,EAAO,WAAU;AAC7C,IAAI,IACA,EAAS,OAAO,KAAK,EAAM,GAE3B,EAAO,IAAI,EAAO,YAAY;KAC1B,UAAU;KACV,QAAQ,CAAC,EAAA;KACZ,CAAA;;AAGT,UAAO,CAAC,GAAG,EAAO,QAAQ,CAAA;IAC7B,EAEK,IAAgB,QACX,KAAK,IAAI,GAAG,EAAQ,MAAM,KAAK,MAAM,EAAE,cAAc,EAAE,EAAE,EAAC,CACpE,EAEK,IAAoB,kBAAS,IAAI,KAAa,CAAA,EAC9C,IAAiB,kBAAS,IAAI,KAAa,CAAA,EAC3C,IAAc,kBAAS,IAAI,KAAqB,CAAA,EAChD,IAAiB,kBAAS,IAAI,KAAa,CAAA,EAE3C,KAAkB,MAAuB;AAC3C,GAAI,EAAkB,IAAI,EAAW,GACjC,EAAkB,OAAO,EAAU,GAEnC,EAAkB,IAAI,EAAU;KAIlC,KAAe,MAAoB;AACrC,GAAI,EAAe,IAAI,EAAQ,GAC3B,EAAe,OAAO,EAAO,GAE7B,EAAe,IAAI,EAAO;KAI5B,IAAsB,OAAO,MAAuB;AAClD,WAAO,cAAc,QAAQ,CAAC,EAAM,kBAGxC;MAAe,IAAI,EAAO,QAAO;AACjC,QAAI;KACA,IAAM,IAAU,MAAM,EAAM,gBAAgB;MACxC,YAAY,EAAO;MACnB,YAAY,EAAO;MACtB,CAAA;AACD,OAAY,IAAI,EAAO,SAAS,EAAO;cACjC;AACN,OAAe,OAAO,EAAO,QAAO;;;KAItC,KAAgB,MAAoB;AACtC,KAAY,OAAO,EAAO;KAGxB,IAAW,EAAI,GAAK,EACpB,IAAgB,QACd,EAAS,QACF,EAAe,QAEnB,EAAe,MAAM,MAAM,GAAG,EAAC,CACzC,EACK,IAAU,QAAe,EAAe,MAAM,SAAS,EAAC;;;UAInD,EAAA,MAAQ,UAAA,GAAA,EAAnB,EA+KM,OA/KN,IA+KM;IA9KF,EAMM,OANN,IAMM;KALF,EAAiD,GAAA;MAAzC,MAAK;MAAkB,OAAM;;OAAY,MACjD,EAAGC,EAAAA,GAAE,gBAAA,CAAA,GAAoB,KACzB,EAAA;KAAA,EAEO,QAFP,IAAsC,OACjC,EAAG,EAAA,MAAe,OAAM,GAAG,MAChC,EAAA;;IAGJ,EAoJK,MApJL,IAoJK,EAAA,EAAA,GAAA,EAnJD,EAkJK,GAAA,MAAA,EAjJe,EAAA,QAAT,YADX,EAkJK,MAAA;KAhJA,KAAK,EAAM,SAAS;KACrB,OAAM;QAEN,EA0BS,UAAA;KAzBL,OAAM;KACL,UAAK,MAAE,EAAe,EAAM,SAAS,WAAA;QACtC,EAIgD,IAAA;KAH3C,MAAM,EAAM,SAAS;KACrB,MAAM,EAAM,SAAS;KACrB,KAAK,EAAM,SAAS;KACpB,UAAU,EAAM,SAAS;;;;;;QAC9B,EAiBM,OAjBN,IAiBM;KAfQ,EAAM,OAAO,SAAM,KAAA,GAAA,EAD7B,EAIO,QAJP,IAIO,EADA,EAAM,OAAO,OAAM,EAAA,EAAA,IAAA,EAAA,IAAA,GAAA;KAE1B,EAGO,QAHP,IAGO,EADA,EAAM,SAAS,SAAQ,EAAA,EAAA;KAE9B,EAMkC,GAAA;MAL7B,MAAuC,EAAkB,IAAI,EAAM,SAAS,WAAU,GAAA,uBAAA;MAKvF,OAAM;;iBAMR,EAAkB,IAAI,EAAM,SAAS,WAAU,IAAA,GAAA,EADzD,EA+GM,OA/GN,GA+GM,CA3GQ,EAAM,SAAS,qBAAA,GAAA,EADzB,EAGmF,GAAA;;KAD9E,UAAU,EAAM,SAAS;KAC1B,OAAM;oDAGV,EAqGM,GAAA,MAAA,EApGc,EAAM,SAAf,YADX,EAqGM,OAAA;KAnGD,KAAK,EAAM;KACZ,OAAM;QACN,EAQS,UAAA;KAPL,OAAM;KACL,UAAK,MAAE,EAAY,EAAM,QAAA;QAC1B,EAIoD,IAAA;KAH/C,SAAS,EAAM;KACf,YAAY,EAAM;KAClB,kBAAgB,EAAA;KAChB,UAAU,EAAe,IAAI,EAAM,QAAA;;;;;;iBAKlC,EAAe,IAAI,EAAM,QAAO,IAAA,GAAA,EAD1C,EAqFM,OArFN,IAqFM,CAlFF,EAgBM,OAhBN,IAgBM,CAfF,EAca,IAAA,EAdD,MAAK,UAAQ,EAAA;sBAOC,CAJZ,EAAY,IAAI,EAAM,QAAO,IAAA,GAAA,EADvC,EAKsB,GAAA;;MAHjB,UAAuD,EAAY,IAAI,EAAM,QAAO;MAGrF,OAAM;wCAGV,EAGsB,GAAA;;MADjB,UAAU,EAAM;MACjB,OAAM;;;gBAKlB,EA8DM,OA9DN,IA8DM;KA1DiD,EAAA,mBAA2D,EAAM,cAAU,QAAA,CAAqD,EAAY,IAAI,EAAM,QAAO,IAAA,GAAA,EADhN,EAmBS,UAAA;;MAbL,OAAM;MACL,UAAmD,EAAe,IAAI,EAAM,QAAO;MAGnF,UAAK,MAAE,EAAoB,EAAA;SAC5B,EAMsB,GAAA;MALjB,MAAmD,EAAe,IAAI,EAAM,QAAO,GAAA,yBAAA;MAKpF,OAAM;8BAAY,MACtB,EAAGA,EAAAA,GAAE,sBAAA,CAAA,EAAA,EAAA,CAAA,EAAA,GAAA,GAAA,IAGM,EAAY,IAAI,EAAM,QAAO,IAAA,GAAA,EAD5C,EAQS,UAAA;;MANL,OAAM;MACL,UAAK,MAAE,EAAa,EAAM,QAAA;SAC3B,EAEsB,GAAA;MADlB,MAAK;MACL,OAAM;WAAY,MACtB,EAAGA,EAAAA,GAAE,wBAAA,CAAA,EAAA,EAAA,CAAA,EAAA,GAAA,GAAA,IAAA,EAAA,IAAA,GAAA;KAKC,EAAM,aAAA,GAAA,EADhB,EAUI,KAAA;;MARC,MAAM,EAAM;MACb,QAAO;MACP,KAAI;MACJ,OAAM;SACN,EAEsB,GAAA;MADlB,MAAK;MACL,OAAM;WAAY,MACtB,EAAGA,EAAAA,GAAE,mBAAA,CAAA,EAAA,EAAA,CAAA,EAAA,GAAA,GAAA,IAAA,EAAA,IAAA,GAAA;KAK0C,EAAA,cAAsD,EAAM,iBAAY,UAAA,GAAA,EAD3H,EAcS,UAAA;;MATL,OAAK,EAAA,CAAC,gFAA8E,EAAA,WAAA,CACtB,EAAM,WAAA,CAAA,CAAA;MAGnE,UAAK,MAAE,EAAA,WAAW,EAAM,WAAA;SACzB,EAEsB,GAAA;MADlB,MAAK;MACL,OAAM;WAAY,MACtB,EAAGA,EAAAA,GAAE,qBAAA,CAAA,EAAA,EAAA,CAAA,EAAA,IAAA,GAAA,IAAA,EAAA,IAAA,GAAA;;IAWvB,EAAA,SAAA,GAAA,EADV,EAcS,UAAA;;KAZL,OAAM;KACL,SAAK,AAAA,EAAA,QAAA,MAAE,EAAA,QAAQ,CAAI,EAAA;QACpB,EAEsB,GAAA;KADjB,MAAM,EAAA,QAAQ,uBAAA;KACf,OAAM;6BAAY,MACtB,EACI,EAAA,QAA+BA,EAAAA,GAAE,kBAAA,GAA0CA,EAAAA,GAAE,mBAAA,EAAA,OAAuD,EAAA,MAAe,SAAM,GAAA,CAAA,CAAA,EAAA,EAAA,CAAA,CAAA,IAAA,EAAA,IAAA,GAAA"}
@@ -1,190 +0,0 @@
1
- import { t as e } from "./useChatbotStore-BNGyIqjI.js";
2
- import { t } from "./PkStreamingMarkdown-CtiMH6FD.js";
3
- import { n, t as r } from "./PkChatbotViewProfile-Cafl_Jf8.js";
4
- import { o as i } from "./utils-DO7emdsn.js";
5
- import { r as a } from "./PkToolShowContactForm-BzzbXuhh.js";
6
- import { t as ee } from "./PkChatbotViewChat-C4haTRtG.js";
7
- import { t as te } from "./PkChatbotViewConversations--vd3MWYy.js";
8
- import { Fragment as o, computed as s, createBlock as c, createCommentVNode as l, createElementBlock as u, createElementVNode as d, createSlots as f, createTextVNode as p, createVNode as m, defineComponent as h, guardReactiveProps as g, mergeModels as _, mergeProps as ne, normalizeClass as re, normalizeProps as v, normalizeStyle as y, openBlock as b, renderList as x, renderSlot as S, toDisplayString as C, toRef as w, unref as T, useModel as E, useSlots as D, watch as O, watchEffect as ie, withCtx as k } from "vue";
9
- import { VvAlert as ae, VvButton as A, VvButtonGroup as oe, VvDropdown as j, VvDropdownAction as M, VvIcon as se } from "@volverjs/ui-vue/components";
10
- import { useI18n as ce } from "vue-i18n";
11
- import { storeToRefs as le } from "pinia";
12
- //#region ../../packages/components/src/chat/PkChatbot.vue?vue&type=script&setup=true&lang.ts
13
- var ue = { class: "pk-chatbot__header-start" }, de = ["title"], fe = { key: 0 }, pe = { class: "pk-chatbot__warning-body" }, me = { class: "pk-chatbot__warning-header" }, he = { class: "pk-chatbot__warning-title" }, ge = { class: "pk-chatbot__warning-text" }, _e = {
14
- key: 4,
15
- class: "pk-chatbot__footer"
16
- }, N = /* @__PURE__ */ h({
17
- __name: "PkChatbot",
18
- props: /* @__PURE__ */ _({
19
- baseUrl: {},
20
- basePath: {},
21
- agentId: {},
22
- agentType: {},
23
- userId: {},
24
- name: {},
25
- model: {},
26
- agentModel: {},
27
- agentTools: {},
28
- agentInterface: {},
29
- actions: {},
30
- revisedAnswers: {},
31
- headers: {},
32
- systemTheme: {},
33
- agentFileUpload: {},
34
- fallbackModels: {},
35
- gatewayOptions: {}
36
- }, {
37
- chatId: {
38
- type: String,
39
- default: void 0
40
- },
41
- chatIdModifiers: {}
42
- }),
43
- emits: /* @__PURE__ */ _([
44
- "message-update",
45
- "show-info",
46
- "revise",
47
- "error"
48
- ], ["update:chatId"]),
49
- setup(h, { expose: _, emit: N }) {
50
- let P = D(), { t: F } = ce({ useScope: "global" }), I = h, L = N, R = E(h, "chatId"), z = e(I.agentId), { messages: B, chat: V, localChatId: H, activeView: U, chatError: ve } = le(z), W = w(z, "agentId"), { startNewChat: G, stopGeneration: K, regenerate: ye, navigate: q } = z;
51
- ie(() => {
52
- z.baseUrl = I.baseUrl, z.basePath = I.basePath, z.name = I.name, z.agentType = I.agentType, z.userId = I.userId, z.agentInterface = I.agentInterface, z.agentModel = I.agentModel, z.agentTools = I.agentTools, z.headers = I.headers, z.revisedAnswers = I.revisedAnswers, z.model = I.model, z.actionsInput = I.actions, z.agentFileUpload = I.agentFileUpload, z.fallbackModels = I.fallbackModels, z.gatewayOptions = I.gatewayOptions;
53
- }), O(() => R.value, (e) => {
54
- e && e !== z.localChatId && (z.localChatId = e);
55
- }, { immediate: !0 }), O(H, (e) => {
56
- R.value = e;
57
- }), O(ve, (e) => {
58
- if (e) try {
59
- L("error", JSON.parse(e.message));
60
- } catch {}
61
- });
62
- let J = s(() => I.agentType === "reasoning"), Y = s(() => I.agentInterface?.useColorsForAgentHeader), be = s(() => {
63
- let e = I.agentInterface?.theme;
64
- return (!e || e === "auto") && (e = I.systemTheme), e ? ["theme", `theme--${e}`] : ["theme"];
65
- }), X = s(() => I.agentInterface?.mainColor), Z = s(() => i(I.agentInterface?.textColor, X.value)), Q = a(() => I.agentInterface?.footerMessage), $ = s(() => U.value === "conversations" ? F("label.conversations") : U.value === "profile" ? F("label.profile") : I.name), xe = s(() => V.value.status === "ready"), Se = s(() => B.value?.[B.value.length - 1]);
66
- return _({
67
- startNewChat: G,
68
- regenerate: ye,
69
- stopGeneration: K
70
- }), O([W, H], async ([e, t]) => {
71
- await z.initialize(e, t);
72
- }, { immediate: !0 }), O(() => I.agentInterface?.initialMessage, () => {
73
- V.value.messages.length === 1 && V.value.messages[0].role === "assistant" && (V.value.messages = []);
74
- }, { deep: !0 }), O(U, (e) => {
75
- e === "conversations" && z.loadConversations(W.value);
76
- }), O(Se, (e) => {
77
- e && L("message-update", e);
78
- }, {
79
- deep: !0,
80
- immediate: !0
81
- }), (e, i) => {
82
- let a = A, s = se, _ = M, w = j, E = oe, D = ae;
83
- return b(), u("div", { class: re(["pk-chatbot", be.value]) }, [
84
- d("div", {
85
- class: "pk-chatbot__header",
86
- style: y(Y.value ? { backgroundColor: X.value } : void 0)
87
- }, [d("div", ue, [T(U) === "chat" ? (b(), c(n, {
88
- key: 1,
89
- modifiers: "surface ring shrink-0",
90
- class: "pk-chatbot__avatar",
91
- name: h.name,
92
- "img-src": h.agentInterface?.logo
93
- }, null, 8, ["name", "img-src"])) : (b(), u(o, { key: 0 }, [m(a, ne({
94
- modifiers: Y.value ? `action-quiet-${Z.value}` : "action-quiet",
95
- icon: "ri:arrow-left-s-line",
96
- title: T(F)("action.goBack")
97
- }, { onClick: i[0] ||= (e) => T(q)("chat") }), null, 16), m(s, {
98
- name: "ri:history-line",
99
- class: "pk-chatbot__nav-icon",
100
- style: y(Y.value ? { color: Z.value } : void 0)
101
- }, null, 8, ["style"])], 64)), d("strong", {
102
- class: "pk-chatbot__title",
103
- title: $.value,
104
- style: y(Y.value ? { color: Z.value } : void 0)
105
- }, C($.value), 13, de)]), m(E, {
106
- class: "pk-chatbot__header-end",
107
- modifiers: "compact"
108
- }, {
109
- default: k(() => [
110
- S(e.$slots, "header-actions", v(g({
111
- mainColor: X.value,
112
- useColorsForAgentHeader: Y.value,
113
- contrastColor: Z.value,
114
- startNewChat: T(G),
115
- stopGeneration: T(K)
116
- }))),
117
- m(w, v(g({
118
- placement: "bottom-end",
119
- modifiers: "menu",
120
- flip: !0,
121
- offset: 3
122
- })), {
123
- items: k(() => [m(_, { onClick: i[1] ||= (e) => T(G)() }, {
124
- default: k(() => [m(s, { name: "ri:edit-box-line" }), p(" " + C(T(F)("action.startNewChat")), 1)]),
125
- _: 1
126
- }), J.value ? l("", !0) : (b(), c(_, {
127
- key: 0,
128
- onClick: i[2] ||= (e) => T(q)("conversations")
129
- }, {
130
- default: k(() => [m(s, { name: "ri:history-line" }), p(" " + C(T(F)("action.viewRecentChats")), 1)]),
131
- _: 1
132
- }))]),
133
- default: k(() => [m(a, v(g({
134
- modifiers: Y.value ? `action-quiet-${Z.value}` : "action-quiet",
135
- icon: "ri:more-2-fill",
136
- disabled: !xe.value,
137
- title: T(F)("action.moreActions")
138
- })), null, 16)]),
139
- _: 1
140
- }, 16),
141
- S(e.$slots, "actions", v(g({
142
- mainColor: X.value,
143
- useColorsForAgentHeader: Y.value,
144
- contrastColor: Z.value,
145
- startNewChat: T(G),
146
- stopGeneration: T(K)
147
- })))
148
- ]),
149
- _: 3
150
- })], 4),
151
- J.value ? (b(), u("div", fe, [d("div", pe, [m(D, { modifiers: "callout" }, {
152
- default: k(() => [d("div", me, [m(s, {
153
- name: "ri:alert-line",
154
- class: "pk-chatbot__warning-icon"
155
- }), d("strong", he, C(T(F)("message.warning")), 1)]), d("p", ge, C(T(F)("message.reasoningAgent")), 1)]),
156
- _: 1
157
- })])])) : l("", !0),
158
- T(U) === "chat" ? (b(), c(ee, {
159
- key: 1,
160
- "agent-id": h.agentId,
161
- onShowInfo: i[3] ||= (e) => L("show-info", e),
162
- onRevise: i[4] ||= (e) => L("revise", e)
163
- }, f({ _: 2 }, [x(Object.keys(T(P)), (t) => ({
164
- name: t,
165
- fn: k((n) => [S(e.$slots, t, v(g(n)))])
166
- }))]), 1032, ["agent-id"])) : T(U) === "conversations" ? (b(), c(te, {
167
- key: 2,
168
- "agent-id": h.agentId
169
- }, f({ _: 2 }, [x(Object.keys(T(P)), (t) => ({
170
- name: t,
171
- fn: k((n) => [S(e.$slots, t, v(g(n)))])
172
- }))]), 1032, ["agent-id"])) : (b(), c(r, {
173
- key: 3,
174
- "agent-id": h.agentId
175
- }, f({ _: 2 }, [x(Object.keys(T(P)), (t) => ({
176
- name: t,
177
- fn: k((n) => [S(e.$slots, t, v(g(n)))])
178
- }))]), 1032, ["agent-id"])),
179
- T(Q) ? (b(), u("div", _e, [m(t, {
180
- markdown: T(Q),
181
- class: "wysiwyg"
182
- }, null, 8, ["markdown"])])) : l("", !0)
183
- ], 2);
184
- };
185
- }
186
- });
187
- //#endregion
188
- export { N as t };
189
-
190
- //# sourceMappingURL=PkChatbot-CkxgCXC4.js.map
@@ -1,40 +0,0 @@
1
- import { m as e, s as t } from "./src-EtGd6cRz.js";
2
- import { t as n } from "./useChatbotStore-BNGyIqjI.js";
3
- import { t as r } from "./PkRelativeTime-jP41qAJ5.js";
4
- import { Fragment as i, createElementBlock as a, createElementVNode as o, createVNode as s, defineComponent as c, normalizeClass as l, openBlock as u, renderList as d, toDisplayString as f, unref as p, withModifiers as m } from "vue";
5
- import { VvButton as h } from "@volverjs/ui-vue/components";
6
- import { useI18n as g } from "vue-i18n";
7
- import { storeToRefs as _ } from "pinia";
8
- //#region ../../packages/components/src/chat/PkChatbotViewConversations.vue?vue&type=script&setup=true&lang.ts
9
- var v = { class: "flex flex-col flex-1 min-h-0 overflow-y-auto p-md gap-sm relative" }, y = {
10
- key: 0,
11
- class: "flex justify-center p-lg text-word-3 text-sm"
12
- }, b = {
13
- key: 1,
14
- class: "flex flex-col min-h-0 gap-8 overflow-auto px-8 pb-8 light-scrollbar pb-64"
15
- }, x = ["onClick"], S = { class: "flex items-center gap-16" }, C = { class: "font-bold truncate block flex-1" }, w = { class: "text-word-4 text-smaller shrink-0" }, T = { class: "text-12 text-word-4 line-clamp-2" }, E = { class: "absolute bottom-0 left-0 right-0 flex justify-center px-16 pb-16 pt-32 bg-gradient-to-t" }, D = /* @__PURE__ */ c({
16
- __name: "PkChatbotViewConversations",
17
- props: { agentId: {} },
18
- setup(c) {
19
- let D = c, { t: O } = g({ useScope: "global" }), k = n(D.agentId), { conversations: A, localChatId: j } = _(k), { navigate: M, startNewChat: N } = k, P = (e) => {
20
- j.value = e, M("chat");
21
- }, F = (e) => j.value === e.id, I = (n, r) => e(t(n.filter((e) => e.role === r).slice(-1)[0]) || "");
22
- return (t, n) => {
23
- let c = h;
24
- return u(), a("div", v, [p(A).length === 0 ? (u(), a("div", y, f(p(O)("message.noConversations")), 1)) : (u(), a("ul", b, [(u(!0), a(i, null, d(p(A), (t) => (u(), a("li", { key: t.id }, [o("button", {
25
- type: "button",
26
- class: l(["rounded-md border p-10 cursor-pointer block w-full transition-colors text-14 leading-relaxed border-b border-surface-3 hover:border-surface-5 hover:bg-surface-1", { "bg-surface-2 border-surface-5": F(t) }]),
27
- onClick: (e) => P(t.id)
28
- }, [o("div", S, [o("strong", C, f(p(e)(t.title) || I(t.messages, "assistant")), 1), o("span", w, [s(r, { date: t.updatedAt }, null, 8, ["date"])])]), o("span", T, f(p(e)(t.summary) || I(t.messages, "user")), 1)], 10, x)]))), 128))])), o("div", E, [s(c, {
29
- class: "text-14",
30
- modifiers: "rounded",
31
- label: p(O)("action.startNewChat"),
32
- onClick: n[0] ||= m((e) => p(N)(), ["stop"])
33
- }, null, 8, ["label"])])]);
34
- };
35
- }
36
- });
37
- //#endregion
38
- export { D as t };
39
-
40
- //# sourceMappingURL=PkChatbotViewConversations--vd3MWYy.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PkChatbotViewConversations--vd3MWYy.js","names":[],"sources":["../../../../packages/components/src/chat/PkChatbotViewConversations.vue","../../../../packages/components/src/chat/PkChatbotViewConversations.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { storeToRefs } from 'pinia'\n import { useI18n } from 'vue-i18n'\n import type { Chat as Conversation, UIChatMessage } from 'models'\n import { stripMarkdown, getTextPart } from 'utils'\n import { useChatbotStore } from 'composables'\n import PkRelativeTime from '../PkRelativeTime.vue'\n\n const props = defineProps<{ agentId: string }>()\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n const store = useChatbotStore(props.agentId)\n const { conversations, localChatId } = storeToRefs(store)\n const { navigate, startNewChat } = store\n\n const openConversation = (id: string) => {\n localChatId.value = id\n navigate('chat')\n }\n\n const isCurrentConversation = (conversation: Conversation) => {\n return localChatId.value === conversation.id\n }\n\n const getLastMessage = (\n messages: UIChatMessage[],\n role: 'user' | 'assistant',\n ) => {\n return stripMarkdown(\n getTextPart(messages.filter((m) => m.role === role).slice(-1)[0]) ||\n '',\n )\n }\n</script>\n\n<template>\n <div\n class=\"flex flex-col flex-1 min-h-0 overflow-y-auto p-md gap-sm relative\">\n <div\n v-if=\"conversations.length === 0\"\n class=\"flex justify-center p-lg text-word-3 text-sm\">\n {{ $t('message.noConversations') }}\n </div>\n <ul\n v-else\n class=\"flex flex-col min-h-0 gap-8 overflow-auto px-8 pb-8 light-scrollbar pb-64\">\n <li v-for=\"conversation in conversations\" :key=\"conversation.id\">\n <button\n type=\"button\"\n class=\"rounded-md border p-10 cursor-pointer block w-full transition-colors text-14 leading-relaxed border-b border-surface-3 hover:border-surface-5 hover:bg-surface-1\"\n :class=\"{\n 'bg-surface-2 border-surface-5':\n isCurrentConversation(conversation),\n }\"\n @click=\"openConversation(conversation.id)\">\n <div class=\"flex items-center gap-16\">\n <strong class=\"font-bold truncate block flex-1\">\n {{\n stripMarkdown(conversation.title) ||\n getLastMessage(\n conversation.messages,\n 'assistant',\n )\n }}\n </strong>\n <span class=\"text-word-4 text-smaller shrink-0\">\n <PkRelativeTime :date=\"conversation.updatedAt\" />\n </span>\n </div>\n <span class=\"text-12 text-word-4 line-clamp-2\">\n {{\n stripMarkdown(conversation.summary) ||\n getLastMessage(conversation.messages, 'user')\n }}\n </span>\n </button>\n </li>\n </ul>\n <div\n class=\"absolute bottom-0 left-0 right-0 flex justify-center px-16 pb-16 pt-32 bg-gradient-to-t\">\n <VvButton\n class=\"text-14\"\n modifiers=\"rounded\"\n :label=\"$t('action.startNewChat')\"\n @click.stop=\"startNewChat()\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { storeToRefs } from 'pinia'\n import { useI18n } from 'vue-i18n'\n import type { Chat as Conversation, UIChatMessage } from 'models'\n import { stripMarkdown, getTextPart } from 'utils'\n import { useChatbotStore } from 'composables'\n import PkRelativeTime from '../PkRelativeTime.vue'\n\n const props = defineProps<{ agentId: string }>()\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n const store = useChatbotStore(props.agentId)\n const { conversations, localChatId } = storeToRefs(store)\n const { navigate, startNewChat } = store\n\n const openConversation = (id: string) => {\n localChatId.value = id\n navigate('chat')\n }\n\n const isCurrentConversation = (conversation: Conversation) => {\n return localChatId.value === conversation.id\n }\n\n const getLastMessage = (\n messages: UIChatMessage[],\n role: 'user' | 'assistant',\n ) => {\n return stripMarkdown(\n getTextPart(messages.filter((m) => m.role === role).slice(-1)[0]) ||\n '',\n )\n }\n</script>\n\n<template>\n <div\n class=\"flex flex-col flex-1 min-h-0 overflow-y-auto p-md gap-sm relative\">\n <div\n v-if=\"conversations.length === 0\"\n class=\"flex justify-center p-lg text-word-3 text-sm\">\n {{ $t('message.noConversations') }}\n </div>\n <ul\n v-else\n class=\"flex flex-col min-h-0 gap-8 overflow-auto px-8 pb-8 light-scrollbar pb-64\">\n <li v-for=\"conversation in conversations\" :key=\"conversation.id\">\n <button\n type=\"button\"\n class=\"rounded-md border p-10 cursor-pointer block w-full transition-colors text-14 leading-relaxed border-b border-surface-3 hover:border-surface-5 hover:bg-surface-1\"\n :class=\"{\n 'bg-surface-2 border-surface-5':\n isCurrentConversation(conversation),\n }\"\n @click=\"openConversation(conversation.id)\">\n <div class=\"flex items-center gap-16\">\n <strong class=\"font-bold truncate block flex-1\">\n {{\n stripMarkdown(conversation.title) ||\n getLastMessage(\n conversation.messages,\n 'assistant',\n )\n }}\n </strong>\n <span class=\"text-word-4 text-smaller shrink-0\">\n <PkRelativeTime :date=\"conversation.updatedAt\" />\n </span>\n </div>\n <span class=\"text-12 text-word-4 line-clamp-2\">\n {{\n stripMarkdown(conversation.summary) ||\n getLastMessage(conversation.messages, 'user')\n }}\n </span>\n </button>\n </li>\n </ul>\n <div\n class=\"absolute bottom-0 left-0 right-0 flex justify-center px-16 pb-16 pt-32 bg-gradient-to-t\">\n <VvButton\n class=\"text-14\"\n modifiers=\"rounded\"\n :label=\"$t('action.startNewChat')\"\n @click.stop=\"startNewChat()\" />\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;EAQI,IAAM,IAAQ,GAER,EAAE,GAAG,MAAO,EAAQ,EAAE,UAAU,UAAU,CAAA,EAE1C,IAAQ,EAAgB,EAAM,QAAO,EACrC,EAAE,kBAAe,mBAAgB,EAAY,EAAK,EAClD,EAAE,aAAU,oBAAiB,GAE7B,KAAoB,MAAe;AAErC,GADA,EAAY,QAAQ,GACpB,EAAS,OAAM;KAGb,KAAyB,MACpB,EAAY,UAAU,EAAa,IAGxC,KACF,GACA,MAEO,EACH,EAAY,EAAS,QAAQ,MAAM,EAAE,SAAS,EAAK,CAAC,MAAM,GAAG,CAAC,GAAG,IAC7D,GACR;;;eAKJ,EAkDM,OAlDN,GAkDM,CA/CQ,EAAA,EAAa,CAAC,WAAM,KAAA,GAAA,EAD9B,EAIM,OAJN,GAIM,EADC,EAAA,EAAE,CAAA,0BAAA,CAAA,EAAA,EAAA,KAAA,GAAA,EAET,EAkCK,MAlCL,GAkCK,EAAA,EAAA,GAAA,EA/BD,EA8BK,GAAA,MAAA,EA9BsB,EAAA,EAAa,GAA7B,YAAX,EA8BK,MAAA,EA9BsC,KAAK,EAAa,IAAA,EAAA,CACzD,EA4BS,UAAA;IA3BL,MAAK;IACL,OAAK,EAAA,CAAC,oKAAkK,EAAA,iCACzE,EAAsB,EAAY,EAAA,CAAA,CAAA;IAIhI,UAAK,MAAE,EAAiB,EAAa,GAAA;OACtC,EAaM,OAbN,GAaM,CAZF,EAQS,UART,GAQS,EAND,EAAA,EAAa,CAAC,EAAa,MAAK,IAAqC,EAAoD,EAAa,UAAA,YAAA,CAAA,EAAA,EAAA,EAO9I,EAEO,QAFP,GAEO,CADH,EAAiD,GAAA,EAAhC,MAAM,EAAa,WAAA,EAAA,MAAA,GAAA,CAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAG5C,EAKO,QALP,GAKO,EAHC,EAAA,EAAa,CAAC,EAAa,QAAO,IAAiC,EAAe,EAAa,UAAQ,OAAA,CAAA,EAAA,EAAA,CAAA,EAAA,IAAA,EAAA,CAAA,CAAA,cAO3H,EAOM,OAPN,GAOM,CALF,EAImC,GAAA;IAH/B,OAAM;IACN,WAAU;IACT,OAAO,EAAA,EAAE,CAAA,sBAAA;IACT,SAAK,AAAA,EAAA,OAAA,GAAA,MAAO,EAAA,EAAY,EAAA,EAAA,CAAA,OAAA,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"PkToolShowSources-BXeGRm4D.js","names":["$t"],"sources":["../../../../packages/models/src/schema/Header.ts","../../../../packages/models/src/schema/Document.ts","../../../../packages/components/src/chat/PkChunkPreview.vue","../../../../packages/components/src/chat/PkChunkPreview.vue","../../../../packages/components/src/chat/PkDocumentHeader.vue","../../../../packages/components/src/chat/PkDocumentHeader.vue","../../../../packages/components/src/chat/PkToolShowSources.vue","../../../../packages/components/src/chat/PkToolShowSources.vue"],"sourcesContent":["import * as z from 'zod'\n\nexport const HeaderSchema = z.object({\n key: z.string().optional(),\n value: z.string().optional(),\n})\n\nexport const HeadesSchema = z.array(HeaderSchema).transform((headers) => {\n return headers?.filter(\n (header) => header.key?.trim() && header.value?.trim(),\n ) as Array<{ key: string; value: string }>\n})\n\nexport type Header = z.infer<typeof HeaderSchema>\nexport type Headers = z.infer<typeof HeadesSchema>\n","import * as z from 'zod'\nimport { zodQs } from '../utils'\nimport {\n SupportedLanguage,\n ExtractionStrategy,\n BrowserEngine,\n} from './constants'\nimport { MediaSchema } from './Media'\nimport { HeadesSchema } from './Header'\n\n/**\n * Processing status for document indexing and embedding generation\n */\nexport enum IndexStatus {\n Pending = 'pending',\n Processing = 'processing',\n Success = 'success',\n Failed = 'failed',\n}\n\n// ===== Document Source Types =====\n\n/**\n * Conversion options for document processing\n * Used when creating or reprocessing documents\n */\nexport const ConversionOptionsSchema = z.object({\n extractionStrategy: z.enum(ExtractionStrategy).optional(),\n browserEngine: z.enum(BrowserEngine).optional(),\n headers: HeadesSchema.nullish(),\n aiDescriptionModel: z.string().optional(),\n aiDescriptionPrompt: z.string().max(5000).optional(),\n language: z.string().optional(),\n})\n\nexport type ConversionOptions = z.infer<typeof ConversionOptionsSchema>\n\n/**\n * Metadata structure for document.metadata column\n * Consolidates all metadata from converters and source info\n */\nexport const DocumentMetadataSchema = z\n .object({\n // === Source Info (URL documents only) ===\n source: z\n .object({\n url: z.string(),\n lastScrapedAt: z.string(),\n })\n .optional(),\n\n // === Media Info (File documents only) ===\n media: MediaSchema.optional(),\n\n // === Common Fields (all document types) ===\n title: z.string().optional(),\n author: z.string().optional(),\n description: z.string().optional(),\n summary: z.string().optional(),\n keywords: z.array(z.string()).optional(),\n\n // === PDF Specific ===\n subject: z.string().optional(),\n creator: z.string().optional(), // Original application\n producer: z.string().optional(), // PDF generator software\n creationDate: z.string().optional(),\n modificationDate: z.string().optional(),\n pageCount: z\n .union([z.number(), z.array(z.unknown())])\n .transform((val) => (Array.isArray(val) ? val.length : val))\n .optional(),\n encrypted: z.boolean().optional(),\n\n // === DOCX Specific ===\n characterCount: z.number().optional(),\n lineCount: z.number().optional(),\n\n // === URL Specific ===\n siteName: z.string().optional(),\n canonicalUrl: z.url().optional(),\n imageUrl: z.url().optional(),\n favicon: z.url().optional(),\n type: z.string().optional(), // og:type (article, website, etc.)\n locale: z.string().optional(),\n tags: z.array(z.string()).optional(),\n publishedTime: z.string().optional(),\n modifiedTime: z.string().optional(),\n\n // === Metrics (all document types) ===\n wordCount: z.number().optional(),\n paragraphCount: z.number().optional(),\n readingTime: z.number().optional(), // in minutes\n\n // === Conversion Options (for reprocessing) ===\n conversionOptions: ConversionOptionsSchema.optional(),\n })\n .loose() // Allow additional custom fields\n\nexport type DocumentMetadata = z.infer<typeof DocumentMetadataSchema>\n\n/**\n * Document type enum\n *\n * - 'file': Document created from uploaded file (PDF, DOCX)\n * - 'url': Document created from web scraping\n * - 'revised-answer': Document created from revised AI answer\n * - 'plain-text': Document created from plain text input\n */\nexport enum DocumentType {\n File = 'file',\n Url = 'url',\n RevisedAnswer = 'revised-answer',\n PlainText = 'plain-text',\n}\n\n// ===== Schemas =====\n\n/**\n * Full document schema from database\n * Extended with computed field chunksCount\n */\nconst BaseDocumentSchema = z.object({\n id: z.string(),\n externalId: z.string().nullable(),\n name: z.string(),\n content: z.string(),\n type: z.string(),\n language: z.string(),\n metadata: z.record(z.string(), z.unknown()),\n indexStatus: z.string(),\n processedAt: z.coerce.date().nullable(),\n createdAt: z.coerce.date(),\n createdBy: z.string(),\n updatedAt: z.coerce.date(),\n updatedBy: z.string(),\n deleted: z.boolean(),\n deletedAt: z.coerce.date().nullable(),\n deletedBy: z.string().nullable(),\n organizationId: z.string(),\n})\n\nexport const DocumentSchema = BaseDocumentSchema.extend({\n type: z.enum(DocumentType),\n indexStatus: z.enum(IndexStatus),\n metadata: DocumentMetadataSchema,\n // Add computed field for chunks count (populated by service layer)\n chunksCount: z.number().optional(),\n})\n\n/**\n * Query parameters for listing documents with pagination, sorting, and filters\n */\nexport const DocumentQuerystringSchema = z.object({\n ...zodQs.pagination(),\n ...zodQs.sort(['id', 'updatedAt', 'createdAt', 'name']),\n ...zodQs.filters(['type', 'language', 'agentId', 'indexStatus']),\n ...zodQs.fullText(),\n ...zodQs.ids(),\n 'filter[similarity]': z.string().optional(),\n})\n\n/**\n * Document creation schema for POST /documents endpoint\n *\n * Supports three types:\n * - 'file': Requires media object with uploaded file info\n * - 'url': Requires url string for web scraping\n * - 'revised-answer': Requires content (created from revisedAnswer service)\n */\nexport const DocumentCreateDtoSchema = z\n .object({\n type: z.enum(DocumentType).default(DocumentType.File),\n name: z.string().min(1).max(255).optional(),\n language: z.enum(SupportedLanguage).optional(),\n organizationId: z.string(),\n agentIds: z.array(z.string()).min(1, 'At least one agent is required'),\n media: MediaSchema.optional(),\n url: z.url().optional(),\n content: z.string().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n extractionStrategy: z.enum(ExtractionStrategy).optional(),\n browserEngine: z.enum(BrowserEngine).optional(),\n headers: HeadesSchema.nullish().default([]),\n aiDescriptionModel: z.string().optional(),\n aiDescriptionPrompt: z.string().max(5000).optional(),\n })\n .superRefine((data, ctx) => {\n if (data.type === DocumentType.File && !data.media) {\n ctx.addIssue({\n code: 'custom',\n params: {\n i18n: 'errors.required',\n },\n path: ['media'],\n })\n return\n }\n if (data.type === DocumentType.Url && !data.url) {\n ctx.addIssue({\n code: 'custom',\n params: {\n i18n: 'errors.required',\n },\n path: ['url'],\n })\n }\n if (\n data.type === DocumentType.PlainText &&\n !(data.name || data.language)\n ) {\n if (!data.name) {\n ctx.addIssue({\n code: 'custom',\n params: {\n i18n: 'errors.required',\n },\n path: ['name'],\n })\n }\n if (!data.language) {\n ctx.addIssue({\n code: 'custom',\n params: {\n i18n: 'errors.required',\n },\n path: ['language'],\n })\n }\n }\n })\n\n/**\n * Document update schema for PUT /documents/:id endpoint\n *\n * All fields are optional, but at least one must be provided\n */\nexport const DocumentUpdateDtoSchema = z.object({\n id: z.string(),\n organizationId: z.string(),\n content: z.string().optional(),\n name: z.string().min(1).max(255).optional(),\n language: z.enum(SupportedLanguage).optional(),\n agentIds: z.array(z.string()).min(1).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n})\n\n// ===== Type Exports =====\n\nexport type Document = z.infer<typeof DocumentSchema>\nexport type DocumentQuerystring = z.infer<typeof DocumentQuerystringSchema>\nexport type DocumentCreateDto = z.infer<typeof DocumentCreateDtoSchema>\nexport type DocumentUpdateDto = z.infer<typeof DocumentUpdateDtoSchema>\n\n// ===== Helper Functions =====\n\nexport const getStatusColor = (status: IndexStatus) => {\n switch (status) {\n case IndexStatus.Success:\n return 'success'\n case IndexStatus.Failed:\n return 'danger'\n case IndexStatus.Processing:\n return 'warning'\n default:\n return 'info'\n }\n}\n\nexport const getStatusIcon = (status: IndexStatus) => {\n switch (status) {\n case IndexStatus.Success:\n return 'ri:check-line'\n case IndexStatus.Failed:\n return 'ri:error-warning-line'\n case IndexStatus.Processing:\n return 'ri:hourglass-line'\n default:\n return 'ri:time-line'\n }\n}\n\nexport const getTypeIcon = (type: DocumentType) => {\n switch (type) {\n case DocumentType.File:\n return 'ri:file-line'\n case DocumentType.Url:\n return 'ri:link'\n case DocumentType.RevisedAnswer:\n return 'ri:feedback-line'\n default:\n return 'ri:input-method-line'\n }\n}\n\nexport const getFileIcon = (extension: string) => {\n const ext = (\n extension.startsWith('.') ? extension.slice(1) : extension\n ).toLowerCase()\n switch (ext) {\n case 'pdf':\n return 'ri:file-pdf-2-line'\n case 'doc':\n case 'docx':\n return 'ri:file-word-line'\n case 'xls':\n case 'xlsx':\n return 'ri:file-excel-line'\n case 'ppt':\n case 'pptx':\n return 'ri:file-ppt-line'\n case 'txt':\n return 'ri:file-text-line'\n case 'mp3':\n case 'wav':\n case 'ogg':\n return 'ri:file-music-line'\n case 'mp4':\n case 'avi':\n case 'mkv':\n return 'ri:file-video-line'\n case 'jpg':\n case 'jpeg':\n case 'png':\n case 'gif':\n case 'bmp':\n case 'svg':\n return 'ri:file-image-line'\n case 'zip':\n case 'rar':\n case '7z':\n return 'ri:file-zip-line'\n default:\n return 'ri:file-line'\n }\n}\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { stripMarkdown } from 'utils'\n\n const props = defineProps<{\n content: string\n similarity?: number\n maxSimilarity?: number\n expanded: boolean\n }>()\n\n const similarityPercent = computed(() => {\n if (props.similarity == null) {\n return null\n }\n const max =\n props.maxSimilarity && props.maxSimilarity > 0\n ? props.maxSimilarity\n : 1\n return Math.round((props.similarity / max) * 100)\n })\n</script>\n\n<template>\n <VvIcon name=\"ri:text-snippet\" class=\"shrink-0 text-12 text-word-4\" />\n <span class=\"text-10 text-word-2 truncate flex-1\" :title=\"content\">\n {{ stripMarkdown(content) }}\n </span>\n <span v-if=\"similarityPercent != null\" class=\"text-10 text-word-4 shrink-0\">\n {{ similarityPercent }}%\n </span>\n <VvIcon\n :name=\"expanded ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-14 text-word-4 shrink-0\" />\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { stripMarkdown } from 'utils'\n\n const props = defineProps<{\n content: string\n similarity?: number\n maxSimilarity?: number\n expanded: boolean\n }>()\n\n const similarityPercent = computed(() => {\n if (props.similarity == null) {\n return null\n }\n const max =\n props.maxSimilarity && props.maxSimilarity > 0\n ? props.maxSimilarity\n : 1\n return Math.round((props.similarity / max) * 100)\n })\n</script>\n\n<template>\n <VvIcon name=\"ri:text-snippet\" class=\"shrink-0 text-12 text-word-4\" />\n <span class=\"text-10 text-word-2 truncate flex-1\" :title=\"content\">\n {{ stripMarkdown(content) }}\n </span>\n <span v-if=\"similarityPercent != null\" class=\"text-10 text-word-4 shrink-0\">\n {{ similarityPercent }}%\n </span>\n <VvIcon\n :name=\"expanded ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-14 text-word-4 shrink-0\" />\n</template>\n","<script setup lang=\"ts\">\n import type { DocumentType } from 'models'\n import { getTypeIcon } from 'models'\n import PkUrl from '../PkUrl.vue'\n\n defineProps<{\n type: string\n name: string\n url?: string\n filename?: string\n }>()\n</script>\n\n<template>\n <VvIcon\n :name=\"getTypeIcon(type as DocumentType)\"\n class=\"shrink-0 text-14 text-word-3\" />\n <div class=\"flex flex-col gap-2 min-w-0 flex-1\">\n <strong class=\"font-bold text-12 text-word-1 truncate block\">\n {{ name }}\n </strong>\n <span v-if=\"filename\" class=\"text-10 text-word-4 truncate\">\n {{ filename }}\n </span>\n <span\n v-if=\"url\"\n class=\"text-10 text-word-4 truncate flex items-center gap-4\">\n <VvIcon name=\"ri:link\" class=\"shrink-0 text-10\" />\n <PkUrl :url=\"url\" />\n </span>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import type { DocumentType } from 'models'\n import { getTypeIcon } from 'models'\n import PkUrl from '../PkUrl.vue'\n\n defineProps<{\n type: string\n name: string\n url?: string\n filename?: string\n }>()\n</script>\n\n<template>\n <VvIcon\n :name=\"getTypeIcon(type as DocumentType)\"\n class=\"shrink-0 text-14 text-word-3\" />\n <div class=\"flex flex-col gap-2 min-w-0 flex-1\">\n <strong class=\"font-bold text-12 text-word-1 truncate block\">\n {{ name }}\n </strong>\n <span v-if=\"filename\" class=\"text-10 text-word-4 truncate\">\n {{ filename }}\n </span>\n <span\n v-if=\"url\"\n class=\"text-10 text-word-4 truncate flex items-center gap-4\">\n <VvIcon name=\"ri:link\" class=\"shrink-0 text-10\" />\n <PkUrl :url=\"url\" />\n </span>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, reactive } from 'vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import PkChunkPreview from './PkChunkPreview.vue'\n import PkDocumentHeader from './PkDocumentHeader.vue'\n\n interface SourceItem {\n chunkId: string\n documentId: string\n documentName: string\n documentType: string\n language: string\n content: string\n chunkIndex?: number | null\n similarity?: number\n sourceUrl?: string\n sourceFilename?: string\n sourceDescription?: string\n sourceImageUrl?: string\n }\n\n const props = defineProps<{\n part: unknown\n onExpandContext?: (payload: {\n documentId: string\n chunkIndex: number\n }) => Promise<string>\n onDownload?: (documentId: string) => void\n }>()\n\n const toolPart = computed(() => {\n return props.part as {\n input?: {\n sources: SourceItem[]\n }\n }\n })\n\n const sources = computed(() => toolPart.value.input?.sources || [])\n\n const groupedSources = computed(() => {\n const groups = new Map<\n string,\n { document: SourceItem; chunks: SourceItem[] }\n >()\n for (const source of sources.value) {\n const existing = groups.get(source.documentId)\n if (existing) {\n existing.chunks.push(source)\n } else {\n groups.set(source.documentId, {\n document: source,\n chunks: [source],\n })\n }\n }\n return [...groups.values()]\n })\n\n const maxSimilarity = computed(() => {\n return Math.max(...sources.value.map((s) => s.similarity ?? 0), 0)\n })\n\n const expandedDocuments = reactive(new Set<string>())\n const expandedChunks = reactive(new Set<string>())\n const contextData = reactive(new Map<string, string>())\n const loadingContext = reactive(new Set<string>())\n\n const toggleDocument = (documentId: string) => {\n if (expandedDocuments.has(documentId)) {\n expandedDocuments.delete(documentId)\n } else {\n expandedDocuments.add(documentId)\n }\n }\n\n const toggleChunk = (chunkId: string) => {\n if (expandedChunks.has(chunkId)) {\n expandedChunks.delete(chunkId)\n } else {\n expandedChunks.add(chunkId)\n }\n }\n\n const handleExpandContext = async (source: SourceItem) => {\n if (source.chunkIndex == null || !props.onExpandContext) {\n return\n }\n loadingContext.add(source.chunkId)\n try {\n const content = await props.onExpandContext({\n documentId: source.documentId,\n chunkIndex: source.chunkIndex,\n })\n contextData.set(source.chunkId, content)\n } finally {\n loadingContext.delete(source.chunkId)\n }\n }\n\n const clearContext = (chunkId: string) => {\n contextData.delete(chunkId)\n }\n\n const showMore = ref(false)\n const visibleGroups = computed(() => {\n if (showMore.value) {\n return groupedSources.value\n }\n return groupedSources.value.slice(0, 3)\n })\n const hasMore = computed(() => groupedSources.value.length > 3)\n</script>\n\n<template>\n <div v-if=\"sources.length\" class=\"flex flex-col gap-xs w-full\">\n <div class=\"flex items-center gap-4 text-12 text-word-3 font-semibold\">\n <VvIcon name=\"ri:article-line\" class=\"text-14\" />\n {{ $t('label.sources') }}\n <span class=\"text-word-4 font-normal\">\n ({{ groupedSources.length }})\n </span>\n </div>\n\n <ul class=\"flex flex-col gap-xs\">\n <li\n v-for=\"group in visibleGroups\"\n :key=\"group.document.documentId\"\n class=\"border border-surface-3 rounded-lg overflow-hidden\">\n <!-- Document header -->\n <button\n class=\"flex items-center gap-8 p-8 w-full text-left hover:bg-surface-1 transition-colors cursor-pointer\"\n @click=\"toggleDocument(group.document.documentId)\">\n <PkDocumentHeader\n :type=\"group.document.documentType\"\n :name=\"group.document.documentName\"\n :url=\"group.document.sourceUrl\"\n :filename=\"group.document.sourceFilename\" />\n <div class=\"flex items-center gap-4 shrink-0\">\n <span\n v-if=\"group.chunks.length > 1\"\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2\">\n {{ group.chunks.length }}\n </span>\n <span\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2 uppercase\">\n {{ group.document.language }}\n </span>\n <VvIcon\n :name=\"\n expandedDocuments.has(group.document.documentId)\n ? 'ri:arrow-up-s-line'\n : 'ri:arrow-down-s-line'\n \"\n class=\"text-16 text-word-3\" />\n </div>\n </button>\n\n <!-- Expanded content -->\n <div\n v-if=\"expandedDocuments.has(group.document.documentId)\"\n class=\"border-t border-surface-3\">\n <PkStreamingMarkdown\n v-if=\"group.document.sourceDescription\"\n :markdown=\"group.document.sourceDescription\"\n class=\"px-8 py-4 text-10 text-word-3 bg-surface-1 border-b border-surface-3\" />\n\n <!-- Chunk excerpts -->\n <div\n v-for=\"chunk in group.chunks\"\n :key=\"chunk.chunkId\"\n class=\"border-b border-surface-3 last:border-b-0\">\n <button\n class=\"flex items-center gap-8 px-8 py-6 w-full text-left hover:bg-surface-1 transition-colors cursor-pointer\"\n @click=\"toggleChunk(chunk.chunkId)\">\n <PkChunkPreview\n :content=\"chunk.content\"\n :similarity=\"chunk.similarity\"\n :max-similarity=\"maxSimilarity\"\n :expanded=\"expandedChunks.has(chunk.chunkId)\" />\n </button>\n\n <!-- Expanded chunk content -->\n <div\n v-if=\"expandedChunks.has(chunk.chunkId)\"\n class=\"bg-surface-1 border-t border-surface-3\">\n <div class=\"p-8 text-10 text-word-3\">\n <transition mode=\"out-in\">\n <!-- Context expansion -->\n <PkStreamingMarkdown\n v-if=\"contextData.has(chunk.chunkId)\"\n :markdown=\"\n contextData.get(chunk.chunkId)!\n \"\n class=\"wysiwyg\" />\n\n <!-- Chunk content -->\n <PkStreamingMarkdown\n v-else\n :markdown=\"chunk.content\"\n class=\"wysiwyg\" />\n </transition>\n </div>\n\n <!-- Actions bar -->\n <div\n class=\"flex items-center gap-8 px-8 py-6 border-t border-surface-3 bg-surface\">\n <!-- Expand / collapse context -->\n <button\n v-if=\"\n onExpandContext &&\n chunk.chunkIndex != null &&\n !contextData.has(chunk.chunkId)\n \"\n class=\"text-10 text-word-3 hover:text-word flex items-center gap-4 cursor-pointer\"\n :disabled=\"\n loadingContext.has(chunk.chunkId)\n \"\n @click=\"handleExpandContext(chunk)\">\n <VvIcon\n :name=\"\n loadingContext.has(chunk.chunkId)\n ? 'line-md:loading-loop'\n : 'ri:expand-up-down-line'\n \"\n class=\"text-12\" />\n {{ $t('label.expandContext') }}\n </button>\n <button\n v-else-if=\"contextData.has(chunk.chunkId)\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n @click=\"clearContext(chunk.chunkId)\">\n <VvIcon\n name=\"ri:collapse-vertical-line\"\n class=\"text-12\" />\n {{ $t('label.collapseContext') }}\n </button>\n\n <!-- Open source URL -->\n <a\n v-if=\"chunk.sourceUrl\"\n :href=\"chunk.sourceUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 ml-auto\">\n <VvIcon\n name=\"ri:external-link-line\"\n class=\"text-12\" />\n {{ $t('label.openSource') }}\n </a>\n\n <!-- Download file -->\n <button\n v-if=\"\n onDownload &&\n chunk.documentType === 'file'\n \"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n :class=\"{\n 'ml-auto': !chunk.sourceUrl,\n }\"\n @click=\"onDownload(chunk.documentId)\">\n <VvIcon\n name=\"ri:download-line\"\n class=\"text-12\" />\n {{ $t('label.downloadFile') }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </li>\n </ul>\n\n <!-- Show more -->\n <button\n v-if=\"hasMore\"\n class=\"text-12 text-word-3 cursor-pointer hover:underline flex items-center gap-4 mx-auto\"\n @click=\"showMore = !showMore\">\n <VvIcon\n :name=\"showMore ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-16\" />\n {{\n showMore\n ? $t('action.showLess')\n : $t('action.showMore', {\n count: groupedSources.length - 3,\n })\n }}\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, reactive } from 'vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import PkChunkPreview from './PkChunkPreview.vue'\n import PkDocumentHeader from './PkDocumentHeader.vue'\n\n interface SourceItem {\n chunkId: string\n documentId: string\n documentName: string\n documentType: string\n language: string\n content: string\n chunkIndex?: number | null\n similarity?: number\n sourceUrl?: string\n sourceFilename?: string\n sourceDescription?: string\n sourceImageUrl?: string\n }\n\n const props = defineProps<{\n part: unknown\n onExpandContext?: (payload: {\n documentId: string\n chunkIndex: number\n }) => Promise<string>\n onDownload?: (documentId: string) => void\n }>()\n\n const toolPart = computed(() => {\n return props.part as {\n input?: {\n sources: SourceItem[]\n }\n }\n })\n\n const sources = computed(() => toolPart.value.input?.sources || [])\n\n const groupedSources = computed(() => {\n const groups = new Map<\n string,\n { document: SourceItem; chunks: SourceItem[] }\n >()\n for (const source of sources.value) {\n const existing = groups.get(source.documentId)\n if (existing) {\n existing.chunks.push(source)\n } else {\n groups.set(source.documentId, {\n document: source,\n chunks: [source],\n })\n }\n }\n return [...groups.values()]\n })\n\n const maxSimilarity = computed(() => {\n return Math.max(...sources.value.map((s) => s.similarity ?? 0), 0)\n })\n\n const expandedDocuments = reactive(new Set<string>())\n const expandedChunks = reactive(new Set<string>())\n const contextData = reactive(new Map<string, string>())\n const loadingContext = reactive(new Set<string>())\n\n const toggleDocument = (documentId: string) => {\n if (expandedDocuments.has(documentId)) {\n expandedDocuments.delete(documentId)\n } else {\n expandedDocuments.add(documentId)\n }\n }\n\n const toggleChunk = (chunkId: string) => {\n if (expandedChunks.has(chunkId)) {\n expandedChunks.delete(chunkId)\n } else {\n expandedChunks.add(chunkId)\n }\n }\n\n const handleExpandContext = async (source: SourceItem) => {\n if (source.chunkIndex == null || !props.onExpandContext) {\n return\n }\n loadingContext.add(source.chunkId)\n try {\n const content = await props.onExpandContext({\n documentId: source.documentId,\n chunkIndex: source.chunkIndex,\n })\n contextData.set(source.chunkId, content)\n } finally {\n loadingContext.delete(source.chunkId)\n }\n }\n\n const clearContext = (chunkId: string) => {\n contextData.delete(chunkId)\n }\n\n const showMore = ref(false)\n const visibleGroups = computed(() => {\n if (showMore.value) {\n return groupedSources.value\n }\n return groupedSources.value.slice(0, 3)\n })\n const hasMore = computed(() => groupedSources.value.length > 3)\n</script>\n\n<template>\n <div v-if=\"sources.length\" class=\"flex flex-col gap-xs w-full\">\n <div class=\"flex items-center gap-4 text-12 text-word-3 font-semibold\">\n <VvIcon name=\"ri:article-line\" class=\"text-14\" />\n {{ $t('label.sources') }}\n <span class=\"text-word-4 font-normal\">\n ({{ groupedSources.length }})\n </span>\n </div>\n\n <ul class=\"flex flex-col gap-xs\">\n <li\n v-for=\"group in visibleGroups\"\n :key=\"group.document.documentId\"\n class=\"border border-surface-3 rounded-lg overflow-hidden\">\n <!-- Document header -->\n <button\n class=\"flex items-center gap-8 p-8 w-full text-left hover:bg-surface-1 transition-colors cursor-pointer\"\n @click=\"toggleDocument(group.document.documentId)\">\n <PkDocumentHeader\n :type=\"group.document.documentType\"\n :name=\"group.document.documentName\"\n :url=\"group.document.sourceUrl\"\n :filename=\"group.document.sourceFilename\" />\n <div class=\"flex items-center gap-4 shrink-0\">\n <span\n v-if=\"group.chunks.length > 1\"\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2\">\n {{ group.chunks.length }}\n </span>\n <span\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2 uppercase\">\n {{ group.document.language }}\n </span>\n <VvIcon\n :name=\"\n expandedDocuments.has(group.document.documentId)\n ? 'ri:arrow-up-s-line'\n : 'ri:arrow-down-s-line'\n \"\n class=\"text-16 text-word-3\" />\n </div>\n </button>\n\n <!-- Expanded content -->\n <div\n v-if=\"expandedDocuments.has(group.document.documentId)\"\n class=\"border-t border-surface-3\">\n <PkStreamingMarkdown\n v-if=\"group.document.sourceDescription\"\n :markdown=\"group.document.sourceDescription\"\n class=\"px-8 py-4 text-10 text-word-3 bg-surface-1 border-b border-surface-3\" />\n\n <!-- Chunk excerpts -->\n <div\n v-for=\"chunk in group.chunks\"\n :key=\"chunk.chunkId\"\n class=\"border-b border-surface-3 last:border-b-0\">\n <button\n class=\"flex items-center gap-8 px-8 py-6 w-full text-left hover:bg-surface-1 transition-colors cursor-pointer\"\n @click=\"toggleChunk(chunk.chunkId)\">\n <PkChunkPreview\n :content=\"chunk.content\"\n :similarity=\"chunk.similarity\"\n :max-similarity=\"maxSimilarity\"\n :expanded=\"expandedChunks.has(chunk.chunkId)\" />\n </button>\n\n <!-- Expanded chunk content -->\n <div\n v-if=\"expandedChunks.has(chunk.chunkId)\"\n class=\"bg-surface-1 border-t border-surface-3\">\n <div class=\"p-8 text-10 text-word-3\">\n <transition mode=\"out-in\">\n <!-- Context expansion -->\n <PkStreamingMarkdown\n v-if=\"contextData.has(chunk.chunkId)\"\n :markdown=\"\n contextData.get(chunk.chunkId)!\n \"\n class=\"wysiwyg\" />\n\n <!-- Chunk content -->\n <PkStreamingMarkdown\n v-else\n :markdown=\"chunk.content\"\n class=\"wysiwyg\" />\n </transition>\n </div>\n\n <!-- Actions bar -->\n <div\n class=\"flex items-center gap-8 px-8 py-6 border-t border-surface-3 bg-surface\">\n <!-- Expand / collapse context -->\n <button\n v-if=\"\n onExpandContext &&\n chunk.chunkIndex != null &&\n !contextData.has(chunk.chunkId)\n \"\n class=\"text-10 text-word-3 hover:text-word flex items-center gap-4 cursor-pointer\"\n :disabled=\"\n loadingContext.has(chunk.chunkId)\n \"\n @click=\"handleExpandContext(chunk)\">\n <VvIcon\n :name=\"\n loadingContext.has(chunk.chunkId)\n ? 'line-md:loading-loop'\n : 'ri:expand-up-down-line'\n \"\n class=\"text-12\" />\n {{ $t('label.expandContext') }}\n </button>\n <button\n v-else-if=\"contextData.has(chunk.chunkId)\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n @click=\"clearContext(chunk.chunkId)\">\n <VvIcon\n name=\"ri:collapse-vertical-line\"\n class=\"text-12\" />\n {{ $t('label.collapseContext') }}\n </button>\n\n <!-- Open source URL -->\n <a\n v-if=\"chunk.sourceUrl\"\n :href=\"chunk.sourceUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 ml-auto\">\n <VvIcon\n name=\"ri:external-link-line\"\n class=\"text-12\" />\n {{ $t('label.openSource') }}\n </a>\n\n <!-- Download file -->\n <button\n v-if=\"\n onDownload &&\n chunk.documentType === 'file'\n \"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n :class=\"{\n 'ml-auto': !chunk.sourceUrl,\n }\"\n @click=\"onDownload(chunk.documentId)\">\n <VvIcon\n name=\"ri:download-line\"\n class=\"text-12\" />\n {{ $t('label.downloadFile') }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </li>\n </ul>\n\n <!-- Show more -->\n <button\n v-if=\"hasMore\"\n class=\"text-12 text-word-3 cursor-pointer hover:underline flex items-center gap-4 mx-auto\"\n @click=\"showMore = !showMore\">\n <VvIcon\n :name=\"showMore ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-16\" />\n {{\n showMore\n ? $t('action.showLess')\n : $t('action.showMore', {\n count: groupedSources.length - 3,\n })\n }}\n </button>\n </div>\n</template>\n"],"mappings":"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"}