@eshal-bot/chat-widget 0.1.77 → 0.1.82

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7869,7 +7869,7 @@
7869
7869
  m$2.hydrateRoot;
7870
7870
  }
7871
7871
 
7872
- var css_248z$1 = "*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }.chat-widget-root{--cw-primary:#2563eb;--cw-primary-hover:#1d4ed8;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}.\\!container{width:100%!important}.container{width:100%}@media (min-width:640px){.\\!container{max-width:640px!important}.container{max-width:640px}}@media (min-width:768px){.\\!container{max-width:768px!important}.container{max-width:768px}}@media (min-width:1024px){.\\!container{max-width:1024px!important}.container{max-width:1024px}}@media (min-width:1280px){.\\!container{max-width:1280px!important}.container{max-width:1280px}}@media (min-width:1536px){.\\!container{max-width:1536px!important}.container{max-width:1536px}}#chat-widget-root .chat-widget-root *{box-sizing:border-box;margin:0;padding:0}#chat-widget-root .chat-messages::-webkit-scrollbar{width:6px}#chat-widget-root .chat-messages::-webkit-scrollbar-track{background:transparent}#chat-widget-root .chat-messages::-webkit-scrollbar-thumb{background:rgba(156,163,175,.5);border-radius:10px}#chat-widget-root .chat-messages::-webkit-scrollbar-thumb:hover{background:rgba(156,163,175,.7)}#chat-widget-root .dark .chat-messages::-webkit-scrollbar-thumb{background:rgba(75,85,99,.5)}#chat-widget-root .dark .chat-messages::-webkit-scrollbar-thumb:hover{background:rgba(75,85,99,.7)}#chat-widget-root .pointer-events-none{pointer-events:none}#chat-widget-root .visible{visibility:visible}#chat-widget-root .collapse{visibility:collapse}#chat-widget-root .static{position:static}#chat-widget-root .fixed{position:fixed}#chat-widget-root .absolute{position:absolute}#chat-widget-root .relative{position:relative}#chat-widget-root .sticky{position:sticky}#chat-widget-root .inset-0{inset:0}#chat-widget-root .-top-8{top:-2rem}#chat-widget-root .bottom-0{bottom:0}#chat-widget-root .bottom-5{bottom:1.25rem}#chat-widget-root .bottom-full{bottom:100%}#chat-widget-root .left-0{left:0}#chat-widget-root .left-1\\/2{left:50%}#chat-widget-root .left-5{left:1.25rem}#chat-widget-root .right-0{right:0}#chat-widget-root .right-5{right:1.25rem}#chat-widget-root .top-0{top:0}#chat-widget-root .top-1\\/2{top:50%}#chat-widget-root .top-5{top:1.25rem}#chat-widget-root .top-full{top:100%}#chat-widget-root .isolate{isolation:isolate}#chat-widget-root .z-10{z-index:10}#chat-widget-root .z-50{z-index:50}#chat-widget-root .z-\\[60\\]{z-index:60}#chat-widget-root .z-\\[70\\]{z-index:70}#chat-widget-root .z-\\[71\\]{z-index:71}#chat-widget-root .z-\\[999999\\]{z-index:999999}#chat-widget-root .z-\\[9999\\]{z-index:9999}#chat-widget-root .m-0{margin:0}#chat-widget-root .mx-2{margin-left:.5rem;margin-right:.5rem}#chat-widget-root .my-3{margin-bottom:.75rem;margin-top:.75rem}#chat-widget-root .my-4{margin-bottom:1rem;margin-top:1rem}#chat-widget-root .-mb-px{margin-bottom:-1px}#chat-widget-root .mb-1{margin-bottom:.25rem}#chat-widget-root .mb-1\\.5{margin-bottom:.375rem}#chat-widget-root .mb-2{margin-bottom:.5rem}#chat-widget-root .mb-3{margin-bottom:.75rem}#chat-widget-root .mb-4{margin-bottom:1rem}#chat-widget-root .mb-5{margin-bottom:1.25rem}#chat-widget-root .ml-0\\.5{margin-left:.125rem}#chat-widget-root .ml-1{margin-left:.25rem}#chat-widget-root .mt-1{margin-top:.25rem}#chat-widget-root .mt-1\\.5{margin-top:.375rem}#chat-widget-root .mt-2{margin-top:.5rem}#chat-widget-root .mt-3{margin-top:.75rem}#chat-widget-root .mt-4{margin-top:1rem}#chat-widget-root .block{display:block}#chat-widget-root .inline-block{display:inline-block}#chat-widget-root .inline{display:inline}#chat-widget-root .flex{display:flex}#chat-widget-root .inline-flex{display:inline-flex}#chat-widget-root .table{display:table}#chat-widget-root .grid{display:grid}#chat-widget-root .hidden{display:none}#chat-widget-root .h-1\\.5{height:.375rem}#chat-widget-root .h-10{height:2.5rem}#chat-widget-root .h-12{height:3rem}#chat-widget-root .h-14{height:3.5rem}#chat-widget-root .h-16{height:4rem}#chat-widget-root .h-2{height:.5rem}#chat-widget-root .h-3{height:.75rem}#chat-widget-root .h-3\\.5{height:.875rem}#chat-widget-root .h-4{height:1rem}#chat-widget-root .h-5{height:1.25rem}#chat-widget-root .h-6{height:1.5rem}#chat-widget-root .h-7{height:1.75rem}#chat-widget-root .h-8{height:2rem}#chat-widget-root .h-\\[48px\\]{height:48px}#chat-widget-root .h-\\[650px\\]{height:650px}#chat-widget-root .h-auto{height:auto}#chat-widget-root .h-full{height:100%}#chat-widget-root .h-px{height:1px}#chat-widget-root .max-h-\\[85vh\\]{max-height:85vh}#chat-widget-root .min-h-0{min-height:0}#chat-widget-root .min-h-\\[48px\\]{min-height:48px}#chat-widget-root .w-1\\.5{width:.375rem}#chat-widget-root .w-10{width:2.5rem}#chat-widget-root .w-12{width:3rem}#chat-widget-root .w-14{width:3.5rem}#chat-widget-root .w-16{width:4rem}#chat-widget-root .w-2{width:.5rem}#chat-widget-root .w-3{width:.75rem}#chat-widget-root .w-3\\.5{width:.875rem}#chat-widget-root .w-4{width:1rem}#chat-widget-root .w-44{width:11rem}#chat-widget-root .w-5{width:1.25rem}#chat-widget-root .w-6{width:1.5rem}#chat-widget-root .w-7{width:1.75rem}#chat-widget-root .w-8{width:2rem}#chat-widget-root .w-80{width:20rem}#chat-widget-root .w-96{width:24rem}#chat-widget-root .w-\\[380px\\]{width:380px}#chat-widget-root .w-\\[48px\\]{width:48px}#chat-widget-root .w-full{width:100%}#chat-widget-root .min-w-0{min-width:0}#chat-widget-root .min-w-\\[60px\\]{min-width:60px}#chat-widget-root .min-w-full{min-width:100%}#chat-widget-root .max-w-\\[75\\%\\]{max-width:75%}#chat-widget-root .max-w-\\[92vw\\]{max-width:92vw}#chat-widget-root .max-w-full{max-width:100%}#chat-widget-root .max-w-none{max-width:none}#chat-widget-root .max-w-sm{max-width:24rem}#chat-widget-root .max-w-xs{max-width:20rem}#chat-widget-root .flex-1{flex:1 1 0%}#chat-widget-root .flex-shrink-0{flex-shrink:0}#chat-widget-root .border-collapse{border-collapse:collapse}#chat-widget-root .-translate-x-1\\/2{--tw-translate-x:-50%}#chat-widget-root .-translate-x-1\\/2,#chat-widget-root .-translate-y-1\\/2{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}#chat-widget-root .-translate-y-1\\/2{--tw-translate-y:-50%}#chat-widget-root .rotate-0{--tw-rotate:0deg}#chat-widget-root .rotate-0,#chat-widget-root .rotate-90{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}#chat-widget-root .rotate-90{--tw-rotate:90deg}#chat-widget-root .scale-0{--tw-scale-x:0;--tw-scale-y:0}#chat-widget-root .scale-0,#chat-widget-root .scale-100{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}#chat-widget-root .scale-100{--tw-scale-x:1;--tw-scale-y:1}#chat-widget-root .scale-110{--tw-scale-x:1.1;--tw-scale-y:1.1}#chat-widget-root .scale-110,#chat-widget-root .scale-125{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}#chat-widget-root .scale-125{--tw-scale-x:1.25;--tw-scale-y:1.25}#chat-widget-root .scale-95{--tw-scale-x:.95;--tw-scale-y:.95}#chat-widget-root .scale-95,#chat-widget-root .transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes bounce{0%,to{animation-timing-function:cubic-bezier(.8,0,1,1);transform:translateY(-25%)}50%{animation-timing-function:cubic-bezier(0,0,.2,1);transform:none}}#chat-widget-root .animate-bounce{animation:bounce 1s infinite}@keyframes pulse{50%{opacity:.5}}#chat-widget-root .animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(1turn)}}#chat-widget-root .animate-spin{animation:spin 1s linear infinite}#chat-widget-root .cursor-ew-resize{cursor:ew-resize}#chat-widget-root .cursor-not-allowed{cursor:not-allowed}#chat-widget-root .cursor-ns-resize{cursor:ns-resize}#chat-widget-root .cursor-nwse-resize{cursor:nwse-resize}#chat-widget-root .cursor-pointer{cursor:pointer}#chat-widget-root .resize-none{resize:none}#chat-widget-root .resize{resize:both}#chat-widget-root .list-decimal{list-style-type:decimal}#chat-widget-root .list-disc{list-style-type:disc}#chat-widget-root .list-none{list-style-type:none}#chat-widget-root .flex-row{flex-direction:row}#chat-widget-root .flex-row-reverse{flex-direction:row-reverse}#chat-widget-root .flex-col{flex-direction:column}#chat-widget-root .flex-wrap{flex-wrap:wrap}#chat-widget-root .items-start{align-items:flex-start}#chat-widget-root .items-end{align-items:flex-end}#chat-widget-root .items-center{align-items:center}#chat-widget-root .justify-start{justify-content:flex-start}#chat-widget-root .justify-end{justify-content:flex-end}#chat-widget-root .justify-center{justify-content:center}#chat-widget-root .justify-between{justify-content:space-between}#chat-widget-root .gap-0{gap:0}#chat-widget-root .gap-0\\.5{gap:.125rem}#chat-widget-root .gap-1{gap:.25rem}#chat-widget-root .gap-1\\.5{gap:.375rem}#chat-widget-root .gap-2{gap:.5rem}#chat-widget-root .gap-2\\.5{gap:.625rem}#chat-widget-root .gap-3{gap:.75rem}#chat-widget-root .gap-4{gap:1rem}#chat-widget-root .gap-6{gap:1.5rem}#chat-widget-root :is(.space-y-1>:not([hidden])~:not([hidden])){--tw-space-y-reverse:0;margin-bottom:calc(.25rem*var(--tw-space-y-reverse));margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))}#chat-widget-root :is(.space-y-2>:not([hidden])~:not([hidden])){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}#chat-widget-root :is(.space-y-4>:not([hidden])~:not([hidden])){--tw-space-y-reverse:0;margin-bottom:calc(1rem*var(--tw-space-y-reverse));margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))}#chat-widget-root .overflow-hidden{overflow:hidden}#chat-widget-root .overflow-visible{overflow:visible}#chat-widget-root .overflow-x-auto{overflow-x:auto}#chat-widget-root .overflow-y-auto{overflow-y:auto}#chat-widget-root .truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#chat-widget-root .whitespace-nowrap{white-space:nowrap}#chat-widget-root .whitespace-pre-wrap{white-space:pre-wrap}#chat-widget-root .break-words{overflow-wrap:break-word}#chat-widget-root .rounded{border-radius:.25rem}#chat-widget-root .rounded-2xl{border-radius:1rem}#chat-widget-root .rounded-3xl{border-radius:1.5rem}#chat-widget-root .rounded-full{border-radius:9999px}#chat-widget-root .rounded-lg{border-radius:.5rem}#chat-widget-root .rounded-md{border-radius:.375rem}#chat-widget-root .rounded-xl{border-radius:.75rem}#chat-widget-root .rounded-t-2xl{border-top-left-radius:1rem;border-top-right-radius:1rem}#chat-widget-root .rounded-tl-sm{border-top-left-radius:.125rem}#chat-widget-root .rounded-tr-sm{border-top-right-radius:.125rem}#chat-widget-root .border{border-width:1px}#chat-widget-root .border-0{border-width:0}#chat-widget-root .border-b{border-bottom-width:1px}#chat-widget-root .border-l-4{border-left-width:4px}#chat-widget-root .border-t{border-top-width:1px}#chat-widget-root .border-t-2{border-top-width:2px}#chat-widget-root .border-dotted{border-style:dotted}#chat-widget-root .border-none{border-style:none}#chat-widget-root .\\!border-red-500{--tw-border-opacity:1!important;border-color:rgb(239 68 68/var(--tw-border-opacity,1))!important}#chat-widget-root .border-blue-200{--tw-border-opacity:1;border-color:rgb(191 219 254/var(--tw-border-opacity,1))}#chat-widget-root .border-blue-700\\/50{border-color:rgba(29,78,216,.5)}#chat-widget-root .border-gray-100{--tw-border-opacity:1;border-color:rgb(243 244 246/var(--tw-border-opacity,1))}#chat-widget-root .border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1))}#chat-widget-root .border-gray-200\\/60{border-color:rgba(229,231,235,.6)}#chat-widget-root .border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1))}#chat-widget-root .border-gray-600{--tw-border-opacity:1;border-color:rgb(75 85 99/var(--tw-border-opacity,1))}#chat-widget-root .border-gray-700{--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity,1))}#chat-widget-root .border-gray-700\\/50{border-color:rgba(55,65,81,.5)}#chat-widget-root .bg-blue-50{--tw-bg-opacity:1;background-color:rgb(239 246 255/var(--tw-bg-opacity,1))}#chat-widget-root .bg-blue-500{--tw-bg-opacity:1;background-color:rgb(59 130 246/var(--tw-bg-opacity,1))}#chat-widget-root .bg-blue-900\\/30{background-color:rgba(30,58,138,.3)}#chat-widget-root .bg-current{background-color:currentColor}#chat-widget-root .bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}#chat-widget-root .bg-gray-400{--tw-bg-opacity:1;background-color:rgb(156 163 175/var(--tw-bg-opacity,1))}#chat-widget-root .bg-gray-50{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}#chat-widget-root .bg-gray-700{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity,1))}#chat-widget-root .bg-gray-700\\/50{background-color:rgba(55,65,81,.5)}#chat-widget-root .bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity,1))}#chat-widget-root .bg-gray-900{--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity,1))}#chat-widget-root .bg-green-200{--tw-bg-opacity:1;background-color:rgb(187 247 208/var(--tw-bg-opacity,1))}#chat-widget-root .bg-orange-200{--tw-bg-opacity:1;background-color:rgb(254 215 170/var(--tw-bg-opacity,1))}#chat-widget-root .bg-pink-200{--tw-bg-opacity:1;background-color:rgb(251 207 232/var(--tw-bg-opacity,1))}#chat-widget-root .bg-red-200{--tw-bg-opacity:1;background-color:rgb(254 202 202/var(--tw-bg-opacity,1))}#chat-widget-root .bg-red-500{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity,1))}#chat-widget-root .bg-slate-50\\/50{background-color:rgba(248,250,252,.5)}#chat-widget-root .bg-slate-800\\/50{background-color:rgba(30,41,59,.5)}#chat-widget-root .bg-transparent{background-color:transparent}#chat-widget-root .bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}#chat-widget-root .bg-white\\/10{background-color:hsla(0,0%,100%,.1)}#chat-widget-root .bg-white\\/20{background-color:hsla(0,0%,100%,.2)}#chat-widget-root .bg-yellow-200{--tw-bg-opacity:1;background-color:rgb(254 240 138/var(--tw-bg-opacity,1))}#chat-widget-root .bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--tw-gradient-stops))}#chat-widget-root .bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}#chat-widget-root .from-gray-50\\/50{--tw-gradient-from:rgba(249,250,251,.5) var(--tw-gradient-from-position);--tw-gradient-to:rgba(249,250,251,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}#chat-widget-root .from-white\\/0{--tw-gradient-from:hsla(0,0%,100%,0) var(--tw-gradient-from-position);--tw-gradient-to:hsla(0,0%,100%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}#chat-widget-root .from-white\\/10{--tw-gradient-from:hsla(0,0%,100%,.1) var(--tw-gradient-from-position);--tw-gradient-to:hsla(0,0%,100%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}#chat-widget-root .from-yellow-200{--tw-gradient-from:#fef08a var(--tw-gradient-from-position);--tw-gradient-to:hsla(53,98%,77%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}#chat-widget-root .via-white\\/5{--tw-gradient-to:hsla(0,0%,100%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),hsla(0,0%,100%,.05) var(--tw-gradient-via-position),var(--tw-gradient-to)}#chat-widget-root .to-transparent{--tw-gradient-to:transparent var(--tw-gradient-to-position)}#chat-widget-root .to-white{--tw-gradient-to:#fff var(--tw-gradient-to-position)}#chat-widget-root .to-white\\/10{--tw-gradient-to:hsla(0,0%,100%,.1) var(--tw-gradient-to-position)}#chat-widget-root .to-yellow-400{--tw-gradient-to:#facc15 var(--tw-gradient-to-position)}#chat-widget-root .object-cover{-o-object-fit:cover;object-fit:cover}#chat-widget-root .p-0{padding:0}#chat-widget-root .p-0\\.5{padding:.125rem}#chat-widget-root .p-3{padding:.75rem}#chat-widget-root .p-5{padding:1.25rem}#chat-widget-root .p-6{padding:1.5rem}#chat-widget-root .p-8{padding:2rem}#chat-widget-root .px-1{padding-left:.25rem;padding-right:.25rem}#chat-widget-root .px-2{padding-left:.5rem;padding-right:.5rem}#chat-widget-root .px-2\\.5{padding-left:.625rem;padding-right:.625rem}#chat-widget-root .px-3{padding-left:.75rem;padding-right:.75rem}#chat-widget-root .px-4{padding-left:1rem;padding-right:1rem}#chat-widget-root .px-5{padding-left:1.25rem;padding-right:1.25rem}#chat-widget-root .py-1{padding-bottom:.25rem;padding-top:.25rem}#chat-widget-root .py-1\\.5{padding-bottom:.375rem;padding-top:.375rem}#chat-widget-root .py-12{padding-bottom:3rem;padding-top:3rem}#chat-widget-root .py-2{padding-bottom:.5rem;padding-top:.5rem}#chat-widget-root .py-2\\.5{padding-bottom:.625rem;padding-top:.625rem}#chat-widget-root .py-3{padding-bottom:.75rem;padding-top:.75rem}#chat-widget-root .py-3\\.5{padding-bottom:.875rem;padding-top:.875rem}#chat-widget-root .py-4{padding-bottom:1rem;padding-top:1rem}#chat-widget-root .pb-1{padding-bottom:.25rem}#chat-widget-root .pb-2{padding-bottom:.5rem}#chat-widget-root .pl-2{padding-left:.5rem}#chat-widget-root .pl-4{padding-left:1rem}#chat-widget-root .pl-\\[50px\\]{padding-left:50px}#chat-widget-root .pr-1{padding-right:.25rem}#chat-widget-root .pt-1{padding-top:.25rem}#chat-widget-root .text-left{text-align:left}#chat-widget-root .text-center{text-align:center}#chat-widget-root .text-right{text-align:right}#chat-widget-root .align-text-bottom{vertical-align:text-bottom}#chat-widget-root .font-sans{font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}#chat-widget-root .text-2xl{font-size:1.5rem;line-height:2rem}#chat-widget-root .text-\\[10px\\]{font-size:10px}#chat-widget-root .text-\\[11px\\]{font-size:11px}#chat-widget-root .text-\\[15px\\]{font-size:15px}#chat-widget-root .text-base{font-size:1rem;line-height:1.5rem}#chat-widget-root .text-lg{font-size:1.125rem;line-height:1.75rem}#chat-widget-root .text-sm{font-size:.875rem;line-height:1.25rem}#chat-widget-root .text-xl{font-size:1.25rem;line-height:1.75rem}#chat-widget-root .text-xs{font-size:.75rem;line-height:1rem}#chat-widget-root .font-bold{font-weight:700}#chat-widget-root .font-medium{font-weight:500}#chat-widget-root .font-semibold{font-weight:600}#chat-widget-root .uppercase{text-transform:uppercase}#chat-widget-root .lowercase{text-transform:lowercase}#chat-widget-root .italic{font-style:italic}#chat-widget-root .tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}#chat-widget-root .leading-5{line-height:1.25rem}#chat-widget-root .leading-none{line-height:1}#chat-widget-root .leading-normal{line-height:1.5}#chat-widget-root .leading-relaxed{line-height:1.625}#chat-widget-root .leading-tight{line-height:1.25}#chat-widget-root .tracking-wide{letter-spacing:.025em}#chat-widget-root .text-\\[\\#4A5568\\]{--tw-text-opacity:1;color:rgb(74 85 104/var(--tw-text-opacity,1))}#chat-widget-root .text-current{color:currentColor}#chat-widget-root .text-gray-100{--tw-text-opacity:1;color:rgb(243 244 246/var(--tw-text-opacity,1))}#chat-widget-root .text-gray-200{--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity,1))}#chat-widget-root .text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity,1))}#chat-widget-root .text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}#chat-widget-root .text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}#chat-widget-root .text-gray-500\\/80{color:hsla(220,9%,46%,.8)}#chat-widget-root .text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}#chat-widget-root .text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}#chat-widget-root .text-gray-800{--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity,1))}#chat-widget-root .text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}#chat-widget-root .text-green-500{--tw-text-opacity:1;color:rgb(34 197 94/var(--tw-text-opacity,1))}#chat-widget-root .text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}#chat-widget-root .text-slate-400{--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity,1))}#chat-widget-root .text-slate-500{--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity,1))}#chat-widget-root .text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}#chat-widget-root .text-yellow-400{--tw-text-opacity:1;color:rgb(250 204 21/var(--tw-text-opacity,1))}#chat-widget-root .no-underline{text-decoration-line:none}#chat-widget-root .placeholder-gray-400::-moz-placeholder{--tw-placeholder-opacity:1;color:rgb(156 163 175/var(--tw-placeholder-opacity,1))}#chat-widget-root .placeholder-gray-400::placeholder{--tw-placeholder-opacity:1;color:rgb(156 163 175/var(--tw-placeholder-opacity,1))}#chat-widget-root .placeholder-gray-500::-moz-placeholder{--tw-placeholder-opacity:1;color:rgb(107 114 128/var(--tw-placeholder-opacity,1))}#chat-widget-root .placeholder-gray-500::placeholder{--tw-placeholder-opacity:1;color:rgb(107 114 128/var(--tw-placeholder-opacity,1))}#chat-widget-root .opacity-0{opacity:0}#chat-widget-root .opacity-50{opacity:.5}#chat-widget-root .opacity-60{opacity:.6}#chat-widget-root .opacity-70{opacity:.7}#chat-widget-root .opacity-80{opacity:.8}#chat-widget-root .shadow{--tw-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1);--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color)}#chat-widget-root .shadow,#chat-widget-root .shadow-2xl{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}#chat-widget-root .shadow-2xl{--tw-shadow:0 25px 50px -12px rgba(0,0,0,.25);--tw-shadow-colored:0 25px 50px -12px var(--tw-shadow-color)}#chat-widget-root .shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}#chat-widget-root .shadow-lg,#chat-widget-root .shadow-md{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}#chat-widget-root .shadow-md{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}#chat-widget-root .shadow-none{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000}#chat-widget-root .shadow-none,#chat-widget-root .shadow-sm{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}#chat-widget-root .shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}#chat-widget-root .shadow-xl{--tw-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 8px 10px -6px rgba(0,0,0,.1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}#chat-widget-root .shadow-black\\/20{--tw-shadow-color:rgba(0,0,0,.2);--tw-shadow:var(--tw-shadow-colored)}#chat-widget-root .shadow-gray-200\\/80{--tw-shadow-color:rgba(229,231,235,.8);--tw-shadow:var(--tw-shadow-colored)}#chat-widget-root .outline-none{outline:2px solid transparent;outline-offset:2px}#chat-widget-root .ring-2{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}#chat-widget-root .ring-blue-100{--tw-ring-opacity:1;--tw-ring-color:rgb(219 234 254/var(--tw-ring-opacity,1))}#chat-widget-root .ring-blue-300{--tw-ring-opacity:1;--tw-ring-color:rgb(147 197 253/var(--tw-ring-opacity,1))}#chat-widget-root .blur{--tw-blur:blur(8px)}#chat-widget-root .blur,#chat-widget-root .drop-shadow{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}#chat-widget-root .drop-shadow{--tw-drop-shadow:drop-shadow(0 1px 2px rgba(0,0,0,.1)) drop-shadow(0 1px 1px rgba(0,0,0,.06))}#chat-widget-root .drop-shadow-md{--tw-drop-shadow:drop-shadow(0 4px 3px rgba(0,0,0,.07)) drop-shadow(0 2px 2px rgba(0,0,0,.06))}#chat-widget-root .drop-shadow-md,#chat-widget-root .drop-shadow-sm{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}#chat-widget-root .drop-shadow-sm{--tw-drop-shadow:drop-shadow(0 1px 1px rgba(0,0,0,.05))}#chat-widget-root .grayscale-\\[0\\.3\\]{--tw-grayscale:grayscale(0.3)}#chat-widget-root .filter,#chat-widget-root .grayscale-\\[0\\.3\\]{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}#chat-widget-root .backdrop-blur-sm{--tw-backdrop-blur:blur(4px);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}#chat-widget-root .transition{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}#chat-widget-root .transition-all{transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1)}#chat-widget-root .transition-colors{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}#chat-widget-root .transition-opacity{transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}#chat-widget-root .transition-transform{transition-duration:.15s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}#chat-widget-root .duration-150{transition-duration:.15s}#chat-widget-root .duration-200{transition-duration:.2s}#chat-widget-root .duration-300{transition-duration:.3s}#chat-widget-root .duration-500{transition-duration:.5s}#chat-widget-root :is(#chat-widget-root .animate-in){animation:slideIn .3s ease-out}#chat-widget-root :is(#chat-widget-root .transition-all){transition-duration:.3s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1)}#chat-widget-root .\\[font-family\\:inherit\\]{font-family:inherit}#chat-widget-root .placeholder\\:text-\\[\\#8C8C8C\\]::-moz-placeholder{--tw-text-opacity:1;color:rgb(140 140 140/var(--tw-text-opacity,1))}#chat-widget-root .placeholder\\:text-\\[\\#8C8C8C\\]::placeholder{--tw-text-opacity:1;color:rgb(140 140 140/var(--tw-text-opacity,1))}#chat-widget-root .placeholder\\:text-\\[\\#A2A9B2\\]::-moz-placeholder{--tw-text-opacity:1;color:rgb(162 169 178/var(--tw-text-opacity,1))}#chat-widget-root .placeholder\\:text-\\[\\#A2A9B2\\]::placeholder{--tw-text-opacity:1;color:rgb(162 169 178/var(--tw-text-opacity,1))}#chat-widget-root .hover\\:scale-105:hover{--tw-scale-x:1.05;--tw-scale-y:1.05}#chat-widget-root .hover\\:scale-105:hover,#chat-widget-root .hover\\:scale-110:hover{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}#chat-widget-root .hover\\:scale-110:hover{--tw-scale-x:1.1;--tw-scale-y:1.1}#chat-widget-root .hover\\:scale-\\[1\\.02\\]:hover{--tw-scale-x:1.02;--tw-scale-y:1.02;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}#chat-widget-root .hover\\:border-blue-400:hover{--tw-border-opacity:1;border-color:rgb(96 165 250/var(--tw-border-opacity,1))}#chat-widget-root .hover\\:border-blue-600:hover{--tw-border-opacity:1;border-color:rgb(37 99 235/var(--tw-border-opacity,1))}#chat-widget-root .hover\\:bg-blue-50:hover{--tw-bg-opacity:1;background-color:rgb(239 246 255/var(--tw-bg-opacity,1))}#chat-widget-root .hover\\:bg-blue-500\\/20:hover{background-color:rgba(59,130,246,.2)}#chat-widget-root .hover\\:bg-blue-900\\/50:hover{background-color:rgba(30,58,138,.5)}#chat-widget-root .hover\\:bg-gray-100:hover{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}#chat-widget-root .hover\\:bg-gray-200:hover{--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity,1))}#chat-widget-root .hover\\:bg-gray-50:hover{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}#chat-widget-root .hover\\:bg-gray-600:hover{--tw-bg-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity,1))}#chat-widget-root .hover\\:bg-gray-700:hover{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity,1))}#chat-widget-root .hover\\:bg-red-600:hover{--tw-bg-opacity:1;background-color:rgb(220 38 38/var(--tw-bg-opacity,1))}#chat-widget-root .hover\\:bg-transparent:hover{background-color:transparent}#chat-widget-root .hover\\:text-blue-500:hover{--tw-text-opacity:1;color:rgb(59 130 246/var(--tw-text-opacity,1))}#chat-widget-root .hover\\:text-gray-200:hover{--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity,1))}#chat-widget-root .hover\\:text-gray-300:hover{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity,1))}#chat-widget-root .hover\\:text-gray-600:hover{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}#chat-widget-root .hover\\:text-gray-700:hover{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}#chat-widget-root .hover\\:underline:hover{text-decoration-line:underline}#chat-widget-root .hover\\:opacity-80:hover{opacity:.8}#chat-widget-root .hover\\:opacity-90:hover{opacity:.9}#chat-widget-root .hover\\:shadow-md:hover{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}#chat-widget-root .hover\\:shadow-md:hover,#chat-widget-root .hover\\:shadow-xl:hover{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}#chat-widget-root .hover\\:shadow-xl:hover{--tw-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 8px 10px -6px rgba(0,0,0,.1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color)}#chat-widget-root .hover\\:grayscale-0:hover{--tw-grayscale:grayscale(0);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}#chat-widget-root .focus\\:\\!border-red-500:focus{--tw-border-opacity:1!important;border-color:rgb(239 68 68/var(--tw-border-opacity,1))!important}#chat-widget-root .focus\\:border-\\[\\#5A6069\\]:focus{--tw-border-opacity:1;border-color:rgb(90 96 105/var(--tw-border-opacity,1))}#chat-widget-root .focus\\:border-\\[\\#B0B0B0\\]:focus{--tw-border-opacity:1;border-color:rgb(176 176 176/var(--tw-border-opacity,1))}#chat-widget-root .focus\\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}#chat-widget-root .focus\\:ring-0:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color)}#chat-widget-root .focus\\:ring-0:focus,#chat-widget-root .focus\\:ring-1:focus{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}#chat-widget-root .focus\\:ring-1:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)}#chat-widget-root .focus\\:ring-gray-300:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(209 213 219/var(--tw-ring-opacity,1))}#chat-widget-root .focus\\:ring-gray-600:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(75 85 99/var(--tw-ring-opacity,1))}#chat-widget-root .focus-visible\\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}#chat-widget-root .focus-visible\\:ring-2:focus-visible{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}#chat-widget-root .focus-visible\\:ring-white\\/40:focus-visible{--tw-ring-color:hsla(0,0%,100%,.4)}#chat-widget-root .active\\:scale-95:active{--tw-scale-x:.95;--tw-scale-y:.95}#chat-widget-root .active\\:scale-95:active,#chat-widget-root .active\\:scale-\\[0\\.97\\]:active{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}#chat-widget-root .active\\:scale-\\[0\\.97\\]:active{--tw-scale-x:0.97;--tw-scale-y:0.97}#chat-widget-root .active\\:scale-\\[0\\.98\\]:active{--tw-scale-x:0.98;--tw-scale-y:0.98;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}#chat-widget-root .active\\:outline-none:active{outline:2px solid transparent;outline-offset:2px}#chat-widget-root .active\\:ring-0:active{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}#chat-widget-root .disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}#chat-widget-root .disabled\\:opacity-40:disabled{opacity:.4}#chat-widget-root .disabled\\:opacity-50:disabled{opacity:.5}#chat-widget-root .disabled\\:shadow-none:disabled{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}#chat-widget-root :is(.group:hover .group-hover\\:scale-100){--tw-scale-x:1;--tw-scale-y:1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}#chat-widget-root :is(.group:hover .group-hover\\:opacity-100){opacity:1}#chat-widget-root .dark\\:text-gray-300:is(.dark *){--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity,1))}#chat-widget-root .dark\\:text-gray-400:is(.dark *){--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}#chat-widget-root .rtl\\:rounded-tl-2xl:where([dir=rtl],[dir=rtl] *){border-top-left-radius:1rem}#chat-widget-root .rtl\\:rounded-tr-sm:where([dir=rtl],[dir=rtl] *){border-top-right-radius:.125rem}#chat-widget-root .\\[\\&\\:first-child\\]\\:\\!mt-0:first-child{margin-top:0!important}#chat-widget-root :is(.\\[\\&\\>\\*\\:first-child\\]\\:\\!mt-0>:first-child){margin-top:0!important}#chat-widget-root :is(.\\[\\&\\>\\*\\:last-child\\]\\:\\!mb-0>:last-child){margin-bottom:0!important}";
7872
+ var css_248z$1 = "*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }.chat-widget-root{--cw-primary:#2563eb;--cw-primary-hover:#1d4ed8;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}.\\!container{width:100%!important}.container{width:100%}@media (min-width:640px){.\\!container{max-width:640px!important}.container{max-width:640px}}@media (min-width:768px){.\\!container{max-width:768px!important}.container{max-width:768px}}@media (min-width:1024px){.\\!container{max-width:1024px!important}.container{max-width:1024px}}@media (min-width:1280px){.\\!container{max-width:1280px!important}.container{max-width:1280px}}@media (min-width:1536px){.\\!container{max-width:1536px!important}.container{max-width:1536px}}#chat-widget-root .chat-widget-root *{box-sizing:border-box;margin:0;padding:0}#chat-widget-root .chat-messages::-webkit-scrollbar{width:6px}#chat-widget-root .chat-messages::-webkit-scrollbar-track{background:transparent}#chat-widget-root .chat-messages::-webkit-scrollbar-thumb{background:rgba(156,163,175,.5);border-radius:10px}#chat-widget-root .chat-messages::-webkit-scrollbar-thumb:hover{background:rgba(156,163,175,.7)}#chat-widget-root .dark .chat-messages::-webkit-scrollbar-thumb{background:rgba(75,85,99,.5)}#chat-widget-root .dark .chat-messages::-webkit-scrollbar-thumb:hover{background:rgba(75,85,99,.7)}#chat-widget-root .pointer-events-none{pointer-events:none}#chat-widget-root .visible{visibility:visible}#chat-widget-root .collapse{visibility:collapse}#chat-widget-root .static{position:static}#chat-widget-root .fixed{position:fixed}#chat-widget-root .absolute{position:absolute}#chat-widget-root .relative{position:relative}#chat-widget-root .sticky{position:sticky}#chat-widget-root .inset-0{inset:0}#chat-widget-root .-top-8{top:-2rem}#chat-widget-root .bottom-0{bottom:0}#chat-widget-root .bottom-5{bottom:1.25rem}#chat-widget-root .bottom-full{bottom:100%}#chat-widget-root .left-0{left:0}#chat-widget-root .left-1\\/2{left:50%}#chat-widget-root .left-5{left:1.25rem}#chat-widget-root .right-0{right:0}#chat-widget-root .right-5{right:1.25rem}#chat-widget-root .top-0{top:0}#chat-widget-root .top-1\\/2{top:50%}#chat-widget-root .top-5{top:1.25rem}#chat-widget-root .top-full{top:100%}#chat-widget-root .isolate{isolation:isolate}#chat-widget-root .z-10{z-index:10}#chat-widget-root .z-50{z-index:50}#chat-widget-root .z-\\[60\\]{z-index:60}#chat-widget-root .z-\\[70\\]{z-index:70}#chat-widget-root .z-\\[71\\]{z-index:71}#chat-widget-root .z-\\[999999\\]{z-index:999999}#chat-widget-root .z-\\[9999\\]{z-index:9999}#chat-widget-root .m-0{margin:0}#chat-widget-root .mx-2{margin-left:.5rem;margin-right:.5rem}#chat-widget-root .my-3{margin-bottom:.75rem;margin-top:.75rem}#chat-widget-root .my-4{margin-bottom:1rem;margin-top:1rem}#chat-widget-root .-mb-px{margin-bottom:-1px}#chat-widget-root .mb-1{margin-bottom:.25rem}#chat-widget-root .mb-1\\.5{margin-bottom:.375rem}#chat-widget-root .mb-2{margin-bottom:.5rem}#chat-widget-root .mb-3{margin-bottom:.75rem}#chat-widget-root .mb-4{margin-bottom:1rem}#chat-widget-root .mb-5{margin-bottom:1.25rem}#chat-widget-root .ml-0\\.5{margin-left:.125rem}#chat-widget-root .ml-1{margin-left:.25rem}#chat-widget-root .mt-1{margin-top:.25rem}#chat-widget-root .mt-1\\.5{margin-top:.375rem}#chat-widget-root .mt-2{margin-top:.5rem}#chat-widget-root .mt-3{margin-top:.75rem}#chat-widget-root .mt-4{margin-top:1rem}#chat-widget-root .block{display:block}#chat-widget-root .inline-block{display:inline-block}#chat-widget-root .inline{display:inline}#chat-widget-root .flex{display:flex}#chat-widget-root .inline-flex{display:inline-flex}#chat-widget-root .table{display:table}#chat-widget-root .grid{display:grid}#chat-widget-root .hidden{display:none}#chat-widget-root .h-1\\.5{height:.375rem}#chat-widget-root .h-10{height:2.5rem}#chat-widget-root .h-12{height:3rem}#chat-widget-root .h-14{height:3.5rem}#chat-widget-root .h-16{height:4rem}#chat-widget-root .h-2{height:.5rem}#chat-widget-root .h-3{height:.75rem}#chat-widget-root .h-3\\.5{height:.875rem}#chat-widget-root .h-4{height:1rem}#chat-widget-root .h-5{height:1.25rem}#chat-widget-root .h-6{height:1.5rem}#chat-widget-root .h-7{height:1.75rem}#chat-widget-root .h-8{height:2rem}#chat-widget-root .h-\\[48px\\]{height:48px}#chat-widget-root .h-\\[650px\\]{height:650px}#chat-widget-root .h-auto{height:auto}#chat-widget-root .h-full{height:100%}#chat-widget-root .h-px{height:1px}#chat-widget-root .max-h-\\[85vh\\]{max-height:85vh}#chat-widget-root .min-h-0{min-height:0}#chat-widget-root .min-h-\\[48px\\]{min-height:48px}#chat-widget-root .w-1\\.5{width:.375rem}#chat-widget-root .w-10{width:2.5rem}#chat-widget-root .w-12{width:3rem}#chat-widget-root .w-14{width:3.5rem}#chat-widget-root .w-16{width:4rem}#chat-widget-root .w-2{width:.5rem}#chat-widget-root .w-3{width:.75rem}#chat-widget-root .w-3\\.5{width:.875rem}#chat-widget-root .w-4{width:1rem}#chat-widget-root .w-44{width:11rem}#chat-widget-root .w-5{width:1.25rem}#chat-widget-root .w-6{width:1.5rem}#chat-widget-root .w-7{width:1.75rem}#chat-widget-root .w-8{width:2rem}#chat-widget-root .w-80{width:20rem}#chat-widget-root .w-96{width:24rem}#chat-widget-root .w-\\[380px\\]{width:380px}#chat-widget-root .w-\\[48px\\]{width:48px}#chat-widget-root .w-full{width:100%}#chat-widget-root .min-w-0{min-width:0}#chat-widget-root .min-w-\\[60px\\]{min-width:60px}#chat-widget-root .min-w-full{min-width:100%}#chat-widget-root .max-w-\\[75\\%\\]{max-width:75%}#chat-widget-root .max-w-\\[92vw\\]{max-width:92vw}#chat-widget-root .max-w-full{max-width:100%}#chat-widget-root .max-w-none{max-width:none}#chat-widget-root .max-w-sm{max-width:24rem}#chat-widget-root .max-w-xs{max-width:20rem}#chat-widget-root .flex-1{flex:1 1 0%}#chat-widget-root .flex-shrink-0{flex-shrink:0}#chat-widget-root .border-collapse{border-collapse:collapse}#chat-widget-root .-translate-x-1\\/2{--tw-translate-x:-50%}#chat-widget-root .-translate-x-1\\/2,#chat-widget-root .-translate-y-1\\/2{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}#chat-widget-root .-translate-y-1\\/2{--tw-translate-y:-50%}#chat-widget-root .-rotate-90{--tw-rotate:-90deg}#chat-widget-root .-rotate-90,#chat-widget-root .rotate-0{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}#chat-widget-root .rotate-0{--tw-rotate:0deg}#chat-widget-root .rotate-180{--tw-rotate:180deg}#chat-widget-root .rotate-180,#chat-widget-root .rotate-90{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}#chat-widget-root .rotate-90{--tw-rotate:90deg}#chat-widget-root .scale-0{--tw-scale-x:0;--tw-scale-y:0}#chat-widget-root .scale-0,#chat-widget-root .scale-100{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}#chat-widget-root .scale-100{--tw-scale-x:1;--tw-scale-y:1}#chat-widget-root .scale-110{--tw-scale-x:1.1;--tw-scale-y:1.1}#chat-widget-root .scale-110,#chat-widget-root .scale-125{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}#chat-widget-root .scale-125{--tw-scale-x:1.25;--tw-scale-y:1.25}#chat-widget-root .scale-95{--tw-scale-x:.95;--tw-scale-y:.95}#chat-widget-root .scale-95,#chat-widget-root .transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes bounce{0%,to{animation-timing-function:cubic-bezier(.8,0,1,1);transform:translateY(-25%)}50%{animation-timing-function:cubic-bezier(0,0,.2,1);transform:none}}#chat-widget-root .animate-bounce{animation:bounce 1s infinite}@keyframes pulse{50%{opacity:.5}}#chat-widget-root .animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(1turn)}}#chat-widget-root .animate-spin{animation:spin 1s linear infinite}#chat-widget-root .cursor-ew-resize{cursor:ew-resize}#chat-widget-root .cursor-nesw-resize{cursor:nesw-resize}#chat-widget-root .cursor-not-allowed{cursor:not-allowed}#chat-widget-root .cursor-ns-resize{cursor:ns-resize}#chat-widget-root .cursor-nwse-resize{cursor:nwse-resize}#chat-widget-root .cursor-pointer{cursor:pointer}#chat-widget-root .resize-none{resize:none}#chat-widget-root .resize{resize:both}#chat-widget-root .list-decimal{list-style-type:decimal}#chat-widget-root .list-disc{list-style-type:disc}#chat-widget-root .list-none{list-style-type:none}#chat-widget-root .flex-row{flex-direction:row}#chat-widget-root .flex-row-reverse{flex-direction:row-reverse}#chat-widget-root .flex-col{flex-direction:column}#chat-widget-root .flex-wrap{flex-wrap:wrap}#chat-widget-root .items-start{align-items:flex-start}#chat-widget-root .items-end{align-items:flex-end}#chat-widget-root .items-center{align-items:center}#chat-widget-root .justify-start{justify-content:flex-start}#chat-widget-root .justify-end{justify-content:flex-end}#chat-widget-root .justify-center{justify-content:center}#chat-widget-root .justify-between{justify-content:space-between}#chat-widget-root .gap-0{gap:0}#chat-widget-root .gap-0\\.5{gap:.125rem}#chat-widget-root .gap-1{gap:.25rem}#chat-widget-root .gap-1\\.5{gap:.375rem}#chat-widget-root .gap-2{gap:.5rem}#chat-widget-root .gap-2\\.5{gap:.625rem}#chat-widget-root .gap-3{gap:.75rem}#chat-widget-root .gap-4{gap:1rem}#chat-widget-root .gap-6{gap:1.5rem}#chat-widget-root :is(.space-y-1>:not([hidden])~:not([hidden])){--tw-space-y-reverse:0;margin-bottom:calc(.25rem*var(--tw-space-y-reverse));margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))}#chat-widget-root :is(.space-y-2>:not([hidden])~:not([hidden])){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}#chat-widget-root :is(.space-y-4>:not([hidden])~:not([hidden])){--tw-space-y-reverse:0;margin-bottom:calc(1rem*var(--tw-space-y-reverse));margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))}#chat-widget-root .overflow-hidden{overflow:hidden}#chat-widget-root .overflow-visible{overflow:visible}#chat-widget-root .overflow-x-auto{overflow-x:auto}#chat-widget-root .overflow-y-auto{overflow-y:auto}#chat-widget-root .truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#chat-widget-root .whitespace-nowrap{white-space:nowrap}#chat-widget-root .whitespace-pre-wrap{white-space:pre-wrap}#chat-widget-root .break-words{overflow-wrap:break-word}#chat-widget-root .rounded{border-radius:.25rem}#chat-widget-root .rounded-2xl{border-radius:1rem}#chat-widget-root .rounded-3xl{border-radius:1.5rem}#chat-widget-root .rounded-full{border-radius:9999px}#chat-widget-root .rounded-lg{border-radius:.5rem}#chat-widget-root .rounded-md{border-radius:.375rem}#chat-widget-root .rounded-xl{border-radius:.75rem}#chat-widget-root .rounded-t-2xl{border-top-left-radius:1rem;border-top-right-radius:1rem}#chat-widget-root .rounded-tl-sm{border-top-left-radius:.125rem}#chat-widget-root .rounded-tr-sm{border-top-right-radius:.125rem}#chat-widget-root .border{border-width:1px}#chat-widget-root .border-0{border-width:0}#chat-widget-root .border-b{border-bottom-width:1px}#chat-widget-root .border-l-4{border-left-width:4px}#chat-widget-root .border-t{border-top-width:1px}#chat-widget-root .border-t-2{border-top-width:2px}#chat-widget-root .border-dotted{border-style:dotted}#chat-widget-root .border-none{border-style:none}#chat-widget-root .\\!border-red-500{--tw-border-opacity:1!important;border-color:rgb(239 68 68/var(--tw-border-opacity,1))!important}#chat-widget-root .border-blue-200{--tw-border-opacity:1;border-color:rgb(191 219 254/var(--tw-border-opacity,1))}#chat-widget-root .border-blue-700\\/50{border-color:rgba(29,78,216,.5)}#chat-widget-root .border-gray-100{--tw-border-opacity:1;border-color:rgb(243 244 246/var(--tw-border-opacity,1))}#chat-widget-root .border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1))}#chat-widget-root .border-gray-200\\/60{border-color:rgba(229,231,235,.6)}#chat-widget-root .border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1))}#chat-widget-root .border-gray-600{--tw-border-opacity:1;border-color:rgb(75 85 99/var(--tw-border-opacity,1))}#chat-widget-root .border-gray-700{--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity,1))}#chat-widget-root .border-gray-700\\/50{border-color:rgba(55,65,81,.5)}#chat-widget-root .bg-blue-50{--tw-bg-opacity:1;background-color:rgb(239 246 255/var(--tw-bg-opacity,1))}#chat-widget-root .bg-blue-500{--tw-bg-opacity:1;background-color:rgb(59 130 246/var(--tw-bg-opacity,1))}#chat-widget-root .bg-blue-900\\/30{background-color:rgba(30,58,138,.3)}#chat-widget-root .bg-current{background-color:currentColor}#chat-widget-root .bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}#chat-widget-root .bg-gray-400{--tw-bg-opacity:1;background-color:rgb(156 163 175/var(--tw-bg-opacity,1))}#chat-widget-root .bg-gray-50{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}#chat-widget-root .bg-gray-700{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity,1))}#chat-widget-root .bg-gray-700\\/50{background-color:rgba(55,65,81,.5)}#chat-widget-root .bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity,1))}#chat-widget-root .bg-gray-900{--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity,1))}#chat-widget-root .bg-green-200{--tw-bg-opacity:1;background-color:rgb(187 247 208/var(--tw-bg-opacity,1))}#chat-widget-root .bg-orange-200{--tw-bg-opacity:1;background-color:rgb(254 215 170/var(--tw-bg-opacity,1))}#chat-widget-root .bg-pink-200{--tw-bg-opacity:1;background-color:rgb(251 207 232/var(--tw-bg-opacity,1))}#chat-widget-root .bg-red-200{--tw-bg-opacity:1;background-color:rgb(254 202 202/var(--tw-bg-opacity,1))}#chat-widget-root .bg-red-500{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity,1))}#chat-widget-root .bg-slate-50\\/50{background-color:rgba(248,250,252,.5)}#chat-widget-root .bg-slate-800\\/50{background-color:rgba(30,41,59,.5)}#chat-widget-root .bg-transparent{background-color:transparent}#chat-widget-root .bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}#chat-widget-root .bg-white\\/10{background-color:hsla(0,0%,100%,.1)}#chat-widget-root .bg-white\\/20{background-color:hsla(0,0%,100%,.2)}#chat-widget-root .bg-yellow-200{--tw-bg-opacity:1;background-color:rgb(254 240 138/var(--tw-bg-opacity,1))}#chat-widget-root .bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--tw-gradient-stops))}#chat-widget-root .bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}#chat-widget-root .from-gray-50\\/50{--tw-gradient-from:rgba(249,250,251,.5) var(--tw-gradient-from-position);--tw-gradient-to:rgba(249,250,251,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}#chat-widget-root .from-white\\/0{--tw-gradient-from:hsla(0,0%,100%,0) var(--tw-gradient-from-position);--tw-gradient-to:hsla(0,0%,100%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}#chat-widget-root .from-white\\/10{--tw-gradient-from:hsla(0,0%,100%,.1) var(--tw-gradient-from-position);--tw-gradient-to:hsla(0,0%,100%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}#chat-widget-root .from-yellow-200{--tw-gradient-from:#fef08a var(--tw-gradient-from-position);--tw-gradient-to:hsla(53,98%,77%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}#chat-widget-root .via-white\\/5{--tw-gradient-to:hsla(0,0%,100%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),hsla(0,0%,100%,.05) var(--tw-gradient-via-position),var(--tw-gradient-to)}#chat-widget-root .to-transparent{--tw-gradient-to:transparent var(--tw-gradient-to-position)}#chat-widget-root .to-white{--tw-gradient-to:#fff var(--tw-gradient-to-position)}#chat-widget-root .to-white\\/10{--tw-gradient-to:hsla(0,0%,100%,.1) var(--tw-gradient-to-position)}#chat-widget-root .to-yellow-400{--tw-gradient-to:#facc15 var(--tw-gradient-to-position)}#chat-widget-root .object-cover{-o-object-fit:cover;object-fit:cover}#chat-widget-root .p-0{padding:0}#chat-widget-root .p-0\\.5{padding:.125rem}#chat-widget-root .p-3{padding:.75rem}#chat-widget-root .p-5{padding:1.25rem}#chat-widget-root .p-6{padding:1.5rem}#chat-widget-root .p-8{padding:2rem}#chat-widget-root .px-1{padding-left:.25rem;padding-right:.25rem}#chat-widget-root .px-2{padding-left:.5rem;padding-right:.5rem}#chat-widget-root .px-2\\.5{padding-left:.625rem;padding-right:.625rem}#chat-widget-root .px-3{padding-left:.75rem;padding-right:.75rem}#chat-widget-root .px-4{padding-left:1rem;padding-right:1rem}#chat-widget-root .px-5{padding-left:1.25rem;padding-right:1.25rem}#chat-widget-root .py-1{padding-bottom:.25rem;padding-top:.25rem}#chat-widget-root .py-1\\.5{padding-bottom:.375rem;padding-top:.375rem}#chat-widget-root .py-12{padding-bottom:3rem;padding-top:3rem}#chat-widget-root .py-2{padding-bottom:.5rem;padding-top:.5rem}#chat-widget-root .py-2\\.5{padding-bottom:.625rem;padding-top:.625rem}#chat-widget-root .py-3{padding-bottom:.75rem;padding-top:.75rem}#chat-widget-root .py-3\\.5{padding-bottom:.875rem;padding-top:.875rem}#chat-widget-root .py-4{padding-bottom:1rem;padding-top:1rem}#chat-widget-root .pb-1{padding-bottom:.25rem}#chat-widget-root .pb-2{padding-bottom:.5rem}#chat-widget-root .pl-2{padding-left:.5rem}#chat-widget-root .pl-4{padding-left:1rem}#chat-widget-root .pl-\\[50px\\]{padding-left:50px}#chat-widget-root .pr-1{padding-right:.25rem}#chat-widget-root .pt-1{padding-top:.25rem}#chat-widget-root .text-left{text-align:left}#chat-widget-root .text-center{text-align:center}#chat-widget-root .text-right{text-align:right}#chat-widget-root .align-text-bottom{vertical-align:text-bottom}#chat-widget-root .font-sans{font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}#chat-widget-root .text-2xl{font-size:1.5rem;line-height:2rem}#chat-widget-root .text-\\[10px\\]{font-size:10px}#chat-widget-root .text-\\[11px\\]{font-size:11px}#chat-widget-root .text-\\[15px\\]{font-size:15px}#chat-widget-root .text-base{font-size:1rem;line-height:1.5rem}#chat-widget-root .text-lg{font-size:1.125rem;line-height:1.75rem}#chat-widget-root .text-sm{font-size:.875rem;line-height:1.25rem}#chat-widget-root .text-xl{font-size:1.25rem;line-height:1.75rem}#chat-widget-root .text-xs{font-size:.75rem;line-height:1rem}#chat-widget-root .font-bold{font-weight:700}#chat-widget-root .font-medium{font-weight:500}#chat-widget-root .font-semibold{font-weight:600}#chat-widget-root .uppercase{text-transform:uppercase}#chat-widget-root .lowercase{text-transform:lowercase}#chat-widget-root .italic{font-style:italic}#chat-widget-root .tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}#chat-widget-root .leading-5{line-height:1.25rem}#chat-widget-root .leading-none{line-height:1}#chat-widget-root .leading-normal{line-height:1.5}#chat-widget-root .leading-relaxed{line-height:1.625}#chat-widget-root .leading-tight{line-height:1.25}#chat-widget-root .tracking-wide{letter-spacing:.025em}#chat-widget-root .text-\\[\\#4A5568\\]{--tw-text-opacity:1;color:rgb(74 85 104/var(--tw-text-opacity,1))}#chat-widget-root .text-current{color:currentColor}#chat-widget-root .text-gray-100{--tw-text-opacity:1;color:rgb(243 244 246/var(--tw-text-opacity,1))}#chat-widget-root .text-gray-200{--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity,1))}#chat-widget-root .text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity,1))}#chat-widget-root .text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}#chat-widget-root .text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}#chat-widget-root .text-gray-500\\/80{color:hsla(220,9%,46%,.8)}#chat-widget-root .text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}#chat-widget-root .text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}#chat-widget-root .text-gray-800{--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity,1))}#chat-widget-root .text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}#chat-widget-root .text-green-500{--tw-text-opacity:1;color:rgb(34 197 94/var(--tw-text-opacity,1))}#chat-widget-root .text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}#chat-widget-root .text-slate-400{--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity,1))}#chat-widget-root .text-slate-500{--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity,1))}#chat-widget-root .text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}#chat-widget-root .text-yellow-400{--tw-text-opacity:1;color:rgb(250 204 21/var(--tw-text-opacity,1))}#chat-widget-root .no-underline{text-decoration-line:none}#chat-widget-root .placeholder-gray-400::-moz-placeholder{--tw-placeholder-opacity:1;color:rgb(156 163 175/var(--tw-placeholder-opacity,1))}#chat-widget-root .placeholder-gray-400::placeholder{--tw-placeholder-opacity:1;color:rgb(156 163 175/var(--tw-placeholder-opacity,1))}#chat-widget-root .placeholder-gray-500::-moz-placeholder{--tw-placeholder-opacity:1;color:rgb(107 114 128/var(--tw-placeholder-opacity,1))}#chat-widget-root .placeholder-gray-500::placeholder{--tw-placeholder-opacity:1;color:rgb(107 114 128/var(--tw-placeholder-opacity,1))}#chat-widget-root .opacity-0{opacity:0}#chat-widget-root .opacity-50{opacity:.5}#chat-widget-root .opacity-60{opacity:.6}#chat-widget-root .opacity-70{opacity:.7}#chat-widget-root .opacity-80{opacity:.8}#chat-widget-root .shadow{--tw-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1);--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color)}#chat-widget-root .shadow,#chat-widget-root .shadow-2xl{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}#chat-widget-root .shadow-2xl{--tw-shadow:0 25px 50px -12px rgba(0,0,0,.25);--tw-shadow-colored:0 25px 50px -12px var(--tw-shadow-color)}#chat-widget-root .shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}#chat-widget-root .shadow-lg,#chat-widget-root .shadow-md{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}#chat-widget-root .shadow-md{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}#chat-widget-root .shadow-none{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000}#chat-widget-root .shadow-none,#chat-widget-root .shadow-sm{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}#chat-widget-root .shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}#chat-widget-root .shadow-xl{--tw-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 8px 10px -6px rgba(0,0,0,.1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}#chat-widget-root .shadow-black\\/20{--tw-shadow-color:rgba(0,0,0,.2);--tw-shadow:var(--tw-shadow-colored)}#chat-widget-root .shadow-gray-200\\/80{--tw-shadow-color:rgba(229,231,235,.8);--tw-shadow:var(--tw-shadow-colored)}#chat-widget-root .outline-none{outline:2px solid transparent;outline-offset:2px}#chat-widget-root .ring-2{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}#chat-widget-root .ring-blue-100{--tw-ring-opacity:1;--tw-ring-color:rgb(219 234 254/var(--tw-ring-opacity,1))}#chat-widget-root .ring-blue-300{--tw-ring-opacity:1;--tw-ring-color:rgb(147 197 253/var(--tw-ring-opacity,1))}#chat-widget-root .blur{--tw-blur:blur(8px)}#chat-widget-root .blur,#chat-widget-root .drop-shadow{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}#chat-widget-root .drop-shadow{--tw-drop-shadow:drop-shadow(0 1px 2px rgba(0,0,0,.1)) drop-shadow(0 1px 1px rgba(0,0,0,.06))}#chat-widget-root .drop-shadow-md{--tw-drop-shadow:drop-shadow(0 4px 3px rgba(0,0,0,.07)) drop-shadow(0 2px 2px rgba(0,0,0,.06))}#chat-widget-root .drop-shadow-md,#chat-widget-root .drop-shadow-sm{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}#chat-widget-root .drop-shadow-sm{--tw-drop-shadow:drop-shadow(0 1px 1px rgba(0,0,0,.05))}#chat-widget-root .grayscale-\\[0\\.3\\]{--tw-grayscale:grayscale(0.3)}#chat-widget-root .filter,#chat-widget-root .grayscale-\\[0\\.3\\]{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}#chat-widget-root .backdrop-blur-sm{--tw-backdrop-blur:blur(4px);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}#chat-widget-root .transition{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}#chat-widget-root .transition-all{transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1)}#chat-widget-root .transition-colors{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}#chat-widget-root .transition-opacity{transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}#chat-widget-root .transition-transform{transition-duration:.15s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}#chat-widget-root .duration-150{transition-duration:.15s}#chat-widget-root .duration-200{transition-duration:.2s}#chat-widget-root .duration-300{transition-duration:.3s}#chat-widget-root .duration-500{transition-duration:.5s}#chat-widget-root :is(#chat-widget-root .animate-in){animation:slideIn .3s ease-out}#chat-widget-root :is(#chat-widget-root .transition-all){transition-duration:.3s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1)}#chat-widget-root .\\[font-family\\:inherit\\]{font-family:inherit}#chat-widget-root .placeholder\\:text-\\[\\#8C8C8C\\]::-moz-placeholder{--tw-text-opacity:1;color:rgb(140 140 140/var(--tw-text-opacity,1))}#chat-widget-root .placeholder\\:text-\\[\\#8C8C8C\\]::placeholder{--tw-text-opacity:1;color:rgb(140 140 140/var(--tw-text-opacity,1))}#chat-widget-root .placeholder\\:text-\\[\\#A2A9B2\\]::-moz-placeholder{--tw-text-opacity:1;color:rgb(162 169 178/var(--tw-text-opacity,1))}#chat-widget-root .placeholder\\:text-\\[\\#A2A9B2\\]::placeholder{--tw-text-opacity:1;color:rgb(162 169 178/var(--tw-text-opacity,1))}#chat-widget-root .hover\\:scale-105:hover{--tw-scale-x:1.05;--tw-scale-y:1.05}#chat-widget-root .hover\\:scale-105:hover,#chat-widget-root .hover\\:scale-110:hover{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}#chat-widget-root .hover\\:scale-110:hover{--tw-scale-x:1.1;--tw-scale-y:1.1}#chat-widget-root .hover\\:scale-\\[1\\.02\\]:hover{--tw-scale-x:1.02;--tw-scale-y:1.02;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}#chat-widget-root .hover\\:border-blue-400:hover{--tw-border-opacity:1;border-color:rgb(96 165 250/var(--tw-border-opacity,1))}#chat-widget-root .hover\\:border-blue-600:hover{--tw-border-opacity:1;border-color:rgb(37 99 235/var(--tw-border-opacity,1))}#chat-widget-root .hover\\:bg-blue-50:hover{--tw-bg-opacity:1;background-color:rgb(239 246 255/var(--tw-bg-opacity,1))}#chat-widget-root .hover\\:bg-blue-500\\/20:hover{background-color:rgba(59,130,246,.2)}#chat-widget-root .hover\\:bg-blue-900\\/50:hover{background-color:rgba(30,58,138,.5)}#chat-widget-root .hover\\:bg-gray-100:hover{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}#chat-widget-root .hover\\:bg-gray-200:hover{--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity,1))}#chat-widget-root .hover\\:bg-gray-50:hover{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}#chat-widget-root .hover\\:bg-gray-600:hover{--tw-bg-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity,1))}#chat-widget-root .hover\\:bg-gray-700:hover{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity,1))}#chat-widget-root .hover\\:bg-red-600:hover{--tw-bg-opacity:1;background-color:rgb(220 38 38/var(--tw-bg-opacity,1))}#chat-widget-root .hover\\:bg-transparent:hover{background-color:transparent}#chat-widget-root .hover\\:text-blue-500:hover{--tw-text-opacity:1;color:rgb(59 130 246/var(--tw-text-opacity,1))}#chat-widget-root .hover\\:text-gray-200:hover{--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity,1))}#chat-widget-root .hover\\:text-gray-300:hover{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity,1))}#chat-widget-root .hover\\:text-gray-600:hover{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}#chat-widget-root .hover\\:text-gray-700:hover{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}#chat-widget-root .hover\\:underline:hover{text-decoration-line:underline}#chat-widget-root .hover\\:opacity-80:hover{opacity:.8}#chat-widget-root .hover\\:opacity-90:hover{opacity:.9}#chat-widget-root .hover\\:shadow-md:hover{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}#chat-widget-root .hover\\:shadow-md:hover,#chat-widget-root .hover\\:shadow-xl:hover{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}#chat-widget-root .hover\\:shadow-xl:hover{--tw-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 8px 10px -6px rgba(0,0,0,.1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color)}#chat-widget-root .hover\\:grayscale-0:hover{--tw-grayscale:grayscale(0);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}#chat-widget-root .focus\\:\\!border-red-500:focus{--tw-border-opacity:1!important;border-color:rgb(239 68 68/var(--tw-border-opacity,1))!important}#chat-widget-root .focus\\:border-\\[\\#5A6069\\]:focus{--tw-border-opacity:1;border-color:rgb(90 96 105/var(--tw-border-opacity,1))}#chat-widget-root .focus\\:border-\\[\\#B0B0B0\\]:focus{--tw-border-opacity:1;border-color:rgb(176 176 176/var(--tw-border-opacity,1))}#chat-widget-root .focus\\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}#chat-widget-root .focus\\:ring-0:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color)}#chat-widget-root .focus\\:ring-0:focus,#chat-widget-root .focus\\:ring-1:focus{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}#chat-widget-root .focus\\:ring-1:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)}#chat-widget-root .focus\\:ring-gray-300:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(209 213 219/var(--tw-ring-opacity,1))}#chat-widget-root .focus\\:ring-gray-600:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(75 85 99/var(--tw-ring-opacity,1))}#chat-widget-root .focus-visible\\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}#chat-widget-root .focus-visible\\:ring-2:focus-visible{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}#chat-widget-root .focus-visible\\:ring-white\\/40:focus-visible{--tw-ring-color:hsla(0,0%,100%,.4)}#chat-widget-root .active\\:scale-95:active{--tw-scale-x:.95;--tw-scale-y:.95}#chat-widget-root .active\\:scale-95:active,#chat-widget-root .active\\:scale-\\[0\\.97\\]:active{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}#chat-widget-root .active\\:scale-\\[0\\.97\\]:active{--tw-scale-x:0.97;--tw-scale-y:0.97}#chat-widget-root .active\\:scale-\\[0\\.98\\]:active{--tw-scale-x:0.98;--tw-scale-y:0.98;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}#chat-widget-root .active\\:outline-none:active{outline:2px solid transparent;outline-offset:2px}#chat-widget-root .active\\:ring-0:active{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}#chat-widget-root .disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}#chat-widget-root .disabled\\:opacity-40:disabled{opacity:.4}#chat-widget-root .disabled\\:opacity-50:disabled{opacity:.5}#chat-widget-root .disabled\\:shadow-none:disabled{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}#chat-widget-root :is(.group:hover .group-hover\\:scale-100){--tw-scale-x:1;--tw-scale-y:1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}#chat-widget-root :is(.group:hover .group-hover\\:opacity-100){opacity:1}#chat-widget-root .dark\\:text-gray-300:is(.dark *){--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity,1))}#chat-widget-root .dark\\:text-gray-400:is(.dark *){--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}#chat-widget-root .rtl\\:rounded-tl-2xl:where([dir=rtl],[dir=rtl] *){border-top-left-radius:1rem}#chat-widget-root .rtl\\:rounded-tr-sm:where([dir=rtl],[dir=rtl] *){border-top-right-radius:.125rem}#chat-widget-root .\\[\\&\\:first-child\\]\\:\\!mt-0:first-child{margin-top:0!important}#chat-widget-root :is(.\\[\\&\\>\\*\\:first-child\\]\\:\\!mt-0>:first-child){margin-top:0!important}#chat-widget-root :is(.\\[\\&\\>\\*\\:last-child\\]\\:\\!mb-0>:last-child){margin-bottom:0!important}";
7873
7873
 
