File: /storage/v4513/tepnot/public_html/wp-content/plugins/echo-knowledge-base/js/ai/ai-chat.min.js
(function(){"use strict";const e=window.wp&&window.wp.element;const t=e||window.React;const n=window.ReactDOM;if(!t||!n){window.EPKBChatUtils.logError("AI Chat","React is not available");return}if(!window.EPKBChatAPI||!window.EPKBChatCache||!window.EPKBChatSession||!window.EPKBChatUtils||!window.EPKBChatDisplay){console.error("AI Chat: Required modules not loaded");return}const{useState:s,useEffect:o,useRef:r,createElement:a}=t;const{ChatAPIClient:c}=window.EPKBChatAPI;const{ChatCacheManager:i}=window.EPKBChatCache;const{SessionManager:l}=window.EPKBChatSession;const{isDebugMode:f,createMessage:u,prepareMessage:d,getChatRootElement:g,logError:h,TypingIndicator:m,LoadingSkeleton:p,useFocusTrap:w}=window.EPKBChatUtils;const{darkenColor:_,createMessageComponent:b,renderChatWidget:C}=window.EPKBChatDisplay;const I=m(t);const y=p(t);const k=w(t);const v=b(t);function x(e){if(!e||!e.length){return""}const t=window.epkbAIChat||{};const n=t.sources_label||"Sources";let s='<div class="epkb-ai-chat-sources">';s+='<div class="epkb-ai-chat-sources__label">'+n+"</div>";s+='<ul class="epkb-ai-chat-sources__list">';e.forEach((function(e){s+='<li class="epkb-ai-chat-sources__item">';s+='<a href="'+e.url+'" target="_blank" rel="noopener noreferrer">';s+=e.title;s+="</a>";s+="</li>"}));s+="</ul>";s+="</div>";return s}function E(e){if(!e||typeof e!=="string"){return[]}return e.split(/[\n,]+/).map((e=>e.trim().toLowerCase())).filter(Boolean)}function M(e,t){if(!e||!t||t.length===0){return false}const n=e.toLowerCase();return t.some((e=>n.includes(e)))}function P(){const e=window.epkbAIChat||{};const n=e.welcome_message||"Hello! How can I help you today?";const a=e.handoff_enabled==="on";const m=e.handoff_method||"email";const p=e.handoff_button_display||"always";const w=e.handoff_button_text||"Contact an Agent";const b=E(e.handoff_keywords||"");const P=e.handoff_consent_text||"";const S=e.handoff_intro_message||"Connecting you with a human agent now. Please provide your details below.";const A=e.handoff_success_message||"Thanks! Our team will reach out via email shortly.";const T=e.handoff_error_message||"Unable to submit your request. Please try again.";const B=e.handoff_i18n||{};const R=e.feedback_i18n||{};const U=e.feedback_enabled!=="off";const F=e.feedback_with_handoff!=="off";const D=R.thanks_message||"Thanks for your feedback!";const K=R.try_different||"Try a different approach";const H=R.talk_to_human||"Talk to a human";const L=R.choice_prompt||"";const q=R.clarify_prompt||"Could you tell me more about what you're looking for?";const $=[D,K,H,L,q].map((e=>typeof e==="string"?e.trim():"")).filter(Boolean);const N=e.widget_header_background_color||"#0073aa";const O=e.user_message_background_color||"#E8F4FF";const W=e.ai_message_background_color||"#F3F4F6";const j={launcher:e.launcher_background_color||"#0073aa",header:N,headerGradient:`linear-gradient(135deg, ${N} 0%, ${_(N,20)} 100%)`,sendButton:e.send_button_background_color||"#0066cc",newButton:e.new_button_background_color||"#3B88C3",userMessage:O,userMessageGradient:`linear-gradient(135deg, ${O} 0%, ${_(O,6)} 100%)`,aiMessage:W,aiMessageGradient:`linear-gradient(135deg, ${W} 0%, ${_(W,5)} 100%)`};const V={generic:e.error_generic_message||"Sorry, something went wrong. Please try again.",network:e.error_network_message||"Connection error. Please check your internet and try again.",timeout:e.error_timeout_message||"The request timed out. Please try again.",rateLimit:e.error_rate_limit_message||"Too many requests. Please wait a moment and try again."};const G=g();const J=G&&G.getAttribute("data-is-admin")==="true";const Y=G&&G.getAttribute("data-collection-id");const z=window.epkbChatCollectionInfo||{};const Q=z.configuration_error||null;const X=f();const Z=J||X;if(X&&!J){console.log("EPKB AI Chat: Debug mode enabled. Technical messages will be shown.");console.log("To disable debug mode, run: epkbEnableDebug(false)")}const ee=r(new i);const te=r(new l({rest_nonce:e.rest_nonce,isAdmin:J,debugMode:X}));const ne=r(new c({rest_url:e.rest_url,rest_nonce:te.current.getNonce(),isAdmin:J,debugMode:X}));o((()=>{te.current.setApiClient(ne.current)}),[]);const[se,oe]=s(false);const[re,ae]=s((()=>localStorage.getItem("epkb-chat-expanded")==="true"));const[ce,ie]=s([u(n,false)]);const[le,fe]=s("");const[ue,de]=s(false);const[ge,he]=s("");const[me,pe]=s(false);const[we,_e]=s(false);const[be,Ce]=s(false);const[Ie,ye]=s(false);const[ke,ve]=s(false);const[xe,Ee]=s(false);const[Me,Pe]=s({first_name:"",email:"",message:""});const[Se,Ae]=s({});const[Te,Be]=s("");const[Re,Ue]=s({messageId:"",vote:"",action:""});const[Fe,De]=s("");const Ke=r(false);const He=r(false);const Le=r("");const qe=r(false);const $e=r({active:false,submitted:false});const Ne=r(null);const Oe=r(false);const We=r(null);const je=r(null);const Ve=r(null);o((()=>{te.current.onNonceUpdate((e=>{ne.current.setNonce(e)}));return()=>{te.current.cleanup()}}),[]);o((()=>{Le.current=Fe}),[Fe]);o((()=>{$e.current={active:Ie,submitted:ke}}),[Ie,ke]);o((()=>{localStorage.setItem("epkb-chat-expanded",re?"true":"false")}),[re]);o((()=>{async function e(){const e=ee.current.loadChatId();if(e){const t=ee.current.loadMessages(e);if(t&&t.length>0){const n=t.map((e=>u(e.content,e.role==="user",e.id)));ie(n);De(e);pe(true);if(Z){console.log(`Loaded ${n.length} messages from cache instantly!`)}return}return}}e()}),[]);o((()=>{if(!se||He.current)return;He.current=true;async function e(){const e=await te.current.startSession();if(!e.success&&Z){h("AI Chat","Failed to establish session on chat open",{errorInfo:e.errorInfo})}if(!me){const e=ee.current.loadChatId();if(e&&ce.length===1){const t=await ne.current.getConversation(e);if(t.success&&t.data){if(t.data.chat_id){De(t.data.chat_id);ee.current.saveChatId(t.data.chat_id)}if(t.data.messages&&t.data.messages.length>0){const e=t.data.messages.map((e=>u(e.content,e.role==="user",e.id)));ie(e);const n=t.data.messages.map((e=>({id:e.id,content:e.content,role:e.role})));ee.current.saveMessages(t.data.chat_id,n);if(Z){console.log(`Loaded ${e.length} messages from server on chat open`)}}}else if(!t.success&&t.errorInfo){const s=t.errorInfo;if(te.current.isSessionError(s)){if(Z){console.log("Authentication error on conversation load, starting fresh")}ee.current.clearChatId();ee.current.clearMessageCache(e);De("");ie([u(n,false)])}}}pe(true)}}e()}),[se,Z]);o((()=>{if(je.current){je.current.scrollIntoView({behavior:"smooth"})}}),[ce,ue]);k(We,se,(()=>oe(false)));o((()=>{if(se){Oe.current=true;if(Ve.current){Ve.current.focus()}}else if(Oe.current){if(Ne.current){Ne.current.focus()}}}),[se]);o((()=>()=>{Ke.current=false;ne.current.clearRetries()}),[]);o((()=>{if(Fe&&ce.length>1){const e=ce.map((e=>({id:e.messageId,content:e.text,role:e.isUser?"user":"assistant"})));ee.current.saveMessages(Fe,e)}}),[Fe,ce]);function Ge(){de(false);Ke.current=false;Ce(false)}function Je(e){te.current.handleNewToken(e)}async function Ye(e=false){return await te.current.refreshNonce(e)}async function ze(t,n,s=0){if(s>2){Ge();he("Unable to establish session. Please refresh the page.");return{success:false}}const o=Fe;if(o&&!o.startsWith("chat_")){if(Z){console.warn("Invalid chat ID format:",o)}De("");ee.current.clearChatId()}const r=qe.current;if(r){qe.current=false;if(Z){console.log("Forcing new conversation for this message")}}const a=await ne.current.sendMessageWithRetry(t,n,o,e.widget_id||"1",Y,0,false,r,{onNewToken:Je,onSessionUpdate:e=>{if(o&&Le.current!==o){if(Z){console.log("Session update ignored - conversation changed")}return}De(e.chatId);ee.current.saveChatId(e.chatId);if(e.chatId){pe(true)}},onSuccess:e=>{if(o&&Le.current!==o){if(Z){console.log("Message response ignored - conversation cleared")}Ge();return}if($e.current.active||$e.current.submitted){Ge();return}let t;if(typeof e.response==="object"&&e.response!==null){t=e.response.text||e.response.content||JSON.stringify(e.response);if(Z){console.log("Response object structure:",e.response)}}else{t=String(e.response)}if(e.sources&&e.sources.length>0){t+=x(e.sources)}const n=u(t,false,e.message_id);ie((e=>{const t=e.some((e=>e.messageId===n.messageId||!e.isUser&&e.text===n.text&&Math.abs(e.id-n.id)<5e3));if(t){if(Z){console.log("Duplicate bot message detected, skipping:",n.messageId)}return e}return[...e,n]}));Ge()},onInvalidNonce:async()=>{await Ye(true)},onTimeoutError:(t,n)=>{Ge();const s=n?n.finalMessage:e.error_generic||"Unable to connect. Please refresh the page and try again.";he(s)},onRetry:(e,t)=>{if(e>1){de(true)}},onFinalError:async(t,o)=>{if(o&&o.code){if(o.code==="duplicate_request"){if(Z){console.log("Duplicate request detected, original request still processing")}return}const e=te.current.handleSessionError(o);if(e==="clear"){Ge();rt();return}else if(e==="expired_conversation"){Ge();at(o);return}else if(e==="refresh_nonce"){return}if(e==="new_session"){if(Z){console.log("Session expired during message send, creating new session...")}const e=await te.current.startSession();if(e.canceled){Ge();ct();return}if(e.success){De("");ee.current.clearChatId();await ze(r,n,s+1);return}}}Ge();if(te.current.isSessionError(o)){if(Z){console.log("Authentication/cookie error detected, starting new conversation")}ct();return}let r;if(o){r=o.finalMessage;if(o.type==="rate_limit"&&o.context.retryAfter){r+=` Please try again in ${o.context.retryAfter} seconds.`}if(J&&o.code){h("AI Chat","Message send failed",{type:o.type,code:o.code,statusCode:o.statusCode,context:o.context})}}else{r=e.error_generic||"Unable to connect. Please refresh the page and try again."}he(r)}});return a}const Qe=async()=>{if(Ke.current||Ie||ke)return;const e=d(le);if(!e.valid){return}ne.current.clearRetries();he("");ie((t=>[...t,e.message]));fe("");if(a&&M(e.text,b)){if(et("keyword",{prefillMessage:e.text})){return}}de(true);Ke.current=true;Ce(true);try{await ze(e.text,e.messageId)}catch(e){if(Z){h("AI Chat","Unexpected error in handleSend",{error:e.message||e,stack:e.stack})}he("An unexpected error occurred. Please try again.");Ge()}finally{if(Ke.current){Ke.current=false}}};function Xe(){ye(false);ve(false);Ee(false);Ae({});Pe({first_name:"",email:"",message:""});Be("")}function Ze(){Ue({messageId:"",vote:"",action:""})}function et(e,t={}){const n=a||e==="thumbs_down";if(!n||Ie||ke||m!=="email"){return false}ne.current.clearRetries();he("");de(false);Ce(false);Ke.current=false;Ae({});Be(e);ye(true);if(e==="button"&&Fe){ne.current.submitHandoffClick({chat_id:Fe,trigger:e}).then((e=>{if(!e.success&&Z){h("AI Chat","Failed to record handoff click",{errorInfo:e.errorInfo})}}))}if(t.prefillMessage){Pe((e=>({...e,message:e.message||t.prefillMessage})))}ie((e=>[...e,u(S,false)]));return true}function tt(){return ce.map((e=>({role:e.isUser?"user":"assistant",content:e.text})))}function nt(e,t){Pe((n=>({...n,[e]:t})));if(Se[e]){Ae((t=>({...t,[e]:""})))}}async function st(t){if(t&&typeof t.preventDefault==="function"){t.preventDefault()}if(xe||ke||!Ie){return}const n={};const s=Me.first_name.trim();const o=Me.email.trim();const r=Me.message.trim();if(!s){n.first_name=B.first_name_required||"Please enter your first name."}if(!o){n.email=B.email_required||"Please enter your email."}else{const e=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;if(!e.test(o)){n.email=B.email_invalid||"Please enter a valid email address."}}if(!r){n.message=B.message_required||"Please describe your issue."}if(Object.keys(n).length>0){Ae(n);return}Ee(true);Ae({});const a={first_name:s,email:o,message:r,chat_id:Fe||"",trigger:Te||"",page_url:window.location.href,page_id:e.page_object_id||0,transcript:tt()};const c=await ne.current.submitHandoff(a);if(c.success){if(c.data&&c.data.new_token){Je(c.data)}ye(false);ve(true);ie((e=>[...e,u(A,false)]))}else{Ae({form:T});if(Z&&c.errorInfo){h("AI Chat","Handoff submission failed",{errorInfo:c.errorInfo})}}Ee(false)}function ot(){if(!Ie||ke){return}Xe();setTimeout((()=>{if(Ve.current){Ve.current.focus()}}),0)}function rt(){if(Z){console.log("User state changed - starting new conversation")}Xe();Ze();const e=Fe;De("");ee.current.clearChatId();if(e){ee.current.clearMessageCache(e)}ie([u(n,false)]);pe(false);qe.current=true}function at(e){const t=e?.finalMessage||"Your previous conversation has expired. Starting a new conversation...";he(t);Xe();Ze();const s=Fe;De("");ee.current.clearChatId();if(s){ee.current.clearMessageCache(s)}ie([u(n,false)]);pe(false);setTimeout((()=>{he("")}),5e3)}function ct(){if(Ke.current){if(Z){console.log("Cannot clear - message is being sent")}return}if(Z){console.log("Clearing conversation...")}Xe();Ze();const e=Fe;ne.current.clearRetries();De("");ee.current.clearChatId();if(e){ee.current.clearMessageCache(e)}ie([u(n,false)]);he("");pe(false);qe.current=true;if(Z){console.log("Conversation cleared. New chat_id will be generated on next message.")}}const it=e=>{if(e.key==="Enter"&&!e.shiftKey){e.preventDefault();Qe()}};const lt=ce.filter((e=>!e.isUser));const ft=ce.some((e=>e.isUser));const ut=lt.length>1;const dt=[...ce].reverse().find((e=>!e.isUser));const gt=dt&&typeof dt.text==="string"?dt.text.trim():"";const ht=gt&&$.includes(gt);const mt=dt?dt.messageId||dt.id:null;const pt=b.length>0&&ce.some((e=>e.isUser&&M(e.text,b)));const wt=U&&!Ie&&!ke&&ft&&ut&&mt&&!ht;let _t="none";if(wt){if(!Re.messageId||Re.messageId!==mt){_t="buttons"}else if(Re.vote==="up"){_t="thanks"}else if(Re.vote==="down"&&!Re.action){_t=F?"choices":"message"}}const bt={messageId:mt,mode:_t,thanksText:D,choicePrompt:L,tryDifferentText:K,talkToHumanText:H};let Ct=false;if(a&&!Ie&&!ke){if(p==="always"){Ct=true}else if(p==="after_first_response"){Ct=ut}else if(p==="after_keyword"){Ct=pt}}const It=async(e,t)=>{if(!Fe){return}const n=await ne.current.submitFeedback({chat_id:Fe,vote:e,message_id:t});if(!n.success&&Z){h("AI Chat","Failed to record feedback",{errorInfo:n.errorInfo})}};const yt=()=>{if(!mt||Re.messageId===mt){return}Ue({messageId:mt,vote:"up",action:""});It("up",mt)};const kt=()=>{if(!mt||Re.messageId===mt){return}Ue({messageId:mt,vote:"down",action:""});It("down",mt)};const vt=()=>{if(Re.messageId!==mt||Re.vote!=="down"||Re.action){return}Ue((e=>({...e,action:"clarify"})));ie((e=>[...e,u(q,false)]))};const xt=()=>{if(Re.messageId!==mt||Re.vote!=="down"||Re.action){return}const e=et("thumbs_down");if(e){Ue((e=>({...e,action:"handoff"})))}};return C({isOpen:se,isExpanded:re,messages:ce,inputValue:le,isTyping:ue,errorMessage:ge,isInitialConversationLoading:we,isSending:be,handoffEnabled:a,handoffActive:Ie,handoffSubmitted:ke,handoffSubmitting:xe,handoffButtonVisible:Ct,handoffButtonText:w,handoffConsentText:P,handoffForm:Me,handoffErrors:Se,handoffI18n:B,feedbackUI:bt,setIsOpen:oe,setIsExpanded:ae,setInputValue:fe,handleSend:Qe,handleKeyDown:it,clearConversation:ct,handleHandoffSubmit:st,handleHandoffFieldChange:nt,handleHandoffButtonClick:()=>et("button"),handleHandoffClose:ot,handleFeedbackUp:yt,handleFeedbackDown:kt,handleFeedbackTryDifferent:vt,handleFeedbackTalkToHuman:xt,chatWindowRef:We,messagesEndRef:je,inputRef:Ve,toggleButtonRef:Ne,config:e,widgetColors:j,isAdmin:J,showTechnicalLogs:Z,configError:Q,Message:v,TypingIndicator:I,LoadingSkeleton:y},t)}function S(){const e=g();if(!e){h("AI Chat","Widget root element not found",{expectedId:window.epkbChatWidgetRoot||"epkb-ai-chat-widget-root"});return}if(typeof n.createRoot==="function"){const t=n.createRoot(e);t.render(a(P))}else{n.render(a(P),e)}}if(document.readyState==="loading"){document.addEventListener("DOMContentLoaded",S)}else{S()}})();