@yassirbenmoussa/aicommerce-sdk 1.6.0 → 1.8.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.
@@ -1,5 +1,5 @@
1
1
  var AICommerceWidget=(function(exports){'use strict';/*! AI Commerce Widget v1.0.0 | MIT License | https://aicommerce.dev */
2
- var L=class i{constructor(r){this.sessionToken=null;this.products={create:async r=>this.request("/api/v1/products",{method:"POST",body:JSON.stringify(r)}),batchUpsert:async r=>this.request("/api/v1/products",{method:"POST",body:JSON.stringify({products:r})}),list:async r=>{let e=new URLSearchParams;r?.page&&e.set("page",String(r.page)),r?.perPage&&e.set("perPage",String(r.perPage)),r?.search&&e.set("search",r.search),r?.categoryId&&e.set("categoryId",r.categoryId),r?.isActive!==void 0&&e.set("isActive",String(r.isActive));let s=e.toString();return this.request(`/api/v1/products${s?`?${s}`:""}`)},get:async r=>this.request(`/api/v1/products/${r}`),update:async(r,e)=>this.request(`/api/v1/products/${r}`,{method:"PUT",body:JSON.stringify(e)}),delete:async r=>this.request(`/api/v1/products/${r}`,{method:"DELETE"})};if(!r.apiKey)throw new Error("AICommerce: apiKey is required");this.apiKey=r.apiKey,this.storeId=r.storeId,this.baseUrl=this.normalizeUrl(r.baseUrl||this.detectBaseUrl()),this.timeout=r.timeout||3e4;}detectBaseUrl(){if(typeof window<"u"){let r=document.querySelector("script[data-aicommerce-url]");if(r)return r.getAttribute("data-aicommerce-url")||"https://api.aicommerce.dev"}return "https://api.aicommerce.dev"}normalizeUrl(r){return r.replace(/\/$/,"")}async request(r,e={}){let s=`${this.baseUrl}${r}`,h=new AbortController,a=setTimeout(()=>h.abort(),this.timeout);try{let m=await fetch(s,{...e,signal:h.signal,headers:{"Content-Type":"application/json","x-api-key":this.apiKey,...this.storeId&&{"x-store-id":this.storeId},...this.sessionToken&&{"X-Session-Token":this.sessionToken},...e.headers}});if(clearTimeout(a),!m.ok){let T=await m.json().catch(()=>({})),f={code:T.code||"UNKNOWN_ERROR",message:T.message||T.error||`HTTP ${m.status}`,status:m.status};throw new P(f.message,f.code,f.status)}return m.json()}catch(m){throw clearTimeout(a),m instanceof P?m:m instanceof Error&&m.name==="AbortError"?new P("Request timeout","TIMEOUT",408):new P(m instanceof Error?m.message:"Unknown error","NETWORK_ERROR",0)}}async chat(r,e){let s=typeof r=="string"?{message:r,context:e,sessionToken:this.sessionToken||void 0}:{...r,sessionToken:r.sessionToken||this.sessionToken||void 0},h=await this.request("/api/v1/chat",{method:"POST",body:JSON.stringify(s)});return h.sessionToken&&(this.sessionToken=h.sessionToken),h}async chatWithAudio(r,e){let s=await r.arrayBuffer(),a={audioBase64:btoa(new Uint8Array(s).reduce((T,f)=>T+String.fromCharCode(f),"")),audioMimeType:r.type||"audio/webm",context:e,sessionToken:this.sessionToken||void 0},m=await this.request("/api/v1/chat",{method:"POST",body:JSON.stringify(a)});return m.sessionToken&&(this.sessionToken=m.sessionToken),m}async createSession(){let r=await this.request("/api/v1/chat/session",{method:"POST"});return this.sessionToken=r.session.token,r.session}clearSession(){this.sessionToken=null;}getSessionToken(){return this.sessionToken}setSessionToken(r){this.sessionToken=r;}async upload(r,e){let s=new FormData;s.append("file",r),e?.folder&&s.append("folder",e.folder),e?.productId&&s.append("productId",e.productId),e?.isPrimary&&s.append("isPrimary","true");let h=`${this.baseUrl}/api/v1/upload`,a=await fetch(h,{method:"POST",headers:{"X-API-Key":this.apiKey},body:s});if(!a.ok){let m=await a.json().catch(()=>({}));throw new P(m.message||m.error||`HTTP ${a.status}`,m.code||"UPLOAD_ERROR",a.status)}return a.json()}static async quickChat(r){return new i({apiKey:r.apiKey,baseUrl:r.baseUrl}).chat(r.message,r.context)}},P=class i extends Error{constructor(r,e,s){super(r),this.name="AICommerceError",this.code=e,this.status=s,Object.setPrototypeOf(this,i.prototype);}};function G(i){let r=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(i);return r?{r:parseInt(r[1],16),g:parseInt(r[2],16),b:parseInt(r[3],16)}:{r:99,g:102,b:241}}function q(i){let r=i.primaryColor,e=G(r),s=i.position==="bottom-left";return `
2
+ var L=class i{constructor(r){this.sessionToken=null;this.products={create:async r=>this.request("/api/v1/products",{method:"POST",body:JSON.stringify(r)}),batchUpsert:async r=>this.request("/api/v1/products",{method:"POST",body:JSON.stringify({products:r})}),list:async r=>{let e=new URLSearchParams;r?.page&&e.set("page",String(r.page)),r?.perPage&&e.set("perPage",String(r.perPage)),r?.search&&e.set("search",r.search),r?.categoryId&&e.set("categoryId",r.categoryId),r?.isActive!==void 0&&e.set("isActive",String(r.isActive));let s=e.toString();return this.request(`/api/v1/products${s?`?${s}`:""}`)},get:async r=>this.request(`/api/v1/products/${r}`),update:async(r,e)=>this.request(`/api/v1/products/${r}`,{method:"PUT",body:JSON.stringify(e)}),delete:async r=>this.request(`/api/v1/products/${r}`,{method:"DELETE"})};if(!r.apiKey)throw new Error("AICommerce: apiKey is required");this.apiKey=r.apiKey,this.storeId=r.storeId,this.baseUrl=this.normalizeUrl(r.baseUrl||this.detectBaseUrl()),this.timeout=r.timeout||3e4;}detectBaseUrl(){if(typeof window<"u"){let r=document.querySelector("script[data-aicommerce-url]");if(r)return r.getAttribute("data-aicommerce-url")||"https://api.aicommerce.dev"}return "https://api.aicommerce.dev"}normalizeUrl(r){return r.replace(/\/$/,"")}async request(r,e={}){let s=`${this.baseUrl}${r}`,b=new AbortController,a=setTimeout(()=>b.abort(),this.timeout);try{let p=await fetch(s,{...e,signal:b.signal,headers:{"Content-Type":"application/json","x-api-key":this.apiKey,...this.storeId&&{"x-store-id":this.storeId},...this.sessionToken&&{"X-Session-Token":this.sessionToken},...e.headers}});if(clearTimeout(a),!p.ok){let T=await p.json().catch(()=>({})),f={code:T.code||"UNKNOWN_ERROR",message:T.message||T.error||`HTTP ${p.status}`,status:p.status};throw new P(f.message,f.code,f.status)}return p.json()}catch(p){throw clearTimeout(a),p instanceof P?p:p instanceof Error&&p.name==="AbortError"?new P("Request timeout","TIMEOUT",408):new P(p instanceof Error?p.message:"Unknown error","NETWORK_ERROR",0)}}async chat(r,e){let s=typeof r=="string"?{message:r,context:e,sessionToken:this.sessionToken||void 0}:{...r,sessionToken:r.sessionToken||this.sessionToken||void 0},b=await this.request("/api/v1/chat",{method:"POST",body:JSON.stringify(s)});return b.sessionToken&&(this.sessionToken=b.sessionToken),b}async chatWithAudio(r,e){let s=await r.arrayBuffer(),a={audioBase64:btoa(new Uint8Array(s).reduce((T,f)=>T+String.fromCharCode(f),"")),audioMimeType:r.type||"audio/webm",context:e,sessionToken:this.sessionToken||void 0},p=await this.request("/api/v1/chat",{method:"POST",body:JSON.stringify(a)});return p.sessionToken&&(this.sessionToken=p.sessionToken),p}async createSession(){let r=await this.request("/api/v1/chat/session",{method:"POST"});return this.sessionToken=r.session.token,r.session}clearSession(){this.sessionToken=null;}getSessionToken(){return this.sessionToken}setSessionToken(r){this.sessionToken=r;}async upload(r,e){let s=new FormData;s.append("file",r),e?.folder&&s.append("folder",e.folder),e?.productId&&s.append("productId",e.productId),e?.isPrimary&&s.append("isPrimary","true");let b=`${this.baseUrl}/api/v1/upload`,a=await fetch(b,{method:"POST",headers:{"X-API-Key":this.apiKey},body:s});if(!a.ok){let p=await a.json().catch(()=>({}));throw new P(p.message||p.error||`HTTP ${a.status}`,p.code||"UPLOAD_ERROR",a.status)}return a.json()}static async quickChat(r){return new i({apiKey:r.apiKey,baseUrl:r.baseUrl}).chat(r.message,r.context)}},P=class i extends Error{constructor(r,e,s){super(r),this.name="AICommerceError",this.code=e,this.status=s,Object.setPrototypeOf(this,i.prototype);}};function G(i){let r=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(i);return r?{r:parseInt(r[1],16),g:parseInt(r[2],16),b:parseInt(r[3],16)}:{r:99,g:102,b:241}}function q(i){let r=i.primaryColor,e=G(r),s=i.position==="bottom-left";return `
3
3
  /* AI Commerce Widget Styles */
4
4
  #aicommerce-widget {
5
5
  --aic-primary: ${r};
@@ -547,46 +547,102 @@ var L=class i{constructor(r){this.sessionToken=null;this.products={create:async
547
547
  .aicommerce-messages::-webkit-scrollbar-thumb:hover {
548
548
  background: var(--aic-text-secondary);
549
549
  }
550
- `}function z(i){let r=document.createElement("style");r.id="aicommerce-widget-styles",r.textContent=i;let e=document.getElementById("aicommerce-widget-styles");return e&&e.remove(),document.head.appendChild(r),r}function Q(i){if(!i.apiKey)throw new Error("AICommerceWidget: apiKey is required");let r=new L({apiKey:i.apiKey,storeId:i.storeId,baseUrl:i.baseUrl}),e={isOpen:false,isLoading:true,isRecording:false,messages:[],storeConfig:null},s=null,h=[],a=null,f=null,u;async function D(){try{let t=i.baseUrl||O(),o=await fetch(`${t}/api/v1/store`,{headers:{"x-api-key":i.apiKey}});return o.ok?(await o.json()).store:null}catch(t){return console.error("Failed to fetch store config:",t),null}}function O(){if(typeof window<"u"){let t=document.querySelector("script[data-aicommerce-url]");if(t)return t.getAttribute("data-aicommerce-url")||""}return "https://api.aicommerce.dev"}async function j(){e.storeConfig=await D(),u={apiKey:i.apiKey,storeId:i.storeId,baseUrl:i.baseUrl||O(),position:i.position||"bottom-right",theme:i.theme||"auto",primaryColor:i.primaryColor||e.storeConfig?.primaryColor||"#6366f1",welcomeMessage:i.welcomeMessage||e.storeConfig?.welcomeMessage||"Hi! How can I help you find the perfect product today?",botName:i.botName||e.storeConfig?.chatBotName||"Shopping Assistant",zIndex:i.zIndex||9999,buttonText:i.buttonText||"\u{1F4AC}",hideLauncher:i.hideLauncher||false,onOpen:i.onOpen,onClose:i.onClose,onProductClick:i.onProductClick,onMessage:i.onMessage};let t=q(u);f=z(t),a=document.createElement("div"),a.id="aicommerce-widget",a.className=`aicommerce-widget aicommerce-${u.position} aicommerce-theme-${u.theme}`,document.body.appendChild(a),b(),e.messages.push({role:"assistant",content:u.welcomeMessage}),e.isLoading=false,b();}function b(){if(!a)return;let t=`
551
- ${u.hideLauncher?"":`
550
+
551
+ /* ============================================
552
+ Embedded Mode Styles
553
+ ============================================ */
554
+
555
+ /* Embedded container - position relative, inline flow */
556
+ #aicommerce-widget.aicommerce-embedded {
557
+ position: relative;
558
+ bottom: auto;
559
+ left: auto;
560
+ right: auto;
561
+ width: 100%;
562
+ height: var(--aic-height, 500px);
563
+ }
564
+
565
+ /* Embedded mode: hide launcher button */
566
+ .aicommerce-embedded .aicommerce-launcher {
567
+ display: none !important;
568
+ }
569
+
570
+ /* Embedded mode: chat is always visible and fills container */
571
+ .aicommerce-embedded .aicommerce-chat {
572
+ position: relative;
573
+ width: 100%;
574
+ height: 100%;
575
+ max-width: 100%;
576
+ max-height: 100%;
577
+ border-radius: var(--aic-radius);
578
+ transform: none !important;
579
+ opacity: 1 !important;
580
+ pointer-events: auto !important;
581
+ }
582
+
583
+ /* Embedded mode: no open/close animations */
584
+ .aicommerce-embedded .aicommerce-chat.aicommerce-closed {
585
+ opacity: 1 !important;
586
+ transform: none !important;
587
+ pointer-events: auto !important;
588
+ }
589
+
590
+ /* Embedded mode: messages area adjusts to container */
591
+ .aicommerce-embedded .aicommerce-messages {
592
+ flex: 1;
593
+ min-height: 0;
594
+ }
595
+
596
+ /* Embedded mode responsive */
597
+ @media (max-width: 420px) {
598
+ #aicommerce-widget.aicommerce-embedded {
599
+ height: var(--aic-height, 400px);
600
+ }
601
+
602
+ .aicommerce-embedded .aicommerce-chat {
603
+ border-radius: 12px;
604
+ }
605
+ }
606
+ `}function D(i){let r=document.createElement("style");r.id="aicommerce-widget-styles",r.textContent=i;let e=document.getElementById("aicommerce-widget-styles");return e&&e.remove(),document.head.appendChild(r),r}function Q(i){if(!i.apiKey)throw new Error("AICommerceWidget: apiKey is required");let r=new L({apiKey:i.apiKey,storeId:i.storeId,baseUrl:i.baseUrl}),e={isOpen:false,isLoading:true,isRecording:false,messages:[],storeConfig:null},s=null,b=[],a=null,f=null,l;async function H(){try{let t=i.baseUrl||O(),o=await fetch(`${t}/api/v1/store`,{headers:{"x-api-key":i.apiKey}});return o.ok?(await o.json()).store:null}catch(t){return console.error("Failed to fetch store config:",t),null}}function O(){if(typeof window<"u"){let t=document.querySelector("script[data-aicommerce-url]");if(t)return t.getAttribute("data-aicommerce-url")||""}return "https://api.aicommerce.dev"}async function j(){e.storeConfig=await H();let t=i.displayMode||"widget",o=t==="embedded";l={apiKey:i.apiKey,storeId:i.storeId,baseUrl:i.baseUrl||O(),displayMode:t,container:i.container,height:i.height||"500px",position:i.position||"bottom-right",theme:i.theme||"auto",primaryColor:i.primaryColor||e.storeConfig?.primaryColor||"#6366f1",welcomeMessage:i.welcomeMessage||e.storeConfig?.welcomeMessage||"Hi! How can I help you find the perfect product today?",botName:i.botName||e.storeConfig?.chatBotName||"Shopping Assistant",zIndex:i.zIndex||9999,buttonText:i.buttonText||"\u{1F4AC}",hideLauncher:i.hideLauncher||false,onOpen:i.onOpen,onClose:i.onClose,onProductClick:i.onProductClick,onMessage:i.onMessage};let c=q(l);if(f=D(c),o){let d=null;if(typeof i.container=="string"?d=document.querySelector(i.container):i.container instanceof HTMLElement&&(d=i.container),!d){console.error("[AI Commerce] Embedded mode requires a valid container element or selector");return}a=document.createElement("div"),a.id="aicommerce-widget",a.className=`aicommerce-widget aicommerce-embedded aicommerce-theme-${l.theme}`,a.style.setProperty("--aic-height",l.height),d.appendChild(a),e.isOpen=true;}else a=document.createElement("div"),a.id="aicommerce-widget",a.className=`aicommerce-widget aicommerce-${l.position} aicommerce-theme-${l.theme}`,document.body.appendChild(a);y(),e.messages.push({role:"assistant",content:l.welcomeMessage}),e.isLoading=false,y();}function y(){if(!a)return;let t=l.displayMode==="embedded",o=`
607
+ ${!t&&!l.hideLauncher?`
552
608
  <button class="aicommerce-launcher ${e.isOpen?"aicommerce-hidden":""}" aria-label="Open chat">
553
- <span class="aicommerce-launcher-icon">${u.buttonText}</span>
609
+ <span class="aicommerce-launcher-icon">${l.buttonText}</span>
554
610
  </button>
555
- `}
611
+ `:""}
556
612
 
557
613
  <div class="aicommerce-chat ${e.isOpen?"aicommerce-open":"aicommerce-closed"}">
558
614
  <div class="aicommerce-header">
559
615
  <div class="aicommerce-header-info">
560
616
  <div class="aicommerce-avatar">
561
- ${e.storeConfig?.logo?`<img src="${e.storeConfig.logo}" alt="${u.botName}" />`:"<span>\u{1F916}</span>"}
617
+ ${e.storeConfig?.logo?`<img src="${e.storeConfig.logo}" alt="${l.botName}" />`:"<span>\u{1F916}</span>"}
562
618
  </div>
563
619
  <div class="aicommerce-header-text">
564
- <span class="aicommerce-bot-name">${u.botName}</span>
620
+ <span class="aicommerce-bot-name">${l.botName}</span>
565
621
  <span class="aicommerce-status">Online</span>
566
622
  </div>
567
623
  </div>
568
- <button class="aicommerce-close" aria-label="Close chat">\u2715</button>
624
+ ${t?"":'<button class="aicommerce-close" aria-label="Close chat">\u2715</button>'}
569
625
  </div>
570
626
 
571
627
  <div class="aicommerce-messages">
572
- ${e.messages.map((n,y)=>{let l=N(n.content),C=n.role==="user";return `
573
- <div class="aicommerce-message aicommerce-${n.role}">
574
- <div class="aicommerce-message-content ${l?"aicommerce-rtl":"aicommerce-ltr"}">
575
- ${n.audioUrl?H(n,y,C):R(n.content)}
628
+ ${e.messages.map((d,u)=>{let C=N(d.content),E=d.role==="user";return `
629
+ <div class="aicommerce-message aicommerce-${d.role}">
630
+ <div class="aicommerce-message-content ${C?"aicommerce-rtl":"aicommerce-ltr"}">
631
+ ${d.audioUrl?z(d,u,E):$(d.content)}
576
632
  </div>
577
- ${n.products&&n.products.length>0?`
633
+ ${d.products&&d.products.length>0?`
578
634
  <div class="aicommerce-products">
579
- ${n.products.map(p=>`
580
- <div class="aicommerce-product-card" data-product-id="${p.id}">
581
- ${p.image||p.imageUrl?`
582
- <img src="${p.image||p.imageUrl}" alt="${R(p.name)}" class="aicommerce-product-image" />
635
+ ${d.products.map(g=>`
636
+ <div class="aicommerce-product-card" data-product-id="${g.id}">
637
+ ${g.image||g.imageUrl?`
638
+ <img src="${g.image||g.imageUrl}" alt="${$(g.name)}" class="aicommerce-product-image" />
583
639
  `:`
584
640
  <div class="aicommerce-product-placeholder">\u{1F4E6}</div>
585
641
  `}
586
642
  <div class="aicommerce-product-info">
587
- <span class="aicommerce-product-name" title="${R(p.name)}">${R(p.name)}</span>
588
- ${p.description?`<p class="aicommerce-product-desc">${R(p.description)}</p>`:""}
589
- <span class="aicommerce-product-price">${_(p.price,p.currency)}</span>
643
+ <span class="aicommerce-product-name" title="${$(g.name)}">${$(g.name)}</span>
644
+ ${g.description?`<p class="aicommerce-product-desc">${$(g.description)}</p>`:""}
645
+ <span class="aicommerce-product-price">${_(g.price,g.currency)}</span>
590
646
  </div>
591
647
  </div>
592
648
  `).join("")}
@@ -631,15 +687,15 @@ var L=class i{constructor(r){this.sessionToken=null;this.products={create:async
631
687
  </button>
632
688
  </div>
633
689
  </div>
634
- `;a.innerHTML=t,W();let o=a.querySelector(".aicommerce-messages");o&&(o.scrollTop=o.scrollHeight);}function H(t,o,n){return `
690
+ `;a.innerHTML=o,W();let c=a.querySelector(".aicommerce-messages");c&&(c.scrollTop=c.scrollHeight);}function z(t,o,c){return `
635
691
  <div class="aicommerce-audio-player" data-message-index="${o}">
636
692
  <button class="aicommerce-audio-btn">
637
693
  <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
638
694
  </button>
639
695
  <div class="aicommerce-audio-waveform">
640
696
  <div class="aicommerce-waveform-bars">
641
- ${(t.waveformBars||Array(40).fill(10)).map(y=>`
642
- <div class="aicommerce-waveform-bar" style="height: ${y}%; background-color: ${n?"rgba(255,255,255,0.4)":"rgba(99,102,241,0.3)"}"></div>
697
+ ${(t.waveformBars||Array(40).fill(10)).map(d=>`
698
+ <div class="aicommerce-waveform-bar" style="height: ${d}%; background-color: ${c?"rgba(255,255,255,0.4)":"rgba(99,102,241,0.3)"}"></div>
643
699
  `).join("")}
644
700
  </div>
645
701
  <div class="aicommerce-audio-time">
@@ -649,5 +705,5 @@ var L=class i{constructor(r){this.sessionToken=null;this.products={create:async
649
705
  </div>
650
706
  <audio src="${t.audioUrl}" preload="metadata"></audio>
651
707
  </div>
652
- `}function W(){if(!a)return;let t=a.querySelector(".aicommerce-launcher");t&&t.addEventListener("click",()=>I());let o=a.querySelector(".aicommerce-close");o&&o.addEventListener("click",()=>A());let n=a.querySelector(".aicommerce-input"),y=a.querySelector(".aicommerce-send");n&&n.addEventListener("keypress",c=>{c.key==="Enter"&&n.value.trim()&&(E(n.value.trim()),n.value="");}),y&&n&&y.addEventListener("click",()=>{n.value.trim()&&(E(n.value.trim()),n.value="");});let l=a.querySelector(".aicommerce-mic");l&&l.addEventListener("click",()=>F()),a.querySelectorAll(".aicommerce-product-card").forEach(c=>{c.addEventListener("click",()=>{let d=c.getAttribute("data-product-id"),g=e.messages.flatMap(x=>x.products||[]).find(x=>x.id===d);g&&(u.onProductClick?u.onProductClick(g):g.url&&window.open(g.url,"_blank","noopener,noreferrer"));});}),a.querySelectorAll(".aicommerce-products").forEach(c=>{let d=false,g=0,x=0;c.addEventListener("mousedown",k=>{d=true,c.style.cursor="grabbing",g=k.pageX-c.offsetLeft,x=c.scrollLeft;}),c.addEventListener("mouseleave",()=>{d=false,c.style.cursor="grab";}),c.addEventListener("mouseup",()=>{d=false,c.style.cursor="grab";}),c.addEventListener("mousemove",k=>{if(!d)return;k.preventDefault();let v=(k.pageX-c.offsetLeft-g)*2;c.scrollLeft=x-v;});}),a.querySelectorAll(".aicommerce-audio-player").forEach(c=>{let d=c.querySelector("audio"),g=c.querySelector(".aicommerce-audio-btn"),x=c.querySelectorAll(".aicommerce-waveform-bar"),k=c.querySelector(".aicommerce-current-time");if(!d||!g)return;g.addEventListener("click",()=>{!d.paused?(d.pause(),g.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>'):(a?.querySelectorAll("audio").forEach(w=>{if(w!==d&&!w.paused){w.pause();let $=w.closest(".aicommerce-audio-player")?.querySelector(".aicommerce-audio-btn");$&&($.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>');}}),d.play(),g.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><rect x="6" y="4" width="4" height="16"></rect><rect x="14" y="4" width="4" height="16"></rect></svg>');}),d.addEventListener("timeupdate",()=>{if(k&&(k.textContent=B(d.currentTime)),d.duration){let v=d.currentTime/d.duration*100;x.forEach((w,U)=>{U/x.length*100<=v?w.style.backgroundColor=c.closest(".aicommerce-user")?"rgba(255,255,255,1)":"var(--aic-primary)":w.style.backgroundColor=c.closest(".aicommerce-user")?"rgba(255,255,255,0.4)":"rgba(99,102,241,0.3)";});}}),d.addEventListener("ended",()=>{g.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>';});let S=c.querySelector(".aicommerce-waveform-bars");S&&S.addEventListener("click",v=>{let w=S.getBoundingClientRect(),$=(v.clientX-w.left)/w.width;d.duration&&(d.currentTime=$*d.duration);});});}async function F(){if(e.isRecording)s&&s.state!=="inactive"&&s.stop();else try{let t=await navigator.mediaDevices.getUserMedia({audio:!0});h=[],s=new MediaRecorder(t,{mimeType:MediaRecorder.isTypeSupported("audio/webm")?"audio/webm":"audio/mp4"}),s.ondataavailable=o=>{o.data.size>0&&h.push(o.data);},s.onstop=async()=>{if(t.getTracks().forEach(o=>o.stop()),h.length>0){let o=new Blob(h,{type:s?.mimeType||"audio/webm"});await K(o);}e.isRecording=!1,b();},s.start(),e.isRecording=!0,b();}catch(t){console.error("Failed to start recording:",t),e.messages.push({role:"assistant",content:"Unable to access microphone. Please check your permissions."}),b();}}async function K(t){let o=URL.createObjectURL(t),n=Array(40).fill(10),y=0;try{n=await Y(t);let l=new Audio(o);await new Promise(C=>{l.onloadedmetadata=()=>{y=l.duration,C();},l.onerror=()=>C();});}catch(l){console.error("Audio analysis failed",l);}e.messages.push({role:"user",content:"Voice message",audioUrl:o,audioDuration:y,waveformBars:n}),e.isLoading=true,b();try{let l=await r.chatWithAudio(t);return e.messages.push({role:"assistant",content:l.reply,products:l.products}),u.onMessage&&u.onMessage("Voice message",l),l}catch(l){throw e.messages.push({role:"assistant",content:"Sorry, I encountered an error processing your voice message. Please try again."}),l}finally{e.isLoading=false,b();}}function N(t){return /[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]/.test(t)}function B(t){let o=Math.floor(t/60),n=Math.floor(t%60);return `${o}:${n.toString().padStart(2,"0")}`}async function Y(t){try{let o=new(window.AudioContext||window.webkitAudioContext),n=await t.arrayBuffer(),l=(await o.decodeAudioData(n)).getChannelData(0),C=40,p=Math.floor(l.length/C),M=[];for(let c=0;c<C;c++){let d=c*p,g=d+p,x=0;for(let v=d;v<g;v++)l[v]&&(x+=l[v]*l[v]);let k=Math.sqrt(x/p),S=Math.min(100,Math.max(10,k*400));M.push(S);}return M}catch(o){return console.error("Analysis error",o),Array.from({length:40},()=>20+Math.random()*60)}}async function E(t){e.messages.push({role:"user",content:t}),e.isLoading=true,b();try{let o=await r.chat(t);return e.messages.push({role:"assistant",content:o.reply,products:o.products}),u.onMessage&&u.onMessage(t,o),o}catch(o){throw e.messages.push({role:"assistant",content:"Sorry, I encountered an error. Please try again."}),o}finally{e.isLoading=false,b();}}function I(){e.isOpen=true,b(),u.onOpen?.(),setTimeout(()=>{a?.querySelector(".aicommerce-input")?.focus();},100);}function A(){e.isOpen=false,b(),u.onClose?.();}function J(){e.isOpen?A():I();}function X(){a&&(a.remove(),a=null),f&&(f.remove(),f=null);}function V(t){if(Object.assign(u,t),t.primaryColor){let o=q(u);f&&(f.textContent=o);}b();}function R(t){let o=document.createElement("div");return o.textContent=t,o.innerHTML}function _(t,o){let y={USD:"$",EUR:"\u20AC",GBP:"\xA3",MAD:"DH",SAR:"SAR",AED:"AED",JPY:"\xA5",CNY:"\xA5"}[o||"USD"]||o||"$";return `${t.toFixed(2)} ${y}`}return j(),{open:I,close:A,toggle:J,destroy:X,sendMessage:E,updateConfig:V}}var Z={init:Q,VERSION:"1.0.0"};typeof window<"u"&&(window.AICommerceWidget=Z);exports.AICommerceWidget=Z;exports.createWidget=Q;return exports;})({});//# sourceMappingURL=widget.min.js.map
708
+ `}function W(){if(!a)return;let t=a.querySelector(".aicommerce-launcher");t&&t.addEventListener("click",()=>M());let o=a.querySelector(".aicommerce-close");o&&o.addEventListener("click",()=>A());let c=a.querySelector(".aicommerce-input"),d=a.querySelector(".aicommerce-send");c&&c.addEventListener("keypress",n=>{n.key==="Enter"&&c.value.trim()&&(I(c.value.trim()),c.value="");}),d&&c&&d.addEventListener("click",()=>{c.value.trim()&&(I(c.value.trim()),c.value="");});let u=a.querySelector(".aicommerce-mic");u&&u.addEventListener("click",()=>F()),a.querySelectorAll(".aicommerce-product-card").forEach(n=>{n.addEventListener("click",()=>{let m=n.getAttribute("data-product-id"),h=e.messages.flatMap(x=>x.products||[]).find(x=>x.id===m);h&&(l.onProductClick?l.onProductClick(h):h.url&&window.open(h.url,"_blank","noopener,noreferrer"));});}),a.querySelectorAll(".aicommerce-products").forEach(n=>{let m=false,h=0,x=0;n.addEventListener("mousedown",k=>{m=true,n.style.cursor="grabbing",h=k.pageX-n.offsetLeft,x=n.scrollLeft;}),n.addEventListener("mouseleave",()=>{m=false,n.style.cursor="grab";}),n.addEventListener("mouseup",()=>{m=false,n.style.cursor="grab";}),n.addEventListener("mousemove",k=>{if(!m)return;k.preventDefault();let v=(k.pageX-n.offsetLeft-h)*2;n.scrollLeft=x-v;});}),a.querySelectorAll(".aicommerce-audio-player").forEach(n=>{let m=n.querySelector("audio"),h=n.querySelector(".aicommerce-audio-btn"),x=n.querySelectorAll(".aicommerce-waveform-bar"),k=n.querySelector(".aicommerce-current-time");if(!m||!h)return;h.addEventListener("click",()=>{!m.paused?(m.pause(),h.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>'):(a?.querySelectorAll("audio").forEach(w=>{if(w!==m&&!w.paused){w.pause();let R=w.closest(".aicommerce-audio-player")?.querySelector(".aicommerce-audio-btn");R&&(R.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>');}}),m.play(),h.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><rect x="6" y="4" width="4" height="16"></rect><rect x="14" y="4" width="4" height="16"></rect></svg>');}),m.addEventListener("timeupdate",()=>{if(k&&(k.textContent=B(m.currentTime)),m.duration){let v=m.currentTime/m.duration*100;x.forEach((w,U)=>{U/x.length*100<=v?w.style.backgroundColor=n.closest(".aicommerce-user")?"rgba(255,255,255,1)":"var(--aic-primary)":w.style.backgroundColor=n.closest(".aicommerce-user")?"rgba(255,255,255,0.4)":"rgba(99,102,241,0.3)";});}}),m.addEventListener("ended",()=>{h.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>';});let S=n.querySelector(".aicommerce-waveform-bars");S&&S.addEventListener("click",v=>{let w=S.getBoundingClientRect(),R=(v.clientX-w.left)/w.width;m.duration&&(m.currentTime=R*m.duration);});});}async function F(){if(e.isRecording)s&&s.state!=="inactive"&&s.stop();else try{let t=await navigator.mediaDevices.getUserMedia({audio:!0});b=[],s=new MediaRecorder(t,{mimeType:MediaRecorder.isTypeSupported("audio/webm")?"audio/webm":"audio/mp4"}),s.ondataavailable=o=>{o.data.size>0&&b.push(o.data);},s.onstop=async()=>{if(t.getTracks().forEach(o=>o.stop()),b.length>0){let o=new Blob(b,{type:s?.mimeType||"audio/webm"});await K(o);}e.isRecording=!1,y();},s.start(),e.isRecording=!0,y();}catch(t){console.error("Failed to start recording:",t),e.messages.push({role:"assistant",content:"Unable to access microphone. Please check your permissions."}),y();}}async function K(t){let o=URL.createObjectURL(t),c=Array(40).fill(10),d=0;try{c=await Y(t);let u=new Audio(o);await new Promise(C=>{u.onloadedmetadata=()=>{d=u.duration,C();},u.onerror=()=>C();});}catch(u){console.error("Audio analysis failed",u);}e.messages.push({role:"user",content:"Voice message",audioUrl:o,audioDuration:d,waveformBars:c}),e.isLoading=true,y();try{let u=await r.chatWithAudio(t);return e.messages.push({role:"assistant",content:u.reply,products:u.products}),l.onMessage&&l.onMessage("Voice message",u),u}catch(u){throw e.messages.push({role:"assistant",content:"Sorry, I encountered an error processing your voice message. Please try again."}),u}finally{e.isLoading=false,y();}}function N(t){return /[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]/.test(t)}function B(t){let o=Math.floor(t/60),c=Math.floor(t%60);return `${o}:${c.toString().padStart(2,"0")}`}async function Y(t){try{let o=new(window.AudioContext||window.webkitAudioContext),c=await t.arrayBuffer(),u=(await o.decodeAudioData(c)).getChannelData(0),C=40,E=Math.floor(u.length/C),g=[];for(let n=0;n<C;n++){let m=n*E,h=m+E,x=0;for(let v=m;v<h;v++)u[v]&&(x+=u[v]*u[v]);let k=Math.sqrt(x/E),S=Math.min(100,Math.max(10,k*400));g.push(S);}return g}catch(o){return console.error("Analysis error",o),Array.from({length:40},()=>20+Math.random()*60)}}async function I(t){e.messages.push({role:"user",content:t}),e.isLoading=true,y();try{let o=await r.chat(t);return e.messages.push({role:"assistant",content:o.reply,products:o.products}),l.onMessage&&l.onMessage(t,o),o}catch(o){throw e.messages.push({role:"assistant",content:"Sorry, I encountered an error. Please try again."}),o}finally{e.isLoading=false,y();}}function M(){e.isOpen=true,y(),l.onOpen?.(),setTimeout(()=>{a?.querySelector(".aicommerce-input")?.focus();},100);}function A(){e.isOpen=false,y(),l.onClose?.();}function J(){e.isOpen?A():M();}function X(){a&&(a.remove(),a=null),f&&(f.remove(),f=null);}function V(t){if(Object.assign(l,t),t.primaryColor){let o=q(l);f&&(f.textContent=o);}y();}function $(t){let o=document.createElement("div");return o.textContent=t,o.innerHTML}function _(t,o){let d={USD:"$",EUR:"\u20AC",GBP:"\xA3",MAD:"DH",SAR:"SAR",AED:"AED",JPY:"\xA5",CNY:"\xA5"}[o||"USD"]||o||"$";return `${t.toFixed(2)} ${d}`}return j(),{open:M,close:A,toggle:J,destroy:X,sendMessage:I,updateConfig:V}}var Z={init:Q,VERSION:"1.0.0"};typeof window<"u"&&(window.AICommerceWidget=Z);exports.AICommerceWidget=Z;exports.createWidget=Q;return exports;})({});//# sourceMappingURL=widget.min.js.map
653
709
  //# sourceMappingURL=widget.min.js.map