7874
7874
  var css_248z = ".chat-widget-root{position:fixed;z-index:999999}.chat-widget-container{color:var(--cw-text-color,inherit);font-family:var(\r\n --cw-font-family,-apple-system,BlinkMacSystemFont,\"Segoe UI\",\"Roboto\",\"Oxygen\",\"Ubuntu\",\"Cantarell\",\"Fira Sans\",\"Droid Sans\",\"Helvetica Neue\",sans-serif\r\n )}#chat-widget-root .chat-messages p{overflow-wrap:anywhere;word-break:break-word}textarea#chat-widget-input::-moz-placeholder{border:none;line-height:48px;outline:none}textarea#chat-widget-input::placeholder{border:none;line-height:48px;outline:none}textarea#chat-widget-input{border:none;line-height:48px;outline:none}@keyframes slideIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes bounce{0%,to{transform:translateY(0)}50%{transform:translateY(-5px)}}#chat-widget-root .scrollbar-hide{-ms-overflow-style:none;scrollbar-width:none}#chat-widget-root .scrollbar-hide::-webkit-scrollbar{display:none}@media print{.chat-widget-root{display:none!important}}";
7875
7875
 
@@ -8041,6 +8041,48 @@
8041
8041
  return response.body;
8042
8042
  };
8043
8043
 
