@alan-ai/alan-sdk-web 1.8.115 → 1.8.117
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AlanButton.d.ts +1 -0
- package/dist/AlanButtonOptions.d.ts +1 -1
- package/dist/alan_lib.js +149 -34
- package/dist/alan_lib.min.js +1 -1
- package/package.json +1 -1
package/dist/AlanButton.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export interface AlanButtonOptions {
|
|
|
16
16
|
onCommand?: (commandData: object) => void;
|
|
17
17
|
onEvent?: (event: object) => void;
|
|
18
18
|
onButtonState?: (state: string) => void;
|
|
19
|
-
onConnectionStatus?: (status: string) => void;
|
|
19
|
+
onConnectionStatus?: (status: string, event: object) => void;
|
|
20
20
|
textChat?: {
|
|
21
21
|
closeDelay?: number;
|
|
22
22
|
showBtnIfChatOpen?: boolean;
|
package/dist/alan_lib.js
CHANGED
|
@@ -224,10 +224,10 @@
|
|
|
224
224
|
|
|
225
225
|
function ConnectionWrapper() {
|
|
226
226
|
var _this = this;
|
|
227
|
-
this._worker = new Worker(window.URL.createObjectURL(new Blob(["(function(ns) {\n 'use strict';\n\n var SENT_TS = 1;\n var REMOTE_TS = 2;\n var TIMESTAMP = 3;\n var AUDIO_DATA = 4;\n var JSON_DATA = 5;\n\n AlanFrame.fields = [\n propUint64(SENT_TS, 'sentTs'),\n propUint64(REMOTE_TS, 'remoteTs'),\n propUint64(TIMESTAMP, 'timestamp'),\n propBytes(AUDIO_DATA, 'audioData'),\n propJson(JSON_DATA, 'jsonData'),\n ];\n\n function AlanFrameProp(type, name, sizeF, readF, writeF) {\n this.type = type;\n this.name = name;\n this.sizeF = sizeF;\n this.writeF = writeF;\n this.readF = readF;\n }\n\n function fixedSize(size) {\n return function() {\n return size;\n }\n }\n\n function bufferSize(buffer) {\n return 4 + byteLength(buffer);\n }\n\n function writeUIntN(uint8array, value, nBytes, offset) {\n for (var i = 0; i < nBytes; i++ ) {\n uint8array[offset + i] = 0xFF & value;\n value /= 256;\n }\n }\n\n function readUIntN(uint8array, nBytes, offset) {\n var r = 0;\n for (var i = nBytes - 1; i >= 0; i-- ) {\n r *= 256;\n r += 0xFF & uint8array[offset + i];\n }\n return r;\n }\n\n function writeUInt64(uint8array, value, offset) {\n writeUIntN(uint8array, value, 8, offset);\n }\n\n function readUInt64(uint8array, offset) {\n return readUIntN(uint8array, 8, offset);\n }\n\n function writeUInt32(uint8array, value, offset) {\n writeUIntN(uint8array, value, 4, offset);\n }\n\n function readUInt32(uint8array, offset) {\n return readUIntN(uint8array, 4, offset);\n }\n\n function writeBuffer(uint8array, buffer, offset) {\n buffer = toUint8(buffer);\n writeUInt32(uint8array, buffer.length, offset);\n for (var i = 0; i < buffer.length; i++ ) {\n uint8array[offset + 4 + i] = buffer[i];\n }\n }\n\n function readBuffer(uint8array, offset) {\n var size = readUInt32(uint8array, offset);\n if (size > 1024 * 1024) {\n throw new Error('buffer too big');\n }\n return uint8array.subarray(offset + 4, offset + 4 + size);\n }\n\n function readUTF8(uint8array, offset) {\n var size = readUInt32(uint8array, offset);\n if (size > 1024 * 1024) {\n throw new Error('string too big');\n }\n return String.fromCharCode.apply(null, uint8array.slice(offset + 4, offset + 4 + size));\n }\n\n function writeUTF8(uint8array, string, offset) {\n writeUInt32(uint8array, string.length, offset);\n for (var i = 0; i < string.length; i++ ) {\n uint8array[offset + 4 + i] = string.charCodeAt(i);\n }\n }\n\n function sizeUTF8(string) {\n return 4 + string.length;\n }\n\n function propUint32(type, name) {\n return new AlanFrameProp(type, name, fixedSize(4), readUInt32, writeUInt32);\n }\n\n function propUint64(type, name) {\n return new AlanFrameProp(type, name, fixedSize(8), readUInt64, writeUInt64);\n }\n\n function propBytes(type, name) {\n return new AlanFrameProp(type, name, bufferSize, readBuffer, writeBuffer);\n }\n\n function propJson(type, name) {\n return new AlanFrameProp(type, name, sizeUTF8, readUTF8, writeUTF8);\n }\n\n AlanFrame.fieldByType = function(type) {\n for (var i = 0; i < AlanFrame.fields.length; i++ ) {\n var frame = AlanFrame.fields[i];\n if (frame.type === type) {\n return frame;\n }\n }\n throw new Error('invalid field: ' + type);\n };\n\n function AlanFrame() {\n this.version = 1;\n }\n\n AlanFrame.prototype.write = function() {\n var result = new Uint8Array(this.writeSize());\n var offset = 1;\n result[0] = 1;\n for (var i = 0; i < AlanFrame.fields.length; i++ ) {\n var field = AlanFrame.fields[i];\n var value = this[field.name];\n if (value) {\n result[offset++] = field.type;\n field.writeF(result, value, offset);\n offset += field.sizeF(value);\n }\n }\n return result.buffer;\n };\n\n /**\n * @returns UInt8Array\n */\n AlanFrame.prototype.writeSize = function() {\n var size = 1;\n for (var i = 0; i < AlanFrame.fields.length; i++ ) {\n var field = AlanFrame.fields[i];\n var value = this[field.name];\n if (value) {\n size += 1 + field.sizeF(value);\n }\n }\n return size;\n };\n\n AlanFrame.prototype.toString = function() {\n var first = true, str = '';\n for (var k in this) {\n if (this.hasOwnProperty(k)) {\n if (first) {\n str += k + ' = ';\n first = false;\n } else {\n str += ', ' + k + ' = ';\n }\n var v = this[k];\n if (typeof(v) === 'object') {\n str += 'bytes[' + byteLength(v) + ']';\n } else {\n str += v;\n }\n }\n }\n return str;\n };\n\n function byteLength(b) {\n if (b instanceof Uint8Array) {\n return b.length;\n }\n if (b instanceof ArrayBuffer) {\n return b.byteLength;\n }\n }\n\n function toArrayBuffer(buffer) {\n if (buffer instanceof ArrayBuffer) {\n return buffer;\n }\n return buffer.buffer;\n }\n\n function toUint8(buffer) {\n if (buffer instanceof Uint8Array) {\n return buffer;\n }\n if (buffer instanceof ArrayBuffer) {\n return new Uint8Array(buffer);\n }\n throw new Error('invalid buffer type');\n }\n\n function parse(uint8array) {\n uint8array = toUint8(uint8array);\n var r = new AlanFrame();\n var offset = 0;\n r.version = uint8array[offset++];\n while (offset < uint8array.length) {\n var frame = AlanFrame.fieldByType(uint8array[offset++]);\n r[frame.name] = frame.readF(uint8array, offset);\n offset += frame.sizeF(r[frame.name]);\n }\n return r;\n }\n\n ns.create = function() {\n return new AlanFrame();\n };\n\n ns.parse = parse;\n\n})(typeof(window) !== 'undefined' ? (function() {window.alanFrame = {}; return window.alanFrame; })() :\n typeof(WorkerGlobalScope) !== 'undefined' ? (function() {alanFrame = {}; return alanFrame; })() :\n exports);\n\n\n'use strict';\n\n\n\nvar ALAN_OFF = 'off';\nvar ALAN_SPEAKING = 'speaking';\nvar ALAN_LISTENING = 'listening';\n\nfunction ConnectionImpl(config, auth, mode) {\n var _this = this;\n this._config = config;\n this._auth = auth;\n this._mode = mode;\n this._projectId = config.projectId;\n this._url = config.url;\n this._connected = false;\n this._authorized = false;\n this._dialogId = null;\n this._callId = 1;\n this._callSent = {};\n this._callWait = [];\n this._failed = false;\n this._closed = false;\n this._reconnectTimeout = 100;\n this._cleanups = [];\n this._format = null;\n this._formatSent = false;\n this._frameQueue = [];\n this._remoteSentTs = 0;\n this._remoteRecvTs = 0;\n this._rtt = 25;\n this._rttAlpha = 1./16;\n this._alanState = ALAN_OFF;\n this._sendTimer = setInterval(_this._flushQueue.bind(_this), 50);\n this._visualState = {};\n this._addCleanup(function() {clearInterval(_this._sendTimer);});\n this._connect();\n console.log('Alan: connection created');\n}\n\nConnectionImpl.prototype._addCleanup = function(f) {\n this._cleanups.push(f);\n};\n\nConnectionImpl.prototype._onConnectStatus = function(s) {\n console.log('Alan: connection status - ' + s);\n this._fire('connectStatus', s);\n};\n\nConnectionImpl.prototype._fire = function(event, object) {\n if (event === 'options') {\n if (object.versions) {\n object.versions['alanbase:web'] = this._config.version;\n }\n }\n postMessage(['fireEvent', event, object]);\n};\n\nConnectionImpl.prototype._connect = function() {\n var _this = this;\n if (this._socket) {\n console.error('socket is already connected');\n return;\n }\n console.log('Alan: connecting - ' + getConnectionDetails(this._url));\n this._socket = new WebSocket(this._url);\n this._socket.binaryType = 'arraybuffer';\n console.time('Alan: connection time');\n this._socket.onopen = function(e) {\n console.info('Alan: connected');\n _this._connected = true;\n _this._reconnectTimeout = 100;\n _this._fire('connection', {status: 'connected'});\n console.timeEnd('Alan: connection time');\n if (_this._auth) {\n _this._fire('connection', {status: 'authorizing'});\n _this._callAuth();\n } else {\n _this._callWait.forEach(function(c) { _this._sendCall(c); });\n _this._callWait = [];\n _this._onConnectStatus('connected');\n }\n };\n this._socket.onmessage = function(msg) {\n if (msg.data instanceof ArrayBuffer) {\n var f = alanFrame.parse(msg.data);\n if (f.sentTs > 0) {\n _this._remoteSentTs = f.sentTs;\n _this._remoteRecvTs = Date.now();\n } else {\n _this._remoteSentTs = null;\n _this._remoteRecvTs = null;\n }\n var rtt = 0;\n if (f.remoteTs) {\n rtt = Date.now() - f.remoteTs;\n }\n _this._rtt = _this._rttAlpha * rtt + (1 - _this._rttAlpha) * _this._rtt;\n var uint8 = new Uint8Array(f.audioData);\n var frame = uint8;\n postMessage(['alanAudio', 'playFrame', frame]);\n } else if (typeof(msg.data) === 'string') {\n msg = JSON.parse(msg.data);\n if (msg.i) {\n var c = _this._callSent[msg.i];\n delete _this._callSent[msg.i];\n if (c && c.callback) {\n c.callback(msg.e, msg.r);\n }\n } else if (msg.e) {\n if (msg.e === 'text') {\n postMessage(['alanAudio', 'playText', msg.p]);\n } else if (msg.e === 'afterText') {\n postMessage(['alanAudio', 'playAfterText', msg.p]);\n } else if (msg.e === 'showPopup') {\n postMessage(['alanAudio', 'showPopup', msg.p]);\n } else if (msg.e === 'showButtons') {\n postMessage(['alanAudio', 'showButtons', msg.p]);\n } else if (msg.e === 'command') {\n postMessage(['alanAudio', 'playCommand', msg.p]);\n } else if (msg.e === 'inactivity') {\n postMessage(['alanAudio', 'stop']);\n } else {\n _this._fire(msg.e, msg.p);\n }\n }\n } else {\n console.error('invalid message type');\n }\n };\n this._socket.onerror = function(evt) {\n _this._onConnectStatus('error');\n console.error('Alan: connection closed due to error: ', evt);\n };\n this._socket.onclose = function(evt) {\n console.info('Alan: connection closed');\n _this._connected = false;\n _this._authorized = false;\n _this._socket = null;\n _this._onConnectStatus('disconnected');\n if (!_this._failed && _this._reconnectTimeout && !_this._closed) {\n console.log('Alan: reconnecting in %s ms.', _this._reconnectTimeout);\n _this._reConnect = setTimeout(_this._connect.bind(_this), _this._reconnectTimeout);\n if (_this._reconnectTimeout < 3000) {\n _this._reconnectTimeout *= 2;\n } else {\n _this._reconnectTimeout += 500;\n }\n _this._reconnectTimeout = Math.min(7000, _this._reconnectTimeout);\n }\n };\n this._addCleanup(function() {\n if (this._socket) {\n this._socket.close();\n this._socket = null;\n }\n });\n};\n\nConnectionImpl.prototype._callAuth = function() {\n var _this = this;\n var callback = function(err, r) {\n if (!err && r.status === 'authorized') {\n _this._authorized = true;\n _this._formatSent = false;\n if (r.dialogId) {\n postMessage(['setDialogId', r.dialogId]);\n _this._dialogId = r.dialogId;\n }\n _this._onAuthorized();\n _this._onConnectStatus('authorized');\n } else if (err === 'auth-failed') {\n _this._onConnectStatus('auth-failed');\n if (_this._socket) {\n _this._socket.close();\n _this._socket = null;\n _this._failed = true;\n }\n } else {\n _this._onConnectStatus('invalid-auth-response');\n console.log('Alan: invalid auth response', err, r);\n }\n };\n var authParam = this._auth;\n authParam.timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n if (this._dialogId) {\n authParam.dialogId = this._dialogId;\n }\n authParam.mode = this._mode;\n this._sendCall({cid: this._callId++, method: '_auth_', callback: callback, param: authParam});\n return this;\n};\n\nConnectionImpl.prototype._sendCall = function(call) {\n this._sendFormatIfNeeded(false);\n this._socket.send(JSON.stringify({i: call.cid, m: call.method, p: call.param}));\n if (call.callback) {\n this._callSent[call.cid] = call;\n }\n};\n\nConnectionImpl.prototype._onAuthorized = function() {\n var _this = this;\n this._callWait.forEach(function(c) {\n _this._sendCall(c);\n });\n this._callWait = [];\n};\n\nConnectionImpl.prototype.close = function() {\n for (var i = 0; i < this._cleanups.length; i++ ) {\n this._cleanups[i]();\n }\n this._cleanups = [];\n this._closed = true;\n \n if (this._socket && (this._socket.readyState === WebSocket.OPEN || this._socket.readyState === WebSocket.CONNECTING)) {\n this._socket.close();\n this._socket = null;\n }\n console.log('Alan: closed connection to: ' + getConnectionDetails(this._url));\n //close(); TODO: delete it!\n};\n\nConnectionImpl.prototype.call = function(cid, method, param) {\n var call = {cid: cid, method: method, param: param, callback: function(err, obj) {\n if (cid) {\n postMessage(['callback', cid, err, obj]);\n }\n }};\n if (this._authorized || this._connected && !this._auth) {\n this._sendCall(call);\n } else {\n this._callWait.push(call);\n }\n};\n\nConnectionImpl.prototype.setVisual = function(state) {\n this._visualState = state;\n this.call(null, '_visual_', state);\n};\n\nConnectionImpl.prototype._sendFrame = function(frame) {\n if (!this._socket) {\n console.error('sendFrame to closed socket');\n return;\n }\n frame.sentTs = Date.now();\n if (this._remoteSentTs > 0 && this._remoteRecvTs > 0) {\n frame.remoteTs = this._remoteSentTs + Date.now() - this._remoteRecvTs;\n }\n this._socket.send(frame.write());\n};\n\nConnectionImpl.prototype._listen = function() {\n var f = alanFrame.create();\n f.jsonData = JSON.stringify({signal: 'listen'});\n this._frameQueue.push(f);\n this._alanState = ALAN_LISTENING;\n};\n\nConnectionImpl.prototype._stopListen = function() {\n var f = alanFrame.create();\n f.jsonData = JSON.stringify({signal: 'stopListen'});\n this._frameQueue.push(f);\n this._alanState = ALAN_OFF;\n};\n\nConnectionImpl.prototype._onAudioFormat = function(format) {\n this._formatSent = false;\n this._format = format;\n};\n\nConnectionImpl.prototype._onMicFrame = function(sampleRate, frame) {\n if (this._alanState === ALAN_SPEAKING) {\n return;\n }\n if (this._alanState === ALAN_OFF) {\n this._listen();\n }\n if (this._alanState !== ALAN_LISTENING) {\n console.error('invalid alan state: ' + this._alanState);\n return;\n }\n this._sendFormatIfNeeded(true);\n var f = alanFrame.create();\n f.audioData = frame;\n this._frameQueue.push(f);\n};\n\nConnectionImpl.prototype._sendFormatIfNeeded = function(inQueue) {\n if (!this._format || this._formatSent) {\n return;\n }\n this._formatSent = true;\n var f = alanFrame.create();\n f.jsonData = JSON.stringify({format: this._format});\n if (inQueue) {\n this._frameQueue.push(f);\n } else {\n this._sendFrame(f);\n }\n};\n\nConnectionImpl.prototype._flushQueue = function() {\n if (!this._socket || !this._connected) {\n var d = 0;\n while (this._frameQueue.length > 100 && !this._frameQueue[0].jsonData) {\n this._frameQueue.shift();\n d++;\n }\n if (d > 0) {\n console.error('dropped: %s, frames', d);\n }\n return;\n }\n while (this._frameQueue.length > 0 && this._socket && this._socket.bufferedAmount < 64 * 1024) {\n this._sendFrame(this._frameQueue.shift());\n }\n};\n\nfunction getConnectionDetails(url){\n var urlParts = url.split('/');\n var host = urlParts[2];\n \n // Find the index of 'ws_project' in the URL parts\n var wsProjectIndex = -1;\n for (var i = 0; i < urlParts.length; i++) {\n if (urlParts[i] === 'ws_project') {\n wsProjectIndex = i;\n break;\n }\n }\n \n var projectId = wsProjectIndex !== -1 ? urlParts[wsProjectIndex + 1] : null;\n var environment = wsProjectIndex !== -1 ? urlParts[wsProjectIndex + 2] : null;\n\n if (projectId && environment && host) {\n return ' (ProjectID: ' + projectId + ', environment: ' + environment + ', host: ' + host + ')';\n }\n\n return url;\n}\n\nfunction connectProject(config, auth, mode) {\n var c = new ConnectionImpl(config, auth, mode);\n c.onAudioEvent = function(event, arg1, arg2) {\n if (event === 'format') {\n c._onAudioFormat(arg1);\n } else if (event === 'frame') {\n c._onMicFrame(arg1, arg2);\n } else if (event === 'micStop') {\n c._stopListen();\n } else if (event === 'playStart') {\n // ignore\n } else {\n console.error('unknown audio event: ' + event, arg1, arg2);\n }\n };\n return c;\n}\n\nvar factories = {\n connectProject: connectProject,\n};\n\nvar currentConnect = null;\n\nonmessage = function(e) {\n var name = e.data[0];\n try {\n if (!currentConnect) {\n currentConnect = factories[name].apply(null, e.data.slice(1, e.data.length));\n } else {\n currentConnect[name].apply(currentConnect, e.data.slice(1, e.data.length));\n }\n } catch(e) {\n console.error('error calling: ' + name, e);\n }\n};\n"], {type: 'text/javascript'})));
|
|
227
|
+
this._worker = new Worker(window.URL.createObjectURL(new Blob(["(function(ns) {\n 'use strict';\n\n var SENT_TS = 1;\n var REMOTE_TS = 2;\n var TIMESTAMP = 3;\n var AUDIO_DATA = 4;\n var JSON_DATA = 5;\n\n AlanFrame.fields = [\n propUint64(SENT_TS, 'sentTs'),\n propUint64(REMOTE_TS, 'remoteTs'),\n propUint64(TIMESTAMP, 'timestamp'),\n propBytes(AUDIO_DATA, 'audioData'),\n propJson(JSON_DATA, 'jsonData'),\n ];\n\n function AlanFrameProp(type, name, sizeF, readF, writeF) {\n this.type = type;\n this.name = name;\n this.sizeF = sizeF;\n this.writeF = writeF;\n this.readF = readF;\n }\n\n function fixedSize(size) {\n return function() {\n return size;\n }\n }\n\n function bufferSize(buffer) {\n return 4 + byteLength(buffer);\n }\n\n function writeUIntN(uint8array, value, nBytes, offset) {\n for (var i = 0; i < nBytes; i++ ) {\n uint8array[offset + i] = 0xFF & value;\n value /= 256;\n }\n }\n\n function readUIntN(uint8array, nBytes, offset) {\n var r = 0;\n for (var i = nBytes - 1; i >= 0; i-- ) {\n r *= 256;\n r += 0xFF & uint8array[offset + i];\n }\n return r;\n }\n\n function writeUInt64(uint8array, value, offset) {\n writeUIntN(uint8array, value, 8, offset);\n }\n\n function readUInt64(uint8array, offset) {\n return readUIntN(uint8array, 8, offset);\n }\n\n function writeUInt32(uint8array, value, offset) {\n writeUIntN(uint8array, value, 4, offset);\n }\n\n function readUInt32(uint8array, offset) {\n return readUIntN(uint8array, 4, offset);\n }\n\n function writeBuffer(uint8array, buffer, offset) {\n buffer = toUint8(buffer);\n writeUInt32(uint8array, buffer.length, offset);\n for (var i = 0; i < buffer.length; i++ ) {\n uint8array[offset + 4 + i] = buffer[i];\n }\n }\n\n function readBuffer(uint8array, offset) {\n var size = readUInt32(uint8array, offset);\n if (size > 1024 * 1024) {\n throw new Error('buffer too big');\n }\n return uint8array.subarray(offset + 4, offset + 4 + size);\n }\n\n function readUTF8(uint8array, offset) {\n var size = readUInt32(uint8array, offset);\n if (size > 1024 * 1024) {\n throw new Error('string too big');\n }\n return String.fromCharCode.apply(null, uint8array.slice(offset + 4, offset + 4 + size));\n }\n\n function writeUTF8(uint8array, string, offset) {\n writeUInt32(uint8array, string.length, offset);\n for (var i = 0; i < string.length; i++ ) {\n uint8array[offset + 4 + i] = string.charCodeAt(i);\n }\n }\n\n function sizeUTF8(string) {\n return 4 + string.length;\n }\n\n function propUint32(type, name) {\n return new AlanFrameProp(type, name, fixedSize(4), readUInt32, writeUInt32);\n }\n\n function propUint64(type, name) {\n return new AlanFrameProp(type, name, fixedSize(8), readUInt64, writeUInt64);\n }\n\n function propBytes(type, name) {\n return new AlanFrameProp(type, name, bufferSize, readBuffer, writeBuffer);\n }\n\n function propJson(type, name) {\n return new AlanFrameProp(type, name, sizeUTF8, readUTF8, writeUTF8);\n }\n\n AlanFrame.fieldByType = function(type) {\n for (var i = 0; i < AlanFrame.fields.length; i++ ) {\n var frame = AlanFrame.fields[i];\n if (frame.type === type) {\n return frame;\n }\n }\n throw new Error('invalid field: ' + type);\n };\n\n function AlanFrame() {\n this.version = 1;\n }\n\n AlanFrame.prototype.write = function() {\n var result = new Uint8Array(this.writeSize());\n var offset = 1;\n result[0] = 1;\n for (var i = 0; i < AlanFrame.fields.length; i++ ) {\n var field = AlanFrame.fields[i];\n var value = this[field.name];\n if (value) {\n result[offset++] = field.type;\n field.writeF(result, value, offset);\n offset += field.sizeF(value);\n }\n }\n return result.buffer;\n };\n\n /**\n * @returns UInt8Array\n */\n AlanFrame.prototype.writeSize = function() {\n var size = 1;\n for (var i = 0; i < AlanFrame.fields.length; i++ ) {\n var field = AlanFrame.fields[i];\n var value = this[field.name];\n if (value) {\n size += 1 + field.sizeF(value);\n }\n }\n return size;\n };\n\n AlanFrame.prototype.toString = function() {\n var first = true, str = '';\n for (var k in this) {\n if (this.hasOwnProperty(k)) {\n if (first) {\n str += k + ' = ';\n first = false;\n } else {\n str += ', ' + k + ' = ';\n }\n var v = this[k];\n if (typeof(v) === 'object') {\n str += 'bytes[' + byteLength(v) + ']';\n } else {\n str += v;\n }\n }\n }\n return str;\n };\n\n function byteLength(b) {\n if (b instanceof Uint8Array) {\n return b.length;\n }\n if (b instanceof ArrayBuffer) {\n return b.byteLength;\n }\n }\n\n function toArrayBuffer(buffer) {\n if (buffer instanceof ArrayBuffer) {\n return buffer;\n }\n return buffer.buffer;\n }\n\n function toUint8(buffer) {\n if (buffer instanceof Uint8Array) {\n return buffer;\n }\n if (buffer instanceof ArrayBuffer) {\n return new Uint8Array(buffer);\n }\n throw new Error('invalid buffer type');\n }\n\n function parse(uint8array) {\n uint8array = toUint8(uint8array);\n var r = new AlanFrame();\n var offset = 0;\n r.version = uint8array[offset++];\n while (offset < uint8array.length) {\n var frame = AlanFrame.fieldByType(uint8array[offset++]);\n r[frame.name] = frame.readF(uint8array, offset);\n offset += frame.sizeF(r[frame.name]);\n }\n return r;\n }\n\n ns.create = function() {\n return new AlanFrame();\n };\n\n ns.parse = parse;\n\n})(typeof(window) !== 'undefined' ? (function() {window.alanFrame = {}; return window.alanFrame; })() :\n typeof(WorkerGlobalScope) !== 'undefined' ? (function() {alanFrame = {}; return alanFrame; })() :\n exports);\n\n\n'use strict';\n\n\n\nvar ALAN_OFF = 'off';\nvar ALAN_SPEAKING = 'speaking';\nvar ALAN_LISTENING = 'listening';\n\nfunction ConnectionImpl(config, auth, mode) {\n var _this = this;\n this._config = config;\n this._auth = auth;\n this._mode = mode;\n this._projectId = config.projectId;\n this._url = config.url;\n this._connected = false;\n this._authorized = false;\n this._dialogId = null;\n this._callId = 1;\n this._callSent = {};\n this._callWait = [];\n this._failed = false;\n this._closed = false;\n this._reconnectTimeout = 100;\n this._cleanups = [];\n this._format = null;\n this._formatSent = false;\n this._frameQueue = [];\n this._remoteSentTs = 0;\n this._remoteRecvTs = 0;\n this._rtt = 25;\n this._rttAlpha = 1./16;\n this._alanState = ALAN_OFF;\n this._sendTimer = setInterval(_this._flushQueue.bind(_this), 50);\n this._visualState = {};\n this._addCleanup(function() {clearInterval(_this._sendTimer);});\n this._connect();\n console.log('Alan: connection created');\n}\n\nConnectionImpl.prototype._addCleanup = function(f) {\n this._cleanups.push(f);\n};\n\nConnectionImpl.prototype._onConnectStatus = function(s, evt) {\n console.log('Alan: connection status - ' + s);\n this._fire('connectStatus', s, evt ? {\n code: evt.code,\n reason: evt.reason,\n wasClean: evt.wasClean,\n } : {});\n};\n\nConnectionImpl.prototype._fire = function(event, object, data) {\n if (event === 'options') {\n if (object.versions) {\n object.versions['alanbase:web'] = this._config.version;\n }\n }\n postMessage(['fireEvent', event, object, data]);\n};\n\nConnectionImpl.prototype._connect = function() {\n var _this = this;\n if (this._socket) {\n console.error('socket is already connected');\n return;\n }\n console.log('Alan: connecting - ' + getConnectionDetails(this._url));\n this._socket = new WebSocket(this._url);\n this._socket.binaryType = 'arraybuffer';\n console.time('Alan: connection time');\n this._socket.onopen = function(e) {\n console.info('Alan: connected');\n _this._connected = true;\n _this._reconnectTimeout = 100;\n _this._fire('connection', {status: 'connected'});\n console.timeEnd('Alan: connection time');\n if (_this._auth) {\n _this._fire('connection', {status: 'authorizing'});\n _this._callAuth();\n } else {\n _this._callWait.forEach(function(c) { _this._sendCall(c); });\n _this._callWait = [];\n _this._onConnectStatus('connected');\n }\n };\n this._socket.onmessage = function(msg) {\n if (msg.data instanceof ArrayBuffer) {\n var f = alanFrame.parse(msg.data);\n if (f.sentTs > 0) {\n _this._remoteSentTs = f.sentTs;\n _this._remoteRecvTs = Date.now();\n } else {\n _this._remoteSentTs = null;\n _this._remoteRecvTs = null;\n }\n var rtt = 0;\n if (f.remoteTs) {\n rtt = Date.now() - f.remoteTs;\n }\n _this._rtt = _this._rttAlpha * rtt + (1 - _this._rttAlpha) * _this._rtt;\n var uint8 = new Uint8Array(f.audioData);\n var frame = uint8;\n postMessage(['alanAudio', 'playFrame', frame]);\n } else if (typeof(msg.data) === 'string') {\n msg = JSON.parse(msg.data);\n if (msg.i) {\n var c = _this._callSent[msg.i];\n delete _this._callSent[msg.i];\n if (c && c.callback) {\n c.callback(msg.e, msg.r);\n }\n } else if (msg.e) {\n if (msg.e === 'text') {\n postMessage(['alanAudio', 'playText', msg.p]);\n } else if (msg.e === 'afterText') {\n postMessage(['alanAudio', 'playAfterText', msg.p]);\n } else if (msg.e === 'showPopup') {\n postMessage(['alanAudio', 'showPopup', msg.p]);\n } else if (msg.e === 'showButtons') {\n postMessage(['alanAudio', 'showButtons', msg.p]);\n } else if (msg.e === 'command') {\n postMessage(['alanAudio', 'playCommand', msg.p]);\n } else if (msg.e === 'inactivity') {\n postMessage(['alanAudio', 'stop']);\n } else {\n _this._fire(msg.e, msg.p);\n }\n }\n } else {\n console.error('invalid message type');\n }\n };\n this._socket.onerror = function(evt) {\n _this._onConnectStatus('error', evt);\n console.error('Alan: connection closed due to error: ', evt);\n };\n this._socket.onclose = function(evt) {\n console.info('Alan: connection closed');\n _this._connected = false;\n _this._authorized = false;\n _this._socket = null;\n _this._onConnectStatus('disconnected', evt);\n if (!_this._failed && _this._reconnectTimeout && !_this._closed) {\n console.log('Alan: reconnecting in %s ms.', _this._reconnectTimeout);\n _this._reConnect = setTimeout(_this._connect.bind(_this), _this._reconnectTimeout);\n if (_this._reconnectTimeout < 3000) {\n _this._reconnectTimeout *= 2;\n } else {\n _this._reconnectTimeout += 500;\n }\n _this._reconnectTimeout = Math.min(7000, _this._reconnectTimeout);\n }\n };\n this._addCleanup(function() {\n if (this._socket) {\n this._socket.close();\n this._socket = null;\n }\n });\n};\n\nConnectionImpl.prototype._callAuth = function() {\n var _this = this;\n var callback = function(err, r) {\n if (!err && r.status === 'authorized') {\n _this._authorized = true;\n _this._formatSent = false;\n if (r.dialogId) {\n postMessage(['setDialogId', r.dialogId]);\n _this._dialogId = r.dialogId;\n }\n _this._onAuthorized();\n _this._onConnectStatus('authorized');\n } else if (err === 'auth-failed') {\n _this._onConnectStatus('auth-failed');\n if (_this._socket) {\n _this._socket.close();\n _this._socket = null;\n _this._failed = true;\n }\n } else {\n _this._onConnectStatus('invalid-auth-response');\n console.log('Alan: invalid auth response', err, r);\n }\n };\n var authParam = this._auth;\n authParam.timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n if (this._dialogId) {\n authParam.dialogId = this._dialogId;\n }\n authParam.mode = this._mode;\n this._sendCall({cid: this._callId++, method: '_auth_', callback: callback, param: authParam});\n return this;\n};\n\nConnectionImpl.prototype._sendCall = function(call) {\n this._sendFormatIfNeeded(false);\n this._socket.send(JSON.stringify({i: call.cid, m: call.method, p: call.param}));\n if (call.callback) {\n this._callSent[call.cid] = call;\n }\n};\n\nConnectionImpl.prototype._onAuthorized = function() {\n var _this = this;\n this._callWait.forEach(function(c) {\n _this._sendCall(c);\n });\n this._callWait = [];\n};\n\nConnectionImpl.prototype.close = function() {\n for (var i = 0; i < this._cleanups.length; i++ ) {\n this._cleanups[i]();\n }\n this._cleanups = [];\n this._closed = true;\n \n if (this._socket && (this._socket.readyState === WebSocket.OPEN || this._socket.readyState === WebSocket.CONNECTING)) {\n this._socket.close();\n this._socket = null;\n }\n console.log('Alan: closed connection to: ' + getConnectionDetails(this._url));\n //close(); TODO: delete it!\n};\n\nConnectionImpl.prototype.call = function(cid, method, param) {\n var call = {cid: cid, method: method, param: param, callback: function(err, obj) {\n if (cid) {\n postMessage(['callback', cid, err, obj]);\n }\n }};\n if (this._authorized || this._connected && !this._auth) {\n this._sendCall(call);\n } else {\n this._callWait.push(call);\n }\n};\n\nConnectionImpl.prototype.setVisual = function(state) {\n this._visualState = state;\n this.call(null, '_visual_', state);\n};\n\nConnectionImpl.prototype._sendFrame = function(frame) {\n if (!this._socket) {\n console.error('sendFrame to closed socket');\n return;\n }\n frame.sentTs = Date.now();\n if (this._remoteSentTs > 0 && this._remoteRecvTs > 0) {\n frame.remoteTs = this._remoteSentTs + Date.now() - this._remoteRecvTs;\n }\n this._socket.send(frame.write());\n};\n\nConnectionImpl.prototype._listen = function() {\n var f = alanFrame.create();\n f.jsonData = JSON.stringify({signal: 'listen'});\n this._frameQueue.push(f);\n this._alanState = ALAN_LISTENING;\n};\n\nConnectionImpl.prototype._stopListen = function() {\n var f = alanFrame.create();\n f.jsonData = JSON.stringify({signal: 'stopListen'});\n this._frameQueue.push(f);\n this._alanState = ALAN_OFF;\n};\n\nConnectionImpl.prototype._onAudioFormat = function(format) {\n this._formatSent = false;\n this._format = format;\n};\n\nConnectionImpl.prototype._onMicFrame = function(sampleRate, frame) {\n if (this._alanState === ALAN_SPEAKING) {\n return;\n }\n if (this._alanState === ALAN_OFF) {\n this._listen();\n }\n if (this._alanState !== ALAN_LISTENING) {\n console.error('invalid alan state: ' + this._alanState);\n return;\n }\n this._sendFormatIfNeeded(true);\n var f = alanFrame.create();\n f.audioData = frame;\n this._frameQueue.push(f);\n};\n\nConnectionImpl.prototype._sendFormatIfNeeded = function(inQueue) {\n if (!this._format || this._formatSent) {\n return;\n }\n this._formatSent = true;\n var f = alanFrame.create();\n f.jsonData = JSON.stringify({format: this._format});\n if (inQueue) {\n this._frameQueue.push(f);\n } else {\n this._sendFrame(f);\n }\n};\n\nConnectionImpl.prototype._flushQueue = function() {\n if (!this._socket || !this._connected) {\n var d = 0;\n while (this._frameQueue.length > 100 && !this._frameQueue[0].jsonData) {\n this._frameQueue.shift();\n d++;\n }\n if (d > 0) {\n console.error('dropped: %s, frames', d);\n }\n return;\n }\n while (this._frameQueue.length > 0 && this._socket && this._socket.bufferedAmount < 64 * 1024) {\n this._sendFrame(this._frameQueue.shift());\n }\n};\n\nfunction getConnectionDetails(url){\n var urlParts = url.split('/');\n var host = urlParts[2];\n \n // Find the index of 'ws_project' in the URL parts\n var wsProjectIndex = -1;\n for (var i = 0; i < urlParts.length; i++) {\n if (urlParts[i] === 'ws_project') {\n wsProjectIndex = i;\n break;\n }\n }\n \n var projectId = wsProjectIndex !== -1 ? urlParts[wsProjectIndex + 1] : null;\n var environment = wsProjectIndex !== -1 ? urlParts[wsProjectIndex + 2] : null;\n\n if (projectId && environment && host) {\n return ' (ProjectID: ' + projectId + ', environment: ' + environment + ', host: ' + host + ')';\n }\n\n return url;\n}\n\nfunction connectProject(config, auth, mode) {\n var c = new ConnectionImpl(config, auth, mode);\n c.onAudioEvent = function(event, arg1, arg2) {\n if (event === 'format') {\n c._onAudioFormat(arg1);\n } else if (event === 'frame') {\n c._onMicFrame(arg1, arg2);\n } else if (event === 'micStop') {\n c._stopListen();\n } else if (event === 'playStart') {\n // ignore\n } else {\n console.error('unknown audio event: ' + event, arg1, arg2);\n }\n };\n return c;\n}\n\nvar factories = {\n connectProject: connectProject,\n};\n\nvar currentConnect = null;\n\nonmessage = function(e) {\n var name = e.data[0];\n try {\n if (!currentConnect) {\n currentConnect = factories[name].apply(null, e.data.slice(1, e.data.length));\n } else {\n currentConnect[name].apply(currentConnect, e.data.slice(1, e.data.length));\n }\n } catch(e) {\n console.error('error calling: ' + name, e);\n }\n};\n"], {type: 'text/javascript'})));
|
|
228
228
|
this._worker.onmessage = function(e) {
|
|
229
229
|
if (e.data[0] === 'fireEvent') {
|
|
230
|
-
_this._fire(e.data[1], e.data[2]);
|
|
230
|
+
_this._fire(e.data[1], e.data[2], e.data[3]);
|
|
231
231
|
return;
|
|
232
232
|
}
|
|
233
233
|
if (e.data[0] === 'alanAudio') {
|
|
@@ -328,11 +328,11 @@
|
|
|
328
328
|
this._worker.terminate();
|
|
329
329
|
};
|
|
330
330
|
|
|
331
|
-
ConnectionWrapper.prototype._fire = function(event, object) {
|
|
331
|
+
ConnectionWrapper.prototype._fire = function(event, object, data) {
|
|
332
332
|
var h = this._handlers[event];
|
|
333
333
|
if (h) {
|
|
334
334
|
for (var i = 0; i < h.length; i++ ) {
|
|
335
|
-
h[i](object);
|
|
335
|
+
h[i](object, data);
|
|
336
336
|
}
|
|
337
337
|
}
|
|
338
338
|
};
|
|
@@ -98082,6 +98082,9 @@
|
|
|
98082
98082
|
opacity:0.8;
|
|
98083
98083
|
}`;
|
|
98084
98084
|
}
|
|
98085
|
+
keyFrames += getStyleSheetMarker() + `.alan-btn__chat-send-btn.alan-btn__disconnected {
|
|
98086
|
+
pointer-events: none!important;
|
|
98087
|
+
}`;
|
|
98085
98088
|
keyFrames += getStyleSheetMarker() + `.alan-btn__chat-mic-btn {
|
|
98086
98089
|
position: absolute;
|
|
98087
98090
|
left: 0px;
|
|
@@ -98875,7 +98878,9 @@
|
|
|
98875
98878
|
width:${likeDislikeBtnWidth}px;
|
|
98876
98879
|
min-width:${likeDislikeBtnWidth}px;
|
|
98877
98880
|
height:${likeDislikeBtnHeight}px;
|
|
98881
|
+
max-height:${likeDislikeBtnHeight}px;
|
|
98878
98882
|
min-height:${likeDislikeBtnHeight}px;
|
|
98883
|
+
overflow: hidden;
|
|
98879
98884
|
` : ``};
|
|
98880
98885
|
|
|
98881
98886
|
}`;
|
|
@@ -98888,7 +98893,9 @@
|
|
|
98888
98893
|
width:${likeDislikeBtnWidth}px;
|
|
98889
98894
|
min-width:${likeDislikeBtnWidth}px;
|
|
98890
98895
|
height:${likeDislikeBtnHeight}px;
|
|
98896
|
+
max-height:${likeDislikeBtnHeight}px;
|
|
98891
98897
|
min-height:${likeDislikeBtnHeight}px;
|
|
98898
|
+
overflow: hidden;
|
|
98892
98899
|
` : ``};
|
|
98893
98900
|
}`;
|
|
98894
98901
|
keyFrames += styleSheetMarker + `.alan-btn__chat-response__copy-btn {
|
|
@@ -98900,7 +98907,9 @@
|
|
|
98900
98907
|
width:${copyBtnWidth}px;
|
|
98901
98908
|
min-width:${copyBtnWidth}px;
|
|
98902
98909
|
height:${copyBtnHeight}px;
|
|
98910
|
+
max-height:${copyBtnHeight}px;
|
|
98903
98911
|
min-height:${copyBtnHeight}px;
|
|
98912
|
+
overflow: hidden;
|
|
98904
98913
|
` : ``};
|
|
98905
98914
|
}`;
|
|
98906
98915
|
const bottomBtnsBgColor = textChatOptions?.bubbles?.response?.bottomBtns?.backgroundColor?.hover || `#dcddde`;
|
|
@@ -98919,14 +98928,17 @@
|
|
|
98919
98928
|
keyFrames += styleSheetMarker + `.alan-btn__chat-response__copy-btn svg {
|
|
98920
98929
|
width: 20px;
|
|
98921
98930
|
}`;
|
|
98922
|
-
|
|
98923
|
-
|
|
98931
|
+
const customCopyIcon = textChatOptions?.bubbles?.response?.copyBtnAppearance?.default?.icon?.svg || textChatOptions?.bubbles?.response?.copyBtnAppearance?.selected?.icon?.svg;
|
|
98932
|
+
keyFrames += styleSheetMarker + ` .alan-btn__chat-response__copy-btn:not(.preview) svg path {
|
|
98933
|
+
fill: ${bottomBtnsColor};
|
|
98924
98934
|
}`;
|
|
98925
|
-
|
|
98926
|
-
|
|
98935
|
+
const customLikeIcon = textChatOptions?.bubbles?.response?.likeBtnAppearance?.default?.icon?.svg || textChatOptions?.bubbles?.response?.likeBtnAppearance?.selected?.icon?.svg;
|
|
98936
|
+
const customDislikeIcon = textChatOptions?.bubbles?.response?.dislikeBtnAppearance?.default?.icon?.svg || textChatOptions?.bubbles?.response?.dislikeBtnAppearance?.selected?.icon?.svg;
|
|
98937
|
+
keyFrames += styleSheetMarker + ` .alan-btn__chat-response__like-btn:not(.preview) svg path {
|
|
98938
|
+
fill: ${bottomBtnsColor};
|
|
98927
98939
|
}`;
|
|
98928
|
-
keyFrames += styleSheetMarker +
|
|
98929
|
-
|
|
98940
|
+
keyFrames += styleSheetMarker + ` .alan-btn__chat-response__dislike-btn:not(.preview) svg path {
|
|
98941
|
+
fill: ${bottomBtnsColor};
|
|
98930
98942
|
}`;
|
|
98931
98943
|
keyFrames += styleSheetMarker + `.alan-btn__chat-graph {
|
|
98932
98944
|
display: none;
|
|
@@ -101024,24 +101036,46 @@ code.hljs {
|
|
|
101024
101036
|
}
|
|
101025
101037
|
|
|
101026
101038
|
// alan_btn/src/textChat/buildCommandsBlock.ts
|
|
101027
|
-
function buildCommandsBlock(msg, textChatOptions) {
|
|
101039
|
+
function buildCommandsBlock(msg, textChatOptions, customClasses = "") {
|
|
101028
101040
|
const isBlockVisible = msg.ctx?.enableFeedback || textChatOptions?.bubbles?.response?.copyBtn;
|
|
101029
101041
|
return `<div class="alan-btn__chat-response-commands-wrapper ${isBlockVisible !== true ? "alan-btn__chat-response-commands-wrapper-hidden" : ""}">
|
|
101030
101042
|
<div class="alan-btn__chat-response-commands-wrapper-content">
|
|
101031
|
-
${buildCopyBtnContent(msg)}
|
|
101043
|
+
${buildCopyBtnContent(msg, textChatOptions, customClasses)}
|
|
101032
101044
|
${msg.ctx?.enableFeedback ? `
|
|
101033
|
-
<span class="alan-btn__chat-response__like-btn ${msg.liked >= 1 ? "selected" : ""}">${getLikeSvgIcon(msg)}</span>
|
|
101034
|
-
<span class="alan-btn__chat-response__dislike-btn ${msg.liked <= -1 ? "selected" : ""}">${getDislikeSvgIcon(msg)}</span>` : ""}
|
|
101045
|
+
<span class="alan-btn__chat-response__like-btn ${customClasses} ${msg.liked >= 1 ? "selected" : ""}">${getLikeSvgIcon(msg, textChatOptions)}</span>
|
|
101046
|
+
<span class="alan-btn__chat-response__dislike-btn ${customClasses} ${msg.liked <= -1 ? "selected" : ""}">${getDislikeSvgIcon(msg, textChatOptions)}</span>` : ""}
|
|
101035
101047
|
</div></div>`;
|
|
101036
101048
|
}
|
|
101037
|
-
function getLikeSvgIcon(msg) {
|
|
101038
|
-
|
|
101049
|
+
function getLikeSvgIcon(msg, textChatOptions) {
|
|
101050
|
+
const likeIcon = textChatOptions?.bubbles?.response?.likeBtnAppearance?.default?.icon?.svg || chatIcons.like;
|
|
101051
|
+
const likeIconSelected = textChatOptions?.bubbles?.response?.likeBtnAppearance?.selected?.icon?.svg || chatIcons.likeSelected;
|
|
101052
|
+
return msg.liked === 1 ? likeIconSelected : likeIcon;
|
|
101053
|
+
}
|
|
101054
|
+
function getDislikeSvgIcon(msg, textChatOptions) {
|
|
101055
|
+
const dislikeIcon = textChatOptions?.bubbles?.response?.dislikeBtnAppearance?.default?.icon?.svg || chatIcons.dislike;
|
|
101056
|
+
const dislikeIconSelected = textChatOptions?.bubbles?.response?.dislikeBtnAppearance?.selected?.icon?.svg || chatIcons.dislikeSelected;
|
|
101057
|
+
return msg.liked === -1 ? dislikeIconSelected : dislikeIcon;
|
|
101058
|
+
}
|
|
101059
|
+
function setSvgClass(svg, className) {
|
|
101060
|
+
if (!svg || typeof svg !== "string") return "";
|
|
101061
|
+
if (/class\s*=\s*["'][^"']*["']/i.test(svg)) {
|
|
101062
|
+
return svg.replace(/class\s*=\s*(["'])([^"']*)\1/i, (match, quote, classes) => {
|
|
101063
|
+
if ((classes || "").split(/\s+/).includes(className)) return match;
|
|
101064
|
+
return `class=${quote}${className} ${classes}${quote}`;
|
|
101065
|
+
});
|
|
101066
|
+
}
|
|
101067
|
+
return svg.replace(/<svg\b/i, `<svg class="${className}"`);
|
|
101039
101068
|
}
|
|
101040
|
-
function
|
|
101041
|
-
|
|
101069
|
+
function getCopySvgIcon(textChatOptions) {
|
|
101070
|
+
const copyIcon = textChatOptions?.bubbles?.response?.copyBtnAppearance?.default?.icon?.svg || chatIcons.copy;
|
|
101071
|
+
return setSvgClass(copyIcon, "alan-btn__copy-icon");
|
|
101042
101072
|
}
|
|
101043
|
-
function
|
|
101044
|
-
const
|
|
101073
|
+
function getCopiedSvgIcon(textChatOptions) {
|
|
101074
|
+
const copiedIcon = textChatOptions?.bubbles?.response?.copyBtnAppearance?.selected?.icon?.svg || chatIcons.copied;
|
|
101075
|
+
return setSvgClass(copiedIcon, "alan-btn__copied-icon");
|
|
101076
|
+
}
|
|
101077
|
+
function buildCopyBtnContent(msg, textChatOptions, customClasses) {
|
|
101078
|
+
const copyBtn = `<div class = "alan-btn__chat-response__copy-btn ${customClasses}">${getCopySvgIcon(textChatOptions)}${getCopiedSvgIcon(textChatOptions)}</div>`;
|
|
101045
101079
|
if (msg.initLoad) return copyBtn;
|
|
101046
101080
|
return msg.type === "response" && isFinalMessage(msg) ? copyBtn : "";
|
|
101047
101081
|
}
|
|
@@ -101054,12 +101088,12 @@ code.hljs {
|
|
|
101054
101088
|
}
|
|
101055
101089
|
}
|
|
101056
101090
|
}
|
|
101057
|
-
function resetStylesForLikeAndDislikeBtns(curMsgBubble, msg) {
|
|
101091
|
+
function resetStylesForLikeAndDislikeBtns(curMsgBubble, msg, textChatOptions) {
|
|
101058
101092
|
const likeBtnEl = curMsgBubble.querySelector(".alan-btn__chat-response__like-btn");
|
|
101059
101093
|
const dislikeBtnEl = curMsgBubble.querySelector(".alan-btn__chat-response__dislike-btn");
|
|
101060
101094
|
if (likeBtnEl && dislikeBtnEl) {
|
|
101061
|
-
likeBtnEl.innerHTML = getLikeSvgIcon(msg);
|
|
101062
|
-
dislikeBtnEl.innerHTML = getDislikeSvgIcon(msg);
|
|
101095
|
+
likeBtnEl.innerHTML = getLikeSvgIcon(msg, textChatOptions);
|
|
101096
|
+
dislikeBtnEl.innerHTML = getDislikeSvgIcon(msg, textChatOptions);
|
|
101063
101097
|
}
|
|
101064
101098
|
}
|
|
101065
101099
|
function deleteHiddenImagesWithCode(str) {
|
|
@@ -143607,8 +143641,8 @@ Expat https://libexpat.github.io
|
|
|
143607
143641
|
// alan_btn/alan_btn.ts
|
|
143608
143642
|
(function(ns) {
|
|
143609
143643
|
const uiState10 = getUIState();
|
|
143610
|
-
uiState10.lib.version = "alan-version.1.8.
|
|
143611
|
-
window.alanLib = { version: "alan-version.1.8.
|
|
143644
|
+
uiState10.lib.version = "alan-version.1.8.117".replace("alan-version.", "");
|
|
143645
|
+
window.alanLib = { version: "alan-version.1.8.117".replace("alan-version.", "") };
|
|
143612
143646
|
if (window.alanBtn) {
|
|
143613
143647
|
console.warn("Alan: the Alan Button source code has already added (v." + uiState10.lib.version + ")");
|
|
143614
143648
|
}
|
|
@@ -143774,6 +143808,9 @@ Expat https://libexpat.github.io
|
|
|
143774
143808
|
isActive: function() {
|
|
143775
143809
|
return isAlanActive;
|
|
143776
143810
|
},
|
|
143811
|
+
isModelReady: function() {
|
|
143812
|
+
return isModelReady;
|
|
143813
|
+
},
|
|
143777
143814
|
sendText: (text5) => {
|
|
143778
143815
|
_sendText(text5);
|
|
143779
143816
|
},
|
|
@@ -143867,6 +143904,8 @@ Expat https://libexpat.github.io
|
|
|
143867
143904
|
window.tutorProject.off("text", onTextCbInMicBtn);
|
|
143868
143905
|
window.tutorProject.off("queryProgress", onQueryProgressCb);
|
|
143869
143906
|
window.tutorProject.off("parsed", onParsedCbInMicBtn);
|
|
143907
|
+
window.tutorProject.off("modelUpdate", onModelUpdate);
|
|
143908
|
+
window.tutorProject.off("scripts", onScriptsUpdate);
|
|
143870
143909
|
alanAudio.off("command", onCommandCbInMicBtn);
|
|
143871
143910
|
alanAudio.off("afterText", onAfterTextCbInMicBtn);
|
|
143872
143911
|
document.removeEventListener("click", alanBtnClickEventListener);
|
|
@@ -143919,6 +143958,7 @@ Expat https://libexpat.github.io
|
|
|
143919
143958
|
"default": "ONLINE",
|
|
143920
143959
|
"offline": "OFFLINE",
|
|
143921
143960
|
"disconnected": "CONNECTING",
|
|
143961
|
+
"modelIsUpdating": "MODEL_IS_UPDATING",
|
|
143922
143962
|
"listening": "LISTEN",
|
|
143923
143963
|
"understood": "PROCESS",
|
|
143924
143964
|
"intermediate": "PROCESS",
|
|
@@ -143933,6 +143973,7 @@ Expat https://libexpat.github.io
|
|
|
143933
143973
|
var INTERMEDIATE = "intermediate";
|
|
143934
143974
|
var UNDERSTOOD = "understood";
|
|
143935
143975
|
var DISCONNECTED = "disconnected";
|
|
143976
|
+
var MODEL_IS_UPDATING = "modelIsUpdating";
|
|
143936
143977
|
var OFFLINE = "offline";
|
|
143937
143978
|
var LOW_VOLUME = "lowVolume";
|
|
143938
143979
|
var PERMISSION_DENIED = "permissionDenied";
|
|
@@ -143953,6 +143994,9 @@ Expat https://libexpat.github.io
|
|
|
143953
143994
|
var previousState = null;
|
|
143954
143995
|
var isAlanSpeaking = false;
|
|
143955
143996
|
var isAlanActive = false;
|
|
143997
|
+
var isModelReady = false;
|
|
143998
|
+
var modelHash = null;
|
|
143999
|
+
var scriptHash = null;
|
|
143956
144000
|
var isLeftAligned = false;
|
|
143957
144001
|
var isRightAligned = true;
|
|
143958
144002
|
var isBottomAligned = false;
|
|
@@ -144687,6 +144731,8 @@ Expat https://libexpat.github.io
|
|
|
144687
144731
|
window.tutorProject.on("text", onTextCbInMicBtn);
|
|
144688
144732
|
window.tutorProject.on("queryProgress", onQueryProgressCb);
|
|
144689
144733
|
window.tutorProject.on("parsed", onParsedCbInMicBtn);
|
|
144734
|
+
window.tutorProject.on("modelUpdate", onModelUpdate);
|
|
144735
|
+
window.tutorProject.on("scripts", onScriptsUpdate);
|
|
144690
144736
|
alanAudio.on("command", onCommandCbInMicBtn);
|
|
144691
144737
|
alanAudio.on("afterText", onAfterTextCbInMicBtn);
|
|
144692
144738
|
}
|
|
@@ -145437,7 +145483,7 @@ Expat https://libexpat.github.io
|
|
|
145437
145483
|
}
|
|
145438
145484
|
return options2;
|
|
145439
145485
|
}
|
|
145440
|
-
function onConnectStatusChange(res) {
|
|
145486
|
+
function onConnectStatusChange(res, event) {
|
|
145441
145487
|
if (res === "disconnected") {
|
|
145442
145488
|
if (previousState !== OFFLINE) {
|
|
145443
145489
|
switchState(getDefaultBtnState(DISCONNECTED));
|
|
@@ -145462,20 +145508,23 @@ ${getSavedDialogId() || "-"} (prev. dialog)`);
|
|
|
145462
145508
|
onNewDialogAutoReconnect();
|
|
145463
145509
|
} else {
|
|
145464
145510
|
if (!(0, import_lodash2.isEmpty)(prevUserId) && (0, import_lodash2.isEmpty)(uiState10.userInfo.userId)) {
|
|
145465
|
-
|
|
145466
|
-
|
|
145467
|
-
|
|
145511
|
+
if (prevUserId !== "default") {
|
|
145512
|
+
savePrevUserId(uiState10.userInfo.userId);
|
|
145513
|
+
connectToNewDialog();
|
|
145514
|
+
return;
|
|
145515
|
+
}
|
|
145468
145516
|
}
|
|
145469
145517
|
saveDialogId(dialogId);
|
|
145470
145518
|
restoreMessagesInChat(true);
|
|
145471
145519
|
}
|
|
145520
|
+
saveDialogId(dialogId);
|
|
145472
145521
|
console.info(`Alan: curDialogId:
|
|
145473
145522
|
${curDialogId}`);
|
|
145474
145523
|
sendSyncPageState(null, "onConnectStatusChange");
|
|
145475
145524
|
}
|
|
145476
145525
|
}
|
|
145477
145526
|
if (options.onConnectionStatus) {
|
|
145478
|
-
options.onConnectionStatus(res);
|
|
145527
|
+
options.onConnectionStatus(res, event);
|
|
145479
145528
|
}
|
|
145480
145529
|
}
|
|
145481
145530
|
function onMicAllowed() {
|
|
@@ -145499,9 +145548,13 @@ ${curDialogId}`);
|
|
|
145499
145548
|
if (window.tutorProject) {
|
|
145500
145549
|
window.tutorProject.off("recognized", onRecognizedCbInMicBtn);
|
|
145501
145550
|
window.tutorProject.off("parsed", onParsedCbInMicBtn);
|
|
145551
|
+
window.tutorProject.off("modelUpdate", onModelUpdate);
|
|
145552
|
+
window.tutorProject.off("scripts", onScriptsUpdate);
|
|
145502
145553
|
window.tutorProject.off("options", onOptionsReceived);
|
|
145503
145554
|
window.tutorProject.on("recognized", onRecognizedCbInMicBtn);
|
|
145504
145555
|
window.tutorProject.on("parsed", onParsedCbInMicBtn);
|
|
145556
|
+
window.tutorProject.on("modelUpdate", onModelUpdate);
|
|
145557
|
+
window.tutorProject.on("scripts", onScriptsUpdate);
|
|
145505
145558
|
window.tutorProject.on("options", onOptionsReceived);
|
|
145506
145559
|
}
|
|
145507
145560
|
}
|
|
@@ -145524,6 +145577,8 @@ ${curDialogId}`);
|
|
|
145524
145577
|
window.tutorProject.off("recognized", onRecognizedCbInMicBtn);
|
|
145525
145578
|
window.tutorProject.off("connectStatus", onConnectStatusChange);
|
|
145526
145579
|
window.tutorProject.off("options", onOptionsReceived);
|
|
145580
|
+
window.tutorProject.off("modelUpdate", onModelUpdate);
|
|
145581
|
+
window.tutorProject.off("scripts", onScriptsUpdate);
|
|
145527
145582
|
}
|
|
145528
145583
|
if (options.onMicStopped) {
|
|
145529
145584
|
options.onMicStopped();
|
|
@@ -145665,6 +145720,37 @@ ${curDialogId}`);
|
|
|
145665
145720
|
deactivateAlanButton();
|
|
145666
145721
|
}
|
|
145667
145722
|
}
|
|
145723
|
+
function onScriptsUpdate(e) {
|
|
145724
|
+
scriptHash = e.hash;
|
|
145725
|
+
if (scriptHash && modelHash) {
|
|
145726
|
+
if (scriptHash === modelHash) {
|
|
145727
|
+
isModelReady = true;
|
|
145728
|
+
switchState(DEFAULT);
|
|
145729
|
+
sendSyncPageState(null, "model_is_ready");
|
|
145730
|
+
} else {
|
|
145731
|
+
isModelReady = false;
|
|
145732
|
+
switchState(MODEL_IS_UPDATING);
|
|
145733
|
+
manageAutocompeteInChat();
|
|
145734
|
+
}
|
|
145735
|
+
}
|
|
145736
|
+
}
|
|
145737
|
+
function onModelUpdate(e) {
|
|
145738
|
+
if (e?.modelHash && e?.scriptHash) {
|
|
145739
|
+
if (e?.modelHash !== e?.scriptHash) {
|
|
145740
|
+
isModelReady = false;
|
|
145741
|
+
switchState(MODEL_IS_UPDATING);
|
|
145742
|
+
modelHash = e.modelHash;
|
|
145743
|
+
scriptHash = e.scriptHash;
|
|
145744
|
+
manageAutocompeteInChat();
|
|
145745
|
+
} else {
|
|
145746
|
+
isModelReady = true;
|
|
145747
|
+
switchState(DEFAULT);
|
|
145748
|
+
modelHash = e.modelHash;
|
|
145749
|
+
scriptHash = e.scriptHash;
|
|
145750
|
+
sendSyncPageState(null, "model_is_ready");
|
|
145751
|
+
}
|
|
145752
|
+
}
|
|
145753
|
+
}
|
|
145668
145754
|
function onParsedCbInMicBtn(e) {
|
|
145669
145755
|
const event = Object.assign(e, { name: "parsed" });
|
|
145670
145756
|
storeSocketHistory(event);
|
|
@@ -146013,7 +146099,7 @@ ${curDialogId}`);
|
|
|
146013
146099
|
msg.liked = msg.liked !== -1 ? -1 : 0;
|
|
146014
146100
|
}
|
|
146015
146101
|
changeMsgLikeStatus(msg, options);
|
|
146016
|
-
resetStylesForLikeAndDislikeBtns(curMsgBubble, msg);
|
|
146102
|
+
resetStylesForLikeAndDislikeBtns(curMsgBubble, msg, uiState10.textChat.options);
|
|
146017
146103
|
saveMessageHistory();
|
|
146018
146104
|
}
|
|
146019
146105
|
document.removeEventListener("click", performLikeOrDislike);
|
|
@@ -146526,6 +146612,8 @@ ${curDialogId}`);
|
|
|
146526
146612
|
window.tutorProject.off("text", onTextCbInMicBtn);
|
|
146527
146613
|
window.tutorProject.off("queryProgress", onQueryProgressCb);
|
|
146528
146614
|
window.tutorProject.off("parsed", onParsedCbInMicBtn);
|
|
146615
|
+
window.tutorProject.off("modelUpdate", onModelUpdate);
|
|
146616
|
+
window.tutorProject.off("scripts", onScriptsUpdate);
|
|
146529
146617
|
window.tutorProject.off("connectStatus", onConnectStatusChange);
|
|
146530
146618
|
window.tutorProject.off("options", onOptionsReceived);
|
|
146531
146619
|
alanAudio.off("command", onCommandCbInMicBtn);
|
|
@@ -146607,6 +146695,10 @@ ${curDialogId}`);
|
|
|
146607
146695
|
}
|
|
146608
146696
|
async function _sendText(text5) {
|
|
146609
146697
|
manageAutocompeteInChat();
|
|
146698
|
+
if (!canMsgBeSent()) {
|
|
146699
|
+
console.warn("Alan: message cannot be sent. Model is not ready or connection is not established.");
|
|
146700
|
+
return;
|
|
146701
|
+
}
|
|
146610
146702
|
var msg = { text: text5, type: "request", name: "text" };
|
|
146611
146703
|
sentMessageInd = null;
|
|
146612
146704
|
clearMessageProgressStatusInterval();
|
|
@@ -146644,6 +146736,12 @@ ${curDialogId}`);
|
|
|
146644
146736
|
clearTimeout(lastSendMsgTs);
|
|
146645
146737
|
lastSendMsgTs = null;
|
|
146646
146738
|
}
|
|
146739
|
+
function canMsgBeSent() {
|
|
146740
|
+
if (!isModelReady || state === DISCONNECTED || state === OFFLINE) {
|
|
146741
|
+
return false;
|
|
146742
|
+
}
|
|
146743
|
+
return true;
|
|
146744
|
+
}
|
|
146647
146745
|
const sendMessageToTextChat = throttle(async function sendMessageToTextChat2() {
|
|
146648
146746
|
var textareaEl = getChatTextareaEl();
|
|
146649
146747
|
var textareaHolderEl = document.getElementById("textarea-holder");
|
|
@@ -146652,6 +146750,9 @@ ${curDialogId}`);
|
|
|
146652
146750
|
if (lastSendMsgTs || text5?.length > maxChars) {
|
|
146653
146751
|
return;
|
|
146654
146752
|
}
|
|
146753
|
+
if (!canMsgBeSent()) {
|
|
146754
|
+
return;
|
|
146755
|
+
}
|
|
146655
146756
|
lastSendMsgTs = setTimeout(() => {
|
|
146656
146757
|
enableTextareaInTheChat();
|
|
146657
146758
|
}, 5e3);
|
|
@@ -146724,6 +146825,10 @@ ${curDialogId}`);
|
|
|
146724
146825
|
manageSendButtonAvailability();
|
|
146725
146826
|
}
|
|
146726
146827
|
function manageAutocompeteInChat() {
|
|
146828
|
+
if (!isModelReady) {
|
|
146829
|
+
clearChatAutocomplete(false);
|
|
146830
|
+
return;
|
|
146831
|
+
}
|
|
146727
146832
|
if (uiState10.textChat?.autocomplete?.enabled === true) {
|
|
146728
146833
|
checkIfNewComplitionNeeded();
|
|
146729
146834
|
fillChatAutocompleteDebounced();
|
|
@@ -146963,6 +147068,9 @@ ${curDialogId}`);
|
|
|
146963
147068
|
let hasRefocusedTextarea = false;
|
|
146964
147069
|
let previousTextValue = "";
|
|
146965
147070
|
function sendSyncPageState(forceUpdate = false, reason) {
|
|
147071
|
+
if (!isModelReady) {
|
|
147072
|
+
return;
|
|
147073
|
+
}
|
|
146966
147074
|
syncPageState(null, forceUpdate, reason);
|
|
146967
147075
|
}
|
|
146968
147076
|
function onChatTextAreaFocus() {
|
|
@@ -147635,6 +147743,12 @@ ${curDialogId}`);
|
|
|
147635
147743
|
var textareaHolderDiv = footerHolderDiv || document.getElementById("textarea-holder-content");
|
|
147636
147744
|
if (chatSendBtn) {
|
|
147637
147745
|
chatSendBtn.innerHTML = getSendChatIcon(uiState10?.textChat?.options);
|
|
147746
|
+
if (!isModelReady) {
|
|
147747
|
+
chatSendBtn.innerHTML = chatIcons.disconnected;
|
|
147748
|
+
chatSendBtn.classList.add("alan-btn__disconnected");
|
|
147749
|
+
} else {
|
|
147750
|
+
chatSendBtn.classList.remove("alan-btn__disconnected");
|
|
147751
|
+
}
|
|
147638
147752
|
if (!textareaInnerDiv || !textareaHolderDiv) return;
|
|
147639
147753
|
if (uiState10?.textChat?.options?.footer?.layout?.name !== "send-btn-outside") {
|
|
147640
147754
|
textareaInnerDiv.appendChild(chatSendBtn);
|
|
@@ -147920,8 +148034,8 @@ ${curDialogId}`);
|
|
|
147920
148034
|
btnOval2.style.animation = "";
|
|
147921
148035
|
btnOval1.style.opacity = "0";
|
|
147922
148036
|
btnOval2.style.opacity = "0";
|
|
147923
|
-
} else if (newState === DISCONNECTED || newState === OFFLINE) {
|
|
147924
|
-
if (newState === DISCONNECTED) {
|
|
148037
|
+
} else if (newState === DISCONNECTED || newState === OFFLINE || newState === MODEL_IS_UPDATING) {
|
|
148038
|
+
if (newState === DISCONNECTED || newState === MODEL_IS_UPDATING) {
|
|
147925
148039
|
rootEl.classList.add("alan-btn-disconnected");
|
|
147926
148040
|
}
|
|
147927
148041
|
if (newState === OFFLINE) {
|
|
@@ -147943,7 +148057,7 @@ ${curDialogId}`);
|
|
|
147943
148057
|
replyStateBtnIconImg
|
|
147944
148058
|
]
|
|
147945
148059
|
);
|
|
147946
|
-
if (newState === DISCONNECTED) {
|
|
148060
|
+
if (newState === DISCONNECTED || newState === MODEL_IS_UPDATING) {
|
|
147947
148061
|
micIconDiv.style.opacity = "0";
|
|
147948
148062
|
disconnectedMicLoaderIconImg.style.opacity = "1";
|
|
147949
148063
|
} else {
|
|
@@ -147975,6 +148089,7 @@ ${curDialogId}`);
|
|
|
147975
148089
|
if (textChatEl) {
|
|
147976
148090
|
switch (newState) {
|
|
147977
148091
|
case OFFLINE:
|
|
148092
|
+
case MODEL_IS_UPDATING:
|
|
147978
148093
|
case DISCONNECTED:
|
|
147979
148094
|
sendBtn.innerHTML = newState === OFFLINE ? chatIcons.noWiFi : chatIcons.disconnected;
|
|
147980
148095
|
textChatEl.classList.add("alan-btn__disconnected");
|