@paramms/chat-widget 1.0.23 → 1.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +237 -234
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/protocol/ids.ts","../node_modules/@msgpack/msgpack/dist.esm/utils/utf8.mjs","../node_modules/@msgpack/msgpack/dist.esm/ExtData.mjs","../node_modules/@msgpack/msgpack/dist.esm/DecodeError.mjs","../node_modules/@msgpack/msgpack/dist.esm/utils/int.mjs","../node_modules/@msgpack/msgpack/dist.esm/timestamp.mjs","../node_modules/@msgpack/msgpack/dist.esm/ExtensionCodec.mjs","../node_modules/@msgpack/msgpack/dist.esm/utils/typedArrays.mjs","../node_modules/@msgpack/msgpack/dist.esm/Encoder.mjs","../node_modules/@msgpack/msgpack/dist.esm/encode.mjs","../node_modules/@msgpack/msgpack/dist.esm/utils/prettyByte.mjs","../node_modules/@msgpack/msgpack/dist.esm/CachedKeyDecoder.mjs","../node_modules/@msgpack/msgpack/dist.esm/Decoder.mjs","../node_modules/@msgpack/msgpack/dist.esm/decode.mjs","../src/protocol/codec.ts","../src/store.ts","../src/connection.ts","../src/outbox.ts","../src/crypto.ts","../src/e2e.ts","../src/renderer.ts","../src/index.ts"],"sourcesContent":["// Branded identifier types. A plain string can't be passed where a TenantId is\n// expected (and vice-versa), so id-confusion bugs — the kind that caused the\n// `t-1` vs `dev-tenant` mismatch in the previous system — become compile errors.\n\nexport type Brand<T, B extends string> = T & { readonly __brand: B }\n\nexport type TenantId = Brand<string, 'TenantId'>\nexport type UserId = Brand<string, 'UserId'>\nexport type ConversationId = Brand<string, 'ConversationId'>\nexport type SubjectId = Brand<string, 'SubjectId'>\nexport type MessageId = Brand<string, 'MessageId'>\nexport type ActionId = Brand<string, 'ActionId'>\nexport type ProfileId = Brand<string, 'ProfileId'>\nexport type ConnectionId = Brand<string, 'ConnectionId'>\n\nexport const asTenantId = (s: string): TenantId => s as TenantId\nexport const asUserId = (s: string): UserId => s as UserId\nexport const asConversationId = (s: string): ConversationId => s as ConversationId\nexport const asSubjectId = (s: string): SubjectId => s as SubjectId\nexport const asMessageId = (s: string): MessageId => s as MessageId\nexport const asActionId = (s: string): ActionId => s as ActionId\nexport const asProfileId = (s: string): ProfileId => s as ProfileId\nexport const asConnectionId = (s: string): ConnectionId => s as ConnectionId\n\n/** Anonymous guests live under this tenant; they bypass cross-tenant scoping but\n * are still gated by conversation membership. */\nexport const ANONYMOUS_TENANT = asTenantId('anonymous')\n","export function utf8Count(str) {\n const strLength = str.length;\n let byteLength = 0;\n let pos = 0;\n while (pos < strLength) {\n let value = str.charCodeAt(pos++);\n if ((value & 0xffffff80) === 0) {\n // 1-byte\n byteLength++;\n continue;\n }\n else if ((value & 0xfffff800) === 0) {\n // 2-bytes\n byteLength += 2;\n }\n else {\n // handle surrogate pair\n if (value >= 0xd800 && value <= 0xdbff) {\n // high surrogate\n if (pos < strLength) {\n const extra = str.charCodeAt(pos);\n if ((extra & 0xfc00) === 0xdc00) {\n ++pos;\n value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000;\n }\n }\n }\n if ((value & 0xffff0000) === 0) {\n // 3-byte\n byteLength += 3;\n }\n else {\n // 4-byte\n byteLength += 4;\n }\n }\n }\n return byteLength;\n}\nexport function utf8EncodeJs(str, output, outputOffset) {\n const strLength = str.length;\n let offset = outputOffset;\n let pos = 0;\n while (pos < strLength) {\n let value = str.charCodeAt(pos++);\n if ((value & 0xffffff80) === 0) {\n // 1-byte\n output[offset++] = value;\n continue;\n }\n else if ((value & 0xfffff800) === 0) {\n // 2-bytes\n output[offset++] = ((value >> 6) & 0x1f) | 0xc0;\n }\n else {\n // handle surrogate pair\n if (value >= 0xd800 && value <= 0xdbff) {\n // high surrogate\n if (pos < strLength) {\n const extra = str.charCodeAt(pos);\n if ((extra & 0xfc00) === 0xdc00) {\n ++pos;\n value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000;\n }\n }\n }\n if ((value & 0xffff0000) === 0) {\n // 3-byte\n output[offset++] = ((value >> 12) & 0x0f) | 0xe0;\n output[offset++] = ((value >> 6) & 0x3f) | 0x80;\n }\n else {\n // 4-byte\n output[offset++] = ((value >> 18) & 0x07) | 0xf0;\n output[offset++] = ((value >> 12) & 0x3f) | 0x80;\n output[offset++] = ((value >> 6) & 0x3f) | 0x80;\n }\n }\n output[offset++] = (value & 0x3f) | 0x80;\n }\n}\n// TextEncoder and TextDecoder are standardized in whatwg encoding:\n// https://encoding.spec.whatwg.org/\n// and available in all the modern browsers:\n// https://caniuse.com/textencoder\n// They are available in Node.js since v12 LTS as well:\n// https://nodejs.org/api/globals.html#textencoder\nconst sharedTextEncoder = new TextEncoder();\n// This threshold should be determined by benchmarking, which might vary in engines and input data.\n// Run `npx ts-node benchmark/encode-string.ts` for details.\nconst TEXT_ENCODER_THRESHOLD = 50;\nexport function utf8EncodeTE(str, output, outputOffset) {\n sharedTextEncoder.encodeInto(str, output.subarray(outputOffset));\n}\nexport function utf8Encode(str, output, outputOffset) {\n if (str.length > TEXT_ENCODER_THRESHOLD) {\n utf8EncodeTE(str, output, outputOffset);\n }\n else {\n utf8EncodeJs(str, output, outputOffset);\n }\n}\nconst CHUNK_SIZE = 4096;\nexport function utf8DecodeJs(bytes, inputOffset, byteLength) {\n let offset = inputOffset;\n const end = offset + byteLength;\n const units = [];\n let result = \"\";\n while (offset < end) {\n const byte1 = bytes[offset++];\n if ((byte1 & 0x80) === 0) {\n // 1 byte\n units.push(byte1);\n }\n else if ((byte1 & 0xe0) === 0xc0) {\n // 2 bytes\n const byte2 = bytes[offset++] & 0x3f;\n units.push(((byte1 & 0x1f) << 6) | byte2);\n }\n else if ((byte1 & 0xf0) === 0xe0) {\n // 3 bytes\n const byte2 = bytes[offset++] & 0x3f;\n const byte3 = bytes[offset++] & 0x3f;\n units.push(((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3);\n }\n else if ((byte1 & 0xf8) === 0xf0) {\n // 4 bytes\n const byte2 = bytes[offset++] & 0x3f;\n const byte3 = bytes[offset++] & 0x3f;\n const byte4 = bytes[offset++] & 0x3f;\n let unit = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4;\n if (unit > 0xffff) {\n unit -= 0x10000;\n units.push(((unit >>> 10) & 0x3ff) | 0xd800);\n unit = 0xdc00 | (unit & 0x3ff);\n }\n units.push(unit);\n }\n else {\n units.push(byte1);\n }\n if (units.length >= CHUNK_SIZE) {\n result += String.fromCharCode(...units);\n units.length = 0;\n }\n }\n if (units.length > 0) {\n result += String.fromCharCode(...units);\n }\n return result;\n}\nconst sharedTextDecoder = new TextDecoder();\n// This threshold should be determined by benchmarking, which might vary in engines and input data.\n// Run `npx ts-node benchmark/decode-string.ts` for details.\nconst TEXT_DECODER_THRESHOLD = 200;\nexport function utf8DecodeTD(bytes, inputOffset, byteLength) {\n const stringBytes = bytes.subarray(inputOffset, inputOffset + byteLength);\n return sharedTextDecoder.decode(stringBytes);\n}\nexport function utf8Decode(bytes, inputOffset, byteLength) {\n if (byteLength > TEXT_DECODER_THRESHOLD) {\n return utf8DecodeTD(bytes, inputOffset, byteLength);\n }\n else {\n return utf8DecodeJs(bytes, inputOffset, byteLength);\n }\n}\n//# sourceMappingURL=utf8.mjs.map","/**\n * ExtData is used to handle Extension Types that are not registered to ExtensionCodec.\n */\nexport class ExtData {\n type;\n data;\n constructor(type, data) {\n this.type = type;\n this.data = data;\n }\n}\n//# sourceMappingURL=ExtData.mjs.map","export class DecodeError extends Error {\n constructor(message) {\n super(message);\n // fix the prototype chain in a cross-platform way\n const proto = Object.create(DecodeError.prototype);\n Object.setPrototypeOf(this, proto);\n Object.defineProperty(this, \"name\", {\n configurable: true,\n enumerable: false,\n value: DecodeError.name,\n });\n }\n}\n//# sourceMappingURL=DecodeError.mjs.map","// Integer Utility\nexport const UINT32_MAX = 4294967295;\n// DataView extension to handle int64 / uint64,\n// where the actual range is 53-bits integer (a.k.a. safe integer)\nexport function setUint64(view, offset, value) {\n const high = value / 4294967296;\n const low = value; // high bits are truncated by DataView\n view.setUint32(offset, high);\n view.setUint32(offset + 4, low);\n}\nexport function setInt64(view, offset, value) {\n const high = Math.floor(value / 4294967296);\n const low = value; // high bits are truncated by DataView\n view.setUint32(offset, high);\n view.setUint32(offset + 4, low);\n}\nexport function getInt64(view, offset) {\n const high = view.getInt32(offset);\n const low = view.getUint32(offset + 4);\n return high * 4294967296 + low;\n}\nexport function getUint64(view, offset) {\n const high = view.getUint32(offset);\n const low = view.getUint32(offset + 4);\n return high * 4294967296 + low;\n}\n//# sourceMappingURL=int.mjs.map","// https://github.com/msgpack/msgpack/blob/master/spec.md#timestamp-extension-type\nimport { DecodeError } from \"./DecodeError.mjs\";\nimport { getInt64, setInt64 } from \"./utils/int.mjs\";\nexport const EXT_TIMESTAMP = -1;\nconst TIMESTAMP32_MAX_SEC = 0x100000000 - 1; // 32-bit unsigned int\nconst TIMESTAMP64_MAX_SEC = 0x400000000 - 1; // 34-bit unsigned int\nexport function encodeTimeSpecToTimestamp({ sec, nsec }) {\n if (sec >= 0 && nsec >= 0 && sec <= TIMESTAMP64_MAX_SEC) {\n // Here sec >= 0 && nsec >= 0\n if (nsec === 0 && sec <= TIMESTAMP32_MAX_SEC) {\n // timestamp 32 = { sec32 (unsigned) }\n const rv = new Uint8Array(4);\n const view = new DataView(rv.buffer);\n view.setUint32(0, sec);\n return rv;\n }\n else {\n // timestamp 64 = { nsec30 (unsigned), sec34 (unsigned) }\n const secHigh = sec / 0x100000000;\n const secLow = sec & 0xffffffff;\n const rv = new Uint8Array(8);\n const view = new DataView(rv.buffer);\n // nsec30 | secHigh2\n view.setUint32(0, (nsec << 2) | (secHigh & 0x3));\n // secLow32\n view.setUint32(4, secLow);\n return rv;\n }\n }\n else {\n // timestamp 96 = { nsec32 (unsigned), sec64 (signed) }\n const rv = new Uint8Array(12);\n const view = new DataView(rv.buffer);\n view.setUint32(0, nsec);\n setInt64(view, 4, sec);\n return rv;\n }\n}\nexport function encodeDateToTimeSpec(date) {\n const msec = date.getTime();\n const sec = Math.floor(msec / 1e3);\n const nsec = (msec - sec * 1e3) * 1e6;\n // Normalizes { sec, nsec } to ensure nsec is unsigned.\n const nsecInSec = Math.floor(nsec / 1e9);\n return {\n sec: sec + nsecInSec,\n nsec: nsec - nsecInSec * 1e9,\n };\n}\nexport function encodeTimestampExtension(object) {\n if (object instanceof Date) {\n const timeSpec = encodeDateToTimeSpec(object);\n return encodeTimeSpecToTimestamp(timeSpec);\n }\n else {\n return null;\n }\n}\nexport function decodeTimestampToTimeSpec(data) {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n // data may be 32, 64, or 96 bits\n switch (data.byteLength) {\n case 4: {\n // timestamp 32 = { sec32 }\n const sec = view.getUint32(0);\n const nsec = 0;\n return { sec, nsec };\n }\n case 8: {\n // timestamp 64 = { nsec30, sec34 }\n const nsec30AndSecHigh2 = view.getUint32(0);\n const secLow32 = view.getUint32(4);\n const sec = (nsec30AndSecHigh2 & 0x3) * 0x100000000 + secLow32;\n const nsec = nsec30AndSecHigh2 >>> 2;\n return { sec, nsec };\n }\n case 12: {\n // timestamp 96 = { nsec32 (unsigned), sec64 (signed) }\n const sec = getInt64(view, 4);\n const nsec = view.getUint32(0);\n return { sec, nsec };\n }\n default:\n throw new DecodeError(`Unrecognized data size for timestamp (expected 4, 8, or 12): ${data.length}`);\n }\n}\nexport function decodeTimestampExtension(data) {\n const timeSpec = decodeTimestampToTimeSpec(data);\n return new Date(timeSpec.sec * 1e3 + timeSpec.nsec / 1e6);\n}\nexport const timestampExtension = {\n type: EXT_TIMESTAMP,\n encode: encodeTimestampExtension,\n decode: decodeTimestampExtension,\n};\n//# sourceMappingURL=timestamp.mjs.map","// ExtensionCodec to handle MessagePack extensions\nimport { ExtData } from \"./ExtData.mjs\";\nimport { timestampExtension } from \"./timestamp.mjs\";\nexport class ExtensionCodec {\n static defaultCodec = new ExtensionCodec();\n // ensures ExtensionCodecType<X> matches ExtensionCodec<X>\n // this will make type errors a lot more clear\n // eslint-disable-next-line @typescript-eslint/naming-convention\n __brand;\n // built-in extensions\n builtInEncoders = [];\n builtInDecoders = [];\n // custom extensions\n encoders = [];\n decoders = [];\n constructor() {\n this.register(timestampExtension);\n }\n register({ type, encode, decode, }) {\n if (type >= 0) {\n // custom extensions\n this.encoders[type] = encode;\n this.decoders[type] = decode;\n }\n else {\n // built-in extensions\n const index = -1 - type;\n this.builtInEncoders[index] = encode;\n this.builtInDecoders[index] = decode;\n }\n }\n tryToEncode(object, context) {\n // built-in extensions\n for (let i = 0; i < this.builtInEncoders.length; i++) {\n const encodeExt = this.builtInEncoders[i];\n if (encodeExt != null) {\n const data = encodeExt(object, context);\n if (data != null) {\n const type = -1 - i;\n return new ExtData(type, data);\n }\n }\n }\n // custom extensions\n for (let i = 0; i < this.encoders.length; i++) {\n const encodeExt = this.encoders[i];\n if (encodeExt != null) {\n const data = encodeExt(object, context);\n if (data != null) {\n const type = i;\n return new ExtData(type, data);\n }\n }\n }\n if (object instanceof ExtData) {\n // to keep ExtData as is\n return object;\n }\n return null;\n }\n decode(data, type, context) {\n const decodeExt = type < 0 ? this.builtInDecoders[-1 - type] : this.decoders[type];\n if (decodeExt) {\n return decodeExt(data, type, context);\n }\n else {\n // decode() does not fail, returns ExtData instead.\n return new ExtData(type, data);\n }\n }\n}\n//# sourceMappingURL=ExtensionCodec.mjs.map","function isArrayBufferLike(buffer) {\n return (buffer instanceof ArrayBuffer || (typeof SharedArrayBuffer !== \"undefined\" && buffer instanceof SharedArrayBuffer));\n}\nexport function ensureUint8Array(buffer) {\n if (buffer instanceof Uint8Array) {\n return buffer;\n }\n else if (ArrayBuffer.isView(buffer)) {\n return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);\n }\n else if (isArrayBufferLike(buffer)) {\n return new Uint8Array(buffer);\n }\n else {\n // ArrayLike<number>\n return Uint8Array.from(buffer);\n }\n}\n//# sourceMappingURL=typedArrays.mjs.map","import { utf8Count, utf8Encode } from \"./utils/utf8.mjs\";\nimport { ExtensionCodec } from \"./ExtensionCodec.mjs\";\nimport { setInt64, setUint64 } from \"./utils/int.mjs\";\nimport { ensureUint8Array } from \"./utils/typedArrays.mjs\";\nexport const DEFAULT_MAX_DEPTH = 100;\nexport const DEFAULT_INITIAL_BUFFER_SIZE = 2048;\nexport class Encoder {\n extensionCodec;\n context;\n useBigInt64;\n maxDepth;\n initialBufferSize;\n sortKeys;\n forceFloat32;\n ignoreUndefined;\n forceIntegerToFloat;\n pos;\n view;\n bytes;\n entered = false;\n constructor(options) {\n this.extensionCodec = options?.extensionCodec ?? ExtensionCodec.defaultCodec;\n this.context = options?.context; // needs a type assertion because EncoderOptions has no context property when ContextType is undefined\n this.useBigInt64 = options?.useBigInt64 ?? false;\n this.maxDepth = options?.maxDepth ?? DEFAULT_MAX_DEPTH;\n this.initialBufferSize = options?.initialBufferSize ?? DEFAULT_INITIAL_BUFFER_SIZE;\n this.sortKeys = options?.sortKeys ?? false;\n this.forceFloat32 = options?.forceFloat32 ?? false;\n this.ignoreUndefined = options?.ignoreUndefined ?? false;\n this.forceIntegerToFloat = options?.forceIntegerToFloat ?? false;\n this.pos = 0;\n this.view = new DataView(new ArrayBuffer(this.initialBufferSize));\n this.bytes = new Uint8Array(this.view.buffer);\n }\n clone() {\n // Because of slightly special argument `context`,\n // type assertion is needed.\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n return new Encoder({\n extensionCodec: this.extensionCodec,\n context: this.context,\n useBigInt64: this.useBigInt64,\n maxDepth: this.maxDepth,\n initialBufferSize: this.initialBufferSize,\n sortKeys: this.sortKeys,\n forceFloat32: this.forceFloat32,\n ignoreUndefined: this.ignoreUndefined,\n forceIntegerToFloat: this.forceIntegerToFloat,\n });\n }\n reinitializeState() {\n this.pos = 0;\n }\n /**\n * This is almost equivalent to {@link Encoder#encode}, but it returns an reference of the encoder's internal buffer and thus much faster than {@link Encoder#encode}.\n *\n * @returns Encodes the object and returns a shared reference the encoder's internal buffer.\n */\n encodeSharedRef(object) {\n if (this.entered) {\n const instance = this.clone();\n return instance.encodeSharedRef(object);\n }\n try {\n this.entered = true;\n this.reinitializeState();\n this.doEncode(object, 1);\n return this.bytes.subarray(0, this.pos);\n }\n finally {\n this.entered = false;\n }\n }\n /**\n * @returns Encodes the object and returns a copy of the encoder's internal buffer.\n */\n encode(object) {\n if (this.entered) {\n const instance = this.clone();\n return instance.encode(object);\n }\n try {\n this.entered = true;\n this.reinitializeState();\n this.doEncode(object, 1);\n return this.bytes.slice(0, this.pos);\n }\n finally {\n this.entered = false;\n }\n }\n doEncode(object, depth) {\n if (depth > this.maxDepth) {\n throw new Error(`Too deep objects in depth ${depth}`);\n }\n if (object == null) {\n this.encodeNil();\n }\n else if (typeof object === \"boolean\") {\n this.encodeBoolean(object);\n }\n else if (typeof object === \"number\") {\n if (!this.forceIntegerToFloat) {\n this.encodeNumber(object);\n }\n else {\n this.encodeNumberAsFloat(object);\n }\n }\n else if (typeof object === \"string\") {\n this.encodeString(object);\n }\n else if (this.useBigInt64 && typeof object === \"bigint\") {\n this.encodeBigInt64(object);\n }\n else {\n this.encodeObject(object, depth);\n }\n }\n ensureBufferSizeToWrite(sizeToWrite) {\n const requiredSize = this.pos + sizeToWrite;\n if (this.view.byteLength < requiredSize) {\n this.resizeBuffer(requiredSize * 2);\n }\n }\n resizeBuffer(newSize) {\n const newBuffer = new ArrayBuffer(newSize);\n const newBytes = new Uint8Array(newBuffer);\n const newView = new DataView(newBuffer);\n newBytes.set(this.bytes);\n this.view = newView;\n this.bytes = newBytes;\n }\n encodeNil() {\n this.writeU8(0xc0);\n }\n encodeBoolean(object) {\n if (object === false) {\n this.writeU8(0xc2);\n }\n else {\n this.writeU8(0xc3);\n }\n }\n encodeNumber(object) {\n if (!this.forceIntegerToFloat && Number.isSafeInteger(object)) {\n if (object >= 0) {\n if (object < 0x80) {\n // positive fixint\n this.writeU8(object);\n }\n else if (object < 0x100) {\n // uint 8\n this.writeU8(0xcc);\n this.writeU8(object);\n }\n else if (object < 0x10000) {\n // uint 16\n this.writeU8(0xcd);\n this.writeU16(object);\n }\n else if (object < 0x100000000) {\n // uint 32\n this.writeU8(0xce);\n this.writeU32(object);\n }\n else if (!this.useBigInt64) {\n // uint 64\n this.writeU8(0xcf);\n this.writeU64(object);\n }\n else {\n this.encodeNumberAsFloat(object);\n }\n }\n else {\n if (object >= -0x20) {\n // negative fixint\n this.writeU8(0xe0 | (object + 0x20));\n }\n else if (object >= -0x80) {\n // int 8\n this.writeU8(0xd0);\n this.writeI8(object);\n }\n else if (object >= -0x8000) {\n // int 16\n this.writeU8(0xd1);\n this.writeI16(object);\n }\n else if (object >= -0x80000000) {\n // int 32\n this.writeU8(0xd2);\n this.writeI32(object);\n }\n else if (!this.useBigInt64) {\n // int 64\n this.writeU8(0xd3);\n this.writeI64(object);\n }\n else {\n this.encodeNumberAsFloat(object);\n }\n }\n }\n else {\n this.encodeNumberAsFloat(object);\n }\n }\n encodeNumberAsFloat(object) {\n if (this.forceFloat32) {\n // float 32\n this.writeU8(0xca);\n this.writeF32(object);\n }\n else {\n // float 64\n this.writeU8(0xcb);\n this.writeF64(object);\n }\n }\n encodeBigInt64(object) {\n if (object >= BigInt(0)) {\n // uint 64\n this.writeU8(0xcf);\n this.writeBigUint64(object);\n }\n else {\n // int 64\n this.writeU8(0xd3);\n this.writeBigInt64(object);\n }\n }\n writeStringHeader(byteLength) {\n if (byteLength < 32) {\n // fixstr\n this.writeU8(0xa0 + byteLength);\n }\n else if (byteLength < 0x100) {\n // str 8\n this.writeU8(0xd9);\n this.writeU8(byteLength);\n }\n else if (byteLength < 0x10000) {\n // str 16\n this.writeU8(0xda);\n this.writeU16(byteLength);\n }\n else if (byteLength < 0x100000000) {\n // str 32\n this.writeU8(0xdb);\n this.writeU32(byteLength);\n }\n else {\n throw new Error(`Too long string: ${byteLength} bytes in UTF-8`);\n }\n }\n encodeString(object) {\n const maxHeaderSize = 1 + 4;\n const byteLength = utf8Count(object);\n this.ensureBufferSizeToWrite(maxHeaderSize + byteLength);\n this.writeStringHeader(byteLength);\n utf8Encode(object, this.bytes, this.pos);\n this.pos += byteLength;\n }\n encodeObject(object, depth) {\n // try to encode objects with custom codec first of non-primitives\n const ext = this.extensionCodec.tryToEncode(object, this.context);\n if (ext != null) {\n this.encodeExtension(ext);\n }\n else if (Array.isArray(object)) {\n this.encodeArray(object, depth);\n }\n else if (ArrayBuffer.isView(object)) {\n this.encodeBinary(object);\n }\n else if (typeof object === \"object\") {\n this.encodeMap(object, depth);\n }\n else {\n // symbol, function and other special object come here unless extensionCodec handles them.\n throw new Error(`Unrecognized object: ${Object.prototype.toString.apply(object)}`);\n }\n }\n encodeBinary(object) {\n const size = object.byteLength;\n if (size < 0x100) {\n // bin 8\n this.writeU8(0xc4);\n this.writeU8(size);\n }\n else if (size < 0x10000) {\n // bin 16\n this.writeU8(0xc5);\n this.writeU16(size);\n }\n else if (size < 0x100000000) {\n // bin 32\n this.writeU8(0xc6);\n this.writeU32(size);\n }\n else {\n throw new Error(`Too large binary: ${size}`);\n }\n const bytes = ensureUint8Array(object);\n this.writeU8a(bytes);\n }\n encodeArray(object, depth) {\n const size = object.length;\n if (size < 16) {\n // fixarray\n this.writeU8(0x90 + size);\n }\n else if (size < 0x10000) {\n // array 16\n this.writeU8(0xdc);\n this.writeU16(size);\n }\n else if (size < 0x100000000) {\n // array 32\n this.writeU8(0xdd);\n this.writeU32(size);\n }\n else {\n throw new Error(`Too large array: ${size}`);\n }\n for (const item of object) {\n this.doEncode(item, depth + 1);\n }\n }\n countWithoutUndefined(object, keys) {\n let count = 0;\n for (const key of keys) {\n if (object[key] !== undefined) {\n count++;\n }\n }\n return count;\n }\n encodeMap(object, depth) {\n const keys = Object.keys(object);\n if (this.sortKeys) {\n keys.sort();\n }\n const size = this.ignoreUndefined ? this.countWithoutUndefined(object, keys) : keys.length;\n if (size < 16) {\n // fixmap\n this.writeU8(0x80 + size);\n }\n else if (size < 0x10000) {\n // map 16\n this.writeU8(0xde);\n this.writeU16(size);\n }\n else if (size < 0x100000000) {\n // map 32\n this.writeU8(0xdf);\n this.writeU32(size);\n }\n else {\n throw new Error(`Too large map object: ${size}`);\n }\n for (const key of keys) {\n const value = object[key];\n if (!(this.ignoreUndefined && value === undefined)) {\n this.encodeString(key);\n this.doEncode(value, depth + 1);\n }\n }\n }\n encodeExtension(ext) {\n if (typeof ext.data === \"function\") {\n const data = ext.data(this.pos + 6);\n const size = data.length;\n if (size >= 0x100000000) {\n throw new Error(`Too large extension object: ${size}`);\n }\n this.writeU8(0xc9);\n this.writeU32(size);\n this.writeI8(ext.type);\n this.writeU8a(data);\n return;\n }\n const size = ext.data.length;\n if (size === 1) {\n // fixext 1\n this.writeU8(0xd4);\n }\n else if (size === 2) {\n // fixext 2\n this.writeU8(0xd5);\n }\n else if (size === 4) {\n // fixext 4\n this.writeU8(0xd6);\n }\n else if (size === 8) {\n // fixext 8\n this.writeU8(0xd7);\n }\n else if (size === 16) {\n // fixext 16\n this.writeU8(0xd8);\n }\n else if (size < 0x100) {\n // ext 8\n this.writeU8(0xc7);\n this.writeU8(size);\n }\n else if (size < 0x10000) {\n // ext 16\n this.writeU8(0xc8);\n this.writeU16(size);\n }\n else if (size < 0x100000000) {\n // ext 32\n this.writeU8(0xc9);\n this.writeU32(size);\n }\n else {\n throw new Error(`Too large extension object: ${size}`);\n }\n this.writeI8(ext.type);\n this.writeU8a(ext.data);\n }\n writeU8(value) {\n this.ensureBufferSizeToWrite(1);\n this.view.setUint8(this.pos, value);\n this.pos++;\n }\n writeU8a(values) {\n const size = values.length;\n this.ensureBufferSizeToWrite(size);\n this.bytes.set(values, this.pos);\n this.pos += size;\n }\n writeI8(value) {\n this.ensureBufferSizeToWrite(1);\n this.view.setInt8(this.pos, value);\n this.pos++;\n }\n writeU16(value) {\n this.ensureBufferSizeToWrite(2);\n this.view.setUint16(this.pos, value);\n this.pos += 2;\n }\n writeI16(value) {\n this.ensureBufferSizeToWrite(2);\n this.view.setInt16(this.pos, value);\n this.pos += 2;\n }\n writeU32(value) {\n this.ensureBufferSizeToWrite(4);\n this.view.setUint32(this.pos, value);\n this.pos += 4;\n }\n writeI32(value) {\n this.ensureBufferSizeToWrite(4);\n this.view.setInt32(this.pos, value);\n this.pos += 4;\n }\n writeF32(value) {\n this.ensureBufferSizeToWrite(4);\n this.view.setFloat32(this.pos, value);\n this.pos += 4;\n }\n writeF64(value) {\n this.ensureBufferSizeToWrite(8);\n this.view.setFloat64(this.pos, value);\n this.pos += 8;\n }\n writeU64(value) {\n this.ensureBufferSizeToWrite(8);\n setUint64(this.view, this.pos, value);\n this.pos += 8;\n }\n writeI64(value) {\n this.ensureBufferSizeToWrite(8);\n setInt64(this.view, this.pos, value);\n this.pos += 8;\n }\n writeBigUint64(value) {\n this.ensureBufferSizeToWrite(8);\n this.view.setBigUint64(this.pos, value);\n this.pos += 8;\n }\n writeBigInt64(value) {\n this.ensureBufferSizeToWrite(8);\n this.view.setBigInt64(this.pos, value);\n this.pos += 8;\n }\n}\n//# sourceMappingURL=Encoder.mjs.map","import { Encoder } from \"./Encoder.mjs\";\n/**\n * It encodes `value` in the MessagePack format and\n * returns a byte buffer.\n *\n * The returned buffer is a slice of a larger `ArrayBuffer`, so you have to use its `#byteOffset` and `#byteLength` in order to convert it to another typed arrays including NodeJS `Buffer`.\n */\nexport function encode(value, options) {\n const encoder = new Encoder(options);\n return encoder.encodeSharedRef(value);\n}\n//# sourceMappingURL=encode.mjs.map","export function prettyByte(byte) {\n return `${byte < 0 ? \"-\" : \"\"}0x${Math.abs(byte).toString(16).padStart(2, \"0\")}`;\n}\n//# sourceMappingURL=prettyByte.mjs.map","import { utf8DecodeJs } from \"./utils/utf8.mjs\";\nconst DEFAULT_MAX_KEY_LENGTH = 16;\nconst DEFAULT_MAX_LENGTH_PER_KEY = 16;\nexport class CachedKeyDecoder {\n hit = 0;\n miss = 0;\n caches;\n maxKeyLength;\n maxLengthPerKey;\n constructor(maxKeyLength = DEFAULT_MAX_KEY_LENGTH, maxLengthPerKey = DEFAULT_MAX_LENGTH_PER_KEY) {\n this.maxKeyLength = maxKeyLength;\n this.maxLengthPerKey = maxLengthPerKey;\n // avoid `new Array(N)`, which makes a sparse array,\n // because a sparse array is typically slower than a non-sparse array.\n this.caches = [];\n for (let i = 0; i < this.maxKeyLength; i++) {\n this.caches.push([]);\n }\n }\n canBeCached(byteLength) {\n return byteLength > 0 && byteLength <= this.maxKeyLength;\n }\n find(bytes, inputOffset, byteLength) {\n const records = this.caches[byteLength - 1];\n FIND_CHUNK: for (const record of records) {\n const recordBytes = record.bytes;\n for (let j = 0; j < byteLength; j++) {\n if (recordBytes[j] !== bytes[inputOffset + j]) {\n continue FIND_CHUNK;\n }\n }\n return record.str;\n }\n return null;\n }\n store(bytes, value) {\n const records = this.caches[bytes.length - 1];\n const record = { bytes, str: value };\n if (records.length >= this.maxLengthPerKey) {\n // `records` are full!\n // Set `record` to an arbitrary position.\n records[(Math.random() * records.length) | 0] = record;\n }\n else {\n records.push(record);\n }\n }\n decode(bytes, inputOffset, byteLength) {\n const cachedValue = this.find(bytes, inputOffset, byteLength);\n if (cachedValue != null) {\n this.hit++;\n return cachedValue;\n }\n this.miss++;\n const str = utf8DecodeJs(bytes, inputOffset, byteLength);\n // Ensure to copy a slice of bytes because the bytes may be a NodeJS Buffer and Buffer#slice() returns a reference to its internal ArrayBuffer.\n const slicedCopyOfBytes = Uint8Array.prototype.slice.call(bytes, inputOffset, inputOffset + byteLength);\n this.store(slicedCopyOfBytes, str);\n return str;\n }\n}\n//# sourceMappingURL=CachedKeyDecoder.mjs.map","import { prettyByte } from \"./utils/prettyByte.mjs\";\nimport { ExtensionCodec } from \"./ExtensionCodec.mjs\";\nimport { getInt64, getUint64, UINT32_MAX } from \"./utils/int.mjs\";\nimport { utf8Decode } from \"./utils/utf8.mjs\";\nimport { ensureUint8Array } from \"./utils/typedArrays.mjs\";\nimport { CachedKeyDecoder } from \"./CachedKeyDecoder.mjs\";\nimport { DecodeError } from \"./DecodeError.mjs\";\nconst STATE_ARRAY = \"array\";\nconst STATE_MAP_KEY = \"map_key\";\nconst STATE_MAP_VALUE = \"map_value\";\nconst mapKeyConverter = (key) => {\n if (typeof key === \"string\" || typeof key === \"number\") {\n return key;\n }\n throw new DecodeError(\"The type of key must be string or number but \" + typeof key);\n};\nclass StackPool {\n stack = [];\n stackHeadPosition = -1;\n get length() {\n return this.stackHeadPosition + 1;\n }\n top() {\n return this.stack[this.stackHeadPosition];\n }\n pushArrayState(size) {\n const state = this.getUninitializedStateFromPool();\n state.type = STATE_ARRAY;\n state.position = 0;\n state.size = size;\n state.array = new Array(size);\n }\n pushMapState(size) {\n const state = this.getUninitializedStateFromPool();\n state.type = STATE_MAP_KEY;\n state.readCount = 0;\n state.size = size;\n state.map = {};\n }\n getUninitializedStateFromPool() {\n this.stackHeadPosition++;\n if (this.stackHeadPosition === this.stack.length) {\n const partialState = {\n type: undefined,\n size: 0,\n array: undefined,\n position: 0,\n readCount: 0,\n map: undefined,\n key: null,\n };\n this.stack.push(partialState);\n }\n return this.stack[this.stackHeadPosition];\n }\n release(state) {\n const topStackState = this.stack[this.stackHeadPosition];\n if (topStackState !== state) {\n throw new Error(\"Invalid stack state. Released state is not on top of the stack.\");\n }\n if (state.type === STATE_ARRAY) {\n const partialState = state;\n partialState.size = 0;\n partialState.array = undefined;\n partialState.position = 0;\n partialState.type = undefined;\n }\n if (state.type === STATE_MAP_KEY || state.type === STATE_MAP_VALUE) {\n const partialState = state;\n partialState.size = 0;\n partialState.map = undefined;\n partialState.readCount = 0;\n partialState.type = undefined;\n }\n this.stackHeadPosition--;\n }\n reset() {\n this.stack.length = 0;\n this.stackHeadPosition = -1;\n }\n}\nconst HEAD_BYTE_REQUIRED = -1;\nconst EMPTY_VIEW = new DataView(new ArrayBuffer(0));\nconst EMPTY_BYTES = new Uint8Array(EMPTY_VIEW.buffer);\ntry {\n // IE11: The spec says it should throw RangeError,\n // IE11: but in IE11 it throws TypeError.\n EMPTY_VIEW.getInt8(0);\n}\ncatch (e) {\n if (!(e instanceof RangeError)) {\n throw new Error(\"This module is not supported in the current JavaScript engine because DataView does not throw RangeError on out-of-bounds access\");\n }\n}\nconst MORE_DATA = new RangeError(\"Insufficient data\");\nconst sharedCachedKeyDecoder = new CachedKeyDecoder();\nexport class Decoder {\n extensionCodec;\n context;\n useBigInt64;\n rawStrings;\n maxStrLength;\n maxBinLength;\n maxArrayLength;\n maxMapLength;\n maxExtLength;\n keyDecoder;\n mapKeyConverter;\n totalPos = 0;\n pos = 0;\n view = EMPTY_VIEW;\n bytes = EMPTY_BYTES;\n headByte = HEAD_BYTE_REQUIRED;\n stack = new StackPool();\n entered = false;\n constructor(options) {\n this.extensionCodec = options?.extensionCodec ?? ExtensionCodec.defaultCodec;\n this.context = options?.context; // needs a type assertion because EncoderOptions has no context property when ContextType is undefined\n this.useBigInt64 = options?.useBigInt64 ?? false;\n this.rawStrings = options?.rawStrings ?? false;\n this.maxStrLength = options?.maxStrLength ?? UINT32_MAX;\n this.maxBinLength = options?.maxBinLength ?? UINT32_MAX;\n this.maxArrayLength = options?.maxArrayLength ?? UINT32_MAX;\n this.maxMapLength = options?.maxMapLength ?? UINT32_MAX;\n this.maxExtLength = options?.maxExtLength ?? UINT32_MAX;\n this.keyDecoder = options?.keyDecoder !== undefined ? options.keyDecoder : sharedCachedKeyDecoder;\n this.mapKeyConverter = options?.mapKeyConverter ?? mapKeyConverter;\n }\n clone() {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n return new Decoder({\n extensionCodec: this.extensionCodec,\n context: this.context,\n useBigInt64: this.useBigInt64,\n rawStrings: this.rawStrings,\n maxStrLength: this.maxStrLength,\n maxBinLength: this.maxBinLength,\n maxArrayLength: this.maxArrayLength,\n maxMapLength: this.maxMapLength,\n maxExtLength: this.maxExtLength,\n keyDecoder: this.keyDecoder,\n });\n }\n reinitializeState() {\n this.totalPos = 0;\n this.headByte = HEAD_BYTE_REQUIRED;\n this.stack.reset();\n // view, bytes, and pos will be re-initialized in setBuffer()\n }\n setBuffer(buffer) {\n const bytes = ensureUint8Array(buffer);\n this.bytes = bytes;\n this.view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n this.pos = 0;\n }\n appendBuffer(buffer) {\n if (this.headByte === HEAD_BYTE_REQUIRED && !this.hasRemaining(1)) {\n this.setBuffer(buffer);\n }\n else {\n const remainingData = this.bytes.subarray(this.pos);\n const newData = ensureUint8Array(buffer);\n // concat remainingData + newData\n const newBuffer = new Uint8Array(remainingData.length + newData.length);\n newBuffer.set(remainingData);\n newBuffer.set(newData, remainingData.length);\n this.setBuffer(newBuffer);\n }\n }\n hasRemaining(size) {\n return this.view.byteLength - this.pos >= size;\n }\n createExtraByteError(posToShow) {\n const { view, pos } = this;\n return new RangeError(`Extra ${view.byteLength - pos} of ${view.byteLength} byte(s) found at buffer[${posToShow}]`);\n }\n /**\n * @throws {@link DecodeError}\n * @throws {@link RangeError}\n */\n decode(buffer) {\n if (this.entered) {\n const instance = this.clone();\n return instance.decode(buffer);\n }\n try {\n this.entered = true;\n this.reinitializeState();\n this.setBuffer(buffer);\n const object = this.doDecodeSync();\n if (this.hasRemaining(1)) {\n throw this.createExtraByteError(this.pos);\n }\n return object;\n }\n finally {\n this.entered = false;\n }\n }\n *decodeMulti(buffer) {\n if (this.entered) {\n const instance = this.clone();\n yield* instance.decodeMulti(buffer);\n return;\n }\n try {\n this.entered = true;\n this.reinitializeState();\n this.setBuffer(buffer);\n while (this.hasRemaining(1)) {\n yield this.doDecodeSync();\n }\n }\n finally {\n this.entered = false;\n }\n }\n async decodeAsync(stream) {\n if (this.entered) {\n const instance = this.clone();\n return instance.decodeAsync(stream);\n }\n try {\n this.entered = true;\n let decoded = false;\n let object;\n for await (const buffer of stream) {\n if (decoded) {\n this.entered = false;\n throw this.createExtraByteError(this.totalPos);\n }\n this.appendBuffer(buffer);\n try {\n object = this.doDecodeSync();\n decoded = true;\n }\n catch (e) {\n if (!(e instanceof RangeError)) {\n throw e; // rethrow\n }\n // fallthrough\n }\n this.totalPos += this.pos;\n }\n if (decoded) {\n if (this.hasRemaining(1)) {\n throw this.createExtraByteError(this.totalPos);\n }\n return object;\n }\n const { headByte, pos, totalPos } = this;\n throw new RangeError(`Insufficient data in parsing ${prettyByte(headByte)} at ${totalPos} (${pos} in the current buffer)`);\n }\n finally {\n this.entered = false;\n }\n }\n decodeArrayStream(stream) {\n return this.decodeMultiAsync(stream, true);\n }\n decodeStream(stream) {\n return this.decodeMultiAsync(stream, false);\n }\n async *decodeMultiAsync(stream, isArray) {\n if (this.entered) {\n const instance = this.clone();\n yield* instance.decodeMultiAsync(stream, isArray);\n return;\n }\n try {\n this.entered = true;\n let isArrayHeaderRequired = isArray;\n let arrayItemsLeft = -1;\n for await (const buffer of stream) {\n if (isArray && arrayItemsLeft === 0) {\n throw this.createExtraByteError(this.totalPos);\n }\n this.appendBuffer(buffer);\n if (isArrayHeaderRequired) {\n arrayItemsLeft = this.readArraySize();\n isArrayHeaderRequired = false;\n this.complete();\n }\n try {\n while (true) {\n yield this.doDecodeSync();\n if (--arrayItemsLeft === 0) {\n break;\n }\n }\n }\n catch (e) {\n if (!(e instanceof RangeError)) {\n throw e; // rethrow\n }\n // fallthrough\n }\n this.totalPos += this.pos;\n }\n }\n finally {\n this.entered = false;\n }\n }\n doDecodeSync() {\n DECODE: while (true) {\n const headByte = this.readHeadByte();\n let object;\n if (headByte >= 0xe0) {\n // negative fixint (111x xxxx) 0xe0 - 0xff\n object = headByte - 0x100;\n }\n else if (headByte < 0xc0) {\n if (headByte < 0x80) {\n // positive fixint (0xxx xxxx) 0x00 - 0x7f\n object = headByte;\n }\n else if (headByte < 0x90) {\n // fixmap (1000 xxxx) 0x80 - 0x8f\n const size = headByte - 0x80;\n if (size !== 0) {\n this.pushMapState(size);\n this.complete();\n continue DECODE;\n }\n else {\n object = {};\n }\n }\n else if (headByte < 0xa0) {\n // fixarray (1001 xxxx) 0x90 - 0x9f\n const size = headByte - 0x90;\n if (size !== 0) {\n this.pushArrayState(size);\n this.complete();\n continue DECODE;\n }\n else {\n object = [];\n }\n }\n else {\n // fixstr (101x xxxx) 0xa0 - 0xbf\n const byteLength = headByte - 0xa0;\n object = this.decodeString(byteLength, 0);\n }\n }\n else if (headByte === 0xc0) {\n // nil\n object = null;\n }\n else if (headByte === 0xc2) {\n // false\n object = false;\n }\n else if (headByte === 0xc3) {\n // true\n object = true;\n }\n else if (headByte === 0xca) {\n // float 32\n object = this.readF32();\n }\n else if (headByte === 0xcb) {\n // float 64\n object = this.readF64();\n }\n else if (headByte === 0xcc) {\n // uint 8\n object = this.readU8();\n }\n else if (headByte === 0xcd) {\n // uint 16\n object = this.readU16();\n }\n else if (headByte === 0xce) {\n // uint 32\n object = this.readU32();\n }\n else if (headByte === 0xcf) {\n // uint 64\n if (this.useBigInt64) {\n object = this.readU64AsBigInt();\n }\n else {\n object = this.readU64();\n }\n }\n else if (headByte === 0xd0) {\n // int 8\n object = this.readI8();\n }\n else if (headByte === 0xd1) {\n // int 16\n object = this.readI16();\n }\n else if (headByte === 0xd2) {\n // int 32\n object = this.readI32();\n }\n else if (headByte === 0xd3) {\n // int 64\n if (this.useBigInt64) {\n object = this.readI64AsBigInt();\n }\n else {\n object = this.readI64();\n }\n }\n else if (headByte === 0xd9) {\n // str 8\n const byteLength = this.lookU8();\n object = this.decodeString(byteLength, 1);\n }\n else if (headByte === 0xda) {\n // str 16\n const byteLength = this.lookU16();\n object = this.decodeString(byteLength, 2);\n }\n else if (headByte === 0xdb) {\n // str 32\n const byteLength = this.lookU32();\n object = this.decodeString(byteLength, 4);\n }\n else if (headByte === 0xdc) {\n // array 16\n const size = this.readU16();\n if (size !== 0) {\n this.pushArrayState(size);\n this.complete();\n continue DECODE;\n }\n else {\n object = [];\n }\n }\n else if (headByte === 0xdd) {\n // array 32\n const size = this.readU32();\n if (size !== 0) {\n this.pushArrayState(size);\n this.complete();\n continue DECODE;\n }\n else {\n object = [];\n }\n }\n else if (headByte === 0xde) {\n // map 16\n const size = this.readU16();\n if (size !== 0) {\n this.pushMapState(size);\n this.complete();\n continue DECODE;\n }\n else {\n object = {};\n }\n }\n else if (headByte === 0xdf) {\n // map 32\n const size = this.readU32();\n if (size !== 0) {\n this.pushMapState(size);\n this.complete();\n continue DECODE;\n }\n else {\n object = {};\n }\n }\n else if (headByte === 0xc4) {\n // bin 8\n const size = this.lookU8();\n object = this.decodeBinary(size, 1);\n }\n else if (headByte === 0xc5) {\n // bin 16\n const size = this.lookU16();\n object = this.decodeBinary(size, 2);\n }\n else if (headByte === 0xc6) {\n // bin 32\n const size = this.lookU32();\n object = this.decodeBinary(size, 4);\n }\n else if (headByte === 0xd4) {\n // fixext 1\n object = this.decodeExtension(1, 0);\n }\n else if (headByte === 0xd5) {\n // fixext 2\n object = this.decodeExtension(2, 0);\n }\n else if (headByte === 0xd6) {\n // fixext 4\n object = this.decodeExtension(4, 0);\n }\n else if (headByte === 0xd7) {\n // fixext 8\n object = this.decodeExtension(8, 0);\n }\n else if (headByte === 0xd8) {\n // fixext 16\n object = this.decodeExtension(16, 0);\n }\n else if (headByte === 0xc7) {\n // ext 8\n const size = this.lookU8();\n object = this.decodeExtension(size, 1);\n }\n else if (headByte === 0xc8) {\n // ext 16\n const size = this.lookU16();\n object = this.decodeExtension(size, 2);\n }\n else if (headByte === 0xc9) {\n // ext 32\n const size = this.lookU32();\n object = this.decodeExtension(size, 4);\n }\n else {\n throw new DecodeError(`Unrecognized type byte: ${prettyByte(headByte)}`);\n }\n this.complete();\n const stack = this.stack;\n while (stack.length > 0) {\n // arrays and maps\n const state = stack.top();\n if (state.type === STATE_ARRAY) {\n state.array[state.position] = object;\n state.position++;\n if (state.position === state.size) {\n object = state.array;\n stack.release(state);\n }\n else {\n continue DECODE;\n }\n }\n else if (state.type === STATE_MAP_KEY) {\n if (object === \"__proto__\") {\n throw new DecodeError(\"The key __proto__ is not allowed\");\n }\n state.key = this.mapKeyConverter(object);\n state.type = STATE_MAP_VALUE;\n continue DECODE;\n }\n else {\n // it must be `state.type === State.MAP_VALUE` here\n state.map[state.key] = object;\n state.readCount++;\n if (state.readCount === state.size) {\n object = state.map;\n stack.release(state);\n }\n else {\n state.key = null;\n state.type = STATE_MAP_KEY;\n continue DECODE;\n }\n }\n }\n return object;\n }\n }\n readHeadByte() {\n if (this.headByte === HEAD_BYTE_REQUIRED) {\n this.headByte = this.readU8();\n // console.log(\"headByte\", prettyByte(this.headByte));\n }\n return this.headByte;\n }\n complete() {\n this.headByte = HEAD_BYTE_REQUIRED;\n }\n readArraySize() {\n const headByte = this.readHeadByte();\n switch (headByte) {\n case 0xdc:\n return this.readU16();\n case 0xdd:\n return this.readU32();\n default: {\n if (headByte < 0xa0) {\n return headByte - 0x90;\n }\n else {\n throw new DecodeError(`Unrecognized array type byte: ${prettyByte(headByte)}`);\n }\n }\n }\n }\n pushMapState(size) {\n if (size > this.maxMapLength) {\n throw new DecodeError(`Max length exceeded: map length (${size}) > maxMapLengthLength (${this.maxMapLength})`);\n }\n this.stack.pushMapState(size);\n }\n pushArrayState(size) {\n if (size > this.maxArrayLength) {\n throw new DecodeError(`Max length exceeded: array length (${size}) > maxArrayLength (${this.maxArrayLength})`);\n }\n this.stack.pushArrayState(size);\n }\n decodeString(byteLength, headerOffset) {\n if (!this.rawStrings || this.stateIsMapKey()) {\n return this.decodeUtf8String(byteLength, headerOffset);\n }\n return this.decodeBinary(byteLength, headerOffset);\n }\n /**\n * @throws {@link RangeError}\n */\n decodeUtf8String(byteLength, headerOffset) {\n if (byteLength > this.maxStrLength) {\n throw new DecodeError(`Max length exceeded: UTF-8 byte length (${byteLength}) > maxStrLength (${this.maxStrLength})`);\n }\n if (this.bytes.byteLength < this.pos + headerOffset + byteLength) {\n throw MORE_DATA;\n }\n const offset = this.pos + headerOffset;\n let object;\n if (this.stateIsMapKey() && this.keyDecoder?.canBeCached(byteLength)) {\n object = this.keyDecoder.decode(this.bytes, offset, byteLength);\n }\n else {\n object = utf8Decode(this.bytes, offset, byteLength);\n }\n this.pos += headerOffset + byteLength;\n return object;\n }\n stateIsMapKey() {\n if (this.stack.length > 0) {\n const state = this.stack.top();\n return state.type === STATE_MAP_KEY;\n }\n return false;\n }\n /**\n * @throws {@link RangeError}\n */\n decodeBinary(byteLength, headOffset) {\n if (byteLength > this.maxBinLength) {\n throw new DecodeError(`Max length exceeded: bin length (${byteLength}) > maxBinLength (${this.maxBinLength})`);\n }\n if (!this.hasRemaining(byteLength + headOffset)) {\n throw MORE_DATA;\n }\n const offset = this.pos + headOffset;\n const object = this.bytes.subarray(offset, offset + byteLength);\n this.pos += headOffset + byteLength;\n return object;\n }\n decodeExtension(size, headOffset) {\n if (size > this.maxExtLength) {\n throw new DecodeError(`Max length exceeded: ext length (${size}) > maxExtLength (${this.maxExtLength})`);\n }\n const extType = this.view.getInt8(this.pos + headOffset);\n const data = this.decodeBinary(size, headOffset + 1 /* extType */);\n return this.extensionCodec.decode(data, extType, this.context);\n }\n lookU8() {\n return this.view.getUint8(this.pos);\n }\n lookU16() {\n return this.view.getUint16(this.pos);\n }\n lookU32() {\n return this.view.getUint32(this.pos);\n }\n readU8() {\n const value = this.view.getUint8(this.pos);\n this.pos++;\n return value;\n }\n readI8() {\n const value = this.view.getInt8(this.pos);\n this.pos++;\n return value;\n }\n readU16() {\n const value = this.view.getUint16(this.pos);\n this.pos += 2;\n return value;\n }\n readI16() {\n const value = this.view.getInt16(this.pos);\n this.pos += 2;\n return value;\n }\n readU32() {\n const value = this.view.getUint32(this.pos);\n this.pos += 4;\n return value;\n }\n readI32() {\n const value = this.view.getInt32(this.pos);\n this.pos += 4;\n return value;\n }\n readU64() {\n const value = getUint64(this.view, this.pos);\n this.pos += 8;\n return value;\n }\n readI64() {\n const value = getInt64(this.view, this.pos);\n this.pos += 8;\n return value;\n }\n readU64AsBigInt() {\n const value = this.view.getBigUint64(this.pos);\n this.pos += 8;\n return value;\n }\n readI64AsBigInt() {\n const value = this.view.getBigInt64(this.pos);\n this.pos += 8;\n return value;\n }\n readF32() {\n const value = this.view.getFloat32(this.pos);\n this.pos += 4;\n return value;\n }\n readF64() {\n const value = this.view.getFloat64(this.pos);\n this.pos += 8;\n return value;\n }\n}\n//# sourceMappingURL=Decoder.mjs.map","import { Decoder } from \"./Decoder.mjs\";\n/**\n * It decodes a single MessagePack object in a buffer.\n *\n * This is a synchronous decoding function.\n * See other variants for asynchronous decoding: {@link decodeAsync}, {@link decodeMultiStream}, or {@link decodeArrayStream}.\n *\n * @throws {@link RangeError} if the buffer is incomplete, including the case where the buffer is empty.\n * @throws {@link DecodeError} if the buffer contains invalid data.\n */\nexport function decode(buffer, options) {\n const decoder = new Decoder(options);\n return decoder.decode(buffer);\n}\n/**\n * It decodes multiple MessagePack objects in a buffer.\n * This is corresponding to {@link decodeMultiStream}.\n *\n * @throws {@link RangeError} if the buffer is incomplete, including the case where the buffer is empty.\n * @throws {@link DecodeError} if the buffer contains invalid data.\n */\nexport function decodeMulti(buffer, options) {\n const decoder = new Decoder(options);\n return decoder.decodeMulti(buffer);\n}\n//# sourceMappingURL=decode.mjs.map","import { encode as mpEncode, decode as mpDecode } from '@msgpack/msgpack'\nimport type { ClientFrame, ServerFrame } from './frames.js'\n\nexport type AnyFrame = ClientFrame | ServerFrame\n\nconst CLIENT_FRAME_TYPES: ReadonlySet<ClientFrame['type']> = new Set([\n 'auth', 'open', 'send', 'sync', 'history', 'read', 'typing', 'react', 'edit', 'delete', 'invoke', 'pubkey', 'ping', 'annotate', 'annotate_clear',\n])\n\n/** True if a decoded frame is one a client is allowed to send. The server uses\n * this to reject server-only frame types before dispatch, so a malicious or\n * buggy client can't reach an unexpected handler path. */\nexport function isClientFrame(frame: AnyFrame): frame is ClientFrame {\n return CLIENT_FRAME_TYPES.has(frame.type as ClientFrame['type'])\n}\n\n/** Encode a frame to a binary msgpack payload for the wire. */\nexport function encodeFrame(frame: AnyFrame): Uint8Array {\n return mpEncode(frame)\n}\n\n/** Decode a binary payload into a frame. Returns null on any malformed input or\n * anything lacking a string `type`, so a bad frame can never crash the handler\n * — the boundary validates `type` before trusting the rest. */\nexport function decodeFrame(bytes: Uint8Array): AnyFrame | null {\n let value: unknown\n try {\n value = mpDecode(bytes)\n } catch {\n return null\n }\n if (typeof value !== 'object' || value === null) return null\n if (typeof (value as { type?: unknown }).type !== 'string') return null\n return value as AnyFrame\n}\n","import type {\n ServerFrame, Message, ManifestAction, MessageContent,\n ConversationId, MessageId, UserId, Subject, AnnotationStroke,\n} from './protocol/index.js'\n\nexport type SendStatus = 'pending' | 'sent' | 'delivered' | 'read'\n\nexport interface RenderMessage extends Message {\n clientMsgId?: string\n status?: SendStatus\n}\n\n/** Pure, DOM-free conversation state. Feed it ServerFrames (and local optimistic\n * sends); read an ordered, de-duplicated view out. Ordering is by `seq`; the\n * same message arriving twice (live + sync on reconnect) is collapsed by id —\n * the structural fix for the old duplicate-bubble bug. */\nexport class ChatStore {\n conversationId?: ConversationId\n state = ''\n version = 0\n hasMoreHistory = false\n lastReadByOthers = 0\n assignedAgentId: UserId | undefined\n accent: string | undefined\n subject: Subject | undefined\n name: string | undefined\n e2e = false\n offline = false\n offlineMessage = ''\n whiteLabel = false\n readonly typing = new Set<string>()\n readonly online = new Set<string>()\n /** Co-browsing: shared whiteboard strokes for this conversation. */\n annotations: AnnotationStroke[] = []\n /** Bumped on any annotation change so the renderer can cheaply detect updates. */\n annotationVersion = 0\n /** Live sentiment of the guest's latest message (agent-side only). */\n sentiment: 'positive' | 'neutral' | 'frustrated' | undefined\n sentimentScore: number | undefined\n\n private actions: ManifestAction[] = []\n private readonly byId = new Map<string, RenderMessage>()\n private readonly keyByClient = new Map<string, string>()\n private _maxSeq = 0\n private _sorted: RenderMessage[] | null = null\n\n constructor(private readonly me: UserId) {}\n\n messages(): RenderMessage[] {\n if (!this._sorted) {\n this._sorted = [...this.byId.values()].sort((a, b) => {\n const ap = a.status === 'pending', bp = b.status === 'pending'\n if (ap !== bp) return ap ? 1 : -1\n if (ap && bp) return a.ts - b.ts\n return a.seq - b.seq\n })\n }\n return this._sorted\n }\n\n visibleActions(): ManifestAction[] {\n return this.actions.filter(a => !a.availableInStates || a.availableInStates.includes(this.state))\n }\n\n highestSeq(): number { return this._maxSeq }\n\n addOptimistic(clientMsgId: string, content: MessageContent): RenderMessage {\n const msg: RenderMessage = {\n id: clientMsgId as MessageId, conversationId: this.conversationId as ConversationId,\n seq: 0, senderId: this.me, senderRole: 'guest', content, ts: Date.now(),\n clientMsgId, status: 'pending',\n }\n this.byId.set(clientMsgId, msg)\n this.keyByClient.set(clientMsgId, clientMsgId)\n this._sorted = null\n return msg\n }\n\n apply(frame: ServerFrame): void {\n switch (frame.type) {\n case 'opened':\n this.conversationId = frame.conversation.id\n this.state = frame.conversation.state\n if (frame.subject) this.subject = frame.subject\n if (frame.annotations) { this.annotations = frame.annotations; this.annotationVersion++ }\n return\n case 'manifest':\n this.actions = frame.actions\n this.version = frame.version\n if (frame.name) this.name = frame.name\n if (frame.theme?.accent) this.accent = frame.theme.accent\n if (frame.e2e) this.e2e = true\n if (frame.offline) this.offline = true\n if (frame.offlineMessage) this.offlineMessage = frame.offlineMessage\n if (frame.whiteLabel) this.whiteLabel = true\n return\n case 'message':\n this.upsert({ ...frame.message })\n return\n case 'ack': {\n const key = this.keyByClient.get(frame.clientMsgId)\n const msg = key ? this.byId.get(key) : undefined\n if (msg && key) {\n this.byId.delete(key)\n const confirmed: RenderMessage = { ...msg, id: frame.messageId, seq: frame.seq, ts: frame.ts, status: 'sent' }\n this.byId.set(frame.messageId, confirmed)\n this.keyByClient.set(frame.clientMsgId, frame.messageId)\n if (frame.seq > this._maxSeq) this._maxSeq = frame.seq\n }\n this._sorted = null\n return\n }\n case 'delivered':\n this.markOwnStatus(frame.seq, 'delivered')\n return\n case 'read':\n if (frame.by !== this.me) {\n this.lastReadByOthers = Math.max(this.lastReadByOthers, frame.seq)\n this.markOwnStatus(frame.seq, 'read')\n }\n return\n case 'sync':\n for (const m of frame.messages) this.upsert({ ...m })\n return\n case 'history':\n for (const m of frame.messages) this.upsert({ ...m })\n this.hasMoreHistory = frame.hasMore\n return\n case 'typing':\n if (frame.userId !== this.me) {\n if (frame.isTyping) this.typing.add(frame.userId)\n else this.typing.delete(frame.userId)\n }\n return\n case 'reaction': {\n const m = this.byId.get(frame.messageId)\n if (!m) return\n const reactions: Record<string, UserId[]> = { ...(m.reactions ?? {}) }\n const users = (reactions[frame.emoji] ?? []).filter(u => u !== frame.by)\n if (!frame.removed) users.push(frame.by)\n if (users.length) reactions[frame.emoji] = users; else delete reactions[frame.emoji]\n this.byId.set(frame.messageId, { ...m, reactions })\n this._sorted = null\n return\n }\n case 'edited': {\n const m = this.byId.get(frame.messageId)\n if (m) { this.byId.set(frame.messageId, { ...m, content: frame.content, editedAt: frame.editedAt }); this._sorted = null }\n return\n }\n case 'deleted': {\n const m = this.byId.get(frame.messageId)\n if (m) { this.byId.set(frame.messageId, { ...m, deletedAt: frame.ts }); this._sorted = null }\n return\n }\n case 'state':\n this.state = frame.state\n return\n case 'assigned':\n this.assignedAgentId = frame.agentId ?? undefined\n return\n case 'presence':\n if (frame.status === 'online') this.online.add(frame.userId)\n else this.online.delete(frame.userId)\n return\n case 'subjectState':\n case 'invoked':\n case 'authed':\n case 'error':\n case 'pong':\n return\n case 'annotation':\n this.annotations = [...this.annotations, frame.stroke]\n this.annotationVersion++\n return\n case 'annotation_clear':\n this.annotations = []\n this.annotationVersion++\n return\n case 'sentiment':\n this.sentiment = frame.label\n this.sentimentScore = frame.score\n return\n default:\n return\n }\n }\n\n private upsert(msg: RenderMessage): void {\n const existing = this.byId.get(msg.id)\n this.byId.set(msg.id, existing ? { ...existing, ...msg } : msg)\n if (msg.seq > this._maxSeq) this._maxSeq = msg.seq\n this._sorted = null\n }\n\n private markOwnStatus(uptoSeq: number, status: SendStatus): void {\n const targetRank = rank(status)\n let changed = false\n for (const [k, m] of this.byId) {\n if (m.senderId !== this.me || m.seq <= 0 || m.seq > uptoSeq) continue\n if (rank(m.status) >= targetRank) continue // already at or above target — skip\n this.byId.set(k, { ...m, status })\n changed = true\n }\n if (changed) this._sorted = null\n }\n}\nfunction rank(s: SendStatus | undefined): number {\n switch (s) { case 'read': return 3; case 'delivered': return 2; case 'sent': return 1; default: return 0 }\n}\n","import {\n encodeFrame, decodeFrame, isClientFrame,\n type ClientFrame, type ServerFrame,\n} from './protocol/index.js'\n\n// Minimal socket surface so tests can inject a fake without a real WebSocket.\nexport interface SocketLike {\n binaryType: string\n send(data: Uint8Array): void\n close(): void\n onopen: (() => void) | null\n onclose: (() => void) | null\n onerror: (() => void) | null\n onmessage: ((ev: { data: ArrayBuffer }) => void) | null\n}\nexport type SocketFactory = (url: string) => SocketLike\n\nexport interface ConnectionOptions {\n url: string\n token: string\n open: ClientFrame // frame sent right after auth (e.g. open a conversation, or subscribe_inbox)\n onFrame: (frame: ServerFrame) => void\n getCursor: () => number // highest seq seen (for sync on reconnect)\n onStatusChange?: (status: 'connecting' | 'open' | 'reconnecting') => void\n socketFactory?: SocketFactory\n backoffBaseMs?: number\n backoffMaxMs?: number\n maxOutbox?: number\n}\n\ntype State = 'idle' | 'connecting' | 'open' | 'closed'\n\nexport class ConnectionManager {\n private socket: SocketLike | null = null\n private state: State = 'idle'\n private authed = false\n private attempt = 0\n private outbox: ClientFrame[] = []\n private stopped = false\n private timer: ReturnType<typeof setTimeout> | null = null\n\n constructor(private readonly opts: ConnectionOptions) {}\n\n connect(): void {\n if (this.state === 'connecting' || this.state === 'open') return\n this.stopped = false\n this.state = 'connecting'\n this.authed = false\n this.opts.onStatusChange?.(this.attempt > 0 ? 'reconnecting' : 'connecting')\n const make = this.opts.socketFactory ?? defaultFactory\n const sock = make(this.opts.url)\n sock.binaryType = 'arraybuffer'\n this.socket = sock\n\n sock.onopen = () => {\n // Don't reset attempt here — reset only after successful auth ('authed').\n // A connection that opens but fails during auth (bad token, server restart)\n // should still back off, not immediately retry at base delay.\n this.raw({ type: 'auth', token: this.opts.token })\n }\n sock.onmessage = (ev) => {\n const frame = decodeFrame(new Uint8Array(ev.data))\n if (!frame || isClientFrame(frame)) return // ignore non-server frames\n this.handle(frame)\n }\n sock.onclose = () => this.onClosed()\n sock.onerror = () => { try { sock.close() } catch { /* */ } }\n }\n\n /** Queue a frame; sent immediately if open, else flushed on (re)connect.\n * The outbox is bounded so a prolonged outage can't grow memory without limit\n * — oldest queued frames are dropped past the cap. */\n send(frame: ClientFrame): void {\n if (this.state === 'open' && this.authed) { this.raw(frame); return }\n const cap = this.opts.maxOutbox ?? 1_000\n if (this.outbox.length >= cap) {\n // Evict oldest half when full to amortise the O(n) cost of overflow.\n this.outbox = this.outbox.slice(this.outbox.length - (cap >> 1))\n }\n this.outbox.push(frame)\n }\n\n close(): void {\n this.stopped = true\n if (this.timer) clearTimeout(this.timer)\n this.state = 'closed'\n try { this.socket?.close() } catch { /* */ }\n }\n\n private handle(frame: ServerFrame): void {\n if (frame.type === 'authed') {\n this.attempt = 0 // reset backoff only after a fully successful auth\n this.state = 'open'\n this.authed = true\n this.opts.onStatusChange?.('open')\n // Open/resolve the conversation. The catch-up `sync` is sent on 'opened'\n // (below), i.e. only after the server has joined us to the room — sending\n // it here would race the async open and be rejected as \"not joined\".\n this.raw(this.opts.open)\n this.flush()\n }\n // 'opened' confirms we're joined — now catch up from our cursor.\n if (frame.type === 'opened') {\n this.raw({ type: 'sync', conversationId: frame.conversation.id, sinceSeq: this.opts.getCursor() })\n }\n this.opts.onFrame(frame)\n }\n\n private flush(): void {\n const pending = this.outbox\n this.outbox = []\n for (const f of pending) this.raw(f)\n }\n\n private raw(frame: ClientFrame): void {\n try { this.socket?.send(encodeFrame(frame)) } catch { this.outbox.push(frame) }\n }\n\n private onClosed(): void {\n this.authed = false\n this.socket = null\n if (this.stopped) { this.state = 'closed'; return }\n this.state = 'idle'\n // Exponential backoff with jitter; reconnect re-auths, re-opens, re-syncs.\n const base = this.opts.backoffBaseMs ?? 500\n const max = this.opts.backoffMaxMs ?? 15_000\n const delay = Math.min(max, base * 2 ** this.attempt) * (0.5 + Math.random() * 0.5)\n this.attempt++\n this.timer = setTimeout(() => this.connect(), delay)\n }\n}\n\nfunction defaultFactory(url: string): SocketLike {\n return new WebSocket(url) as unknown as SocketLike\n}\n","import type { MessageContent } from './protocol/index.js'\n\nexport interface OutboxItem {\n clientMsgId: string\n content: MessageContent\n ts: number\n}\n\nconst MAX_ITEMS = 200 // cap so a long outage can't grow storage unboundedly\nconst MAX_AGE_MS = 7 * 86_400_000 // drop anything older than 7 days on load\n\n/** Persists not-yet-acknowledged outgoing messages to localStorage, keyed by\n * guest token, so a page reload during a connectivity drop doesn't silently\n * lose what the user typed (the \"WhatsApp\" guarantee: your message is queued\n * until it's confirmed sent, even across app restarts). */\nexport class PersistentOutbox {\n private readonly key: string\n\n constructor(token: string) {\n this.key = `ocw_outbox_${token}`\n }\n\n /** All pending items, oldest first, with stale (>7d) entries dropped. */\n load(): OutboxItem[] {\n try {\n const raw = localStorage.getItem(this.key)\n if (!raw) return []\n const items = JSON.parse(raw) as OutboxItem[]\n const cutoff = Date.now() - MAX_AGE_MS\n const fresh = items.filter(i => i.ts >= cutoff)\n if (fresh.length !== items.length) this.save(fresh)\n return fresh\n } catch {\n return []\n }\n }\n\n add(item: OutboxItem): void {\n try {\n const items = this.load()\n items.push(item)\n // Evict oldest when full — matches the in-memory ConnectionManager outbox policy.\n this.save(items.length > MAX_ITEMS ? items.slice(items.length - MAX_ITEMS) : items)\n } catch { /* localStorage unavailable (private mode, quota) — best-effort only */ }\n }\n\n /** Remove an item once it's been acknowledged by the server. */\n remove(clientMsgId: string): void {\n try {\n const items = this.load().filter(i => i.clientMsgId !== clientMsgId)\n this.save(items)\n } catch { /* best-effort */ }\n }\n\n private save(items: OutboxItem[]): void {\n try { localStorage.setItem(this.key, JSON.stringify(items)) } catch { /* quota exceeded — drop silently */ }\n }\n}\n","/**\n * End-to-end encryption primitives (Web Crypto): ECDH P-256 for key agreement\n * + AES-GCM for message content. The server only ever relays public keys and\n * stores ciphertext — it cannot read messages.\n *\n * Scope/limitations (honest): this secures a *live 1:1* session — the guest and\n * one agent exchange public keys while both are connected, then messages between\n * them are encrypted. True asynchronous E2E (encrypting to an offline party)\n * needs a prekey/X3DH scheme, which is out of scope here. When E2E is on, the\n * AI assistant cannot read the room (by design).\n */\n\nconst subtle = (): SubtleCrypto => globalThis.crypto.subtle\n\nfunction b64encode(buf: ArrayBuffer | Uint8Array): string {\n const bytes = buf instanceof Uint8Array ? buf : new Uint8Array(buf)\n let s = ''\n for (const b of bytes) s += String.fromCharCode(b)\n return btoa(s)\n}\nfunction b64decode(s: string): Uint8Array<ArrayBuffer> {\n const bin = atob(s)\n const buf = new ArrayBuffer(bin.length)\n const out = new Uint8Array(buf)\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i)\n return out\n}\n\nexport interface KeyPair { publicKey: CryptoKey; privateKey: CryptoKey }\n\nexport async function generateKeyPair(): Promise<KeyPair> {\n const kp = await subtle().generateKey({ name: 'ECDH', namedCurve: 'P-256' }, true, ['deriveKey', 'deriveBits'])\n return { publicKey: kp.publicKey, privateKey: kp.privateKey }\n}\n\n/** Export a public key to a compact base64 string (raw, 65 bytes for P-256). */\nexport async function exportPublicKey(key: CryptoKey): Promise<string> {\n return b64encode(await subtle().exportKey('raw', key))\n}\n\nasync function importPeerPublicKey(b64: string): Promise<CryptoKey> {\n return subtle().importKey('raw', b64decode(b64), { name: 'ECDH', namedCurve: 'P-256' }, false, [])\n}\n\n/** Derive the shared AES-GCM key from our private key + the peer's public key. */\nexport async function deriveSharedKey(privateKey: CryptoKey, peerPublicKeyB64: string): Promise<CryptoKey> {\n const peer = await importPeerPublicKey(peerPublicKeyB64)\n return subtle().deriveKey(\n { name: 'ECDH', public: peer },\n privateKey,\n { name: 'AES-GCM', length: 256 },\n false,\n ['encrypt', 'decrypt'],\n )\n}\n\nexport interface Ciphertext { ct: string; iv: string }\n\nexport async function encrypt(key: CryptoKey, plaintext: string): Promise<Ciphertext> {\n const iv = globalThis.crypto.getRandomValues(new Uint8Array(12))\n const data = new TextEncoder().encode(plaintext)\n const ct = await subtle().encrypt({ name: 'AES-GCM', iv }, key, data)\n return { ct: b64encode(ct), iv: b64encode(iv) }\n}\n\nexport async function decrypt(key: CryptoKey, ct: string, iv: string): Promise<string> {\n const plain = await subtle().decrypt({ name: 'AES-GCM', iv: b64decode(iv) }, key, b64decode(ct))\n return new TextDecoder().decode(plain)\n}\n\n/** Persist/restore our keypair across reloads (so prior ciphertext stays readable). */\nexport async function loadOrCreateKeyPair(storageKey: string): Promise<KeyPair> {\n try {\n const raw = globalThis.localStorage?.getItem(storageKey)\n if (raw) {\n const { pub, priv } = JSON.parse(raw) as { pub: JsonWebKey; priv: JsonWebKey }\n const publicKey = await subtle().importKey('jwk', pub, { name: 'ECDH', namedCurve: 'P-256' }, true, [])\n const privateKey = await subtle().importKey('jwk', priv, { name: 'ECDH', namedCurve: 'P-256' }, true, ['deriveKey', 'deriveBits'])\n return { publicKey, privateKey }\n }\n } catch { /* fall through to fresh keys */ }\n const kp = await generateKeyPair()\n try {\n const pub = await subtle().exportKey('jwk', kp.publicKey)\n const priv = await subtle().exportKey('jwk', kp.privateKey)\n globalThis.localStorage?.setItem(storageKey, JSON.stringify({ pub, priv }))\n } catch { /* non-persistent environment is fine */ }\n return kp\n}\n\n// ── X3DH async E2E ────────────────────────────────────────────────────────────\n// Extended Triple Diffie-Hellman (X3DH) allows encrypting to an *offline* peer\n// using their published prekey bundle. This enables asynchronous E2E: the sender\n// can encrypt before the recipient connects.\n//\n// Key roles:\n// IK = long-term identity key (ECDH P-256, persistent in localStorage)\n// SPK = signed prekey (ECDH P-256, rotated periodically, server-stored)\n// OPK = one-time prekey (ECDH P-256, single-use pool, server-stored)\n// EK = ephemeral key (ECDH P-256, generated per-message, discarded after)\n//\n// X3DH shared secret = KDF(DH(IK_s, SPK_r) || DH(EK, IK_r) || DH(EK, SPK_r) || DH(EK, OPK_r))\n// Where _s = sender, _r = recipient.\n\n/** Sign a prekey public key bytes using ECDSA P-256 SHA-256.\n * The signingKey must be an ECDSA P-256 private key (not ECDH).\n * In the full X3DH setup the identity key pair contains both an ECDH key\n * (for DH) and an ECDSA key (for signing). We keep them separate here. */\nexport async function signPrekey(signingPrivateKey: CryptoKey, spkPublicKey: CryptoKey): Promise<string> {\n const spkRaw = await subtle().exportKey('raw', spkPublicKey)\n const sig = await subtle().sign({ name: 'ECDSA', hash: 'SHA-256' }, signingPrivateKey, spkRaw)\n return b64encode(sig)\n}\n\n/** Verify an SPK signature. verifyPublicKey must be an ECDSA P-256 public key. */\nexport async function verifyPrekeySignature(verifyPublicKeyB64: string, spkPublicKeyB64: string, signatureB64: string): Promise<boolean> {\n try {\n const verKey = await subtle().importKey('raw', b64decode(verifyPublicKeyB64), { name: 'ECDSA', namedCurve: 'P-256' }, false, ['verify'])\n return await subtle().verify({ name: 'ECDSA', hash: 'SHA-256' }, verKey, b64decode(signatureB64), b64decode(spkPublicKeyB64))\n } catch { return false }\n}\n\n/** A full identity keypair for X3DH: ECDH key for DH computations + ECDSA key\n * for signing prekeys. The two key objects share the same P-256 curve but have\n * different usages, so Web Crypto treats them separately. */\nexport interface IdentityKeyPair {\n ecdhKP: KeyPair // for DH in X3DH\n ecdsaKP: { publicKey: CryptoKey; privateKey: CryptoKey } // for signing SPKs\n /** The ECDH public key exported as base64 — used as the X3DH identity key. */\n publicKeyB64: string\n /** The ECDSA public key exported as base64 — used for SPK signature verification. */\n sigPublicKeyB64: string\n}\n\n/** Generate a full X3DH identity keypair (ECDH + ECDSA on the same P-256 curve). */\nexport async function generateIdentityKeyPair(): Promise<IdentityKeyPair> {\n const ecdhKP = await generateKeyPair()\n const ecdsaKP = await subtle().generateKey({ name: 'ECDSA', namedCurve: 'P-256' }, true, ['sign', 'verify'])\n return {\n ecdhKP,\n ecdsaKP: { publicKey: ecdsaKP.publicKey, privateKey: ecdsaKP.privateKey },\n publicKeyB64: await exportPublicKey(ecdhKP.publicKey),\n sigPublicKeyB64: await exportPublicKey(ecdsaKP.publicKey),\n }\n}\n\n/** Load or generate an identity keypair, persisting both components. */\nexport async function loadOrCreateIdentityKeyPair(storageKey: string): Promise<IdentityKeyPair> {\n try {\n const raw = globalThis.localStorage?.getItem(`${storageKey}-identity`)\n if (raw) {\n const d = JSON.parse(raw) as { ecdhPub: JsonWebKey; ecdhPriv: JsonWebKey; ecdsaPub: JsonWebKey; ecdsaPriv: JsonWebKey }\n const ecdhPub = await subtle().importKey('jwk', d.ecdhPub, { name: 'ECDH', namedCurve: 'P-256' }, true, [])\n const ecdhPriv = await subtle().importKey('jwk', d.ecdhPriv, { name: 'ECDH', namedCurve: 'P-256' }, true, ['deriveKey', 'deriveBits'])\n const ecdsaPub = await subtle().importKey('jwk', d.ecdsaPub, { name: 'ECDSA', namedCurve: 'P-256' }, true, ['verify'])\n const ecdsaPriv = await subtle().importKey('jwk', d.ecdsaPriv, { name: 'ECDSA', namedCurve: 'P-256' }, true, ['sign'])\n return {\n ecdhKP: { publicKey: ecdhPub, privateKey: ecdhPriv },\n ecdsaKP: { publicKey: ecdsaPub, privateKey: ecdsaPriv },\n publicKeyB64: await exportPublicKey(ecdhPub),\n sigPublicKeyB64: await exportPublicKey(ecdsaPub),\n }\n }\n } catch { /* generate fresh */ }\n const ikp = await generateIdentityKeyPair()\n try {\n const ecdhPub = await subtle().exportKey('jwk', ikp.ecdhKP.publicKey)\n const ecdhPriv = await subtle().exportKey('jwk', ikp.ecdhKP.privateKey)\n const ecdsaPub = await subtle().exportKey('jwk', ikp.ecdsaKP.publicKey)\n const ecdsaPriv = await subtle().exportKey('jwk', ikp.ecdsaKP.privateKey)\n globalThis.localStorage?.setItem(`${storageKey}-identity`, JSON.stringify({ ecdhPub, ecdhPriv, ecdsaPub, ecdsaPriv }))\n } catch { /* non-persistent ok */ }\n return ikp\n}\n\nexport interface X3DHBundle {\n identityKey: string // base64 raw P-256 public key\n signedPrekey: string // base64 raw P-256 public key\n signedPrekeyId: string // opaque ID for key rotation tracking\n signature: string // base64 ECDSA signature of SPK by IK\n oneTimePrekey?: string // base64 raw P-256 public key (optional)\n}\n\n/** X3DH sender side: derive a shared key from the recipient's prekey bundle.\n * Returns the shared AES-GCM key and the ephemeral public key to transmit. */\nexport async function x3dhSend(\n senderIK: KeyPair,\n recipientBundle: X3DHBundle,\n): Promise<{ sharedKey: CryptoKey; ephemeralPublicKey: string }> {\n const ek = await generateKeyPair()\n const epkB64 = await exportPublicKey(ek.publicKey)\n\n // Import recipient keys for DH.\n const ik_r = await importPeerPublicKey(recipientBundle.identityKey)\n const spk_r = await importPeerPublicKey(recipientBundle.signedPrekey)\n const opk_r = recipientBundle.oneTimePrekey ? await importPeerPublicKey(recipientBundle.oneTimePrekey) : null\n\n // Four DH computations per spec (three if no OPK).\n const dh1 = await rawDH(senderIK.privateKey, spk_r) // DH(IK_s, SPK_r)\n const dh2 = await rawDH(ek.privateKey, ik_r) // DH(EK, IK_r)\n const dh3 = await rawDH(ek.privateKey, spk_r) // DH(EK, SPK_r)\n const dh4 = opk_r ? await rawDH(ek.privateKey, opk_r) : null // DH(EK, OPK_r)\n\n const ikm = concatBuffers(dh1, dh2, dh3, ...(dh4 ? [dh4] : []))\n const sharedKey = await hkdfDeriveKey(ikm)\n\n return { sharedKey, ephemeralPublicKey: epkB64 }\n}\n\n/** X3DH recipient side: rederive the shared key from an init message.\n * Returns the shared AES-GCM key. */\nexport async function x3dhReceive(\n recipientIK: KeyPair,\n recipientSPK: KeyPair,\n senderIKb64: string,\n ephemeralKeyB64: string,\n recipientOPK?: KeyPair,\n): Promise<CryptoKey> {\n const ik_s = await importPeerPublicKey(senderIKb64)\n const ek_s = await importPeerPublicKey(ephemeralKeyB64)\n\n const dh1 = await rawDH(recipientSPK.privateKey, ik_s) // DH(SPK_r, IK_s)\n const dh2 = await rawDH(recipientIK.privateKey, ek_s) // DH(IK_r, EK)\n const dh3 = await rawDH(recipientSPK.privateKey, ek_s) // DH(SPK_r, EK)\n const dh4 = recipientOPK ? await rawDH(recipientOPK.privateKey, ek_s) : null\n\n const ikm = concatBuffers(dh1, dh2, dh3, ...(dh4 ? [dh4] : []))\n return hkdfDeriveKey(ikm)\n}\n\nasync function rawDH(privateKey: CryptoKey, publicKey: CryptoKey): Promise<ArrayBuffer> {\n return subtle().deriveBits({ name: 'ECDH', public: publicKey }, privateKey, 256)\n}\n\nfunction concatBuffers(...bufs: ArrayBuffer[]): ArrayBuffer {\n const total = bufs.reduce((n, b) => n + b.byteLength, 0)\n const out = new Uint8Array(total)\n let offset = 0\n for (const b of bufs) { out.set(new Uint8Array(b), offset); offset += b.byteLength }\n return out.buffer\n}\n\nasync function hkdfDeriveKey(ikm: ArrayBuffer): Promise<CryptoKey> {\n const ikmKey = await subtle().importKey('raw', ikm, 'HKDF', false, ['deriveKey'])\n return subtle().deriveKey(\n { name: 'HKDF', hash: 'SHA-256', salt: new Uint8Array(32), info: new TextEncoder().encode('ObjectChat X3DH v1') },\n ikmKey,\n { name: 'AES-GCM', length: 256 },\n false,\n ['encrypt', 'decrypt'],\n )\n}\n","import type { MessageContent, UserId } from './protocol/index.js'\nimport type { ServerFrame } from './protocol/index.js'\nimport {\n type KeyPair, loadOrCreateKeyPair, exportPublicKey, deriveSharedKey, encrypt, decrypt,\n generateKeyPair, signPrekey, x3dhSend, x3dhReceive, type X3DHBundle,\n loadOrCreateIdentityKeyPair, type IdentityKeyPair,\n} from './crypto.js'\n\n// Number of one-time prekeys to generate per upload batch.\nconst OTP_BATCH_SIZE = 20\n\n/**\n * Per-user E2E session. Supports two modes:\n *\n * LIVE (original): Both parties are online. ECDH P-256 key exchange via the\n * `pubkey`/`peerkey` frames. Instant but requires both parties to be connected.\n *\n * ASYNC (X3DH): The sender encrypts to the recipient's prekey bundle while the\n * recipient is offline. Uses X3DH (Extended Triple DH) with identity keys,\n * signed prekeys, and one-time prekeys. The recipient derives the same shared\n * key from the init message when they come online.\n *\n * Both modes produce an AES-GCM 256 shared key for message encryption.\n */\nexport class E2ESession {\n // Live ECDH mode state\n private kp?: KeyPair\n private shared?: CryptoKey\n\n // X3DH async mode state\n private identityKP: IdentityKeyPair | undefined = undefined\n private signedPreKP: KeyPair | undefined = undefined\n private signedPrekeyId: string | undefined = undefined\n private readonly otpKeys: KeyPair[] = [] // one-time prekeys awaiting matching\n private x3dhShared?: CryptoKey\n // Queued init messages arriving before we could derive (shouldn't happen, but safe)\n private pendingX3DH: { senderIK: string; ephemeralKey: string; spkId: string } | undefined = undefined\n\n constructor(private readonly storageKey: string) {}\n\n get ready(): boolean { return !!(this.shared ?? this.x3dhShared) }\n\n /** Live ECDH mode: Generate/restore our keypair and return our public key to publish. */\n async begin(): Promise<string> {\n this.kp = await loadOrCreateKeyPair(this.storageKey)\n return exportPublicKey(this.kp.publicKey)\n }\n\n /** Live ECDH mode: A peer published their key — derive the shared secret. */\n async onPeerKey(peerKeyB64: string): Promise<void> {\n if (!this.kp) return\n this.shared = await deriveSharedKey(this.kp.privateKey, peerKeyB64)\n }\n\n // ── X3DH async mode ────────────────────────────────────────────────────────\n\n /** X3DH: Generate identity key, signed prekey, and OTP prekeys.\n * Returns the upload frame payload the caller should send to the server. */\n async initX3DH(): Promise<{\n identityKey: string; signedPrekey: string; signedPrekeyId: string;\n signature: string; oneTimePrekeys: string[]\n }> {\n // Restore or generate persistent identity keypair (ECDH + ECDSA).\n this.identityKP = await loadOrCreateIdentityKeyPair(this.storageKey)\n // Always generate a fresh signed prekey (rotation).\n this.signedPreKP = await generateKeyPair()\n this.signedPrekeyId = `spk-${Date.now()}-${Math.random().toString(36).slice(2)}`\n // Batch of one-time prekeys.\n for (let i = 0; i < OTP_BATCH_SIZE; i++) this.otpKeys.push(await generateKeyPair())\n\n const signedPrekeyPub = await exportPublicKey(this.signedPreKP.publicKey)\n const signature = await signPrekey(this.identityKP.ecdsaKP.privateKey, this.signedPreKP.publicKey)\n const oneTimePrekeys = await Promise.all(this.otpKeys.map(kp => exportPublicKey(kp.publicKey)))\n\n return {\n identityKey: this.identityKP.publicKeyB64,\n signedPrekey: signedPrekeyPub,\n signedPrekeyId: this.signedPrekeyId,\n signature,\n oneTimePrekeys,\n }\n }\n\n /** X3DH sender: given a recipient's prekey bundle, derive the shared key and\n * return the init message fields to embed in the first encrypted message. */\n async x3dhSendTo(bundle: X3DHBundle): Promise<{ ephemeralKey: string; spkId: string; usedOTP: boolean; senderIK: string }> {\n if (!this.identityKP) this.identityKP = await loadOrCreateIdentityKeyPair(this.storageKey)\n const { sharedKey, ephemeralPublicKey } = await x3dhSend(this.identityKP.ecdhKP, bundle)\n this.x3dhShared = sharedKey\n return { ephemeralKey: ephemeralPublicKey, spkId: bundle.signedPrekeyId, usedOTP: !!bundle.oneTimePrekey, senderIK: this.identityKP.publicKeyB64 }\n }\n\n /** X3DH recipient: given an init message's sender IK + EK + SPK ID, derive the shared key. */\n async x3dhReceiveFrom(senderIKb64: string, ephemeralKeyB64: string, spkId: string): Promise<void> {\n if (!this.identityKP || !this.signedPreKP) {\n // Keys not yet initialised — queue for when initX3DH completes.\n this.pendingX3DH = { senderIK: senderIKb64, ephemeralKey: ephemeralKeyB64, spkId }\n return\n }\n // Find OTP key if used (we pop the first available)\n const otp = this.otpKeys.shift()\n this.x3dhShared = await x3dhReceive(this.identityKP.ecdhKP, this.signedPreKP, senderIKb64, ephemeralKeyB64, otp)\n void spkId // we matched by position; full impl would look up by ID\n }\n\n /** Flush pending X3DH derivation after initX3DH() completes. */\n async flushPendingX3DH(): Promise<void> {\n if (!this.pendingX3DH) return\n const { senderIK, ephemeralKey, spkId } = this.pendingX3DH\n this.pendingX3DH = undefined\n await this.x3dhReceiveFrom(senderIK, ephemeralKey, spkId)\n }\n\n /** Encrypt outgoing text into a wire content object. For X3DH init messages,\n * the caller should pass x3dhInit fields to embed in the content. */\n async sealText(text: string, x3dhInit?: { ephemeralKey: string; spkId: string; senderIK: string }): Promise<MessageContent> {\n const key = this.x3dhShared ?? this.shared\n if (!key) throw new Error('secure channel not ready')\n const { ct, iv } = await encrypt(key, text)\n return {\n kind: 'text', text: ct, enc: true, iv,\n ...(x3dhInit ? { x3dhEK: x3dhInit.ephemeralKey, x3dhSPK: x3dhInit.spkId, x3dhIK: x3dhInit.senderIK } as never : {}),\n }\n }\n\n /** Decrypt one content object if it is encrypted (otherwise pass through). */\n private async openContent(content: MessageContent): Promise<MessageContent> {\n if (content.kind !== 'text' || !content.enc || !content.iv) return content\n const key = this.x3dhShared ?? this.shared\n if (!key) return { kind: 'text', text: '🔒 encrypted' }\n try { return { kind: 'text', text: await decrypt(key, content.text, content.iv) } }\n catch { return { kind: 'text', text: '🔒 unable to decrypt' } }\n }\n\n /** Decrypt any encrypted message content carried by an incoming frame, in place. */\n async openFrame(frame: ServerFrame): Promise<void> {\n if (frame.type === 'message') frame.message.content = await this.openContent(frame.message.content)\n else if (frame.type === 'sync') {\n for (const m of frame.messages) m.content = await this.openContent(m.content)\n }\n }\n}\n\n/** X3DH init fields embedded in a text MessageContent (as extra properties).\n * Present only on the very first message from a sender to an offline peer. */\nexport interface X3DHInitFields {\n x3dhEK: string // sender's ephemeral public key (base64)\n x3dhSPK: string // recipient's signed prekey ID used\n x3dhIK: string // sender's identity public key (base64)\n}\n\nexport function extractX3DHInit(content: MessageContent): X3DHInitFields | null {\n if (content.kind !== 'text' || !content.enc) return null\n const c = content as MessageContent & Partial<X3DHInitFields>\n if (!c.x3dhEK || !c.x3dhSPK || !c.x3dhIK) return null\n return { x3dhEK: c.x3dhEK, x3dhSPK: c.x3dhSPK, x3dhIK: c.x3dhIK }\n}\n\nexport { type X3DHBundle } from './crypto.js'\nexport { type UserId }\n\n","import type { ManifestAction, MessageContent, AnnotationStroke } from './protocol/index.js'\nimport type { ChatStore, RenderMessage } from './store.js'\n\nexport interface WidgetConfig {\n subject?: { title?: string; subtitle?: string; tags?: string[]; status?: string; ownerLabel?: string }\n quickReplies?: string[]\n accent?: string\n /** Identified user info — shown as the guest avatar/name in the widget header. */\n userInfo?: { name?: string; avatar?: string }\n /** i18n string overrides */\n i18n?: { placeholder?: string; send?: string; offline?: string; poweredBy?: string }\n\n}\n\nexport interface RendererHandlers {\n onSend(text: string): void\n onAttach?(file: File): void\n onInvoke(actionId: string, inputs?: Record<string, unknown>): void\n onTyping(isTyping: boolean, preview?: string): void\n onReadUpTo(seq: number): void\n onReact?(messageId: string, emoji: string, remove: boolean): void\n onCsat?(score: number): void\n onLoadMore?(): void\n onEdit?(messageId: string, newText: string): void\n onDelete?(messageId: string): void\n /** Co-browsing: a freehand stroke was completed on the shared whiteboard. */\n onAnnotate?(stroke: Omit<AnnotationStroke, 'by'>): void\n /** Co-browsing: clear the shared whiteboard for everyone. */\n onAnnotateClear?(): void\n /** Translate a message's text for display. Return null if unavailable —\n * the renderer shows a brief \"unavailable\" hint and leaves the original. */\n onTranslate?(text: string): Promise<string | null>\n /** Multi-subject chat list (e.g. a marketplace with one thread per item):\n * fetch the guest's other conversations. Omit to hide the list button\n * entirely — single-conversation embeds don't need this. */\n /** Switch the active conversation to a different one from the list —\n * effectively a re-open with a different subjectId. */\n}\n\nconst STYLE_ID = 'objectchat-widget-styles'\nconst REACTION_EMOJIS = ['👍', '❤️', '😂', '😮', '😢', '🙏']\nconst CSS = `\n.ocw { --ocw-accent:#4F63F5; --ocw-bg:#f3efe9; --ocw-card:#fff; --ocw-line:#ececec; --ocw-ink:#1c1b1a; --ocw-mut:#9b9690;\n position:relative;\n display:flex; flex-direction:column; height:100%; min-height:320px; background:var(--ocw-bg);\n font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif; color:var(--ocw-ink); overflow:hidden; }\n@media (max-width:480px) {\n .ocw { min-height:100dvh; border-radius:0 !important; }\n .ocw-bubble { font-size:15px; }\n .ocw-input textarea { font-size:16px; } /* prevent iOS zoom on focus */\n .ocw-chip { padding:9px 14px; font-size:14px; }\n .ocw-modal-card { width:90%; }\n .ocw-row { max-width:94%; }\n}\n/* RTL support: when the host element has dir=rtl, flip layout direction */\n[dir=\"rtl\"] .ocw-row.mine { flex-direction:row; }\n[dir=\"rtl\"] .ocw-row.theirs { flex-direction:row-reverse; }\n[dir=\"rtl\"] .mine .ocw-bubble { border-bottom-right-radius:18px; border-bottom-left-radius:6px; }\n[dir=\"rtl\"] .theirs .ocw-bubble { border-bottom-left-radius:18px; border-bottom-right-radius:6px; }\n[dir=\"rtl\"] .ocw-input { flex-direction:row-reverse; }\n[dir=\"rtl\"] .mine .ocw-meta { text-align:left; }\n.ocw-head { display:flex; align-items:center; gap:10px; padding:12px 14px; background:var(--ocw-card); border-bottom:1px solid var(--ocw-line); }\n.ocw-avatar { width:34px; height:34px; border-radius:50%; background:#ffe9d6; display:flex; align-items:center; justify-content:center; font-size:17px; flex:none; }\n.ocw-head-main { flex:1; min-width:0; }\n.ocw-head-name { font-weight:700; font-size:15px; }\n.ocw-head-meta { color:var(--ocw-mut); font-size:12px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }\n.ocw-badge { font-size:12px; font-weight:600; color:#15803d; background:#e8f6ec; border-radius:999px; padding:3px 10px; }\n.ocw-e2e { font-size:11px; font-weight:700; color:#3730a3; background:#eef2ff; border-radius:999px; padding:3px 9px; align-items:center; }\n.ocw-menu { color:var(--ocw-mut); width:30px; height:30px; border-radius:50%; border:1px solid var(--ocw-line); background:#fff; cursor:pointer; }\n.ocw-chiprow { display:flex; gap:8px; padding:10px 12px; background:var(--ocw-card); border-bottom:1px solid var(--ocw-line); overflow-x:auto; }\n.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; }\n.ocw-chip:hover { border-color:var(--ocw-accent); color:var(--ocw-accent); }\n.ocw-scroll { flex:1; min-height:0; overflow-y:auto; padding:16px 14px; display:flex; flex-direction:column; gap:10px; }\n.ocw-subject { background:var(--ocw-card); border:1px solid var(--ocw-line); border-radius:16px; padding:14px 16px; }\n.ocw-subject-title { font-weight:700; font-size:16px; margin-bottom:2px; }\n.ocw-subject-sub { color:var(--ocw-mut); font-size:13px; margin-bottom:10px; }\n.ocw-tags { display:flex; flex-wrap:wrap; gap:6px; }\n.ocw-tag { font-size:12px; color:#5b554e; background:#efeae3; border-radius:8px; padding:4px 10px; }\n.ocw-row { display:flex; align-items:flex-end; gap:8px; max-width:86%; }\n.ocw-row.mine { align-self:flex-end; flex-direction:row-reverse; }\n.ocw-row.theirs { align-self:flex-start; }\n.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; }\n.ocw-bubble { padding:10px 14px; border-radius:18px; font-size:14.5px; line-height:1.4; word-wrap:break-word; }\n.theirs .ocw-bubble { background:#fff; border:1px solid var(--ocw-line); border-bottom-left-radius:6px; }\n.mine .ocw-bubble { background:var(--ocw-accent); color:#fff; border-bottom-right-radius:6px; }\n.ocw-sys { align-self:center; color:var(--ocw-mut); font-size:12.5px; font-style:italic; text-align:center; max-width:90%; }\n.ocw-bot .ocw-bubble { background:#f0fdf4; border-color:#cdebd6; }\n.ocw-note .ocw-bubble { background:#fffbeb; border:1.5px dashed #f59e0b; color:#78350f; border-radius:12px !important; }\n.ocw-note .ocw-bubble::before { content:'🔒 Note — '; font-size:11px; font-weight:700; color:#b45309; display:block; margin-bottom:3px; letter-spacing:.3px; }\n.ocw-time { font-size:10.5px; color:var(--ocw-mut); margin-top:3px; }\n.mine .ocw-meta { text-align:right; }\n.ocw-tick { margin-left:4px; font-size:11px; color:var(--ocw-mut); }\n.ocw-tick.read { color:#3b82f6; }\n.ocw-tick.delivered { color:var(--ocw-mut); }\n.ocw-deleted { font-style:italic; color:var(--ocw-mut); }\n.ocw-edited { font-size:10px; color:var(--ocw-mut); margin-left:4px; }\n.ocw-react { font-size:12px; margin-top:3px; display:flex; flex-wrap:wrap; gap:3px; }\n.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; }\n.ocw-react-pill:hover { border-color:var(--ocw-accent); }\n.ocw-react-pill.mine { border-color:var(--ocw-accent); background:#fff8f5; }\n.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; }\n.ocw-react-wrap { position:relative; }\n.ocw-react-wrap:not(:hover) .ocw-react-picker { display:none; }\n.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; }\n.ocw-react-picker button { background:none; border:none; font-size:16px; cursor:pointer; padding:2px; border-radius:6px; }\n.ocw-react-picker button:hover { background:#f3efe9; }\n.ocw-react-btn { background:none; border:1px solid #e3ded7; border-radius:999px; padding:2px 7px; font-size:12px; cursor:pointer; color:var(--ocw-mut); }\n.ocw-react-btn:hover { border-color:var(--ocw-accent); color:var(--ocw-accent); }\n.ocw-msg-menu { position:absolute; top:0; right:0; display:none; gap:3px; }\n.ocw-row.mine:hover .ocw-msg-menu { display:flex; }\n.ocw-row.theirs:hover .ocw-msg-menu { display:flex; left:0; right:auto; }\n.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); }\n.ocw-msg-menu button:hover { border-color:var(--ocw-accent); color:var(--ocw-accent); }\n.ocw-msg-menu button.del:hover { border-color:#e74c3c; color:#e74c3c; }\n.ocw-bubble-wrap { position:relative; }\n.ocw-seen { font-size:10.5px; color:var(--ocw-mut); }\n.ocw-appt { background:#f0f7ff; border:1px solid #c7deff; border-radius:12px; padding:12px 14px; max-width:260px; }\n.ocw-appt-title { font-weight:700; font-size:14px; margin-bottom:4px; }\n.ocw-appt-time { font-size:12px; color:#1d4ed8; margin-bottom:4px; }\n.ocw-appt-loc { font-size:12px; color:var(--ocw-mut); margin-bottom:4px; }\n.ocw-appt-desc { font-size:12px; color:var(--ocw-mut); margin-bottom:10px; white-space:pre-wrap; }\n.ocw-appt-links { display:flex; flex-direction:column; gap:6px; }\n.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; }\n.ocw-appt-btn-sec { background:#fff; color:var(--ocw-accent); border:1px solid var(--ocw-accent); }\n.ocw-conn-status { font-size:10px; color:var(--ocw-mut); margin-left:4px; }\n.ocw-conn-status.warn { color:#e67e22; }\n.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; }\n.ocw-load-more:hover { border-color:var(--ocw-accent); color:var(--ocw-accent); }\n.ocw-offline { margin:20px 14px; padding:20px; background:#fff; border:1px solid #e3ded7; border-radius:16px; text-align:center; }\n.ocw-offline-icon { font-size:32px; margin-bottom:8px; }\n.ocw-offline-title { font-weight:700; font-size:16px; margin-bottom:6px; }\n.ocw-offline-msg { font-size:13px; color:var(--ocw-mut); margin-bottom:16px; }\n.ocw-offline-form { display:flex; flex-direction:column; gap:8px; text-align:left; }\n.ocw-offline-input { border:1px solid #e3ded7; border-radius:10px; padding:10px 12px; font-size:13px; font-family:inherit; }\n.ocw-offline-input:focus { outline:none; border-color:var(--ocw-accent); }\n.ocw-offline-submit { background:var(--ocw-accent); color:#fff; border:none; border-radius:10px; padding:11px; font-size:14px; font-weight:600; cursor:pointer; }\n.ocw-offline-thanks { font-size:14px; color:#15803d; font-weight:600; }\n.ocw-csat-title { font-size:13px; font-weight:600; margin-bottom:8px; }\n.ocw-csat-stars { display:flex; gap:6px; }\n.ocw-csat-star { background:none; border:none; font-size:22px; cursor:pointer; padding:2px; opacity:.4; transition:opacity .15s; }\n.ocw-csat-star:hover, .ocw-csat-star.lit { opacity:1; }\n.ocw-csat-done { font-size:12px; color:var(--ocw-mut); margin-top:6px; }\n\n.ocw-typing { min-height:22px; padding:0 16px 4px; display:flex; align-items:center; }\n.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; }\n.ocw-typing.active .ocw-typing-bubble { display:flex; }\n.ocw-typing-dot { width:6px; height:6px; border-radius:50%; background:var(--ocw-mut); animation:ocw-bounce 1.2s infinite ease-in-out; }\n.ocw-typing-dot:nth-child(2) { animation-delay:.2s; }\n.ocw-typing-dot:nth-child(3) { animation-delay:.4s; }\n@keyframes ocw-bounce { 0%,60%,100%{transform:translateY(0)} 30%{transform:translateY(-5px)} }\n.ocw-quick { display:flex; gap:8px; padding:8px 12px 6px; overflow-x:auto; scrollbar-width:none; flex-shrink:0; }\n.ocw-quick::-webkit-scrollbar { display:none; }\n.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; }\n.ocw-quick button:hover { border-color:var(--ocw-accent); color:var(--ocw-accent); }\n.ocw-form-host:empty { display:none; }\n.ocw-form { margin:6px 12px 0; padding:12px; background:var(--ocw-card); border:1px solid var(--ocw-line); border-radius:14px; }\n.ocw-form-title { font-weight:700; font-size:14px; margin-bottom:8px; }\n.ocw-form-row { display:flex; flex-direction:column; gap:3px; margin-bottom:8px; }\n.ocw-form-lbl { font-size:12px; color:var(--ocw-mut); }\n.ocw-form-input { border:1px solid #e3ded7; border-radius:9px; padding:9px 11px; font:inherit; font-size:14px; outline:none; }\n.ocw-form-input:focus { border-color:var(--ocw-accent); }\n.ocw-form-actions { display:flex; justify-content:flex-end; gap:8px; margin-top:4px; }\n.ocw-form-cancel { background:none; border:none; color:var(--ocw-mut); font-size:13px; cursor:pointer; padding:8px 10px; }\n.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; }\n.ocw-modal { position:absolute; inset:0; background:rgba(20,18,16,.42); display:flex; align-items:center; justify-content:center; z-index:50; }\n.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); }\n.ocw-modal-title { font-weight:700; font-size:16px; margin-bottom:6px; }\n.ocw-modal-body { color:var(--ocw-mut); font-size:14px; margin-bottom:16px; }\n.ocw-modal-actions { display:flex; justify-content:flex-end; gap:8px; }\n.ocw-modal-cancel { background:none; border:none; color:var(--ocw-mut); font-size:14px; cursor:pointer; padding:9px 12px; }\n.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; }\n.ocw-input { display:flex; align-items:center; gap:10px; padding:12px; }\n.ocw-footer { text-align:center; font-size:11px; color:var(--ocw-mut); padding:6px 0 8px; }\n.ocw-footer a { color:var(--ocw-mut); text-decoration:none; font-weight:600; }\n.ocw-footer a:hover { color:var(--ocw-accent); }\n.ocw-attach { background:none;border:none;cursor:pointer;font-size:18px;padding:4px 6px;opacity:.6;flex-none; }\n.ocw-attach:hover { opacity:1; }\n.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; }\n.ocw-input textarea:focus { border-color:var(--ocw-accent); }\n.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; }\n.ocw-sendbtn:disabled { opacity:.5; cursor:default; }\n.ocw-cobrowse-btn { display:none; }\n.ocw-cobrowse-btn.show { display:inline-flex; }\n.ocw-cobrowse-btn.on { color:var(--ocw-accent); border-color:var(--ocw-accent); }\n.ocw-cobrowse-canvas { position:absolute; inset:0; z-index:40; touch-action:none; display:none; }\n.ocw-cobrowse-canvas.active { display:block; cursor:crosshair; }\n.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); }\n.ocw-cobrowse-toolbar.active { display:flex; align-items:center; }\n.ocw-cobrowse-swatch { width:18px; height:18px; border-radius:50%; border:2px solid transparent; cursor:pointer; padding:0; }\n.ocw-cobrowse-swatch.sel { border-color:#1c1b1a; }\n.ocw-cobrowse-clear { background:none; border:1px solid #e3ded7; border-radius:999px; font-size:11px; padding:3px 8px; cursor:pointer; color:var(--ocw-mut); }\n.ocw-cobrowse-clear:hover { border-color:#e74c3c; color:#e74c3c; }\n.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; }\n.ocw-cobrowse-hint.active { display:block; }\n\n.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; }\n.ocw-row.theirs .ocw-translate-btn { right:auto; left:-26px; }\n.ocw-bubble-wrap:hover .ocw-translate-btn { opacity:1; }\n.ocw-translated-tag { font-size:10px; color:var(--ocw-mut); margin-top:2px; }\n`\n\nfunction injectStyles(): void {\n if (typeof document === 'undefined' || document.getElementById(STYLE_ID)) return\n const s = document.createElement('style'); s.id = STYLE_ID; s.textContent = CSS; document.head.appendChild(s)\n}\n\nfunction el<K extends keyof HTMLElementTagNameMap>(tag: K, cls?: string, text?: string): HTMLElementTagNameMap[K] {\n const n = document.createElement(tag); if (cls) n.className = cls; if (text !== undefined) n.textContent = text; return n\n}\nfunction fmtTime(ts: number): string {\n try { return new Date(ts).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) } catch { return '' }\n}\nfunction contentText(c: MessageContent): string {\n switch (c.kind) {\n case 'text': return c.text\n case 'system': return typeof c.data?.['message'] === 'string' ? String(c.data['message']) : c.event\n case 'card': return [c.title, c.body].filter(Boolean).join(' — ')\n case 'attachment': return c.name ?? c.url\n case 'form': return c.prompt\n case 'appointment': return `📅 ${c.title} — ${new Date(c.startIso).toLocaleString()}`\n }\n}\n\n/** Renders a ChatStore into a host element in the Image-1 layout: header →\n * subject card → action chips → chat → quick replies → input. Self-injects its\n * stylesheet so it looks right wherever it mounts. Accent comes from the\n * dashboard-authored profile theme (via the manifest), falling back to config. */\nexport class Renderer {\n private readonly scroll: HTMLElement\n private readonly chips: HTMLElement\n private readonly typing: HTMLElement\n private readonly quick: HTMLElement\n private readonly formHost: HTMLElement\n private readonly csatPanel: HTMLElement\n private readonly offlinePanel: HTMLElement\n private readonly footer: HTMLElement\n private readonly input: HTMLTextAreaElement\n private readonly subjectCard: HTMLElement\n private readonly e2eBadge: HTMLElement\n private readonly statusBadge: HTMLElement\n private readonly headerName: HTMLElement\n private readonly connStatus: HTMLElement\n private typingTimer: ReturnType<typeof setTimeout> | null = null\n private csatSubmitted = false\n\n // ── Co-browsing (shared whiteboard) ─────────────────────────────────────\n private readonly cobrowseBtn: HTMLButtonElement\n private readonly cobrowseCanvas: HTMLCanvasElement\n private readonly cobrowseToolbar: HTMLElement\n private readonly cobrowseHint: HTMLElement\n private cobrowseActive = false\n private cobrowseColor = '#f5713c'\n private lastAnnotationVersion = -1\n private storeRef: ChatStore | null = null\n private scrollCleanup: (() => void) | null = null\n\n /** Returns the scroll container so history.ts can attach scroll listeners. */\n getScrollEl(): HTMLElement | null { return this.scroll }\n\n /** Registers a cleanup fn removed on destroy() to prevent listener leaks. */\n setScrollCleanup(fn: () => void): void {\n this.scrollCleanup?.()\n this.scrollCleanup = fn\n }\n\n // ── Live translation ──────────────────────────────────────────────────-\n private readonly translationCache = new Map<string, string>()\n private readonly showingTranslation = new Set<string>()\n\n\n /** Last seq the guest has seen per conversationId — used to compute unread badges. */\n\n\n constructor(\n private readonly root: HTMLElement,\n private readonly me: string,\n private readonly h: RendererHandlers,\n private readonly cfg: WidgetConfig = {},\n ) {\n injectStyles()\n // Clear any previous widget content on this element before building.\n // This is the last line of defence against double-mounts: even if mount()\n // is called twice on the same element (React StrictMode, HMR, caller bug),\n // the second Renderer wipes the first one's DOM so only one UI is visible.\n root.replaceChildren()\n root.classList.add('ocw')\n if (cfg.accent) root.style.setProperty('--ocw-accent', cfg.accent)\n\n // Header\n const head = el('div', 'ocw-head')\n const avatarEl = el('div', 'ocw-avatar')\n if (cfg.userInfo?.avatar) {\n const img = document.createElement('img')\n img.src = cfg.userInfo.avatar; img.alt = cfg.userInfo.name ?? 'You'\n img.style.cssText = 'width:100%;height:100%;border-radius:50%;object-fit:cover'\n avatarEl.append(img)\n } else {\n avatarEl.textContent = cfg.userInfo?.name ? cfg.userInfo.name[0]!.toUpperCase() : '🧑'\n }\n head.append(avatarEl)\n const hm = el('div', 'ocw-head-main')\n this.headerName = el('div', 'ocw-head-name', cfg.subject?.ownerLabel ?? cfg.subject?.title ?? '')\n hm.append(this.headerName)\n if (cfg.subject?.subtitle) hm.append(el('div', 'ocw-head-meta', cfg.subject.subtitle))\n head.append(hm)\n this.statusBadge = el('span', 'ocw-badge', cfg.subject?.status ?? '')\n if (!cfg.subject?.status) this.statusBadge.style.display = 'none'\n head.append(this.statusBadge)\n this.e2eBadge = el('span', 'ocw-e2e', '🔒 E2E'); this.e2eBadge.style.display = 'none'; head.append(this.e2eBadge)\n this.connStatus = el('span', 'ocw-conn-status'); this.connStatus.style.display = 'none'; head.append(this.connStatus)\n this.cobrowseBtn = el('button', 'ocw-menu ocw-cobrowse-btn', '🖍') as HTMLButtonElement\n this.cobrowseBtn.title = 'Shared whiteboard — draw to point things out together'\n this.cobrowseBtn.addEventListener('click', () => { this.cobrowseActive = !this.cobrowseActive; this.updateCobrowseUI() })\n head.append(this.cobrowseBtn)\n\n head.append(el('button', 'ocw-menu', '⋯'))\n\n // Action chips (filled in render)\n this.chips = el('div', 'ocw-chiprow')\n\n // Scroll area with optional subject card + messages\n this.scroll = el('div', 'ocw-scroll')\n this.subjectCard = el('div', 'ocw-subject')\n this.typing = el('div', 'ocw-typing')\n const typingBubble = el('div', 'ocw-typing-bubble')\n typingBubble.append(el('div', 'ocw-typing-dot'), el('div', 'ocw-typing-dot'), el('div', 'ocw-typing-dot'))\n this.typing.append(el('div', 'ocw-dot', '🧑'), typingBubble)\n this.quick = el('div', 'ocw-quick')\n for (const q of cfg.quickReplies ?? []) {\n const b = el('button', undefined, q)\n b.addEventListener('click', () => {\n this.h.onSend(q)\n // Hide quick replies immediately after one is tapped\n this.quick.style.display = 'none'\n })\n this.quick.append(b)\n }\n\n // Input\n this.formHost = el('div', 'ocw-form-host')\n this.csatPanel = el('div', 'ocw-csat'); this.csatPanel.style.display = 'none'\n this.offlinePanel = el('div', 'ocw-offline'); this.offlinePanel.style.display = 'none'\n this.input = el('textarea', undefined); this.input.rows = 1; this.input.placeholder = 'Message…'\n const sendBtn = el('button', 'ocw-sendbtn', cfg.i18n?.send ?? '➤')\n sendBtn.addEventListener('click', () => this.flushSend())\n this.input.addEventListener('keydown', (e) => {\n // Guard against IME composition (Korean/Japanese/Chinese input): while\n // the user is selecting a candidate from the IME's suggestion list,\n // pressing Enter to CONFIRM the candidate also fires a keydown with\n // key === 'Enter'. Without this check, that confirmation keystroke was\n // being treated as \"send the message\" — firing early with a partial\n // composition, and then firing again on the real Enter press with\n // whatever text was left, producing two bubbles for one message\n // (e.g. typing \"음식\" sends \"음식\" then \"식\").\n // e.isComposing covers most browsers; keyCode 229 is the long-standing\n // fallback for browsers/IMEs that don't set isComposing reliably.\n if (e.isComposing || e.keyCode === 229) return\n if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); this.flushSend() } else this.signalTyping()\n })\n\n const attachBtn = el('button', 'ocw-attach', '📎'); attachBtn.title = 'Attach image or file'\n const fileInput = document.createElement('input'); fileInput.type = 'file'\n fileInput.accept = 'image/*,.pdf,.txt,.doc,.docx'; fileInput.style.display = 'none'\n attachBtn.addEventListener('click', () => fileInput.click())\n fileInput.addEventListener('change', () => { if (fileInput.files?.[0] && this.h.onAttach) this.h.onAttach(fileInput.files[0]); fileInput.value = '' })\n\n const inputRow = el('div', 'ocw-input'); inputRow.append(attachBtn, fileInput, this.input, sendBtn)\n\n const footer = el('div', 'ocw-footer')\n // i18n.poweredBy: if the caller provides it, treat as plain text — no innerHTML.\n // Only our own hardcoded default renders the anchor as HTML.\n if (cfg.i18n?.poweredBy !== undefined) {\n footer.textContent = cfg.i18n.poweredBy\n } else {\n footer.innerHTML = 'Powered by <a href=\"https://relay.paramms.com\" target=\"_blank\" rel=\"noopener\">Relay</a>'\n }\n this.footer = footer\n\n root.append(head, this.chips, this.scroll, this.typing, this.quick, this.formHost, this.csatPanel, this.offlinePanel, inputRow, this.footer)\n\n // Co-browsing overlay: a freehand canvas layered over the whole widget.\n this.cobrowseCanvas = el('canvas', 'ocw-cobrowse-canvas') as HTMLCanvasElement\n this.cobrowseToolbar = el('div', 'ocw-cobrowse-toolbar')\n for (const c of ['#f5713c', '#1c1b1a', '#2563eb', '#16a34a', '#dc2626']) {\n const sw = el('button', 'ocw-cobrowse-swatch') as HTMLButtonElement\n sw.style.background = c\n sw.type = 'button'\n if (c === this.cobrowseColor) sw.classList.add('sel')\n sw.addEventListener('click', () => {\n this.cobrowseColor = c\n for (const n of this.cobrowseToolbar.querySelectorAll('.ocw-cobrowse-swatch')) n.classList.remove('sel')\n sw.classList.add('sel')\n })\n this.cobrowseToolbar.append(sw)\n }\n const cobrowseClear = el('button', 'ocw-cobrowse-clear', 'Clear')\n cobrowseClear.addEventListener('click', () => this.h.onAnnotateClear?.())\n this.cobrowseToolbar.append(cobrowseClear)\n this.cobrowseHint = el('div', 'ocw-cobrowse-hint', '🖍 Draw to point things out — visible to both sides')\n root.append(this.cobrowseCanvas, this.cobrowseToolbar, this.cobrowseHint)\n this.bindCobrowsePointerEvents()\n\n }\n\n /** Call when the widget is unmounted. Disconnects scroll listeners and clears timers. */\n destroy(): void {\n this.scrollCleanup?.()\n this.scrollCleanup = null\n if (this.typingTimer) { clearTimeout(this.typingTimer); this.typingTimer = null }\n }\n\n\n /** Render list rows, optionally filtered by search query. */\n\n\n /** Build a single WhatsApp-style conversation row. */\n\n /** Returns true when the chat screen is visible (not the list). */\n\n /** Navigate to the chat screen (slide list left, slide chat in from right). */\n\n /** Navigate back to the list screen. */\n\n private flushSend(): void {\n const text = this.input.value.trim()\n if (!text) return\n this.input.value = ''\n this.h.onTyping(false)\n this.h.onSend(text)\n }\n private signalTyping(): void {\n const preview = this.input.value.trim().slice(0, 100) || undefined\n this.h.onTyping(true, preview)\n if (this.typingTimer) clearTimeout(this.typingTimer)\n this.typingTimer = setTimeout(() => this.h.onTyping(false), 2000)\n }\n\n render(store: ChatStore): void {\n this.storeRef = store\n // Co-browsing toggle is only meaningful for subject-anchored conversations.\n this.cobrowseBtn.classList.toggle('show', !!store.subject)\n if (!store.subject && this.cobrowseActive) { this.cobrowseActive = false; this.updateCobrowseUI() }\n if (this.cobrowseActive && store.annotationVersion !== this.lastAnnotationVersion) {\n this.lastAnnotationVersion = store.annotationVersion\n this.resizeCobrowseCanvas()\n this.redrawCobrowse()\n }\n if (store.accent) this.root.style.setProperty('--ocw-accent', store.accent)\n this.e2eBadge.style.display = store.e2e ? 'inline-flex' : 'none'\n this.buildSubjectCard(store)\n // Header: when a subject is attached, show ownerLabel (\"Seller\", \"Host\")\n // or nothing — the subject card below carries the identity.\n // Without a subject, the header is already set to cfg.subject?.ownerLabel\n // or \"Chat\" from the constructor — don't overwrite it with the domain name\n // which would duplicate the subject card title or clutter a plain chat.\n if (store.subject) {\n const ownerLabel = this.cfg.subject?.ownerLabel\n if (ownerLabel) this.headerName.textContent = ownerLabel\n // else leave constructor default (\"Chat\")\n }\n // Without a subject: leave header as-is (set once in constructor)\n\n // Action chips from the manifest (filtered by state in the store)\n this.chips.replaceChildren()\n const actions = store.visibleActions()\n this.chips.style.display = actions.length ? 'flex' : 'none'\n for (const a of actions) this.chips.append(this.chipEl(a))\n\n // Messages\n // Preserve scroll anchor when history is prepended: capture height before\n // replaceChildren so we can restore relative position after.\n const prevScrollHeight = this.scroll.scrollHeight\n const prevScrollTop = this.scroll.scrollTop\n\n this.scroll.replaceChildren()\n if (this.subjectCard.childNodes.length) this.scroll.append(this.subjectCard)\n if (store.hasMoreHistory) {\n // Sentinel at top — scroll to here triggers load-more via the scroll\n // listener set up by restoreHistory. Shows a subtle loading indicator\n // so the user knows older messages are available.\n const sentinel = el('div', 'ocw-load-more')\n sentinel.textContent = '↑ Loading earlier messages…'\n sentinel.style.pointerEvents = 'none'\n this.scroll.append(sentinel)\n }\n let maxOther = 0\n for (const m of store.messages()) {\n this.scroll.append(this.messageEl(m, store))\n if (m.senderId !== this.me && m.seq > maxOther) maxOther = m.seq\n }\n // Auto-scroll to bottom only for new messages; restore anchor when history was prepended.\n if (prevScrollTop > 20) {\n this.scroll.scrollTop = this.scroll.scrollHeight - prevScrollHeight + prevScrollTop\n } else {\n this.scroll.scrollTop = this.scroll.scrollHeight\n }\n if (maxOther > 0) this.h.onReadUpTo(maxOther)\n\n const typingNames = [...store.typing]\n this.typing.classList.toggle('active', typingNames.length > 0)\n // Bubble is always present in DOM (hidden via CSS); just update label\n const bubble = this.typing.querySelector('.ocw-typing-bubble')\n if (bubble) bubble.setAttribute('aria-label', typingNames.length ? 'typing' : '')\n this.footer.style.display = store.whiteLabel ? 'none' : 'block'\n\n // Offline mode: show form instead of chat input\n if (store.offline) {\n if (this.offlinePanel.style.display === 'none') this.buildOfflinePanel(store.offlineMessage)\n this.offlinePanel.style.display = 'block'\n ;(this.root.querySelector('.ocw-input') as HTMLElement | null)?.style.setProperty('display', 'none')\n } else {\n this.offlinePanel.style.display = 'none'\n ;(this.root.querySelector('.ocw-input') as HTMLElement | null)?.style.removeProperty('display')\n }\n\n // CSAT: show star-rating panel when conversation reaches a terminal state\n // and the user hasn't yet rated. Terminal states are heuristic: 'resolved',\n // 'closed', 'sold', 'issued', 'checked_out'. The panel self-dismisses on submit.\n const terminalStates = ['resolved', 'closed', 'sold', 'issued', 'checked_out']\n if (this.h.onCsat && !this.csatSubmitted && terminalStates.includes(store.state) && store.messages().length > 0) {\n if (this.csatPanel.style.display === 'none') this.buildCsatPanel()\n this.csatPanel.style.display = 'block'\n }\n }\n\n setConnStatus(status: 'connecting' | 'open' | 'reconnecting'): void {\n if (status === 'open') { this.connStatus.style.display = 'none'; return }\n this.connStatus.style.display = ''\n this.connStatus.className = `ocw-conn-status${status === 'reconnecting' ? ' warn' : ''}`\n this.connStatus.textContent = status === 'reconnecting' ? '↻ reconnecting…' : '● connecting…'\n }\n\n private buildOfflinePanel(offlineMessage?: string): void {\n this.offlinePanel.replaceChildren()\n this.offlinePanel.append(el('div', 'ocw-offline-icon', '🌙'))\n this.offlinePanel.append(el('div', 'ocw-offline-title', this.cfg.i18n?.offline ?? \"We're offline right now\"))\n this.offlinePanel.append(el('div', 'ocw-offline-msg', offlineMessage || \"Leave your details and we'll get back to you soon.\"))\n const form = el('div', 'ocw-offline-form')\n const nameIn = el('input', 'ocw-offline-input') as HTMLInputElement; nameIn.placeholder = 'Your name'; nameIn.type = 'text'\n const emailIn = el('input', 'ocw-offline-input') as HTMLInputElement; emailIn.placeholder = 'Your email'; emailIn.type = 'email'\n const msgIn = el('textarea', 'ocw-offline-input') as HTMLTextAreaElement; msgIn.placeholder = 'Your message'; msgIn.rows = 3\n const submit = el('button', 'ocw-offline-submit', 'Send message')\n submit.addEventListener('click', () => {\n if (!emailIn.value.trim() || !msgIn.value.trim()) return\n // Post as a regular message (offline form is stored as a conversation once submitted)\n this.h.onSend(`[Offline form]\\nName: ${nameIn.value || 'Anonymous'}\\nEmail: ${emailIn.value}\\nMessage: ${msgIn.value}`)\n this.offlinePanel.replaceChildren(el('div', 'ocw-offline-thanks', '✓ Message sent! We\\'ll reply to your email.'))\n })\n form.append(nameIn, emailIn, msgIn, submit)\n this.offlinePanel.append(form)\n }\n\n private buildCsatPanel(): void {\n this.csatPanel.replaceChildren()\n this.csatPanel.append(el('div', 'ocw-csat-title', 'How did we do?'))\n const stars = el('div', 'ocw-csat-stars')\n const btns: HTMLButtonElement[] = []\n for (let i = 1; i <= 5; i++) {\n const b = el('button', 'ocw-csat-star', '★')\n b.dataset['score'] = String(i)\n b.addEventListener('mouseenter', () => btns.forEach((bb, idx) => bb.classList.toggle('lit', idx < i)))\n b.addEventListener('mouseleave', () => btns.forEach(bb => bb.classList.remove('lit')))\n b.addEventListener('click', () => {\n this.csatSubmitted = true\n this.csatPanel.replaceChildren(el('div', 'ocw-csat-done', `Thanks for your ${i}★ rating!`))\n this.h.onCsat?.(i)\n })\n btns.push(b); stars.append(b)\n }\n this.csatPanel.append(stars)\n }\n\n private subjectBuilt = false\n /** Subject card from the server's Subject entity (per chatroom), with the\n * mount config as a fallback. Built once when data first arrives. */\n // ── Co-browsing (shared whiteboard) ──────────────────────────────────────\n private updateCobrowseUI(): void {\n this.cobrowseCanvas.classList.toggle('active', this.cobrowseActive)\n this.cobrowseToolbar.classList.toggle('active', this.cobrowseActive)\n this.cobrowseHint.classList.toggle('active', this.cobrowseActive)\n this.cobrowseBtn.classList.toggle('on', this.cobrowseActive)\n if (this.cobrowseActive) {\n this.resizeCobrowseCanvas()\n this.redrawCobrowse()\n }\n }\n\n private resizeCobrowseCanvas(): void {\n this.cobrowseCanvas.width = this.root.clientWidth || 1\n this.cobrowseCanvas.height = this.root.clientHeight || 1\n }\n\n /** Draw a stroke whose points are normalized to 0..1, scaled to the current\n * canvas size — so strokes line up across different viewport sizes. */\n private drawStroke(stroke: { points: { x: number; y: number }[]; color: string; width: number }): void {\n const ctx = this.cobrowseCanvas.getContext('2d')\n if (!ctx || stroke.points.length < 2) return\n const w = this.cobrowseCanvas.width, h = this.cobrowseCanvas.height\n ctx.strokeStyle = stroke.color\n ctx.lineWidth = Math.max(1, stroke.width * Math.min(w, h))\n ctx.lineJoin = 'round'\n ctx.lineCap = 'round'\n ctx.beginPath()\n ctx.moveTo(stroke.points[0]!.x * w, stroke.points[0]!.y * h)\n for (const p of stroke.points.slice(1)) ctx.lineTo(p.x * w, p.y * h)\n ctx.stroke()\n }\n\n private redrawCobrowse(): void {\n const ctx = this.cobrowseCanvas.getContext('2d')\n if (!ctx) return\n ctx.clearRect(0, 0, this.cobrowseCanvas.width, this.cobrowseCanvas.height)\n for (const s of this.storeRef?.annotations ?? []) this.drawStroke(s)\n }\n\n private bindCobrowsePointerEvents(): void {\n let drawing = false\n let current: { x: number; y: number }[] = []\n const posFromEvent = (e: PointerEvent): { x: number; y: number } => {\n const rect = this.cobrowseCanvas.getBoundingClientRect()\n const x = rect.width > 0 ? (e.clientX - rect.left) / rect.width : 0\n const y = rect.height > 0 ? (e.clientY - rect.top) / rect.height : 0\n return { x: Math.min(1, Math.max(0, x)), y: Math.min(1, Math.max(0, y)) }\n }\n const STROKE_WIDTH = 0.006 // normalized — ~6px on a 1000px-wide canvas\n this.cobrowseCanvas.addEventListener('pointerdown', (e) => {\n if (!this.cobrowseActive) return\n drawing = true\n current = [posFromEvent(e)]\n this.cobrowseCanvas.setPointerCapture(e.pointerId)\n })\n this.cobrowseCanvas.addEventListener('pointermove', (e) => {\n if (!drawing) return\n current.push(posFromEvent(e))\n this.redrawCobrowse()\n this.drawStroke({ points: current, color: this.cobrowseColor, width: STROKE_WIDTH })\n })\n const finish = (e: PointerEvent): void => {\n if (!drawing) return\n drawing = false\n if (current.length > 1) {\n this.h.onAnnotate?.({ id: `an_${Date.now()}_${Math.random().toString(36).slice(2)}`, points: current, color: this.cobrowseColor, width: STROKE_WIDTH })\n }\n current = []\n try { this.cobrowseCanvas.releasePointerCapture(e.pointerId) } catch { /* not captured */ }\n }\n this.cobrowseCanvas.addEventListener('pointerup', finish)\n this.cobrowseCanvas.addEventListener('pointercancel', finish)\n }\n\n private buildSubjectCard(store: ChatStore): void {\n if (this.subjectBuilt) return\n const s = store.subject\n const cfg = this.cfg.subject\n // Only show the subject card when there is actual subject data (from the\n // server) or an explicit subject config passed by the embedder (title,\n // tags, status). Never fall back to store.name — that's the domain/profile\n // name and is already shown in the header; rendering it here as well is\n // what caused the duplication seen in the Hotel front desk screenshot.\n const title = s?.title ?? cfg?.title\n if (!title) return\n this.subjectBuilt = true\n this.subjectCard.replaceChildren()\n this.subjectCard.append(el('div', 'ocw-subject-title', title))\n if (cfg?.subtitle) this.subjectCard.append(el('div', 'ocw-subject-sub', cfg.subtitle))\n const tags = el('div', 'ocw-tags')\n if (s) for (const [k, v] of Object.entries(s.fields)) tags.append(el('span', 'ocw-tag', `${k}: ${v}`))\n else for (const t of cfg?.tags ?? []) tags.append(el('span', 'ocw-tag', t))\n if (tags.childNodes.length) this.subjectCard.append(tags)\n const status = s?.state ?? cfg?.status\n if (status) { this.statusBadge.textContent = status; this.statusBadge.style.display = 'inline-flex' }\n }\n\n private chipEl(a: ManifestAction): HTMLButtonElement {\n const btn = el('button', 'ocw-chip', a.icon ? `${a.icon} ${a.label}` : a.label)\n btn.dataset['actionId'] = a.id\n btn.addEventListener('click', async () => {\n if (a.confirm && !(await this.confirm(a.label))) return\n if (a.input?.length) this.openForm(a)\n else this.h.onInvoke(a.id)\n })\n return btn\n }\n\n /** In-widget confirmation modal (replaces window.confirm). */\n private confirm(label: string): Promise<boolean> {\n return new Promise((resolve) => {\n const overlay = el('div', 'ocw-modal')\n const card = el('div', 'ocw-modal-card')\n card.append(el('div', 'ocw-modal-title', label))\n card.append(el('div', 'ocw-modal-body', `Confirm “${label}”?`))\n const row = el('div', 'ocw-modal-actions')\n const cancel = el('button', 'ocw-modal-cancel', 'Cancel')\n const ok = el('button', 'ocw-modal-ok', 'Confirm')\n const close = (v: boolean) => { overlay.remove(); resolve(v) }\n cancel.addEventListener('click', () => close(false))\n ok.addEventListener('click', () => close(true))\n overlay.addEventListener('click', (e) => { if (e.target === overlay) close(false) })\n row.append(cancel, ok); card.append(row); overlay.append(card)\n this.root.append(overlay)\n ok.focus()\n })\n }\n\n /** Inline form for a form-effect action: typed inputs (date picker, number,\n * text) rendered above the composer — no browser prompts. */\n private openForm(a: ManifestAction): void {\n this.formHost.replaceChildren()\n const panel = el('div', 'ocw-form')\n panel.append(el('div', 'ocw-form-title', a.icon ? `${a.icon} ${a.label}` : a.label))\n const inputs = new Map<string, HTMLInputElement>()\n for (const f of a.input ?? []) {\n const row = el('label', 'ocw-form-row'); row.append(el('span', 'ocw-form-lbl', f.label))\n if (f.type === 'select' && f.options?.length) {\n const sel = el('select', 'ocw-form-input')\n if (!f.required) sel.append(el('option', undefined, '— select —'))\n for (const opt of f.options) { const o = el('option'); o.value = opt; o.textContent = opt; sel.append(o) }\n if (f.required) sel.required = true\n row.append(sel)\n inputs.set(f.name, sel as unknown as HTMLInputElement)\n } else {\n const inp = el('input', 'ocw-form-input')\n inp.type = f.type === 'number' ? 'number' : f.type === 'date' ? 'datetime-local' : 'text'\n if (f.required) inp.required = true\n row.append(inp); inputs.set(f.name, inp)\n }\n panel.append(row)\n }\n const actions = el('div', 'ocw-form-actions')\n const cancel = el('button', 'ocw-form-cancel', 'Cancel')\n const submit = el('button', 'ocw-form-submit', 'Send')\n cancel.addEventListener('click', () => this.formHost.replaceChildren())\n submit.addEventListener('click', () => {\n const out: Record<string, unknown> = {}\n for (const [name, inp] of inputs) {\n if (inp.required && !inp.value) { inp.style.borderColor = '#e5484d'; return }\n out[name] = inp.type === 'number' ? Number(inp.value) : inp.value\n }\n this.formHost.replaceChildren()\n this.h.onInvoke(a.id, out)\n })\n actions.append(cancel, submit); panel.append(actions)\n this.formHost.append(panel)\n inputs.values().next().value?.focus()\n }\n\n private messageEl(m: RenderMessage, store: ChatStore): HTMLElement {\n if (m.senderRole === 'system') {\n const sys = el('div', 'ocw-sys'); sys.textContent = m.deletedAt ? 'message deleted' : contentText(m.content); return sys\n }\n const mine = m.senderId === this.me\n const isNote = !!m.internal\n const row = el('div', `ocw-row ${isNote ? 'ocw-note mine' : mine ? 'mine' : 'theirs'} ${m.senderRole === 'bot' ? 'ocw-bot' : ''}`)\n if (!mine && !isNote) row.append(el('div', 'ocw-dot', m.senderRole === 'bot' ? '🤖' : '🧑'))\n const col = el('div')\n const bubbleWrap = el('div', 'ocw-bubble-wrap')\n // Reply-to context if present\n if (m.replyToId) {\n const replyCtx = el('div', 'ocw-reply-to', '↩ replying to a message')\n replyCtx.style.cssText = 'font-size:11px;color:var(--ocw-mut);margin-bottom:2px;font-style:italic'\n col.append(replyCtx)\n }\n const bubble = el('div', 'ocw-bubble')\n let textNode: Text | null = null\n if (m.deletedAt) bubble.append(el('span', 'ocw-deleted', 'message deleted'))\n else if (m.content.kind === 'attachment') {\n const c = m.content\n if (c.mime?.startsWith('image/')) {\n const img = document.createElement('img')\n img.src = c.url; img.alt = c.name ?? 'image'\n img.style.cssText = 'max-width:220px;max-height:160px;border-radius:10px;display:block;cursor:pointer'\n img.addEventListener('click', () => window.open(c.url, '_blank'))\n bubble.append(img)\n } else {\n const a = document.createElement('a')\n a.href = c.url; a.target = '_blank'; a.rel = 'noopener'\n a.style.cssText = 'display:flex;align-items:center;gap:8px;color:inherit;text-decoration:none'\n a.append(el('span', undefined, '📄'), el('span', undefined, c.name ?? 'file'))\n bubble.append(a)\n }\n } else {\n if (m.content.kind === 'appointment') {\n const ap = m.content\n const card = el('div', 'ocw-appt')\n card.append(el('div', 'ocw-appt-title', `\\u{1F4C5} ${ap.title}`))\n card.append(el('div', 'ocw-appt-time', new Date(ap.startIso).toLocaleString() + ' \\u2013 ' + new Date(ap.endIso).toLocaleTimeString()))\n if (ap.location) card.append(el('div', 'ocw-appt-loc', `\\u{1F4CD} ${ap.location}`))\n if (ap.description) card.append(el('div', 'ocw-appt-desc', ap.description))\n const links = el('div', 'ocw-appt-links')\n const gLink = document.createElement('a'); gLink.href = ap.googleUrl; gLink.target = '_blank'; gLink.rel = 'noopener'; gLink.className = 'ocw-appt-btn'; gLink.textContent = '\\u{1F4C5} Add to Google Calendar'\n const iLink = document.createElement('a'); iLink.href = ap.icalUrl; iLink.download = `${ap.title}.ics`; iLink.className = 'ocw-appt-btn ocw-appt-btn-sec'; iLink.textContent = '\\u{1F34E} Apple / iCal'\n links.append(gLink, iLink); card.append(links); bubble.append(card)\n } else {\n textNode = document.createTextNode(contentText(m.content))\n bubble.append(textNode)\n if (m.editedAt) bubble.append(el('span', 'ocw-edited', '(edited)'))\n }\n }\n bubbleWrap.append(bubble)\n\n // Live translation: only for the other party's plain-text messages (not notes).\n if (!mine && !isNote && this.h.onTranslate && m.content.kind === 'text' && !m.deletedAt && m.seq > 0 && textNode) {\n const original = m.content.text\n if (original.trim()) {\n const translateBtn = el('button', 'ocw-translate-btn', '🌐')\n translateBtn.type = 'button'\n translateBtn.title = 'Translate'\n translateBtn.addEventListener('click', (e) => {\n e.stopPropagation()\n if (this.showingTranslation.has(m.id)) {\n this.showingTranslation.delete(m.id)\n textNode!.textContent = original\n translateBtn.textContent = '🌐'\n translateBtn.title = 'Translate'\n return\n }\n const cached = this.translationCache.get(m.id)\n if (cached !== undefined) {\n this.showingTranslation.add(m.id)\n textNode!.textContent = cached\n translateBtn.textContent = '↩'\n translateBtn.title = 'Show original'\n return\n }\n translateBtn.textContent = '⏳'\n void this.h.onTranslate!(original).then((result) => {\n if (result === null) {\n translateBtn.textContent = '⚠️'\n translateBtn.title = 'Translation unavailable'\n setTimeout(() => { translateBtn.textContent = '🌐'; translateBtn.title = 'Translate' }, 1500)\n return\n }\n this.translationCache.set(m.id, result)\n this.showingTranslation.add(m.id)\n textNode!.textContent = result\n translateBtn.textContent = '↩'\n translateBtn.title = 'Show original'\n })\n })\n bubbleWrap.append(translateBtn)\n }\n }\n // Edit/delete context menu on own non-deleted messages\n if (mine && !m.deletedAt && m.seq > 0 && (this.h.onEdit ?? this.h.onDelete)) {\n const menu = el('div', 'ocw-msg-menu')\n if (this.h.onEdit) {\n const editBtn = el('button', undefined, '✏️')\n editBtn.title = 'Edit'\n editBtn.addEventListener('click', (e) => {\n e.stopPropagation()\n // Inline edit: replace bubble text with a small textarea + save/cancel\n const original = contentText(m.content)\n const ta = document.createElement('textarea')\n ta.value = original\n ta.rows = Math.min(4, Math.ceil(original.length / 40) + 1)\n ta.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'\n const saveBtn = el('button', 'ocw-form-submit', 'Save')\n saveBtn.style.cssText = 'margin-top:6px;padding:5px 14px;font-size:13px'\n const cancelBtn = el('button', 'ocw-form-cancel', 'Cancel')\n cancelBtn.style.cssText = 'margin-top:6px;padding:5px 10px;font-size:13px'\n const btnRow = el('div'); btnRow.style.cssText = 'display:flex;gap:6px;justify-content:flex-end'\n btnRow.append(cancelBtn, saveBtn)\n const editPanel = el('div'); editPanel.append(ta, btnRow)\n bubble.replaceChildren(editPanel)\n ta.focus(); ta.select()\n const restore = () => bubble.replaceChildren(textNode ?? document.createTextNode(original))\n cancelBtn.addEventListener('click', restore)\n saveBtn.addEventListener('click', () => {\n const newText = ta.value.trim()\n if (newText && newText !== original) { this.h.onEdit!(m.id, newText); restore() }\n else restore()\n })\n ta.addEventListener('keydown', (ke) => {\n if (ke.key === 'Enter' && !ke.shiftKey) { ke.preventDefault(); saveBtn.click() }\n if (ke.key === 'Escape') restore()\n })\n })\n menu.append(editBtn)\n }\n if (this.h.onDelete) {\n const delBtn = el('button', 'del', '🗑')\n delBtn.title = 'Delete'\n delBtn.addEventListener('click', (e) => { e.stopPropagation(); this.h.onDelete!(m.id) })\n menu.append(delBtn)\n }\n bubbleWrap.append(menu)\n }\n col.append(bubbleWrap)\n\n // Reactions: existing pills + add-reaction picker (hover-revealed)\n if (this.h.onReact && !m.deletedAt && m.seq > 0) {\n const reactWrap = el('div', 'ocw-react-wrap')\n const reactRow = el('div', 'ocw-react')\n // Existing reaction pills\n if (m.reactions && Object.keys(m.reactions).length) {\n for (const [emoji, users] of Object.entries(m.reactions)) {\n const pill = el('button', `ocw-react-pill${(users as string[]).includes(this.me) ? ' mine' : ''}`, `${emoji} ${(users as string[]).length}`)\n pill.addEventListener('click', () => this.h.onReact?.(m.id, emoji, (users as string[]).includes(this.me)))\n reactRow.append(pill)\n }\n }\n // Add-reaction button + picker\n const addBtn = el('button', 'ocw-react-btn', '+')\n const picker = el('div', 'ocw-react-picker')\n for (const emoji of REACTION_EMOJIS) {\n const pb = el('button', undefined, emoji)\n pb.addEventListener('click', (e) => {\n e.stopPropagation()\n const alreadyReacted = m.reactions?.[emoji]?.includes(this.me as never)\n this.h.onReact?.(m.id, emoji, !!alreadyReacted)\n picker.style.display = 'none'\n })\n picker.append(pb)\n }\n picker.style.display = 'none'\n addBtn.addEventListener('click', (e) => {\n e.stopPropagation()\n picker.style.display = picker.style.display === 'none' ? 'flex' : 'none'\n })\n document.addEventListener('click', () => { picker.style.display = 'none' }, { once: true })\n reactRow.append(addBtn)\n reactWrap.append(reactRow, picker)\n col.append(reactWrap)\n } else if (m.reactions && Object.keys(m.reactions).length) {\n col.append(el('div', 'ocw-react', Object.entries(m.reactions).map(([e, u]) => `${e}${(u as string[]).length}`).join(' ')))\n }\n void store // suppress unused warning — store available for future use\n\n const meta = el('div', 'ocw-time ocw-meta', fmtTime(m.ts))\n if (mine && m.status) {\n const t = el('span', `ocw-tick${m.status === 'read' ? ' read' : m.status === 'delivered' ? ' delivered' : ''}`, tick(m.status))\n meta.append(t)\n }\n // \"Seen\" indicator when agent has read past this message\n if (mine && m.seq > 0 && store.lastReadByOthers >= m.seq) {\n meta.append(el('span', 'ocw-seen', ' · Seen'))\n }\n col.append(meta)\n row.append(col)\n return row\n }\n}\n\nfunction tick(s: NonNullable<RenderMessage['status']>): string {\n switch (s) {\n case 'read': return '✓✓' // blue double tick rendered via CSS colour\n case 'delivered': return '✓✓'\n case 'sent': return '✓'\n default: return '🕓'\n }\n}\n","import { persistentUid } from './uid.js'\nimport {\n asConversationId,\n type ClientFrame, type ConversationId,\n} from './protocol/index.js'\nimport { ChatStore } from './store.js'\nimport { ConnectionManager } from './connection.js'\nimport { PersistentOutbox } from './outbox.js'\nimport { E2ESession, extractX3DHInit } from './e2e.js'\nimport { Renderer, type WidgetConfig } from './renderer.js'\nimport { restoreHistory, resolveRelayUrls } from './history.js'\n\nexport interface UserInfo {\n /** Display name shown in the conversation (e.g. \"Sarah Chen\"). */\n name?: string\n /** Email address — passed as conversation metadata for agent context. */\n email?: string\n /** Avatar URL — shown as the guest's avatar in both widget and dashboard. */\n avatar?: string\n /** Any custom key/value metadata to attach to the conversation\n * (e.g. plan tier, account ID, page URL). Shown to agents in the sidebar. */\n meta?: Record<string, string>\n}\n\nexport interface MountOptions {\n el: HTMLElement\n /** Relay URL. Any scheme works — `https://api.example.com` is fine; the widget\n * derives the WebSocket URL (`wss://…/ws`) and REST base from it. */\n url: string\n /** HTTP(S) base for REST calls — only needed when the REST API is on a\n * DIFFERENT origin than the socket. Normally leave unset. */\n apiUrl?: string\n profileId: string\n subjectId?: string\n /** IDENTITY (tiered — the host owns identity, the widget never has to persist it):\n * 1. `token` — a signed identity token. Either a capability token, or (recommended\n * for embedders) an ES256 JWT `{sub,iat,exp}` signed by your backend with the\n * private key whose public half is set as the chatroom's `guestPublicKey`.\n * The server cryptographically verifies it. Works in ANY language/environment,\n * no cookies or storage required. This is the production path.\n * 2. `userId` — a stable id you already have for the visitor (e.g. your logged-in\n * user id). Unauthenticated (\"you vouch for it\") but works everywhere. Used\n * only when `token` is absent.\n * 3. Neither — the widget falls back to best-effort local identity on the host\n * origin (first-party cookie + localStorage). A returning visitor on the same\n * browser keeps their history; if storage is blocked they get a fresh chat. */\n token?: string\n userId?: string\n subject?: WidgetConfig['subject']\n quickReplies?: string[]\n accent?: string\n /** If set, shows a 🌐 translate button on incoming messages that translates\n * them into this language (ISO code or language name) via the server's\n * /translate endpoint. Omit to disable the feature. */\n translateLang?: string\n /** If true, mount as a floating launcher button that opens/closes the chat */\n launcher?: boolean\n /** Position of the launcher button: default 'bottom-right' */\n position?: 'bottom-right' | 'bottom-left'\n /** Optional user info for identified users. When provided, the name/email/\n * avatar are shown to agents in the dashboard instead of the anonymous ID.\n * The token still controls identity — this is display metadata only.\n * Anonymous users (no token, no user) remain fully anonymous. */\n user?: UserInfo\n /** i18n: override UI strings. All keys are optional — omitted keys fall\n * back to English defaults. */\n i18n?: {\n placeholder?: string // input placeholder, default \"Message…\"\n send?: string // send button label, default \"➤\"\n offline?: string // offline panel title, default \"We're offline right now\"\n poweredBy?: string // footer text, default \"Powered by Relay\"\n }\n}\n\nexport interface WidgetHandle { close(): void }\n\n\n// ── Mount registry ────────────────────────────────────────────────────────────\n// Tracks active widget instances per host element. Prevents double-mounting\n// when React strict mode, HMR, or caller code calls mount() twice on the same\n// element — the most common cause of two widgets appearing on one page.\nconst _registry = new WeakMap<Element, WidgetHandle>()\n\n/** Unmount any widget currently mounted on `el`. No-op if nothing is mounted. */\nexport function unmount(el: Element): void {\n _registry.get(el)?.close()\n _registry.delete(el)\n}\n\nexport function mount(opts: MountOptions): WidgetHandle {\n // Auto-close any previous instance on this exact element before re-mounting.\n // Covers React double-invoke in StrictMode, HMR, and accidental duplicate calls.\n if (_registry.has(opts.el)) {\n _registry.get(opts.el)!.close()\n _registry.delete(opts.el)\n }\n\n // Tiered identity (see MountOptions): a host-provided signed token wins, then a\n // host-vouched userId, then best-effort local persistence. The widget never\n // depends on its own storage when the host supplies identity — which is what\n // makes it safe to embed in any environment (iframes, webviews, SSR, etc.).\n const token = opts.token ?? opts.userId ?? persistentUid()\n // Accept any scheme on `url` (https/http/wss/ws) and derive both the concrete\n // WebSocket URL and the REST base from it. `apiUrl` overrides the REST base\n // only when the API is on a different origin than the socket.\n const { wsUrl, httpBase } = resolveRelayUrls(opts.url, opts.apiUrl)\n let store = new ChatStore(token as never)\n // Key the outbox by token + subjectId so each listing has its own pending queue.\n // Without this, a pending message from listing A appears as a ghost on listing B.\n const outboxKey = opts.subjectId ? `${token}::${opts.subjectId}` : token\n const outbox = new PersistentOutbox(outboxKey)\n let cid: ConversationId | undefined\n let outboxRestored = false\n\n let _mql: MediaQueryList | null = null\n let _mqlHandler: ((e: MediaQueryListEvent) => void) | null = null\n // (e.g. a bare `<div id=\"chat\"></div>` with no CSS). Without this the\n // widget's internal `height:100%` collapses to near-zero. Only applies\n // when the element truly has no height set — explicit CSS always wins.\n if (!opts.launcher && !opts.el.style.height && opts.el.clientHeight === 0) {\n opts.el.style.width = opts.el.style.width || '100%'\n opts.el.style.height = '600px'\n }\n\n // Restore pending outbox items for this specific listing/conversation.\n // The outbox is keyed by token+subjectId so ghost bubbles from other listings\n // never appear here.\n for (const item of outbox.load()) store.addOptimistic(item.clientMsgId, item.content)\n\n // ── Launcher mode ─────────────────────────────────────────────────────────\n let launcherEl: HTMLElement | null = null\n let badgeEl: HTMLElement | null = null\n let unread = 0\n let open = !opts.launcher // start open when not in launcher mode\n\n if (opts.launcher) {\n const pos = opts.position ?? 'bottom-right'\n const isRight = pos.includes('right')\n\n // Outer wrapper holds both the panel and the bubble button\n launcherEl = document.createElement('div')\n launcherEl.style.cssText = `position:fixed;${isRight ? 'right:20px' : 'left:20px'};bottom:20px;z-index:9999;display:flex;flex-direction:column;align-items:${isRight ? 'flex-end' : 'flex-start'};gap:12px`\n\n // ── Chat panel — fixed 380×600, sits above the bubble ─────────────────\n const panel = document.createElement('div')\n // Responsive panel: full-screen on mobile (<480px), 380×600 on desktop.\n // Use a MediaQueryList so the layout updates if the user rotates their phone\n // or resizes the browser window — not just the state at mount time.\n const mql = typeof window !== 'undefined' ? window.matchMedia('(max-width: 479px)') : null\n const applyPanelLayout = (mobile: boolean) => {\n panel.style.cssText = mobile ? [\n 'position:fixed', 'inset:0', 'width:100%', 'height:100%',\n 'border-radius:0', 'overflow:hidden',\n 'box-shadow:none', 'display:none', 'flex-direction:column', 'background:#fff',\n 'transition:opacity .18s', 'opacity:0', 'z-index:9998',\n ].join(';') : [\n 'width:380px', 'height:600px', 'border-radius:16px', 'overflow:hidden',\n 'box-shadow:0 8px 40px rgba(0,0,0,.18)',\n 'display:none', 'flex-direction:column', 'background:#fff',\n 'transform-origin:bottom ' + (isRight ? 'right' : 'left'),\n 'transition:opacity .18s,transform .18s', 'opacity:0', 'transform:scale(.95)',\n ].join(';')\n }\n applyPanelLayout(mql?.matches ?? false)\n const mqlHandler = (e: MediaQueryListEvent): void => applyPanelLayout(e.matches)\n mql?.addEventListener('change', mqlHandler)\n _mql = mql; _mqlHandler = mqlHandler\n\n // Move the mount target INSIDE the panel — not full-page\n opts.el.style.cssText = 'width:100%;height:100%;overflow:hidden'\n panel.append(opts.el)\n\n // ── Bubble button ─────────────────────────────────────────────────────\n const btn = document.createElement('button')\n btn.style.cssText = [\n `width:56px;height:56px;border-radius:50%`,\n `background:${opts.accent ?? '#4F63F5'}`,\n `color:#fff;border:none;font-size:24px;cursor:pointer`,\n `box-shadow:0 4px 16px rgba(0,0,0,.25)`,\n `position:relative;flex:none`,\n `transition:transform .15s`,\n ].join(';')\n btn.textContent = '💬'\n btn.onmouseenter = () => { btn.style.transform = 'scale(1.08)' }\n btn.onmouseleave = () => { btn.style.transform = 'scale(1)' }\n\n badgeEl = document.createElement('span')\n badgeEl.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`\n btn.append(badgeEl)\n\n launcherEl.append(panel, btn)\n document.body.append(launcherEl)\n\n const showPanel = (show: boolean) => {\n if (show) {\n panel.style.display = 'flex'\n requestAnimationFrame(() => { panel.style.opacity = '1'; panel.style.transform = 'scale(1)' })\n } else {\n panel.style.opacity = '0'; panel.style.transform = 'scale(.95)'\n setTimeout(() => { if (!open) panel.style.display = 'none' }, 180)\n }\n }\n\n btn.addEventListener('click', () => {\n open = !open\n showPanel(open)\n btn.textContent = open ? '✕' : '💬'\n btn.append(badgeEl!)\n if (open) { unread = 0; if (badgeEl) badgeEl.style.display = 'none' }\n })\n\n // Close on Escape\n document.addEventListener('keydown', (e) => {\n if (e.key === 'Escape' && open) { open = false; showPanel(false); btn.textContent = '💬'; btn.append(badgeEl!) }\n })\n }\n\n const addUnread = () => {\n if (open) return\n unread++\n if (badgeEl) { badgeEl.textContent = String(unread); badgeEl.style.display = 'flex' }\n }\n\n // ── Notification sound ────────────────────────────────────────────────────\n const playSound = () => {\n try {\n const ctx = new AudioContext()\n const osc = ctx.createOscillator(); const gain = ctx.createGain()\n osc.connect(gain); gain.connect(ctx.destination)\n osc.frequency.setValueAtTime(880, ctx.currentTime)\n osc.frequency.exponentialRampToValueAtTime(440, ctx.currentTime + 0.15)\n gain.gain.setValueAtTime(0.3, ctx.currentTime)\n gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.3)\n osc.start(); osc.stop(ctx.currentTime + 0.3)\n } catch { /* audio not available */ }\n }\n\n // Messages typed before the 'opened' frame arrives are queued here and\n // flushed once cid is known. This prevents silent message loss when the\n // user types immediately after the widget mounts (before WS handshake).\n const preSendQueue: { clientMsgId: string; content: import('./protocol/index.js').MessageContent }[] = []\n\n const flushPreSendQueue = (conversationId: ConversationId) => {\n while (preSendQueue.length) {\n const item = preSendQueue.shift()!\n outbox.add({ clientMsgId: item.clientMsgId, content: item.content, ts: Date.now() })\n conn.send({ type: 'send', conversationId, clientMsgId: item.clientMsgId, content: item.content })\n }\n }\n\n let conn: ConnectionManager\n const e2e = new E2ESession(`ocw-e2e-${opts.profileId}`)\n let e2eStarted = false\n // Live ECDH pending (peer not yet online)\n const pending: { clientMsgId: string; text: string }[] = []\n // X3DH async: pending send awaiting the peer's prekey bundle\n const x3dhPending: { clientMsgId: string; text: string }[] = []\n let x3dhBundleFetched = false\n\n const sendSealed = (clientMsgId: string, text: string): void => {\n void e2e.sealText(text).then((content) => {\n if (cid) conn.send({ type: 'send', conversationId: cid, clientMsgId, content })\n })\n }\n\n const sendSealedX3DH = (clientMsgId: string, text: string, x3dhInit: { ephemeralKey: string; spkId: string; senderIK: string }): void => {\n void e2e.sealText(text, x3dhInit).then((content) => {\n if (cid) conn.send({ type: 'send', conversationId: cid, clientMsgId, content })\n })\n }\n\n const flushPending = (): void => {\n while (pending.length) { const p = pending.shift()!; sendSealed(p.clientMsgId, p.text) }\n while (x3dhPending.length) { const p = x3dhPending.shift()!; sendSealed(p.clientMsgId, p.text) }\n }\n\n /** Fetch the peer's prekey bundle and perform X3DH sender init. */\n const fetchAndX3DH = (targetUserId: string): void => {\n conn.send({ type: 'fetchPrekey', targetUserId: targetUserId as never })\n }\n\n const i18n = opts.i18n ?? {}\n // Auto-detect RTL for Arabic/Hebrew/Persian/Urdu regardless of i18n strings\n const rtlLocales = ['ar', 'he', 'fa', 'ur']\n const browserLang = typeof navigator !== 'undefined' ? (navigator.language ?? '').slice(0, 2).toLowerCase() : ''\n if (rtlLocales.includes(browserLang) && !opts.el.dir) {\n opts.el.dir = 'rtl'\n opts.el.style.fontFamily = opts.el.style.fontFamily || 'Tahoma,Arial,system-ui,sans-serif'\n }\n const renderer = new Renderer(opts.el, token, {\n onSend(text) {\n const clientMsgId = `cm_${Math.random().toString(36).slice(2)}`\n const content: import('./protocol/index.js').MessageContent = { kind: 'text', text }\n store.addOptimistic(clientMsgId, content)\n renderer.render(store)\n if (store.e2e) {\n if (e2e.ready) {\n sendSealed(clientMsgId, text)\n } else if (x3dhBundleFetched) {\n x3dhPending.push({ clientMsgId, text })\n } else {\n pending.push({ clientMsgId, text })\n if (store.assignedAgentId) fetchAndX3DH(store.assignedAgentId)\n }\n } else if (!cid) {\n // Connection not yet opened — queue the message; flushed on 'opened'\n preSendQueue.push({ clientMsgId, content })\n } else {\n outbox.add({ clientMsgId, content, ts: Date.now() })\n conn.send({ type: 'send', conversationId: cid, clientMsgId, content })\n }\n },\n async onAttach(file: File) {\n if (!cid) return\n const uploadUrl = `${httpBase}/upload?name=${encodeURIComponent(file.name)}`\n const clientMsgId = `cm_${Math.random().toString(36).slice(2)}`\n // Optimistic: show uploading state\n store.addOptimistic(clientMsgId, { kind: 'text', text: `📎 Uploading ${file.name}…` })\n renderer.render(store)\n try {\n const res = await fetch(uploadUrl, {\n method: 'POST',\n headers: { 'content-type': file.type, ...(opts.token ? { authorization: `Bearer ${opts.token}` } : {}) },\n body: file,\n })\n if (!res.ok) throw new Error(`Upload failed: ${res.status}`)\n const { url, name, mime, size } = await res.json() as { url: string; name: string; mime: string; size: number }\n conn.send({ type: 'send', conversationId: cid, clientMsgId, content: { kind: 'attachment', url, name, mime, size } })\n } catch (e) {\n store.addOptimistic(clientMsgId, { kind: 'text', text: `⚠️ Upload failed: ${(e as Error).message}` })\n renderer.render(store)\n }\n },\n onInvoke(actionId, inputs) {\n if (!cid) return\n conn.send({ type: 'invoke', conversationId: cid, actionId, clientInvokeId: `iv_${Math.random().toString(36).slice(2)}`, ...(inputs ? { inputs } : {}) })\n },\n onTyping(isTyping, preview) { if (cid) conn.send({ type: 'typing', conversationId: cid, isTyping, ...(preview ? { preview } : {}) }) },\n onReadUpTo(seq) { if (cid) conn.send({ type: 'read', conversationId: cid, seq }) },\n onLoadMore() {\n // WS fallback for E2E rooms where REST history can't be decrypted.\n // Non-E2E rooms use scroll-triggered REST pagination from restoreHistory().\n if (!cid || !store.e2e) return\n const oldest = store.messages()[0]\n if (oldest) conn.send({ type: 'history', conversationId: cid, beforeSeq: oldest.seq, limit: 20 })\n },\n onEdit(messageId, newText) {\n if (cid) conn.send({ type: 'edit', conversationId: cid, messageId: messageId as never, content: { kind: 'text', text: newText } })\n },\n onDelete(messageId) {\n if (cid) conn.send({ type: 'delete', conversationId: cid, messageId: messageId as never })\n },\n onReact(messageId, emoji, remove) {\n if (!cid) return\n conn.send({ type: 'react', conversationId: cid, messageId: messageId as never, emoji, remove })\n },\n onCsat(score) {\n if (!cid) return\n fetch(`${httpBase}/conversations/${cid}/csat`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },\n body: JSON.stringify({ score }),\n }).catch(() => {})\n },\n onAnnotate(stroke) {\n if (cid) conn.send({ type: 'annotate', conversationId: cid, stroke })\n },\n onAnnotateClear() {\n if (cid) conn.send({ type: 'annotate_clear', conversationId: cid })\n },\n ...(opts.translateLang ? {\n async onTranslate(text: string) {\n try {\n const res = await fetch(`${httpBase}/translate`, {\n method: 'POST',\n headers: { 'content-type': 'application/json', authorization: `Bearer ${token}` },\n body: JSON.stringify({ text, targetLang: opts.translateLang }),\n })\n if (!res.ok) return null\n const { translated } = await res.json() as { translated: string | null }\n return translated\n } catch { return null }\n },\n } : {}),\n }, {\n ...(opts.subject ? { subject: opts.subject } : {}),\n ...(opts.quickReplies ? { quickReplies: opts.quickReplies } : {}),\n ...(opts.accent ? { accent: opts.accent } : {}),\n ...(opts.user?.name || opts.user?.avatar ? { userInfo: { ...(opts.user.name ? { name: opts.user.name } : {}), ...(opts.user.avatar ? { avatar: opts.user.avatar } : {}) } } : {}),\n i18n,\n\n })\n\n const openFrame: Extract<ClientFrame, { type: 'open' }> = {\n type: 'open', profileId: opts.profileId as never,\n ...(opts.subjectId ? { subjectId: opts.subjectId as never } : {}),\n ...(typeof location !== 'undefined' ? { pageUrl: location.href } : {}),\n ...(typeof document !== 'undefined' && document.title ? { pageTitle: document.title } : {}),\n // Pass subject display info so the server can persist it to the Subject record.\n // This is how listingTitle and listingMeta get saved without a separate API call.\n ...(opts.subject?.title ? { subjectTitle: opts.subject.title } : {}),\n ...(opts.subject?.subtitle ? { subjectMeta: opts.subject.subtitle } : {}),\n }\n\n // Attach user info as a special first message so agents see it immediately.\n // Sent after 'opened' confirms the conversation exists, not in the open frame\n // itself (the protocol has no user-info field on 'open').\n const sendUserInfo = (conversationId: ConversationId): void => {\n const u = opts.user\n if (!u || (!u.name && !u.email && !u.avatar && !u.meta)) return\n const parts: string[] = []\n if (u.name) parts.push(`Name: ${u.name}`)\n if (u.email) parts.push(`Email: ${u.email}`)\n if (u.avatar) parts.push(`Avatar: ${u.avatar}`)\n if (u.meta) for (const [k, v] of Object.entries(u.meta)) parts.push(`${k}: ${v}`)\n // Send as an internal system message — agents see it, guest doesn't\n conn.send({ type: 'note', conversationId, clientMsgId: `ui_${Date.now()}`, text: `[User info]\\n${parts.join('\\n')}` })\n }\n\n conn = new ConnectionManager({\n url: wsUrl, token, open: openFrame,\n getCursor: () => store.highestSeq(),\n onStatusChange: (s) => renderer.setConnStatus(s),\n onFrame(frame) {\n if (frame.type === 'opened') {\n const isFirstOpen = cid === undefined\n cid = frame.conversation.id\n\n // Flush persistent outbox exactly once (idempotent: items are ack-removed).\n if (!outboxRestored) {\n outboxRestored = true\n for (const item of outbox.load()) {\n conn.send({ type: 'send', conversationId: cid, clientMsgId: item.clientMsgId, content: item.content })\n }\n }\n\n // Restore history on EVERY successful open (covers reconnects too).\n // On reconnect the store still has messages in memory so this is a\n // no-op if there's nothing newer — cheap REST call, correct behaviour.\n void restoreHistory(wsUrl, token, cid, store, renderer, httpBase)\n\n // Flush any messages typed while the connection was still opening.\n if (preSendQueue.length) flushPreSendQueue(cid)\n\n if (isFirstOpen && frame.conversation.lastSeq === 0) sendUserInfo(cid)\n }\n\n if (frame.type === 'ack') outbox.remove(frame.clientMsgId)\n\n // X3DH: handle incoming prekey bundle response\n if (frame.type === 'prekeyBundle') {\n if (frame.bundle) {\n x3dhBundleFetched = true\n void e2e.x3dhSendTo(frame.bundle).then((x3dhInit) => {\n // Drain any X3DH-pending messages with the derived key.\n const toSend = [...pending.splice(0), ...x3dhPending.splice(0)]\n for (const p of toSend) sendSealedX3DH(p.clientMsgId, p.text, x3dhInit)\n renderer.render(store)\n })\n }\n // If no bundle, peer has no prekeys; fall back to live ECDH queue\n return\n }\n\n // X3DH recipient: detect init message in incoming encrypted messages\n if (frame.type === 'message' && store.e2e) {\n const x3dh = extractX3DHInit(frame.message.content)\n if (x3dh && !e2e.ready) {\n void e2e.x3dhReceiveFrom(x3dh.x3dhIK, x3dh.x3dhEK, x3dh.x3dhSPK).then(async () => {\n // Now decrypt the message that carried the init\n await e2e.openFrame(frame)\n store.apply(frame)\n renderer.render(store)\n })\n return\n }\n }\n\n if (frame.type === 'peerkey') {\n void e2e.onPeerKey(frame.key).then(() => { flushPending(); renderer.render(store) })\n return\n }\n void (async () => {\n if (store.e2e) await e2e.openFrame(frame)\n store.apply(frame)\n // Trigger badge + sound for new messages from others.\n // In chatList mode, skip the badge if the user is already in the chat\n // screen for this conversation — they can see the message immediately.\n if (frame.type === 'message' && frame.message.senderId !== (token as never) && !frame.message.internal) {\n addUnread()\n playSound()\n }\n // Once we learn the room is E2E, run the key handshake exactly once.\n if (store.e2e && cid && !e2eStarted) {\n e2eStarted = true\n // Upload our prekey bundle for async E2E support.\n const prekeyPayload = await e2e.initX3DH()\n conn.send({ type: 'uploadPrekeys', ...prekeyPayload })\n // Also do live ECDH handshake in case peer is already online.\n const liveKey = await e2e.begin()\n conn.send({ type: 'pubkey', conversationId: cid, key: liveKey })\n }\n renderer.render(store)\n // Keep seenSeq in sync so the chat list shows accurate unread counts\n })()\n },\n })\n\n\n conn.connect()\n // Show restored 'pending' bubbles (if any) immediately, before the socket opens.\n renderer.render(store)\n\n const handle: WidgetHandle = { close: () => {\n conn.close(); launcherEl?.remove(); renderer.destroy()\n if (_mql && _mqlHandler) _mql.removeEventListener('change', _mqlHandler)\n _registry.delete(opts.el)\n } }\n _registry.set(opts.el, handle)\n return handle\n}\n\nexport { ChatStore } from './store.js'\nexport { ConnectionManager } from './connection.js'\nexport { Renderer } from './renderer.js'\nexport { asConversationId }\nexport { E2ESession, extractX3DHInit, type X3DHBundle } from './e2e.js'\nexport { PersistentOutbox, type OutboxItem } from './outbox.js'\nexport { restoreHistory, httpBaseFromWsUrl, resolveRelayUrls } from './history.js'\n\n"],"names":["asConversationId","utf8Count","str","strLength","byteLength","pos","value","extra","utf8EncodeJs","output","outputOffset","offset","sharedTextEncoder","TEXT_ENCODER_THRESHOLD","utf8EncodeTE","utf8Encode","CHUNK_SIZE","utf8DecodeJs","bytes","inputOffset","end","units","result","byte1","byte2","byte3","byte4","unit","sharedTextDecoder","TEXT_DECODER_THRESHOLD","utf8DecodeTD","stringBytes","utf8Decode","ExtData","type","data","__publicField","DecodeError","message","proto","UINT32_MAX","setUint64","view","high","low","setInt64","getInt64","getUint64","EXT_TIMESTAMP","TIMESTAMP32_MAX_SEC","TIMESTAMP64_MAX_SEC","encodeTimeSpecToTimestamp","sec","nsec","rv","secHigh","secLow","encodeDateToTimeSpec","date","msec","nsecInSec","encodeTimestampExtension","object","timeSpec","decodeTimestampToTimeSpec","nsec30AndSecHigh2","secLow32","decodeTimestampExtension","timestampExtension","_ExtensionCodec","encode","decode","index","context","encodeExt","decodeExt","ExtensionCodec","isArrayBufferLike","buffer","ensureUint8Array","DEFAULT_MAX_DEPTH","DEFAULT_INITIAL_BUFFER_SIZE","Encoder","options","depth","sizeToWrite","requiredSize","newSize","newBuffer","newBytes","newView","ext","size","item","keys","count","key","values","prettyByte","byte","DEFAULT_MAX_KEY_LENGTH","DEFAULT_MAX_LENGTH_PER_KEY","CachedKeyDecoder","maxKeyLength","maxLengthPerKey","records","FIND_CHUNK","record","recordBytes","j","cachedValue","slicedCopyOfBytes","STATE_ARRAY","STATE_MAP_KEY","STATE_MAP_VALUE","mapKeyConverter","StackPool","state","partialState","HEAD_BYTE_REQUIRED","EMPTY_VIEW","EMPTY_BYTES","e","MORE_DATA","sharedCachedKeyDecoder","Decoder","remainingData","newData","posToShow","stream","decoded","headByte","totalPos","isArray","isArrayHeaderRequired","arrayItemsLeft","DECODE","stack","headerOffset","_a","headOffset","extType","CLIENT_FRAME_TYPES","isClientFrame","frame","encodeFrame","mpEncode","decodeFrame","mpDecode","ChatStore","me","a","b","ap","bp","clientMsgId","content","msg","confirmed","m","reactions","users","u","existing","uptoSeq","status","targetRank","rank","changed","k","ConnectionManager","opts","_b","sock","defaultFactory","ev","cap","pending","f","base","max","delay","url","MAX_ITEMS","MAX_AGE_MS","PersistentOutbox","token","raw","items","cutoff","fresh","i","subtle","b64encode","buf","s","b64decode","bin","out","generateKeyPair","kp","exportPublicKey","importPeerPublicKey","b64","deriveSharedKey","privateKey","peerPublicKeyB64","peer","encrypt","plaintext","iv","ct","decrypt","plain","loadOrCreateKeyPair","storageKey","pub","priv","publicKey","signPrekey","signingPrivateKey","spkPublicKey","spkRaw","sig","generateIdentityKeyPair","ecdhKP","ecdsaKP","loadOrCreateIdentityKeyPair","d","ecdhPub","ecdhPriv","ecdsaPub","ecdsaPriv","ikp","x3dhSend","senderIK","recipientBundle","ek","epkB64","ik_r","spk_r","opk_r","dh1","rawDH","dh2","dh3","dh4","ikm","concatBuffers","hkdfDeriveKey","x3dhReceive","recipientIK","recipientSPK","senderIKb64","ephemeralKeyB64","recipientOPK","ik_s","ek_s","bufs","total","ikmKey","OTP_BATCH_SIZE","E2ESession","peerKeyB64","signedPrekeyPub","signature","oneTimePrekeys","bundle","sharedKey","ephemeralPublicKey","spkId","otp","ephemeralKey","text","x3dhInit","extractX3DHInit","c","STYLE_ID","REACTION_EMOJIS","CSS","injectStyles","el","tag","cls","n","fmtTime","ts","contentText","Renderer","root","h","cfg","head","avatarEl","img","hm","_c","_d","_e","_f","_g","typingBubble","q","sendBtn","_h","attachBtn","fileInput","inputRow","footer","_i","sw","cobrowseClear","fn","preview","store","ownerLabel","actions","prevScrollHeight","prevScrollTop","sentinel","maxOther","typingNames","bubble","terminalStates","offlineMessage","form","nameIn","emailIn","msgIn","submit","stars","btns","bb","idx","stroke","ctx","w","p","drawing","current","posFromEvent","rect","x","y","STROKE_WIDTH","finish","title","tags","v","t","btn","label","resolve","overlay","card","row","cancel","ok","close","panel","inputs","sel","opt","o","inp","name","sys","mine","isNote","col","bubbleWrap","replyCtx","textNode","links","gLink","iLink","original","translateBtn","cached","menu","editBtn","ta","saveBtn","cancelBtn","btnRow","editPanel","restore","newText","ke","delBtn","reactWrap","reactRow","emoji","pill","addBtn","picker","pb","alreadyReacted","meta","tick","_registry","unmount","mount","persistentUid","wsUrl","httpBase","resolveRelayUrls","outboxKey","outbox","cid","outboxRestored","_mql","_mqlHandler","launcherEl","badgeEl","unread","open","isRight","mql","applyPanelLayout","mobile","mqlHandler","showPanel","show","addUnread","playSound","osc","gain","preSendQueue","flushPreSendQueue","conversationId","conn","e2e","e2eStarted","x3dhPending","x3dhBundleFetched","sendSealed","sendSealedX3DH","flushPending","fetchAndX3DH","targetUserId","i18n","rtlLocales","browserLang","renderer","file","uploadUrl","res","mime","actionId","isTyping","seq","oldest","messageId","remove","score","translated","openFrame","sendUserInfo","parts","isFirstOpen","restoreHistory","toSend","x3dh","prekeyPayload","liveKey","handle"],"mappings":"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","x_google_ignoreList":[1,2,3,4,5,6,7,8,9,10,11,12,13]}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/protocol/ids.ts","../node_modules/@msgpack/msgpack/dist.esm/utils/utf8.mjs","../node_modules/@msgpack/msgpack/dist.esm/ExtData.mjs","../node_modules/@msgpack/msgpack/dist.esm/DecodeError.mjs","../node_modules/@msgpack/msgpack/dist.esm/utils/int.mjs","../node_modules/@msgpack/msgpack/dist.esm/timestamp.mjs","../node_modules/@msgpack/msgpack/dist.esm/ExtensionCodec.mjs","../node_modules/@msgpack/msgpack/dist.esm/utils/typedArrays.mjs","../node_modules/@msgpack/msgpack/dist.esm/Encoder.mjs","../node_modules/@msgpack/msgpack/dist.esm/encode.mjs","../node_modules/@msgpack/msgpack/dist.esm/utils/prettyByte.mjs","../node_modules/@msgpack/msgpack/dist.esm/CachedKeyDecoder.mjs","../node_modules/@msgpack/msgpack/dist.esm/Decoder.mjs","../node_modules/@msgpack/msgpack/dist.esm/decode.mjs","../src/protocol/codec.ts","../src/store.ts","../src/connection.ts","../src/outbox.ts","../src/crypto.ts","../src/e2e.ts","../src/renderer.ts","../src/index.ts"],"sourcesContent":["// Branded identifier types. A plain string can't be passed where a TenantId is\n// expected (and vice-versa), so id-confusion bugs — the kind that caused the\n// `t-1` vs `dev-tenant` mismatch in the previous system — become compile errors.\n\nexport type Brand<T, B extends string> = T & { readonly __brand: B }\n\nexport type TenantId = Brand<string, 'TenantId'>\nexport type UserId = Brand<string, 'UserId'>\nexport type ConversationId = Brand<string, 'ConversationId'>\nexport type SubjectId = Brand<string, 'SubjectId'>\nexport type MessageId = Brand<string, 'MessageId'>\nexport type ActionId = Brand<string, 'ActionId'>\nexport type ProfileId = Brand<string, 'ProfileId'>\nexport type ConnectionId = Brand<string, 'ConnectionId'>\n\nexport const asTenantId = (s: string): TenantId => s as TenantId\nexport const asUserId = (s: string): UserId => s as UserId\nexport const asConversationId = (s: string): ConversationId => s as ConversationId\nexport const asSubjectId = (s: string): SubjectId => s as SubjectId\nexport const asMessageId = (s: string): MessageId => s as MessageId\nexport const asActionId = (s: string): ActionId => s as ActionId\nexport const asProfileId = (s: string): ProfileId => s as ProfileId\nexport const asConnectionId = (s: string): ConnectionId => s as ConnectionId\n\n/** Anonymous guests live under this tenant; they bypass cross-tenant scoping but\n * are still gated by conversation membership. */\nexport const ANONYMOUS_TENANT = asTenantId('anonymous')\n","export function utf8Count(str) {\n const strLength = str.length;\n let byteLength = 0;\n let pos = 0;\n while (pos < strLength) {\n let value = str.charCodeAt(pos++);\n if ((value & 0xffffff80) === 0) {\n // 1-byte\n byteLength++;\n continue;\n }\n else if ((value & 0xfffff800) === 0) {\n // 2-bytes\n byteLength += 2;\n }\n else {\n // handle surrogate pair\n if (value >= 0xd800 && value <= 0xdbff) {\n // high surrogate\n if (pos < strLength) {\n const extra = str.charCodeAt(pos);\n if ((extra & 0xfc00) === 0xdc00) {\n ++pos;\n value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000;\n }\n }\n }\n if ((value & 0xffff0000) === 0) {\n // 3-byte\n byteLength += 3;\n }\n else {\n // 4-byte\n byteLength += 4;\n }\n }\n }\n return byteLength;\n}\nexport function utf8EncodeJs(str, output, outputOffset) {\n const strLength = str.length;\n let offset = outputOffset;\n let pos = 0;\n while (pos < strLength) {\n let value = str.charCodeAt(pos++);\n if ((value & 0xffffff80) === 0) {\n // 1-byte\n output[offset++] = value;\n continue;\n }\n else if ((value & 0xfffff800) === 0) {\n // 2-bytes\n output[offset++] = ((value >> 6) & 0x1f) | 0xc0;\n }\n else {\n // handle surrogate pair\n if (value >= 0xd800 && value <= 0xdbff) {\n // high surrogate\n if (pos < strLength) {\n const extra = str.charCodeAt(pos);\n if ((extra & 0xfc00) === 0xdc00) {\n ++pos;\n value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000;\n }\n }\n }\n if ((value & 0xffff0000) === 0) {\n // 3-byte\n output[offset++] = ((value >> 12) & 0x0f) | 0xe0;\n output[offset++] = ((value >> 6) & 0x3f) | 0x80;\n }\n else {\n // 4-byte\n output[offset++] = ((value >> 18) & 0x07) | 0xf0;\n output[offset++] = ((value >> 12) & 0x3f) | 0x80;\n output[offset++] = ((value >> 6) & 0x3f) | 0x80;\n }\n }\n output[offset++] = (value & 0x3f) | 0x80;\n }\n}\n// TextEncoder and TextDecoder are standardized in whatwg encoding:\n// https://encoding.spec.whatwg.org/\n// and available in all the modern browsers:\n// https://caniuse.com/textencoder\n// They are available in Node.js since v12 LTS as well:\n// https://nodejs.org/api/globals.html#textencoder\nconst sharedTextEncoder = new TextEncoder();\n// This threshold should be determined by benchmarking, which might vary in engines and input data.\n// Run `npx ts-node benchmark/encode-string.ts` for details.\nconst TEXT_ENCODER_THRESHOLD = 50;\nexport function utf8EncodeTE(str, output, outputOffset) {\n sharedTextEncoder.encodeInto(str, output.subarray(outputOffset));\n}\nexport function utf8Encode(str, output, outputOffset) {\n if (str.length > TEXT_ENCODER_THRESHOLD) {\n utf8EncodeTE(str, output, outputOffset);\n }\n else {\n utf8EncodeJs(str, output, outputOffset);\n }\n}\nconst CHUNK_SIZE = 4096;\nexport function utf8DecodeJs(bytes, inputOffset, byteLength) {\n let offset = inputOffset;\n const end = offset + byteLength;\n const units = [];\n let result = \"\";\n while (offset < end) {\n const byte1 = bytes[offset++];\n if ((byte1 & 0x80) === 0) {\n // 1 byte\n units.push(byte1);\n }\n else if ((byte1 & 0xe0) === 0xc0) {\n // 2 bytes\n const byte2 = bytes[offset++] & 0x3f;\n units.push(((byte1 & 0x1f) << 6) | byte2);\n }\n else if ((byte1 & 0xf0) === 0xe0) {\n // 3 bytes\n const byte2 = bytes[offset++] & 0x3f;\n const byte3 = bytes[offset++] & 0x3f;\n units.push(((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3);\n }\n else if ((byte1 & 0xf8) === 0xf0) {\n // 4 bytes\n const byte2 = bytes[offset++] & 0x3f;\n const byte3 = bytes[offset++] & 0x3f;\n const byte4 = bytes[offset++] & 0x3f;\n let unit = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4;\n if (unit > 0xffff) {\n unit -= 0x10000;\n units.push(((unit >>> 10) & 0x3ff) | 0xd800);\n unit = 0xdc00 | (unit & 0x3ff);\n }\n units.push(unit);\n }\n else {\n units.push(byte1);\n }\n if (units.length >= CHUNK_SIZE) {\n result += String.fromCharCode(...units);\n units.length = 0;\n }\n }\n if (units.length > 0) {\n result += String.fromCharCode(...units);\n }\n return result;\n}\nconst sharedTextDecoder = new TextDecoder();\n// This threshold should be determined by benchmarking, which might vary in engines and input data.\n// Run `npx ts-node benchmark/decode-string.ts` for details.\nconst TEXT_DECODER_THRESHOLD = 200;\nexport function utf8DecodeTD(bytes, inputOffset, byteLength) {\n const stringBytes = bytes.subarray(inputOffset, inputOffset + byteLength);\n return sharedTextDecoder.decode(stringBytes);\n}\nexport function utf8Decode(bytes, inputOffset, byteLength) {\n if (byteLength > TEXT_DECODER_THRESHOLD) {\n return utf8DecodeTD(bytes, inputOffset, byteLength);\n }\n else {\n return utf8DecodeJs(bytes, inputOffset, byteLength);\n }\n}\n//# sourceMappingURL=utf8.mjs.map","/**\n * ExtData is used to handle Extension Types that are not registered to ExtensionCodec.\n */\nexport class ExtData {\n type;\n data;\n constructor(type, data) {\n this.type = type;\n this.data = data;\n }\n}\n//# sourceMappingURL=ExtData.mjs.map","export class DecodeError extends Error {\n constructor(message) {\n super(message);\n // fix the prototype chain in a cross-platform way\n const proto = Object.create(DecodeError.prototype);\n Object.setPrototypeOf(this, proto);\n Object.defineProperty(this, \"name\", {\n configurable: true,\n enumerable: false,\n value: DecodeError.name,\n });\n }\n}\n//# sourceMappingURL=DecodeError.mjs.map","// Integer Utility\nexport const UINT32_MAX = 4294967295;\n// DataView extension to handle int64 / uint64,\n// where the actual range is 53-bits integer (a.k.a. safe integer)\nexport function setUint64(view, offset, value) {\n const high = value / 4294967296;\n const low = value; // high bits are truncated by DataView\n view.setUint32(offset, high);\n view.setUint32(offset + 4, low);\n}\nexport function setInt64(view, offset, value) {\n const high = Math.floor(value / 4294967296);\n const low = value; // high bits are truncated by DataView\n view.setUint32(offset, high);\n view.setUint32(offset + 4, low);\n}\nexport function getInt64(view, offset) {\n const high = view.getInt32(offset);\n const low = view.getUint32(offset + 4);\n return high * 4294967296 + low;\n}\nexport function getUint64(view, offset) {\n const high = view.getUint32(offset);\n const low = view.getUint32(offset + 4);\n return high * 4294967296 + low;\n}\n//# sourceMappingURL=int.mjs.map","// https://github.com/msgpack/msgpack/blob/master/spec.md#timestamp-extension-type\nimport { DecodeError } from \"./DecodeError.mjs\";\nimport { getInt64, setInt64 } from \"./utils/int.mjs\";\nexport const EXT_TIMESTAMP = -1;\nconst TIMESTAMP32_MAX_SEC = 0x100000000 - 1; // 32-bit unsigned int\nconst TIMESTAMP64_MAX_SEC = 0x400000000 - 1; // 34-bit unsigned int\nexport function encodeTimeSpecToTimestamp({ sec, nsec }) {\n if (sec >= 0 && nsec >= 0 && sec <= TIMESTAMP64_MAX_SEC) {\n // Here sec >= 0 && nsec >= 0\n if (nsec === 0 && sec <= TIMESTAMP32_MAX_SEC) {\n // timestamp 32 = { sec32 (unsigned) }\n const rv = new Uint8Array(4);\n const view = new DataView(rv.buffer);\n view.setUint32(0, sec);\n return rv;\n }\n else {\n // timestamp 64 = { nsec30 (unsigned), sec34 (unsigned) }\n const secHigh = sec / 0x100000000;\n const secLow = sec & 0xffffffff;\n const rv = new Uint8Array(8);\n const view = new DataView(rv.buffer);\n // nsec30 | secHigh2\n view.setUint32(0, (nsec << 2) | (secHigh & 0x3));\n // secLow32\n view.setUint32(4, secLow);\n return rv;\n }\n }\n else {\n // timestamp 96 = { nsec32 (unsigned), sec64 (signed) }\n const rv = new Uint8Array(12);\n const view = new DataView(rv.buffer);\n view.setUint32(0, nsec);\n setInt64(view, 4, sec);\n return rv;\n }\n}\nexport function encodeDateToTimeSpec(date) {\n const msec = date.getTime();\n const sec = Math.floor(msec / 1e3);\n const nsec = (msec - sec * 1e3) * 1e6;\n // Normalizes { sec, nsec } to ensure nsec is unsigned.\n const nsecInSec = Math.floor(nsec / 1e9);\n return {\n sec: sec + nsecInSec,\n nsec: nsec - nsecInSec * 1e9,\n };\n}\nexport function encodeTimestampExtension(object) {\n if (object instanceof Date) {\n const timeSpec = encodeDateToTimeSpec(object);\n return encodeTimeSpecToTimestamp(timeSpec);\n }\n else {\n return null;\n }\n}\nexport function decodeTimestampToTimeSpec(data) {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n // data may be 32, 64, or 96 bits\n switch (data.byteLength) {\n case 4: {\n // timestamp 32 = { sec32 }\n const sec = view.getUint32(0);\n const nsec = 0;\n return { sec, nsec };\n }\n case 8: {\n // timestamp 64 = { nsec30, sec34 }\n const nsec30AndSecHigh2 = view.getUint32(0);\n const secLow32 = view.getUint32(4);\n const sec = (nsec30AndSecHigh2 & 0x3) * 0x100000000 + secLow32;\n const nsec = nsec30AndSecHigh2 >>> 2;\n return { sec, nsec };\n }\n case 12: {\n // timestamp 96 = { nsec32 (unsigned), sec64 (signed) }\n const sec = getInt64(view, 4);\n const nsec = view.getUint32(0);\n return { sec, nsec };\n }\n default:\n throw new DecodeError(`Unrecognized data size for timestamp (expected 4, 8, or 12): ${data.length}`);\n }\n}\nexport function decodeTimestampExtension(data) {\n const timeSpec = decodeTimestampToTimeSpec(data);\n return new Date(timeSpec.sec * 1e3 + timeSpec.nsec / 1e6);\n}\nexport const timestampExtension = {\n type: EXT_TIMESTAMP,\n encode: encodeTimestampExtension,\n decode: decodeTimestampExtension,\n};\n//# sourceMappingURL=timestamp.mjs.map","// ExtensionCodec to handle MessagePack extensions\nimport { ExtData } from \"./ExtData.mjs\";\nimport { timestampExtension } from \"./timestamp.mjs\";\nexport class ExtensionCodec {\n static defaultCodec = new ExtensionCodec();\n // ensures ExtensionCodecType<X> matches ExtensionCodec<X>\n // this will make type errors a lot more clear\n // eslint-disable-next-line @typescript-eslint/naming-convention\n __brand;\n // built-in extensions\n builtInEncoders = [];\n builtInDecoders = [];\n // custom extensions\n encoders = [];\n decoders = [];\n constructor() {\n this.register(timestampExtension);\n }\n register({ type, encode, decode, }) {\n if (type >= 0) {\n // custom extensions\n this.encoders[type] = encode;\n this.decoders[type] = decode;\n }\n else {\n // built-in extensions\n const index = -1 - type;\n this.builtInEncoders[index] = encode;\n this.builtInDecoders[index] = decode;\n }\n }\n tryToEncode(object, context) {\n // built-in extensions\n for (let i = 0; i < this.builtInEncoders.length; i++) {\n const encodeExt = this.builtInEncoders[i];\n if (encodeExt != null) {\n const data = encodeExt(object, context);\n if (data != null) {\n const type = -1 - i;\n return new ExtData(type, data);\n }\n }\n }\n // custom extensions\n for (let i = 0; i < this.encoders.length; i++) {\n const encodeExt = this.encoders[i];\n if (encodeExt != null) {\n const data = encodeExt(object, context);\n if (data != null) {\n const type = i;\n return new ExtData(type, data);\n }\n }\n }\n if (object instanceof ExtData) {\n // to keep ExtData as is\n return object;\n }\n return null;\n }\n decode(data, type, context) {\n const decodeExt = type < 0 ? this.builtInDecoders[-1 - type] : this.decoders[type];\n if (decodeExt) {\n return decodeExt(data, type, context);\n }\n else {\n // decode() does not fail, returns ExtData instead.\n return new ExtData(type, data);\n }\n }\n}\n//# sourceMappingURL=ExtensionCodec.mjs.map","function isArrayBufferLike(buffer) {\n return (buffer instanceof ArrayBuffer || (typeof SharedArrayBuffer !== \"undefined\" && buffer instanceof SharedArrayBuffer));\n}\nexport function ensureUint8Array(buffer) {\n if (buffer instanceof Uint8Array) {\n return buffer;\n }\n else if (ArrayBuffer.isView(buffer)) {\n return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);\n }\n else if (isArrayBufferLike(buffer)) {\n return new Uint8Array(buffer);\n }\n else {\n // ArrayLike<number>\n return Uint8Array.from(buffer);\n }\n}\n//# sourceMappingURL=typedArrays.mjs.map","import { utf8Count, utf8Encode } from \"./utils/utf8.mjs\";\nimport { ExtensionCodec } from \"./ExtensionCodec.mjs\";\nimport { setInt64, setUint64 } from \"./utils/int.mjs\";\nimport { ensureUint8Array } from \"./utils/typedArrays.mjs\";\nexport const DEFAULT_MAX_DEPTH = 100;\nexport const DEFAULT_INITIAL_BUFFER_SIZE = 2048;\nexport class Encoder {\n extensionCodec;\n context;\n useBigInt64;\n maxDepth;\n initialBufferSize;\n sortKeys;\n forceFloat32;\n ignoreUndefined;\n forceIntegerToFloat;\n pos;\n view;\n bytes;\n entered = false;\n constructor(options) {\n this.extensionCodec = options?.extensionCodec ?? ExtensionCodec.defaultCodec;\n this.context = options?.context; // needs a type assertion because EncoderOptions has no context property when ContextType is undefined\n this.useBigInt64 = options?.useBigInt64 ?? false;\n this.maxDepth = options?.maxDepth ?? DEFAULT_MAX_DEPTH;\n this.initialBufferSize = options?.initialBufferSize ?? DEFAULT_INITIAL_BUFFER_SIZE;\n this.sortKeys = options?.sortKeys ?? false;\n this.forceFloat32 = options?.forceFloat32 ?? false;\n this.ignoreUndefined = options?.ignoreUndefined ?? false;\n this.forceIntegerToFloat = options?.forceIntegerToFloat ?? false;\n this.pos = 0;\n this.view = new DataView(new ArrayBuffer(this.initialBufferSize));\n this.bytes = new Uint8Array(this.view.buffer);\n }\n clone() {\n // Because of slightly special argument `context`,\n // type assertion is needed.\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n return new Encoder({\n extensionCodec: this.extensionCodec,\n context: this.context,\n useBigInt64: this.useBigInt64,\n maxDepth: this.maxDepth,\n initialBufferSize: this.initialBufferSize,\n sortKeys: this.sortKeys,\n forceFloat32: this.forceFloat32,\n ignoreUndefined: this.ignoreUndefined,\n forceIntegerToFloat: this.forceIntegerToFloat,\n });\n }\n reinitializeState() {\n this.pos = 0;\n }\n /**\n * This is almost equivalent to {@link Encoder#encode}, but it returns an reference of the encoder's internal buffer and thus much faster than {@link Encoder#encode}.\n *\n * @returns Encodes the object and returns a shared reference the encoder's internal buffer.\n */\n encodeSharedRef(object) {\n if (this.entered) {\n const instance = this.clone();\n return instance.encodeSharedRef(object);\n }\n try {\n this.entered = true;\n this.reinitializeState();\n this.doEncode(object, 1);\n return this.bytes.subarray(0, this.pos);\n }\n finally {\n this.entered = false;\n }\n }\n /**\n * @returns Encodes the object and returns a copy of the encoder's internal buffer.\n */\n encode(object) {\n if (this.entered) {\n const instance = this.clone();\n return instance.encode(object);\n }\n try {\n this.entered = true;\n this.reinitializeState();\n this.doEncode(object, 1);\n return this.bytes.slice(0, this.pos);\n }\n finally {\n this.entered = false;\n }\n }\n doEncode(object, depth) {\n if (depth > this.maxDepth) {\n throw new Error(`Too deep objects in depth ${depth}`);\n }\n if (object == null) {\n this.encodeNil();\n }\n else if (typeof object === \"boolean\") {\n this.encodeBoolean(object);\n }\n else if (typeof object === \"number\") {\n if (!this.forceIntegerToFloat) {\n this.encodeNumber(object);\n }\n else {\n this.encodeNumberAsFloat(object);\n }\n }\n else if (typeof object === \"string\") {\n this.encodeString(object);\n }\n else if (this.useBigInt64 && typeof object === \"bigint\") {\n this.encodeBigInt64(object);\n }\n else {\n this.encodeObject(object, depth);\n }\n }\n ensureBufferSizeToWrite(sizeToWrite) {\n const requiredSize = this.pos + sizeToWrite;\n if (this.view.byteLength < requiredSize) {\n this.resizeBuffer(requiredSize * 2);\n }\n }\n resizeBuffer(newSize) {\n const newBuffer = new ArrayBuffer(newSize);\n const newBytes = new Uint8Array(newBuffer);\n const newView = new DataView(newBuffer);\n newBytes.set(this.bytes);\n this.view = newView;\n this.bytes = newBytes;\n }\n encodeNil() {\n this.writeU8(0xc0);\n }\n encodeBoolean(object) {\n if (object === false) {\n this.writeU8(0xc2);\n }\n else {\n this.writeU8(0xc3);\n }\n }\n encodeNumber(object) {\n if (!this.forceIntegerToFloat && Number.isSafeInteger(object)) {\n if (object >= 0) {\n if (object < 0x80) {\n // positive fixint\n this.writeU8(object);\n }\n else if (object < 0x100) {\n // uint 8\n this.writeU8(0xcc);\n this.writeU8(object);\n }\n else if (object < 0x10000) {\n // uint 16\n this.writeU8(0xcd);\n this.writeU16(object);\n }\n else if (object < 0x100000000) {\n // uint 32\n this.writeU8(0xce);\n this.writeU32(object);\n }\n else if (!this.useBigInt64) {\n // uint 64\n this.writeU8(0xcf);\n this.writeU64(object);\n }\n else {\n this.encodeNumberAsFloat(object);\n }\n }\n else {\n if (object >= -0x20) {\n // negative fixint\n this.writeU8(0xe0 | (object + 0x20));\n }\n else if (object >= -0x80) {\n // int 8\n this.writeU8(0xd0);\n this.writeI8(object);\n }\n else if (object >= -0x8000) {\n // int 16\n this.writeU8(0xd1);\n this.writeI16(object);\n }\n else if (object >= -0x80000000) {\n // int 32\n this.writeU8(0xd2);\n this.writeI32(object);\n }\n else if (!this.useBigInt64) {\n // int 64\n this.writeU8(0xd3);\n this.writeI64(object);\n }\n else {\n this.encodeNumberAsFloat(object);\n }\n }\n }\n else {\n this.encodeNumberAsFloat(object);\n }\n }\n encodeNumberAsFloat(object) {\n if (this.forceFloat32) {\n // float 32\n this.writeU8(0xca);\n this.writeF32(object);\n }\n else {\n // float 64\n this.writeU8(0xcb);\n this.writeF64(object);\n }\n }\n encodeBigInt64(object) {\n if (object >= BigInt(0)) {\n // uint 64\n this.writeU8(0xcf);\n this.writeBigUint64(object);\n }\n else {\n // int 64\n this.writeU8(0xd3);\n this.writeBigInt64(object);\n }\n }\n writeStringHeader(byteLength) {\n if (byteLength < 32) {\n // fixstr\n this.writeU8(0xa0 + byteLength);\n }\n else if (byteLength < 0x100) {\n // str 8\n this.writeU8(0xd9);\n this.writeU8(byteLength);\n }\n else if (byteLength < 0x10000) {\n // str 16\n this.writeU8(0xda);\n this.writeU16(byteLength);\n }\n else if (byteLength < 0x100000000) {\n // str 32\n this.writeU8(0xdb);\n this.writeU32(byteLength);\n }\n else {\n throw new Error(`Too long string: ${byteLength} bytes in UTF-8`);\n }\n }\n encodeString(object) {\n const maxHeaderSize = 1 + 4;\n const byteLength = utf8Count(object);\n this.ensureBufferSizeToWrite(maxHeaderSize + byteLength);\n this.writeStringHeader(byteLength);\n utf8Encode(object, this.bytes, this.pos);\n this.pos += byteLength;\n }\n encodeObject(object, depth) {\n // try to encode objects with custom codec first of non-primitives\n const ext = this.extensionCodec.tryToEncode(object, this.context);\n if (ext != null) {\n this.encodeExtension(ext);\n }\n else if (Array.isArray(object)) {\n this.encodeArray(object, depth);\n }\n else if (ArrayBuffer.isView(object)) {\n this.encodeBinary(object);\n }\n else if (typeof object === \"object\") {\n this.encodeMap(object, depth);\n }\n else {\n // symbol, function and other special object come here unless extensionCodec handles them.\n throw new Error(`Unrecognized object: ${Object.prototype.toString.apply(object)}`);\n }\n }\n encodeBinary(object) {\n const size = object.byteLength;\n if (size < 0x100) {\n // bin 8\n this.writeU8(0xc4);\n this.writeU8(size);\n }\n else if (size < 0x10000) {\n // bin 16\n this.writeU8(0xc5);\n this.writeU16(size);\n }\n else if (size < 0x100000000) {\n // bin 32\n this.writeU8(0xc6);\n this.writeU32(size);\n }\n else {\n throw new Error(`Too large binary: ${size}`);\n }\n const bytes = ensureUint8Array(object);\n this.writeU8a(bytes);\n }\n encodeArray(object, depth) {\n const size = object.length;\n if (size < 16) {\n // fixarray\n this.writeU8(0x90 + size);\n }\n else if (size < 0x10000) {\n // array 16\n this.writeU8(0xdc);\n this.writeU16(size);\n }\n else if (size < 0x100000000) {\n // array 32\n this.writeU8(0xdd);\n this.writeU32(size);\n }\n else {\n throw new Error(`Too large array: ${size}`);\n }\n for (const item of object) {\n this.doEncode(item, depth + 1);\n }\n }\n countWithoutUndefined(object, keys) {\n let count = 0;\n for (const key of keys) {\n if (object[key] !== undefined) {\n count++;\n }\n }\n return count;\n }\n encodeMap(object, depth) {\n const keys = Object.keys(object);\n if (this.sortKeys) {\n keys.sort();\n }\n const size = this.ignoreUndefined ? this.countWithoutUndefined(object, keys) : keys.length;\n if (size < 16) {\n // fixmap\n this.writeU8(0x80 + size);\n }\n else if (size < 0x10000) {\n // map 16\n this.writeU8(0xde);\n this.writeU16(size);\n }\n else if (size < 0x100000000) {\n // map 32\n this.writeU8(0xdf);\n this.writeU32(size);\n }\n else {\n throw new Error(`Too large map object: ${size}`);\n }\n for (const key of keys) {\n const value = object[key];\n if (!(this.ignoreUndefined && value === undefined)) {\n this.encodeString(key);\n this.doEncode(value, depth + 1);\n }\n }\n }\n encodeExtension(ext) {\n if (typeof ext.data === \"function\") {\n const data = ext.data(this.pos + 6);\n const size = data.length;\n if (size >= 0x100000000) {\n throw new Error(`Too large extension object: ${size}`);\n }\n this.writeU8(0xc9);\n this.writeU32(size);\n this.writeI8(ext.type);\n this.writeU8a(data);\n return;\n }\n const size = ext.data.length;\n if (size === 1) {\n // fixext 1\n this.writeU8(0xd4);\n }\n else if (size === 2) {\n // fixext 2\n this.writeU8(0xd5);\n }\n else if (size === 4) {\n // fixext 4\n this.writeU8(0xd6);\n }\n else if (size === 8) {\n // fixext 8\n this.writeU8(0xd7);\n }\n else if (size === 16) {\n // fixext 16\n this.writeU8(0xd8);\n }\n else if (size < 0x100) {\n // ext 8\n this.writeU8(0xc7);\n this.writeU8(size);\n }\n else if (size < 0x10000) {\n // ext 16\n this.writeU8(0xc8);\n this.writeU16(size);\n }\n else if (size < 0x100000000) {\n // ext 32\n this.writeU8(0xc9);\n this.writeU32(size);\n }\n else {\n throw new Error(`Too large extension object: ${size}`);\n }\n this.writeI8(ext.type);\n this.writeU8a(ext.data);\n }\n writeU8(value) {\n this.ensureBufferSizeToWrite(1);\n this.view.setUint8(this.pos, value);\n this.pos++;\n }\n writeU8a(values) {\n const size = values.length;\n this.ensureBufferSizeToWrite(size);\n this.bytes.set(values, this.pos);\n this.pos += size;\n }\n writeI8(value) {\n this.ensureBufferSizeToWrite(1);\n this.view.setInt8(this.pos, value);\n this.pos++;\n }\n writeU16(value) {\n this.ensureBufferSizeToWrite(2);\n this.view.setUint16(this.pos, value);\n this.pos += 2;\n }\n writeI16(value) {\n this.ensureBufferSizeToWrite(2);\n this.view.setInt16(this.pos, value);\n this.pos += 2;\n }\n writeU32(value) {\n this.ensureBufferSizeToWrite(4);\n this.view.setUint32(this.pos, value);\n this.pos += 4;\n }\n writeI32(value) {\n this.ensureBufferSizeToWrite(4);\n this.view.setInt32(this.pos, value);\n this.pos += 4;\n }\n writeF32(value) {\n this.ensureBufferSizeToWrite(4);\n this.view.setFloat32(this.pos, value);\n this.pos += 4;\n }\n writeF64(value) {\n this.ensureBufferSizeToWrite(8);\n this.view.setFloat64(this.pos, value);\n this.pos += 8;\n }\n writeU64(value) {\n this.ensureBufferSizeToWrite(8);\n setUint64(this.view, this.pos, value);\n this.pos += 8;\n }\n writeI64(value) {\n this.ensureBufferSizeToWrite(8);\n setInt64(this.view, this.pos, value);\n this.pos += 8;\n }\n writeBigUint64(value) {\n this.ensureBufferSizeToWrite(8);\n this.view.setBigUint64(this.pos, value);\n this.pos += 8;\n }\n writeBigInt64(value) {\n this.ensureBufferSizeToWrite(8);\n this.view.setBigInt64(this.pos, value);\n this.pos += 8;\n }\n}\n//# sourceMappingURL=Encoder.mjs.map","import { Encoder } from \"./Encoder.mjs\";\n/**\n * It encodes `value` in the MessagePack format and\n * returns a byte buffer.\n *\n * The returned buffer is a slice of a larger `ArrayBuffer`, so you have to use its `#byteOffset` and `#byteLength` in order to convert it to another typed arrays including NodeJS `Buffer`.\n */\nexport function encode(value, options) {\n const encoder = new Encoder(options);\n return encoder.encodeSharedRef(value);\n}\n//# sourceMappingURL=encode.mjs.map","export function prettyByte(byte) {\n return `${byte < 0 ? \"-\" : \"\"}0x${Math.abs(byte).toString(16).padStart(2, \"0\")}`;\n}\n//# sourceMappingURL=prettyByte.mjs.map","import { utf8DecodeJs } from \"./utils/utf8.mjs\";\nconst DEFAULT_MAX_KEY_LENGTH = 16;\nconst DEFAULT_MAX_LENGTH_PER_KEY = 16;\nexport class CachedKeyDecoder {\n hit = 0;\n miss = 0;\n caches;\n maxKeyLength;\n maxLengthPerKey;\n constructor(maxKeyLength = DEFAULT_MAX_KEY_LENGTH, maxLengthPerKey = DEFAULT_MAX_LENGTH_PER_KEY) {\n this.maxKeyLength = maxKeyLength;\n this.maxLengthPerKey = maxLengthPerKey;\n // avoid `new Array(N)`, which makes a sparse array,\n // because a sparse array is typically slower than a non-sparse array.\n this.caches = [];\n for (let i = 0; i < this.maxKeyLength; i++) {\n this.caches.push([]);\n }\n }\n canBeCached(byteLength) {\n return byteLength > 0 && byteLength <= this.maxKeyLength;\n }\n find(bytes, inputOffset, byteLength) {\n const records = this.caches[byteLength - 1];\n FIND_CHUNK: for (const record of records) {\n const recordBytes = record.bytes;\n for (let j = 0; j < byteLength; j++) {\n if (recordBytes[j] !== bytes[inputOffset + j]) {\n continue FIND_CHUNK;\n }\n }\n return record.str;\n }\n return null;\n }\n store(bytes, value) {\n const records = this.caches[bytes.length - 1];\n const record = { bytes, str: value };\n if (records.length >= this.maxLengthPerKey) {\n // `records` are full!\n // Set `record` to an arbitrary position.\n records[(Math.random() * records.length) | 0] = record;\n }\n else {\n records.push(record);\n }\n }\n decode(bytes, inputOffset, byteLength) {\n const cachedValue = this.find(bytes, inputOffset, byteLength);\n if (cachedValue != null) {\n this.hit++;\n return cachedValue;\n }\n this.miss++;\n const str = utf8DecodeJs(bytes, inputOffset, byteLength);\n // Ensure to copy a slice of bytes because the bytes may be a NodeJS Buffer and Buffer#slice() returns a reference to its internal ArrayBuffer.\n const slicedCopyOfBytes = Uint8Array.prototype.slice.call(bytes, inputOffset, inputOffset + byteLength);\n this.store(slicedCopyOfBytes, str);\n return str;\n }\n}\n//# sourceMappingURL=CachedKeyDecoder.mjs.map","import { prettyByte } from \"./utils/prettyByte.mjs\";\nimport { ExtensionCodec } from \"./ExtensionCodec.mjs\";\nimport { getInt64, getUint64, UINT32_MAX } from \"./utils/int.mjs\";\nimport { utf8Decode } from \"./utils/utf8.mjs\";\nimport { ensureUint8Array } from \"./utils/typedArrays.mjs\";\nimport { CachedKeyDecoder } from \"./CachedKeyDecoder.mjs\";\nimport { DecodeError } from \"./DecodeError.mjs\";\nconst STATE_ARRAY = \"array\";\nconst STATE_MAP_KEY = \"map_key\";\nconst STATE_MAP_VALUE = \"map_value\";\nconst mapKeyConverter = (key) => {\n if (typeof key === \"string\" || typeof key === \"number\") {\n return key;\n }\n throw new DecodeError(\"The type of key must be string or number but \" + typeof key);\n};\nclass StackPool {\n stack = [];\n stackHeadPosition = -1;\n get length() {\n return this.stackHeadPosition + 1;\n }\n top() {\n return this.stack[this.stackHeadPosition];\n }\n pushArrayState(size) {\n const state = this.getUninitializedStateFromPool();\n state.type = STATE_ARRAY;\n state.position = 0;\n state.size = size;\n state.array = new Array(size);\n }\n pushMapState(size) {\n const state = this.getUninitializedStateFromPool();\n state.type = STATE_MAP_KEY;\n state.readCount = 0;\n state.size = size;\n state.map = {};\n }\n getUninitializedStateFromPool() {\n this.stackHeadPosition++;\n if (this.stackHeadPosition === this.stack.length) {\n const partialState = {\n type: undefined,\n size: 0,\n array: undefined,\n position: 0,\n readCount: 0,\n map: undefined,\n key: null,\n };\n this.stack.push(partialState);\n }\n return this.stack[this.stackHeadPosition];\n }\n release(state) {\n const topStackState = this.stack[this.stackHeadPosition];\n if (topStackState !== state) {\n throw new Error(\"Invalid stack state. Released state is not on top of the stack.\");\n }\n if (state.type === STATE_ARRAY) {\n const partialState = state;\n partialState.size = 0;\n partialState.array = undefined;\n partialState.position = 0;\n partialState.type = undefined;\n }\n if (state.type === STATE_MAP_KEY || state.type === STATE_MAP_VALUE) {\n const partialState = state;\n partialState.size = 0;\n partialState.map = undefined;\n partialState.readCount = 0;\n partialState.type = undefined;\n }\n this.stackHeadPosition--;\n }\n reset() {\n this.stack.length = 0;\n this.stackHeadPosition = -1;\n }\n}\nconst HEAD_BYTE_REQUIRED = -1;\nconst EMPTY_VIEW = new DataView(new ArrayBuffer(0));\nconst EMPTY_BYTES = new Uint8Array(EMPTY_VIEW.buffer);\ntry {\n // IE11: The spec says it should throw RangeError,\n // IE11: but in IE11 it throws TypeError.\n EMPTY_VIEW.getInt8(0);\n}\ncatch (e) {\n if (!(e instanceof RangeError)) {\n throw new Error(\"This module is not supported in the current JavaScript engine because DataView does not throw RangeError on out-of-bounds access\");\n }\n}\nconst MORE_DATA = new RangeError(\"Insufficient data\");\nconst sharedCachedKeyDecoder = new CachedKeyDecoder();\nexport class Decoder {\n extensionCodec;\n context;\n useBigInt64;\n rawStrings;\n maxStrLength;\n maxBinLength;\n maxArrayLength;\n maxMapLength;\n maxExtLength;\n keyDecoder;\n mapKeyConverter;\n totalPos = 0;\n pos = 0;\n view = EMPTY_VIEW;\n bytes = EMPTY_BYTES;\n headByte = HEAD_BYTE_REQUIRED;\n stack = new StackPool();\n entered = false;\n constructor(options) {\n this.extensionCodec = options?.extensionCodec ?? ExtensionCodec.defaultCodec;\n this.context = options?.context; // needs a type assertion because EncoderOptions has no context property when ContextType is undefined\n this.useBigInt64 = options?.useBigInt64 ?? false;\n this.rawStrings = options?.rawStrings ?? false;\n this.maxStrLength = options?.maxStrLength ?? UINT32_MAX;\n this.maxBinLength = options?.maxBinLength ?? UINT32_MAX;\n this.maxArrayLength = options?.maxArrayLength ?? UINT32_MAX;\n this.maxMapLength = options?.maxMapLength ?? UINT32_MAX;\n this.maxExtLength = options?.maxExtLength ?? UINT32_MAX;\n this.keyDecoder = options?.keyDecoder !== undefined ? options.keyDecoder : sharedCachedKeyDecoder;\n this.mapKeyConverter = options?.mapKeyConverter ?? mapKeyConverter;\n }\n clone() {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n return new Decoder({\n extensionCodec: this.extensionCodec,\n context: this.context,\n useBigInt64: this.useBigInt64,\n rawStrings: this.rawStrings,\n maxStrLength: this.maxStrLength,\n maxBinLength: this.maxBinLength,\n maxArrayLength: this.maxArrayLength,\n maxMapLength: this.maxMapLength,\n maxExtLength: this.maxExtLength,\n keyDecoder: this.keyDecoder,\n });\n }\n reinitializeState() {\n this.totalPos = 0;\n this.headByte = HEAD_BYTE_REQUIRED;\n this.stack.reset();\n // view, bytes, and pos will be re-initialized in setBuffer()\n }\n setBuffer(buffer) {\n const bytes = ensureUint8Array(buffer);\n this.bytes = bytes;\n this.view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n this.pos = 0;\n }\n appendBuffer(buffer) {\n if (this.headByte === HEAD_BYTE_REQUIRED && !this.hasRemaining(1)) {\n this.setBuffer(buffer);\n }\n else {\n const remainingData = this.bytes.subarray(this.pos);\n const newData = ensureUint8Array(buffer);\n // concat remainingData + newData\n const newBuffer = new Uint8Array(remainingData.length + newData.length);\n newBuffer.set(remainingData);\n newBuffer.set(newData, remainingData.length);\n this.setBuffer(newBuffer);\n }\n }\n hasRemaining(size) {\n return this.view.byteLength - this.pos >= size;\n }\n createExtraByteError(posToShow) {\n const { view, pos } = this;\n return new RangeError(`Extra ${view.byteLength - pos} of ${view.byteLength} byte(s) found at buffer[${posToShow}]`);\n }\n /**\n * @throws {@link DecodeError}\n * @throws {@link RangeError}\n */\n decode(buffer) {\n if (this.entered) {\n const instance = this.clone();\n return instance.decode(buffer);\n }\n try {\n this.entered = true;\n this.reinitializeState();\n this.setBuffer(buffer);\n const object = this.doDecodeSync();\n if (this.hasRemaining(1)) {\n throw this.createExtraByteError(this.pos);\n }\n return object;\n }\n finally {\n this.entered = false;\n }\n }\n *decodeMulti(buffer) {\n if (this.entered) {\n const instance = this.clone();\n yield* instance.decodeMulti(buffer);\n return;\n }\n try {\n this.entered = true;\n this.reinitializeState();\n this.setBuffer(buffer);\n while (this.hasRemaining(1)) {\n yield this.doDecodeSync();\n }\n }\n finally {\n this.entered = false;\n }\n }\n async decodeAsync(stream) {\n if (this.entered) {\n const instance = this.clone();\n return instance.decodeAsync(stream);\n }\n try {\n this.entered = true;\n let decoded = false;\n let object;\n for await (const buffer of stream) {\n if (decoded) {\n this.entered = false;\n throw this.createExtraByteError(this.totalPos);\n }\n this.appendBuffer(buffer);\n try {\n object = this.doDecodeSync();\n decoded = true;\n }\n catch (e) {\n if (!(e instanceof RangeError)) {\n throw e; // rethrow\n }\n // fallthrough\n }\n this.totalPos += this.pos;\n }\n if (decoded) {\n if (this.hasRemaining(1)) {\n throw this.createExtraByteError(this.totalPos);\n }\n return object;\n }\n const { headByte, pos, totalPos } = this;\n throw new RangeError(`Insufficient data in parsing ${prettyByte(headByte)} at ${totalPos} (${pos} in the current buffer)`);\n }\n finally {\n this.entered = false;\n }\n }\n decodeArrayStream(stream) {\n return this.decodeMultiAsync(stream, true);\n }\n decodeStream(stream) {\n return this.decodeMultiAsync(stream, false);\n }\n async *decodeMultiAsync(stream, isArray) {\n if (this.entered) {\n const instance = this.clone();\n yield* instance.decodeMultiAsync(stream, isArray);\n return;\n }\n try {\n this.entered = true;\n let isArrayHeaderRequired = isArray;\n let arrayItemsLeft = -1;\n for await (const buffer of stream) {\n if (isArray && arrayItemsLeft === 0) {\n throw this.createExtraByteError(this.totalPos);\n }\n this.appendBuffer(buffer);\n if (isArrayHeaderRequired) {\n arrayItemsLeft = this.readArraySize();\n isArrayHeaderRequired = false;\n this.complete();\n }\n try {\n while (true) {\n yield this.doDecodeSync();\n if (--arrayItemsLeft === 0) {\n break;\n }\n }\n }\n catch (e) {\n if (!(e instanceof RangeError)) {\n throw e; // rethrow\n }\n // fallthrough\n }\n this.totalPos += this.pos;\n }\n }\n finally {\n this.entered = false;\n }\n }\n doDecodeSync() {\n DECODE: while (true) {\n const headByte = this.readHeadByte();\n let object;\n if (headByte >= 0xe0) {\n // negative fixint (111x xxxx) 0xe0 - 0xff\n object = headByte - 0x100;\n }\n else if (headByte < 0xc0) {\n if (headByte < 0x80) {\n // positive fixint (0xxx xxxx) 0x00 - 0x7f\n object = headByte;\n }\n else if (headByte < 0x90) {\n // fixmap (1000 xxxx) 0x80 - 0x8f\n const size = headByte - 0x80;\n if (size !== 0) {\n this.pushMapState(size);\n this.complete();\n continue DECODE;\n }\n else {\n object = {};\n }\n }\n else if (headByte < 0xa0) {\n // fixarray (1001 xxxx) 0x90 - 0x9f\n const size = headByte - 0x90;\n if (size !== 0) {\n this.pushArrayState(size);\n this.complete();\n continue DECODE;\n }\n else {\n object = [];\n }\n }\n else {\n // fixstr (101x xxxx) 0xa0 - 0xbf\n const byteLength = headByte - 0xa0;\n object = this.decodeString(byteLength, 0);\n }\n }\n else if (headByte === 0xc0) {\n // nil\n object = null;\n }\n else if (headByte === 0xc2) {\n // false\n object = false;\n }\n else if (headByte === 0xc3) {\n // true\n object = true;\n }\n else if (headByte === 0xca) {\n // float 32\n object = this.readF32();\n }\n else if (headByte === 0xcb) {\n // float 64\n object = this.readF64();\n }\n else if (headByte === 0xcc) {\n // uint 8\n object = this.readU8();\n }\n else if (headByte === 0xcd) {\n // uint 16\n object = this.readU16();\n }\n else if (headByte === 0xce) {\n // uint 32\n object = this.readU32();\n }\n else if (headByte === 0xcf) {\n // uint 64\n if (this.useBigInt64) {\n object = this.readU64AsBigInt();\n }\n else {\n object = this.readU64();\n }\n }\n else if (headByte === 0xd0) {\n // int 8\n object = this.readI8();\n }\n else if (headByte === 0xd1) {\n // int 16\n object = this.readI16();\n }\n else if (headByte === 0xd2) {\n // int 32\n object = this.readI32();\n }\n else if (headByte === 0xd3) {\n // int 64\n if (this.useBigInt64) {\n object = this.readI64AsBigInt();\n }\n else {\n object = this.readI64();\n }\n }\n else if (headByte === 0xd9) {\n // str 8\n const byteLength = this.lookU8();\n object = this.decodeString(byteLength, 1);\n }\n else if (headByte === 0xda) {\n // str 16\n const byteLength = this.lookU16();\n object = this.decodeString(byteLength, 2);\n }\n else if (headByte === 0xdb) {\n // str 32\n const byteLength = this.lookU32();\n object = this.decodeString(byteLength, 4);\n }\n else if (headByte === 0xdc) {\n // array 16\n const size = this.readU16();\n if (size !== 0) {\n this.pushArrayState(size);\n this.complete();\n continue DECODE;\n }\n else {\n object = [];\n }\n }\n else if (headByte === 0xdd) {\n // array 32\n const size = this.readU32();\n if (size !== 0) {\n this.pushArrayState(size);\n this.complete();\n continue DECODE;\n }\n else {\n object = [];\n }\n }\n else if (headByte === 0xde) {\n // map 16\n const size = this.readU16();\n if (size !== 0) {\n this.pushMapState(size);\n this.complete();\n continue DECODE;\n }\n else {\n object = {};\n }\n }\n else if (headByte === 0xdf) {\n // map 32\n const size = this.readU32();\n if (size !== 0) {\n this.pushMapState(size);\n this.complete();\n continue DECODE;\n }\n else {\n object = {};\n }\n }\n else if (headByte === 0xc4) {\n // bin 8\n const size = this.lookU8();\n object = this.decodeBinary(size, 1);\n }\n else if (headByte === 0xc5) {\n // bin 16\n const size = this.lookU16();\n object = this.decodeBinary(size, 2);\n }\n else if (headByte === 0xc6) {\n // bin 32\n const size = this.lookU32();\n object = this.decodeBinary(size, 4);\n }\n else if (headByte === 0xd4) {\n // fixext 1\n object = this.decodeExtension(1, 0);\n }\n else if (headByte === 0xd5) {\n // fixext 2\n object = this.decodeExtension(2, 0);\n }\n else if (headByte === 0xd6) {\n // fixext 4\n object = this.decodeExtension(4, 0);\n }\n else if (headByte === 0xd7) {\n // fixext 8\n object = this.decodeExtension(8, 0);\n }\n else if (headByte === 0xd8) {\n // fixext 16\n object = this.decodeExtension(16, 0);\n }\n else if (headByte === 0xc7) {\n // ext 8\n const size = this.lookU8();\n object = this.decodeExtension(size, 1);\n }\n else if (headByte === 0xc8) {\n // ext 16\n const size = this.lookU16();\n object = this.decodeExtension(size, 2);\n }\n else if (headByte === 0xc9) {\n // ext 32\n const size = this.lookU32();\n object = this.decodeExtension(size, 4);\n }\n else {\n throw new DecodeError(`Unrecognized type byte: ${prettyByte(headByte)}`);\n }\n this.complete();\n const stack = this.stack;\n while (stack.length > 0) {\n // arrays and maps\n const state = stack.top();\n if (state.type === STATE_ARRAY) {\n state.array[state.position] = object;\n state.position++;\n if (state.position === state.size) {\n object = state.array;\n stack.release(state);\n }\n else {\n continue DECODE;\n }\n }\n else if (state.type === STATE_MAP_KEY) {\n if (object === \"__proto__\") {\n throw new DecodeError(\"The key __proto__ is not allowed\");\n }\n state.key = this.mapKeyConverter(object);\n state.type = STATE_MAP_VALUE;\n continue DECODE;\n }\n else {\n // it must be `state.type === State.MAP_VALUE` here\n state.map[state.key] = object;\n state.readCount++;\n if (state.readCount === state.size) {\n object = state.map;\n stack.release(state);\n }\n else {\n state.key = null;\n state.type = STATE_MAP_KEY;\n continue DECODE;\n }\n }\n }\n return object;\n }\n }\n readHeadByte() {\n if (this.headByte === HEAD_BYTE_REQUIRED) {\n this.headByte = this.readU8();\n // console.log(\"headByte\", prettyByte(this.headByte));\n }\n return this.headByte;\n }\n complete() {\n this.headByte = HEAD_BYTE_REQUIRED;\n }\n readArraySize() {\n const headByte = this.readHeadByte();\n switch (headByte) {\n case 0xdc:\n return this.readU16();\n case 0xdd:\n return this.readU32();\n default: {\n if (headByte < 0xa0) {\n return headByte - 0x90;\n }\n else {\n throw new DecodeError(`Unrecognized array type byte: ${prettyByte(headByte)}`);\n }\n }\n }\n }\n pushMapState(size) {\n if (size > this.maxMapLength) {\n throw new DecodeError(`Max length exceeded: map length (${size}) > maxMapLengthLength (${this.maxMapLength})`);\n }\n this.stack.pushMapState(size);\n }\n pushArrayState(size) {\n if (size > this.maxArrayLength) {\n throw new DecodeError(`Max length exceeded: array length (${size}) > maxArrayLength (${this.maxArrayLength})`);\n }\n this.stack.pushArrayState(size);\n }\n decodeString(byteLength, headerOffset) {\n if (!this.rawStrings || this.stateIsMapKey()) {\n return this.decodeUtf8String(byteLength, headerOffset);\n }\n return this.decodeBinary(byteLength, headerOffset);\n }\n /**\n * @throws {@link RangeError}\n */\n decodeUtf8String(byteLength, headerOffset) {\n if (byteLength > this.maxStrLength) {\n throw new DecodeError(`Max length exceeded: UTF-8 byte length (${byteLength}) > maxStrLength (${this.maxStrLength})`);\n }\n if (this.bytes.byteLength < this.pos + headerOffset + byteLength) {\n throw MORE_DATA;\n }\n const offset = this.pos + headerOffset;\n let object;\n if (this.stateIsMapKey() && this.keyDecoder?.canBeCached(byteLength)) {\n object = this.keyDecoder.decode(this.bytes, offset, byteLength);\n }\n else {\n object = utf8Decode(this.bytes, offset, byteLength);\n }\n this.pos += headerOffset + byteLength;\n return object;\n }\n stateIsMapKey() {\n if (this.stack.length > 0) {\n const state = this.stack.top();\n return state.type === STATE_MAP_KEY;\n }\n return false;\n }\n /**\n * @throws {@link RangeError}\n */\n decodeBinary(byteLength, headOffset) {\n if (byteLength > this.maxBinLength) {\n throw new DecodeError(`Max length exceeded: bin length (${byteLength}) > maxBinLength (${this.maxBinLength})`);\n }\n if (!this.hasRemaining(byteLength + headOffset)) {\n throw MORE_DATA;\n }\n const offset = this.pos + headOffset;\n const object = this.bytes.subarray(offset, offset + byteLength);\n this.pos += headOffset + byteLength;\n return object;\n }\n decodeExtension(size, headOffset) {\n if (size > this.maxExtLength) {\n throw new DecodeError(`Max length exceeded: ext length (${size}) > maxExtLength (${this.maxExtLength})`);\n }\n const extType = this.view.getInt8(this.pos + headOffset);\n const data = this.decodeBinary(size, headOffset + 1 /* extType */);\n return this.extensionCodec.decode(data, extType, this.context);\n }\n lookU8() {\n return this.view.getUint8(this.pos);\n }\n lookU16() {\n return this.view.getUint16(this.pos);\n }\n lookU32() {\n return this.view.getUint32(this.pos);\n }\n readU8() {\n const value = this.view.getUint8(this.pos);\n this.pos++;\n return value;\n }\n readI8() {\n const value = this.view.getInt8(this.pos);\n this.pos++;\n return value;\n }\n readU16() {\n const value = this.view.getUint16(this.pos);\n this.pos += 2;\n return value;\n }\n readI16() {\n const value = this.view.getInt16(this.pos);\n this.pos += 2;\n return value;\n }\n readU32() {\n const value = this.view.getUint32(this.pos);\n this.pos += 4;\n return value;\n }\n readI32() {\n const value = this.view.getInt32(this.pos);\n this.pos += 4;\n return value;\n }\n readU64() {\n const value = getUint64(this.view, this.pos);\n this.pos += 8;\n return value;\n }\n readI64() {\n const value = getInt64(this.view, this.pos);\n this.pos += 8;\n return value;\n }\n readU64AsBigInt() {\n const value = this.view.getBigUint64(this.pos);\n this.pos += 8;\n return value;\n }\n readI64AsBigInt() {\n const value = this.view.getBigInt64(this.pos);\n this.pos += 8;\n return value;\n }\n readF32() {\n const value = this.view.getFloat32(this.pos);\n this.pos += 4;\n return value;\n }\n readF64() {\n const value = this.view.getFloat64(this.pos);\n this.pos += 8;\n return value;\n }\n}\n//# sourceMappingURL=Decoder.mjs.map","import { Decoder } from \"./Decoder.mjs\";\n/**\n * It decodes a single MessagePack object in a buffer.\n *\n * This is a synchronous decoding function.\n * See other variants for asynchronous decoding: {@link decodeAsync}, {@link decodeMultiStream}, or {@link decodeArrayStream}.\n *\n * @throws {@link RangeError} if the buffer is incomplete, including the case where the buffer is empty.\n * @throws {@link DecodeError} if the buffer contains invalid data.\n */\nexport function decode(buffer, options) {\n const decoder = new Decoder(options);\n return decoder.decode(buffer);\n}\n/**\n * It decodes multiple MessagePack objects in a buffer.\n * This is corresponding to {@link decodeMultiStream}.\n *\n * @throws {@link RangeError} if the buffer is incomplete, including the case where the buffer is empty.\n * @throws {@link DecodeError} if the buffer contains invalid data.\n */\nexport function decodeMulti(buffer, options) {\n const decoder = new Decoder(options);\n return decoder.decodeMulti(buffer);\n}\n//# sourceMappingURL=decode.mjs.map","import { encode as mpEncode, decode as mpDecode } from '@msgpack/msgpack'\nimport type { ClientFrame, ServerFrame } from './frames.js'\n\nexport type AnyFrame = ClientFrame | ServerFrame\n\nconst CLIENT_FRAME_TYPES: ReadonlySet<ClientFrame['type']> = new Set([\n 'auth', 'open', 'send', 'sync', 'history', 'read', 'typing', 'react', 'edit', 'delete', 'invoke', 'pubkey', 'ping', 'annotate', 'annotate_clear',\n])\n\n/** True if a decoded frame is one a client is allowed to send. The server uses\n * this to reject server-only frame types before dispatch, so a malicious or\n * buggy client can't reach an unexpected handler path. */\nexport function isClientFrame(frame: AnyFrame): frame is ClientFrame {\n return CLIENT_FRAME_TYPES.has(frame.type as ClientFrame['type'])\n}\n\n/** Encode a frame to a binary msgpack payload for the wire. */\nexport function encodeFrame(frame: AnyFrame): Uint8Array {\n return mpEncode(frame)\n}\n\n/** Decode a binary payload into a frame. Returns null on any malformed input or\n * anything lacking a string `type`, so a bad frame can never crash the handler\n * — the boundary validates `type` before trusting the rest. */\nexport function decodeFrame(bytes: Uint8Array): AnyFrame | null {\n let value: unknown\n try {\n value = mpDecode(bytes)\n } catch {\n return null\n }\n if (typeof value !== 'object' || value === null) return null\n if (typeof (value as { type?: unknown }).type !== 'string') return null\n return value as AnyFrame\n}\n","import type {\n ServerFrame, Message, ManifestAction, MessageContent,\n ConversationId, MessageId, UserId, Subject, AnnotationStroke,\n} from './protocol/index.js'\n\nexport type SendStatus = 'pending' | 'sent' | 'delivered' | 'read'\n\nexport interface RenderMessage extends Message {\n clientMsgId?: string\n status?: SendStatus\n}\n\n/** Pure, DOM-free conversation state. Feed it ServerFrames (and local optimistic\n * sends); read an ordered, de-duplicated view out. Ordering is by `seq`; the\n * same message arriving twice (live + sync on reconnect) is collapsed by id —\n * the structural fix for the old duplicate-bubble bug. */\nexport class ChatStore {\n conversationId?: ConversationId\n state = ''\n version = 0\n hasMoreHistory = false\n lastReadByOthers = 0\n assignedAgentId: UserId | undefined\n accent: string | undefined\n subject: Subject | undefined\n name: string | undefined\n e2e = false\n offline = false\n offlineMessage = ''\n whiteLabel = false\n readonly typing = new Set<string>()\n readonly online = new Set<string>()\n /** Co-browsing: shared whiteboard strokes for this conversation. */\n annotations: AnnotationStroke[] = []\n /** Bumped on any annotation change so the renderer can cheaply detect updates. */\n annotationVersion = 0\n /** Live sentiment of the guest's latest message (agent-side only). */\n sentiment: 'positive' | 'neutral' | 'frustrated' | undefined\n sentimentScore: number | undefined\n\n private actions: ManifestAction[] = []\n private readonly byId = new Map<string, RenderMessage>()\n private readonly keyByClient = new Map<string, string>()\n private _maxSeq = 0\n private _sorted: RenderMessage[] | null = null\n\n constructor(private readonly me: UserId) {}\n\n messages(): RenderMessage[] {\n if (!this._sorted) {\n this._sorted = [...this.byId.values()].sort((a, b) => {\n const ap = a.status === 'pending', bp = b.status === 'pending'\n if (ap !== bp) return ap ? 1 : -1\n if (ap && bp) return a.ts - b.ts\n return a.seq - b.seq\n })\n }\n return this._sorted\n }\n\n visibleActions(): ManifestAction[] {\n return this.actions.filter(a => !a.availableInStates || a.availableInStates.includes(this.state))\n }\n\n highestSeq(): number { return this._maxSeq }\n\n addOptimistic(clientMsgId: string, content: MessageContent): RenderMessage {\n const msg: RenderMessage = {\n id: clientMsgId as MessageId, conversationId: this.conversationId as ConversationId,\n seq: 0, senderId: this.me, senderRole: 'guest', content, ts: Date.now(),\n clientMsgId, status: 'pending',\n }\n this.byId.set(clientMsgId, msg)\n this.keyByClient.set(clientMsgId, clientMsgId)\n this._sorted = null\n return msg\n }\n\n apply(frame: ServerFrame): void {\n switch (frame.type) {\n case 'opened':\n this.conversationId = frame.conversation.id\n this.state = frame.conversation.state\n if (frame.subject) this.subject = frame.subject\n if (frame.annotations) { this.annotations = frame.annotations; this.annotationVersion++ }\n return\n case 'manifest':\n this.actions = frame.actions\n this.version = frame.version\n if (frame.name) this.name = frame.name\n if (frame.theme?.accent) this.accent = frame.theme.accent\n if (frame.e2e) this.e2e = true\n if (frame.offline) this.offline = true\n if (frame.offlineMessage) this.offlineMessage = frame.offlineMessage\n if (frame.whiteLabel) this.whiteLabel = true\n return\n case 'message':\n this.upsert({ ...frame.message })\n return\n case 'ack': {\n const key = this.keyByClient.get(frame.clientMsgId)\n const msg = key ? this.byId.get(key) : undefined\n if (msg && key) {\n this.byId.delete(key)\n const confirmed: RenderMessage = { ...msg, id: frame.messageId, seq: frame.seq, ts: frame.ts, status: 'sent' }\n this.byId.set(frame.messageId, confirmed)\n this.keyByClient.set(frame.clientMsgId, frame.messageId)\n if (frame.seq > this._maxSeq) this._maxSeq = frame.seq\n }\n this._sorted = null\n return\n }\n case 'delivered':\n this.markOwnStatus(frame.seq, 'delivered')\n return\n case 'read':\n if (frame.by !== this.me) {\n this.lastReadByOthers = Math.max(this.lastReadByOthers, frame.seq)\n this.markOwnStatus(frame.seq, 'read')\n }\n return\n case 'sync':\n for (const m of frame.messages) this.upsert({ ...m })\n return\n case 'history':\n for (const m of frame.messages) this.upsert({ ...m })\n this.hasMoreHistory = frame.hasMore\n return\n case 'typing':\n if (frame.userId !== this.me) {\n if (frame.isTyping) this.typing.add(frame.userId)\n else this.typing.delete(frame.userId)\n }\n return\n case 'reaction': {\n const m = this.byId.get(frame.messageId)\n if (!m) return\n const reactions: Record<string, UserId[]> = { ...(m.reactions ?? {}) }\n const users = (reactions[frame.emoji] ?? []).filter(u => u !== frame.by)\n if (!frame.removed) users.push(frame.by)\n if (users.length) reactions[frame.emoji] = users; else delete reactions[frame.emoji]\n this.byId.set(frame.messageId, { ...m, reactions })\n this._sorted = null\n return\n }\n case 'edited': {\n const m = this.byId.get(frame.messageId)\n if (m) { this.byId.set(frame.messageId, { ...m, content: frame.content, editedAt: frame.editedAt }); this._sorted = null }\n return\n }\n case 'deleted': {\n const m = this.byId.get(frame.messageId)\n if (m) { this.byId.set(frame.messageId, { ...m, deletedAt: frame.ts }); this._sorted = null }\n return\n }\n case 'state':\n this.state = frame.state\n return\n case 'assigned':\n this.assignedAgentId = frame.agentId ?? undefined\n return\n case 'presence':\n if (frame.status === 'online') this.online.add(frame.userId)\n else this.online.delete(frame.userId)\n return\n case 'subjectState':\n case 'invoked':\n case 'authed':\n case 'error':\n case 'pong':\n return\n case 'annotation':\n this.annotations = [...this.annotations, frame.stroke]\n this.annotationVersion++\n return\n case 'annotation_clear':\n this.annotations = []\n this.annotationVersion++\n return\n case 'sentiment':\n this.sentiment = frame.label\n this.sentimentScore = frame.score\n return\n default:\n return\n }\n }\n\n private upsert(msg: RenderMessage): void {\n const existing = this.byId.get(msg.id)\n this.byId.set(msg.id, existing ? { ...existing, ...msg } : msg)\n if (msg.seq > this._maxSeq) this._maxSeq = msg.seq\n this._sorted = null\n }\n\n private markOwnStatus(uptoSeq: number, status: SendStatus): void {\n const targetRank = rank(status)\n let changed = false\n for (const [k, m] of this.byId) {\n if (m.senderId !== this.me || m.seq <= 0 || m.seq > uptoSeq) continue\n if (rank(m.status) >= targetRank) continue // already at or above target — skip\n this.byId.set(k, { ...m, status })\n changed = true\n }\n if (changed) this._sorted = null\n }\n}\nfunction rank(s: SendStatus | undefined): number {\n switch (s) { case 'read': return 3; case 'delivered': return 2; case 'sent': return 1; default: return 0 }\n}\n","import {\n encodeFrame, decodeFrame, isClientFrame,\n type ClientFrame, type ServerFrame,\n} from './protocol/index.js'\n\n// Minimal socket surface so tests can inject a fake without a real WebSocket.\nexport interface SocketLike {\n binaryType: string\n send(data: Uint8Array): void\n close(): void\n onopen: (() => void) | null\n onclose: (() => void) | null\n onerror: (() => void) | null\n onmessage: ((ev: { data: ArrayBuffer }) => void) | null\n}\nexport type SocketFactory = (url: string) => SocketLike\n\nexport interface ConnectionOptions {\n url: string\n token: string\n open: ClientFrame // frame sent right after auth (e.g. open a conversation, or subscribe_inbox)\n onFrame: (frame: ServerFrame) => void\n getCursor: () => number // highest seq seen (for sync on reconnect)\n onStatusChange?: (status: 'connecting' | 'open' | 'reconnecting') => void\n socketFactory?: SocketFactory\n backoffBaseMs?: number\n backoffMaxMs?: number\n maxOutbox?: number\n}\n\ntype State = 'idle' | 'connecting' | 'open' | 'closed'\n\nexport class ConnectionManager {\n private socket: SocketLike | null = null\n private state: State = 'idle'\n private authed = false\n private attempt = 0\n private outbox: ClientFrame[] = []\n private stopped = false\n private timer: ReturnType<typeof setTimeout> | null = null\n\n constructor(private readonly opts: ConnectionOptions) {}\n\n connect(): void {\n if (this.state === 'connecting' || this.state === 'open') return\n this.stopped = false\n this.state = 'connecting'\n this.authed = false\n this.opts.onStatusChange?.(this.attempt > 0 ? 'reconnecting' : 'connecting')\n const make = this.opts.socketFactory ?? defaultFactory\n const sock = make(this.opts.url)\n sock.binaryType = 'arraybuffer'\n this.socket = sock\n\n sock.onopen = () => {\n // Don't reset attempt here — reset only after successful auth ('authed').\n // A connection that opens but fails during auth (bad token, server restart)\n // should still back off, not immediately retry at base delay.\n this.raw({ type: 'auth', token: this.opts.token })\n }\n sock.onmessage = (ev) => {\n const frame = decodeFrame(new Uint8Array(ev.data))\n if (!frame || isClientFrame(frame)) return // ignore non-server frames\n this.handle(frame)\n }\n sock.onclose = () => this.onClosed()\n sock.onerror = () => { try { sock.close() } catch { /* */ } }\n }\n\n /** Queue a frame; sent immediately if open, else flushed on (re)connect.\n * The outbox is bounded so a prolonged outage can't grow memory without limit\n * — oldest queued frames are dropped past the cap. */\n send(frame: ClientFrame): void {\n if (this.state === 'open' && this.authed) { this.raw(frame); return }\n const cap = this.opts.maxOutbox ?? 1_000\n if (this.outbox.length >= cap) {\n // Evict oldest half when full to amortise the O(n) cost of overflow.\n this.outbox = this.outbox.slice(this.outbox.length - (cap >> 1))\n }\n this.outbox.push(frame)\n }\n\n close(): void {\n this.stopped = true\n if (this.timer) clearTimeout(this.timer)\n this.state = 'closed'\n try { this.socket?.close() } catch { /* */ }\n }\n\n private handle(frame: ServerFrame): void {\n if (frame.type === 'authed') {\n this.attempt = 0 // reset backoff only after a fully successful auth\n this.state = 'open'\n this.authed = true\n this.opts.onStatusChange?.('open')\n // Open/resolve the conversation. The catch-up `sync` is sent on 'opened'\n // (below), i.e. only after the server has joined us to the room — sending\n // it here would race the async open and be rejected as \"not joined\".\n this.raw(this.opts.open)\n this.flush()\n }\n // 'opened' confirms we're joined — now catch up from our cursor.\n if (frame.type === 'opened') {\n this.raw({ type: 'sync', conversationId: frame.conversation.id, sinceSeq: this.opts.getCursor() })\n }\n this.opts.onFrame(frame)\n }\n\n private flush(): void {\n const pending = this.outbox\n this.outbox = []\n for (const f of pending) this.raw(f)\n }\n\n private raw(frame: ClientFrame): void {\n try { this.socket?.send(encodeFrame(frame)) } catch { this.outbox.push(frame) }\n }\n\n private onClosed(): void {\n this.authed = false\n this.socket = null\n if (this.stopped) { this.state = 'closed'; return }\n this.state = 'idle'\n // Exponential backoff with jitter; reconnect re-auths, re-opens, re-syncs.\n const base = this.opts.backoffBaseMs ?? 500\n const max = this.opts.backoffMaxMs ?? 15_000\n const delay = Math.min(max, base * 2 ** this.attempt) * (0.5 + Math.random() * 0.5)\n this.attempt++\n this.timer = setTimeout(() => this.connect(), delay)\n }\n}\n\nfunction defaultFactory(url: string): SocketLike {\n return new WebSocket(url) as unknown as SocketLike\n}\n","import type { MessageContent } from './protocol/index.js'\n\nexport interface OutboxItem {\n clientMsgId: string\n content: MessageContent\n ts: number\n}\n\nconst MAX_ITEMS = 200 // cap so a long outage can't grow storage unboundedly\nconst MAX_AGE_MS = 7 * 86_400_000 // drop anything older than 7 days on load\n\n/** Persists not-yet-acknowledged outgoing messages to localStorage, keyed by\n * guest token, so a page reload during a connectivity drop doesn't silently\n * lose what the user typed (the \"WhatsApp\" guarantee: your message is queued\n * until it's confirmed sent, even across app restarts). */\nexport class PersistentOutbox {\n private readonly key: string\n\n constructor(token: string) {\n this.key = `ocw_outbox_${token}`\n }\n\n /** All pending items, oldest first, with stale (>7d) entries dropped. */\n load(): OutboxItem[] {\n try {\n const raw = localStorage.getItem(this.key)\n if (!raw) return []\n const items = JSON.parse(raw) as OutboxItem[]\n const cutoff = Date.now() - MAX_AGE_MS\n const fresh = items.filter(i => i.ts >= cutoff)\n if (fresh.length !== items.length) this.save(fresh)\n return fresh\n } catch {\n return []\n }\n }\n\n add(item: OutboxItem): void {\n try {\n const items = this.load()\n items.push(item)\n // Evict oldest when full — matches the in-memory ConnectionManager outbox policy.\n this.save(items.length > MAX_ITEMS ? items.slice(items.length - MAX_ITEMS) : items)\n } catch { /* localStorage unavailable (private mode, quota) — best-effort only */ }\n }\n\n /** Remove an item once it's been acknowledged by the server. */\n remove(clientMsgId: string): void {\n try {\n const items = this.load().filter(i => i.clientMsgId !== clientMsgId)\n this.save(items)\n } catch { /* best-effort */ }\n }\n\n private save(items: OutboxItem[]): void {\n try { localStorage.setItem(this.key, JSON.stringify(items)) } catch { /* quota exceeded — drop silently */ }\n }\n}\n","/**\n * End-to-end encryption primitives (Web Crypto): ECDH P-256 for key agreement\n * + AES-GCM for message content. The server only ever relays public keys and\n * stores ciphertext — it cannot read messages.\n *\n * Scope/limitations (honest): this secures a *live 1:1* session — the guest and\n * one agent exchange public keys while both are connected, then messages between\n * them are encrypted. True asynchronous E2E (encrypting to an offline party)\n * needs a prekey/X3DH scheme, which is out of scope here. When E2E is on, the\n * AI assistant cannot read the room (by design).\n */\n\nconst subtle = (): SubtleCrypto => globalThis.crypto.subtle\n\nfunction b64encode(buf: ArrayBuffer | Uint8Array): string {\n const bytes = buf instanceof Uint8Array ? buf : new Uint8Array(buf)\n let s = ''\n for (const b of bytes) s += String.fromCharCode(b)\n return btoa(s)\n}\nfunction b64decode(s: string): Uint8Array<ArrayBuffer> {\n const bin = atob(s)\n const buf = new ArrayBuffer(bin.length)\n const out = new Uint8Array(buf)\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i)\n return out\n}\n\nexport interface KeyPair { publicKey: CryptoKey; privateKey: CryptoKey }\n\nexport async function generateKeyPair(): Promise<KeyPair> {\n const kp = await subtle().generateKey({ name: 'ECDH', namedCurve: 'P-256' }, true, ['deriveKey', 'deriveBits'])\n return { publicKey: kp.publicKey, privateKey: kp.privateKey }\n}\n\n/** Export a public key to a compact base64 string (raw, 65 bytes for P-256). */\nexport async function exportPublicKey(key: CryptoKey): Promise<string> {\n return b64encode(await subtle().exportKey('raw', key))\n}\n\nasync function importPeerPublicKey(b64: string): Promise<CryptoKey> {\n return subtle().importKey('raw', b64decode(b64), { name: 'ECDH', namedCurve: 'P-256' }, false, [])\n}\n\n/** Derive the shared AES-GCM key from our private key + the peer's public key. */\nexport async function deriveSharedKey(privateKey: CryptoKey, peerPublicKeyB64: string): Promise<CryptoKey> {\n const peer = await importPeerPublicKey(peerPublicKeyB64)\n return subtle().deriveKey(\n { name: 'ECDH', public: peer },\n privateKey,\n { name: 'AES-GCM', length: 256 },\n false,\n ['encrypt', 'decrypt'],\n )\n}\n\nexport interface Ciphertext { ct: string; iv: string }\n\nexport async function encrypt(key: CryptoKey, plaintext: string): Promise<Ciphertext> {\n const iv = globalThis.crypto.getRandomValues(new Uint8Array(12))\n const data = new TextEncoder().encode(plaintext)\n const ct = await subtle().encrypt({ name: 'AES-GCM', iv }, key, data)\n return { ct: b64encode(ct), iv: b64encode(iv) }\n}\n\nexport async function decrypt(key: CryptoKey, ct: string, iv: string): Promise<string> {\n const plain = await subtle().decrypt({ name: 'AES-GCM', iv: b64decode(iv) }, key, b64decode(ct))\n return new TextDecoder().decode(plain)\n}\n\n/** Persist/restore our keypair across reloads (so prior ciphertext stays readable). */\nexport async function loadOrCreateKeyPair(storageKey: string): Promise<KeyPair> {\n try {\n const raw = globalThis.localStorage?.getItem(storageKey)\n if (raw) {\n const { pub, priv } = JSON.parse(raw) as { pub: JsonWebKey; priv: JsonWebKey }\n const publicKey = await subtle().importKey('jwk', pub, { name: 'ECDH', namedCurve: 'P-256' }, true, [])\n const privateKey = await subtle().importKey('jwk', priv, { name: 'ECDH', namedCurve: 'P-256' }, true, ['deriveKey', 'deriveBits'])\n return { publicKey, privateKey }\n }\n } catch { /* fall through to fresh keys */ }\n const kp = await generateKeyPair()\n try {\n const pub = await subtle().exportKey('jwk', kp.publicKey)\n const priv = await subtle().exportKey('jwk', kp.privateKey)\n globalThis.localStorage?.setItem(storageKey, JSON.stringify({ pub, priv }))\n } catch { /* non-persistent environment is fine */ }\n return kp\n}\n\n// ── X3DH async E2E ────────────────────────────────────────────────────────────\n// Extended Triple Diffie-Hellman (X3DH) allows encrypting to an *offline* peer\n// using their published prekey bundle. This enables asynchronous E2E: the sender\n// can encrypt before the recipient connects.\n//\n// Key roles:\n// IK = long-term identity key (ECDH P-256, persistent in localStorage)\n// SPK = signed prekey (ECDH P-256, rotated periodically, server-stored)\n// OPK = one-time prekey (ECDH P-256, single-use pool, server-stored)\n// EK = ephemeral key (ECDH P-256, generated per-message, discarded after)\n//\n// X3DH shared secret = KDF(DH(IK_s, SPK_r) || DH(EK, IK_r) || DH(EK, SPK_r) || DH(EK, OPK_r))\n// Where _s = sender, _r = recipient.\n\n/** Sign a prekey public key bytes using ECDSA P-256 SHA-256.\n * The signingKey must be an ECDSA P-256 private key (not ECDH).\n * In the full X3DH setup the identity key pair contains both an ECDH key\n * (for DH) and an ECDSA key (for signing). We keep them separate here. */\nexport async function signPrekey(signingPrivateKey: CryptoKey, spkPublicKey: CryptoKey): Promise<string> {\n const spkRaw = await subtle().exportKey('raw', spkPublicKey)\n const sig = await subtle().sign({ name: 'ECDSA', hash: 'SHA-256' }, signingPrivateKey, spkRaw)\n return b64encode(sig)\n}\n\n/** Verify an SPK signature. verifyPublicKey must be an ECDSA P-256 public key. */\nexport async function verifyPrekeySignature(verifyPublicKeyB64: string, spkPublicKeyB64: string, signatureB64: string): Promise<boolean> {\n try {\n const verKey = await subtle().importKey('raw', b64decode(verifyPublicKeyB64), { name: 'ECDSA', namedCurve: 'P-256' }, false, ['verify'])\n return await subtle().verify({ name: 'ECDSA', hash: 'SHA-256' }, verKey, b64decode(signatureB64), b64decode(spkPublicKeyB64))\n } catch { return false }\n}\n\n/** A full identity keypair for X3DH: ECDH key for DH computations + ECDSA key\n * for signing prekeys. The two key objects share the same P-256 curve but have\n * different usages, so Web Crypto treats them separately. */\nexport interface IdentityKeyPair {\n ecdhKP: KeyPair // for DH in X3DH\n ecdsaKP: { publicKey: CryptoKey; privateKey: CryptoKey } // for signing SPKs\n /** The ECDH public key exported as base64 — used as the X3DH identity key. */\n publicKeyB64: string\n /** The ECDSA public key exported as base64 — used for SPK signature verification. */\n sigPublicKeyB64: string\n}\n\n/** Generate a full X3DH identity keypair (ECDH + ECDSA on the same P-256 curve). */\nexport async function generateIdentityKeyPair(): Promise<IdentityKeyPair> {\n const ecdhKP = await generateKeyPair()\n const ecdsaKP = await subtle().generateKey({ name: 'ECDSA', namedCurve: 'P-256' }, true, ['sign', 'verify'])\n return {\n ecdhKP,\n ecdsaKP: { publicKey: ecdsaKP.publicKey, privateKey: ecdsaKP.privateKey },\n publicKeyB64: await exportPublicKey(ecdhKP.publicKey),\n sigPublicKeyB64: await exportPublicKey(ecdsaKP.publicKey),\n }\n}\n\n/** Load or generate an identity keypair, persisting both components. */\nexport async function loadOrCreateIdentityKeyPair(storageKey: string): Promise<IdentityKeyPair> {\n try {\n const raw = globalThis.localStorage?.getItem(`${storageKey}-identity`)\n if (raw) {\n const d = JSON.parse(raw) as { ecdhPub: JsonWebKey; ecdhPriv: JsonWebKey; ecdsaPub: JsonWebKey; ecdsaPriv: JsonWebKey }\n const ecdhPub = await subtle().importKey('jwk', d.ecdhPub, { name: 'ECDH', namedCurve: 'P-256' }, true, [])\n const ecdhPriv = await subtle().importKey('jwk', d.ecdhPriv, { name: 'ECDH', namedCurve: 'P-256' }, true, ['deriveKey', 'deriveBits'])\n const ecdsaPub = await subtle().importKey('jwk', d.ecdsaPub, { name: 'ECDSA', namedCurve: 'P-256' }, true, ['verify'])\n const ecdsaPriv = await subtle().importKey('jwk', d.ecdsaPriv, { name: 'ECDSA', namedCurve: 'P-256' }, true, ['sign'])\n return {\n ecdhKP: { publicKey: ecdhPub, privateKey: ecdhPriv },\n ecdsaKP: { publicKey: ecdsaPub, privateKey: ecdsaPriv },\n publicKeyB64: await exportPublicKey(ecdhPub),\n sigPublicKeyB64: await exportPublicKey(ecdsaPub),\n }\n }\n } catch { /* generate fresh */ }\n const ikp = await generateIdentityKeyPair()\n try {\n const ecdhPub = await subtle().exportKey('jwk', ikp.ecdhKP.publicKey)\n const ecdhPriv = await subtle().exportKey('jwk', ikp.ecdhKP.privateKey)\n const ecdsaPub = await subtle().exportKey('jwk', ikp.ecdsaKP.publicKey)\n const ecdsaPriv = await subtle().exportKey('jwk', ikp.ecdsaKP.privateKey)\n globalThis.localStorage?.setItem(`${storageKey}-identity`, JSON.stringify({ ecdhPub, ecdhPriv, ecdsaPub, ecdsaPriv }))\n } catch { /* non-persistent ok */ }\n return ikp\n}\n\nexport interface X3DHBundle {\n identityKey: string // base64 raw P-256 public key\n signedPrekey: string // base64 raw P-256 public key\n signedPrekeyId: string // opaque ID for key rotation tracking\n signature: string // base64 ECDSA signature of SPK by IK\n oneTimePrekey?: string // base64 raw P-256 public key (optional)\n}\n\n/** X3DH sender side: derive a shared key from the recipient's prekey bundle.\n * Returns the shared AES-GCM key and the ephemeral public key to transmit. */\nexport async function x3dhSend(\n senderIK: KeyPair,\n recipientBundle: X3DHBundle,\n): Promise<{ sharedKey: CryptoKey; ephemeralPublicKey: string }> {\n const ek = await generateKeyPair()\n const epkB64 = await exportPublicKey(ek.publicKey)\n\n // Import recipient keys for DH.\n const ik_r = await importPeerPublicKey(recipientBundle.identityKey)\n const spk_r = await importPeerPublicKey(recipientBundle.signedPrekey)\n const opk_r = recipientBundle.oneTimePrekey ? await importPeerPublicKey(recipientBundle.oneTimePrekey) : null\n\n // Four DH computations per spec (three if no OPK).\n const dh1 = await rawDH(senderIK.privateKey, spk_r) // DH(IK_s, SPK_r)\n const dh2 = await rawDH(ek.privateKey, ik_r) // DH(EK, IK_r)\n const dh3 = await rawDH(ek.privateKey, spk_r) // DH(EK, SPK_r)\n const dh4 = opk_r ? await rawDH(ek.privateKey, opk_r) : null // DH(EK, OPK_r)\n\n const ikm = concatBuffers(dh1, dh2, dh3, ...(dh4 ? [dh4] : []))\n const sharedKey = await hkdfDeriveKey(ikm)\n\n return { sharedKey, ephemeralPublicKey: epkB64 }\n}\n\n/** X3DH recipient side: rederive the shared key from an init message.\n * Returns the shared AES-GCM key. */\nexport async function x3dhReceive(\n recipientIK: KeyPair,\n recipientSPK: KeyPair,\n senderIKb64: string,\n ephemeralKeyB64: string,\n recipientOPK?: KeyPair,\n): Promise<CryptoKey> {\n const ik_s = await importPeerPublicKey(senderIKb64)\n const ek_s = await importPeerPublicKey(ephemeralKeyB64)\n\n const dh1 = await rawDH(recipientSPK.privateKey, ik_s) // DH(SPK_r, IK_s)\n const dh2 = await rawDH(recipientIK.privateKey, ek_s) // DH(IK_r, EK)\n const dh3 = await rawDH(recipientSPK.privateKey, ek_s) // DH(SPK_r, EK)\n const dh4 = recipientOPK ? await rawDH(recipientOPK.privateKey, ek_s) : null\n\n const ikm = concatBuffers(dh1, dh2, dh3, ...(dh4 ? [dh4] : []))\n return hkdfDeriveKey(ikm)\n}\n\nasync function rawDH(privateKey: CryptoKey, publicKey: CryptoKey): Promise<ArrayBuffer> {\n return subtle().deriveBits({ name: 'ECDH', public: publicKey }, privateKey, 256)\n}\n\nfunction concatBuffers(...bufs: ArrayBuffer[]): ArrayBuffer {\n const total = bufs.reduce((n, b) => n + b.byteLength, 0)\n const out = new Uint8Array(total)\n let offset = 0\n for (const b of bufs) { out.set(new Uint8Array(b), offset); offset += b.byteLength }\n return out.buffer\n}\n\nasync function hkdfDeriveKey(ikm: ArrayBuffer): Promise<CryptoKey> {\n const ikmKey = await subtle().importKey('raw', ikm, 'HKDF', false, ['deriveKey'])\n return subtle().deriveKey(\n { name: 'HKDF', hash: 'SHA-256', salt: new Uint8Array(32), info: new TextEncoder().encode('ObjectChat X3DH v1') },\n ikmKey,\n { name: 'AES-GCM', length: 256 },\n false,\n ['encrypt', 'decrypt'],\n )\n}\n","import type { MessageContent, UserId } from './protocol/index.js'\nimport type { ServerFrame } from './protocol/index.js'\nimport {\n type KeyPair, loadOrCreateKeyPair, exportPublicKey, deriveSharedKey, encrypt, decrypt,\n generateKeyPair, signPrekey, x3dhSend, x3dhReceive, type X3DHBundle,\n loadOrCreateIdentityKeyPair, type IdentityKeyPair,\n} from './crypto.js'\n\n// Number of one-time prekeys to generate per upload batch.\nconst OTP_BATCH_SIZE = 20\n\n/**\n * Per-user E2E session. Supports two modes:\n *\n * LIVE (original): Both parties are online. ECDH P-256 key exchange via the\n * `pubkey`/`peerkey` frames. Instant but requires both parties to be connected.\n *\n * ASYNC (X3DH): The sender encrypts to the recipient's prekey bundle while the\n * recipient is offline. Uses X3DH (Extended Triple DH) with identity keys,\n * signed prekeys, and one-time prekeys. The recipient derives the same shared\n * key from the init message when they come online.\n *\n * Both modes produce an AES-GCM 256 shared key for message encryption.\n */\nexport class E2ESession {\n // Live ECDH mode state\n private kp?: KeyPair\n private shared?: CryptoKey\n\n // X3DH async mode state\n private identityKP: IdentityKeyPair | undefined = undefined\n private signedPreKP: KeyPair | undefined = undefined\n private signedPrekeyId: string | undefined = undefined\n private readonly otpKeys: KeyPair[] = [] // one-time prekeys awaiting matching\n private x3dhShared?: CryptoKey\n // Queued init messages arriving before we could derive (shouldn't happen, but safe)\n private pendingX3DH: { senderIK: string; ephemeralKey: string; spkId: string } | undefined = undefined\n\n constructor(private readonly storageKey: string) {}\n\n get ready(): boolean { return !!(this.shared ?? this.x3dhShared) }\n\n /** Live ECDH mode: Generate/restore our keypair and return our public key to publish. */\n async begin(): Promise<string> {\n this.kp = await loadOrCreateKeyPair(this.storageKey)\n return exportPublicKey(this.kp.publicKey)\n }\n\n /** Live ECDH mode: A peer published their key — derive the shared secret. */\n async onPeerKey(peerKeyB64: string): Promise<void> {\n if (!this.kp) return\n this.shared = await deriveSharedKey(this.kp.privateKey, peerKeyB64)\n }\n\n // ── X3DH async mode ────────────────────────────────────────────────────────\n\n /** X3DH: Generate identity key, signed prekey, and OTP prekeys.\n * Returns the upload frame payload the caller should send to the server. */\n async initX3DH(): Promise<{\n identityKey: string; signedPrekey: string; signedPrekeyId: string;\n signature: string; oneTimePrekeys: string[]\n }> {\n // Restore or generate persistent identity keypair (ECDH + ECDSA).\n this.identityKP = await loadOrCreateIdentityKeyPair(this.storageKey)\n // Always generate a fresh signed prekey (rotation).\n this.signedPreKP = await generateKeyPair()\n this.signedPrekeyId = `spk-${Date.now()}-${Math.random().toString(36).slice(2)}`\n // Batch of one-time prekeys.\n for (let i = 0; i < OTP_BATCH_SIZE; i++) this.otpKeys.push(await generateKeyPair())\n\n const signedPrekeyPub = await exportPublicKey(this.signedPreKP.publicKey)\n const signature = await signPrekey(this.identityKP.ecdsaKP.privateKey, this.signedPreKP.publicKey)\n const oneTimePrekeys = await Promise.all(this.otpKeys.map(kp => exportPublicKey(kp.publicKey)))\n\n return {\n identityKey: this.identityKP.publicKeyB64,\n signedPrekey: signedPrekeyPub,\n signedPrekeyId: this.signedPrekeyId,\n signature,\n oneTimePrekeys,\n }\n }\n\n /** X3DH sender: given a recipient's prekey bundle, derive the shared key and\n * return the init message fields to embed in the first encrypted message. */\n async x3dhSendTo(bundle: X3DHBundle): Promise<{ ephemeralKey: string; spkId: string; usedOTP: boolean; senderIK: string }> {\n if (!this.identityKP) this.identityKP = await loadOrCreateIdentityKeyPair(this.storageKey)\n const { sharedKey, ephemeralPublicKey } = await x3dhSend(this.identityKP.ecdhKP, bundle)\n this.x3dhShared = sharedKey\n return { ephemeralKey: ephemeralPublicKey, spkId: bundle.signedPrekeyId, usedOTP: !!bundle.oneTimePrekey, senderIK: this.identityKP.publicKeyB64 }\n }\n\n /** X3DH recipient: given an init message's sender IK + EK + SPK ID, derive the shared key. */\n async x3dhReceiveFrom(senderIKb64: string, ephemeralKeyB64: string, spkId: string): Promise<void> {\n if (!this.identityKP || !this.signedPreKP) {\n // Keys not yet initialised — queue for when initX3DH completes.\n this.pendingX3DH = { senderIK: senderIKb64, ephemeralKey: ephemeralKeyB64, spkId }\n return\n }\n // Find OTP key if used (we pop the first available)\n const otp = this.otpKeys.shift()\n this.x3dhShared = await x3dhReceive(this.identityKP.ecdhKP, this.signedPreKP, senderIKb64, ephemeralKeyB64, otp)\n void spkId // we matched by position; full impl would look up by ID\n }\n\n /** Flush pending X3DH derivation after initX3DH() completes. */\n async flushPendingX3DH(): Promise<void> {\n if (!this.pendingX3DH) return\n const { senderIK, ephemeralKey, spkId } = this.pendingX3DH\n this.pendingX3DH = undefined\n await this.x3dhReceiveFrom(senderIK, ephemeralKey, spkId)\n }\n\n /** Encrypt outgoing text into a wire content object. For X3DH init messages,\n * the caller should pass x3dhInit fields to embed in the content. */\n async sealText(text: string, x3dhInit?: { ephemeralKey: string; spkId: string; senderIK: string }): Promise<MessageContent> {\n const key = this.x3dhShared ?? this.shared\n if (!key) throw new Error('secure channel not ready')\n const { ct, iv } = await encrypt(key, text)\n return {\n kind: 'text', text: ct, enc: true, iv,\n ...(x3dhInit ? { x3dhEK: x3dhInit.ephemeralKey, x3dhSPK: x3dhInit.spkId, x3dhIK: x3dhInit.senderIK } as never : {}),\n }\n }\n\n /** Decrypt one content object if it is encrypted (otherwise pass through). */\n private async openContent(content: MessageContent): Promise<MessageContent> {\n if (content.kind !== 'text' || !content.enc || !content.iv) return content\n const key = this.x3dhShared ?? this.shared\n if (!key) return { kind: 'text', text: '🔒 encrypted' }\n try { return { kind: 'text', text: await decrypt(key, content.text, content.iv) } }\n catch { return { kind: 'text', text: '🔒 unable to decrypt' } }\n }\n\n /** Decrypt any encrypted message content carried by an incoming frame, in place. */\n async openFrame(frame: ServerFrame): Promise<void> {\n if (frame.type === 'message') frame.message.content = await this.openContent(frame.message.content)\n else if (frame.type === 'sync') {\n for (const m of frame.messages) m.content = await this.openContent(m.content)\n }\n }\n}\n\n/** X3DH init fields embedded in a text MessageContent (as extra properties).\n * Present only on the very first message from a sender to an offline peer. */\nexport interface X3DHInitFields {\n x3dhEK: string // sender's ephemeral public key (base64)\n x3dhSPK: string // recipient's signed prekey ID used\n x3dhIK: string // sender's identity public key (base64)\n}\n\nexport function extractX3DHInit(content: MessageContent): X3DHInitFields | null {\n if (content.kind !== 'text' || !content.enc) return null\n const c = content as MessageContent & Partial<X3DHInitFields>\n if (!c.x3dhEK || !c.x3dhSPK || !c.x3dhIK) return null\n return { x3dhEK: c.x3dhEK, x3dhSPK: c.x3dhSPK, x3dhIK: c.x3dhIK }\n}\n\nexport { type X3DHBundle } from './crypto.js'\nexport { type UserId }\n\n","import type { ManifestAction, MessageContent, AnnotationStroke } from './protocol/index.js'\nimport type { ChatStore, RenderMessage } from './store.js'\n\nexport interface WidgetConfig {\n subject?: { title?: string; subtitle?: string; tags?: string[]; status?: string; ownerLabel?: string }\n quickReplies?: string[]\n accent?: string\n /** Identified user info — shown as the guest avatar/name in the widget header. */\n userInfo?: { name?: string; avatar?: string }\n /** i18n string overrides */\n i18n?: { placeholder?: string; send?: string; offline?: string; poweredBy?: string }\n\n}\n\nexport interface RendererHandlers {\n onSend(text: string): void\n onAttach?(file: File): void\n onInvoke(actionId: string, inputs?: Record<string, unknown>): void\n onTyping(isTyping: boolean, preview?: string): void\n onReadUpTo(seq: number): void\n onReact?(messageId: string, emoji: string, remove: boolean): void\n onCsat?(score: number): void\n onLoadMore?(): void\n onEdit?(messageId: string, newText: string): void\n onDelete?(messageId: string): void\n /** Co-browsing: a freehand stroke was completed on the shared whiteboard. */\n onAnnotate?(stroke: Omit<AnnotationStroke, 'by'>): void\n /** Co-browsing: clear the shared whiteboard for everyone. */\n onAnnotateClear?(): void\n /** Translate a message's text for display. Return null if unavailable —\n * the renderer shows a brief \"unavailable\" hint and leaves the original. */\n onTranslate?(text: string): Promise<string | null>\n /** Multi-subject chat list (e.g. a marketplace with one thread per item):\n * fetch the guest's other conversations. Omit to hide the list button\n * entirely — single-conversation embeds don't need this. */\n /** Switch the active conversation to a different one from the list —\n * effectively a re-open with a different subjectId. */\n}\n\nconst STYLE_ID = 'objectchat-widget-styles'\nconst REACTION_EMOJIS = ['👍', '❤️', '😂', '😮', '😢', '🙏']\nconst CSS = `\n.ocw { --ocw-accent:#4F63F5; --ocw-bg:#f3efe9; --ocw-card:#fff; --ocw-line:#ececec; --ocw-ink:#1c1b1a; --ocw-mut:#9b9690;\n position:relative;\n display:flex; flex-direction:column; height:100%; min-height:320px; background:var(--ocw-bg);\n font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif; color:var(--ocw-ink); overflow:hidden; }\n@media (max-width:480px) {\n .ocw { min-height:100dvh; border-radius:0 !important; }\n .ocw-bubble { font-size:15px; }\n .ocw-input textarea { font-size:16px; } /* prevent iOS zoom on focus */\n .ocw-chip { padding:9px 14px; font-size:14px; }\n .ocw-modal-card { width:90%; }\n .ocw-row { max-width:94%; }\n}\n/* RTL support: when the host element has dir=rtl, flip layout direction */\n[dir=\"rtl\"] .ocw-row.mine { flex-direction:row; }\n[dir=\"rtl\"] .ocw-row.theirs { flex-direction:row-reverse; }\n[dir=\"rtl\"] .mine .ocw-bubble { border-bottom-right-radius:18px; border-bottom-left-radius:6px; }\n[dir=\"rtl\"] .theirs .ocw-bubble { border-bottom-left-radius:18px; border-bottom-right-radius:6px; }\n[dir=\"rtl\"] .ocw-input { flex-direction:row-reverse; }\n[dir=\"rtl\"] .mine .ocw-meta { text-align:left; }\n.ocw-head { display:flex; align-items:center; gap:10px; padding:12px 14px; background:var(--ocw-card); border-bottom:1px solid var(--ocw-line); }\n.ocw-avatar { width:34px; height:34px; border-radius:50%; background:#ffe9d6; display:flex; align-items:center; justify-content:center; font-size:17px; flex:none; }\n.ocw-head-main { flex:1; min-width:0; }\n.ocw-head-name { font-weight:700; font-size:15px; }\n.ocw-head-meta { color:var(--ocw-mut); font-size:12px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }\n.ocw-badge { font-size:12px; font-weight:600; color:#15803d; background:#e8f6ec; border-radius:999px; padding:3px 10px; }\n.ocw-e2e { font-size:11px; font-weight:700; color:#3730a3; background:#eef2ff; border-radius:999px; padding:3px 9px; align-items:center; }\n.ocw-menu { color:var(--ocw-mut); width:30px; height:30px; border-radius:50%; border:1px solid var(--ocw-line); background:#fff; cursor:pointer; }\n.ocw-chiprow { display:flex; gap:8px; padding:10px 12px; background:var(--ocw-card); border-bottom:1px solid var(--ocw-line); overflow-x:auto; }\n.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; }\n.ocw-chip:hover { border-color:var(--ocw-accent); color:var(--ocw-accent); }\n.ocw-scroll { flex:1; min-height:0; overflow-y:auto; padding:16px 14px; display:flex; flex-direction:column; gap:10px; }\n.ocw-subject { background:var(--ocw-card); border:1px solid var(--ocw-line); border-radius:16px; padding:14px 16px; }\n.ocw-subject-title { font-weight:700; font-size:16px; margin-bottom:2px; }\n.ocw-subject-sub { color:var(--ocw-mut); font-size:13px; margin-bottom:10px; }\n.ocw-tags { display:flex; flex-wrap:wrap; gap:6px; }\n.ocw-tag { font-size:12px; color:#5b554e; background:#efeae3; border-radius:8px; padding:4px 10px; }\n.ocw-row { display:flex; align-items:flex-end; gap:8px; max-width:86%; }\n.ocw-row.mine { align-self:flex-end; flex-direction:row-reverse; }\n.ocw-row.theirs { align-self:flex-start; }\n.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; }\n.ocw-bubble { padding:10px 14px; border-radius:18px; font-size:14.5px; line-height:1.4; word-wrap:break-word; }\n.theirs .ocw-bubble { background:#fff; border:1px solid var(--ocw-line); border-bottom-left-radius:6px; }\n.mine .ocw-bubble { background:var(--ocw-accent); color:#fff; border-bottom-right-radius:6px; }\n.ocw-sys { align-self:center; color:var(--ocw-mut); font-size:12.5px; font-style:italic; text-align:center; max-width:90%; }\n.ocw-bot .ocw-bubble { background:#f0fdf4; border-color:#cdebd6; }\n.ocw-note .ocw-bubble { background:#fffbeb; border:1.5px dashed #f59e0b; color:#78350f; border-radius:12px !important; }\n.ocw-note .ocw-bubble::before { content:'🔒 Note — '; font-size:11px; font-weight:700; color:#b45309; display:block; margin-bottom:3px; letter-spacing:.3px; }\n.ocw-time { font-size:10.5px; color:var(--ocw-mut); margin-top:3px; }\n.mine .ocw-meta { text-align:right; }\n.ocw-tick { margin-left:4px; font-size:11px; color:var(--ocw-mut); }\n.ocw-tick.read { color:#3b82f6; }\n.ocw-tick.delivered { color:var(--ocw-mut); }\n.ocw-deleted { font-style:italic; color:var(--ocw-mut); }\n.ocw-edited { font-size:10px; color:var(--ocw-mut); margin-left:4px; }\n.ocw-react { font-size:12px; margin-top:3px; display:flex; flex-wrap:wrap; gap:3px; }\n.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; }\n.ocw-react-pill:hover { border-color:var(--ocw-accent); }\n.ocw-react-pill.mine { border-color:var(--ocw-accent); background:#fff8f5; }\n.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; }\n.ocw-react-wrap { position:relative; }\n.ocw-react-wrap:not(:hover) .ocw-react-picker { display:none; }\n.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; }\n.ocw-react-picker button { background:none; border:none; font-size:16px; cursor:pointer; padding:2px; border-radius:6px; }\n.ocw-react-picker button:hover { background:#f3efe9; }\n.ocw-react-btn { background:none; border:1px solid #e3ded7; border-radius:999px; padding:2px 7px; font-size:12px; cursor:pointer; color:var(--ocw-mut); }\n.ocw-react-btn:hover { border-color:var(--ocw-accent); color:var(--ocw-accent); }\n.ocw-msg-menu { position:absolute; top:0; right:0; display:none; gap:3px; }\n.ocw-row.mine:hover .ocw-msg-menu { display:flex; }\n.ocw-row.theirs:hover .ocw-msg-menu { display:flex; left:0; right:auto; }\n.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); }\n.ocw-msg-menu button:hover { border-color:var(--ocw-accent); color:var(--ocw-accent); }\n.ocw-msg-menu button.del:hover { border-color:#e74c3c; color:#e74c3c; }\n.ocw-bubble-wrap { position:relative; }\n.ocw-seen { font-size:10.5px; color:var(--ocw-mut); }\n.ocw-appt { background:#f0f7ff; border:1px solid #c7deff; border-radius:12px; padding:12px 14px; max-width:260px; }\n.ocw-appt-title { font-weight:700; font-size:14px; margin-bottom:4px; }\n.ocw-appt-time { font-size:12px; color:#1d4ed8; margin-bottom:4px; }\n.ocw-appt-loc { font-size:12px; color:var(--ocw-mut); margin-bottom:4px; }\n.ocw-appt-desc { font-size:12px; color:var(--ocw-mut); margin-bottom:10px; white-space:pre-wrap; }\n.ocw-appt-links { display:flex; flex-direction:column; gap:6px; }\n.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; }\n.ocw-appt-btn-sec { background:#fff; color:var(--ocw-accent); border:1px solid var(--ocw-accent); }\n.ocw-conn-status { font-size:10px; color:var(--ocw-mut); margin-left:4px; }\n.ocw-conn-status.warn { color:#e67e22; }\n.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; }\n.ocw-load-more:hover { border-color:var(--ocw-accent); color:var(--ocw-accent); }\n.ocw-offline { margin:20px 14px; padding:20px; background:#fff; border:1px solid #e3ded7; border-radius:16px; text-align:center; }\n.ocw-offline-icon { font-size:32px; margin-bottom:8px; }\n.ocw-offline-title { font-weight:700; font-size:16px; margin-bottom:6px; }\n.ocw-offline-msg { font-size:13px; color:var(--ocw-mut); margin-bottom:16px; }\n.ocw-offline-form { display:flex; flex-direction:column; gap:8px; text-align:left; }\n.ocw-offline-input { border:1px solid #e3ded7; border-radius:10px; padding:10px 12px; font-size:13px; font-family:inherit; }\n.ocw-offline-input:focus { outline:none; border-color:var(--ocw-accent); }\n.ocw-offline-submit { background:var(--ocw-accent); color:#fff; border:none; border-radius:10px; padding:11px; font-size:14px; font-weight:600; cursor:pointer; }\n.ocw-offline-thanks { font-size:14px; color:#15803d; font-weight:600; }\n.ocw-csat-title { font-size:13px; font-weight:600; margin-bottom:8px; }\n.ocw-csat-stars { display:flex; gap:6px; }\n.ocw-csat-star { background:none; border:none; font-size:22px; cursor:pointer; padding:2px; opacity:.4; transition:opacity .15s; }\n.ocw-csat-star:hover, .ocw-csat-star.lit { opacity:1; }\n.ocw-csat-done { font-size:12px; color:var(--ocw-mut); margin-top:6px; }\n\n.ocw-typing { min-height:22px; padding:0 16px 4px; display:flex; align-items:center; }\n.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; }\n.ocw-typing.active .ocw-typing-bubble { display:flex; }\n.ocw-typing-dot { width:6px; height:6px; border-radius:50%; background:var(--ocw-mut); animation:ocw-bounce 1.2s infinite ease-in-out; }\n.ocw-typing-dot:nth-child(2) { animation-delay:.2s; }\n.ocw-typing-dot:nth-child(3) { animation-delay:.4s; }\n@keyframes ocw-bounce { 0%,60%,100%{transform:translateY(0)} 30%{transform:translateY(-5px)} }\n.ocw-quick { display:flex; gap:8px; padding:8px 12px 6px; overflow-x:auto; scrollbar-width:none; flex-shrink:0; }\n.ocw-quick::-webkit-scrollbar { display:none; }\n.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; }\n.ocw-quick button:hover { border-color:var(--ocw-accent); color:var(--ocw-accent); }\n.ocw-form-host:empty { display:none; }\n.ocw-form { margin:6px 12px 0; padding:12px; background:var(--ocw-card); border:1px solid var(--ocw-line); border-radius:14px; }\n.ocw-form-title { font-weight:700; font-size:14px; margin-bottom:8px; }\n.ocw-form-row { display:flex; flex-direction:column; gap:3px; margin-bottom:8px; }\n.ocw-form-lbl { font-size:12px; color:var(--ocw-mut); }\n.ocw-form-input { border:1px solid #e3ded7; border-radius:9px; padding:9px 11px; font:inherit; font-size:14px; outline:none; }\n.ocw-form-input:focus { border-color:var(--ocw-accent); }\n.ocw-form-actions { display:flex; justify-content:flex-end; gap:8px; margin-top:4px; }\n.ocw-form-cancel { background:none; border:none; color:var(--ocw-mut); font-size:13px; cursor:pointer; padding:8px 10px; }\n.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; }\n.ocw-modal { position:absolute; inset:0; background:rgba(20,18,16,.42); display:flex; align-items:center; justify-content:center; z-index:50; }\n.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); }\n.ocw-modal-title { font-weight:700; font-size:16px; margin-bottom:6px; }\n.ocw-modal-body { color:var(--ocw-mut); font-size:14px; margin-bottom:16px; }\n.ocw-modal-actions { display:flex; justify-content:flex-end; gap:8px; }\n.ocw-modal-cancel { background:none; border:none; color:var(--ocw-mut); font-size:14px; cursor:pointer; padding:9px 12px; }\n.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; }\n.ocw-input { display:flex; align-items:center; gap:10px; padding:12px; }\n.ocw-footer { text-align:center; font-size:11px; color:var(--ocw-mut); padding:6px 0 8px; }\n.ocw-footer a { color:var(--ocw-mut); text-decoration:none; font-weight:600; }\n.ocw-footer a:hover { color:var(--ocw-accent); }\n.ocw-attach { background:none;border:none;cursor:pointer;font-size:18px;padding:4px 6px;opacity:.6;flex-none; }\n.ocw-attach:hover { opacity:1; }\n.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; }\n.ocw-input textarea:focus { border-color:var(--ocw-accent); }\n.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; }\n.ocw-sendbtn:disabled { opacity:.5; cursor:default; }\n.ocw-cobrowse-btn { display:none; }\n.ocw-cobrowse-btn.show { display:inline-flex; }\n.ocw-cobrowse-btn.on { color:var(--ocw-accent); border-color:var(--ocw-accent); }\n.ocw-cobrowse-canvas { position:absolute; inset:0; z-index:40; touch-action:none; display:none; }\n.ocw-cobrowse-canvas.active { display:block; cursor:crosshair; }\n.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); }\n.ocw-cobrowse-toolbar.active { display:flex; align-items:center; }\n.ocw-cobrowse-swatch { width:18px; height:18px; border-radius:50%; border:2px solid transparent; cursor:pointer; padding:0; }\n.ocw-cobrowse-swatch.sel { border-color:#1c1b1a; }\n.ocw-cobrowse-clear { background:none; border:1px solid #e3ded7; border-radius:999px; font-size:11px; padding:3px 8px; cursor:pointer; color:var(--ocw-mut); }\n.ocw-cobrowse-clear:hover { border-color:#e74c3c; color:#e74c3c; }\n.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; }\n.ocw-cobrowse-hint.active { display:block; }\n\n.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; }\n.ocw-row.theirs .ocw-translate-btn { right:auto; left:-26px; }\n.ocw-bubble-wrap:hover .ocw-translate-btn { opacity:1; }\n.ocw-translated-tag { font-size:10px; color:var(--ocw-mut); margin-top:2px; }\n`\n\nfunction injectStyles(): void {\n if (typeof document === 'undefined' || document.getElementById(STYLE_ID)) return\n const s = document.createElement('style'); s.id = STYLE_ID; s.textContent = CSS; document.head.appendChild(s)\n}\n\nfunction el<K extends keyof HTMLElementTagNameMap>(tag: K, cls?: string, text?: string): HTMLElementTagNameMap[K] {\n const n = document.createElement(tag); if (cls) n.className = cls; if (text !== undefined) n.textContent = text; return n\n}\nfunction fmtTime(ts: number): string {\n try { return new Date(ts).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) } catch { return '' }\n}\nfunction contentText(c: MessageContent): string {\n switch (c.kind) {\n case 'text': return c.text\n case 'system': return typeof c.data?.['message'] === 'string' ? String(c.data['message']) : c.event\n case 'card': return [c.title, c.body].filter(Boolean).join(' — ')\n case 'attachment': return c.name ?? c.url\n case 'form': return c.prompt\n case 'appointment': return `📅 ${c.title} — ${new Date(c.startIso).toLocaleString()}`\n }\n}\n\n/** Renders a ChatStore into a host element in the Image-1 layout: header →\n * subject card → action chips → chat → quick replies → input. Self-injects its\n * stylesheet so it looks right wherever it mounts. Accent comes from the\n * dashboard-authored profile theme (via the manifest), falling back to config. */\nexport class Renderer {\n private readonly scroll: HTMLElement\n private readonly chips: HTMLElement\n private readonly typing: HTMLElement\n private readonly quick: HTMLElement\n private readonly formHost: HTMLElement\n private readonly csatPanel: HTMLElement\n private readonly offlinePanel: HTMLElement\n private readonly footer: HTMLElement\n private readonly input: HTMLTextAreaElement\n private readonly subjectCard: HTMLElement\n private readonly e2eBadge: HTMLElement\n private readonly statusBadge: HTMLElement\n private readonly headerName: HTMLElement\n private readonly connStatus: HTMLElement\n private typingTimer: ReturnType<typeof setTimeout> | null = null\n private csatSubmitted = false\n\n // ── Co-browsing (shared whiteboard) ─────────────────────────────────────\n private readonly cobrowseBtn: HTMLButtonElement\n private readonly cobrowseCanvas: HTMLCanvasElement\n private readonly cobrowseToolbar: HTMLElement\n private readonly cobrowseHint: HTMLElement\n private cobrowseActive = false\n private cobrowseColor = '#f5713c'\n private lastAnnotationVersion = -1\n private storeRef: ChatStore | null = null\n private scrollCleanup: (() => void) | null = null\n\n /** Returns the scroll container so history.ts can attach scroll listeners. */\n getScrollEl(): HTMLElement | null { return this.scroll }\n\n /** Registers a cleanup fn removed on destroy() to prevent listener leaks. */\n setScrollCleanup(fn: () => void): void {\n this.scrollCleanup?.()\n this.scrollCleanup = fn\n }\n\n // ── Live translation ──────────────────────────────────────────────────-\n private readonly translationCache = new Map<string, string>()\n private readonly showingTranslation = new Set<string>()\n\n\n /** Last seq the guest has seen per conversationId — used to compute unread badges. */\n\n\n constructor(\n private readonly root: HTMLElement,\n private readonly me: string,\n private readonly h: RendererHandlers,\n private readonly cfg: WidgetConfig = {},\n ) {\n injectStyles()\n // Clear any previous widget content on this element before building.\n // This is the last line of defence against double-mounts: even if mount()\n // is called twice on the same element (React StrictMode, HMR, caller bug),\n // the second Renderer wipes the first one's DOM so only one UI is visible.\n root.replaceChildren()\n root.classList.add('ocw')\n if (cfg.accent) root.style.setProperty('--ocw-accent', cfg.accent)\n\n // Header\n const head = el('div', 'ocw-head')\n const avatarEl = el('div', 'ocw-avatar')\n if (cfg.userInfo?.avatar) {\n const img = document.createElement('img')\n img.src = cfg.userInfo.avatar; img.alt = cfg.userInfo.name ?? 'You'\n img.style.cssText = 'width:100%;height:100%;border-radius:50%;object-fit:cover'\n avatarEl.append(img)\n } else {\n avatarEl.textContent = cfg.userInfo?.name ? cfg.userInfo.name[0]!.toUpperCase() : '🧑'\n }\n head.append(avatarEl)\n const hm = el('div', 'ocw-head-main')\n this.headerName = el('div', 'ocw-head-name', cfg.subject?.ownerLabel ?? cfg.subject?.title ?? '')\n hm.append(this.headerName)\n if (cfg.subject?.subtitle) hm.append(el('div', 'ocw-head-meta', cfg.subject.subtitle))\n head.append(hm)\n this.statusBadge = el('span', 'ocw-badge', cfg.subject?.status ?? '')\n if (!cfg.subject?.status) this.statusBadge.style.display = 'none'\n head.append(this.statusBadge)\n this.e2eBadge = el('span', 'ocw-e2e', '🔒 E2E'); this.e2eBadge.style.display = 'none'; head.append(this.e2eBadge)\n this.connStatus = el('span', 'ocw-conn-status'); this.connStatus.style.display = 'none'; head.append(this.connStatus)\n this.cobrowseBtn = el('button', 'ocw-menu ocw-cobrowse-btn', '🖍') as HTMLButtonElement\n this.cobrowseBtn.title = 'Shared whiteboard — draw to point things out together'\n this.cobrowseBtn.addEventListener('click', () => { this.cobrowseActive = !this.cobrowseActive; this.updateCobrowseUI() })\n head.append(this.cobrowseBtn)\n\n head.append(el('button', 'ocw-menu', '⋯'))\n\n // Action chips (filled in render)\n this.chips = el('div', 'ocw-chiprow')\n\n // Scroll area with optional subject card + messages\n this.scroll = el('div', 'ocw-scroll')\n this.subjectCard = el('div', 'ocw-subject')\n this.typing = el('div', 'ocw-typing')\n const typingBubble = el('div', 'ocw-typing-bubble')\n typingBubble.append(el('div', 'ocw-typing-dot'), el('div', 'ocw-typing-dot'), el('div', 'ocw-typing-dot'))\n this.typing.append(el('div', 'ocw-dot', '🧑'), typingBubble)\n this.quick = el('div', 'ocw-quick')\n for (const q of cfg.quickReplies ?? []) {\n const b = el('button', undefined, q)\n b.addEventListener('click', () => {\n this.h.onSend(q)\n // Hide quick replies immediately after one is tapped\n this.quick.style.display = 'none'\n })\n this.quick.append(b)\n }\n\n // Input\n this.formHost = el('div', 'ocw-form-host')\n this.csatPanel = el('div', 'ocw-csat'); this.csatPanel.style.display = 'none'\n this.offlinePanel = el('div', 'ocw-offline'); this.offlinePanel.style.display = 'none'\n this.input = el('textarea', undefined); this.input.rows = 1; this.input.placeholder = 'Message…'\n const sendBtn = el('button', 'ocw-sendbtn', cfg.i18n?.send ?? '➤')\n sendBtn.addEventListener('click', () => this.flushSend())\n this.input.addEventListener('keydown', (e) => {\n // Guard against IME composition (Korean/Japanese/Chinese input): while\n // the user is selecting a candidate from the IME's suggestion list,\n // pressing Enter to CONFIRM the candidate also fires a keydown with\n // key === 'Enter'. Without this check, that confirmation keystroke was\n // being treated as \"send the message\" — firing early with a partial\n // composition, and then firing again on the real Enter press with\n // whatever text was left, producing two bubbles for one message\n // (e.g. typing \"음식\" sends \"음식\" then \"식\").\n // e.isComposing covers most browsers; keyCode 229 is the long-standing\n // fallback for browsers/IMEs that don't set isComposing reliably.\n if (e.isComposing || e.keyCode === 229) return\n if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); this.flushSend() } else this.signalTyping()\n })\n\n const attachBtn = el('button', 'ocw-attach', '📎'); attachBtn.title = 'Attach image or file'\n const fileInput = document.createElement('input'); fileInput.type = 'file'\n fileInput.accept = 'image/*,.pdf,.txt,.doc,.docx'; fileInput.style.display = 'none'\n attachBtn.addEventListener('click', () => fileInput.click())\n fileInput.addEventListener('change', () => { if (fileInput.files?.[0] && this.h.onAttach) this.h.onAttach(fileInput.files[0]); fileInput.value = '' })\n\n const inputRow = el('div', 'ocw-input'); inputRow.append(attachBtn, fileInput, this.input, sendBtn)\n\n const footer = el('div', 'ocw-footer')\n // i18n.poweredBy: if the caller provides it, treat as plain text — no innerHTML.\n // Only our own hardcoded default renders the anchor as HTML.\n if (cfg.i18n?.poweredBy !== undefined) {\n footer.textContent = cfg.i18n.poweredBy\n } else {\n footer.innerHTML = 'Powered by <a href=\"https://relay.paramms.com\" target=\"_blank\" rel=\"noopener\">Relay</a>'\n }\n this.footer = footer\n\n root.append(head, this.chips, this.scroll, this.typing, this.quick, this.formHost, this.csatPanel, this.offlinePanel, inputRow, this.footer)\n\n // Co-browsing overlay: a freehand canvas layered over the whole widget.\n this.cobrowseCanvas = el('canvas', 'ocw-cobrowse-canvas') as HTMLCanvasElement\n this.cobrowseToolbar = el('div', 'ocw-cobrowse-toolbar')\n for (const c of ['#f5713c', '#1c1b1a', '#2563eb', '#16a34a', '#dc2626']) {\n const sw = el('button', 'ocw-cobrowse-swatch') as HTMLButtonElement\n sw.style.background = c\n sw.type = 'button'\n if (c === this.cobrowseColor) sw.classList.add('sel')\n sw.addEventListener('click', () => {\n this.cobrowseColor = c\n for (const n of this.cobrowseToolbar.querySelectorAll('.ocw-cobrowse-swatch')) n.classList.remove('sel')\n sw.classList.add('sel')\n })\n this.cobrowseToolbar.append(sw)\n }\n const cobrowseClear = el('button', 'ocw-cobrowse-clear', 'Clear')\n cobrowseClear.addEventListener('click', () => this.h.onAnnotateClear?.())\n this.cobrowseToolbar.append(cobrowseClear)\n this.cobrowseHint = el('div', 'ocw-cobrowse-hint', '🖍 Draw to point things out — visible to both sides')\n root.append(this.cobrowseCanvas, this.cobrowseToolbar, this.cobrowseHint)\n this.bindCobrowsePointerEvents()\n\n }\n\n /** Call when the widget is unmounted. Disconnects scroll listeners and clears timers. */\n destroy(): void {\n this.scrollCleanup?.()\n this.scrollCleanup = null\n if (this.typingTimer) { clearTimeout(this.typingTimer); this.typingTimer = null }\n }\n\n\n /** Render list rows, optionally filtered by search query. */\n\n\n /** Build a single WhatsApp-style conversation row. */\n\n /** Returns true when the chat screen is visible (not the list). */\n\n /** Navigate to the chat screen (slide list left, slide chat in from right). */\n\n /** Navigate back to the list screen. */\n\n private flushSend(): void {\n const text = this.input.value.trim()\n if (!text) return\n this.input.value = ''\n this.h.onTyping(false)\n this.h.onSend(text)\n }\n private signalTyping(): void {\n const preview = this.input.value.trim().slice(0, 100) || undefined\n this.h.onTyping(true, preview)\n if (this.typingTimer) clearTimeout(this.typingTimer)\n this.typingTimer = setTimeout(() => this.h.onTyping(false), 2000)\n }\n\n render(store: ChatStore): void {\n this.storeRef = store\n // Co-browsing toggle is only meaningful for subject-anchored conversations.\n this.cobrowseBtn.classList.toggle('show', !!store.subject)\n if (!store.subject && this.cobrowseActive) { this.cobrowseActive = false; this.updateCobrowseUI() }\n if (this.cobrowseActive && store.annotationVersion !== this.lastAnnotationVersion) {\n this.lastAnnotationVersion = store.annotationVersion\n this.resizeCobrowseCanvas()\n this.redrawCobrowse()\n }\n if (store.accent) this.root.style.setProperty('--ocw-accent', store.accent)\n this.e2eBadge.style.display = store.e2e ? 'inline-flex' : 'none'\n this.buildSubjectCard(store)\n // Header: when a subject is attached, show ownerLabel (\"Seller\", \"Host\")\n // or nothing — the subject card below carries the identity.\n // Without a subject, the header is already set to cfg.subject?.ownerLabel\n // or \"Chat\" from the constructor — don't overwrite it with the domain name\n // which would duplicate the subject card title or clutter a plain chat.\n if (store.subject) {\n const ownerLabel = this.cfg.subject?.ownerLabel\n if (ownerLabel) this.headerName.textContent = ownerLabel\n // else leave constructor default (\"Chat\")\n }\n // Without a subject: leave header as-is (set once in constructor)\n\n // Action chips from the manifest (filtered by state in the store)\n this.chips.replaceChildren()\n const actions = store.visibleActions()\n this.chips.style.display = actions.length ? 'flex' : 'none'\n for (const a of actions) this.chips.append(this.chipEl(a))\n\n // Messages\n // Preserve scroll anchor when history is prepended: capture height before\n // replaceChildren so we can restore relative position after.\n const prevScrollHeight = this.scroll.scrollHeight\n const prevScrollTop = this.scroll.scrollTop\n\n this.scroll.replaceChildren()\n if (this.subjectCard.childNodes.length) this.scroll.append(this.subjectCard)\n if (store.hasMoreHistory) {\n // Sentinel at top — scroll to here triggers load-more via the scroll\n // listener set up by restoreHistory. Shows a subtle loading indicator\n // so the user knows older messages are available.\n const sentinel = el('div', 'ocw-load-more')\n sentinel.textContent = '↑ Loading earlier messages…'\n sentinel.style.pointerEvents = 'none'\n this.scroll.append(sentinel)\n }\n let maxOther = 0\n for (const m of store.messages()) {\n this.scroll.append(this.messageEl(m, store))\n if (m.senderId !== this.me && m.seq > maxOther) maxOther = m.seq\n }\n // Auto-scroll to bottom only for new messages; restore anchor when history was prepended.\n if (prevScrollTop > 20) {\n this.scroll.scrollTop = this.scroll.scrollHeight - prevScrollHeight + prevScrollTop\n } else {\n this.scroll.scrollTop = this.scroll.scrollHeight\n }\n if (maxOther > 0) this.h.onReadUpTo(maxOther)\n\n const typingNames = [...store.typing]\n this.typing.classList.toggle('active', typingNames.length > 0)\n // Bubble is always present in DOM (hidden via CSS); just update label\n const bubble = this.typing.querySelector('.ocw-typing-bubble')\n if (bubble) bubble.setAttribute('aria-label', typingNames.length ? 'typing' : '')\n this.footer.style.display = store.whiteLabel ? 'none' : 'block'\n\n // Offline mode: show form instead of chat input\n if (store.offline) {\n if (this.offlinePanel.style.display === 'none') this.buildOfflinePanel(store.offlineMessage)\n this.offlinePanel.style.display = 'block'\n ;(this.root.querySelector('.ocw-input') as HTMLElement | null)?.style.setProperty('display', 'none')\n } else {\n this.offlinePanel.style.display = 'none'\n ;(this.root.querySelector('.ocw-input') as HTMLElement | null)?.style.removeProperty('display')\n }\n\n // CSAT: show star-rating panel when conversation reaches a terminal state\n // and the user hasn't yet rated. Terminal states are heuristic: 'resolved',\n // 'closed', 'sold', 'issued', 'checked_out'. The panel self-dismisses on submit.\n const terminalStates = ['resolved', 'closed', 'sold', 'issued', 'checked_out']\n if (this.h.onCsat && !this.csatSubmitted && terminalStates.includes(store.state) && store.messages().length > 0) {\n if (this.csatPanel.style.display === 'none') this.buildCsatPanel()\n this.csatPanel.style.display = 'block'\n }\n }\n\n setConnStatus(status: 'connecting' | 'open' | 'reconnecting'): void {\n if (status === 'open') { this.connStatus.style.display = 'none'; return }\n this.connStatus.style.display = ''\n this.connStatus.className = `ocw-conn-status${status === 'reconnecting' ? ' warn' : ''}`\n this.connStatus.textContent = status === 'reconnecting' ? '↻ reconnecting…' : '● connecting…'\n }\n\n private buildOfflinePanel(offlineMessage?: string): void {\n this.offlinePanel.replaceChildren()\n this.offlinePanel.append(el('div', 'ocw-offline-icon', '🌙'))\n this.offlinePanel.append(el('div', 'ocw-offline-title', this.cfg.i18n?.offline ?? \"We're offline right now\"))\n this.offlinePanel.append(el('div', 'ocw-offline-msg', offlineMessage || \"Leave your details and we'll get back to you soon.\"))\n const form = el('div', 'ocw-offline-form')\n const nameIn = el('input', 'ocw-offline-input') as HTMLInputElement; nameIn.placeholder = 'Your name'; nameIn.type = 'text'\n const emailIn = el('input', 'ocw-offline-input') as HTMLInputElement; emailIn.placeholder = 'Your email'; emailIn.type = 'email'\n const msgIn = el('textarea', 'ocw-offline-input') as HTMLTextAreaElement; msgIn.placeholder = 'Your message'; msgIn.rows = 3\n const submit = el('button', 'ocw-offline-submit', 'Send message')\n submit.addEventListener('click', () => {\n if (!emailIn.value.trim() || !msgIn.value.trim()) return\n // Post as a regular message (offline form is stored as a conversation once submitted)\n this.h.onSend(`[Offline form]\\nName: ${nameIn.value || 'Anonymous'}\\nEmail: ${emailIn.value}\\nMessage: ${msgIn.value}`)\n this.offlinePanel.replaceChildren(el('div', 'ocw-offline-thanks', '✓ Message sent! We\\'ll reply to your email.'))\n })\n form.append(nameIn, emailIn, msgIn, submit)\n this.offlinePanel.append(form)\n }\n\n private buildCsatPanel(): void {\n this.csatPanel.replaceChildren()\n this.csatPanel.append(el('div', 'ocw-csat-title', 'How did we do?'))\n const stars = el('div', 'ocw-csat-stars')\n const btns: HTMLButtonElement[] = []\n for (let i = 1; i <= 5; i++) {\n const b = el('button', 'ocw-csat-star', '★')\n b.dataset['score'] = String(i)\n b.addEventListener('mouseenter', () => btns.forEach((bb, idx) => bb.classList.toggle('lit', idx < i)))\n b.addEventListener('mouseleave', () => btns.forEach(bb => bb.classList.remove('lit')))\n b.addEventListener('click', () => {\n this.csatSubmitted = true\n this.csatPanel.replaceChildren(el('div', 'ocw-csat-done', `Thanks for your ${i}★ rating!`))\n this.h.onCsat?.(i)\n })\n btns.push(b); stars.append(b)\n }\n this.csatPanel.append(stars)\n }\n\n private subjectBuilt = false\n /** Subject card from the server's Subject entity (per chatroom), with the\n * mount config as a fallback. Built once when data first arrives. */\n // ── Co-browsing (shared whiteboard) ──────────────────────────────────────\n private updateCobrowseUI(): void {\n this.cobrowseCanvas.classList.toggle('active', this.cobrowseActive)\n this.cobrowseToolbar.classList.toggle('active', this.cobrowseActive)\n this.cobrowseHint.classList.toggle('active', this.cobrowseActive)\n this.cobrowseBtn.classList.toggle('on', this.cobrowseActive)\n if (this.cobrowseActive) {\n this.resizeCobrowseCanvas()\n this.redrawCobrowse()\n }\n }\n\n private resizeCobrowseCanvas(): void {\n this.cobrowseCanvas.width = this.root.clientWidth || 1\n this.cobrowseCanvas.height = this.root.clientHeight || 1\n }\n\n /** Draw a stroke whose points are normalized to 0..1, scaled to the current\n * canvas size — so strokes line up across different viewport sizes. */\n private drawStroke(stroke: { points: { x: number; y: number }[]; color: string; width: number }): void {\n const ctx = this.cobrowseCanvas.getContext('2d')\n if (!ctx || stroke.points.length < 2) return\n const w = this.cobrowseCanvas.width, h = this.cobrowseCanvas.height\n ctx.strokeStyle = stroke.color\n ctx.lineWidth = Math.max(1, stroke.width * Math.min(w, h))\n ctx.lineJoin = 'round'\n ctx.lineCap = 'round'\n ctx.beginPath()\n ctx.moveTo(stroke.points[0]!.x * w, stroke.points[0]!.y * h)\n for (const p of stroke.points.slice(1)) ctx.lineTo(p.x * w, p.y * h)\n ctx.stroke()\n }\n\n private redrawCobrowse(): void {\n const ctx = this.cobrowseCanvas.getContext('2d')\n if (!ctx) return\n ctx.clearRect(0, 0, this.cobrowseCanvas.width, this.cobrowseCanvas.height)\n for (const s of this.storeRef?.annotations ?? []) this.drawStroke(s)\n }\n\n private bindCobrowsePointerEvents(): void {\n let drawing = false\n let current: { x: number; y: number }[] = []\n const posFromEvent = (e: PointerEvent): { x: number; y: number } => {\n const rect = this.cobrowseCanvas.getBoundingClientRect()\n const x = rect.width > 0 ? (e.clientX - rect.left) / rect.width : 0\n const y = rect.height > 0 ? (e.clientY - rect.top) / rect.height : 0\n return { x: Math.min(1, Math.max(0, x)), y: Math.min(1, Math.max(0, y)) }\n }\n const STROKE_WIDTH = 0.006 // normalized — ~6px on a 1000px-wide canvas\n this.cobrowseCanvas.addEventListener('pointerdown', (e) => {\n if (!this.cobrowseActive) return\n drawing = true\n current = [posFromEvent(e)]\n this.cobrowseCanvas.setPointerCapture(e.pointerId)\n })\n this.cobrowseCanvas.addEventListener('pointermove', (e) => {\n if (!drawing) return\n current.push(posFromEvent(e))\n this.redrawCobrowse()\n this.drawStroke({ points: current, color: this.cobrowseColor, width: STROKE_WIDTH })\n })\n const finish = (e: PointerEvent): void => {\n if (!drawing) return\n drawing = false\n if (current.length > 1) {\n this.h.onAnnotate?.({ id: `an_${Date.now()}_${Math.random().toString(36).slice(2)}`, points: current, color: this.cobrowseColor, width: STROKE_WIDTH })\n }\n current = []\n try { this.cobrowseCanvas.releasePointerCapture(e.pointerId) } catch { /* not captured */ }\n }\n this.cobrowseCanvas.addEventListener('pointerup', finish)\n this.cobrowseCanvas.addEventListener('pointercancel', finish)\n }\n\n private buildSubjectCard(store: ChatStore): void {\n if (this.subjectBuilt) return\n const s = store.subject\n const cfg = this.cfg.subject\n // Only show the subject card when there is actual subject data (from the\n // server) or an explicit subject config passed by the embedder (title,\n // tags, status). Never fall back to store.name — that's the domain/profile\n // name and is already shown in the header; rendering it here as well is\n // what caused the duplication seen in the Hotel front desk screenshot.\n const title = s?.title ?? cfg?.title\n if (!title) return\n this.subjectBuilt = true\n this.subjectCard.replaceChildren()\n this.subjectCard.append(el('div', 'ocw-subject-title', title))\n if (cfg?.subtitle) this.subjectCard.append(el('div', 'ocw-subject-sub', cfg.subtitle))\n const tags = el('div', 'ocw-tags')\n if (s) for (const [k, v] of Object.entries(s.fields)) tags.append(el('span', 'ocw-tag', `${k}: ${v}`))\n else for (const t of cfg?.tags ?? []) tags.append(el('span', 'ocw-tag', t))\n if (tags.childNodes.length) this.subjectCard.append(tags)\n const status = s?.state ?? cfg?.status\n if (status) { this.statusBadge.textContent = status; this.statusBadge.style.display = 'inline-flex' }\n }\n\n private chipEl(a: ManifestAction): HTMLButtonElement {\n const btn = el('button', 'ocw-chip', a.icon ? `${a.icon} ${a.label}` : a.label)\n btn.dataset['actionId'] = a.id\n btn.addEventListener('click', async () => {\n if (a.confirm && !(await this.confirm(a.label))) return\n if (a.input?.length) this.openForm(a)\n else this.h.onInvoke(a.id)\n })\n return btn\n }\n\n /** In-widget confirmation modal (replaces window.confirm). */\n private confirm(label: string): Promise<boolean> {\n return new Promise((resolve) => {\n const overlay = el('div', 'ocw-modal')\n const card = el('div', 'ocw-modal-card')\n card.append(el('div', 'ocw-modal-title', label))\n card.append(el('div', 'ocw-modal-body', `Confirm “${label}”?`))\n const row = el('div', 'ocw-modal-actions')\n const cancel = el('button', 'ocw-modal-cancel', 'Cancel')\n const ok = el('button', 'ocw-modal-ok', 'Confirm')\n const close = (v: boolean) => { overlay.remove(); resolve(v) }\n cancel.addEventListener('click', () => close(false))\n ok.addEventListener('click', () => close(true))\n overlay.addEventListener('click', (e) => { if (e.target === overlay) close(false) })\n row.append(cancel, ok); card.append(row); overlay.append(card)\n this.root.append(overlay)\n ok.focus()\n })\n }\n\n /** Inline form for a form-effect action: typed inputs (date picker, number,\n * text) rendered above the composer — no browser prompts. */\n private openForm(a: ManifestAction): void {\n this.formHost.replaceChildren()\n const panel = el('div', 'ocw-form')\n panel.append(el('div', 'ocw-form-title', a.icon ? `${a.icon} ${a.label}` : a.label))\n const inputs = new Map<string, HTMLInputElement>()\n for (const f of a.input ?? []) {\n const row = el('label', 'ocw-form-row'); row.append(el('span', 'ocw-form-lbl', f.label))\n if (f.type === 'select' && f.options?.length) {\n const sel = el('select', 'ocw-form-input')\n if (!f.required) sel.append(el('option', undefined, '— select —'))\n for (const opt of f.options) { const o = el('option'); o.value = opt; o.textContent = opt; sel.append(o) }\n if (f.required) sel.required = true\n row.append(sel)\n inputs.set(f.name, sel as unknown as HTMLInputElement)\n } else {\n const inp = el('input', 'ocw-form-input')\n inp.type = f.type === 'number' ? 'number' : f.type === 'date' ? 'datetime-local' : 'text'\n if (f.required) inp.required = true\n row.append(inp); inputs.set(f.name, inp)\n }\n panel.append(row)\n }\n const actions = el('div', 'ocw-form-actions')\n const cancel = el('button', 'ocw-form-cancel', 'Cancel')\n const submit = el('button', 'ocw-form-submit', 'Send')\n cancel.addEventListener('click', () => this.formHost.replaceChildren())\n submit.addEventListener('click', () => {\n const out: Record<string, unknown> = {}\n for (const [name, inp] of inputs) {\n if (inp.required && !inp.value) { inp.style.borderColor = '#e5484d'; return }\n out[name] = inp.type === 'number' ? Number(inp.value) : inp.value\n }\n this.formHost.replaceChildren()\n this.h.onInvoke(a.id, out)\n })\n actions.append(cancel, submit); panel.append(actions)\n this.formHost.append(panel)\n inputs.values().next().value?.focus()\n }\n\n private messageEl(m: RenderMessage, store: ChatStore): HTMLElement {\n if (m.senderRole === 'system') {\n const sys = el('div', 'ocw-sys'); sys.textContent = m.deletedAt ? 'message deleted' : contentText(m.content); return sys\n }\n const mine = m.senderId === this.me\n const isNote = !!m.internal\n const row = el('div', `ocw-row ${isNote ? 'ocw-note mine' : mine ? 'mine' : 'theirs'} ${m.senderRole === 'bot' ? 'ocw-bot' : ''}`)\n if (!mine && !isNote) row.append(el('div', 'ocw-dot', m.senderRole === 'bot' ? '🤖' : '🧑'))\n const col = el('div')\n const bubbleWrap = el('div', 'ocw-bubble-wrap')\n // Reply-to context if present\n if (m.replyToId) {\n const replyCtx = el('div', 'ocw-reply-to', '↩ replying to a message')\n replyCtx.style.cssText = 'font-size:11px;color:var(--ocw-mut);margin-bottom:2px;font-style:italic'\n col.append(replyCtx)\n }\n const bubble = el('div', 'ocw-bubble')\n let textNode: Text | null = null\n if (m.deletedAt) bubble.append(el('span', 'ocw-deleted', 'message deleted'))\n else if (m.content.kind === 'attachment') {\n const c = m.content\n if (c.mime?.startsWith('image/')) {\n const img = document.createElement('img')\n img.src = c.url; img.alt = c.name ?? 'image'\n img.style.cssText = 'max-width:220px;max-height:160px;border-radius:10px;display:block;cursor:pointer'\n img.addEventListener('click', () => window.open(c.url, '_blank'))\n bubble.append(img)\n } else {\n const a = document.createElement('a')\n a.href = c.url; a.target = '_blank'; a.rel = 'noopener'\n a.style.cssText = 'display:flex;align-items:center;gap:8px;color:inherit;text-decoration:none'\n a.append(el('span', undefined, '📄'), el('span', undefined, c.name ?? 'file'))\n bubble.append(a)\n }\n } else {\n if (m.content.kind === 'appointment') {\n const ap = m.content\n const card = el('div', 'ocw-appt')\n card.append(el('div', 'ocw-appt-title', `\\u{1F4C5} ${ap.title}`))\n card.append(el('div', 'ocw-appt-time', new Date(ap.startIso).toLocaleString() + ' \\u2013 ' + new Date(ap.endIso).toLocaleTimeString()))\n if (ap.location) card.append(el('div', 'ocw-appt-loc', `\\u{1F4CD} ${ap.location}`))\n if (ap.description) card.append(el('div', 'ocw-appt-desc', ap.description))\n const links = el('div', 'ocw-appt-links')\n const gLink = document.createElement('a'); gLink.href = ap.googleUrl; gLink.target = '_blank'; gLink.rel = 'noopener'; gLink.className = 'ocw-appt-btn'; gLink.textContent = '\\u{1F4C5} Add to Google Calendar'\n const iLink = document.createElement('a'); iLink.href = ap.icalUrl; iLink.download = `${ap.title}.ics`; iLink.className = 'ocw-appt-btn ocw-appt-btn-sec'; iLink.textContent = '\\u{1F34E} Apple / iCal'\n links.append(gLink, iLink); card.append(links); bubble.append(card)\n } else {\n textNode = document.createTextNode(contentText(m.content))\n bubble.append(textNode)\n if (m.editedAt) bubble.append(el('span', 'ocw-edited', '(edited)'))\n }\n }\n bubbleWrap.append(bubble)\n\n // Live translation: only for the other party's plain-text messages (not notes).\n if (!mine && !isNote && this.h.onTranslate && m.content.kind === 'text' && !m.deletedAt && m.seq > 0 && textNode) {\n const original = m.content.text\n if (original.trim()) {\n const translateBtn = el('button', 'ocw-translate-btn', '🌐')\n translateBtn.type = 'button'\n translateBtn.title = 'Translate'\n translateBtn.addEventListener('click', (e) => {\n e.stopPropagation()\n if (this.showingTranslation.has(m.id)) {\n this.showingTranslation.delete(m.id)\n textNode!.textContent = original\n translateBtn.textContent = '🌐'\n translateBtn.title = 'Translate'\n return\n }\n const cached = this.translationCache.get(m.id)\n if (cached !== undefined) {\n this.showingTranslation.add(m.id)\n textNode!.textContent = cached\n translateBtn.textContent = '↩'\n translateBtn.title = 'Show original'\n return\n }\n translateBtn.textContent = '⏳'\n void this.h.onTranslate!(original).then((result) => {\n if (result === null) {\n translateBtn.textContent = '⚠️'\n translateBtn.title = 'Translation unavailable'\n setTimeout(() => { translateBtn.textContent = '🌐'; translateBtn.title = 'Translate' }, 1500)\n return\n }\n this.translationCache.set(m.id, result)\n this.showingTranslation.add(m.id)\n textNode!.textContent = result\n translateBtn.textContent = '↩'\n translateBtn.title = 'Show original'\n })\n })\n bubbleWrap.append(translateBtn)\n }\n }\n // Edit/delete context menu on own non-deleted messages\n if (mine && !m.deletedAt && m.seq > 0 && (this.h.onEdit ?? this.h.onDelete)) {\n const menu = el('div', 'ocw-msg-menu')\n if (this.h.onEdit) {\n const editBtn = el('button', undefined, '✏️')\n editBtn.title = 'Edit'\n editBtn.addEventListener('click', (e) => {\n e.stopPropagation()\n // Inline edit: replace bubble text with a small textarea + save/cancel\n const original = contentText(m.content)\n const ta = document.createElement('textarea')\n ta.value = original\n ta.rows = Math.min(4, Math.ceil(original.length / 40) + 1)\n ta.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'\n const saveBtn = el('button', 'ocw-form-submit', 'Save')\n saveBtn.style.cssText = 'margin-top:6px;padding:5px 14px;font-size:13px'\n const cancelBtn = el('button', 'ocw-form-cancel', 'Cancel')\n cancelBtn.style.cssText = 'margin-top:6px;padding:5px 10px;font-size:13px'\n const btnRow = el('div'); btnRow.style.cssText = 'display:flex;gap:6px;justify-content:flex-end'\n btnRow.append(cancelBtn, saveBtn)\n const editPanel = el('div'); editPanel.append(ta, btnRow)\n bubble.replaceChildren(editPanel)\n ta.focus(); ta.select()\n const restore = () => bubble.replaceChildren(textNode ?? document.createTextNode(original))\n cancelBtn.addEventListener('click', restore)\n saveBtn.addEventListener('click', () => {\n const newText = ta.value.trim()\n if (newText && newText !== original) { this.h.onEdit!(m.id, newText); restore() }\n else restore()\n })\n ta.addEventListener('keydown', (ke) => {\n if (ke.key === 'Enter' && !ke.shiftKey) { ke.preventDefault(); saveBtn.click() }\n if (ke.key === 'Escape') restore()\n })\n })\n menu.append(editBtn)\n }\n if (this.h.onDelete) {\n const delBtn = el('button', 'del', '🗑')\n delBtn.title = 'Delete'\n delBtn.addEventListener('click', (e) => { e.stopPropagation(); this.h.onDelete!(m.id) })\n menu.append(delBtn)\n }\n bubbleWrap.append(menu)\n }\n col.append(bubbleWrap)\n\n // Reactions: existing pills + add-reaction picker (hover-revealed)\n if (this.h.onReact && !m.deletedAt && m.seq > 0) {\n const reactWrap = el('div', 'ocw-react-wrap')\n const reactRow = el('div', 'ocw-react')\n // Existing reaction pills\n if (m.reactions && Object.keys(m.reactions).length) {\n for (const [emoji, users] of Object.entries(m.reactions)) {\n const pill = el('button', `ocw-react-pill${(users as string[]).includes(this.me) ? ' mine' : ''}`, `${emoji} ${(users as string[]).length}`)\n pill.addEventListener('click', () => this.h.onReact?.(m.id, emoji, (users as string[]).includes(this.me)))\n reactRow.append(pill)\n }\n }\n // Add-reaction button + picker\n const addBtn = el('button', 'ocw-react-btn', '+')\n const picker = el('div', 'ocw-react-picker')\n for (const emoji of REACTION_EMOJIS) {\n const pb = el('button', undefined, emoji)\n pb.addEventListener('click', (e) => {\n e.stopPropagation()\n const alreadyReacted = m.reactions?.[emoji]?.includes(this.me as never)\n this.h.onReact?.(m.id, emoji, !!alreadyReacted)\n picker.style.display = 'none'\n })\n picker.append(pb)\n }\n picker.style.display = 'none'\n addBtn.addEventListener('click', (e) => {\n e.stopPropagation()\n picker.style.display = picker.style.display === 'none' ? 'flex' : 'none'\n })\n document.addEventListener('click', () => { picker.style.display = 'none' }, { once: true })\n reactRow.append(addBtn)\n reactWrap.append(reactRow, picker)\n col.append(reactWrap)\n } else if (m.reactions && Object.keys(m.reactions).length) {\n col.append(el('div', 'ocw-react', Object.entries(m.reactions).map(([e, u]) => `${e}${(u as string[]).length}`).join(' ')))\n }\n void store // suppress unused warning — store available for future use\n\n const meta = el('div', 'ocw-time ocw-meta', fmtTime(m.ts))\n if (mine && m.status) {\n const t = el('span', `ocw-tick${m.status === 'read' ? ' read' : m.status === 'delivered' ? ' delivered' : ''}`, tick(m.status))\n meta.append(t)\n }\n // \"Seen\" indicator when agent has read past this message\n if (mine && m.seq > 0 && store.lastReadByOthers >= m.seq) {\n meta.append(el('span', 'ocw-seen', ' · Seen'))\n }\n col.append(meta)\n row.append(col)\n return row\n }\n}\n\nfunction tick(s: NonNullable<RenderMessage['status']>): string {\n switch (s) {\n case 'read': return '✓✓' // blue double tick rendered via CSS colour\n case 'delivered': return '✓✓'\n case 'sent': return '✓'\n default: return '🕓'\n }\n}\n","import { persistentUid } from './uid.js'\nimport {\n asConversationId,\n type ClientFrame, type ConversationId,\n} from './protocol/index.js'\nimport { ChatStore } from './store.js'\nimport { ConnectionManager } from './connection.js'\nimport { PersistentOutbox } from './outbox.js'\nimport { E2ESession, extractX3DHInit } from './e2e.js'\nimport { Renderer, type WidgetConfig } from './renderer.js'\nimport { restoreHistory, resolveRelayUrls } from './history.js'\n\nexport interface UserInfo {\n /** Display name shown in the conversation (e.g. \"Sarah Chen\"). */\n name?: string\n /** Email address — passed as conversation metadata for agent context. */\n email?: string\n /** Avatar URL — shown as the guest's avatar in both widget and dashboard. */\n avatar?: string\n /** Any custom key/value metadata to attach to the conversation\n * (e.g. plan tier, account ID, page URL). Shown to agents in the sidebar. */\n meta?: Record<string, string>\n}\n\nexport interface MountOptions {\n el: HTMLElement\n /** Relay URL. Any scheme works — `https://api.example.com` is fine; the widget\n * derives the WebSocket URL (`wss://…/ws`) and REST base from it. */\n url: string\n /** HTTP(S) base for REST calls — only needed when the REST API is on a\n * DIFFERENT origin than the socket. Normally leave unset. */\n apiUrl?: string\n profileId: string\n subjectId?: string\n /** IDENTITY (tiered — the host owns identity, the widget never has to persist it):\n * 1. `token` — a signed identity token. Either a capability token, or (recommended\n * for embedders) an ES256 JWT `{sub,iat,exp}` signed by your backend with the\n * private key whose public half is set as the chatroom's `guestPublicKey`.\n * The server cryptographically verifies it. Works in ANY language/environment,\n * no cookies or storage required. This is the production path.\n * 2. `userId` — a stable id you already have for the visitor (e.g. your logged-in\n * user id). Unauthenticated (\"you vouch for it\") but works everywhere. Used\n * only when `token` is absent.\n * 3. Neither — the widget falls back to best-effort local identity on the host\n * origin (first-party cookie + localStorage). A returning visitor on the same\n * browser keeps their history; if storage is blocked they get a fresh chat. */\n token?: string\n userId?: string\n subject?: WidgetConfig['subject']\n quickReplies?: string[]\n accent?: string\n /** If set, shows a 🌐 translate button on incoming messages that translates\n * them into this language (ISO code or language name) via the server's\n * /translate endpoint. Omit to disable the feature. */\n translateLang?: string\n /** If true, mount as a floating launcher button that opens/closes the chat */\n launcher?: boolean\n /** Position of the launcher button: default 'bottom-right' */\n position?: 'bottom-right' | 'bottom-left'\n /** Optional user info for identified users. When provided, the name/email/\n * avatar are shown to agents in the dashboard instead of the anonymous ID.\n * The token still controls identity — this is display metadata only.\n * Anonymous users (no token, no user) remain fully anonymous. */\n user?: UserInfo\n /** i18n: override UI strings. All keys are optional — omitted keys fall\n * back to English defaults. */\n i18n?: {\n placeholder?: string // input placeholder, default \"Message…\"\n send?: string // send button label, default \"➤\"\n offline?: string // offline panel title, default \"We're offline right now\"\n poweredBy?: string // footer text, default \"Powered by Relay\"\n }\n}\n\nexport interface WidgetHandle { close(): void }\n\n\n// ── Mount registry ────────────────────────────────────────────────────────────\n// Tracks active widget instances per host element. Prevents double-mounting\n// when React strict mode, HMR, or caller code calls mount() twice on the same\n// element — the most common cause of two widgets appearing on one page.\nconst _registry = new WeakMap<Element, WidgetHandle>()\n// Launcher widgets attach to document.body (not the ref div), and in launcher\n// mode React may re-create the ref div on re-render — so the el-keyed registry\n// above can't catch a stale launcher. This slot-keyed registry guarantees at\n// most ONE launcher per (profileId, subjectId), so an identity flicker or\n// re-render can never leave two stacked bubbles/panels on the page.\nconst _launcherRegistry = new Map<string, WidgetHandle>()\nfunction launcherSlot(opts: MountOptions): string {\n return `relay-launcher::${opts.profileId}::${opts.subjectId ?? ''}`\n}\n\n/** Unmount any widget currently mounted on `el`. No-op if nothing is mounted. */\nexport function unmount(el: Element): void {\n _registry.get(el)?.close()\n _registry.delete(el)\n}\n\nexport function mount(opts: MountOptions): WidgetHandle {\n // Auto-close any previous instance on this exact element before re-mounting.\n // Covers React double-invoke in StrictMode, HMR, and accidental duplicate calls.\n if (_registry.has(opts.el)) {\n _registry.get(opts.el)!.close()\n _registry.delete(opts.el)\n }\n // Launcher mode: also close any prior launcher for the same slot, even if it\n // was mounted on a now-detached div (React re-creates the ref div on\n // re-render). This is what prevents two stacked widgets after an identity\n // flicker (anonymous → logged-in).\n if (opts.launcher) _launcherRegistry.get(launcherSlot(opts))?.close()\n\n // Tiered identity (see MountOptions): a host-provided signed token wins, then a\n // host-vouched userId, then best-effort local persistence. The widget never\n // depends on its own storage when the host supplies identity — which is what\n // makes it safe to embed in any environment (iframes, webviews, SSR, etc.).\n const token = opts.token ?? opts.userId ?? persistentUid()\n // Accept any scheme on `url` (https/http/wss/ws) and derive both the concrete\n // WebSocket URL and the REST base from it. `apiUrl` overrides the REST base\n // only when the API is on a different origin than the socket.\n const { wsUrl, httpBase } = resolveRelayUrls(opts.url, opts.apiUrl)\n let store = new ChatStore(token as never)\n // Key the outbox by token + subjectId so each listing has its own pending queue.\n // Without this, a pending message from listing A appears as a ghost on listing B.\n const outboxKey = opts.subjectId ? `${token}::${opts.subjectId}` : token\n const outbox = new PersistentOutbox(outboxKey)\n let cid: ConversationId | undefined\n let outboxRestored = false\n\n let _mql: MediaQueryList | null = null\n let _mqlHandler: ((e: MediaQueryListEvent) => void) | null = null\n // (e.g. a bare `<div id=\"chat\"></div>` with no CSS). Without this the\n // widget's internal `height:100%` collapses to near-zero. Only applies\n // when the element truly has no height set — explicit CSS always wins.\n if (!opts.launcher && !opts.el.style.height && opts.el.clientHeight === 0) {\n opts.el.style.width = opts.el.style.width || '100%'\n opts.el.style.height = '600px'\n }\n\n // Restore pending outbox items for this specific listing/conversation.\n // The outbox is keyed by token+subjectId so ghost bubbles from other listings\n // never appear here.\n for (const item of outbox.load()) store.addOptimistic(item.clientMsgId, item.content)\n\n // ── Launcher mode ─────────────────────────────────────────────────────────\n let launcherEl: HTMLElement | null = null\n let badgeEl: HTMLElement | null = null\n let unread = 0\n let open = !opts.launcher // start open when not in launcher mode\n\n if (opts.launcher) {\n const pos = opts.position ?? 'bottom-right'\n const isRight = pos.includes('right')\n\n // Outer wrapper holds both the panel and the bubble button\n launcherEl = document.createElement('div')\n launcherEl.style.cssText = `position:fixed;${isRight ? 'right:20px' : 'left:20px'};bottom:20px;z-index:9999;display:flex;flex-direction:column;align-items:${isRight ? 'flex-end' : 'flex-start'};gap:12px`\n\n // ── Chat panel — fixed 380×600, sits above the bubble ─────────────────\n const panel = document.createElement('div')\n // Responsive panel: full-screen on mobile (<480px), 380×600 on desktop.\n // Use a MediaQueryList so the layout updates if the user rotates their phone\n // or resizes the browser window — not just the state at mount time.\n const mql = typeof window !== 'undefined' ? window.matchMedia('(max-width: 479px)') : null\n const applyPanelLayout = (mobile: boolean) => {\n panel.style.cssText = mobile ? [\n 'position:fixed', 'inset:0', 'width:100%', 'height:100%',\n 'border-radius:0', 'overflow:hidden',\n 'box-shadow:none', 'display:none', 'flex-direction:column', 'background:#fff',\n 'transition:opacity .18s', 'opacity:0', 'z-index:9998',\n ].join(';') : [\n 'width:380px', 'height:600px', 'border-radius:16px', 'overflow:hidden',\n 'box-shadow:0 8px 40px rgba(0,0,0,.18)',\n 'display:none', 'flex-direction:column', 'background:#fff',\n 'transform-origin:bottom ' + (isRight ? 'right' : 'left'),\n 'transition:opacity .18s,transform .18s', 'opacity:0', 'transform:scale(.95)',\n ].join(';')\n }\n applyPanelLayout(mql?.matches ?? false)\n const mqlHandler = (e: MediaQueryListEvent): void => applyPanelLayout(e.matches)\n mql?.addEventListener('change', mqlHandler)\n _mql = mql; _mqlHandler = mqlHandler\n\n // Move the mount target INSIDE the panel — not full-page\n opts.el.style.cssText = 'width:100%;height:100%;overflow:hidden'\n panel.append(opts.el)\n\n // ── Bubble button ─────────────────────────────────────────────────────\n const btn = document.createElement('button')\n btn.style.cssText = [\n `width:56px;height:56px;border-radius:50%`,\n `background:${opts.accent ?? '#4F63F5'}`,\n `color:#fff;border:none;font-size:24px;cursor:pointer`,\n `box-shadow:0 4px 16px rgba(0,0,0,.25)`,\n `position:relative;flex:none`,\n `transition:transform .15s`,\n ].join(';')\n btn.textContent = '💬'\n btn.onmouseenter = () => { btn.style.transform = 'scale(1.08)' }\n btn.onmouseleave = () => { btn.style.transform = 'scale(1)' }\n\n badgeEl = document.createElement('span')\n badgeEl.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`\n btn.append(badgeEl)\n\n launcherEl.append(panel, btn)\n document.body.append(launcherEl)\n\n const showPanel = (show: boolean) => {\n if (show) {\n panel.style.display = 'flex'\n requestAnimationFrame(() => { panel.style.opacity = '1'; panel.style.transform = 'scale(1)' })\n } else {\n panel.style.opacity = '0'; panel.style.transform = 'scale(.95)'\n setTimeout(() => { if (!open) panel.style.display = 'none' }, 180)\n }\n }\n\n btn.addEventListener('click', () => {\n open = !open\n showPanel(open)\n btn.textContent = open ? '✕' : '💬'\n btn.append(badgeEl!)\n if (open) { unread = 0; if (badgeEl) badgeEl.style.display = 'none' }\n })\n\n // Close on Escape\n document.addEventListener('keydown', (e) => {\n if (e.key === 'Escape' && open) { open = false; showPanel(false); btn.textContent = '💬'; btn.append(badgeEl!) }\n })\n }\n\n const addUnread = () => {\n if (open) return\n unread++\n if (badgeEl) { badgeEl.textContent = String(unread); badgeEl.style.display = 'flex' }\n }\n\n // ── Notification sound ────────────────────────────────────────────────────\n const playSound = () => {\n try {\n const ctx = new AudioContext()\n const osc = ctx.createOscillator(); const gain = ctx.createGain()\n osc.connect(gain); gain.connect(ctx.destination)\n osc.frequency.setValueAtTime(880, ctx.currentTime)\n osc.frequency.exponentialRampToValueAtTime(440, ctx.currentTime + 0.15)\n gain.gain.setValueAtTime(0.3, ctx.currentTime)\n gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.3)\n osc.start(); osc.stop(ctx.currentTime + 0.3)\n } catch { /* audio not available */ }\n }\n\n // Messages typed before the 'opened' frame arrives are queued here and\n // flushed once cid is known. This prevents silent message loss when the\n // user types immediately after the widget mounts (before WS handshake).\n const preSendQueue: { clientMsgId: string; content: import('./protocol/index.js').MessageContent }[] = []\n\n const flushPreSendQueue = (conversationId: ConversationId) => {\n while (preSendQueue.length) {\n const item = preSendQueue.shift()!\n outbox.add({ clientMsgId: item.clientMsgId, content: item.content, ts: Date.now() })\n conn.send({ type: 'send', conversationId, clientMsgId: item.clientMsgId, content: item.content })\n }\n }\n\n let conn: ConnectionManager\n const e2e = new E2ESession(`ocw-e2e-${opts.profileId}`)\n let e2eStarted = false\n // Live ECDH pending (peer not yet online)\n const pending: { clientMsgId: string; text: string }[] = []\n // X3DH async: pending send awaiting the peer's prekey bundle\n const x3dhPending: { clientMsgId: string; text: string }[] = []\n let x3dhBundleFetched = false\n\n const sendSealed = (clientMsgId: string, text: string): void => {\n void e2e.sealText(text).then((content) => {\n if (cid) conn.send({ type: 'send', conversationId: cid, clientMsgId, content })\n })\n }\n\n const sendSealedX3DH = (clientMsgId: string, text: string, x3dhInit: { ephemeralKey: string; spkId: string; senderIK: string }): void => {\n void e2e.sealText(text, x3dhInit).then((content) => {\n if (cid) conn.send({ type: 'send', conversationId: cid, clientMsgId, content })\n })\n }\n\n const flushPending = (): void => {\n while (pending.length) { const p = pending.shift()!; sendSealed(p.clientMsgId, p.text) }\n while (x3dhPending.length) { const p = x3dhPending.shift()!; sendSealed(p.clientMsgId, p.text) }\n }\n\n /** Fetch the peer's prekey bundle and perform X3DH sender init. */\n const fetchAndX3DH = (targetUserId: string): void => {\n conn.send({ type: 'fetchPrekey', targetUserId: targetUserId as never })\n }\n\n const i18n = opts.i18n ?? {}\n // Auto-detect RTL for Arabic/Hebrew/Persian/Urdu regardless of i18n strings\n const rtlLocales = ['ar', 'he', 'fa', 'ur']\n const browserLang = typeof navigator !== 'undefined' ? (navigator.language ?? '').slice(0, 2).toLowerCase() : ''\n if (rtlLocales.includes(browserLang) && !opts.el.dir) {\n opts.el.dir = 'rtl'\n opts.el.style.fontFamily = opts.el.style.fontFamily || 'Tahoma,Arial,system-ui,sans-serif'\n }\n const renderer = new Renderer(opts.el, token, {\n onSend(text) {\n const clientMsgId = `cm_${Math.random().toString(36).slice(2)}`\n const content: import('./protocol/index.js').MessageContent = { kind: 'text', text }\n store.addOptimistic(clientMsgId, content)\n renderer.render(store)\n if (store.e2e) {\n if (e2e.ready) {\n sendSealed(clientMsgId, text)\n } else if (x3dhBundleFetched) {\n x3dhPending.push({ clientMsgId, text })\n } else {\n pending.push({ clientMsgId, text })\n if (store.assignedAgentId) fetchAndX3DH(store.assignedAgentId)\n }\n } else if (!cid) {\n // Connection not yet opened — queue the message; flushed on 'opened'\n preSendQueue.push({ clientMsgId, content })\n } else {\n outbox.add({ clientMsgId, content, ts: Date.now() })\n conn.send({ type: 'send', conversationId: cid, clientMsgId, content })\n }\n },\n async onAttach(file: File) {\n if (!cid) return\n const uploadUrl = `${httpBase}/upload?name=${encodeURIComponent(file.name)}`\n const clientMsgId = `cm_${Math.random().toString(36).slice(2)}`\n // Optimistic: show uploading state\n store.addOptimistic(clientMsgId, { kind: 'text', text: `📎 Uploading ${file.name}…` })\n renderer.render(store)\n try {\n const res = await fetch(uploadUrl, {\n method: 'POST',\n headers: { 'content-type': file.type, ...(opts.token ? { authorization: `Bearer ${opts.token}` } : {}) },\n body: file,\n })\n if (!res.ok) throw new Error(`Upload failed: ${res.status}`)\n const { url, name, mime, size } = await res.json() as { url: string; name: string; mime: string; size: number }\n conn.send({ type: 'send', conversationId: cid, clientMsgId, content: { kind: 'attachment', url, name, mime, size } })\n } catch (e) {\n store.addOptimistic(clientMsgId, { kind: 'text', text: `⚠️ Upload failed: ${(e as Error).message}` })\n renderer.render(store)\n }\n },\n onInvoke(actionId, inputs) {\n if (!cid) return\n conn.send({ type: 'invoke', conversationId: cid, actionId, clientInvokeId: `iv_${Math.random().toString(36).slice(2)}`, ...(inputs ? { inputs } : {}) })\n },\n onTyping(isTyping, preview) { if (cid) conn.send({ type: 'typing', conversationId: cid, isTyping, ...(preview ? { preview } : {}) }) },\n onReadUpTo(seq) { if (cid) conn.send({ type: 'read', conversationId: cid, seq }) },\n onLoadMore() {\n // WS fallback for E2E rooms where REST history can't be decrypted.\n // Non-E2E rooms use scroll-triggered REST pagination from restoreHistory().\n if (!cid || !store.e2e) return\n const oldest = store.messages()[0]\n if (oldest) conn.send({ type: 'history', conversationId: cid, beforeSeq: oldest.seq, limit: 20 })\n },\n onEdit(messageId, newText) {\n if (cid) conn.send({ type: 'edit', conversationId: cid, messageId: messageId as never, content: { kind: 'text', text: newText } })\n },\n onDelete(messageId) {\n if (cid) conn.send({ type: 'delete', conversationId: cid, messageId: messageId as never })\n },\n onReact(messageId, emoji, remove) {\n if (!cid) return\n conn.send({ type: 'react', conversationId: cid, messageId: messageId as never, emoji, remove })\n },\n onCsat(score) {\n if (!cid) return\n fetch(`${httpBase}/conversations/${cid}/csat`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },\n body: JSON.stringify({ score }),\n }).catch(() => {})\n },\n onAnnotate(stroke) {\n if (cid) conn.send({ type: 'annotate', conversationId: cid, stroke })\n },\n onAnnotateClear() {\n if (cid) conn.send({ type: 'annotate_clear', conversationId: cid })\n },\n ...(opts.translateLang ? {\n async onTranslate(text: string) {\n try {\n const res = await fetch(`${httpBase}/translate`, {\n method: 'POST',\n headers: { 'content-type': 'application/json', authorization: `Bearer ${token}` },\n body: JSON.stringify({ text, targetLang: opts.translateLang }),\n })\n if (!res.ok) return null\n const { translated } = await res.json() as { translated: string | null }\n return translated\n } catch { return null }\n },\n } : {}),\n }, {\n ...(opts.subject ? { subject: opts.subject } : {}),\n ...(opts.quickReplies ? { quickReplies: opts.quickReplies } : {}),\n ...(opts.accent ? { accent: opts.accent } : {}),\n ...(opts.user?.name || opts.user?.avatar ? { userInfo: { ...(opts.user.name ? { name: opts.user.name } : {}), ...(opts.user.avatar ? { avatar: opts.user.avatar } : {}) } } : {}),\n i18n,\n\n })\n\n const openFrame: Extract<ClientFrame, { type: 'open' }> = {\n type: 'open', profileId: opts.profileId as never,\n ...(opts.subjectId ? { subjectId: opts.subjectId as never } : {}),\n ...(typeof location !== 'undefined' ? { pageUrl: location.href } : {}),\n ...(typeof document !== 'undefined' && document.title ? { pageTitle: document.title } : {}),\n // Pass subject display info so the server can persist it to the Subject record.\n // This is how listingTitle and listingMeta get saved without a separate API call.\n ...(opts.subject?.title ? { subjectTitle: opts.subject.title } : {}),\n ...(opts.subject?.subtitle ? { subjectMeta: opts.subject.subtitle } : {}),\n }\n\n // Attach user info as a special first message so agents see it immediately.\n // Sent after 'opened' confirms the conversation exists, not in the open frame\n // itself (the protocol has no user-info field on 'open').\n const sendUserInfo = (conversationId: ConversationId): void => {\n const u = opts.user\n if (!u || (!u.name && !u.email && !u.avatar && !u.meta)) return\n const parts: string[] = []\n if (u.name) parts.push(`Name: ${u.name}`)\n if (u.email) parts.push(`Email: ${u.email}`)\n if (u.avatar) parts.push(`Avatar: ${u.avatar}`)\n if (u.meta) for (const [k, v] of Object.entries(u.meta)) parts.push(`${k}: ${v}`)\n // Send as an internal system message — agents see it, guest doesn't\n conn.send({ type: 'note', conversationId, clientMsgId: `ui_${Date.now()}`, text: `[User info]\\n${parts.join('\\n')}` })\n }\n\n conn = new ConnectionManager({\n url: wsUrl, token, open: openFrame,\n getCursor: () => store.highestSeq(),\n onStatusChange: (s) => renderer.setConnStatus(s),\n onFrame(frame) {\n if (frame.type === 'opened') {\n const isFirstOpen = cid === undefined\n cid = frame.conversation.id\n\n // Flush persistent outbox exactly once (idempotent: items are ack-removed).\n if (!outboxRestored) {\n outboxRestored = true\n for (const item of outbox.load()) {\n conn.send({ type: 'send', conversationId: cid, clientMsgId: item.clientMsgId, content: item.content })\n }\n }\n\n // Restore history on EVERY successful open (covers reconnects too).\n // On reconnect the store still has messages in memory so this is a\n // no-op if there's nothing newer — cheap REST call, correct behaviour.\n void restoreHistory(wsUrl, token, cid, store, renderer, httpBase)\n\n // Flush any messages typed while the connection was still opening.\n if (preSendQueue.length) flushPreSendQueue(cid)\n\n if (isFirstOpen && frame.conversation.lastSeq === 0) sendUserInfo(cid)\n }\n\n if (frame.type === 'ack') outbox.remove(frame.clientMsgId)\n\n // X3DH: handle incoming prekey bundle response\n if (frame.type === 'prekeyBundle') {\n if (frame.bundle) {\n x3dhBundleFetched = true\n void e2e.x3dhSendTo(frame.bundle).then((x3dhInit) => {\n // Drain any X3DH-pending messages with the derived key.\n const toSend = [...pending.splice(0), ...x3dhPending.splice(0)]\n for (const p of toSend) sendSealedX3DH(p.clientMsgId, p.text, x3dhInit)\n renderer.render(store)\n })\n }\n // If no bundle, peer has no prekeys; fall back to live ECDH queue\n return\n }\n\n // X3DH recipient: detect init message in incoming encrypted messages\n if (frame.type === 'message' && store.e2e) {\n const x3dh = extractX3DHInit(frame.message.content)\n if (x3dh && !e2e.ready) {\n void e2e.x3dhReceiveFrom(x3dh.x3dhIK, x3dh.x3dhEK, x3dh.x3dhSPK).then(async () => {\n // Now decrypt the message that carried the init\n await e2e.openFrame(frame)\n store.apply(frame)\n renderer.render(store)\n })\n return\n }\n }\n\n if (frame.type === 'peerkey') {\n void e2e.onPeerKey(frame.key).then(() => { flushPending(); renderer.render(store) })\n return\n }\n void (async () => {\n if (store.e2e) await e2e.openFrame(frame)\n store.apply(frame)\n // Trigger badge + sound for new messages from others.\n // In chatList mode, skip the badge if the user is already in the chat\n // screen for this conversation — they can see the message immediately.\n if (frame.type === 'message' && frame.message.senderId !== (token as never) && !frame.message.internal) {\n addUnread()\n playSound()\n }\n // Once we learn the room is E2E, run the key handshake exactly once.\n if (store.e2e && cid && !e2eStarted) {\n e2eStarted = true\n // Upload our prekey bundle for async E2E support.\n const prekeyPayload = await e2e.initX3DH()\n conn.send({ type: 'uploadPrekeys', ...prekeyPayload })\n // Also do live ECDH handshake in case peer is already online.\n const liveKey = await e2e.begin()\n conn.send({ type: 'pubkey', conversationId: cid, key: liveKey })\n }\n renderer.render(store)\n // Keep seenSeq in sync so the chat list shows accurate unread counts\n })()\n },\n })\n\n\n conn.connect()\n // Show restored 'pending' bubbles (if any) immediately, before the socket opens.\n renderer.render(store)\n\n const slot = opts.launcher ? launcherSlot(opts) : null\n const handle: WidgetHandle = { close: () => {\n conn.close(); launcherEl?.remove(); renderer.destroy()\n if (_mql && _mqlHandler) _mql.removeEventListener('change', _mqlHandler)\n _registry.delete(opts.el)\n if (slot && _launcherRegistry.get(slot) === handle) _launcherRegistry.delete(slot)\n } }\n _registry.set(opts.el, handle)\n if (slot) _launcherRegistry.set(slot, handle)\n return handle\n}\n\nexport { ChatStore } from './store.js'\nexport { ConnectionManager } from './connection.js'\nexport { Renderer } from './renderer.js'\nexport { asConversationId }\nexport { E2ESession, extractX3DHInit, type X3DHBundle } from './e2e.js'\nexport { PersistentOutbox, type OutboxItem } from './outbox.js'\nexport { restoreHistory, httpBaseFromWsUrl, resolveRelayUrls } from './history.js'\n\n"],"names":["asConversationId","utf8Count","str","strLength","byteLength","pos","value","extra","utf8EncodeJs","output","outputOffset","offset","sharedTextEncoder","TEXT_ENCODER_THRESHOLD","utf8EncodeTE","utf8Encode","CHUNK_SIZE","utf8DecodeJs","bytes","inputOffset","end","units","result","byte1","byte2","byte3","byte4","unit","sharedTextDecoder","TEXT_DECODER_THRESHOLD","utf8DecodeTD","stringBytes","utf8Decode","ExtData","type","data","__publicField","DecodeError","message","proto","UINT32_MAX","setUint64","view","high","low","setInt64","getInt64","getUint64","EXT_TIMESTAMP","TIMESTAMP32_MAX_SEC","TIMESTAMP64_MAX_SEC","encodeTimeSpecToTimestamp","sec","nsec","rv","secHigh","secLow","encodeDateToTimeSpec","date","msec","nsecInSec","encodeTimestampExtension","object","timeSpec","decodeTimestampToTimeSpec","nsec30AndSecHigh2","secLow32","decodeTimestampExtension","timestampExtension","_ExtensionCodec","encode","decode","index","context","encodeExt","decodeExt","ExtensionCodec","isArrayBufferLike","buffer","ensureUint8Array","DEFAULT_MAX_DEPTH","DEFAULT_INITIAL_BUFFER_SIZE","Encoder","options","depth","sizeToWrite","requiredSize","newSize","newBuffer","newBytes","newView","ext","size","item","keys","count","key","values","prettyByte","byte","DEFAULT_MAX_KEY_LENGTH","DEFAULT_MAX_LENGTH_PER_KEY","CachedKeyDecoder","maxKeyLength","maxLengthPerKey","records","FIND_CHUNK","record","recordBytes","j","cachedValue","slicedCopyOfBytes","STATE_ARRAY","STATE_MAP_KEY","STATE_MAP_VALUE","mapKeyConverter","StackPool","state","partialState","HEAD_BYTE_REQUIRED","EMPTY_VIEW","EMPTY_BYTES","e","MORE_DATA","sharedCachedKeyDecoder","Decoder","remainingData","newData","posToShow","stream","decoded","headByte","totalPos","isArray","isArrayHeaderRequired","arrayItemsLeft","DECODE","stack","headerOffset","_a","headOffset","extType","CLIENT_FRAME_TYPES","isClientFrame","frame","encodeFrame","mpEncode","decodeFrame","mpDecode","ChatStore","me","a","b","ap","bp","clientMsgId","content","msg","confirmed","m","reactions","users","u","existing","uptoSeq","status","targetRank","rank","changed","k","ConnectionManager","opts","_b","sock","defaultFactory","ev","cap","pending","f","base","max","delay","url","MAX_ITEMS","MAX_AGE_MS","PersistentOutbox","token","raw","items","cutoff","fresh","i","subtle","b64encode","buf","s","b64decode","bin","out","generateKeyPair","kp","exportPublicKey","importPeerPublicKey","b64","deriveSharedKey","privateKey","peerPublicKeyB64","peer","encrypt","plaintext","iv","ct","decrypt","plain","loadOrCreateKeyPair","storageKey","pub","priv","publicKey","signPrekey","signingPrivateKey","spkPublicKey","spkRaw","sig","generateIdentityKeyPair","ecdhKP","ecdsaKP","loadOrCreateIdentityKeyPair","d","ecdhPub","ecdhPriv","ecdsaPub","ecdsaPriv","ikp","x3dhSend","senderIK","recipientBundle","ek","epkB64","ik_r","spk_r","opk_r","dh1","rawDH","dh2","dh3","dh4","ikm","concatBuffers","hkdfDeriveKey","x3dhReceive","recipientIK","recipientSPK","senderIKb64","ephemeralKeyB64","recipientOPK","ik_s","ek_s","bufs","total","ikmKey","OTP_BATCH_SIZE","E2ESession","peerKeyB64","signedPrekeyPub","signature","oneTimePrekeys","bundle","sharedKey","ephemeralPublicKey","spkId","otp","ephemeralKey","text","x3dhInit","extractX3DHInit","c","STYLE_ID","REACTION_EMOJIS","CSS","injectStyles","el","tag","cls","n","fmtTime","ts","contentText","Renderer","root","h","cfg","head","avatarEl","img","hm","_c","_d","_e","_f","_g","typingBubble","q","sendBtn","_h","attachBtn","fileInput","inputRow","footer","_i","sw","cobrowseClear","fn","preview","store","ownerLabel","actions","prevScrollHeight","prevScrollTop","sentinel","maxOther","typingNames","bubble","terminalStates","offlineMessage","form","nameIn","emailIn","msgIn","submit","stars","btns","bb","idx","stroke","ctx","w","p","drawing","current","posFromEvent","rect","x","y","STROKE_WIDTH","finish","title","tags","v","t","btn","label","resolve","overlay","card","row","cancel","ok","close","panel","inputs","sel","opt","o","inp","name","sys","mine","isNote","col","bubbleWrap","replyCtx","textNode","links","gLink","iLink","original","translateBtn","cached","menu","editBtn","ta","saveBtn","cancelBtn","btnRow","editPanel","restore","newText","ke","delBtn","reactWrap","reactRow","emoji","pill","addBtn","picker","pb","alreadyReacted","meta","tick","_registry","_launcherRegistry","launcherSlot","unmount","mount","persistentUid","wsUrl","httpBase","resolveRelayUrls","outboxKey","outbox","cid","outboxRestored","_mql","_mqlHandler","launcherEl","badgeEl","unread","open","isRight","mql","applyPanelLayout","mobile","mqlHandler","showPanel","show","addUnread","playSound","osc","gain","preSendQueue","flushPreSendQueue","conversationId","conn","e2e","e2eStarted","x3dhPending","x3dhBundleFetched","sendSealed","sendSealedX3DH","flushPending","fetchAndX3DH","targetUserId","i18n","rtlLocales","browserLang","renderer","file","uploadUrl","res","mime","actionId","isTyping","seq","oldest","messageId","remove","score","translated","openFrame","sendUserInfo","parts","isFirstOpen","restoreHistory","toSend","x3dh","prekeyPayload","liveKey","slot","handle"],"mappings":"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","x_google_ignoreList":[1,2,3,4,5,6,7,8,9,10,11,12,13]}
|