8044
+ /**
8045
+ * Persists pre-chat onboarding answers (name/email/phone) directly onto the
8046
+ * Conversation row via the lightweight `/api/v1/support/onboarding` endpoint
8047
+ * (EV-1802). This is a plain DB upsert with no LLM/RAG involvement — unlike
8048
+ * routing each field through `sendStreamingRequest`, which triggered a full
8049
+ * ~5-12s agent turn per field purely to derive the same contact columns,
8050
+ * then threw the generated answer away.
8051
+ * @param {Record<string, string>} answers - flat { fieldType: value } map
8052
+ * @param {{ conversationId: string, organizationId: string }} ids
8053
+ * @param {string} apiBaseUrl - Base URL for the API
8054
+ * @param {Function|undefined} getAuthToken - async fn returning a Bearer token, or undefined
8055
+ */
8056
+ const sendOnboardingAnswers = async (answers, _ref, apiBaseUrl, getAuthToken) => {
8057
+ let {
8058
+ conversationId,
8059
+ organizationId
8060
+ } = _ref;
8061
+ const headers = {
8062
+ 'Content-Type': 'application/json'
8063
+ };
8064
+ if (typeof getAuthToken === 'function') {
8065
+ const token = await getAuthToken();
8066
+ if (token) {
8067
+ headers['Authorization'] = "Bearer ".concat(token);
8068
+ }
8069
+ }
8070
+ const response = await fetch("".concat(apiBaseUrl.replace(/\/$/, ''), "/api/v1/support/onboarding"), {
8071
+ method: 'POST',
8072
+ headers,
8073
+ credentials: 'include',
8074
+ body: JSON.stringify({
8075
+ conversationId,
8076
+ organizationId,
8077
+ answers
8078
+ })
8079
+ });
8080
+ if (!response.ok) {
8081
+ throw new Error("HTTP error! status: ".concat(response.status));
8082
+ }
8083
+ return response.json();
8084
+ };
8085
+
8044
8086
  // ============================================================================
8045
8087
  // UI HELPERS
8046
8088
  // ============================================================================
@@ -8145,11 +8187,11 @@
8145
8187
  const updatedMessages = [...(prev || [])];
8146
8188
  const lastMessage = updatedMessages[updatedMessages.length - 1];
8147
8189
  if ((lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.role) === 'assistant') {
8148
- const _ref = metadata || {},
8190
+ const _ref2 = metadata || {},
8149
8191
  {
8150
8192
  prompts
8151
- } = _ref,
8152
- extraFields = _objectWithoutProperties$m(_ref, _excluded$o);
8193
+ } = _ref2,
8194
+ extraFields = _objectWithoutProperties$m(_ref2, _excluded$o);
8153
8195
  updatedMessages[updatedMessages.length - 1] = _objectSpread2(_objectSpread2(_objectSpread2({}, lastMessage), extraFields), {}, {
8154
8196
  // e.g. conclusionDetected or other flags
8155
8197
  content,
@@ -8345,6 +8387,16 @@
8345
8387
  continue;
8346
8388
  }
8347
8389
 
8390
+ // Human-handoff: responder='human', so the backend short-circuits and
8391
+ // emits ONLY {type:'human_handoff'} + [DONE] (no AI content). Treat it
8392
+ // as a terminal signal so we DON'T throw IncompleteStreamError (which
8393
+ // would retry-send the message 3× and render an error bubble). The
8394
+ // human agent's reply arrives via the SSE EventSource instead.
8395
+ if (parsed.type === 'human_handoff') {
8396
+ streamCompleted = true;
8397
+ continue;
8398
+ }
8399
+
8348
8400
  // Handle text_chunk events
8349
8401
  if (parsed.type === 'text_chunk') {
8350
8402
  var _parsed$choices;
@@ -8383,17 +8435,23 @@
8383
8435
 
8384
8436
  // Handle complete events
8385
8437
  if (parsed.type === 'complete') {
8386
- var _ref2, _parsed$Sources, _parsed$choices2;
8438
+ var _ref3, _parsed$Sources, _parsed$choices2;
8387
8439
  streamCompleted = true;
8388
8440
  // Normalize Sources from stream (API may send "Sources" or "sources")
8389
- const rawSources = (_ref2 = (_parsed$Sources = parsed.Sources) !== null && _parsed$Sources !== void 0 ? _parsed$Sources : parsed.sources) !== null && _ref2 !== void 0 ? _ref2 : [];
8441
+ const rawSources = (_ref3 = (_parsed$Sources = parsed.Sources) !== null && _parsed$Sources !== void 0 ? _parsed$Sources : parsed.sources) !== null && _ref3 !== void 0 ? _ref3 : [];
8390
8442
  const sources = Array.isArray(rawSources) ? rawSources.map(s => {
8391
- var _ref3, _s$source_type, _s$sourceid, _ref4, _s$source_name;
8443
+ var _ref4, _s$source_type, _s$sourceid, _ref5, _s$source_name, _s$citation_indices;
8392
8444
  return {
8393
- source_type: (_ref3 = (_s$source_type = s.source_type) !== null && _s$source_type !== void 0 ? _s$source_type : s.sourceType) !== null && _ref3 !== void 0 ? _ref3 : 'website',
8445
+ source_type: (_ref4 = (_s$source_type = s.source_type) !== null && _s$source_type !== void 0 ? _s$source_type : s.sourceType) !== null && _ref4 !== void 0 ? _ref4 : 'website',
8394
8446
  source_id: (_s$sourceid = s.sourceid) !== null && _s$sourceid !== void 0 ? _s$sourceid : s.source_id,
8395
- source_name: (_ref4 = (_s$source_name = s.source_name) !== null && _s$source_name !== void 0 ? _s$source_name : s.sourceName) !== null && _ref4 !== void 0 ? _ref4 : '',
8396
- url: s.url
8447
+ source_name: (_ref5 = (_s$source_name = s.source_name) !== null && _s$source_name !== void 0 ? _s$source_name : s.sourceName) !== null && _ref5 !== void 0 ? _ref5 : '',
8448
+ url: s.url,
8449
+ // 2026-07-14 — preserve citation_indices so
8450
+ // `<CitationPill>` can resolve `[N]` markers even
8451
+ // when N exceeds sources.length (post inline-cite
8452
+ // filter, the emit list is shorter than the LLM's
8453
+ // manifest — sources[N-1] misses on high indices).
8454
+ citation_indices: (_s$citation_indices = s.citation_indices) !== null && _s$citation_indices !== void 0 ? _s$citation_indices : s.citationIndices
8397
8455
  };
8398
8456
  }).filter(s => s.source_id || s.url) : [];
8399
8457
 
@@ -9048,21 +9106,37 @@
9048
9106
  localStorage.setItem("".concat(SESSION_KEY$1, "_").concat(orgId), JSON.stringify(session));
9049
9107
  } catch (_unused6) {}
9050
9108
  };
9051
- const markOnboardingCompleted = orgId => {
9109
+ const markOnboardingCompleted = (orgId, name) => {
9052
9110
  try {
9053
9111
  const session = getSession(orgId);
9054
9112
  if (!session) return;
9055
9113
  session.onboardingCompleted = true;
9114
+ // Persist the collected name so greetings stay personalised on re-entry
9115
+ // (a returning visitor skips the form, so without this the name would be
9116
+ // lost and the restart greeting would fall back to the generic wording).
9117
+ // A blank name leaves any previously-stored name untouched.
9118
+ const clean = (name !== null && name !== void 0 ? name : "").trim();
9119
+ if (clean) session.onboardingName = clean;
9056
9120
  localStorage.setItem("".concat(SESSION_KEY$1, "_").concat(orgId), JSON.stringify(session));
9057
9121
  } catch (_unused7) {}
9058
9122
  };
9123
+
9124
+ // Read the persisted onboarding name for this org ("" when none / unavailable).
9125
+ const getOnboardingName = orgId => {
9126
+ try {
9127
+ var _getSession$onboardin, _getSession;
9128
+ return (_getSession$onboardin = (_getSession = getSession(orgId)) === null || _getSession === void 0 ? void 0 : _getSession.onboardingName) !== null && _getSession$onboardin !== void 0 ? _getSession$onboardin : "";
9129
+ } catch (_unused8) {
9130
+ return "";
9131
+ }
9132
+ };
9059
9133
  const markCsatSubmitted = orgId => {
9060
9134
  try {
9061
9135
  const session = getSession(orgId);
9062
9136
  if (!session) return;
9063
9137
  session.csatSubmitted = true;
9064
9138
  localStorage.setItem("".concat(SESSION_KEY$1, "_").concat(orgId), JSON.stringify(session));
9065
- } catch (_unused8) {}
9139
+ } catch (_unused9) {}
9066
9140
  };
9067
9141
  const clearSession$2 = orgId => {
9068
9142
  try {
@@ -9076,7 +9150,7 @@
9076
9150
  if (existing !== null && existing !== void 0 && existing.conversationId) {
9077
9151
  clearSessionMessages(orgId, existing.conversationId);
9078
9152
  }
9079
- } catch (_unused9) {}
9153
+ } catch (_unused0) {}
9080
9154
  };
9081
9155
  const savePromptSuggestions = (orgId, prompts) => {
9082
9156
  try {
@@ -9086,34 +9160,125 @@
9086
9160
  return;
9087
9161
  }
9088
9162
  localStorage.setItem("".concat(SESSION_KEY$1, "_prompts_").concat(orgId), JSON.stringify(prompts));
9089
- } catch (_unused0) {}
9163
+ } catch (_unused1) {}
9090
9164
  };
9091
9165
  const getPromptSuggestions = orgId => {
9092
9166
  try {
9093
9167
  const raw = localStorage.getItem("".concat(SESSION_KEY$1, "_prompts_").concat(orgId));
9094
9168
  if (!raw) return [];
9095
9169
  return JSON.parse(raw) || [];
9096
- } catch (_unused1) {
9170
+ } catch (_unused10) {
9097
9171
  return [];
9098
9172
  }
9099
9173
  };
9100
9174
 
