@paramms/chat-widget 1.0.25 → 1.0.27

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.
@@ -17,7 +17,7 @@ export interface ConnectionOptions {
17
17
  open: ClientFrame;
18
18
  onFrame: (frame: ServerFrame) => void;
19
19
  getCursor: () => number;
20
- onStatusChange?: (status: 'connecting' | 'open' | 'reconnecting') => void;
20
+ onStatusChange?: (status: 'connecting' | 'open' | 'reconnecting' | 'error', message?: string) => void;
21
21
  socketFactory?: SocketFactory;
22
22
  backoffBaseMs?: number;
23
23
  backoffMaxMs?: number;
@@ -28,6 +28,7 @@ export declare class ConnectionManager {
28
28
  private socket;
29
29
  private state;
30
30
  private authed;
31
+ private everAuthed;
31
32
  private attempt;
32
33
  private outbox;
33
34
  private stopped;
@@ -0,0 +1,35 @@
1
+ /** Everything an embedder can pass. All optional except `appId`. Names are
2
+ * intentionally plain — no knowledge of the widget internals required. */
3
+ export interface RelaySettings {
4
+ /** The chatroom id (from your Relay dashboard). Required. `profileId` is an alias. */
5
+ appId?: string;
6
+ profileId?: string;
7
+ /** Relay server URL. Defaults to the hosted relay; set for self-hosted. */
8
+ url?: string;
9
+ apiUrl?: string;
10
+ /** IDENTITY (optional, tiered): `token` (a signed JWT from your backend) is the
11
+ * secure path; `userId` (any stable string you have) is the easy path; omit
12
+ * both for an anonymous visitor. See EMBED.md. */
13
+ token?: string;
14
+ userId?: string;
15
+ /** Display info shown to agents (not identity). */
16
+ name?: string;
17
+ email?: string;
18
+ avatar?: string;
19
+ /** Subject the chat is about (e.g. a marketplace listing). `listingId` is sugar
20
+ * for `subjectId: "listing_<id>"`. */
21
+ subjectId?: string;
22
+ listingId?: string;
23
+ subjectTitle?: string;
24
+ subjectMeta?: string;
25
+ subjectPrice?: number;
26
+ subjectStatus?: string;
27
+ /** Appearance. `launcher` defaults to true (a floating bubble). */
28
+ accent?: string;
29
+ launcher?: boolean;
30
+ position?: 'bottom-right' | 'bottom-left';
31
+ translateLang?: string;
32
+ }
33
+ export type RelayCommand = 'boot' | 'update' | 'identify' | 'shutdown';
34
+ /** The public command dispatcher exposed as `window.Relay`. */
35
+ export declare function Relay(command: RelayCommand | string, arg?: unknown): void;
package/dist/embed.js ADDED
@@ -0,0 +1,166 @@
1
+ var RelayEmbed=function(D){"use strict";var xn=Object.defineProperty;var yn=(D,z,q)=>z in D?xn(D,z,{enumerable:!0,configurable:!0,writable:!0,value:q}):D[z]=q;var a=(D,z,q)=>yn(D,typeof z!="symbol"?z+"":z,q);const z="oc_uid";function q(i){try{const e=document.cookie.match(new RegExp(`(?:^|; )${i}=([^;]*)`));return e?decodeURIComponent(e[1]):null}catch{return null}}function Re(i,e){try{const n=location.protocol==="https:"?"; Secure":"";document.cookie=`${i}=${encodeURIComponent(e)}; Max-Age=31536000; Path=/; SameSite=Lax${n}`}catch{}}function He(){return`g_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`}function je(){let i=null;try{i=localStorage.getItem(z)}catch{}i||(i=q(z));const e=i??He();try{localStorage.setItem(z,e)}catch{}return Re(z,e),e}function Fe(i){const e=i.length;let t=0,n=0;for(;n<e;){let s=i.charCodeAt(n++);if(s&4294967168)if(!(s&4294965248))t+=2;else{if(s>=55296&&s<=56319&&n<e){const o=i.charCodeAt(n);(o&64512)===56320&&(++n,s=((s&1023)<<10)+(o&1023)+65536)}s&4294901760?t+=4:t+=3}else{t++;continue}}return t}function qe(i,e,t){const n=i.length;let s=t,o=0;for(;o<n;){let r=i.charCodeAt(o++);if(r&4294967168)if(!(r&4294965248))e[s++]=r>>6&31|192;else{if(r>=55296&&r<=56319&&o<n){const h=i.charCodeAt(o);(h&64512)===56320&&(++o,r=((r&1023)<<10)+(h&1023)+65536)}r&4294901760?(e[s++]=r>>18&7|240,e[s++]=r>>12&63|128,e[s++]=r>>6&63|128):(e[s++]=r>>12&15|224,e[s++]=r>>6&63|128)}else{e[s++]=r;continue}e[s++]=r&63|128}}const Oe=new TextEncoder,Ne=50;function Ve(i,e,t){Oe.encodeInto(i,e.subarray(t))}function We(i,e,t){i.length>Ne?Ve(i,e,t):qe(i,e,t)}const Xe=4096;function ge(i,e,t){let n=e;const s=n+t,o=[];let r="";for(;n<s;){const h=i[n++];if(!(h&128))o.push(h);else if((h&224)===192){const w=i[n++]&63;o.push((h&31)<<6|w)}else if((h&240)===224){const w=i[n++]&63,d=i[n++]&63;o.push((h&31)<<12|w<<6|d)}else if((h&248)===240){const w=i[n++]&63,d=i[n++]&63,b=i[n++]&63;let x=(h&7)<<18|w<<12|d<<6|b;x>65535&&(x-=65536,o.push(x>>>10&1023|55296),x=56320|x&1023),o.push(x)}else o.push(h);o.length>=Xe&&(r+=String.fromCharCode(...o),o.length=0)}return o.length>0&&(r+=String.fromCharCode(...o)),r}const Ye=new TextDecoder,Je=200;function Ge(i,e,t){const n=i.subarray(e,e+t);return Ye.decode(n)}function Ze(i,e,t){return t>Je?Ge(i,e,t):ge(i,e,t)}class Q{constructor(e,t){a(this,"type");a(this,"data");this.type=e,this.data=t}}class B extends Error{constructor(e){super(e);const t=Object.create(B.prototype);Object.setPrototypeOf(this,t),Object.defineProperty(this,"name",{configurable:!0,enumerable:!1,value:B.name})}}const W=4294967295;function Qe(i,e,t){const n=t/4294967296,s=t;i.setUint32(e,n),i.setUint32(e+4,s)}function be(i,e,t){const n=Math.floor(t/4294967296),s=t;i.setUint32(e,n),i.setUint32(e+4,s)}function me(i,e){const t=i.getInt32(e),n=i.getUint32(e+4);return t*4294967296+n}function et(i,e){const t=i.getUint32(e),n=i.getUint32(e+4);return t*4294967296+n}const tt=-1,nt=4294967296-1,it=17179869184-1;function st({sec:i,nsec:e}){if(i>=0&&e>=0&&i<=it)if(e===0&&i<=nt){const t=new Uint8Array(4);return new DataView(t.buffer).setUint32(0,i),t}else{const t=i/4294967296,n=i&4294967295,s=new Uint8Array(8),o=new DataView(s.buffer);return o.setUint32(0,e<<2|t&3),o.setUint32(4,n),s}else{const t=new Uint8Array(12),n=new DataView(t.buffer);return n.setUint32(0,e),be(n,4,i),t}}function ot(i){const e=i.getTime(),t=Math.floor(e/1e3),n=(e-t*1e3)*1e6,s=Math.floor(n/1e9);return{sec:t+s,nsec:n-s*1e9}}function rt(i){if(i instanceof Date){const e=ot(i);return st(e)}else return null}function at(i){const e=new DataView(i.buffer,i.byteOffset,i.byteLength);switch(i.byteLength){case 4:return{sec:e.getUint32(0),nsec:0};case 8:{const t=e.getUint32(0),n=e.getUint32(4),s=(t&3)*4294967296+n,o=t>>>2;return{sec:s,nsec:o}}case 12:{const t=me(e,4),n=e.getUint32(0);return{sec:t,nsec:n}}default:throw new B(`Unrecognized data size for timestamp (expected 4, 8, or 12): ${i.length}`)}}function ct(i){const e=at(i);return new Date(e.sec*1e3+e.nsec/1e6)}const dt={type:tt,encode:rt,decode:ct},ie=class ie{constructor(){a(this,"__brand");a(this,"builtInEncoders",[]);a(this,"builtInDecoders",[]);a(this,"encoders",[]);a(this,"decoders",[]);this.register(dt)}register({type:e,encode:t,decode:n}){if(e>=0)this.encoders[e]=t,this.decoders[e]=n;else{const s=-1-e;this.builtInEncoders[s]=t,this.builtInDecoders[s]=n}}tryToEncode(e,t){for(let n=0;n<this.builtInEncoders.length;n++){const s=this.builtInEncoders[n];if(s!=null){const o=s(e,t);if(o!=null){const r=-1-n;return new Q(r,o)}}}for(let n=0;n<this.encoders.length;n++){const s=this.encoders[n];if(s!=null){const o=s(e,t);if(o!=null){const r=n;return new Q(r,o)}}}return e instanceof Q?e:null}decode(e,t,n){const s=t<0?this.builtInDecoders[-1-t]:this.decoders[t];return s?s(e,t,n):new Q(t,e)}};a(ie,"defaultCodec",new ie);let ee=ie;function lt(i){return i instanceof ArrayBuffer||typeof SharedArrayBuffer<"u"&&i instanceof SharedArrayBuffer}function ce(i){return i instanceof Uint8Array?i:ArrayBuffer.isView(i)?new Uint8Array(i.buffer,i.byteOffset,i.byteLength):lt(i)?new Uint8Array(i):Uint8Array.from(i)}const ht=100,pt=2048;class de{constructor(e){a(this,"extensionCodec");a(this,"context");a(this,"useBigInt64");a(this,"maxDepth");a(this,"initialBufferSize");a(this,"sortKeys");a(this,"forceFloat32");a(this,"ignoreUndefined");a(this,"forceIntegerToFloat");a(this,"pos");a(this,"view");a(this,"bytes");a(this,"entered",!1);this.extensionCodec=(e==null?void 0:e.extensionCodec)??ee.defaultCodec,this.context=e==null?void 0:e.context,this.useBigInt64=(e==null?void 0:e.useBigInt64)??!1,this.maxDepth=(e==null?void 0:e.maxDepth)??ht,this.initialBufferSize=(e==null?void 0:e.initialBufferSize)??pt,this.sortKeys=(e==null?void 0:e.sortKeys)??!1,this.forceFloat32=(e==null?void 0:e.forceFloat32)??!1,this.ignoreUndefined=(e==null?void 0:e.ignoreUndefined)??!1,this.forceIntegerToFloat=(e==null?void 0:e.forceIntegerToFloat)??!1,this.pos=0,this.view=new DataView(new ArrayBuffer(this.initialBufferSize)),this.bytes=new Uint8Array(this.view.buffer)}clone(){return new de({extensionCodec:this.extensionCodec,context:this.context,useBigInt64:this.useBigInt64,maxDepth:this.maxDepth,initialBufferSize:this.initialBufferSize,sortKeys:this.sortKeys,forceFloat32:this.forceFloat32,ignoreUndefined:this.ignoreUndefined,forceIntegerToFloat:this.forceIntegerToFloat})}reinitializeState(){this.pos=0}encodeSharedRef(e){if(this.entered)return this.clone().encodeSharedRef(e);try{return this.entered=!0,this.reinitializeState(),this.doEncode(e,1),this.bytes.subarray(0,this.pos)}finally{this.entered=!1}}encode(e){if(this.entered)return this.clone().encode(e);try{return this.entered=!0,this.reinitializeState(),this.doEncode(e,1),this.bytes.slice(0,this.pos)}finally{this.entered=!1}}doEncode(e,t){if(t>this.maxDepth)throw new Error(`Too deep objects in depth ${t}`);e==null?this.encodeNil():typeof e=="boolean"?this.encodeBoolean(e):typeof e=="number"?this.forceIntegerToFloat?this.encodeNumberAsFloat(e):this.encodeNumber(e):typeof e=="string"?this.encodeString(e):this.useBigInt64&&typeof e=="bigint"?this.encodeBigInt64(e):this.encodeObject(e,t)}ensureBufferSizeToWrite(e){const t=this.pos+e;this.view.byteLength<t&&this.resizeBuffer(t*2)}resizeBuffer(e){const t=new ArrayBuffer(e),n=new Uint8Array(t),s=new DataView(t);n.set(this.bytes),this.view=s,this.bytes=n}encodeNil(){this.writeU8(192)}encodeBoolean(e){e===!1?this.writeU8(194):this.writeU8(195)}encodeNumber(e){!this.forceIntegerToFloat&&Number.isSafeInteger(e)?e>=0?e<128?this.writeU8(e):e<256?(this.writeU8(204),this.writeU8(e)):e<65536?(this.writeU8(205),this.writeU16(e)):e<4294967296?(this.writeU8(206),this.writeU32(e)):this.useBigInt64?this.encodeNumberAsFloat(e):(this.writeU8(207),this.writeU64(e)):e>=-32?this.writeU8(224|e+32):e>=-128?(this.writeU8(208),this.writeI8(e)):e>=-32768?(this.writeU8(209),this.writeI16(e)):e>=-2147483648?(this.writeU8(210),this.writeI32(e)):this.useBigInt64?this.encodeNumberAsFloat(e):(this.writeU8(211),this.writeI64(e)):this.encodeNumberAsFloat(e)}encodeNumberAsFloat(e){this.forceFloat32?(this.writeU8(202),this.writeF32(e)):(this.writeU8(203),this.writeF64(e))}encodeBigInt64(e){e>=BigInt(0)?(this.writeU8(207),this.writeBigUint64(e)):(this.writeU8(211),this.writeBigInt64(e))}writeStringHeader(e){if(e<32)this.writeU8(160+e);else if(e<256)this.writeU8(217),this.writeU8(e);else if(e<65536)this.writeU8(218),this.writeU16(e);else if(e<4294967296)this.writeU8(219),this.writeU32(e);else throw new Error(`Too long string: ${e} bytes in UTF-8`)}encodeString(e){const n=Fe(e);this.ensureBufferSizeToWrite(5+n),this.writeStringHeader(n),We(e,this.bytes,this.pos),this.pos+=n}encodeObject(e,t){const n=this.extensionCodec.tryToEncode(e,this.context);if(n!=null)this.encodeExtension(n);else if(Array.isArray(e))this.encodeArray(e,t);else if(ArrayBuffer.isView(e))this.encodeBinary(e);else if(typeof e=="object")this.encodeMap(e,t);else throw new Error(`Unrecognized object: ${Object.prototype.toString.apply(e)}`)}encodeBinary(e){const t=e.byteLength;if(t<256)this.writeU8(196),this.writeU8(t);else if(t<65536)this.writeU8(197),this.writeU16(t);else if(t<4294967296)this.writeU8(198),this.writeU32(t);else throw new Error(`Too large binary: ${t}`);const n=ce(e);this.writeU8a(n)}encodeArray(e,t){const n=e.length;if(n<16)this.writeU8(144+n);else if(n<65536)this.writeU8(220),this.writeU16(n);else if(n<4294967296)this.writeU8(221),this.writeU32(n);else throw new Error(`Too large array: ${n}`);for(const s of e)this.doEncode(s,t+1)}countWithoutUndefined(e,t){let n=0;for(const s of t)e[s]!==void 0&&n++;return n}encodeMap(e,t){const n=Object.keys(e);this.sortKeys&&n.sort();const s=this.ignoreUndefined?this.countWithoutUndefined(e,n):n.length;if(s<16)this.writeU8(128+s);else if(s<65536)this.writeU8(222),this.writeU16(s);else if(s<4294967296)this.writeU8(223),this.writeU32(s);else throw new Error(`Too large map object: ${s}`);for(const o of n){const r=e[o];this.ignoreUndefined&&r===void 0||(this.encodeString(o),this.doEncode(r,t+1))}}encodeExtension(e){if(typeof e.data=="function"){const n=e.data(this.pos+6),s=n.length;if(s>=4294967296)throw new Error(`Too large extension object: ${s}`);this.writeU8(201),this.writeU32(s),this.writeI8(e.type),this.writeU8a(n);return}const t=e.data.length;if(t===1)this.writeU8(212);else if(t===2)this.writeU8(213);else if(t===4)this.writeU8(214);else if(t===8)this.writeU8(215);else if(t===16)this.writeU8(216);else if(t<256)this.writeU8(199),this.writeU8(t);else if(t<65536)this.writeU8(200),this.writeU16(t);else if(t<4294967296)this.writeU8(201),this.writeU32(t);else throw new Error(`Too large extension object: ${t}`);this.writeI8(e.type),this.writeU8a(e.data)}writeU8(e){this.ensureBufferSizeToWrite(1),this.view.setUint8(this.pos,e),this.pos++}writeU8a(e){const t=e.length;this.ensureBufferSizeToWrite(t),this.bytes.set(e,this.pos),this.pos+=t}writeI8(e){this.ensureBufferSizeToWrite(1),this.view.setInt8(this.pos,e),this.pos++}writeU16(e){this.ensureBufferSizeToWrite(2),this.view.setUint16(this.pos,e),this.pos+=2}writeI16(e){this.ensureBufferSizeToWrite(2),this.view.setInt16(this.pos,e),this.pos+=2}writeU32(e){this.ensureBufferSizeToWrite(4),this.view.setUint32(this.pos,e),this.pos+=4}writeI32(e){this.ensureBufferSizeToWrite(4),this.view.setInt32(this.pos,e),this.pos+=4}writeF32(e){this.ensureBufferSizeToWrite(4),this.view.setFloat32(this.pos,e),this.pos+=4}writeF64(e){this.ensureBufferSizeToWrite(8),this.view.setFloat64(this.pos,e),this.pos+=8}writeU64(e){this.ensureBufferSizeToWrite(8),Qe(this.view,this.pos,e),this.pos+=8}writeI64(e){this.ensureBufferSizeToWrite(8),be(this.view,this.pos,e),this.pos+=8}writeBigUint64(e){this.ensureBufferSizeToWrite(8),this.view.setBigUint64(this.pos,e),this.pos+=8}writeBigInt64(e){this.ensureBufferSizeToWrite(8),this.view.setBigInt64(this.pos,e),this.pos+=8}}function ut(i,e){return new de(e).encodeSharedRef(i)}function le(i){return`${i<0?"-":""}0x${Math.abs(i).toString(16).padStart(2,"0")}`}const ft=16,wt=16;class xt{constructor(e=ft,t=wt){a(this,"hit",0);a(this,"miss",0);a(this,"caches");a(this,"maxKeyLength");a(this,"maxLengthPerKey");this.maxKeyLength=e,this.maxLengthPerKey=t,this.caches=[];for(let n=0;n<this.maxKeyLength;n++)this.caches.push([])}canBeCached(e){return e>0&&e<=this.maxKeyLength}find(e,t,n){const s=this.caches[n-1];e:for(const o of s){const r=o.bytes;for(let h=0;h<n;h++)if(r[h]!==e[t+h])continue e;return o.str}return null}store(e,t){const n=this.caches[e.length-1],s={bytes:e,str:t};n.length>=this.maxLengthPerKey?n[Math.random()*n.length|0]=s:n.push(s)}decode(e,t,n){const s=this.find(e,t,n);if(s!=null)return this.hit++,s;this.miss++;const o=ge(e,t,n),r=Uint8Array.prototype.slice.call(e,t,t+n);return this.store(r,o),o}}const he="array",X="map_key",ve="map_value",yt=i=>{if(typeof i=="string"||typeof i=="number")return i;throw new B("The type of key must be string or number but "+typeof i)};class gt{constructor(){a(this,"stack",[]);a(this,"stackHeadPosition",-1)}get length(){return this.stackHeadPosition+1}top(){return this.stack[this.stackHeadPosition]}pushArrayState(e){const t=this.getUninitializedStateFromPool();t.type=he,t.position=0,t.size=e,t.array=new Array(e)}pushMapState(e){const t=this.getUninitializedStateFromPool();t.type=X,t.readCount=0,t.size=e,t.map={}}getUninitializedStateFromPool(){if(this.stackHeadPosition++,this.stackHeadPosition===this.stack.length){const e={type:void 0,size:0,array:void 0,position:0,readCount:0,map:void 0,key:null};this.stack.push(e)}return this.stack[this.stackHeadPosition]}release(e){if(this.stack[this.stackHeadPosition]!==e)throw new Error("Invalid stack state. Released state is not on top of the stack.");if(e.type===he){const n=e;n.size=0,n.array=void 0,n.position=0,n.type=void 0}if(e.type===X||e.type===ve){const n=e;n.size=0,n.map=void 0,n.readCount=0,n.type=void 0}this.stackHeadPosition--}reset(){this.stack.length=0,this.stackHeadPosition=-1}}const Y=-1,pe=new DataView(new ArrayBuffer(0)),bt=new Uint8Array(pe.buffer);try{pe.getInt8(0)}catch(i){if(!(i instanceof RangeError))throw new Error("This module is not supported in the current JavaScript engine because DataView does not throw RangeError on out-of-bounds access")}const ke=new RangeError("Insufficient data"),mt=new xt;class ue{constructor(e){a(this,"extensionCodec");a(this,"context");a(this,"useBigInt64");a(this,"rawStrings");a(this,"maxStrLength");a(this,"maxBinLength");a(this,"maxArrayLength");a(this,"maxMapLength");a(this,"maxExtLength");a(this,"keyDecoder");a(this,"mapKeyConverter");a(this,"totalPos",0);a(this,"pos",0);a(this,"view",pe);a(this,"bytes",bt);a(this,"headByte",Y);a(this,"stack",new gt);a(this,"entered",!1);this.extensionCodec=(e==null?void 0:e.extensionCodec)??ee.defaultCodec,this.context=e==null?void 0:e.context,this.useBigInt64=(e==null?void 0:e.useBigInt64)??!1,this.rawStrings=(e==null?void 0:e.rawStrings)??!1,this.maxStrLength=(e==null?void 0:e.maxStrLength)??W,this.maxBinLength=(e==null?void 0:e.maxBinLength)??W,this.maxArrayLength=(e==null?void 0:e.maxArrayLength)??W,this.maxMapLength=(e==null?void 0:e.maxMapLength)??W,this.maxExtLength=(e==null?void 0:e.maxExtLength)??W,this.keyDecoder=(e==null?void 0:e.keyDecoder)!==void 0?e.keyDecoder:mt,this.mapKeyConverter=(e==null?void 0:e.mapKeyConverter)??yt}clone(){return new ue({extensionCodec:this.extensionCodec,context:this.context,useBigInt64:this.useBigInt64,rawStrings:this.rawStrings,maxStrLength:this.maxStrLength,maxBinLength:this.maxBinLength,maxArrayLength:this.maxArrayLength,maxMapLength:this.maxMapLength,maxExtLength:this.maxExtLength,keyDecoder:this.keyDecoder})}reinitializeState(){this.totalPos=0,this.headByte=Y,this.stack.reset()}setBuffer(e){const t=ce(e);this.bytes=t,this.view=new DataView(t.buffer,t.byteOffset,t.byteLength),this.pos=0}appendBuffer(e){if(this.headByte===Y&&!this.hasRemaining(1))this.setBuffer(e);else{const t=this.bytes.subarray(this.pos),n=ce(e),s=new Uint8Array(t.length+n.length);s.set(t),s.set(n,t.length),this.setBuffer(s)}}hasRemaining(e){return this.view.byteLength-this.pos>=e}createExtraByteError(e){const{view:t,pos:n}=this;return new RangeError(`Extra ${t.byteLength-n} of ${t.byteLength} byte(s) found at buffer[${e}]`)}decode(e){if(this.entered)return this.clone().decode(e);try{this.entered=!0,this.reinitializeState(),this.setBuffer(e);const t=this.doDecodeSync();if(this.hasRemaining(1))throw this.createExtraByteError(this.pos);return t}finally{this.entered=!1}}*decodeMulti(e){if(this.entered){yield*this.clone().decodeMulti(e);return}try{for(this.entered=!0,this.reinitializeState(),this.setBuffer(e);this.hasRemaining(1);)yield this.doDecodeSync()}finally{this.entered=!1}}async decodeAsync(e){if(this.entered)return this.clone().decodeAsync(e);try{this.entered=!0;let t=!1,n;for await(const h of e){if(t)throw this.entered=!1,this.createExtraByteError(this.totalPos);this.appendBuffer(h);try{n=this.doDecodeSync(),t=!0}catch(w){if(!(w instanceof RangeError))throw w}this.totalPos+=this.pos}if(t){if(this.hasRemaining(1))throw this.createExtraByteError(this.totalPos);return n}const{headByte:s,pos:o,totalPos:r}=this;throw new RangeError(`Insufficient data in parsing ${le(s)} at ${r} (${o} in the current buffer)`)}finally{this.entered=!1}}decodeArrayStream(e){return this.decodeMultiAsync(e,!0)}decodeStream(e){return this.decodeMultiAsync(e,!1)}async*decodeMultiAsync(e,t){if(this.entered){yield*this.clone().decodeMultiAsync(e,t);return}try{this.entered=!0;let n=t,s=-1;for await(const o of e){if(t&&s===0)throw this.createExtraByteError(this.totalPos);this.appendBuffer(o),n&&(s=this.readArraySize(),n=!1,this.complete());try{for(;yield this.doDecodeSync(),--s!==0;);}catch(r){if(!(r instanceof RangeError))throw r}this.totalPos+=this.pos}}finally{this.entered=!1}}doDecodeSync(){e:for(;;){const e=this.readHeadByte();let t;if(e>=224)t=e-256;else if(e<192)if(e<128)t=e;else if(e<144){const s=e-128;if(s!==0){this.pushMapState(s),this.complete();continue e}else t={}}else if(e<160){const s=e-144;if(s!==0){this.pushArrayState(s),this.complete();continue e}else t=[]}else{const s=e-160;t=this.decodeString(s,0)}else if(e===192)t=null;else if(e===194)t=!1;else if(e===195)t=!0;else if(e===202)t=this.readF32();else if(e===203)t=this.readF64();else if(e===204)t=this.readU8();else if(e===205)t=this.readU16();else if(e===206)t=this.readU32();else if(e===207)this.useBigInt64?t=this.readU64AsBigInt():t=this.readU64();else if(e===208)t=this.readI8();else if(e===209)t=this.readI16();else if(e===210)t=this.readI32();else if(e===211)this.useBigInt64?t=this.readI64AsBigInt():t=this.readI64();else if(e===217){const s=this.lookU8();t=this.decodeString(s,1)}else if(e===218){const s=this.lookU16();t=this.decodeString(s,2)}else if(e===219){const s=this.lookU32();t=this.decodeString(s,4)}else if(e===220){const s=this.readU16();if(s!==0){this.pushArrayState(s),this.complete();continue e}else t=[]}else if(e===221){const s=this.readU32();if(s!==0){this.pushArrayState(s),this.complete();continue e}else t=[]}else if(e===222){const s=this.readU16();if(s!==0){this.pushMapState(s),this.complete();continue e}else t={}}else if(e===223){const s=this.readU32();if(s!==0){this.pushMapState(s),this.complete();continue e}else t={}}else if(e===196){const s=this.lookU8();t=this.decodeBinary(s,1)}else if(e===197){const s=this.lookU16();t=this.decodeBinary(s,2)}else if(e===198){const s=this.lookU32();t=this.decodeBinary(s,4)}else if(e===212)t=this.decodeExtension(1,0);else if(e===213)t=this.decodeExtension(2,0);else if(e===214)t=this.decodeExtension(4,0);else if(e===215)t=this.decodeExtension(8,0);else if(e===216)t=this.decodeExtension(16,0);else if(e===199){const s=this.lookU8();t=this.decodeExtension(s,1)}else if(e===200){const s=this.lookU16();t=this.decodeExtension(s,2)}else if(e===201){const s=this.lookU32();t=this.decodeExtension(s,4)}else throw new B(`Unrecognized type byte: ${le(e)}`);this.complete();const n=this.stack;for(;n.length>0;){const s=n.top();if(s.type===he)if(s.array[s.position]=t,s.position++,s.position===s.size)t=s.array,n.release(s);else continue e;else if(s.type===X){if(t==="__proto__")throw new B("The key __proto__ is not allowed");s.key=this.mapKeyConverter(t),s.type=ve;continue e}else if(s.map[s.key]=t,s.readCount++,s.readCount===s.size)t=s.map,n.release(s);else{s.key=null,s.type=X;continue e}}return t}}readHeadByte(){return this.headByte===Y&&(this.headByte=this.readU8()),this.headByte}complete(){this.headByte=Y}readArraySize(){const e=this.readHeadByte();switch(e){case 220:return this.readU16();case 221:return this.readU32();default:{if(e<160)return e-144;throw new B(`Unrecognized array type byte: ${le(e)}`)}}}pushMapState(e){if(e>this.maxMapLength)throw new B(`Max length exceeded: map length (${e}) > maxMapLengthLength (${this.maxMapLength})`);this.stack.pushMapState(e)}pushArrayState(e){if(e>this.maxArrayLength)throw new B(`Max length exceeded: array length (${e}) > maxArrayLength (${this.maxArrayLength})`);this.stack.pushArrayState(e)}decodeString(e,t){return!this.rawStrings||this.stateIsMapKey()?this.decodeUtf8String(e,t):this.decodeBinary(e,t)}decodeUtf8String(e,t){var o;if(e>this.maxStrLength)throw new B(`Max length exceeded: UTF-8 byte length (${e}) > maxStrLength (${this.maxStrLength})`);if(this.bytes.byteLength<this.pos+t+e)throw ke;const n=this.pos+t;let s;return this.stateIsMapKey()&&((o=this.keyDecoder)!=null&&o.canBeCached(e))?s=this.keyDecoder.decode(this.bytes,n,e):s=Ze(this.bytes,n,e),this.pos+=t+e,s}stateIsMapKey(){return this.stack.length>0?this.stack.top().type===X:!1}decodeBinary(e,t){if(e>this.maxBinLength)throw new B(`Max length exceeded: bin length (${e}) > maxBinLength (${this.maxBinLength})`);if(!this.hasRemaining(e+t))throw ke;const n=this.pos+t,s=this.bytes.subarray(n,n+e);return this.pos+=t+e,s}decodeExtension(e,t){if(e>this.maxExtLength)throw new B(`Max length exceeded: ext length (${e}) > maxExtLength (${this.maxExtLength})`);const n=this.view.getInt8(this.pos+t),s=this.decodeBinary(e,t+1);return this.extensionCodec.decode(s,n,this.context)}lookU8(){return this.view.getUint8(this.pos)}lookU16(){return this.view.getUint16(this.pos)}lookU32(){return this.view.getUint32(this.pos)}readU8(){const e=this.view.getUint8(this.pos);return this.pos++,e}readI8(){const e=this.view.getInt8(this.pos);return this.pos++,e}readU16(){const e=this.view.getUint16(this.pos);return this.pos+=2,e}readI16(){const e=this.view.getInt16(this.pos);return this.pos+=2,e}readU32(){const e=this.view.getUint32(this.pos);return this.pos+=4,e}readI32(){const e=this.view.getInt32(this.pos);return this.pos+=4,e}readU64(){const e=et(this.view,this.pos);return this.pos+=8,e}readI64(){const e=me(this.view,this.pos);return this.pos+=8,e}readU64AsBigInt(){const e=this.view.getBigUint64(this.pos);return this.pos+=8,e}readI64AsBigInt(){const e=this.view.getBigInt64(this.pos);return this.pos+=8,e}readF32(){const e=this.view.getFloat32(this.pos);return this.pos+=4,e}readF64(){const e=this.view.getFloat64(this.pos);return this.pos+=8,e}}function vt(i,e){return new ue(e).decode(i)}const kt=new Set(["auth","open","send","sync","history","read","typing","react","edit","delete","invoke","pubkey","ping","annotate","annotate_clear"]);function St(i){return kt.has(i.type)}function It(i){return ut(i)}function Et(i){let e;try{e=vt(i)}catch{return null}return typeof e!="object"||e===null||typeof e.type!="string"?null:e}class Ct{constructor(e){a(this,"conversationId");a(this,"state","");a(this,"version",0);a(this,"hasMoreHistory",!1);a(this,"lastReadByOthers",0);a(this,"assignedAgentId");a(this,"accent");a(this,"subject");a(this,"name");a(this,"e2e",!1);a(this,"offline",!1);a(this,"offlineMessage","");a(this,"whiteLabel",!1);a(this,"typing",new Set);a(this,"online",new Set);a(this,"annotations",[]);a(this,"annotationVersion",0);a(this,"sentiment");a(this,"sentimentScore");a(this,"actions",[]);a(this,"byId",new Map);a(this,"keyByClient",new Map);a(this,"_maxSeq",0);a(this,"_sorted",null);this.me=e}messages(){return this._sorted||(this._sorted=[...this.byId.values()].sort((e,t)=>{const n=e.status==="pending",s=t.status==="pending";return n!==s?n?1:-1:n&&s?e.ts-t.ts:e.seq-t.seq})),this._sorted}visibleActions(){return this.actions.filter(e=>!e.availableInStates||e.availableInStates.includes(this.state))}highestSeq(){return this._maxSeq}addOptimistic(e,t){const n={id:e,conversationId:this.conversationId,seq:0,senderId:this.me,senderRole:"guest",content:t,ts:Date.now(),clientMsgId:e,status:"pending"};return this.byId.set(e,n),this.keyByClient.set(e,e),this._sorted=null,n}apply(e){var t;switch(e.type){case"opened":this.conversationId=e.conversation.id,this.state=e.conversation.state,e.subject&&(this.subject=e.subject),e.annotations&&(this.annotations=e.annotations,this.annotationVersion++);return;case"manifest":this.actions=e.actions,this.version=e.version,e.name&&(this.name=e.name),(t=e.theme)!=null&&t.accent&&(this.accent=e.theme.accent),e.e2e&&(this.e2e=!0),e.offline&&(this.offline=!0),e.offlineMessage&&(this.offlineMessage=e.offlineMessage),e.whiteLabel&&(this.whiteLabel=!0);return;case"message":this.upsert({...e.message});return;case"ack":{const n=this.keyByClient.get(e.clientMsgId),s=n?this.byId.get(n):void 0;if(s&&n){this.byId.delete(n);const o={...s,id:e.messageId,seq:e.seq,ts:e.ts,status:"sent"};this.byId.set(e.messageId,o),this.keyByClient.set(e.clientMsgId,e.messageId),e.seq>this._maxSeq&&(this._maxSeq=e.seq)}this._sorted=null;return}case"delivered":this.markOwnStatus(e.seq,"delivered");return;case"read":e.by!==this.me&&(this.lastReadByOthers=Math.max(this.lastReadByOthers,e.seq),this.markOwnStatus(e.seq,"read"));return;case"sync":for(const n of e.messages)this.upsert({...n});return;case"history":for(const n of e.messages)this.upsert({...n});this.hasMoreHistory=e.hasMore;return;case"typing":e.userId!==this.me&&(e.isTyping?this.typing.add(e.userId):this.typing.delete(e.userId));return;case"reaction":{const n=this.byId.get(e.messageId);if(!n)return;const s={...n.reactions??{}},o=(s[e.emoji]??[]).filter(r=>r!==e.by);e.removed||o.push(e.by),o.length?s[e.emoji]=o:delete s[e.emoji],this.byId.set(e.messageId,{...n,reactions:s}),this._sorted=null;return}case"edited":{const n=this.byId.get(e.messageId);n&&(this.byId.set(e.messageId,{...n,content:e.content,editedAt:e.editedAt}),this._sorted=null);return}case"deleted":{const n=this.byId.get(e.messageId);n&&(this.byId.set(e.messageId,{...n,deletedAt:e.ts}),this._sorted=null);return}case"state":this.state=e.state;return;case"assigned":this.assignedAgentId=e.agentId??void 0;return;case"presence":e.status==="online"?this.online.add(e.userId):this.online.delete(e.userId);return;case"subjectState":case"invoked":case"authed":case"error":case"pong":return;case"annotation":this.annotations=[...this.annotations,e.stroke],this.annotationVersion++;return;case"annotation_clear":this.annotations=[],this.annotationVersion++;return;case"sentiment":this.sentiment=e.label,this.sentimentScore=e.score;return;default:return}}upsert(e){const t=this.byId.get(e.id);this.byId.set(e.id,t?{...t,...e}:e),e.seq>this._maxSeq&&(this._maxSeq=e.seq),this._sorted=null}markOwnStatus(e,t){const n=Se(t);let s=!1;for(const[o,r]of this.byId)r.senderId!==this.me||r.seq<=0||r.seq>e||Se(r.status)>=n||(this.byId.set(o,{...r,status:t}),s=!0);s&&(this._sorted=null)}}function Se(i){switch(i){case"read":return 3;case"delivered":return 2;case"sent":return 1;default:return 0}}class Tt{constructor(e){a(this,"socket",null);a(this,"state","idle");a(this,"authed",!1);a(this,"everAuthed",!1);a(this,"attempt",0);a(this,"outbox",[]);a(this,"stopped",!1);a(this,"timer",null);this.opts=e}connect(){var n,s;if(this.state==="connecting"||this.state==="open")return;this.stopped=!1,this.state="connecting",this.authed=!1,(s=(n=this.opts).onStatusChange)==null||s.call(n,this.attempt>0?"reconnecting":"connecting");const t=(this.opts.socketFactory??At)(this.opts.url);t.binaryType="arraybuffer",this.socket=t,t.onopen=()=>{this.raw({type:"auth",token:this.opts.token})},t.onmessage=o=>{const r=Et(new Uint8Array(o.data));!r||St(r)||this.handle(r)},t.onclose=()=>this.onClosed(),t.onerror=()=>{try{t.close()}catch{}}}send(e){if(this.state==="open"&&this.authed){this.raw(e);return}const t=this.opts.maxOutbox??1e3;this.outbox.length>=t&&(this.outbox=this.outbox.slice(this.outbox.length-(t>>1))),this.outbox.push(e)}close(){var e;this.stopped=!0,this.timer&&clearTimeout(this.timer),this.state="closed";try{(e=this.socket)==null||e.close()}catch{}}handle(e){var t,n,s,o,r;if(e.type==="authed"&&(this.attempt=0,this.state="open",this.authed=!0,this.everAuthed=!0,(n=(t=this.opts).onStatusChange)==null||n.call(t,"open"),this.raw(this.opts.open),this.flush()),e.type==="opened"&&this.raw({type:"sync",conversationId:e.conversation.id,sinceSeq:this.opts.getCursor()}),e.type==="error"&&Ut.has(e.code)){this.stopped=!0;try{(s=this.socket)==null||s.close()}catch{}this.state="closed",(r=(o=this.opts).onStatusChange)==null||r.call(o,"error",Pt(e.code)),this.opts.onFrame(e);return}this.opts.onFrame(e)}flush(){const e=this.outbox;this.outbox=[];for(const t of e)this.raw(t)}raw(e){var t;try{(t=this.socket)==null||t.send(It(e))}catch{this.outbox.push(e)}}onClosed(){var s,o;if(this.authed=!1,this.socket=null,this.stopped){this.state="closed";return}this.state="idle";const e=this.opts.backoffBaseMs??500,t=this.opts.backoffMaxMs??15e3,n=Math.min(t,e*2**this.attempt)*(.5+Math.random()*.5);this.attempt++,this.attempt>=3&&!this.everAuthed&&((o=(s=this.opts).onStatusChange)==null||o.call(s,"reconnecting","Can't reach chat — retrying…")),this.timer=setTimeout(()=>this.connect(),n)}}const Ut=new Set(["UNAUTHORIZED"]);function Pt(i){switch(i){case"UNAUTHORIZED":return"Chat unavailable — sign-in/token was rejected";default:return"Chat unavailable"}}function At(i){return new WebSocket(i)}const Ie=200,Bt=7*864e5;class Kt{constructor(e){a(this,"key");this.key=`ocw_outbox_${e}`}load(){try{const e=localStorage.getItem(this.key);if(!e)return[];const t=JSON.parse(e),n=Date.now()-Bt,s=t.filter(o=>o.ts>=n);return s.length!==t.length&&this.save(s),s}catch{return[]}}add(e){try{const t=this.load();t.push(e),this.save(t.length>Ie?t.slice(t.length-Ie):t)}catch{}}remove(e){try{const t=this.load().filter(n=>n.clientMsgId!==e);this.save(t)}catch{}}save(e){try{localStorage.setItem(this.key,JSON.stringify(e))}catch{}}}const E=()=>globalThis.crypto.subtle;function te(i){const e=i instanceof Uint8Array?i:new Uint8Array(i);let t="";for(const n of e)t+=String.fromCharCode(n);return btoa(t)}function fe(i){const e=atob(i),t=new ArrayBuffer(e.length),n=new Uint8Array(t);for(let s=0;s<e.length;s++)n[s]=e.charCodeAt(s);return n}async function J(){const i=await E().generateKey({name:"ECDH",namedCurve:"P-256"},!0,["deriveKey","deriveBits"]);return{publicKey:i.publicKey,privateKey:i.privateKey}}async function _(i){return te(await E().exportKey("raw",i))}async function O(i){return E().importKey("raw",fe(i),{name:"ECDH",namedCurve:"P-256"},!1,[])}async function Lt(i,e){const t=await O(e);return E().deriveKey({name:"ECDH",public:t},i,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}async function zt(i,e){const t=globalThis.crypto.getRandomValues(new Uint8Array(12)),n=new TextEncoder().encode(e),s=await E().encrypt({name:"AES-GCM",iv:t},i,n);return{ct:te(s),iv:te(t)}}async function Mt(i,e,t){const n=await E().decrypt({name:"AES-GCM",iv:fe(t)},i,fe(e));return new TextDecoder().decode(n)}async function $t(i){var t,n;try{const s=(t=globalThis.localStorage)==null?void 0:t.getItem(i);if(s){const{pub:o,priv:r}=JSON.parse(s),h=await E().importKey("jwk",o,{name:"ECDH",namedCurve:"P-256"},!0,[]),w=await E().importKey("jwk",r,{name:"ECDH",namedCurve:"P-256"},!0,["deriveKey","deriveBits"]);return{publicKey:h,privateKey:w}}}catch{}const e=await J();try{const s=await E().exportKey("jwk",e.publicKey),o=await E().exportKey("jwk",e.privateKey);(n=globalThis.localStorage)==null||n.setItem(i,JSON.stringify({pub:s,priv:o}))}catch{}return e}async function Dt(i,e){const t=await E().exportKey("raw",e),n=await E().sign({name:"ECDSA",hash:"SHA-256"},i,t);return te(n)}async function _t(){const i=await J(),e=await E().generateKey({name:"ECDSA",namedCurve:"P-256"},!0,["sign","verify"]);return{ecdhKP:i,ecdsaKP:{publicKey:e.publicKey,privateKey:e.privateKey},publicKeyB64:await _(i.publicKey),sigPublicKeyB64:await _(e.publicKey)}}async function Ee(i){var t,n;try{const s=(t=globalThis.localStorage)==null?void 0:t.getItem(`${i}-identity`);if(s){const o=JSON.parse(s),r=await E().importKey("jwk",o.ecdhPub,{name:"ECDH",namedCurve:"P-256"},!0,[]),h=await E().importKey("jwk",o.ecdhPriv,{name:"ECDH",namedCurve:"P-256"},!0,["deriveKey","deriveBits"]),w=await E().importKey("jwk",o.ecdsaPub,{name:"ECDSA",namedCurve:"P-256"},!0,["verify"]),d=await E().importKey("jwk",o.ecdsaPriv,{name:"ECDSA",namedCurve:"P-256"},!0,["sign"]);return{ecdhKP:{publicKey:r,privateKey:h},ecdsaKP:{publicKey:w,privateKey:d},publicKeyB64:await _(r),sigPublicKeyB64:await _(w)}}}catch{}const e=await _t();try{const s=await E().exportKey("jwk",e.ecdhKP.publicKey),o=await E().exportKey("jwk",e.ecdhKP.privateKey),r=await E().exportKey("jwk",e.ecdsaKP.publicKey),h=await E().exportKey("jwk",e.ecdsaKP.privateKey);(n=globalThis.localStorage)==null||n.setItem(`${i}-identity`,JSON.stringify({ecdhPub:s,ecdhPriv:o,ecdsaPub:r,ecdsaPriv:h}))}catch{}return e}async function Rt(i,e){const t=await J(),n=await _(t.publicKey),s=await O(e.identityKey),o=await O(e.signedPrekey),r=e.oneTimePrekey?await O(e.oneTimePrekey):null,h=await R(i.privateKey,o),w=await R(t.privateKey,s),d=await R(t.privateKey,o),b=r?await R(t.privateKey,r):null,x=Ce(h,w,d,...b?[b]:[]);return{sharedKey:await Te(x),ephemeralPublicKey:n}}async function Ht(i,e,t,n,s){const o=await O(t),r=await O(n),h=await R(e.privateKey,o),w=await R(i.privateKey,r),d=await R(e.privateKey,r),b=s?await R(s.privateKey,r):null,x=Ce(h,w,d,...b?[b]:[]);return Te(x)}async function R(i,e){return E().deriveBits({name:"ECDH",public:e},i,256)}function Ce(...i){const e=i.reduce((s,o)=>s+o.byteLength,0),t=new Uint8Array(e);let n=0;for(const s of i)t.set(new Uint8Array(s),n),n+=s.byteLength;return t.buffer}async function Te(i){const e=await E().importKey("raw",i,"HKDF",!1,["deriveKey"]);return E().deriveKey({name:"HKDF",hash:"SHA-256",salt:new Uint8Array(32),info:new TextEncoder().encode("ObjectChat X3DH v1")},e,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}const jt=20;class Ft{constructor(e){a(this,"kp");a(this,"shared");a(this,"identityKP");a(this,"signedPreKP");a(this,"signedPrekeyId");a(this,"otpKeys",[]);a(this,"x3dhShared");a(this,"pendingX3DH");this.storageKey=e}get ready(){return!!(this.shared??this.x3dhShared)}async begin(){return this.kp=await $t(this.storageKey),_(this.kp.publicKey)}async onPeerKey(e){this.kp&&(this.shared=await Lt(this.kp.privateKey,e))}async initX3DH(){this.identityKP=await Ee(this.storageKey),this.signedPreKP=await J(),this.signedPrekeyId=`spk-${Date.now()}-${Math.random().toString(36).slice(2)}`;for(let s=0;s<jt;s++)this.otpKeys.push(await J());const e=await _(this.signedPreKP.publicKey),t=await Dt(this.identityKP.ecdsaKP.privateKey,this.signedPreKP.publicKey),n=await Promise.all(this.otpKeys.map(s=>_(s.publicKey)));return{identityKey:this.identityKP.publicKeyB64,signedPrekey:e,signedPrekeyId:this.signedPrekeyId,signature:t,oneTimePrekeys:n}}async x3dhSendTo(e){this.identityKP||(this.identityKP=await Ee(this.storageKey));const{sharedKey:t,ephemeralPublicKey:n}=await Rt(this.identityKP.ecdhKP,e);return this.x3dhShared=t,{ephemeralKey:n,spkId:e.signedPrekeyId,usedOTP:!!e.oneTimePrekey,senderIK:this.identityKP.publicKeyB64}}async x3dhReceiveFrom(e,t,n){if(!this.identityKP||!this.signedPreKP){this.pendingX3DH={senderIK:e,ephemeralKey:t,spkId:n};return}const s=this.otpKeys.shift();this.x3dhShared=await Ht(this.identityKP.ecdhKP,this.signedPreKP,e,t,s)}async flushPendingX3DH(){if(!this.pendingX3DH)return;const{senderIK:e,ephemeralKey:t,spkId:n}=this.pendingX3DH;this.pendingX3DH=void 0,await this.x3dhReceiveFrom(e,t,n)}async sealText(e,t){const n=this.x3dhShared??this.shared;if(!n)throw new Error("secure channel not ready");const{ct:s,iv:o}=await zt(n,e);return{kind:"text",text:s,enc:!0,iv:o,...t?{x3dhEK:t.ephemeralKey,x3dhSPK:t.spkId,x3dhIK:t.senderIK}:{}}}async openContent(e){if(e.kind!=="text"||!e.enc||!e.iv)return e;const t=this.x3dhShared??this.shared;if(!t)return{kind:"text",text:"🔒 encrypted"};try{return{kind:"text",text:await Mt(t,e.text,e.iv)}}catch{return{kind:"text",text:"🔒 unable to decrypt"}}}async openFrame(e){if(e.type==="message")e.message.content=await this.openContent(e.message.content);else if(e.type==="sync")for(const t of e.messages)t.content=await this.openContent(t.content)}}function qt(i){if(i.kind!=="text"||!i.enc)return null;const e=i;return!e.x3dhEK||!e.x3dhSPK||!e.x3dhIK?null:{x3dhEK:e.x3dhEK,x3dhSPK:e.x3dhSPK,x3dhIK:e.x3dhIK}}const Ue="objectchat-widget-styles",Ot=["👍","❤️","😂","😮","😢","🙏"],Nt=`
2
+ .ocw { --ocw-accent:#4F63F5; --ocw-bg:#f3efe9; --ocw-card:#fff; --ocw-line:#ececec; --ocw-ink:#1c1b1a; --ocw-mut:#9b9690;
3
+ position:relative;
4
+ display:flex; flex-direction:column; height:100%; min-height:320px; background:var(--ocw-bg);
5
+ font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif; color:var(--ocw-ink); overflow:hidden; }
6
+ @media (max-width:480px) {
7
+ .ocw { min-height:100dvh; border-radius:0 !important; }
8
+ .ocw-bubble { font-size:15px; }
9
+ .ocw-input textarea { font-size:16px; } /* prevent iOS zoom on focus */
10
+ .ocw-chip { padding:9px 14px; font-size:14px; }
11
+ .ocw-modal-card { width:90%; }
12
+ .ocw-row { max-width:94%; }
13
+ }
14
+ /* RTL support: when the host element has dir=rtl, flip layout direction */
15
+ [dir="rtl"] .ocw-row.mine { flex-direction:row; }
16
+ [dir="rtl"] .ocw-row.theirs { flex-direction:row-reverse; }
17
+ [dir="rtl"] .mine .ocw-bubble { border-bottom-right-radius:18px; border-bottom-left-radius:6px; }
18
+ [dir="rtl"] .theirs .ocw-bubble { border-bottom-left-radius:18px; border-bottom-right-radius:6px; }
19
+ [dir="rtl"] .ocw-input { flex-direction:row-reverse; }
20
+ [dir="rtl"] .mine .ocw-meta { text-align:left; }
21
+ .ocw-head { display:flex; align-items:center; gap:10px; padding:12px 14px; background:var(--ocw-card); border-bottom:1px solid var(--ocw-line); }
22
+ .ocw-avatar { width:34px; height:34px; border-radius:50%; background:#ffe9d6; display:flex; align-items:center; justify-content:center; font-size:17px; flex:none; }
23
+ .ocw-head-main { flex:1; min-width:0; }
24
+ .ocw-head-name { font-weight:700; font-size:15px; }
25
+ .ocw-head-meta { color:var(--ocw-mut); font-size:12px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
26
+ .ocw-badge { font-size:12px; font-weight:600; color:#15803d; background:#e8f6ec; border-radius:999px; padding:3px 10px; }
27
+ .ocw-e2e { font-size:11px; font-weight:700; color:#3730a3; background:#eef2ff; border-radius:999px; padding:3px 9px; align-items:center; }
28
+ .ocw-menu { color:var(--ocw-mut); width:30px; height:30px; border-radius:50%; border:1px solid var(--ocw-line); background:#fff; cursor:pointer; }
29
+ .ocw-chiprow { display:flex; gap:8px; padding:10px 12px; background:var(--ocw-card); border-bottom:1px solid var(--ocw-line); overflow-x:auto; }
30
+ .ocw-chip { flex:none; display:flex; align-items:center; gap:6px; border:1px solid #e3ded7; background:#fff; border-radius:999px; padding:7px 13px; font-size:13px; font-weight:600; cursor:pointer; white-space:nowrap; }
31
+ .ocw-chip:hover { border-color:var(--ocw-accent); color:var(--ocw-accent); }
32
+ .ocw-scroll { flex:1; min-height:0; overflow-y:auto; padding:16px 14px; display:flex; flex-direction:column; gap:10px; }
33
+ .ocw-subject { background:var(--ocw-card); border:1px solid var(--ocw-line); border-radius:16px; padding:14px 16px; }
34
+ .ocw-subject-title { font-weight:700; font-size:16px; margin-bottom:2px; }
35
+ .ocw-subject-sub { color:var(--ocw-mut); font-size:13px; margin-bottom:10px; }
36
+ .ocw-tags { display:flex; flex-wrap:wrap; gap:6px; }
37
+ .ocw-tag { font-size:12px; color:#5b554e; background:#efeae3; border-radius:8px; padding:4px 10px; }
38
+ .ocw-row { display:flex; align-items:flex-end; gap:8px; max-width:86%; }
39
+ .ocw-row.mine { align-self:flex-end; flex-direction:row-reverse; }
40
+ .ocw-row.theirs { align-self:flex-start; }
41
+ .ocw-dot { width:26px; height:26px; border-radius:50%; background:var(--ocw-accent); color:#fff; font-size:12px; font-weight:700; display:flex; align-items:center; justify-content:center; flex:none; }
42
+ .ocw-bubble { padding:10px 14px; border-radius:18px; font-size:14.5px; line-height:1.4; word-wrap:break-word; }
43
+ .theirs .ocw-bubble { background:#fff; border:1px solid var(--ocw-line); border-bottom-left-radius:6px; }
44
+ .mine .ocw-bubble { background:var(--ocw-accent); color:#fff; border-bottom-right-radius:6px; }
45
+ .ocw-sys { align-self:center; color:var(--ocw-mut); font-size:12.5px; font-style:italic; text-align:center; max-width:90%; }
46
+ .ocw-bot .ocw-bubble { background:#f0fdf4; border-color:#cdebd6; }
47
+ .ocw-note .ocw-bubble { background:#fffbeb; border:1.5px dashed #f59e0b; color:#78350f; border-radius:12px !important; }
48
+ .ocw-note .ocw-bubble::before { content:'🔒 Note — '; font-size:11px; font-weight:700; color:#b45309; display:block; margin-bottom:3px; letter-spacing:.3px; }
49
+ .ocw-time { font-size:10.5px; color:var(--ocw-mut); margin-top:3px; }
50
+ .mine .ocw-meta { text-align:right; }
51
+ .ocw-tick { margin-left:4px; font-size:11px; color:var(--ocw-mut); }
52
+ .ocw-tick.read { color:#3b82f6; }
53
+ .ocw-tick.delivered { color:var(--ocw-mut); }
54
+ .ocw-deleted { font-style:italic; color:var(--ocw-mut); }
55
+ .ocw-edited { font-size:10px; color:var(--ocw-mut); margin-left:4px; }
56
+ .ocw-react { font-size:12px; margin-top:3px; display:flex; flex-wrap:wrap; gap:3px; }
57
+ .ocw-react-pill { display:inline-flex; align-items:center; gap:3px; border:1px solid #e3ded7; border-radius:999px; padding:2px 7px; background:#fff; font-size:12px; cursor:pointer; }
58
+ .ocw-react-pill:hover { border-color:var(--ocw-accent); }
59
+ .ocw-react-pill.mine { border-color:var(--ocw-accent); background:#fff8f5; }
60
+ .ocw-react-add { display:none; position:absolute; bottom:100%; left:0; margin-bottom:4px; background:#fff; border:1px solid #e3ded7; border-radius:14px; padding:6px 8px; box-shadow:0 4px 16px rgba(0,0,0,.12); display:flex; gap:4px; z-index:10; }
61
+ .ocw-react-wrap { position:relative; }
62
+ .ocw-react-wrap:not(:hover) .ocw-react-picker { display:none; }
63
+ .ocw-react-picker { position:absolute; bottom:calc(100% + 4px); left:0; background:#fff; border:1px solid #e3ded7; border-radius:14px; padding:6px 8px; box-shadow:0 4px 16px rgba(0,0,0,.12); display:flex; gap:4px; z-index:10; white-space:nowrap; }
64
+ .ocw-react-picker button { background:none; border:none; font-size:16px; cursor:pointer; padding:2px; border-radius:6px; }
65
+ .ocw-react-picker button:hover { background:#f3efe9; }
66
+ .ocw-react-btn { background:none; border:1px solid #e3ded7; border-radius:999px; padding:2px 7px; font-size:12px; cursor:pointer; color:var(--ocw-mut); }
67
+ .ocw-react-btn:hover { border-color:var(--ocw-accent); color:var(--ocw-accent); }
68
+ .ocw-msg-menu { position:absolute; top:0; right:0; display:none; gap:3px; }
69
+ .ocw-row.mine:hover .ocw-msg-menu { display:flex; }
70
+ .ocw-row.theirs:hover .ocw-msg-menu { display:flex; left:0; right:auto; }
71
+ .ocw-msg-menu button { background:#fff; border:1px solid #e3ded7; border-radius:6px; font-size:11px; padding:2px 6px; cursor:pointer; color:var(--ocw-mut); }
72
+ .ocw-msg-menu button:hover { border-color:var(--ocw-accent); color:var(--ocw-accent); }
73
+ .ocw-msg-menu button.del:hover { border-color:#e74c3c; color:#e74c3c; }
74
+ .ocw-bubble-wrap { position:relative; }
75
+ .ocw-seen { font-size:10.5px; color:var(--ocw-mut); }
76
+ .ocw-appt { background:#f0f7ff; border:1px solid #c7deff; border-radius:12px; padding:12px 14px; max-width:260px; }
77
+ .ocw-appt-title { font-weight:700; font-size:14px; margin-bottom:4px; }
78
+ .ocw-appt-time { font-size:12px; color:#1d4ed8; margin-bottom:4px; }
79
+ .ocw-appt-loc { font-size:12px; color:var(--ocw-mut); margin-bottom:4px; }
80
+ .ocw-appt-desc { font-size:12px; color:var(--ocw-mut); margin-bottom:10px; white-space:pre-wrap; }
81
+ .ocw-appt-links { display:flex; flex-direction:column; gap:6px; }
82
+ .ocw-appt-btn { display:block; text-align:center; padding:8px 12px; border-radius:8px; font-size:13px; font-weight:600; text-decoration:none; background:var(--ocw-accent); color:#fff; }
83
+ .ocw-appt-btn-sec { background:#fff; color:var(--ocw-accent); border:1px solid var(--ocw-accent); }
84
+ .ocw-conn-status { font-size:10px; color:var(--ocw-mut); margin-left:4px; }
85
+ .ocw-conn-status.warn { color:#e67e22; }
86
+ .ocw-conn-status.err { color:#c0392b; font-weight:600; }
87
+ .ocw-load-more { display:block; width:100%; background:none; border:1px solid #e3ded7; border-radius:10px; padding:6px 0; font-size:12px; color:var(--ocw-mut); cursor:pointer; margin-bottom:8px; }
88
+ .ocw-load-more:hover { border-color:var(--ocw-accent); color:var(--ocw-accent); }
89
+ .ocw-offline { margin:20px 14px; padding:20px; background:#fff; border:1px solid #e3ded7; border-radius:16px; text-align:center; }
90
+ .ocw-offline-icon { font-size:32px; margin-bottom:8px; }
91
+ .ocw-offline-title { font-weight:700; font-size:16px; margin-bottom:6px; }
92
+ .ocw-offline-msg { font-size:13px; color:var(--ocw-mut); margin-bottom:16px; }
93
+ .ocw-offline-form { display:flex; flex-direction:column; gap:8px; text-align:left; }
94
+ .ocw-offline-input { border:1px solid #e3ded7; border-radius:10px; padding:10px 12px; font-size:13px; font-family:inherit; }
95
+ .ocw-offline-input:focus { outline:none; border-color:var(--ocw-accent); }
96
+ .ocw-offline-submit { background:var(--ocw-accent); color:#fff; border:none; border-radius:10px; padding:11px; font-size:14px; font-weight:600; cursor:pointer; }
97
+ .ocw-offline-thanks { font-size:14px; color:#15803d; font-weight:600; }
98
+ .ocw-csat-title { font-size:13px; font-weight:600; margin-bottom:8px; }
99
+ .ocw-csat-stars { display:flex; gap:6px; }
100
+ .ocw-csat-star { background:none; border:none; font-size:22px; cursor:pointer; padding:2px; opacity:.4; transition:opacity .15s; }
101
+ .ocw-csat-star:hover, .ocw-csat-star.lit { opacity:1; }
102
+ .ocw-csat-done { font-size:12px; color:var(--ocw-mut); margin-top:6px; }
103
+
104
+ .ocw-typing { min-height:22px; padding:0 16px 4px; display:flex; align-items:center; }
105
+ .ocw-typing-bubble { display:none; align-items:center; gap:3px; background:#fff; border:1px solid var(--ocw-line); border-radius:14px; border-bottom-left-radius:4px; padding:7px 12px; }
106
+ .ocw-typing.active .ocw-typing-bubble { display:flex; }
107
+ .ocw-typing-dot { width:6px; height:6px; border-radius:50%; background:var(--ocw-mut); animation:ocw-bounce 1.2s infinite ease-in-out; }
108
+ .ocw-typing-dot:nth-child(2) { animation-delay:.2s; }
109
+ .ocw-typing-dot:nth-child(3) { animation-delay:.4s; }
110
+ @keyframes ocw-bounce { 0%,60%,100%{transform:translateY(0)} 30%{transform:translateY(-5px)} }
111
+ .ocw-quick { display:flex; gap:8px; padding:8px 12px 6px; overflow-x:auto; scrollbar-width:none; flex-shrink:0; }
112
+ .ocw-quick::-webkit-scrollbar { display:none; }
113
+ .ocw-quick button { flex:none; border:1px solid #e3ded7; background:#fff; border-radius:999px; padding:7px 14px; font-size:13px; cursor:pointer; color:#444; white-space:nowrap; transition:border-color .12s,color .12s; }
114
+ .ocw-quick button:hover { border-color:var(--ocw-accent); color:var(--ocw-accent); }
115
+ .ocw-form-host:empty { display:none; }
116
+ .ocw-form { margin:6px 12px 0; padding:12px; background:var(--ocw-card); border:1px solid var(--ocw-line); border-radius:14px; }
117
+ .ocw-form-title { font-weight:700; font-size:14px; margin-bottom:8px; }
118
+ .ocw-form-row { display:flex; flex-direction:column; gap:3px; margin-bottom:8px; }
119
+ .ocw-form-lbl { font-size:12px; color:var(--ocw-mut); }
120
+ .ocw-form-input { border:1px solid #e3ded7; border-radius:9px; padding:9px 11px; font:inherit; font-size:14px; outline:none; }
121
+ .ocw-form-input:focus { border-color:var(--ocw-accent); }
122
+ .ocw-form-actions { display:flex; justify-content:flex-end; gap:8px; margin-top:4px; }
123
+ .ocw-form-cancel { background:none; border:none; color:var(--ocw-mut); font-size:13px; cursor:pointer; padding:8px 10px; }
124
+ .ocw-form-submit { background:var(--ocw-accent); color:#fff; border:none; border-radius:999px; padding:8px 18px; font-size:13px; font-weight:600; cursor:pointer; }
125
+ .ocw-modal { position:absolute; inset:0; background:rgba(20,18,16,.42); display:flex; align-items:center; justify-content:center; z-index:50; }
126
+ .ocw-modal-card { background:#fff; border-radius:16px; padding:20px; width:78%; max-width:300px; box-shadow:0 14px 44px rgba(0,0,0,.22); }
127
+ .ocw-modal-title { font-weight:700; font-size:16px; margin-bottom:6px; }
128
+ .ocw-modal-body { color:var(--ocw-mut); font-size:14px; margin-bottom:16px; }
129
+ .ocw-modal-actions { display:flex; justify-content:flex-end; gap:8px; }
130
+ .ocw-modal-cancel { background:none; border:none; color:var(--ocw-mut); font-size:14px; cursor:pointer; padding:9px 12px; }
131
+ .ocw-modal-ok { background:var(--ocw-accent); color:#fff; border:none; border-radius:999px; padding:9px 20px; font-size:14px; font-weight:600; cursor:pointer; }
132
+ .ocw-input { display:flex; align-items:center; gap:10px; padding:12px; }
133
+ .ocw-footer { text-align:center; font-size:11px; color:var(--ocw-mut); padding:6px 0 8px; }
134
+ .ocw-footer a { color:var(--ocw-mut); text-decoration:none; font-weight:600; }
135
+ .ocw-footer a:hover { color:var(--ocw-accent); }
136
+ .ocw-attach { background:none;border:none;cursor:pointer;font-size:18px;padding:4px 6px;opacity:.6;flex-none; }
137
+ .ocw-attach:hover { opacity:1; }
138
+ .ocw-input textarea { flex:1; resize:none; border:1px solid #e3ded7; border-radius:22px; padding:11px 16px; font:inherit; font-size:14px; background:#fff; outline:none; max-height:96px; }
139
+ .ocw-input textarea:focus { border-color:var(--ocw-accent); }
140
+ .ocw-sendbtn { width:42px; height:42px; border-radius:50%; border:none; background:var(--ocw-accent); color:#fff; font-size:18px; cursor:pointer; flex:none; display:flex; align-items:center; justify-content:center; }
141
+ .ocw-sendbtn:disabled { opacity:.5; cursor:default; }
142
+ .ocw-cobrowse-btn { display:none; }
143
+ .ocw-cobrowse-btn.show { display:inline-flex; }
144
+ .ocw-cobrowse-btn.on { color:var(--ocw-accent); border-color:var(--ocw-accent); }
145
+ .ocw-cobrowse-canvas { position:absolute; inset:0; z-index:40; touch-action:none; display:none; }
146
+ .ocw-cobrowse-canvas.active { display:block; cursor:crosshair; }
147
+ .ocw-cobrowse-toolbar { position:absolute; top:8px; right:8px; z-index:41; display:none; gap:6px; background:rgba(255,255,255,.92); border-radius:999px; padding:5px 8px; box-shadow:0 2px 10px rgba(0,0,0,.12); }
148
+ .ocw-cobrowse-toolbar.active { display:flex; align-items:center; }
149
+ .ocw-cobrowse-swatch { width:18px; height:18px; border-radius:50%; border:2px solid transparent; cursor:pointer; padding:0; }
150
+ .ocw-cobrowse-swatch.sel { border-color:#1c1b1a; }
151
+ .ocw-cobrowse-clear { background:none; border:1px solid #e3ded7; border-radius:999px; font-size:11px; padding:3px 8px; cursor:pointer; color:var(--ocw-mut); }
152
+ .ocw-cobrowse-clear:hover { border-color:#e74c3c; color:#e74c3c; }
153
+ .ocw-cobrowse-hint { position:absolute; bottom:8px; left:8px; z-index:41; font-size:11px; color:var(--ocw-mut); background:rgba(255,255,255,.9); border-radius:8px; padding:3px 8px; display:none; }
154
+ .ocw-cobrowse-hint.active { display:block; }
155
+
156
+ .ocw-translate-btn { position:absolute; bottom:2px; right:-26px; background:#fff; border:1px solid #e3ded7; border-radius:50%; width:22px; height:22px; font-size:11px; cursor:pointer; color:var(--ocw-mut); display:flex; align-items:center; justify-content:center; opacity:0; transition:opacity .15s; padding:0; }
157
+ .ocw-row.theirs .ocw-translate-btn { right:auto; left:-26px; }
158
+ .ocw-bubble-wrap:hover .ocw-translate-btn { opacity:1; }
159
+ .ocw-translated-tag { font-size:10px; color:var(--ocw-mut); margin-top:2px; }
160
+ `;function Vt(){if(typeof document>"u"||document.getElementById(Ue))return;const i=document.createElement("style");i.id=Ue,i.textContent=Nt,document.head.appendChild(i)}function c(i,e,t){const n=document.createElement(i);return e&&(n.className=e),t!==void 0&&(n.textContent=t),n}function Wt(i){try{return new Date(i).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}catch{return""}}function we(i){var e;switch(i.kind){case"text":return i.text;case"system":return typeof((e=i.data)==null?void 0:e.message)=="string"?String(i.data.message):i.event;case"card":return[i.title,i.body].filter(Boolean).join(" — ");case"attachment":return i.name??i.url;case"form":return i.prompt;case"appointment":return`📅 ${i.title} — ${new Date(i.startIso).toLocaleString()}`}}class Xt{constructor(e,t,n,s={}){a(this,"scroll");a(this,"chips");a(this,"typing");a(this,"quick");a(this,"formHost");a(this,"csatPanel");a(this,"offlinePanel");a(this,"footer");a(this,"input");a(this,"subjectCard");a(this,"e2eBadge");a(this,"statusBadge");a(this,"headerName");a(this,"connStatus");a(this,"typingTimer",null);a(this,"csatSubmitted",!1);a(this,"cobrowseBtn");a(this,"cobrowseCanvas");a(this,"cobrowseToolbar");a(this,"cobrowseHint");a(this,"cobrowseActive",!1);a(this,"cobrowseColor","#f5713c");a(this,"lastAnnotationVersion",-1);a(this,"storeRef",null);a(this,"scrollCleanup",null);a(this,"translationCache",new Map);a(this,"showingTranslation",new Set);a(this,"subjectBuilt",!1);var k,g,U,K,P,L,m,I,j;this.root=e,this.me=t,this.h=n,this.cfg=s,Vt(),e.replaceChildren(),e.classList.add("ocw"),s.accent&&e.style.setProperty("--ocw-accent",s.accent);const o=c("div","ocw-head"),r=c("div","ocw-avatar");if((k=s.userInfo)!=null&&k.avatar){const S=document.createElement("img");S.src=s.userInfo.avatar,S.alt=s.userInfo.name??"You",S.style.cssText="width:100%;height:100%;border-radius:50%;object-fit:cover",r.append(S)}else r.textContent=(g=s.userInfo)!=null&&g.name?s.userInfo.name[0].toUpperCase():"🧑";o.append(r);const h=c("div","ocw-head-main");this.headerName=c("div","ocw-head-name",((U=s.subject)==null?void 0:U.ownerLabel)??((K=s.subject)==null?void 0:K.title)??""),h.append(this.headerName),(P=s.subject)!=null&&P.subtitle&&h.append(c("div","ocw-head-meta",s.subject.subtitle)),o.append(h),this.statusBadge=c("span","ocw-badge",((L=s.subject)==null?void 0:L.status)??""),(m=s.subject)!=null&&m.status||(this.statusBadge.style.display="none"),o.append(this.statusBadge),this.e2eBadge=c("span","ocw-e2e","🔒 E2E"),this.e2eBadge.style.display="none",o.append(this.e2eBadge),this.connStatus=c("span","ocw-conn-status"),this.connStatus.style.display="none",o.append(this.connStatus),this.cobrowseBtn=c("button","ocw-menu ocw-cobrowse-btn","🖍"),this.cobrowseBtn.title="Shared whiteboard — draw to point things out together",this.cobrowseBtn.addEventListener("click",()=>{this.cobrowseActive=!this.cobrowseActive,this.updateCobrowseUI()}),o.append(this.cobrowseBtn),o.append(c("button","ocw-menu","⋯")),this.chips=c("div","ocw-chiprow"),this.scroll=c("div","ocw-scroll"),this.subjectCard=c("div","ocw-subject"),this.typing=c("div","ocw-typing");const w=c("div","ocw-typing-bubble");w.append(c("div","ocw-typing-dot"),c("div","ocw-typing-dot"),c("div","ocw-typing-dot")),this.typing.append(c("div","ocw-dot","🧑"),w),this.quick=c("div","ocw-quick");for(const S of s.quickReplies??[]){const T=c("button",void 0,S);T.addEventListener("click",()=>{this.h.onSend(S),this.quick.style.display="none"}),this.quick.append(T)}this.formHost=c("div","ocw-form-host"),this.csatPanel=c("div","ocw-csat"),this.csatPanel.style.display="none",this.offlinePanel=c("div","ocw-offline"),this.offlinePanel.style.display="none",this.input=c("textarea",void 0),this.input.rows=1,this.input.placeholder="Message…";const d=c("button","ocw-sendbtn",((I=s.i18n)==null?void 0:I.send)??"➤");d.addEventListener("click",()=>this.flushSend()),this.input.addEventListener("keydown",S=>{S.isComposing||S.keyCode===229||(S.key==="Enter"&&!S.shiftKey?(S.preventDefault(),this.flushSend()):this.signalTyping())});const b=c("button","ocw-attach","📎");b.title="Attach image or file";const x=document.createElement("input");x.type="file",x.accept="image/*,.pdf,.txt,.doc,.docx",x.style.display="none",b.addEventListener("click",()=>x.click()),x.addEventListener("change",()=>{var S;(S=x.files)!=null&&S[0]&&this.h.onAttach&&this.h.onAttach(x.files[0]),x.value=""});const f=c("div","ocw-input");f.append(b,x,this.input,d);const p=c("div","ocw-footer");((j=s.i18n)==null?void 0:j.poweredBy)!==void 0?p.textContent=s.i18n.poweredBy:p.innerHTML='Powered by <a href="https://relay.paramms.com" target="_blank" rel="noopener">Relay</a>',this.footer=p,e.append(o,this.chips,this.scroll,this.typing,this.quick,this.formHost,this.csatPanel,this.offlinePanel,f,this.footer),this.cobrowseCanvas=c("canvas","ocw-cobrowse-canvas"),this.cobrowseToolbar=c("div","ocw-cobrowse-toolbar");for(const S of["#f5713c","#1c1b1a","#2563eb","#16a34a","#dc2626"]){const T=c("button","ocw-cobrowse-swatch");T.style.background=S,T.type="button",S===this.cobrowseColor&&T.classList.add("sel"),T.addEventListener("click",()=>{this.cobrowseColor=S;for(const se of this.cobrowseToolbar.querySelectorAll(".ocw-cobrowse-swatch"))se.classList.remove("sel");T.classList.add("sel")}),this.cobrowseToolbar.append(T)}const v=c("button","ocw-cobrowse-clear","Clear");v.addEventListener("click",()=>{var S,T;return(T=(S=this.h).onAnnotateClear)==null?void 0:T.call(S)}),this.cobrowseToolbar.append(v),this.cobrowseHint=c("div","ocw-cobrowse-hint","🖍 Draw to point things out — visible to both sides"),e.append(this.cobrowseCanvas,this.cobrowseToolbar,this.cobrowseHint),this.bindCobrowsePointerEvents()}getScrollEl(){return this.scroll}setScrollCleanup(e){var t;(t=this.scrollCleanup)==null||t.call(this),this.scrollCleanup=e}destroy(){var e;(e=this.scrollCleanup)==null||e.call(this),this.scrollCleanup=null,this.typingTimer&&(clearTimeout(this.typingTimer),this.typingTimer=null)}flushSend(){const e=this.input.value.trim();e&&(this.input.value="",this.h.onTyping(!1),this.h.onSend(e))}signalTyping(){const e=this.input.value.trim().slice(0,100)||void 0;this.h.onTyping(!0,e),this.typingTimer&&clearTimeout(this.typingTimer),this.typingTimer=setTimeout(()=>this.h.onTyping(!1),2e3)}render(e){var d,b,x;if(this.storeRef=e,this.cobrowseBtn.classList.toggle("show",!!e.subject),!e.subject&&this.cobrowseActive&&(this.cobrowseActive=!1,this.updateCobrowseUI()),this.cobrowseActive&&e.annotationVersion!==this.lastAnnotationVersion&&(this.lastAnnotationVersion=e.annotationVersion,this.resizeCobrowseCanvas(),this.redrawCobrowse()),e.accent&&this.root.style.setProperty("--ocw-accent",e.accent),this.e2eBadge.style.display=e.e2e?"inline-flex":"none",this.buildSubjectCard(e),e.subject){const f=(d=this.cfg.subject)==null?void 0:d.ownerLabel;f&&(this.headerName.textContent=f)}this.quick.style.display=e.messages().length===0?"flex":"none",this.chips.replaceChildren();const t=e.visibleActions();this.chips.style.display=t.length?"flex":"none";for(const f of t)this.chips.append(this.chipEl(f));const n=this.scroll.scrollHeight,s=this.scroll.scrollTop;if(this.scroll.replaceChildren(),this.subjectCard.childNodes.length&&this.scroll.append(this.subjectCard),e.hasMoreHistory){const f=c("div","ocw-load-more");f.textContent="↑ Loading earlier messages…",f.style.pointerEvents="none",this.scroll.append(f)}let o=0;for(const f of e.messages())this.scroll.append(this.messageEl(f,e)),f.senderId!==this.me&&f.seq>o&&(o=f.seq);s>20?this.scroll.scrollTop=this.scroll.scrollHeight-n+s:this.scroll.scrollTop=this.scroll.scrollHeight,o>0&&this.h.onReadUpTo(o);const r=[...e.typing];this.typing.classList.toggle("active",r.length>0);const h=this.typing.querySelector(".ocw-typing-bubble");h&&h.setAttribute("aria-label",r.length?"typing":""),this.footer.style.display=e.whiteLabel?"none":"block",e.offline?(this.offlinePanel.style.display==="none"&&this.buildOfflinePanel(e.offlineMessage),this.offlinePanel.style.display="block",(b=this.root.querySelector(".ocw-input"))==null||b.style.setProperty("display","none")):(this.offlinePanel.style.display="none",(x=this.root.querySelector(".ocw-input"))==null||x.style.removeProperty("display"));const w=["resolved","closed","sold","issued","checked_out"];this.h.onCsat&&!this.csatSubmitted&&w.includes(e.state)&&e.messages().length>0&&(this.csatPanel.style.display==="none"&&this.buildCsatPanel(),this.csatPanel.style.display="block")}setConnStatus(e,t){if(e==="open"){this.connStatus.style.display="none";return}this.connStatus.style.display="";const n=e==="error";this.connStatus.className=`ocw-conn-status${n?" err":e==="reconnecting"?" warn":""}`,this.connStatus.textContent=n?`⚠ ${t??"Chat unavailable"}`:e==="reconnecting"?t??"↻ reconnecting…":"● connecting…"}buildOfflinePanel(e){var h;this.offlinePanel.replaceChildren(),this.offlinePanel.append(c("div","ocw-offline-icon","🌙")),this.offlinePanel.append(c("div","ocw-offline-title",((h=this.cfg.i18n)==null?void 0:h.offline)??"We're offline right now")),this.offlinePanel.append(c("div","ocw-offline-msg",e||"Leave your details and we'll get back to you soon."));const t=c("div","ocw-offline-form"),n=c("input","ocw-offline-input");n.placeholder="Your name",n.type="text";const s=c("input","ocw-offline-input");s.placeholder="Your email",s.type="email";const o=c("textarea","ocw-offline-input");o.placeholder="Your message",o.rows=3;const r=c("button","ocw-offline-submit","Send message");r.addEventListener("click",()=>{!s.value.trim()||!o.value.trim()||(this.h.onSend(`[Offline form]
161
+ Name: ${n.value||"Anonymous"}
162
+ Email: ${s.value}
163
+ Message: ${o.value}`),this.offlinePanel.replaceChildren(c("div","ocw-offline-thanks","✓ Message sent! We'll reply to your email.")))}),t.append(n,s,o,r),this.offlinePanel.append(t)}buildCsatPanel(){this.csatPanel.replaceChildren(),this.csatPanel.append(c("div","ocw-csat-title","How did we do?"));const e=c("div","ocw-csat-stars"),t=[];for(let n=1;n<=5;n++){const s=c("button","ocw-csat-star","★");s.dataset.score=String(n),s.addEventListener("mouseenter",()=>t.forEach((o,r)=>o.classList.toggle("lit",r<n))),s.addEventListener("mouseleave",()=>t.forEach(o=>o.classList.remove("lit"))),s.addEventListener("click",()=>{var o,r;this.csatSubmitted=!0,this.csatPanel.replaceChildren(c("div","ocw-csat-done",`Thanks for your ${n}★ rating!`)),(r=(o=this.h).onCsat)==null||r.call(o,n)}),t.push(s),e.append(s)}this.csatPanel.append(e)}updateCobrowseUI(){this.cobrowseCanvas.classList.toggle("active",this.cobrowseActive),this.cobrowseToolbar.classList.toggle("active",this.cobrowseActive),this.cobrowseHint.classList.toggle("active",this.cobrowseActive),this.cobrowseBtn.classList.toggle("on",this.cobrowseActive),this.cobrowseActive&&(this.resizeCobrowseCanvas(),this.redrawCobrowse())}resizeCobrowseCanvas(){this.cobrowseCanvas.width=this.root.clientWidth||1,this.cobrowseCanvas.height=this.root.clientHeight||1}drawStroke(e){const t=this.cobrowseCanvas.getContext("2d");if(!t||e.points.length<2)return;const n=this.cobrowseCanvas.width,s=this.cobrowseCanvas.height;t.strokeStyle=e.color,t.lineWidth=Math.max(1,e.width*Math.min(n,s)),t.lineJoin="round",t.lineCap="round",t.beginPath(),t.moveTo(e.points[0].x*n,e.points[0].y*s);for(const o of e.points.slice(1))t.lineTo(o.x*n,o.y*s);t.stroke()}redrawCobrowse(){var t;const e=this.cobrowseCanvas.getContext("2d");if(e){e.clearRect(0,0,this.cobrowseCanvas.width,this.cobrowseCanvas.height);for(const n of((t=this.storeRef)==null?void 0:t.annotations)??[])this.drawStroke(n)}}bindCobrowsePointerEvents(){let e=!1,t=[];const n=r=>{const h=this.cobrowseCanvas.getBoundingClientRect(),w=h.width>0?(r.clientX-h.left)/h.width:0,d=h.height>0?(r.clientY-h.top)/h.height:0;return{x:Math.min(1,Math.max(0,w)),y:Math.min(1,Math.max(0,d))}},s=.006;this.cobrowseCanvas.addEventListener("pointerdown",r=>{this.cobrowseActive&&(e=!0,t=[n(r)],this.cobrowseCanvas.setPointerCapture(r.pointerId))}),this.cobrowseCanvas.addEventListener("pointermove",r=>{e&&(t.push(n(r)),this.redrawCobrowse(),this.drawStroke({points:t,color:this.cobrowseColor,width:s}))});const o=r=>{var h,w;if(e){e=!1,t.length>1&&((w=(h=this.h).onAnnotate)==null||w.call(h,{id:`an_${Date.now()}_${Math.random().toString(36).slice(2)}`,points:t,color:this.cobrowseColor,width:s})),t=[];try{this.cobrowseCanvas.releasePointerCapture(r.pointerId)}catch{}}};this.cobrowseCanvas.addEventListener("pointerup",o),this.cobrowseCanvas.addEventListener("pointercancel",o)}buildSubjectCard(e){if(this.subjectBuilt)return;const t=e.subject,n=this.cfg.subject,s=(t==null?void 0:t.title)??(n==null?void 0:n.title);if(!s)return;this.subjectBuilt=!0,this.subjectCard.replaceChildren(),this.subjectCard.append(c("div","ocw-subject-title",s)),n!=null&&n.subtitle&&this.subjectCard.append(c("div","ocw-subject-sub",n.subtitle));const o=c("div","ocw-tags");if(t)for(const[h,w]of Object.entries(t.fields))o.append(c("span","ocw-tag",`${h}: ${w}`));else for(const h of(n==null?void 0:n.tags)??[])o.append(c("span","ocw-tag",h));o.childNodes.length&&this.subjectCard.append(o);const r=(t==null?void 0:t.state)??(n==null?void 0:n.status);r&&(this.statusBadge.textContent=r,this.statusBadge.style.display="inline-flex")}chipEl(e){const t=c("button","ocw-chip",e.icon?`${e.icon} ${e.label}`:e.label);return t.dataset.actionId=e.id,t.addEventListener("click",async()=>{var n;e.confirm&&!await this.confirm(e.label)||((n=e.input)!=null&&n.length?this.openForm(e):this.h.onInvoke(e.id))}),t}confirm(e){return new Promise(t=>{const n=c("div","ocw-modal"),s=c("div","ocw-modal-card");s.append(c("div","ocw-modal-title",e)),s.append(c("div","ocw-modal-body",`Confirm “${e}”?`));const o=c("div","ocw-modal-actions"),r=c("button","ocw-modal-cancel","Cancel"),h=c("button","ocw-modal-ok","Confirm"),w=d=>{n.remove(),t(d)};r.addEventListener("click",()=>w(!1)),h.addEventListener("click",()=>w(!0)),n.addEventListener("click",d=>{d.target===n&&w(!1)}),o.append(r,h),s.append(o),n.append(s),this.root.append(n),h.focus()})}openForm(e){var h,w;this.formHost.replaceChildren();const t=c("div","ocw-form");t.append(c("div","ocw-form-title",e.icon?`${e.icon} ${e.label}`:e.label));const n=new Map;for(const d of e.input??[]){const b=c("label","ocw-form-row");if(b.append(c("span","ocw-form-lbl",d.label)),d.type==="select"&&((h=d.options)!=null&&h.length)){const x=c("select","ocw-form-input");d.required||x.append(c("option",void 0,"— select —"));for(const f of d.options){const p=c("option");p.value=f,p.textContent=f,x.append(p)}d.required&&(x.required=!0),b.append(x),n.set(d.name,x)}else{const x=c("input","ocw-form-input");x.type=d.type==="number"?"number":d.type==="date"?"datetime-local":"text",d.required&&(x.required=!0),b.append(x),n.set(d.name,x)}t.append(b)}const s=c("div","ocw-form-actions"),o=c("button","ocw-form-cancel","Cancel"),r=c("button","ocw-form-submit","Send");o.addEventListener("click",()=>this.formHost.replaceChildren()),r.addEventListener("click",()=>{const d={};for(const[b,x]of n){if(x.required&&!x.value){x.style.borderColor="#e5484d";return}d[b]=x.type==="number"?Number(x.value):x.value}this.formHost.replaceChildren(),this.h.onInvoke(e.id,d)}),s.append(o,r),t.append(s),this.formHost.append(t),(w=n.values().next().value)==null||w.focus()}messageEl(e,t){var x;if(e.senderRole==="system"){const f=c("div","ocw-sys");return f.textContent=e.deletedAt?"message deleted":we(e.content),f}const n=e.senderId===this.me,s=!!e.internal,o=c("div",`ocw-row ${s?"ocw-note mine":n?"mine":"theirs"} ${e.senderRole==="bot"?"ocw-bot":""}`);!n&&!s&&o.append(c("div","ocw-dot",e.senderRole==="bot"?"🤖":"🧑"));const r=c("div"),h=c("div","ocw-bubble-wrap");if(e.replyToId){const f=c("div","ocw-reply-to","↩ replying to a message");f.style.cssText="font-size:11px;color:var(--ocw-mut);margin-bottom:2px;font-style:italic",r.append(f)}const w=c("div","ocw-bubble");let d=null;if(e.deletedAt)w.append(c("span","ocw-deleted","message deleted"));else if(e.content.kind==="attachment"){const f=e.content;if((x=f.mime)!=null&&x.startsWith("image/")){const p=document.createElement("img");p.src=f.url,p.alt=f.name??"image",p.style.cssText="max-width:220px;max-height:160px;border-radius:10px;display:block;cursor:pointer",p.addEventListener("click",()=>window.open(f.url,"_blank")),w.append(p)}else{const p=document.createElement("a");p.href=f.url,p.target="_blank",p.rel="noopener",p.style.cssText="display:flex;align-items:center;gap:8px;color:inherit;text-decoration:none",p.append(c("span",void 0,"📄"),c("span",void 0,f.name??"file")),w.append(p)}}else if(e.content.kind==="appointment"){const f=e.content,p=c("div","ocw-appt");p.append(c("div","ocw-appt-title",`📅 ${f.title}`)),p.append(c("div","ocw-appt-time",new Date(f.startIso).toLocaleString()+" – "+new Date(f.endIso).toLocaleTimeString())),f.location&&p.append(c("div","ocw-appt-loc",`📍 ${f.location}`)),f.description&&p.append(c("div","ocw-appt-desc",f.description));const v=c("div","ocw-appt-links"),k=document.createElement("a");k.href=f.googleUrl,k.target="_blank",k.rel="noopener",k.className="ocw-appt-btn",k.textContent="📅 Add to Google Calendar";const g=document.createElement("a");g.href=f.icalUrl,g.download=`${f.title}.ics`,g.className="ocw-appt-btn ocw-appt-btn-sec",g.textContent="🍎 Apple / iCal",v.append(k,g),p.append(v),w.append(p)}else d=document.createTextNode(we(e.content)),w.append(d),e.editedAt&&w.append(c("span","ocw-edited","(edited)"));if(h.append(w),!n&&!s&&this.h.onTranslate&&e.content.kind==="text"&&!e.deletedAt&&e.seq>0&&d){const f=e.content.text;if(f.trim()){const p=c("button","ocw-translate-btn","🌐");p.type="button",p.title="Translate",p.addEventListener("click",v=>{if(v.stopPropagation(),this.showingTranslation.has(e.id)){this.showingTranslation.delete(e.id),d.textContent=f,p.textContent="🌐",p.title="Translate";return}const k=this.translationCache.get(e.id);if(k!==void 0){this.showingTranslation.add(e.id),d.textContent=k,p.textContent="↩",p.title="Show original";return}p.textContent="⏳",this.h.onTranslate(f).then(g=>{if(g===null){p.textContent="⚠️",p.title="Translation unavailable",setTimeout(()=>{p.textContent="🌐",p.title="Translate"},1500);return}this.translationCache.set(e.id,g),this.showingTranslation.add(e.id),d.textContent=g,p.textContent="↩",p.title="Show original"})}),h.append(p)}}if(n&&!e.deletedAt&&e.seq>0&&(this.h.onEdit??this.h.onDelete)){const f=c("div","ocw-msg-menu");if(this.h.onEdit){const p=c("button",void 0,"✏️");p.title="Edit",p.addEventListener("click",v=>{v.stopPropagation();const k=we(e.content),g=document.createElement("textarea");g.value=k,g.rows=Math.min(4,Math.ceil(k.length/40)+1),g.style.cssText="width:100%;resize:vertical;border:1px solid var(--ocw-accent);border-radius:8px;padding:6px 10px;font:inherit;font-size:14px;background:#fff;color:#1c1b1a;box-sizing:border-box";const U=c("button","ocw-form-submit","Save");U.style.cssText="margin-top:6px;padding:5px 14px;font-size:13px";const K=c("button","ocw-form-cancel","Cancel");K.style.cssText="margin-top:6px;padding:5px 10px;font-size:13px";const P=c("div");P.style.cssText="display:flex;gap:6px;justify-content:flex-end",P.append(K,U);const L=c("div");L.append(g,P),w.replaceChildren(L),g.focus(),g.select();const m=()=>w.replaceChildren(d??document.createTextNode(k));K.addEventListener("click",m),U.addEventListener("click",()=>{const I=g.value.trim();I&&I!==k&&this.h.onEdit(e.id,I),m()}),g.addEventListener("keydown",I=>{I.key==="Enter"&&!I.shiftKey&&(I.preventDefault(),U.click()),I.key==="Escape"&&m()})}),f.append(p)}if(this.h.onDelete){const p=c("button","del","🗑");p.title="Delete",p.addEventListener("click",v=>{v.stopPropagation(),this.h.onDelete(e.id)}),f.append(p)}h.append(f)}if(r.append(h),this.h.onReact&&!e.deletedAt&&e.seq>0){const f=c("div","ocw-react-wrap"),p=c("div","ocw-react");if(e.reactions&&Object.keys(e.reactions).length)for(const[g,U]of Object.entries(e.reactions)){const K=c("button",`ocw-react-pill${U.includes(this.me)?" mine":""}`,`${g} ${U.length}`);K.addEventListener("click",()=>{var P,L;return(L=(P=this.h).onReact)==null?void 0:L.call(P,e.id,g,U.includes(this.me))}),p.append(K)}const v=c("button","ocw-react-btn","+"),k=c("div","ocw-react-picker");for(const g of Ot){const U=c("button",void 0,g);U.addEventListener("click",K=>{var L,m,I,j;K.stopPropagation();const P=(m=(L=e.reactions)==null?void 0:L[g])==null?void 0:m.includes(this.me);(j=(I=this.h).onReact)==null||j.call(I,e.id,g,!!P),k.style.display="none"}),k.append(U)}k.style.display="none",v.addEventListener("click",g=>{g.stopPropagation(),k.style.display=k.style.display==="none"?"flex":"none"}),document.addEventListener("click",()=>{k.style.display="none"},{once:!0}),p.append(v),f.append(p,k),r.append(f)}else e.reactions&&Object.keys(e.reactions).length&&r.append(c("div","ocw-react",Object.entries(e.reactions).map(([f,p])=>`${f}${p.length}`).join(" ")));const b=c("div","ocw-time ocw-meta",Wt(e.ts));if(n&&e.status){const f=c("span",`ocw-tick${e.status==="read"?" read":e.status==="delivered"?" delivered":""}`,Yt(e.status));b.append(f)}return n&&e.seq>0&&t.lastReadByOthers>=e.seq&&b.append(c("span","ocw-seen"," · Seen")),r.append(b),o.append(r),o}}function Yt(i){switch(i){case"read":return"✓✓";case"delivered":return"✓✓";case"sent":return"✓";default:return"🕓"}}const Jt=20;function Pe(i,e){var w;const t=i.trim().replace(/\/+$/,""),n=(w=t.match(/^(https|http|wss|ws):\/\//))==null?void 0:w[1],s=n?n==="https"||n==="wss":!0,o=(n?t.slice(n.length+3):t).replace(/\/ws$/,""),r=e?e.trim().replace(/\/+$/,""):`${s?"https":"http"}://${o}`;return{wsUrl:`${s?"wss":"ws"}://${o}/ws`,httpBase:r}}function Gt(i){return Pe(i).httpBase}function Zt(i,e,t,n){const s=`beforeSeq=${t}&limit=${n}`;return[`${i}/conversations/${e}/messages?${s}`,`${i}/conversations/${e}/history?${s}`]}async function Ae(i,e,t,n,s=Jt){for(const o of Zt(i,e,n,s))try{const r=await fetch(o,{headers:{authorization:`Bearer ${t}`}});if(!r.ok)continue;const h=await r.json();return{messages:h.messages??[],hasMore:h.hasMore??!1}}catch{}return null}async function Qt(i,e,t,n,s,o){const r=o?o.replace(/\/+$/,""):Gt(i),h=await Ae(r,t,e,Number.MAX_SAFE_INTEGER);if(!h||(h.messages.length?(n.apply({type:"sync",conversationId:t,messages:h.messages}),n.apply({type:"history",conversationId:t,messages:[],hasMore:h.hasMore}),s.render(n)):n.apply({type:"history",conversationId:t,messages:[],hasMore:!1}),!h.hasMore))return;let w=!1;const d=async()=>{if(w||!n.hasMoreHistory)return;w=!0;const p=n.messages()[0];if(!p){w=!1;return}const v=await Ae(r,t,e,p.seq);v&&(n.apply({type:"history",conversationId:t,messages:v.messages,hasMore:v.hasMore}),s.render(n)),w=!1},b=s.getScrollEl();if(!b)return;let x=!1;setTimeout(()=>{x=!0},300);const f=()=>{x&&b.scrollTop<80&&n.hasMoreHistory&&!w&&d()};b.addEventListener("scroll",f,{passive:!0}),s.setScrollCleanup(()=>b.removeEventListener("scroll",f))}const G=new WeakMap,ne=new Map;function Be(i){return`relay-launcher::${i.profileId}::${i.subjectId??""}`}function en(i){var ze,Me,$e,De,_e;G.has(i.el)&&(G.get(i.el).close(),G.delete(i.el)),i.launcher&&((ze=ne.get(Be(i)))==null||ze.close());const e=je(),t=i.token??i.userId??e,n=t!==e?e:void 0,{wsUrl:s,httpBase:o}=Pe(i.url,i.apiUrl);let r=new Ct(t);const h=i.subjectId?`${t}::${i.subjectId}`:t,w=new Kt(h);let d,b=!1,x=null,f=null;!i.launcher&&!i.el.style.height&&i.el.clientHeight===0&&(i.el.style.width=i.el.style.width||"100%",i.el.style.height="600px");for(const l of w.load())r.addOptimistic(l.clientMsgId,l.content);let p=null,v=null,k=0,g=!i.launcher;if(i.launcher){const u=(i.position??"bottom-right").includes("right");p=document.createElement("div"),p.style.cssText=`position:fixed;${u?"right:20px":"left:20px"};bottom:20px;z-index:9999;display:flex;flex-direction:column;align-items:${u?"flex-end":"flex-start"};gap:12px`;const y=document.createElement("div"),C=typeof window<"u"?window.matchMedia("(max-width: 479px)"):null,V=F=>{y.style.cssText=F?["position:fixed","inset:0","width:100%","height:100%","border-radius:0","overflow:hidden","box-shadow:none","display:none","flex-direction:column","background:#fff","transition:opacity .18s","opacity:0","z-index:9998"].join(";"):["width:380px","height:600px","border-radius:16px","overflow:hidden","box-shadow:0 8px 40px rgba(0,0,0,.18)","display:none","flex-direction:column","background:#fff","transform-origin:bottom "+(u?"right":"left"),"transition:opacity .18s,transform .18s","opacity:0","transform:scale(.95)"].join(";")};V((C==null?void 0:C.matches)??!1);const re=F=>V(F.matches);C==null||C.addEventListener("change",re),x=C,f=re,i.el.style.cssText="width:100%;height:100%;overflow:hidden",y.append(i.el);const A=document.createElement("button");A.style.cssText=["width:56px;height:56px;border-radius:50%",`background:${i.accent??"#4F63F5"}`,"color:#fff;border:none;font-size:24px;cursor:pointer","box-shadow:0 4px 16px rgba(0,0,0,.25)","position:relative;flex:none","transition:transform .15s"].join(";"),A.textContent="💬",A.onmouseenter=()=>{A.style.transform="scale(1.08)"},A.onmouseleave=()=>{A.style.transform="scale(1)"},v=document.createElement("span"),v.style.cssText="position:absolute;top:-4px;right:-4px;background:#ef4444;color:#fff;border-radius:50%;width:20px;height:20px;font-size:11px;font-weight:700;display:none;align-items:center;justify-content:center",A.append(v),p.append(y,A),document.body.append(p);const ae=F=>{F?(y.style.display="flex",requestAnimationFrame(()=>{y.style.opacity="1",y.style.transform="scale(1)"})):(y.style.opacity="0",y.style.transform="scale(.95)",setTimeout(()=>{g||(y.style.display="none")},180))};A.addEventListener("click",()=>{g=!g,ae(g),A.textContent=g?"✕":"💬",A.append(v),g&&(k=0,v&&(v.style.display="none"))}),document.addEventListener("keydown",F=>{F.key==="Escape"&&g&&(g=!1,ae(!1),A.textContent="💬",A.append(v))})}const U=()=>{g||(k++,v&&(v.textContent=String(k),v.style.display="flex"))},K=()=>{try{const l=new AudioContext,u=l.createOscillator(),y=l.createGain();u.connect(y),y.connect(l.destination),u.frequency.setValueAtTime(880,l.currentTime),u.frequency.exponentialRampToValueAtTime(440,l.currentTime+.15),y.gain.setValueAtTime(.3,l.currentTime),y.gain.exponentialRampToValueAtTime(.001,l.currentTime+.3),u.start(),u.stop(l.currentTime+.3)}catch{}},P=[],L=l=>{for(;P.length;){const u=P.shift();w.add({clientMsgId:u.clientMsgId,content:u.content,ts:Date.now()}),m.send({type:"send",conversationId:l,clientMsgId:u.clientMsgId,content:u.content})}};let m;const I=new Ft(`ocw-e2e-${i.profileId}`);let j=!1;const S=[],T=[];let se=!1;const ye=(l,u)=>{I.sealText(u).then(y=>{d&&m.send({type:"send",conversationId:d,clientMsgId:l,content:y})})},cn=(l,u,y)=>{I.sealText(u,y).then(C=>{d&&m.send({type:"send",conversationId:d,clientMsgId:l,content:C})})},dn=()=>{for(;S.length;){const l=S.shift();ye(l.clientMsgId,l.text)}for(;T.length;){const l=T.shift();ye(l.clientMsgId,l.text)}},ln=l=>{m.send({type:"fetchPrekey",targetUserId:l})},hn=i.i18n??{},pn=["ar","he","fa","ur"],un=typeof navigator<"u"?(navigator.language??"").slice(0,2).toLowerCase():"";pn.includes(un)&&!i.el.dir&&(i.el.dir="rtl",i.el.style.fontFamily=i.el.style.fontFamily||"Tahoma,Arial,system-ui,sans-serif");const M=new Xt(i.el,t,{onSend(l){const u=`cm_${Math.random().toString(36).slice(2)}`,y={kind:"text",text:l};r.addOptimistic(u,y),M.render(r),r.e2e?I.ready?ye(u,l):se?T.push({clientMsgId:u,text:l}):(S.push({clientMsgId:u,text:l}),r.assignedAgentId&&ln(r.assignedAgentId)):d?(w.add({clientMsgId:u,content:y,ts:Date.now()}),m.send({type:"send",conversationId:d,clientMsgId:u,content:y})):P.push({clientMsgId:u,content:y})},async onAttach(l){if(!d)return;const u=`${o}/upload?name=${encodeURIComponent(l.name)}`,y=`cm_${Math.random().toString(36).slice(2)}`;r.addOptimistic(y,{kind:"text",text:`📎 Uploading ${l.name}…`}),M.render(r);try{const C=await fetch(u,{method:"POST",headers:{"content-type":l.type,...i.token?{authorization:`Bearer ${i.token}`}:{}},body:l});if(!C.ok)throw new Error(`Upload failed: ${C.status}`);const{url:V,name:re,mime:A,size:ae}=await C.json();m.send({type:"send",conversationId:d,clientMsgId:y,content:{kind:"attachment",url:V,name:re,mime:A,size:ae}})}catch(C){r.addOptimistic(y,{kind:"text",text:`⚠️ Upload failed: ${C.message}`}),M.render(r)}},onInvoke(l,u){d&&m.send({type:"invoke",conversationId:d,actionId:l,clientInvokeId:`iv_${Math.random().toString(36).slice(2)}`,...u?{inputs:u}:{}})},onTyping(l,u){d&&m.send({type:"typing",conversationId:d,isTyping:l,...u?{preview:u}:{}})},onReadUpTo(l){d&&m.send({type:"read",conversationId:d,seq:l})},onLoadMore(){if(!d||!r.e2e)return;const l=r.messages()[0];l&&m.send({type:"history",conversationId:d,beforeSeq:l.seq,limit:20})},onEdit(l,u){d&&m.send({type:"edit",conversationId:d,messageId:l,content:{kind:"text",text:u}})},onDelete(l){d&&m.send({type:"delete",conversationId:d,messageId:l})},onReact(l,u,y){d&&m.send({type:"react",conversationId:d,messageId:l,emoji:u,remove:y})},onCsat(l){d&&fetch(`${o}/conversations/${d}/csat`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({score:l})}).catch(()=>{})},onAnnotate(l){d&&m.send({type:"annotate",conversationId:d,stroke:l})},onAnnotateClear(){d&&m.send({type:"annotate_clear",conversationId:d})},...i.translateLang?{async onTranslate(l){try{const u=await fetch(`${o}/translate`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${t}`},body:JSON.stringify({text:l,targetLang:i.translateLang})});if(!u.ok)return null;const{translated:y}=await u.json();return y}catch{return null}}}:{}},{...i.subject?{subject:i.subject}:{},...i.quickReplies?{quickReplies:i.quickReplies}:{},...i.accent?{accent:i.accent}:{},...(Me=i.user)!=null&&Me.name||($e=i.user)!=null&&$e.avatar?{userInfo:{...i.user.name?{name:i.user.name}:{},...i.user.avatar?{avatar:i.user.avatar}:{}}}:{},i18n:hn}),fn={type:"open",profileId:i.profileId,...i.subjectId?{subjectId:i.subjectId}:{},...n?{linkFrom:n}:{},...typeof location<"u"?{pageUrl:location.href}:{},...typeof document<"u"&&document.title?{pageTitle:document.title}:{},...(De=i.subject)!=null&&De.title?{subjectTitle:i.subject.title}:{},...(_e=i.subject)!=null&&_e.subtitle?{subjectMeta:i.subject.subtitle}:{}},wn=l=>{const u=i.user;if(!u||!u.name&&!u.email&&!u.avatar&&!u.meta)return;const y=[];if(u.name&&y.push(`Name: ${u.name}`),u.email&&y.push(`Email: ${u.email}`),u.avatar&&y.push(`Avatar: ${u.avatar}`),u.meta)for(const[C,V]of Object.entries(u.meta))y.push(`${C}: ${V}`);m.send({type:"note",conversationId:l,clientMsgId:`ui_${Date.now()}`,text:`[User info]
164
+ ${y.join(`
165
+ `)}`})};m=new Tt({url:s,token:t,open:fn,getCursor:()=>r.highestSeq(),onStatusChange:(l,u)=>M.setConnStatus(l,u),onFrame(l){if(l.type==="opened"){const u=d===void 0;if(d=l.conversation.id,!b){b=!0;for(const y of w.load())m.send({type:"send",conversationId:d,clientMsgId:y.clientMsgId,content:y.content})}Qt(s,t,d,r,M,o),P.length&&L(d),u&&l.conversation.lastSeq===0&&wn(d)}if(l.type==="ack"&&w.remove(l.clientMsgId),l.type==="prekeyBundle"){l.bundle&&(se=!0,I.x3dhSendTo(l.bundle).then(u=>{const y=[...S.splice(0),...T.splice(0)];for(const C of y)cn(C.clientMsgId,C.text,u);M.render(r)}));return}if(l.type==="message"&&r.e2e){const u=qt(l.message.content);if(u&&!I.ready){I.x3dhReceiveFrom(u.x3dhIK,u.x3dhEK,u.x3dhSPK).then(async()=>{await I.openFrame(l),r.apply(l),M.render(r)});return}}if(l.type==="peerkey"){I.onPeerKey(l.key).then(()=>{dn(),M.render(r)});return}(async()=>{if(r.e2e&&await I.openFrame(l),r.apply(l),l.type==="message"&&l.message.senderId!==t&&!l.message.internal&&(U(),K()),r.e2e&&d&&!j){j=!0;const u=await I.initX3DH();m.send({type:"uploadPrekeys",...u});const y=await I.begin();m.send({type:"pubkey",conversationId:d,key:y})}M.render(r)})()}}),m.connect(),M.render(r);const Z=i.launcher?Be(i):null,oe={close:()=>{m.close(),p==null||p.remove(),M.destroy(),x&&f&&x.removeEventListener("change",f),G.delete(i.el),Z&&ne.get(Z)===oe&&ne.delete(Z)}};return G.set(i.el,oe),Z&&ne.set(Z,oe),oe}const tn="wss://api.paramms.com/ws";let H=null,$=null,N={};function nn(i,e){const t=i.profileId??i.appId;if(!t)throw new Error("Relay: `appId` is required (your chatroom id, e.g. 'p_...').");const n=i.subjectId??(i.listingId?`listing_${i.listingId}`:void 0),s=i.subjectTitle?{title:i.subjectTitle,...i.subjectMeta?{subtitle:i.subjectMeta}:{},...i.subjectPrice!=null?{tags:[`$${i.subjectPrice.toLocaleString()}`]}:{},...i.subjectStatus?{status:i.subjectStatus}:{}}:void 0,o=i.name||i.email||i.avatar?{...i.name?{name:i.name}:{},...i.email?{email:i.email}:{},...i.avatar?{avatar:i.avatar}:{}}:void 0;return{el:e,url:i.url??tn,profileId:t,...i.apiUrl?{apiUrl:i.apiUrl}:{},...n?{subjectId:n}:{},...i.token?{token:i.token}:{},...i.userId?{userId:i.userId}:{},...s?{subject:s}:{},...o?{user:o}:{},...i.accent?{accent:i.accent}:{},...i.translateLang?{translateLang:i.translateLang}:{},launcher:i.launcher??!0,position:i.position??"bottom-right"}}function sn(){return(!$||!$.isConnected)&&($=document.createElement("div"),$.id="relay-widget-root",document.body.appendChild($)),$}function Ke(i){try{H==null||H.close(),H=en(nn(i,sn()))}catch(e){console.error("[Relay]",e instanceof Error?e.message:e)}}function Le(i){N={...i},Ke(N)}function on(i){N={...N,...i},Ke(N)}function rn(){H==null||H.close(),H=null,$==null||$.remove(),$=null,N={}}function xe(i,e){switch(i){case"boot":Le(e??{});break;case"update":case"identify":on(e??{});break;case"shutdown":rn();break;default:console.warn("[Relay] unknown command:",i)}}function an(){if(typeof document>"u")return null;const i=document.querySelector("script[data-relay-app]"),e=i==null?void 0:i.dataset.relayApp;if(!e)return null;const t=i.dataset,n={appId:e};t.relayUser&&(n.userId=t.relayUser),t.relayToken&&(n.token=t.relayToken),t.relayListing&&(n.listingId=t.relayListing),t.relayAccent&&(n.accent=t.relayAccent),t.relayUrl&&(n.url=t.relayUrl);const s=t.relayPosition;return(s==="bottom-left"||s==="bottom-right")&&(n.position=s),t.relayLauncher==="false"&&(n.launcher=!1),n}if(typeof window<"u"){const i=window,e=i.Relay&&i.Relay.q?i.Relay.q:[];i.Relay=xe;let t=!1;for(const n of e){const[s,o]=n;s==="boot"&&(t=!0),xe(s,o)}if(!t){const n=i.relaySettings??an();n&&Le(n)}}return D.Relay=xe,Object.defineProperty(D,Symbol.toStringTag,{value:"Module"}),D}({});
166
+ //# sourceMappingURL=embed.js.map