@codedevin/dify-chat
Version:
A beautiful and configurable chatbot widget for Dify integration with multiple display modes
140 lines (120 loc) • 45.3 kB
JavaScript
(function(l,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("react/jsx-runtime"),require("react"),require("react-dom"),require("clsx"),require("framer-motion"),require("lucide-react"),require("marked"),require("react-markdown"),require("remark-gfm")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react","react-dom","clsx","framer-motion","lucide-react","marked","react-markdown","remark-gfm"],e):(l=typeof globalThis<"u"?globalThis:l||self,e(l.DifyChatTools={},l.React,l.React,l.ReactDOM,l.clsx,l.FramerMotion,l.LucideReact,l.marked,l.ReactMarkdown,l.remarkGfm))})(this,function(l,e,o,Ae,V,q,$,De,xe,ve){"use strict";var Ze=Object.defineProperty;var Re=(l,e,o)=>e in l?Ze(l,e,{enumerable:!0,configurable:!0,writable:!0,value:o}):l[e]=o;var fe=(l,e,o)=>Re(l,typeof e!="symbol"?e+"":e,o);class we{constructor(s){fe(this,"config");fe(this,"conversationId",null);fe(this,"currentTaskId",null);this.config=s}getHeaders(){return{Authorization:`Bearer ${this.config.apiKey}`,"Content-Type":"application/json"}}setConversationId(s){this.conversationId=s}getConversationId(){return this.conversationId}async sendMessage(s,r){const a={inputs:this.config.inputs||{},query:s,user:this.config.userId||"anonymous",conversation_id:this.conversationId,response_mode:"blocking",files:(r==null?void 0:r.map(g=>({type:g.type,transfer_method:g.id?"local_file":"remote_url",upload_file_id:g.id,url:g.url})))||[]},n=await fetch(`${this.config.baseUrl}/chat-messages`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(a)});if(!n.ok){const g=await n.json().catch(()=>({message:"Request failed"}));throw new Error(g.message||"Failed to send message")}const d=await n.json();return d.conversation_id&&!this.conversationId&&(this.conversationId=d.conversation_id),d}async sendMessageStream(s,r,a){var _;const n={inputs:this.config.inputs||{},query:s,user:this.config.userId||"anonymous",conversation_id:this.conversationId,response_mode:"streaming",files:(r==null?void 0:r.map(m=>({type:m.type,transfer_method:m.id?"local_file":"remote_url",upload_file_id:m.id,url:m.url})))||[]},d=await fetch(`${this.config.baseUrl}/chat-messages`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(n)});if(!d.ok){const m=await d.json().catch(()=>({message:"Request failed"}));throw new Error(m.message||"Failed to send message")}const g=(_=d.body)==null?void 0:_.getReader();if(!g)throw new Error("Failed to get response stream");const b=new TextDecoder;let F="";try{for(;;){const{done:m,value:C}=await g.read();if(m)break;F+=b.decode(C,{stream:!0});const T=F.split(`
`);F=T.pop()||"";for(const P of T)if(P.trim()!==""){if(P.startsWith("data: ")){const E=P.slice(6).trim();if(E==="[DONE]")break;try{const v=JSON.parse(E);v.conversation_id&&!this.conversationId&&(this.conversationId=v.conversation_id),v.task_id&&(this.currentTaskId=v.task_id),a==null||a(v)}catch{}}else if(P.startsWith("event: "))continue}}}finally{g.releaseLock()}}async uploadFile(s){const r=new FormData;r.append("file",s),r.append("user",this.config.userId||"anonymous");const a=await fetch(`${this.config.baseUrl}/files/upload`,{method:"POST",headers:{Authorization:`Bearer ${this.config.apiKey}`},body:r});if(!a.ok){const d=await a.json().catch(()=>({message:"Upload failed"}));throw new Error(d.message||"Failed to upload file")}return{id:(await a.json()).id,type:this.getFileType(s.type),name:s.name,size:s.size}}getFileType(s){return s.startsWith("image/")?"image":s.startsWith("audio/")?"audio":s.startsWith("video/")?"video":"document"}async stopMessage(){if(!this.currentTaskId)throw new Error("No active task to stop");const s={user:this.config.userId||"anonymous"},r=await fetch(`${this.config.baseUrl}/chat-messages/${this.currentTaskId}/stop`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(s)});if(!r.ok){const a=await r.json().catch(()=>({message:"Failed to stop message"}));throw new Error(a.message||"Failed to stop message")}this.currentTaskId=null}getCurrentTaskId(){return this.currentTaskId}resetConversation(){this.conversationId=null,this.currentTaskId=null}}const ke=({config:t,onMessage:s,onError:r,enableStreaming:a=!0})=>{const[n,d]=o.useState([]),[g,b]=o.useState(!1),[F,_]=o.useState(null),[m,C]=o.useState(!1),T=o.useRef(new we(t)),P=()=>Math.random().toString(36).substring(2,15),E=y=>{try{const p=y.match(/'error':\s*\{\s*'message':\s*"([^"]+)"/);if(p&&p[1])return p[1];const w=y.match(/"message":\s*"([^"]+)"/);return w&&w[1]?w[1]:y}catch{return y}},v=o.useCallback(y=>{d(p=>[...p,y]),s==null||s(y)},[s]),I=o.useCallback(y=>{d(p=>{const w=[...p],f=w[w.length-1];if(f&&f.role==="assistant"){const h={...f,content:y,timestamp:Date.now()};w[w.length-1]=h,s==null||s(h)}return w})},[s]),L=o.useCallback(async(y,p)=>{if(!y.trim()&&!(p!=null&&p.length))return;_(null),b(!0);const w={id:P(),role:"user",content:y.trim(),timestamp:Date.now(),attachments:p};v(w);try{if(a){let f="",h=!1;await T.current.sendMessageStream(y,p,c=>{var k;switch(c.event){case"message":if(c.answer){if(!h){const W={id:P(),role:"assistant",content:"",timestamp:Date.now()};v(W),h=!0}f+=c.answer,I(f)}break;case"agent_message":if(c.answer){if(!h){const W={id:P(),role:"assistant",content:"",timestamp:Date.now()};v(W),h=!0}f+=c.answer,I(f)}break;case"message_end":(k=c.metadata)!=null&&k.usage;break;case"workflow_started":break;case"workflow_finished":break;case"node_started":break;case"node_finished":break;case"error":b(!1);const x=E(c.message||"Stream error occurred"),S=new Error(x);throw _(S),r==null||r(S),S;default:break}}),b(!1)}else{const f=await T.current.sendMessage(y,p),h={id:P(),role:"assistant",content:f.answer,timestamp:Date.now()};v(h),b(!1)}}catch(f){const h=f instanceof Error?f:new Error("Unknown error");_(h),r==null||r(h),b(!1),d(c=>{const k=c[c.length-1];return k&&k.role==="assistant"&&!k.content.trim()?c.slice(0,-1):c})}},[a,v,I,r]),j=o.useCallback(async y=>{try{return await T.current.uploadFile(y)}catch(p){const w=p instanceof Error?p:new Error("Upload failed");throw _(w),r==null||r(w),w}},[r]),z=o.useCallback(()=>{d([]),_(null)},[]),M=o.useCallback(()=>{T.current.resetConversation(),z()},[z]),H=o.useCallback(async()=>{if(!(!g||m)){C(!0);try{await T.current.stopMessage(),b(!1)}catch(y){const p=y instanceof Error?y:new Error("Failed to stop message");_(p),r==null||r(p)}finally{C(!1)}}},[g,m,r]);return{messages:n,isLoading:g,error:F,isStopping:m,sendMessage:L,stopMessage:H,uploadFile:j,clearMessages:z,resetConversation:M}},ue=({size:t=16,className:s=""})=>e.jsx("svg",{width:t,height:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:s,children:e.jsx("path",{d:"M9.813 15.904L9 18.75l-.813-2.846a4.5 4.5 0 00-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 003.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 003.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 00-3.09 3.09zM18.259 8.715L18 9.75l-.259-1.035a3.375 3.375 0 00-2.455-2.456L14.25 6l1.036-.259a3.375 3.375 0 002.455-2.456L18 2.25l.259 1.035a3.375 3.375 0 002.456 2.456L21.75 6l-1.035.259a3.375 3.375 0 00-2.456 2.456zM16.894 20.567L16.5 22.5l-.394-1.933a2.25 2.25 0 00-1.423-1.423L12.75 18.75l1.933-.394a2.25 2.25 0 001.423-1.423L16.5 15l.394 1.933a2.25 2.25 0 001.423 1.423l1.933.394-1.933.394a2.25 2.25 0 00-1.423 1.423z",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})});function G(...t){return V.clsx(t)}const Ne=({className:t})=>e.jsxs("svg",{className:t,width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2"}),e.jsx("path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"})]}),Me=({className:t})=>e.jsx("svg",{className:t,width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:e.jsx("path",{d:"M20 6 9 17l-5-5"})}),ae=t=>typeof t=="string"?t:Array.isArray(t)?t.map(ae).join(""):o.isValidElement(t)?ae(t.props.children):"",Ce=o.memo(({children:t,className:s,language:r,...a})=>{const[n,d]=o.useState(null),[g,b]=o.useState(!1),F=ae(t),_=async()=>{try{await navigator.clipboard.writeText(F),b(!0),setTimeout(()=>b(!1),2e3)}catch(C){console.error("Failed to copy code:",C)}};o.useEffect(()=>{(async()=>{try{const{codeToTokens:T,bundledLanguages:P}=await import("shiki"),E=ae(t);if(!(r in P)){d(e.jsx("pre",{...a,className:G("my-0 overflow-x-auto w-full rounded-b-xl bg-[#f9f9f9] text-zinc-900 dark:bg-zinc-950 dark:text-zinc-50 border-0 p-4",s),children:e.jsx("code",{className:"whitespace-pre-wrap",children:t})}));return}const{tokens:v}=await T(E,{lang:r,themes:{light:"github-light",dark:"github-dark"}});d(e.jsx("pre",{...a,className:G("my-0 overflow-x-auto w-full rounded-b-xl bg-[#f9f9f9] text-zinc-900 dark:bg-zinc-950 dark:text-zinc-50 border-0 p-4",s),children:e.jsx("code",{className:"whitespace-pre-wrap",children:v.map((I,L)=>e.jsxs("span",{children:[I.map((j,z)=>{const M=typeof j.htmlStyle=="string"?void 0:j.htmlStyle;return e.jsx("span",{style:M,children:j.content},`token-${z}`)}),L!==v.length-1&&`
`]},`line-${L}`))})}))}catch(T){console.error("Failed to highlight code:",T),d(e.jsx("pre",{...a,className:G("my-0 overflow-x-auto w-full rounded-b-xl bg-[#f9f9f9] text-zinc-900 dark:bg-zinc-950 dark:text-zinc-50 border-0 p-4",s),children:e.jsx("code",{className:"whitespace-pre-wrap",children:t})}))}})()},[t,r]);const m=e.jsx("pre",{...a,className:G("my-0 overflow-x-auto w-full rounded-b-xl bg-[#f9f9f9] text-zinc-900 dark:bg-zinc-950 dark:text-zinc-50 border-0 p-4",s),children:e.jsx("code",{className:"whitespace-pre-wrap",children:t})});return e.jsxs("div",{className:"relative group my-4 w-full",children:[e.jsxs("div",{className:"flex items-center justify-between px-4 py-2 bg-[#f9f9f9] text-zinc-900 dark:bg-zinc-950 dark:text-zinc-50 rounded-t-xl w-full",children:[e.jsx("span",{className:"text-sm text-zinc-600 dark:text-zinc-300 font-medium",children:r}),e.jsx("button",{onClick:_,className:"flex items-center gap-2 px-2 py-1 text-xs text-zinc-500 hover:text-zinc-700 hover:bg-zinc-200 dark:text-zinc-400 dark:hover:text-zinc-200 dark:hover:bg-zinc-800 rounded transition-colors",title:g?"Copied!":"Copy code",children:g?e.jsxs(e.Fragment,{children:[e.jsx(Me,{className:"w-3 h-3"}),"Copied"]}):e.jsxs(e.Fragment,{children:[e.jsx(Ne,{className:"w-3 h-3"}),"Copy"]})})]}),n||m]})});Ce.displayName="HighlightedPre";const Se=({children:t,language:s,className:r,...a})=>e.jsx(o.Suspense,{fallback:e.jsxs("div",{className:"relative group my-4 w-full",children:[e.jsxs("div",{className:"flex items-center justify-between px-4 py-2 bg-[#f9f9f9] text-zinc-900 dark:bg-zinc-950 dark:text-zinc-50 rounded-t-xl w-full",children:[e.jsx("span",{className:"text-sm text-zinc-600 dark:text-zinc-300 font-medium",children:s}),e.jsxs("button",{className:"flex items-center gap-2 px-2 py-1 text-xs text-zinc-500 dark:text-zinc-400 rounded",disabled:!0,children:[e.jsx(Ne,{className:"w-3 h-3"}),"Copy"]})]}),e.jsx("pre",{...a,className:G("my-0 overflow-x-auto w-full rounded-b-xl bg-[#f9f9f9] text-zinc-900 dark:bg-zinc-950 dark:text-zinc-50 border-0 p-4",r),children:e.jsx("code",{className:"whitespace-pre-wrap",children:t})})]}),children:e.jsx(Ce,{language:s,className:r,...a,children:t})});Se.displayName="CodeBlock";const ze={h1:({children:t,...s})=>e.jsx("h1",{className:"mt-2 scroll-m-20 text-4xl font-bold",...s,children:t}),h2:({children:t,...s})=>e.jsx("h2",{className:"mt-8 scroll-m-20 border-b pb-2 text-2xl font-semibold tracking-tight first:mt-0",...s,children:t}),h3:({children:t,...s})=>e.jsx("h3",{className:"mt-4 scroll-m-20 text-xl font-semibold tracking-tight",...s,children:t}),h4:({children:t,...s})=>e.jsx("h4",{className:"mt-4 scroll-m-20 text-lg font-semibold tracking-tight",...s,children:t}),h5:({children:t,...s})=>e.jsx("h5",{className:"mt-4 scroll-m-20 text-lg font-semibold tracking-tight",...s,children:t}),h6:({children:t,...s})=>e.jsx("h6",{className:"mt-4 scroll-m-20 text-base font-semibold tracking-tight",...s,children:t}),p:({children:t,...s})=>e.jsx("p",{className:"leading-6 [&:not(:first-child)]:mt-4",...s,children:t}),strong:({children:t,...s})=>e.jsx("span",{className:"font-semibold",...s,children:t}),a:({children:t,...s})=>e.jsx("a",{className:"font-medium underline underline-offset-4",target:"_blank",rel:"noreferrer",...s,children:t}),ol:({children:t,...s})=>e.jsx("ol",{className:"my-4 ml-6 list-decimal",...s,children:t}),ul:({children:t,...s})=>e.jsx("ul",{className:"my-4 ml-6 list-disc",...s,children:t}),li:({children:t,...s})=>e.jsx("li",{className:"mt-2",...s,children:t}),blockquote:({children:t,...s})=>e.jsx("blockquote",{className:"mt-4 border-l-2 pl-6 italic",...s,children:t}),hr:t=>e.jsx("hr",{className:"my-4 md:my-8",...t}),table:({children:t,...s})=>e.jsx("div",{className:"my-6 w-full overflow-y-auto",children:e.jsx("table",{className:"relative w-full overflow-hidden border-none text-sm",...s,children:t})}),tr:({children:t,...s})=>e.jsx("tr",{className:"last:border-b-none m-0 border-b",...s,children:t}),th:({children:t,...s})=>e.jsx("th",{className:"px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right",...s,children:t}),td:({children:t,...s})=>e.jsx("td",{className:"px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right",...s,children:t}),img:({alt:t,...s})=>e.jsx("img",{className:"rounded-md",alt:t,...s}),code:({children:t,node:s,className:r,...a})=>{const n=/language-(\w+)/.exec(r||"");return n?e.jsx(Se,{language:n[1],className:r,...a,children:t}):e.jsx("code",{className:G("rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm",r),...a,children:t})},pre:({children:t})=>e.jsx(e.Fragment,{children:t})};function Le(t){return t?De.marked.lexer(t).map(r=>r.raw):[]}const Te=o.memo(({content:t,className:s})=>e.jsx("div",{className:s,children:e.jsx(xe,{remarkPlugins:[ve],components:ze,children:t})}),(t,s)=>t.content===s.content);Te.displayName="MemoizedMarkdownBlock";const je=o.memo(({content:t,id:s,className:r})=>o.useMemo(()=>Le(t||""),[t]).map((n,d)=>e.jsx(Te,{content:n,className:r},`${s}-block_${d}`)));je.displayName="MarkdownContent";const Be=({children:t})=>e.jsx("div",{className:"markdown-content",children:e.jsx(xe,{remarkPlugins:[ve],components:ze,children:t})}),Pe=({message:t,showAvatar:s=!0,assistantAvatar:r,userAvatar:a})=>{const[n,d]=o.useState(!1),g=async()=>{try{await navigator.clipboard.writeText(t.content),d(!0),setTimeout(()=>d(!1),2e3)}catch{}};return e.jsx(q.AnimatePresence,{children:e.jsx(q.motion.div,{"data-testid":`message-${t.role}`,className:"w-full mx-auto max-w-3xl px-4 group/message",initial:{y:5,opacity:0},animate:{y:0,opacity:1},"data-role":t.role,children:e.jsxs("div",{className:V.clsx("flex gap-4 w-full group-data-[role=user]/message:ml-auto group-data-[role=user]/message:max-w-2xl",{"group-data-[role=user]/message:w-fit":!0}),children:[t.role==="assistant"&&s&&e.jsx("div",{className:"size-8 flex items-center rounded-full justify-center ring-1 shrink-0 ring-border bg-background",children:e.jsx("div",{className:"translate-y-px",children:r?e.jsx("img",{src:r,alt:"Assistant",className:"h-4 w-4 rounded-full object-cover"}):e.jsx(ue,{size:14,className:"text-muted-foreground"})})}),e.jsxs("div",{className:"flex flex-col gap-4 w-full",children:[t.attachments&&t.attachments.length>0&&e.jsx("div",{"data-testid":"message-attachments",className:"flex flex-row justify-end gap-2",children:t.attachments.map((b,F)=>e.jsxs("div",{className:"flex items-center gap-2 text-xs bg-muted rounded-lg px-3 py-2",children:[e.jsx("span",{children:"📎"}),e.jsx("span",{className:"truncate max-w-[120px]",children:b.name}),e.jsxs("span",{className:"text-xs opacity-60",children:["(",Math.round(b.size/1024),"KB)"]})]},F))}),e.jsx("div",{className:"flex flex-row gap-2 items-start",children:e.jsx("div",{"data-testid":"message-content",className:V.clsx("flex flex-col gap-4 message-text",{"bg-muted px-3 py-2 rounded-xl":t.role==="user","":t.role==="assistant"}),children:e.jsx(Be,{children:t.content})})}),t.role==="assistant"&&e.jsx("div",{className:"flex flex-row gap-2",children:e.jsx("button",{className:"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border border-input bg-background hover:bg-accent hover:text-accent-foreground py-1 px-2 h-fit text-muted-foreground",onClick:g,title:n?"Copied!":"Copy message","data-state":"closed",children:n?e.jsx($.Check,{className:"h-4 w-4 "}):e.jsx($.Clipboard,{className:"h-4 w-4"})})})]})]})})})},Ie=({showAvatar:t=!0,assistantAvatar:s})=>e.jsx(q.motion.div,{"data-testid":"message-assistant-loading",className:"w-full mx-auto max-w-3xl px-4 group/message",initial:{y:5,opacity:0},animate:{y:0,opacity:1,transition:{delay:.5}},"data-role":"assistant",children:e.jsxs("div",{className:"flex gap-4 w-full",children:[t&&e.jsx("div",{className:"size-8 flex items-center rounded-full justify-center ring-1 shrink-0 ring-border bg-background",children:e.jsx("div",{className:"translate-y-px",children:s?e.jsx("img",{src:s,alt:"Assistant",className:"h-4 w-4 rounded-full object-cover"}):e.jsx(ue,{size:14,className:" text-muted-foreground"})})}),e.jsx("div",{className:"flex flex-col gap-4 w-full mt-[0.7rem]",children:e.jsx("div",{className:"flex flex-row gap-2 items-center",children:e.jsxs("div",{className:"flex space-x-1 items-center",children:[e.jsx("div",{className:"w-2 h-2 bg-muted-foreground rounded-full animate-pulse"}),e.jsx("div",{className:"w-2 h-2 bg-muted-foreground rounded-full animate-pulse",style:{animationDelay:"0.2s"}}),e.jsx("div",{className:"w-2 h-2 bg-muted-foreground rounded-full animate-pulse",style:{animationDelay:"0.4s"}})]})})})]})}),qe=({size:t=14})=>e.jsx("svg",{width:t,height:t,viewBox:"0 0 24 24",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg",children:e.jsx("rect",{x:"6",y:"6",width:"12",height:"12",rx:"1",ry:"1"})}),Fe=({onSendMessage:t,onUploadFile:s,placeholder:r="Type your message...",disabled:a=!1,allowFileUpload:n=!1,allowedFileTypes:d,maxFileSize:g=15*1024*1024,status:b="ready",onStop:F,autoFocus:_=!1,initialMessage:m="",showResetButton:C=!1,onReset:T})=>{const P=n?d||["image/png","image/jpeg"]:[],[E,v]=o.useState(m),[I,L]=o.useState([]),[j,z]=o.useState(!1),M=o.useRef(null),H=o.useRef(null),y=o.useCallback(async()=>{!E.trim()&&I.length===0||a||b!=="ready"||(t(E.trim(),I),v(""),L([]),H.current&&(H.current.style.height="auto"))},[E,I,a,b,t]),p=c=>{c.key==="Enter"&&!c.shiftKey&&!c.nativeEvent.isComposing&&(c.preventDefault(),b!=="ready"||y())},w=async c=>{const k=Array.from(c.target.files||[]);if(!(!k.length||!s)){z(!0);try{for(const x of k){if(x.size>g)throw new Error(`File ${x.name} is too large. Maximum size is ${Math.round(g/1024/1024)}MB`);if(!P.some(u=>u.startsWith(".")?x.name.toLowerCase().endsWith(u.toLowerCase()):x.type.match(u.replace("*",".*"))))throw new Error(`File type ${x.type} is not allowed`);const W=await s(x);L(u=>[...u,W])}}catch{}finally{z(!1),M.current&&(M.current.value="")}}},f=c=>{L(k=>k.filter((x,S)=>S!==c))},h=c=>{v(c.target.value);const k=c.target;k.style.height="auto",k.style.height=Math.min(k.scrollHeight,120)+"px"};return e.jsxs("div",{className:"relative w-full flex flex-col gap-4",children:[e.jsx("input",{type:"file",className:"fixed -top-4 -left-4 size-0.5 opacity-0 pointer-events-none",ref:M,multiple:!0,accept:P.join(","),onChange:w,tabIndex:-1}),I.length>0&&e.jsx("div",{className:"flex flex-wrap gap-2 px-4",children:I.map((c,k)=>e.jsxs("div",{className:"flex items-center gap-2 bg-muted rounded-lg px-3 py-2 text-sm",children:[e.jsx("span",{children:"📎"}),e.jsx("span",{className:"truncate max-w-[120px]",children:c.name}),e.jsx("button",{onClick:()=>f(k),className:"text-muted-foreground hover:text-foreground",children:e.jsx($.X,{className:"h-3 w-3"})})]},k))}),e.jsxs("div",{className:"relative",children:[e.jsx("textarea",{"data-testid":"multimodal-input",ref:H,placeholder:r,value:E,onChange:h,onKeyDown:p,className:V.clsx("flex w-full border border-input px-3 py-2 ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 min-h-[24px] max-h-[calc(75dvh)] overflow-hidden resize-none rounded-2xl bg-muted pb-10 text-sm text-foreground input-text overflow-y-auto"),rows:2,autoFocus:_,disabled:a}),e.jsxs("div",{className:"absolute bottom-0 p-2 w-fit flex flex-row justify-start gap-1",children:[C&&T&&e.jsx("button",{"data-testid":"reset-button",className:"inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 hover:bg-accent hover:text-accent-foreground py-1 px-2 h-fit text-muted-foreground rounded-md button-text",disabled:b!=="ready"||a,onClick:T,title:"Reset conversation","data-state":"closed",children:e.jsx($.RotateCcw,{size:14})}),n&&s&&e.jsx("button",{"data-testid":"attachments-button",className:"inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 hover:bg-accent hover:text-accent-foreground py-1 px-2 h-fit text-muted-foreground rounded-md rounded-bl-lg button-text",disabled:b!=="ready"||a,onClick:()=>{var c;return(c=M.current)==null?void 0:c.click()},title:"Attach file","data-state":"closed",children:e.jsx($.Paperclip,{size:14,className:"-rotate-45"})})]}),e.jsx("div",{className:"absolute bottom-0 right-0 p-2 w-fit flex flex-row justify-end",children:b==="submitted"||b==="streaming"?e.jsx("button",{"data-testid":"stop-button",className:"inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-primary text-primary-foreground hover:bg-primary/90 rounded-full p-1.5 h-fit border dark:border-zinc-600 button-text",onClick:F,title:"Stop generation","data-state":"closed",children:e.jsx(qe,{size:14})}):e.jsx("button",{"data-testid":"send-button",className:"inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 bg-primary text-primary-foreground hover:bg-primary/90 rounded-full p-1.5 h-fit border dark:border-zinc-600 button-text",onClick:y,disabled:a||!E.trim()&&I.length===0||j,title:"Send message","data-state":"closed",children:e.jsx($.ArrowUp,{size:14})})})]}),j&&e.jsx("div",{className:"px-4 text-sm text-muted-foreground",children:"Uploading files..."})]})},Z=o.forwardRef(({config:t,theme:s,displayMode:r="embedded",placeholder:a="Type your message...",title:n="Chat Assistant",subtitle:d,avatar:g,className:b,style:F,onMessage:_,onError:m,onFullscreenChange:C,maxHeight:T=500,maxWidth:P=400,showHeader:E=!0,showAvatar:v=!0,allowFileUpload:I=!1,allowedFileTypes:L,maxFileSize:j=15*1024*1024,autoFocus:z=!1,disabled:M=!1,initialMessage:H=""},y)=>{var Ee;const p=o.useRef(null),w=o.useRef(null),f=o.useRef(null),h=I?L||["image/png","image/jpeg"]:[],[c,k]=o.useState(!1),[x,S]=o.useState(!1),W=()=>S(i=>!i);o.useEffect(()=>{C==null||C(x)},[x,C]);const{messages:u,isLoading:O,error:J,sendMessage:he,stopMessage:ne,uploadFile:ie,resetConversation:Q}=ke({config:t,onMessage:_,onError:m,enableStreaming:!0}),[Y,ee]=o.useState(0),[te,le]=o.useState(!0);o.useEffect(()=>{const i=f.current;if(!i||!te)return;const D=u.length>Y;(O||D)&&requestAnimationFrame(()=>{i.scrollTop=i.scrollHeight}),ee(u.length)},[u,O,te]),o.useEffect(()=>{const i=f.current;if(!i)return;const D=()=>{const{scrollTop:re,scrollHeight:oe,clientHeight:me}=i,be=oe-re-me<50;k(!be&&u.length>0)};return i.addEventListener("scroll",D,{passive:!0}),()=>i.removeEventListener("scroll",D)},[u.length]);const ce=()=>{const i=f.current;if(!i)return{scrollTop:0,scrollHeight:0,clientHeight:0,isAtTop:!0,isAtBottom:!0,isNearBottom:!0};const{scrollTop:D,scrollHeight:re,clientHeight:oe}=i,me=D===0,be=D+oe>=re,Qe=re-D-oe<50;return{scrollTop:D,scrollHeight:re,clientHeight:oe,isAtTop:me,isAtBottom:be,isNearBottom:Qe}},de=()=>{requestAnimationFrame(()=>{const i=f.current;i&&(i.scrollTop=0)})},se=()=>{requestAnimationFrame(()=>{const i=f.current;i&&(i.scrollTop=i.scrollHeight)})},ge=i=>{requestAnimationFrame(()=>{const D=f.current;D&&(D.scrollTop=i)})},N=i=>{requestAnimationFrame(()=>{const D=f.current;D&&(D.scrollTop+=i)})},A=()=>{le(!0)},U=()=>{le(!1)},K=()=>te;o.useImperativeHandle(y,()=>({getScrollInfo:ce,scrollToTop:de,scrollToBottom:se,scrollTo:ge,scrollBy:N,enableAutoScroll:A,disableAutoScroll:U,isAutoScrollEnabled:K}));const B=(s==null?void 0:s.background)&&(s.background.includes("9%")||s.background.includes("4.9%")||s.background.includes("3.9%"));o.useEffect(()=>{if(w.current){const i=w.current;B?i.classList.add("dark"):i.classList.remove("dark"),s&&(s.primary&&i.style.setProperty("--primary",s.primary),s.secondary&&i.style.setProperty("--secondary",s.secondary),s.background&&i.style.setProperty("--background",s.background),s.text&&i.style.setProperty("--foreground",s.text),s.border&&i.style.setProperty("--border",s.border),s.borderRadius&&i.style.setProperty("--radius",s.borderRadius),s.fontFamily&&(i.style.fontFamily=s.fontFamily))}},[s,B]),o.useEffect(()=>{const i=D=>{D.key==="Escape"&&x&&S(!1)};return document.addEventListener("keydown",i),()=>{document.removeEventListener("keydown",i)}},[x]);const X={...F,...x?{zIndex:999999,width:"100vw",height:"100vh",maxHeight:"none",maxWidth:"none",position:"fixed",top:0,left:0,right:0,bottom:0}:{maxHeight:T,maxWidth:P}},ye=e.jsxs("div",{ref:w,className:V.clsx("dify-chatbot dify-chatbot-container flex flex-col min-w-0 bg-background p-[2px]",{"h-full border border-border rounded-lg":!x&&r==="embedded",dark:B},b),style:X,children:[E&&e.jsxs("div",{className:"flex items-center justify-between p-4 border-b bg-card",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[v&&g&&e.jsx("img",{src:g,alt:"Assistant",className:"h-8 w-8 rounded-full object-cover"}),e.jsxs("div",{children:[e.jsx("h3",{className:"font-semibold text-card-foreground",children:n}),d&&e.jsx("p",{className:"text-sm text-muted-foreground",children:d})]})]}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("button",{onClick:Q,title:"Reset conversation",className:"border border-input bg-background hover:bg-accent hover:text-accent-foreground p-1 rounded-md",children:e.jsx($.RotateCcw,{className:"h-4 w-4"})}),e.jsx("button",{onClick:W,title:x?"Exit fullscreen":"Enter fullscreen",className:"border border-input bg-background hover:bg-accent hover:text-accent-foreground p-1 rounded-md",children:x?e.jsx($.Minimize2,{className:"h-4 w-4"}):e.jsx($.Maximize2,{className:"h-4 w-4"})})]})]}),e.jsxs("div",{ref:f,className:"dify-chatbot-messages flex flex-col min-w-0 gap-6 flex-1 overflow-y-auto pt-4 relative",style:{overscrollBehavior:"contain",touchAction:"pan-y"},children:[u.length===0&&e.jsx("div",{className:"flex-1 flex items-center justify-center",children:e.jsxs("div",{className:"text-center text-muted-foreground",children:[e.jsx("div",{className:"mb-4",children:e.jsx(ue,{size:48,className:"mx-auto text-muted-foreground/30"})}),e.jsx("p",{className:"text-lg font-medium text-foreground",children:"How can I help you today?"}),d&&e.jsx("p",{className:"text-sm mt-2 text-muted-foreground",children:d})]})}),u.map(i=>e.jsx(Pe,{message:i,showAvatar:v,assistantAvatar:g},i.id)),O&&u.length>0&&((Ee=u[u.length-1])==null?void 0:Ee.role)==="user"&&e.jsx(Ie,{showAvatar:v,assistantAvatar:g}),J&&e.jsx("div",{className:"w-full mx-auto max-w-3xl px-4",children:e.jsxs("div",{className:"text-center text-destructive text-sm py-2 bg-destructive/10 rounded-md",children:["Error: ",J.message]})}),e.jsx("div",{ref:p,className:"shrink-0 min-w-[24px] min-h-[24px]"})]}),e.jsx("form",{className:"flex mx-auto px-4 bg-background pb-4 md:pb-6 gap-2 w-full md:max-w-3xl",onSubmit:i=>i.preventDefault(),children:e.jsxs("div",{className:"relative w-full flex flex-col gap-4",children:[c&&e.jsx("div",{className:"absolute left-1/2 bottom-28 -translate-x-1/2 z-50",children:e.jsx("button",{onClick:se,className:"inline-flex items-center justify-center border border-input bg-background hover:bg-accent hover:text-accent-foreground h-8 w-8 rounded-full",children:e.jsx($.ArrowDown,{className:"h-4 w-4"})})}),e.jsx(Fe,{onSendMessage:he,onUploadFile:I?ie:void 0,placeholder:a,disabled:M,allowFileUpload:I,allowedFileTypes:h,maxFileSize:j,autoFocus:z,initialMessage:H,status:O?"streaming":"ready",onStop:ne,showResetButton:!E,onReset:Q})]})})]});return x?Ae.createPortal(ye,document.body):ye});Z.displayName="DifyChatbot";const $e={default:"bg-primary text-primary-foreground hover:bg-primary/90",destructive:"bg-destructive text-destructive-foreground hover:bg-destructive/90",outline:"border border-input bg-background hover:bg-accent hover:text-accent-foreground",secondary:"bg-secondary text-secondary-foreground hover:bg-secondary/80",ghost:"hover:bg-accent hover:text-accent-foreground",link:"text-primary underline-offset-4 hover:underline"},He={default:"h-10 px-4 py-2",sm:"h-9 rounded-md px-3",lg:"h-11 rounded-md px-8",icon:"h-10 w-10"},pe=o.forwardRef(({className:t,variant:s="default",size:r="default",...a},n)=>e.jsx("button",{className:V.clsx("inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",$e[s],He[r],t),ref:n,...a}));pe.displayName="Button";const Oe=({config:t,theme:s,placeholder:r="Type your message...",title:a="Chat Assistant",subtitle:n,avatar:d,className:g,style:b,onMessage:F,onError:_,maxHeight:m=500,maxWidth:C=400,showHeader:T=!0,showAvatar:P=!0,allowFileUpload:E=!1,allowedFileTypes:v,maxFileSize:I=15*1024*1024,autoFocus:L=!1,disabled:j=!1,position:z="bottom-right",offset:M={x:0,y:0},trigger:H,defaultOpen:y=!1,onOpenChange:p,triggerIcon:w,triggerText:f})=>{const[h,c]=o.useState(y);o.useEffect(()=>{p==null||p(h)},[h,p]);const k=()=>{c(!h)},x=()=>"dify-chatbot dify-floating-chatbot ",S=()=>{const u=M.x,O=M.y;switch(z){case"bottom-right":return{bottom:20+O,right:20+u,zIndex:999999999,position:"fixed"};case"bottom-left":return{bottom:20+O,left:20+u,zIndex:999999999,position:"fixed"};case"top-right":return{top:20+O,right:20+u,zIndex:999999999,position:"fixed"};case"top-left":return{top:20+O,left:20+u,zIndex:999999999,position:"fixed"};default:return{bottom:20,right:20,zIndex:999999999,position:"fixed"}}},W=()=>{switch(z){case"bottom-right":case"bottom-left":return{y:20,opacity:0};case"top-right":case"top-left":return{y:-20,opacity:0};default:return{y:20,opacity:0}}};return e.jsxs("div",{className:x(),style:S(),children:[e.jsx(q.AnimatePresence,{children:h&&e.jsx(q.motion.div,{initial:W(),animate:{y:0,opacity:1},exit:W(),transition:{duration:.2,ease:"easeOut"},className:V.clsx("mb-4",z.includes("top")&&"mb-0 mt-4"),style:{width:C,height:m},children:e.jsx(Z,{config:t,theme:s,displayMode:"embedded",placeholder:r,title:a,subtitle:n,avatar:d,className:g,style:b,onMessage:F,onError:_,maxHeight:m,maxWidth:C,showHeader:T,showAvatar:P,allowFileUpload:E,allowedFileTypes:v,maxFileSize:I,autoFocus:L,disabled:j,preventExternalScroll:!0})})}),e.jsx(q.motion.div,{whileHover:{scale:1.05},whileTap:{scale:.95},children:H?e.jsx("div",{onClick:k,className:"cursor-pointer",children:H}):e.jsx(pe,{onClick:k,size:f?"default":"icon",className:V.clsx(f?"h-auto px-4 py-2 rounded-full shadow-lg":"h-10 w-10 rounded-full shadow-lg","bg-primary hover:bg-primary/90 text-primary-foreground","transition-all duration-200"),title:h?"Close chat":"Open chat",children:e.jsx(q.AnimatePresence,{mode:"wait",children:h?e.jsxs(q.motion.div,{initial:{rotate:-90,opacity:0},animate:{rotate:0,opacity:1},exit:{rotate:90,opacity:0},transition:{duration:.15},className:f?"flex items-center gap-2":"",children:[e.jsx($.X,{className:"h-5 w-5"}),f&&e.jsx("span",{className:"text-sm font-medium",children:"Close"})]},"close"):e.jsxs(q.motion.div,{initial:{rotate:90,opacity:0},animate:{rotate:0,opacity:1},exit:{rotate:-90,opacity:0},transition:{duration:.15},className:f?"flex items-center gap-2":"",children:[w||e.jsx($.MessageCircle,{className:"h-6 w-6"}),f&&e.jsx("span",{className:"text-sm font-medium",children:f})]},"open")})})})]})},Ue=({config:t,theme:s,placeholder:r="Ask about the selected text...",title:a="Chat Assistant",subtitle:n,avatar:d,className:g,style:b,onMessage:F,onError:_,maxHeight:m=400,maxWidth:C=350,showHeader:T=!0,showAvatar:P=!0,allowFileUpload:E=!1,allowedFileTypes:v=[],maxFileSize:I=15*1024*1024,autoFocus:L=!0,disabled:j=!1,enabled:z=!0,minSelectionLength:M=3,maxSelectionLength:H=1e3,onSelectionChange:y,targetAttribute:p,triggerIcon:w,triggerText:f="Ask AI"})=>{const[h,c]=o.useState(""),[k,x]=o.useState(!1),[S,W]=o.useState({x:0,y:0,width:0,height:0}),[u,O]=o.useState(!1),[J,he]=o.useState(!1),[ne,ie]=o.useState(!1);o.useEffect(()=>{},[u]);const Q=o.useRef(null),Y=o.useCallback(()=>{z&&setTimeout(()=>{const N=window.getSelection(),A=(N==null?void 0:N.toString().trim())||"";if(A.length>=M&&A.length<=H){const U=N==null?void 0:N.getRangeAt(0);if(U){if(p){const B=U.commonAncestorContainer,X=B.nodeType===Node.TEXT_NODE?B.parentElement:B;if(!(X==null?void 0:X.closest(`[${p}]`))){x(!1),c("");return}}const K=U.getBoundingClientRect();W({x:K.left+K.width/2,y:K.top,width:K.width,height:K.height}),c(A),x(!0),y==null||y(A)}}else x(!1),c("")},10)},[z,M,H,y,p,u]),ee=o.useCallback(N=>{const A=N.target;J||ne||Q.current&&Q.current.contains(A)||A!=null&&A.closest('[data-testid="ask-ai-button"]')||(x(!1),O(!1))},[J,ne]),te=o.useCallback(N=>{ie(!0),he(N),!N&&!u&&O(!0),setTimeout(()=>{ie(!1)},100)},[u]);o.useEffect(()=>{if(z&&!u)return document.addEventListener("selectionchange",Y),document.addEventListener("mouseup",Y),()=>{document.removeEventListener("selectionchange",Y),document.removeEventListener("mouseup",Y)}},[z,Y,u]),o.useEffect(()=>{if(z)return document.addEventListener("click",ee),()=>{document.removeEventListener("click",ee)}},[z,ee]);const le=N=>{N.preventDefault(),N.stopPropagation(),setTimeout(()=>{O(!0)},0)},ce=()=>{const N=window.innerWidth,A=window.innerHeight,U=20;let K=S.x-C/2,B=S.y+S.height+10;if(K=Math.max(U,Math.min(K,N-C-U)),B+m>A-U){const X=S.y-m-10;X>=U?B=X:B=Math.max(U,(A-m)/2)}return B=Math.max(U,Math.min(B,A-m-U)),{x:K,y:B}},[de,se]=o.useState({x:0,y:0});o.useEffect(()=>{if(u&&S){const N=ce();se(N)}},[u,S,C,m]),o.useEffect(()=>{const N=()=>{if(u&&S){const A=ce();se(A)}};return window.addEventListener("resize",N),()=>window.removeEventListener("resize",N)},[u,S,C,m]);const ge=N=>{const A={...N,context:h};F==null||F(A)};return z?e.jsxs("div",{className:"dify-chatbot dify-text-selection-chatbot",children:[e.jsx(q.AnimatePresence,{children:k&&!u&&e.jsx(q.motion.div,{initial:{opacity:0,scale:.8,y:-10},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.8,y:-10},transition:{duration:.15},className:"fixed pointer-events-none",style:{left:S.x-25,top:S.y+S.height+5},children:e.jsxs("button",{onClick:le,className:"inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 bg-primary text-primary-foreground hover:bg-primary/90 rounded-md py-2 px-4 h-fit pointer-events-auto shadow-lg",title:"Ask about selected text","data-testid":"ask-ai-button","data-state":"closed",children:[w||e.jsx($.MessageCircle,{className:"h-4 w-4"}),e.jsx("span",{className:"text-xs",children:f})]})})}),e.jsx(q.AnimatePresence,{children:(u||J)&&e.jsx(q.motion.div,{ref:Q,initial:{opacity:0,scale:.9,y:10},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.9,y:10},transition:{duration:.2},className:V.clsx("dify-chatbot",{"fixed shadow-xl":!J}),style:J?{zIndex:999999}:{left:de.x,top:de.y,width:C,height:m,zIndex:999999},children:e.jsx("div",{className:"relative h-full",children:e.jsx("div",{className:V.clsx("h-full"),children:e.jsx(Z,{config:{...t,inputs:{...t.inputs,selected_text:h}},theme:s,displayMode:"embedded",placeholder:`Ask about: "${h==null?void 0:h.substring(0,50)}${h&&h.length>50?"...":""}"`,title:a,subtitle:n,avatar:d,className:g,style:b,onMessage:ge,onError:_,maxHeight:J?void 0:m,maxWidth:J?void 0:C,showHeader:T,showAvatar:P,allowFileUpload:E,allowedFileTypes:v,maxFileSize:I,autoFocus:L,disabled:j,initialMessage:`Please explain this text: "${h}"`,onFullscreenChange:te})})})})})]}):null},R={primary:"221.2 83.2% 53.3%",secondary:"210 40% 96%",background:"0 0% 100%",text:"222.2 84% 4.9%",border:"214.3 31.8% 91.4%",borderRadius:"0.5rem",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif'},_e={primary:"210 100% 70%",secondary:"215 25% 15%",background:"220 13% 9%",text:"210 40% 98%",border:"215 25% 20%",borderRadius:"0.5rem",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif'},We=R,Ke={light:R,dark:_e},Ve=({theme:t,container:s}={})=>{const r=o.useRef(null);return o.useEffect(()=>{const a=s||r.current;if(!a)return;const n={...R,...t};return n.primary&&a.style.setProperty("--primary",n.primary),n.secondary&&a.style.setProperty("--secondary",n.secondary),n.background&&a.style.setProperty("--background",n.background),n.text&&a.style.setProperty("--foreground",n.text),n.border&&a.style.setProperty("--border",n.border),n.borderRadius&&a.style.setProperty("--radius",n.borderRadius),n.fontFamily&&(a.style.fontFamily=n.fontFamily),()=>{a&&(a.style.removeProperty("--primary"),a.style.removeProperty("--secondary"),a.style.removeProperty("--background"),a.style.removeProperty("--foreground"),a.style.removeProperty("--border"),a.style.removeProperty("--radius"),a.style.removeProperty("font-family"))}},[t,s]),r},Je=(t,s)=>{const r={...R,...s};r.primary&&t.style.setProperty("--primary",r.primary),r.secondary&&t.style.setProperty("--secondary",r.secondary),r.background&&t.style.setProperty("--background",r.background),r.text&&t.style.setProperty("--foreground",r.text),r.border&&t.style.setProperty("--border",r.border),r.borderRadius&&t.style.setProperty("--radius",r.borderRadius),r.fontFamily&&(t.style.fontFamily=r.fontFamily)},Xe=t=>{t.style.removeProperty("--primary"),t.style.removeProperty("--secondary"),t.style.removeProperty("--background"),t.style.removeProperty("--foreground"),t.style.removeProperty("--border"),t.style.removeProperty("--radius"),t.style.removeProperty("font-family")},Ye=t=>{const{config:s,theme:r,container:a}=t;if(!s.apiKey)throw new Error("Dify API key is required");if(!s.baseUrl)throw new Error("Dify base URL is required");if(!document.getElementById("dify-chat-tools-styles")){const n=document.createElement("style");n.id="dify-chat-tools-styles",n.textContent=`
/* Dify Chat Tools Global Styles */
.dify-chatbot {
font-family: Arial,Helvetica,sans-serif, 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.dify-chatbot-container {
/* 完整的 pfchat CSS 变量定义 - 与 globals.css 保持一致 */
--pfchat-background: 0 0% 100%;
--pfchat-foreground: 240 10% 3.9%;
--pfchat-card: 0 0% 100%;
--pfchat-card-foreground: 240 10% 3.9%;
--pfchat-popover: 0 0% 100%;
--pfchat-popover-foreground: 240 10% 3.9%;
--pfchat-primary: 240 5.9% 10%;
--pfchat-primary-foreground: 0 0% 98%;
--pfchat-secondary: 240 4.8% 95.9%;
--pfchat-secondary-foreground: 240 5.9% 10%;
--pfchat-muted: 240 4.8% 95.9%;
--pfchat-muted-foreground: 240 3.8% 46.1%;
--pfchat-accent: 240 4.8% 95.9%;
--pfchat-accent-foreground: 240 5.9% 10%;
--pfchat-destructive: 0 84.2% 60.2%;
--pfchat-destructive-foreground: 0 0% 98%;
--pfchat-border: 240 5.9% 90%;
--pfchat-input: 240 5.9% 90%;
--pfchat-ring: 240 10% 3.9%;
--pfchat-radius: 0.75rem;
}
.dify-chatbot-container.dark {
/* 暗色主题的 pfchat CSS 变量定义 */
--pfchat-background: 220 13% 9%;
--pfchat-foreground: 210 40% 98%;
--pfchat-card: 220 13% 9%;
--pfchat-card-foreground: 210 40% 98%;
--pfchat-popover: 220 13% 9%;
--pfchat-popover-foreground: 210 40% 98%;
--pfchat-primary: 210 100% 70%;
--pfchat-primary-foreground: 220 13% 9%;
--pfchat-secondary: 215 25% 15%;
--pfchat-secondary-foreground: 210 40% 98%;
--pfchat-muted: 215 25% 15%;
--pfchat-muted-foreground: 215 20% 65%;
--pfchat-accent: 215 25% 15%;
--pfchat-accent-foreground: 210 40% 98%;
--pfchat-destructive: 0 62.8% 30.6%;
--pfchat-destructive-foreground: 210 40% 98%;
--pfchat-border: 215 25% 20%;
--pfchat-input: 215 25% 15%;
--pfchat-ring: 210 100% 70%;
}
.dify-chatbot-messages {
scrollbar-width: thin;
scrollbar-color: hsl(var(--pfchat-muted)) transparent;
}
.dify-chatbot-messages::-webkit-scrollbar {
width: 6px;
}
.dify-chatbot-messages::-webkit-scrollbar-track {
background: transparent;
}
.dify-chatbot-messages::-webkit-scrollbar-thumb {
background-color: hsl(var(--pfchat-muted));
border-radius: 3px;
}
.dify-chatbot-messages::-webkit-scrollbar-thumb:hover {
background-color: hsl(var(--pfchat-muted-foreground));
}
@keyframes dify-fade-in {
from { opacity: 0; transform: scale(0.95); }
to { opacity: 1; transform: scale(1); }
}
@keyframes dify-slide-up {
from { transform: translateY(100%); }
to { transform: translateY(0); }
}
@keyframes dify-typing {
0%, 60% { opacity: 1; }
30% { opacity: 0.5; }
}
.dify-fade-in {
animation: dify-fade-in 0.2s ease-out;
}
.dify-slide-up {
animation: dify-slide-up 0.3s ease-out;
}
.dify-typing {
animation: dify-typing 1.5s ease-in-out infinite;
}
.dify-text-selection {
background-color: rgba(59, 130, 246, 0.2);
border-radius: 2px;
padding: 1px 2px;
}
.dify-floating-chatbot {
position: fixed;
z-index: 9999;
}
.dify-floating-chatbot.bottom-right {
bottom: 20px;
right: 20px;
}
.dify-floating-chatbot.bottom-left {
bottom: 20px;
left: 20px;
}
.dify-floating-chatbot.top-right {
top: 20px;
right: 20px;
}
.dify-floating-chatbot.top-left {
top: 20px;
left: 20px;
}
`,document.head.appendChild(n)}if(r&&a){const n=typeof a=="string"?document.querySelector(a):a;n&&(r.primary&&n.style.setProperty("--pfchat-primary",r.primary),r.secondary&&n.style.setProperty("--pfchat-secondary",r.secondary),r.background&&n.style.setProperty("--pfchat-background",r.background),r.text&&n.style.setProperty("--pfchat-foreground",r.text),r.border&&n.style.setProperty("--pfchat-border",r.border),r.borderRadius&&n.style.setProperty("--pfchat-radius",r.borderRadius),r.fontFamily&&(n.style.fontFamily=r.fontFamily))}return{config:s,theme:r,container:a}},Ge=()=>{const t=document.getElementById("dify-chat-tools-styles");t&&t.remove()};l.Button=pe,l.ChatInput=Fe,l.DifyApi=we,l.DifyChatbot=Z,l.DifyFloatingChatbot=Oe,l.DifyTextSelectionChatbot=Ue,l.Message=Pe,l.TypingIndicator=Ie,l.applyThemeToElement=Je,l.cleanupDifyChat=Ge,l.darkTheme=_e,l.default=Z,l.defaultTheme=We,l.initDifyChat=Ye,l.lightTheme=R,l.presetThemes=Ke,l.removeThemeFromElement=Xe,l.useDifyChat=ke,l.useTheme=Ve,Object.defineProperties(l,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});