9175
+ /**
9176
+ * Greeting personalisation using the onboarding-collected name.
9177
+ *
9178
+ * Product (2026-07-20): once onboarding captures the user's name, every
9179
+ * greeting (initial / follow-up / re-entry) should address them by it —
9180
+ * "Hi, how can I help you?" → "Hi Rishabh, how can I help you?" — and a name
9181
+ * typed all-lowercase is title-cased first ("rishabh" → "Rishabh").
9182
+ *
9183
+ * This is a byte-for-byte port of the agent-sdk helper
9184
+ * (packages/agent-sdk/src/lib/personalizeGreeting.ts), which carries the unit
9185
+ * tests for this logic — the widget bundles via rollup and can't import across
9186
+ * package boundaries, so the logic is duplicated here rather than shared. Keep
9187
+ * the two in sync; the SDK version is the source of truth.
9188
+ */
9189
+
9190
+ /**
9191
+ * Title-case a person's name for display: "rishabh" → "Rishabh",
9192
+ * "john doe" → "John Doe". Only the FIRST letter of each whitespace-separated
9193
+ * word is upper-cased; the rest is left as-typed so intentional casing
9194
+ * ("McDonald") isn't flattened. Collapses internal whitespace.
9195
+ */
9196
+ function capitalizeName(name) {
9197
+ return String(name !== null && name !== void 0 ? name : "").trim().split(/\s+/).filter(Boolean).map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
9198
+ }
9199
+
9200
+ /**
9201
+ * Return `greeting` with the (title-cased) `name` injected after its leading
9202
+ * salutation. No-op when `name` is empty/whitespace or `greeting` is blank, so
9203
+ * callers can apply it unconditionally. Idempotent — applying twice can't
9204
+ * double-inject the name.
9205
+ */
9206
+ function personalizeGreeting(greeting, name) {
9207
+ const g = greeting == null ? "" : String(greeting);
9208
+ const clean = String(name !== null && name !== void 0 ? name : "").trim();
9209
+ if (!clean || !g.trim()) return g;
9210
+ const cap = capitalizeName(clean);
9211
+
9212
+ // Already personalised with this name → don't inject again.
9213
+ const already = new RegExp("^\\s*(?:hi|hey|hello)\\s+".concat(cap.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "\\b"), "i");
9214
+ if (already.test(g)) return g;
9215
+
9216
+ // Leading salutation ("Hi"/"Hey"/"Hello"), an optional "there", then any
9217
+ // opening punctuation. Kept tight so "Welcome to Acme" isn't mangled.
9218
+ const m = g.match(/^\s*(hi|hey|hello)(?:\s+there)?\s*([,!.:;—-]+)?\s*/i);
9219
+ if (m) {
9220
+ var _m$;
9221
+ const salutation = m[1];
9222
+ const punct = (_m$ = m[2]) !== null && _m$ !== void 0 ? _m$ : ",";
9223
+ const rest = g.slice(m[0].length);
9224
+ return "".concat(salutation, " ").concat(cap).concat(punct).concat(rest ? " ".concat(rest) : "");
9225
+ }
9226
+
9227
+ // No recognised salutation — prepend a fresh one.
9228
+ return "Hi ".concat(cap, ", ").concat(g);
9229
+ }
9230
+
9231
+ /**
9232
+ * Pull the user's name out of the widget's onboarding answers. The widget keys
9233
+ * answers by `fieldType`, and the name lives in the FIRST question whose
9234
+ * fieldType is a dedicated name type (fullName / name / userName,
9235
+ * case-insensitive) — how the agent-builder configures the name field. A
9236
+ * generic `text` field is deliberately NOT treated as a name (it's used for
9237
+ * company / reason / etc.; guessing would produce "Hi <generic answer>").
9238
+ * Returns "" when no name-type answer is present.
9239
+ */
9240
+ const NAME_FIELD_TYPES = new Set(["fullname", "name", "username"]);
9241
+ function extractOnboardingName(questions, answers) {
9242
+ if (!Array.isArray(questions) || !answers) return "";
9243
+ for (const q of questions) {
9244
+ var _q$fieldType, _q$fieldType2;
9245
+ const ft = String((_q$fieldType = q === null || q === void 0 ? void 0 : q.fieldType) !== null && _q$fieldType !== void 0 ? _q$fieldType : "").toLowerCase();
9246
+ if (!NAME_FIELD_TYPES.has(ft)) continue;
9247
+ const raw = answers[(_q$fieldType2 = q === null || q === void 0 ? void 0 : q.fieldType) !== null && _q$fieldType2 !== void 0 ? _q$fieldType2 : ""];
9248
+ if (typeof raw !== "string") continue;
9249
+ const trimmed = raw.trim();
9250
+ if (trimmed) return trimmed;
9251
+ }
9252
+ return "";
9253
+ }
9254
+
9255
+ // 2026-07-06 — accept and preserve `attachments` on the returned
9256
+ // message object. Historically createMessage's destructure omitted
9257
+ // this field, so callers who spread `{...(attachmentsPayload.length
9258
+ // ? { attachments } : {})}` into the input silently lost it — the
9259
+ // user's outgoing bubble in the widget rendered without the file
9260
+ // chip even though the /support payload correctly carried the
9261
+ // attachments to the backend. MessageBubble.jsx line 1279 reads
9262
+ // `message.attachments` — a shape createMessage now supplies.
9101
9263
  const createMessage = _ref => {
9102
9264
  let {
9103
9265
  id,
9104
9266
  role,
9105
9267
  content,
9106
9268
  isProcessing = false,
9107
- metadata
9269
+ metadata,
9270
+ attachments
9108
9271
  } = _ref;
9109
- return {
9272
+ return _objectSpread2({
9110
9273
  id,
9111
9274
  role,
9112
9275
  content,
9113
9276
  timestamp: new Date(),
9114
9277
  isProcessing,
9115
9278
  metadata
9116
- };
9279
+ }, Array.isArray(attachments) && attachments.length > 0 ? {
9280
+ attachments
9281
+ } : {});
9117
9282
  };
9118
9283
 
9119
9284
  // Merge the text (SSE) and voice (Bidi) message arrays into one chronological
@@ -9192,10 +9357,17 @@
9192
9357
  if (!welcomeMessage) {
9193
9358
  return [];
9194
9359
  }
9360
+ // Personalise with any persisted name so a returning visitor's first
9361
+ // paint already reads "Hi <Name>, …" (no-op for a genuinely fresh visit,
9362
+ // where onboarding hasn't run yet).
9363
+ let initialWelcome = welcomeMessage;
9364
+ try {
9365
+ initialWelcome = personalizeGreeting(welcomeMessage, getOnboardingName(organizationId));
9366
+ } catch (_unused2) {}
9195
9367
  return [_objectSpread2(_objectSpread2({}, createMessage({
9196
9368
  id: Date.now().toString(),
9197
9369
  role: "assistant",
9198
- content: welcomeMessage
9370
+ content: initialWelcome
9199
9371
  })), {}, {
9200
9372
  isWelcome: true
9201
9373
  })];
@@ -9248,9 +9420,25 @@
9248
9420
  try {
9249
9421
  const existing = getSession(organizationId);
9250
9422
  if (existing && existing.onboardingCompleted) return true;
9251
- } catch (_unused2) {}
9423
+ } catch (_unused3) {}
9252
9424
  return false;
9253
9425
  });
9426
+ // Onboarding-collected name, restored from the session so a returning
9427
+ // visitor's greeting is personalised from first paint (the form is skipped
9428
+ // on re-entry, so the name has to come from persistence). Updated on submit
9429
+ // in handleOnboardingFormSubmit; drives `personalizedWelcome` below.
9430
+ const [onboardingName, setOnboardingName] = reactExports.useState(() => {
9431
+ try {
9432
+ return getOnboardingName(organizationId) || "";
9433
+ } catch (_unused4) {
9434
+ return "";
9435
+ }
9436
+ });
9437
+ // Greeting with the onboarding name injected ("Hi Rishabh, …"). No-op
9438
+ // without a name, so every welcome-bubble construction below can use this
9439
+ // unconditionally. Recomputes when the name arrives (post-onboarding) so the
9440
+ // existing welcome bubble updates in place via the sync effect.
9441
+ const personalizedWelcome = reactExports.useMemo(() => personalizeGreeting(welcomeMessage, onboardingName), [welcomeMessage, onboardingName]);
9254
9442
  const [pendingUserIntent, setPendingUserIntent] = reactExports.useState(null);
9255
9443
  const [onboardingAnswers, setOnboardingAnswers] = reactExports.useState({});
9256
9444
  const pendingIntentProcessedRef = reactExports.useRef(false);
@@ -9278,11 +9466,27 @@
9278
9466
  if (inactivityTimeoutValue !== undefined && existing && isSessionValid(existing, inactivityTimeoutValue, inactivityTimeoutUnit)) {
9279
9467
  return existing.conversationId;
9280
9468
  }
9281
- } catch (_unused3) {}
9469
+ } catch (_unused5) {}
9282
9470
  // Otherwise start with a fresh ID (which may be reverted to restored ID in effect if found valid later)
9283
9471
  return "widget-session-".concat(Math.random().toString(36).slice(2, 9));
9284
9472
  });
9285
9473
 
9474
+ // Handoff EventSource — receives human agent messages in real-time
9475
+ const handoffEventSourceRef = reactExports.useRef(null);
9476
+ const HANDOFF_TRIGGER = "Connect with a human representative";
9477
+ // True once a human agent owns the conversation (visitor clicked handoff, or
9478
+ // reload surfaced human-agent messages). While true the AI stays silent
9479
+ // (backend short-circuits knowledge-api) so we skip the "concierge is
9480
+ // responding" loader and don't stream an AI reply — the human's reply arrives
9481
+ // over the SSE EventSource instead. The ref mirrors the state for a
9482
+ // synchronous read inside sendMessage (whose useCallback deps are fixed).
9483
+ const [isHandedOff, setIsHandedOff] = reactExports.useState(false);
9484
+ const isHandedOffRef = reactExports.useRef(false);
9485
+ const markHandedOff = reactExports.useCallback(() => {
9486
+ isHandedOffRef.current = true;
9487
+ setIsHandedOff(true);
9488
+ }, []);
9489
+
9286
9490
  // Bidi refs
9287
9491
  const websocketRef = reactExports.useRef(null);
9288
9492
  const audioPlayerNodeRef = reactExports.useRef(null);
@@ -9318,6 +9522,47 @@
9318
9522
  // Null when the SDK's IP/geo resolver is blocked — conversations from
9319
9523
  // those visitors fall into the "Other" bucket on the analytics dashboard.
9320
9524
  const visitorProfileRef = reactExports.useRef(null);
9525
+ const startHandoffEventSource = reactExports.useCallback(onConnected => {
9526
+ if (handoffEventSourceRef.current) {
9527
+ if (onConnected) onConnected();
9528
+ return;
9529
+ }
9530
+ if (!apiBaseUrl || !bidiSessionId) return;
9531
+ const url = "".concat(apiBaseUrl.replace(/\/$/, ''), "/api/v1/widget/events/").concat(encodeURIComponent(bidiSessionId));
9532
+ const es = new EventSource(url);
9533
+ es.onmessage = event => {
9534
+ try {
9535
+ const data = JSON.parse(event.data);
9536
+ if (data.type === 'message_created' && data.message) {
9537
+ setMessages(prev => {
9538
+ if (prev.some(m => m.id === data.message.id)) return prev;
9539
+ return [...prev, createMessage({
9540
+ id: data.message.id,
9541
+ role: data.message.role || 'assistant',
9542
+ content: data.message.content,
9543
+ isProcessing: false,
9544
+ metadata: {
9545
+ senderName: data.message.senderName
9546
+ }
9547
+ })];
9548
+ });
9549
+ }
9550
+ } catch (_unused6) {}
9551
+ };
9552
+ es.onopen = () => {
9553
+ if (onConnected) onConnected();
9554
+ };
9555
+ es.onerror = () => {};
9556
+ handoffEventSourceRef.current = es;
9557
+ }, [apiBaseUrl, bidiSessionId]);
9558
+ reactExports.useEffect(() => {
9559
+ return () => {
9560
+ if (handoffEventSourceRef.current) {
9561
+ handoffEventSourceRef.current.close();
9562
+ handoffEventSourceRef.current = null;
9563
+ }
9564
+ };
9565
+ }, []);
9321
9566
  const websocketUrl = reactExports.useMemo(() => {
9322
9567
  if (!organizationId) return null;
9323
9568
  const resolvedWsBaseUrl = getWebSocketUrl(apiBaseUrl, wsBaseUrl);
@@ -9380,7 +9625,7 @@
9380
9625
  timezone: g.timezone || null
9381
9626
  };
9382
9627
  }
9383
- } catch (_unused4) {
9628
+ } catch (_unused7) {
9384
9629
  // SDK failed to load or init — leave refs null.
9385
9630
  }
9386
9631
  })();
@@ -9439,7 +9684,7 @@
9439
9684
  const welcomeMsg = _objectSpread2(_objectSpread2({}, createMessage({
9440
9685
  id: 'welcome-restored',
9441
9686
  role: 'assistant',
9442
- content: welcomeMessage
9687
+ content: personalizedWelcome
9443
9688
  })), {}, {
9444
9689
  isWelcome: true,
9445
9690
  timestamp: new Date(firstTsMs - 1)
@@ -9517,6 +9762,85 @@
9517
9762
  }
9518
9763
  }, [organizationId, bidiSessionId, apiBaseUrl, inactivityTimeoutValue, inactivityTimeoutUnit]);
9519
9764
 
9765
+ // ── Merge server-side human-agent replies into the transcript on load.
9766
+ //
9767
+ // localStorage owns the /support transcript (user + AI turns). But replies a
9768
+ // HUMAN agent sends from the Inbox are persisted server-side and only reach
9769
+ // the widget over SSE *while it is connected*. After a reload — or if the
9770
+ // agent replied while the widget was closed — those replies live only in
9771
+ // Mongo. We fetch them and MERGE (never replace), so an empty/failed response
9772
+ // (e.g. inbox-route-OFF orgs never persist rows) can't wipe the local replay.
9773
+ // Scoped to human-agent messages (contentType human_reply | handoff_ack) so
9774
+ // the /support transcript stays localStorage-owned and nothing duplicates.
9775
+ // Keyed on the conversation id (NOT a plain boolean): on reload the widget
9776
+ // first paints with a throwaway session id, then swaps to the restored id
9777
+ // once the async deploy-agent config arrives. A boolean guard would fire for
9778
+ // the throwaway id and never re-fetch the real conversation. Keying on the id
9779
+ // makes the fetch re-run when bidiSessionId transitions to the restored id
9780
+ // (and again after a session reset/rotation).
9781
+ const serverHistoryFetchedRef = reactExports.useRef(null);
9782
+ reactExports.useEffect(() => {
9783
+ if (!apiBaseUrl || !organizationId || !bidiSessionId) return;
9784
+ if (serverHistoryFetchedRef.current === bidiSessionId) return;
9785
+ serverHistoryFetchedRef.current = bidiSessionId;
9786
+ let cancelled = false;
9787
+ (async () => {
9788
+ try {
9789
+ const headers = {};
9790
+ if (typeof getAuthToken === 'function') {
9791
+ const token = await getAuthToken();
9792
+ if (token) headers['Authorization'] = "Bearer ".concat(token);
9793
+ }
9794
+ const res = await fetch("".concat(apiBaseUrl.replace(/\/$/, ''), "/api/v1/widget/history/").concat(encodeURIComponent(bidiSessionId)), {
9795
+ headers,
9796
+ credentials: 'include'
9797
+ });
9798
+ if (!res.ok || cancelled) return;
9799
+ const data = await res.json();
9800
+ const serverMsgs = Array.isArray(data === null || data === void 0 ? void 0 : data.messages) ? data.messages : [];
9801
+ const agentMsgs = serverMsgs.filter(m => (m === null || m === void 0 ? void 0 : m.contentType) === 'human_reply' || (m === null || m === void 0 ? void 0 : m.contentType) === 'handoff_ack');
9802
+
9803
+ // Merge past human-agent replies into the transcript (regardless of
9804
+ // current responder — they're real history worth showing).
9805
+ if (!cancelled && agentMsgs.length > 0) {
9806
+ setMessages(prev => {
9807
+ const seen = new Set(prev.map(m => m.id));
9808
+ const additions = agentMsgs.filter(m => !seen.has(m.id)).map(m => _objectSpread2(_objectSpread2({}, createMessage({
9809
+ id: m.id,
9810
+ role: m.role || 'assistant',
9811
+ content: m.content,
9812
+ isProcessing: false
9813
+ })), {}, {
9814
+ timestamp: m.createdAt ? new Date(m.createdAt) : new Date()
9815
+ }));
9816
+ if (additions.length === 0) return prev;
9817
+ const tsMs = m => {
9818
+ const t = m.timestamp instanceof Date ? m.timestamp.getTime() : new Date(m.timestamp).getTime();
9819
+ return Number.isFinite(t) ? t : 0;
9820
+ };
9821
+ const merged = [...prev, ...additions];
9822
+ merged.sort((a, b) => tsMs(a) - tsMs(b));
9823
+ return merged;
9824
+ });
9825
+ }
9826
+
9827
+ // Suppress the AI loader + open the live SSE ONLY when a human agent
9828
+ // currently owns the conversation. Gating on the live `responder`
9829
+ // (not merely the presence of past agent messages) means a reopened
9830
+ // conversation (responder back to 'ai') is AI-handled again.
9831
+ if (!cancelled && (data === null || data === void 0 ? void 0 : data.responder) === 'human') {
9832
+ markHandedOff();
9833
+ startHandoffEventSource();
9834
+ }
9835
+ } catch (_unused8) {
9836
+ /* network/parse failure — localStorage replay stands unchanged */
9837
+ }
9838
+ })();
9839
+ return () => {
9840
+ cancelled = true;
9841
+ };
9842
+ }, [apiBaseUrl, organizationId, bidiSessionId, getAuthToken, startHandoffEventSource, markHandedOff]);
9843
+
9520
9844
  // Persist prompt suggestions to localStorage so they survive page refresh
9521
9845
  reactExports.useEffect(() => {
9522
9846
  if (!organizationId || !messages || messages.length === 0) return;
@@ -9565,7 +9889,9 @@
9565
9889
  }
9566
9890
  }, [onboardingEnabled, onboardingCompleted, onboardingQuestions]);
9567
9891
 
9568
- // Sync welcome message updates — skip entirely when history has been loaded
9892
+ // Sync welcome message updates — skip entirely when history has been loaded.
9893
+ // Also fires when the onboarding name arrives (personalizedWelcome changes),
9894
+ // updating the already-rendered welcome bubble in place to "Hi <Name>, …".
9569
9895
  reactExports.useEffect(() => {
9570
9896
  if (!welcomeMessage || historyHasMessagesRef.current) {
9571
9897
  return;
@@ -9575,7 +9901,7 @@
9575
9901
  return [_objectSpread2(_objectSpread2({}, createMessage({
9576
9902
  id: Date.now().toString(),
9577
9903
  role: "assistant",
9578
- content: welcomeMessage
9904
+ content: personalizedWelcome
9579
9905
  })), {}, {
9580
9906
  isWelcome: true
9581
9907
  })];
@@ -9583,12 +9909,12 @@
9583
9909
  const [first, ...rest] = prev;
9584
9910
  if (first.isWelcome) {
9585
9911
  return [_objectSpread2(_objectSpread2({}, first), {}, {
9586
- content: welcomeMessage
9912
+ content: personalizedWelcome
9587
9913
  }), ...rest];
9588
9914
  }
9589
9915
  return prev;
9590
9916
  });
9591
- }, [welcomeMessage]);
9917
+ }, [welcomeMessage, personalizedWelcome]);
9592
9918
  reactExports.useCallback(updater => {
9593
9919
  setMessages(prev => prev.map(message => {
9594
9920
  if (message.id === updater.id) {
@@ -9649,6 +9975,29 @@
9649
9975
  };
9650
9976
  }
9651
9977
  isSendingRef.current = true;
9978
+ if (trimmed === HANDOFF_TRIGGER) {
9979
+ const fireWidgetHandoff = async () => {
9980
+ if (apiBaseUrl && bidiSessionId) {
9981
+ const hdrs = {
9982
+ 'Content-Type': 'application/json'
9983
+ };
9984
+ if (typeof getAuthToken === 'function') {
9985
+ const token = await getAuthToken();
9986
+ if (token) hdrs['Authorization'] = "Bearer ".concat(token);
9987
+ }
9988
+ fetch("".concat(apiBaseUrl.replace(/\/$/, ''), "/api/v1/widget/handoff/").concat(encodeURIComponent(bidiSessionId)), {
9989
+ method: 'POST',
9990
+ headers: hdrs,
9991
+ credentials: 'include',
9992
+ body: JSON.stringify({
9993
+ reason: 'User clicked handoff button'
9994
+ })
9995
+ }).catch(() => {});
9996
+ }
9997
+ };
9998
+ markHandedOff();
9999
+ startHandoffEventSource(fireWidgetHandoff);
10000
+ }
9652
10001
 
9653
10002
  // PR-I + PR-P: cache the user's question so handleDecision can
9654
10003
  // re-send it after a routing-clarification chip pick. Update
@@ -9716,7 +10065,9 @@
9716
10065
  return opts && opts.skipUserAppend ? cleared : [...cleared, userMessage];
9717
10066
  });
9718
10067
  setInputValue("");
9719
- setIsLoading(true);
10068
+ // Handed off → no AI reply is coming, so don't show the typing loader
10069
+ // (it's gated on isLoading). The human's reply arrives via the SSE.
10070
+ if (!isHandedOffRef.current) setIsLoading(true);
9720
10071
  } else {
9721
10072
  // For onboarding fields, clear input immediately
9722
10073
  setInputValue("");
@@ -9810,6 +10161,30 @@
9810
10161
  success: true
9811
10162
  };
9812
10163
  }
10164
+
10165
+ // Handed off to a human → the AI must not reply. Send the message so
10166
+ // the backend persists it (it short-circuits knowledge-api and writes
10167
+ // it to the inbox), but DON'T processStream and DON'T show a loader.
10168
+ // Drain and discard the short-circuit response ({type:'human_handoff'}
10169
+ // + [DONE]); the human's reply arrives via the SSE EventSource.
10170
+ if (isHandedOffRef.current && (apiType === 'inquiry' || apiType === 'complaint' || apiType === 'technical')) {
10171
+ try {
10172
+ const stream = await sendStreamingRequest(chatRequest, apiBaseUrl, getAuthToken);
10173
+ const reader = stream.getReader();
10174
+ while (true) {
10175
+ const {
10176
+ done
10177
+ } = await reader.read();
10178
+ if (done) break;
10179
+ }
10180
+ } catch (_unused9) {
10181
+ /* persistence is best-effort; the human reply still arrives via SSE */
10182
+ }
10183
+ updateActivity(organizationId);
10184
+ return {
10185
+ success: true
10186
+ };
10187
+ }
9813
10188
  if (apiType === 'inquiry' || apiType === 'complaint' || apiType === 'technical') {
9814
10189
  let lastErr;
9815
10190
  for (let attempt = 0; attempt <= STREAM_RETRY_DELAYS_MS.length; attempt += 1) {
@@ -9882,36 +10257,51 @@
9882
10257
  const handleOnboardingFormSubmit = reactExports.useCallback(async answers => {
9883
10258
  const questions = getOnboardingQuestions(onboardingQuestions);
9884
10259
  if (questions.length === 0) return;
10260
+
10261
+ // Pull the user's name out of the answers (first name-type field wins,
10262
+ // matching the backend's contactName mapping) so the greeting can address
10263
+ // them by name. Persist it alongside the completed flag for re-entry.
10264
+ const collectedName = extractOnboardingName(questions, answers);
10265
+
10266
+ // Navigate to chat immediately — don't block on the API calls.
10267
+ setOnboardingActive(false);
10268
+ setOnboardingCompleted(true);
10269
+ markOnboardingCompleted(organizationId, collectedName);
10270
+ if (collectedName) setOnboardingName(collectedName);
10271
+ setOnboardingAnswers(prev => _objectSpread2(_objectSpread2({}, prev), answers));
10272
+ if (pendingUserIntent && !pendingIntentProcessedRef.current) {
10273
+ pendingIntentProcessedRef.current = true;
10274
+ setInputValue(pendingUserIntent);
10275
+ setPendingUserIntent(null);
10276
+ }
10277
+
10278
+ // Persist the onboarding fields in one lightweight background call
10279
+ // (EV-1802). This used to loop `sendMessage` per field, which routed
10280
+ // each value through the full chat/RAG/LLM pipeline (~5-12s each,
10281
+ // serialized by sendMessage's concurrency lock) purely to derive the
10282
+ // same contactName/contactEmail/contactMobile columns that
10283
+ // /api/v1/support/onboarding writes directly — and the generated
10284
+ // "answer" was thrown away either way (see sendMessage's userName/
10285
+ // email/phone branch). A single fast upsert replaces all of that.
9885
10286
  const sorted = [...questions].sort((a, b) => getOnboardingFieldOrder(a.fieldType) - getOnboardingFieldOrder(b.fieldType));
10287
+ const payloadAnswers = {};
9886
10288
  for (const q of sorted) {
9887
10289
  var _answers$key;
9888
10290
  const key = q.fieldType || "question";
9889
10291
  const value = ((_answers$key = answers[key]) !== null && _answers$key !== void 0 ? _answers$key : "").trim();
9890
- if (!value) continue;
9891
- const res = await sendMessage(value, key);
9892
- if (!(res !== null && res !== void 0 && res.success)) {
9893
- const errorMsg = createMessage({
9894
- id: getNextMessageId(),
9895
- role: "assistant",
9896
- content: (res === null || res === void 0 ? void 0 : res.error) || "Something went wrong. Please try again.",
9897
- isProcessing: false
9898
- });
9899
- setMessages(prev => [...prev, errorMsg]);
9900
- return;
9901
- }
10292
+ if (value) payloadAnswers[key] = value;
9902
10293
  }
9903
- setOnboardingActive(false);
9904
- setOnboardingCompleted(true);
9905
- markOnboardingCompleted(organizationId);
9906
- setOnboardingAnswers(prev => _objectSpread2(_objectSpread2({}, prev), answers));
9907
- if (pendingUserIntent && !pendingIntentProcessedRef.current) {
9908
- pendingIntentProcessedRef.current = true;
9909
- setTimeout(() => {
9910
- setInputValue(pendingUserIntent);
9911
- setPendingUserIntent(null);
9912
- }, 500);
10294
+ if (Object.keys(payloadAnswers).length > 0 && apiBaseUrl && bidiSessionId) {
10295
+ try {
10296
+ await sendOnboardingAnswers(payloadAnswers, {
10297
+ conversationId: bidiSessionId,
10298
+ organizationId
10299
+ }, apiBaseUrl, getAuthToken);
10300
+ } catch (err) {
10301
+ console.error("[onboarding] failed to save onboarding answers", err);
10302
+ }
9913
10303
  }
9914
- }, [onboardingQuestions, sendMessage, getNextMessageId, pendingUserIntent, organizationId]);
10304
+ }, [onboardingQuestions, pendingUserIntent, organizationId, apiBaseUrl, bidiSessionId, getAuthToken]);
9915
10305
  const handleSmartSubmit = reactExports.useCallback(async (rawTextOverride, attachments) => {
9916
10306
  // Attachment-only send: when the user uploads a file and hits
9917
10307
  // Send without typing, the trimmed input is empty but committed
@@ -10619,12 +11009,17 @@
10619
11009
  const rawSources = (_event$sources = event.sources) !== null && _event$sources !== void 0 ? _event$sources : event.Sources;
10620
11010
  if (Array.isArray(rawSources) && rawSources.length > 0) {
10621
11011
  const normalizedSources = rawSources.map(s => {
10622
- var _ref3, _s$source_type, _ref4, _s$source_id, _ref5, _s$source_name;
11012
+ var _ref3, _s$source_type, _ref4, _s$source_id, _ref5, _s$source_name, _s$citation_indices;
10623
11013
  return {
10624
11014
  source_type: (_ref3 = (_s$source_type = s.source_type) !== null && _s$source_type !== void 0 ? _s$source_type : s.sourceType) !== null && _ref3 !== void 0 ? _ref3 : 'file',
10625
11015
  source_id: (_ref4 = (_s$source_id = s.source_id) !== null && _s$source_id !== void 0 ? _s$source_id : s.sourceid) !== null && _ref4 !== void 0 ? _ref4 : s.sourceId,
10626
11016
  source_name: (_ref5 = (_s$source_name = s.source_name) !== null && _s$source_name !== void 0 ? _s$source_name : s.sourceName) !== null && _ref5 !== void 0 ? _ref5 : '',
10627
- url: s.url
11017
+ url: s.url,
11018
+ // 2026-07-14 — preserve citation_indices so
11019
+ // `<CitationPill>` can resolve high-numbered `[N]`
11020
+ // markers (post-filter, sources[] is shorter than the
11021
+ // LLM's manifest — sources[N-1] misses on high indices).
11022
+ citation_indices: (_s$citation_indices = s.citation_indices) !== null && _s$citation_indices !== void 0 ? _s$citation_indices : s.citationIndices
10628
11023
  };
10629
11024
  }).filter(s => s.source_id || s.url);
10630
11025
  if (normalizedSources.length === 0) return;
@@ -10880,7 +11275,7 @@
10880
11275
  const welcomeMsg = createMessage({
10881
11276
  id: "bidi-welcome-".concat(Date.now()),
10882
11277
  role: "assistant",
10883
- content: welcomeMessage,
11278
+ content: personalizedWelcome,
10884
11279
  metadata: {
10885
11280
  source: "bidi"
10886
11281
  }
@@ -10895,7 +11290,7 @@
10895
11290
  setVoiceError(error instanceof Error ? error.message : "Unable to access microphone");
10896
11291
  setVoiceStatus("error");
10897
11292
  }
10898
- }, [enableVoiceInteraction, organizationId, welcomeMessage, connectWebsocket, initializeAudioPipeline, messages]);
11293
+ }, [enableVoiceInteraction, organizationId, welcomeMessage, personalizedWelcome, connectWebsocket, initializeAudioPipeline, messages]);
10899
11294
  const handleVoiceToggle = reactExports.useCallback(() => {
10900
11295
  if (isVoiceSessionActive) {
10901
11296
  stopVoiceSession();
@@ -10988,15 +11383,27 @@
10988
11383
  // BEFORE we rotate to a fresh sessionId, otherwise the old bucket leaks.
10989
11384
  clearSessionMessages(organizationId, bidiSessionId);
10990
11385
 
10991
- // Reset onboarding
11386
+ // Reset onboarding. Clear the name too — the new session (saveSession
11387
+ // below writes a fresh record without it) will re-collect it, so the
11388
+ // re-shown welcome stays generic until the user re-onboards.
10992
11389
  setOnboardingActive(false);
10993
11390
  setOnboardingCompleted(false);
10994
11391
  setOnboardingAnswers({});
11392
+ setOnboardingName("");
10995
11393
  setPendingUserIntent(null);
10996
11394
  pendingIntentProcessedRef.current = false;
10997
11395
  userHasSpokenRef.current = false;
10998
11396
  historyLoadedRef.current = false;
10999
11397
  historyHasMessagesRef.current = false;
11398
+ // New conversation starts AI-owned again. Close the old conversation's
11399
+ // handoff SSE so it doesn't leak human-agent messages into the new session.
11400
+ isHandedOffRef.current = false;
11401
+ setIsHandedOff(false);
11402
+ serverHistoryFetchedRef.current = null;
11403
+ if (handoffEventSourceRef.current) {
11404
+ handoffEventSourceRef.current.close();
11405
+ handoffEventSourceRef.current = null;
11406
+ }
11000
11407
 
11001
11408
  // Create a new session id and persist it
11002
11409
  const newSessionId = "widget-session-".concat(Math.random().toString(36).slice(2, 9));
@@ -91901,6 +92308,14 @@
91901
92308
  })]
91902
92309
  });
