@crestapps/ai-chat-ui 1.0.0-preview.19 → 1.0.0-preview.23
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/ai-chat.min.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["ai-chat.js"],"names":["_excluded","_regenerator","e","t","r","Symbol","n","iterator","o","toStringTag","i","c","prototype","Generator","u","Object","create","_regeneratorDefine2","f","p","y","G","v","a","d","bind","length","l","TypeError","call","done","value","GeneratorFunction","GeneratorFunctionPrototype","getPrototypeOf","this","setPrototypeOf","__proto__","displayName","w","m","defineProperty","_invoke","enumerable","configurable","writable","asyncGeneratorStep","Promise","resolve","then","_asyncToGenerator","arguments","apply","_next","_throw","_toConsumableArray","_arrayWithoutHoles","_iterableToArray","_unsupportedIterableToArray","_nonIterableSpread","Array","from","isArray","_arrayLikeToArray","_objectWithoutProperties","_objectWithoutPropertiesLoose","getOwnPropertySymbols","indexOf","propertyIsEnumerable","hasOwnProperty","_createForOfIteratorHelper","_n","F","s","next","_slicedToArray","_arrayWithHoles","_iterableToArrayLimit","_nonIterableRest","toString","slice","constructor","name","test","push","_typeof","window","openAIChatManager","defaultConfig","generatedImageAltText","generatedImageMaxWidth","downloadImageTitle","downloadChartTitle","downloadChartButtonText","userLabel","assistantLabel","thumbsUpTitle","thumbsDownTitle","copyTitle","codeCopiedText","widget","chatWidgetContainer","chatWidgetStateName","chatHistorySection","showHistoryButton","closeHistoryButton","newChatButton","toggleButtonSelector","resetSizeButtonSelector","dragHandleSelector","enableDragging","enableResizing","persistLayout","defaultWidth","defaultHeight","minWidth","minHeight","messageTemplate","indicatorTemplate","sanitizeUrl","url","trimmed","trim","escapeHtmlEntities","text","span","document","createElement","textContent","innerHTML","normalizeReference","reference","_ref","_normalized$index","_ref2","_normalized$text","_ref3","_normalized$title","_ref4","_normalized$link","_ref5","_normalized$reference","normalized","assign","index","Index","Text","title","Title","link","Link","referenceType","ReferenceType","isDownloadCitationReference","toLowerCase","normalizeReferences","references","_i","_Object$entries","entries","_normalizeReference","_Object$entries$_i","key","getCitationLabel","updateMessagePresentation","message","messageReferences","rawContent","content","citationDisplay","processedContent","keys","citations","citedRefs","filter","_ref6","includes","sort","_ref8","_ref9","b","_step","displayIndex","_iterator","_step$value","placeholder","concat","replaceAll","referenceKey","label","isDownload","err","_i2","_citations","citation","map","_ref10","buildCitationDisplay","displayContent","citationReferences","copyContent","_step2","_iterator2","_step3","_iterator3","trimEnd","buildCopyContent","htmlContent","parseMarkdownContent","renderer","marked","Renderer","data","href","code","lang","highlighted","hljs","getLanguage","highlight","language","_","highlightAuto","langDisplay","image","src","alt","maxWidth","chartCounter","_pendingCharts","renderChartsInMessage","charts","requestAnimationFrame","_step4","_iterator4","renderChartOnCanvas","chartId","config","canvas","getElementById","Chart","console","warn","offsetParent","__chartConfigs","_cfg$options","_cfg$options2","_cfg$options2$aspectR","_chartInstance","destroy","cfg","JSON","parse","options","responsive","maintainAspectRatio","aspectRatio","error","html","DOMPurify","sanitize","ADD_TAGS","ADD_ATTR","use","extensions","level","start","idx","undefined","tokenizer","extracted","token","jsonStart","depth","inString","escape","ch","jsonEnd","closeBracketIndex","startIndex","endIndex","json","substring","tryExtractChartMarker","type","raw","renderPendingCharts","configs","_i3","_Object$keys","initialize","instanceConfig","hasWidgetConfig","widgetBehavior","openAIChatWidgetBehavior","signalRHubUrl","appElementSelector","chatContainerElementSelector","inputElementSelector","sendButtonElementSelector","appDefinition","inputElement","buttonElement","chatContainer","isSessionStarted","isPlaceholderVisible","isStreaming","isNavigatingAway","autoScroll","stream","messages","notifications","prompt","documents","existingDocuments","isUploading","isDocumentOperationPending","documentOperationQueue","uploadErrors","isDragOver","documentBar","metricsEnabled","isRecording","mediaRecorder","preRecordingPrompt","micButton","speechToTextEnabled","chatMode","textToSpeechEnabled","ttsVoiceName","audioChunks","audioPlayQueue","isPlayingAudio","currentAudioElement","currentAudioUrl","ttsButton","ttsPlayingMessageIndex","ttsAudioCache","ttsInstanceId","Math","random","singleResponseMode","conversationModeEnabled","conversationButton","isConversationMode","notificationDismissTimers","pendingSessionPromise","pendingSessionResolver","pendingSessionRejector","pendingSessionTimeoutId","computed","lastAssistantIndex","role","methods","handleBeforeUnload","handleDragOver","sessionDocumentsEnabled","preventDefault","stopPropagation","inputArea","closest","classList","add","handleDragLeave","remove","handleDrop","dataTransfer","files","uploadFiles","triggerFileInput","fileInput","click","handleFileInputChange","target","queueDocumentOperation","operation","self","nextOperation","_callee","_context","_this","_callee3","filesToUpload","_context3","uploadDocumentUrl","_callee2","sessionId","profileId","formData","response","errorText","uploadError","result","_t","_t2","_context2","getSessionId","getProfileId","ensureSessionForDocuments","fileName","renderDocumentBar","FormData","append","fetch","method","body","ok","extractReadableErrorMessage","initializeSession","uploaded","failed","reloadCurrentSession","removeDocument","doc","_this2","_callee5","_context5","removeDocumentUrl","_callee4","removeError","_t3","_context4","headers","stringify","itemId","documentId","splice","status","formatFileSize","bytes","toFixed","escapeHtml","failedItem","failedName","errorMsg","supportedExtensionsText","replaceChildren","RETURN_DOM_FRAGMENT","closeButtons","querySelectorAll","j","addEventListener","docToRemove","parseInt","getAttribute","errorCloseButtons","addBtn","querySelector","div","fallbackMessage","startsWith","parsed","detail","normalizeAssistantAppearance","appearance","icon","cssClass","disableStreamingAnimation","getAssistantLabel","getAssistantRoleClasses","classes","getAssistantIconClasses","shouldAnimateAssistantIcon","getAssistantIcon","startConnection","_this3","_callee6","_t4","_context6","connection","signalR","HubConnectionBuilder","withUrl","withAutomaticReconnect","build","serverTimeoutInMilliseconds","keepAliveIntervalInMilliseconds","on","_data$messages","forEach","msg","addMessage","$nextTick","refreshAllFeedbackIcons","initialPrompt","sendMessage","stopRecording","handleReceiveError","messageId","userRating","find","id","isFinal","_conversationPartialTranscript","replace","_conversationPartialMessage","hidePlaceholder","isPartial","scrollToBottom","_audioInputSent","dispatchEvent","Event","stopAudio","_conversationAssistantMessage","oldMsg","escaped","responseId","hideTypingIndicator","msgIndex","newMessage","base64Audio","contentType","binaryString","atob","Uint8Array","charCodeAt","playCollectedAudio","notification","receiveNotification","updateNotification","notificationType","removeNotification","onreconnecting","onreconnected","info","autoCreateSession","startNewSession","onclose","addMessageInternal","_this4","fireEvent","CustomEvent","_message$rawContent","_this5","addMessages","_this6","showPlaceholder","isOrchestratorAvailable","applyOrchestratorAvailability","unavailableMessage","orchestratorUnavailableMessage","disabled","micButtonElement","style","display","conversationButtonElement","event","isIndicator","trimmedPrompt","streamMessage","startRecording","_this7","navigator","mediaDevices","getUserMedia","audio","echoCancellation","noiseSuppression","autoGainControl","mimeType","MediaRecorder","isTypeSupported","audioBitsPerSecond","subject","Subject","pendingChunk","size","_callee7","uint8Array","base64","_context7","arrayBuffer","reduce","str","byte","String","fromCharCode","btoa","getTracks","track","stop","complete","documentElement","send","updateMicButton","toggleRecording","sessionProfileId","_this8","dispose","streamingStarted","showTypingIndicator","lastResponseId","messageIndex","currentSessionId","subscribe","chunk","_i4","_Object$entries2","_normalizeReference2","_Object$entries2$_i","_this8$stream","processReferences","streamingFinished","synthesizeSpeech","_this8$stream2","getServiceDownMessage","_this9","_ref15","_message$rawContent2","stopIcon","setAttribute","startIcon","removeAttribute","focus","icons","handleExternalTtsStop","_e$detail","sourceId","updateTtsPlaybackButtons","_this0","button","isPlaying","Number","iconHtml","toggle","cacheIndex","_this1","_ttsCacheIndex","invoke","toggleMessageTts","_this10","playAudioBlob","_this11","_step5","totalLength","sum","combined","offset","_iterator5","set","blob","Blob","_this12","URL","createObjectURL","Audio","revokeObjectURL","playNextInQueue","play","_this13","nextBlob","shift","conversationModeOnAudioEnded","_this14","pause","currentTime","toggleConversationMode","stopConversationMode","startConversationMode","_this15","updateConversationButton","_conversationSubject","_conversationStream","AudioCtx","AudioContext","webkitAudioContext","_conversationAudioCtx","_conversationAnalyser","createAnalyser","fftSize","createMediaStreamSource","connect","analyser","freqData","frequencyBinCount","getByteFrequencyData","k","_callee8","_context8","close","dismissible","autoDismissMs","endHtml","blur","startHtml","conversationModeSendPrompt","generatePrompt","element","templateProfileId","createSessionUrl","baseUrl","param","fullUrl","location","origin","searchParams","originalLength","_this16","clearNotificationDismiss","existingIndex","findIndex","scheduleNotificationDismiss","_this17","setTimeout","timerId","clearTimeout","dismissNotification","handleNotificationAction","actionName","_this18","scrollTop","scrollHeight","clientHeight","handleUserInput","setSessionId","resetSession","rejectPendingSessionRequest","sessionRating","onSessionReset","requestNewSession","_this19","_callee9","_context9","_this20","reject","resolvePendingSessionRequest","clearPendingSessionRequest","initializeApp","_this21","placeholderElementSelector","loadSession","documentBarSelector","className","multiple","allowedExtensions","accept","parentElement","appendChild","atBottom","shiftKey","lastMsg","pop","promptGenerators","getElementsByClassName","chatSessions","showChatScreen","btn","block","codeEl","clipboard","writeText","copiedText","micButtonElementSelector","conversationButtonElementSelector","force","onSessionInitialized","resolveSessionId","copyResponse","_ref17","_message$copyContent","updateFeedbackIcons","container","upBtn","downBtn","upClass","upIcon","fontSize","downClass","downIcon","containers","$el","msgId","rateMessage","isPositive","newRating","feedbackContainer","btnClass","offsetWidth","onEnd","removeEventListener","watch","handler","onDocumentsChanged","deep","active","mounted","_this22","_callee0","_context0","onMounted","beforeUnmount","onBeforeUnmount","template","app","Vue","createApp","mount","attach","download","toDataURL","img","res","removeChild"],"mappings":"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","file":"ai-chat.min.js","sourcesContent":["window.openAIChatManager = function () {\n\n // Defaults (can be overridden by instanceConfig)\n var defaultConfig = {\n // UI defaults for generated media\n generatedImageAltText: 'Generated Image',\n generatedImageMaxWidth: 400,\n downloadImageTitle: 'Download image',\n downloadChartTitle: 'Download chart as image',\n downloadChartButtonText: 'Download',\n userLabel: 'You',\n assistantLabel: 'Assistant',\n thumbsUpTitle: 'Thumbs up',\n thumbsDownTitle: 'Thumbs down',\n copyTitle: 'Click here to copy response to clipboard.',\n codeCopiedText: 'Copied!',\n widget: {\n chatWidgetContainer: null,\n chatWidgetStateName: null,\n chatHistorySection: null,\n showHistoryButton: null,\n closeHistoryButton: null,\n newChatButton: null,\n toggleButtonSelector: null,\n resetSizeButtonSelector: null,\n dragHandleSelector: '.ai-chat-widget-header',\n enableDragging: true,\n enableResizing: true,\n persistLayout: true,\n defaultWidth: null,\n defaultHeight: null,\n minWidth: 320,\n minHeight: 420\n },\n messageTemplate: `\n <div class=\"ai-chat-messages\">\n <div v-for=\"(message, index) in messages\" :key=\"'msg-' + index\" class=\"ai-chat-message-item\">\n <div>\n <div v-if=\"message.role === 'user'\" class=\"ai-chat-msg-role ai-chat-msg-role-user\">{{ userLabel }}</div>\n <div v-else-if=\"message.role !== 'indicator'\" :class=\"getAssistantRoleClasses(message)\">\n <span :class=\"getAssistantIconClasses(message, index)\"><span :class=\"getAssistantIcon(message)\"></span></span>\n {{ getAssistantLabel(message) }}\n </div>\n <div class=\"ai-chat-message-body lh-base\">\n <h4 v-if=\"message.title\">{{ message.title }}</h4>\n <div v-html=\"message.htmlContent\"></div>\n <ol v-if=\"message.citationReferences && message.citationReferences.length\" class=\"ai-chat-citation-list\">\n <li v-for=\"citation in message.citationReferences\" :key=\"'citation-' + (citation.referenceKey || citation.displayIndex)\" class=\"ai-chat-citation-item\">\n <a v-if=\"citation.link\" :href=\"citation.link\" :target=\"citation.isDownload ? null : '_blank'\" :rel=\"citation.isDownload ? null : 'noopener noreferrer'\">{{ citation.label }}</a>\n <span v-else>{{ citation.label }}</span>\n </li>\n </ol>\n <span class=\"message-buttons-container\" v-if=\"!isIndicator(message)\">\n <template v-if=\"metricsEnabled && message.role === 'assistant'\">\n <span class=\"ai-chat-message-assistant-feedback\" :data-message-id=\"message.id\">\n <button class=\"btn btn-sm btn-link text-success p-0 me-2 button-message-toolbox rate-up-btn\" @click=\"rateMessage(message, true, $event)\" :title=\"thumbsUpTitle\">\n <span class=\"fa-regular fa-thumbs-up\"></span>\n </button>\n <button class=\"btn btn-sm btn-link text-danger p-0 me-2 button-message-toolbox rate-down-btn\" @click=\"rateMessage(message, false, $event)\" :title=\"thumbsDownTitle\">\n <span class=\"fa-regular fa-thumbs-down\"></span>\n </button>\n </span>\n </template>\n <button v-if=\"textToSpeechEnabled && !isConversationMode && message.role === 'assistant' && !message.isStreaming\" class=\"btn btn-sm btn-link text-secondary p-0 me-1 button-message-toolbox\" :class=\"{ 'tts-playing': ttsPlayingMessageIndex === index }\" :data-tts-message-index=\"index\" @click=\"toggleMessageTts(message, index)\" :title=\"ttsPlayingMessageIndex === index ? 'Pause audio' : 'Read aloud'\">\n <span :class=\"ttsPlayingMessageIndex === index ? 'fa-solid fa-circle-pause' : 'fa-solid fa-circle-play'\"></span>\n </button>\n <button class=\"btn btn-sm btn-link text-secondary p-0 button-message-toolbox\" @click=\"copyResponse(message)\" :title=\"copyTitle\">\n <span class=\"fa-solid fa-copy\"></span>\n </button>\n </span>\n </div>\n </div>\n </div>\n <div v-for=\"notification in notifications\" :key=\"'notif-' + notification.type\" class=\"ai-chat-notification\" :class=\"'ai-chat-notification-' + (notification.type || 'info') + ' ' + (notification.cssClass || '')\">\n <div class=\"ai-chat-notification-content\">\n <span v-if=\"notification.icon\" :class=\"notification.icon\" class=\"ai-chat-notification-icon\"></span>\n <span class=\"ai-chat-notification-text\">{{ notification.content }}</span>\n <button v-if=\"notification.dismissible\" class=\"btn btn-sm btn-link p-0 ms-2 ai-chat-notification-dismiss\" @click=\"dismissNotification(notification.type)\" title=\"Dismiss\">\n <span class=\"fa-solid fa-xmark\"></span>\n </button>\n </div>\n <div v-if=\"notification.actions && notification.actions.length\" class=\"ai-chat-notification-actions\">\n <button v-for=\"action in notification.actions\" :key=\"action.name\" class=\"btn btn-sm\" :class=\"action.cssClass || 'btn-outline-secondary'\" @click=\"handleNotificationAction(notification.type, action.name)\">\n <span v-if=\"action.icon\" :class=\"action.icon\" class=\"me-1\"></span>\n {{ action.label }}\n </button>\n </div>\n </div>\n </div>\n `,\n indicatorTemplate: `\n <div class=\"ai-chat-msg-role ai-chat-msg-role-assistant\">\n <span class=\"ai-streaming-icon\"><span class=\"fa fa-robot\" style=\"display: inline-block;\"></span></span>\n Assistant\n </div>\n `\n };\n\n // Sanitize URLs to prevent javascript: protocol injection.\n function sanitizeUrl(url) {\n if (!url) return '';\n var trimmed = url.trim();\n if (/^javascript:/i.test(trimmed) || /^vbscript:/i.test(trimmed) || /^data:text\\/html/i.test(trimmed)) {\n return '';\n }\n return url;\n }\n\n // Safely HTML-encode a string using the DOM (avoids regex-based HTML filtering).\n function escapeHtmlEntities(text) {\n var span = document.createElement('span');\n span.textContent = text;\n return span.innerHTML;\n }\n\n function parsePixelValue(value) {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n\n if (typeof value !== 'string') {\n return null;\n }\n\n var parsed = parseFloat(value);\n return Number.isFinite(parsed) ? parsed : null;\n }\n\n function clamp(value, min, max) {\n return Math.min(Math.max(value, min), max);\n }\n\n function normalizeReference(reference) {\n if (!reference || typeof reference !== 'object') {\n return null;\n }\n\n const normalized = Object.assign({}, reference);\n normalized.index = normalized.index ?? normalized.Index ?? 0;\n normalized.text = normalized.text ?? normalized.Text ?? null;\n normalized.title = normalized.title ?? normalized.Title ?? null;\n normalized.link = sanitizeUrl(normalized.link ?? normalized.Link ?? null);\n normalized.referenceType = normalized.referenceType ?? normalized.ReferenceType ?? null;\n\n return normalized;\n }\n\n function isDownloadCitationReference(reference) {\n if (!reference || typeof reference !== 'object') {\n return false;\n }\n\n if (typeof reference.referenceType === 'string' && reference.referenceType.toLowerCase() === 'document') {\n return true;\n }\n\n if (typeof reference.link === 'string' && /\\/ai\\/documents\\/.+\\/download(?:$|\\?)/i.test(reference.link)) {\n return true;\n }\n\n return false;\n }\n\n function normalizeReferences(references) {\n if (!references || typeof references !== 'object') {\n return {};\n }\n\n const normalized = {};\n\n for (const [key, value] of Object.entries(references)) {\n normalized[key] = normalizeReference(value) ?? {};\n }\n\n return normalized;\n }\n\n function getCitationLabel(reference, key) {\n return reference.title || reference.text || key;\n }\n\n function buildCitationDisplay(content, references) {\n let processedContent = (content || '').trim();\n const messageReferences = normalizeReferences(references);\n\n if (!processedContent || !Object.keys(messageReferences).length) {\n return { content: processedContent, citations: [] };\n }\n\n const citedRefs = Object.entries(messageReferences).filter(([key]) => processedContent.includes(key));\n\n if (!citedRefs.length) {\n return { content: processedContent, citations: [] };\n }\n\n citedRefs.sort(([, a], [, b]) => a.index - b.index);\n\n const citations = [];\n let displayIndex = 1;\n\n for (const [key, value] of citedRefs) {\n const placeholder = `__CITE_${displayIndex}_${value.index || displayIndex}__`;\n processedContent = processedContent.replaceAll(key, placeholder);\n citations.push({\n referenceKey: key,\n displayIndex: displayIndex,\n label: getCitationLabel(value, key),\n link: value.link || null,\n isDownload: isDownloadCitationReference(value),\n placeholder: placeholder,\n });\n\n displayIndex++;\n }\n\n for (const citation of citations) {\n processedContent = processedContent.replaceAll(citation.placeholder, `<sup>${citation.displayIndex}</sup>`);\n }\n\n processedContent = processedContent.replaceAll('</sup><sup>', '</sup><sup>,</sup><sup>');\n\n return {\n content: processedContent,\n citations: citations.map(({ placeholder, ...citation }) => citation),\n };\n }\n\n function buildCopyContent(content, citations) {\n let copyContent = (content || '').trim();\n\n if (!copyContent || !Array.isArray(citations) || citations.length === 0) {\n return copyContent;\n }\n\n for (const citation of citations) {\n copyContent = copyContent.replaceAll(citation.referenceKey, `[${citation.displayIndex}]`);\n }\n\n copyContent += '\\n\\nReferences:\\n';\n\n for (const citation of citations) {\n copyContent += `${citation.displayIndex}. ${citation.label}`;\n\n if (citation.link) {\n copyContent += ` - ${citation.link}`;\n }\n\n copyContent += '\\n';\n }\n\n return copyContent.trimEnd();\n }\n\n function updateMessagePresentation(message, references) {\n const messageReferences = normalizeReferences(references ?? message.references);\n const rawContent = typeof message.rawContent === 'string'\n ? message.rawContent\n : typeof message.content === 'string'\n ? message.content\n : '';\n const citationDisplay = buildCitationDisplay(rawContent, messageReferences);\n\n message.rawContent = rawContent;\n message.content = rawContent;\n message.displayContent = citationDisplay.content;\n message.references = messageReferences;\n message.citationReferences = citationDisplay.citations;\n message.copyContent = buildCopyContent(rawContent, citationDisplay.citations);\n message.htmlContent = parseMarkdownContent(citationDisplay.content, message);\n\n return message;\n }\n\n const renderer = new marked.Renderer();\n\n // Modify the link rendering to open in a new tab\n renderer.link = function (data) {\n var href = sanitizeUrl(data.href);\n if (!href) return data.text || '';\n return `<a href=\"${href}\" target=\"_blank\" rel=\"noopener noreferrer\">${data.text}</a>`;\n };\n\n // Custom code block renderer with highlight.js integration and copy button.\n renderer.code = function (data) {\n var code = data.text || '';\n var lang = (data.lang || '').trim();\n var highlighted = code;\n\n if (typeof hljs !== 'undefined') {\n if (lang && hljs.getLanguage(lang)) {\n try {\n highlighted = hljs.highlight(code, { language: lang }).value;\n } catch (_) { }\n } else {\n try {\n highlighted = hljs.highlightAuto(code).value;\n } catch (_) { }\n }\n } else {\n highlighted = escapeHtmlEntities(code);\n }\n\n var langDisplay = lang ? escapeHtmlEntities(lang) : 'code';\n return `<div class=\"ai-code-block\"><div class=\"ai-code-header\"><span class=\"ai-code-lang\"><span class=\"fa-solid fa-code\"></span> ${langDisplay}</span><button type=\"button\" class=\"ai-code-copy-btn\" title=\"Copy code\"><span class=\"fa-regular fa-copy\"></span></button></div><pre><code class=\"hljs${lang ? ' language-' + lang : ''}\">${highlighted}</code></pre></div>`;\n };\n\n // Custom image renderer for generated images with thumbnail styling and download button.\n // Handles both URL and data-URI sources (data URIs are converted to blobs for download).\n renderer.image = function (data) {\n const src = sanitizeUrl(data.href);\n if (!src) return '';\n const alt = data.text || defaultConfig.generatedImageAltText;\n const maxWidth = defaultConfig.generatedImageMaxWidth;\n return `<div class=\"generated-image-container\">\n <img src=\"${src}\" alt=\"${alt}\" class=\"img-thumbnail\" style=\"max-width: ${maxWidth}px; height: auto;\" />\n <div class=\"mt-2\">\n <a href=\"${src}\" target=\"_blank\" download=\"${alt}\" title=\"${defaultConfig.downloadImageTitle}\" class=\"btn btn-sm btn-outline-secondary ai-download-image\">\n <span class=\"fa-solid fa-download\"></span>\n </a>\n </div>\n </div>`;\n };\n\n // Chart counter for unique IDs\n let chartCounter = 0;\n\n // Collector for charts discovered during marked parsing.\n let _pendingCharts = [];\n\n // Global chart config map: any page (e.g., Chat Interactions) that uses\n // the shared marked instance can call window.renderPendingCharts() after\n // its DOM update to render charts it didn't create itself.\n window.__chartConfigs = window.__chartConfigs || {};\n\n function createChartHtml(chartId) {\n return `<div class=\"chart-container\" style=\"position: relative; width: 100%; max-width: 560px; min-height: 420px;\">`\n + `<canvas id=\"${chartId}\"></canvas>`\n + `</div>`\n + `<div class=\"mt-2\">`\n + `<button type=\"button\" class=\"btn btn-sm btn-outline-secondary download-chart-btn\" data-chart-id=\"${chartId}\" title=\"${defaultConfig.downloadChartTitle}\">`\n + `<span class=\"fa-solid fa-download\"></span> ${defaultConfig.downloadChartButtonText}`\n + `</button>`\n + `</div>`;\n }\n\n // Register [chart:{...json...}] as a native marked block extension so the\n // markdown parser handles chart markers inline with surrounding text.\n marked.use({\n extensions: [{\n name: 'chart',\n level: 'block',\n start(src) {\n const idx = src.indexOf('[chart:');\n return idx >= 0 ? idx : undefined;\n },\n tokenizer(src) {\n const extracted = tryExtractChartMarker(src);\n if (!extracted || extracted.startIndex !== 0) {\n return undefined;\n }\n\n const chartId = `chat_chart_${++chartCounter}`;\n\n return {\n type: 'chart',\n raw: src.substring(0, extracted.endIndex),\n chartId: chartId,\n json: extracted.json,\n };\n },\n renderer(token) {\n _pendingCharts.push({ chartId: token.chartId, config: token.json });\n window.__chartConfigs[token.chartId] = token.json;\n return createChartHtml(token.chartId);\n }\n }]\n });\n\n // Extract a [chart:{...json...}] marker. This avoids regex issues with nested brackets.\n function tryExtractChartMarker(text) {\n const token = '[chart:';\n const start = text.indexOf(token);\n if (start < 0) {\n return null;\n }\n\n // Find JSON object boundary by balancing braces\n const jsonStart = start + token.length;\n let i = jsonStart;\n while (i < text.length && (text[i] === ' ' || text[i] === '\\n' || text[i] === '\\r' || text[i] === '\\t')) {\n i++;\n }\n\n if (i >= text.length || text[i] !== '{') {\n return null;\n }\n\n let depth = 0;\n let inString = false;\n let escape = false;\n\n for (; i < text.length; i++) {\n const ch = text[i];\n\n if (inString) {\n if (escape) {\n escape = false;\n continue;\n }\n if (ch === '\\\\') {\n escape = true;\n continue;\n }\n if (ch === '\"') {\n inString = false;\n }\n continue;\n }\n\n if (ch === '\"') {\n inString = true;\n continue;\n }\n\n if (ch === '{') {\n depth++;\n } else if (ch === '}') {\n depth--;\n if (depth === 0) {\n const jsonEnd = i;\n // Expect closing bracket after JSON\n const closeBracketIndex = text.indexOf(']', jsonEnd + 1);\n if (closeBracketIndex < 0) {\n return null;\n }\n\n const json = text.substring(jsonStart, jsonEnd + 1).trim();\n return {\n startIndex: start,\n endIndex: closeBracketIndex + 1,\n json: json\n };\n }\n }\n }\n\n return null;\n }\n\n function renderChartsInMessage(message) {\n if (!message || !message._pendingCharts || !message._pendingCharts.length) {\n return;\n }\n\n // Copy and clear pending charts immediately to prevent duplicate renders.\n const charts = [...message._pendingCharts];\n message._pendingCharts = [];\n\n // Defer to requestAnimationFrame so the browser has fully laid out the\n // canvas elements before Chart.js reads their dimensions.\n requestAnimationFrame(() => {\n for (const c of charts) {\n renderChartOnCanvas(c.chartId, c.config);\n }\n });\n }\n\n function renderChartOnCanvas(chartId, config) {\n const canvas = document.getElementById(chartId);\n if (!canvas) {\n return false;\n }\n\n if (typeof Chart === 'undefined') {\n console.warn('Chart.js is not loaded. To render interactive charts, include the Chart.js library on the page (e.g., <script src=\"https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js\"></script>).');\n return false;\n }\n\n // When the canvas is inside a hidden container (e.g., a widget panel with\n // display:none), it has zero dimensions and Chart.js cannot render correctly.\n // Keep the config in __chartConfigs so renderPendingCharts() can retry later\n // once the container becomes visible.\n if (canvas.offsetParent === null) {\n window.__chartConfigs[chartId] = config;\n return false;\n }\n\n try {\n if (canvas._chartInstance) {\n canvas._chartInstance.destroy();\n }\n\n const cfg = typeof config === 'string' ? JSON.parse(config) : config;\n cfg.options ??= {};\n cfg.options.responsive = true;\n cfg.options.maintainAspectRatio = true;\n cfg.options.aspectRatio ??= 4 / 3;\n\n canvas._chartInstance = new Chart(canvas, cfg);\n delete window.__chartConfigs[chartId];\n return true;\n } catch (e) {\n console.error('Error creating chart:', e);\n return false;\n }\n }\n\n // Global function: renders any chart canvases whose configs are in the\n // global __chartConfigs map. Called by pages (e.g., Chat Interactions)\n // that share the marked instance but have their own rendering pipeline.\n window.renderPendingCharts = function () {\n if (typeof Chart === 'undefined') {\n return;\n }\n\n const configs = window.__chartConfigs;\n if (!configs) {\n return;\n }\n\n requestAnimationFrame(() => {\n for (const chartId of Object.keys(configs)) {\n renderChartOnCanvas(chartId, configs[chartId]);\n }\n });\n };\n\n // Parse markdown content via marked (which natively handles [chart:...] markers\n // through the registered extension) and collect pending chart configs for later\n // Chart.js rendering.\n function parseMarkdownContent(content, message) {\n _pendingCharts = [];\n const html = marked.parse(content, { renderer });\n message._pendingCharts = _pendingCharts.length > 0 ? [..._pendingCharts] : [];\n return DOMPurify.sanitize(html, { ADD_TAGS: ['canvas'], ADD_ATTR: ['target'] });\n }\n\n const initialize = (instanceConfig) => {\n\n const config = Object.assign({}, defaultConfig, instanceConfig);\n config.widget = Object.assign({}, defaultConfig.widget || {}, instanceConfig && instanceConfig.widget ? instanceConfig.widget : {});\n const hasWidgetConfig = !!(instanceConfig && instanceConfig.widget && instanceConfig.widget.chatWidgetContainer && instanceConfig.widget.chatWidgetStateName);\n const widgetBehavior = window.openAIChatWidgetBehavior || null;\n // Keep defaultConfig in sync so renderers use overridden values\n defaultConfig = config;\n\n if (!config.signalRHubUrl) {\n console.error('The signalRHubUrl is required.');\n return;\n }\n\n if (!config.appElementSelector) {\n console.error('The appElementSelector is required.');\n return;\n }\n\n if (!config.chatContainerElementSelector) {\n console.error('The chatContainerElementSelector is required.');\n return;\n }\n\n if (!config.inputElementSelector) {\n console.error('The inputElementSelector is required.');\n return;\n }\n\n if (!config.sendButtonElementSelector) {\n console.error('The sendButtonElementSelector is required.');\n return;\n }\n\n const appDefinition = {\n data() {\n return {\n inputElement: null,\n buttonElement: null,\n chatContainer: null,\n placeholder: null,\n isSessionStarted: false,\n isPlaceholderVisible: true,\n isStreaming: false,\n isNavigatingAway: false,\n autoScroll: true,\n stream: null,\n messages: [],\n notifications: [],\n prompt: '',\n documents: config.existingDocuments || [],\n isUploading: false,\n isDocumentOperationPending: false,\n documentOperationQueue: null,\n uploadErrors: [],\n isDragOver: false,\n documentBar: null,\n metricsEnabled: !!config.metricsEnabled,\n userLabel: config.userLabel,\n assistantLabel: config.assistantLabel,\n thumbsUpTitle: config.thumbsUpTitle,\n thumbsDownTitle: config.thumbsDownTitle,\n copyTitle: config.copyTitle,\n isRecording: false,\n mediaRecorder: null,\n preRecordingPrompt: '',\n micButton: null,\n speechToTextEnabled: config.chatMode === 'AudioInput' || config.chatMode === 'Conversation',\n textToSpeechEnabled: config.chatMode === 'Conversation' || !!config.textToSpeechEnabled,\n ttsVoiceName: config.ttsVoiceName || null,\n audioChunks: [],\n audioPlayQueue: [],\n isPlayingAudio: false,\n currentAudioElement: null,\n currentAudioUrl: null,\n ttsButton: null,\n ttsPlayingMessageIndex: -1,\n ttsAudioCache: {},\n ttsInstanceId: 'ai-chat-' + Math.random().toString(36).slice(2),\n singleResponseMode: !!config.singleResponseMode,\n conversationModeEnabled: config.chatMode === 'Conversation',\n conversationButton: null,\n isConversationMode: false,\n notificationDismissTimers: {},\n pendingSessionPromise: null,\n pendingSessionResolver: null,\n pendingSessionRejector: null,\n pendingSessionTimeoutId: null,\n };\n },\n computed: {\n lastAssistantIndex() {\n for (var i = this.messages.length - 1; i >= 0; i--) {\n if (this.messages[i].role === 'assistant') {\n return i;\n }\n }\n return -1;\n }\n },\n methods: {\n handleBeforeUnload() {\n this.isNavigatingAway = true;\n },\n handleDragOver(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = true;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.add('ai-chat-drag-over');\n },\n handleDragLeave(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = false;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.remove('ai-chat-drag-over');\n },\n handleDrop(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = false;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.remove('ai-chat-drag-over');\n if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n this.uploadFiles(Array.from(e.dataTransfer.files));\n }\n },\n triggerFileInput() {\n if (!config.sessionDocumentsEnabled || this.isDocumentOperationPending) return;\n var fileInput = document.getElementById('ai-chat-doc-input');\n if (fileInput) fileInput.click();\n },\n handleFileInputChange(e) {\n var files = e.target.files ? Array.from(e.target.files) : [];\n if (files && files.length > 0) {\n this.uploadFiles(files);\n }\n e.target.value = '';\n },\n queueDocumentOperation(operation) {\n var self = this;\n var previousOperation = this.documentOperationQueue || Promise.resolve();\n var nextOperation = previousOperation\n .catch(function () { })\n .then(async function () {\n self.isDocumentOperationPending = true;\n try {\n return await operation();\n } finally {\n self.isDocumentOperationPending = false;\n }\n });\n\n this.documentOperationQueue = nextOperation.finally(function () {\n if (self.documentOperationQueue === nextOperation) {\n self.documentOperationQueue = null;\n }\n });\n\n return this.documentOperationQueue;\n },\n async uploadFiles(files) {\n if (!config.uploadDocumentUrl) return;\n\n var filesToUpload = Array.isArray(files) ? files.slice() : Array.from(files || []);\n if (filesToUpload.length === 0) return;\n\n return this.queueDocumentOperation(async () => {\n var sessionId = this.getSessionId();\n var profileId = this.getProfileId();\n\n if (!sessionId) {\n try {\n sessionId = await this.ensureSessionForDocuments(profileId);\n } catch (err) {\n console.error('Failed to create a chat session for document upload:', err);\n this.uploadErrors = [{ fileName: '', error: 'Could not create a chat session for the upload.' }];\n this.renderDocumentBar();\n return;\n }\n }\n\n if (!sessionId) {\n console.warn('Cannot upload documents without a session or profile.');\n this.uploadErrors = [{ fileName: '', error: 'Could not create a chat session for the upload.' }];\n this.renderDocumentBar();\n return;\n }\n\n this.isUploading = true;\n this.uploadErrors = [];\n this.renderDocumentBar();\n try {\n var formData = new FormData();\n formData.append('sessionId', sessionId);\n for (var i = 0; i < filesToUpload.length; i++) {\n formData.append('files', filesToUpload[i]);\n }\n\n var response = await fetch(config.uploadDocumentUrl, {\n method: 'POST',\n body: formData\n });\n\n if (!response.ok) {\n var errorText = await response.text();\n var uploadError = this.extractReadableErrorMessage(errorText, 'Upload failed. Please try again.');\n console.error('Upload failed:', errorText);\n this.uploadErrors = [{ fileName: '', error: uploadError }];\n return;\n }\n\n var result = await response.json();\n\n if (result.sessionId && result.sessionId !== this.getSessionId()) {\n this.initializeSession(result.sessionId);\n }\n\n if (Array.isArray(result.documents)) {\n this.documents = result.documents;\n } else if (result.uploaded && result.uploaded.length > 0) {\n this.documents = this.documents.concat(result.uploaded);\n }\n\n if (result.failed && result.failed.length > 0) {\n this.uploadErrors = result.failed;\n }\n } catch (err) {\n console.error('Upload error:', err);\n this.uploadErrors = [{ fileName: '', error: 'Upload failed. Please try again.' }];\n\n if (this.getSessionId()) {\n this.reloadCurrentSession();\n }\n } finally {\n this.isUploading = false;\n this.renderDocumentBar();\n }\n });\n },\n async removeDocument(doc) {\n if (!config.removeDocumentUrl) return;\n\n return this.queueDocumentOperation(async () => {\n try {\n var sessionId = this.getSessionId();\n var response = await fetch(config.removeDocumentUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ itemId: sessionId, documentId: doc.documentId })\n });\n\n if (response.ok) {\n var result = await response.json();\n\n if (Array.isArray(result.documents)) {\n this.documents = result.documents;\n } else {\n var idx = this.documents.indexOf(doc);\n if (idx > -1) {\n this.documents.splice(idx, 1);\n }\n }\n } else {\n var errorText = await response.text();\n var removeError = this.extractReadableErrorMessage(errorText, 'Failed to remove document. Please try again.');\n console.error('Failed to remove document:', response.status, errorText);\n this.uploadErrors = [{ fileName: doc.fileName || '', error: removeError }];\n if (sessionId) {\n this.reloadCurrentSession();\n }\n this.renderDocumentBar();\n }\n } catch (err) {\n console.error('Remove document error:', err);\n this.uploadErrors = [{ fileName: doc.fileName || '', error: 'Failed to remove document. Please try again.' }];\n if (this.getSessionId()) {\n this.reloadCurrentSession();\n }\n this.renderDocumentBar();\n }\n });\n },\n formatFileSize(bytes) {\n if (bytes < 1024) return bytes + ' B';\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n },\n renderDocumentBar() {\n if (!this.documentBar) return;\n\n if (!config.sessionDocumentsEnabled) {\n this.documentBar.classList.add('d-none');\n return;\n }\n\n this.documentBar.classList.remove('d-none');\n\n var html = '<div class=\"ai-chat-doc-bar p-2\">';\n html += '<div class=\"d-flex flex-wrap align-items-center gap-1\">';\n\n for (var i = 0; i < this.documents.length; i++) {\n var doc = this.documents[i];\n var name = doc.fileName || 'Document';\n if (name.length > 20) name = name.substring(0, 17) + '...';\n html += '<span class=\"badge bg-secondary bg-opacity-25 text-dark d-inline-flex align-items-center gap-1 px-2 py-1\" style=\"font-size: 0.8rem;\" title=\"' + this.escapeHtml(doc.fileName || '') + '\">';\n html += '<span class=\"fa-solid fa-file-lines\" style=\"font-size: 0.7rem;\"></span> ';\n html += this.escapeHtml(name);\n html += ' <button type=\"button\" class=\"btn-close btn-close-sm ms-1\" style=\"font-size: 0.5rem;\" data-doc-index=\"' + i + '\" aria-label=\"Remove\"' + (this.isDocumentOperationPending ? ' disabled' : '') + '></button>';\n html += '</span>';\n }\n\n for (var m = 0; m < this.uploadErrors.length; m++) {\n var failedItem = this.uploadErrors[m];\n var failedName = failedItem.fileName || 'File';\n var errorMsg = failedItem.error || 'Upload failed';\n if (failedName.length > 15) failedName = failedName.substring(0, 12) + '...';\n html += '<span class=\"badge bg-danger bg-opacity-25 text-danger d-inline-flex align-items-center gap-1 px-2 py-1\" style=\"font-size: 0.8rem;\" title=\"' + this.escapeHtml((failedItem.fileName || '') + ': ' + errorMsg) + '\">';\n html += '<span class=\"fa-solid fa-circle-exclamation\" style=\"font-size: 0.7rem;\"></span> ';\n html += this.escapeHtml(failedName);\n html += ' <button type=\"button\" class=\"btn-close btn-close-sm ms-1\" style=\"font-size: 0.5rem;\" data-error-index=\"' + m + '\" aria-label=\"Dismiss\"></button>';\n html += '</span>';\n }\n\n if (this.isUploading) {\n html += '<span class=\"badge bg-info bg-opacity-25 text-dark d-inline-flex align-items-center gap-1 px-2 py-1\" style=\"font-size: 0.8rem;\">';\n html += '<span class=\"spinner-border spinner-border-sm\" style=\"width: 0.7rem; height: 0.7rem;\"></span> Uploading...';\n html += '</span>';\n }\n\n html += '<button type=\"button\" class=\"btn btn-sm btn-outline-secondary rounded-pill ai-chat-doc-add-btn d-inline-flex align-items-center gap-1\" style=\"font-size: 0.75rem; padding: 0.15rem 0.5rem;\" title=\"Attach documents\"' + (this.isDocumentOperationPending ? ' disabled' : '') + '>';\n html += '<span class=\"fa-solid fa-paperclip\"></span>';\n if (this.documents.length === 0 && !this.isUploading) {\n html += ' <span>Attach files</span>';\n }\n html += '</button>';\n html += '</div>';\n if (config.supportedExtensionsText) {\n html += '<div class=\"small text-muted mt-2\">Supported formats: ' + this.escapeHtml(config.supportedExtensionsText) + '</div>';\n }\n\n html += '</div>';\n\n this.documentBar.replaceChildren(DOMPurify.sanitize(html, { RETURN_DOM_FRAGMENT: true }));\n\n // Bind remove handlers\n var self = this;\n var closeButtons = this.documentBar.querySelectorAll('[data-doc-index]');\n for (var j = 0; j < closeButtons.length; j++) {\n closeButtons[j].addEventListener('click', (function (idx) {\n return function (e) {\n e.preventDefault();\n e.stopPropagation();\n if (self.isDocumentOperationPending) {\n return;\n }\n\n var docToRemove = self.documents[idx];\n if (docToRemove) self.removeDocument(docToRemove);\n };\n })(parseInt(closeButtons[j].getAttribute('data-doc-index'))));\n }\n\n // Bind error dismiss handlers\n var errorCloseButtons = this.documentBar.querySelectorAll('[data-error-index]');\n for (var n = 0; n < errorCloseButtons.length; n++) {\n errorCloseButtons[n].addEventListener('click', (function (idx) {\n return function (e) {\n e.preventDefault();\n e.stopPropagation();\n self.uploadErrors.splice(idx, 1);\n self.renderDocumentBar();\n };\n })(parseInt(errorCloseButtons[n].getAttribute('data-error-index'))));\n }\n\n // Bind add button\n var addBtn = this.documentBar.querySelector('.ai-chat-doc-add-btn');\n if (addBtn) {\n addBtn.addEventListener('click', function (e) {\n e.preventDefault();\n if (self.isDocumentOperationPending) {\n return;\n }\n self.triggerFileInput();\n });\n }\n },\n escapeHtml(text) {\n var div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n },\n extractReadableErrorMessage(errorText, fallbackMessage) {\n if (!errorText || typeof errorText !== 'string') {\n return fallbackMessage;\n }\n\n var trimmed = errorText.trim();\n if (!trimmed) {\n return fallbackMessage;\n }\n\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n var parsed = JSON.parse(trimmed);\n var message = parsed?.error || parsed?.message || parsed?.title || parsed?.detail;\n return typeof message === 'string' && message.trim()\n ? message.trim()\n : fallbackMessage;\n } catch (err) {\n return fallbackMessage;\n }\n }\n\n if (/<[^>]+>/.test(trimmed)) {\n return fallbackMessage;\n }\n\n return trimmed;\n },\n normalizeAssistantAppearance(appearance) {\n if (!appearance) {\n return null;\n }\n\n var label = typeof appearance.label === 'string' ? appearance.label.trim() : '';\n var icon = typeof appearance.icon === 'string' ? appearance.icon.trim() : '';\n var cssClass = typeof appearance.cssClass === 'string' ? appearance.cssClass.trim() : '';\n var disableStreamingAnimation = !!appearance.disableStreamingAnimation;\n\n if (!label && !icon && !cssClass && !disableStreamingAnimation) {\n return null;\n }\n\n return {\n label: label,\n icon: icon,\n cssClass: cssClass,\n disableStreamingAnimation: disableStreamingAnimation,\n };\n },\n getAssistantLabel(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.label ? appearance.label : this.assistantLabel;\n },\n getAssistantRoleClasses(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n var classes = ['ai-chat-msg-role'];\n\n if (appearance && appearance.cssClass) {\n classes.push(appearance.cssClass);\n } else {\n classes.push('ai-chat-msg-role-assistant');\n }\n\n return classes;\n },\n getAssistantIconClasses(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return [this.shouldAnimateAssistantIcon(message, index) ? 'ai-streaming-icon' : 'ai-bot-icon', appearance && appearance.cssClass ? appearance.cssClass : ''];\n },\n getAssistantIcon(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.icon ? appearance.icon : 'fa fa-robot';\n },\n shouldAnimateAssistantIcon(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return !!message &&\n message.isStreaming &&\n index === this.lastAssistantIndex &&\n !(appearance && appearance.disableStreamingAnimation);\n },\n async startConnection() {\n this.connection = new signalR.HubConnectionBuilder()\n .withUrl(config.signalRHubUrl)\n .withAutomaticReconnect()\n .build();\n\n // Allow long-running operations (e.g., multi-step MCP tool calls)\n // without the client disconnecting prematurely.\n this.connection.serverTimeoutInMilliseconds = 600000;\n this.connection.keepAliveIntervalInMilliseconds = 15000;\n\n this.connection.on(\"LoadSession\", (data) => {\n this.initializeSession(data.sessionId, true);\n this.messages = [];\n this.documents = data.documents || [];\n this.uploadErrors = [];\n\n (data.messages ?? []).forEach(msg => {\n this.addMessage(msg);\n\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n });\n });\n\n // Update feedback icons in the DOM after all messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // When the session is new (no messages) and an initial prompt is configured,\n // automatically send it as the first user message to trigger an AI response.\n if (this.messages.length === 0 && config.initialPrompt) {\n this.prompt = config.initialPrompt;\n this.sendMessage();\n }\n });\n\n this.connection.on(\"ReceiveError\", (error) => {\n console.error(\"SignalR Error: \", error);\n\n if (this.isRecording) {\n this.stopRecording();\n }\n\n if (widgetBehavior && typeof widgetBehavior.handleReceiveError === 'function') {\n widgetBehavior.handleReceiveError(this, error, config);\n }\n });\n\n this.connection.on(\"MessageRated\", (messageId, userRating) => {\n var msg = this.messages.find(m => m.id === messageId);\n if (msg) {\n msg.userRating = userRating;\n }\n });\n\n this.connection.on(\"ReceiveTranscript\", (sessionId, text, isFinal) => {\n if (this.isConversationMode) {\n if (!isFinal && text) {\n this._conversationPartialTranscript = text;\n var escaped = text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n var html = '<p class=\"ai-partial-transcript\">' + escaped + '</p>';\n\n // Show partial transcript as a live user message.\n if (!this._conversationPartialMessage) {\n this.hidePlaceholder();\n this._conversationPartialMessage = {\n role: 'user',\n content: text,\n htmlContent: html,\n isPartial: true\n };\n this.messages.push(this._conversationPartialMessage);\n } else {\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = html;\n }\n this.scrollToBottom();\n }\n return;\n }\n\n if (text && !this._audioInputSent) {\n this.prompt = this.preRecordingPrompt + text;\n if (this.inputElement) {\n this.inputElement.value = this.prompt;\n this.inputElement.dispatchEvent(new Event('input'));\n }\n }\n });\n\n this.connection.on(\"ReceiveConversationUserMessage\", (sessionId, text) => {\n if (text) {\n this.stopAudio();\n\n // If there's an interrupted assistant message still streaming,\n // mark it as done to stop the spinner animation.\n if (this._conversationAssistantMessage) {\n var oldMsg = this.messages[this._conversationAssistantMessage.index];\n if (oldMsg) {\n oldMsg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '<p>' + escaped + '</p>';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (sessionId, messageId, token, responseId, references, appearance) => {\n if (!this._conversationAssistantMessage) {\n this.stopAudio();\n this.hideTypingIndicator();\n\n // Ensure no stale streaming indicators remain from prior messages.\n for (var j = 0; j < this.messages.length; j++) {\n if (this.messages[j].isStreaming) {\n this.messages[j].isStreaming = false;\n }\n }\n\n var msgIndex = this.messages.length;\n var newMessage = {\n id: messageId,\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n appearance: this.normalizeAssistantAppearance(appearance),\n references: {},\n };\n this.messages.push(newMessage);\n this._conversationAssistantMessage = { index: msgIndex, content: '' };\n }\n\n this._conversationAssistantMessage.content += token;\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n if (!msg.appearance) {\n msg.appearance = this.normalizeAssistantAppearance(appearance);\n }\n msg.rawContent = this._conversationAssistantMessage.content;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n this.scrollToBottom();\n });\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantComplete\", (sessionId, messageId, references) => {\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n }\n this._conversationAssistantMessage = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (sessionId, base64Audio, contentType) => {\n if (base64Audio) {\n const binaryString = atob(base64Audio);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n this.audioChunks.push(bytes);\n }\n });\n\n this.connection.on(\"ReceiveAudioComplete\", (sessionId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"ReceiveNotification\", (notification) => {\n this.receiveNotification(notification);\n });\n\n this.connection.on(\"UpdateNotification\", (notification) => {\n this.updateNotification(notification);\n });\n\n this.connection.on(\"RemoveNotification\", (notificationType) => {\n this.removeNotification(notificationType);\n });\n\n this.connection.onreconnecting(() => {\n console.warn(\"SignalR: reconnecting...\");\n });\n\n this.connection.onreconnected(() => {\n console.info(\"SignalR: reconnected.\");\n\n if (this.isSessionStarted) {\n this.reloadCurrentSession();\n } else if (config.autoCreateSession) {\n this.startNewSession();\n }\n });\n\n this.connection.onclose((error) => {\n if (this.isNavigatingAway) {\n return;\n }\n\n if (error) {\n console.warn(\"SignalR connection closed with error:\", error.message || error);\n }\n });\n\n try {\n await this.connection.start();\n } catch (err) {\n console.error(\"SignalR Connection Error: \", err);\n }\n },\n addMessageInternal(message) {\n if (message.role === 'assistant') {\n message.appearance = this.normalizeAssistantAppearance(message.appearance);\n }\n\n if (message.content && !message.htmlContent) {\n message.htmlContent = parseMarkdownContent(message.content, message);\n }\n this.fireEvent(new CustomEvent(\"addingOpenAIPromotMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedOpenAIPromotMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\n\n // Ensure userRating is always defined for Vue reactivity.\n if (message.userRating === undefined) {\n message.userRating = null;\n }\n\n if (message.content) {\n message.rawContent = message.rawContent ?? message.content;\n updateMessagePresentation(message, message.references);\n }\n\n this.addMessageInternal(message);\n this.hidePlaceholder();\n\n this.$nextTick(() => {\n // Render any pending charts once the DOM is updated\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n addMessages(messages) {\n\n for (let i = 0; i < messages.length; i++) {\n this.addMessageInternal(messages[i]);\n }\n\n this.hidePlaceholder();\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n hidePlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.add('d-none');\n }\n this.isPlaceholderVisible = false;\n },\n showPlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.remove('d-none');\n }\n this.isPlaceholderVisible = true;\n },\n isOrchestratorAvailable() {\n return config.isOrchestratorAvailable !== false;\n },\n applyOrchestratorAvailability() {\n if (this.isOrchestratorAvailable()) {\n return true;\n }\n\n const unavailableMessage = config.orchestratorUnavailableMessage || \"This orchestrator is not currently available.\";\n\n if (this.inputElement) {\n this.inputElement.disabled = true;\n this.inputElement.value = '';\n this.inputElement.placeholder = unavailableMessage;\n }\n\n if (this.buttonElement) {\n this.buttonElement.disabled = true;\n }\n\n if (this.micButtonElement) {\n this.micButtonElement.disabled = true;\n this.micButtonElement.style.display = 'none';\n }\n\n if (this.conversationButtonElement) {\n this.conversationButtonElement.disabled = true;\n this.conversationButtonElement.style.display = 'none';\n }\n\n return false;\n },\n fireEvent(event) {\n document.dispatchEvent(event);\n },\n isIndicator(message) {\n return message.role === 'indicator';\n },\n sendMessage() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n let trimmedPrompt = this.prompt.trim();\n\n if (!trimmedPrompt) {\n return;\n }\n\n // Stop any active recording before sending.\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // Prevent stale ReceiveTranscript events from repopulating the prompt.\n this._audioInputSent = true;\n\n // In single-response mode, clear all previous messages.\n if (this.singleResponseMode) {\n this.messages.splice(0, this.messages.length);\n }\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n this.streamMessage(this.getProfileId(), trimmedPrompt, null);\n this.inputElement.value = '';\n this.prompt = '';\n },\n startRecording() {\n if (this.isRecording || !this.connection) {\n return;\n }\n\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this.preRecordingPrompt = this.prompt;\n this._audioInputSent = false;\n\n var subject = new signalR.Subject();\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var pendingChunk = Promise.resolve();\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n subject.next(base64);\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => subject.complete());\n });\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"SendAudioStream\", profileId, sessionId, subject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n this.updateMicButton();\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n });\n },\n stopRecording() {\n if (!this.isRecording || !this.mediaRecorder) {\n return;\n }\n\n this.mediaRecorder.stop();\n this.isRecording = false;\n this.updateMicButton();\n },\n toggleRecording() {\n if (this.isRecording) {\n this.stopRecording();\n } else {\n this.startRecording();\n }\n },\n updateMicButton() {\n if (!this.micButton) {\n return;\n }\n\n if (this.isRecording) {\n this.micButton.classList.add('stt-recording');\n this.micButton.innerHTML = '<span class=\"fa-solid fa-stop\"></span>';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '<span class=\"fa-solid fa-microphone\"></span>';\n }\n },\n streamMessage(profileId, trimmedPrompt, sessionProfileId) {\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n\n this.streamingStarted();\n this.showTypingIndicator();\n this.autoScroll = true;\n\n var content = '';\n var references = {};\n var lastResponseId = null;\n\n // Get the index after showing typing indicator.\n var messageIndex = this.messages.length;\n var currentSessionId = this.getSessionId();\n\n this.stream = this.connection.stream(\"SendMessage\", profileId, trimmedPrompt, currentSessionId, sessionProfileId)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n\n if (chunk.sessionId && !currentSessionId) {\n this.initializeSession(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n // Re-assign the index after hiding the typing indicator.\n messageIndex = this.messages.length;\n let newMessage = {\n id: chunk.messageId,\n role: \"assistant\",\n title: chunk.title,\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n };\n\n this.messages.push(newMessage);\n\n message = newMessage;\n }\n\n if (chunk.title && (!message.title || message.title !== chunk.title)) {\n message.title = chunk.title;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\n\n // When the responseId changes (e.g., after an internal tool call),\n // insert a line break to visually separate response segments.\n if (chunk.responseId && lastResponseId && chunk.responseId !== lastResponseId) {\n content += '\\n\\n';\n }\n\n if (chunk.responseId) {\n lastResponseId = chunk.responseId;\n }\n\n content += chunk.content;\n }\n\n // Update the existing message\n message.rawContent = content;\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n complete: () => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n if (!msg || !msg.content) {\n // No content received at all.\n this.hideTypingIndicator();\n }\n\n // Trigger text-to-speech only in conversation mode.\n if (this.isConversationMode && this.textToSpeechEnabled && msg && msg.content) {\n this.synthesizeSpeech(msg.content);\n }\n\n this.stream?.dispose();\n this.stream = null;\n },\n error: (err) => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n this.hideTypingIndicator();\n\n if (!this.isNavigatingAway) {\n this.addMessage(this.getServiceDownMessage());\n }\n\n this.stream?.dispose();\n this.stream = null;\n\n console.error(\"Stream error:\", err);\n }\n });\n },\n getServiceDownMessage() {\n let newMessage = {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n\n return newMessage;\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\n\n let message = this.messages[messageIndex];\n message.rawContent = message.rawContent ?? message.content ?? '';\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n }\n },\n streamingStarted() {\n var stopIcon = this.buttonElement.getAttribute('data-stop-icon');\n\n if (stopIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(stopIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.setAttribute('disabled', 'disabled');\n }\n },\n streamingFinished() {\n var startIcon = this.buttonElement.getAttribute('data-start-icon');\n\n if (startIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(startIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.removeAttribute('disabled');\n this.inputElement.focus();\n }\n\n // Directly manipulate the DOM to stop all streaming animations.\n if (this.chatContainer) {\n var icons = this.chatContainer.querySelectorAll('.ai-streaming-icon');\n for (var i = 0; i < icons.length; i++) {\n icons[i].classList.remove('ai-streaming-icon');\n icons[i].classList.add('ai-bot-icon');\n }\n }\n\n // Also update Vue data for consistency.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n },\n handleExternalTtsStop(e) {\n if (e?.detail?.sourceId === this.ttsInstanceId) {\n return;\n }\n\n this.stopAudio(false);\n },\n updateTtsPlaybackButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-tts-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-tts-message-index'));\n var isPlaying = buttonIndex === this.ttsPlayingMessageIndex;\n var iconHtml = isPlaying\n ? '<span class=\"fa-solid fa-circle-pause\"></span>'\n : '<span class=\"fa-solid fa-circle-play\"></span>';\n\n button.classList.toggle('tts-playing', isPlaying);\n button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\n });\n },\n synthesizeSpeech(text, cacheIndex) {\n if (!this.textToSpeechEnabled || !text || !this.connection) {\n return;\n }\n\n this.audioChunks = [];\n this.isPlayingAudio = true;\n this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;\n\n this.connection.invoke(\"SynthesizeSpeech\", this.getProfileId(), this.getSessionId(), text, this.ttsVoiceName)\n .catch(err => {\n console.error(\"TTS synthesis error:\", err);\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this._ttsCacheIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n });\n },\n toggleMessageTts(message, index) {\n if (this.ttsPlayingMessageIndex === index) {\n this.stopAudio();\n return;\n }\n\n this.stopAudio(false);\n window.dispatchEvent(new CustomEvent('crestapps-ai-chat-stop-tts', {\n detail: { sourceId: this.ttsInstanceId }\n }));\n this.ttsPlayingMessageIndex = index;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n\n if (this.ttsAudioCache[index]) {\n this.playAudioBlob(this.ttsAudioCache[index]);\n return;\n }\n\n this.synthesizeSpeech(message.content, index);\n },\n playCollectedAudio() {\n if (this.audioChunks.length === 0) {\n if (!this.currentAudioElement && this.audioPlayQueue.length === 0) {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n }\n return;\n }\n\n const totalLength = this.audioChunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const combined = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of this.audioChunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n this.audioChunks = [];\n\n const blob = new Blob([combined], { type: 'audio/mp3' });\n\n if (this._ttsCacheIndex >= 0) {\n this.ttsAudioCache[this._ttsCacheIndex] = blob;\n this._ttsCacheIndex = -1;\n }\n\n // If audio is already playing, queue this blob for sequential playback.\n if (this.currentAudioElement) {\n this.audioPlayQueue.push(blob);\n return;\n }\n\n this.playAudioBlob(blob);\n },\n playAudioBlob(blob) {\n const url = URL.createObjectURL(blob);\n const audio = new Audio(url);\n\n this.currentAudioUrl = url;\n this.currentAudioElement = audio;\n this.isPlayingAudio = true;\n\n audio.addEventListener('ended', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.addEventListener('error', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.play().catch(err => {\n console.error(\"Audio playback error:\", err);\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n });\n },\n playNextInQueue() {\n if (this.audioPlayQueue.length > 0) {\n var nextBlob = this.audioPlayQueue.shift();\n this.playAudioBlob(nextBlob);\n } else {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n this.conversationModeOnAudioEnded();\n }\n },\n stopAudio() {\n if (this.currentAudioElement) {\n this.currentAudioElement.pause();\n this.currentAudioElement.currentTime = 0;\n this.currentAudioElement = null;\n }\n if (this.currentAudioUrl) {\n URL.revokeObjectURL(this.currentAudioUrl);\n this.currentAudioUrl = null;\n }\n this.audioChunks = [];\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n },\n toggleConversationMode() {\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n startConversationMode() {\n if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {\n return;\n }\n\n this.isConversationMode = true;\n this.updateConversationButton();\n this._conversationPartialTranscript = '';\n this._conversationAssistantMessage = null;\n this._conversationPartialMessage = null;\n\n // Remove any previous conversation ended notification.\n this.removeNotification('conversation-ended');\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this._conversationSubject = new signalR.Subject();\n this._conversationStream = stream;\n\n // Create an AnalyserNode for volume-based interrupt detection.\n // During TTS playback, detect when the user speaks above\n // the threshold to stop TTS (interrupt). Audio chunks are\n // always forwarded — browser echo cancellation handles\n // speaker echo so the STT stream has no gaps.\n var AudioCtx = window.AudioContext || window.webkitAudioContext;\n if (AudioCtx) {\n this._conversationAudioCtx = new AudioCtx();\n this._conversationAnalyser = this._conversationAudioCtx.createAnalyser();\n this._conversationAnalyser.fftSize = 256;\n var micSource = this._conversationAudioCtx.createMediaStreamSource(stream);\n micSource.connect(this._conversationAnalyser);\n }\n\n var pendingChunk = Promise.resolve();\n var analyser = this._conversationAnalyser;\n var interruptVolumeThreshold = 30;\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n // During TTS playback, check mic volume to detect\n // user interruption (speaking above threshold).\n if (this.isPlayingAudio && analyser) {\n var freqData = new Uint8Array(analyser.frequencyBinCount);\n analyser.getByteFrequencyData(freqData);\n var sum = 0;\n for (var k = 0; k < freqData.length; k++) { sum += freqData[k]; }\n var avg = sum / freqData.length;\n\n if (avg >= interruptVolumeThreshold) {\n // User is speaking — interrupt TTS playback.\n this.stopAudio();\n }\n }\n\n // Always send audio to STT — browser echo cancellation\n // handles speaker echo; continuous audio avoids gaps\n // that increase recognition latency.\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n try {\n this._conversationSubject.next(base64);\n } catch (err) {\n // Subject may have been completed already.\n }\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => {\n try {\n this._conversationSubject.complete();\n } catch (err) {\n // Already completed.\n }\n });\n });\n\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var language = navigator.language || document.documentElement.lang || 'en-US';\n\n this.connection.send(\"StartConversation\", profileId, sessionId, this._conversationSubject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n this.isConversationMode = false;\n this.updateConversationButton();\n });\n },\n stopConversationMode() {\n if (!this.isConversationMode) {\n return;\n }\n\n this.isConversationMode = false;\n this.updateConversationButton();\n\n // Signal the server to cancel all in-progress STT/TTS streams immediately.\n if (this.connection) {\n this.connection.invoke(\"StopConversation\").catch(function () { });\n }\n\n if (this.isRecording && this.mediaRecorder) {\n this.mediaRecorder.stop();\n this.isRecording = false;\n }\n\n this.stopAudio();\n this._conversationPartialTranscript = '';\n this._conversationPartialMessage = null;\n\n // Clean up the AudioContext used for volume monitoring.\n if (this._conversationAudioCtx) {\n this._conversationAudioCtx.close().catch(function () { });\n this._conversationAudioCtx = null;\n this._conversationAnalyser = null;\n }\n\n // Mark any in-flight assistant message as done to stop the spinner.\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Safety net: clear all lingering streaming indicators.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n\n // Show a \"conversation ended\" notification system message.\n this.receiveNotification({\n type: 'conversation-ended',\n content: 'Conversation ended.',\n icon: 'fa-solid fa-circle-check',\n dismissible: true,\n autoDismissMs: 5000\n });\n },\n updateConversationButton() {\n if (!this.conversationButton) {\n return;\n }\n\n if (this.isConversationMode) {\n this.conversationButton.classList.add('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-dark', 'btn-outline-secondary');\n this.conversationButton.title = this.conversationButton.getAttribute('data-end-title') || 'End Conversation';\n var endHtml = this.conversationButton.getAttribute('data-end-html');\n if (endHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(endHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n } else {\n this.conversationButton.classList.remove('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-secondary');\n this.conversationButton.classList.add('btn-outline-dark');\n this.conversationButton.blur();\n this.conversationButton.title = this.conversationButton.getAttribute('data-start-title') || 'Start Conversation';\n var startHtml = this.conversationButton.getAttribute('data-start-html');\n if (startHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(startHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n }\n },\n conversationModeSendPrompt() {\n // Legacy: only used by AudioInput mode's ReceiveTranscript.\n },\n conversationModeOnAudioEnded() {\n // Legacy: in conversation mode, audio playback continuation\n // is handled by the persistent stream. This method is only\n // called from playCollectedAudio for non-conversation TTS.\n },\n generatePrompt(element) {\n if (!element) {\n console.error('The element paramter is required.');\n\n return;\n }\n\n let templateProfileId = element.getAttribute('data-profile-id');\n let sessionId = this.getSessionId();\n let sessionProfileId = this.getProfileId();\n\n if (!templateProfileId || !sessionId) {\n\n console.error('The given element is missing data-profile-id or the session has not yet started.');\n return;\n }\n\n // streamMessage() already shows the typing indicator.\n this.streamMessage(templateProfileId, null, sessionProfileId);\n },\n createSessionUrl(baseUrl, param, value) {\n\n const fullUrl = baseUrl.toLowerCase().startsWith('http') ? baseUrl : window.location.origin + baseUrl;\n const url = new URL(fullUrl);\n\n url.searchParams.set(param, value);\n\n return url.toString();\n },\n showTypingIndicator() {\n this.addMessage({\n role: 'indicator',\n htmlContent: config.indicatorTemplate\n });\n },\n hideTypingIndicator() {\n const originalLength = this.messages.length;\n this.messages = this.messages.filter(msg => msg.role !== 'indicator');\n const removedCount = originalLength - this.messages.length;\n return removedCount;\n },\n receiveNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n } else {\n this.notifications.push(notification);\n }\n this.scheduleNotificationDismiss(notification);\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n updateNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n this.scheduleNotificationDismiss(notification);\n }\n },\n scheduleNotificationDismiss(notification) {\n if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {\n return;\n }\n this.notificationDismissTimers[notification.type] = setTimeout(() => {\n this.removeNotification(notification.type);\n }, notification.autoDismissMs);\n },\n clearNotificationDismiss(notificationType) {\n var timerId = this.notificationDismissTimers[notificationType];\n if (!timerId) {\n return;\n }\n clearTimeout(timerId);\n delete this.notificationDismissTimers[notificationType];\n },\n removeNotification(notificationType) {\n this.clearNotificationDismiss(notificationType);\n this.notifications = this.notifications.filter(n => n.type !== notificationType);\n },\n dismissNotification(notificationType) {\n this.removeNotification(notificationType);\n },\n handleNotificationAction(notificationType, actionName) {\n if (!this.connection) {\n return;\n }\n var sessionId = this.getSessionId();\n this.connection.invoke(\"HandleNotificationAction\", sessionId, notificationType, actionName).catch(function (err) {\n console.error(\"Error handling notification action:\", err);\n });\n },\n scrollToBottom() {\n if (!this.autoScroll) {\n return;\n }\n setTimeout(() => {\n this.chatContainer.scrollTop = this.chatContainer.scrollHeight - this.chatContainer.clientHeight;\n }, 50);\n },\n handleUserInput(event) {\n this.prompt = event.target.value;\n },\n getProfileId() {\n return this.inputElement\n ? this.inputElement.getAttribute('data-profile-id')\n : null;\n },\n setSessionId(sessionId) {\n if (!this.inputElement) {\n return;\n }\n\n this.inputElement.setAttribute('data-session-id', sessionId || '');\n },\n resetSession() {\n this.stopRecording();\n this.rejectPendingSessionRequest('Session was reset.');\n this.setSessionId('');\n this.isSessionStarted = false;\n this.sessionRating = null;\n this.messages = [];\n this.documents = [];\n if (!config.autoCreateSession) {\n this.showPlaceholder();\n }\n\n if (config.autoCreateSession) {\n this.startNewSession();\n }\n\n if (widgetBehavior && typeof widgetBehavior.onSessionReset === 'function') {\n widgetBehavior.onSessionReset(this, config);\n }\n },\n startNewSession() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n const profileId = this.getProfileId();\n if (!profileId || !this.connection) {\n return;\n }\n\n this.requestNewSession(profileId).catch(err => console.error(err));\n },\n async ensureSessionForDocuments(profileId) {\n var sessionId = this.getSessionId();\n if (sessionId) {\n return sessionId;\n }\n\n if (!profileId || !this.connection) {\n return null;\n }\n\n return await this.requestNewSession(profileId);\n },\n requestNewSession(profileId) {\n if (this.pendingSessionPromise) {\n return this.pendingSessionPromise;\n }\n\n if (!profileId || !this.connection) {\n return Promise.resolve(null);\n }\n\n this.pendingSessionPromise = new Promise((resolve, reject) => {\n this.pendingSessionResolver = resolve;\n this.pendingSessionRejector = reject;\n this.pendingSessionTimeoutId = window.setTimeout(() => {\n this.rejectPendingSessionRequest('Timed out while creating a chat session.');\n }, 15000);\n });\n\n this.connection.invoke(\"StartSession\", profileId, null).catch(err => {\n this.rejectPendingSessionRequest(err);\n });\n\n return this.pendingSessionPromise;\n },\n resolvePendingSessionRequest(sessionId) {\n if (this.pendingSessionResolver) {\n this.pendingSessionResolver(sessionId);\n }\n\n this.clearPendingSessionRequest();\n },\n rejectPendingSessionRequest(error) {\n if (this.pendingSessionRejector) {\n this.pendingSessionRejector(error);\n }\n\n this.clearPendingSessionRequest();\n },\n clearPendingSessionRequest() {\n if (this.pendingSessionTimeoutId) {\n window.clearTimeout(this.pendingSessionTimeoutId);\n }\n\n this.pendingSessionPromise = null;\n this.pendingSessionResolver = null;\n this.pendingSessionRejector = null;\n this.pendingSessionTimeoutId = null;\n },\n initializeApp() {\n this.inputElement = document.querySelector(config.inputElementSelector);\n this.buttonElement = document.querySelector(config.sendButtonElementSelector);\n this.chatContainer = document.querySelector(config.chatContainerElementSelector);\n this.placeholder = document.querySelector(config.placeholderElementSelector);\n\n if (!this.inputElement || !this.buttonElement || !this.chatContainer || !this.placeholder) {\n console.error('AI chat app could not initialize because one or more required elements were not found.', {\n inputElementSelector: config.inputElementSelector,\n sendButtonElementSelector: config.sendButtonElementSelector,\n chatContainerElementSelector: config.chatContainerElementSelector,\n placeholderElementSelector: config.placeholderElementSelector\n });\n\n return false;\n }\n\n this.applyOrchestratorAvailability();\n\n const sessionId = this.getSessionId();\n if (!hasWidgetConfig && sessionId) {\n this.loadSession(sessionId);\n } else if (this.isOrchestratorAvailable() && config.autoCreateSession && !hasWidgetConfig && !sessionId) {\n this.startNewSession();\n }\n\n // Initialize document bar if enabled.\n if (config.sessionDocumentsEnabled && config.documentBarSelector) {\n this.documentBar = document.querySelector(config.documentBarSelector);\n if (this.documentBar) {\n this.renderDocumentBar();\n\n // Create hidden file input for document uploads.\n var fileInput = document.createElement('input');\n fileInput.type = 'file';\n fileInput.id = 'ai-chat-doc-input';\n fileInput.className = 'd-none';\n fileInput.multiple = true;\n if (config.allowedExtensions) {\n fileInput.accept = config.allowedExtensions;\n }\n fileInput.addEventListener('change', (e) => this.handleFileInputChange(e));\n this.documentBar.parentElement.appendChild(fileInput);\n\n // Set up drag-and-drop on the input area.\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) {\n inputArea.addEventListener('dragover', (e) => this.handleDragOver(e));\n inputArea.addEventListener('dragleave', (e) => this.handleDragLeave(e));\n inputArea.addEventListener('drop', (e) => this.handleDrop(e));\n }\n }\n }\n\n // Pause auto-scroll when the user manually scrolls up during streaming.\n this.chatContainer.addEventListener('scroll', () => {\n if (!this.stream) {\n return;\n }\n const threshold = 30;\n const atBottom = this.chatContainer.scrollHeight - this.chatContainer.clientHeight - this.chatContainer.scrollTop <= threshold;\n this.autoScroll = atBottom;\n });\n\n this.inputElement.addEventListener('keydown', event => {\n\n if (this.stream != null) {\n return;\n }\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n this.buttonElement.click();\n }\n });\n\n this.inputElement.addEventListener('input', (e) => {\n this.handleUserInput(e);\n\n if (e.target.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n });\n\n this.buttonElement.addEventListener('click', () => {\n\n if (this.stream != null) {\n this.stream.dispose();\n this.stream = null;\n\n this.streamingFinished();\n this.hideTypingIndicator();\n\n // Clean up: remove empty assistant message or stop streaming animation.\n if (this.messages.length > 0) {\n const lastMsg = this.messages[this.messages.length - 1];\n if (lastMsg.role === 'assistant' && !lastMsg.content) {\n this.messages.pop();\n } else if (lastMsg.isStreaming) {\n lastMsg.isStreaming = false;\n }\n }\n\n return;\n }\n\n this.sendMessage();\n });\n\n const promptGenerators = document.getElementsByClassName('profile-generated-prompt');\n\n for (var i = 0; i < promptGenerators.length; i++) {\n promptGenerators[i].addEventListener('click', (e) => {\n e.preventDefault();\n this.generatePrompt(e.target);\n });\n }\n\n const chatSessions = document.getElementsByClassName('chat-session-history-item');\n\n for (var i = 0; i < chatSessions.length; i++) {\n chatSessions[i].addEventListener('click', (e) => {\n e.preventDefault();\n\n var sessionId = e.target.getAttribute('data-session-id');\n\n if (!sessionId) {\n console.error('an element with the class chat-session-history-item with no data-session-id set.');\n\n return;\n }\n\n this.loadSession(sessionId);\n this.showChatScreen();\n });\n }\n\n for (let i = 0; i < config.messages.length; i++) {\n this.addMessage(config.messages[i]);\n }\n\n // Update feedback icons in the DOM after initial messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // Delegate click for code block copy buttons.\n if (this.chatContainer) {\n this.chatContainer.addEventListener('click', (e) => {\n var btn = e.target.closest('.ai-code-copy-btn');\n if (!btn) {\n return;\n }\n\n var block = btn.closest('.ai-code-block') || btn.closest('pre');\n if (!block) {\n return;\n }\n\n var codeEl = block.querySelector('code');\n if (codeEl) {\n navigator.clipboard.writeText(codeEl.textContent);\n var copiedText = config.codeCopiedText || 'Copied!';\n btn.innerHTML = '<span class=\"fa-solid fa-check\"></span> ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '<span class=\"fa-regular fa-copy\"></span>';\n }, 2000);\n }\n });\n }\n\n // Initialize speech-to-text microphone button.\n if (this.speechToTextEnabled && config.micButtonElementSelector) {\n this.micButton = document.querySelector(config.micButtonElementSelector);\n if (this.micButton) {\n this.micButton.style.display = '';\n this.micButton.addEventListener('click', () => {\n this.toggleRecording();\n });\n }\n }\n\n // Initialize conversation mode button.\n if (this.conversationModeEnabled && config.conversationButtonElementSelector) {\n this.conversationButton = document.querySelector(config.conversationButtonElementSelector);\n if (this.conversationButton) {\n this.conversationButton.addEventListener('click', () => {\n this.toggleConversationMode();\n });\n }\n }\n\n return true;\n },\n loadSession(sessionId) {\n this.connection.invoke(\"LoadSession\", sessionId).catch(err => console.error(err));\n },\n reloadCurrentSession() {\n\n var sessionId = this.getSessionId();\n if (sessionId) {\n this.loadSession(sessionId);\n }\n },\n initializeSession(sessionId, force) {\n if (this.isSessionStarted && !force) {\n if (sessionId && this.getSessionId() === sessionId) {\n this.resolvePendingSessionRequest(sessionId);\n }\n\n return\n }\n this.fireEvent(new CustomEvent(\"initializingSessionOpenAIChat\", { detail: { sessionId: sessionId } }))\n this.setSessionId(sessionId);\n this.isSessionStarted = true;\n this.resolvePendingSessionRequest(sessionId);\n\n if (widgetBehavior && typeof widgetBehavior.onSessionInitialized === 'function') {\n widgetBehavior.onSessionInitialized(this, sessionId, config);\n }\n },\n getSessionId() {\n let sessionId = this.inputElement\n ? this.inputElement.getAttribute('data-session-id')\n : null;\n\n if (!sessionId && widgetBehavior && typeof widgetBehavior.resolveSessionId === 'function') {\n sessionId = widgetBehavior.resolveSessionId(this, config);\n }\n\n return sessionId;\n },\n copyResponse(message) {\n const text = message && typeof message === 'object'\n ? message.copyContent ?? message.content ?? ''\n : message ?? '';\n\n navigator.clipboard.writeText(text);\n },\n updateFeedbackIcons(container, userRating) {\n if (!container) {\n return;\n }\n\n var upBtn = container.querySelector('.rate-up-btn');\n var downBtn = container.querySelector('.rate-down-btn');\n\n // Keep feedback icons as simple span-based Font Awesome markup so\n // later state updates do not depend on i2svg replacement.\n if (upBtn) {\n var upClass = userRating === true ? 'fa-solid fa-thumbs-up' : 'fa-regular fa-thumbs-up';\n var upIcon = document.createElement('span');\n upIcon.className = upClass;\n upIcon.style.fontSize = '0.9rem';\n upBtn.textContent = '';\n upBtn.appendChild(upIcon);\n }\n\n if (downBtn) {\n var downClass = userRating === false ? 'fa-solid fa-thumbs-down' : 'fa-regular fa-thumbs-down';\n var downIcon = document.createElement('span');\n downIcon.className = downClass;\n downIcon.style.fontSize = '0.9rem';\n downBtn.textContent = '';\n downBtn.appendChild(downIcon);\n }\n },\n refreshAllFeedbackIcons() {\n var containers = this.$el.querySelectorAll('.ai-chat-message-assistant-feedback');\n\n for (var i = 0; i < containers.length; i++) {\n var msgId = containers[i].getAttribute('data-message-id');\n var msg = this.messages.find(m => m.id === msgId);\n\n if (msg) {\n this.updateFeedbackIcons(containers[i], msg.userRating);\n }\n }\n },\n rateMessage(message, isPositive, event) {\n var sessionId = this.getSessionId();\n\n if (!sessionId || !message.id || !this.connection) {\n return;\n }\n\n // Toggle: clicking the same rating again clears it.\n var newRating = message.userRating === isPositive ? null : isPositive;\n message.userRating = newRating;\n\n // Find the feedback container by message ID for reliable DOM targeting.\n var feedbackContainer = this.$el.querySelector(\n '.ai-chat-message-assistant-feedback[data-message-id=\"' + message.id + '\"]'\n );\n\n this.updateFeedbackIcons(feedbackContainer, newRating);\n\n // Trigger spark animation after Font Awesome has re-processed icons.\n if (newRating !== null && feedbackContainer) {\n setTimeout(() => {\n var btnClass = isPositive ? '.rate-up-btn' : '.rate-down-btn';\n var btn = feedbackContainer.querySelector(btnClass);\n\n if (btn) {\n btn.classList.remove('spark-effect');\n void btn.offsetWidth;\n btn.classList.add('spark-effect');\n btn.addEventListener('animationend', function onEnd() {\n btn.removeEventListener('animationend', onEnd);\n btn.classList.remove('spark-effect');\n });\n }\n }, 50);\n }\n\n this.connection.invoke(\"RateMessage\", sessionId, message.id, isPositive).catch(function (err) {\n console.error('Failed to rate message:', err);\n });\n }\n },\n watch: {\n documents: {\n handler() {\n this.renderDocumentBar();\n if (widgetBehavior && typeof widgetBehavior.onDocumentsChanged === 'function') {\n widgetBehavior.onDocumentsChanged(this, this.documents, config);\n }\n },\n deep: true\n },\n isUploading() { this.renderDocumentBar(); },\n isDocumentOperationPending() { this.renderDocumentBar(); },\n isPlayingAudio() {\n // Reserved for future use — volume-based interrupt detection\n // no longer mutes tracks; browser echo cancellation handles echo.\n },\n isConversationMode(active) {\n // Hide/show mic button.\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n // Hide/show send button.\n if (this.buttonElement) {\n this.buttonElement.style.display = active ? 'none' : '';\n }\n\n // Disable/enable textarea.\n if (this.inputElement) {\n this.inputElement.disabled = active;\n if (active) {\n this.inputElement.placeholder = '';\n }\n }\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n const isInitialized = this.initializeApp();\n if (isInitialized && hasWidgetConfig && widgetBehavior && typeof widgetBehavior.onMounted === 'function') {\n widgetBehavior.onMounted(this, config);\n }\n })();\n\n window.addEventListener('beforeunload', this.handleBeforeUnload);\n window.addEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n },\n beforeUnmount() {\n window.removeEventListener('beforeunload', this.handleBeforeUnload);\n window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n\n this.stopAudio(false);\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n if (this.connection) {\n this.connection.stop();\n }\n\n if (widgetBehavior && typeof widgetBehavior.onBeforeUnmount === 'function') {\n widgetBehavior.onBeforeUnmount(this, config);\n }\n },\n template: config.messageTemplate\n };\n\n const app = Vue.createApp(appDefinition).mount(config.appElementSelector);\n\n if (widgetBehavior && typeof widgetBehavior.attach === 'function') {\n widgetBehavior.attach(app, config);\n }\n\n return app;\n };\n\n return {\n initialize: initialize\n };\n}();\n\n// Download chart as image via event delegation (DOMPurify strips inline onclick).\ndocument.addEventListener('click', function (e) {\n const btn = e.target.closest('.download-chart-btn');\n if (!btn) {\n return;\n }\n const chartId = btn.getAttribute('data-chart-id');\n const canvas = chartId ? document.getElementById(chartId) : null;\n if (!canvas) {\n console.error('Chart canvas not found:', chartId);\n return;\n }\n const link = document.createElement('a');\n link.download = 'chart-' + chartId + '.png';\n link.href = canvas.toDataURL('image/png');\n link.click();\n});\n\n// Intercept download clicks for data-URI images and convert to blob downloads.\ndocument.addEventListener('click', function (e) {\n const link = e.target.closest('.ai-download-image');\n if (!link) {\n return;\n }\n\n const container = link.closest('.generated-image-container');\n const img = container?.querySelector('img');\n if (!img) {\n return;\n }\n\n const src = img.src;\n if (!src || !src.startsWith('data:')) {\n return; // Normal URL – let the default <a> behaviour handle it.\n }\n\n e.preventDefault();\n\n fetch(src)\n .then(function (res) { return res.blob(); })\n .then(function (blob) {\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = link.getAttribute('download') || 'generated-image.png';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n setTimeout(function () { URL.revokeObjectURL(url); }, 100);\n })\n .catch(function (err) { console.error('Failed to download image:', err); });\n});\n\n"]}
|
|
1
|
+
{"version":3,"sources":["ai-chat.js"],"names":["_excluded","_regenerator","e","t","r","Symbol","n","iterator","o","toStringTag","i","c","prototype","Generator","u","Object","create","_regeneratorDefine2","f","p","y","G","v","a","d","bind","length","l","TypeError","call","done","value","GeneratorFunction","GeneratorFunctionPrototype","getPrototypeOf","this","setPrototypeOf","__proto__","displayName","w","m","defineProperty","_invoke","enumerable","configurable","writable","asyncGeneratorStep","Promise","resolve","then","_asyncToGenerator","arguments","apply","_next","_throw","_toConsumableArray","_arrayWithoutHoles","_iterableToArray","_unsupportedIterableToArray","_nonIterableSpread","Array","from","isArray","_arrayLikeToArray","_objectWithoutProperties","_objectWithoutPropertiesLoose","getOwnPropertySymbols","indexOf","propertyIsEnumerable","hasOwnProperty","_createForOfIteratorHelper","_n","F","s","next","_slicedToArray","_arrayWithHoles","_iterableToArrayLimit","_nonIterableRest","toString","slice","constructor","name","test","push","_typeof","window","openAIChatManager","defaultConfig","generatedImageAltText","generatedImageMaxWidth","downloadImageTitle","downloadChartTitle","downloadChartButtonText","userLabel","assistantLabel","thumbsUpTitle","thumbsDownTitle","copyTitle","codeCopiedText","widget","chatWidgetContainer","chatWidgetStateName","chatHistorySection","showHistoryButton","closeHistoryButton","newChatButton","toggleButtonSelector","resetSizeButtonSelector","dragHandleSelector","enableDragging","enableResizing","persistLayout","defaultWidth","defaultHeight","minWidth","minHeight","messageTemplate","indicatorTemplate","sanitizeUrl","url","trimmed","trim","escapeHtmlEntities","text","span","document","createElement","textContent","innerHTML","normalizeReference","reference","_ref","_normalized$index","_ref2","_normalized$text","_ref3","_normalized$title","_ref4","_normalized$link","_ref5","_normalized$reference","normalized","assign","index","Index","Text","title","Title","link","Link","referenceType","ReferenceType","isDownloadCitationReference","toLowerCase","normalizeReferences","references","_i","_Object$entries","entries","_normalizeReference","_Object$entries$_i","key","getCitationLabel","updateMessagePresentation","message","messageReferences","rawContent","content","citationDisplay","processedContent","keys","citations","citedRefs","filter","_ref6","includes","sort","_ref8","_ref9","b","_step","displayIndex","_iterator","_step$value","placeholder","concat","replaceAll","referenceKey","label","isDownload","err","_i2","_citations","citation","map","_ref10","buildCitationDisplay","displayContent","citationReferences","copyContent","_step2","_iterator2","_step3","_iterator3","trimEnd","buildCopyContent","htmlContent","parseMarkdownContent","renderer","marked","Renderer","data","href","code","lang","highlighted","hljs","getLanguage","highlight","language","_","highlightAuto","langDisplay","image","src","alt","maxWidth","chartCounter","_pendingCharts","renderChartsInMessage","charts","requestAnimationFrame","_step4","_iterator4","renderChartOnCanvas","chartId","config","canvas","getElementById","Chart","console","warn","offsetParent","__chartConfigs","_cfg$options","_cfg$options2","_cfg$options2$aspectR","_chartInstance","destroy","cfg","JSON","parse","options","responsive","maintainAspectRatio","aspectRatio","error","html","DOMPurify","sanitize","ADD_TAGS","ADD_ATTR","use","extensions","level","start","idx","undefined","tokenizer","extracted","token","jsonStart","depth","inString","escape","ch","jsonEnd","closeBracketIndex","startIndex","endIndex","json","substring","tryExtractChartMarker","type","raw","renderPendingCharts","configs","_i3","_Object$keys","initialize","instanceConfig","hasWidgetConfig","widgetBehavior","openAIChatWidgetBehavior","signalRHubUrl","appElementSelector","chatContainerElementSelector","inputElementSelector","sendButtonElementSelector","appDefinition","inputElement","buttonElement","chatContainer","isSessionStarted","isPlaceholderVisible","isStreaming","isNavigatingAway","autoScroll","stream","messages","notifications","prompt","documents","existingDocuments","isUploading","isDocumentOperationPending","documentOperationQueue","uploadErrors","isDragOver","documentBar","metricsEnabled","isRecording","mediaRecorder","preRecordingPrompt","micButton","speechToTextEnabled","chatMode","textToSpeechEnabled","ttsVoiceName","audioChunks","audioPlayQueue","isPlayingAudio","currentAudioElement","currentAudioUrl","ttsButton","ttsPlayingMessageIndex","ttsAudioCache","ttsInstanceId","Math","random","singleResponseMode","conversationModeEnabled","conversationButton","isConversationMode","notificationDismissTimers","pendingSessionPromise","pendingSessionResolver","pendingSessionRejector","pendingSessionTimeoutId","computed","lastAssistantIndex","role","methods","handleBeforeUnload","handleDragOver","sessionDocumentsEnabled","preventDefault","stopPropagation","inputArea","closest","classList","add","handleDragLeave","remove","handleDrop","dataTransfer","files","uploadFiles","triggerFileInput","fileInput","click","handleFileInputChange","target","queueDocumentOperation","operation","self","nextOperation","_callee","_context","_this","_callee3","filesToUpload","_context3","uploadDocumentUrl","_callee2","sessionId","profileId","formData","response","errorText","uploadError","result","_t","_t2","_context2","getSessionId","getProfileId","ensureSessionForDocuments","fileName","renderDocumentBar","FormData","append","fetch","method","body","ok","extractReadableErrorMessage","initializeSession","uploaded","failed","reloadCurrentSession","removeDocument","doc","_this2","_callee5","_context5","removeDocumentUrl","_callee4","removeError","_t3","_context4","headers","stringify","itemId","documentId","splice","status","formatFileSize","bytes","toFixed","escapeHtml","failedItem","failedName","errorMsg","supportedExtensionsText","replaceChildren","RETURN_DOM_FRAGMENT","closeButtons","querySelectorAll","j","addEventListener","docToRemove","parseInt","getAttribute","errorCloseButtons","addBtn","querySelector","div","fallbackMessage","startsWith","parsed","detail","normalizeAssistantAppearance","appearance","icon","cssClass","disableStreamingAnimation","getAssistantLabel","getAssistantRoleClasses","classes","getAssistantIconClasses","shouldAnimateAssistantIcon","getAssistantIcon","startConnection","_this3","_callee6","_t4","_context6","connection","signalR","HubConnectionBuilder","withUrl","withAutomaticReconnect","build","serverTimeoutInMilliseconds","keepAliveIntervalInMilliseconds","on","_data$messages","forEach","msg","addMessage","$nextTick","refreshAllFeedbackIcons","initialPrompt","sendMessage","stopRecording","handleReceiveError","messageId","userRating","find","id","isFinal","_conversationPartialTranscript","replace","_conversationPartialMessage","hidePlaceholder","isPartial","scrollToBottom","_audioInputSent","dispatchEvent","Event","stopAudio","_conversationAssistantMessage","oldMsg","escaped","responseId","hideTypingIndicator","msgIndex","newMessage","base64Audio","contentType","binaryString","atob","Uint8Array","charCodeAt","playCollectedAudio","notification","receiveNotification","updateNotification","notificationType","removeNotification","onreconnecting","onreconnected","info","autoCreateSession","startNewSession","onclose","addMessageInternal","_this4","fireEvent","CustomEvent","_message$rawContent","_this5","addMessages","_this6","showPlaceholder","isOrchestratorAvailable","applyOrchestratorAvailability","unavailableMessage","orchestratorUnavailableMessage","disabled","micButtonElement","style","display","conversationButtonElement","event","isIndicator","trimmedPrompt","streamMessage","startRecording","_this7","navigator","mediaDevices","getUserMedia","audio","echoCancellation","noiseSuppression","autoGainControl","mimeType","MediaRecorder","isTypeSupported","audioBitsPerSecond","subject","Subject","pendingChunk","size","_callee7","uint8Array","base64","_context7","arrayBuffer","reduce","str","byte","String","fromCharCode","btoa","getTracks","track","stop","complete","documentElement","send","updateMicButton","toggleRecording","sessionProfileId","_this8","dispose","streamingStarted","showTypingIndicator","lastResponseId","messageIndex","currentSessionId","subscribe","chunk","_i4","_Object$entries2","_normalizeReference2","_Object$entries2$_i","_this8$stream","processReferences","streamingFinished","synthesizeSpeech","_this8$stream2","getServiceDownMessage","_this9","_ref15","_message$rawContent2","stopIcon","setAttribute","startIcon","removeAttribute","focus","icons","handleExternalTtsStop","_e$detail","sourceId","updateTtsPlaybackButtons","_this0","button","isPlaying","Number","iconHtml","toggle","cacheIndex","_this1","_ttsCacheIndex","invoke","toggleMessageTts","_this10","playAudioBlob","_this11","_step5","totalLength","sum","combined","offset","_iterator5","set","blob","Blob","_this12","URL","createObjectURL","Audio","revokeObjectURL","playNextInQueue","play","_this13","nextBlob","shift","conversationModeOnAudioEnded","_this14","pause","currentTime","toggleConversationMode","stopConversationMode","startConversationMode","_this15","updateConversationButton","_conversationSubject","_conversationStream","AudioCtx","AudioContext","webkitAudioContext","_conversationAudioCtx","_conversationAnalyser","createAnalyser","fftSize","createMediaStreamSource","connect","analyser","freqData","frequencyBinCount","getByteFrequencyData","k","_callee8","_context8","close","dismissible","autoDismissMs","endHtml","blur","startHtml","conversationModeSendPrompt","generatePrompt","element","templateProfileId","createSessionUrl","baseUrl","param","fullUrl","location","origin","searchParams","originalLength","_this16","clearNotificationDismiss","existingIndex","findIndex","scheduleNotificationDismiss","_this17","setTimeout","timerId","clearTimeout","dismissNotification","handleNotificationAction","actionName","_this18","scrollTop","scrollHeight","clientHeight","handleUserInput","setSessionId","resetSession","rejectPendingSessionRequest","sessionRating","onSessionReset","requestNewSession","_this19","_callee9","_context9","_this20","reject","resolvePendingSessionRequest","clearPendingSessionRequest","initializeApp","_this21","placeholderElementSelector","loadSession","documentBarSelector","className","multiple","allowedExtensions","accept","parentElement","appendChild","atBottom","shiftKey","lastMsg","pop","promptGenerators","getElementsByClassName","chatSessions","showChatScreen","btn","block","codeEl","clipboard","writeText","copiedText","micButtonElementSelector","conversationButtonElementSelector","force","onSessionInitialized","resolveSessionId","copyResponse","_ref17","_message$copyContent","updateFeedbackIcons","container","upBtn","downBtn","upClass","upIcon","fontSize","downClass","downIcon","containers","$el","msgId","rateMessage","isPositive","newRating","feedbackContainer","btnClass","offsetWidth","onEnd","removeEventListener","watch","handler","onDocumentsChanged","deep","active","mounted","_this22","_callee0","_context0","onMounted","beforeUnmount","onBeforeUnmount","template","app","Vue","createApp","mount","attach","download","toDataURL","img","res","removeChild"],"mappings":"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","file":"ai-chat.min.js","sourcesContent":["window.openAIChatManager = function () {\n\n // Defaults (can be overridden by instanceConfig)\n var defaultConfig = {\n // UI defaults for generated media\n generatedImageAltText: 'Generated Image',\n generatedImageMaxWidth: 400,\n downloadImageTitle: 'Download image',\n downloadChartTitle: 'Download chart as image',\n downloadChartButtonText: 'Download',\n userLabel: 'You',\n assistantLabel: 'Assistant',\n thumbsUpTitle: 'Thumbs up',\n thumbsDownTitle: 'Thumbs down',\n copyTitle: 'Click here to copy response to clipboard.',\n codeCopiedText: 'Copied!',\n widget: {\n chatWidgetContainer: null,\n chatWidgetStateName: null,\n chatHistorySection: null,\n showHistoryButton: null,\n closeHistoryButton: null,\n newChatButton: null,\n toggleButtonSelector: null,\n resetSizeButtonSelector: null,\n dragHandleSelector: '.ai-chat-widget-header',\n enableDragging: true,\n enableResizing: true,\n persistLayout: true,\n defaultWidth: null,\n defaultHeight: null,\n minWidth: 320,\n minHeight: 420\n },\n messageTemplate: `\n <div class=\"ai-chat-messages\">\n <div v-for=\"(message, index) in messages\" :key=\"'msg-' + index\" class=\"ai-chat-message-item\">\n <div>\n <div v-if=\"message.role === 'user'\" class=\"ai-chat-msg-role ai-chat-msg-role-user\">{{ userLabel }}</div>\n <div v-else-if=\"message.role !== 'indicator'\" :class=\"getAssistantRoleClasses(message)\">\n <span :class=\"getAssistantIconClasses(message, index)\"><span :class=\"getAssistantIcon(message)\"></span></span>\n {{ getAssistantLabel(message) }}\n </div>\n <div class=\"ai-chat-message-body lh-base\">\n <h4 v-if=\"message.title\">{{ message.title }}</h4>\n <div v-html=\"message.htmlContent\"></div>\n <ol v-if=\"message.citationReferences && message.citationReferences.length\" class=\"ai-chat-citation-list\">\n <li v-for=\"citation in message.citationReferences\" :key=\"'citation-' + (citation.referenceKey || citation.displayIndex)\" class=\"ai-chat-citation-item\">\n <a v-if=\"citation.link\" :href=\"citation.link\" :target=\"citation.isDownload ? null : '_blank'\" :rel=\"citation.isDownload ? null : 'noopener noreferrer'\">{{ citation.label }}</a>\n <span v-else>{{ citation.label }}</span>\n </li>\n </ol>\n <span class=\"message-buttons-container\" v-if=\"!isIndicator(message)\">\n <template v-if=\"metricsEnabled && message.role === 'assistant'\">\n <span class=\"ai-chat-message-assistant-feedback\" :data-message-id=\"message.id\">\n <button class=\"btn btn-sm btn-link text-success p-0 me-2 button-message-toolbox rate-up-btn\" @click=\"rateMessage(message, true, $event)\" :title=\"thumbsUpTitle\">\n <span class=\"fa-regular fa-thumbs-up\"></span>\n </button>\n <button class=\"btn btn-sm btn-link text-danger p-0 me-2 button-message-toolbox rate-down-btn\" @click=\"rateMessage(message, false, $event)\" :title=\"thumbsDownTitle\">\n <span class=\"fa-regular fa-thumbs-down\"></span>\n </button>\n </span>\n </template>\n <button v-if=\"textToSpeechEnabled && !isConversationMode && message.role === 'assistant' && !message.isStreaming\" class=\"btn btn-sm btn-link text-secondary p-0 me-1 button-message-toolbox\" :class=\"{ 'tts-playing': ttsPlayingMessageIndex === index }\" :data-tts-message-index=\"index\" @click=\"toggleMessageTts(message, index)\" :title=\"ttsPlayingMessageIndex === index ? 'Pause audio' : 'Read aloud'\">\n <span :class=\"ttsPlayingMessageIndex === index ? 'fa-solid fa-circle-pause' : 'fa-solid fa-circle-play'\"></span>\n </button>\n <button class=\"btn btn-sm btn-link text-secondary p-0 button-message-toolbox\" @click=\"copyResponse(message)\" :title=\"copyTitle\">\n <span class=\"fa-solid fa-copy\"></span>\n </button>\n </span>\n </div>\n </div>\n </div>\n <div v-for=\"notification in notifications\" :key=\"'notif-' + notification.type\" class=\"ai-chat-notification\" :class=\"'ai-chat-notification-' + (notification.type || 'info') + ' ' + (notification.cssClass || '')\">\n <div class=\"ai-chat-notification-content\">\n <span v-if=\"notification.icon\" :class=\"notification.icon\" class=\"ai-chat-notification-icon\"></span>\n <span class=\"ai-chat-notification-text\">{{ notification.content }}</span>\n <button v-if=\"notification.dismissible\" class=\"btn btn-sm btn-link p-0 ms-2 ai-chat-notification-dismiss\" @click=\"dismissNotification(notification.type)\" title=\"Dismiss\">\n <span class=\"fa-solid fa-xmark\"></span>\n </button>\n </div>\n <div v-if=\"notification.actions && notification.actions.length\" class=\"ai-chat-notification-actions\">\n <button v-for=\"action in notification.actions\" :key=\"action.name\" class=\"btn btn-sm\" :class=\"action.cssClass || 'btn-outline-secondary'\" @click=\"handleNotificationAction(notification.type, action.name)\">\n <span v-if=\"action.icon\" :class=\"action.icon\" class=\"me-1\"></span>\n {{ action.label }}\n </button>\n </div>\n </div>\n </div>\n `,\n indicatorTemplate: `\n <div class=\"ai-chat-msg-role ai-chat-msg-role-assistant\">\n <span class=\"ai-streaming-icon\"><span class=\"fa fa-robot\" style=\"display: inline-block;\"></span></span>\n Assistant\n </div>\n `\n };\n\n // Sanitize URLs to prevent javascript: protocol injection.\n function sanitizeUrl(url) {\n if (!url) return '';\n var trimmed = url.trim();\n if (/^javascript:/i.test(trimmed) || /^vbscript:/i.test(trimmed) || /^data:text\\/html/i.test(trimmed)) {\n return '';\n }\n return url;\n }\n\n // Safely HTML-encode a string using the DOM (avoids regex-based HTML filtering).\n function escapeHtmlEntities(text) {\n var span = document.createElement('span');\n span.textContent = text;\n return span.innerHTML;\n }\n\n function parsePixelValue(value) {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n\n if (typeof value !== 'string') {\n return null;\n }\n\n var parsed = parseFloat(value);\n return Number.isFinite(parsed) ? parsed : null;\n }\n\n function clamp(value, min, max) {\n return Math.min(Math.max(value, min), max);\n }\n\n function normalizeReference(reference) {\n if (!reference || typeof reference !== 'object') {\n return null;\n }\n\n const normalized = Object.assign({}, reference);\n normalized.index = normalized.index ?? normalized.Index ?? 0;\n normalized.text = normalized.text ?? normalized.Text ?? null;\n normalized.title = normalized.title ?? normalized.Title ?? null;\n normalized.link = sanitizeUrl(normalized.link ?? normalized.Link ?? null);\n normalized.referenceType = normalized.referenceType ?? normalized.ReferenceType ?? null;\n\n return normalized;\n }\n\n function isDownloadCitationReference(reference) {\n if (!reference || typeof reference !== 'object') {\n return false;\n }\n\n if (typeof reference.referenceType === 'string' && reference.referenceType.toLowerCase() === 'document') {\n return true;\n }\n\n if (typeof reference.link === 'string' && /\\/ai\\/documents\\/.+\\/download(?:$|\\?)/i.test(reference.link)) {\n return true;\n }\n\n return false;\n }\n\n function normalizeReferences(references) {\n if (!references || typeof references !== 'object') {\n return {};\n }\n\n const normalized = {};\n\n for (const [key, value] of Object.entries(references)) {\n normalized[key] = normalizeReference(value) ?? {};\n }\n\n return normalized;\n }\n\n function getCitationLabel(reference, key) {\n return reference.title || reference.text || key;\n }\n\n function buildCitationDisplay(content, references) {\n let processedContent = (content || '').trim();\n const messageReferences = normalizeReferences(references);\n\n if (!processedContent || !Object.keys(messageReferences).length) {\n return { content: processedContent, citations: [] };\n }\n\n const citedRefs = Object.entries(messageReferences).filter(([key]) => processedContent.includes(key));\n\n if (!citedRefs.length) {\n return { content: processedContent, citations: [] };\n }\n\n citedRefs.sort(([, a], [, b]) => a.index - b.index);\n\n const citations = [];\n let displayIndex = 1;\n\n for (const [key, value] of citedRefs) {\n const placeholder = `__CITE_${displayIndex}_${value.index || displayIndex}__`;\n processedContent = processedContent.replaceAll(key, placeholder);\n citations.push({\n referenceKey: key,\n displayIndex: displayIndex,\n label: getCitationLabel(value, key),\n link: value.link || null,\n isDownload: isDownloadCitationReference(value),\n placeholder: placeholder,\n });\n\n displayIndex++;\n }\n\n for (const citation of citations) {\n processedContent = processedContent.replaceAll(citation.placeholder, `<sup>${citation.displayIndex}</sup>`);\n }\n\n processedContent = processedContent.replaceAll('</sup><sup>', '</sup><sup>,</sup><sup>');\n\n return {\n content: processedContent,\n citations: citations.map(({ placeholder, ...citation }) => citation),\n };\n }\n\n function buildCopyContent(content, citations) {\n let copyContent = (content || '').trim();\n\n if (!copyContent || !Array.isArray(citations) || citations.length === 0) {\n return copyContent;\n }\n\n for (const citation of citations) {\n copyContent = copyContent.replaceAll(citation.referenceKey, `[${citation.displayIndex}]`);\n }\n\n copyContent += '\\n\\nReferences:\\n';\n\n for (const citation of citations) {\n copyContent += `${citation.displayIndex}. ${citation.label}`;\n\n if (citation.link) {\n copyContent += ` - ${citation.link}`;\n }\n\n copyContent += '\\n';\n }\n\n return copyContent.trimEnd();\n }\n\n function updateMessagePresentation(message, references) {\n const messageReferences = normalizeReferences(references ?? message.references);\n const rawContent = typeof message.rawContent === 'string'\n ? message.rawContent\n : typeof message.content === 'string'\n ? message.content\n : '';\n const citationDisplay = buildCitationDisplay(rawContent, messageReferences);\n\n message.rawContent = rawContent;\n message.content = rawContent;\n message.displayContent = citationDisplay.content;\n message.references = messageReferences;\n message.citationReferences = citationDisplay.citations;\n message.copyContent = buildCopyContent(rawContent, citationDisplay.citations);\n message.htmlContent = parseMarkdownContent(citationDisplay.content, message);\n\n return message;\n }\n\n const renderer = new marked.Renderer();\n\n // Modify the link rendering to open in a new tab\n renderer.link = function (data) {\n var href = sanitizeUrl(data.href);\n if (!href) return data.text || '';\n return `<a href=\"${href}\" target=\"_blank\" rel=\"noopener noreferrer\">${data.text}</a>`;\n };\n\n // Custom code block renderer with highlight.js integration and copy button.\n renderer.code = function (data) {\n var code = data.text || '';\n var lang = (data.lang || '').trim();\n var highlighted = code;\n\n if (typeof hljs !== 'undefined') {\n if (lang && hljs.getLanguage(lang)) {\n try {\n highlighted = hljs.highlight(code, { language: lang }).value;\n } catch (_) { }\n } else {\n try {\n highlighted = hljs.highlightAuto(code).value;\n } catch (_) { }\n }\n } else {\n highlighted = escapeHtmlEntities(code);\n }\n\n var langDisplay = lang ? escapeHtmlEntities(lang) : 'code';\n return `<div class=\"ai-code-block\"><div class=\"ai-code-header\"><span class=\"ai-code-lang\"><span class=\"fa-solid fa-code\"></span> ${langDisplay}</span><button type=\"button\" class=\"ai-code-copy-btn\" title=\"Copy code\"><span class=\"fa-regular fa-copy\"></span></button></div><pre><code class=\"hljs${lang ? ' language-' + lang : ''}\">${highlighted}</code></pre></div>`;\n };\n\n // Custom image renderer for generated images with thumbnail styling and download button.\n // Handles both URL and data-URI sources (data URIs are converted to blobs for download).\n renderer.image = function (data) {\n const src = sanitizeUrl(data.href);\n if (!src) return '';\n const alt = data.text || defaultConfig.generatedImageAltText;\n const maxWidth = defaultConfig.generatedImageMaxWidth;\n return `<div class=\"generated-image-container\">\n <img src=\"${src}\" alt=\"${alt}\" class=\"img-thumbnail\" style=\"max-width: ${maxWidth}px; height: auto;\" />\n <div class=\"mt-2\">\n <a href=\"${src}\" target=\"_blank\" download=\"${alt}\" title=\"${defaultConfig.downloadImageTitle}\" class=\"btn btn-sm btn-outline-secondary ai-download-image\">\n <span class=\"fa-solid fa-download\"></span>\n </a>\n </div>\n </div>`;\n };\n\n // Chart counter for unique IDs\n let chartCounter = 0;\n\n // Collector for charts discovered during marked parsing.\n let _pendingCharts = [];\n\n // Global chart config map: any page (e.g., Chat Interactions) that uses\n // the shared marked instance can call window.renderPendingCharts() after\n // its DOM update to render charts it didn't create itself.\n window.__chartConfigs = window.__chartConfigs || {};\n\n function createChartHtml(chartId) {\n return `<div class=\"chart-container\" style=\"position: relative; width: 100%; max-width: 560px; min-height: 420px;\">`\n + `<canvas id=\"${chartId}\"></canvas>`\n + `</div>`\n + `<div class=\"mt-2\">`\n + `<button type=\"button\" class=\"btn btn-sm btn-outline-secondary download-chart-btn\" data-chart-id=\"${chartId}\" title=\"${defaultConfig.downloadChartTitle}\">`\n + `<span class=\"fa-solid fa-download\"></span> ${defaultConfig.downloadChartButtonText}`\n + `</button>`\n + `</div>`;\n }\n\n // Register [chart:{...json...}] as a native marked block extension so the\n // markdown parser handles chart markers inline with surrounding text.\n marked.use({\n extensions: [{\n name: 'chart',\n level: 'block',\n start(src) {\n const idx = src.indexOf('[chart:');\n return idx >= 0 ? idx : undefined;\n },\n tokenizer(src) {\n const extracted = tryExtractChartMarker(src);\n if (!extracted || extracted.startIndex !== 0) {\n return undefined;\n }\n\n const chartId = `chat_chart_${++chartCounter}`;\n\n return {\n type: 'chart',\n raw: src.substring(0, extracted.endIndex),\n chartId: chartId,\n json: extracted.json,\n };\n },\n renderer(token) {\n _pendingCharts.push({ chartId: token.chartId, config: token.json });\n window.__chartConfigs[token.chartId] = token.json;\n return createChartHtml(token.chartId);\n }\n }]\n });\n\n // Extract a [chart:{...json...}] marker. This avoids regex issues with nested brackets.\n function tryExtractChartMarker(text) {\n const token = '[chart:';\n const start = text.indexOf(token);\n if (start < 0) {\n return null;\n }\n\n // Find JSON object boundary by balancing braces\n const jsonStart = start + token.length;\n let i = jsonStart;\n while (i < text.length && (text[i] === ' ' || text[i] === '\\n' || text[i] === '\\r' || text[i] === '\\t')) {\n i++;\n }\n\n if (i >= text.length || text[i] !== '{') {\n return null;\n }\n\n let depth = 0;\n let inString = false;\n let escape = false;\n\n for (; i < text.length; i++) {\n const ch = text[i];\n\n if (inString) {\n if (escape) {\n escape = false;\n continue;\n }\n if (ch === '\\\\') {\n escape = true;\n continue;\n }\n if (ch === '\"') {\n inString = false;\n }\n continue;\n }\n\n if (ch === '\"') {\n inString = true;\n continue;\n }\n\n if (ch === '{') {\n depth++;\n } else if (ch === '}') {\n depth--;\n if (depth === 0) {\n const jsonEnd = i;\n // Expect closing bracket after JSON\n const closeBracketIndex = text.indexOf(']', jsonEnd + 1);\n if (closeBracketIndex < 0) {\n return null;\n }\n\n const json = text.substring(jsonStart, jsonEnd + 1).trim();\n return {\n startIndex: start,\n endIndex: closeBracketIndex + 1,\n json: json\n };\n }\n }\n }\n\n return null;\n }\n\n function renderChartsInMessage(message) {\n if (!message || !message._pendingCharts || !message._pendingCharts.length) {\n return;\n }\n\n // Copy and clear pending charts immediately to prevent duplicate renders.\n const charts = [...message._pendingCharts];\n message._pendingCharts = [];\n\n // Defer to requestAnimationFrame so the browser has fully laid out the\n // canvas elements before Chart.js reads their dimensions.\n requestAnimationFrame(() => {\n for (const c of charts) {\n renderChartOnCanvas(c.chartId, c.config);\n }\n });\n }\n\n function renderChartOnCanvas(chartId, config) {\n const canvas = document.getElementById(chartId);\n if (!canvas) {\n return false;\n }\n\n if (typeof Chart === 'undefined') {\n console.warn('Chart.js is not loaded. To render interactive charts, include the Chart.js library on the page (e.g., <script src=\"https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js\"></script>).');\n return false;\n }\n\n // When the canvas is inside a hidden container (e.g., a widget panel with\n // display:none), it has zero dimensions and Chart.js cannot render correctly.\n // Keep the config in __chartConfigs so renderPendingCharts() can retry later\n // once the container becomes visible.\n if (canvas.offsetParent === null) {\n window.__chartConfigs[chartId] = config;\n return false;\n }\n\n try {\n if (canvas._chartInstance) {\n canvas._chartInstance.destroy();\n }\n\n const cfg = typeof config === 'string' ? JSON.parse(config) : config;\n cfg.options ??= {};\n cfg.options.responsive = true;\n cfg.options.maintainAspectRatio = true;\n cfg.options.aspectRatio ??= 4 / 3;\n\n canvas._chartInstance = new Chart(canvas, cfg);\n delete window.__chartConfigs[chartId];\n return true;\n } catch (e) {\n console.error('Error creating chart:', e);\n return false;\n }\n }\n\n // Global function: renders any chart canvases whose configs are in the\n // global __chartConfigs map. Called by pages (e.g., Chat Interactions)\n // that share the marked instance but have their own rendering pipeline.\n window.renderPendingCharts = function () {\n if (typeof Chart === 'undefined') {\n return;\n }\n\n const configs = window.__chartConfigs;\n if (!configs) {\n return;\n }\n\n requestAnimationFrame(() => {\n for (const chartId of Object.keys(configs)) {\n renderChartOnCanvas(chartId, configs[chartId]);\n }\n });\n };\n\n // Parse markdown content via marked (which natively handles [chart:...] markers\n // through the registered extension) and collect pending chart configs for later\n // Chart.js rendering.\n function parseMarkdownContent(content, message) {\n _pendingCharts = [];\n const html = marked.parse(content, { renderer });\n message._pendingCharts = _pendingCharts.length > 0 ? [..._pendingCharts] : [];\n return DOMPurify.sanitize(html, { ADD_TAGS: ['canvas'], ADD_ATTR: ['target'] });\n }\n\n const initialize = (instanceConfig) => {\n\n const config = Object.assign({}, defaultConfig, instanceConfig);\n config.widget = Object.assign({}, defaultConfig.widget || {}, instanceConfig && instanceConfig.widget ? instanceConfig.widget : {});\n const hasWidgetConfig = !!(instanceConfig && instanceConfig.widget && instanceConfig.widget.chatWidgetContainer && instanceConfig.widget.chatWidgetStateName);\n const widgetBehavior = window.openAIChatWidgetBehavior || null;\n // Keep defaultConfig in sync so renderers use overridden values\n defaultConfig = config;\n\n if (!config.signalRHubUrl) {\n console.error('The signalRHubUrl is required.');\n return;\n }\n\n if (!config.appElementSelector) {\n console.error('The appElementSelector is required.');\n return;\n }\n\n if (!config.chatContainerElementSelector) {\n console.error('The chatContainerElementSelector is required.');\n return;\n }\n\n if (!config.inputElementSelector) {\n console.error('The inputElementSelector is required.');\n return;\n }\n\n if (!config.sendButtonElementSelector) {\n console.error('The sendButtonElementSelector is required.');\n return;\n }\n\n const appDefinition = {\n data() {\n return {\n inputElement: null,\n buttonElement: null,\n chatContainer: null,\n placeholder: null,\n isSessionStarted: false,\n isPlaceholderVisible: true,\n isStreaming: false,\n isNavigatingAway: false,\n autoScroll: true,\n stream: null,\n messages: [],\n notifications: [],\n prompt: '',\n documents: config.existingDocuments || [],\n isUploading: false,\n isDocumentOperationPending: false,\n documentOperationQueue: null,\n uploadErrors: [],\n isDragOver: false,\n documentBar: null,\n metricsEnabled: !!config.metricsEnabled,\n userLabel: config.userLabel,\n assistantLabel: config.assistantLabel,\n thumbsUpTitle: config.thumbsUpTitle,\n thumbsDownTitle: config.thumbsDownTitle,\n copyTitle: config.copyTitle,\n isRecording: false,\n mediaRecorder: null,\n preRecordingPrompt: '',\n micButton: null,\n speechToTextEnabled: config.chatMode === 'AudioInput' || config.chatMode === 'Conversation',\n textToSpeechEnabled: config.chatMode === 'Conversation' || !!config.textToSpeechEnabled,\n ttsVoiceName: config.ttsVoiceName || null,\n audioChunks: [],\n audioPlayQueue: [],\n isPlayingAudio: false,\n currentAudioElement: null,\n currentAudioUrl: null,\n ttsButton: null,\n ttsPlayingMessageIndex: -1,\n ttsAudioCache: {},\n ttsInstanceId: 'ai-chat-' + Math.random().toString(36).slice(2),\n singleResponseMode: !!config.singleResponseMode,\n conversationModeEnabled: config.chatMode === 'Conversation',\n conversationButton: null,\n isConversationMode: false,\n notificationDismissTimers: {},\n pendingSessionPromise: null,\n pendingSessionResolver: null,\n pendingSessionRejector: null,\n pendingSessionTimeoutId: null,\n };\n },\n computed: {\n lastAssistantIndex() {\n for (var i = this.messages.length - 1; i >= 0; i--) {\n if (this.messages[i].role === 'assistant') {\n return i;\n }\n }\n return -1;\n }\n },\n methods: {\n handleBeforeUnload() {\n this.isNavigatingAway = true;\n },\n handleDragOver(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = true;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.add('ai-chat-drag-over');\n },\n handleDragLeave(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = false;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.remove('ai-chat-drag-over');\n },\n handleDrop(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = false;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.remove('ai-chat-drag-over');\n if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n this.uploadFiles(Array.from(e.dataTransfer.files));\n }\n },\n triggerFileInput() {\n if (!config.sessionDocumentsEnabled || this.isDocumentOperationPending) return;\n var fileInput = document.getElementById('ai-chat-doc-input');\n if (fileInput) fileInput.click();\n },\n handleFileInputChange(e) {\n var files = e.target.files ? Array.from(e.target.files) : [];\n if (files && files.length > 0) {\n this.uploadFiles(files);\n }\n e.target.value = '';\n },\n queueDocumentOperation(operation) {\n var self = this;\n var previousOperation = this.documentOperationQueue || Promise.resolve();\n var nextOperation = previousOperation\n .catch(function () { })\n .then(async function () {\n self.isDocumentOperationPending = true;\n try {\n return await operation();\n } finally {\n self.isDocumentOperationPending = false;\n }\n });\n\n this.documentOperationQueue = nextOperation.finally(function () {\n if (self.documentOperationQueue === nextOperation) {\n self.documentOperationQueue = null;\n }\n });\n\n return this.documentOperationQueue;\n },\n async uploadFiles(files) {\n if (!config.uploadDocumentUrl) return;\n\n var filesToUpload = Array.isArray(files) ? files.slice() : Array.from(files || []);\n if (filesToUpload.length === 0) return;\n\n return this.queueDocumentOperation(async () => {\n var sessionId = this.getSessionId();\n var profileId = this.getProfileId();\n\n if (!sessionId) {\n try {\n sessionId = await this.ensureSessionForDocuments(profileId);\n } catch (err) {\n console.error('Failed to create a chat session for document upload:', err);\n this.uploadErrors = [{ fileName: '', error: 'Could not create a chat session for the upload.' }];\n this.renderDocumentBar();\n return;\n }\n }\n\n if (!sessionId) {\n console.warn('Cannot upload documents without a session or profile.');\n this.uploadErrors = [{ fileName: '', error: 'Could not create a chat session for the upload.' }];\n this.renderDocumentBar();\n return;\n }\n\n this.isUploading = true;\n this.uploadErrors = [];\n this.renderDocumentBar();\n try {\n var formData = new FormData();\n formData.append('sessionId', sessionId);\n for (var i = 0; i < filesToUpload.length; i++) {\n formData.append('files', filesToUpload[i]);\n }\n\n var response = await fetch(config.uploadDocumentUrl, {\n method: 'POST',\n body: formData\n });\n\n if (!response.ok) {\n var errorText = await response.text();\n var uploadError = this.extractReadableErrorMessage(errorText, 'Upload failed. Please try again.');\n console.error('Upload failed:', errorText);\n this.uploadErrors = [{ fileName: '', error: uploadError }];\n return;\n }\n\n var result = await response.json();\n\n if (result.sessionId && result.sessionId !== this.getSessionId()) {\n this.initializeSession(result.sessionId);\n }\n\n if (Array.isArray(result.documents)) {\n this.documents = result.documents;\n } else if (result.uploaded && result.uploaded.length > 0) {\n this.documents = this.documents.concat(result.uploaded);\n }\n\n if (result.failed && result.failed.length > 0) {\n this.uploadErrors = result.failed;\n }\n } catch (err) {\n console.error('Upload error:', err);\n this.uploadErrors = [{ fileName: '', error: 'Upload failed. Please try again.' }];\n\n if (this.getSessionId()) {\n this.reloadCurrentSession();\n }\n } finally {\n this.isUploading = false;\n this.renderDocumentBar();\n }\n });\n },\n async removeDocument(doc) {\n if (!config.removeDocumentUrl) return;\n\n return this.queueDocumentOperation(async () => {\n try {\n var sessionId = this.getSessionId();\n var response = await fetch(config.removeDocumentUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ itemId: sessionId, documentId: doc.documentId })\n });\n\n if (response.ok) {\n var result = await response.json();\n\n if (Array.isArray(result.documents)) {\n this.documents = result.documents;\n } else {\n var idx = this.documents.indexOf(doc);\n if (idx > -1) {\n this.documents.splice(idx, 1);\n }\n }\n } else {\n var errorText = await response.text();\n var removeError = this.extractReadableErrorMessage(errorText, 'Failed to remove document. Please try again.');\n console.error('Failed to remove document:', response.status, errorText);\n this.uploadErrors = [{ fileName: doc.fileName || '', error: removeError }];\n if (sessionId) {\n this.reloadCurrentSession();\n }\n this.renderDocumentBar();\n }\n } catch (err) {\n console.error('Remove document error:', err);\n this.uploadErrors = [{ fileName: doc.fileName || '', error: 'Failed to remove document. Please try again.' }];\n if (this.getSessionId()) {\n this.reloadCurrentSession();\n }\n this.renderDocumentBar();\n }\n });\n },\n formatFileSize(bytes) {\n if (bytes < 1024) return bytes + ' B';\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n },\n renderDocumentBar() {\n if (!this.documentBar) return;\n\n if (!config.sessionDocumentsEnabled) {\n this.documentBar.classList.add('d-none');\n return;\n }\n\n this.documentBar.classList.remove('d-none');\n\n var html = '<div class=\"ai-chat-doc-bar p-2\">';\n html += '<div class=\"d-flex flex-wrap align-items-center gap-1\">';\n\n for (var i = 0; i < this.documents.length; i++) {\n var doc = this.documents[i];\n var name = doc.fileName || 'Document';\n if (name.length > 20) name = name.substring(0, 17) + '...';\n html += '<span class=\"badge bg-secondary bg-opacity-25 text-dark d-inline-flex align-items-center gap-1 px-2 py-1\" style=\"font-size: 0.8rem;\" title=\"' + this.escapeHtml(doc.fileName || '') + '\">';\n html += '<span class=\"fa-solid fa-file-lines\" style=\"font-size: 0.7rem;\"></span> ';\n html += this.escapeHtml(name);\n html += ' <button type=\"button\" class=\"btn-close btn-close-sm ms-1\" style=\"font-size: 0.5rem;\" data-doc-index=\"' + i + '\" aria-label=\"Remove\"' + (this.isDocumentOperationPending ? ' disabled' : '') + '></button>';\n html += '</span>';\n }\n\n for (var m = 0; m < this.uploadErrors.length; m++) {\n var failedItem = this.uploadErrors[m];\n var failedName = failedItem.fileName || 'File';\n var errorMsg = failedItem.error || 'Upload failed';\n if (failedName.length > 15) failedName = failedName.substring(0, 12) + '...';\n html += '<span class=\"badge bg-danger bg-opacity-25 text-danger d-inline-flex align-items-center gap-1 px-2 py-1\" style=\"font-size: 0.8rem;\" title=\"' + this.escapeHtml((failedItem.fileName || '') + ': ' + errorMsg) + '\">';\n html += '<span class=\"fa-solid fa-circle-exclamation\" style=\"font-size: 0.7rem;\"></span> ';\n html += this.escapeHtml(failedName);\n html += ' <button type=\"button\" class=\"btn-close btn-close-sm ms-1\" style=\"font-size: 0.5rem;\" data-error-index=\"' + m + '\" aria-label=\"Dismiss\"></button>';\n html += '</span>';\n }\n\n if (this.isUploading) {\n html += '<span class=\"badge bg-info bg-opacity-25 text-dark d-inline-flex align-items-center gap-1 px-2 py-1\" style=\"font-size: 0.8rem;\">';\n html += '<span class=\"spinner-border spinner-border-sm\" style=\"width: 0.7rem; height: 0.7rem;\"></span> Uploading...';\n html += '</span>';\n }\n\n html += '<button type=\"button\" class=\"btn btn-sm btn-outline-secondary rounded-pill ai-chat-doc-add-btn d-inline-flex align-items-center gap-1\" style=\"font-size: 0.75rem; padding: 0.15rem 0.5rem;\" title=\"Attach documents\"' + (this.isDocumentOperationPending ? ' disabled' : '') + '>';\n html += '<span class=\"fa-solid fa-paperclip\"></span>';\n if (this.documents.length === 0 && !this.isUploading) {\n html += ' <span>Attach files</span>';\n }\n html += '</button>';\n html += '</div>';\n if (config.supportedExtensionsText) {\n html += '<div class=\"small text-muted mt-2\">Supported formats: ' + this.escapeHtml(config.supportedExtensionsText) + '</div>';\n }\n\n html += '</div>';\n\n this.documentBar.replaceChildren(DOMPurify.sanitize(html, { RETURN_DOM_FRAGMENT: true }));\n\n // Bind remove handlers\n var self = this;\n var closeButtons = this.documentBar.querySelectorAll('[data-doc-index]');\n for (var j = 0; j < closeButtons.length; j++) {\n closeButtons[j].addEventListener('click', (function (idx) {\n return function (e) {\n e.preventDefault();\n e.stopPropagation();\n if (self.isDocumentOperationPending) {\n return;\n }\n\n var docToRemove = self.documents[idx];\n if (docToRemove) self.removeDocument(docToRemove);\n };\n })(parseInt(closeButtons[j].getAttribute('data-doc-index'))));\n }\n\n // Bind error dismiss handlers\n var errorCloseButtons = this.documentBar.querySelectorAll('[data-error-index]');\n for (var n = 0; n < errorCloseButtons.length; n++) {\n errorCloseButtons[n].addEventListener('click', (function (idx) {\n return function (e) {\n e.preventDefault();\n e.stopPropagation();\n self.uploadErrors.splice(idx, 1);\n self.renderDocumentBar();\n };\n })(parseInt(errorCloseButtons[n].getAttribute('data-error-index'))));\n }\n\n // Bind add button\n var addBtn = this.documentBar.querySelector('.ai-chat-doc-add-btn');\n if (addBtn) {\n addBtn.addEventListener('click', function (e) {\n e.preventDefault();\n if (self.isDocumentOperationPending) {\n return;\n }\n self.triggerFileInput();\n });\n }\n },\n escapeHtml(text) {\n var div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n },\n extractReadableErrorMessage(errorText, fallbackMessage) {\n if (!errorText || typeof errorText !== 'string') {\n return fallbackMessage;\n }\n\n var trimmed = errorText.trim();\n if (!trimmed) {\n return fallbackMessage;\n }\n\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n var parsed = JSON.parse(trimmed);\n var message = parsed?.error || parsed?.message || parsed?.title || parsed?.detail;\n return typeof message === 'string' && message.trim()\n ? message.trim()\n : fallbackMessage;\n } catch (err) {\n return fallbackMessage;\n }\n }\n\n if (/<[^>]+>/.test(trimmed)) {\n return fallbackMessage;\n }\n\n return trimmed;\n },\n normalizeAssistantAppearance(appearance) {\n if (!appearance) {\n return null;\n }\n\n var label = typeof appearance.label === 'string' ? appearance.label.trim() : '';\n var icon = typeof appearance.icon === 'string' ? appearance.icon.trim() : '';\n var cssClass = typeof appearance.cssClass === 'string' ? appearance.cssClass.trim() : '';\n var disableStreamingAnimation = !!appearance.disableStreamingAnimation;\n\n if (!label && !icon && !cssClass && !disableStreamingAnimation) {\n return null;\n }\n\n return {\n label: label,\n icon: icon,\n cssClass: cssClass,\n disableStreamingAnimation: disableStreamingAnimation,\n };\n },\n getAssistantLabel(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.label ? appearance.label : this.assistantLabel;\n },\n getAssistantRoleClasses(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n var classes = ['ai-chat-msg-role'];\n\n if (appearance && appearance.cssClass) {\n classes.push(appearance.cssClass);\n } else {\n classes.push('ai-chat-msg-role-assistant');\n }\n\n return classes;\n },\n getAssistantIconClasses(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return [this.shouldAnimateAssistantIcon(message, index) ? 'ai-streaming-icon' : 'ai-bot-icon', appearance && appearance.cssClass ? appearance.cssClass : ''];\n },\n getAssistantIcon(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.icon ? appearance.icon : 'fa fa-robot';\n },\n shouldAnimateAssistantIcon(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return !!message &&\n message.isStreaming &&\n index === this.lastAssistantIndex &&\n !(appearance && appearance.disableStreamingAnimation);\n },\n async startConnection() {\n this.connection = new signalR.HubConnectionBuilder()\n .withUrl(config.signalRHubUrl)\n .withAutomaticReconnect()\n .build();\n\n // Allow long-running operations (e.g., multi-step MCP tool calls)\n // without the client disconnecting prematurely.\n this.connection.serverTimeoutInMilliseconds = 600000;\n this.connection.keepAliveIntervalInMilliseconds = 15000;\n\n this.connection.on(\"LoadSession\", (data) => {\n this.initializeSession(data.sessionId, true);\n this.messages = [];\n this.documents = data.documents || [];\n this.uploadErrors = [];\n\n (data.messages ?? []).forEach(msg => {\n this.addMessage(msg);\n\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n });\n });\n\n // Update feedback icons in the DOM after all messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // When the session is new (no messages) and an initial prompt is configured,\n // automatically send it as the first user message to trigger an AI response.\n if (this.messages.length === 0 && config.initialPrompt) {\n this.prompt = config.initialPrompt;\n this.sendMessage();\n }\n });\n\n this.connection.on(\"ReceiveError\", (error) => {\n console.error(\"SignalR Error: \", error);\n\n if (this.isRecording) {\n this.stopRecording();\n }\n\n if (widgetBehavior && typeof widgetBehavior.handleReceiveError === 'function') {\n widgetBehavior.handleReceiveError(this, error, config);\n }\n });\n\n this.connection.on(\"MessageRated\", (messageId, userRating) => {\n var msg = this.messages.find(m => m.id === messageId);\n if (msg) {\n msg.userRating = userRating;\n }\n });\n\n this.connection.on(\"ReceiveTranscript\", (sessionId, text, isFinal) => {\n if (this.isConversationMode) {\n if (!isFinal && text) {\n this._conversationPartialTranscript = text;\n var escaped = text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n var html = '<p class=\"ai-partial-transcript\">' + escaped + '</p>';\n\n // Show partial transcript as a live user message.\n if (!this._conversationPartialMessage) {\n this.hidePlaceholder();\n this._conversationPartialMessage = {\n role: 'user',\n content: text,\n htmlContent: html,\n isPartial: true\n };\n this.messages.push(this._conversationPartialMessage);\n } else {\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = html;\n }\n this.scrollToBottom();\n }\n return;\n }\n\n if (text && !this._audioInputSent) {\n this.prompt = this.preRecordingPrompt + text;\n if (this.inputElement) {\n this.inputElement.value = this.prompt;\n this.inputElement.dispatchEvent(new Event('input'));\n }\n }\n });\n\n this.connection.on(\"ReceiveConversationUserMessage\", (sessionId, text) => {\n if (text) {\n this.stopAudio();\n\n // If there's an interrupted assistant message still streaming,\n // mark it as done to stop the spinner animation.\n if (this._conversationAssistantMessage) {\n var oldMsg = this.messages[this._conversationAssistantMessage.index];\n if (oldMsg) {\n oldMsg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '<p>' + escaped + '</p>';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (sessionId, messageId, token, responseId, references, appearance) => {\n if (!this._conversationAssistantMessage) {\n this.stopAudio();\n this.hideTypingIndicator();\n\n // Ensure no stale streaming indicators remain from prior messages.\n for (var j = 0; j < this.messages.length; j++) {\n if (this.messages[j].isStreaming) {\n this.messages[j].isStreaming = false;\n }\n }\n\n var msgIndex = this.messages.length;\n var newMessage = {\n id: messageId,\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n appearance: this.normalizeAssistantAppearance(appearance),\n references: {},\n };\n this.messages.push(newMessage);\n this._conversationAssistantMessage = { index: msgIndex, content: '' };\n }\n\n this._conversationAssistantMessage.content += token;\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n if (!msg.appearance) {\n msg.appearance = this.normalizeAssistantAppearance(appearance);\n }\n msg.rawContent = this._conversationAssistantMessage.content;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n this.scrollToBottom();\n });\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantComplete\", (sessionId, messageId, references) => {\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n }\n this._conversationAssistantMessage = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (sessionId, base64Audio, contentType) => {\n if (base64Audio) {\n const binaryString = atob(base64Audio);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n this.audioChunks.push(bytes);\n }\n });\n\n this.connection.on(\"ReceiveAudioComplete\", (sessionId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"ReceiveNotification\", (notification) => {\n this.receiveNotification(notification);\n });\n\n this.connection.on(\"UpdateNotification\", (notification) => {\n this.updateNotification(notification);\n });\n\n this.connection.on(\"RemoveNotification\", (notificationType) => {\n this.removeNotification(notificationType);\n });\n\n this.connection.onreconnecting(() => {\n console.warn(\"SignalR: reconnecting...\");\n });\n\n this.connection.onreconnected(() => {\n console.info(\"SignalR: reconnected.\");\n\n if (this.isSessionStarted) {\n this.reloadCurrentSession();\n } else if (config.autoCreateSession) {\n this.startNewSession();\n }\n });\n\n this.connection.onclose((error) => {\n if (this.isNavigatingAway) {\n return;\n }\n\n if (error) {\n console.warn(\"SignalR connection closed with error:\", error.message || error);\n }\n });\n\n try {\n await this.connection.start();\n } catch (err) {\n console.error(\"SignalR Connection Error: \", err);\n }\n },\n addMessageInternal(message) {\n if (message.role === 'assistant') {\n message.appearance = this.normalizeAssistantAppearance(message.appearance);\n }\n\n if (message.content && !message.htmlContent) {\n message.htmlContent = parseMarkdownContent(message.content, message);\n }\n this.fireEvent(new CustomEvent(\"addingOpenAIPromotMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedOpenAIPromotMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\n\n // Ensure userRating is always defined for Vue reactivity.\n if (message.userRating === undefined) {\n message.userRating = null;\n }\n\n if (message.content) {\n message.rawContent = message.rawContent ?? message.content;\n updateMessagePresentation(message, message.references);\n }\n\n this.addMessageInternal(message);\n this.hidePlaceholder();\n\n this.$nextTick(() => {\n // Render any pending charts once the DOM is updated\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n addMessages(messages) {\n\n for (let i = 0; i < messages.length; i++) {\n this.addMessageInternal(messages[i]);\n }\n\n this.hidePlaceholder();\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n hidePlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.add('d-none');\n }\n this.isPlaceholderVisible = false;\n },\n showPlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.remove('d-none');\n }\n this.isPlaceholderVisible = true;\n },\n isOrchestratorAvailable() {\n return config.isOrchestratorAvailable !== false;\n },\n applyOrchestratorAvailability() {\n if (this.isOrchestratorAvailable()) {\n return true;\n }\n\n const unavailableMessage = config.orchestratorUnavailableMessage || \"This orchestrator is not currently available.\";\n\n if (this.inputElement) {\n this.inputElement.disabled = true;\n this.inputElement.value = '';\n this.inputElement.placeholder = unavailableMessage;\n }\n\n if (this.buttonElement) {\n this.buttonElement.disabled = true;\n }\n\n if (this.micButtonElement) {\n this.micButtonElement.disabled = true;\n this.micButtonElement.style.display = 'none';\n }\n\n if (this.conversationButtonElement) {\n this.conversationButtonElement.disabled = true;\n this.conversationButtonElement.style.display = 'none';\n }\n\n return false;\n },\n fireEvent(event) {\n document.dispatchEvent(event);\n },\n isIndicator(message) {\n return message.role === 'indicator';\n },\n sendMessage() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n let trimmedPrompt = this.prompt.trim();\n\n if (!trimmedPrompt) {\n return;\n }\n\n // Stop any active recording before sending.\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // Prevent stale ReceiveTranscript events from repopulating the prompt.\n this._audioInputSent = true;\n\n // In single-response mode, clear all previous messages.\n if (this.singleResponseMode) {\n this.messages.splice(0, this.messages.length);\n }\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n this.streamMessage(this.getProfileId(), trimmedPrompt, null);\n this.inputElement.value = '';\n this.prompt = '';\n },\n startRecording() {\n if (this.isRecording || !this.connection) {\n return;\n }\n\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this.preRecordingPrompt = this.prompt;\n this._audioInputSent = false;\n\n var subject = new signalR.Subject();\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var pendingChunk = Promise.resolve();\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n subject.next(base64);\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => subject.complete());\n });\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"SendAudioStream\", profileId, sessionId, subject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n this.updateMicButton();\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n });\n },\n stopRecording() {\n if (!this.isRecording || !this.mediaRecorder) {\n return;\n }\n\n this.mediaRecorder.stop();\n this.isRecording = false;\n this.updateMicButton();\n },\n toggleRecording() {\n if (this.isRecording) {\n this.stopRecording();\n } else {\n this.startRecording();\n }\n },\n updateMicButton() {\n if (!this.micButton) {\n return;\n }\n\n if (this.isRecording) {\n this.micButton.classList.add('stt-recording');\n this.micButton.innerHTML = '<span class=\"fa-solid fa-stop\"></span>';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '<span class=\"fa-solid fa-microphone\"></span>';\n }\n },\n streamMessage(profileId, trimmedPrompt, sessionProfileId) {\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n\n this.streamingStarted();\n this.showTypingIndicator();\n this.autoScroll = true;\n\n var content = '';\n var references = {};\n var lastResponseId = null;\n\n // Get the index after showing typing indicator.\n var messageIndex = this.messages.length;\n var currentSessionId = this.getSessionId();\n\n this.stream = this.connection.stream(\"SendMessage\", profileId, trimmedPrompt, currentSessionId, sessionProfileId)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n\n if (chunk.sessionId && !currentSessionId) {\n this.initializeSession(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n // Re-assign the index after hiding the typing indicator.\n messageIndex = this.messages.length;\n let newMessage = {\n id: chunk.messageId,\n role: \"assistant\",\n title: chunk.title,\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n };\n\n this.messages.push(newMessage);\n\n message = newMessage;\n }\n\n if (chunk.title && (!message.title || message.title !== chunk.title)) {\n message.title = chunk.title;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\n\n // When the responseId changes (e.g., after an internal tool call),\n // insert a line break to visually separate response segments.\n if (chunk.responseId && lastResponseId && chunk.responseId !== lastResponseId) {\n content += '\\n\\n';\n }\n\n if (chunk.responseId) {\n lastResponseId = chunk.responseId;\n }\n\n content += chunk.content;\n }\n\n // Update the existing message\n message.rawContent = content;\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n complete: () => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n if (!msg || !msg.content) {\n // No content received at all.\n this.hideTypingIndicator();\n }\n\n // Trigger text-to-speech only in conversation mode.\n if (this.isConversationMode && this.textToSpeechEnabled && msg && msg.content) {\n this.synthesizeSpeech(msg.content);\n }\n\n this.stream?.dispose();\n this.stream = null;\n },\n error: (err) => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n this.hideTypingIndicator();\n\n if (!this.isNavigatingAway) {\n this.addMessage(this.getServiceDownMessage());\n }\n\n this.stream?.dispose();\n this.stream = null;\n\n console.error(\"Stream error:\", err);\n }\n });\n },\n getServiceDownMessage() {\n let newMessage = {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n\n return newMessage;\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\n\n let message = this.messages[messageIndex];\n message.rawContent = message.rawContent ?? message.content ?? '';\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n }\n },\n streamingStarted() {\n var stopIcon = this.buttonElement.getAttribute('data-stop-icon');\n\n if (stopIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(stopIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.setAttribute('disabled', 'disabled');\n }\n },\n streamingFinished() {\n var startIcon = this.buttonElement.getAttribute('data-start-icon');\n\n if (startIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(startIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.removeAttribute('disabled');\n this.inputElement.focus();\n }\n\n // Directly manipulate the DOM to stop all streaming animations.\n if (this.chatContainer) {\n var icons = this.chatContainer.querySelectorAll('.ai-streaming-icon');\n for (var i = 0; i < icons.length; i++) {\n icons[i].classList.remove('ai-streaming-icon');\n icons[i].classList.add('ai-bot-icon');\n }\n }\n\n // Also update Vue data for consistency.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n },\n handleExternalTtsStop(e) {\n if (e?.detail?.sourceId === this.ttsInstanceId) {\n return;\n }\n\n this.stopAudio(false);\n },\n updateTtsPlaybackButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-tts-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-tts-message-index'));\n var isPlaying = buttonIndex === this.ttsPlayingMessageIndex;\n var iconHtml = isPlaying\n ? '<span class=\"fa-solid fa-circle-pause\"></span>'\n : '<span class=\"fa-solid fa-circle-play\"></span>';\n\n button.classList.toggle('tts-playing', isPlaying);\n button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\n });\n },\n synthesizeSpeech(text, cacheIndex) {\n if (!this.textToSpeechEnabled || !text || !this.connection) {\n return;\n }\n\n this.audioChunks = [];\n this.isPlayingAudio = true;\n this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;\n\n this.connection.invoke(\"SynthesizeSpeech\", this.getProfileId(), this.getSessionId(), text, this.ttsVoiceName)\n .catch(err => {\n console.error(\"TTS synthesis error:\", err);\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this._ttsCacheIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n });\n },\n toggleMessageTts(message, index) {\n if (this.ttsPlayingMessageIndex === index) {\n this.stopAudio();\n return;\n }\n\n this.stopAudio(false);\n window.dispatchEvent(new CustomEvent('crestapps-ai-chat-stop-tts', {\n detail: { sourceId: this.ttsInstanceId }\n }));\n this.ttsPlayingMessageIndex = index;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n\n if (this.ttsAudioCache[index]) {\n this.playAudioBlob(this.ttsAudioCache[index]);\n return;\n }\n\n this.synthesizeSpeech(message.content, index);\n },\n playCollectedAudio() {\n if (this.audioChunks.length === 0) {\n if (!this.currentAudioElement && this.audioPlayQueue.length === 0) {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n }\n return;\n }\n\n const totalLength = this.audioChunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const combined = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of this.audioChunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n this.audioChunks = [];\n\n const blob = new Blob([combined], { type: 'audio/mp3' });\n\n if (this._ttsCacheIndex >= 0) {\n this.ttsAudioCache[this._ttsCacheIndex] = blob;\n this._ttsCacheIndex = -1;\n }\n\n // If audio is already playing, queue this blob for sequential playback.\n if (this.currentAudioElement) {\n this.audioPlayQueue.push(blob);\n return;\n }\n\n this.playAudioBlob(blob);\n },\n playAudioBlob(blob) {\n const url = URL.createObjectURL(blob);\n const audio = new Audio(url);\n\n this.currentAudioUrl = url;\n this.currentAudioElement = audio;\n this.isPlayingAudio = true;\n\n audio.addEventListener('ended', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.addEventListener('error', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.play().catch(err => {\n console.error(\"Audio playback error:\", err);\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n });\n },\n playNextInQueue() {\n if (this.audioPlayQueue.length > 0) {\n var nextBlob = this.audioPlayQueue.shift();\n this.playAudioBlob(nextBlob);\n } else {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n this.conversationModeOnAudioEnded();\n }\n },\n stopAudio() {\n if (this.currentAudioElement) {\n this.currentAudioElement.pause();\n this.currentAudioElement.currentTime = 0;\n this.currentAudioElement = null;\n }\n if (this.currentAudioUrl) {\n URL.revokeObjectURL(this.currentAudioUrl);\n this.currentAudioUrl = null;\n }\n this.audioChunks = [];\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n },\n toggleConversationMode() {\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n startConversationMode() {\n if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {\n return;\n }\n\n this.isConversationMode = true;\n this.updateConversationButton();\n this._conversationPartialTranscript = '';\n this._conversationAssistantMessage = null;\n this._conversationPartialMessage = null;\n\n // Remove any previous conversation ended notification.\n this.removeNotification('conversation-ended');\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this._conversationSubject = new signalR.Subject();\n this._conversationStream = stream;\n\n // Create an AnalyserNode for volume-based interrupt detection.\n // During TTS playback, detect when the user speaks above\n // the threshold to stop TTS (interrupt). Audio chunks are\n // always forwarded — browser echo cancellation handles\n // speaker echo so the STT stream has no gaps.\n var AudioCtx = window.AudioContext || window.webkitAudioContext;\n if (AudioCtx) {\n this._conversationAudioCtx = new AudioCtx();\n this._conversationAnalyser = this._conversationAudioCtx.createAnalyser();\n this._conversationAnalyser.fftSize = 256;\n var micSource = this._conversationAudioCtx.createMediaStreamSource(stream);\n micSource.connect(this._conversationAnalyser);\n }\n\n var pendingChunk = Promise.resolve();\n var analyser = this._conversationAnalyser;\n var interruptVolumeThreshold = 30;\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n // During TTS playback, check mic volume to detect\n // user interruption (speaking above threshold).\n if (this.isPlayingAudio && analyser) {\n var freqData = new Uint8Array(analyser.frequencyBinCount);\n analyser.getByteFrequencyData(freqData);\n var sum = 0;\n for (var k = 0; k < freqData.length; k++) { sum += freqData[k]; }\n var avg = sum / freqData.length;\n\n if (avg >= interruptVolumeThreshold) {\n // User is speaking — interrupt TTS playback.\n this.stopAudio();\n }\n }\n\n // Always send audio to STT — browser echo cancellation\n // handles speaker echo; continuous audio avoids gaps\n // that increase recognition latency.\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n try {\n this._conversationSubject.next(base64);\n } catch (err) {\n // Subject may have been completed already.\n }\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => {\n try {\n this._conversationSubject.complete();\n } catch (err) {\n // Already completed.\n }\n });\n });\n\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var language = navigator.language || document.documentElement.lang || 'en-US';\n\n this.connection.send(\"StartConversation\", profileId, sessionId, this._conversationSubject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n this.isConversationMode = false;\n this.updateConversationButton();\n });\n },\n stopConversationMode() {\n if (!this.isConversationMode) {\n return;\n }\n\n this.isConversationMode = false;\n this.updateConversationButton();\n\n // Signal the server to cancel all in-progress STT/TTS streams immediately.\n if (this.connection) {\n this.connection.invoke(\"StopConversation\").catch(function () { });\n }\n\n if (this.isRecording && this.mediaRecorder) {\n this.mediaRecorder.stop();\n this.isRecording = false;\n }\n\n this.stopAudio();\n this._conversationPartialTranscript = '';\n this._conversationPartialMessage = null;\n\n // Clean up the AudioContext used for volume monitoring.\n if (this._conversationAudioCtx) {\n this._conversationAudioCtx.close().catch(function () { });\n this._conversationAudioCtx = null;\n this._conversationAnalyser = null;\n }\n\n // Mark any in-flight assistant message as done to stop the spinner.\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Safety net: clear all lingering streaming indicators.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n\n // Show a \"conversation ended\" notification system message.\n this.receiveNotification({\n type: 'conversation-ended',\n content: 'Conversation ended.',\n icon: 'fa-solid fa-circle-check',\n dismissible: true,\n autoDismissMs: 5000\n });\n },\n updateConversationButton() {\n if (!this.conversationButton) {\n return;\n }\n\n if (this.isConversationMode) {\n this.conversationButton.classList.add('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-dark', 'btn-outline-secondary');\n this.conversationButton.title = this.conversationButton.getAttribute('data-end-title') || 'End Conversation';\n var endHtml = this.conversationButton.getAttribute('data-end-html');\n if (endHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(endHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n } else {\n this.conversationButton.classList.remove('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-secondary');\n this.conversationButton.classList.add('btn-outline-dark');\n this.conversationButton.blur();\n this.conversationButton.title = this.conversationButton.getAttribute('data-start-title') || 'Start Conversation';\n var startHtml = this.conversationButton.getAttribute('data-start-html');\n if (startHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(startHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n }\n },\n conversationModeSendPrompt() {\n // Legacy: only used by AudioInput mode's ReceiveTranscript.\n },\n conversationModeOnAudioEnded() {\n // Legacy: in conversation mode, audio playback continuation\n // is handled by the persistent stream. This method is only\n // called from playCollectedAudio for non-conversation TTS.\n },\n generatePrompt(element) {\n if (!element) {\n console.error('The element paramter is required.');\n\n return;\n }\n\n let templateProfileId = element.getAttribute('data-profile-id');\n let sessionId = this.getSessionId();\n let sessionProfileId = this.getProfileId();\n\n if (!templateProfileId || !sessionId) {\n\n console.error('The given element is missing data-profile-id or the session has not yet started.');\n return;\n }\n\n // streamMessage() already shows the typing indicator.\n this.streamMessage(templateProfileId, null, sessionProfileId);\n },\n createSessionUrl(baseUrl, param, value) {\n\n const fullUrl = baseUrl.toLowerCase().startsWith('http') ? baseUrl : window.location.origin + baseUrl;\n const url = new URL(fullUrl);\n\n url.searchParams.set(param, value);\n\n return url.toString();\n },\n showTypingIndicator() {\n this.addMessage({\n role: 'indicator',\n htmlContent: config.indicatorTemplate\n });\n },\n hideTypingIndicator() {\n const originalLength = this.messages.length;\n this.messages = this.messages.filter(msg => msg.role !== 'indicator');\n const removedCount = originalLength - this.messages.length;\n return removedCount;\n },\n receiveNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n } else {\n this.notifications.push(notification);\n }\n this.scheduleNotificationDismiss(notification);\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n updateNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n this.scheduleNotificationDismiss(notification);\n }\n },\n scheduleNotificationDismiss(notification) {\n if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {\n return;\n }\n this.notificationDismissTimers[notification.type] = setTimeout(() => {\n this.removeNotification(notification.type);\n }, notification.autoDismissMs);\n },\n clearNotificationDismiss(notificationType) {\n var timerId = this.notificationDismissTimers[notificationType];\n if (!timerId) {\n return;\n }\n clearTimeout(timerId);\n delete this.notificationDismissTimers[notificationType];\n },\n removeNotification(notificationType) {\n this.clearNotificationDismiss(notificationType);\n this.notifications = this.notifications.filter(n => n.type !== notificationType);\n },\n dismissNotification(notificationType) {\n this.removeNotification(notificationType);\n },\n handleNotificationAction(notificationType, actionName) {\n if (!this.connection) {\n return;\n }\n var sessionId = this.getSessionId();\n this.connection.invoke(\"HandleNotificationAction\", sessionId, notificationType, actionName).catch(function (err) {\n console.error(\"Error handling notification action:\", err);\n });\n },\n scrollToBottom() {\n if (!this.autoScroll) {\n return;\n }\n setTimeout(() => {\n this.chatContainer.scrollTop = this.chatContainer.scrollHeight - this.chatContainer.clientHeight;\n }, 50);\n },\n handleUserInput(event) {\n this.prompt = event.target.value;\n },\n getProfileId() {\n return this.inputElement\n ? this.inputElement.getAttribute('data-profile-id')\n : null;\n },\n setSessionId(sessionId) {\n if (!this.inputElement) {\n return;\n }\n\n this.inputElement.setAttribute('data-session-id', sessionId || '');\n },\n resetSession() {\n this.stopRecording();\n this.rejectPendingSessionRequest('Session was reset.');\n this.setSessionId('');\n this.isSessionStarted = false;\n this.sessionRating = null;\n this.messages = [];\n this.documents = [];\n if (!config.autoCreateSession) {\n this.showPlaceholder();\n }\n\n if (config.autoCreateSession) {\n this.startNewSession();\n }\n\n if (widgetBehavior && typeof widgetBehavior.onSessionReset === 'function') {\n widgetBehavior.onSessionReset(this, config);\n }\n },\n startNewSession() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n const profileId = this.getProfileId();\n if (!profileId || !this.connection) {\n return;\n }\n\n this.requestNewSession(profileId).catch(err => console.error(err));\n },\n async ensureSessionForDocuments(profileId) {\n var sessionId = this.getSessionId();\n if (sessionId) {\n return sessionId;\n }\n\n if (!profileId || !this.connection) {\n return null;\n }\n\n return await this.requestNewSession(profileId);\n },\n requestNewSession(profileId) {\n if (this.pendingSessionPromise) {\n return this.pendingSessionPromise;\n }\n\n if (!profileId || !this.connection) {\n return Promise.resolve(null);\n }\n\n this.pendingSessionPromise = new Promise((resolve, reject) => {\n this.pendingSessionResolver = resolve;\n this.pendingSessionRejector = reject;\n this.pendingSessionTimeoutId = window.setTimeout(() => {\n this.rejectPendingSessionRequest('Timed out while creating a chat session.');\n }, 15000);\n });\n\n this.connection.invoke(\"StartSession\", profileId, null).catch(err => {\n this.rejectPendingSessionRequest(err);\n });\n\n return this.pendingSessionPromise;\n },\n resolvePendingSessionRequest(sessionId) {\n if (this.pendingSessionResolver) {\n this.pendingSessionResolver(sessionId);\n }\n\n this.clearPendingSessionRequest();\n },\n rejectPendingSessionRequest(error) {\n if (this.pendingSessionRejector) {\n this.pendingSessionRejector(error);\n }\n\n this.clearPendingSessionRequest();\n },\n clearPendingSessionRequest() {\n if (this.pendingSessionTimeoutId) {\n window.clearTimeout(this.pendingSessionTimeoutId);\n }\n\n this.pendingSessionPromise = null;\n this.pendingSessionResolver = null;\n this.pendingSessionRejector = null;\n this.pendingSessionTimeoutId = null;\n },\n initializeApp() {\n this.inputElement = document.querySelector(config.inputElementSelector);\n this.buttonElement = document.querySelector(config.sendButtonElementSelector);\n this.chatContainer = document.querySelector(config.chatContainerElementSelector);\n this.placeholder = document.querySelector(config.placeholderElementSelector);\n\n if (!this.inputElement || !this.buttonElement || !this.chatContainer || !this.placeholder) {\n console.error('AI chat app could not initialize because one or more required elements were not found.', {\n inputElementSelector: config.inputElementSelector,\n sendButtonElementSelector: config.sendButtonElementSelector,\n chatContainerElementSelector: config.chatContainerElementSelector,\n placeholderElementSelector: config.placeholderElementSelector\n });\n\n return false;\n }\n\n this.applyOrchestratorAvailability();\n\n const sessionId = this.getSessionId();\n if (!hasWidgetConfig && sessionId) {\n this.loadSession(sessionId);\n } else if (this.isOrchestratorAvailable() && config.autoCreateSession && !hasWidgetConfig && !sessionId) {\n this.startNewSession();\n }\n\n // Initialize document bar if enabled.\n if (config.sessionDocumentsEnabled && config.documentBarSelector) {\n this.documentBar = document.querySelector(config.documentBarSelector);\n if (this.documentBar) {\n this.renderDocumentBar();\n\n // Create hidden file input for document uploads.\n var fileInput = document.createElement('input');\n fileInput.type = 'file';\n fileInput.id = 'ai-chat-doc-input';\n fileInput.className = 'd-none';\n fileInput.multiple = true;\n if (config.allowedExtensions) {\n fileInput.accept = config.allowedExtensions;\n }\n fileInput.addEventListener('change', (e) => this.handleFileInputChange(e));\n this.documentBar.parentElement.appendChild(fileInput);\n\n // Set up drag-and-drop on the input area.\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) {\n inputArea.addEventListener('dragover', (e) => this.handleDragOver(e));\n inputArea.addEventListener('dragleave', (e) => this.handleDragLeave(e));\n inputArea.addEventListener('drop', (e) => this.handleDrop(e));\n }\n }\n }\n\n // Pause auto-scroll when the user manually scrolls up during streaming.\n this.chatContainer.addEventListener('scroll', () => {\n if (!this.stream) {\n return;\n }\n const threshold = 30;\n const atBottom = this.chatContainer.scrollHeight - this.chatContainer.clientHeight - this.chatContainer.scrollTop <= threshold;\n this.autoScroll = atBottom;\n });\n\n this.inputElement.addEventListener('keydown', event => {\n\n if (this.stream != null) {\n return;\n }\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n this.buttonElement.click();\n }\n });\n\n this.inputElement.addEventListener('input', (e) => {\n this.handleUserInput(e);\n\n if (e.target.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n });\n\n this.buttonElement.addEventListener('click', () => {\n\n if (this.stream != null) {\n this.stream.dispose();\n this.stream = null;\n\n this.streamingFinished();\n this.hideTypingIndicator();\n\n // Clean up: remove empty assistant message or stop streaming animation.\n if (this.messages.length > 0) {\n const lastMsg = this.messages[this.messages.length - 1];\n if (lastMsg.role === 'assistant' && !lastMsg.content) {\n this.messages.pop();\n } else if (lastMsg.isStreaming) {\n lastMsg.isStreaming = false;\n }\n }\n\n return;\n }\n\n this.sendMessage();\n });\n\n const promptGenerators = document.getElementsByClassName('profile-generated-prompt');\n\n for (var i = 0; i < promptGenerators.length; i++) {\n promptGenerators[i].addEventListener('click', (e) => {\n e.preventDefault();\n this.generatePrompt(e.target);\n });\n }\n\n const chatSessions = document.getElementsByClassName('chat-session-history-item');\n\n for (var i = 0; i < chatSessions.length; i++) {\n chatSessions[i].addEventListener('click', (e) => {\n e.preventDefault();\n\n var sessionId = e.target.getAttribute('data-session-id');\n\n if (!sessionId) {\n console.error('an element with the class chat-session-history-item with no data-session-id set.');\n\n return;\n }\n\n this.loadSession(sessionId);\n this.showChatScreen();\n });\n }\n\n for (let i = 0; i < config.messages.length; i++) {\n this.addMessage(config.messages[i]);\n }\n\n // Update feedback icons in the DOM after initial messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // Delegate click for code block copy buttons.\n if (this.chatContainer) {\n this.chatContainer.addEventListener('click', (e) => {\n var btn = e.target.closest('.ai-code-copy-btn');\n if (!btn) {\n return;\n }\n\n var block = btn.closest('.ai-code-block') || btn.closest('pre');\n if (!block) {\n return;\n }\n\n var codeEl = block.querySelector('code');\n if (codeEl) {\n navigator.clipboard.writeText(codeEl.textContent);\n var copiedText = config.codeCopiedText || 'Copied!';\n btn.innerHTML = '<span class=\"fa-solid fa-check\"></span> ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '<span class=\"fa-regular fa-copy\"></span>';\n }, 2000);\n }\n });\n }\n\n // Initialize speech-to-text microphone button.\n if (this.speechToTextEnabled && config.micButtonElementSelector) {\n this.micButton = document.querySelector(config.micButtonElementSelector);\n if (this.micButton) {\n this.micButton.style.display = '';\n this.micButton.addEventListener('click', () => {\n this.toggleRecording();\n });\n }\n }\n\n // Initialize conversation mode button.\n if (this.conversationModeEnabled && config.conversationButtonElementSelector) {\n this.conversationButton = document.querySelector(config.conversationButtonElementSelector);\n if (this.conversationButton) {\n this.conversationButton.addEventListener('click', () => {\n this.toggleConversationMode();\n });\n }\n }\n\n return true;\n },\n loadSession(sessionId) {\n this.connection.invoke(\"LoadSession\", sessionId).catch(err => console.error(err));\n },\n reloadCurrentSession() {\n\n var sessionId = this.getSessionId();\n if (sessionId) {\n this.loadSession(sessionId);\n }\n },\n initializeSession(sessionId, force) {\n if (this.isSessionStarted && !force) {\n if (sessionId && this.getSessionId() === sessionId) {\n this.resolvePendingSessionRequest(sessionId);\n }\n\n return\n }\n this.fireEvent(new CustomEvent(\"initializingSessionOpenAIChat\", { detail: { sessionId: sessionId } }))\n this.setSessionId(sessionId);\n this.isSessionStarted = true;\n this.resolvePendingSessionRequest(sessionId);\n\n if (widgetBehavior && typeof widgetBehavior.onSessionInitialized === 'function') {\n widgetBehavior.onSessionInitialized(this, sessionId, config);\n }\n },\n getSessionId() {\n let sessionId = this.inputElement\n ? this.inputElement.getAttribute('data-session-id')\n : null;\n\n if (!sessionId && widgetBehavior && typeof widgetBehavior.resolveSessionId === 'function') {\n sessionId = widgetBehavior.resolveSessionId(this, config);\n }\n\n return sessionId;\n },\n copyResponse(message) {\n const text = message && typeof message === 'object'\n ? message.copyContent ?? message.content ?? ''\n : message ?? '';\n\n navigator.clipboard.writeText(text);\n },\n updateFeedbackIcons(container, userRating) {\n if (!container) {\n return;\n }\n\n var upBtn = container.querySelector('.rate-up-btn');\n var downBtn = container.querySelector('.rate-down-btn');\n\n // Keep feedback icons as simple span-based Font Awesome markup so\n // later state updates do not depend on i2svg replacement.\n if (upBtn) {\n var upClass = userRating === true ? 'fa-solid fa-thumbs-up' : 'fa-regular fa-thumbs-up';\n var upIcon = document.createElement('span');\n upIcon.className = upClass;\n upIcon.style.fontSize = '0.9rem';\n upBtn.textContent = '';\n upBtn.appendChild(upIcon);\n }\n\n if (downBtn) {\n var downClass = userRating === false ? 'fa-solid fa-thumbs-down' : 'fa-regular fa-thumbs-down';\n var downIcon = document.createElement('span');\n downIcon.className = downClass;\n downIcon.style.fontSize = '0.9rem';\n downBtn.textContent = '';\n downBtn.appendChild(downIcon);\n }\n },\n refreshAllFeedbackIcons() {\n var containers = this.$el.querySelectorAll('.ai-chat-message-assistant-feedback');\n\n for (var i = 0; i < containers.length; i++) {\n var msgId = containers[i].getAttribute('data-message-id');\n var msg = this.messages.find(m => m.id === msgId);\n\n if (msg) {\n this.updateFeedbackIcons(containers[i], msg.userRating);\n }\n }\n },\n rateMessage(message, isPositive, event) {\n var sessionId = this.getSessionId();\n\n if (!sessionId || !message.id || !this.connection) {\n return;\n }\n\n // Toggle: clicking the same rating again clears it.\n var newRating = message.userRating === isPositive ? null : isPositive;\n message.userRating = newRating;\n\n // Find the feedback container by message ID for reliable DOM targeting.\n var feedbackContainer = this.$el.querySelector(\n '.ai-chat-message-assistant-feedback[data-message-id=\"' + message.id + '\"]'\n );\n\n this.updateFeedbackIcons(feedbackContainer, newRating);\n\n // Trigger spark animation after Font Awesome has re-processed icons.\n if (newRating !== null && feedbackContainer) {\n setTimeout(() => {\n var btnClass = isPositive ? '.rate-up-btn' : '.rate-down-btn';\n var btn = feedbackContainer.querySelector(btnClass);\n\n if (btn) {\n btn.classList.remove('spark-effect');\n void btn.offsetWidth;\n btn.classList.add('spark-effect');\n btn.addEventListener('animationend', function onEnd() {\n btn.removeEventListener('animationend', onEnd);\n btn.classList.remove('spark-effect');\n });\n }\n }, 50);\n }\n\n this.connection.invoke(\"RateMessage\", sessionId, message.id, isPositive).catch(function (err) {\n console.error('Failed to rate message:', err);\n });\n }\n },\n watch: {\n documents: {\n handler() {\n this.renderDocumentBar();\n if (widgetBehavior && typeof widgetBehavior.onDocumentsChanged === 'function') {\n widgetBehavior.onDocumentsChanged(this, this.documents, config);\n }\n },\n deep: true\n },\n isUploading() { this.renderDocumentBar(); },\n isDocumentOperationPending() { this.renderDocumentBar(); },\n isPlayingAudio() {\n // Reserved for future use — volume-based interrupt detection\n // no longer mutes tracks; browser echo cancellation handles echo.\n },\n isConversationMode(active) {\n // Hide/show mic button.\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n // Hide/show send button.\n if (this.buttonElement) {\n this.buttonElement.style.display = active ? 'none' : '';\n }\n\n // Disable/enable textarea.\n if (this.inputElement) {\n this.inputElement.disabled = active;\n if (active) {\n this.inputElement.placeholder = '';\n }\n }\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n const isInitialized = this.initializeApp();\n if (isInitialized && hasWidgetConfig && widgetBehavior && typeof widgetBehavior.onMounted === 'function') {\n widgetBehavior.onMounted(this, config);\n }\n })();\n\n window.addEventListener('beforeunload', this.handleBeforeUnload);\n window.addEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n },\n beforeUnmount() {\n window.removeEventListener('beforeunload', this.handleBeforeUnload);\n window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n\n this.stopAudio(false);\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n if (this.connection) {\n this.connection.stop();\n }\n\n if (widgetBehavior && typeof widgetBehavior.onBeforeUnmount === 'function') {\n widgetBehavior.onBeforeUnmount(this, config);\n }\n },\n template: config.messageTemplate\n };\n\n const app = Vue.createApp(appDefinition).mount(config.appElementSelector);\n\n if (widgetBehavior && typeof widgetBehavior.attach === 'function') {\n widgetBehavior.attach(app, config);\n }\n\n return app;\n };\n\n return {\n initialize: initialize\n };\n}();\n\n// Download chart as image via event delegation (DOMPurify strips inline onclick).\ndocument.addEventListener('click', function (e) {\n const btn = e.target.closest('.download-chart-btn');\n if (!btn) {\n return;\n }\n const chartId = btn.getAttribute('data-chart-id');\n const canvas = chartId ? document.getElementById(chartId) : null;\n if (!canvas) {\n console.error('Chart canvas not found:', chartId);\n return;\n }\n const link = document.createElement('a');\n link.download = 'chart-' + chartId + '.png';\n link.href = canvas.toDataURL('image/png');\n link.click();\n});\n\n// Intercept download clicks for data-URI images and convert to blob downloads.\ndocument.addEventListener('click', function (e) {\n const link = e.target.closest('.ai-download-image');\n if (!link) {\n return;\n }\n\n const container = link.closest('.generated-image-container');\n const img = container?.querySelector('img');\n if (!img) {\n return;\n }\n\n const src = img.src;\n if (!src || !src.startsWith('data:')) {\n return; // Normal URL – let the default <a> behaviour handle it.\n }\n\n e.preventDefault();\n\n fetch(src)\n .then(function (res) { return res.blob(); })\n .then(function (blob) {\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = link.getAttribute('download') || 'generated-image.png';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n setTimeout(function () { URL.revokeObjectURL(url); }, 100);\n })\n .catch(function (err) { console.error('Failed to download image:', err); });\n});\n"]}
|