@accurix/centrinfo-widget 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,1153 @@
1
+ import{createContext as e,render as t}from"preact";import{useCallback as n,useContext as r,useEffect as i,useMemo as a,useRef as o,useState as s}from"preact/hooks";import{Fragment as c,jsx as l,jsxs as u}from"preact/jsx-runtime";var d=class extends Error{constructor(e,t){super(t),this.status=e,this.name=`ApiError`}};const f=()=>({agentName:`Assistant`,greeting:`Hi! ๐Ÿ‘‹ How can I help you today?`,allowVoiceInput:!1,availableActions:[]});var p=class{constructor(e,t,n){this.baseUrl=e,this.token=t,this.gifApiKey=n}headers(e=!0){let t={Authorization:`Bearer ${this.token}`};return e&&(t[`Content-Type`]=`application/json`),t}async json(e){let t;try{t=await e.json()}catch{t=void 0}if(!e.ok){let n=h(t)??`request failed (${e.status})`;throw new d(e.status,n)}return t?.data??t}async bootstrap(){try{let e=await fetch(`${this.baseUrl}/public-chat/bootstrap`,{headers:this.headers(!1)});if(!e.ok)return f();let t=await this.json(e);return{...f(),...t}}catch{return f()}}async stream(e,t,n){let r=await fetch(`${this.baseUrl}/public-chat/stream`,{method:`POST`,headers:this.headers(),body:JSON.stringify({question:e,sessionId:t}),signal:n.signal});return!r.ok||!r.body?this.send(e,t,n):g(r.body,n)}async send(e,t,n){let r=await fetch(`${this.baseUrl}/public-chat`,{method:`POST`,headers:this.headers(),body:JSON.stringify({question:e,sessionId:t}),signal:n.signal}),i=await this.json(r);return n.onChunk(i.answer??``),{answer:i.answer??``,sources:i.sources??[],suggestedReplies:i.suggestedReplies??[],availableActions:i.availableActions??[],handoffOffered:i.handoffOffered??!1,requestedContactFields:v(i.requestedContactFields),conversationEnded:i.conversationEnded??!1}}async action(e,t){let n=await fetch(`${this.baseUrl}/public-chat/${e}`,{method:`POST`,headers:this.headers(),body:JSON.stringify(t)}),r=await this.json(n);return{ok:!0,note:r?.note,booking:r?.booking}}async identify(e,t){if(!(!e||!t))try{let n=await fetch(`${this.baseUrl}/public-chat/identify`,{method:`POST`,headers:this.headers(),body:JSON.stringify(m(e,t))});if(!n.ok)try{await n.text()}catch{}}catch{}}async transcribe(e,t){let n=await fetch(`${this.baseUrl}/public-chat/transcribe`,{method:`POST`,headers:this.headers(),body:JSON.stringify({audioBase64:e,mimeType:t})});return(await this.json(n)).text??``}async endConversation(e){try{let t=await fetch(`${this.baseUrl}/public-chat/end`,{method:`POST`,headers:this.headers(),body:JSON.stringify({sessionId:e})});if(!t.ok)try{await t.text()}catch{}}catch{}}async sendFeedback(e){try{let t=await fetch(`${this.baseUrl}/public-chat/feedback`,{method:`POST`,headers:this.headers(),body:JSON.stringify(e)});if(!t.ok)try{await t.text()}catch{}}catch{}}async extract(e,t,n){let r=await fetch(`${this.baseUrl}/public-chat/extract`,{method:`POST`,headers:this.headers(),body:JSON.stringify({fileBase64:e,mimeType:t,filename:n})});return(await this.json(r)).text??``}async demoSlots(e,t){try{let n=`from=${encodeURIComponent(e)}&to=${encodeURIComponent(t)}`,r=await fetch(`${this.baseUrl}/public-chat/demo-slots?${n}`,{headers:this.headers(!1)});if(!r.ok)return{taken:[],busy:[]};let i=await this.json(r);return{taken:i?.taken??[],busy:i?.busy??[]}}catch{return{taken:[],busy:[]}}}async searchGifs(e){if(!this.gifApiKey)return[];let t=`https://tenor.googleapis.com/v2/search?q=${encodeURIComponent(e.trim()||`trending`)}&key=${this.gifApiKey}&limit=24&media_filter=tinygif,gif&contentfilter=high`;try{let e=await fetch(t);return e.ok?((await e.json()).results??[]).map(e=>({id:e.id,url:e.media_formats?.gif?.url??e.media_formats?.tinygif?.url??``,preview:e.media_formats?.tinygif?.url??e.media_formats?.gif?.url??``,alt:e.content_description||`GIF`})).filter(e=>e.url):[]}catch{return[]}}};const m=(e,t)=>{let n={...t.customAttributes??{},...t.metadata??{}};t.createdAt!==void 0&&(n.createdAt=t.createdAt),t.avatarUrl&&(n.avatarUrl=t.avatarUrl),t.company&&(n.company=t.company);let r={sessionId:e},i=t.externalId??t.userId;return i&&(r.externalId=i),t.email&&(r.email=t.email),t.firstName&&(r.firstName=t.firstName),t.lastName&&(r.lastName=t.lastName),t.name&&(r.name=t.name),t.phone&&(r.phone=t.phone),Object.keys(n).length>0&&(r.metadata=n),r},h=e=>{let t=e?.message;if(Array.isArray(t))return t.join(`, `);if(typeof t==`string`)return t},g=async(e,t)=>{let n=e.getReader(),r=new TextDecoder,i={answer:``,sources:[],suggestedReplies:[],availableActions:[],handoffOffered:!1,requestedContactFields:[],conversationEnded:!1},a=``;for(;;){let{done:e,value:o}=await n.read();if(e)break;a+=r.decode(o,{stream:!0});let s;for(;(s=a.indexOf(`
2
+
3
+ `))!==-1;){let e=a.slice(0,s);a=a.slice(s+2);let n=_(e);if(n){if(n.event===`error`)throw new d(502,n.data?.message??`stream error`);if(n.event===`chunk`&&typeof n.data?.text==`string`)i.answer+=n.data.text,t.onChunk(n.data.text);else if(n.event===`final`&&n.data)i.sources=n.data.sources??[],i.suggestedReplies=n.data.suggestedReplies??[],i.availableActions=n.data.availableActions??[],i.handoffOffered=!!n.data.handoffOffered,i.requestedContactFields=v(n.data.requestedContactFields),i.conversationEnded=!!n.data.conversationEnded;else if(n.event===`done`)return i}}}return i},_=e=>{let t=`message`,n=[];for(let r of e.split(`
4
+ `))r.startsWith(`event:`)?t=r.slice(6).trim():r.startsWith(`data:`)&&n.push(r.slice(5).trim());if(n.length===0)return{event:t};try{return{event:t,data:JSON.parse(n.join(`
5
+ `))}}catch{return{event:t}}},v=e=>Array.isArray(e)?e.filter(e=>typeof e==`string`):[],y=e=>new Promise(t=>setTimeout(t,e)),b={agentName:`Sara`,agentAvatarUrl:``,greeting:`Hi! ๐Ÿ‘‹ I'm Sara, the Northwind assistant. Ask me anything about tracking, customs, or pricing โ€” or book a demo.`,allowVoiceInput:!0,availableActions:[`public_book_demo`,`public_capture_contact`,`public_submit_inquiry`],agentDescription:`I help with shipment tracking, customs, and pricing.`,welcomeSubtitle:`Ask me anything โ€” most answers are instant.`,disclaimerText:`Sara is an AI assistant; answers may be imperfect.`,starterQuestions:[`How do I track a shipment?`,`How does customs work?`,`What's your pricing?`]},x=[{match:/^\s*(hi+|hey+|hello|yo|sup|howdy|hola|thanks|thank you|thx|good (morning|afternoon|evening))\b/i,result:{answer:`Hello! ๐Ÿ‘‹ How can I help you today?`,sources:[],suggestedReplies:[`How do I track a shipment?`,`How does customs work?`],handoffOffered:!1}},{match:/track|shipment|where|status/i,result:{answer:`You can track any shipment in real time from the **Tracking** tab โ€” we merge GPS pings with carrier scan events, so the status is usually fresher than the carrier's own site. Each shipment also has a shareable link you can send to customers.`,sources:[{title:`Real-time tracking`,url:`https://northwind.example/docs/tracking`},{title:`Shareable tracking links`,url:`https://northwind.example/docs/share`}],suggestedReplies:[`How fresh is the data?`,`Can customers track too?`],handoffOffered:!1}},{match:/custom|clear|duty|tariff|import/i,result:{answer:`Customs is automated end-to-end: HS codes are auto-classified from your product catalog, duties are estimated up front, and most lanes are pre-cleared before the freight lands. If a shipment needs a human broker, we flag it early so it never sits at the border.`,sources:[{title:`Smart customs`,url:`https://northwind.example/docs/customs`}],suggestedReplies:[`Which countries are pre-cleared?`,`What does it cost?`],handoffOffered:!1}},{match:/price|cost|pricing|plan|quote/i,result:{answer:`Pricing is usage-based โ€” you pay per shipment, with volume tiers that kick in automatically. There's no platform fee and no per-seat charge. I can have someone put together a quote for your lanes if you'd like.`,sources:[{title:`Pricing`,url:`https://northwind.example/pricing`}],suggestedReplies:[`How do volume tiers work?`,`Is there a free trial?`],handoffOffered:!1}}],S={answer:`That's a great question โ€” I don't have a confident answer from Northwind's published docs yet. Want me to pass it to the team so a human can follow up? You can also book a quick demo.`,sources:[],suggestedReplies:[`What can you help with?`],handoffOffered:!0};var C=class{async bootstrap(){return await y(180),b}async stream(e,t,n){await y(550);let r=x.find(t=>t.match.test(e)),i=r?r.result:S,a=i.answer.split(/(\s+)/);for(let e of a){if(n.signal?.aborted)break;n.onChunk(e),await y(18+Math.min(40,e.length*6))}return{...i,availableActions:b.availableActions}}async action(e,t){return await y(450),{ok:!0,note:{"book-demo":`Demo requested โ€” we'll email you a few times that work. ๐Ÿ“…`,contact:`Got it โ€” saved your details. โœ…`,inquiry:`Thanks! We'll get back to you shortly. โœ‰๏ธ`,"request-callback":`We'll call you back soon. ๐Ÿ“ž`,"subscribe-newsletter":`You're subscribed. ๐ŸŽ‰`}[e]}}async transcribe(e,t){return await y(700),`How do I track a shipment?`}async extract(e,t,n){return await y(600),`[Attached file${n?`: ${n}`:``}] Invoice #4821 โ€” 3 pallets, Rotterdam โ†’ Lagos, ETA 12 days.`}async identify(e,t){await y(50)}async endConversation(e){await y(50)}async sendFeedback(){await y(50)}async demoSlots(e,t){return await y(150),{taken:[[11,0],[15,0]].map(([e,t])=>{let n=new Date;return n.setHours(e,t,0,0),n.toISOString()}),busy:[]}}async searchGifs(e){await y(280);let t=e.trim().toLowerCase(),n=t?D.filter(e=>e.alt.includes(t)||e.tags.some(e=>e.includes(t)||t.includes(e))):D;return(n.length>0?n:D).map(e=>({id:e.id,url:E(e.emoji,e.anim),preview:E(e.emoji,e.anim),alt:e.alt}))}};const w=`<animateTransform attributeName='transform' attributeType='XML' type='translate' values='0 0;0 -16;0 0' dur='0.7s' repeatCount='indefinite'/>`,T=`<animateTransform attributeName='transform' attributeType='XML' type='rotate' values='-14 64 110;14 64 110;-14 64 110' dur='0.9s' repeatCount='indefinite'/>`,E=(e,t)=>{let n=`<svg xmlns='http://www.w3.org/2000/svg' width='128' height='128'><rect width='128' height='128' rx='14' fill='#eef1f4'/><text x='64' y='88' font-size='64' text-anchor='middle'>${e}${t}</text></svg>`;return`data:image/svg+xml,${encodeURIComponent(n)}`},D=[{id:`g1`,emoji:`๐Ÿ‘`,alt:`thumbs up`,tags:[`thumbs`,`yes`,`ok`,`great`,`good`],anim:w},{id:`g2`,emoji:`๐ŸŽ‰`,alt:`celebrate`,tags:[`party`,`yay`,`congrats`,`celebrate`],anim:T},{id:`g3`,emoji:`๐Ÿ‘‹`,alt:`wave hello`,tags:[`hi`,`hello`,`hey`,`wave`,`bye`],anim:T},{id:`g4`,emoji:`โค๏ธ`,alt:`heart`,tags:[`love`,`thanks`,`heart`],anim:w},{id:`g5`,emoji:`๐Ÿค”`,alt:`thinking`,tags:[`hmm`,`think`,`thinking`],anim:T},{id:`g6`,emoji:`๐Ÿ˜‚`,alt:`laughing`,tags:[`lol`,`funny`,`haha`,`laugh`],anim:w},{id:`g7`,emoji:`๐Ÿ”ฅ`,alt:`fire`,tags:[`fire`,`hot`,`lit`,`awesome`],anim:w},{id:`g8`,emoji:`๐Ÿš€`,alt:`rocket`,tags:[`rocket`,`launch`,`fast`,`go`],anim:T}],O=e=>new Promise(t=>setTimeout(t,e));var k=class{constructor(e,t){this.real=e,this.strings=t}bootstrap(){return this.real.bootstrap()}async stream(e,t,n){await O(300);for(let e of this.strings.previewReply.split(/(\s+)/)){if(n.signal?.aborted)break;n.onChunk(e),await O(16)}return{answer:this.strings.previewReply,sources:[],suggestedReplies:[],availableActions:[],handoffOffered:!1}}async action(){return await O(250),{ok:!0,note:this.strings.previewActionNote}}async identify(){}async endConversation(){}async sendFeedback(){}async transcribe(){return``}async extract(){return``}async searchGifs(){return[]}async demoSlots(){return{taken:[],busy:[]}}};const A=[{name:`Smileys`,emojis:`๐Ÿ˜€.๐Ÿ˜ƒ.๐Ÿ˜„.๐Ÿ˜.๐Ÿ˜….๐Ÿ˜‚.๐Ÿคฃ.๐Ÿ˜Š.๐Ÿ˜‡.๐Ÿ™‚.๐Ÿ™ƒ.๐Ÿ˜‰.๐Ÿ˜Œ.๐Ÿ˜.๐Ÿฅฐ.๐Ÿ˜˜.๐Ÿ˜‹.๐Ÿ˜›.๐Ÿ˜œ.๐Ÿคช.๐Ÿค—.๐Ÿคญ.๐Ÿค”.๐Ÿค.๐Ÿ˜.๐Ÿ˜ถ.๐Ÿ˜.๐Ÿ™„.๐Ÿ˜ด.๐Ÿฅณ.๐Ÿ˜Ž.๐Ÿค“.๐Ÿฅบ.๐Ÿ˜ข.๐Ÿ˜ญ.๐Ÿ˜ค.๐Ÿ˜ .๐Ÿคฏ.๐Ÿ˜ฌ.๐Ÿ˜ฑ.๐Ÿคฉ.๐Ÿฅฑ`.split(`.`)},{name:`Gestures`,emojis:[`๐Ÿ‘`,`๐Ÿ‘Ž`,`๐Ÿ‘Œ`,`๐ŸคŒ`,`โœŒ๏ธ`,`๐Ÿคž`,`๐ŸคŸ`,`๐Ÿค˜`,`๐Ÿค™`,`๐Ÿ‘ˆ`,`๐Ÿ‘‰`,`๐Ÿ‘†`,`๐Ÿ‘‡`,`โœ‹`,`๐Ÿ–๏ธ`,`๐Ÿ‘‹`,`๐Ÿค`,`๐Ÿ™`,`๐Ÿ’ช`,`๐Ÿ‘`,`๐Ÿ™Œ`,`๐Ÿ‘`,`๐Ÿคฒ`,`๐Ÿซถ`]},{name:`Hearts & symbols`,emojis:`โค๏ธ.๐Ÿงก.๐Ÿ’›.๐Ÿ’š.๐Ÿ’™.๐Ÿ’œ.๐Ÿ–ค.๐Ÿค.๐Ÿ’”.โฃ๏ธ.๐Ÿ’•.๐Ÿ’–.๐Ÿ’˜.๐Ÿ’.โœจ.โญ.๐ŸŒŸ.๐Ÿ’ซ.๐Ÿ”ฅ.๐ŸŽ‰.๐ŸŽŠ.โœ….โŒ.โšก.๐Ÿ’ฏ.๐Ÿš€`.split(`.`)},{name:`Animals & nature`,emojis:[`๐Ÿถ`,`๐Ÿฑ`,`๐ŸฆŠ`,`๐Ÿป`,`๐Ÿผ`,`๐Ÿจ`,`๐Ÿฆ`,`๐Ÿฎ`,`๐Ÿธ`,`๐Ÿต`,`๐Ÿง`,`๐Ÿฆ„`,`๐Ÿ`,`๐Ÿฆ‹`,`๐Ÿข`,`๐Ÿฌ`,`๐ŸŒท`,`๐ŸŒธ`,`๐ŸŒน`,`๐ŸŒป`,`๐ŸŒณ`,`๐Ÿ€`]},{name:`Food & drink`,emojis:[`๐ŸŽ`,`๐ŸŒ`,`๐Ÿ‰`,`๐Ÿ“`,`๐Ÿ’`,`๐Ÿฅ‘`,`๐Ÿ”`,`๐ŸŸ`,`๐Ÿ•`,`๐ŸŒฎ`,`๐Ÿฟ`,`๐Ÿฉ`,`๐Ÿช`,`๐ŸŽ‚`,`โ˜•`,`๐Ÿต`,`๐Ÿบ`,`๐Ÿฅ‚`,`๐Ÿท`]},{name:`Objects & travel`,emojis:`๐Ÿš€.โœˆ๏ธ.๐Ÿš—.๐Ÿ .๐Ÿ“ฆ.๐Ÿ“ฑ.๐Ÿ’ป.โŒš.๐Ÿ“ท.๐Ÿ’ก.๐Ÿ”‘.๐ŸŽ.๐Ÿ“Œ.โœ๏ธ.๐Ÿ“.๐Ÿ“ž.๐Ÿ“ง.๐Ÿ’ฐ.๐Ÿ“ˆ.โฐ.๐Ÿ””.๐ŸŽฏ.๐Ÿ†.๐ŸŽฎ.๐ŸŽต.๐Ÿ’ฌ.๐Ÿ‘€`.split(`.`)}],j={inquiry:{title:`Leave a message`,submit:`Send message`,fields:[{key:`visitorName`,label:`Name`,kind:`text`,identity:`name`},{key:`visitorEmail`,label:`Email`,kind:`email`,required:!0,identity:`email`},{key:`message`,label:`Message`,kind:`textarea`,required:!0,placeholder:`How can we help?`}]},contact:{title:`Share your details`,submit:`Save`,fields:[{key:`name`,label:`Name`,kind:`text`,identity:`name`},{key:`email`,label:`Email`,kind:`email`,required:!0,identity:`email`},{key:`phone`,label:`Phone`,kind:`tel`,identity:`phone`}]},"book-demo":{title:`Book a demo`,submit:`Request demo`,fields:[{key:`visitorName`,label:`Name`,kind:`text`,identity:`name`},{key:`visitorEmail`,label:`Email`,kind:`email`,required:!0,identity:`email`},{key:`preferredAt`,label:`Preferred time`,kind:`text`,placeholder:`e.g. Thursday 3pm`},{key:`notes`,label:`Notes`,kind:`textarea`,placeholder:`Anything we should know?`}]},"request-callback":{title:`Request a callback`,submit:`Request callback`,fields:[{key:`visitorName`,label:`Name`,kind:`text`,identity:`name`},{key:`visitorPhone`,label:`Phone`,kind:`tel`,required:!0,identity:`phone`},{key:`bestTime`,label:`Best time to call`,kind:`text`,placeholder:`e.g. tomorrow afternoon`},{key:`topic`,label:`Topic`,kind:`text`,placeholder:`What should we call about?`}]},"subscribe-newsletter":{title:`Subscribe`,submit:`Subscribe`,fields:[{key:`visitorName`,label:`Name`,kind:`text`,identity:`name`},{key:`visitorEmail`,label:`Email`,kind:`email`,required:!0,identity:`email`}]}},M={openChat:`Open chat`,closeChat:`Close chat`,muteSounds:`Mute sounds`,unmuteSounds:`Unmute sounds`,statusOnline:`Online ยท replies instantly`,statusOffline:`Away ยท leave a message`,composerPlaceholder:`Type your messageโ€ฆ`,send:`Send message`,emoji:`Emoji`,gifs:`GIFs`,attachFile:`Attach a file`,recordVoice:`Record a voice message`,stopRecording:`Stop recording`,stop:`Stop`,copy:`Copy`,copied:`Copied`,retry:`Retry`,clearChat:`Clear conversation`,clearChatConfirm:`Clear this conversation?`,clearChatConfirmBody:`This clears the messages on this device and starts a fresh chat.`,clearConfirmCta:`Clear chat`,endChat:`End conversation`,endChatConfirm:`End this conversation?`,endChatConfirmBody:`You won't be able to send more messages in this chat, but you can start a new one anytime.`,endConfirmCta:`End conversation`,conversationEnded:`This conversation has ended.`,startNewChat:`Start a new conversation`,pastConversations:`Past conversations`,viewingPast:`Viewing a past conversation (read-only)`,backToChat:`Back to current chat`,historyEnded:`ended`,feedbackHelpful:`Helpful`,feedbackNotHelpful:`Not helpful`,feedbackThanks:`Thanks for the feedback`,csatPrompt:`How was this chat?`,feedbackCommentPlaceholder:`What went wrong? (optional)`,feedbackSend:`Send`,cancel:`Cancel`,newMessages:`New messages`,poweredBy:`Powered by`,searchGifs:`Search GIFsโ€ฆ`,searchingGifs:`Searchingโ€ฆ`,noGifs:`No GIFs found`,assistantTyping:`Assistant is typing`,emptyReply:`Sorry, I couldn't generate a reply.`,errorGeneric:`Something went wrong reaching the assistant. Please try again.`,errorRateLimit:`Youโ€™re sending messages a little fast โ€” give it a second and try again.`,attaching:`Reading fileโ€ฆ`,attachTooLarge:`That file is too large (max 8 MB).`,attachFailed:`Couldnโ€™t read that file โ€” try another.`,handoffTitle:`Want our team to follow up?`,handoffName:`Name (optional)`,handoffEmail:`Your email`,handoffNotify:`Notify the team`,sending:`Sendingโ€ฆ`,handoffShared:`Iโ€™ve shared this with our team โ€” theyโ€™ll get back to you at {email}.`,formThanks:`Thanks! Weโ€™ll be in touch.`,formError:`Something went wrong โ€” please try again.`,bookingPickTime:`What time works best?`,bookingDuration:`30-minute demo`,bookingRequested:`Requested for {when} โ€” weโ€™ll confirm by email.`,bookingConfirmed:`Youโ€™re booked for {when}! A calendar invite is on its way. ๐Ÿ“…`,bookingSlotTaken:`That time was just taken โ€” please pick another.`,bookingViaProvider:`Pick a time that works for you on {provider}.`,bookingOpenScheduler:`Open the scheduler`,bookingLinkOpened:`Opening the scheduler โ€” pick a time that suits you. ๐Ÿ“…`,bookingMeetingLink:`Meeting link`,previewReply:`๐Ÿ‘‹ This is a preview โ€” replies here are samples. Publish the widget on your site to chat with the live AI.`,previewActionNote:`Preview โ€” nothing was actually sent. This works for real once you publish.`,previewBanner:`Preview โ€” sample replies, no AI`},N=(e,t)=>e.replace(/\{(\w+)\}/g,(e,n)=>t[n]??``),ee=e=>e?{...M,...e}:M,te=e(M),ne=te.Provider,P=()=>r(te),F=(e,t)=>l(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,"stroke-width":`2`,"stroke-linecap":`round`,"stroke-linejoin":`round`,"aria-hidden":`true`,...t,children:e}),re=e=>l(`svg`,{viewBox:`0 0 24 24`,fill:`currentColor`,"aria-hidden":`true`,...e,children:l(`path`,{"fill-rule":`evenodd`,"clip-rule":`evenodd`,d:`M5 3.25h14A3.75 3.75 0 0 1 22.75 7v6A3.75 3.75 0 0 1 19 16.75h-7.19l-4.26 3.84A.75.75 0 0 1 6.25 20v-3.32A3.75 3.75 0 0 1 2.25 13V7A3.75 3.75 0 0 1 6 3.25Zm3 7.75a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5Zm4 0a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5Zm4 0a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5Z`})}),ie=e=>F(l(`path`,{d:`m6 9 6 6 6-6`}),e),I=e=>F(u(c,{children:[l(`path`,{d:`m22 2-7 20-4-9-9-4Z`}),l(`path`,{d:`M22 2 11 13`})]}),e),L=e=>F(u(c,{children:[l(`path`,{d:`M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z`}),l(`path`,{d:`M19 10v2a7 7 0 0 1-14 0v-2`}),l(`line`,{x1:`12`,y1:`19`,x2:`12`,y2:`22`})]}),e),R=e=>F(u(c,{children:[l(`path`,{d:`M15 3h6v6`}),l(`path`,{d:`M10 14 21 3`}),l(`path`,{d:`M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6`})]}),e),z=e=>F(u(c,{children:[l(`rect`,{x:`3`,y:`4`,width:`18`,height:`18`,rx:`2`}),l(`line`,{x1:`16`,y1:`2`,x2:`16`,y2:`6`}),l(`line`,{x1:`8`,y1:`2`,x2:`8`,y2:`6`}),l(`line`,{x1:`3`,y1:`10`,x2:`21`,y2:`10`})]}),e),B=e=>F(u(c,{children:[l(`rect`,{x:`2`,y:`4`,width:`20`,height:`16`,rx:`2`}),l(`path`,{d:`m22 7-10 5L2 7`})]}),e),V=e=>F(l(`path`,{d:`M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.91.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92Z`}),e),H=e=>F(u(c,{children:[l(`circle`,{cx:`12`,cy:`12`,r:`9`}),l(`path`,{d:`M8.5 14.5a4 4 0 0 0 7 0`}),l(`line`,{x1:`9`,y1:`9.5`,x2:`9.01`,y2:`9.5`}),l(`line`,{x1:`15`,y1:`9.5`,x2:`15.01`,y2:`9.5`})]}),e),ae=e=>F(u(c,{children:[l(`line`,{x1:`18`,y1:`6`,x2:`6`,y2:`18`}),l(`line`,{x1:`6`,y1:`6`,x2:`18`,y2:`18`})]}),e),oe=e=>F(u(c,{children:[l(`path`,{d:`M11 5 6 9H2v6h4l5 4z`}),l(`path`,{d:`M15.5 8.5a5 5 0 0 1 0 7`}),l(`path`,{d:`M19 5a9 9 0 0 1 0 14`})]}),e),se=e=>F(u(c,{children:[l(`path`,{d:`M11 5 6 9H2v6h4l5 4z`}),l(`line`,{x1:`22`,y1:`9`,x2:`16`,y2:`15`}),l(`line`,{x1:`16`,y1:`9`,x2:`22`,y2:`15`})]}),e),ce=e=>F(l(`path`,{d:`M20 6 9 17l-5-5`}),e),le=e=>F(u(c,{children:[l(`rect`,{x:`9`,y:`9`,width:`13`,height:`13`,rx:`2`}),l(`path`,{d:`M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1`})]}),e),ue=e=>F(u(c,{children:[l(`path`,{d:`M1 4v6h6`}),l(`path`,{d:`M3.51 15a9 9 0 1 0 2.13-9.36L1 10`})]}),e),de=e=>F(l(`rect`,{x:`6`,y:`6`,width:`12`,height:`12`,rx:`2`}),e),U=e=>F(l(`path`,{d:`M21.44 11.05 12.25 20.24a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48`}),e),fe=e=>F(u(c,{children:[l(`path`,{d:`M18.36 6.64a9 9 0 1 1-12.73 0`}),l(`line`,{x1:`12`,y1:`2`,x2:`12`,y2:`12`})]}),e),pe=e=>F(u(c,{children:[l(`circle`,{cx:`12`,cy:`12`,r:`9`}),l(`path`,{d:`M12 7v5l3 2`})]}),e),me=e=>F(u(c,{children:[l(`path`,{d:`M7 10v12`}),l(`path`,{d:`M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z`})]}),e),he=e=>F(u(c,{children:[l(`path`,{d:`M17 14V2`}),l(`path`,{d:`M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88Z`})]}),e),ge=e=>F(u(c,{children:[l(`line`,{x1:`12`,y1:`5`,x2:`12`,y2:`19`}),l(`path`,{d:`m19 12-7 7-7-7`})]}),e),_e=/(`[^`]+`)|(\*\*[^*]+\*\*)|(\[[^\]]+\]\(https?:\/\/[^\s)]+\))|(https?:\/\/[^\s)]+)/g,W=e=>{let t=[],n=0,r=0,i;for(_e.lastIndex=0;(i=_e.exec(e))!==null;){i.index>n&&t.push(e.slice(n,i.index));let a=i[0];if(a.startsWith("`"))t.push(l(`code`,{class:`cf-md-code`,children:a.slice(1,-1)},r++));else if(a.startsWith(`**`))t.push(l(`strong`,{children:a.slice(2,-2)},r++));else if(a.startsWith(`[`)){let e=/^\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)$/.exec(a),n=e?e[1]:a,i=e?e[2]:`#`;t.push(l(`a`,{href:i,target:`_blank`,rel:`noopener noreferrer nofollow`,children:n},r++))}else t.push(l(`a`,{href:a,target:`_blank`,rel:`noopener noreferrer nofollow`,children:a},r++));n=i.index+a.length}return n<e.length&&t.push(e.slice(n)),t},ve=/^(```|#{1,6}\s|\s*[-*]\s|\s*\d+\.\s)/,ye=e=>{let t=e.replace(/\r\n/g,`
6
+ `).split(`
7
+ `),n=[],r=0,i=0;for(;i<t.length;){let e=t[i];if(e.trim().startsWith("```")){let e=[];for(i++;i<t.length&&!t[i].trim().startsWith("```");)e.push(t[i]),i++;i++,n.push(l(`pre`,{class:`cf-md-pre`,children:l(`code`,{children:e.join(`
8
+ `)})},r++));continue}if(e.trim()===``){i++;continue}let a=/^(#{1,6})\s+(.*)$/.exec(e);if(a){n.push(l(`div`,{class:`cf-md-h`,children:W(a[2])},r++)),i++;continue}if(/^\s*[-*]\s+/.test(e)){let e=[];for(;i<t.length&&/^\s*[-*]\s+/.test(t[i]);)e.push(l(`li`,{children:W(t[i].replace(/^\s*[-*]\s+/,``))},e.length)),i++;n.push(l(`ul`,{class:`cf-md-list`,children:e},r++));continue}if(/^\s*\d+\.\s+/.test(e)){let e=[];for(;i<t.length&&/^\s*\d+\.\s+/.test(t[i]);)e.push(l(`li`,{children:W(t[i].replace(/^\s*\d+\.\s+/,``))},e.length)),i++;n.push(l(`ol`,{class:`cf-md-list`,children:e},r++));continue}let o=[e];for(i++;i<t.length&&t[i].trim()!==``&&!ve.test(t[i]);)o.push(t[i]),i++;n.push(l(`p`,{children:W(o.join(` `))},r++))}return n},G=()=>{let e=o(null);return i(()=>{let t=requestAnimationFrame(()=>e.current?.scrollIntoView({block:`end`}));return()=>cancelAnimationFrame(t)},[]),e},K=e=>e.trim().split(/\s+/).slice(0,2).map(e=>e[0]?.toUpperCase()??``).join(``)||`๐Ÿค–`,be=({persona:e,small:t})=>{let n=t?`cf-msg__avatar`:`cf-header__avatar`;return e?.agentAvatarUrl?l(`span`,{class:n,children:l(`img`,{src:e.agentAvatarUrl,alt:``})}):l(`span`,{class:n,children:e?K(e.agentName):`ยท`})},q=()=>{let e=P();return u(`div`,{class:`cf-msg__bubble cf-typing`,"aria-label":e.assistantTyping,children:[l(`span`,{class:`cf-typing__dot`}),l(`span`,{class:`cf-typing__dot`}),l(`span`,{class:`cf-typing__dot`})]})},xe=({msg:e})=>{if(!e.sources||e.sources.length===0)return null;let t=new Set,n=[];for(let r of e.sources){let e=(r.url||r.title||``).toLowerCase();!e||t.has(e)||(t.add(e),n.push(r))}if(n.length===0)return null;let r=n.slice(0,3),i=n.length-r.length;return u(`div`,{class:`cf-sources`,children:[r.map((e,t)=>e.url?u(`a`,{class:`cf-source`,href:e.url,target:`_blank`,rel:`noopener noreferrer nofollow`,title:e.title||e.url,children:[l(R,{}),l(`span`,{children:e.title||e.url})]},t):u(`span`,{class:`cf-source`,title:e.title,children:[l(R,{}),l(`span`,{children:e.title})]},t)),i>0&&u(`span`,{class:`cf-source cf-source--more`,children:[`+`,i,` more`]})]})},Se=({replies:e,onPick:t})=>e&&e.length>0?l(`div`,{class:`cf-chips`,children:e.map((e,n)=>l(`button`,{type:`button`,class:`cf-chip`,onClick:()=>t(e),children:e},n))}):null,Ce={public_book_demo:{type:`book-demo`,label:`Book a demo`,Icon:z},public_submit_inquiry:{type:`inquiry`,label:`Leave a message`,Icon:B},public_request_callback:{type:`request-callback`,label:`Request a callback`,Icon:V},public_subscribe_newsletter:{type:`subscribe-newsletter`,label:`Subscribe`,Icon:B}},we=({field:e,value:t,onInput:n})=>{let r=e.placeholder??e.label,i={class:`cf-form__input`,placeholder:e.required?`${r} *`:r,value:t,"aria-label":e.label,onInput:e=>n(e.target.value)};return e.kind===`textarea`?l(`textarea`,{rows:2,...i}):l(`input`,{type:e.kind,...i})},Te=({spec:e,visitor:t,onSubmit:n,onCancel:r})=>{let i=P(),a=G(),[o,c]=s(()=>{let n={};for(let r of e.fields)r.identity&&t[r.identity]&&(n[r.key]=t[r.identity]);return n}),[d,f]=s(`idle`),[p,m]=s(``),h=e=>!!(e.identity&&t[e.identity]?.trim()),g=e.fields.filter(e=>!h(e)),_=g.every(e=>!e.required||(o[e.key]?.trim()??``)!==``),v=t.email||t.name||``;return d===`done`?u(`div`,{class:`cf-form cf-form--done`,children:[l(ce,{}),l(`span`,{children:p})]}):u(`div`,{class:`cf-form`,ref:a,children:[l(`div`,{class:`cf-form__title`,children:e.title}),g.length===0&&v&&u(`div`,{class:`cf-form__as`,children:[`as `,v]}),g.map(e=>l(we,{field:e,value:o[e.key]??``,onInput:t=>c(n=>({...n,[e.key]:t}))},e.key)),d===`error`&&l(`div`,{class:`cf-form__err`,children:i.formError}),u(`div`,{class:`cf-form__actions`,children:[r&&l(`button`,{type:`button`,class:`cf-form__cancel`,onClick:r,children:`Cancel`}),l(`button`,{type:`button`,class:`cf-form__submit`,disabled:!_||d===`submitting`,onClick:async()=>{if(!_||d===`submitting`)return;f(`submitting`);let t={},r={};for(let n of e.fields){let e=o[n.key]?.trim();e&&(t[n.key]=e,n.identity&&(r[n.identity]=e))}try{m((await n(t,r)).note||i.formThanks),f(`done`)}catch{f(`error`)}},children:d===`submitting`?i.sending:e.submit})]})]})},J=e=>String(e).padStart(2,`0`),Ee=()=>{let e=[];for(let t=9;t<=17;t++)e.push(`${J(t)}:00`),e.push(`${J(t)}:30`);return e},De=e=>{let t=new Date;return t.setHours(0,0,0,0),Array.from({length:e},(e,n)=>{let r=new Date(t);return r.setDate(t.getDate()+n),r})},Y=(e,t)=>{let[n,r]=t.split(`:`).map(Number),i=new Date(e.getFullYear(),e.getMonth(),e.getDate(),n??0,r??0);try{return new Intl.DateTimeFormat(void 0,{weekday:`short`,day:`numeric`,month:`short`,year:`numeric`,hour:`2-digit`,minute:`2-digit`,timeZoneName:`short`}).format(i)}catch{return`${e.toDateString()} ${t}`}},X=(e,t)=>{let[n,r]=t.split(`:`).map(Number);return new Date(e.getFullYear(),e.getMonth(),e.getDate(),n??0,r??0)},Oe=({visitor:e,onSubmit:t,onCancel:n,onDemoSlots:r,scheduler:o})=>{let d=P(),f=G(),p=a(()=>De(14),[]),m=a(()=>Ee(),[]),[h,g]=s(a(()=>{let e=Date.now();for(let t=0;t<p.length;t++)if(m.some(n=>X(p[t],n).getTime()>e))return t;return 0},[p,m])),[_,v]=s(null),[y,b]=s(e.name??``),[x,S]=s(e.email??``),[C,w]=s(`idle`),[T,E]=s(``),[D,O]=s(``),[k,A]=s(``),M=o?.connected&&o.mode===`link`,ee=async()=>{if(C===`submitting`||!e.email?.trim()&&!x.trim())return;w(`submitting`),O(``);let n={};x.trim()&&(n.email=x.trim()),y.trim()&&(n.name=y.trim());try{let e=await t({...x.trim()?{visitorEmail:x.trim()}:{},...y.trim()?{visitorName:y.trim()}:{}},n),r=e.booking?.schedulingLink||o?.bookingLink||``;if(!r){w(`error`);return}try{window.open(r,`_blank`,`noopener,noreferrer`)}catch{}A(r),E(e.note||d.bookingLinkOpened),w(`done`)}catch{w(`error`)}},[te,ne]=s(new Set),[F,re]=s([]),[ie,I]=s(0),[L,z]=s(!1);i(()=>{if(!r)return;let e=!0,t=new Date,n=new Date;return n.setDate(n.getDate()+15),r(t.toISOString(),n.toISOString()).then(t=>{e&&(ne(new Set(t.taken.map(e=>Date.parse(e)).filter(e=>!Number.isNaN(e)))),re(t.busy.map(e=>[Date.parse(e.start),Date.parse(e.end)]).filter(([e,t])=>!Number.isNaN(e)&&!Number.isNaN(t))))}).catch(()=>{}),()=>{e=!1}},[r,ie]);let B=!!e.email?.trim(),V=!!_&&(B||x.trim()!==``),H=e.email||e.name||``,ae=e=>te.has(X(p[h],e).getTime()),oe=e=>X(p[h],e).getTime()<=Date.now(),se=e=>{let t=X(p[h],e).getTime(),n=t+18e5;return F.some(([e,r])=>t<r&&n>e)},le=async()=>{if(!V||C===`submitting`||!_)return;w(`submitting`),z(!1),O(``);let e=X(p[h],_),n=Y(p[h],_),r={};x.trim()&&(r.email=x.trim()),y.trim()&&(r.name=y.trim());try{let i=await t({preferredAt:n,slotAt:e.toISOString(),...x.trim()?{visitorEmail:x.trim()}:{},...y.trim()?{visitorName:y.trim()}:{}},r);i.booking?.confirmed?(E(i.note||N(d.bookingConfirmed,{when:n})),A(i.booking.meetingUrl||i.booking.eventLink||``)):E(i.note||N(d.bookingRequested,{when:n})),w(`done`)}catch(t){if(t?.status===409)ne(t=>new Set(t).add(e.getTime())),v(null),z(!0),I(e=>e+1),w(`idle`);else{let e=t?.message;O(e&&e.length<120?e:``),w(`error`)}}};return C===`done`?u(`div`,{class:`cf-form cf-form--done`,children:[l(ce,{}),l(`span`,{children:T}),k&&u(`a`,{class:`cf-booking__link`,href:k,target:`_blank`,rel:`noopener noreferrer`,children:[M?d.bookingOpenScheduler:d.bookingMeetingLink,` `,l(R,{})]})]}):M?u(`div`,{class:`cf-form cf-booking`,ref:f,children:[l(`div`,{class:`cf-form__title`,children:j[`book-demo`].title}),l(`div`,{class:`cf-booking__hint`,children:N(d.bookingViaProvider,{provider:o?.label??`the scheduler`})}),B?H?u(`div`,{class:`cf-form__as`,children:[`as `,H]}):null:u(c,{children:[l(`input`,{class:`cf-form__input`,type:`text`,placeholder:d.handoffName,value:y,"aria-label":d.handoffName,onInput:e=>b(e.target.value)}),l(`input`,{class:`cf-form__input`,type:`email`,placeholder:`${d.handoffEmail} *`,value:x,"aria-label":d.handoffEmail,onInput:e=>S(e.target.value)})]}),C===`error`&&l(`div`,{class:`cf-form__err`,children:D||d.formError}),u(`div`,{class:`cf-form__actions`,children:[n&&l(`button`,{type:`button`,class:`cf-form__cancel`,onClick:n,children:d.cancel}),l(`button`,{type:`button`,class:`cf-form__submit`,disabled:C===`submitting`||!B&&x.trim()===``,onClick:ee,children:C===`submitting`?d.sending:d.bookingOpenScheduler})]})]}):u(`div`,{class:`cf-form cf-booking`,ref:f,children:[l(`div`,{class:`cf-form__title`,children:j[`book-demo`].title}),u(`div`,{class:`cf-booking__hint`,children:[d.bookingPickTime,` ยท `,l(`span`,{class:`cf-booking__dur`,children:d.bookingDuration})]}),l(`div`,{class:`cf-booking__dates`,role:`tablist`,"aria-label":`Pick a day`,children:p.map((e,t)=>u(`button`,{type:`button`,role:`tab`,"aria-selected":t===h,class:`cf-booking__date ${t===h?`is-selected`:``}`,onClick:()=>{g(t),v(null)},children:[l(`span`,{class:`cf-booking__dow`,children:e.toLocaleDateString(void 0,{weekday:`short`})}),l(`span`,{class:`cf-booking__dom`,children:e.getDate()})]},t))}),l(`div`,{class:`cf-booking__slots`,role:`listbox`,"aria-label":`Pick a time`,children:m.map(e=>{let t=oe(e),n=se(e),r=ae(e),i=r||t||n;return l(`button`,{type:`button`,role:`option`,"aria-selected":_===e,disabled:i,title:t?`Earlier today`:n?`Busy on the calendar`:r?`Already booked`:void 0,class:`cf-booking__slot ${_===e?`is-selected`:``} ${i?`is-taken`:``}`,onClick:()=>v(e),children:e},e)})}),L&&l(`div`,{class:`cf-form__err`,children:d.bookingSlotTaken}),B?H?u(`div`,{class:`cf-form__as`,children:[`as `,H]}):null:u(c,{children:[l(`input`,{class:`cf-form__input`,type:`text`,placeholder:d.handoffName,value:y,"aria-label":d.handoffName,onInput:e=>b(e.target.value)}),l(`input`,{class:`cf-form__input`,type:`email`,placeholder:`${d.handoffEmail} *`,value:x,"aria-label":d.handoffEmail,onInput:e=>S(e.target.value)})]}),C===`error`&&l(`div`,{class:`cf-form__err`,children:D||d.formError}),u(`div`,{class:`cf-form__actions`,children:[n&&l(`button`,{type:`button`,class:`cf-form__cancel`,onClick:n,children:d.cancel}),l(`button`,{type:`button`,class:`cf-form__submit`,disabled:!V||C===`submitting`,onClick:le,children:C===`submitting`?d.sending:j[`book-demo`].submit})]})]})},ke=({actions:e,visitor:t,onSubmitForm:n,onDemoSlots:r,scheduler:i,exclude:a=[]})=>{let[o,c]=s(null),d=(e??[]).map(e=>Ce[e]).filter(e=>!!e&&!a.includes(e.type));return d.length===0?null:o===`book-demo`?l(Oe,{visitor:t,onCancel:()=>c(null),onSubmit:(e,t)=>n(`book-demo`,e,t),onDemoSlots:r,scheduler:i}):o?l(Te,{spec:j[o],visitor:t,onCancel:()=>c(null),onSubmit:(e,t)=>n(o,e,t)}):l(`div`,{class:`cf-actions`,children:d.map(({type:e,label:t,Icon:n})=>u(`button`,{type:`button`,class:`cf-action`,onClick:()=>c(e),children:[l(n,{}),t]},e))})},Ae=({hasEmail:e,visitor:t,question:n,onSubmitForm:r})=>{let i=P(),[a,o]=s(!1),[c,d]=s(!1),[f,p]=s(t.name??``),[m,h]=s(t.email??``);if(e)return null;if(a){let e=t.email||m;return u(`div`,{class:`cf-handoff cf-handoff--done`,children:[l(ce,{}),l(`span`,{children:N(i.handoffShared,{email:e})})]})}let g=async()=>{if(!(!m.trim()||c)){d(!0);try{await r(`inquiry`,{visitorEmail:m.trim(),...f.trim()?{visitorName:f.trim()}:{},message:n||`I had a question the assistant couldnโ€™t answer.`,subject:`Help request from chat`},{email:m.trim(),name:f.trim()||void 0}),o(!0)}catch{d(!1)}}};return u(`div`,{class:`cf-handoff`,children:[l(`div`,{class:`cf-handoff__title`,children:i.handoffTitle}),l(`input`,{class:`cf-form__input`,type:`text`,placeholder:i.handoffName,value:f,"aria-label":i.handoffName,onInput:e=>p(e.target.value)}),l(`input`,{class:`cf-form__input`,type:`email`,placeholder:`${i.handoffEmail} *`,value:m,"aria-label":i.handoffEmail,onInput:e=>h(e.target.value)}),l(`button`,{type:`button`,class:`cf-form__submit`,disabled:!m.trim()||c,onClick:g,children:c?i.sending:i.handoffNotify})]})},je=({text:e})=>{let t=P(),[n,r]=s(!1);return u(`button`,{type:`button`,class:`cf-tool`,onClick:async()=>{try{await navigator.clipboard.writeText(e),r(!0),setTimeout(()=>r(!1),1500)}catch{}},"aria-label":t.copy,children:[l(n?ce:le,{}),n?t.copied:t.copy]})},Me=({items:e,onPick:t})=>e.length===0?null:l(`div`,{class:`cf-starters`,children:e.map((e,n)=>l(`button`,{type:`button`,class:`cf-starter`,onClick:()=>t(e),children:e},n))}),Ne=({msg:e,onRate:t})=>{let n=P(),[r,i]=s(!1),[a,o]=s(``),c=e.feedback,d=()=>{t(e.id,`up`),i(!1)},f=()=>{t(e.id,`down`),i(!0)},p=()=>{t(e.id,`down`,a.trim()),i(!1)};return u(`div`,{class:`cf-feedback`,children:[u(`div`,{class:`cf-feedback__row`,children:[l(`button`,{type:`button`,class:`cf-feedback__btn ${c===`up`?`is-active`:``}`,"aria-label":n.feedbackHelpful,"aria-pressed":c===`up`,onClick:d,children:l(me,{})}),l(`button`,{type:`button`,class:`cf-feedback__btn ${c===`down`?`is-active`:``}`,"aria-label":n.feedbackNotHelpful,"aria-pressed":c===`down`,onClick:f,children:l(he,{})}),c&&!r&&l(`span`,{class:`cf-feedback__thanks`,children:n.feedbackThanks})]}),r&&c===`down`&&u(`div`,{class:`cf-feedback__comment`,children:[l(`textarea`,{class:`cf-feedback__input`,rows:2,placeholder:n.feedbackCommentPlaceholder,value:a,onInput:e=>o(e.target.value)}),l(`button`,{type:`button`,class:`cf-feedback__send`,onClick:p,children:n.feedbackSend})]})]})},Pe=({msg:e,persona:t,isLast:n,visitor:r,hasEmail:i,lastQuestion:a,showActions:o,onPickReply:s,onSubmitForm:d,onDemoSlots:f,onRetry:p,ratable:m,onRate:h})=>{let g=P(),_=e.role===`user`,v=e.requestedContactFields?.includes(`email`)===!0,y=n&&!_&&!!(e.handoffOffered||v),b=y&&!i?[`inquiry`]:[],x=!e.pending&&!e.streaming;return u(`div`,{class:`cf-msg cf-msg--${_?`user`:`agent`}`,children:[!_&&l(be,{persona:t,small:!0}),u(`div`,{class:`cf-msg__col`,children:[e.pending&&e.content===``?l(q,{}):e.imageUrl?u(`div`,{class:`cf-msg__bubble cf-msg__bubble--media`,children:[l(`img`,{class:`cf-msg__media`,src:e.imageUrl,alt:`GIF`}),e.content&&l(`span`,{class:`cf-msg__caption`,children:e.content})]}):u(`div`,{class:`cf-msg__bubble`,children:[_?e.content:ye(e.content),e.streaming&&l(`span`,{class:`cf-caret`,"aria-hidden":`true`})]}),_&&e.attachmentName&&u(`div`,{class:`cf-attach-chip`,title:e.attachmentName,children:[l(U,{}),l(`span`,{children:e.attachmentName})]}),!_&&u(c,{children:[x&&(e.error||e.content)&&l(`div`,{class:`cf-msg__tools`,children:e.error?u(`button`,{type:`button`,class:`cf-tool`,onClick:()=>p(e.id,e.retryText??``),children:[l(ue,{}),g.retry]}):l(je,{text:e.content})}),x&&m&&!e.error&&e.content&&l(Ne,{msg:e,onRate:h}),l(xe,{msg:e}),n&&l(Se,{replies:e.suggestedReplies,onPick:s}),y&&l(Ae,{hasEmail:i,visitor:r,question:a,onSubmitForm:d}),o&&l(ke,{actions:e.availableActions,visitor:r,onSubmitForm:d,onDemoSlots:f,scheduler:t?.scheduler,exclude:b})]})]})]})},Fe=e=>new Promise((t,n)=>{let r=new FileReader;r.onload=()=>t(String(r.result).split(`,`)[1]??``),r.onerror=n,r.readAsDataURL(e)}),Ie=({onPick:e})=>l(`div`,{class:`cf-picker cf-emoji`,children:A.map(t=>u(`div`,{class:`cf-emoji__group`,children:[l(`div`,{class:`cf-emoji__label`,children:t.name}),l(`div`,{class:`cf-emoji__grid`,children:t.emojis.map((t,n)=>l(`button`,{type:`button`,class:`cf-emoji__btn`,onClick:()=>e(t),"aria-label":t,children:t},n))})]},t.name))}),Le=({onSearch:e,onPick:t})=>{let n=P(),[r,a]=s(``),[o,c]=s([]),[d,f]=s(!0);return i(()=>{let t=!0;f(!0);let n=setTimeout(()=>{e(r).then(e=>t&&(c(e),f(!1))).catch(()=>t&&(c([]),f(!1)))},300);return()=>{t=!1,clearTimeout(n)}},[r,e]),u(`div`,{class:`cf-picker cf-gif`,children:[l(`input`,{class:`cf-gif__search`,placeholder:n.searchGifs,value:r,"aria-label":n.searchGifs,onInput:e=>a(e.target.value)}),l(`div`,{class:`cf-gif__grid`,children:d?l(`div`,{class:`cf-gif__hint`,children:n.searchingGifs}):o.length===0?l(`div`,{class:`cf-gif__hint`,children:n.noGifs}):o.map(e=>l(`button`,{type:`button`,class:`cf-gif__item`,onClick:()=>t(e.url),"aria-label":e.alt,children:l(`img`,{src:e.preview,alt:e.alt,loading:`lazy`})},e.id))}),l(`div`,{class:`cf-gif__powered`,children:`via Tenor`})]})},Re=({onSend:e,onSendGif:t,disabled:n,allowVoice:r,onTranscribe:a,gifEnabled:d,onSearchGifs:f,allowAttach:p,onExtract:m})=>{let h=P(),[g,_]=s(``),[v,y]=s(!1),[b,x]=s(`none`),[S,C]=s(null),[w,T]=s(!1),[E,D]=s(``),O=o(null),k=o(null),A=o(null),j=o(null),M=o([]);i(()=>{let e=O.current;e&&(e.style.height=`auto`,e.style.height=`${Math.min(e.scrollHeight,110)}px`)},[g]),i(()=>{if(b===`none`)return;let e=e=>{k.current&&!e.composedPath().includes(k.current)&&x(`none`)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[b]);let N=e=>x(t=>t===e?`none`:e),ee=e=>{let t=O.current;if(!t){_(t=>t+e);return}let n=t.selectionStart??g.length,r=t.selectionEnd??g.length;_(g.slice(0,n)+e+g.slice(r)),requestAnimationFrame(()=>{t.focus();let r=n+e.length;t.setSelectionRange(r,r)})},te=e=>{x(`none`),t(e)},ne=async e=>{let t=e.target,n=t.files?.[0];if(t.value=``,n){if(D(``),n.size>8388608){D(h.attachTooLarge);return}T(!0);try{let e=await m(await Fe(n),n.type||`application/octet-stream`,n.name);if(!e){D(h.attachFailed);return}C({name:n.name,text:e})}catch{D(h.attachFailed)}finally{T(!1)}}},F=(!!g.trim()||!!S)&&!n&&!w,re=()=>{F&&(e(g,S?{attachmentName:S.name,attachmentText:S.text}:void 0),_(``),C(null),D(``))},ie=e=>{e.key===`Enter`&&!e.shiftKey?(e.preventDefault(),re()):e.key===`Escape`&&b!==`none`&&(e.preventDefault(),e.stopPropagation(),x(`none`))},R=async()=>{if(v){j.current?.stop();return}try{let e=await navigator.mediaDevices.getUserMedia({audio:!0}),t=new MediaRecorder(e);M.current=[],t.ondataavailable=e=>e.data.size>0&&M.current.push(e.data),t.onstop=async()=>{e.getTracks().forEach(e=>e.stop()),y(!1);let n=new Blob(M.current,{type:t.mimeType||`audio/webm`});try{let e=await a(await Fe(n),n.type);e&&_(t=>t?`${t} ${e}`:e)}catch{}},j.current=t,t.start(),y(!0)}catch{let e=await a(``,`audio/webm`).catch(()=>``);e&&_(t=>t?`${t} ${e}`:e)}};return u(`div`,{class:`cf-composer`,ref:k,children:[b===`emoji`&&l(Ie,{onPick:ee}),b===`gif`&&l(Le,{onSearch:f,onPick:te}),(S||w||E)&&l(`div`,{class:`cf-attach-row`,children:w?l(`span`,{class:`cf-attach-status`,children:h.attaching}):E?l(`span`,{class:`cf-attach-status cf-attach-status--err`,children:E}):S&&u(`span`,{class:`cf-attach-chip`,title:S.name,children:[l(U,{}),l(`span`,{children:S.name}),l(`button`,{type:`button`,class:`cf-attach-x`,"aria-label":`Remove attachment`,onClick:()=>C(null),children:l(ae,{})})]})}),u(`div`,{class:`cf-composer__field`,children:[l(`button`,{type:`button`,class:`cf-iconbtn ${b===`emoji`?`is-active`:``}`,"aria-label":h.emoji,"aria-pressed":b===`emoji`,onClick:()=>N(`emoji`),children:l(b===`emoji`?ae:H,{})}),d&&l(`button`,{type:`button`,class:`cf-iconbtn cf-gifbtn ${b===`gif`?`is-active`:``}`,"aria-label":h.gifs,"aria-pressed":b===`gif`,onClick:()=>N(`gif`),children:l(`span`,{class:`cf-gif-label`,children:`GIF`})}),p&&u(c,{children:[l(`input`,{ref:A,type:`file`,class:`cf-file-input`,accept:`image/png,image/jpeg,image/webp,image/gif,application/pdf`,onChange:ne,tabIndex:-1,"aria-hidden":`true`}),l(`button`,{type:`button`,class:`cf-iconbtn`,"aria-label":h.attachFile,disabled:w,onClick:()=>A.current?.click(),children:l(U,{})})]}),l(`textarea`,{ref:O,class:`cf-textarea`,rows:1,placeholder:h.composerPlaceholder,value:g,"aria-label":h.composerPlaceholder,disabled:n,onInput:e=>_(e.target.value),onKeyDown:ie}),r&&l(`button`,{type:`button`,class:`cf-iconbtn cf-mic ${v?`is-recording`:``}`,"aria-label":v?h.stopRecording:h.recordVoice,"aria-pressed":v,onClick:R,children:l(L,{})}),l(`button`,{type:`button`,class:`cf-send`,"aria-label":h.send,disabled:!F,onClick:re,children:l(I,{})})]})]})};let ze=!0,Z=null;const Be=e=>{ze=e},Ve=()=>{let e=typeof window<`u`?window.AudioContext??window.webkitAudioContext:void 0;if(!e)return null;if(!Z)try{Z=new e}catch{return null}return Z.state===`suspended`&&Z.resume(),Z},He=(e,t,n,r,i,a)=>{let o=e.createOscillator(),s=e.createGain();o.type=i,o.frequency.setValueAtTime(t,n),o.connect(s),s.connect(e.destination),s.gain.setValueAtTime(1e-4,n),s.gain.exponentialRampToValueAtTime(a,n+.012),s.gain.exponentialRampToValueAtTime(1e-4,n+r),o.start(n),o.stop(n+r+.03)},Ue=e=>{if(!ze)return;let t=Ve();if(!t)return;let n=t.currentTime;try{e===`open`?(He(t,523,n,.12,`sine`,.05),He(t,784,n+.08,.16,`sine`,.05)):e===`send`?He(t,660,n,.08,`triangle`,.04):e===`receive`&&(He(t,880,n,.1,`sine`,.045),He(t,1175,n+.09,.14,`sine`,.045))}catch{}},Q=()=>typeof crypto<`u`&&crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.round(Math.random()*1e9)}`,$=e=>{try{return e===`none`?null:e===`session`?sessionStorage:localStorage}catch{return null}},We=e=>`centrinfo:session:${e.slice(0,12)}`,Ge=e=>`centrinfo:visitor:${e.slice(0,12)}`,Ke=(e,t)=>`centrinfo:chat:${e.slice(0,12)}:${t}`,qe=e=>`centrinfo:history:${e.slice(0,12)}`,Je=720*60*60*1e3,Ye=(e,t)=>{try{return JSON.parse(e?.getItem(Ge(t))||`{}`)}catch{return{}}},Xe=(e,t)=>{if(!e)return Q();try{let n=We(t),r=e.getItem(n);if(r)return r;let i=Q();return e.setItem(n,i),i}catch{return Q()}},Ze=(e,t,n)=>{if(!e)return{};try{let r=e.getItem(Ke(t,n));return r?JSON.parse(r):{}}catch{return{}}},Qe=(e,t,n)=>{let{ts:r,messages:i}=Ze(e,t,n);return!Array.isArray(i)||typeof r==`number`&&Date.now()-r>Je?[]:i},$e=(e,t,n)=>{let{ts:r,messages:i,ended:a}=Ze(e,t,n);return!Array.isArray(i)||i.length===0||typeof r==`number`&&Date.now()-r>Je?!1:a===!0||typeof r==`number`&&Date.now()-r>864e5},et=(e,t,n,r,i)=>{if(e)try{let a=r.filter(e=>!e.pending).slice(-50);if(a.length===0)return;e.setItem(Ke(t,n),JSON.stringify({ts:Date.now(),messages:a,ended:i}))}catch{}},tt=(e,t)=>{if(!e)return[];try{let n=e.getItem(qe(t)),r=n?JSON.parse(n):[];return Array.isArray(r)?r:[]}catch{return[]}},nt=(e,t,n)=>{if(e)try{e.setItem(qe(t),JSON.stringify(n.slice(0,20)))}catch{}},rt=(e,t)=>{if(e)try{let n=`centrinfo:chat:${t.slice(0,12)}:`,r=new Set([We(t),Ge(t),qe(t)]),i=[];for(let t=0;t<e.length;t++){let a=e.key(t);a&&(r.has(a)||a.startsWith(n))&&i.push(a)}i.forEach(t=>e.removeItem(t))}catch{}},it=e=>{let t=(e.find(e=>e.role===`user`&&e.content.trim())?.content||e.find(e=>e.content.trim())?.content||``).trim().replace(/\s+/g,` `);return t.length>60?t.slice(0,60)+`โ€ฆ`:t||`Conversation`},at=(e,t)=>{let r=o($(t.persistence)).current,a=o(Xe(r,t.token)),c=o(null),[l,u]=s(null),[d,f]=s(()=>Qe(r,t.token,a.current)),[p,m]=s(!1),[h,g]=s(()=>$e(r,t.token,a.current)),[_,v]=s(()=>Ye(r,t.token)),[y,b]=s(()=>tt(r,t.token)),[x,S]=s(null),[C,w]=s([]),T=o(_);i(()=>{T.current=_},[_]);let E=n(()=>{c.current?.abort(),rt(r,t.token);let e=Q();a.current=e;try{r?.setItem(We(t.token),e)}catch{}S(null),w([]),g(!1),b([]),v({}),f(l?[{id:Q(),role:`assistant`,content:l.greeting,availableActions:l.availableActions}]:[])},[r,t.token,l]),D=n(e=>{try{r?.setItem(Ge(t.token),JSON.stringify(e))}catch{}},[r,t.token]),O=n(t=>{let n=(t.email??``).trim().toLowerCase(),r=(T.current.email??``).trim().toLowerCase();n&&r&&n!==r&&E();let i={};t.email?.trim()&&(i.email=t.email.trim()),t.phone?.trim()&&(i.phone=t.phone.trim());let o=[t.firstName,t.lastName].filter(e=>!!e?.trim()).join(` `).trim()||t.name?.trim()||``;o&&(i.name=o),Object.keys(i).length>0&&v(e=>{let t={...i,...e};return D(t),t}),e.identify(a.current,t).catch(()=>{})},[e,D,E]);i(()=>{let n=!0;return e.bootstrap().then(e=>{n&&(u(e),f(t=>t.length>0?t:[{id:Q(),role:`assistant`,content:e.greeting,availableActions:e.availableActions}]))}),t.user&&O(t.user),()=>{n=!1}},[]),i(()=>{et(r,t.token,a.current,d,h)},[d,h,r,t.token]),i(()=>{d.some(e=>e.role===`user`)&&b(e=>{let n=a.current,i=[{sessionId:n,ts:Date.now(),title:it(d),ended:h},...e.filter(e=>e.sessionId!==n)];return nt(r,t.token,i),i.slice(0,20)})},[d,h,r,t.token]);let k=n((e,t)=>{f(n=>n.map(n=>n.id===e?{...n,...t}:n))},[]),A=n((n,r)=>{m(!0);let i=new AbortController;c.current=i,e.stream(n,a.current,{signal:i.signal,onChunk:e=>f(t=>t.map(t=>t.id===r?{...t,content:t.content+e,pending:!1,streaming:!0}:t))}).then(e=>{f(n=>n.map(n=>n.id===r?{...n,content:e.answer||n.content||t.strings.emptyReply,pending:!1,streaming:!1,error:!1,retryText:void 0,sources:e.sources,suggestedReplies:e.suggestedReplies,availableActions:e.availableActions,handoffOffered:e.handoffOffered,requestedContactFields:e.requestedContactFields}:n)),Ue(`receive`),t.onMessage?.({role:`assistant`,content:e.answer}),e.handoffOffered&&t.onHandoff?.(),e.conversationEnded&&g(!0)}).catch(e=>{if(i.signal.aborted){k(r,{pending:!1,streaming:!1});return}k(r,{content:e?.status===429?t.strings.errorRateLimit:t.strings.errorGeneric,pending:!1,streaming:!1,error:!0,retryText:n})}).finally(()=>{m(!1),c.current=null})},[e,t,k]),j=n((e,n={})=>{let r=e.trim(),{imageUrl:i,attachmentName:a,attachmentText:o}=n;if(!r&&!i&&!o||p||h)return;let s=r;o?s=`${r}\n\n[Attached file${a?` "${a}"`:``}]:\n${o}`.trim():!s&&i&&(s=i);let c={id:Q(),role:`user`,content:r,imageUrl:i,attachmentName:a},l=Q();f(e=>[...e,c,{id:l,role:`assistant`,content:``,pending:!0}]),Ue(`send`),t.onMessage?.({role:`user`,content:s}),A(s,l)},[p,h,t,A]),M=n(()=>c.current?.abort(),[]),N=n((e,t)=>{p||h||!t||(k(e,{content:``,pending:!0,streaming:!1,error:!1}),Ue(`send`),A(t,e))},[p,h,k,A]),ee=n((t,n,r)=>{k(t,{feedback:n});let i=d.findIndex(e=>e.id===t),o=i>=0?d[i]?.content:void 0,s;for(let e=i-1;e>=0;e--)if(d[e]?.role===`user`){s=d[e]?.content;break}e.sendFeedback({sessionId:a.current,messageId:t,rating:n,comment:r,question:s,answer:o}).catch(()=>{})},[e,k,d]),te=n(async(n,r,i={})=>{t.onAction?.(n);let o=await e.action(n,{sessionId:a.current,...r}),s={};return i.name?.trim()&&(s.name=i.name.trim()),i.email?.trim()&&(s.email=i.email.trim()),i.phone?.trim()&&(s.phone=i.phone.trim()),Object.keys(s).length>0&&(v(e=>{let t={...e,...s};return D(t),t}),s.email&&n!==`contact`&&e.action(`contact`,{sessionId:a.current,...s}).catch(()=>{})),Ue(`receive`),o},[e,t,D]),ne=n(e=>{let t=e.trim();t&&f(e=>e.some(e=>e.role===`assistant`&&e.content===t)?e:[...e,{id:Q(),role:`assistant`,content:t}])},[]),P=n((t,n)=>{e.sendFeedback({sessionId:a.current,messageId:`__csat__`,rating:t,comment:n}).catch(()=>{})},[e]),F=n((t,n)=>e.transcribe(t,n),[e]),re=n((t,n,r)=>e.extract(t,n,r),[e]),ie=n(t=>e.searchGifs(t),[e]),I=n((t,n)=>e.demoSlots(t,n),[e]),L=n(e=>j(``,{imageUrl:e}),[j]),R=t.demo||!!t.gifApiKey,z=n(()=>{c.current?.abort(),g(!0),e.endConversation(a.current).catch(()=>{})},[e]),B=n(()=>{c.current?.abort();let e=Q();a.current=e;try{r?.setItem(We(t.token),e)}catch{}S(null),w([]),g(!1),f(l?[{id:Q(),role:`assistant`,content:l.greeting,availableActions:l.availableActions}]:[])},[r,t.token,l]),V=n(e=>{if(e===a.current){S(null);return}w(Qe(r,t.token,e)),S(e)},[r,t.token]),H=n(()=>{S(null),w([])},[]);return{persona:l,messages:d,sending:p,visitor:_,starters:t.starters.length>0?t.starters:l?.starterQuestions??[],hasEmail:!!_.email,send:j,sendGif:L,stop:M,retry:N,rateMessage:ee,injectAssistant:ne,submitCsat:P,submitForm:te,transcribe:F,extract:re,searchGifs:ie,demoSlots:I,gifEnabled:R,identify:O,ended:h,endConversation:z,startNew:B,history:y,viewingSessionId:x,viewMessages:C,openConversation:V,closeHistoryView:H,shutdown:E}},ot=e=>{let[t,n]=s(`light`);return i(()=>{if(e!==`auto`||typeof matchMedia>`u`)return;let t=matchMedia(`(prefers-color-scheme: dark)`),r=()=>n(t.matches?`dark`:`light`);return r(),t.addEventListener(`change`,r),()=>t.removeEventListener(`change`,r)},[e]),e===`auto`?t:e},st=({transport:e,config:t,bindControls:r})=>{let a=t.strings,{persona:c,messages:d,sending:f,visitor:p,hasEmail:m,starters:h,send:g,sendGif:_,stop:v,retry:y,rateMessage:b,injectAssistant:x,submitCsat:S,submitForm:C,transcribe:w,extract:T,searchGifs:E,demoSlots:D,gifEnabled:O,identify:k,ended:A,endConversation:j,startNew:M,history:N,viewingSessionId:ee,viewMessages:te,openConversation:P,closeHistoryView:F,shutdown:I}=at(e,t),[L,R]=s(t.openByDefault),[z,B]=s(0),[V,H]=s(()=>{try{return localStorage.getItem(`centrinfo:muted`)===`1`}catch{return!1}}),ae=ot(t.theme);i(()=>{Be(t.sound&&!V)},[t.sound,V]);let ce=n(()=>{H(e=>{let t=!e;try{localStorage.setItem(`centrinfo:muted`,t?`1`:`0`)}catch{}return t})},[]),le=o(null),ue=o(null),U=o(null),_e=o(0),[W,ve]=s(!0),[ye,G]=s(!1),[K,q]=s(!1),xe=o(null),[Se,Ce]=s(!1),[we,Te]=s(!1),J=!!ee,Ee=J?te:d,De=n(()=>{R(!0),B(0),Ue(`open`),t.onOpen?.(),t.onShow?.()},[t]),Y=n(()=>{R(!1),t.onClose?.(),t.onHide?.(),ue.current?.focus()},[t]),X=n(()=>L?Y():De(),[L,De,Y]),Oe=n(()=>q(!0),[]),ke=n(()=>{j(),q(!1)},[j]),Ae=n(()=>{M(),G(!1),ve(!0)},[M]);i(()=>{K&&xe.current?.focus()},[K]),i(()=>{r({open:De,close:Y,toggle:X,identify:k,startNew:M,endConversation:j,shutdown:I})},[r,De,Y,X,k,M,j,I]),i(()=>{let e=d.filter(e=>e.role===`assistant`&&!e.pending).length;if(L){_e.current=e;return}e>_e.current&&B(e-_e.current)},[d,L]),i(()=>{t.onUnreadChange?.(z)},[z,t]),i(()=>{let e=t.sessionDurationMinutes;if(!e||e<=0)return;let n=setTimeout(()=>I(),e*60*1e3);return()=>clearTimeout(n)},[t.sessionDurationMinutes,d,L,I]),i(()=>{let e=t.customLauncherSelector;if(!e||typeof document>`u`)return;let n=[];try{n=Array.from(document.querySelectorAll(e))}catch{return}let r=e=>{e.preventDefault(),X()};return n.forEach(e=>e.addEventListener(`click`,r)),()=>n.forEach(e=>e.removeEventListener(`click`,r))},[t.customLauncherSelector,X]);let je=o(!1);i(()=>{let e=t.proactiveMessage?.trim();if(!e||je.current)return;let n=t.proactiveOnPaths??[],r=typeof location<`u`?location.pathname:``;if(n.length>0&&!n.some(e=>r.includes(e)))return;let i=`centrinfo:proactive:${t.token.slice(0,12)}`;try{if(sessionStorage.getItem(i)===`1`)return}catch{}let a=setTimeout(()=>{if(!(L||A||d.some(e=>e.role===`user`))){je.current=!0;try{sessionStorage.setItem(i,`1`)}catch{}x(e),De()}},Math.max(0,t.proactiveDelaySeconds)*1e3);return()=>clearTimeout(a)},[t.proactiveMessage]),i(()=>{let e=U.current;!L||!e||(d[d.length-1]?.role===`user`||W?(e.scrollTop=e.scrollHeight,G(!1)):G(!0))},[d,L,f,W]);let Ne=n(()=>{let e=U.current;if(!e)return;let t=e.scrollHeight-e.scrollTop-e.clientHeight<80;ve(t),t&&G(!1)},[]),Fe=n(()=>{let e=U.current;e&&(e.scrollTop=e.scrollHeight),G(!1),ve(!0)},[]),[Ie,Le]=s(``),ze=o(!1);i(()=>{if(ze.current&&!f){let e=[...d].reverse().find(e=>e.role===`assistant`&&!e.streaming&&!e.pending&&e.content);e&&Le(e.content)}ze.current=f},[f,d]),i(()=>{if(!L)return;let e=le.current;K||e?.querySelector(`.cf-textarea`)?.focus();let t=t=>{if(t.key===`Escape`){if(t.preventDefault(),K){q(!1);return}Y();return}if(t.key!==`Tab`||!e)return;let n=e.querySelectorAll(`button, [href], textarea, input, [tabindex]:not([tabindex="-1"])`),r=Array.from(n).filter(e=>!e.hasAttribute(`disabled`));if(r.length===0)return;let i=r[0],a=r[r.length-1],o=e.getRootNode()instanceof ShadowRoot?e.getRootNode().activeElement:document.activeElement;t.shiftKey&&o===i?(t.preventDefault(),a.focus()):!t.shiftKey&&o===a&&(t.preventDefault(),i.focus())};return e?.addEventListener(`keydown`,t),()=>e?.removeEventListener(`keydown`,t)},[L,Y,K]),i(()=>{let e=le.current;e&&(L?e.removeAttribute(`inert`):e.setAttribute(`inert`,``))},[L]);let Z=t.accentColor??c?.accentColor,Ve={zIndex:t.zIndex,"--cf-h-pad":`${t.horizontalPadding}px`,"--cf-v-pad":`${t.verticalPadding}px`,...Z?{"--cf-accent":Z,"--cf-accent-2":`color-mix(in oklab, ${Z} 76%, #14141f)`}:{}},He=e=>g(e),Q=[...d].reverse().find(e=>e.role===`user`&&e.content.trim())?.content??``,$=d.some(e=>e.role===`user`),We=!$&&!!(c?.agentDescription||c?.welcomeSubtitle);return l(ne,{value:a,children:u(`div`,{class:`cf-root`,"data-theme":ae,"data-align":t.alignment,style:Ve,children:[u(`div`,{ref:le,class:`cf-panel ${L?`is-open`:``}`,role:`dialog`,"aria-modal":`false`,"aria-label":`Chat with ${c?.agentName??`us`}`,"aria-hidden":!L,children:[u(`div`,{class:`cf-header`,children:[l(be,{persona:c}),u(`div`,{class:`cf-header__meta`,children:[l(`div`,{class:`cf-header__name`,children:c?.agentName??`Chat`}),l(`div`,{class:`cf-header__status ${c?.offline?`cf-header__status--offline`:``}`,children:l(`span`,{class:`cf-header__status-text`,children:c?.offline?a.statusOffline:a.statusOnline})})]}),u(`div`,{class:`cf-header__actions`,children:[N.length>0&&l(`button`,{type:`button`,class:`cf-header__btn`,"aria-label":a.pastConversations,title:a.pastConversations,"aria-pressed":Se,onClick:()=>Ce(e=>!e),children:l(pe,{})}),$&&!A&&!J&&l(`button`,{type:`button`,class:`cf-header__btn`,"aria-label":a.endChat,title:a.endChat,onClick:Oe,children:l(fe,{})}),t.sound&&l(`button`,{type:`button`,class:`cf-header__btn`,"aria-label":V?a.unmuteSounds:a.muteSounds,"aria-pressed":V,onClick:ce,children:l(V?se:oe,{})}),l(`button`,{type:`button`,class:`cf-header__btn`,"aria-label":a.closeChat,onClick:Y,children:l(ie,{})})]})]}),t.preview&&l(`div`,{class:`cf-preview-banner`,children:a.previewBanner}),J&&l(`div`,{class:`cf-viewing-banner`,children:a.viewingPast}),u(`div`,{class:`cf-body`,ref:U,role:`log`,onScroll:Ne,children:[We&&!J&&u(`div`,{class:`cf-welcome`,children:[c?.agentDescription&&l(`p`,{class:`cf-welcome__desc`,children:c.agentDescription}),c?.welcomeSubtitle&&l(`p`,{class:`cf-welcome__sub`,children:c.welcomeSubtitle})]}),Ee.map((e,t)=>l(Pe,{msg:e,persona:c,isLast:!J&&t===Ee.length-1,visitor:p,hasEmail:m,lastQuestion:Q,showActions:!J&&t===Ee.length-1&&(!$||!!e.handoffOffered),onPickReply:He,onSubmitForm:C,onDemoSlots:D,onRetry:y,ratable:!J&&Ee.slice(0,t).some(e=>e.role===`user`),onRate:b},e.id)),!$&&!J&&l(Me,{items:h,onPick:g}),ye&&u(`button`,{type:`button`,class:`cf-newmsg`,onClick:Fe,children:[l(ge,{}),a.newMessages]})]}),l(`div`,{class:`cf-sr-live`,"aria-live":`polite`,"aria-atomic":`true`,children:Ie}),f&&!A&&!J&&l(`div`,{class:`cf-stopbar`,children:u(`button`,{type:`button`,class:`cf-stop`,onClick:v,children:[l(de,{}),a.stop]})}),J?l(`div`,{class:`cf-ended`,children:l(`button`,{type:`button`,class:`cf-ended__btn`,onClick:F,children:a.backToChat})}):A?u(`div`,{class:`cf-ended`,children:[l(`p`,{class:`cf-ended__text`,children:a.conversationEnded}),t.csat&&$?we?l(`p`,{class:`cf-ended__text`,children:a.feedbackThanks}):u(`div`,{class:`cf-csat`,children:[l(`span`,{class:`cf-csat__q`,children:a.csatPrompt}),l(`button`,{type:`button`,class:`cf-csat__btn`,"aria-label":a.feedbackHelpful,onClick:()=>{S(`up`),Te(!0)},children:l(me,{})}),l(`button`,{type:`button`,class:`cf-csat__btn`,"aria-label":a.feedbackNotHelpful,onClick:()=>{S(`down`),Te(!0)},children:l(he,{})})]}):null,l(`button`,{type:`button`,class:`cf-ended__btn`,onClick:Ae,children:a.startNewChat})]}):l(Re,{onSend:g,onSendGif:_,disabled:f,allowVoice:!!c?.allowVoiceInput,onTranscribe:w,gifEnabled:O,onSearchGifs:E,allowAttach:t.attachments,onExtract:T}),!A&&c?.disclaimerText&&l(`div`,{class:`cf-disclaimer`,children:c.disclaimerText}),u(`div`,{class:`cf-footer`,children:[a.poweredBy,` `,l(`a`,{href:`https://accurix.tech/centrinfo`,target:`_blank`,rel:`noopener noreferrer`,children:`Centrinfo`})]}),K&&l(`div`,{class:`cf-confirm`,onClick:()=>q(!1),children:u(`div`,{class:`cf-confirm__card`,role:`alertdialog`,"aria-modal":`true`,"aria-label":a.endChatConfirm,onClick:e=>e.stopPropagation(),children:[l(`div`,{class:`cf-confirm__title`,children:a.endChatConfirm}),l(`div`,{class:`cf-confirm__body`,children:a.endChatConfirmBody}),u(`div`,{class:`cf-confirm__actions`,children:[l(`button`,{ref:xe,type:`button`,class:`cf-confirm__btn cf-confirm__btn--cancel`,onClick:()=>q(!1),children:a.cancel}),l(`button`,{type:`button`,class:`cf-confirm__btn cf-confirm__btn--danger`,onClick:ke,children:a.endConfirmCta})]})]})}),Se&&l(`div`,{class:`cf-confirm`,onClick:()=>Ce(!1),children:u(`div`,{class:`cf-history`,role:`dialog`,"aria-modal":`true`,"aria-label":a.pastConversations,onClick:e=>e.stopPropagation(),children:[u(`div`,{class:`cf-history__head`,children:[l(`span`,{children:a.pastConversations}),l(`button`,{type:`button`,class:`cf-header__btn`,"aria-label":a.closeChat,onClick:()=>Ce(!1),children:l(ie,{})})]}),l(`div`,{class:`cf-history__list`,children:N.map(e=>u(`button`,{type:`button`,class:`cf-history__item ${e.sessionId===ee?`is-active`:``}`,onClick:()=>{P(e.sessionId),Ce(!1)},children:[l(`span`,{class:`cf-history__title`,children:e.title}),u(`span`,{class:`cf-history__meta`,children:[new Date(e.ts).toLocaleDateString(void 0,{month:`short`,day:`numeric`}),e.ended?` ยท ${a.historyEnded}`:``]})]},e.sessionId))})]})})]}),!t.hideDefaultLauncher&&u(`button`,{ref:ue,type:`button`,class:`cf-launcher`,"aria-label":L?a.closeChat:a.openChat,"aria-expanded":L,onClick:X,children:[t.launcherIcon?l(`img`,{class:`cf-launcher__img`,src:t.launcherIcon,alt:``}):l(re,{}),!L&&z>0&&l(`span`,{class:`cf-launcher__badge`,children:z})]})]})})},ct=e=>{if(!e||typeof e.token!=`string`||e.token.length===0)throw Error("[centrinfo-widget] `token` is required โ€” pass your pub_* token to Centrinfo.init({ token }).");return{token:e.token,apiBaseUrl:(e.apiBaseUrl??`https://api.accurixtech.com`).replace(/\/$/,``),accentColor:e.accentColor,launcherIcon:e.launcherIcon,gifApiKey:e.gifApiKey,theme:e.theme??`auto`,openByDefault:e.openByDefault??!1,sound:e.sound??!0,starters:e.starters??[],strings:ee(e.labels),persistence:e.persistence??`local`,attachments:e.attachments??!0,zIndex:e.zIndex??2147483e3,demo:e.demo??!1,preview:e.preview??!1,alignment:e.alignment===`left`?`left`:`right`,horizontalPadding:typeof e.horizontalPadding==`number`?e.horizontalPadding:20,verticalPadding:typeof e.verticalPadding==`number`?e.verticalPadding:20,hideDefaultLauncher:e.hideDefaultLauncher??!1,customLauncherSelector:e.customLauncherSelector,sessionDurationMinutes:typeof e.sessionDurationMinutes==`number`?e.sessionDurationMinutes:0,proactiveMessage:e.proactiveMessage,proactiveDelaySeconds:typeof e.proactiveDelaySeconds==`number`?e.proactiveDelaySeconds:5,proactiveOnPaths:e.proactiveOnPaths,csat:e.csat??!0,user:e.user,onOpen:e.onOpen,onClose:e.onClose,onShow:e.onShow,onHide:e.onHide,onUnreadChange:e.onUnreadChange,onMessage:e.onMessage,onAction:e.onAction,onHandoff:e.onHandoff}},lt=`
9
+ :host {
10
+ all: initial;
11
+ }
12
+ .cf-root {
13
+ --cf-accent: #2f7f55;
14
+ --cf-accent-2: #2f7de8;
15
+ --cf-accent-ink: #ffffff;
16
+ --cf-bg: #ffffff;
17
+ --cf-surface: #f4f6f8;
18
+ --cf-surface-2: #eef1f4;
19
+ --cf-text: #0f1e2a;
20
+ --cf-muted: #5b7186;
21
+ --cf-border: #e4e9ee;
22
+ --cf-shadow: 0 12px 48px -12px rgba(15, 30, 42, 0.4), 0 4px 12px -4px rgba(15, 30, 42, 0.2);
23
+ --cf-radius: 18px;
24
+ --cf-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
25
+
26
+ position: fixed;
27
+ bottom: 0;
28
+ right: 0;
29
+ font-family: var(--cf-font);
30
+ font-size: 15px;
31
+ line-height: 1.5;
32
+ color: var(--cf-text);
33
+ -webkit-font-smoothing: antialiased;
34
+ }
35
+ .cf-root[data-theme='dark'] {
36
+ --cf-accent-ink: #ffffff;
37
+ --cf-bg: #0f1c27;
38
+ --cf-surface: #1a2a37;
39
+ --cf-surface-2: #213442;
40
+ --cf-text: #eef3f7;
41
+ --cf-muted: #93a7b6;
42
+ --cf-border: #2a3d4c;
43
+ --cf-shadow: 0 12px 48px -12px rgba(0, 0, 0, 0.6), 0 4px 12px -4px rgba(0, 0, 0, 0.4);
44
+ }
45
+ .cf-root *,
46
+ .cf-root *::before,
47
+ .cf-root *::after {
48
+ box-sizing: border-box;
49
+ }
50
+ /* :where() keeps this reset at ZERO added specificity, so component button
51
+ styles (.cf-launcher, .cf-send, .cf-chip, .cf-action) win over it. Without
52
+ it, ".cf-root button" (class+element) out-specifies ".cf-launcher" (class)
53
+ and silently wipes every button background โ€” the launcher rendered white. */
54
+ .cf-root :where(button) {
55
+ font-family: inherit;
56
+ cursor: pointer;
57
+ border: none;
58
+ background: none;
59
+ padding: 0;
60
+ color: inherit;
61
+ }
62
+
63
+ /* ---------- Launcher ---------- */
64
+ .cf-launcher {
65
+ position: fixed;
66
+ bottom: var(--cf-v-pad, 20px);
67
+ right: var(--cf-h-pad, 20px);
68
+ z-index: 1;
69
+ /* The host element is pointer-events: none so it can't swallow
70
+ clicks on host-page UI behind it (see mount.tsx). Re-enable here
71
+ on the only two visible surfaces (launcher + panel) so they DO
72
+ receive clicks where they're actually drawn. */
73
+ pointer-events: auto;
74
+ width: 60px;
75
+ height: 60px;
76
+ border-radius: 50%;
77
+ background: linear-gradient(135deg, var(--cf-accent, #2f7f55) 0%, var(--cf-accent-2, #2f7de8) 140%);
78
+ color: var(--cf-accent-ink);
79
+ display: grid;
80
+ place-items: center;
81
+ box-shadow: 0 8px 24px -6px rgba(15, 30, 42, 0.45);
82
+ transition: transform 0.22s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.2s ease;
83
+ animation: cf-pop 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) both;
84
+ }
85
+ .cf-launcher:hover {
86
+ transform: scale(1.06);
87
+ box-shadow: 0 12px 28px -6px rgba(15, 30, 42, 0.5);
88
+ }
89
+ .cf-launcher:active {
90
+ transform: scale(0.95);
91
+ }
92
+ .cf-launcher:focus-visible {
93
+ outline: 3px solid var(--cf-accent-2);
94
+ outline-offset: 3px;
95
+ }
96
+ .cf-launcher svg {
97
+ width: 30px;
98
+ height: 30px;
99
+ transition: transform 0.25s ease, opacity 0.2s ease;
100
+ }
101
+ /* Custom org logo in the launcher (config.launcherIcon). */
102
+ .cf-launcher__img {
103
+ width: 34px;
104
+ height: 34px;
105
+ border-radius: 50%;
106
+ object-fit: cover;
107
+ }
108
+ .cf-launcher__badge {
109
+ position: absolute;
110
+ top: -2px;
111
+ right: -2px;
112
+ min-width: 20px;
113
+ height: 20px;
114
+ padding: 0 5px;
115
+ border-radius: 10px;
116
+ background: #f25767;
117
+ color: #fff;
118
+ font-size: 11px;
119
+ font-weight: 700;
120
+ display: grid;
121
+ place-items: center;
122
+ box-shadow: 0 0 0 2px var(--cf-bg);
123
+ animation: cf-badge-pop 0.3s ease both;
124
+ }
125
+
126
+ /* ---------- Panel ---------- */
127
+ .cf-panel {
128
+ position: fixed;
129
+ /* Pair to .cf-launcher's pointer-events: auto โ€” the host element
130
+ itself is pointer-events: none, so each visible surface re-enables. */
131
+ pointer-events: auto;
132
+ bottom: var(--cf-v-pad, 20px);
133
+ right: var(--cf-h-pad, 20px);
134
+ /* Above the launcher so the open chat covers it (no second button showing). */
135
+ z-index: 2;
136
+ width: 384px;
137
+ max-width: calc(100vw - 32px);
138
+ height: 640px;
139
+ max-height: calc(100vh - 40px);
140
+ background: var(--cf-bg);
141
+ border-radius: var(--cf-radius);
142
+ box-shadow: var(--cf-shadow);
143
+ display: flex;
144
+ flex-direction: column;
145
+ overflow: hidden;
146
+ transform-origin: bottom right;
147
+ opacity: 0;
148
+ transform: translateY(16px) scale(0.96);
149
+ pointer-events: none;
150
+ transition: opacity 0.24s ease, transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
151
+ }
152
+ .cf-panel.is-open {
153
+ opacity: 1;
154
+ transform: translateY(0) scale(1);
155
+ pointer-events: auto;
156
+ }
157
+
158
+ /* Left-aligned messenger (alignment: 'left') โ€” dock to the left edge. */
159
+ .cf-root[data-align='left'] .cf-launcher { right: auto; left: var(--cf-h-pad, 20px); }
160
+ .cf-root[data-align='left'] .cf-panel { right: auto; left: var(--cf-h-pad, 20px); transform-origin: bottom left; }
161
+
162
+ /* ---------- Header ---------- */
163
+ .cf-header {
164
+ position: relative;
165
+ padding: 16px 14px 18px 18px;
166
+ background: linear-gradient(135deg, var(--cf-accent, #2f7f55) 0%, var(--cf-accent-2, #2f7de8) 150%);
167
+ color: var(--cf-accent-ink);
168
+ display: flex;
169
+ align-items: center;
170
+ gap: 10px;
171
+ flex-shrink: 0;
172
+ }
173
+ .cf-header__avatar {
174
+ width: 42px;
175
+ height: 42px;
176
+ border-radius: 50%;
177
+ background: rgba(255, 255, 255, 0.18);
178
+ display: grid;
179
+ place-items: center;
180
+ font-weight: 700;
181
+ font-size: 17px;
182
+ overflow: hidden;
183
+ flex-shrink: 0;
184
+ box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.25);
185
+ }
186
+ .cf-header__avatar img {
187
+ width: 100%;
188
+ height: 100%;
189
+ object-fit: cover;
190
+ }
191
+ .cf-header__meta {
192
+ min-width: 0;
193
+ flex: 1 1 auto;
194
+ }
195
+ .cf-header__name {
196
+ font-weight: 700;
197
+ font-size: 16px;
198
+ letter-spacing: -0.2px;
199
+ white-space: nowrap;
200
+ overflow: hidden;
201
+ text-overflow: ellipsis;
202
+ }
203
+ .cf-header__status {
204
+ display: flex;
205
+ align-items: center;
206
+ gap: 6px;
207
+ font-size: 12.5px;
208
+ opacity: 0.9;
209
+ margin-top: 1px;
210
+ min-width: 0;
211
+ }
212
+ .cf-header__status::before {
213
+ content: '';
214
+ width: 7px;
215
+ height: 7px;
216
+ border-radius: 50%;
217
+ background: #7ee2a8;
218
+ box-shadow: 0 0 0 2px rgba(126, 226, 168, 0.3);
219
+ flex-shrink: 0;
220
+ }
221
+ /* Keep the status on one line โ€” the icons no longer squeeze it to wrap. */
222
+ .cf-header__status-text {
223
+ white-space: nowrap;
224
+ overflow: hidden;
225
+ text-overflow: ellipsis;
226
+ }
227
+ /* Action icons cluster tightly together, separated from the meta by the
228
+ header gap, and never shrink (so the meta yields space first). */
229
+ .cf-header__actions {
230
+ display: flex;
231
+ align-items: center;
232
+ gap: 2px;
233
+ flex-shrink: 0;
234
+ }
235
+ .cf-header__btn {
236
+ width: 30px;
237
+ height: 30px;
238
+ border-radius: 8px;
239
+ display: grid;
240
+ place-items: center;
241
+ color: var(--cf-accent-ink);
242
+ opacity: 0.85;
243
+ transition: background 0.15s ease, opacity 0.15s ease;
244
+ flex-shrink: 0;
245
+ }
246
+ .cf-header__btn:hover {
247
+ background: rgba(255, 255, 255, 0.16);
248
+ opacity: 1;
249
+ }
250
+ .cf-header__btn svg {
251
+ width: 17px;
252
+ height: 17px;
253
+ }
254
+ .cf-header__btn:focus-visible {
255
+ outline: 2px solid #fff;
256
+ outline-offset: 1px;
257
+ }
258
+
259
+ /* Preview-mode banner (data-preview) โ€” sample replies, no AI. */
260
+ .cf-preview-banner {
261
+ flex-shrink: 0;
262
+ padding: 5px 12px;
263
+ text-align: center;
264
+ font-size: 11.5px;
265
+ font-weight: 600;
266
+ letter-spacing: 0.2px;
267
+ color: #7a5b00;
268
+ background: #fff3cd;
269
+ border-bottom: 1px solid #ffe69c;
270
+ }
271
+ .cf-root[data-theme='dark'] .cf-preview-banner {
272
+ color: #ffe08a;
273
+ background: #3a3320;
274
+ border-bottom-color: #4d4427;
275
+ }
276
+
277
+ /* ---------- Body / messages ---------- */
278
+ .cf-body {
279
+ flex: 1;
280
+ overflow-y: auto;
281
+ /* Never scroll/shift horizontally โ€” a long source pill or code line is
282
+ clipped, not allowed to push the whole thread sideways. */
283
+ overflow-x: hidden;
284
+ padding: 18px 16px 8px;
285
+ display: flex;
286
+ flex-direction: column;
287
+ gap: 12px;
288
+ scroll-behavior: smooth;
289
+ background: var(--cf-bg);
290
+ }
291
+ .cf-body::-webkit-scrollbar {
292
+ width: 8px;
293
+ }
294
+ .cf-body::-webkit-scrollbar-thumb {
295
+ background: var(--cf-border);
296
+ border-radius: 4px;
297
+ }
298
+ .cf-msg {
299
+ display: flex;
300
+ gap: 8px;
301
+ max-width: 100%;
302
+ animation: cf-msg-in 0.32s cubic-bezier(0.22, 1, 0.36, 1) both;
303
+ }
304
+ .cf-msg--user {
305
+ justify-content: flex-end;
306
+ }
307
+ .cf-msg__avatar {
308
+ width: 26px;
309
+ height: 26px;
310
+ border-radius: 50%;
311
+ background: linear-gradient(135deg, var(--cf-accent, #2f7f55), var(--cf-accent-2, #2f7de8));
312
+ color: #fff;
313
+ display: grid;
314
+ place-items: center;
315
+ font-size: 11px;
316
+ font-weight: 700;
317
+ flex-shrink: 0;
318
+ overflow: hidden;
319
+ align-self: flex-end;
320
+ }
321
+ .cf-msg__avatar img { width: 100%; height: 100%; object-fit: cover; }
322
+ .cf-msg__bubble {
323
+ padding: 10px 13px;
324
+ border-radius: 16px;
325
+ max-width: 100%;
326
+ /* break-word (not anywhere) only breaks words too long to fit โ€” so short
327
+ words like "Hello" never split mid-word. */
328
+ overflow-wrap: break-word;
329
+ white-space: pre-wrap;
330
+ font-size: 14.5px;
331
+ }
332
+ .cf-msg--agent .cf-msg__bubble {
333
+ background: var(--cf-surface);
334
+ border-bottom-left-radius: 5px;
335
+ color: var(--cf-text);
336
+ }
337
+ .cf-msg--user .cf-msg__bubble {
338
+ background: linear-gradient(135deg, var(--cf-accent, #2f7f55) 0%, var(--cf-accent-2, #2f7de8) 160%);
339
+ color: var(--cf-accent-ink);
340
+ border-bottom-right-radius: 5px;
341
+ }
342
+ .cf-msg__bubble a {
343
+ color: inherit;
344
+ text-decoration: underline;
345
+ }
346
+ .cf-msg__bubble strong { font-weight: 700; }
347
+ .cf-msg__bubble p { margin: 0 0 8px; }
348
+ .cf-msg__bubble p:last-child { margin-bottom: 0; }
349
+ .cf-msg__col { min-width: 0; max-width: 85%; display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
350
+ .cf-msg--user .cf-msg__col { align-items: flex-end; }
351
+
352
+ /* ---------- Markdown in answers ---------- */
353
+ .cf-msg__bubble .cf-md-h { font-weight: 700; font-size: 14.5px; margin: 4px 0 2px; }
354
+ .cf-msg__bubble ul.cf-md-list, .cf-msg__bubble ol.cf-md-list { margin: 4px 0; padding-left: 20px; }
355
+ .cf-msg__bubble .cf-md-list li { margin: 2px 0; }
356
+ .cf-md-code {
357
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
358
+ font-size: 0.86em;
359
+ background: var(--cf-surface-2);
360
+ padding: 1px 5px;
361
+ border-radius: 5px;
362
+ }
363
+ .cf-msg--user .cf-md-code { background: rgba(255, 255, 255, 0.22); }
364
+ .cf-md-pre {
365
+ margin: 6px 0;
366
+ padding: 10px 12px;
367
+ background: var(--cf-surface-2);
368
+ border: 1px solid var(--cf-border);
369
+ border-radius: 10px;
370
+ overflow-x: auto;
371
+ }
372
+ .cf-md-pre code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; white-space: pre; color: var(--cf-text); }
373
+ .cf-msg--user .cf-md-pre { background: rgba(0, 0, 0, 0.18); border-color: rgba(255, 255, 255, 0.18); }
374
+ .cf-msg--user .cf-md-pre code { color: var(--cf-accent-ink); }
375
+
376
+ /* streaming caret */
377
+ .cf-caret {
378
+ display: inline-block;
379
+ width: 7px;
380
+ height: 1em;
381
+ margin-left: 2px;
382
+ vertical-align: text-bottom;
383
+ background: var(--cf-accent);
384
+ border-radius: 1px;
385
+ animation: cf-blink 1s step-end infinite;
386
+ }
387
+ @keyframes cf-blink {
388
+ 0%, 100% { opacity: 1; }
389
+ 50% { opacity: 0; }
390
+ }
391
+
392
+ /* message tools (copy / retry) */
393
+ .cf-msg__tools { display: flex; gap: 6px; }
394
+ .cf-tool {
395
+ display: inline-flex;
396
+ align-items: center;
397
+ gap: 5px;
398
+ font-size: 12px;
399
+ color: var(--cf-muted);
400
+ padding: 3px 7px;
401
+ border-radius: 7px;
402
+ opacity: 0.6;
403
+ transition: opacity 0.15s ease, background 0.15s ease, color 0.15s ease;
404
+ }
405
+ .cf-msg:hover .cf-tool { opacity: 1; }
406
+ .cf-tool:hover { background: var(--cf-surface); color: var(--cf-text); }
407
+ .cf-tool svg { width: 13px; height: 13px; }
408
+
409
+ /* Per-message ๐Ÿ‘/๐Ÿ‘Ž feedback. */
410
+ .cf-feedback { margin-top: 4px; }
411
+ .cf-feedback__row { display: flex; align-items: center; gap: 4px; }
412
+ .cf-feedback__btn {
413
+ display: inline-flex;
414
+ align-items: center;
415
+ justify-content: center;
416
+ width: 26px;
417
+ height: 26px;
418
+ border-radius: 7px;
419
+ color: var(--cf-muted);
420
+ opacity: 0.6;
421
+ cursor: pointer;
422
+ transition: opacity 0.15s ease, background 0.15s ease, color 0.15s ease;
423
+ }
424
+ .cf-msg:hover .cf-feedback__btn { opacity: 1; }
425
+ .cf-feedback__btn:hover { background: var(--cf-surface); color: var(--cf-text); }
426
+ .cf-feedback__btn.is-active { opacity: 1; color: var(--cf-accent); background: var(--cf-surface); }
427
+ .cf-feedback__btn svg { width: 14px; height: 14px; }
428
+ .cf-feedback__thanks { margin-left: 4px; font-size: 11.5px; color: var(--cf-muted); }
429
+ .cf-feedback__comment { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; max-width: 260px; }
430
+ .cf-feedback__input {
431
+ width: 100%;
432
+ resize: none;
433
+ font: inherit;
434
+ font-size: 12.5px;
435
+ line-height: 1.4;
436
+ color: var(--cf-text);
437
+ background: var(--cf-bg);
438
+ border: 1px solid var(--cf-border);
439
+ border-radius: 9px;
440
+ padding: 7px 9px;
441
+ box-sizing: border-box;
442
+ }
443
+ .cf-feedback__input:focus { outline: none; border-color: var(--cf-accent); }
444
+ .cf-feedback__send {
445
+ align-self: flex-end;
446
+ font-size: 12px;
447
+ font-weight: 600;
448
+ color: var(--cf-accent-ink);
449
+ background: var(--cf-accent);
450
+ border: none;
451
+ border-radius: 999px;
452
+ padding: 5px 14px;
453
+ cursor: pointer;
454
+ transition: opacity 0.15s ease;
455
+ }
456
+ .cf-feedback__send:hover { opacity: 0.9; }
457
+
458
+ /* conversation starters */
459
+ .cf-starters { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; margin: 2px 0 4px 34px; }
460
+ .cf-starter {
461
+ padding: 9px 13px;
462
+ border-radius: 14px;
463
+ border: 1px solid var(--cf-border);
464
+ background: var(--cf-bg);
465
+ color: var(--cf-text);
466
+ font-size: 13.5px;
467
+ font-weight: 500;
468
+ text-align: left;
469
+ transition: border-color 0.15s ease, transform 0.1s ease;
470
+ }
471
+ .cf-starter:hover { border-color: var(--cf-accent); }
472
+ .cf-starter:active { transform: scale(0.98); }
473
+
474
+ /* stop generating */
475
+ .cf-stopbar { display: flex; justify-content: center; padding: 6px 0 2px; flex-shrink: 0; }
476
+ .cf-stop {
477
+ display: inline-flex;
478
+ align-items: center;
479
+ gap: 6px;
480
+ font-size: 12.5px;
481
+ font-weight: 600;
482
+ color: var(--cf-muted);
483
+ background: var(--cf-bg);
484
+ border: 1px solid var(--cf-border);
485
+ border-radius: 999px;
486
+ padding: 6px 14px;
487
+ box-shadow: var(--cf-shadow);
488
+ transition: border-color 0.15s ease, color 0.15s ease;
489
+ }
490
+ .cf-stop:hover { border-color: var(--cf-accent); color: var(--cf-text); }
491
+ .cf-stop svg { width: 13px; height: 13px; }
492
+
493
+ /* typing */
494
+ .cf-typing {
495
+ display: inline-flex;
496
+ gap: 4px;
497
+ padding: 13px 14px;
498
+ }
499
+ .cf-typing__dot {
500
+ width: 7px;
501
+ height: 7px;
502
+ border-radius: 50%;
503
+ background: var(--cf-muted);
504
+ animation: cf-typing 1.1s infinite ease-in-out;
505
+ }
506
+ .cf-typing__dot:nth-child(2) { animation-delay: 0.15s; }
507
+ .cf-typing__dot:nth-child(3) { animation-delay: 0.3s; }
508
+
509
+ /* sources */
510
+ .cf-sources {
511
+ display: flex;
512
+ flex-wrap: wrap;
513
+ gap: 6px;
514
+ /* Tie the row to the message column so a long title can't widen the thread. */
515
+ max-width: 100%;
516
+ min-width: 0;
517
+ }
518
+ .cf-source {
519
+ display: inline-flex;
520
+ align-items: center;
521
+ gap: 5px;
522
+ padding: 5px 10px;
523
+ border-radius: 999px;
524
+ background: var(--cf-surface-2);
525
+ border: 1px solid var(--cf-border);
526
+ color: var(--cf-muted);
527
+ font-size: 12px;
528
+ text-decoration: none;
529
+ max-width: 100%;
530
+ min-width: 0;
531
+ transition: border-color 0.15s ease, color 0.15s ease;
532
+ }
533
+ .cf-source:hover { color: var(--cf-text); border-color: var(--cf-accent); }
534
+ .cf-source--more { color: var(--cf-muted); cursor: default; }
535
+ .cf-source--more:hover { border-color: var(--cf-border); color: var(--cf-muted); }
536
+ .cf-source svg { width: 12px; height: 12px; flex-shrink: 0; }
537
+ .cf-source span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
538
+
539
+ /* chips + actions */
540
+ .cf-chips, .cf-actions {
541
+ display: flex;
542
+ flex-wrap: wrap;
543
+ gap: 8px;
544
+ }
545
+ .cf-chip {
546
+ padding: 8px 13px;
547
+ border-radius: 999px;
548
+ background: var(--cf-bg);
549
+ border: 1.5px solid var(--cf-accent);
550
+ color: var(--cf-accent);
551
+ font-size: 13px;
552
+ font-weight: 600;
553
+ transition: background 0.15s ease, color 0.15s ease, transform 0.1s ease;
554
+ }
555
+ .cf-root[data-theme='dark'] .cf-chip { color: var(--cf-text); border-color: var(--cf-border); }
556
+ .cf-chip:hover { background: var(--cf-accent); color: var(--cf-accent-ink); }
557
+ .cf-chip:active { transform: scale(0.97); }
558
+ .cf-chip:focus-visible { outline: 2px solid var(--cf-accent-2); outline-offset: 2px; }
559
+ .cf-action {
560
+ display: inline-flex;
561
+ align-items: center;
562
+ gap: 7px;
563
+ padding: 9px 14px;
564
+ border-radius: 12px;
565
+ background: var(--cf-surface);
566
+ border: 1px solid var(--cf-border);
567
+ color: var(--cf-text);
568
+ font-size: 13.5px;
569
+ font-weight: 600;
570
+ transition: border-color 0.15s ease, transform 0.1s ease;
571
+ }
572
+ .cf-action:hover { border-color: var(--cf-accent); }
573
+ .cf-action:active { transform: scale(0.98); }
574
+ .cf-action svg { width: 15px; height: 15px; color: var(--cf-accent); }
575
+
576
+ /* ---------- Inline forms + handoff card ---------- */
577
+ .cf-form {
578
+ display: flex;
579
+ flex-direction: column;
580
+ gap: 8px;
581
+ width: 100%;
582
+ max-width: 300px;
583
+ padding: 12px;
584
+ border-radius: 14px;
585
+ border: 1px solid var(--cf-border);
586
+ background: var(--cf-surface);
587
+ animation: cf-msg-in 0.2s ease both;
588
+ }
589
+ .cf-form__title { font-size: 13.5px; font-weight: 700; color: var(--cf-fg, var(--cf-text)); }
590
+ .cf-form__as { font-size: 12.5px; color: var(--cf-muted); margin-top: -2px; }
591
+ .cf-form__input {
592
+ width: 100%;
593
+ padding: 9px 11px;
594
+ border: 1.5px solid var(--cf-border);
595
+ border-radius: 10px;
596
+ background: var(--cf-bg);
597
+ color: var(--cf-text);
598
+ font-family: inherit;
599
+ font-size: 14px;
600
+ outline: none;
601
+ resize: none;
602
+ }
603
+ .cf-form__input:focus { border-color: var(--cf-accent); }
604
+ .cf-form__input::placeholder { color: var(--cf-muted); }
605
+ .cf-form__actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 2px; }
606
+ .cf-form__submit {
607
+ padding: 8px 14px;
608
+ border-radius: 10px;
609
+ font-size: 13.5px;
610
+ font-weight: 600;
611
+ background: linear-gradient(135deg, var(--cf-accent, #2f7f55) 0%, var(--cf-accent-2, #2f7de8) 160%);
612
+ color: var(--cf-accent-ink);
613
+ transition: opacity 0.15s ease, transform 0.1s ease;
614
+ }
615
+ .cf-form__submit:disabled { opacity: 0.45; cursor: default; }
616
+ .cf-form__submit:not(:disabled):active { transform: scale(0.97); }
617
+ .cf-form__cancel { padding: 8px 12px; border-radius: 10px; font-size: 13.5px; font-weight: 600; color: var(--cf-muted); }
618
+ .cf-form__cancel:hover { color: var(--cf-text); }
619
+ .cf-form__err { font-size: 12.5px; color: #f25767; }
620
+ .cf-form--done {
621
+ flex-direction: row;
622
+ align-items: center;
623
+ gap: 8px;
624
+ font-size: 13.5px;
625
+ color: var(--cf-text);
626
+ }
627
+ .cf-form--done svg { width: 18px; height: 18px; color: var(--cf-accent); flex-shrink: 0; }
628
+ .cf-form--done { flex-wrap: wrap; }
629
+ .cf-booking__link {
630
+ display: inline-flex;
631
+ align-items: center;
632
+ gap: 4px;
633
+ font-size: 13px;
634
+ font-weight: 600;
635
+ color: var(--cf-accent);
636
+ text-decoration: none;
637
+ flex-basis: 100%;
638
+ }
639
+ .cf-booking__link svg { width: 13px; height: 13px; }
640
+ .cf-booking__link:hover { text-decoration: underline; }
641
+
642
+ .cf-handoff {
643
+ display: flex;
644
+ flex-direction: column;
645
+ gap: 8px;
646
+ width: 100%;
647
+ max-width: 300px;
648
+ padding: 12px;
649
+ border-radius: 14px;
650
+ border: 1.5px solid var(--cf-accent);
651
+ background: color-mix(in oklab, var(--cf-accent) 8%, var(--cf-bg));
652
+ animation: cf-msg-in 0.2s ease both;
653
+ }
654
+ .cf-handoff__title { font-size: 13.5px; font-weight: 700; color: var(--cf-text); }
655
+
656
+ /* ---------- Demo booking picker ---------- */
657
+ .cf-booking { max-width: 320px; }
658
+ .cf-booking__hint { font-size: 12.5px; color: var(--cf-muted); margin-top: -2px; }
659
+ .cf-booking__dur { font-weight: 600; color: var(--cf-text); }
660
+ .cf-booking__dates {
661
+ display: flex;
662
+ gap: 6px;
663
+ overflow-x: auto;
664
+ padding-bottom: 4px;
665
+ scrollbar-width: thin;
666
+ }
667
+ .cf-booking__dates::-webkit-scrollbar { height: 5px; }
668
+ .cf-booking__dates::-webkit-scrollbar-thumb { background: var(--cf-border); border-radius: 3px; }
669
+ .cf-booking__date {
670
+ flex-shrink: 0;
671
+ display: flex;
672
+ flex-direction: column;
673
+ align-items: center;
674
+ gap: 1px;
675
+ width: 46px;
676
+ padding: 7px 0;
677
+ border-radius: 10px;
678
+ border: 1px solid var(--cf-border);
679
+ background: var(--cf-bg);
680
+ color: var(--cf-text);
681
+ transition: border-color 0.15s ease, background 0.15s ease, transform 0.1s ease;
682
+ }
683
+ .cf-booking__date:hover { border-color: var(--cf-accent); }
684
+ .cf-booking__date:active { transform: scale(0.96); }
685
+ .cf-booking__date.is-selected {
686
+ border-color: var(--cf-accent);
687
+ background: color-mix(in oklab, var(--cf-accent) 14%, var(--cf-bg));
688
+ color: var(--cf-accent);
689
+ }
690
+ .cf-root[data-theme='dark'] .cf-booking__date.is-selected { color: var(--cf-text); }
691
+ .cf-booking__dow { font-size: 10px; text-transform: uppercase; letter-spacing: 0.4px; color: var(--cf-muted); }
692
+ .cf-booking__date.is-selected .cf-booking__dow { color: inherit; }
693
+ .cf-booking__dom { font-size: 15px; font-weight: 700; line-height: 1.1; }
694
+ .cf-booking__slots {
695
+ display: grid;
696
+ grid-template-columns: repeat(3, 1fr);
697
+ gap: 6px;
698
+ max-height: 156px;
699
+ overflow-y: auto;
700
+ padding: 2px;
701
+ }
702
+ .cf-booking__slots::-webkit-scrollbar { width: 6px; }
703
+ .cf-booking__slots::-webkit-scrollbar-thumb { background: var(--cf-border); border-radius: 3px; }
704
+ .cf-booking__slot {
705
+ padding: 8px 0;
706
+ border-radius: 9px;
707
+ border: 1px solid var(--cf-border);
708
+ background: var(--cf-bg);
709
+ color: var(--cf-accent);
710
+ font-size: 13px;
711
+ font-weight: 600;
712
+ transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease, transform 0.1s ease;
713
+ }
714
+ .cf-root[data-theme='dark'] .cf-booking__slot { color: var(--cf-text); }
715
+ .cf-booking__slot:hover { border-color: var(--cf-accent); }
716
+ .cf-booking__slot:active { transform: scale(0.96); }
717
+ .cf-booking__slot.is-selected {
718
+ background: linear-gradient(135deg, var(--cf-accent, #2f7f55) 0%, var(--cf-accent-2, #2f7de8) 160%);
719
+ color: var(--cf-accent-ink);
720
+ border-color: var(--cf-accent);
721
+ }
722
+ .cf-booking__slot.is-taken,
723
+ .cf-booking__slot:disabled {
724
+ color: var(--cf-muted);
725
+ background: var(--cf-surface);
726
+ border-color: var(--cf-border);
727
+ text-decoration: line-through;
728
+ cursor: not-allowed;
729
+ opacity: 0.55;
730
+ }
731
+ .cf-booking__slot.is-taken:hover { border-color: var(--cf-border); }
732
+ .cf-handoff--done {
733
+ flex-direction: row;
734
+ align-items: center;
735
+ border-color: var(--cf-border);
736
+ background: var(--cf-surface);
737
+ font-size: 13.5px;
738
+ }
739
+ .cf-handoff--done svg { width: 18px; height: 18px; color: var(--cf-accent); flex-shrink: 0; }
740
+
741
+ /* note (action confirmation) */
742
+ .cf-note {
743
+ align-self: center;
744
+ font-size: 12.5px;
745
+ color: var(--cf-muted);
746
+ background: var(--cf-surface);
747
+ padding: 7px 12px;
748
+ border-radius: 999px;
749
+ animation: cf-msg-in 0.3s ease both;
750
+ }
751
+
752
+ /* ---------- Composer ---------- */
753
+ .cf-composer {
754
+ flex-shrink: 0;
755
+ padding: 10px 12px;
756
+ border-top: 1px solid var(--cf-border);
757
+ background: var(--cf-bg);
758
+ }
759
+ .cf-composer__field {
760
+ display: flex;
761
+ align-items: flex-end;
762
+ gap: 6px;
763
+ background: var(--cf-surface);
764
+ border: 1.5px solid var(--cf-border);
765
+ border-radius: 14px;
766
+ padding: 6px 6px 6px 12px;
767
+ transition: border-color 0.15s ease;
768
+ }
769
+ .cf-composer__field:focus-within { border-color: var(--cf-accent); }
770
+ .cf-textarea {
771
+ flex: 1;
772
+ border: none;
773
+ background: none;
774
+ resize: none;
775
+ outline: none;
776
+ font-family: inherit;
777
+ font-size: 14.5px;
778
+ color: var(--cf-text);
779
+ max-height: 110px;
780
+ line-height: 1.45;
781
+ padding: 6px 0;
782
+ }
783
+ .cf-textarea::placeholder { color: var(--cf-muted); }
784
+ .cf-iconbtn {
785
+ width: 36px;
786
+ height: 36px;
787
+ border-radius: 10px;
788
+ display: grid;
789
+ place-items: center;
790
+ flex-shrink: 0;
791
+ color: var(--cf-muted);
792
+ transition: background 0.15s ease, color 0.15s ease;
793
+ }
794
+ .cf-iconbtn:hover { background: var(--cf-surface-2); color: var(--cf-text); }
795
+ .cf-iconbtn:focus-visible { outline: 2px solid var(--cf-accent-2); outline-offset: 1px; }
796
+ .cf-iconbtn svg { width: 19px; height: 19px; }
797
+ .cf-send {
798
+ width: 36px;
799
+ height: 36px;
800
+ border-radius: 10px;
801
+ display: grid;
802
+ place-items: center;
803
+ flex-shrink: 0;
804
+ background: linear-gradient(135deg, var(--cf-accent, #2f7f55) 0%, var(--cf-accent-2, #2f7de8) 160%);
805
+ color: var(--cf-accent-ink);
806
+ transition: opacity 0.15s ease, transform 0.1s ease;
807
+ }
808
+ .cf-send:disabled { opacity: 0.4; cursor: default; }
809
+ .cf-send:not(:disabled):hover { transform: scale(1.05); }
810
+ .cf-send:not(:disabled):active { transform: scale(0.94); }
811
+ .cf-send svg { width: 18px; height: 18px; }
812
+ .cf-mic.is-recording { color: #f25767; animation: cf-pulse 1s infinite; }
813
+
814
+ .cf-iconbtn.is-active { background: var(--cf-surface-2); color: var(--cf-accent); }
815
+ .cf-gif-label { font-size: 11px; font-weight: 800; letter-spacing: 0.5px; }
816
+
817
+ /* ---------- Emoji + GIF pickers ---------- */
818
+ .cf-composer { position: relative; }
819
+ .cf-picker {
820
+ position: absolute;
821
+ left: 8px;
822
+ right: 8px;
823
+ bottom: calc(100% - 4px);
824
+ background: var(--cf-bg);
825
+ border: 1px solid var(--cf-border);
826
+ border-radius: 14px;
827
+ box-shadow: var(--cf-shadow);
828
+ overflow: hidden;
829
+ animation: cf-msg-in 0.18s ease both;
830
+ z-index: 2;
831
+ }
832
+ .cf-emoji { max-height: 260px; overflow-y: auto; padding: 8px 10px 10px; }
833
+ .cf-emoji__label {
834
+ font-size: 11px;
835
+ font-weight: 700;
836
+ text-transform: uppercase;
837
+ letter-spacing: 0.5px;
838
+ color: var(--cf-muted);
839
+ margin: 8px 2px 4px;
840
+ }
841
+ .cf-emoji__grid { display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px; }
842
+ .cf-emoji__btn {
843
+ font-size: 21px;
844
+ line-height: 1;
845
+ height: 34px;
846
+ border-radius: 8px;
847
+ transition: background 0.12s ease, transform 0.08s ease;
848
+ }
849
+ .cf-emoji__btn:hover { background: var(--cf-surface); }
850
+ .cf-emoji__btn:active { transform: scale(0.9); }
851
+
852
+ .cf-gif { display: flex; flex-direction: column; max-height: 320px; }
853
+ .cf-gif__search {
854
+ margin: 10px 10px 8px;
855
+ padding: 9px 12px;
856
+ border: 1.5px solid var(--cf-border);
857
+ border-radius: 10px;
858
+ background: var(--cf-surface);
859
+ color: var(--cf-text);
860
+ font-family: inherit;
861
+ font-size: 14px;
862
+ outline: none;
863
+ }
864
+ .cf-gif__search:focus { border-color: var(--cf-accent); }
865
+ .cf-gif__search::placeholder { color: var(--cf-muted); }
866
+ .cf-gif__grid {
867
+ flex: 1;
868
+ overflow-y: auto;
869
+ display: grid;
870
+ grid-template-columns: 1fr 1fr;
871
+ gap: 6px;
872
+ padding: 0 10px 8px;
873
+ align-content: start;
874
+ }
875
+ .cf-gif__item {
876
+ border-radius: 10px;
877
+ overflow: hidden;
878
+ background: var(--cf-surface);
879
+ aspect-ratio: 1 / 1;
880
+ transition: transform 0.1s ease, box-shadow 0.12s ease;
881
+ }
882
+ .cf-gif__item:hover { transform: scale(1.03); box-shadow: 0 0 0 2px var(--cf-accent); }
883
+ .cf-gif__item img { width: 100%; height: 100%; object-fit: cover; display: block; }
884
+ .cf-gif__hint { grid-column: 1 / -1; text-align: center; color: var(--cf-muted); font-size: 13px; padding: 24px 0; }
885
+ .cf-gif__powered { text-align: right; font-size: 10px; color: var(--cf-muted); padding: 0 12px 8px; }
886
+
887
+ /* Inline media (GIF) in a message bubble. */
888
+ .cf-msg__bubble--media { padding: 4px; background: var(--cf-surface); overflow: hidden; }
889
+ .cf-msg--user .cf-msg__bubble--media { background: var(--cf-surface-2); }
890
+ .cf-msg__media { display: block; max-width: 200px; width: 100%; border-radius: 12px; }
891
+ .cf-msg__caption { display: block; padding: 4px 6px 2px; font-size: 14px; }
892
+
893
+ .cf-footer {
894
+ text-align: center;
895
+ padding: 7px 0 9px;
896
+ font-size: 11px;
897
+ color: var(--cf-muted);
898
+ }
899
+ .cf-footer a { color: var(--cf-muted); text-decoration: none; font-weight: 600; }
900
+ .cf-footer a:hover { color: var(--cf-accent); }
901
+
902
+ /* ---------- Welcome intro (token branding) ---------- */
903
+ .cf-welcome { text-align: center; padding: 2px 14px 4px; }
904
+ .cf-welcome__desc { margin: 0 0 4px; font-size: 14px; font-weight: 600; color: var(--cf-text); }
905
+ .cf-welcome__sub { margin: 0; font-size: 12.5px; color: var(--cf-muted); }
906
+
907
+ /* Offline presence dot (amber instead of green). */
908
+ .cf-header__status--offline::before { background: #e2c07e; box-shadow: 0 0 0 2px rgba(226, 192, 126, 0.3); }
909
+
910
+ /* Disclaimer fine-print under the composer. */
911
+ .cf-disclaimer { padding: 0 16px 2px; font-size: 10.5px; line-height: 1.45; color: var(--cf-muted); text-align: center; }
912
+
913
+ /* Read-only banner shown while viewing a past conversation. */
914
+ .cf-viewing-banner {
915
+ padding: 7px 16px;
916
+ font-size: 12px;
917
+ font-weight: 600;
918
+ text-align: center;
919
+ color: var(--cf-muted);
920
+ background: var(--cf-surface);
921
+ border-bottom: 1px solid var(--cf-border);
922
+ flex-shrink: 0;
923
+ }
924
+
925
+ /* Past-conversations history panel (over the chat, like the confirm dialog). */
926
+ .cf-history {
927
+ width: min(340px, 90%);
928
+ max-height: 70%;
929
+ display: flex;
930
+ flex-direction: column;
931
+ background: var(--cf-bg);
932
+ border-radius: 14px;
933
+ box-shadow: var(--cf-shadow);
934
+ overflow: hidden;
935
+ }
936
+ .cf-history__head {
937
+ display: flex;
938
+ align-items: center;
939
+ justify-content: space-between;
940
+ padding: 12px 14px;
941
+ font-size: 14px;
942
+ font-weight: 700;
943
+ color: var(--cf-text);
944
+ border-bottom: 1px solid var(--cf-border);
945
+ }
946
+ .cf-history__list { overflow-y: auto; padding: 6px; }
947
+ .cf-history__item {
948
+ display: flex;
949
+ flex-direction: column;
950
+ gap: 2px;
951
+ width: 100%;
952
+ text-align: left;
953
+ padding: 9px 10px;
954
+ border-radius: 9px;
955
+ cursor: pointer;
956
+ transition: background 0.15s ease;
957
+ }
958
+ .cf-history__item:hover { background: var(--cf-surface); }
959
+ .cf-history__item.is-active { background: var(--cf-surface); }
960
+ .cf-history__title { font-size: 13px; color: var(--cf-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
961
+ .cf-history__meta { font-size: 11px; color: var(--cf-muted); }
962
+
963
+ /* Ended-conversation bar โ€” replaces the composer once the chat is closed. */
964
+ .cf-ended {
965
+ display: flex;
966
+ flex-direction: column;
967
+ align-items: center;
968
+ gap: 10px;
969
+ padding: 14px 16px 16px;
970
+ flex-shrink: 0;
971
+ text-align: center;
972
+ }
973
+ .cf-ended__text { margin: 0; font-size: 12.5px; line-height: 1.45; color: var(--cf-muted); }
974
+ .cf-csat { display: inline-flex; align-items: center; gap: 8px; }
975
+ .cf-csat__q { font-size: 12.5px; color: var(--cf-muted); }
976
+ .cf-csat__btn {
977
+ display: inline-flex;
978
+ align-items: center;
979
+ justify-content: center;
980
+ width: 30px;
981
+ height: 30px;
982
+ border-radius: 8px;
983
+ color: var(--cf-muted);
984
+ cursor: pointer;
985
+ transition: background 0.15s ease, color 0.15s ease;
986
+ }
987
+ .cf-csat__btn:hover { background: var(--cf-surface); color: var(--cf-accent); }
988
+ .cf-csat__btn svg { width: 16px; height: 16px; }
989
+ .cf-ended__btn {
990
+ font-size: 13px;
991
+ font-weight: 600;
992
+ color: var(--cf-accent-ink);
993
+ background: var(--cf-accent);
994
+ border: none;
995
+ border-radius: 999px;
996
+ padding: 9px 18px;
997
+ cursor: pointer;
998
+ transition: opacity 0.15s ease;
999
+ }
1000
+ .cf-ended__btn:hover { opacity: 0.9; }
1001
+ .cf-ended__btn:focus-visible { outline: 2px solid var(--cf-accent); outline-offset: 2px; }
1002
+
1003
+ /* "โ†“ New messages" pill โ€” shown when a reply streams in while scrolled up. */
1004
+ .cf-newmsg {
1005
+ /* Sticky inside the scroll body: pins to the bottom of the visible thread,
1006
+ just above the composer (never overlapping it). Horizontal centering via
1007
+ align-self so it doesn't fight the entrance animation's transform. */
1008
+ position: sticky;
1009
+ bottom: 10px;
1010
+ align-self: center;
1011
+ z-index: 3;
1012
+ pointer-events: auto;
1013
+ display: inline-flex;
1014
+ align-items: center;
1015
+ gap: 6px;
1016
+ font-size: 12.5px;
1017
+ font-weight: 600;
1018
+ color: var(--cf-accent-ink);
1019
+ background: linear-gradient(135deg, var(--cf-accent, #2f7f55) 0%, var(--cf-accent-2, #2f7de8) 160%);
1020
+ border-radius: 999px;
1021
+ padding: 7px 14px;
1022
+ box-shadow: var(--cf-shadow);
1023
+ animation: cf-msg-in 0.2s ease both;
1024
+ }
1025
+ .cf-newmsg svg { width: 14px; height: 14px; }
1026
+
1027
+ /* ---------- Clear-chat confirm dialog (in-widget, replaces window.confirm) ---------- */
1028
+ .cf-confirm {
1029
+ position: absolute;
1030
+ inset: 0;
1031
+ z-index: 6;
1032
+ pointer-events: auto;
1033
+ display: grid;
1034
+ place-items: center;
1035
+ padding: 22px;
1036
+ background: color-mix(in oklab, var(--cf-bg) 62%, transparent);
1037
+ backdrop-filter: blur(2px);
1038
+ animation: cf-fade-in 0.14s ease both;
1039
+ }
1040
+ .cf-confirm__card {
1041
+ width: 100%;
1042
+ max-width: 300px;
1043
+ background: var(--cf-bg);
1044
+ border: 1px solid var(--cf-border);
1045
+ border-radius: 16px;
1046
+ box-shadow: var(--cf-shadow);
1047
+ padding: 18px;
1048
+ text-align: center;
1049
+ animation: cf-msg-in 0.18s cubic-bezier(0.22, 1, 0.36, 1) both;
1050
+ }
1051
+ .cf-confirm__title { font-size: 15px; font-weight: 700; color: var(--cf-text); }
1052
+ .cf-confirm__body { margin-top: 6px; font-size: 13px; line-height: 1.45; color: var(--cf-muted); }
1053
+ .cf-confirm__actions { margin-top: 16px; display: flex; gap: 8px; justify-content: center; }
1054
+ .cf-confirm__btn {
1055
+ padding: 9px 16px;
1056
+ border-radius: 10px;
1057
+ font-size: 13.5px;
1058
+ font-weight: 600;
1059
+ transition: transform 0.1s ease, opacity 0.15s ease, border-color 0.15s ease, background 0.15s ease;
1060
+ }
1061
+ .cf-confirm__btn:active { transform: scale(0.97); }
1062
+ .cf-confirm__btn:focus-visible { outline: 2px solid var(--cf-accent-2); outline-offset: 2px; }
1063
+ .cf-confirm__btn--cancel { background: var(--cf-surface); color: var(--cf-text); border: 1px solid var(--cf-border); }
1064
+ .cf-confirm__btn--cancel:hover { border-color: var(--cf-accent); }
1065
+ .cf-confirm__btn--danger { background: #f25767; color: #fff; }
1066
+ .cf-confirm__btn--danger:hover { opacity: 0.9; }
1067
+
1068
+ /* Visually-hidden live region (announces the final answer only). */
1069
+ .cf-sr-live {
1070
+ position: absolute;
1071
+ width: 1px;
1072
+ height: 1px;
1073
+ padding: 0;
1074
+ margin: -1px;
1075
+ overflow: hidden;
1076
+ clip: rect(0 0 0 0);
1077
+ white-space: nowrap;
1078
+ border: 0;
1079
+ }
1080
+
1081
+ /* ---------- Attachments ---------- */
1082
+ .cf-file-input { display: none; }
1083
+ .cf-iconbtn:disabled { opacity: 0.4; cursor: default; }
1084
+ .cf-attach-row { padding: 0 4px 8px; }
1085
+ .cf-attach-status { font-size: 12px; color: var(--cf-muted); }
1086
+ .cf-attach-status--err { color: #f25767; }
1087
+ .cf-attach-chip {
1088
+ display: inline-flex;
1089
+ align-items: center;
1090
+ gap: 6px;
1091
+ max-width: 100%;
1092
+ padding: 5px 6px 5px 10px;
1093
+ border-radius: 999px;
1094
+ background: var(--cf-surface-2);
1095
+ border: 1px solid var(--cf-border);
1096
+ color: var(--cf-text);
1097
+ font-size: 12px;
1098
+ }
1099
+ .cf-attach-chip > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1100
+ .cf-attach-chip svg { width: 13px; height: 13px; flex-shrink: 0; color: var(--cf-muted); }
1101
+ .cf-attach-x { display: grid; place-items: center; width: 18px; height: 18px; border-radius: 50%; color: var(--cf-muted); flex-shrink: 0; }
1102
+ .cf-attach-x:hover { background: var(--cf-surface); color: var(--cf-text); }
1103
+ .cf-attach-x svg { width: 11px; height: 11px; }
1104
+
1105
+ /* ---------- Mobile: full-screen panel ---------- */
1106
+ @media (max-width: 480px) {
1107
+ .cf-panel {
1108
+ bottom: 0;
1109
+ right: 0;
1110
+ width: 100vw;
1111
+ max-width: 100vw;
1112
+ height: 100dvh;
1113
+ max-height: 100dvh;
1114
+ border-radius: 0;
1115
+ }
1116
+ .cf-launcher { bottom: 16px; right: 16px; }
1117
+ }
1118
+
1119
+ /* ---------- Keyframes ---------- */
1120
+ @keyframes cf-pop {
1121
+ from { transform: scale(0); opacity: 0; }
1122
+ to { transform: scale(1); opacity: 1; }
1123
+ }
1124
+ @keyframes cf-badge-pop {
1125
+ from { transform: scale(0); }
1126
+ to { transform: scale(1); }
1127
+ }
1128
+ @keyframes cf-msg-in {
1129
+ from { opacity: 0; transform: translateY(8px); }
1130
+ to { opacity: 1; transform: none; }
1131
+ }
1132
+ @keyframes cf-fade-in {
1133
+ from { opacity: 0; }
1134
+ to { opacity: 1; }
1135
+ }
1136
+ @keyframes cf-typing {
1137
+ 0%, 80%, 100% { opacity: 0.35; transform: translateY(0); }
1138
+ 40% { opacity: 1; transform: translateY(-4px); }
1139
+ }
1140
+ @keyframes cf-pulse {
1141
+ 0%, 100% { opacity: 1; }
1142
+ 50% { opacity: 0.4; }
1143
+ }
1144
+
1145
+ @media (prefers-reduced-motion: reduce) {
1146
+ .cf-root *, .cf-root *::before, .cf-root *::after {
1147
+ animation-duration: 0.01ms !important;
1148
+ animation-iteration-count: 1 !important;
1149
+ transition-duration: 0.01ms !important;
1150
+ scroll-behavior: auto !important;
1151
+ }
1152
+ }
1153
+ `;function ut(e){"@babel/helpers - typeof";return ut=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},ut(e)}function dt(e,t){if(ut(e)!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(ut(r)!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function ft(e){var t=dt(e,`string`);return ut(t)==`symbol`?t:t+``}function pt(e,t,n){return(t=ft(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}const mt=`centrinfo-widget`;var ht=class extends HTMLElement{constructor(...e){super(...e),pt(this,`controls`,null)}mountWith(e){let n=ct(e),r=this.shadowRoot??this.attachShadow({mode:`open`});if(`adoptedStyleSheets`in Document.prototype&&typeof CSSStyleSheet<`u`){let e=new CSSStyleSheet;e.replaceSync(lt),r.adoptedStyleSheets=[e]}else{let e=document.createElement(`style`);e.textContent=lt,r.appendChild(e)}t(l(st,{transport:n.demo?new C:n.preview?new k(new p(n.apiBaseUrl,n.token,n.gifApiKey),n.strings):new p(n.apiBaseUrl,n.token,n.gifApiKey),config:n,bindControls:e=>this.controls=e}),r)}open(){this.controls?.open()}close(){this.controls?.close()}toggle(){this.controls?.toggle()}identify(e){this.controls?.identify(e)}clear(){this.controls?.startNew()}shutdown(){this.controls?.shutdown()}unmount(){this.shadowRoot&&t(null,this.shadowRoot)}};typeof customElements<`u`&&!customElements.get(mt)&&customElements.define(mt,ht);const gt=e=>{if(typeof document>`u`)throw Error(`[centrinfo-widget] createWidget must run in a browser.`);let t=document.createElement(mt);return t.style.pointerEvents=`none`,t.style.position=`fixed`,t.style.inset=`0`,t.style.width=`0`,t.style.height=`0`,document.body.appendChild(t),t.mountWith(e),{open:()=>t.open(),close:()=>t.close(),toggle:()=>t.toggle(),show:()=>t.open(),hide:()=>t.close(),identify:e=>t.identify(e),update:e=>t.identify(e),clear:()=>t.clear(),shutdown:()=>t.shutdown(),logout:()=>t.shutdown(),destroy:()=>{t.unmount(),t.remove()}}};let _t=null;const vt=e=>(_t?.destroy(),_t=gt(e),_t),yt={init:vt,createWidget:gt};export{yt as Centrinfo,gt as createWidget,vt as init};