91903
92310
  }
92311
+ const hasLongLabels = data.some(d => {
92312
+ var _d$label;
92313
+ return String((_d$label = d.label) !== null && _d$label !== void 0 ? _d$label : '').length > 10;
92314
+ });
92315
+ const xAngle = hasLongLabels ? -35 : 0;
92316
+ const xAnchor = hasLongLabels ? 'end' : 'middle';
92317
+ const bottomMargin = hasLongLabels ? 48 : 20;
92318
+ const chartHeight = hasLongLabels ? 250 : 220;
91904
92319
  return /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
91905
92320
  style: {
91906
92321
  borderRadius: 8,
@@ -91920,7 +92335,7 @@
91920
92335
  children: props.title
91921
92336
  }), /*#__PURE__*/jsxRuntimeExports.jsx("div", {
91922
92337
  style: {
91923
- height: 220,
92338
+ height: chartHeight,
91924
92339
  width: '100%'
91925
92340
  },
91926
92341
  children: /*#__PURE__*/jsxRuntimeExports.jsx(ResponsiveContainer, {
@@ -91929,10 +92344,10 @@
91929
92344
  children: /*#__PURE__*/jsxRuntimeExports.jsxs(BarChart, {
91930
92345
  data: data,
91931
92346
  margin: {
91932
- top: 8,
92347
+ top: 16,
91933
92348
  right: 12,
91934
92349
  left: 12,
91935
- bottom: 20
92350
+ bottom: bottomMargin
91936
92351
  },
91937
92352
  children: [/*#__PURE__*/jsxRuntimeExports.jsx(CartesianGrid, {
91938
92353
  strokeDasharray: "3 3",
@@ -91943,9 +92358,13 @@
91943
92358
  fontSize: 11,
91944
92359
  fill: labelColor
91945
92360
  },
91946
- angle: 0,
91947
- textAnchor: "middle",
92361
+ angle: xAngle,
92362
+ textAnchor: xAnchor,
91948
92363
  interval: 0,
92364
+ tickFormatter: v => {
92365
+ const s = String(v !== null && v !== void 0 ? v : '');
92366
+ return s.replace(/[_\-]+/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
92367
+ },
91949
92368
  label: props.xAxisLabel ? {
91950
92369
  value: props.xAxisLabel,
91951
92370
  position: 'insideBottom',
@@ -91980,7 +92399,13 @@
91980
92399
  dataKey: "value",
91981
92400
  name: seriesName,
91982
92401
  fill: "#3b82f6",
91983
- radius: [2, 2, 0, 0]
92402
+ radius: [2, 2, 0, 0],
92403
+ label: {
92404
+ position: 'top',
92405
+ fill: labelColor,
92406
+ fontSize: 10,
92407
+ formatter: v => currency ? formatCurrencyCompact(v) : formatCompactNumber(v)
92408
+ }
91984
92409
  })]
91985
92410
  })
91986
92411
  })
@@ -93859,20 +94284,593 @@
93859
94284
  return base;
93860
94285
  }
93861
94286
 
93862
- const _excluded$1 = ["children"],
93863
- _excluded2 = ["node", "children"],
94287
+ /**
94288
+ * Parse an assistant message body into a mix of TEXT and CITATION-CLUSTER
94289
+ * segments, so the renderer can swap each cluster for an inline
94290
+ * `<CitationPill>` while leaving prose intact.
94291
+ *
94292
+ * Cluster rule: consecutive `[N]` markers separated only by whitespace
94293
+ * (`[1][2]`, `[1] [2]`, `[1,3]` — same intent) collapse into ONE cluster.
94294
+ * A break in-between (`[1] some text [2]`) yields two separate clusters.
94295
+ *
94296
+ * Preserves Markdown links `[label](url)` — the negative lookahead in
94297
+ * the regex skips any `]` immediately followed by `(`.
94298
+ *
94299
+ * DUPLICATED across three surfaces — copies live at:
94300
+ * * packages/frontend/src/lib/messages/parseCitationClusters.ts
94301
+ * * packages/widget/src/utils/parseCitationClusters.js (this file)
94302
+ * * packages/agent-sdk/src/utils/parseCitationClusters.ts
94303
+ * Regex + cluster rule kept byte-identical across all three; a parity
94304
+ * test asserts the same input → same segment list on every surface.
94305
+ */
94306
+
94307
+ // Latin `[N]` / `[N,M]` markers, plus Devanagari digits `[१]` / `[१,२]`.
94308
+ // The negative lookahead `(?!\()` excludes Markdown link syntax
94309
+ // `[label](url)`.
94310
+ const MARKER_RE = /\[([\d०-९][\d०-९\s,]*)\](?!\()/g;
94311
+ const DEV_DIGIT_MAP = {
94312
+ "०": "0",
94313
+ "१": "1",
94314
+ "२": "2",
94315
+ "३": "3",
94316
+ "४": "4",
94317
+ "५": "5",
94318
+ "६": "6",
94319
+ "७": "7",
94320
+ "८": "8",
94321
+ "९": "9"
94322
+ };
94323
+ function normalizeDigits(s) {
94324
+ return s.replace(/[०-९]/g, d => {
94325
+ var _DEV_DIGIT_MAP$d;
94326
+ return (_DEV_DIGIT_MAP$d = DEV_DIGIT_MAP[d]) !== null && _DEV_DIGIT_MAP$d !== void 0 ? _DEV_DIGIT_MAP$d : d;
94327
+ });
94328
+ }
94329
+ function parseIndicesInside(inner) {
94330
+ const out = [];
94331
+ for (const part of normalizeDigits(inner).split(",")) {
94332
+ const t = part.trim();
94333
+ if (/^\d+$/.test(t)) {
94334
+ const n = parseInt(t, 10);
94335
+ if (n >= 1) out.push(n);
94336
+ }
94337
+ }
94338
+ return out;
94339
+ }
94340
+ function dedupPreserveOrder(nums) {
94341
+ const seen = new Set();
94342
+ const out = [];
94343
+ for (const n of nums) {
94344
+ if (!seen.has(n)) {
94345
+ seen.add(n);
94346
+ out.push(n);
94347
+ }
94348
+ }
94349
+ return out;
94350
+ }
94351
+ function parseCitationClusters(text) {
94352
+ if (!text) return [];
94353
+ const markers = [];
94354
+ MARKER_RE.lastIndex = 0;
94355
+ let m;
94356
+ while ((m = MARKER_RE.exec(text)) !== null) {
94357
+ const indices = parseIndicesInside(m[1]);
94358
+ if (indices.length === 0) continue;
94359
+ markers.push({
94360
+ start: m.index,
94361
+ end: MARKER_RE.lastIndex,
94362
+ indices
94363
+ });
94364
+ }
94365
+ if (markers.length === 0) {
94366
+ return [{
94367
+ type: "text",
94368
+ value: text
94369
+ }];
94370
+ }
94371
+
94372
+ // Merge markers that are separated only by whitespace into a single
94373
+ // cluster. `[1][2]`, `[1] [2]`, and `[1,2]` all read as one citation
94374
+ // cluster attached to the preceding sentence.
94375
+ const clusters = [];
94376
+ for (const cur of markers) {
94377
+ const last = clusters.length ? clusters[clusters.length - 1] : null;
94378
+ if (last && /^\s*$/.test(text.slice(last.end, cur.start))) {
94379
+ last.end = cur.end;
94380
+ last.indices.push(...cur.indices);
94381
+ } else {
94382
+ clusters.push({
94383
+ start: cur.start,
94384
+ end: cur.end,
94385
+ indices: [...cur.indices]
94386
+ });
94387
+ }
94388
+ }
94389
+ const out = [];
94390
+ let cursor = 0;
94391
+ for (const c of clusters) {
94392
+ if (c.start > cursor) {
94393
+ out.push({
94394
+ type: "text",
94395
+ value: text.slice(cursor, c.start)
94396
+ });
94397
+ }
94398
+ out.push({
94399
+ type: "cite",
94400
+ indices: dedupPreserveOrder(c.indices)
94401
+ });
94402
+ cursor = c.end;
94403
+ }
94404
+ if (cursor < text.length) {
94405
+ out.push({
94406
+ type: "text",
94407
+ value: text.slice(cursor)
94408
+ });
94409
+ }
94410
+ return out;
94411
+ }
94412
+ function serializeCitationIndices(indices) {
94413
+ return indices.join(",");
94414
+ }
94415
+ function parseCitationIndicesFromAttr(attr) {
94416
+ if (!attr) return [];
94417
+ const out = [];
94418
+ for (const t of String(attr).split(",")) {
94419
+ const n = parseInt(t.trim(), 10);
94420
+ if (Number.isFinite(n) && n >= 1) out.push(n);
94421
+ }
94422
+ return dedupPreserveOrder(out);
94423
+ }
94424
+
94425
+ /**
94426
+ * rehype plugin — walks HAST text nodes emitted by remark and replaces
94427
+ * `[N]` citation markers with `<span data-eshal-citation="1,3">`
94428
+ * placeholders. A `components.span` override in MessageBubble swaps
94429
+ * each placeholder for a `<CitationPill>` React node at render time.
94430
+ *
94431
+ * Why a HAST plugin and not a pre-ReactMarkdown string transform:
94432
+ * Markdown spans (bold, italic, links) can wrap the marker text —
94433
+ * pre-splitting the raw string breaks formatting boundaries. HAST-time
94434
+ * replacement only touches text nodes, so `**bold [1]**` stays one
94435
+ * bold span with the pill nested at the right place.
94436
+ *
94437
+ * Ported byte-for-byte from packages/agent-sdk/src/utils/rehypeCitations.ts —
94438
+ * keep in sync.
94439
+ */
94440
+ function rehypeCitations() {
94441
+ return tree => {
94442
+ visit(tree, "text", (node, index, parent) => {
94443
+ if (index == null || parent == null) return;
94444
+ // Skip text inside <code> / <pre> — markers there are not
94445
+ // citations (someone's showing example markdown).
94446
+ if (parent.type === "element" && (parent.tagName === "code" || parent.tagName === "pre")) {
94447
+ return;
94448
+ }
94449
+ const segments = parseCitationClusters(node.value);
94450
+ // No markers found — leave the text node untouched.
94451
+ if (segments.length === 1 && segments[0].type === "text") return;
94452
+
94453
+ // 2026-07-14 — glue pill to preceding word (non-breaking space)
94454
+ // so HTML doesn't wrap the pill alone onto a new line. Preserves
94455
+ // the "sentence ending [pill]" reading flow.
94456
+ const replacements = segments.map((seg, i) => {
94457
+ if (seg.type === "text") {
94458
+ const nextIsCite = i + 1 < segments.length && segments[i + 1].type === "cite";
94459
+ const value = nextIsCite ? seg.value.replace(/[ \t]+$/, "\u00a0") : seg.value;
94460
+ return {
94461
+ type: "text",
94462
+ value
94463
+ };
94464
+ }
94465
+ return {
94466
+ type: "element",
94467
+ tagName: "span",
94468
+ properties: {
94469
+ dataEshalCitation: serializeCitationIndices(seg.indices)
94470
+ },
94471
+ children: []
94472
+ };
94473
+ });
94474
+ parent.children.splice(index, 1, ...replacements);
94475
+ return [SKIP, index + replacements.length];
94476
+ });
94477
+ };
94478
+ }
94479
+
94480
+ const WidgetCitationContext = /*#__PURE__*/reactExports.createContext(null);
94481
+ function decodeName(name) {
94482
+ if (!name) return "";
94483
+ try {
94484
+ return decodeURIComponent(String(name));
94485
+ } catch (_unused) {
94486
+ return String(name);
94487
+ }
94488
+ }
94489
+ function isFileLikeSource(s) {
94490
+ if (!s) return false;
94491
+ const src_type = s.source_type;
94492
+ const url = s.url;
94493
+ return src_type === "file" || typeof url === "string" && url.includes("/api/v1/sharepoint/file/") || !!s.source_id && !url;
94494
+ }
94495
+ function displayLabel(s, fallbackIndex) {
94496
+ return decodeName(s.source_name) || s.url || s.source_type || "Source ".concat(fallbackIndex);
94497
+ }
94498
+ function pillKey(s) {
94499
+ return s.url || s.source_id || s.sourceid || s.source_name || "";
94500
+ }
94501
+ function CitationPill(_ref) {
94502
+ let {
94503
+ indices
94504
+ } = _ref;
94505
+ const ctx = reactExports.useContext(WidgetCitationContext);
94506
+ const anchorRef = reactExports.useRef(null);
94507
+ // 2026-07-14 — popover is portaled to document.body, not inside
94508
+ // anchor. Track it so the outside-click handler can distinguish
94509
+ // "click inside popover" from "click outside" — otherwise moving
94510
+ // the mouse to click a source row closes the popover before the
94511
+ // click lands.
94512
+ const popoverRef = reactExports.useRef(null);
94513
+ const [open, setOpen] = reactExports.useState(false);
94514
+ const [pos, setPos] = reactExports.useState(null);
94515
+
94516
+ // The widget passes the message's sources into the context directly,
94517
+ // so no DOM traversal is required. Resolve 1-based indices → source
94518
+ // objects. Prefer the backend-emitted `citation_indices` array on
94519
+ // each source (2026-07-14 refactor — preserves the LLM's original
94520
+ // chunk-manifest position through filter + dedup + ACL). Fall back
94521
+ // to array-position lookup for responses from an older backend.
94522
+ // Skip out-of-range so a hallucinated `[99]` doesn't blank the pill.
94523
+ //
94524
+ // 2026-07-14 — DEDUP by source identity. When a cluster like
94525
+ // `[1,4,6]` resolves to THREE indices all pointing at the same
94526
+ // PDF (same source_name + url after backend dedup merged the
94527
+ // chunks), the popover used to render the same "State Textile
94528
+ // Policy.pdf" three times. Collapse to unique sources; keep the
94529
+ // FIRST index encountered as the display anchor.
94530
+ const referenced = reactExports.useMemo(() => {
94531
+ if (!ctx || !Array.isArray(ctx.sources)) return [];
94532
+ const out = [];
94533
+ const seen = new Set();
94534
+ for (const n of indices) {
94535
+ var _ref2, _ref3, _ref4, _src$url;
94536
+ const byCitationIndex = ctx.sources.find(s => Array.isArray(s === null || s === void 0 ? void 0 : s.citation_indices) && s.citation_indices.includes(n));
94537
+ const src = byCitationIndex !== null && byCitationIndex !== void 0 ? byCitationIndex : ctx.sources[n - 1];
94538
+ if (!src) continue;
94539
+ // 2026-07-15 — prioritise URL (unique per web page) over
94540
+ // sourceid (shared across every page of the same Knowledge row).
94541
+ // Website-connector sources emit distinct URLs for distinct
94542
+ // pages but a single Knowledge row id — dedupping on sourceid
94543
+ // first collapsed them to one row in the popover.
94544
+ const key = String((_ref2 = (_ref3 = (_ref4 = (_src$url = src.url) !== null && _src$url !== void 0 ? _src$url : src.source_id) !== null && _ref4 !== void 0 ? _ref4 : src.sourceid) !== null && _ref3 !== void 0 ? _ref3 : src.source_name) !== null && _ref2 !== void 0 ? _ref2 : "").toLowerCase();
94545
+ if (key && seen.has(key)) continue;
94546
+ if (key) seen.add(key);
94547
+ out.push({
94548
+ src,
94549
+ index: n
94550
+ });
94551
+ }
94552
+ return out;
94553
+ }, [ctx, indices]);
94554
+
94555
+ // Close on Esc / outside click.
94556
+ //
94557
+ // 2026-07-15 — must use event.composedPath() rather than
94558
+ // event.target + .contains(). The widget renders inside a Shadow DOM
94559
+ // (mode:open) — when a native mousedown reaches the document-level
94560
+ // listener the event.target is RETARGETED to the shadow HOST, not the
94561
+ // element actually clicked. `anchorRef.current.contains(shadowHost)`
94562
+ // and `popoverRef.current.contains(shadowHost)` both return FALSE →
94563
+ // every click, including the one that opens the popover, is treated
94564
+ // as an outside click and the popover closes immediately. composedPath
94565
+ // returns the true event path THROUGH shadow trees, so the inAnchor /
94566
+ // inPopover checks resolve correctly. Same fix as ChatHeader.jsx:49.
94567
+ reactExports.useEffect(() => {
94568
+ if (!open) return undefined;
94569
+ const onDocClick = e => {
94570
+ const path = typeof e.composedPath === "function" ? e.composedPath() : [];
94571
+ const inAnchor = anchorRef.current && path.includes(anchorRef.current);
94572
+ const inPopover = popoverRef.current && path.includes(popoverRef.current);
94573
+ if (inAnchor || inPopover) return;
94574
+ setOpen(false);
94575
+ };
94576
+ const onKey = e => {
94577
+ if (e.key === "Escape") setOpen(false);
94578
+ };
94579
+ document.addEventListener("mousedown", onDocClick);
94580
+ document.addEventListener("keydown", onKey);
94581
+ return () => {
94582
+ document.removeEventListener("mousedown", onDocClick);
94583
+ document.removeEventListener("keydown", onKey);
94584
+ };
94585
+ }, [open]);
94586
+ const openPopover = () => {
94587
+ const anchor = anchorRef.current;
94588
+ if (!anchor) return;
94589
+ const rect = anchor.getBoundingClientRect();
94590
+ setPos({
94591
+ top: rect.bottom + window.scrollY + 4,
94592
+ left: rect.left + window.scrollX
94593
+ });
94594
+ setOpen(true);
94595
+ };
94596
+
94597
+ // No context (rendered outside a chat) — degrade to raw marker.
94598
+ if (!ctx) {
94599
+ return /*#__PURE__*/jsxRuntimeExports.jsxs("span", {
94600
+ style: {
94601
+ opacity: 0.5
94602
+ },
94603
+ children: ["[", indices.join(","), "]"]
94604
+ });
94605
+ }
94606
+
94607
+ // 2026-07-14 — HIDE marker entirely when message has NO sources at
94608
+ // all (backend explicitly emitted []). Covers greeting / fallback /
94609
+ // private-only ACL turns where the LLM emitted `[N]` but backend
94610
+ // suppressed the citation cards. Uniform client fix across all 3
94611
+ // surfaces + all backend paths.
94612
+ if (Array.isArray(ctx.sources) && ctx.sources.length === 0) {
94613
+ return null;
94614
+ }
94615
+
94616
+ // Sources not resolved (e.g. the eshal.sources chunk arrived late,
94617
+ // or a hallucinated `[99]`) — render a subtle placeholder so the
94618
+ // reader still sees the citation exists.
94619
+ if (referenced.length === 0) {
94620
+ return /*#__PURE__*/jsxRuntimeExports.jsxs("span", {
94621
+ ref: anchorRef,
94622
+ style: {
94623
+ display: "inline-block",
94624
+ padding: "0 4px",
94625
+ fontSize: 11,
94626
+ borderRadius: 4,
94627
+ background: "rgba(0,0,0,0.06)",
94628
+ verticalAlign: "1px",
94629
+ opacity: 0.6
94630
+ },
94631
+ children: ["[", indices.join(","), "]"]
94632
+ });
94633
+ }
94634
+ const first = referenced[0];
94635
+ const extraCount = referenced.length - 1;
94636
+ const firstLabel = displayLabel(first.src, first.index);
94637
+ const firstIsFile = isFileLikeSource(first.src);
94638
+ const busy = ctx.downloadingKey && ctx.downloadingKey === pillKey(first.src);
94639
+ const activate = s => {
94640
+ if (typeof ctx.onSourceActivate === "function") {
94641
+ ctx.onSourceActivate(s);
94642
+ }
94643
+ };
94644
+ const onPillClick = e => {
94645
+ e.preventDefault();
94646
+ e.stopPropagation();
94647
+ if (referenced.length === 1) {
94648
+ activate(first.src);
94649
+ return;
94650
+ }
94651
+ if (open) setOpen(false);else openPopover();
94652
+ };
94653
+ const iconSize = 12;
94654
+ return /*#__PURE__*/jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
94655
+ children: [/*#__PURE__*/jsxRuntimeExports.jsxs("span", {
94656
+ ref: anchorRef,
94657
+ role: "button",
94658
+ tabIndex: 0,
94659
+ title: firstLabel + (extraCount ? " (+".concat(extraCount, " more)") : ""),
94660
+ onClick: onPillClick,
94661
+ onKeyDown: e => {
94662
+ if (e.key === "Enter" || e.key === " ") {
94663
+ e.preventDefault();
94664
+ onPillClick(e);
94665
+ }
94666
+ },
94667
+ style: {
94668
+ display: "inline-flex",
94669
+ alignItems: "center",
94670
+ gap: 3,
94671
+ height: 20,
94672
+ padding: "0 5px 0 6px",
94673
+ margin: "0 2px",
94674
+ fontSize: 11,
94675
+ lineHeight: 1,
94676
+ borderRadius: 5,
94677
+ background: "rgba(59, 130, 246, 0.10)",
94678
+ color: "rgb(37, 99, 235)",
94679
+ border: "0.5px solid rgba(59, 130, 246, 0.35)",
94680
+ cursor: "pointer",
94681
+ userSelect: "none",
94682
+ maxWidth: 180,
94683
+ verticalAlign: "1px",
94684
+ textDecoration: "none",
94685
+ fontWeight: 500,
94686
+ whiteSpace: "nowrap"
94687
+ },
94688
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx("span", {
94689
+ style: {
94690
+ display: "inline-flex",
94691
+ flexShrink: 0
94692
+ },
94693
+ children: firstIsFile ? /*#__PURE__*/jsxRuntimeExports.jsx(FileText, {
94694
+ size: iconSize,
94695
+ strokeWidth: 2,
94696
+ "aria-hidden": true
94697
+ }) : /*#__PURE__*/jsxRuntimeExports.jsx(Globe, {
94698
+ size: iconSize,
94699
+ strokeWidth: 2,
94700
+ "aria-hidden": true
94701
+ })
94702
+ }), /*#__PURE__*/jsxRuntimeExports.jsx("span", {
94703
+ style: {
94704
+ overflow: "hidden",
94705
+ textOverflow: "ellipsis",
94706
+ whiteSpace: "nowrap",
94707
+ maxWidth: 110
94708
+ },
94709
+ children: firstLabel
94710
+ }), extraCount > 0 && /*#__PURE__*/jsxRuntimeExports.jsxs("span", {
94711
+ style: {
94712
+ background: "rgb(37, 99, 235)",
94713
+ color: "white",
94714
+ borderRadius: 3,
94715
+ padding: "1px 4px",
94716
+ fontSize: 9,
94717
+ lineHeight: 1,
94718
+ fontWeight: 600,
94719
+ marginLeft: 1
94720
+ },
94721
+ children: ["+", extraCount]
94722
+ }), referenced.length === 1 && /*#__PURE__*/jsxRuntimeExports.jsx("span", {
94723
+ style: {
94724
+ display: "inline-flex",
94725
+ alignItems: "center",
94726
+ justifyContent: "center",
94727
+ flexShrink: 0,
94728
+ paddingLeft: 3,
94729
+ borderLeft: "0.5px solid rgba(59, 130, 246, 0.35)",
94730
+ marginLeft: 2
94731
+ },
94732
+ children: busy ? /*#__PURE__*/jsxRuntimeExports.jsx(LoaderCircle, {
94733
+ size: iconSize,
94734
+ strokeWidth: 2,
94735
+ className: "animate-spin"
94736
+ }) : firstIsFile ? /*#__PURE__*/jsxRuntimeExports.jsx(Download, {
94737
+ size: iconSize,
94738
+ strokeWidth: 2
94739
+ }) : /*#__PURE__*/jsxRuntimeExports.jsx(ExternalLink, {
94740
+ size: iconSize,
94741
+ strokeWidth: 2
94742
+ })
94743
+ })]
94744
+ }), open && pos && typeof document !== "undefined" && /*#__PURE__*/reactDomExports.createPortal(/*#__PURE__*/jsxRuntimeExports.jsxs("div", {
94745
+ ref: popoverRef,
94746
+ role: "dialog",
94747
+ "aria-label": "".concat(referenced.length, " sources cited"),
94748
+ style: {
94749
+ position: "absolute",
94750
+ top: pos.top,
94751
+ left: pos.left,
94752
+ // 2026-07-15 — must sit ABOVE the widget's chat-widget-root
94753
+ // which uses z-[999999]. Portalled popover was rendering
94754
+ // BEHIND the chat panel. Max int32 puts us above every
94755
+ // known widget stacking context.
94756
+ zIndex: 2147483647,
94757
+ background: "#fff",
94758
+ color: "#111",
94759
+ border: "0.5px solid rgba(0, 0, 0, 0.12)",
94760
+ borderRadius: 8,
94761
+ boxShadow: "0 4px 16px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0,0,0,0.06)",
94762
+ padding: 6,
94763
+ minWidth: 240,
94764
+ maxWidth: 360,
94765
+ fontSize: 12
94766
+ },
94767
+ onClick: e => e.stopPropagation(),
94768
+ onMouseDown: e => e.stopPropagation(),
94769
+ children: [/*#__PURE__*/jsxRuntimeExports.jsxs("div", {
94770
+ style: {
94771
+ fontSize: 10,
94772
+ textTransform: "uppercase",
94773
+ opacity: 0.55,
94774
+ letterSpacing: "0.06em",
94775
+ padding: "4px 6px 6px"
94776
+ },
94777
+ children: [referenced.length, " source", referenced.length === 1 ? "" : "s"]
94778
+ }), referenced.map(_ref5 => {
94779
+ let {
94780
+ src,
94781
+ index
94782
+ } = _ref5;
94783
+ const label = displayLabel(src, index);
94784
+ const rowIsFile = isFileLikeSource(src);
94785
+ const kBusy = ctx.downloadingKey && ctx.downloadingKey === pillKey(src);
94786
+ return /*#__PURE__*/jsxRuntimeExports.jsxs("button", {
94787
+ type: "button",
94788
+ onClick: () => activate(src),
94789
+ disabled: !!kBusy,
94790
+ title: label,
94791
+ style: {
94792
+ display: "flex",
94793
+ alignItems: "center",
94794
+ gap: 8,
94795
+ width: "100%",
94796
+ padding: "6px 8px",
94797
+ border: 0,
94798
+ background: "transparent",
94799
+ color: "inherit",
94800
+ cursor: kBusy ? "default" : "pointer",
94801
+ textAlign: "left",
94802
+ borderRadius: 4,
94803
+ font: "inherit"
94804
+ },
94805
+ onMouseEnter: e => {
94806
+ e.currentTarget.style.background = "rgba(0,0,0,0.04)";
94807
+ },
94808
+ onMouseLeave: e => {
94809
+ e.currentTarget.style.background = "transparent";
94810
+ },
94811
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx("span", {
94812
+ style: {
94813
+ display: "inline-flex",
94814
+ flexShrink: 0,
94815
+ opacity: 0.8
94816
+ },
94817
+ children: rowIsFile ? /*#__PURE__*/jsxRuntimeExports.jsx(FileText, {
94818
+ size: 14,
94819
+ strokeWidth: 2,
94820
+ "aria-hidden": true
94821
+ }) : /*#__PURE__*/jsxRuntimeExports.jsx(Globe, {
94822
+ size: 14,
94823
+ strokeWidth: 2,
94824
+ "aria-hidden": true
94825
+ })
94826
+ }), /*#__PURE__*/jsxRuntimeExports.jsx("span", {
94827
+ style: {
94828
+ flex: 1,
94829
+ minWidth: 0,
94830
+ overflow: "hidden",
94831
+ textOverflow: "ellipsis",
94832
+ whiteSpace: "nowrap"
94833
+ },
94834
+ children: label
94835
+ }), /*#__PURE__*/jsxRuntimeExports.jsx("span", {
94836
+ style: {
94837
+ display: "inline-flex",
94838
+ flexShrink: 0,
94839
+ opacity: 0.7
94840
+ },
94841
+ children: kBusy ? /*#__PURE__*/jsxRuntimeExports.jsx(LoaderCircle, {
94842
+ size: 14,
94843
+ strokeWidth: 2,
94844
+ className: "animate-spin"
94845
+ }) : rowIsFile ? /*#__PURE__*/jsxRuntimeExports.jsx(Download, {
94846
+ size: 14,
94847
+ strokeWidth: 2
94848
+ }) : /*#__PURE__*/jsxRuntimeExports.jsx(ExternalLink, {
94849
+ size: 14,
94850
+ strokeWidth: 2
94851
+ })
94852
+ })]
94853
+ }, "".concat(index, "-").concat(pillKey(src) || index));
94854
+ })]
94855
+ }), document.body)]
94856
+ });
94857
+ }
94858
+
94859
+ const _excluded$1 = ["node", "children"],
94860
+ _excluded2 = ["children"],
93864
94861
  _excluded3 = ["node", "children"],
