@yassirbenmoussa/aicommerce-sdk 1.1.0 → 1.3.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.
@@ -0,0 +1,653 @@
1
+ var AICommerceWidget=(function(exports){'use strict';/*! AI Commerce Widget v1.0.0 | MIT License | https://aicommerce.dev */
2
+ var L=class a{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.baseUrl=this.normalizeUrl(r.baseUrl||this.detectBaseUrl()),this.timeout=r.timeout||3e4;}detectBaseUrl(){return typeof window<"u"?window.location.origin:"https://api.aicommerce.dev"}normalizeUrl(r){return r.replace(/\/$/,"")}async request(r,e={}){let s=`${this.baseUrl}${r}`,g=new AbortController,i=setTimeout(()=>g.abort(),this.timeout);try{let m=await fetch(s,{...e,signal:g.signal,headers:{"Content-Type":"application/json","X-API-Key":this.apiKey,...this.sessionToken&&{"X-Session-Token":this.sessionToken},...e.headers}});if(clearTimeout(i),!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(i),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},g=await this.request("/api/v1/chat",{method:"POST",body:JSON.stringify(s)});return g.sessionToken&&(this.sessionToken=g.sessionToken),g}async chatWithAudio(r,e){let s=await r.arrayBuffer(),i={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(i)});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 g=`${this.baseUrl}/api/v1/upload`,i=await fetch(g,{method:"POST",headers:{"X-API-Key":this.apiKey},body:s});if(!i.ok){let m=await i.json().catch(()=>({}));throw new P(m.message||m.error||`HTTP ${i.status}`,m.code||"UPLOAD_ERROR",i.status)}return i.json()}static async quickChat(r){return new a({apiKey:r.apiKey,baseUrl:r.baseUrl}).chat(r.message,r.context)}},P=class a extends Error{constructor(r,e,s){super(r),this.name="AICommerceError",this.code=e,this.status=s,Object.setPrototypeOf(this,a.prototype);}};function _(a){let r=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(a);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(a){let r=a.primaryColor,e=_(r),s=a.position==="bottom-left";return `
3
+ /* AI Commerce Widget Styles */
4
+ #aicommerce-widget {
5
+ --aic-primary: ${r};
6
+ --aic-primary-rgb: ${e.r}, ${e.g}, ${e.b};
7
+ --aic-primary-light: rgba(${e.r}, ${e.g}, ${e.b}, 0.1);
8
+ --aic-primary-dark: rgba(${e.r}, ${e.g}, ${e.b}, 0.9);
9
+ --aic-bg: #ffffff;
10
+ --aic-bg-secondary: #f8fafc;
11
+ --aic-text: #1e293b;
12
+ --aic-text-secondary: #64748b;
13
+ --aic-border: #e2e8f0;
14
+ --aic-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
15
+ --aic-radius: 16px;
16
+ --aic-z-index: ${a.zIndex};
17
+
18
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
19
+ font-size: 14px;
20
+ line-height: 1.5;
21
+ position: fixed;
22
+ bottom: 20px;
23
+ ${s?"left: 20px;":"right: 20px;"}
24
+ z-index: var(--aic-z-index);
25
+ }
26
+
27
+ /* Dark theme */
28
+ #aicommerce-widget.aicommerce-theme-dark,
29
+ @media (prefers-color-scheme: dark) {
30
+ #aicommerce-widget.aicommerce-theme-auto {
31
+ --aic-bg: #1e293b;
32
+ --aic-bg-secondary: #0f172a;
33
+ --aic-text: #f1f5f9;
34
+ --aic-text-secondary: #94a3b8;
35
+ --aic-border: #334155;
36
+ }
37
+ }
38
+
39
+ /* Launcher Button */
40
+ .aicommerce-launcher {
41
+ width: 60px;
42
+ height: 60px;
43
+ border-radius: 50%;
44
+ background: linear-gradient(135deg, var(--aic-primary), var(--aic-primary-dark));
45
+ border: none;
46
+ cursor: pointer;
47
+ box-shadow: 0 4px 20px rgba(var(--aic-primary-rgb), 0.4);
48
+ display: flex;
49
+ align-items: center;
50
+ justify-content: center;
51
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
52
+ animation: aic-pulse 2s infinite;
53
+ }
54
+
55
+ .aicommerce-launcher:hover {
56
+ transform: scale(1.1);
57
+ box-shadow: 0 6px 30px rgba(var(--aic-primary-rgb), 0.5);
58
+ }
59
+
60
+ .aicommerce-launcher-icon {
61
+ font-size: 24px;
62
+ }
63
+
64
+ .aicommerce-hidden {
65
+ display: none !important;
66
+ }
67
+
68
+ @keyframes aic-pulse {
69
+ 0%, 100% { box-shadow: 0 4px 20px rgba(var(--aic-primary-rgb), 0.4); }
70
+ 50% { box-shadow: 0 4px 30px rgba(var(--aic-primary-rgb), 0.6); }
71
+ }
72
+
73
+ /* Chat Window */
74
+ .aicommerce-chat {
75
+ position: absolute;
76
+ bottom: 0;
77
+ ${s?"left: 0;":"right: 0;"}
78
+ width: 380px;
79
+ max-width: calc(100vw - 40px);
80
+ height: 600px;
81
+ max-height: calc(100vh - 100px);
82
+ background: var(--aic-bg);
83
+ border-radius: var(--aic-radius);
84
+ box-shadow: var(--aic-shadow);
85
+ display: flex;
86
+ flex-direction: column;
87
+ overflow: hidden;
88
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
89
+ transform-origin: bottom ${s?"left":"right"};
90
+ }
91
+
92
+ .aicommerce-chat.aicommerce-closed {
93
+ opacity: 0;
94
+ transform: scale(0.9) translateY(20px);
95
+ pointer-events: none;
96
+ }
97
+
98
+ .aicommerce-chat.aicommerce-open {
99
+ opacity: 1;
100
+ transform: scale(1) translateY(0);
101
+ }
102
+
103
+ /* Header */
104
+ .aicommerce-header {
105
+ background: linear-gradient(135deg, var(--aic-primary), var(--aic-primary-dark));
106
+ color: white;
107
+ padding: 16px 20px;
108
+ display: flex;
109
+ align-items: center;
110
+ justify-content: space-between;
111
+ }
112
+
113
+ .aicommerce-header-info {
114
+ display: flex;
115
+ align-items: center;
116
+ gap: 12px;
117
+ }
118
+
119
+ .aicommerce-avatar {
120
+ width: 40px;
121
+ height: 40px;
122
+ border-radius: 50%;
123
+ background: rgba(255, 255, 255, 0.2);
124
+ display: flex;
125
+ align-items: center;
126
+ justify-content: center;
127
+ font-size: 20px;
128
+ overflow: hidden;
129
+ }
130
+
131
+ .aicommerce-avatar img {
132
+ width: 100%;
133
+ height: 100%;
134
+ object-fit: cover;
135
+ }
136
+
137
+ .aicommerce-header-text {
138
+ display: flex;
139
+ flex-direction: column;
140
+ }
141
+
142
+ .aicommerce-bot-name {
143
+ font-weight: 600;
144
+ font-size: 16px;
145
+ }
146
+
147
+ .aicommerce-status {
148
+ font-size: 12px;
149
+ opacity: 0.9;
150
+ }
151
+
152
+ .aicommerce-close {
153
+ width: 32px;
154
+ height: 32px;
155
+ border-radius: 50%;
156
+ background: rgba(255, 255, 255, 0.2);
157
+ border: none;
158
+ color: white;
159
+ cursor: pointer;
160
+ display: flex;
161
+ align-items: center;
162
+ justify-content: center;
163
+ font-size: 16px;
164
+ transition: background 0.2s;
165
+ }
166
+
167
+ .aicommerce-close:hover {
168
+ background: rgba(255, 255, 255, 0.3);
169
+ }
170
+
171
+ /* Messages */
172
+ .aicommerce-messages {
173
+ flex: 1;
174
+ overflow-y: auto;
175
+ padding: 20px;
176
+ display: flex;
177
+ flex-direction: column;
178
+ gap: 16px;
179
+ background: var(--aic-bg-secondary);
180
+ }
181
+
182
+ .aicommerce-message {
183
+ max-width: 85%;
184
+ animation: aic-slide-in 0.3s ease-out;
185
+ }
186
+
187
+ .aicommerce-message.aicommerce-user {
188
+ align-self: flex-end;
189
+ }
190
+
191
+ .aicommerce-message.aicommerce-assistant {
192
+ align-self: flex-start;
193
+ }
194
+
195
+ .aicommerce-message-content {
196
+ padding: 12px 16px;
197
+ border-radius: 16px;
198
+ line-height: 1.5;
199
+ }
200
+
201
+ .aicommerce-user .aicommerce-message-content {
202
+ background: var(--aic-primary);
203
+ color: white;
204
+ border-bottom-right-radius: 4px;
205
+ }
206
+
207
+ .aicommerce-assistant .aicommerce-message-content {
208
+ background: var(--aic-bg);
209
+ color: var(--aic-text);
210
+ border-bottom-left-radius: 4px;
211
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
212
+ }
213
+
214
+ @keyframes aic-slide-in {
215
+ from { opacity: 0; transform: translateY(10px); }
216
+ to { opacity: 1; transform: translateY(0); }
217
+ }
218
+
219
+ /* Typing Indicator */
220
+ .aicommerce-typing {
221
+ display: flex;
222
+ gap: 4px;
223
+ padding: 12px 16px;
224
+ background: var(--aic-bg);
225
+ border-radius: 16px;
226
+ width: fit-content;
227
+ }
228
+
229
+ .aicommerce-typing span {
230
+ width: 8px;
231
+ height: 8px;
232
+ background: var(--aic-text-secondary);
233
+ border-radius: 50%;
234
+ animation: aic-bounce 1.4s infinite ease-in-out;
235
+ }
236
+
237
+ .aicommerce-typing span:nth-child(1) { animation-delay: -0.32s; }
238
+ .aicommerce-typing span:nth-child(2) { animation-delay: -0.16s; }
239
+
240
+ @keyframes aic-bounce {
241
+ 0%, 80%, 100% { transform: scale(0); }
242
+ 40% { transform: scale(1); }
243
+ }
244
+
245
+ /* Product Cards */
246
+ .aicommerce-products {
247
+ display: flex;
248
+ gap: 16px;
249
+ margin-top: 12px;
250
+ overflow-x: auto;
251
+ padding-bottom: 16px;
252
+ width: 100%;
253
+ max-width: 100%;
254
+ cursor: grab;
255
+ user-select: none;
256
+ -webkit-user-select: none;
257
+ scrollbar-width: none; /* Firefox */
258
+ }
259
+ .aicommerce-products::-webkit-scrollbar {
260
+ display: none; /* Chrome/Safari */
261
+ }
262
+
263
+ .aicommerce-product-card {
264
+ flex-shrink: 0;
265
+ width: 280px;
266
+ background: var(--aic-bg);
267
+ border-radius: 12px;
268
+ overflow: hidden;
269
+ cursor: pointer;
270
+ transition: all 0.2s;
271
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
272
+ }
273
+
274
+ .aicommerce-product-card:hover {
275
+ transform: translateY(-2px);
276
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
277
+ }
278
+
279
+ .aicommerce-product-image {
280
+ width: 100%;
281
+ aspect-ratio: 16/9;
282
+ height: auto;
283
+ object-fit: cover;
284
+ }
285
+
286
+ .aicommerce-product-placeholder {
287
+ width: 100%;
288
+ aspect-ratio: 16/9;
289
+ height: auto;
290
+ background: var(--aic-bg-secondary);
291
+ display: flex;
292
+ align-items: center;
293
+ justify-content: center;
294
+ font-size: 32px;
295
+ }
296
+
297
+ .aicommerce-product-info {
298
+ padding: 10px;
299
+ display: flex;
300
+ flex-direction: column;
301
+ gap: 4px;
302
+ }
303
+
304
+ .aicommerce-product-name {
305
+ font-weight: 500;
306
+ font-size: 13px;
307
+ color: var(--aic-text);
308
+ white-space: nowrap;
309
+ overflow: hidden;
310
+ text-overflow: ellipsis;
311
+ }
312
+
313
+ .aicommerce-product-price {
314
+ font-weight: 600;
315
+ font-size: 14px;
316
+ color: var(--aic-primary);
317
+ }
318
+
319
+ .aicommerce-product-desc {
320
+ font-size: 12px;
321
+ color: var(--aic-text-secondary);
322
+ line-height: 1.4;
323
+ display: -webkit-box;
324
+ -webkit-line-clamp: 2;
325
+ -webkit-box-orient: vertical;
326
+ overflow: hidden;
327
+ margin-top: 4px;
328
+ }
329
+
330
+ /* Audio Player */
331
+ .aicommerce-audio-player {
332
+ display: flex;
333
+ align-items: center;
334
+ gap: 12px;
335
+ min-width: 240px;
336
+ padding: 4px 0;
337
+ }
338
+
339
+ .aicommerce-audio-btn {
340
+ width: 40px;
341
+ height: 40px;
342
+ border-radius: 50%;
343
+ display: flex;
344
+ align-items: center;
345
+ justify-content: center;
346
+ border: none;
347
+ cursor: pointer;
348
+ transition: all 0.2s;
349
+ background: rgba(255, 255, 255, 0.25);
350
+ color: white;
351
+ flex-shrink: 0;
352
+ padding: 0;
353
+ }
354
+
355
+ .aicommerce-audio-btn:hover {
356
+ background: rgba(255, 255, 255, 0.35);
357
+ transform: scale(1.05);
358
+ }
359
+
360
+ .aicommerce-audio-btn:active {
361
+ transform: scale(0.95);
362
+ }
363
+
364
+ /* Invert colors for assistant (since background is white/gray) */
365
+ .aicommerce-assistant .aicommerce-audio-btn {
366
+ background: var(--aic-primary);
367
+ color: white;
368
+ }
369
+ .aicommerce-assistant .aicommerce-audio-btn:hover {
370
+ background: var(--aic-primary-dark);
371
+ }
372
+
373
+ .aicommerce-audio-waveform {
374
+ flex: 1;
375
+ display: flex;
376
+ flex-direction: column;
377
+ gap: 6px;
378
+ min-width: 0; /* Prevent overflow */
379
+ }
380
+
381
+ .aicommerce-waveform-bars {
382
+ display: flex;
383
+ align-items: center;
384
+ gap: 2px;
385
+ height: 24px;
386
+ cursor: pointer;
387
+ width: 100%;
388
+ }
389
+
390
+ .aicommerce-waveform-bar {
391
+ width: 3px;
392
+ border-radius: 2px;
393
+ min-height: 3px;
394
+ transition: background-color 0.1s;
395
+ flex-shrink: 0;
396
+ }
397
+
398
+ .aicommerce-audio-time {
399
+ display: flex;
400
+ justify-content: space-between;
401
+ font-size: 11px;
402
+ font-weight: 500;
403
+ }
404
+
405
+ .aicommerce-user .aicommerce-audio-time {
406
+ color: rgba(255, 255, 255, 0.8);
407
+ }
408
+ .aicommerce-assistant .aicommerce-audio-time {
409
+ color: var(--aic-text-secondary);
410
+ }
411
+
412
+ /* RTL Support */
413
+ .aicommerce-rtl {
414
+ direction: rtl;
415
+ text-align: right;
416
+ }
417
+ .aicommerce-ltr {
418
+ direction: ltr;
419
+ text-align: left;
420
+ }
421
+
422
+ /* Input Area */
423
+ .aicommerce-input-container {
424
+ padding: 16px 20px;
425
+ background: var(--aic-bg);
426
+ border-top: 1px solid var(--aic-border);
427
+ display: flex;
428
+ gap: 12px;
429
+ }
430
+
431
+ .aicommerce-input {
432
+ flex: 1;
433
+ padding: 12px 16px;
434
+ border: 1px solid var(--aic-border);
435
+ border-radius: 24px;
436
+ background: var(--aic-bg-secondary);
437
+ color: var(--aic-text);
438
+ font-size: 14px;
439
+ outline: none;
440
+ transition: all 0.2s;
441
+ }
442
+
443
+ .aicommerce-input:focus {
444
+ border-color: var(--aic-primary);
445
+ box-shadow: 0 0 0 3px var(--aic-primary-light);
446
+ }
447
+
448
+ .aicommerce-input::placeholder {
449
+ color: var(--aic-text-secondary);
450
+ }
451
+
452
+ .aicommerce-send {
453
+ width: 44px;
454
+ height: 44px;
455
+ border-radius: 50%;
456
+ background: var(--aic-primary);
457
+ border: none;
458
+ color: white;
459
+ cursor: pointer;
460
+ display: flex;
461
+ align-items: center;
462
+ justify-content: center;
463
+ transition: all 0.2s;
464
+ }
465
+
466
+ .aicommerce-send:hover:not(:disabled) {
467
+ background: var(--aic-primary-dark);
468
+ transform: scale(1.05);
469
+ }
470
+
471
+ .aicommerce-send:disabled {
472
+ opacity: 0.6;
473
+ cursor: not-allowed;
474
+ }
475
+
476
+ /* Microphone Button */
477
+ .aicommerce-mic {
478
+ width: 44px;
479
+ height: 44px;
480
+ border-radius: 50%;
481
+ background: var(--aic-bg-secondary);
482
+ border: 1px solid var(--aic-border);
483
+ color: var(--aic-text-secondary);
484
+ cursor: pointer;
485
+ display: flex;
486
+ align-items: center;
487
+ justify-content: center;
488
+ transition: all 0.2s;
489
+ }
490
+
491
+ .aicommerce-mic:hover:not(:disabled) {
492
+ background: var(--aic-primary-light);
493
+ border-color: var(--aic-primary);
494
+ color: var(--aic-primary);
495
+ }
496
+
497
+ .aicommerce-mic.aicommerce-recording {
498
+ background: #ef4444;
499
+ border-color: #ef4444;
500
+ color: white;
501
+ animation: aic-recording-pulse 1s infinite;
502
+ }
503
+
504
+ .aicommerce-mic:disabled {
505
+ opacity: 0.6;
506
+ cursor: not-allowed;
507
+ }
508
+
509
+ @keyframes aic-recording-pulse {
510
+ 0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.4); }
511
+ 50% { transform: scale(1.05); box-shadow: 0 0 0 8px rgba(239, 68, 68, 0); }
512
+ }
513
+
514
+ /* Mobile Responsive */
515
+ @media (max-width: 420px) {
516
+ #aicommerce-widget {
517
+ bottom: 16px;
518
+ ${s?"left: 16px;":"right: 16px;"}
519
+ }
520
+
521
+ .aicommerce-chat {
522
+ width: calc(100vw - 32px);
523
+ height: calc(100vh - 100px);
524
+ border-radius: 12px;
525
+ }
526
+
527
+ .aicommerce-launcher {
528
+ width: 56px;
529
+ height: 56px;
530
+ }
531
+ }
532
+
533
+ /* Scrollbar */
534
+ .aicommerce-messages::-webkit-scrollbar {
535
+ width: 6px;
536
+ }
537
+
538
+ .aicommerce-messages::-webkit-scrollbar-track {
539
+ background: transparent;
540
+ }
541
+
542
+ .aicommerce-messages::-webkit-scrollbar-thumb {
543
+ background: var(--aic-border);
544
+ border-radius: 3px;
545
+ }
546
+
547
+ .aicommerce-messages::-webkit-scrollbar-thumb:hover {
548
+ background: var(--aic-text-secondary);
549
+ }
550
+ `}function z(a){let r=document.createElement("style");r.id="aicommerce-widget-styles",r.textContent=a;let e=document.getElementById("aicommerce-widget-styles");return e&&e.remove(),document.head.appendChild(r),r}function Q(a){if(!a.apiKey)throw new Error("AICommerceWidget: apiKey is required");let r=new L({apiKey:a.apiKey,baseUrl:a.baseUrl}),e={isOpen:false,isLoading:true,isRecording:false,messages:[],storeConfig:null},s=null,g=[],i=null,f=null,u;async function D(){try{let t=a.baseUrl||O(),o=await fetch(`${t}/api/v1/store`,{headers:{"x-api-key":a.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:a.apiKey,baseUrl:a.baseUrl||O(),position:a.position||"bottom-right",theme:a.theme||"auto",primaryColor:a.primaryColor||e.storeConfig?.primaryColor||"#6366f1",welcomeMessage:a.welcomeMessage||e.storeConfig?.welcomeMessage||"Hi! How can I help you find the perfect product today?",botName:a.botName||e.storeConfig?.chatBotName||"Shopping Assistant",zIndex:a.zIndex||9999,buttonText:a.buttonText||"\u{1F4AC}",hideLauncher:a.hideLauncher||false,onOpen:a.onOpen,onClose:a.onClose,onProductClick:a.onProductClick,onMessage:a.onMessage};let t=q(u);f=z(t),i=document.createElement("div"),i.id="aicommerce-widget",i.className=`aicommerce-widget aicommerce-${u.position} aicommerce-theme-${u.theme}`,document.body.appendChild(i),b(),e.messages.push({role:"assistant",content:u.welcomeMessage}),e.isLoading=false,b();}function b(){if(!i)return;let t=`
551
+ ${u.hideLauncher?"":`
552
+ <button class="aicommerce-launcher ${e.isOpen?"aicommerce-hidden":""}" aria-label="Open chat">
553
+ <span class="aicommerce-launcher-icon">${u.buttonText}</span>
554
+ </button>
555
+ `}
556
+
557
+ <div class="aicommerce-chat ${e.isOpen?"aicommerce-open":"aicommerce-closed"}">
558
+ <div class="aicommerce-header">
559
+ <div class="aicommerce-header-info">
560
+ <div class="aicommerce-avatar">
561
+ ${e.storeConfig?.logo?`<img src="${e.storeConfig.logo}" alt="${u.botName}" />`:"<span>\u{1F916}</span>"}
562
+ </div>
563
+ <div class="aicommerce-header-text">
564
+ <span class="aicommerce-bot-name">${u.botName}</span>
565
+ <span class="aicommerce-status">Online</span>
566
+ </div>
567
+ </div>
568
+ <button class="aicommerce-close" aria-label="Close chat">\u2715</button>
569
+ </div>
570
+
571
+ <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)}
576
+ </div>
577
+ ${n.products&&n.products.length>0?`
578
+ <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" />
583
+ `:`
584
+ <div class="aicommerce-product-placeholder">\u{1F4E6}</div>
585
+ `}
586
+ <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">${G(p.price,p.currency)}</span>
590
+ </div>
591
+ </div>
592
+ `).join("")}
593
+ </div>
594
+ `:""}
595
+ </div>
596
+ `}).join("")}
597
+ ${e.isLoading?`
598
+ <div class="aicommerce-message aicommerce-assistant">
599
+ <div class="aicommerce-typing">
600
+ <span></span><span></span><span></span>
601
+ </div>
602
+ </div>
603
+ `:""}
604
+ </div>
605
+
606
+ <div class="aicommerce-input-container">
607
+ <input
608
+ type="text"
609
+ class="aicommerce-input"
610
+ placeholder="Type your message..."
611
+ ${e.isLoading||e.isRecording?"disabled":""}
612
+ />
613
+ <button class="aicommerce-mic ${e.isRecording?"aicommerce-recording":""}" ${e.isLoading?"disabled":""} aria-label="${e.isRecording?"Stop recording":"Voice input"}">
614
+ ${e.isRecording?`
615
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
616
+ <rect x="6" y="6" width="12" height="12" rx="2"/>
617
+ </svg>
618
+ `:`
619
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
620
+ <path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/>
621
+ <path d="M19 10v2a7 7 0 0 1-14 0v-2"/>
622
+ <line x1="12" y1="19" x2="12" y2="23"/>
623
+ <line x1="8" y1="23" x2="16" y2="23"/>
624
+ </svg>
625
+ `}
626
+ </button>
627
+ <button class="aicommerce-send" ${e.isLoading||e.isRecording?"disabled":""} aria-label="Send message">
628
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
629
+ <path d="M22 2L11 13M22 2L15 22L11 13M22 2L2 9L11 13"/>
630
+ </svg>
631
+ </button>
632
+ </div>
633
+ </div>
634
+ `;i.innerHTML=t,W();let o=i.querySelector(".aicommerce-messages");o&&(o.scrollTop=o.scrollHeight);}function H(t,o,n){return `
635
+ <div class="aicommerce-audio-player" data-message-index="${o}">
636
+ <button class="aicommerce-audio-btn">
637
+ <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
+ </button>
639
+ <div class="aicommerce-audio-waveform">
640
+ <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>
643
+ `).join("")}
644
+ </div>
645
+ <div class="aicommerce-audio-time">
646
+ <span class="aicommerce-current-time">0:00</span>
647
+ <span>${B(t.audioDuration||0)}</span>
648
+ </div>
649
+ </div>
650
+ <audio src="${t.audioUrl}" preload="metadata"></audio>
651
+ </div>
652
+ `}function W(){if(!i)return;let t=i.querySelector(".aicommerce-launcher");t&&t.addEventListener("click",()=>A());let o=i.querySelector(".aicommerce-close");o&&o.addEventListener("click",()=>M());let n=i.querySelector(".aicommerce-input"),y=i.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=i.querySelector(".aicommerce-mic");l&&l.addEventListener("click",()=>F()),i.querySelectorAll(".aicommerce-product-card").forEach(c=>{c.addEventListener("click",()=>{let d=c.getAttribute("data-product-id"),h=e.messages.flatMap(x=>x.products||[]).find(x=>x.id===d);h&&u.onProductClick&&u.onProductClick(h);});}),i.querySelectorAll(".aicommerce-products").forEach(c=>{let d=false,h=0,x=0;c.addEventListener("mousedown",k=>{d=true,c.style.cursor="grabbing",h=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-h)*2;c.scrollLeft=x-v;});}),i.querySelectorAll(".aicommerce-audio-player").forEach(c=>{let d=c.querySelector("audio"),h=c.querySelector(".aicommerce-audio-btn"),x=c.querySelectorAll(".aicommerce-waveform-bar"),k=c.querySelector(".aicommerce-current-time");if(!d||!h)return;h.addEventListener("click",()=>{!d.paused?(d.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>'):(i?.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(),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>');}),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",()=>{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=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});g=[],s=new MediaRecorder(t,{mimeType:MediaRecorder.isTypeSupported("audio/webm")?"audio/webm":"audio/mp4"}),s.ondataavailable=o=>{o.data.size>0&&g.push(o.data);},s.onstop=async()=>{if(t.getTracks().forEach(o=>o.stop()),g.length>0){let o=new Blob(g,{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 X(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 X(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),I=[];for(let c=0;c<C;c++){let d=c*p,h=d+p,x=0;for(let v=d;v<h;v++)l[v]&&(x+=l[v]*l[v]);let k=Math.sqrt(x/p),S=Math.min(100,Math.max(10,k*400));I.push(S);}return I}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 A(){e.isOpen=true,b(),u.onOpen?.(),setTimeout(()=>{i?.querySelector(".aicommerce-input")?.focus();},100);}function M(){e.isOpen=false,b(),u.onClose?.();}function Y(){e.isOpen?M():A();}function J(){i&&(i.remove(),i=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 G(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:A,close:M,toggle:Y,destroy:J,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
653
+ //# sourceMappingURL=widget.min.js.map