var ChatbotSDK=function(){"use strict";const n="[ChatbotSDK]";let e=!0;const t={},r={info(t,r){e&&console.log(n,t,void 0!==r?r:"")},warn(t,r){e&&console.warn(n,t,void 0!==r?r:"")},error(e,t){console.error(n,e,void 0!==t?t:"")},time(n){t[n]=Date.now()},timeEnd(r,o){const s=t[r];if(void 0!==s){const i=Date.now()-s;if(delete t[r],e){const e=o?`${o} ${i}ms`:`${r} ${i}ms`;console.log(n,e)}return i}return 0},lifecycleInit(n,e){this.info(`初始化完成 integrateId=${n} requestDomain=${e}`)},lifecycleDestroy(n){this.info(`销毁实例 integrateId=${n}`)},lifecycleSend(n,e){this.info(`发送消息 integrateId=${n} length=${e}`),this.time(`send_${n}`)},lifecycleReply(n,e){const t=this.timeEnd(`send_${n}`,"AI 回复");this.info(`AI 回复 integrateId=${n} length=${e} duration=${t}ms`)},lifecycleError(n,e,t){this.timeEnd(`send_${n}`),this.error(`请求失败 integrateId=${n} status=${e} message=${t}`)},lifecycleClear(n){this.info(`清空会话 integrateId=${n}`)},lifecycleStreamDone(n,e){const t=this.timeEnd(`send_${n}`,"流式回复");this.info(`流式回复完成 integrateId=${n} length=${e} duration=${t}ms`)},lifecycleCategoryChange(n){this.info(`切换知识库分类 categoryId=${n}`)}};const o={"zh-CN":{title:"AI 智能助手",minimize:"最小化",close:"关闭",placeholder:"输入您的问题...",send:"发送",loading:"正在思考...",stream_interrupted:"回复被中断",stream_unstable:"网络不稳定,内容可能不完整",category_placeholder:"选择知识库分类",category_all:"全部分类",category_load_error:"加载分类失败",source_title:"参考来源",source_count:"{n} 条参考来源",source_loading:"加载来源中...",clear:"清空对话",clear_confirm:"确定清空所有对话记录?",history_title:"历史会话",history_empty:"暂无历史会话",history_load_error:"加载会话列表失败",history_delete_confirm:"确定删除该会话?",history_export:"导出",history_delete:"删除",error_network:"网络连接失败,请检查网络",error_timeout:"请求超时,请稍后重试",error_server:"服务器异常,请稍后重试",error_cors:"跨域请求被拦截,请联系管理员将当前域名加入 API 白名单",error_auth:"鉴权失败,请联系管理员",error_forbidden:"无访问权限,请联系管理员配置",error_not_found:"请求的资源不存在",error_rate_limit:"请求过于频繁,请稍后重试",error_unavailable:"服务暂不可用,请稍后重试",error_unknown:"请求发生未知错误",error_send:"发送失败,请稍后重试",error_stream_unsupported:"浏览器不支持流式读取"},en:{title:"AI Assistant",minimize:"Minimize",close:"Close",placeholder:"Type your question...",send:"Send",loading:"Thinking...",stream_interrupted:"Response interrupted",stream_unstable:"Network unstable, content may be incomplete",category_placeholder:"Select category",category_all:"All categories",category_load_error:"Failed to load categories",source_title:"Sources",source_count:"{n} source(s)",source_loading:"Loading sources...",clear:"Clear chat",clear_confirm:"Clear all conversation history?",history_title:"History",history_empty:"No conversations yet",history_load_error:"Failed to load conversations",history_delete_confirm:"Delete this conversation?",history_export:"Export",history_delete:"Delete",error_network:"Network connection failed",error_timeout:"Request timed out, please try again",error_server:"Server error, please try again later",error_cors:"CORS request blocked. Please contact admin to whitelist your domain",error_auth:"Authentication failed, please contact admin",error_forbidden:"Access denied, please contact admin",error_not_found:"Resource not found",error_rate_limit:"Too many requests, please try again later",error_unavailable:"Service temporarily unavailable",error_unknown:"Unknown request error",error_send:"Failed to send, please try again",error_stream_unsupported:"Browser does not support streaming"}};let s="zh-CN";function i(n,e){let t=(o[s]||o["zh-CN"])[n]||o["zh-CN"][n]||n;if(e)for(const[n,r]of Object.entries(e))t=t.replace(`{${n}}`,String(r));return t}let a=null;function c(n){if(!a)throw new Error("API 配置未初始化");return`${a.requestDomain.replace(/\/+$/,"")}${n.startsWith("/")?n:`/${n}`}`}function l(n,e,t){null!=t&&("string"==typeof t&&""===t.trim()||n.set(e,String(t)))}async function d(n,e={},t=3e4){const r=new AbortController,o=setTimeout(()=>r.abort(),t);try{return await fetch(n,Object.assign(Object.assign({},e),{signal:r.signal,mode:"cors",credentials:"include"}))}catch(n){if(n instanceof DOMException&&"AbortError"===n.name)throw new u(i("error_timeout"),"timeout");if(n instanceof TypeError&&n.message.includes("Failed to fetch"))throw new u(i("error_cors"),"cors");throw new u(i("error_network"),"network")}finally{clearTimeout(o)}}class u extends Error{constructor(n,e){super(n),this.name="CskError",this.type=e}}function p(n){switch(n){case 401:return i("error_auth");case 403:return i("error_forbidden");case 404:return i("error_not_found");case 429:return i("error_rate_limit");case 500:return i("error_server");case 502:case 503:return i("error_unavailable");default:return`${i("error_unknown")}(${n})`}}async function m(n){const e=function(n){const e=new URLSearchParams;return e.set("message",n),e.set("chatId",a.chatId),l(e,"roleId",a.integrateId),l(e,"accountId",a.userId),c(`/ai/assistant_app/chat/sync?${e.toString()}`)}(n);r.lifecycleSend(a.integrateId,n.length);try{const n=await d(e);if(!n.ok){const e=p(n.status);throw r.lifecycleError(a.integrateId,String(n.status),e),new u(e,`http_${n.status}`)}const t=await n.text();return r.lifecycleReply(a.integrateId,t.length),t}catch(n){if(n instanceof u)throw n;throw r.lifecycleError(a.integrateId,"unknown",String(n)),new u(i("error_unknown"),"unknown")}}async function h(n,e,t,o,s,m){var h;const g=m?function(n,e){const t=new URLSearchParams;return t.set("message",n),t.set("chatId",a.chatId),t.set("rewriteStrategy","REWRITE"),l(t,"roleId",a.integrateId),l(t,"accountId",a.userId),l(t,"categoryId",null!=e?e:a.categoryId),c(`/ai/assistant_app/chat/rag/sse?${t.toString()}`)}(n,s):function(n,e){const t=new URLSearchParams;return t.set("message",n),t.set("chatId",a.chatId),l(t,"roleId",a.integrateId),l(t,"accountId",a.userId),l(t,"categoryId",null!=e?e:a.categoryId),c(`/ai/assistant_app/chat/sse?${t.toString()}`)}(n,s);let k="";r.lifecycleSend(a.integrateId,n.length);try{const n=await d(g,{},6e4);if(!n.ok){const e=p(n.status);return r.lifecycleError(a.integrateId,String(n.status),e),void o(new u(e,`http_${n.status}`))}const s=null===(h=n.body)||void 0===h?void 0:h.getReader();if(!s)return void o(new u(i("error_stream_unsupported"),"stream_unsupported"));const c=new TextDecoder("utf-8",{stream:!0});let l="";try{for(;;){const{done:n,value:t}=await s.read();if(n)break;l+=c.decode(t,{stream:!0});const r=l.split("\n");l=r.pop()||"";for(const n of r){const t=n.trim();if(t&&!t.startsWith(":"))if(t.startsWith("data:")){const n=t.substring(5).trim();n&&(k+=n,e(n))}else{if("[DONE]"===t)break;t.startsWith("event:")||t.startsWith("id:")||t.startsWith("retry:")||(k+=t,e(t))}}}if(l.trim()){const n=l.trim();if(n.startsWith("data:")){const t=n.substring(5).trim();t&&(k+=t,e(t))}else"[DONE]"!==n&&(k+=n,e(n))}}catch(n){if(!(k.length>0))throw n;e("\n\n"+i("stream_unstable"))}finally{s.releaseLock()}r.lifecycleStreamDone(a.integrateId,k.length),t()}catch(n){n instanceof u?o(n):(r.lifecycleError(a.integrateId,"unknown",String(n)),o(new u(i("error_network"),"network")))}}async function g(n,e){const t=function(n,e){const t=new URLSearchParams;return t.set("message",n),t.set("chatId",a.chatId),t.set("rewriteStrategy","REWRITE"),l(t,"roleId",a.integrateId),l(t,"accountId",a.userId),l(t,"categoryId",null!=e?e:a.categoryId),c(`/ai/assistant_app/rag/sources?${t.toString()}`)}(n,e);try{const n=await d(t);if(!n.ok)throw new u(p(n.status),`http_${n.status}`);const e=await n.json();return e.success&&Array.isArray(e.data)?(r.info(`获取引用来源 count=${e.data.length}`),e.data):[]}catch(n){return r.error("获取引用来源失败",n),[]}}async function k(n=1,e=20,t,o){let s=`/conversation/list?page=${n}&size=${e}`;t&&(s+=`&accountId=${encodeURIComponent(t)}`),o&&(s+=`&roleId=${encodeURIComponent(o)}`);const i=c(s);try{const n=await d(i);if(!n.ok)throw new u(p(n.status),`http_${n.status}`);const e=await n.json();return{list:e.success&&Array.isArray(e.data)?e.data:[],total:e.total||0,pages:e.pages||0}}catch(n){return r.error("加载会话列表失败",n),{list:[],total:0,pages:0}}}async function f(){if(!a)return"";const n=function(n,e){try{return localStorage.getItem(y(n,e))||""}catch(n){return""}}(a.integrateId,a.userId);if(n)return a.chatId=n,r.info(`从缓存恢复 chatId=${n}`),n;try{const n=await k(1,5,a.userId,a.integrateId);if(n.list.length>0){const e=n.list[0],t=e.conversationId||e.chatId||"";if(t)return a.chatId=t,b(a.integrateId,a.userId,t),r.info(`从后端恢复会话 chatId=${t} messageCount=${e.messageCount}`),t}}catch(n){r.warn("查询后端会话列表失败,将生成新 chatId",n)}const e=function(){const n="undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID().substring(0,8):Math.random().toString(36).substring(2,10);return`sdk_${Date.now()}_${n}`}();return a.chatId=e,b(a.integrateId,a.userId,e),r.info(`生成新 chatId=${e}`),e}function y(n,e){return`csk_chatId_${n}${e?"_"+e:""}`}function b(n,e,t){try{t?localStorage.setItem(y(n,e),t):localStorage.removeItem(y(n,e))}catch(n){}}let x=null;function _(n){const e=function(n,e){const t=n.match(/^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/);if(!t)return n;const r=n=>Math.max(0,Math.min(255,n)),o=r(parseInt(t[1],16)+e),s=r(parseInt(t[2],16)+e),i=r(parseInt(t[3],16)+e);return`#${o.toString(16).padStart(2,"0")}${s.toString(16).padStart(2,"0")}${i.toString(16).padStart(2,"0")}`}(n.primaryColor,-15);return`\n --csk-primary: ${n.primaryColor};\n --csk-primary-hover: ${e};\n --csk-bg-user: var(--csk-primary);\n --csk-bg-ai: #F3F4F6;\n --csk-text-user: #FFFFFF;\n --csk-text-ai: #1F2937;\n --csk-window-width: ${n.width}px;\n `}function w(n){document.querySelector("style[data-csk-sdk]")||(x=document.createElement("style"),x.setAttribute("data-csk-sdk",""),x.textContent=function(n){return`\n/* ChatbotSDK 样式 - csk- 命名空间 */\n.csk-root {\n ${_(n)}\n font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans SC", sans-serif;\n font-size: 14px;\n line-height: 1.5;\n color: #1F2937;\n}\n\n/* ========== 悬浮按钮 ========== */\n.csk-launcher {\n position: fixed;\n bottom: 20px;\n z-index: 9998;\n width: 56px;\n height: 56px;\n border-radius: 50%;\n background: #fff;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.2s ease;\n border: none;\n color: var(--csk-primary);\n user-select: none;\n}\n.csk-launcher--right {\n right: 20px;\n}\n.csk-launcher--left {\n left: 20px;\n}\n.csk-launcher:hover {\n transform: scale(1.1);\n box-shadow: 0 6px 24px rgba(0, 0, 0, 0.2);\n}\n.csk-launcher:active {\n transform: scale(0.95);\n}\n\n/* ========== 聊天弹窗 ========== */\n.csk-window {\n position: fixed;\n bottom: 20px;\n z-index: 9999;\n width: var(--csk-window-width);\n height: 560px;\n background: #fff;\n border-radius: 12px;\n box-shadow: 0 8px 40px rgba(0, 0, 0, 0.18);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n transition: opacity 0.2s ease, transform 0.2s ease;\n}\n.csk-window--right {\n right: 20px;\n}\n.csk-window--left {\n left: 20px;\n}\n.csk-window--hidden {\n display: none;\n}\n\n/* ========== 头部 ========== */\n.csk-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0 16px;\n height: 48px;\n min-height: 48px;\n background: var(--csk-primary);\n color: #fff;\n border-radius: 12px 12px 0 0;\n cursor: move;\n user-select: none;\n}\n.csk-header__title {\n font-size: 15px;\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.csk-header__actions {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n.csk-header__btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n color: #fff;\n cursor: pointer;\n border-radius: 6px;\n transition: background 0.15s;\n}\n.csk-header__btn:hover {\n background: rgba(255, 255, 255, 0.2);\n}\n\n/* ========== 消息区 ========== */\n.csk-messages {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n background: #FAFAFA;\n scroll-behavior: smooth;\n}\n.csk-messages::-webkit-scrollbar {\n width: 5px;\n}\n.csk-messages::-webkit-scrollbar-track {\n background: transparent;\n}\n.csk-messages::-webkit-scrollbar-thumb {\n background: #D1D5DB;\n border-radius: 3px;\n}\n\n/* 消息气泡 */\n.csk-msg {\n display: flex;\n flex-direction: column;\n margin-bottom: 16px;\n max-width: 85%;\n word-break: break-word;\n}\n.csk-msg--user {\n margin-left: auto;\n align-items: flex-end;\n}\n.csk-msg--ai {\n margin-right: auto;\n align-items: flex-start;\n}\n.csk-msg__bubble {\n padding: 10px 14px;\n border-radius: 12px;\n font-size: 14px;\n line-height: 1.6;\n}\n.csk-msg--user .csk-msg__bubble {\n background: var(--csk-bg-user);\n color: var(--csk-text-user);\n border-radius: 12px 12px 4px 12px;\n}\n.csk-msg--ai .csk-msg__bubble {\n background: var(--csk-bg-ai);\n color: var(--csk-text-ai);\n border-radius: 12px 12px 12px 4px;\n}\n.csk-msg__time {\n font-size: 11px;\n color: #9CA3AF;\n margin-top: 4px;\n padding: 0 4px;\n}\n\n/* ========== Loading 动画 ========== */\n.csk-loading {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 12px 14px;\n margin-bottom: 16px;\n}\n.csk-loading__dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: #D1D5DB;\n animation: csk-bounce 1.4s ease-in-out infinite both;\n}\n.csk-loading__dot:nth-child(1) { animation-delay: 0s; }\n.csk-loading__dot:nth-child(2) { animation-delay: 0.16s; }\n.csk-loading__dot:nth-child(3) { animation-delay: 0.32s; }\n\n@keyframes csk-bounce {\n 0%, 80%, 100% { transform: scale(0.6); }\n 40% { transform: scale(1); }\n}\n\n/* ========== 输入区 ========== */\n.csk-input-area {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n border-top: 1px solid #E5E7EB;\n background: #fff;\n gap: 8px;\n}\n.csk-input {\n flex: 1;\n border: 1px solid #E5E7EB;\n border-radius: 8px;\n padding: 10px 12px;\n font-size: 14px;\n outline: none;\n transition: border-color 0.2s;\n font-family: inherit;\n resize: none;\n min-height: 20px;\n max-height: 100px;\n}\n.csk-input:focus {\n border-color: var(--csk-primary);\n}\n.csk-input::placeholder {\n color: #9CA3AF;\n}\n.csk-send-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n min-width: 40px;\n border: none;\n border-radius: 8px;\n background: var(--csk-primary);\n color: #fff;\n cursor: pointer;\n transition: background 0.2s;\n}\n.csk-send-btn:hover {\n background: var(--csk-primary-hover);\n}\n.csk-send-btn:disabled {\n background: #D1D5DB;\n cursor: not-allowed;\n}\n\n/* ========== 清空按钮 ========== */\n.csk-clear-btn {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 6px 12px;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n background: #fff;\n color: #6B7280;\n font-size: 12px;\n cursor: pointer;\n margin: 0 auto 8px;\n transition: all 0.15s;\n}\n.csk-clear-btn:hover {\n background: #FEE2E2;\n border-color: #FCA5A5;\n color: #DC2626;\n}\n\n/* ========== P1: 知识库分类下拉 ========== */\n.csk-category-bar {\n display: flex;\n align-items: center;\n padding: 6px 12px;\n border-top: 1px solid #E5E7EB;\n background: #F9FAFB;\n gap: 8px;\n}\n.csk-category-bar__label {\n font-size: 12px;\n color: #6B7280;\n white-space: nowrap;\n}\n.csk-category-select {\n flex: 1;\n padding: 5px 8px;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n font-size: 12px;\n color: #374151;\n background: #fff;\n outline: none;\n cursor: pointer;\n font-family: inherit;\n transition: border-color 0.2s;\n max-width: 200px;\n}\n.csk-category-select:focus {\n border-color: var(--csk-primary);\n}\n\n/* ========== P1: RAG 引用来源卡片 ========== */\n.csk-sources {\n margin-top: 8px;\n border: 1px solid #E5E7EB;\n border-radius: 8px;\n overflow: hidden;\n font-size: 12px;\n max-width: 100%;\n}\n.csk-sources__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 12px;\n background: #F9FAFB;\n cursor: pointer;\n user-select: none;\n transition: background 0.15s;\n}\n.csk-sources__header:hover {\n background: #F3F4F6;\n}\n.csk-sources__title {\n display: flex;\n align-items: center;\n gap: 4px;\n font-weight: 500;\n color: #374151;\n}\n.csk-sources__arrow {\n transition: transform 0.2s;\n color: #9CA3AF;\n}\n.csk-sources--collapsed .csk-sources__arrow {\n transform: rotate(-90deg);\n}\n.csk-sources__body {\n border-top: 1px solid #E5E7EB;\n padding: 0;\n}\n.csk-sources--collapsed .csk-sources__body {\n display: none;\n}\n.csk-source-item {\n padding: 8px 12px;\n border-bottom: 1px solid #F3F4F6;\n transition: background 0.15s;\n}\n.csk-source-item:last-child {\n border-bottom: none;\n}\n.csk-source-item:hover {\n background: #F9FAFB;\n}\n.csk-source-item__name {\n font-weight: 500;\n color: #1F2937;\n margin-bottom: 2px;\n}\n.csk-source-item__snippet {\n color: #6B7280;\n line-height: 1.4;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n.csk-source-item__meta {\n font-size: 11px;\n color: #9CA3AF;\n margin-top: 2px;\n}\n\n/* ========== P1: Markdown 渲染样式 ========== */\n.csk-msg--ai .csk-msg__bubble .csk-md-p {\n margin: 0 0 8px;\n}\n.csk-msg--ai .csk-msg__bubble .csk-md-p:last-child {\n margin-bottom: 0;\n}\n.csk-msg--ai .csk-msg__bubble .csk-md-h1,\n.csk-msg--ai .csk-msg__bubble .csk-md-h2,\n.csk-msg--ai .csk-msg__bubble .csk-md-h3,\n.csk-msg--ai .csk-msg__bubble .csk-md-h4,\n.csk-msg--ai .csk-msg__bubble .csk-md-h5,\n.csk-msg--ai .csk-msg__bubble .csk-md-h6 {\n margin: 12px 0 6px;\n font-weight: 600;\n line-height: 1.3;\n}\n.csk-msg--ai .csk-msg__bubble .csk-md-h1 { font-size: 20px; }\n.csk-msg--ai .csk-msg__bubble .csk-md-h2 { font-size: 17px; }\n.csk-msg--ai .csk-msg__bubble .csk-md-h3 { font-size: 15px; }\n.csk-msg--ai .csk-msg__bubble .csk-md-h4 { font-size: 14px; }\n\n.csk-md-code-block {\n background: #1E293B;\n color: #E2E8F0;\n padding: 12px 14px;\n border-radius: 8px;\n overflow-x: auto;\n margin: 8px 0;\n font-size: 13px;\n line-height: 1.5;\n font-family: 'SF Mono', 'Consolas', 'Menlo', monospace;\n}\n.csk-md-code-block code {\n background: none;\n padding: 0;\n border-radius: 0;\n font-size: inherit;\n color: inherit;\n}\n.csk-md-inline-code {\n background: #E5E7EB;\n color: #DC2626;\n padding: 1px 6px;\n border-radius: 4px;\n font-size: 13px;\n font-family: 'SF Mono', 'Consolas', 'Menlo', monospace;\n}\n.csk-msg--ai .csk-msg__bubble .csk-md-ul,\n.csk-msg--ai .csk-msg__bubble .csk-md-ol {\n padding-left: 20px;\n margin: 6px 0;\n}\n.csk-msg--ai .csk-msg__bubble .csk-md-ul li,\n.csk-msg--ai .csk-msg__bubble .csk-md-ol li {\n margin-bottom: 4px;\n}\n.csk-md-blockquote {\n border-left: 3px solid var(--csk-primary);\n padding-left: 12px;\n margin: 8px 0;\n color: #6B7280;\n}\n.csk-md-link {\n color: var(--csk-primary);\n text-decoration: none;\n}\n.csk-md-link:hover {\n text-decoration: underline;\n}\n.csk-md-hr {\n border: none;\n border-top: 1px solid #E5E7EB;\n margin: 12px 0;\n}\n\n/* ========== P2: 会话管理面板 ========== */\n.csk-history-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n color: #fff;\n cursor: pointer;\n border-radius: 6px;\n transition: background 0.15s;\n}\n.csk-history-btn:hover {\n background: rgba(255, 255, 255, 0.2);\n}\n.csk-history-panel {\n position: absolute;\n top: 48px;\n left: 0;\n right: 0;\n bottom: 0;\n background: #fff;\n z-index: 10;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.csk-history-panel--hidden {\n display: none;\n}\n.csk-history-panel__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n border-bottom: 1px solid #E5E7EB;\n background: #F9FAFB;\n}\n.csk-history-panel__title {\n font-size: 14px;\n font-weight: 600;\n color: #1F2937;\n}\n.csk-history-panel__back {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n background: #fff;\n color: #374151;\n font-size: 12px;\n cursor: pointer;\n transition: all 0.15s;\n}\n.csk-history-panel__back:hover {\n background: #F3F4F6;\n}\n.csk-history-panel__list {\n flex: 1;\n overflow-y: auto;\n padding: 8px;\n}\n.csk-history-panel__list::-webkit-scrollbar {\n width: 4px;\n}\n.csk-history-panel__list::-webkit-scrollbar-thumb {\n background: #E5E7EB;\n border-radius: 2px;\n}\n.csk-history-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.15s;\n margin-bottom: 4px;\n}\n.csk-history-item:hover {\n background: #F3F4F6;\n}\n.csk-history-item__info {\n flex: 1;\n min-width: 0;\n}\n.csk-history-item__id {\n font-size: 13px;\n font-weight: 500;\n color: #1F2937;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.csk-history-item__meta {\n font-size: 11px;\n color: #9CA3AF;\n margin-top: 2px;\n}\n.csk-history-item__actions {\n display: flex;\n gap: 4px;\n margin-left: 8px;\n opacity: 0;\n transition: opacity 0.15s;\n}\n.csk-history-item:hover .csk-history-item__actions {\n opacity: 1;\n}\n.csk-history-action {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n font-size: 12px;\n transition: all 0.15s;\n}\n.csk-history-action--export {\n background: #EFF6FF;\n color: #2563EB;\n}\n.csk-history-action--export:hover {\n background: #DBEAFE;\n}\n.csk-history-action--delete {\n background: #FEF2F2;\n color: #DC2626;\n}\n.csk-history-action--delete:hover {\n background: #FEE2E2;\n}\n.csk-history-panel__empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n color: #9CA3AF;\n font-size: 13px;\n text-align: center;\n}\n.csk-history-panel__empty-icon {\n font-size: 32px;\n margin-bottom: 8px;\n opacity: 0.5;\n}\n.csk-history-panel__loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px;\n color: #9CA3AF;\n font-size: 13px;\n}\n.csk-history-panel__loadmore {\n display: block;\n width: 100%;\n padding: 10px;\n border: none;\n background: #F9FAFB;\n color: #6B7280;\n font-size: 12px;\n cursor: pointer;\n text-align: center;\n transition: background 0.15s;\n}\n.csk-history-panel__loadmore:hover {\n background: #F3F4F6;\n}\n\n/* ========== 移动端适配 ========== */\n@media (max-width: 480px) {\n .csk-window {\n width: 100vw !important;\n height: 100vh !important;\n bottom: 0 !important;\n right: 0 !important;\n left: 0 !important;\n border-radius: 0;\n }\n .csk-header {\n border-radius: 0;\n }\n}\n`}(n),document.head.appendChild(x))}function v(){return"undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{const e=16*Math.random()|0;return("x"===n?e:3&e|8).toString(16)})}function E(n){const e={"&":"&","<":"<",">":">",'"':""","'":"'"};return n.replace(/[&<>"']/g,n=>e[n]||n)}function I(){return Date.now()}function C(n,e){const t=document.createElement("div");t.id="csk-launcher",t.className="csk-launcher csk-launcher--"+("left-bottom"===n.position?"left":"right"),t.setAttribute("title",n.title),t.setAttribute("aria-label",n.title),t.setAttribute("role","button"),t.setAttribute("tabindex","0"),t.innerHTML=n.launcherIcon;const r=function(n,e){let t=null;return function(...r){null!==t&&clearTimeout(t),t=setTimeout(()=>{n.apply(this,r),t=null},e)}}(e,300);return t.addEventListener("click",r),t.addEventListener("keydown",n=>{"Enter"!==n.key&&" "!==n.key||(n.preventDefault(),r())}),t}function $(n,e,t){const r=document.createElement("div");r.className="csk-msg csk-msg--user";const o=document.createElement("div");o.className="csk-msg__bubble",o.textContent=e;const s=document.createElement("div");return s.className="csk-msg__time",s.textContent=N(t),r.appendChild(o),r.appendChild(s),n.appendChild(r),r}function S(n,e,t,r){const o=document.createElement("div");o.className="csk-msg csk-msg--ai";const s=document.createElement("div");s.className="csk-msg__bubble",r?s.innerHTML=r(e):s.textContent=e;const i=document.createElement("div");return i.className="csk-msg__time",i.textContent=N(t),o.appendChild(s),o.appendChild(i),n.appendChild(o),o}function A(n,e){const t=n.querySelector(".csk-sources");if(t&&t.remove(),!e||0===e.length)return;const r=document.createElement("div");r.className="csk-sources csk-sources--collapsed";const o=document.createElement("div");o.className="csk-sources__header";const s=document.createElement("span");s.className="csk-sources__title",s.textContent=`📚 ${i("source_count",{n:e.length})}`;const a=document.createElement("span");a.className="csk-sources__arrow",a.textContent="▼",o.appendChild(s),o.appendChild(a),o.addEventListener("click",()=>{r.classList.toggle("csk-sources--collapsed")});const c=document.createElement("div");c.className="csk-sources__body";for(const n of e){const e=document.createElement("div");e.className="csk-source-item";const t=document.createElement("div");if(t.className="csk-source-item__name",t.textContent=n.title||n.sourceName||"未知文档",n.snippet){const t=document.createElement("div");t.className="csk-source-item__snippet",t.textContent=n.snippet,e.appendChild(t)}const r=document.createElement("div");r.className="csk-source-item__meta";const o=[];n.sourceName&&o.push(n.sourceName),void 0!==n.chunkIndex&&o.push(`分块 #${n.chunkIndex}`),void 0!==n.score&&o.push(`相关度 ${(100*n.score).toFixed(0)}%`),r.textContent=o.join(" · "),e.appendChild(t),e.appendChild(r),c.appendChild(e)}r.appendChild(o),r.appendChild(c);const l=n.querySelector(".csk-msg__time");l?n.insertBefore(r,l):n.appendChild(r)}function F(n){n.scrollTop=n.scrollHeight}function N(n){const e=new Date(n);return`${String(e.getHours()).padStart(2,"0")}:${String(e.getMinutes()).padStart(2,"0")}`}function L(n){return`csk_history_${n}`}function D(n,e){try{let t=e;t.length>200&&(t=t.slice(50),r.warn(`消息数量达到上限,已裁剪最早 50 条,当前 ${t.length} 条`));const o={messages:t,updatedAt:Date.now()};localStorage.setItem(L(n),JSON.stringify(o))}catch(n){n instanceof Error&&"QuotaExceededError"===n.name?r.error("localStorage 空间不足,会话历史保存失败。建议清空历史记录。"):r.error("保存会话历史失败",n)}}function B(n){try{localStorage.removeItem(L(n))}catch(n){r.warn("清空会话历史失败",n)}}const M="\0CODEBLOCK_",z="\0INLINECODE_";function T(n){if(!n||"string"!=typeof n)return"";const e=[];let t=n;t=t.replace(/```(\w*)\n([\s\S]*?)```/g,(n,t,r)=>{const o=e.length,s=E(r.trimEnd()),i=t?` class="language-${E(t)}"`:"";return e.push(`
${s}`),`${M}${o}\0`});const r=[];t=t.replace(/`([^`\n]+)`/g,(n,e)=>{const t=r.length;return r.push(`${E(e)}`),`${z}${t}\0`}),t=E(t),t=q(t,M,e),t=q(t,z,r);const o=t.split("\n"),s=[];let i=!1,a="",c=!1,l=[];for(let n=0;n')),s.push(`"),c=!1)}}function q(n,e,t){return n.replace(new RegExp(e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")+"(\\d+)\0","g"),(n,e)=>t[parseInt(e)]||"")}let j,H=null,R=[],U=null,P=null,O=null,W=null,K=null,V=null,J=null,X=null,Y=!1,G=!1;function Q(n,e){H=n,U=e.messagesContainer,P=e.inputEl,O=e.sendBtn,W=e.clearBtn,K=e.categorySelect,V=e.historyPanel,J=e.showLoading,X=e.hideLoading,j=n.categoryId,G=!!n.categoryId||!!n.showCategorySwitch,function(){if(!P||!O)return;O.addEventListener("click",()=>en()),P.addEventListener("keydown",n=>{"Enter"!==n.key||n.shiftKey||(n.preventDefault(),en())}),P.addEventListener("input",()=>nn()),W&&W.addEventListener("click",()=>function(){if(!H)return;if(!confirm(i("clear_confirm")))return;if(R=[],U){U.querySelectorAll(".csk-msg, .csk-loading").forEach(n=>n.remove())}W&&(W.style.display="none");B(H.integrateId);const n=function(){const n="undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID().substring(0,8):Math.random().toString(36).substring(2,10);return`sdk_${Date.now()}_${n}`}();e=n,a&&(a.chatId=e),b(H.integrateId,H.userId,n),r.lifecycleClear(H.integrateId),r.info(`新 chatId=${n}`);var e}())}(),n.showCategorySwitch&&K&&async function(){if(!K)return;try{const n=await async function(){const n=c("/category/tree");try{const e=await d(n);if(!e.ok)throw new u(p(e.status),`http_${e.status}`);const t=await e.json();return t.success&&Array.isArray(t.data)?(r.info(`加载分类树成功 count=${t.data.length}`),t.data):[]}catch(n){return n instanceof u?r.error(`加载分类树失败: ${n.message}`):r.error("加载分类树失败",n),[]}}();if(0===n.length)return;K.innerHTML=``;const e=(n,t=0)=>{for(const r of n){const n=document.createElement("option");n.value=String(r.id),n.textContent=`${" ".repeat(t)}${r.name}`,void 0!==j&&String(r.id)===String(j)&&(n.selected=!0),K.appendChild(n),r.children&&r.children.length>0&&e(r.children,t+1)}};e(n),r.info(`知识库分类加载成功 count=${n.length}`)}catch(n){r.error(i("category_load_error"),n)}}()}async function Z(){if(H&&U&&(await f(),await async function(){if(!H||!U)return;const n=(null==a?void 0:a.chatId)||"";if(!n)return;try{const e=await async function(n){const e=c(`/conversation/${n}/messages`);try{const n=await d(e);if(!n.ok)throw new u(p(n.status),`http_${n.status}`);const t=await n.json();return{messages:t.success&&Array.isArray(t.data)?t.data:[],total:t.total||0}}catch(n){return r.error("加载会话消息失败",n),{messages:[],total:0}}}(n);e.messages.length>0&&(R=e.messages.map((n,e)=>({id:v(),role:"USER"===n.messageType?"user":"ai",content:n.content,timestamp:new Date(n.createTime).getTime()})),tn(),r.info(`从后端加载 ${R.length} 条历史消息`),D(H.integrateId,R))}catch(n){r.warn("从后端加载历史消息失败",n)}}(),0===R.length)){const n=function(n){try{const e=localStorage.getItem(L(n));if(!e)return[];const t=JSON.parse(e);return t&&Array.isArray(t.messages)?(r.info(`加载历史消息 integrateId=${n} count=${t.messages.length}`),t.messages):[]}catch(n){return r.warn("加载会话历史失败",n),[]}}(H.integrateId);n.length>0&&(R=n,tn(),r.info(`从本地缓存恢复 ${n.length} 条消息`))}}function nn(){if(!O||!P)return;P.value.trim().length>0&&!Y?O.removeAttribute("disabled"):O.setAttribute("disabled","true")}async function en(){if(!P||!H||Y)return;const n=P.value.trim();if(""===n)return;P.value="",nn(),P.style.height="auto",Y=!0,nn(),H.chatId||await f();const e=I();U&&$(U,n,e);const t={id:v(),role:"user",content:n,timestamp:e};R.push(t),W&&R.length>0&&(W.style.display="inline-flex"),U&&F(U),J&&J(),U&&F(U);try{let e;const t=I(),o=G&&(void 0!==j||void 0!==H.categoryId);e=H.streaming?await async function(n,e,t){return new Promise((r,o)=>{let s=null,a="",c=!1;h(n,n=>{if(a+=n,!c&&U){X&&X();const{bubble:n}=function(n,e){const t=document.createElement("div");t.className="csk-msg csk-msg--ai";const r=document.createElement("div");r.className="csk-msg__bubble",r.innerHTML="";const o=document.createElement("div");return o.className="csk-msg__time",o.textContent=N(e),t.appendChild(r),t.appendChild(o),n.appendChild(t),{wrapper:t,bubble:r}}(U,e);s=n,c=!0}s&&(s.textContent=a),U&&F(U)},()=>{c||""!==a?(s&&a&&(s.innerHTML=T(a)),r(a)):m(n).then(r).catch(o)},n=>{a.length>0?(s&&(s.innerHTML=T(a+"\n\n"+i("stream_interrupted"))),r(a)):o(n)},j,t)})}(n,t,o):await m(n),X&&X(),!H.streaming&&U&&S(U,e,t,T);const s={id:v(),role:"ai",content:e,timestamp:t};R.push(s),D(H.integrateId,R),U&&F(U),o&&async function(n,e){try{const t=await g(n,j);if(t.length>0){const n=t.map(n=>{var e,t;return{documentId:n.documentId||"",title:n.title||"",sourceName:n.sourceName||"",chunkIndex:null!==(e=n.chunkIndex)&&void 0!==e?e:0,score:null!==(t=n.score)&&void 0!==t?t:0,snippet:n.snippet||""}});if(e.sources=n,U){const e=U.querySelector(".csk-msg--ai:last-of-type");e&&A(e,n)}H&&D(H.integrateId,R)}}catch(n){r.warn("获取引用来源失败",n)}}(n,s)}catch(n){X&&X();const e=n instanceof u?n.message:i("error_send");if(U){const n=document.createElement("div");n.className="csk-msg csk-msg--ai";const t=document.createElement("div");t.className="csk-msg__bubble",t.style.color="#DC2626",t.textContent=`⚠ ${e}`,n.appendChild(t),U.appendChild(n)}r.error(`发送失败 integrateId=${H.integrateId}`,n)}finally{Y=!1,nn()}}function tn(){if(!U)return;const n=U.querySelector(".csk-history-panel");U.querySelectorAll(".csk-msg, .csk-loading").forEach(n=>n.remove());for(const n of R)if("user"===n.role)$(U,n.content,n.timestamp);else{const e=S(U,n.content,n.timestamp,T);n.sources&&n.sources.length>0&&A(e,n.sources)}F(U),W&&R.length>0&&(W.style.display="inline-flex"),n&&!U.contains(n)&&U.appendChild(n)}async function rn(){if(!V||!H)return;const n=V.querySelector("#csk-history-list");if(n){n.innerHTML='${d(r[1])}
`);continue}c&&m();const h=e.match(/^[\-\*]\s+(.+)/);if(h){u(),m(),i&&"ul"===a||(p(),i=!0,a="ul",s.push('')),s.push(`
":""),i=!1,a="")}function m(){c&&(s.push("- ${d(h[1])}
`);continue}const g=e.match(/^\d+\.\s+(.+)/);g?(u(),m(),i&&"ol"===a||(p(),i=!0,a="ol",s.push('')),s.push(`
- ${d(g[1])}
`)):""!==e.trim()?/^(\*{3,}|-{3,}|_{3,})$/.test(e.trim())?(u(),p(),m(),s.push('
')):(p(),m(),l.push(d(e))):(u(),p())}return u(),p(),m(),s.join("\n");function d(n){return n=(n=(n=(n=(n=(n=n.replace(/\*\*(.+?)\*\*/g,"$1")).replace(/__(.+?)__/g,"$1")).replace(/\*(.+?)\*/g,"$1")).replace(/(?$1")).replace(/~~(.+?)~~/g,"$1")).replace(/\[([^\]]+)\]\(([^)]+)\)/g,(n,e,t)=>`${e}`)}function u(){l.length>0&&(s.push(`${l.join("
`),l=[])}function p(){i&&(s.push("ul"===a?"
")}