93865
94862
  _excluded4 = ["node", "children"],
93866
- _excluded5 = ["node", "children", "start"],
93867
- _excluded6 = ["node", "children", "data-ol-index"],
93868
- _excluded7 = ["node", "children"],
94863
+ _excluded5 = ["node", "children"],
94864
+ _excluded6 = ["node", "children", "start"],
94865
+ _excluded7 = ["node", "children", "data-ol-index"],
93869
94866
  _excluded8 = ["node", "children"],
93870
94867
  _excluded9 = ["node", "children"],
93871
94868
  _excluded0 = ["node", "children"],
93872
94869
  _excluded1 = ["node", "children"],
93873
94870
  _excluded10 = ["node", "children"],
93874
94871
  _excluded11 = ["node", "children"],
93875
- _excluded12 = ["className", "children"];
94872
+ _excluded12 = ["node", "children"],
94873
+ _excluded13 = ["className", "children"];
93876
94874
  const A2UI_FENCE_LANGS = new Set(["eshal-ui", "eshal-chart", "chart"]);
93877
94875
 
93878
94876
  // Returns true when a ReactMarkdown `pre` node's only child is a `code` block
@@ -93947,7 +94945,8 @@
93947
94945
  textColor,
93948
94946
  fontFamily,
93949
94947
  fontSize,
93950
- onButtonClick
94948
+ onButtonClick,
94949
+ provideCitations = true
93951
94950
  } = _ref;
93952
94951
  const [displayedContent, setDisplayedContent] = reactExports.useState("");
93953
94952
  const [showCursor, setShowCursor] = reactExports.useState(false);
@@ -94022,17 +95021,45 @@
94022
95021
  },
94023
95022
  children: [/*#__PURE__*/jsxRuntimeExports.jsx(Markdown, {
94024
95023
  className: "max-w-none [&>*:last-child]:!mb-0 [&>*:first-child]:!mt-0",
94025
- remarkPlugins: [remarkGfm],
95024
+ remarkPlugins: [remarkGfm]
95025
+ // Skip the rehypeCitations plugin when the org opted out —
95026
+ // markers then render as plain text so nothing squeaks
95027
+ // through as a placeholder pill.
95028
+ ,
95029
+ rehypePlugins: provideCitations ? [rehypeCitations] : [],
94026
95030
  components: {
95031
+ // Citation-marker → pill swap. Every `<span>` normally passes
95032
+ // through unchanged; when the HAST plugin has tagged it as a
95033
+ // citation, swap for `<CitationPill>`.
95034
+ span(_ref2) {
95035
+ var _props$dataEshalCit;
95036
+ let {
95037
+ node,
95038
+ children
95039
+ } = _ref2,
95040
+ props = _objectWithoutProperties$m(_ref2, _excluded$1);
95041
+ const attr = (_props$dataEshalCit = props["data-eshal-citation"]) !== null && _props$dataEshalCit !== void 0 ? _props$dataEshalCit : props.dataEshalCitation;
95042
+ if (typeof attr === "string" && attr.length > 0) {
95043
+ const indices = parseCitationIndicesFromAttr(attr);
95044
+ if (indices.length > 0) {
95045
+ return /*#__PURE__*/jsxRuntimeExports.jsx(CitationPill, {
95046
+ indices: indices
95047
+ });
95048
+ }
95049
+ }
95050
+ return /*#__PURE__*/jsxRuntimeExports.jsx("span", _objectSpread2(_objectSpread2({}, props), {}, {
95051
+ children: children
95052
+ }));
95053
+ },
94027
95054
  // Unwrap the <pre> shell when its child is an A2UI fence so the
94028
95055
  // chart card sits directly in the bubble flow, not inside a <pre>
94029
95056
  // (which forces monospace font and defeats the card border-radius).
94030
95057
  // Ordinary code blocks (```python```, ```sql```) keep their <pre>.
94031
- pre(_ref2) {
95058
+ pre(_ref3) {
94032
95059
  let {
94033
95060
  children
94034
- } = _ref2,
94035
- props = _objectWithoutProperties$m(_ref2, _excluded$1);
95061
+ } = _ref3,
95062
+ props = _objectWithoutProperties$m(_ref3, _excluded2);
94036
95063
  if (preWrapsKnownFence(children)) return /*#__PURE__*/jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, {
94037
95064
  children: children
94038
95065
  });
@@ -94040,12 +95067,12 @@
94040
95067
  children: children
94041
95068
  }));
94042
95069
  },
94043
- a(_ref3) {
95070
+ a(_ref4) {
94044
95071
  let {
94045
95072
  node,
94046
95073
  children
94047
- } = _ref3,
94048
- props = _objectWithoutProperties$m(_ref3, _excluded2);
95074
+ } = _ref4,
95075
+ props = _objectWithoutProperties$m(_ref4, _excluded3);
94049
95076
  return /*#__PURE__*/jsxRuntimeExports.jsx("a", _objectSpread2(_objectSpread2({
94050
95077
  className: "hover:underline",
94051
95078
  dir: "ltr",
@@ -94059,13 +95086,13 @@
94059
95086
  children: children
94060
95087
  }));
94061
95088
  },
94062
- p(_ref4) {
95089
+ p(_ref5) {
94063
95090
  var _node$parent;
94064
95091
  let {
94065
95092
  node,
94066
95093
  children
94067
- } = _ref4,
94068
- props = _objectWithoutProperties$m(_ref4, _excluded3);
95094
+ } = _ref5,
95095
+ props = _objectWithoutProperties$m(_ref5, _excluded4);
94069
95096
  const isInsideListItem = (node === null || node === void 0 || (_node$parent = node.parent) === null || _node$parent === void 0 ? void 0 : _node$parent.tagName) === "li";
94070
95097
  return /*#__PURE__*/jsxRuntimeExports.jsx("p", _objectSpread2(_objectSpread2({
94071
95098
  className: "leading-relaxed [&:first-child]:!mt-0",
@@ -94075,38 +95102,42 @@
94075
95102
  fontSize: fontSize || "14px",
94076
95103
  margin: 0,
94077
95104
  marginTop: 0,
94078
- marginBottom: isInsideListItem ? "0.125rem" : "0.5rem",
94079
- lineHeight: "1.5",
95105
+ // Paragraph rhythm — 0.85rem gives clear separation between
95106
+ // paragraphs (and between a citation-pill-ended paragraph and
95107
+ // the next), instead of the old cramped 0.5rem that read as
95108
+ // "clubbed". List-item paragraphs stay tight.
95109
+ marginBottom: isInsideListItem ? "0.125rem" : "0.85rem",
95110
+ lineHeight: "1.6",
94080
95111
  padding: 0
94081
95112
  }
94082
95113
  }, props), {}, {
94083
95114
  children: children
94084
95115
  }));
94085
95116
  },
94086
- ul(_ref5) {
95117
+ ul(_ref6) {
94087
95118
  let {
94088
95119
  node,
94089
95120
  children
94090
- } = _ref5,
94091
- props = _objectWithoutProperties$m(_ref5, _excluded4);
95121
+ } = _ref6,
95122
+ props = _objectWithoutProperties$m(_ref6, _excluded5);
94092
95123
  return /*#__PURE__*/jsxRuntimeExports.jsx("ul", _objectSpread2(_objectSpread2({
94093
95124
  className: "list-disc [&:first-child]:!mt-0",
94094
95125
  style: {
94095
95126
  marginTop: 0,
94096
- marginBottom: "0.4rem",
95127
+ marginBottom: "0.6rem",
94097
95128
  paddingInlineStart: "1.2rem"
94098
95129
  }
94099
95130
  }, props), {}, {
94100
95131
  children: children
94101
95132
  }));
94102
95133
  },
94103
- ol(_ref6) {
95134
+ ol(_ref7) {
94104
95135
  let {
94105
95136
  node,
94106
95137
  children,
94107
95138
  start = 1
94108
- } = _ref6,
94109
- props = _objectWithoutProperties$m(_ref6, _excluded5);
95139
+ } = _ref7,
95140
+ props = _objectWithoutProperties$m(_ref7, _excluded6);
94110
95141
  // Why we DON'T use `list-decimal` here:
94111
95142
  //
94112
95143
  // `list-decimal` renders the "1.", "2.", … markers via
@@ -94136,7 +95167,7 @@
94136
95167
  style: {
94137
95168
  listStyle: "none",
94138
95169
  marginTop: 0,
94139
- marginBottom: "0.4rem",
95170
+ marginBottom: "0.6rem",
94140
95171
  paddingInlineStart: 0
94141
95172
  }
94142
95173
  }, props), {}, {
@@ -94150,13 +95181,13 @@
94150
95181
  })
94151
95182
  }));
94152
95183
  },
94153
- li(_ref7) {
95184
+ li(_ref8) {
94154
95185
  let {
94155
95186
  node,
94156
95187
  children,
94157
95188
  "data-ol-index": dataOlIndex
94158
- } = _ref7,
94159
- props = _objectWithoutProperties$m(_ref7, _excluded6);
95189
+ } = _ref8,
95190
+ props = _objectWithoutProperties$m(_ref8, _excluded7);
94160
95191
  // Inline-marker rendering (see <ol> comment above for the
94161
95192
  // ::marker font bug this works around). When `dataOlIndex`
94162
95193
  // is present, we're inside a custom-numbered <ol>; render
@@ -94209,12 +95240,12 @@
94209
95240
  children: children
94210
95241
  }));
94211
95242
  },
94212
- h1(_ref8) {
95243
+ h1(_ref9) {
94213
95244
  let {
94214
95245
  node,
94215
95246
  children
94216
- } = _ref8,
94217
- props = _objectWithoutProperties$m(_ref8, _excluded7);
95247
+ } = _ref9,
95248
+ props = _objectWithoutProperties$m(_ref9, _excluded8);
94218
95249
  return /*#__PURE__*/jsxRuntimeExports.jsx("h1", _objectSpread2(_objectSpread2({
94219
95250
  className: "text-xl font-bold [&:first-child]:!mt-0",
94220
95251
  style: {
@@ -94228,12 +95259,12 @@
94228
95259
  children: children
94229
95260
  }));
94230
95261
  },
94231
- h2(_ref9) {
95262
+ h2(_ref0) {
94232
95263
  let {
94233
95264
  node,
94234
95265
  children
94235
- } = _ref9,
94236
- props = _objectWithoutProperties$m(_ref9, _excluded8);
95266
+ } = _ref0,
95267
+ props = _objectWithoutProperties$m(_ref0, _excluded9);
94237
95268
  return /*#__PURE__*/jsxRuntimeExports.jsx("h2", _objectSpread2(_objectSpread2({
94238
95269
  className: "text-lg font-semibold [&:first-child]:!mt-0",
94239
95270
  style: {
@@ -94247,12 +95278,12 @@
94247
95278
  children: children
94248
95279
  }));
94249
95280
  },
94250
- h3(_ref0) {
95281
+ h3(_ref1) {
94251
95282
  let {
94252
95283
  node,
94253
95284
  children
94254
- } = _ref0,
94255
- props = _objectWithoutProperties$m(_ref0, _excluded9);
95285
+ } = _ref1,
95286
+ props = _objectWithoutProperties$m(_ref1, _excluded0);
94256
95287
  return /*#__PURE__*/jsxRuntimeExports.jsx("h3", _objectSpread2(_objectSpread2({
94257
95288
  className: "text-base font-semibold [&:first-child]:!mt-0",
94258
95289
  style: {
@@ -94266,25 +95297,25 @@
94266
95297
  children: children
94267
95298
  }));
94268
95299
  },
94269
- blockquote(_ref1) {
95300
+ blockquote(_ref10) {
94270
95301
  let {
94271
95302
  node,
94272
95303
  children
94273
- } = _ref1,
94274
- props = _objectWithoutProperties$m(_ref1, _excluded0);
95304
+ } = _ref10,
95305
+ props = _objectWithoutProperties$m(_ref10, _excluded1);
94275
95306
  return /*#__PURE__*/jsxRuntimeExports.jsx("blockquote", _objectSpread2(_objectSpread2({
94276
95307
  className: "border-l-4 pl-4 italic ".concat(isDark ? "border-gray-600 text-gray-300" : "border-gray-300 text-gray-700")
94277
95308
  }, props), {}, {
94278
95309
  children: children
94279
95310
  }));
94280
95311
  },
94281
- table(_ref10) {
95312
+ table(_ref11) {
94282
95313
  var _node$children;
94283
95314
  let {
94284
95315
  node,
94285
95316
  children
94286
- } = _ref10,
94287
- props = _objectWithoutProperties$m(_ref10, _excluded1);
95317
+ } = _ref11,
95318
+ props = _objectWithoutProperties$m(_ref11, _excluded10);
94288
95319
  // react-markdown v9 passes HAST nodes (not MDAST), so the
94289
95320
  // table's children are <thead> / <tbody> elements, not
94290
95321
  // tableRow nodes. Traverse accordingly to extract columns
@@ -94332,36 +95363,36 @@
94332
95363
  }))
94333
95364
  });
94334
95365
  },
94335
- th(_ref11) {
95366
+ th(_ref12) {
94336
95367
  let {
94337
95368
  node,
94338
95369
  children
94339
- } = _ref11,
94340
- props = _objectWithoutProperties$m(_ref11, _excluded10);
95370
+ } = _ref12,
95371
+ props = _objectWithoutProperties$m(_ref12, _excluded11);
94341
95372
  return /*#__PURE__*/jsxRuntimeExports.jsx("th", _objectSpread2(_objectSpread2({
94342
95373
  className: "border border-gray-300 bg-gray-100 px-3 py-2 text-left font-semibold"
94343
95374
  }, props), {}, {
94344
95375
  children: children
94345
95376
  }));
94346
95377
  },
94347
- td(_ref12) {
95378
+ td(_ref13) {
94348
95379
  let {
94349
95380
  node,
94350
95381
  children
94351
- } = _ref12,
94352
- props = _objectWithoutProperties$m(_ref12, _excluded11);
95382
+ } = _ref13,
95383
+ props = _objectWithoutProperties$m(_ref13, _excluded12);
94353
95384
  return /*#__PURE__*/jsxRuntimeExports.jsx("td", _objectSpread2(_objectSpread2({
94354
95385
  className: "border border-gray-300 px-3 py-2"
94355
95386
  }, props), {}, {
94356
95387
  children: children
94357
95388
  }));
94358
95389
  },
94359
- code(_ref13) {
95390
+ code(_ref14) {
94360
95391
  let {
94361
95392
  className,
94362
95393
  children
94363
- } = _ref13,
94364
- props = _objectWithoutProperties$m(_ref13, _excluded12);
95394
+ } = _ref14,
95395
+ props = _objectWithoutProperties$m(_ref14, _excluded13);
94365
95396
  const match = /language-([\w-]+)/.exec(className || "");
94366
95397
  const lang = match ? match[1] : null;
94367
95398
 
@@ -94417,7 +95448,7 @@
94417
95448
  })]
94418
95449
  });
94419
95450
  };
94420
- const TypingIndicator = _ref14 => {
95451
+ const TypingIndicator = _ref15 => {
94421
95452
  return /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
94422
95453
  className: "flex gap-1.5",
94423
95454
  children: [/*#__PURE__*/jsxRuntimeExports.jsx("div", {
@@ -94439,156 +95470,126 @@
94439
95470
  });
94440
95471
  };
94441
95472
 
94442
- // Sources section: citations and file downloads from stream complete chunk
94443
- const MessageSources = _ref15 => {
95473
+ // Decision widget component for HITL (Human-in-the-Loop)
95474
+ const DecisionWidget = _ref18 => {
94444
95475
  let {
94445
- sources = [],
94446
- apiBaseUrl,
94447
- getAuthToken,
94448
- isDark,
94449
- textColor,
94450
- fontFamily,
94451
- fontSize
94452
- } = _ref15;
94453
- const [downloadingId, setDownloadingId] = reactExports.useState(null);
95476
+ question,
95477
+ options,
95478
+ onDecision,
95479
+ disabled,
95480
+ isDark = false
95481
+ } = _ref18;
95482
+ return /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
95483
+ className: "mt-3 p-3 rounded-lg border ".concat(isDark ? "bg-blue-900/30 border-blue-700/50" : "bg-blue-50 border-blue-200"),
95484
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx("p", {
95485
+ className: "text-sm font-medium mb-2 ".concat(isDark ? "text-gray-100" : "text-gray-900"),
95486
+ children: question
95487
+ }), /*#__PURE__*/jsxRuntimeExports.jsx("div", {
95488
+ className: "space-y-2",
95489
+ children: options.map(option => /*#__PURE__*/jsxRuntimeExports.jsx("button", {
95490
+ onClick: () => onDecision(option.id, option.label),
95491
+ disabled: disabled,
95492
+ className: "w-full text-left px-3 py-2 text-sm rounded transition-all ".concat(isDark ? "bg-gray-800 border border-gray-700 hover:bg-blue-900/50 hover:border-blue-600 disabled:opacity-50 disabled:cursor-not-allowed" : "bg-white border border-gray-300 hover:bg-blue-50 hover:border-blue-400 disabled:opacity-50 disabled:cursor-not-allowed"),
95493
+ children: option.label
95494
+ }, option.id))
95495
+ })]
95496
+ });
95497
+ };
94454
95498
 
