@paramms/chat-widget 0.1.0 → 1.0.1
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/README.md +138 -12
- package/dist/connection.d.ts +48 -0
- package/dist/crypto.d.ts +69 -0
- package/dist/e2e.d.ts +75 -0
- package/dist/history.d.ts +14 -0
- package/dist/index.d.ts +60 -0
- package/dist/index.js +2638 -0
- package/dist/index.js.map +1 -0
- package/dist/outbox.d.ts +20 -0
- package/dist/protocol/actions.d.ts +98 -0
- package/dist/protocol/codec.d.ts +12 -0
- package/dist/protocol/entities.d.ts +109 -0
- package/dist/protocol/frames.d.ts +248 -0
- package/dist/protocol/ids.d.ts +22 -0
- package/dist/protocol/index.d.ts +5 -0
- package/dist/react.d.ts +124 -0
- package/dist/react.js +143 -0
- package/dist/react.js.map +1 -0
- package/dist/renderer.d.ts +163 -0
- package/dist/store.d.ts +48 -0
- package/package.json +31 -2
- package/build-preview.js +0 -136
- package/index.html +0 -37
- package/src/__tests__/chatlist.test.ts +0 -133
- package/src/__tests__/connection.test.ts +0 -163
- package/src/__tests__/crypto.test.ts +0 -28
- package/src/__tests__/history.test.ts +0 -91
- package/src/__tests__/ime.test.ts +0 -93
- package/src/__tests__/render.test.ts +0 -58
- package/src/__tests__/render_new.test.ts +0 -441
- package/src/__tests__/store.test.ts +0 -86
- package/src/__tests__/x3dh.test.ts +0 -204
- package/src/connection.ts +0 -133
- package/src/crypto.ts +0 -252
- package/src/e2e.ts +0 -161
- package/src/history.ts +0 -43
- package/src/index.ts +0 -380
- package/src/outbox.ts +0 -58
- package/src/protocol/actions.ts +0 -114
- package/src/protocol/codec.ts +0 -35
- package/src/protocol/entities.ts +0 -104
- package/src/protocol/frames.ts +0 -86
- package/src/protocol/ids.ts +0 -27
- package/src/protocol/index.ts +0 -5
- package/src/react.tsx +0 -37
- package/src/renderer.ts +0 -906
- package/src/store.ts +0 -207
- package/tsconfig.json +0 -33
- package/vercel.json +0 -22
- package/vite.config.ts +0 -26
- package/vitest.config.ts +0 -2
|
@@ -0,0 +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/history.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 for (const [k, m] of this.byId) {\n if (m.senderId === this.me && m.seq > 0 && m.seq <= uptoSeq && rank(status) > rank(m.status)) {\n this.byId.set(k, { ...m, status })\n this._sorted = null\n }\n }\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: Extract<ClientFrame, { type: 'open' }> // what to (re)open on connect\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 /** When showChatList=true, start on the chat screen instead of the list screen.\n * Set when a specific conversation/listing is already known (e.g. MarketplaceChat\n * with listingId). The list is still accessible via the back button. */\n startOnChat?: boolean\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): 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 onListChats?(): Promise<ChatListEntry[]>\n /** Switch the active conversation to a different one from the list —\n * effectively a re-open with a different subjectId. */\n onSwitchChat?(entry: ChatListEntry): void\n}\n\nexport interface ChatListEntry {\n id: string\n subjectId?: string\n subjectTitle?: string\n state: string\n updatedAt: number\n /** Server-assigned highest message seq — used to compute unread count. */\n lastSeq?: number\n /** Snippet of the last message text — shown as preview in the list row. */\n lastMessage?: string\n}\n\nconst STYLE_ID = 'objectchat-widget-styles'\nconst REACTION_EMOJIS = ['👍', '❤️', '😂', '😮', '😢', '🙏']\nconst CSS = `\n.ocw { --ocw-accent:#f5713c; --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 0; overflow-x:auto; }\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; }\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/* ── Chat-app mode (showChatList=true): WhatsApp-style two-screen navigation ── */\n/* Screen A: conversation list — full widget, like WhatsApp's home screen */\n.ocw-screen { position:absolute; inset:0; display:flex; flex-direction:column; background:var(--ocw-bg); transition:transform .22s cubic-bezier(.4,0,.2,1); will-change:transform; }\n.ocw-screen-list { transform:translateX(0); z-index:10; }\n.ocw-screen-chat { transform:translateX(100%); z-index:20; background:var(--ocw-card); }\n.ocw-screen-list.hidden { transform:translateX(-30%); }\n.ocw-screen-chat.visible { transform:translateX(0); }\n/* List header */\n.ocw-cl-head { display:flex; align-items:center; padding:14px 16px 10px; background:var(--ocw-card); border-bottom:1px solid var(--ocw-line); gap:8px; }\n.ocw-cl-title { flex:1; font-size:17px; font-weight:700; color:var(--ocw-ink); }\n.ocw-cl-new { width:34px; height:34px; border-radius:50%; border:none; background:var(--ocw-accent); color:#fff; font-size:20px; cursor:pointer; display:flex; align-items:center; justify-content:center; flex:none; }\n/* Search bar */\n.ocw-cl-search-wrap { padding:8px 12px; background:var(--ocw-card); }\n.ocw-cl-search { width:100%; box-sizing:border-box; border:none; background:var(--ocw-bg); border-radius:20px; padding:8px 14px; font:inherit; font-size:14px; color:var(--ocw-ink); outline:none; }\n/* Section dividers: read / unread */\n.ocw-cl-section { padding:4px 16px 4px; font-size:11px; font-weight:700; color:var(--ocw-mut); letter-spacing:.5px; text-transform:uppercase; background:var(--ocw-bg); }\n/* Conversation row */\n.ocw-cl-row { display:flex; align-items:center; gap:12px; padding:10px 16px; background:var(--ocw-card); border:none; width:100%; text-align:left; cursor:pointer; border-bottom:1px solid var(--ocw-line); transition:background .1s; }\n.ocw-cl-row:hover, .ocw-cl-row:active { background:#faf8f6; }\n.ocw-cl-row.unread { background:var(--ocw-card); }\n/* Avatar circle with initial */\n.ocw-cl-av { width:46px; height:46px; border-radius:50%; background:var(--ocw-accent); color:#fff; font-size:18px; font-weight:700; display:flex; align-items:center; justify-content:center; flex:none; position:relative; }\n.ocw-cl-av img { width:100%; height:100%; border-radius:50%; object-fit:cover; }\n/* Status dot on avatar: green=open, grey=resolved */\n.ocw-cl-status { position:absolute; bottom:1px; right:1px; width:12px; height:12px; border-radius:50%; border:2px solid var(--ocw-card); background:#9b9690; }\n.ocw-cl-status.open { background:#22c55e; }\n.ocw-cl-status.waiting { background:#f59e0b; }\n/* Row content */\n.ocw-cl-body { flex:1; min-width:0; }\n.ocw-cl-name { font-size:15px; font-weight:600; color:var(--ocw-ink); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; margin-bottom:2px; }\n.ocw-cl-row.unread .ocw-cl-name { font-weight:700; }\n.ocw-cl-preview { font-size:13px; color:var(--ocw-mut); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }\n.ocw-cl-row.unread .ocw-cl-preview { color:var(--ocw-ink); }\n/* Right side: time + unread badge */\n.ocw-cl-right { display:flex; flex-direction:column; align-items:flex-end; gap:4px; flex:none; }\n.ocw-cl-time { font-size:11px; color:var(--ocw-mut); }\n.ocw-cl-row.unread .ocw-cl-time { color:var(--ocw-accent); font-weight:600; }\n.ocw-cl-badge { background:var(--ocw-accent); color:#fff; border-radius:999px; font-size:11px; font-weight:700; min-width:20px; height:20px; padding:0 5px; display:flex; align-items:center; justify-content:center; }\n.ocw-cl-body-scroll { flex:1; overflow-y:auto; }\n/* Chat screen back button */\n.ocw-chat-back { background:none; border:none; cursor:pointer; font-size:22px; color:var(--ocw-ink); padding:2px 6px 2px 0; line-height:1; display:none; }\n.ocw-chat-back.show { display:block; }\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 timeAgo(ts: number): string {\n const sec = Math.floor((Date.now() - ts) / 1000)\n if (sec < 60) return 'now'\n if (sec < 3600) return `${Math.floor(sec / 60)}m`\n if (sec < 86400) return `${Math.floor(sec / 3600)}h`\n return `${Math.floor(sec / 86400)}d`\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 // ── Chat-app two-screen navigation ──────────────────────────────────────────\n private listScreen: HTMLElement | null = null\n private chatScreen: HTMLElement | null = null\n private listBody: HTMLElement | null = null\n private listSearch: HTMLInputElement | null = null\n private backBtn: HTMLButtonElement | null = null\n private activeChatId: string | null = null\n private inChatScreen = false\n private allEntries: ChatListEntry[] = []\n /** Last seq the guest has seen per conversationId — used to compute unread badges. */\n private readonly seenSeq = new Map<string, number>()\n private seenSeqKey = ''\n\n /** Load seenSeq from localStorage (keyed by userId+profileId). */\n initSeenSeq(key: string): void {\n this.seenSeqKey = key\n try {\n const saved = localStorage.getItem(`ocw_seen_${key}`)\n if (saved) {\n const parsed = JSON.parse(saved) as Record<string, number>\n for (const [id, seq] of Object.entries(parsed)) this.seenSeq.set(id, seq)\n }\n } catch { /* ignore */ }\n }\n\n setSeenSeq(conversationId: string, seq: number): void {\n this.seenSeq.set(conversationId, Math.max(this.seenSeq.get(conversationId) ?? 0, seq))\n // Persist to localStorage so unread state survives page reloads\n if (this.seenSeqKey) {\n try {\n const obj: Record<string, number> = {}\n for (const [id, s] of this.seenSeq) obj[id] = s\n localStorage.setItem(`ocw_seen_${this.seenSeqKey}`, JSON.stringify(obj))\n } catch { /* ignore */ }\n }\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 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 // In chatList mode the back arrow lives in the chat screen header (built below)\n if (this.h.onListChats) {\n // back button — shown only inside the chat screen\n this.backBtn = el('button', 'ocw-chat-back', '←') as HTMLButtonElement\n this.backBtn.addEventListener('click', () => this.showListScreen())\n head.prepend(this.backBtn)\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); b.addEventListener('click', () => this.h.onSend(q)); 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 footer.innerHTML = cfg.i18n?.poweredBy !== undefined ? cfg.i18n.poweredBy : 'Powered by <a href=\"https://relay.paramms.com\" target=\"_blank\" rel=\"noopener\">Relay</a>'\n this.footer = footer\n\n if (this.h.onListChats) {\n // ── List screen — the home screen (like WhatsApp's chat list) ────────────\n const listScreen = el('div', 'ocw-screen ocw-screen-list')\n // List header\n const lHead = el('div', 'ocw-cl-head')\n lHead.append(el('span', 'ocw-cl-title', 'Messages'))\n const newBtn = el('button', 'ocw-cl-new', '+') as HTMLButtonElement\n newBtn.title = 'New conversation'\n newBtn.addEventListener('click', () => {\n // Start a new generic conversation (no subjectId) by switching to the default thread\n this.h.onSwitchChat?.({ id: '__new__', state: 'open', updatedAt: Date.now() })\n })\n lHead.append(newBtn)\n // Search bar\n const searchWrap = el('div', 'ocw-cl-search-wrap')\n const searchIn = el('input', 'ocw-cl-search') as HTMLInputElement\n searchIn.placeholder = '🔍 Search'\n searchIn.type = 'search'\n searchIn.addEventListener('input', () => this.renderListRows(this.allEntries, searchIn.value.trim().toLowerCase()))\n searchWrap.append(searchIn)\n // List body\n const listBody = el('div', 'ocw-cl-body-scroll')\n listBody.append(el('div', 'ocw-cl-section', 'Loading…'))\n listScreen.append(lHead, searchWrap, listBody)\n root.append(listScreen)\n this.listScreen = listScreen\n this.listBody = listBody\n this.listSearch = searchIn\n\n // ── Chat screen — slides in when a conversation is selected ─────────────\n const chatScreen = el('div', 'ocw-screen ocw-screen-chat')\n chatScreen.append(head, this.chips, this.scroll, this.typing, this.quick, this.formHost, this.csatPanel, this.offlinePanel, inputRow, this.footer)\n root.append(chatScreen)\n this.chatScreen = chatScreen\n\n // Start on chat screen immediately when a specific conversation is known\n // (MarketplaceChat with listingId). Avoids the list flash on mount.\n // Pure inbox mode (no listingId) starts on the list as home screen.\n if (cfg.startOnChat) {\n this.inChatScreen = true\n this.listScreen.classList.add('hidden')\n this.chatScreen.classList.add('visible')\n this.backBtn?.classList.add('show')\n } else {\n this.inChatScreen = false\n }\n // Always populate the list so back button works\n this.refreshList()\n } else {\n // Single-conversation mode — existing layout unchanged\n root.append(head, this.chips, this.scroll, this.typing, this.quick, this.formHost, this.csatPanel, this.offlinePanel, inputRow, this.footer)\n }\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 /** Fetch the list and re-render it. Called on mount and after switching chats. */\n private destroyed = false\n\n /** Call when the widget is unmounted. Disconnects scroll listeners and\n * prevents in-flight fetches from writing to dead DOM. */\n destroy(): void {\n this.destroyed = true\n this.scrollCleanup?.()\n this.scrollCleanup = null\n }\n\n refreshList(): void {\n if (!this.listBody || this.destroyed) return\n this.h.onListChats?.().then(entries => {\n if (this.destroyed) return\n this.allEntries = entries\n this.renderListRows(entries, this.listSearch?.value.trim().toLowerCase() ?? '')\n }).catch(() => {\n if (this.destroyed) return\n this.listBody?.replaceChildren(el('div', 'ocw-cl-section', 'Could not load conversations.'))\n })\n }\n\n /** Render list rows, optionally filtered by search query. */\n private renderListRows(entries: ChatListEntry[], query: string): void {\n if (!this.listBody) return\n const filtered = query\n ? entries.filter(e => (e.subjectTitle ?? 'General enquiry').toLowerCase().includes(query) || e.state.includes(query))\n : entries\n\n if (!filtered.length) {\n this.listBody.replaceChildren(el('div', 'ocw-cl-section', query ? 'No results.' : 'No conversations yet.'))\n return\n }\n\n // Partition: unread vs read, each sorted newest first\n const unread = filtered.filter(e => this.isUnread(e)).sort((a,b) => b.updatedAt - a.updatedAt)\n const read = filtered.filter(e => !this.isUnread(e)).sort((a,b) => b.updatedAt - a.updatedAt)\n\n this.listBody.replaceChildren()\n if (unread.length) {\n this.listBody.append(el('div', 'ocw-cl-section', `Unread (${unread.length})`))\n for (const e of unread) this.listBody.append(this.buildRow(e))\n }\n if (read.length) {\n this.listBody.append(el('div', 'ocw-cl-section', unread.length ? 'Read' : 'All conversations'))\n for (const e of read) this.listBody.append(this.buildRow(e))\n }\n }\n\n private isUnread(e: ChatListEntry): boolean {\n if (e.id === this.activeChatId) return false\n return (e.lastSeq ?? 0) > (this.seenSeq.get(e.id) ?? 0)\n }\n\n /** Build a single WhatsApp-style conversation row. */\n private buildRow(entry: ChatListEntry): HTMLElement {\n const seen = this.seenSeq.get(entry.id) ?? 0\n const lastSeq = entry.lastSeq ?? 0\n const unreadCount = this.isUnread(entry) ? Math.max(1, lastSeq - seen) : 0\n const name = entry.subjectTitle ?? 'General enquiry'\n const initial = name[0]?.toUpperCase() ?? '?'\n\n const row = el('button', `ocw-cl-row${unreadCount > 0 ? ' unread' : ''}`) as HTMLButtonElement\n\n // Avatar with coloured initial\n const av = el('div', 'ocw-cl-av', initial)\n // Status dot: green=open, amber=awaiting_staff, grey=resolved/closed\n const dot = el('div', 'ocw-cl-status')\n if (entry.state === 'open') dot.classList.add('open')\n else if (entry.state === 'awaiting_staff') dot.classList.add('waiting')\n av.append(dot)\n row.append(av)\n\n // Main content\n const body = el('div', 'ocw-cl-body')\n body.append(el('div', 'ocw-cl-name', name))\n\n // Preview: last message placeholder (state-based since we don't fetch full messages here)\n const stateMap: Record<string, string> = {\n 'open': 'Conversation open',\n 'awaiting_staff': 'Waiting for reply…',\n 'resolved': 'Conversation resolved ✓',\n 'closed': 'Conversation closed',\n }\n const preview = entry.lastMessage ?? stateMap[entry.state] ?? entry.state\n body.append(el('div', 'ocw-cl-preview', preview))\n row.append(body)\n\n // Right: time + unread badge\n const right = el('div', 'ocw-cl-right')\n right.append(el('div', 'ocw-cl-time', timeAgo(entry.updatedAt)))\n if (unreadCount > 0) {\n right.append(el('div', 'ocw-cl-badge', String(unreadCount > 99 ? '99+' : unreadCount)))\n }\n row.append(right)\n\n row.addEventListener('click', () => {\n if (lastSeq > 0) this.seenSeq.set(entry.id, lastSeq)\n this.activeChatId = entry.id\n this.showChatScreen()\n this.h.onSwitchChat?.(entry)\n })\n return row\n }\n\n /** Returns true when the chat screen is visible (not the list). */\n isInChatScreen(): boolean { return this.inChatScreen }\n\n /** Navigate to the chat screen (slide list left, slide chat in from right). */\n showChatScreen(): void {\n if (this.inChatScreen) return\n this.inChatScreen = true\n this.listScreen?.classList.add('hidden')\n this.chatScreen?.classList.add('visible')\n this.backBtn?.classList.add('show')\n }\n\n /** Navigate back to the list screen. */\n showListScreen(): void {\n if (!this.inChatScreen) return\n this.inChatScreen = false\n this.listScreen?.classList.remove('hidden')\n this.chatScreen?.classList.remove('visible')\n this.backBtn?.classList.remove('show')\n // activeChatId stays set so the row remains highlighted in the list.\n // It's updated when a different row is tapped (buildRow click handler).\n // Refresh so unread counts and lastMessage previews are up to date.\n this.refreshList()\n }\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 this.h.onTyping(true)\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 const text = contentText(m.content)\n const newText = prompt('Edit message:', text)\n if (newText !== null && newText.trim() && newText !== text) this.h.onEdit!(m.id, newText.trim())\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","// history.ts — shared REST history-fetch logic for both the guest widget\n// (index.ts) and the agent dashboard (operate.ts).\n//\n// Strategy:\n// • On open: fetch the latest 20 messages. Fast, cheap, covers most chats.\n// • hasMore=true → show a sentinel div at the top of the scroll area.\n// • When the sentinel scrolls into view (IntersectionObserver) fetch the\n// next 20 older messages and prepend — no button click required.\n// • This is the same infinite-scroll-upward pattern used by WhatsApp/Telegram.\n\nimport type { ChatStore } from './store.js'\nimport type { Message, ConversationId } from './protocol/index.js'\nimport type { Renderer } from './renderer.js'\n\nconst PAGE = 20 // messages per fetch — fast first load, smooth pagination\n\n/** Derive the HTTP(S) base origin from a ws(s):// URL. */\nexport function httpBaseFromWsUrl(wsUrl: string): string {\n return wsUrl.replace(/^ws/, 'http').replace(/\\/ws\\/?$/, '')\n}\n\n/** Build the best history URL for the given token context.\n * Staff tokens use /messages (full access); guest tokens use /history. */\nfunction historyUrl(httpBase: string, conversationId: string, beforeSeq: number, limit: number): string[] {\n const qs = `beforeSeq=${beforeSeq}&limit=${limit}`\n return [\n `${httpBase}/conversations/${conversationId}/messages?${qs}`,\n `${httpBase}/conversations/${conversationId}/history?${qs}`,\n ]\n}\n\n/** Fetch one page of history. Tries staff endpoint first, falls back to guest. */\nasync function fetchPage(\n httpBase: string,\n conversationId: string,\n token: string,\n beforeSeq: number,\n limit = PAGE,\n): Promise<{ messages: Message[]; hasMore: boolean } | null> {\n for (const url of historyUrl(httpBase, conversationId, beforeSeq, limit)) {\n try {\n const res = await fetch(url, { headers: { authorization: `Bearer ${token}` } })\n if (!res.ok) continue\n const data = await res.json() as { messages?: Message[]; hasMore?: boolean }\n return { messages: data.messages ?? [], hasMore: data.hasMore ?? false }\n } catch { /* try next */ }\n }\n return null\n}\n\n/** Initial history restore on conversation open.\n *\n * Fetches the latest PAGE messages and sets up scroll-triggered loading for\n * older messages via IntersectionObserver on a sentinel at the top of the\n * scroll container. No buttons — scrolling up loads more automatically.\n *\n * Returns a cleanup function — call it when the conversation is closed to\n * disconnect the observer and prevent stale updates. */\nexport async function restoreHistory(\n wsUrl: string,\n token: string,\n conversationId: ConversationId,\n store: ChatStore,\n renderer: Renderer,\n): Promise<void> {\n const httpBase = httpBaseFromWsUrl(wsUrl)\n\n const page = await fetchPage(httpBase, conversationId as string, token, Number.MAX_SAFE_INTEGER)\n if (!page) return\n\n if (page.messages.length) {\n store.apply({ type: 'sync', conversationId, messages: page.messages })\n // Always set hasMore from the response\n store.apply({ type: 'history', conversationId, messages: [], hasMore: page.hasMore })\n renderer.render(store)\n } else {\n // No messages — still record hasMore=false so the sentinel doesn't show\n store.apply({ type: 'history', conversationId, messages: [], hasMore: false })\n }\n\n if (!page.hasMore) return\n\n // ── Scroll-triggered load-more ────────────────────────────────────────────\n // Watch the sentinel div (the \"↑ Load earlier messages\" button rendered by\n // the Renderer at the top of the scroll area). When it becomes visible,\n // fetch the next page of older messages.\n let loading = false\n\n const loadOlder = async () => {\n if (loading || !store.hasMoreHistory) return\n loading = true\n const oldest = store.messages()[0]\n if (!oldest) { loading = false; return }\n const page2 = await fetchPage(httpBase, conversationId as string, token, oldest.seq)\n if (page2) {\n store.apply({ type: 'history', conversationId, messages: page2.messages, hasMore: page2.hasMore })\n renderer.render(store)\n }\n loading = false\n }\n\n // Use IntersectionObserver to detect when the user scrolls to the top.\n // We observe the scroll container itself — when scrollTop < 40px, load more.\n const scrollEl = renderer.getScrollEl()\n if (!scrollEl) return\n\n // Wait 300ms before arming the scroll listener — the initial render scrolls\n // to the bottom, which briefly passes through scrollTop=0 and could trigger\n // a spurious load before the user actually scrolls up.\n let armed = false\n setTimeout(() => { armed = true }, 300)\n\n const onScroll = () => {\n if (!armed) return\n if (scrollEl.scrollTop < 80 && store.hasMoreHistory && !loading) {\n void loadOlder()\n }\n }\n scrollEl.addEventListener('scroll', onScroll, { passive: true })\n renderer.setScrollCleanup(() => scrollEl.removeEventListener('scroll', onScroll))\n}\n","import {\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, type ChatListEntry } from './renderer.js'\nimport { restoreHistory, httpBaseFromWsUrl } 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 url: string\n profileId: string\n subjectId?: string\n token?: 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 /** If true, shows a 💬 button in the header that opens a list of the\n * guest's other conversations (e.g. a marketplace where each item gets\n * its own subjectId/thread) and lets them switch between them.\n * Off by default — single-conversation embeds don't need this. */\n showChatList?: boolean\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/** Persistent anonymous identity, reused across reloads (per the old widget's\n * oc_uid pattern). */\nfunction persistentUid(): string {\n const key = 'oc_uid'\n try {\n const existing = localStorage.getItem(key)\n if (existing) return existing\n const id = `g_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`\n localStorage.setItem(key, id)\n return id\n } catch {\n return `g_${Math.random().toString(36).slice(2)}`\n }\n}\n\nexport function mount(opts: MountOptions): WidgetHandle {\n const token = opts.token ?? persistentUid()\n const store = new ChatStore(token as never)\n const outbox = new PersistentOutbox(token)\n let cid: ConversationId | undefined\n let outboxRestored = false\n // Self-reference so onSwitchChat can close this mount and replace it with\n // a fresh one for the newly-selected conversation, without the embedder\n // needing to manage that lifecycle themselves.\n let currentHandle: WidgetHandle | null = null\n\n // Give the host element a sane default size if the embedder didn't set one\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 any messages that were queued but not yet acknowledged before the\n // last reload — show them as 'pending' immediately, matching the WhatsApp\n // pattern of never silently dropping a typed message.\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 panel.style.cssText = [\n 'width:380px',\n 'height:600px',\n 'border-radius:16px',\n 'overflow:hidden',\n 'box-shadow:0 8px 40px rgba(0,0,0,.18)',\n 'display:none', // hidden until bubble clicked\n 'flex-direction:column',\n 'background:#fff',\n 'transform-origin:bottom ' + (isRight ? 'right' : 'left'),\n 'transition:opacity .18s,transform .18s',\n 'opacity:0',\n 'transform:scale(.95)',\n ].join(';')\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 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 if (!cid) return\n const clientMsgId = `cm_${Math.random().toString(36).slice(2)}`\n store.addOptimistic(clientMsgId, { kind: 'text', text })\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 {\n outbox.add({ clientMsgId, content: { kind: 'text', text }, ts: Date.now() })\n conn.send({ type: 'send', conversationId: cid, clientMsgId, content: { kind: 'text', text } })\n }\n },\n async onAttach(file: File) {\n if (!cid) return\n const wsUrl = opts.url // derive HTTP upload URL from WS URL\n const httpUrl = wsUrl.replace(/^ws/, 'http').replace(/\\/ws$/, '')\n const uploadUrl = `${httpUrl}/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) { if (cid) conn.send({ type: 'typing', conversationId: cid, isTyping }) },\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 // POST CSAT via fetch to the control-plane (the WS server also listens on HTTP).\n // We extract the base URL from the WS URL best-effort.\n const base = opts.url.replace(/^ws/, 'http').replace(/\\/+$/, '').replace(/:\\d+$/, m => m) // keep port\n // Use the conversation id once it's known — post to /conversations/:id/csat\n fetch(`${base}/conversations/${cid}/csat`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },\n body: JSON.stringify({ score }),\n }).catch(() => {}) // best-effort\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 const base = opts.url.replace(/^ws/, 'http').replace(/\\/+$/, '')\n try {\n const res = await fetch(`${base}/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 ...(opts.showChatList ? {\n async onListChats() {\n const base = httpBaseFromWsUrl(opts.url)\n try {\n const res = await fetch(`${base}/conversations/mine?profileId=${encodeURIComponent(opts.profileId)}`, {\n headers: { authorization: `Bearer ${token}` },\n })\n if (!res.ok) return []\n const data = await res.json() as { conversations?: ChatListEntry[] }\n return data.conversations ?? []\n } catch { return [] }\n },\n onSwitchChat(entry: ChatListEntry) {\n if (!entry.id || entry.id === '__new__') return\n currentHandle?.close()\n opts.el.replaceChildren()\n // Strip subjectId and token from opts — supply resolved versions below.\n // token must be the locally-resolved uid (may differ from opts.token\n // when the widget fell back to persistentUid() for anonymous guests).\n const { subjectId: _dropSub, token: _dropTok, ...rest } = opts\n currentHandle = mount({\n ...rest,\n token, // always the resolved identity, never undefined\n ...(entry.subjectId ? { subjectId: entry.subjectId } : {}),\n showChatList: true,\n })\n // showChatScreen() is called by the NEW renderer's isFirstOpen handler\n // once the WebSocket confirms the conversation — no need to call it here.\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 // Start directly on chat screen when a specific conversation is known upfront\n ...(opts.showChatList && opts.subjectId ? { startOnChat: true } : {}),\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 // Auto-capture the page context so agents know where the guest is browsing.\n // This is pure display metadata — it never affects identity or access.\n ...(typeof location !== 'undefined' ? { pageUrl: location.href } : {}),\n ...(typeof document !== 'undefined' && document.title ? { pageTitle: document.title } : {}),\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: opts.url, 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 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 if (isFirstOpen) {\n void restoreHistory(opts.url, token, cid, store, renderer)\n if (frame.conversation.lastSeq === 0) sendUserInfo(cid)\n // startOnChat: the renderer already started on the chat screen\n // (WidgetConfig.startOnChat=true when subjectId + showChatList).\n // No need to call showChatScreen() here — it would be a no-op anyway\n // since inChatScreen is already true, but keeping it explicit:\n if (opts.showChatList && opts.subjectId) renderer.showChatScreen()\n }\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 const isViewingThisChat = opts.showChatList && renderer.isInChatScreen()\n if (!isViewingThisChat) 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 if (cid) renderer.setSeenSeq(cid as string, store.highestSeq())\n })()\n },\n })\n // Seed seenSeq from localStorage so unread state is correct across reloads\n if (opts.showChatList) {\n renderer.initSeenSeq(`${opts.profileId}_${token.slice(-8)}`)\n }\n\n // Inbox-only mode: showChatList=true with no subjectId means this is a\n // standalone messages page. Don't open a WebSocket — just show the list.\n // The WS connects when the user taps a conversation (onSwitchChat below).\n if (opts.showChatList && !opts.subjectId) {\n // List will populate via onListChats. No WS needed yet.\n currentHandle = { close: () => { launcherEl?.remove(); renderer.destroy() } }\n return currentHandle\n }\n\n conn.connect()\n // Show restored 'pending' bubbles (if any) immediately, before the socket opens.\n renderer.render(store)\n\n currentHandle = { close: () => { conn.close(); launcherEl?.remove(); renderer.destroy() } }\n return currentHandle\n}\n\nexport { ChatStore } from './store.js'\nexport { ConnectionManager } from './connection.js'\nexport { Renderer, type ChatListEntry } from './renderer.js'\nexport { asConversationId }\nexport { E2ESession, extractX3DHInit, type X3DHBundle } from './e2e.js'\nexport { PersistentOutbox, type OutboxItem } from './outbox.js'\nexport { restoreHistory, httpBaseFromWsUrl } 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","i","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","k","rank","ConnectionManager","opts","_b","sock","defaultFactory","ev","cap","pending","f","base","max","delay","url","MAX_ITEMS","MAX_AGE_MS","PersistentOutbox","token","raw","items","cutoff","fresh","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","n","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","fmtTime","ts","timeAgo","contentText","Renderer","root","h","cfg","_c","_d","_e","_f","_g","_h","_i","_j","head","avatarEl","img","hm","typingBubble","q","sendBtn","attachBtn","fileInput","inputRow","footer","listScreen","lHead","newBtn","searchWrap","searchIn","listBody","chatScreen","sw","cobrowseClear","fn","saved","parsed","id","seq","conversationId","obj","entries","query","filtered","unread","read","entry","seen","lastSeq","unreadCount","name","initial","row","av","dot","body","stateMap","preview","right","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","cancel","ok","close","panel","inputs","sel","opt","o","inp","sys","mine","isNote","col","bubbleWrap","replyCtx","textNode","links","gLink","iLink","original","translateBtn","cached","menu","editBtn","newText","delBtn","reactWrap","reactRow","emoji","pill","addBtn","picker","pb","alreadyReacted","meta","tick","PAGE","httpBaseFromWsUrl","wsUrl","historyUrl","httpBase","beforeSeq","limit","qs","fetchPage","res","restoreHistory","renderer","page","loading","loadOlder","oldest","page2","scrollEl","armed","onScroll","persistentUid","mount","outbox","cid","outboxRestored","currentHandle","launcherEl","badgeEl","open","isRight","showPanel","show","addUnread","playSound","osc","gain","conn","e2e","e2eStarted","x3dhPending","x3dhBundleFetched","sendSealed","sendSealedX3DH","flushPending","fetchAndX3DH","targetUserId","i18n","rtlLocales","browserLang","file","uploadUrl","mime","actionId","isTyping","messageId","remove","score","translated","_dropSub","_dropTok","rest","openFrame","sendUserInfo","parts","isFirstOpen","toSend","x3dh","prekeyPayload","liveKey"],"mappings":"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","x_google_ignoreList":[1,2,3,4,5,6,7,8,9,10,11,12,13]}
|