94455
- // RAG-citation-1 v10: per-citation download key.
94456
- //
94457
- // For multi-file Knowledge sources, N citations share a single
94458
- // source_id. The previous key `s.source_id || s.url || ""`
94459
- // returned the same string for every citation in the same source,
94460
- // so clicking ONE download icon set the loading state on ALL N
94461
- // siblings — they all spun together until one resolved. Concrete
94462
- // UX failure: textile-tenant 8-file Knowledge source — clicking
94463
- // any download icon lit up the spinner on all 8.
94464
- //
94465
- // Fix: prefer the per-file url first (post-#821 every file-upload
94466
- // citation carries a distinct blob name; SharePoint citations
94467
- // carry a distinct proxy URL). Fall back to source_id for the
94468
- // legacy single-file case where url might be missing. Final fall-
94469
- // back to source_name keeps the spinner functional on very old
94470
- // corpora that have none of the above.
94471
- const _downloadKey = s => s.url || s.source_id || s.source_name || "";
94472
- const handleFileDownload = async source => {
94473
- if (!apiBaseUrl) return;
94474
- // 2026-07-03 — RAG-attach-1 download path. Attachment source
94475
- // cards carry a presigned READ URL as `source.url` (added by
94476
- // citation_sources.build_source_obj + chat_utils inline loop
94477
- // when the chunk has `_is_attachment_chunk: True`). Their
94478
- // sourceid is `attachment:<storage_key>` — not resolvable by
94479
- // the legacy /file-download endpoint, which expects a Milvus
94480
- // Knowledge row id. Open the SAS URL directly instead — same
94481
- // pattern SharePoint uses, but via the URL the backend already
94482
- // handed us so no proxy round-trip is needed.
95499
+ /**
95500
+ * useSourceDownloader — shared with `<CitationPill>` via
95501
+ * `WidgetCitationContext`. File sources go through the same
95502
+ * three-branch fetch as the (now-removed) `<MessageSources>` did:
95503
+ * attachment SAS URL → direct GET; SharePoint proxy → GET on the
95504
+ * proxy path; Knowledge blob → POST `/api/v1/support/file-download`.
95505
+ * Web sources open the URL in a new tab.
95506
+ *
95507
+ * Returns `{ onSourceActivate, downloadingKey }` for a
95508
+ * `WidgetCitationContext.Provider` value.
95509
+ */
95510
+ function useSourceDownloader(_ref19) {
95511
+ let {
95512
+ apiBaseUrl,
95513
+ getAuthToken
95514
+ } = _ref19;
95515
+ const [downloadingKey, setDownloadingKey] = reactExports.useState(null);
95516
+ const onSourceActivate = reactExports.useCallback(async source => {
95517
+ if (!source) return;
95518
+ // Compute a stable key for spinner state.
95519
+ const key = source.url || source.source_id || source.sourceid || source.source_name || "";
94483
95520
  const attachmentSourceId = String(source.source_id || source.sourceid || "");
94484
95521
  const isAttachment = attachmentSourceId.startsWith("attachment:");
94485
- if (isAttachment) {
94486
- if (!source.url) {
94487
- console.warn("[widget] attachment source has no URL; download unavailable");
94488
- return;
95522
+ const isSharePointProxy = typeof source.url === "string" && source.url.includes("/api/v1/sharepoint/file/");
95523
+ const isFileLike = source.source_type === "file" || isSharePointProxy || isAttachment || !!(source.source_id || source.sourceid) && !source.url;
95524
+
95525
+ // Web source — open the URL directly, no proxy round-trip.
95526
+ if (!isFileLike) {
95527
+ const url = source.url;
95528
+ if (url) {
95529
+ try {
95530
+ window.open(url, "_blank", "noopener,noreferrer");
95531
+ } catch (_unused2) {
95532
+ /* pop-up blocked */
95533
+ }
94489
95534
  }
94490
- const downloadKey = _downloadKey(source) || "attachment";
94491
- setDownloadingId(downloadKey);
94492
- try {
94493
- // 2026-07-03 — user reported the download dialog was
94494
- // suggesting the storage-key blob name (e.g. `<uuid>-
94495
- // RishabhResume.pdf`) instead of the original filename.
94496
- // Root cause: the server behind `/api/v1/files/...` sends
94497
- // a `Content-Disposition: attachment; filename=<blob>`
94498
- // header, and browsers give that precedence over the
94499
- // `<a download="…">` attribute. Workaround: fetch the
94500
- // bytes into a Blob, mint an object URL, and use `a.download`
94501
- // — object URLs have no `Content-Disposition` so the
94502
- // attribute wins and the user gets the pretty filename.
94503
- // Same pattern the KB /file-download branch below uses.
94504
- const fetchHeaders = {};
95535
+ return;
95536
+ }
95537
+ if (!apiBaseUrl && !isAttachment) {
95538
+ console.warn("[widget] citation download skipped: apiBaseUrl missing and " + "source is not an attachment (no fallback URL to fetch). " + "Source:", source);
95539
+ return;
95540
+ }
95541
+ setDownloadingKey(key);
95542
+ // eslint-disable-next-line no-console
95543
+ console.debug("[widget] citation download starting:", {
95544
+ source_id: source.source_id || source.sourceid,
95545
+ source_name: source.source_name,
95546
+ source_type: source.source_type,
95547
+ isAttachment,
95548
+ isSharePointProxy,
95549
+ isFileLike
95550
+ });
95551
+ try {
95552
+ let res;
95553
+ if (isAttachment) {
95554
+ if (!source.url) throw new Error("attachment has no URL");
95555
+ const headers = {};
94505
95556
  if (typeof getAuthToken === "function") {
94506
95557
  const token = await getAuthToken();
94507
- if (token) fetchHeaders["Authorization"] = "Bearer ".concat(token);
95558
+ if (token) headers["Authorization"] = "Bearer ".concat(token);
94508
95559
  }
94509
- const res = await fetch(source.url, {
95560
+ res = await fetch(source.url, {
94510
95561
  method: "GET",
94511
- headers: fetchHeaders,
95562
+ headers,
94512
95563
  credentials: "include"
94513
95564
  });
94514
- if (!res.ok) {
94515
- throw new Error("Attachment fetch failed: ".concat(res.status));
94516
- }
94517
- const blob = await res.blob();
94518
- const objectUrl = URL.createObjectURL(blob);
94519
- const a = document.createElement("a");
94520
- a.href = objectUrl;
94521
- a.download = source.source_name || "download";
94522
- a.click();
94523
- URL.revokeObjectURL(objectUrl);
94524
- } catch (e) {
94525
- console.error("Attachment download failed:", e);
94526
- } finally {
94527
- setDownloadingId(null);
94528
- }
94529
- return;
94530
- }
94531
- // SharePoint proxy URLs are GET endpoints that stream the file
94532
- // directly via Microsoft Graph using the stored OAuth credential.
94533
- // Bypass the legacy POST /file-download lookup (which expects an
94534
- // NFS-backed Knowledge.config.blobName) and fetch the proxy URL
94535
- // directly. The proxy validates org membership via the session
94536
- // cookie (`credentials: 'include'`).
94537
- const isSharePointProxy = typeof source.url === "string" && source.url.includes("/api/v1/sharepoint/file/");
94538
- if (!isSharePointProxy && !source.source_id) return;
94539
- const downloadKey = _downloadKey(source) || "sharepoint";
94540
- setDownloadingId(downloadKey);
94541
- try {
94542
- let res;
94543
- if (isSharePointProxy) {
94544
- // RAG-citation-1 v5 — when the proxy URL is path-only (the
94545
- // typical case post-PR #813, where the backend can't know
94546
- // the public API hostname at chat-time), prepend apiBaseUrl.
94547
- // Without this, fetch() resolves the path-only URL against
94548
- // the widget's current ORIGIN — i.e. the customer's host
94549
- // page where the widget is embedded, NOT the eshal API
94550
- // host that actually serves /api/v1/sharepoint/file/...
94551
- // and the result is a 404 from the customer's webserver.
94552
- // Absolute URLs (older corpora where PUBLIC_API_URL was
94553
- // set, or future deployments that set it) pass through
94554
- // unchanged.
95565
+ } else if (isSharePointProxy) {
94555
95566
  const spUrl = source.url.startsWith("http") ? source.url : "".concat(apiBaseUrl.replace(/\/$/, "")).concat(source.url);
94556
- const spHeaders = {};
94557
- if (typeof getAuthToken === 'function') {
95567
+ const headers = {};
95568
+ if (typeof getAuthToken === "function") {
94558
95569
  const token = await getAuthToken();
94559
- if (token) spHeaders['Authorization'] = "Bearer ".concat(token);
95570
+ if (token) headers["Authorization"] = "Bearer ".concat(token);
94560
95571
  }
94561
95572
  res = await fetch(spUrl, {
94562
95573
  method: "GET",
94563
- headers: spHeaders,
95574
+ headers,
94564
95575
  credentials: "include"
94565
95576
  });
94566
95577
  } else {
94567
95578
  const base = apiBaseUrl.replace(/\/$/, "");
94568
95579
  const url = "".concat(base, "/api/v1/support/file-download");
94569
- // RAG-citation-1 v6 — send per-file disambiguation alongside
94570
- // source_id. For multi-file Knowledge sources, N citations
94571
- // share one source_id and the server can only resolve one
94572
- // arbitrary chunk's blob by source_id alone — every download
94573
- // ended up identical. The citation already carries:
94574
- // - source.url (the per-file blob name, e.g.
94575
- // "1778406193812-2-6a4f68f4.pdf")
94576
- // - source.source_name (the user's original filename)
94577
- // Sending both lets the server skip the Milvus resolution
94578
- // AND advertise the readable name in Content-Disposition.
94579
- const dlHeaders = {
95580
+ const headers = {
94580
95581
  "Content-Type": "application/json"
94581
95582
  };
94582
- if (typeof getAuthToken === 'function') {
95583
+ if (typeof getAuthToken === "function") {
94583
95584
  const token = await getAuthToken();
94584
- if (token) dlHeaders['Authorization'] = "Bearer ".concat(token);
95585
+ if (token) headers["Authorization"] = "Bearer ".concat(token);
94585
95586
  }
94586
95587
  res = await fetch(url, {
94587
95588
  method: "POST",
94588
- headers: dlHeaders,
95589
+ headers,
94589
95590
  credentials: "include",
94590
95591
  body: JSON.stringify({
94591
- source_id: source.source_id,
95592
+ source_id: source.source_id || source.sourceid,
94592
95593
  file_name: source.url || "",
94593
95594
  source_name: source.source_name || ""
94594
95595
  })
@@ -94601,159 +95602,40 @@
94601
95602
  const blob = await res.blob();
94602
95603
  const disposition = res.headers.get("content-disposition");
94603
95604
  let filename = source.source_name || "download";
94604
- const match = disposition && /filename\*?=(?:UTF-8'')?["']?([^"'\s;]+)["']?/i.exec(disposition);
94605
- if (match) filename = decodeURIComponent(match[1].replace(/\\"/g, '"'));
95605
+ // Attachments carry the clean filename on source_name; the NFS
95606
+ // Content-Disposition holds the UUID-prefixed storage key we
95607
+ // don't want to show. Skip CD parsing for those.
95608
+ if (!isAttachment) {
95609
+ const match = disposition && /filename\*?=(?:UTF-8'')?["']?([^"'\s;]+)["']?/i.exec(disposition);
95610
+ if (match) {
95611
+ try {
95612
+ filename = decodeURIComponent(match[1].replace(/\\"/g, '"'));
95613
+ } catch (_unused3) {
95614
+ /* keep fallback */
95615
+ }
95616
+ }
95617
+ }
94606
95618
  const a = document.createElement("a");
94607
- a.href = URL.createObjectURL(blob);
95619
+ const objectUrl = URL.createObjectURL(blob);
95620
+ a.href = objectUrl;
94608
95621
  a.download = filename;
95622
+ document.body.appendChild(a);
94609
95623
  a.click();
94610
- URL.revokeObjectURL(a.href);
95624
+ a.remove();
95625
+ URL.revokeObjectURL(objectUrl);
94611
95626
  } catch (e) {
94612
- console.error("File download failed:", e);
95627
+ // eslint-disable-next-line no-console
95628
+ console.error("[widget] source download failed:", e);
94613
95629
  } finally {
94614
- setDownloadingId(null);
94615
- }
94616
- };
94617
- if (!(sources !== null && sources !== void 0 && sources.length)) return null;
94618
- const color = textColor !== null && textColor !== void 0 ? textColor : isDark ? "#f3f4f6" : "#1A1A1A";
94619
- const decodedName = name => {
94620
- if (!name) return "";
94621
- try {
94622
- return decodeURIComponent(String(name));
94623
- } catch (_unused) {
94624
- return name;
95630
+ setDownloadingKey(null);
94625
95631
  }
95632
+ }, [apiBaseUrl, getAuthToken]);
95633
+ return {
95634
+ onSourceActivate,
95635
+ downloadingKey
94626
95636
  };
94627
- return /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
94628
- className: "mt-3 min-w-0 max-w-full",
94629
- style: {
94630
- color,
94631
- fontFamily: fontFamily || "Inter",
94632
- fontSize: fontSize || "14px"
94633
- },
94634
- children: [/*#__PURE__*/jsxRuntimeExports.jsx("p", {
94635
- className: "font-semibold mb-2",
94636
- children: "Sources"
94637
- }), /*#__PURE__*/jsxRuntimeExports.jsx("ul", {
94638
- className: "space-y-2 list-none p-0 m-0 min-w-0 w-full max-w-full",
94639
- children: sources.map((source, i) => /*#__PURE__*/jsxRuntimeExports.jsx("li", {
94640
- className: "flex items-start gap-2 min-w-0 w-full max-w-full",
94641
- children: source.source_type === "file" ? /*#__PURE__*/jsxRuntimeExports.jsx("div", {
94642
- className: "min-w-0 w-full",
94643
- children: /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
94644
- className: "flex items-start gap-1 min-w-0",
94645
- style: {
94646
- color,
94647
- fontFamily: fontFamily || "Inter",
94648
- fontSize: fontSize || "14px"
94649
- },
94650
- children: [/*#__PURE__*/jsxRuntimeExports.jsx(FileText, {
94651
- className: "flex-shrink-0 text-current opacity-80",
94652
- strokeWidth: 2,
94653
- style: {
94654
- width: '1em',
94655
- height: '1em',
94656
- marginTop: '0.15em'
94657
- },
94658
- "aria-hidden": true
94659
- }), /*#__PURE__*/jsxRuntimeExports.jsxs("span", {
94660
- className: "min-w-0 flex-1",
94661
- title: decodedName(source.source_name) || "File",
94662
- style: {
94663
- wordBreak: 'break-word',
94664
- overflowWrap: 'anywhere'
94665
- },
94666
- children: [decodedName(source.source_name) || "File", /*#__PURE__*/jsxRuntimeExports.jsx("button", {
94667
- type: "button",
94668
- onClick: () => handleFileDownload(source),
94669
- disabled: downloadingId === _downloadKey(source),
94670
- className: "inline-flex items-center ml-1 p-0 rounded bg-transparent border-0 hover:bg-transparent disabled:opacity-50 transition-opacity focus:outline-none focus-visible:outline-none cursor-pointer disabled:cursor-not-allowed",
94671
- style: {
94672
- color,
94673
- width: '1em',
94674
- height: '1em',
94675
- verticalAlign: '-0.1em'
94676
- },
94677
- "aria-label": downloadingId === _downloadKey(source) ? "Downloading…" : "Download file",
94678
- title: downloadingId === _downloadKey(source) ? "Downloading…" : "Download",
94679
- children: downloadingId === _downloadKey(source) ? /*#__PURE__*/jsxRuntimeExports.jsx(LoaderCircle, {
94680
- size: "1em",
94681
- strokeWidth: 2,
94682
- className: "animate-spin"
94683
- }) : /*#__PURE__*/jsxRuntimeExports.jsx(Download, {
94684
- size: "1em",
94685
- strokeWidth: 2
94686
- })
94687
- })]
94688
- })]
94689
- })
94690
- }) : /*#__PURE__*/jsxRuntimeExports.jsxs("a", {
94691
- href: source.url || "#",
94692
- target: "_blank",
94693
- rel: "noopener noreferrer",
94694
- className: "block min-w-0 flex-1 hover:underline",
94695
- title: source.source_name || source.url || "Link",
94696
- style: {
94697
- color,
94698
- fontFamily: fontFamily || "Inter",
94699
- fontSize: fontSize || "14px",
94700
- wordBreak: 'break-word',
94701
- overflowWrap: 'anywhere',
94702
- paddingLeft: '1.5em',
94703
- textIndent: '-1.5em'
94704
- },
94705
- children: [/*#__PURE__*/jsxRuntimeExports.jsx(Globe, {
94706
- className: "inline-block opacity-80",
94707
- strokeWidth: 2,
94708
- style: {
94709
- width: '1em',
94710
- height: '1em',
94711
- marginRight: '0.5em',
94712
- verticalAlign: '-0.15em'
94713
- },
94714
- "aria-hidden": true
94715
- }), source.source_name || source.url || "Link", /*#__PURE__*/jsxRuntimeExports.jsx(ExternalLink, {
94716
- className: "inline-block ml-1",
94717
- style: {
94718
- width: '0.85em',
94719
- height: '0.85em',
94720
- verticalAlign: '-0.1em'
94721
- },
94722
- "aria-hidden": true
94723
- })]
94724
- })
94725
- }, source.source_id || source.url || i))
94726
- })]
94727
- });
94728
- };
94729
-
94730
- // Decision widget component for HITL (Human-in-the-Loop)
94731
- const DecisionWidget = _ref17 => {
94732
- let {
94733
- question,
94734
- options,
94735
- onDecision,
94736
- disabled,
94737
- isDark = false
94738
- } = _ref17;
94739
- return /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
94740
- className: "mt-3 p-3 rounded-lg border ".concat(isDark ? "bg-blue-900/30 border-blue-700/50" : "bg-blue-50 border-blue-200"),
94741
- children: [/*#__PURE__*/jsxRuntimeExports.jsx("p", {
94742
- className: "text-sm font-medium mb-2 ".concat(isDark ? "text-gray-100" : "text-gray-900"),
94743
- children: question
94744
- }), /*#__PURE__*/jsxRuntimeExports.jsx("div", {
94745
- className: "space-y-2",
94746
- children: options.map(option => /*#__PURE__*/jsxRuntimeExports.jsx("button", {
94747
- onClick: () => onDecision(option.id, option.label),
94748
- disabled: disabled,
94749
- className: "w-full text-left px-3 py-2 text-sm rounded transition-all ".concat(isDark ? "bg-gray-800 border border-gray-700 hover:bg-blue-900/50 hover:border-blue-600 disabled:opacity-50 disabled:cursor-not-allowed" : "bg-white border border-gray-300 hover:bg-blue-50 hover:border-blue-400 disabled:opacity-50 disabled:cursor-not-allowed"),
94750
- children: option.label
94751
- }, option.id))
94752
- })]
94753
- });
94754
- };
94755
- const AssistantMessage = _ref18 => {
94756
- var _message$sources, _message$sources2;
95637
+ }
95638
+ const AssistantMessage = _ref20 => {
94757
95639
  let {
94758
95640
  message,
94759
95641
  formatTime,
@@ -94778,8 +95660,14 @@
94778
95660
  provideCitations = true,
94779
95661
  onFeedback,
94780
95662
  headerTextColor
94781
- } = _ref18;
94782
- const displayContent = typeof message.content === "string" ? message.content : "";
95663
+ } = _ref20;
95664
+ const rawContent = typeof message.content === "string" ? message.content : "";
95665
+ // 2026-07-14 — `[N]` markers are preserved verbatim in `displayContent`
95666
+ // so the ReactMarkdown pipeline's `rehypeCitations` plugin can spot
95667
+ // them and render `<CitationPill>` chips inline. The old
95668
+ // `stripCitationMarkers` call and the separate `<MessageSources>`
95669
+ // footer were removed in the same refactor.
95670
+ const displayContent = rawContent;
94783
95671
  const isTypingMessage = message.isProcessing && (!displayContent || displayContent.length === 0);
94784
95672
 
94785
95673
  // Feedback state.
@@ -94863,59 +95751,99 @@
94863
95751
  const messageFontFamily = agentMessageBubbleFontFamily !== undefined && agentMessageBubbleFontFamily !== null ? agentMessageBubbleFontFamily : fontFamily !== undefined && fontFamily !== null ? fontFamily : "Inter";
94864
95752
  const messageFontSize = agentMessageBubbleFontSize !== undefined && agentMessageBubbleFontSize !== null ? agentMessageBubbleFontSize : fontSize !== undefined && fontSize !== null ? fontSize : "14px";
94865
95753
  useGoogleFont(messageFontFamily);
95754
+
95755
+ // 2026-07-14 — inline citation chip context. Supplies this
95756
+ // message's `sources` array + a download handler to every
95757
+ // `<CitationPill>` rendered inside the ReactMarkdown output.
95758
+ const {
95759
+ onSourceActivate,
95760
+ downloadingKey
95761
+ } = useSourceDownloader({
95762
+ apiBaseUrl,
95763
+ getAuthToken
95764
+ });
95765
+ const citationCtxValue = reactExports.useMemo(() => ({
95766
+ sources: message.sources || [],
95767
+ onSourceActivate,
95768
+ downloadingKey
95769
+ }), [message.sources, onSourceActivate, downloadingKey]);
94866
95770
  return (
94867
95771
  /*#__PURE__*/
94868
95772
  // `min-w-0` on the outer flex-row mirrors the same guard in the
94869
95773
  // frontend AssistantMessage. Without it a chart / table / wide
94870
95774
  // A2UI block sized at intrinsic width pushes the row past the
94871
95775
  // bubble's `max-w-[75%]` cap.
94872
- jsxRuntimeExports.jsxs("div", {
94873
- className: "flex gap-3 flex-row animate-in min-w-0",
94874
- children: [/*#__PURE__*/jsxRuntimeExports.jsx("div", {
94875
- className: "flex-shrink-0 mt-1",
94876
- children: /*#__PURE__*/jsxRuntimeExports.jsx("div", {
94877
- className: "w-8 h-8 rounded-full overflow-hidden flex items-center justify-center",
94878
- style: {
94879
- backgroundColor: primaryColor || '#2563eb'
94880
- },
94881
- children: companyLogo ? /*#__PURE__*/jsxRuntimeExports.jsx("div", {
94882
- className: "w-full h-full bg-white/10 flex items-center justify-center",
94883
- children: /*#__PURE__*/jsxRuntimeExports.jsx("img", {
94884
- src: companyLogo,
94885
- alt: "Company logo",
94886
- className: "object-cover rounded-full",
95776
+ jsxRuntimeExports.jsx(WidgetCitationContext.Provider, {
95777
+ value: citationCtxValue,
95778
+ children: /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
95779
+ className: "flex gap-3 flex-row animate-in min-w-0",
95780
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx("div", {
95781
+ className: "flex-shrink-0 mt-1",
95782
+ children: /*#__PURE__*/jsxRuntimeExports.jsx("div", {
95783
+ className: "w-8 h-8 rounded-full overflow-hidden flex items-center justify-center",
95784
+ style: {
95785
+ backgroundColor: primaryColor || '#2563eb'
95786
+ },
95787
+ children: companyLogo ? /*#__PURE__*/jsxRuntimeExports.jsx("div", {
95788
+ className: "w-full h-full bg-white/10 flex items-center justify-center",
95789
+ children: /*#__PURE__*/jsxRuntimeExports.jsx("img", {
95790
+ src: companyLogo,
95791
+ alt: "Company logo",
95792
+ className: "object-cover rounded-full",
95793
+ style: {
95794
+ maxWidth: "100%",
95795
+ maxHeight: "100%"
95796
+ }
95797
+ })
95798
+ }) : /*#__PURE__*/jsxRuntimeExports.jsx("div", {
95799
+ className: "w-full h-full flex items-center justify-center",
94887
95800
  style: {
94888
- maxWidth: "100%",
94889
- maxHeight: "100%"
94890
- }
95801
+ fontSize: "18px",
95802
+ fontFamily: fontFamily || "Inter",
95803
+ color: headerTextColor || "#FFFFFF"
95804
+ },
95805
+ children: (conciergeName || "A").charAt(0).toUpperCase()
94891
95806
  })
94892
- }) : /*#__PURE__*/jsxRuntimeExports.jsx("div", {
94893
- className: "w-full h-full flex items-center justify-center",
95807
+ })
95808
+ }), /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
95809
+ className: "flex flex-col items-start min-w-0 max-w-[75%]",
95810
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx("div", {
95811
+ className: "rounded-2xl px-4 py-2.5 shadow-sm border rounded-tl-sm rtl:rounded-tl-2xl rtl:rounded-tr-sm min-w-0 max-w-full overflow-hidden ".concat(isDark ? "border-gray-700" : "border-gray-200"),
94894
95812
  style: {
94895
- fontSize: "18px",
94896
- fontFamily: fontFamily || "Inter",
94897
- color: headerTextColor || "#FFFFFF"
95813
+ backgroundColor: bubbleColor,
95814
+ color: messageTextColor,
95815
+ fontFamily: messageFontFamily,
95816
+ fontSize: messageFontSize,
95817
+ textAlign: isRtl ? "right" : "left"
94898
95818
  },
94899
- children: (conciergeName || "A").charAt(0).toUpperCase()
94900
- })
94901
- })
94902
- }), /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
94903
- className: "flex flex-col items-start min-w-0 max-w-[75%]",
94904
- children: [/*#__PURE__*/jsxRuntimeExports.jsx("div", {
94905
- className: "rounded-2xl px-4 py-2.5 shadow-sm border rounded-tl-sm rtl:rounded-tl-2xl rtl:rounded-tr-sm min-w-0 max-w-full overflow-hidden ".concat(isDark ? "border-gray-700" : "border-gray-200"),
94906
- style: {
94907
- backgroundColor: bubbleColor,
94908
- color: messageTextColor,
94909
- fontFamily: messageFontFamily,
94910
- fontSize: messageFontSize,
94911
- textAlign: isRtl ? "right" : "left"
94912
- },
94913
- children: isTypingMessage ? /*#__PURE__*/jsxRuntimeExports.jsx(TypingIndicator, {
94914
- isDark: isDark
94915
- }) : /*#__PURE__*/jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, {
94916
- children: message.requiresDecision && message.decisionData && onDecision ? /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
94917
- children: [displayContent && /*#__PURE__*/jsxRuntimeExports.jsx("div", {
94918
- className: "mb-3",
95819
+ children: isTypingMessage ? /*#__PURE__*/jsxRuntimeExports.jsx(TypingIndicator, {
95820
+ isDark: isDark
95821
+ }) : /*#__PURE__*/jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, {
95822
+ children: message.requiresDecision && message.decisionData && onDecision ? /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
95823
+ children: [displayContent && /*#__PURE__*/jsxRuntimeExports.jsx("div", {
95824
+ className: "mb-3",
95825
+ children: /*#__PURE__*/jsxRuntimeExports.jsx(StreamingMarkdown, {
95826
+ content: displayContent,
95827
+ isStreaming: message.isProcessing,
95828
+ isDark: isDark,
95829
+ isRtl: isRtl,
95830
+ textColor: messageTextColor,
95831
+ fontFamily: messageFontFamily,
95832
+ fontSize: messageFontSize,
95833
+ onButtonClick: onPromptSuggestionClick,
95834
+ provideCitations: provideCitations
95835
+ })
95836
+ }), /*#__PURE__*/jsxRuntimeExports.jsx(DecisionWidget, {
95837
+ question: message.decisionData.question,
95838
+ options: message.decisionData.options,
95839
+ onDecision: (optionId, optionValue) => onDecision(message.decisionData.decisionId, optionId, optionValue),
95840
+ disabled: !!message.decisionResponse,
95841
+ isDark: isDark
95842
+ }), message.decisionResponse && /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
95843
+ className: "mt-2 text-xs ".concat(isDark ? "text-gray-400" : "text-gray-500"),
95844
+ children: ["Selected: ", message.decisionResponse.selectedOption]
95845
+ })]
95846
+ }) : displayContent ? /*#__PURE__*/jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, {
94919
95847
  children: /*#__PURE__*/jsxRuntimeExports.jsx(StreamingMarkdown, {
94920
95848
  content: displayContent,
94921
95849
  isStreaming: message.isProcessing,
@@ -94924,156 +95852,107 @@
94924
95852
  textColor: messageTextColor,
94925
95853
  fontFamily: messageFontFamily,
94926
95854
  fontSize: messageFontSize,
94927
- onButtonClick: onPromptSuggestionClick
95855
+ onButtonClick: onPromptSuggestionClick,
95856
+ provideCitations: provideCitations
95857
+ })
95858
+ }) : null
95859
+ })
95860
+ }), /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
95861
+ className: "flex items-center gap-1.5 mt-1.5 px-1",
95862
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx("p", {
95863
+ className: "text-[11px] leading-none ".concat(isDark ? "text-gray-500" : "text-gray-400"),
95864
+ dir: "auto",
95865
+ children: formatTime(message.timestamp)
95866
+ }), allowFeedback !== false && onFeedback && !isTypingMessage && !message.isProcessing && displayContent && message.type !== 'welcome' && !message.isWelcome && /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
95867
+ className: "flex items-center gap-0.5 ml-0.5",
95868
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx("button", {
95869
+ type: "button",
95870
+ onClick: () => handleFeedbackClick('like'),
95871
+ className: "p-0.5 rounded transition-colors ".concat(activeFeedback === 'like' || pendingFeedback === 'like' ? 'text-green-500' : isDark ? 'text-gray-500 hover:text-gray-300' : 'text-gray-400 hover:text-gray-600'),
95872
+ style: {
95873
+ border: "none",
95874
+ background: "transparent",
95875
+ appearance: "none",
95876
+ WebkitAppearance: "none",
95877
+ cursor: "pointer"
95878
+ },
95879
+ "aria-label": "Like",
95880
+ children: /*#__PURE__*/jsxRuntimeExports.jsx(ThumbsUp, {
95881
+ className: "w-3 h-3"
95882
+ })
95883
+ }), /*#__PURE__*/jsxRuntimeExports.jsx("button", {
95884
+ type: "button",
95885
+ onClick: () => handleFeedbackClick('dislike'),
95886
+ className: "p-0.5 rounded transition-colors ".concat(activeFeedback === 'dislike' || pendingFeedback === 'dislike' ? 'text-red-500' : isDark ? 'text-gray-500 hover:text-gray-300' : 'text-gray-400 hover:text-gray-600'),
95887
+ style: {
95888
+ border: "none",
95889
+ background: "transparent",
95890
+ appearance: "none",
95891
+ WebkitAppearance: "none",
95892
+ cursor: "pointer"
95893
+ },
95894
+ "aria-label": "Dislike",
95895
+ children: /*#__PURE__*/jsxRuntimeExports.jsx(ThumbsDown, {
95896
+ className: "w-3 h-3"
94928
95897
  })
94929
- }), /*#__PURE__*/jsxRuntimeExports.jsx(DecisionWidget, {
94930
- question: message.decisionData.question,
94931
- options: message.decisionData.options,
94932
- onDecision: (optionId, optionValue) => onDecision(message.decisionData.decisionId, optionId, optionValue),
94933
- disabled: !!message.decisionResponse,
94934
- isDark: isDark
94935
- }), message.decisionResponse && /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
94936
- className: "mt-2 text-xs ".concat(isDark ? "text-gray-400" : "text-gray-500"),
94937
- children: ["Selected: ", message.decisionResponse.selectedOption]
94938
- }), provideCitations !== false && ((_message$sources = message.sources) === null || _message$sources === void 0 ? void 0 : _message$sources.length) > 0 && /*#__PURE__*/jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
94939
- children: [/*#__PURE__*/jsxRuntimeExports.jsx("div", {
94940
- className: "mt-3",
94941
- style: {
94942
- borderTop: "1px solid ".concat(messageTextColor)
94943
- }
94944
- }), /*#__PURE__*/jsxRuntimeExports.jsx(MessageSources, {
94945
- sources: message.sources,
94946
- apiBaseUrl: apiBaseUrl,
94947
- getAuthToken: getAuthToken,
94948
- isDark: isDark,
94949
- textColor: messageTextColor,
94950
- fontFamily: messageFontFamily,
94951
- fontSize: messageFontSize
94952
- })]
94953
- })]
94954
- }) : displayContent ? /*#__PURE__*/jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
94955
- children: [/*#__PURE__*/jsxRuntimeExports.jsx(StreamingMarkdown, {
94956
- content: displayContent,
94957
- isStreaming: message.isProcessing,
94958
- isDark: isDark,
94959
- isRtl: isRtl,
94960
- textColor: messageTextColor,
94961
- fontFamily: messageFontFamily,
94962
- fontSize: messageFontSize,
94963
- onButtonClick: onPromptSuggestionClick
94964
- }), provideCitations !== false && ((_message$sources2 = message.sources) === null || _message$sources2 === void 0 ? void 0 : _message$sources2.length) > 0 && /*#__PURE__*/jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
94965
- children: [/*#__PURE__*/jsxRuntimeExports.jsx("div", {
94966
- className: "mt-3",
94967
- style: {
94968
- borderTop: "1px solid ".concat(messageTextColor)
94969
- }
94970
- }), /*#__PURE__*/jsxRuntimeExports.jsx(MessageSources, {
94971
- sources: message.sources,
94972
- apiBaseUrl: apiBaseUrl,
94973
- getAuthToken: getAuthToken,
94974
- isDark: isDark,
94975
- textColor: messageTextColor,
94976
- fontFamily: messageFontFamily,
94977
- fontSize: messageFontSize
94978
- })]
94979
95898
  })]
94980
- }) : null
94981
- })
94982
- }), /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
94983
- className: "flex items-center gap-1.5 mt-1.5 px-1",
94984
- children: [/*#__PURE__*/jsxRuntimeExports.jsx("p", {
94985
- className: "text-[11px] leading-none ".concat(isDark ? "text-gray-500" : "text-gray-400"),
94986
- dir: "auto",
94987
- children: formatTime(message.timestamp)
94988
- }), allowFeedback !== false && onFeedback && !isTypingMessage && !message.isProcessing && displayContent && message.type !== 'welcome' && !message.isWelcome && /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
94989
- className: "flex items-center gap-0.5 ml-0.5",
94990
- children: [/*#__PURE__*/jsxRuntimeExports.jsx("button", {
94991
- type: "button",
94992
- onClick: () => handleFeedbackClick('like'),
94993
- className: "p-0.5 rounded transition-colors ".concat(activeFeedback === 'like' || pendingFeedback === 'like' ? 'text-green-500' : isDark ? 'text-gray-500 hover:text-gray-300' : 'text-gray-400 hover:text-gray-600'),
94994
- style: {
94995
- border: "none",
94996
- background: "transparent",
94997
- appearance: "none",
94998
- WebkitAppearance: "none",
94999
- cursor: "pointer"
95000
- },
95001
- "aria-label": "Like",
95002
- children: /*#__PURE__*/jsxRuntimeExports.jsx(ThumbsUp, {
95003
- className: "w-3 h-3"
95004
- })
95005
- }), /*#__PURE__*/jsxRuntimeExports.jsx("button", {
95006
- type: "button",
95007
- onClick: () => handleFeedbackClick('dislike'),
95008
- className: "p-0.5 rounded transition-colors ".concat(activeFeedback === 'dislike' || pendingFeedback === 'dislike' ? 'text-red-500' : isDark ? 'text-gray-500 hover:text-gray-300' : 'text-gray-400 hover:text-gray-600'),
95009
- style: {
95010
- border: "none",
95011
- background: "transparent",
95012
- appearance: "none",
95013
- WebkitAppearance: "none",
95014
- cursor: "pointer"
95015
- },
95016
- "aria-label": "Dislike",
95017
- children: /*#__PURE__*/jsxRuntimeExports.jsx(ThumbsDown, {
95018
- className: "w-3 h-3"
95019
- })
95020
95899
  })]
95021
- })]
95022
- }), showFeedbackForm && pendingFeedback === 'dislike' && /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
95023
- className: "mt-2 w-full rounded-xl border p-3 shadow ".concat(isDark ? "bg-gray-800 border-gray-700" : "bg-white border-gray-200"),
95024
- style: {
95025
- direction: isRtl ? "rtl" : "ltr"
95026
- },
95027
- children: [/*#__PURE__*/jsxRuntimeExports.jsx("textarea", {
95028
- ref: feedbackInputRef,
95029
- value: feedbackText,
95030
- onChange: e => setFeedbackText(e.target.value),
95031
- onKeyDown: e => {
95032
- if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
95033
- e.preventDefault();
95034
- handleFeedbackSubmit();
95035
- } else if (e.key === "Escape") {
95036
- e.preventDefault();
95037
- handleFeedbackCancel();
95038
- }
95039
- },
95040
- placeholder: "What went wrong? (optional)",
95041
- rows: 2,
95042
- className: "w-full resize-none rounded-lg border px-2 py-1.5 text-xs focus:outline-none focus:ring-1 ".concat(isDark ? "bg-gray-900 border-gray-700 text-gray-100 placeholder-gray-500 focus:ring-gray-600" : "bg-white border-gray-200 text-gray-900 placeholder-gray-400 focus:ring-gray-300"),
95900
+ }), showFeedbackForm && pendingFeedback === 'dislike' && /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
95901
+ className: "mt-2 w-full rounded-xl border p-3 shadow ".concat(isDark ? "bg-gray-800 border-gray-700" : "bg-white border-gray-200"),
95043
95902
  style: {
95044
- fontFamily: messageFontFamily,
95045
- textAlign: isRtl ? "right" : "left"
95046
- }
95047
- }), /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
95048
- className: "flex items-center justify-end gap-1.5 mt-1.5",
95049
- children: [/*#__PURE__*/jsxRuntimeExports.jsx("button", {
95050
- type: "button",
95051
- onClick: handleFeedbackCancel,
95052
- className: "text-xs px-2 py-1 rounded transition-colors ".concat(isDark ? "text-gray-400 hover:text-gray-200" : "text-gray-500 hover:text-gray-700"),
95053
- style: {
95054
- border: "none",
95055
- background: "transparent",
95056
- cursor: "pointer"
95903
+ direction: isRtl ? "rtl" : "ltr"
95904
+ },
95905
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx("textarea", {
95906
+ ref: feedbackInputRef,
95907
+ value: feedbackText,
95908
+ onChange: e => setFeedbackText(e.target.value),
95909
+ onKeyDown: e => {
95910
+ if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
95911
+ e.preventDefault();
95912
+ handleFeedbackSubmit();
95913
+ } else if (e.key === "Escape") {
95914
+ e.preventDefault();
95915
+ handleFeedbackCancel();
95916
+ }
95057
95917
  },
95058
- children: "Cancel"
95059
- }), /*#__PURE__*/jsxRuntimeExports.jsx("button", {
95060
- type: "button",
95061
- onClick: handleFeedbackSubmit,
95062
- className: "text-xs px-2.5 py-1 rounded text-white transition-opacity hover:opacity-90",
95918
+ placeholder: "What went wrong? (optional)",
95919
+ rows: 2,
95920
+ className: "w-full resize-none rounded-lg border px-2 py-1.5 text-xs focus:outline-none focus:ring-1 ".concat(isDark ? "bg-gray-900 border-gray-700 text-gray-100 placeholder-gray-500 focus:ring-gray-600" : "bg-white border-gray-200 text-gray-900 placeholder-gray-400 focus:ring-gray-300"),
95063
95921
  style: {
95064
- backgroundColor: primaryColor || "#2563eb",
95065
- border: "none",
95066
- cursor: "pointer"
95067
- },
95068
- children: "Submit"
95922
+ fontFamily: messageFontFamily,
95923
+ textAlign: isRtl ? "right" : "left"
95924
+ }
95925
+ }), /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
95926
+ className: "flex items-center justify-end gap-1.5 mt-1.5",
95927
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx("button", {
95928
+ type: "button",
95929
+ onClick: handleFeedbackCancel,
95930
+ className: "text-xs px-2 py-1 rounded transition-colors ".concat(isDark ? "text-gray-400 hover:text-gray-200" : "text-gray-500 hover:text-gray-700"),
95931
+ style: {
95932
+ border: "none",
95933
+ background: "transparent",
95934
+ cursor: "pointer"
95935
+ },
95936
+ children: "Cancel"
95937
+ }), /*#__PURE__*/jsxRuntimeExports.jsx("button", {
95938
+ type: "button",
95939
+ onClick: handleFeedbackSubmit,
95940
+ className: "text-xs px-2.5 py-1 rounded text-white transition-opacity hover:opacity-90",
95941
+ style: {
95942
+ backgroundColor: primaryColor || "#2563eb",
95943
+ border: "none",
95944
+ cursor: "pointer"
95945
+ },
95946
+ children: "Submit"
95947
+ })]
95069
95948
  })]
95070
95949
  })]
95071
95950
  })]
95072
- })]
95951
+ })
95073
95952
  })
95074
95953
  );
95075
95954
  };
95076
- const UserMessage = _ref19 => {
95955
+ const UserMessage = _ref21 => {
95077
95956
  let {
95078
95957
  message,
95079
95958
  formatTime,
@@ -95087,7 +95966,7 @@
95087
95966
  fontSize,
95088
95967
  isDark,
95089
95968
  isRtl
95090
- } = _ref19;
95969
+ } = _ref21;
95091
95970
  const primary = userMessageBoxColor !== undefined && userMessageBoxColor !== null ? userMessageBoxColor : primaryColor !== undefined && primaryColor !== null ? primaryColor : "#2563eb";
95092
95971
  const messageTextColor = userTextColor !== undefined && userTextColor !== null ? userTextColor : textColor !== undefined && textColor !== null ? textColor : "#FFFFFF";
95093
95972
  const messageFontFamily = userMessageBubbleFontFamily !== undefined && userMessageBubbleFontFamily !== null ? userMessageBubbleFontFamily : fontFamily !== undefined && fontFamily !== null ? fontFamily : "Inter";
@@ -95180,7 +96059,7 @@
95180
96059
  })
95181
96060
  });
95182
96061
  };
95183
- const MessageBubble = _ref20 => {
96062
+ const MessageBubble = _ref22 => {
95184
96063
  let {
95185
96064
  message,
95186
96065
  isDark,
@@ -95209,7 +96088,7 @@
95209
96088
  provideCitations,
95210
96089
  onFeedback,
95211
96090
  headerTextColor
95212
- } = _ref20;
96091
+ } = _ref22;
95213
96092
  if (!message) {
95214
96093
  return null;
95215
96094
  }
@@ -96447,7 +97326,10 @@
96447
97326
  try {
96448
97327
  const parsed = JSON.parse(xhr.responseText);
96449
97328
  resolve({
96450
- url: typeof (parsed === null || parsed === void 0 ? void 0 : parsed.url) === "string" ? parsed.url : undefined
97329
+ url: typeof (parsed === null || parsed === void 0 ? void 0 : parsed.url) === "string" ? parsed.url : undefined,
97330
+ // 2026-07-04 — surface server-side storageKey so the caller
97331
+ // can persist it in preference to presign's key.
97332
+ storageKey: typeof (parsed === null || parsed === void 0 ? void 0 : parsed.storageKey) === "string" ? parsed.storageKey : undefined
96451
97333
  });
96452
97334
  } catch (_unused) {
96453
97335
  resolve({});
@@ -96588,6 +97470,11 @@
96588
97470
  // ingest hits `if not url: skip` and the file is never
96589
97471
  // extracted into the retrieval union.
96590
97472
  let uploadedReadUrl;
97473
+ // 2026-07-04 — see agent-sdk useFileUpload for full context.
97474
+ // `/multipart` re-runs buildAttachmentStorageKey → fresh UUID,
97475
+ // so presign's key and multipart's save key diverge. Persist
97476
+ // the multipart-returned key so the file's serve URL resolves.
97477
+ let uploadedStorageKey;
96591
97478
  try {
96592
97479
  if (presign.useMultipart) {
96593
97480
  const multipartResp = await postMultipartWithProgress({
@@ -96601,6 +97488,7 @@
96601
97488
  registerXhr: xhr => inflightRef.current.set(attachmentId, xhr)
96602
97489
  });
96603
97490
  uploadedReadUrl = multipartResp.url;
97491
+ uploadedStorageKey = multipartResp.storageKey;
96604
97492
  } else if (presign.uploadUrl) {
96605
97493
  await putWithProgress({
96606
97494
  url: presign.uploadUrl,
@@ -96623,7 +97511,7 @@
96623
97511
  patchAttachment(attachmentId, _objectSpread2({
96624
97512
  status: "ready",
96625
97513
  progress: 100,
96626
- storageKey: presign.storageKey
97514
+ storageKey: uploadedStorageKey || presign.storageKey
96627
97515
  }, uploadedReadUrl ? {
96628
97516
  url: uploadedReadUrl
96629
97517
  } : {}));
@@ -98994,6 +99882,16 @@
98994
99882
  });
98995
99883
  const fileInputRef = reactExports.useRef(null);
98996
99884
  const showPaperclip = !!uploadConfig.fileUploadEnabled && !!apiEndpoint;
99885
+ // 2026-07-10 — paperclip must reflect the per-message file cap
99886
+ // proactively: disable the button when the current attachment count
99887
+ // equals the org's configured `fileUploadMaxFiles` and surface the
99888
+ // reason in a hover tooltip. Previously the button stayed enabled and
99889
+ // the user learned the limit only after clicking (via the toast
99890
+ // "Max N files per message" from useFileUpload). Uses the org's
99891
+ // configured limit — the number in `Max ${N} files per message.` is
99892
+ // dynamic, NOT the pre-fix hardcoded 2.
99893
+ const attachmentsAtLimit = attachments.length >= uploadConfig.fileUploadMaxFiles;
99894
+ const paperclipLimitTooltip = "Max ".concat(uploadConfig.fileUploadMaxFiles, " files per message.");
98997
99895
  const acceptAttr = reactExports.useMemo(() => uploadConfig.fileUploadAllowedMimes.length > 0 ? uploadConfig.fileUploadAllowedMimes.join(",") : undefined, [uploadConfig.fileUploadAllowedMimes]);
98998
99896
  const [tooltipPosition, setTooltipPosition] = reactExports.useState({
98999
99897
  top: 0,
@@ -99232,7 +100130,45 @@
99232
100130
  }, att.id))
99233
100131
  }), /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
99234
100132
  className: "flex items-center px-5 gap-1.5",
99235
- children: [/*#__PURE__*/jsxRuntimeExports.jsx("div", {
100133
+ children: [showPaperclip && /*#__PURE__*/jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
100134
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx("input", {
100135
+ ref: fileInputRef,
100136
+ type: "file",
100137
+ multiple: true,
100138
+ accept: acceptAttr,
100139
+ className: "hidden",
100140
+ style: {
100141
+ display: "none"
100142
+ },
100143
+ onChange: e => {
100144
+ const files = e.target.files;
100145
+ if (files && files.length && !attachmentsAtLimit) {
100146
+ void addFiles(files);
100147
+ }
100148
+ e.currentTarget.value = "";
100149
+ }
100150
+ }), /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
100151
+ className: "relative group",
100152
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx("button", {
100153
+ type: "button",
100154
+ onClick: () => fileInputRef.current && fileInputRef.current.click(),
100155
+ disabled: csatVisible || isConversationLoading || isLoading || attachmentsAtLimit,
100156
+ "aria-label": attachmentsAtLimit ? paperclipLimitTooltip : "Attach file",
100157
+ title: attachmentsAtLimit ? paperclipLimitTooltip : "Attach file",
100158
+ className: "h-10 w-10 rounded-xl flex items-center justify-center transition-all duration-200 ".concat(isDark ? "bg-gray-800 text-gray-200 hover:bg-gray-700" : "bg-white text-gray-600 hover:bg-gray-100", " disabled:opacity-40 disabled:cursor-not-allowed"),
100159
+ style: {
100160
+ border: "none"
100161
+ },
100162
+ children: /*#__PURE__*/jsxRuntimeExports.jsx(Paperclip, {
100163
+ className: "w-4 h-4"
100164
+ })
100165
+ }), attachmentsAtLimit && /*#__PURE__*/jsxRuntimeExports.jsx("div", {
100166
+ role: "tooltip",
100167
+ className: "pointer-events-none absolute bottom-full left-1/2 -translate-x-1/2 mb-2 opacity-0 group-hover:opacity-100 transition-opacity px-3 py-1.5 text-xs rounded-lg whitespace-nowrap shadow-lg ".concat(isDark ? "bg-gray-700 text-gray-100" : "bg-gray-800 text-white"),
100168
+ children: paperclipLimitTooltip
100169
+ })]
100170
+ })]
100171
+ }), /*#__PURE__*/jsxRuntimeExports.jsx("div", {
99236
100172
  className: "flex-1 flex items-center min-h-[48px] ".concat(isDark ? "bg-gray-800" : "bg-gray-50", " rounded-2xl transition-all duration-200"),
99237
100173
  style: {
99238
100174
  borderStyle: "solid",
@@ -99363,37 +100299,6 @@
99363
100299
  })]
99364
100300
  })]
99365
100301
  }), document.body)]
99366
- }), showPaperclip && /*#__PURE__*/jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
99367
- children: [/*#__PURE__*/jsxRuntimeExports.jsx("input", {
99368
- ref: fileInputRef,
99369
- type: "file",
99370
- multiple: true,
99371
- accept: acceptAttr,
99372
- className: "hidden",
99373
- style: {
99374
- display: "none"
99375
- },
99376
- onChange: e => {
99377
- const files = e.target.files;
99378
- if (files && files.length) void addFiles(files);
99379
- // Reset so re-selecting the same file after removal
99380
- // still fires the change event.
99381
- e.currentTarget.value = "";
99382
- }
99383
- }), /*#__PURE__*/jsxRuntimeExports.jsx("button", {
99384
- type: "button",
99385
- onClick: () => fileInputRef.current && fileInputRef.current.click(),
99386
- disabled: csatVisible || isConversationLoading || isLoading,
99387
- "aria-label": "Attach file",
99388
- title: "Attach file",
99389
- className: "h-10 w-10 rounded-xl flex items-center justify-center transition-all duration-200 ".concat(isDark ? "bg-gray-800 text-gray-200 hover:bg-gray-700" : "bg-white text-gray-600 hover:bg-gray-100", " disabled:opacity-40 disabled:cursor-not-allowed"),
99390
- style: {
99391
- border: "none"
99392
- },
99393
- children: /*#__PURE__*/jsxRuntimeExports.jsx(Paperclip, {
99394
- className: "w-4 h-4"
99395
- })
99396
- })]
99397
100302
  }), /*#__PURE__*/jsxRuntimeExports.jsx("button", {
99398
100303
  onClick: isVoiceSessionActive && onBidiSubmit ? onBidiSubmit : sendWithAttachments,
99399
100304
  disabled: csatVisible || isDisabled || isVoiceSessionActive && voiceStatus !== "connected",
@@ -99502,6 +100407,7 @@
99502
100407
  const resolvedHeaderFontSize = headerFontSize || fontSize;
99503
100408
  useGoogleFont(resolvedHeaderFontFamily);
99504
100409
  const t = reactExports.useMemo(() => createTranslator(defaultLanguage), [defaultLanguage]);
100410
+ const isRtl = isRtlLocale(defaultLanguage);
99505
100411
  const [showMenu, setShowMenu] = reactExports.useState(false);
99506
100412
  const menuRef = reactExports.useRef(null);
99507
100413
 
@@ -99581,7 +100487,8 @@
99581
100487
  strokeWidth: 1.6
99582
100488
  })
99583
100489
  }), showMenu && /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
99584
- className: "absolute right-0 top-full mt-1 w-44 rounded-xl border shadow-lg py-1 z-[9999] animate-in fade-in slide-in-from-top-1 duration-150 ".concat(isDark ? "bg-gray-800 border-gray-700" : "bg-white border-gray-200"),
100490
+ dir: isRtl ? "rtl" : "ltr",
100491
+ className: "absolute top-full mt-1 w-44 rounded-xl border shadow-lg py-1 z-[9999] animate-in fade-in slide-in-from-top-1 duration-150 ".concat(isRtl ? "left-0" : "right-0", " ").concat(isDark ? "bg-gray-800 border-gray-700" : "bg-white border-gray-200"),
99585
100492
  style: {
99586
100493
  fontFamily: "Inter, system-ui, sans-serif"
99587
100494
  },
@@ -99598,7 +100505,7 @@
99598
100505
  background: "transparent",
99599
100506
  appearance: "none",
99600
100507
  WebkitAppearance: "none",
99601
- textAlign: "left"
100508
+ textAlign: isRtl ? "right" : "left"
99602
100509
  },
99603
100510
  children: [/*#__PURE__*/jsxRuntimeExports.jsx(RotateCcw, {
99604
100511
  className: "w-3.5 h-3.5 flex-shrink-0"
@@ -99616,7 +100523,7 @@
99616
100523
  background: "transparent",
99617
100524
  appearance: "none",
99618
100525
  WebkitAppearance: "none",
99619
- textAlign: "left"
100526
+ textAlign: isRtl ? "right" : "left"
99620
100527
  },
99621
100528
  children: [/*#__PURE__*/jsxRuntimeExports.jsx(Copy, {
99622
100529
  className: "w-3.5 h-3.5 flex-shrink-0"
@@ -99634,7 +100541,7 @@
99634
100541
  background: "transparent",
99635
100542
  appearance: "none",
99636
100543
  WebkitAppearance: "none",
99637
- textAlign: "left"
100544
+ textAlign: isRtl ? "right" : "left"
99638
100545
  },
99639
100546
  children: [isDark ? /*#__PURE__*/jsxRuntimeExports.jsx(Sun, {
99640
100547
  className: "w-3.5 h-3.5 flex-shrink-0"
@@ -100451,8 +101358,9 @@
100451
101358
  width: 380,
100452
101359
  height: 650
100453
101360
  };
101361
+ const cornerCursor = anchorRight === anchorBottom ? "nwse-resize" : "nesw-resize";
100454
101362
  const cursorMap = {
100455
- corner: "nwse-resize",
101363
+ corner: cornerCursor,
100456
101364
  horizontal: "ew-resize",
100457
101365
  vertical: "ns-resize"
100458
101366
  };
@@ -100951,10 +101859,10 @@
100951
101859
  onMouseDown: e => handleResizeStart("corner", e),
100952
101860
  role: "separator",
100953
101861
  "aria-label": "Resize chat",
100954
- className: "absolute bottom-0 w-4 h-4 cursor-nwse-resize text-gray-400 hover:text-blue-500 transition-colors z-[71] flex items-end p-0.5 ".concat(anchorRight ? "right-0 justify-end" : "left-0 justify-start"),
101862
+ className: "absolute w-4 h-4 ".concat(anchorRight === anchorBottom ? "cursor-nwse-resize" : "cursor-nesw-resize", " text-gray-400 hover:text-blue-500 transition-colors z-[71] flex p-0.5 ").concat(anchorBottom ? "top-0 items-start" : "bottom-0 items-end", " ").concat(anchorRight ? "left-0 justify-start" : "right-0 justify-end"),
100955
101863
  children: /*#__PURE__*/jsxRuntimeExports.jsx("svg", {
100956
101864
  viewBox: "0 0 12 12",
100957
- className: "w-3 h-3 ".concat(anchorRight ? "" : "rotate-90"),
101865
+ className: "w-3 h-3 ".concat(anchorBottom && anchorRight ? "rotate-180" : anchorBottom ? "-rotate-90" : anchorRight ? "rotate-90" : ""),
100958
101866
  "aria-hidden": true,
100959
101867
  children: /*#__PURE__*/jsxRuntimeExports.jsx("path", {
100960
101868
  d: "M11 1 L1 11 M11 5 L5 11 M11 9 L9 11",
@@ -101048,6 +101956,7 @@
101048
101956
  companyName: companyName,
101049
101957
  apiBaseUrl: apiBaseUrl,
101050
101958
  getAuthToken: getAuthToken,
101959
+ onPromptSuggestionClick: stableOnPromptSuggestionClick,
101051
101960
  conversationResetKey: conversationId,
101052
101961
  allowFeedback: allowFeedback,
101053
101962
  provideCitations: provideCitations,
@@ -101249,10 +102158,10 @@
101249
102158
  const iconColor = headerTextColor || "#FFFFFF";
101250
102159
  return /*#__PURE__*/jsxRuntimeExports.jsxs("button", {
101251
102160
  onClick: onToggle,
101252
- className: "group relative w-16 h-16 rounded-full shadow-2xl transition-all duration-300 flex items-center justify-center text-white overflow-hidden ".concat(isOpen ? "rotate-0 scale-100" : "hover:scale-110"),
102161
+ className: "group relative w-16 h-16 rounded-full shadow-2xl transition-all duration-300 flex items-center justify-center text-white overflow-hidden ".concat(isOpen ? "rotate-0 scale-100 mt-3" : "hover:scale-110"),
101253
102162
  style: {
101254
- background: isOpen ? isDark ? "#1f2937" : "#374151" : "linear-gradient(135deg, ".concat(launcherBg, " 0%, ").concat(launcherBg, "dd 100%)"),
101255
- boxShadow: isOpen ? "0 10px 30px rgba(0,0,0,0.3)" : "0 10px 30px ".concat(launcherBg, "40"),
102163
+ background: "linear-gradient(135deg, ".concat(launcherBg, " 0%, ").concat(launcherBg, "dd 100%)"),
102164
+ boxShadow: "0 10px 30px ".concat(launcherBg, "40"),
101256
102165
  border: "none"
101257
102166
  },
101258
102167
  "aria-label": isOpen ? t("closeChat") : t("openChat"),
@@ -101345,7 +102254,7 @@
101345
102254
  };
101346
102255
 
101347
102256
  const ChatWidget = _ref => {
101348
- var _agentConfig$concierg;
102257
+ var _widgetConfig$launche, _agentConfig$concierg;
101349
102258
  let {
101350
102259
  /**
101351
102260
  * @param {Function|undefined} getAuthToken - async fn returning a Keycloak Bearer token (in-app JWT path)
@@ -101716,7 +102625,7 @@
101716
102625
  id: "chat-widget-root",
101717
102626
  children: /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
101718
102627
  ref: widgetRef,
101719
- className: "chat-widget-root fixed flex flex-col items-end z-[999999] ".concat(isDark ? "dark" : "", " ").concat(className, " ").concat(positionClasses[widgetConfig.launcherPosition] || positionClasses["bottom-right"]),
102628
+ className: "chat-widget-root fixed flex flex-col ".concat((_widgetConfig$launche = widgetConfig.launcherPosition) !== null && _widgetConfig$launche !== void 0 && _widgetConfig$launche.includes("left") ? "items-start" : "items-end", " z-[999999] ").concat(isDark ? "dark" : "", " ").concat(className, " ").concat(positionClasses[widgetConfig.launcherPosition] || positionClasses["bottom-right"]),
101720
102629
  children: [/*#__PURE__*/jsxRuntimeExports.jsx(ChatWindow, {
101721
102630
  isOpen: isOpen,
101722
102631
  isMinimized: isMinimized,
@@ -101809,7 +102718,7 @@
101809
102718
  ,
101810
102719
  chatFeatures: widgetConfig.chatFeatures,
101811
102720
  organizationId: widgetConfig.organizationId
101812
- }), !isOpen && /*#__PURE__*/jsxRuntimeExports.jsx(ToggleButton, {
102721
+ }), /*#__PURE__*/jsxRuntimeExports.jsx(ToggleButton, {
101813
102722
  isOpen: isOpen,
101814
102723
  isDark: isDark,
101815
102724
  primaryColor: widgetConfig.primaryColor,