From deb444977428df841cc31459238919976599049d Mon Sep 17 00:00:00 2001 From: Mike Alhayek Date: Tue, 22 Sep 2026 09:06:04 -0700 Subject: [PATCH] Put the figure download over the picture, and let a figure be opened The MVC chat sample moved its download onto the picture and gained click-to-enlarge in #215, but it did both inline in its own view. The shared chat UI every other surface renders with -- the chat page, the widget and the chat-interaction page -- kept the old shape: a button on a row of its own beneath the picture, and a thumbnail that could not be opened. A figure is capped to a fraction of the viewport so a stack of them does not push the conversation off screen, which makes every one of them a thumbnail; in the widget, 380px wide, more so. So the two things a reader wants are to see it larger and to keep a copy, and the second was costing a band of vertical space under every figure to offer. The download is now drawn over the picture's lower corner and revealed by pointing at the figure, on a pale ground of its own because it sits on whatever the drawing puts in that corner. focus-within keeps it reachable by keyboard, and a touch screen -- which has no hover to reveal it with -- simply always shows it. The link is otherwise untouched: same address, same download attribute, so the existing data-URI interception still names the saved file the way it did. Enlarging is wired to medium-zoom on the same deferred pass as the broken-image handler, because a picture arrives after the markdown is handed back and a streamed answer rewrites it on every chunk. The library is the host's to load: without it the picture is still shown and still downloadable, and only the enlarging is missing, so a host that has not registered it loses nothing it had. The opened copy is matched on its own class, since the library appends it to the body rather than inside the figure -- the widget stylesheet repeats that one rule unscoped for the same reason. Co-Authored-By: Claude Opus 5 --- .../Assets/css/ai-chat.css | 62 +++++++++++++ .../Assets/css/chat-widget.css | 61 +++++++++++++ .../Assets/js/ai-chat.js | 43 +++++++-- .../Assets/js/chat-interaction.js | 43 +++++++-- .../wwwroot/scripts/ai-chat.js | 78 ++++++++++++---- .../wwwroot/scripts/ai-chat.js.map | 2 +- .../wwwroot/scripts/ai-chat.min.js | 2 +- .../wwwroot/scripts/ai-chat.min.js.map | 2 +- .../wwwroot/scripts/chat-interaction.js | 90 +++++++++++++------ .../wwwroot/scripts/chat-interaction.js.map | 2 +- .../wwwroot/scripts/chat-interaction.min.js | 2 +- .../scripts/chat-interaction.min.js.map | 2 +- .../wwwroot/styles/ai-chat.css | 62 +++++++++++++ .../wwwroot/styles/ai-chat.css.map | 2 +- .../wwwroot/styles/ai-chat.min.css | 2 +- .../wwwroot/styles/chat-widget.css | 61 +++++++++++++ .../wwwroot/styles/chat-widget.css.map | 2 +- .../wwwroot/styles/chat-widget.min.css | 2 +- 18 files changed, 456 insertions(+), 64 deletions(-) diff --git a/src/Resources/CrestApps.AI.Resources/Assets/css/ai-chat.css b/src/Resources/CrestApps.AI.Resources/Assets/css/ai-chat.css index f550de91..4f2a9d38 100644 --- a/src/Resources/CrestApps.AI.Resources/Assets/css/ai-chat.css +++ b/src/Resources/CrestApps.AI.Resources/Assets/css/ai-chat.css @@ -448,6 +448,8 @@ display: inline-block; vertical-align: top; margin-top: 0.5rem; + /* The positioning context for the download that sits inside it. */ + position: relative; } .generated-image-container img { @@ -455,6 +457,66 @@ max-height: 60vh; height: auto; object-fit: contain; + /* The cap above is what makes a figure a thumbnail: an ingested diagram lands at roughly half size, + legible as a picture but not as a drawing. Pointing at it says it can be opened. */ + cursor: zoom-in; +} + +/* The opened picture is a copy the library appends outside the figure, so it is matched on its own class + rather than through the container -- a rule written as a descendant of the figure never reaches it. The + copy carries the thumbnail's classes, so the frame is taken off here: its padding and white ground are + scaled up with the drawing and would otherwise ring the picture with a broad white border. The cap is + lifted for the same reason, and only here, so the thumbnail sitting in the conversation is left exactly + as it was. */ +img.medium-zoom-image--opened { + max-width: none !important; + max-height: none !important; + padding: 0; + border: 0; + background: none; +} + +/* Over the picture's lower corner rather than below it, so a figure costs only the height of the picture. + It is drawn on a ground of its own because it sits on whatever the drawing happens to put in that + corner. */ +.generated-image-container .ai-download-image { + position: absolute; + right: 0.5rem; + bottom: 0.5rem; + z-index: 2; + opacity: 0; + color: #1f2933; + background-color: rgba(255, 255, 255, 0.92); + border-color: rgba(0, 0, 0, 0.15); + transition: opacity 0.15s ease-in-out; +} + +/* The outline button this is built from inverts on hover: it fills itself with its own colour and turns + its label white. Against the pale ground kept here that leaves a white icon on white -- the button is + still there and still works, but there is nothing to see. Both colours are therefore stated for every + state the button can be in rather than only the resting one. */ +.generated-image-container .ai-download-image:hover, +.generated-image-container .ai-download-image:focus, +.generated-image-container .ai-download-image:focus-visible, +.generated-image-container .ai-download-image:active { + color: #1f2933; + background-color: #ffffff; + border-color: rgba(0, 0, 0, 0.35); +} + +/* Revealed by pointing at the figure. focus-within is what keeps it reachable by keyboard: the button is + invisible until it takes focus, and an invisible control that cannot be brought into view cannot be + used at all. */ +.generated-image-container:hover .ai-download-image, +.generated-image-container:focus-within .ai-download-image { + opacity: 1; +} + +/* A touch screen has no hover to reveal it with, so there it is simply always shown. */ +@media (hover: none) { + .generated-image-container .ai-download-image { + opacity: 1; + } } /* ── Tables ── */ diff --git a/src/Resources/CrestApps.AI.Resources/Assets/css/chat-widget.css b/src/Resources/CrestApps.AI.Resources/Assets/css/chat-widget.css index 76a64fbb..3bb98704 100644 --- a/src/Resources/CrestApps.AI.Resources/Assets/css/chat-widget.css +++ b/src/Resources/CrestApps.AI.Resources/Assets/css/chat-widget.css @@ -419,12 +419,73 @@ display: inline-block; vertical-align: top; margin-top: 0.5rem; + /* The positioning context for the download that sits inside it. */ + position: relative; } .ai-chat-widget-messages .generated-image-container img { max-width: 100% !important; max-height: 50vh; object-fit: contain; + /* The panel is 380px wide, so a figure in it is a thumbnail whatever it was drawn at. Pointing at it + says it can be opened to the size of the window. */ + cursor: zoom-in; +} + +/* Deliberately not scoped to the panel. The opened picture is a copy the library appends to the document + body, which is outside the widget entirely, so a rule under .ai-chat-widget-messages never reaches it. + It is repeated from ai-chat.css because a page that mounts only the widget loads only this file. The + copy carries the thumbnail's classes, so the frame and the cap are taken off here -- both are scaled up + with the drawing and would otherwise ring the picture with a broad white border. */ +img.medium-zoom-image--opened { + max-width: none !important; + max-height: none !important; + padding: 0; + border: 0; + background: none; +} + +/* Over the picture's lower corner rather than below it. In a panel this narrow a row of its own cost a + band of vertical space per figure, which a conversation full of them pays for once each. */ +.ai-chat-widget-messages .generated-image-container .ai-download-image { + position: absolute; + right: 0.5rem; + bottom: 0.5rem; + z-index: 2; + opacity: 0; + color: #1f2933; + background-color: rgba(255, 255, 255, 0.92); + border-color: rgba(0, 0, 0, 0.15); + transition: opacity 0.15s ease-in-out; +} + +/* The outline button this is built from inverts on hover: it fills itself with its own colour and turns + its label white. Against the pale ground kept here that leaves a white icon on white -- the button is + still there and still works, but there is nothing to see. Both colours are therefore stated for every + state the button can be in rather than only the resting one. */ +.ai-chat-widget-messages .generated-image-container .ai-download-image:hover, +.ai-chat-widget-messages .generated-image-container .ai-download-image:focus, +.ai-chat-widget-messages .generated-image-container .ai-download-image:focus-visible, +.ai-chat-widget-messages .generated-image-container .ai-download-image:active { + color: #1f2933; + background-color: #ffffff; + border-color: rgba(0, 0, 0, 0.35); +} + +/* Revealed by pointing at the figure. focus-within is what keeps it reachable by keyboard: the button is + invisible until it takes focus, and an invisible control that cannot be brought into view cannot be + used at all. */ +.ai-chat-widget-messages .generated-image-container:hover .ai-download-image, +.ai-chat-widget-messages .generated-image-container:focus-within .ai-download-image { + opacity: 1; +} + +/* A touch screen has no hover to reveal it with, so there it is simply always shown. The widget is the + surface most likely to be read on one. */ +@media (hover: none) { + .ai-chat-widget-messages .generated-image-container .ai-download-image { + opacity: 1; + } } /* ── Tables inside widget ── */ diff --git a/src/Resources/CrestApps.AI.Resources/Assets/js/ai-chat.js b/src/Resources/CrestApps.AI.Resources/Assets/js/ai-chat.js index 90684741..712ba9e2 100644 --- a/src/Resources/CrestApps.AI.Resources/Assets/js/ai-chat.js +++ b/src/Resources/CrestApps.AI.Resources/Assets/js/ai-chat.js @@ -489,13 +489,15 @@ window.coreAIChatManager = function () { // at the first one, so the sentence is torn into fragments and the commas between the markers are // left stranded on their own lines. Inline-block keeps the figure looking exactly the same while // remaining something a paragraph can legally contain. + // The download sits over the picture's lower corner rather than on a line of its own beneath it. + // A row of its own cost a band of vertical space under every figure, which a conversation full of + // them pays for once per figure. The link itself is unchanged -- same address, same download + // attribute, same behaviour -- only where it is drawn. return ` ${alt} - - - - - + + + `; }; @@ -578,6 +580,37 @@ window.coreAIChatManager = function () { // Deferred for the same reason the charts below are: the render that produced these elements has // not necessarily been flushed to the DOM when this runs. requestAnimationFrame(wireBrokenImageHandlers); + requestAnimationFrame(wireImageZoom); + } + + // A picture arrives after the markdown is handed back -- the view writes it, and a streamed answer + // rewrites it on every chunk -- so zooming cannot be attached once at load. It is attached on the same + // pass as the broken-image handler above, and the attribute marks a picture already attached so a + // re-render does not bind it a second time. + function wireImageZoom() { + // The library is the host's to load. Without it the picture is still shown and still downloadable; + // only the enlarging is missing, so this is not worth failing a render over. + if (typeof mediumZoom !== 'function') { + return; + } + + const images = document.querySelectorAll('.generated-image-container img:not([data-zoom-wired])'); + + if (images.length === 0) { + return; + } + + for (const image of images) { + image.setAttribute('data-zoom-wired', 'true'); + } + + mediumZoom(images, { + // The drawing is bounded by the window rather than by this margin, so the margin is kept + // small: an ingested figure is read detail by detail, and every pixel given away here comes + // off the size it is read at. + margin: 16, + background: 'rgba(15, 15, 15, 0.92)', + }); } function wireBrokenImageHandlers() { diff --git a/src/Resources/CrestApps.AI.Resources/Assets/js/chat-interaction.js b/src/Resources/CrestApps.AI.Resources/Assets/js/chat-interaction.js index f38b17ae..34a420be 100644 --- a/src/Resources/CrestApps.AI.Resources/Assets/js/chat-interaction.js +++ b/src/Resources/CrestApps.AI.Resources/Assets/js/chat-interaction.js @@ -411,13 +411,15 @@ window.chatInteractionManager = function () { // at the first one, so the sentence is torn into fragments and the commas between the markers are // left stranded on their own lines. Inline-block keeps the figure looking exactly the same while // remaining something a paragraph can legally contain. + // The download sits over the picture's lower corner rather than on a line of its own beneath it. + // A row of its own cost a band of vertical space under every figure, which a conversation full of + // them pays for once per figure. The link itself is unchanged -- same address, same download + // attribute, same behaviour -- only where it is drawn. return ` ${alt} - - - - - + + + `; }; @@ -498,6 +500,37 @@ window.chatInteractionManager = function () { // Deferred for the same reason the charts below are: the render that produced these elements has // not necessarily been flushed to the DOM when this runs. requestAnimationFrame(wireBrokenImageHandlers); + requestAnimationFrame(wireImageZoom); + } + + // A picture arrives after the markdown is handed back -- the view writes it, and a streamed answer + // rewrites it on every chunk -- so zooming cannot be attached once at load. It is attached on the same + // pass as the broken-image handler above, and the attribute marks a picture already attached so a + // re-render does not bind it a second time. + function wireImageZoom() { + // The library is the host's to load. Without it the picture is still shown and still downloadable; + // only the enlarging is missing, so this is not worth failing a render over. + if (typeof mediumZoom !== 'function') { + return; + } + + const images = document.querySelectorAll('.generated-image-container img:not([data-zoom-wired])'); + + if (images.length === 0) { + return; + } + + for (const image of images) { + image.setAttribute('data-zoom-wired', 'true'); + } + + mediumZoom(images, { + // The drawing is bounded by the window rather than by this margin, so the margin is kept + // small: an ingested figure is read detail by detail, and every pixel given away here comes + // off the size it is read at. + margin: 16, + background: 'rgba(15, 15, 15, 0.92)', + }); } function wireBrokenImageHandlers() { diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.js b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.js index a6d9832f..029bde83 100644 --- a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.js +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.js @@ -517,7 +517,11 @@ window.coreAIChatManager = function (_window$CoreAIChatMar, _window$CoreAIChatMa // at the first one, so the sentence is torn into fragments and the commas between the markers are // left stranded on their own lines. Inline-block keeps the figure looking exactly the same while // remaining something a paragraph can legally contain. - return "\n \"").concat(alt,\n \n \n \n \n \n "); + // The download sits over the picture's lower corner rather than on a line of its own beneath it. + // A row of its own cost a band of vertical space under every figure, which a conversation full of + // them pays for once per figure. The link itself is unchanged -- same address, same download + // attribute, same behaviour -- only where it is drawn. + return "\n \"").concat(alt,\n \n \n \n "); }; // Chart counter for unique IDs @@ -592,14 +596,50 @@ window.coreAIChatManager = function (_window$CoreAIChatMar, _window$CoreAIChatMa // Deferred for the same reason the charts below are: the render that produced these elements has // not necessarily been flushed to the DOM when this runs. requestAnimationFrame(wireBrokenImageHandlers); + requestAnimationFrame(wireImageZoom); } - function wireBrokenImageHandlers() { - var images = document.querySelectorAll('.generated-image-container img:not([data-broken-wired])'); + + // A picture arrives after the markdown is handed back -- the view writes it, and a streamed answer + // rewrites it on every chunk -- so zooming cannot be attached once at load. It is attached on the same + // pass as the broken-image handler above, and the attribute marks a picture already attached so a + // re-render does not bind it a second time. + function wireImageZoom() { + // The library is the host's to load. Without it the picture is still shown and still downloadable; + // only the enlarging is missing, so this is not worth failing a render over. + if (typeof mediumZoom !== 'function') { + return; + } + var images = document.querySelectorAll('.generated-image-container img:not([data-zoom-wired])'); + if (images.length === 0) { + return; + } var _iterator6 = _createForOfIteratorHelper(images), _step6; try { - var _loop = function _loop() { + for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) { var image = _step6.value; + image.setAttribute('data-zoom-wired', 'true'); + } + } catch (err) { + _iterator6.e(err); + } finally { + _iterator6.f(); + } + mediumZoom(images, { + // The drawing is bounded by the window rather than by this margin, so the margin is kept + // small: an ingested figure is read detail by detail, and every pixel given away here comes + // off the size it is read at. + margin: 16, + background: 'rgba(15, 15, 15, 0.92)' + }); + } + function wireBrokenImageHandlers() { + var images = document.querySelectorAll('.generated-image-container img:not([data-broken-wired])'); + var _iterator7 = _createForOfIteratorHelper(images), + _step7; + try { + var _loop = function _loop() { + var image = _step7.value; image.setAttribute('data-broken-wired', 'true'); image.addEventListener('error', function () { var container = image.closest('.generated-image-container'); @@ -616,13 +656,13 @@ window.coreAIChatManager = function (_window$CoreAIChatMar, _window$CoreAIChatMa once: true }); }; - for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) { + for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) { _loop(); } } catch (err) { - _iterator6.e(err); + _iterator7.e(err); } finally { - _iterator6.f(); + _iterator7.f(); } } function renderMessageMedia(message) { @@ -638,17 +678,17 @@ window.coreAIChatManager = function (_window$CoreAIChatMar, _window$CoreAIChatMa // Defer to requestAnimationFrame so the browser has fully laid out the // canvas elements before Chart.js reads their dimensions. requestAnimationFrame(function () { - var _iterator7 = _createForOfIteratorHelper(charts), - _step7; + var _iterator8 = _createForOfIteratorHelper(charts), + _step8; try { - for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) { - var c = _step7.value; + for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) { + var c = _step8.value; renderChartOnCanvas(c.chartId, c.config); } } catch (err) { - _iterator7.e(err); + _iterator8.e(err); } finally { - _iterator7.f(); + _iterator8.f(); } }); } @@ -2313,18 +2353,18 @@ window.coreAIChatManager = function (_window$CoreAIChatMar, _window$CoreAIChatMa }, 0); var combined = new Uint8Array(totalLength); var offset = 0; - var _iterator8 = _createForOfIteratorHelper(this.audioChunks), - _step8; + var _iterator9 = _createForOfIteratorHelper(this.audioChunks), + _step9; try { - for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) { - var chunk = _step8.value; + for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) { + var chunk = _step9.value; combined.set(chunk, offset); offset += chunk.length; } } catch (err) { - _iterator8.e(err); + _iterator9.e(err); } finally { - _iterator8.f(); + _iterator9.f(); } this.audioChunks = []; var blob = new Blob([combined], { diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.js.map b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.js.map index 11eff7b0..dd4a9852 100644 --- a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.js.map +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.js.map @@ -1 +1 @@ -{"version":3,"sources":["ai-chat.js"],"names":["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","setPrototypeOf","__proto__","displayName","_regenerator","w","m","defineProperty","_regeneratorDefine","_invoke","enumerable","configurable","writable","_toConsumableArray","_arrayWithoutHoles","_iterableToArray","_unsupportedIterableToArray","_nonIterableSpread","Array","from","isArray","_arrayLikeToArray","_objectWithoutProperties","_objectWithoutPropertiesLoose","getOwnPropertySymbols","indexOf","propertyIsEnumerable","hasOwnProperty","_createForOfIteratorHelper","_n","F","s","next","asyncGeneratorStep","Promise","resolve","then","_asyncToGenerator","arguments","apply","_next","_throw","_slicedToArray","_arrayWithHoles","_iterableToArrayLimit","_nonIterableRest","toString","slice","constructor","name","test","push","_typeof","window","coreAIChatManager","_window$CoreAIChatMar","_window$CoreAIChatMar2","_window$CoreAIChatMar3","_window$CoreAIChatMar4","_window$CoreAIChatMar5","_window$CoreAIChatMar6","_window$CoreAIChatMar7","_window$CoreAIChatMar8","_window$CoreAIChatMar9","_window$CoreAIChatMar0","defaultConfig","generatedImageAltText","generatedImageMaxWidth","downloadImageTitle","downloadChartTitle","downloadChartButtonText","userLabel","assistantLabel","thumbsUpTitle","thumbsDownTitle","copyTitle","copiedTitle","codeCopiedText","copyResetDelayMs","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","containsFontAwesomePlaceholders","root","nodeType","selector","matches","querySelector","refreshFontAwesomeIcons","fontAwesome","FontAwesome","dom","i2svg","node","observeFontAwesomeIcons","MutationObserver","observer","mutations","forEach","mutation","addedNodes","observe","childList","subtree","parsePixelValue","Number","isFinite","parsed","parseFloat","clamp","min","max","Math","normalizeReference","reference","_ref","_normalized$index","_ref2","_normalized$text","_ref3","_normalized$title","_ref4","_normalized$link","_ref5","_normalized$reference","_normalized$isGenerat","_normalized$isImage","normalized","assign","index","Index","Text","title","Title","link","Link","referenceType","ReferenceType","isGenerated","IsGenerated","isImage","IsImage","isDownloadCitationReference","toLowerCase","normalizeReferences","references","_i","_Object$entries","entries","_normalizeReference","_Object$entries$_i","key","readJsonResponse","_x","_x2","_readJsonResponse","_callee0","response","fallbackMessage","contentType","message","_t6","_t7","_context0","headers","get","redirected","ok","data","json","expandImageMarkers","CoreAIChatMarkers","getCitationLabel","unmergedCitationCount","citationIdentity","concat","splitCombinedCitations","content","collapseRepeatedCitations","html","separateAdjacentCitations","citationMarkerHtml","displayIndex","buildCitationDisplay","processedContent","messageReferences","referenceEntries","citations","citedRefs","filter","_ref6","_ref7","includes","generatedRefs","_ref8","_ref9","sort","_ref0","_ref1","_ref10","_ref11","b","_ref12","_ref13","_ref14","_ref15","citationsByIdentity","Map","placeholders","_iterator","_step","_step$value","label","identity","citation","referenceKey","referenceKeys","isDownload","set","placeholder","replaceAll","err","_i2","_placeholders","entry","_iterator2","_step2","_step2$value","map","_ref16","_excluded","buildCopyContent","copyContent","_iterator3","_step3","_citation$referenceKe","_iterator5","_step5","_iterator4","_step4","trimEnd","updateMessagePresentation","rawContent","displayContent","citationDisplay","citationReferences","htmlContent","parseMarkdownContent","renderer","marked","Renderer","href","code","lang","highlighted","hljs","getLanguage","highlight","language","_","highlightAuto","langDisplay","image","src","alt","maxWidth","chartCounter","_pendingCharts","__chartConfigs","createChartHtml","chartId","findChartMarker","use","extensions","level","start","idx","undefined","tokenizer","extracted","startIndex","type","raw","substring","endIndex","token","config","markBrokenImagesInMessage","requestAnimationFrame","wireBrokenImageHandlers","images","querySelectorAll","_iterator6","_step6","_loop","setAttribute","addEventListener","container","closest","dataset","brokenHandled","hidden","note","className","insertAdjacentElement","once","renderMessageMedia","charts","_iterator7","_step7","renderChartOnCanvas","canvas","getElementById","Chart","console","warn","offsetParent","_cfg$options","_cfg$options2","_cfg$options2$aspectR","_chartInstance","destroy","cfg","JSON","parse","options","responsive","maintainAspectRatio","aspectRatio","error","renderPendingCharts","configs","_i3","_Object$keys","keys","styleMarkdownTables","replace","DOMPurify","sanitize","ADD_TAGS","ADD_ATTR","compactObject","source","fromEntries","_ref17","_ref18","resolveIndicatorTemplate","template","encodedAssistantLabel","initialize","instanceConfig","normalizedInstanceConfig","normalizedWidgetConfig","hasWidgetConfig","widgetBehavior","coreAIChatWidgetBehavior","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","realtimeEnabled","chatMode","textToSpeechEnabled","ttsVoiceName","audioChunks","audioPlayQueue","isPlayingAudio","currentAudioElement","currentAudioUrl","ttsButton","ttsPlayingMessageIndex","ttsAudioCache","ttsInstanceId","random","singleResponseMode","conversationModeEnabled","realtimeWebRtcEnabled","RTCPeerConnection","realtimeWebRtcIceServers","realtimeVoiceName","conversationButton","realtimeHintElement","realtimeHintElementSelector","isConversationMode","notificationDismissTimers","pendingSessionPromise","pendingSessionResolver","pendingSessionRejector","pendingSessionTimeoutId","copiedMessageIndex","copyResetTimeoutId","activeCopyButton","computed","lastAssistantIndex","role","methods","handleBeforeUnload","handleDragOver","sessionDocumentsEnabled","preventDefault","stopPropagation","inputArea","classList","add","handleDragLeave","remove","handleDrop","dataTransfer","files","uploadFiles","triggerFileInput","fileInput","click","handleFileInputChange","target","queueDocumentOperation","operation","self","previousOperation","nextOperation","_callee","_context","_this","_callee3","filesToUpload","_context3","uploadDocumentUrl","_callee2","sessionId","profileId","formData","errorText","uploadError","result","_t","_t2","_context2","getSessionId","getProfileId","ensureSessionForDocuments","fileName","renderDocumentBar","FormData","append","fetch","method","body","extractReadableErrorMessage","status","initializeSession","uploaded","failed","reloadCurrentSession","removeDocument","doc","_this2","_callee5","_context5","removeDocumentUrl","_callee4","secondParsed","removeError","_t3","_context4","stringify","itemId","documentId","splice","formatFileSize","bytes","toFixed","escapeHtml","failedItem","failedName","errorMsg","supportedExtensionsText","replaceChildren","RETURN_DOM_FRAGMENT","closeButtons","j","docToRemove","parseInt","getAttribute","errorCloseButtons","addBtn","div","startsWith","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","forceStopActiveVoice","msg","addMessage","$nextTick","refreshAllFeedbackIcons","initialPrompt","stopRecording","rejectPendingSessionRequest","hideTypingIndicator","handleReceiveError","getErrorMessage","reason","messageId","userRating","find","id","isFinal","_conversationPartialTranscript","escaped","_conversationPartialMessage","hidePlaceholder","isPartial","scrollToBottom","_audioInputSent","dispatchEvent","Event","turnId","_realtimePendingTurns","pending","stopAudio","fillRealtimePendingTurn","_conversationAssistantMessage","at","userMsg","responseId","_conversationAssistantResponseId","prev","msgIndex","newMessage","base64Audio","binaryString","atob","Uint8Array","charCodeAt","realtimeController","receivePcm","playCollectedAudio","notification","receiveNotification","updateNotification","notificationType","removeNotification","onreconnecting","stopRealtimeConversation","onreconnected","info","onclose","ensureConnectionStarted","_this4","_callee7","states","_t5","_context7","HubConnectionState","state","Connected","Disconnected","settle","clearTimeout","timeoutId","clearInterval","intervalId","setTimeout","setInterval","addMessageInternal","_this5","fireEvent","CustomEvent","_this6","_message$rawContent","addMessages","_this7","showPlaceholder","isOrchestratorAvailable","applyOrchestratorAvailability","unavailableMessage","orchestratorUnavailableMessage","disabled","micButtonElement","style","display","conversationButtonElement","event","isIndicator","sendMessage","trimmedPrompt","streamMessage","startRecording","_this8","navigator","mediaDevices","getUserMedia","audio","echoCancellation","noiseSuppression","autoGainControl","subject","Subject","_sttCapture","_createPcmCapture","base64","_sttSubject","rate","sampleRate","documentElement","send","updateMicButton","_stopPcmCapture","complete","onChunk","AudioCtx","AudioContext","webkitAudioContext","audioContext","srcRate","createMediaStreamSource","processor","createScriptProcessor","onaudioprocess","input","inputBuffer","getChannelData","pcm16","_downsampleToInt16","sum","rms","sqrt","buffer","binary","String","fromCharCode","btoa","connect","destination","capture","disconnect","getTracks","stop","close","dstRate","same","Int16Array","ratio","newLen","floor","out","i0","i1","frac","toggleRecording","sessionProfileId","_this9","dispose","streamingStarted","showTypingIndicator","lastResponseId","messageIndex","currentSessionId","subscribe","chunk","_i4","_Object$entries2","_normalizeReference2","_Object$entries2$_i","_this9$stream","processReferences","streamingFinished","synthesizeSpeech","_this9$stream2","getServiceDownMessage","_this0","_ref22","_message$rawContent2","stopIcon","startIcon","removeAttribute","focus","icons","handleExternalTtsStop","_e$detail","sourceId","updateTtsPlaybackButtons","_this1","buttons","button","buttonIndex","isPlaying","toggle","updateCopyButtons","_this10","isCopied","iconHtml","setCopyButtonState","cacheIndex","_this11","_ttsCacheIndex","invoke","toggleMessageTts","_this12","playAudioBlob","_this13","totalLength","reduce","combined","offset","_iterator8","_step8","blob","Blob","_this14","URL","createObjectURL","Audio","revokeObjectURL","playNextInQueue","play","_this15","nextBlob","shift","conversationModeOnAudioEnded","_this16","pause","currentTime","voiceSettingsElement","nextElementSibling","setVoiceSessionLive","live","audioSettings","hint","toggleConversationMode","stopConversationMode","startConversationMode","startRealtimeConversation","setupRealtimeController","CoreAIRealtime","attach","ensureConnected","connected","Error","sendStart","voice","silenceMs","vadThreshold","allowInterruption","webRtcEnabled","sendStartWebRtc","offerSdp","webRtcIceServers","voiceName","getVoiceName","selectors","realtimeButton","conversationButtonElementSelector","micButtonElementSelector","onSessionStateChanged","active","onActivate","onDeactivate","finishRealtimeConversationCleanup","onUserTurnPending","addRealtimePendingTurn","onUserTurnDropped","dropRealtimePendingTurn","dismissible","autoDismissMs","emptyAt","dropped","_this17","updateConversationButton","_conversationSubject","_conversationStream","interruptRmsThreshold","_conversationCapture","endHtml","blur","startHtml","conversationModeSendPrompt","generatePrompt","element","templateProfileId","createSessionUrl","baseUrl","param","fullUrl","location","origin","searchParams","originalLength","removedCount","_this18","clearNotificationDismiss","existingIndex","findIndex","scheduleNotificationDismiss","_this19","timerId","dismissNotification","handleNotificationAction","actionName","_this20","scrollTop","scrollHeight","clientHeight","handleUserInput","setSessionId","resetSession","sessionRating","onSessionReset","startNewSession","requestNewSession","_this21","_callee8","_context8","_this22","reject","resolvePendingSessionRequest","clearPendingSessionRequest","initializeApp","_this23","placeholderElementSelector","loadSession","documentBarSelector","multiple","allowedExtensions","accept","parentElement","appendChild","threshold","atBottom","shiftKey","lastMsg","pop","promptGenerators","getElementsByClassName","chatSessions","showChatScreen","initialMessages","btn","block","codeEl","clipboard","writeText","copiedText","force","onSessionInitialized","sessionUrlTemplate","history","replaceState","sessionUrl","encodeURIComponent","resolveSessionId","clearCopiedMessageState","copyResponse","_ref23","_message$copyContent","_event$target","_event$target$closest","_this24","currentTarget","updateFeedbackIcons","upBtn","downBtn","upClass","upIcon","fontSize","downClass","downIcon","containers","$el","msgId","rateMessage","isPositive","newRating","feedbackContainer","btnClass","offsetWidth","onEnd","removeEventListener","watch","handler","onDocumentsChanged","deep","_this25","mounted","_this26","_callee9","isInitialized","_context9","onMounted","fontAwesomeObserver","beforeUnmount","onBeforeUnmount","app","Vue","createApp","mount","autoInitializeSelector","getAttributeValue","attributeName","parseBooleanAttributeValue","parseJsonAttribute","description","rawValue","buildConfigFromDataAttributes","_parseJsonAttribute","_parseJsonAttribute2","settings","hasAttribute","allowWidgetHost","booleanAttributes","buildConfigFromElement","jsonConfig","attributeConfig","initializeFromElement","coreAiChatInitialized","__coreAIChatApp","scanForAutoInitialization","startAutoInitialization","readyState","download","toDataURL","img","res","removeChild"],"mappings":"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","file":"ai-chat.js","sourcesContent":["/*\n * Figure markers: the short labels the model writes, turned into pictures by the host.\n *\n * Retrieval hands the model a label -- [fig:1] -- and keeps the picture's real link in the message's reference\n * map, the same way a text citation keeps its source behind \"[doc:1]\". A model asked to reproduce a long opaque\n * identifier does not reproduce it: it copies the shape and substitutes ordinals, so links to figures that were\n * never in the results came back as 404s. A label short enough to be written exactly, with the link put back\n * here where the model cannot reach it, is what stops that.\n *\n * It sits on window rather than inside the manager below so the host can reach it, and so its rules can be\n * exercised in a bare sandbox with no browser and no DOM -- see tests/realtime-client/figure-markers.test.js --\n * exactly as window.CoreAIRealtime exposes the microphone gate's rules.\n *\n * The same block sits at the top of chat-interaction.js: the two chat clients are separate bundles that share no\n * module of their own, and both render the same markdown. Change one, change the other.\n */\n// CoreAIChatMarkers lives in chat-markers.js, which every chat surface loads before this file.\n\nwindow.coreAIChatManager = 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 copiedTitle: 'Response copied to clipboard.',\n codeCopiedText: 'Copied!',\n copyResetDelayMs: 2000,\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
\n
\n
\n
\n {{ userLabel }}\n
\n
\n
\n \n {{ getAssistantLabel(message) }}\n
\n
\n
\n

{{ message.title }}

\n
\n
    \n
  1. \n {{ citation.label }}\n {{ citation.label }}\n
  2. \n
\n \n \n \n \n \n
\n
\n
\n
\n
\n \n {{ notification.content }}\n \n
\n
\n \n
\n
\n
\n `,\n indicatorTemplate: `\n
\n
\n \n Assistant\n
\n
\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 containsFontAwesomePlaceholders(root) {\n if (!root || root.nodeType !== 1) {\n return false;\n }\n\n var selector = 'i[class*=\"fa-\"],i.fa,i.fas,i.far,i.fab';\n if (typeof root.matches === 'function' && root.matches(selector)) {\n return true;\n }\n\n return typeof root.querySelector === 'function' && !!root.querySelector(selector);\n }\n\n function refreshFontAwesomeIcons(root) {\n var fontAwesome = window.FontAwesome;\n if (!containsFontAwesomePlaceholders(root) || !fontAwesome || !fontAwesome.dom || typeof fontAwesome.dom.i2svg !== 'function') {\n return;\n }\n\n fontAwesome.dom.i2svg({ node: root });\n }\n\n function observeFontAwesomeIcons(root) {\n if (!root || typeof MutationObserver === 'undefined') {\n return null;\n }\n\n var observer = new MutationObserver(function (mutations) {\n mutations.forEach(function (mutation) {\n mutation.addedNodes.forEach(function (node) {\n refreshFontAwesomeIcons(node);\n });\n });\n });\n\n observer.observe(root, {\n childList: true,\n subtree: true\n });\n\n return observer;\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 normalized.isGenerated = (normalized.isGenerated ?? normalized.IsGenerated) === true;\n normalized.isImage = (normalized.isImage ?? normalized.IsImage) === true;\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 // Installed at the top of this file so it can be unit tested without a browser; see the comment there.\n\n /*\n * Reads a JSON response body, or explains why it is not JSON.\n *\n * fetch follows a redirect silently and reports the page it landed on as a success, so an endpoint that\n * answers \"forbidden\" with a redirect to a sign-in page arrives here as response.ok with HTML in it.\n * Calling response.json() on that throws \"unexpected character at line 1 column 1\", which is what the\n * reader was shown instead of being told they are not allowed to upload.\n *\n * Returns { ok, data, message }. A caller shows message when ok is false; it is never a parser error.\n */\n async function readJsonResponse(response, fallbackMessage) {\n const contentType = (response.headers && response.headers.get('content-type')) || '';\n\n if (contentType.toLowerCase().indexOf('json') < 0) {\n // A redirect that landed somewhere else is the common case and worth naming, because the endpoint\n // did not refuse -- something in front of it did.\n const message = response.redirected\n ? 'You may not be signed in, or you do not have permission for this. Please reload and try again.'\n : fallbackMessage;\n\n return { ok: false, data: null, message: message };\n }\n\n try {\n return { ok: true, data: await response.json(), message: null };\n } catch (error) {\n return { ok: false, data: null, message: fallbackMessage };\n }\n }\n\n const expandImageMarkers = window.CoreAIChatMarkers.expandImageMarkers;\n\n function getCitationLabel(reference, key) {\n return reference.title || reference.text || key;\n }\n\n // Which references are one citation, and how a repeated marker reads, are statements about strings and\n // live in chat-markers.js so every chat surface numbers them the same way. Without the module each\n // reference keeps an identity of its own and nothing merges, which is the numbering this script had\n // before it.\n let unmergedCitationCount = 0;\n const citationIdentity = window.CoreAIChatMarkers?.citationIdentity\n ?? (() => `unmerged-${++unmergedCitationCount}`);\n const splitCombinedCitations = window.CoreAIChatMarkers?.splitCombinedCitations\n ?? (content => content);\n const collapseRepeatedCitations = window.CoreAIChatMarkers?.collapseRepeatedCitations\n ?? (html => html);\n const separateAdjacentCitations = window.CoreAIChatMarkers?.separateAdjacentCitations\n ?? (html => html);\n const citationMarkerHtml = window.CoreAIChatMarkers?.citationMarkerHtml\n ?? (displayIndex => `${displayIndex}`);\n\n function buildCitationDisplay(content, references) {\n // Before anything looks for a reference key, the combined form the model tends to write is split into\n // the keys it means. A key that is not found is not replaced, and an unreplaced key reaches the reader\n // as a raw marker mid-sentence.\n let processedContent = splitCombinedCitations((content || '').trim());\n const messageReferences = normalizeReferences(references);\n const referenceEntries = Object.entries(messageReferences);\n\n if (!referenceEntries.length) {\n return { content: processedContent, citations: [] };\n }\n\n const citedRefs = referenceEntries.filter(([key]) => processedContent.includes(key));\n const generatedRefs = referenceEntries.filter(([key, value]) => value.isGenerated && !processedContent.includes(key));\n\n if (!citedRefs.length && !generatedRefs.length) {\n return { content: processedContent, citations: [] };\n }\n\n citedRefs.sort(([, a], [, b]) => a.index - b.index);\n generatedRefs.sort(([, a], [, b]) => a.index - b.index);\n\n const citations = [];\n const citationsByIdentity = new Map();\n const placeholders = [];\n let displayIndex = 1;\n\n for (const [key, value] of citedRefs) {\n const label = getCitationLabel(value, key);\n const link = value.link || null;\n const identity = citationIdentity(label, link);\n let citation = citationsByIdentity.get(identity);\n\n // Every reference still has its key replaced, so the text never keeps a raw key; what the merge\n // changes is only how many numbers the reader is given for them.\n if (!citation) {\n citation = {\n referenceKey: key,\n referenceKeys: [],\n displayIndex: displayIndex++,\n label: label,\n link: link,\n isDownload: isDownloadCitationReference(value),\n };\n\n citationsByIdentity.set(identity, citation);\n citations.push(citation);\n }\n\n citation.referenceKeys.push(key);\n\n const placeholder = `__CITE_${citation.displayIndex}_${value.index || citation.displayIndex}__`;\n processedContent = processedContent.replaceAll(key, placeholder);\n placeholders.push({ placeholder, displayIndex: citation.displayIndex, label: citation.label });\n }\n\n for (const entry of placeholders) {\n processedContent = processedContent.replaceAll(entry.placeholder, citationMarkerHtml(entry.displayIndex, entry.label));\n }\n\n // Merged citations can leave the same number twice over a sentence; that is collapsed before the\n // commas go in, or the reader is given \"1,1\".\n processedContent = collapseRepeatedCitations(processedContent);\n processedContent = separateAdjacentCitations(processedContent);\n\n // Generated files (such as exported tabular data) are always offered as a download even when\n // the model does not cite them inline, so the user never loses access to the produced file.\n for (const [key, value] of generatedRefs) {\n citations.push({\n referenceKey: key,\n referenceKeys: [key],\n displayIndex: displayIndex,\n label: getCitationLabel(value, key),\n link: value.link || null,\n isDownload: true,\n placeholder: null,\n });\n\n displayIndex++;\n }\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 // Every key the citation absorbed is replaced, not just the first: a merged key left behind would\n // reach the clipboard as the raw reference token the reader never saw on the page.\n for (const citation of citations) {\n for (const key of (citation.referenceKeys?.length ? citation.referenceKeys : [citation.referenceKey])) {\n copyContent = copyContent.replaceAll(key, `[${citation.displayIndex}]`);\n }\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 // Figure markers become images before anything else reads the content: the citation pass looks for its\n // own keys in what is left, and the markdown parser then sees an ordinary image.\n const displayContent = expandImageMarkers(rawContent, messageReferences);\n const citationDisplay = buildCitationDisplay(displayContent, 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 // Copied from the expanded content, so a copied answer carries the picture's link rather than a label\n // that means nothing outside this page.\n // Split here too: the copy is built from the expanded content rather than the display path's output,\n // so a combined marker would otherwise survive into the clipboard as a raw key.\n message.copyContent = buildCopyContent(splitCombinedCitations(displayContent), 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 `${data.text}`;\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 `
${langDisplay}
${highlighted}
`;\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 // Spans, not divs. A figure marker is often written mid-sentence -- \"Figures [fig:1], [fig:2] and\n // [fig:3] show...\" -- and a block element cannot sit inside a paragraph: the browser closes the

\n // at the first one, so the sentence is torn into fragments and the commas between the markers are\n // left stranded on their own lines. Inline-block keeps the figure looking exactly the same while\n // remaining something a paragraph can legally contain.\n return `\n \"${alt}\"\n \n \n \n \n \n `;\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 `

`\n + ``\n + `
`\n + `
`\n + ``\n + `
`;\n }\n\n // The marker itself is read by chat-markers.js, shared with every other chat surface, so the three of them\n // cannot disagree about what a marker is. Everything below -- the container, the id scheme, the Chart.js\n // call -- is this surface's own and legitimately differs from the others.\n const findChartMarker = window.CoreAIChatMarkers.findChartMarker;\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 = findChartMarker(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 // An image the assistant named but the server will not serve. The address is written by a language\n // model from what retrieval handed it, so a mistyped or invented one is possible, and the browser's\n // default for that is a broken-image icon captioned with the alt text -- which reads as a real picture\n // that failed to arrive. Saying plainly that it could not be loaded is both truer and quieter.\n //\n // Wired here rather than as an inline onerror attribute because message bodies go through DOMPurify,\n // which strips event-handler attributes.\n function markBrokenImagesInMessage() {\n // Scanning the document rather than one message, because the value threaded through the render\n // path is the message DATA object -- the thing carrying content, references and pending charts --\n // and not the element it was rendered into. Wiring is idempotent via the data-broken-wired mark,\n // so re-scanning after each render costs a query over the handful of images already handled.\n if (typeof document === 'undefined' || typeof requestAnimationFrame !== 'function') {\n return;\n }\n\n // Deferred for the same reason the charts below are: the render that produced these elements has\n // not necessarily been flushed to the DOM when this runs.\n requestAnimationFrame(wireBrokenImageHandlers);\n }\n\n function wireBrokenImageHandlers() {\n const images = document.querySelectorAll('.generated-image-container img:not([data-broken-wired])');\n\n for (const image of images) {\n image.setAttribute('data-broken-wired', 'true');\n image.addEventListener('error', function () {\n const container = image.closest('.generated-image-container');\n\n if (!container || container.dataset.brokenHandled) {\n return;\n }\n\n container.dataset.brokenHandled = 'true';\n container.hidden = true;\n\n const note = document.createElement('p');\n note.className = 'text-muted small fst-italic mb-2';\n note.textContent = image.alt\n ? `(the picture \"${image.alt}\" could not be loaded)`\n : '(that picture could not be loaded)';\n container.insertAdjacentElement('afterend', note);\n }, { once: true });\n }\n }\n\n function renderMessageMedia(message) {\n markBrokenImagesInMessage();\n\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., ).');\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 // A markdown table becomes a bare , which Bootstrap leaves completely unstyled: it renders\n // as cramped, borderless text that reads as plain output rather than a table. Adding the framework's\n // own classes styles it wherever Bootstrap is loaded, and the wrapper lets a wide table scroll on\n // its own instead of stretching the conversation. Markdown tables cannot nest, so the plain\n // replacement is safe.\n function styleMarkdownTables(html) {\n return html\n .replace(/
/g, '
')\n .replace(/<\\/table>/g, '
');\n }\n\n function parseMarkdownContent(content, message) {\n _pendingCharts = [];\n const html = styleMarkdownTables(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 function compactObject(source) {\n if (!source || typeof source !== 'object') {\n return {};\n }\n\n return Object.fromEntries(\n Object.entries(source).filter(([, value]) => value !== undefined)\n );\n }\n\n function resolveIndicatorTemplate(template, assistantLabel) {\n if (!template) {\n return template;\n }\n\n const encodedAssistantLabel = escapeHtmlEntities(assistantLabel || 'Assistant');\n return template.replace(/\\{\\{\\s*assistantLabel\\s*\\}\\}/g, encodedAssistantLabel);\n }\n\n const initialize = (instanceConfig) => {\n const normalizedInstanceConfig = compactObject(instanceConfig);\n const normalizedWidgetConfig = compactObject(normalizedInstanceConfig.widget);\n const config = Object.assign({}, defaultConfig, normalizedInstanceConfig);\n config.widget = Object.assign({}, defaultConfig.widget || {}, normalizedWidgetConfig);\n config.indicatorTemplate = resolveIndicatorTemplate(config.indicatorTemplate, config.assistantLabel);\n const hasWidgetConfig = !!(normalizedWidgetConfig.chatWidgetContainer && normalizedWidgetConfig.chatWidgetStateName);\n const widgetBehavior = window.coreAIChatWidgetBehavior || 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 copiedTitle: config.copiedTitle,\n isRecording: false,\n mediaRecorder: null,\n preRecordingPrompt: '',\n micButton: null,\n // Conversation mode is carried either by a realtime session or by the speech-to-text plus\n // text-to-speech cascade, never both. Dictation and spoken playback belong to the cascade.\n speechToTextEnabled: !config.realtimeEnabled && (config.chatMode === 'AudioInput' || config.chatMode === 'Conversation'),\n textToSpeechEnabled: (!config.realtimeEnabled && 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 realtimeEnabled: !!config.realtimeEnabled,\n // Server-relay WebRTC transport: primary when advertised and supported; the client falls back\n // to the WebSocket path below if the peer cannot connect.\n realtimeWebRtcEnabled: config.realtimeWebRtcEnabled === true && typeof window.RTCPeerConnection === 'function',\n // A host-supplied override. Normally the servers are fetched from the hub right before the\n // peer is created (resolveRealtimeIceServers) so configured TURN relays — and their\n // short-lived credentials — are actually used instead of a public STUN server.\n realtimeWebRtcIceServers: (Array.isArray(config.realtimeWebRtcIceServers) && config.realtimeWebRtcIceServers.length)\n ? config.realtimeWebRtcIceServers\n : null,\n realtimeVoiceName: config.realtimeVoiceName || null,\n conversationButton: null,\n realtimeHintElement: config.realtimeHintElementSelector\n ? document.querySelector(config.realtimeHintElementSelector)\n : null,\n isConversationMode: false,\n notificationDismissTimers: {},\n pendingSessionPromise: null,\n pendingSessionResolver: null,\n pendingSessionRejector: null,\n pendingSessionTimeoutId: null,\n copiedMessageIndex: -1,\n copyResetTimeoutId: null,\n activeCopyButton: 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 parsed = await readJsonResponse(response, 'Upload failed. Please try again.');\n\n if (!parsed.ok) {\n console.error('Upload failed: response was not JSON.', { status: response.status, redirected: response.redirected });\n this.uploadErrors = [{ fileName: '', error: parsed.message }];\n\n return;\n }\n\n var result = parsed.data;\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 secondParsed = await readJsonResponse(response, 'The request could not be completed.');\n\n if (!secondParsed.ok) {\n console.error('Response was not JSON.', { status: response.status, redirected: response.redirected });\n\n return;\n }\n\n var result = secondParsed.data;\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 = '
';\n html += '
';\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 += '';\n html += ' ';\n html += this.escapeHtml(name);\n html += ' ';\n html += '';\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 // The reason is shown, not hidden behind a tooltip. A pill reading \"quarterly-report-2...\"\n // tells a reader their upload failed and nothing about why, and a title attribute is\n // unreachable on a touch device -- so the one sentence that tells them what to do next\n // was the one thing the widget would not display.\n html += '';\n html += '';\n html += '';\n\n if (failedItem.fileName) {\n html += '' + this.escapeHtml(failedItem.fileName) + ': ';\n }\n\n html += this.escapeHtml(errorMsg);\n html += '';\n html += '';\n html += '';\n }\n\n if (this.isUploading) {\n html += '';\n html += ' Uploading...';\n html += '';\n }\n\n html += '';\n html += '
';\n if (config.supportedExtensionsText) {\n html += '
Supported formats: ' + this.escapeHtml(config.supportedExtensionsText) + '
';\n }\n\n html += '
';\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 // Switching to another session must not leave a prior realtime/voice session running.\n this.forceStopActiveVoice();\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 renderMessageMedia(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 // display it as the first assistant message without invoking the AI.\n if (this.messages.length === 0 && config.initialPrompt) {\n this.addMessage({\n role: 'assistant',\n content: config.initialPrompt\n });\n }\n });\n\n // Realtime lifecycle events (ReceiveRealtimeEvent, and ReceiveError while a voice session is\n // live) are handled by the shared CoreAIRealtime module — see setupRealtimeController.\n\n this.connection.on(\"ReceiveError\", (error) => {\n console.error(\"SignalR Error: \", error);\n\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // A server-side error (for example a session-start rate-limit rejection) ends the\n // in-flight request. Reject any pending new-session promise so the UI stops waiting\n // until it times out, and clear the typing indicator that a send may have shown.\n this.rejectPendingSessionRequest(error);\n this.hideTypingIndicator();\n\n if (widgetBehavior && typeof widgetBehavior.handleReceiveError === 'function') {\n widgetBehavior.handleReceiveError(this, error, config);\n } else if (!this.isNavigatingAway) {\n // Surface the message to the user instead of failing silently.\n this.addMessage(this.getErrorMessage(error));\n }\n });\n\n this.connection.on(\"ReceiveSessionStartRejected\", (reason) => {\n // A rate-limit rejection is a definitive \"wait and retry\", not a recoverable\n // session/connection error. Unblock any pending new-session request, clear the\n // typing indicator, and show the message for every host (main app and widget)\n // without triggering the widget's clear-and-retry recovery, which would wipe the\n // visitor's state and fire another throttled StartSession.\n this.rejectPendingSessionRequest(reason);\n this.hideTypingIndicator();\n\n if (!this.isNavigatingAway) {\n this.addMessage(this.getErrorMessage(reason));\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, '>');\n var html = '

' + escaped + '

';\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, turnId, text) => {\n // Realtime creates the chat session server-side; adopt its id (and update the page URL)\n // on the first turn so a refresh reloads the conversation instead of starting fresh.\n if (sessionId && this.getSessionId() !== sessionId) {\n this.initializeSession(sessionId);\n }\n\n // Realtime: a placeholder for this turn was already inserted in the right position when\n // the utterance was captured (see user_turn_pending), so just fill in its text.\n if (turnId && this._realtimePendingTurns && this._realtimePendingTurns[turnId]) {\n var pending = this._realtimePendingTurns[turnId];\n delete this._realtimePendingTurns[turnId];\n this.stopAudio();\n this.fillRealtimePendingTurn(pending, text);\n\n return;\n }\n\n if (text) {\n this.stopAudio();\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '

' + escaped + '

';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else if (this._conversationAssistantMessage) {\n // Realtime: the user's transcript lags the assistant's reply for the SAME turn (the\n // model answers the audio before speech-to-text finishes). Insert the user message\n // just before the streaming assistant message so the order stays You -> Assistant,\n // and keep that message streaming — ending it here split one reply into two bubbles\n // above the prompt.\n var at = this._conversationAssistantMessage.index;\n var userMsg = { role: 'user', content: text, rawContent: text, userRating: null, references: {} };\n updateMessagePresentation(userMsg, userMsg.references);\n this.messages.splice(at, 0, userMsg);\n this._conversationAssistantMessage.index = at + 1;\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 // A new response id means a new turn — finalize the previous assistant message so two replies\n // never merge into one bubble (also covers barge-in, which starts a fresh response).\n if (this._conversationAssistantMessage && this._conversationAssistantResponseId && responseId && this._conversationAssistantResponseId !== responseId) {\n var prev = this.messages[this._conversationAssistantMessage.index];\n if (prev) { prev.isStreaming = false; }\n this._conversationAssistantMessage = null;\n }\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 this._conversationAssistantResponseId = responseId;\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 renderMessageMedia(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 this._conversationAssistantResponseId = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (sessionId, base64Audio, contentType) => {\n if (!base64Audio) {\n return;\n }\n\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\n // Realtime audio arrives as raw PCM16 (WebSocket transport) and is scheduled for immediate\n // playback by the shared module; conversation/TTS audio (mp3/wav) is collected and played on\n // complete.\n if (contentType === 'audio/pcm') {\n if (this.realtimeController) { this.realtimeController.receivePcm(bytes); }\n } else {\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 // The realtime session lived inside the dropped connection; it cannot survive a reconnect.\n if (this.realtimeEnabled && this.isConversationMode) {\n this.stopRealtimeConversation();\n }\n });\n\n this.connection.onreconnected(() => {\n console.info(\"SignalR: reconnected.\");\n\n if (this.isSessionStarted) {\n this.reloadCurrentSession();\n }\n });\n\n this.connection.onclose((error) => {\n if (this.isNavigatingAway) {\n return;\n }\n\n if (this.realtimeEnabled && this.isConversationMode) {\n this.stopRealtimeConversation();\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 async ensureConnectionStarted() {\n if (!this.connection) {\n return false;\n }\n\n var states = signalR.HubConnectionState;\n if (this.connection.state === states.Connected) {\n return true;\n }\n\n // If the initial start failed or has not begun, start it now.\n if (this.connection.state === states.Disconnected) {\n try {\n await this.connection.start();\n } catch (err) {\n console.error(\"SignalR Connection Error: \", err);\n }\n\n return this.connection.state === states.Connected;\n }\n\n // The connection is still Connecting or Reconnecting: wait for it to settle so callers\n // (e.g. starting a realtime session) do not send before the socket is ready.\n return await new Promise((resolve) => {\n var settle = (value) => {\n clearTimeout(timeoutId);\n clearInterval(intervalId);\n resolve(value);\n };\n var timeoutId = setTimeout(() => settle(this.connection.state === states.Connected), 10000);\n var intervalId = setInterval(() => {\n if (this.connection.state === states.Connected) {\n settle(true);\n } else if (this.connection.state === states.Disconnected) {\n settle(false);\n }\n }, 100);\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(\"addingCoreAIPromotMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedCoreAIPromotMessage\", { 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 renderMessageMedia(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 // A live voice session and a typed turn are two writers into one chat session, and they\n // would interleave. End the session first; the turns it already produced are persisted, so\n // the typed message simply continues the same thread.\n this.forceStopActiveVoice();\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 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\n // Capture raw 16 kHz PCM (16-bit mono) via Web Audio instead of MediaRecorder.\n // Browsers only agree on WebM/Opus for MediaRecorder, and Azure's speech SDK cannot\n // demux that container from a streaming push (it fails inside GStreamer). Raw PCM is\n // decoded natively with no GStreamer and is produced identically by every browser.\n this._sttCapture = this._createPcmCapture(stream, (base64) => {\n try { subject.next(base64); } catch (err) { /* completed */ }\n });\n this._sttSubject = subject;\n\n var rate = (this._sttCapture && this._sttCapture.sampleRate) || 16000;\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"SendAudioStream\", profileId, sessionId, subject, \"audio/pcm;rate=\" + rate, language);\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) {\n return;\n }\n\n this._stopPcmCapture(this._sttCapture);\n this._sttCapture = null;\n if (this._sttSubject) {\n try { this._sttSubject.complete(); } catch (err) { /* already completed */ }\n this._sttSubject = null;\n }\n this.isRecording = false;\n this.updateMicButton();\n },\n // Captures microphone audio as raw 16 kHz, 16-bit mono PCM using Web Audio and invokes\n // onChunk(base64Pcm, rms) for each block. Returns a handle for _stopPcmCapture. This replaces\n // MediaRecorder so every browser streams a format Azure decodes without GStreamer.\n _createPcmCapture(stream, onChunk) {\n var AudioCtx = window.AudioContext || window.webkitAudioContext;\n // Ask the browser to resample the mic to 16 kHz; fall back to manual resampling if it will not.\n var audioContext;\n try {\n audioContext = new AudioCtx({ sampleRate: 16000 });\n } catch (e) {\n audioContext = new AudioCtx();\n }\n var srcRate = audioContext.sampleRate;\n var source = audioContext.createMediaStreamSource(stream);\n var processor = audioContext.createScriptProcessor(4096, 1, 1);\n var self = this;\n processor.onaudioprocess = function (e) {\n var input = e.inputBuffer.getChannelData(0);\n var pcm16 = self._downsampleToInt16(input, srcRate, 16000);\n if (!pcm16 || pcm16.length === 0) {\n return;\n }\n var sum = 0;\n for (var i = 0; i < pcm16.length; i++) {\n var v = pcm16[i] / 32768;\n sum += v * v;\n }\n var rms = Math.sqrt(sum / pcm16.length);\n var bytes = new Uint8Array(pcm16.buffer);\n var binary = '';\n for (var j = 0; j < bytes.length; j++) {\n binary += String.fromCharCode(bytes[j]);\n }\n onChunk(btoa(binary), rms);\n };\n source.connect(processor);\n // Some browsers only fire onaudioprocess while the node is connected to a destination.\n processor.connect(audioContext.destination);\n return { audioContext: audioContext, source: source, processor: processor, stream: stream, sampleRate: 16000 };\n },\n _stopPcmCapture(capture) {\n if (!capture) {\n return;\n }\n try { if (capture.processor) { capture.processor.onaudioprocess = null; capture.processor.disconnect(); } } catch (e) { }\n try { if (capture.source) { capture.source.disconnect(); } } catch (e) { }\n try { if (capture.stream) { capture.stream.getTracks().forEach(function (t) { t.stop(); }); } } catch (e) { }\n try { if (capture.audioContext) { capture.audioContext.close(); } } catch (e) { }\n },\n // Converts a Float32 sample block to 16-bit PCM, resampling from srcRate to dstRate when needed.\n _downsampleToInt16(input, srcRate, dstRate) {\n var s, i;\n if (!(dstRate < srcRate)) {\n var same = new Int16Array(input.length);\n for (i = 0; i < input.length; i++) {\n s = Math.max(-1, Math.min(1, input[i]));\n same[i] = s < 0 ? s * 0x8000 : s * 0x7FFF;\n }\n return same;\n }\n var ratio = srcRate / dstRate;\n var newLen = Math.floor(input.length / ratio);\n var out = new Int16Array(newLen);\n for (var j = 0; j < newLen; j++) {\n var idx = j * ratio;\n var i0 = Math.floor(idx);\n var i1 = (i0 + 1 < input.length) ? i0 + 1 : input.length - 1;\n var frac = idx - i0;\n s = input[i0] * (1 - frac) + input[i1] * frac;\n s = Math.max(-1, Math.min(1, s));\n out[j] = s < 0 ? s * 0x8000 : s * 0x7FFF;\n }\n return out;\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 = '';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '';\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 renderMessageMedia(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 getErrorMessage(error) {\n var content = (typeof error === 'string' && error.trim())\n ? error\n : \"Something went wrong. Please try again.\";\n\n return {\n role: \"assistant\",\n content: content,\n htmlContent: \"\",\n };\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 renderMessageMedia(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\n button.classList.toggle('tts-playing', isPlaying);\n button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');\n });\n },\n updateCopyButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-copy-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-copy-message-index'));\n var isCopied = buttonIndex === this.copiedMessageIndex;\n var iconHtml = isCopied\n ? ''\n : '';\n\n button.classList.toggle('text-success', isCopied);\n button.classList.toggle('text-secondary', !isCopied);\n button.setAttribute('title', isCopied ? this.copiedTitle : this.copyTitle);\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\n });\n },\n setCopyButtonState(button, isCopied) {\n if (!button) {\n return;\n }\n\n var iconHtml = isCopied\n ? ''\n : '';\n\n button.classList.toggle('text-success', isCopied);\n button.classList.toggle('text-secondary', !isCopied);\n button.setAttribute('title', isCopied ? this.copiedTitle : this.copyTitle);\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\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 // A live voice session takes the message box away and puts the audio settings in its place; ending\n // the session gives it back. Sending a typed message already force-stopped the session, so the box\n // was never a way to say something *during* one -- hiding it only makes that honest, and frees the\n // row for the gear. Both transports land here: realtime through the module's onActivate, the\n // speech-to-text cascade through startConversationMode.\n // The realtime module inserts its settings popover directly after the button it was handed, and\n // hard-codes the element id. A page can host two chat clients at once -- this one and the admin\n // widget -- so that id is not unique and getElementById would hand the widget the page's gear.\n // Each client finds its own next to its own button.\n voiceSettingsElement() {\n var next = this.conversationButton && this.conversationButton.nextElementSibling;\n\n return next && next.id === 'realtime-audio-settings' ? next : null;\n },\n setVoiceSessionLive(live) {\n if (this.inputElement) {\n this.inputElement.hidden = live;\n }\n\n if (this.buttonElement) {\n this.buttonElement.hidden = live;\n }\n\n // With the message box gone the button would otherwise sit at its natural width in an empty\n // row, so it takes the space the box left behind and reads as the thing now in charge. The\n // settings popover does not grow, so it stays at the right-hand end.\n if (this.conversationButton) {\n this.conversationButton.classList.toggle('flex-grow-1', live);\n }\n\n // The gear is built by the realtime module next to its button, and only in realtime mode, so\n // it is absent on the cascade. It belongs to a live session rather than to the surface.\n var audioSettings = this.voiceSettingsElement();\n if (audioSettings) {\n audioSettings.hidden = !live;\n }\n\n var hint = this.realtimeHintElement;\n if (hint) {\n hint.classList.toggle('d-none', !live);\n }\n },\n toggleConversationMode() {\n if (this.realtimeEnabled) {\n // Realtime is driven by the shared module, which owns the button; this only exists for\n // callers that toggle programmatically.\n if (this.realtimeController) { this.realtimeController.toggle(); }\n\n return;\n }\n\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n // Force-stop any in-progress voice/realtime session (mic, playback, and the streamed audio),\n // e.g. before starting a new chat or switching sessions, so it never keeps running in the background.\n forceStopActiveVoice() {\n if (!this.isConversationMode) {\n return;\n }\n if (this.realtimeEnabled) {\n this.stopRealtimeConversation();\n } else {\n this.stopConversationMode();\n }\n },\n startRealtimeConversation() {\n if (this.realtimeController) { this.realtimeController.start(); }\n },\n stopRealtimeConversation() {\n if (this.realtimeController) { this.realtimeController.stop(); }\n },\n // Realtime (speech-to-speech) is the shared CoreAIRealtime module (realtime-audio.js): microphone\n // capture and gating, the WebRTC transport with its WebSocket fallback, playback, the settings\n // popover, push-to-talk, and the server-driven session lifecycle all live there, so this app and the\n // chat-interaction client cannot drift apart. What is wired here is only how the module reaches this\n // app's hub and transcript.\n setupRealtimeController(config) {\n if (this.realtimeController || !this.conversationButton) { return; }\n if (!window.CoreAIRealtime || typeof window.CoreAIRealtime.attach !== 'function') {\n console.error('realtime-audio.js is not loaded; realtime voice is unavailable on this page.');\n\n return;\n }\n\n var self = this;\n this.realtimeController = window.CoreAIRealtime.attach({\n connection: this.connection,\n ensureConnected: function () {\n return self.ensureConnectionStarted().then(function (connected) {\n if (!connected) { throw new Error('The chat connection is not available.'); }\n\n return connected;\n });\n },\n sendStart: function (subject, voice, language, silenceMs, vadThreshold, allowInterruption) {\n self.connection.send('StartRealtimeConversation', self.getProfileId(), self.getSessionId() || '', subject, voice, language, silenceMs, vadThreshold, allowInterruption);\n },\n webRtcEnabled: this.realtimeWebRtcEnabled,\n sendStartWebRtc: function (offerSdp, voice, language, silenceMs, vadThreshold, allowInterruption) {\n self.connection.send('StartRealtimeWebRtc', self.getProfileId(), self.getSessionId() || '', offerSdp, voice, language, silenceMs, vadThreshold, allowInterruption);\n },\n webRtcIceServers: this.realtimeWebRtcIceServers || undefined,\n voiceName: this.realtimeVoiceName || '',\n getVoiceName: function () { return self.realtimeVoiceName || ''; },\n realtimeEnabled: true,\n // The conversation button doubles as the realtime button on this host; the module owns its\n // click, label and state from here on.\n //\n // input and sendButton are deliberately not handed over. The module hides every control it\n // is given when realtime takes over, and typing has to stay available during a voice\n // conversation -- that is the whole feature.\n //\n // conversationButton is not handed over either. It is the same element as the realtime\n // button here, and the module hides the conversation button before showing the realtime\n // one -- naming it twice would ask it to hide the control it then has to show.\n selectors: {\n realtimeButton: config.conversationButtonElementSelector,\n micButton: config.micButtonElementSelector\n },\n // The module owns whether a session is live, so the message box follows its flag rather\n // than this app's copy of it. Losing one of these events used to leave the box hidden\n // under a button that had already gone back to \"Start speaking\".\n onSessionStateChanged: function (active) {\n self.setVoiceSessionLive(active);\n },\n onActivate: function () {\n self.isConversationMode = true;\n self._conversationAssistantMessage = null;\n self._conversationPartialMessage = null;\n self.removeNotification('conversation-ended');\n },\n onDeactivate: function () {\n self.isConversationMode = false;\n self.finishRealtimeConversationCleanup();\n },\n onUserTurnPending: function (turnId) { self.addRealtimePendingTurn(turnId); },\n onUserTurnDropped: function (turnId) { self.dropRealtimePendingTurn(turnId); }\n });\n },\n // Shared teardown tail: clears any in-flight streaming state and shows the conversation-ended\n // notification.\n finishRealtimeConversationCleanup() {\n if (this._conversationAssistantMessage) {\n var m = this.messages[this._conversationAssistantMessage.index];\n if (m) { m.isStreaming = false; }\n this._conversationAssistantMessage = null;\n }\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) { this.messages[i].isStreaming = false; }\n }\n\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 // The utterance has been captured but not transcribed yet. Showing a placeholder now puts the\n // prompt above the reply it produces: transcription lags the spoken answer, so a bubble added only\n // when the text arrives lands underneath its own reply.\n addRealtimePendingTurn(turnId) {\n if (!turnId) { return; }\n this._realtimePendingTurns = this._realtimePendingTurns || {};\n var index = this.messages.length;\n this.addMessage({ role: 'user', content: '', isPartial: true });\n this._realtimePendingTurns[turnId] = this.messages[index];\n },\n fillRealtimePendingTurn(pending, text) {\n if (!pending) { return; }\n if (!text) {\n var emptyAt = this.messages.indexOf(pending);\n if (emptyAt >= 0) { this.messages.splice(emptyAt, 1); }\n\n return;\n }\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n pending.content = text;\n pending.htmlContent = '

' + escaped + '

';\n pending.isPartial = false;\n },\n dropRealtimePendingTurn(turnId) {\n if (!turnId || !this._realtimePendingTurns) { return; }\n var dropped = this._realtimePendingTurns[turnId];\n if (!dropped) { return; }\n delete this._realtimePendingTurns[turnId];\n var at = this.messages.indexOf(dropped);\n if (at >= 0) { this.messages.splice(at, 1); }\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 this._conversationSubject = new signalR.Subject();\n this._conversationStream = stream;\n\n // RMS (0..1) above which speech during TTS playback counts as an interrupt.\n var interruptRmsThreshold = 0.12;\n\n // Capture raw 16 kHz PCM (16-bit mono) via Web Audio instead of MediaRecorder — see\n // startRecording for why WebM/Opus is avoided. The per-block RMS drives interrupt\n // detection during TTS playback, replacing the previous AnalyserNode.\n this._conversationCapture = this._createPcmCapture(stream, (base64, rms) => {\n if (this.isPlayingAudio && rms >= interruptRmsThreshold) {\n // User is speaking over TTS — interrupt playback.\n this.stopAudio();\n }\n try {\n this._conversationSubject.next(base64);\n } catch (err) {\n // Subject may have been completed already.\n }\n });\n\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var language = navigator.language || document.documentElement.lang || 'en-US';\n var rate = (this._conversationCapture && this._conversationCapture.sampleRate) || 16000;\n\n this.connection.send(\"StartConversation\", profileId, sessionId, this._conversationSubject, \"audio/pcm;rate=\" + rate, language);\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) {\n this._stopPcmCapture(this._conversationCapture);\n this._conversationCapture = null;\n if (this._conversationSubject) {\n try { this._conversationSubject.complete(); } catch (err) { /* already completed */ }\n }\n this.isRecording = false;\n }\n\n this.stopAudio();\n this._conversationPartialTranscript = '';\n this._conversationPartialMessage = null;\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 // Force-stop an in-progress voice/realtime conversation so it doesn't keep running under the new session.\n this.forceStopActiveVoice();\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\n // When an initial prompt is configured, show it as the first\n // assistant message instead of the generic placeholder.\n if (config.initialPrompt) {\n this.addMessage({\n role: 'assistant',\n content: config.initialPrompt\n });\n } else {\n this.showPlaceholder();\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 // Force-stop any live voice/realtime session before starting a new chat.\n this.forceStopActiveVoice();\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 }\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 const initialMessages = Array.isArray(config.messages) ? config.messages : [];\n\n for (let i = 0; i < initialMessages.length; i++) {\n this.addMessage(initialMessages[i]);\n }\n\n // When no messages were loaded and an initial prompt is configured,\n // display it as the first assistant message without invoking the AI.\n if (this.messages.length === 0 && config.initialPrompt) {\n this.addMessage({\n role: 'assistant',\n content: config.initialPrompt\n });\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 = ' ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '';\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 (used for both STT/TTS conversation and realtime).\n if ((this.conversationModeEnabled || this.realtimeEnabled) && config.conversationButtonElementSelector) {\n this.conversationButton = document.querySelector(config.conversationButtonElementSelector);\n if (this.conversationButton) {\n if (this.realtimeEnabled) {\n // The shared realtime module owns the button (click, label, state) and adds the\n // voice settings popover next to it.\n this.setupRealtimeController(config);\n\n // The module reveals the gear as soon as the surface enters realtime mode, but it\n // belongs to a live session. The watcher that would hide it only runs on a change,\n // so the idle state has to be stated once here.\n this.setVoiceSessionLive(false);\n } else {\n this.conversationButton.addEventListener('click', () => {\n this.toggleConversationMode();\n });\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(\"initializingSessionCoreAIChat\", { 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 // For non-widget pages, update the browser URL so that a page\n // refresh reloads the correct session instead of starting fresh.\n if (!hasWidgetConfig && sessionId && config.sessionUrlTemplate && typeof history !== 'undefined' && history.replaceState) {\n var sessionUrl = config.sessionUrlTemplate.replace('{sessionId}', encodeURIComponent(sessionId));\n history.replaceState(null, '', sessionUrl);\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 clearCopiedMessageState() {\n if (this.copyResetTimeoutId) {\n window.clearTimeout(this.copyResetTimeoutId);\n this.copyResetTimeoutId = null;\n }\n\n if (this.activeCopyButton) {\n this.setCopyButtonState(this.activeCopyButton, false);\n this.activeCopyButton = null;\n }\n\n this.copiedMessageIndex = -1;\n },\n copyResponse(message, index, event) {\n const text = message && typeof message === 'object'\n ? message.copyContent ?? message.content ?? ''\n : message ?? '';\n const button = event?.currentTarget || event?.target?.closest?.('[data-copy-message-index]') || null;\n\n navigator.clipboard.writeText(text)\n .then(() => {\n this.clearCopiedMessageState();\n this.copiedMessageIndex = typeof index === 'number' ? index : -1;\n this.activeCopyButton = button;\n\n if (button) {\n this.setCopyButtonState(button, true);\n } else {\n this.$nextTick(() => this.updateCopyButtons());\n }\n\n this.copyResetTimeoutId = window.setTimeout(() => {\n this.clearCopiedMessageState();\n this.$nextTick(() => this.updateCopyButtons());\n }, Number(config.copyResetDelayMs) || 2000);\n })\n .catch(err => console.error('Failed to copy response:', err));\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 copiedMessageIndex() {\n this.$nextTick(() => this.updateCopyButtons());\n },\n isConversationMode(active) {\n // The dictation microphone is hidden while a voice conversation runs: the conversation\n // already owns the microphone, and a second one would mean something different.\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n // The message box and the send button give way to the voice settings while the conversation\n // runs, and come back when it ends. Both kinds of turn still land in the same thread; what\n // they cannot do is overlap.\n //\n // Only the cascade is driven from here. Realtime follows the module's own session flag\n // (onSessionStateChanged), so the two never disagree about whether a session is live.\n if (!this.realtimeEnabled) {\n this.setVoiceSessionLive(active);\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 this.$nextTick(() => {\n this.updateCopyButtons();\n refreshFontAwesomeIcons(this.$el);\n this.fontAwesomeObserver = observeFontAwesomeIcons(this.$el);\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 if (this.fontAwesomeObserver) {\n this.fontAwesomeObserver.disconnect();\n this.fontAwesomeObserver = null;\n }\n\n this.clearCopiedMessageState();\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 const autoInitializeSelector = '[data-coreai-chat-config],[data-coreai-chat-app-element-selector]';\n\n function getAttributeValue(element, attributeName) {\n const value = element.getAttribute(attributeName);\n return value === null || value === '' ? null : value;\n }\n\n function parseBooleanAttributeValue(value) {\n if (value === null || value === undefined) {\n return null;\n }\n\n if (typeof value === 'boolean') {\n return value;\n }\n\n const normalized = String(value).trim().toLowerCase();\n if (normalized === 'true') {\n return true;\n }\n\n if (normalized === 'false') {\n return false;\n }\n\n return null;\n }\n\n function parseJsonAttribute(element, attributeName, description) {\n const rawValue = getAttributeValue(element, attributeName);\n if (!rawValue) {\n return null;\n }\n\n try {\n return JSON.parse(rawValue);\n } catch (error) {\n console.error('Failed to parse ' + description + ' JSON.', error);\n return null;\n }\n }\n\n function buildConfigFromDataAttributes(element, options) {\n const settings = options || {};\n\n if (element.hasAttribute('data-coreai-chat-widget-container-selector') && settings.allowWidgetHost !== true) {\n return null;\n }\n\n const appElementSelector = getAttributeValue(element, 'data-coreai-chat-app-element-selector');\n if (!appElementSelector) {\n return null;\n }\n\n const config = {\n signalRHubUrl: getAttributeValue(element, 'data-coreai-chat-signalr-hub-url'),\n appElementSelector: appElementSelector,\n chatContainerElementSelector: getAttributeValue(element, 'data-coreai-chat-container-element-selector'),\n inputElementSelector: getAttributeValue(element, 'data-coreai-chat-input-element-selector'),\n sendButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-send-button-element-selector'),\n placeholderElementSelector: getAttributeValue(element, 'data-coreai-chat-placeholder-element-selector'),\n messages: parseJsonAttribute(element, 'data-coreai-chat-messages', 'CoreAI chat messages') ?? undefined,\n chatMode: getAttributeValue(element, 'data-coreai-chat-mode'),\n micButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-mic-button-element-selector'),\n conversationButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-conversation-button-element-selector'),\n realtimeHintElementSelector: getAttributeValue(element, 'data-coreai-chat-realtime-hint-element-selector'),\n ttsVoiceName: getAttributeValue(element, 'data-coreai-chat-tts-voice-name'),\n realtimeVoiceName: getAttributeValue(element, 'data-coreai-chat-realtime-voice-name'),\n documentBarSelector: getAttributeValue(element, 'data-coreai-chat-document-bar-selector'),\n uploadDocumentUrl: getAttributeValue(element, 'data-coreai-chat-upload-document-url'),\n removeDocumentUrl: getAttributeValue(element, 'data-coreai-chat-remove-document-url'),\n allowedExtensions: getAttributeValue(element, 'data-coreai-chat-allowed-extensions'),\n supportedExtensionsText: getAttributeValue(element, 'data-coreai-chat-supported-extensions-text'),\n existingDocuments: parseJsonAttribute(element, 'data-coreai-chat-existing-documents', 'CoreAI chat existing documents') ?? undefined,\n initialPrompt: getAttributeValue(element, 'data-coreai-chat-initial-prompt'),\n sessionUrlTemplate: getAttributeValue(element, 'data-coreai-chat-session-url-template'),\n userLabel: getAttributeValue(element, 'data-coreai-chat-user-label'),\n assistantLabel: getAttributeValue(element, 'data-coreai-chat-assistant-label'),\n copyTitle: getAttributeValue(element, 'data-coreai-chat-copy-title'),\n copiedTitle: getAttributeValue(element, 'data-coreai-chat-copied-title'),\n };\n\n const booleanAttributes = {\n metricsEnabled: 'data-coreai-chat-metrics-enabled',\n textToSpeechEnabled: 'data-coreai-chat-text-to-speech-enabled',\n sessionDocumentsEnabled: 'data-coreai-chat-session-documents-enabled',\n singleResponseMode: 'data-coreai-chat-single-response-mode',\n realtimeEnabled: 'data-coreai-chat-realtime-enabled',\n realtimeWebRtcEnabled: 'data-coreai-chat-realtime-webrtc-enabled',\n };\n\n Object.keys(booleanAttributes).forEach(key => {\n const parsed = parseBooleanAttributeValue(getAttributeValue(element, booleanAttributes[key]));\n if (parsed !== null) {\n config[key] = parsed;\n }\n });\n\n return compactObject(config);\n }\n\n function buildConfigFromElement(element, options) {\n const jsonConfig = parseJsonAttribute(element, 'data-coreai-chat-config', 'CoreAI chat config');\n const attributeConfig = buildConfigFromDataAttributes(element, options);\n\n if (!jsonConfig && !attributeConfig) {\n return null;\n }\n\n return Object.assign({}, jsonConfig || {}, attributeConfig || {});\n }\n\n function initializeFromElement(element) {\n if (!element || element.dataset.coreAiChatInitialized === 'true') {\n return element ? element.__coreAIChatApp || null : null;\n }\n\n const config = buildConfigFromElement(element);\n if (!config) {\n return null;\n }\n\n const app = initialize(config);\n if (!app) {\n return null;\n }\n\n element.dataset.coreAiChatInitialized = 'true';\n element.__coreAIChatApp = app;\n\n return app;\n }\n\n function scanForAutoInitialization(root) {\n if (!root || typeof root.querySelectorAll !== 'function') {\n return;\n }\n\n if (typeof root.matches === 'function' && root.matches(autoInitializeSelector)) {\n initializeFromElement(root);\n }\n\n root.querySelectorAll(autoInitializeSelector).forEach(initializeFromElement);\n }\n\n function startAutoInitialization() {\n scanForAutoInitialization(document);\n\n if (typeof MutationObserver === 'undefined') {\n return;\n }\n\n const observer = new MutationObserver(mutations => {\n mutations.forEach(mutation => {\n mutation.addedNodes.forEach(node => {\n if (node && node.nodeType === 1) {\n scanForAutoInitialization(node);\n }\n });\n });\n });\n\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n });\n }\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', startAutoInitialization, { once: true });\n } else {\n startAutoInitialization();\n }\n\n return {\n initialize: initialize,\n initializeFromElement: initializeFromElement,\n buildConfigFromElement: buildConfigFromElement,\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 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"]} +{"version":3,"sources":["ai-chat.js"],"names":["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","setPrototypeOf","__proto__","displayName","_regenerator","w","m","defineProperty","_regeneratorDefine","_invoke","enumerable","configurable","writable","_toConsumableArray","_arrayWithoutHoles","_iterableToArray","_unsupportedIterableToArray","_nonIterableSpread","Array","from","isArray","_arrayLikeToArray","_objectWithoutProperties","_objectWithoutPropertiesLoose","getOwnPropertySymbols","indexOf","propertyIsEnumerable","hasOwnProperty","_createForOfIteratorHelper","_n","F","s","next","asyncGeneratorStep","Promise","resolve","then","_asyncToGenerator","arguments","apply","_next","_throw","_slicedToArray","_arrayWithHoles","_iterableToArrayLimit","_nonIterableRest","toString","slice","constructor","name","test","push","_typeof","window","coreAIChatManager","_window$CoreAIChatMar","_window$CoreAIChatMar2","_window$CoreAIChatMar3","_window$CoreAIChatMar4","_window$CoreAIChatMar5","_window$CoreAIChatMar6","_window$CoreAIChatMar7","_window$CoreAIChatMar8","_window$CoreAIChatMar9","_window$CoreAIChatMar0","defaultConfig","generatedImageAltText","generatedImageMaxWidth","downloadImageTitle","downloadChartTitle","downloadChartButtonText","userLabel","assistantLabel","thumbsUpTitle","thumbsDownTitle","copyTitle","copiedTitle","codeCopiedText","copyResetDelayMs","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","containsFontAwesomePlaceholders","root","nodeType","selector","matches","querySelector","refreshFontAwesomeIcons","fontAwesome","FontAwesome","dom","i2svg","node","observeFontAwesomeIcons","MutationObserver","observer","mutations","forEach","mutation","addedNodes","observe","childList","subtree","parsePixelValue","Number","isFinite","parsed","parseFloat","clamp","min","max","Math","normalizeReference","reference","_ref","_normalized$index","_ref2","_normalized$text","_ref3","_normalized$title","_ref4","_normalized$link","_ref5","_normalized$reference","_normalized$isGenerat","_normalized$isImage","normalized","assign","index","Index","Text","title","Title","link","Link","referenceType","ReferenceType","isGenerated","IsGenerated","isImage","IsImage","isDownloadCitationReference","toLowerCase","normalizeReferences","references","_i","_Object$entries","entries","_normalizeReference","_Object$entries$_i","key","readJsonResponse","_x","_x2","_readJsonResponse","_callee0","response","fallbackMessage","contentType","message","_t6","_t7","_context0","headers","get","redirected","ok","data","json","expandImageMarkers","CoreAIChatMarkers","getCitationLabel","unmergedCitationCount","citationIdentity","concat","splitCombinedCitations","content","collapseRepeatedCitations","html","separateAdjacentCitations","citationMarkerHtml","displayIndex","buildCitationDisplay","processedContent","messageReferences","referenceEntries","citations","citedRefs","filter","_ref6","_ref7","includes","generatedRefs","_ref8","_ref9","sort","_ref0","_ref1","_ref10","_ref11","b","_ref12","_ref13","_ref14","_ref15","citationsByIdentity","Map","placeholders","_iterator","_step","_step$value","label","identity","citation","referenceKey","referenceKeys","isDownload","set","placeholder","replaceAll","err","_i2","_placeholders","entry","_iterator2","_step2","_step2$value","map","_ref16","_excluded","buildCopyContent","copyContent","_iterator3","_step3","_citation$referenceKe","_iterator5","_step5","_iterator4","_step4","trimEnd","updateMessagePresentation","rawContent","displayContent","citationDisplay","citationReferences","htmlContent","parseMarkdownContent","renderer","marked","Renderer","href","code","lang","highlighted","hljs","getLanguage","highlight","language","_","highlightAuto","langDisplay","image","src","alt","maxWidth","chartCounter","_pendingCharts","__chartConfigs","createChartHtml","chartId","findChartMarker","use","extensions","level","start","idx","undefined","tokenizer","extracted","startIndex","type","raw","substring","endIndex","token","config","markBrokenImagesInMessage","requestAnimationFrame","wireBrokenImageHandlers","wireImageZoom","mediumZoom","images","querySelectorAll","_iterator6","_step6","setAttribute","margin","background","_iterator7","_step7","_loop","addEventListener","container","closest","dataset","brokenHandled","hidden","note","className","insertAdjacentElement","once","renderMessageMedia","charts","_iterator8","_step8","renderChartOnCanvas","canvas","getElementById","Chart","console","warn","offsetParent","_cfg$options","_cfg$options2","_cfg$options2$aspectR","_chartInstance","destroy","cfg","JSON","parse","options","responsive","maintainAspectRatio","aspectRatio","error","renderPendingCharts","configs","_i3","_Object$keys","keys","styleMarkdownTables","replace","DOMPurify","sanitize","ADD_TAGS","ADD_ATTR","compactObject","source","fromEntries","_ref17","_ref18","resolveIndicatorTemplate","template","encodedAssistantLabel","initialize","instanceConfig","normalizedInstanceConfig","normalizedWidgetConfig","hasWidgetConfig","widgetBehavior","coreAIChatWidgetBehavior","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","realtimeEnabled","chatMode","textToSpeechEnabled","ttsVoiceName","audioChunks","audioPlayQueue","isPlayingAudio","currentAudioElement","currentAudioUrl","ttsButton","ttsPlayingMessageIndex","ttsAudioCache","ttsInstanceId","random","singleResponseMode","conversationModeEnabled","realtimeWebRtcEnabled","RTCPeerConnection","realtimeWebRtcIceServers","realtimeVoiceName","conversationButton","realtimeHintElement","realtimeHintElementSelector","isConversationMode","notificationDismissTimers","pendingSessionPromise","pendingSessionResolver","pendingSessionRejector","pendingSessionTimeoutId","copiedMessageIndex","copyResetTimeoutId","activeCopyButton","computed","lastAssistantIndex","role","methods","handleBeforeUnload","handleDragOver","sessionDocumentsEnabled","preventDefault","stopPropagation","inputArea","classList","add","handleDragLeave","remove","handleDrop","dataTransfer","files","uploadFiles","triggerFileInput","fileInput","click","handleFileInputChange","target","queueDocumentOperation","operation","self","previousOperation","nextOperation","_callee","_context","_this","_callee3","filesToUpload","_context3","uploadDocumentUrl","_callee2","sessionId","profileId","formData","errorText","uploadError","result","_t","_t2","_context2","getSessionId","getProfileId","ensureSessionForDocuments","fileName","renderDocumentBar","FormData","append","fetch","method","body","extractReadableErrorMessage","status","initializeSession","uploaded","failed","reloadCurrentSession","removeDocument","doc","_this2","_callee5","_context5","removeDocumentUrl","_callee4","secondParsed","removeError","_t3","_context4","stringify","itemId","documentId","splice","formatFileSize","bytes","toFixed","escapeHtml","failedItem","failedName","errorMsg","supportedExtensionsText","replaceChildren","RETURN_DOM_FRAGMENT","closeButtons","j","docToRemove","parseInt","getAttribute","errorCloseButtons","addBtn","div","startsWith","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","forceStopActiveVoice","msg","addMessage","$nextTick","refreshAllFeedbackIcons","initialPrompt","stopRecording","rejectPendingSessionRequest","hideTypingIndicator","handleReceiveError","getErrorMessage","reason","messageId","userRating","find","id","isFinal","_conversationPartialTranscript","escaped","_conversationPartialMessage","hidePlaceholder","isPartial","scrollToBottom","_audioInputSent","dispatchEvent","Event","turnId","_realtimePendingTurns","pending","stopAudio","fillRealtimePendingTurn","_conversationAssistantMessage","at","userMsg","responseId","_conversationAssistantResponseId","prev","msgIndex","newMessage","base64Audio","binaryString","atob","Uint8Array","charCodeAt","realtimeController","receivePcm","playCollectedAudio","notification","receiveNotification","updateNotification","notificationType","removeNotification","onreconnecting","stopRealtimeConversation","onreconnected","info","onclose","ensureConnectionStarted","_this4","_callee7","states","_t5","_context7","HubConnectionState","state","Connected","Disconnected","settle","clearTimeout","timeoutId","clearInterval","intervalId","setTimeout","setInterval","addMessageInternal","_this5","fireEvent","CustomEvent","_this6","_message$rawContent","addMessages","_this7","showPlaceholder","isOrchestratorAvailable","applyOrchestratorAvailability","unavailableMessage","orchestratorUnavailableMessage","disabled","micButtonElement","style","display","conversationButtonElement","event","isIndicator","sendMessage","trimmedPrompt","streamMessage","startRecording","_this8","navigator","mediaDevices","getUserMedia","audio","echoCancellation","noiseSuppression","autoGainControl","subject","Subject","_sttCapture","_createPcmCapture","base64","_sttSubject","rate","sampleRate","documentElement","send","updateMicButton","_stopPcmCapture","complete","onChunk","AudioCtx","AudioContext","webkitAudioContext","audioContext","srcRate","createMediaStreamSource","processor","createScriptProcessor","onaudioprocess","input","inputBuffer","getChannelData","pcm16","_downsampleToInt16","sum","rms","sqrt","buffer","binary","String","fromCharCode","btoa","connect","destination","capture","disconnect","getTracks","stop","close","dstRate","same","Int16Array","ratio","newLen","floor","out","i0","i1","frac","toggleRecording","sessionProfileId","_this9","dispose","streamingStarted","showTypingIndicator","lastResponseId","messageIndex","currentSessionId","subscribe","chunk","_i4","_Object$entries2","_normalizeReference2","_Object$entries2$_i","_this9$stream","processReferences","streamingFinished","synthesizeSpeech","_this9$stream2","getServiceDownMessage","_this0","_ref22","_message$rawContent2","stopIcon","startIcon","removeAttribute","focus","icons","handleExternalTtsStop","_e$detail","sourceId","updateTtsPlaybackButtons","_this1","buttons","button","buttonIndex","isPlaying","toggle","updateCopyButtons","_this10","isCopied","iconHtml","setCopyButtonState","cacheIndex","_this11","_ttsCacheIndex","invoke","toggleMessageTts","_this12","playAudioBlob","_this13","totalLength","reduce","combined","offset","_iterator9","_step9","blob","Blob","_this14","URL","createObjectURL","Audio","revokeObjectURL","playNextInQueue","play","_this15","nextBlob","shift","conversationModeOnAudioEnded","_this16","pause","currentTime","voiceSettingsElement","nextElementSibling","setVoiceSessionLive","live","audioSettings","hint","toggleConversationMode","stopConversationMode","startConversationMode","startRealtimeConversation","setupRealtimeController","CoreAIRealtime","attach","ensureConnected","connected","Error","sendStart","voice","silenceMs","vadThreshold","allowInterruption","webRtcEnabled","sendStartWebRtc","offerSdp","webRtcIceServers","voiceName","getVoiceName","selectors","realtimeButton","conversationButtonElementSelector","micButtonElementSelector","onSessionStateChanged","active","onActivate","onDeactivate","finishRealtimeConversationCleanup","onUserTurnPending","addRealtimePendingTurn","onUserTurnDropped","dropRealtimePendingTurn","dismissible","autoDismissMs","emptyAt","dropped","_this17","updateConversationButton","_conversationSubject","_conversationStream","interruptRmsThreshold","_conversationCapture","endHtml","blur","startHtml","conversationModeSendPrompt","generatePrompt","element","templateProfileId","createSessionUrl","baseUrl","param","fullUrl","location","origin","searchParams","originalLength","removedCount","_this18","clearNotificationDismiss","existingIndex","findIndex","scheduleNotificationDismiss","_this19","timerId","dismissNotification","handleNotificationAction","actionName","_this20","scrollTop","scrollHeight","clientHeight","handleUserInput","setSessionId","resetSession","sessionRating","onSessionReset","startNewSession","requestNewSession","_this21","_callee8","_context8","_this22","reject","resolvePendingSessionRequest","clearPendingSessionRequest","initializeApp","_this23","placeholderElementSelector","loadSession","documentBarSelector","multiple","allowedExtensions","accept","parentElement","appendChild","threshold","atBottom","shiftKey","lastMsg","pop","promptGenerators","getElementsByClassName","chatSessions","showChatScreen","initialMessages","btn","block","codeEl","clipboard","writeText","copiedText","force","onSessionInitialized","sessionUrlTemplate","history","replaceState","sessionUrl","encodeURIComponent","resolveSessionId","clearCopiedMessageState","copyResponse","_ref23","_message$copyContent","_event$target","_event$target$closest","_this24","currentTarget","updateFeedbackIcons","upBtn","downBtn","upClass","upIcon","fontSize","downClass","downIcon","containers","$el","msgId","rateMessage","isPositive","newRating","feedbackContainer","btnClass","offsetWidth","onEnd","removeEventListener","watch","handler","onDocumentsChanged","deep","_this25","mounted","_this26","_callee9","isInitialized","_context9","onMounted","fontAwesomeObserver","beforeUnmount","onBeforeUnmount","app","Vue","createApp","mount","autoInitializeSelector","getAttributeValue","attributeName","parseBooleanAttributeValue","parseJsonAttribute","description","rawValue","buildConfigFromDataAttributes","_parseJsonAttribute","_parseJsonAttribute2","settings","hasAttribute","allowWidgetHost","booleanAttributes","buildConfigFromElement","jsonConfig","attributeConfig","initializeFromElement","coreAiChatInitialized","__coreAIChatApp","scanForAutoInitialization","startAutoInitialization","readyState","download","toDataURL","img","res","removeChild"],"mappings":"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","file":"ai-chat.js","sourcesContent":["/*\n * Figure markers: the short labels the model writes, turned into pictures by the host.\n *\n * Retrieval hands the model a label -- [fig:1] -- and keeps the picture's real link in the message's reference\n * map, the same way a text citation keeps its source behind \"[doc:1]\". A model asked to reproduce a long opaque\n * identifier does not reproduce it: it copies the shape and substitutes ordinals, so links to figures that were\n * never in the results came back as 404s. A label short enough to be written exactly, with the link put back\n * here where the model cannot reach it, is what stops that.\n *\n * It sits on window rather than inside the manager below so the host can reach it, and so its rules can be\n * exercised in a bare sandbox with no browser and no DOM -- see tests/realtime-client/figure-markers.test.js --\n * exactly as window.CoreAIRealtime exposes the microphone gate's rules.\n *\n * The same block sits at the top of chat-interaction.js: the two chat clients are separate bundles that share no\n * module of their own, and both render the same markdown. Change one, change the other.\n */\n// CoreAIChatMarkers lives in chat-markers.js, which every chat surface loads before this file.\n\nwindow.coreAIChatManager = 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 copiedTitle: 'Response copied to clipboard.',\n codeCopiedText: 'Copied!',\n copyResetDelayMs: 2000,\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
\n \n
\n
\n \n {{ notification.content }}\n \n
\n
\n \n
\n
\n
\n `,\n indicatorTemplate: `\n
\n
\n \n Assistant\n
\n
\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 containsFontAwesomePlaceholders(root) {\n if (!root || root.nodeType !== 1) {\n return false;\n }\n\n var selector = 'i[class*=\"fa-\"],i.fa,i.fas,i.far,i.fab';\n if (typeof root.matches === 'function' && root.matches(selector)) {\n return true;\n }\n\n return typeof root.querySelector === 'function' && !!root.querySelector(selector);\n }\n\n function refreshFontAwesomeIcons(root) {\n var fontAwesome = window.FontAwesome;\n if (!containsFontAwesomePlaceholders(root) || !fontAwesome || !fontAwesome.dom || typeof fontAwesome.dom.i2svg !== 'function') {\n return;\n }\n\n fontAwesome.dom.i2svg({ node: root });\n }\n\n function observeFontAwesomeIcons(root) {\n if (!root || typeof MutationObserver === 'undefined') {\n return null;\n }\n\n var observer = new MutationObserver(function (mutations) {\n mutations.forEach(function (mutation) {\n mutation.addedNodes.forEach(function (node) {\n refreshFontAwesomeIcons(node);\n });\n });\n });\n\n observer.observe(root, {\n childList: true,\n subtree: true\n });\n\n return observer;\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 normalized.isGenerated = (normalized.isGenerated ?? normalized.IsGenerated) === true;\n normalized.isImage = (normalized.isImage ?? normalized.IsImage) === true;\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 // Installed at the top of this file so it can be unit tested without a browser; see the comment there.\n\n /*\n * Reads a JSON response body, or explains why it is not JSON.\n *\n * fetch follows a redirect silently and reports the page it landed on as a success, so an endpoint that\n * answers \"forbidden\" with a redirect to a sign-in page arrives here as response.ok with HTML in it.\n * Calling response.json() on that throws \"unexpected character at line 1 column 1\", which is what the\n * reader was shown instead of being told they are not allowed to upload.\n *\n * Returns { ok, data, message }. A caller shows message when ok is false; it is never a parser error.\n */\n async function readJsonResponse(response, fallbackMessage) {\n const contentType = (response.headers && response.headers.get('content-type')) || '';\n\n if (contentType.toLowerCase().indexOf('json') < 0) {\n // A redirect that landed somewhere else is the common case and worth naming, because the endpoint\n // did not refuse -- something in front of it did.\n const message = response.redirected\n ? 'You may not be signed in, or you do not have permission for this. Please reload and try again.'\n : fallbackMessage;\n\n return { ok: false, data: null, message: message };\n }\n\n try {\n return { ok: true, data: await response.json(), message: null };\n } catch (error) {\n return { ok: false, data: null, message: fallbackMessage };\n }\n }\n\n const expandImageMarkers = window.CoreAIChatMarkers.expandImageMarkers;\n\n function getCitationLabel(reference, key) {\n return reference.title || reference.text || key;\n }\n\n // Which references are one citation, and how a repeated marker reads, are statements about strings and\n // live in chat-markers.js so every chat surface numbers them the same way. Without the module each\n // reference keeps an identity of its own and nothing merges, which is the numbering this script had\n // before it.\n let unmergedCitationCount = 0;\n const citationIdentity = window.CoreAIChatMarkers?.citationIdentity\n ?? (() => `unmerged-${++unmergedCitationCount}`);\n const splitCombinedCitations = window.CoreAIChatMarkers?.splitCombinedCitations\n ?? (content => content);\n const collapseRepeatedCitations = window.CoreAIChatMarkers?.collapseRepeatedCitations\n ?? (html => html);\n const separateAdjacentCitations = window.CoreAIChatMarkers?.separateAdjacentCitations\n ?? (html => html);\n const citationMarkerHtml = window.CoreAIChatMarkers?.citationMarkerHtml\n ?? (displayIndex => `${displayIndex}`);\n\n function buildCitationDisplay(content, references) {\n // Before anything looks for a reference key, the combined form the model tends to write is split into\n // the keys it means. A key that is not found is not replaced, and an unreplaced key reaches the reader\n // as a raw marker mid-sentence.\n let processedContent = splitCombinedCitations((content || '').trim());\n const messageReferences = normalizeReferences(references);\n const referenceEntries = Object.entries(messageReferences);\n\n if (!referenceEntries.length) {\n return { content: processedContent, citations: [] };\n }\n\n const citedRefs = referenceEntries.filter(([key]) => processedContent.includes(key));\n const generatedRefs = referenceEntries.filter(([key, value]) => value.isGenerated && !processedContent.includes(key));\n\n if (!citedRefs.length && !generatedRefs.length) {\n return { content: processedContent, citations: [] };\n }\n\n citedRefs.sort(([, a], [, b]) => a.index - b.index);\n generatedRefs.sort(([, a], [, b]) => a.index - b.index);\n\n const citations = [];\n const citationsByIdentity = new Map();\n const placeholders = [];\n let displayIndex = 1;\n\n for (const [key, value] of citedRefs) {\n const label = getCitationLabel(value, key);\n const link = value.link || null;\n const identity = citationIdentity(label, link);\n let citation = citationsByIdentity.get(identity);\n\n // Every reference still has its key replaced, so the text never keeps a raw key; what the merge\n // changes is only how many numbers the reader is given for them.\n if (!citation) {\n citation = {\n referenceKey: key,\n referenceKeys: [],\n displayIndex: displayIndex++,\n label: label,\n link: link,\n isDownload: isDownloadCitationReference(value),\n };\n\n citationsByIdentity.set(identity, citation);\n citations.push(citation);\n }\n\n citation.referenceKeys.push(key);\n\n const placeholder = `__CITE_${citation.displayIndex}_${value.index || citation.displayIndex}__`;\n processedContent = processedContent.replaceAll(key, placeholder);\n placeholders.push({ placeholder, displayIndex: citation.displayIndex, label: citation.label });\n }\n\n for (const entry of placeholders) {\n processedContent = processedContent.replaceAll(entry.placeholder, citationMarkerHtml(entry.displayIndex, entry.label));\n }\n\n // Merged citations can leave the same number twice over a sentence; that is collapsed before the\n // commas go in, or the reader is given \"1,1\".\n processedContent = collapseRepeatedCitations(processedContent);\n processedContent = separateAdjacentCitations(processedContent);\n\n // Generated files (such as exported tabular data) are always offered as a download even when\n // the model does not cite them inline, so the user never loses access to the produced file.\n for (const [key, value] of generatedRefs) {\n citations.push({\n referenceKey: key,\n referenceKeys: [key],\n displayIndex: displayIndex,\n label: getCitationLabel(value, key),\n link: value.link || null,\n isDownload: true,\n placeholder: null,\n });\n\n displayIndex++;\n }\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 // Every key the citation absorbed is replaced, not just the first: a merged key left behind would\n // reach the clipboard as the raw reference token the reader never saw on the page.\n for (const citation of citations) {\n for (const key of (citation.referenceKeys?.length ? citation.referenceKeys : [citation.referenceKey])) {\n copyContent = copyContent.replaceAll(key, `[${citation.displayIndex}]`);\n }\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 // Figure markers become images before anything else reads the content: the citation pass looks for its\n // own keys in what is left, and the markdown parser then sees an ordinary image.\n const displayContent = expandImageMarkers(rawContent, messageReferences);\n const citationDisplay = buildCitationDisplay(displayContent, 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 // Copied from the expanded content, so a copied answer carries the picture's link rather than a label\n // that means nothing outside this page.\n // Split here too: the copy is built from the expanded content rather than the display path's output,\n // so a combined marker would otherwise survive into the clipboard as a raw key.\n message.copyContent = buildCopyContent(splitCombinedCitations(displayContent), 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 `${data.text}`;\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 `
${langDisplay}
${highlighted}
`;\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 // Spans, not divs. A figure marker is often written mid-sentence -- \"Figures [fig:1], [fig:2] and\n // [fig:3] show...\" -- and a block element cannot sit inside a paragraph: the browser closes the

\n // at the first one, so the sentence is torn into fragments and the commas between the markers are\n // left stranded on their own lines. Inline-block keeps the figure looking exactly the same while\n // remaining something a paragraph can legally contain.\n // The download sits over the picture's lower corner rather than on a line of its own beneath it.\n // A row of its own cost a band of vertical space under every figure, which a conversation full of\n // them pays for once per figure. The link itself is unchanged -- same address, same download\n // attribute, same behaviour -- only where it is drawn.\n return `\n \"${alt}\"\n \n \n \n `;\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 `

`\n + ``\n + `
`\n + `
`\n + ``\n + `
`;\n }\n\n // The marker itself is read by chat-markers.js, shared with every other chat surface, so the three of them\n // cannot disagree about what a marker is. Everything below -- the container, the id scheme, the Chart.js\n // call -- is this surface's own and legitimately differs from the others.\n const findChartMarker = window.CoreAIChatMarkers.findChartMarker;\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 = findChartMarker(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 // An image the assistant named but the server will not serve. The address is written by a language\n // model from what retrieval handed it, so a mistyped or invented one is possible, and the browser's\n // default for that is a broken-image icon captioned with the alt text -- which reads as a real picture\n // that failed to arrive. Saying plainly that it could not be loaded is both truer and quieter.\n //\n // Wired here rather than as an inline onerror attribute because message bodies go through DOMPurify,\n // which strips event-handler attributes.\n function markBrokenImagesInMessage() {\n // Scanning the document rather than one message, because the value threaded through the render\n // path is the message DATA object -- the thing carrying content, references and pending charts --\n // and not the element it was rendered into. Wiring is idempotent via the data-broken-wired mark,\n // so re-scanning after each render costs a query over the handful of images already handled.\n if (typeof document === 'undefined' || typeof requestAnimationFrame !== 'function') {\n return;\n }\n\n // Deferred for the same reason the charts below are: the render that produced these elements has\n // not necessarily been flushed to the DOM when this runs.\n requestAnimationFrame(wireBrokenImageHandlers);\n requestAnimationFrame(wireImageZoom);\n }\n\n // A picture arrives after the markdown is handed back -- the view writes it, and a streamed answer\n // rewrites it on every chunk -- so zooming cannot be attached once at load. It is attached on the same\n // pass as the broken-image handler above, and the attribute marks a picture already attached so a\n // re-render does not bind it a second time.\n function wireImageZoom() {\n // The library is the host's to load. Without it the picture is still shown and still downloadable;\n // only the enlarging is missing, so this is not worth failing a render over.\n if (typeof mediumZoom !== 'function') {\n return;\n }\n\n const images = document.querySelectorAll('.generated-image-container img:not([data-zoom-wired])');\n\n if (images.length === 0) {\n return;\n }\n\n for (const image of images) {\n image.setAttribute('data-zoom-wired', 'true');\n }\n\n mediumZoom(images, {\n // The drawing is bounded by the window rather than by this margin, so the margin is kept\n // small: an ingested figure is read detail by detail, and every pixel given away here comes\n // off the size it is read at.\n margin: 16,\n background: 'rgba(15, 15, 15, 0.92)',\n });\n }\n\n function wireBrokenImageHandlers() {\n const images = document.querySelectorAll('.generated-image-container img:not([data-broken-wired])');\n\n for (const image of images) {\n image.setAttribute('data-broken-wired', 'true');\n image.addEventListener('error', function () {\n const container = image.closest('.generated-image-container');\n\n if (!container || container.dataset.brokenHandled) {\n return;\n }\n\n container.dataset.brokenHandled = 'true';\n container.hidden = true;\n\n const note = document.createElement('p');\n note.className = 'text-muted small fst-italic mb-2';\n note.textContent = image.alt\n ? `(the picture \"${image.alt}\" could not be loaded)`\n : '(that picture could not be loaded)';\n container.insertAdjacentElement('afterend', note);\n }, { once: true });\n }\n }\n\n function renderMessageMedia(message) {\n markBrokenImagesInMessage();\n\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., ).');\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 // A markdown table becomes a bare , which Bootstrap leaves completely unstyled: it renders\n // as cramped, borderless text that reads as plain output rather than a table. Adding the framework's\n // own classes styles it wherever Bootstrap is loaded, and the wrapper lets a wide table scroll on\n // its own instead of stretching the conversation. Markdown tables cannot nest, so the plain\n // replacement is safe.\n function styleMarkdownTables(html) {\n return html\n .replace(/
/g, '
')\n .replace(/<\\/table>/g, '
');\n }\n\n function parseMarkdownContent(content, message) {\n _pendingCharts = [];\n const html = styleMarkdownTables(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 function compactObject(source) {\n if (!source || typeof source !== 'object') {\n return {};\n }\n\n return Object.fromEntries(\n Object.entries(source).filter(([, value]) => value !== undefined)\n );\n }\n\n function resolveIndicatorTemplate(template, assistantLabel) {\n if (!template) {\n return template;\n }\n\n const encodedAssistantLabel = escapeHtmlEntities(assistantLabel || 'Assistant');\n return template.replace(/\\{\\{\\s*assistantLabel\\s*\\}\\}/g, encodedAssistantLabel);\n }\n\n const initialize = (instanceConfig) => {\n const normalizedInstanceConfig = compactObject(instanceConfig);\n const normalizedWidgetConfig = compactObject(normalizedInstanceConfig.widget);\n const config = Object.assign({}, defaultConfig, normalizedInstanceConfig);\n config.widget = Object.assign({}, defaultConfig.widget || {}, normalizedWidgetConfig);\n config.indicatorTemplate = resolveIndicatorTemplate(config.indicatorTemplate, config.assistantLabel);\n const hasWidgetConfig = !!(normalizedWidgetConfig.chatWidgetContainer && normalizedWidgetConfig.chatWidgetStateName);\n const widgetBehavior = window.coreAIChatWidgetBehavior || 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 copiedTitle: config.copiedTitle,\n isRecording: false,\n mediaRecorder: null,\n preRecordingPrompt: '',\n micButton: null,\n // Conversation mode is carried either by a realtime session or by the speech-to-text plus\n // text-to-speech cascade, never both. Dictation and spoken playback belong to the cascade.\n speechToTextEnabled: !config.realtimeEnabled && (config.chatMode === 'AudioInput' || config.chatMode === 'Conversation'),\n textToSpeechEnabled: (!config.realtimeEnabled && 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 realtimeEnabled: !!config.realtimeEnabled,\n // Server-relay WebRTC transport: primary when advertised and supported; the client falls back\n // to the WebSocket path below if the peer cannot connect.\n realtimeWebRtcEnabled: config.realtimeWebRtcEnabled === true && typeof window.RTCPeerConnection === 'function',\n // A host-supplied override. Normally the servers are fetched from the hub right before the\n // peer is created (resolveRealtimeIceServers) so configured TURN relays — and their\n // short-lived credentials — are actually used instead of a public STUN server.\n realtimeWebRtcIceServers: (Array.isArray(config.realtimeWebRtcIceServers) && config.realtimeWebRtcIceServers.length)\n ? config.realtimeWebRtcIceServers\n : null,\n realtimeVoiceName: config.realtimeVoiceName || null,\n conversationButton: null,\n realtimeHintElement: config.realtimeHintElementSelector\n ? document.querySelector(config.realtimeHintElementSelector)\n : null,\n isConversationMode: false,\n notificationDismissTimers: {},\n pendingSessionPromise: null,\n pendingSessionResolver: null,\n pendingSessionRejector: null,\n pendingSessionTimeoutId: null,\n copiedMessageIndex: -1,\n copyResetTimeoutId: null,\n activeCopyButton: 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 parsed = await readJsonResponse(response, 'Upload failed. Please try again.');\n\n if (!parsed.ok) {\n console.error('Upload failed: response was not JSON.', { status: response.status, redirected: response.redirected });\n this.uploadErrors = [{ fileName: '', error: parsed.message }];\n\n return;\n }\n\n var result = parsed.data;\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 secondParsed = await readJsonResponse(response, 'The request could not be completed.');\n\n if (!secondParsed.ok) {\n console.error('Response was not JSON.', { status: response.status, redirected: response.redirected });\n\n return;\n }\n\n var result = secondParsed.data;\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 = '
';\n html += '
';\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 += '';\n html += ' ';\n html += this.escapeHtml(name);\n html += ' ';\n html += '';\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 // The reason is shown, not hidden behind a tooltip. A pill reading \"quarterly-report-2...\"\n // tells a reader their upload failed and nothing about why, and a title attribute is\n // unreachable on a touch device -- so the one sentence that tells them what to do next\n // was the one thing the widget would not display.\n html += '';\n html += '';\n html += '';\n\n if (failedItem.fileName) {\n html += '' + this.escapeHtml(failedItem.fileName) + ': ';\n }\n\n html += this.escapeHtml(errorMsg);\n html += '';\n html += '';\n html += '';\n }\n\n if (this.isUploading) {\n html += '';\n html += ' Uploading...';\n html += '';\n }\n\n html += '';\n html += '
';\n if (config.supportedExtensionsText) {\n html += '
Supported formats: ' + this.escapeHtml(config.supportedExtensionsText) + '
';\n }\n\n html += '
';\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 // Switching to another session must not leave a prior realtime/voice session running.\n this.forceStopActiveVoice();\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 renderMessageMedia(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 // display it as the first assistant message without invoking the AI.\n if (this.messages.length === 0 && config.initialPrompt) {\n this.addMessage({\n role: 'assistant',\n content: config.initialPrompt\n });\n }\n });\n\n // Realtime lifecycle events (ReceiveRealtimeEvent, and ReceiveError while a voice session is\n // live) are handled by the shared CoreAIRealtime module — see setupRealtimeController.\n\n this.connection.on(\"ReceiveError\", (error) => {\n console.error(\"SignalR Error: \", error);\n\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // A server-side error (for example a session-start rate-limit rejection) ends the\n // in-flight request. Reject any pending new-session promise so the UI stops waiting\n // until it times out, and clear the typing indicator that a send may have shown.\n this.rejectPendingSessionRequest(error);\n this.hideTypingIndicator();\n\n if (widgetBehavior && typeof widgetBehavior.handleReceiveError === 'function') {\n widgetBehavior.handleReceiveError(this, error, config);\n } else if (!this.isNavigatingAway) {\n // Surface the message to the user instead of failing silently.\n this.addMessage(this.getErrorMessage(error));\n }\n });\n\n this.connection.on(\"ReceiveSessionStartRejected\", (reason) => {\n // A rate-limit rejection is a definitive \"wait and retry\", not a recoverable\n // session/connection error. Unblock any pending new-session request, clear the\n // typing indicator, and show the message for every host (main app and widget)\n // without triggering the widget's clear-and-retry recovery, which would wipe the\n // visitor's state and fire another throttled StartSession.\n this.rejectPendingSessionRequest(reason);\n this.hideTypingIndicator();\n\n if (!this.isNavigatingAway) {\n this.addMessage(this.getErrorMessage(reason));\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, '>');\n var html = '

' + escaped + '

';\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, turnId, text) => {\n // Realtime creates the chat session server-side; adopt its id (and update the page URL)\n // on the first turn so a refresh reloads the conversation instead of starting fresh.\n if (sessionId && this.getSessionId() !== sessionId) {\n this.initializeSession(sessionId);\n }\n\n // Realtime: a placeholder for this turn was already inserted in the right position when\n // the utterance was captured (see user_turn_pending), so just fill in its text.\n if (turnId && this._realtimePendingTurns && this._realtimePendingTurns[turnId]) {\n var pending = this._realtimePendingTurns[turnId];\n delete this._realtimePendingTurns[turnId];\n this.stopAudio();\n this.fillRealtimePendingTurn(pending, text);\n\n return;\n }\n\n if (text) {\n this.stopAudio();\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '

' + escaped + '

';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else if (this._conversationAssistantMessage) {\n // Realtime: the user's transcript lags the assistant's reply for the SAME turn (the\n // model answers the audio before speech-to-text finishes). Insert the user message\n // just before the streaming assistant message so the order stays You -> Assistant,\n // and keep that message streaming — ending it here split one reply into two bubbles\n // above the prompt.\n var at = this._conversationAssistantMessage.index;\n var userMsg = { role: 'user', content: text, rawContent: text, userRating: null, references: {} };\n updateMessagePresentation(userMsg, userMsg.references);\n this.messages.splice(at, 0, userMsg);\n this._conversationAssistantMessage.index = at + 1;\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 // A new response id means a new turn — finalize the previous assistant message so two replies\n // never merge into one bubble (also covers barge-in, which starts a fresh response).\n if (this._conversationAssistantMessage && this._conversationAssistantResponseId && responseId && this._conversationAssistantResponseId !== responseId) {\n var prev = this.messages[this._conversationAssistantMessage.index];\n if (prev) { prev.isStreaming = false; }\n this._conversationAssistantMessage = null;\n }\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 this._conversationAssistantResponseId = responseId;\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 renderMessageMedia(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 this._conversationAssistantResponseId = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (sessionId, base64Audio, contentType) => {\n if (!base64Audio) {\n return;\n }\n\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\n // Realtime audio arrives as raw PCM16 (WebSocket transport) and is scheduled for immediate\n // playback by the shared module; conversation/TTS audio (mp3/wav) is collected and played on\n // complete.\n if (contentType === 'audio/pcm') {\n if (this.realtimeController) { this.realtimeController.receivePcm(bytes); }\n } else {\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 // The realtime session lived inside the dropped connection; it cannot survive a reconnect.\n if (this.realtimeEnabled && this.isConversationMode) {\n this.stopRealtimeConversation();\n }\n });\n\n this.connection.onreconnected(() => {\n console.info(\"SignalR: reconnected.\");\n\n if (this.isSessionStarted) {\n this.reloadCurrentSession();\n }\n });\n\n this.connection.onclose((error) => {\n if (this.isNavigatingAway) {\n return;\n }\n\n if (this.realtimeEnabled && this.isConversationMode) {\n this.stopRealtimeConversation();\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 async ensureConnectionStarted() {\n if (!this.connection) {\n return false;\n }\n\n var states = signalR.HubConnectionState;\n if (this.connection.state === states.Connected) {\n return true;\n }\n\n // If the initial start failed or has not begun, start it now.\n if (this.connection.state === states.Disconnected) {\n try {\n await this.connection.start();\n } catch (err) {\n console.error(\"SignalR Connection Error: \", err);\n }\n\n return this.connection.state === states.Connected;\n }\n\n // The connection is still Connecting or Reconnecting: wait for it to settle so callers\n // (e.g. starting a realtime session) do not send before the socket is ready.\n return await new Promise((resolve) => {\n var settle = (value) => {\n clearTimeout(timeoutId);\n clearInterval(intervalId);\n resolve(value);\n };\n var timeoutId = setTimeout(() => settle(this.connection.state === states.Connected), 10000);\n var intervalId = setInterval(() => {\n if (this.connection.state === states.Connected) {\n settle(true);\n } else if (this.connection.state === states.Disconnected) {\n settle(false);\n }\n }, 100);\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(\"addingCoreAIPromotMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedCoreAIPromotMessage\", { 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 renderMessageMedia(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 // A live voice session and a typed turn are two writers into one chat session, and they\n // would interleave. End the session first; the turns it already produced are persisted, so\n // the typed message simply continues the same thread.\n this.forceStopActiveVoice();\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 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\n // Capture raw 16 kHz PCM (16-bit mono) via Web Audio instead of MediaRecorder.\n // Browsers only agree on WebM/Opus for MediaRecorder, and Azure's speech SDK cannot\n // demux that container from a streaming push (it fails inside GStreamer). Raw PCM is\n // decoded natively with no GStreamer and is produced identically by every browser.\n this._sttCapture = this._createPcmCapture(stream, (base64) => {\n try { subject.next(base64); } catch (err) { /* completed */ }\n });\n this._sttSubject = subject;\n\n var rate = (this._sttCapture && this._sttCapture.sampleRate) || 16000;\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"SendAudioStream\", profileId, sessionId, subject, \"audio/pcm;rate=\" + rate, language);\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) {\n return;\n }\n\n this._stopPcmCapture(this._sttCapture);\n this._sttCapture = null;\n if (this._sttSubject) {\n try { this._sttSubject.complete(); } catch (err) { /* already completed */ }\n this._sttSubject = null;\n }\n this.isRecording = false;\n this.updateMicButton();\n },\n // Captures microphone audio as raw 16 kHz, 16-bit mono PCM using Web Audio and invokes\n // onChunk(base64Pcm, rms) for each block. Returns a handle for _stopPcmCapture. This replaces\n // MediaRecorder so every browser streams a format Azure decodes without GStreamer.\n _createPcmCapture(stream, onChunk) {\n var AudioCtx = window.AudioContext || window.webkitAudioContext;\n // Ask the browser to resample the mic to 16 kHz; fall back to manual resampling if it will not.\n var audioContext;\n try {\n audioContext = new AudioCtx({ sampleRate: 16000 });\n } catch (e) {\n audioContext = new AudioCtx();\n }\n var srcRate = audioContext.sampleRate;\n var source = audioContext.createMediaStreamSource(stream);\n var processor = audioContext.createScriptProcessor(4096, 1, 1);\n var self = this;\n processor.onaudioprocess = function (e) {\n var input = e.inputBuffer.getChannelData(0);\n var pcm16 = self._downsampleToInt16(input, srcRate, 16000);\n if (!pcm16 || pcm16.length === 0) {\n return;\n }\n var sum = 0;\n for (var i = 0; i < pcm16.length; i++) {\n var v = pcm16[i] / 32768;\n sum += v * v;\n }\n var rms = Math.sqrt(sum / pcm16.length);\n var bytes = new Uint8Array(pcm16.buffer);\n var binary = '';\n for (var j = 0; j < bytes.length; j++) {\n binary += String.fromCharCode(bytes[j]);\n }\n onChunk(btoa(binary), rms);\n };\n source.connect(processor);\n // Some browsers only fire onaudioprocess while the node is connected to a destination.\n processor.connect(audioContext.destination);\n return { audioContext: audioContext, source: source, processor: processor, stream: stream, sampleRate: 16000 };\n },\n _stopPcmCapture(capture) {\n if (!capture) {\n return;\n }\n try { if (capture.processor) { capture.processor.onaudioprocess = null; capture.processor.disconnect(); } } catch (e) { }\n try { if (capture.source) { capture.source.disconnect(); } } catch (e) { }\n try { if (capture.stream) { capture.stream.getTracks().forEach(function (t) { t.stop(); }); } } catch (e) { }\n try { if (capture.audioContext) { capture.audioContext.close(); } } catch (e) { }\n },\n // Converts a Float32 sample block to 16-bit PCM, resampling from srcRate to dstRate when needed.\n _downsampleToInt16(input, srcRate, dstRate) {\n var s, i;\n if (!(dstRate < srcRate)) {\n var same = new Int16Array(input.length);\n for (i = 0; i < input.length; i++) {\n s = Math.max(-1, Math.min(1, input[i]));\n same[i] = s < 0 ? s * 0x8000 : s * 0x7FFF;\n }\n return same;\n }\n var ratio = srcRate / dstRate;\n var newLen = Math.floor(input.length / ratio);\n var out = new Int16Array(newLen);\n for (var j = 0; j < newLen; j++) {\n var idx = j * ratio;\n var i0 = Math.floor(idx);\n var i1 = (i0 + 1 < input.length) ? i0 + 1 : input.length - 1;\n var frac = idx - i0;\n s = input[i0] * (1 - frac) + input[i1] * frac;\n s = Math.max(-1, Math.min(1, s));\n out[j] = s < 0 ? s * 0x8000 : s * 0x7FFF;\n }\n return out;\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 = '';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '';\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 renderMessageMedia(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 getErrorMessage(error) {\n var content = (typeof error === 'string' && error.trim())\n ? error\n : \"Something went wrong. Please try again.\";\n\n return {\n role: \"assistant\",\n content: content,\n htmlContent: \"\",\n };\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 renderMessageMedia(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\n button.classList.toggle('tts-playing', isPlaying);\n button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');\n });\n },\n updateCopyButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-copy-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-copy-message-index'));\n var isCopied = buttonIndex === this.copiedMessageIndex;\n var iconHtml = isCopied\n ? ''\n : '';\n\n button.classList.toggle('text-success', isCopied);\n button.classList.toggle('text-secondary', !isCopied);\n button.setAttribute('title', isCopied ? this.copiedTitle : this.copyTitle);\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\n });\n },\n setCopyButtonState(button, isCopied) {\n if (!button) {\n return;\n }\n\n var iconHtml = isCopied\n ? ''\n : '';\n\n button.classList.toggle('text-success', isCopied);\n button.classList.toggle('text-secondary', !isCopied);\n button.setAttribute('title', isCopied ? this.copiedTitle : this.copyTitle);\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\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 // A live voice session takes the message box away and puts the audio settings in its place; ending\n // the session gives it back. Sending a typed message already force-stopped the session, so the box\n // was never a way to say something *during* one -- hiding it only makes that honest, and frees the\n // row for the gear. Both transports land here: realtime through the module's onActivate, the\n // speech-to-text cascade through startConversationMode.\n // The realtime module inserts its settings popover directly after the button it was handed, and\n // hard-codes the element id. A page can host two chat clients at once -- this one and the admin\n // widget -- so that id is not unique and getElementById would hand the widget the page's gear.\n // Each client finds its own next to its own button.\n voiceSettingsElement() {\n var next = this.conversationButton && this.conversationButton.nextElementSibling;\n\n return next && next.id === 'realtime-audio-settings' ? next : null;\n },\n setVoiceSessionLive(live) {\n if (this.inputElement) {\n this.inputElement.hidden = live;\n }\n\n if (this.buttonElement) {\n this.buttonElement.hidden = live;\n }\n\n // With the message box gone the button would otherwise sit at its natural width in an empty\n // row, so it takes the space the box left behind and reads as the thing now in charge. The\n // settings popover does not grow, so it stays at the right-hand end.\n if (this.conversationButton) {\n this.conversationButton.classList.toggle('flex-grow-1', live);\n }\n\n // The gear is built by the realtime module next to its button, and only in realtime mode, so\n // it is absent on the cascade. It belongs to a live session rather than to the surface.\n var audioSettings = this.voiceSettingsElement();\n if (audioSettings) {\n audioSettings.hidden = !live;\n }\n\n var hint = this.realtimeHintElement;\n if (hint) {\n hint.classList.toggle('d-none', !live);\n }\n },\n toggleConversationMode() {\n if (this.realtimeEnabled) {\n // Realtime is driven by the shared module, which owns the button; this only exists for\n // callers that toggle programmatically.\n if (this.realtimeController) { this.realtimeController.toggle(); }\n\n return;\n }\n\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n // Force-stop any in-progress voice/realtime session (mic, playback, and the streamed audio),\n // e.g. before starting a new chat or switching sessions, so it never keeps running in the background.\n forceStopActiveVoice() {\n if (!this.isConversationMode) {\n return;\n }\n if (this.realtimeEnabled) {\n this.stopRealtimeConversation();\n } else {\n this.stopConversationMode();\n }\n },\n startRealtimeConversation() {\n if (this.realtimeController) { this.realtimeController.start(); }\n },\n stopRealtimeConversation() {\n if (this.realtimeController) { this.realtimeController.stop(); }\n },\n // Realtime (speech-to-speech) is the shared CoreAIRealtime module (realtime-audio.js): microphone\n // capture and gating, the WebRTC transport with its WebSocket fallback, playback, the settings\n // popover, push-to-talk, and the server-driven session lifecycle all live there, so this app and the\n // chat-interaction client cannot drift apart. What is wired here is only how the module reaches this\n // app's hub and transcript.\n setupRealtimeController(config) {\n if (this.realtimeController || !this.conversationButton) { return; }\n if (!window.CoreAIRealtime || typeof window.CoreAIRealtime.attach !== 'function') {\n console.error('realtime-audio.js is not loaded; realtime voice is unavailable on this page.');\n\n return;\n }\n\n var self = this;\n this.realtimeController = window.CoreAIRealtime.attach({\n connection: this.connection,\n ensureConnected: function () {\n return self.ensureConnectionStarted().then(function (connected) {\n if (!connected) { throw new Error('The chat connection is not available.'); }\n\n return connected;\n });\n },\n sendStart: function (subject, voice, language, silenceMs, vadThreshold, allowInterruption) {\n self.connection.send('StartRealtimeConversation', self.getProfileId(), self.getSessionId() || '', subject, voice, language, silenceMs, vadThreshold, allowInterruption);\n },\n webRtcEnabled: this.realtimeWebRtcEnabled,\n sendStartWebRtc: function (offerSdp, voice, language, silenceMs, vadThreshold, allowInterruption) {\n self.connection.send('StartRealtimeWebRtc', self.getProfileId(), self.getSessionId() || '', offerSdp, voice, language, silenceMs, vadThreshold, allowInterruption);\n },\n webRtcIceServers: this.realtimeWebRtcIceServers || undefined,\n voiceName: this.realtimeVoiceName || '',\n getVoiceName: function () { return self.realtimeVoiceName || ''; },\n realtimeEnabled: true,\n // The conversation button doubles as the realtime button on this host; the module owns its\n // click, label and state from here on.\n //\n // input and sendButton are deliberately not handed over. The module hides every control it\n // is given when realtime takes over, and typing has to stay available during a voice\n // conversation -- that is the whole feature.\n //\n // conversationButton is not handed over either. It is the same element as the realtime\n // button here, and the module hides the conversation button before showing the realtime\n // one -- naming it twice would ask it to hide the control it then has to show.\n selectors: {\n realtimeButton: config.conversationButtonElementSelector,\n micButton: config.micButtonElementSelector\n },\n // The module owns whether a session is live, so the message box follows its flag rather\n // than this app's copy of it. Losing one of these events used to leave the box hidden\n // under a button that had already gone back to \"Start speaking\".\n onSessionStateChanged: function (active) {\n self.setVoiceSessionLive(active);\n },\n onActivate: function () {\n self.isConversationMode = true;\n self._conversationAssistantMessage = null;\n self._conversationPartialMessage = null;\n self.removeNotification('conversation-ended');\n },\n onDeactivate: function () {\n self.isConversationMode = false;\n self.finishRealtimeConversationCleanup();\n },\n onUserTurnPending: function (turnId) { self.addRealtimePendingTurn(turnId); },\n onUserTurnDropped: function (turnId) { self.dropRealtimePendingTurn(turnId); }\n });\n },\n // Shared teardown tail: clears any in-flight streaming state and shows the conversation-ended\n // notification.\n finishRealtimeConversationCleanup() {\n if (this._conversationAssistantMessage) {\n var m = this.messages[this._conversationAssistantMessage.index];\n if (m) { m.isStreaming = false; }\n this._conversationAssistantMessage = null;\n }\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) { this.messages[i].isStreaming = false; }\n }\n\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 // The utterance has been captured but not transcribed yet. Showing a placeholder now puts the\n // prompt above the reply it produces: transcription lags the spoken answer, so a bubble added only\n // when the text arrives lands underneath its own reply.\n addRealtimePendingTurn(turnId) {\n if (!turnId) { return; }\n this._realtimePendingTurns = this._realtimePendingTurns || {};\n var index = this.messages.length;\n this.addMessage({ role: 'user', content: '', isPartial: true });\n this._realtimePendingTurns[turnId] = this.messages[index];\n },\n fillRealtimePendingTurn(pending, text) {\n if (!pending) { return; }\n if (!text) {\n var emptyAt = this.messages.indexOf(pending);\n if (emptyAt >= 0) { this.messages.splice(emptyAt, 1); }\n\n return;\n }\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n pending.content = text;\n pending.htmlContent = '

' + escaped + '

';\n pending.isPartial = false;\n },\n dropRealtimePendingTurn(turnId) {\n if (!turnId || !this._realtimePendingTurns) { return; }\n var dropped = this._realtimePendingTurns[turnId];\n if (!dropped) { return; }\n delete this._realtimePendingTurns[turnId];\n var at = this.messages.indexOf(dropped);\n if (at >= 0) { this.messages.splice(at, 1); }\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 this._conversationSubject = new signalR.Subject();\n this._conversationStream = stream;\n\n // RMS (0..1) above which speech during TTS playback counts as an interrupt.\n var interruptRmsThreshold = 0.12;\n\n // Capture raw 16 kHz PCM (16-bit mono) via Web Audio instead of MediaRecorder — see\n // startRecording for why WebM/Opus is avoided. The per-block RMS drives interrupt\n // detection during TTS playback, replacing the previous AnalyserNode.\n this._conversationCapture = this._createPcmCapture(stream, (base64, rms) => {\n if (this.isPlayingAudio && rms >= interruptRmsThreshold) {\n // User is speaking over TTS — interrupt playback.\n this.stopAudio();\n }\n try {\n this._conversationSubject.next(base64);\n } catch (err) {\n // Subject may have been completed already.\n }\n });\n\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var language = navigator.language || document.documentElement.lang || 'en-US';\n var rate = (this._conversationCapture && this._conversationCapture.sampleRate) || 16000;\n\n this.connection.send(\"StartConversation\", profileId, sessionId, this._conversationSubject, \"audio/pcm;rate=\" + rate, language);\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) {\n this._stopPcmCapture(this._conversationCapture);\n this._conversationCapture = null;\n if (this._conversationSubject) {\n try { this._conversationSubject.complete(); } catch (err) { /* already completed */ }\n }\n this.isRecording = false;\n }\n\n this.stopAudio();\n this._conversationPartialTranscript = '';\n this._conversationPartialMessage = null;\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 // Force-stop an in-progress voice/realtime conversation so it doesn't keep running under the new session.\n this.forceStopActiveVoice();\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\n // When an initial prompt is configured, show it as the first\n // assistant message instead of the generic placeholder.\n if (config.initialPrompt) {\n this.addMessage({\n role: 'assistant',\n content: config.initialPrompt\n });\n } else {\n this.showPlaceholder();\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 // Force-stop any live voice/realtime session before starting a new chat.\n this.forceStopActiveVoice();\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 }\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 const initialMessages = Array.isArray(config.messages) ? config.messages : [];\n\n for (let i = 0; i < initialMessages.length; i++) {\n this.addMessage(initialMessages[i]);\n }\n\n // When no messages were loaded and an initial prompt is configured,\n // display it as the first assistant message without invoking the AI.\n if (this.messages.length === 0 && config.initialPrompt) {\n this.addMessage({\n role: 'assistant',\n content: config.initialPrompt\n });\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 = ' ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '';\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 (used for both STT/TTS conversation and realtime).\n if ((this.conversationModeEnabled || this.realtimeEnabled) && config.conversationButtonElementSelector) {\n this.conversationButton = document.querySelector(config.conversationButtonElementSelector);\n if (this.conversationButton) {\n if (this.realtimeEnabled) {\n // The shared realtime module owns the button (click, label, state) and adds the\n // voice settings popover next to it.\n this.setupRealtimeController(config);\n\n // The module reveals the gear as soon as the surface enters realtime mode, but it\n // belongs to a live session. The watcher that would hide it only runs on a change,\n // so the idle state has to be stated once here.\n this.setVoiceSessionLive(false);\n } else {\n this.conversationButton.addEventListener('click', () => {\n this.toggleConversationMode();\n });\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(\"initializingSessionCoreAIChat\", { 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 // For non-widget pages, update the browser URL so that a page\n // refresh reloads the correct session instead of starting fresh.\n if (!hasWidgetConfig && sessionId && config.sessionUrlTemplate && typeof history !== 'undefined' && history.replaceState) {\n var sessionUrl = config.sessionUrlTemplate.replace('{sessionId}', encodeURIComponent(sessionId));\n history.replaceState(null, '', sessionUrl);\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 clearCopiedMessageState() {\n if (this.copyResetTimeoutId) {\n window.clearTimeout(this.copyResetTimeoutId);\n this.copyResetTimeoutId = null;\n }\n\n if (this.activeCopyButton) {\n this.setCopyButtonState(this.activeCopyButton, false);\n this.activeCopyButton = null;\n }\n\n this.copiedMessageIndex = -1;\n },\n copyResponse(message, index, event) {\n const text = message && typeof message === 'object'\n ? message.copyContent ?? message.content ?? ''\n : message ?? '';\n const button = event?.currentTarget || event?.target?.closest?.('[data-copy-message-index]') || null;\n\n navigator.clipboard.writeText(text)\n .then(() => {\n this.clearCopiedMessageState();\n this.copiedMessageIndex = typeof index === 'number' ? index : -1;\n this.activeCopyButton = button;\n\n if (button) {\n this.setCopyButtonState(button, true);\n } else {\n this.$nextTick(() => this.updateCopyButtons());\n }\n\n this.copyResetTimeoutId = window.setTimeout(() => {\n this.clearCopiedMessageState();\n this.$nextTick(() => this.updateCopyButtons());\n }, Number(config.copyResetDelayMs) || 2000);\n })\n .catch(err => console.error('Failed to copy response:', err));\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 copiedMessageIndex() {\n this.$nextTick(() => this.updateCopyButtons());\n },\n isConversationMode(active) {\n // The dictation microphone is hidden while a voice conversation runs: the conversation\n // already owns the microphone, and a second one would mean something different.\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n // The message box and the send button give way to the voice settings while the conversation\n // runs, and come back when it ends. Both kinds of turn still land in the same thread; what\n // they cannot do is overlap.\n //\n // Only the cascade is driven from here. Realtime follows the module's own session flag\n // (onSessionStateChanged), so the two never disagree about whether a session is live.\n if (!this.realtimeEnabled) {\n this.setVoiceSessionLive(active);\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 this.$nextTick(() => {\n this.updateCopyButtons();\n refreshFontAwesomeIcons(this.$el);\n this.fontAwesomeObserver = observeFontAwesomeIcons(this.$el);\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 if (this.fontAwesomeObserver) {\n this.fontAwesomeObserver.disconnect();\n this.fontAwesomeObserver = null;\n }\n\n this.clearCopiedMessageState();\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 const autoInitializeSelector = '[data-coreai-chat-config],[data-coreai-chat-app-element-selector]';\n\n function getAttributeValue(element, attributeName) {\n const value = element.getAttribute(attributeName);\n return value === null || value === '' ? null : value;\n }\n\n function parseBooleanAttributeValue(value) {\n if (value === null || value === undefined) {\n return null;\n }\n\n if (typeof value === 'boolean') {\n return value;\n }\n\n const normalized = String(value).trim().toLowerCase();\n if (normalized === 'true') {\n return true;\n }\n\n if (normalized === 'false') {\n return false;\n }\n\n return null;\n }\n\n function parseJsonAttribute(element, attributeName, description) {\n const rawValue = getAttributeValue(element, attributeName);\n if (!rawValue) {\n return null;\n }\n\n try {\n return JSON.parse(rawValue);\n } catch (error) {\n console.error('Failed to parse ' + description + ' JSON.', error);\n return null;\n }\n }\n\n function buildConfigFromDataAttributes(element, options) {\n const settings = options || {};\n\n if (element.hasAttribute('data-coreai-chat-widget-container-selector') && settings.allowWidgetHost !== true) {\n return null;\n }\n\n const appElementSelector = getAttributeValue(element, 'data-coreai-chat-app-element-selector');\n if (!appElementSelector) {\n return null;\n }\n\n const config = {\n signalRHubUrl: getAttributeValue(element, 'data-coreai-chat-signalr-hub-url'),\n appElementSelector: appElementSelector,\n chatContainerElementSelector: getAttributeValue(element, 'data-coreai-chat-container-element-selector'),\n inputElementSelector: getAttributeValue(element, 'data-coreai-chat-input-element-selector'),\n sendButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-send-button-element-selector'),\n placeholderElementSelector: getAttributeValue(element, 'data-coreai-chat-placeholder-element-selector'),\n messages: parseJsonAttribute(element, 'data-coreai-chat-messages', 'CoreAI chat messages') ?? undefined,\n chatMode: getAttributeValue(element, 'data-coreai-chat-mode'),\n micButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-mic-button-element-selector'),\n conversationButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-conversation-button-element-selector'),\n realtimeHintElementSelector: getAttributeValue(element, 'data-coreai-chat-realtime-hint-element-selector'),\n ttsVoiceName: getAttributeValue(element, 'data-coreai-chat-tts-voice-name'),\n realtimeVoiceName: getAttributeValue(element, 'data-coreai-chat-realtime-voice-name'),\n documentBarSelector: getAttributeValue(element, 'data-coreai-chat-document-bar-selector'),\n uploadDocumentUrl: getAttributeValue(element, 'data-coreai-chat-upload-document-url'),\n removeDocumentUrl: getAttributeValue(element, 'data-coreai-chat-remove-document-url'),\n allowedExtensions: getAttributeValue(element, 'data-coreai-chat-allowed-extensions'),\n supportedExtensionsText: getAttributeValue(element, 'data-coreai-chat-supported-extensions-text'),\n existingDocuments: parseJsonAttribute(element, 'data-coreai-chat-existing-documents', 'CoreAI chat existing documents') ?? undefined,\n initialPrompt: getAttributeValue(element, 'data-coreai-chat-initial-prompt'),\n sessionUrlTemplate: getAttributeValue(element, 'data-coreai-chat-session-url-template'),\n userLabel: getAttributeValue(element, 'data-coreai-chat-user-label'),\n assistantLabel: getAttributeValue(element, 'data-coreai-chat-assistant-label'),\n copyTitle: getAttributeValue(element, 'data-coreai-chat-copy-title'),\n copiedTitle: getAttributeValue(element, 'data-coreai-chat-copied-title'),\n };\n\n const booleanAttributes = {\n metricsEnabled: 'data-coreai-chat-metrics-enabled',\n textToSpeechEnabled: 'data-coreai-chat-text-to-speech-enabled',\n sessionDocumentsEnabled: 'data-coreai-chat-session-documents-enabled',\n singleResponseMode: 'data-coreai-chat-single-response-mode',\n realtimeEnabled: 'data-coreai-chat-realtime-enabled',\n realtimeWebRtcEnabled: 'data-coreai-chat-realtime-webrtc-enabled',\n };\n\n Object.keys(booleanAttributes).forEach(key => {\n const parsed = parseBooleanAttributeValue(getAttributeValue(element, booleanAttributes[key]));\n if (parsed !== null) {\n config[key] = parsed;\n }\n });\n\n return compactObject(config);\n }\n\n function buildConfigFromElement(element, options) {\n const jsonConfig = parseJsonAttribute(element, 'data-coreai-chat-config', 'CoreAI chat config');\n const attributeConfig = buildConfigFromDataAttributes(element, options);\n\n if (!jsonConfig && !attributeConfig) {\n return null;\n }\n\n return Object.assign({}, jsonConfig || {}, attributeConfig || {});\n }\n\n function initializeFromElement(element) {\n if (!element || element.dataset.coreAiChatInitialized === 'true') {\n return element ? element.__coreAIChatApp || null : null;\n }\n\n const config = buildConfigFromElement(element);\n if (!config) {\n return null;\n }\n\n const app = initialize(config);\n if (!app) {\n return null;\n }\n\n element.dataset.coreAiChatInitialized = 'true';\n element.__coreAIChatApp = app;\n\n return app;\n }\n\n function scanForAutoInitialization(root) {\n if (!root || typeof root.querySelectorAll !== 'function') {\n return;\n }\n\n if (typeof root.matches === 'function' && root.matches(autoInitializeSelector)) {\n initializeFromElement(root);\n }\n\n root.querySelectorAll(autoInitializeSelector).forEach(initializeFromElement);\n }\n\n function startAutoInitialization() {\n scanForAutoInitialization(document);\n\n if (typeof MutationObserver === 'undefined') {\n return;\n }\n\n const observer = new MutationObserver(mutations => {\n mutations.forEach(mutation => {\n mutation.addedNodes.forEach(node => {\n if (node && node.nodeType === 1) {\n scanForAutoInitialization(node);\n }\n });\n });\n });\n\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n });\n }\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', startAutoInitialization, { once: true });\n } else {\n startAutoInitialization();\n }\n\n return {\n initialize: initialize,\n initializeFromElement: initializeFromElement,\n buildConfigFromElement: buildConfigFromElement,\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 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"]} diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.min.js b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.min.js index c3270568..020b1e4d 100644 --- a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.min.js +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.min.js @@ -1,2 +1,2 @@ -var _excluded=["placeholder"];function _regenerator(){/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */var e,t,n="function"==typeof Symbol?Symbol:{},i=n.iterator||"@@iterator",o=n.toStringTag||"@@toStringTag";function s(n,i,o,s){var c=i&&i.prototype instanceof r?i:r,l=Object.create(c.prototype);return _regeneratorDefine2(l,"_invoke",function(n,i,o){var s,r,c,l=0,u=o||[],d=!1,h={p:0,n:0,v:e,a:m,f:m.bind(e,4),d:function(t,n){return s=t,r=0,c=e,h.n=n,a}};function m(n,i){for(r=n,c=i,t=0;!d&&l&&!o&&t3?(o=f===i)&&(c=s[(r=s[4])?5:(r=3,3)],s[4]=s[5]=e):s[0]<=m&&((o=n<2&&mi||i>f)&&(s[4]=n,s[5]=i,h.n=f,r=0))}if(o||n>1)return a;throw d=!0,i}return function(o,u,f){if(l>1)throw TypeError("Generator is already running");for(d&&1===u&&m(u,f),r=u,c=f;(t=r<2?e:c)||!d;){s||(r?r<3?(r>1&&(h.n=-1),m(r,c)):h.n=c:h.v=c);try{if(l=2,s){if(r||(o="next"),t=s[o]){if(!(t=t.call(s,c)))throw TypeError("iterator result is not an object");if(!t.done)return t;c=t.value,r<2&&(r=0)}else 1===r&&(t=s.return)&&t.call(s),r<2&&(c=TypeError("The iterator does not provide a '"+o+"' method"),r=1);s=e}else if((t=(d=h.n<0)?c:n.call(i,h))!==a)break}catch(t){s=e,r=1,c=t}finally{l=1}}return{value:t,done:d}}}(n,o,s),!0),l}var a={};function r(){}function c(){}function l(){}t=Object.getPrototypeOf;var u=[][i]?t(t([][i]())):(_regeneratorDefine2(t={},i,function(){return this}),t),d=l.prototype=r.prototype=Object.create(u);function h(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,l):(e.__proto__=l,_regeneratorDefine2(e,o,"GeneratorFunction")),e.prototype=Object.create(d),e}return c.prototype=l,_regeneratorDefine2(d,"constructor",l),_regeneratorDefine2(l,"constructor",c),c.displayName="GeneratorFunction",_regeneratorDefine2(l,o,"GeneratorFunction"),_regeneratorDefine2(d),_regeneratorDefine2(d,o,"Generator"),_regeneratorDefine2(d,i,function(){return this}),_regeneratorDefine2(d,"toString",function(){return"[object Generator]"}),(_regenerator=function(){return{w:s,m:h}})()}function _regeneratorDefine2(e,t,n,i){var o=Object.defineProperty;try{o({},"",{})}catch(e){o=0}_regeneratorDefine2=function(e,t,n,i){function s(t,n){_regeneratorDefine2(e,t,function(e){return this._invoke(t,n,e)})}t?o?o(e,t,{value:n,enumerable:!i,configurable:!i,writable:!i}):e[t]=n:(s("next",0),s("throw",1),s("return",2))},_regeneratorDefine2(e,t,n,i)}function _toConsumableArray(e){return _arrayWithoutHoles(e)||_iterableToArray(e)||_unsupportedIterableToArray(e)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _iterableToArray(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}function _arrayWithoutHoles(e){if(Array.isArray(e))return _arrayLikeToArray(e)}function _objectWithoutProperties(e,t){if(null==e)return{};var n,i,o=_objectWithoutPropertiesLoose(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(i=0;i=e.length?{done:!0}:{done:!1,value:e[i++]}},e:function(e){throw e},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var s,a=!0,r=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return a=e.done,e},e:function(e){r=!0,s=e},f:function(){try{a||null==n.return||n.return()}finally{if(r)throw s}}}}function asyncGeneratorStep(e,t,n,i,o,s,a){try{var r=e[s](a),c=r.value}catch(e){return void n(e)}r.done?t(c):Promise.resolve(c).then(i,o)}function _asyncToGenerator(e){return function(){var t=this,n=arguments;return new Promise(function(i,o){var s=e.apply(t,n);function a(e){asyncGeneratorStep(s,i,o,a,r,"next",e)}function r(e){asyncGeneratorStep(s,i,o,a,r,"throw",e)}a(void 0)})}}function _slicedToArray(e,t){return _arrayWithHoles(e)||_iterableToArrayLimit(e,t)||_unsupportedIterableToArray(e,t)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(e,t){if(e){if("string"==typeof e)return _arrayLikeToArray(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_arrayLikeToArray(e,t):void 0}}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,i=Array(t);n\n \n
\n
\n \n {{ notification.content }}\n \n
\n
\n \n
\n
\n \n ',indicatorTemplate:'\n
\n
\n \n Assistant\n
\n
\n '};function d(e){if(!e)return"";var t=e.trim();return/^javascript:/i.test(t)||/^vbscript:/i.test(t)||/^data:text\/html/i.test(t)?"":e}function h(e){var t=document.createElement("span");return t.textContent=e,t.innerHTML}function m(e){var t=window.FontAwesome;(function(e){if(!e||1!==e.nodeType)return!1;var t='i[class*="fa-"],i.fa,i.fas,i.far,i.fab';return!("function"!=typeof e.matches||!e.matches(t))||"function"==typeof e.querySelector&&!!e.querySelector(t)})(e)&&t&&t.dom&&"function"==typeof t.dom.i2svg&&t.dom.i2svg({node:e})}function f(e){if(!e||"undefined"==typeof MutationObserver)return null;var t=new MutationObserver(function(e){e.forEach(function(e){e.addedNodes.forEach(function(e){m(e)})})});return t.observe(e,{childList:!0,subtree:!0}),t}function p(e){var t,n,i,o,s,a,r,c,l,u,h,m;if(!e||"object"!==_typeof(e))return null;var f=Object.assign({},e);return f.index=null!==(t=null!==(n=f.index)&&void 0!==n?n:f.Index)&&void 0!==t?t:0,f.text=null!==(i=null!==(o=f.text)&&void 0!==o?o:f.Text)&&void 0!==i?i:null,f.title=null!==(s=null!==(a=f.title)&&void 0!==a?a:f.Title)&&void 0!==s?s:null,f.link=d(null!==(r=null!==(c=f.link)&&void 0!==c?c:f.Link)&&void 0!==r?r:null),f.referenceType=null!==(l=null!==(u=f.referenceType)&&void 0!==u?u:f.ReferenceType)&&void 0!==l?l:null,f.isGenerated=!0===(null!==(h=f.isGenerated)&&void 0!==h?h:f.IsGenerated),f.isImage=!0===(null!==(m=f.isImage)&&void 0!==m?m:f.IsImage),f}function g(e){return!(!e||"object"!==_typeof(e))&&("string"==typeof e.referenceType&&"document"===e.referenceType.toLowerCase()||!("string"!=typeof e.link||!/\/ai\/documents\/.+\/download(?:$|\?)/i.test(e.link)))}function v(e){if(!e||"object"!==_typeof(e))return{};for(var t={},n=0,i=Object.entries(e);n".concat(e,"")};function x(e,t){var n=v(null!=t?t:e.references),i="string"==typeof e.rawContent?e.rawContent:"string"==typeof e.content?e.content:"",o=S(i,n),s=function(e,t){var n=T((e||"").trim()),i=v(t),o=Object.entries(i);if(!o.length)return{content:n,citations:[]};var s=o.filter(function(e){var t=_slicedToArray(e,1)[0];return n.includes(t)}),a=o.filter(function(e){var t=_slicedToArray(e,2),i=t[0];return t[1].isGenerated&&!n.includes(i)});if(!s.length&&!a.length)return{content:n,citations:[]};s.sort(function(e,t){var n=_slicedToArray(e,2)[1],i=_slicedToArray(t,2)[1];return n.index-i.index}),a.sort(function(e,t){var n=_slicedToArray(e,2)[1],i=_slicedToArray(t,2)[1];return n.index-i.index});var r,c=[],l=new Map,u=[],d=1,h=_createForOfIteratorHelper(s);try{for(h.s();!(r=h.n()).done;){var m=_slicedToArray(r.value,2),f=m[0],p=m[1],b=C(p,f),y=p.link||null,S=E(b,y),A=l.get(S);A||(A={referenceKey:f,referenceKeys:[],displayIndex:d++,label:b,link:y,isDownload:g(p)},l.set(S,A),c.push(A)),A.referenceKeys.push(f);var x="__CITE_".concat(A.displayIndex,"_").concat(p.index||A.displayIndex,"__");n=n.replaceAll(f,x),u.push({placeholder:x,displayIndex:A.displayIndex,label:A.label})}}catch(e){h.e(e)}finally{h.f()}for(var M=0,R=u;M').concat(e.text,""):e.text||""},M.code=function(e){var t=e.text||"",n=(e.lang||"").trim(),i=t;if("undefined"!=typeof hljs)if(n&&hljs.getLanguage(n))try{i=hljs.highlight(t,{language:n}).value}catch(e){}else try{i=hljs.highlightAuto(t).value}catch(e){}else i=h(t);var o=n?h(n):"code";return'
'.concat(o,'
').concat(i,"
")},M.image=function(e){var t=d(e.href);if(!t)return"";var n=e.text||u.generatedImageAltText,i=u.generatedImageMaxWidth;return'\n ').concat(n,'\n \n \n \n \n \n ')};var R=0,k=[];window.__chartConfigs=window.__chartConfigs||{};var P=window.CoreAIChatMarkers.findChartMarker;function B(){var e,t=_createForOfIteratorHelper(document.querySelectorAll(".generated-image-container img:not([data-broken-wired])"));try{var n=function(){var t=e.value;t.setAttribute("data-broken-wired","true"),t.addEventListener("error",function(){var e=t.closest(".generated-image-container");if(e&&!e.dataset.brokenHandled){e.dataset.brokenHandled="true",e.hidden=!0;var n=document.createElement("p");n.className="text-muted small fst-italic mb-2",n.textContent=t.alt?'(the picture "'.concat(t.alt,'" could not be loaded)'):"(that picture could not be loaded)",e.insertAdjacentElement("afterend",n)}},{once:!0})};for(t.s();!(e=t.n()).done;)n()}catch(e){t.e(e)}finally{t.f()}}function D(e){if("undefined"!=typeof document&&"function"==typeof requestAnimationFrame&&requestAnimationFrame(B),e&&e._pendingCharts&&e._pendingCharts.length){var t=_toConsumableArray(e._pendingCharts);e._pendingCharts=[],requestAnimationFrame(function(){var e,n=_createForOfIteratorHelper(t);try{for(n.s();!(e=n.n()).done;){var i=e.value;O(i.chartId,i.config)}}catch(e){n.e(e)}finally{n.f()}})}}function O(e,t){var n=document.getElementById(e);if(!n)return!1;if("undefined"==typeof Chart)return console.warn('Chart.js is not loaded. To render interactive charts, include the Chart.js library on the page (e.g., ).');\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 // A markdown table becomes a bare , which Bootstrap leaves completely unstyled: it renders\n // as cramped, borderless text that reads as plain output rather than a table. Adding the framework's\n // own classes styles it wherever Bootstrap is loaded, and the wrapper lets a wide table scroll on\n // its own instead of stretching the conversation. Markdown tables cannot nest, so the plain\n // replacement is safe.\n function styleMarkdownTables(html) {\n return html\n .replace(/
/g, '
')\n .replace(/<\\/table>/g, '
');\n }\n\n function parseMarkdownContent(content, message) {\n _pendingCharts = [];\n const html = styleMarkdownTables(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 function compactObject(source) {\n if (!source || typeof source !== 'object') {\n return {};\n }\n\n return Object.fromEntries(\n Object.entries(source).filter(([, value]) => value !== undefined)\n );\n }\n\n function resolveIndicatorTemplate(template, assistantLabel) {\n if (!template) {\n return template;\n }\n\n const encodedAssistantLabel = escapeHtmlEntities(assistantLabel || 'Assistant');\n return template.replace(/\\{\\{\\s*assistantLabel\\s*\\}\\}/g, encodedAssistantLabel);\n }\n\n const initialize = (instanceConfig) => {\n const normalizedInstanceConfig = compactObject(instanceConfig);\n const normalizedWidgetConfig = compactObject(normalizedInstanceConfig.widget);\n const config = Object.assign({}, defaultConfig, normalizedInstanceConfig);\n config.widget = Object.assign({}, defaultConfig.widget || {}, normalizedWidgetConfig);\n config.indicatorTemplate = resolveIndicatorTemplate(config.indicatorTemplate, config.assistantLabel);\n const hasWidgetConfig = !!(normalizedWidgetConfig.chatWidgetContainer && normalizedWidgetConfig.chatWidgetStateName);\n const widgetBehavior = window.coreAIChatWidgetBehavior || 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 copiedTitle: config.copiedTitle,\n isRecording: false,\n mediaRecorder: null,\n preRecordingPrompt: '',\n micButton: null,\n // Conversation mode is carried either by a realtime session or by the speech-to-text plus\n // text-to-speech cascade, never both. Dictation and spoken playback belong to the cascade.\n speechToTextEnabled: !config.realtimeEnabled && (config.chatMode === 'AudioInput' || config.chatMode === 'Conversation'),\n textToSpeechEnabled: (!config.realtimeEnabled && 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 realtimeEnabled: !!config.realtimeEnabled,\n // Server-relay WebRTC transport: primary when advertised and supported; the client falls back\n // to the WebSocket path below if the peer cannot connect.\n realtimeWebRtcEnabled: config.realtimeWebRtcEnabled === true && typeof window.RTCPeerConnection === 'function',\n // A host-supplied override. Normally the servers are fetched from the hub right before the\n // peer is created (resolveRealtimeIceServers) so configured TURN relays — and their\n // short-lived credentials — are actually used instead of a public STUN server.\n realtimeWebRtcIceServers: (Array.isArray(config.realtimeWebRtcIceServers) && config.realtimeWebRtcIceServers.length)\n ? config.realtimeWebRtcIceServers\n : null,\n realtimeVoiceName: config.realtimeVoiceName || null,\n conversationButton: null,\n realtimeHintElement: config.realtimeHintElementSelector\n ? document.querySelector(config.realtimeHintElementSelector)\n : null,\n isConversationMode: false,\n notificationDismissTimers: {},\n pendingSessionPromise: null,\n pendingSessionResolver: null,\n pendingSessionRejector: null,\n pendingSessionTimeoutId: null,\n copiedMessageIndex: -1,\n copyResetTimeoutId: null,\n activeCopyButton: 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 parsed = await readJsonResponse(response, 'Upload failed. Please try again.');\n\n if (!parsed.ok) {\n console.error('Upload failed: response was not JSON.', { status: response.status, redirected: response.redirected });\n this.uploadErrors = [{ fileName: '', error: parsed.message }];\n\n return;\n }\n\n var result = parsed.data;\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 secondParsed = await readJsonResponse(response, 'The request could not be completed.');\n\n if (!secondParsed.ok) {\n console.error('Response was not JSON.', { status: response.status, redirected: response.redirected });\n\n return;\n }\n\n var result = secondParsed.data;\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 = '
';\n html += '
';\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 += '';\n html += ' ';\n html += this.escapeHtml(name);\n html += ' ';\n html += '';\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 // The reason is shown, not hidden behind a tooltip. A pill reading \"quarterly-report-2...\"\n // tells a reader their upload failed and nothing about why, and a title attribute is\n // unreachable on a touch device -- so the one sentence that tells them what to do next\n // was the one thing the widget would not display.\n html += '';\n html += '';\n html += '';\n\n if (failedItem.fileName) {\n html += '' + this.escapeHtml(failedItem.fileName) + ': ';\n }\n\n html += this.escapeHtml(errorMsg);\n html += '';\n html += '';\n html += '';\n }\n\n if (this.isUploading) {\n html += '';\n html += ' Uploading...';\n html += '';\n }\n\n html += '';\n html += '
';\n if (config.supportedExtensionsText) {\n html += '
Supported formats: ' + this.escapeHtml(config.supportedExtensionsText) + '
';\n }\n\n html += '
';\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 // Switching to another session must not leave a prior realtime/voice session running.\n this.forceStopActiveVoice();\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 renderMessageMedia(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 // display it as the first assistant message without invoking the AI.\n if (this.messages.length === 0 && config.initialPrompt) {\n this.addMessage({\n role: 'assistant',\n content: config.initialPrompt\n });\n }\n });\n\n // Realtime lifecycle events (ReceiveRealtimeEvent, and ReceiveError while a voice session is\n // live) are handled by the shared CoreAIRealtime module — see setupRealtimeController.\n\n this.connection.on(\"ReceiveError\", (error) => {\n console.error(\"SignalR Error: \", error);\n\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // A server-side error (for example a session-start rate-limit rejection) ends the\n // in-flight request. Reject any pending new-session promise so the UI stops waiting\n // until it times out, and clear the typing indicator that a send may have shown.\n this.rejectPendingSessionRequest(error);\n this.hideTypingIndicator();\n\n if (widgetBehavior && typeof widgetBehavior.handleReceiveError === 'function') {\n widgetBehavior.handleReceiveError(this, error, config);\n } else if (!this.isNavigatingAway) {\n // Surface the message to the user instead of failing silently.\n this.addMessage(this.getErrorMessage(error));\n }\n });\n\n this.connection.on(\"ReceiveSessionStartRejected\", (reason) => {\n // A rate-limit rejection is a definitive \"wait and retry\", not a recoverable\n // session/connection error. Unblock any pending new-session request, clear the\n // typing indicator, and show the message for every host (main app and widget)\n // without triggering the widget's clear-and-retry recovery, which would wipe the\n // visitor's state and fire another throttled StartSession.\n this.rejectPendingSessionRequest(reason);\n this.hideTypingIndicator();\n\n if (!this.isNavigatingAway) {\n this.addMessage(this.getErrorMessage(reason));\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, '>');\n var html = '

' + escaped + '

';\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, turnId, text) => {\n // Realtime creates the chat session server-side; adopt its id (and update the page URL)\n // on the first turn so a refresh reloads the conversation instead of starting fresh.\n if (sessionId && this.getSessionId() !== sessionId) {\n this.initializeSession(sessionId);\n }\n\n // Realtime: a placeholder for this turn was already inserted in the right position when\n // the utterance was captured (see user_turn_pending), so just fill in its text.\n if (turnId && this._realtimePendingTurns && this._realtimePendingTurns[turnId]) {\n var pending = this._realtimePendingTurns[turnId];\n delete this._realtimePendingTurns[turnId];\n this.stopAudio();\n this.fillRealtimePendingTurn(pending, text);\n\n return;\n }\n\n if (text) {\n this.stopAudio();\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '

' + escaped + '

';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else if (this._conversationAssistantMessage) {\n // Realtime: the user's transcript lags the assistant's reply for the SAME turn (the\n // model answers the audio before speech-to-text finishes). Insert the user message\n // just before the streaming assistant message so the order stays You -> Assistant,\n // and keep that message streaming — ending it here split one reply into two bubbles\n // above the prompt.\n var at = this._conversationAssistantMessage.index;\n var userMsg = { role: 'user', content: text, rawContent: text, userRating: null, references: {} };\n updateMessagePresentation(userMsg, userMsg.references);\n this.messages.splice(at, 0, userMsg);\n this._conversationAssistantMessage.index = at + 1;\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 // A new response id means a new turn — finalize the previous assistant message so two replies\n // never merge into one bubble (also covers barge-in, which starts a fresh response).\n if (this._conversationAssistantMessage && this._conversationAssistantResponseId && responseId && this._conversationAssistantResponseId !== responseId) {\n var prev = this.messages[this._conversationAssistantMessage.index];\n if (prev) { prev.isStreaming = false; }\n this._conversationAssistantMessage = null;\n }\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 this._conversationAssistantResponseId = responseId;\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 renderMessageMedia(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 this._conversationAssistantResponseId = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (sessionId, base64Audio, contentType) => {\n if (!base64Audio) {\n return;\n }\n\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\n // Realtime audio arrives as raw PCM16 (WebSocket transport) and is scheduled for immediate\n // playback by the shared module; conversation/TTS audio (mp3/wav) is collected and played on\n // complete.\n if (contentType === 'audio/pcm') {\n if (this.realtimeController) { this.realtimeController.receivePcm(bytes); }\n } else {\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 // The realtime session lived inside the dropped connection; it cannot survive a reconnect.\n if (this.realtimeEnabled && this.isConversationMode) {\n this.stopRealtimeConversation();\n }\n });\n\n this.connection.onreconnected(() => {\n console.info(\"SignalR: reconnected.\");\n\n if (this.isSessionStarted) {\n this.reloadCurrentSession();\n }\n });\n\n this.connection.onclose((error) => {\n if (this.isNavigatingAway) {\n return;\n }\n\n if (this.realtimeEnabled && this.isConversationMode) {\n this.stopRealtimeConversation();\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 async ensureConnectionStarted() {\n if (!this.connection) {\n return false;\n }\n\n var states = signalR.HubConnectionState;\n if (this.connection.state === states.Connected) {\n return true;\n }\n\n // If the initial start failed or has not begun, start it now.\n if (this.connection.state === states.Disconnected) {\n try {\n await this.connection.start();\n } catch (err) {\n console.error(\"SignalR Connection Error: \", err);\n }\n\n return this.connection.state === states.Connected;\n }\n\n // The connection is still Connecting or Reconnecting: wait for it to settle so callers\n // (e.g. starting a realtime session) do not send before the socket is ready.\n return await new Promise((resolve) => {\n var settle = (value) => {\n clearTimeout(timeoutId);\n clearInterval(intervalId);\n resolve(value);\n };\n var timeoutId = setTimeout(() => settle(this.connection.state === states.Connected), 10000);\n var intervalId = setInterval(() => {\n if (this.connection.state === states.Connected) {\n settle(true);\n } else if (this.connection.state === states.Disconnected) {\n settle(false);\n }\n }, 100);\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(\"addingCoreAIPromotMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedCoreAIPromotMessage\", { 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 renderMessageMedia(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 // A live voice session and a typed turn are two writers into one chat session, and they\n // would interleave. End the session first; the turns it already produced are persisted, so\n // the typed message simply continues the same thread.\n this.forceStopActiveVoice();\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 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\n // Capture raw 16 kHz PCM (16-bit mono) via Web Audio instead of MediaRecorder.\n // Browsers only agree on WebM/Opus for MediaRecorder, and Azure's speech SDK cannot\n // demux that container from a streaming push (it fails inside GStreamer). Raw PCM is\n // decoded natively with no GStreamer and is produced identically by every browser.\n this._sttCapture = this._createPcmCapture(stream, (base64) => {\n try { subject.next(base64); } catch (err) { /* completed */ }\n });\n this._sttSubject = subject;\n\n var rate = (this._sttCapture && this._sttCapture.sampleRate) || 16000;\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"SendAudioStream\", profileId, sessionId, subject, \"audio/pcm;rate=\" + rate, language);\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) {\n return;\n }\n\n this._stopPcmCapture(this._sttCapture);\n this._sttCapture = null;\n if (this._sttSubject) {\n try { this._sttSubject.complete(); } catch (err) { /* already completed */ }\n this._sttSubject = null;\n }\n this.isRecording = false;\n this.updateMicButton();\n },\n // Captures microphone audio as raw 16 kHz, 16-bit mono PCM using Web Audio and invokes\n // onChunk(base64Pcm, rms) for each block. Returns a handle for _stopPcmCapture. This replaces\n // MediaRecorder so every browser streams a format Azure decodes without GStreamer.\n _createPcmCapture(stream, onChunk) {\n var AudioCtx = window.AudioContext || window.webkitAudioContext;\n // Ask the browser to resample the mic to 16 kHz; fall back to manual resampling if it will not.\n var audioContext;\n try {\n audioContext = new AudioCtx({ sampleRate: 16000 });\n } catch (e) {\n audioContext = new AudioCtx();\n }\n var srcRate = audioContext.sampleRate;\n var source = audioContext.createMediaStreamSource(stream);\n var processor = audioContext.createScriptProcessor(4096, 1, 1);\n var self = this;\n processor.onaudioprocess = function (e) {\n var input = e.inputBuffer.getChannelData(0);\n var pcm16 = self._downsampleToInt16(input, srcRate, 16000);\n if (!pcm16 || pcm16.length === 0) {\n return;\n }\n var sum = 0;\n for (var i = 0; i < pcm16.length; i++) {\n var v = pcm16[i] / 32768;\n sum += v * v;\n }\n var rms = Math.sqrt(sum / pcm16.length);\n var bytes = new Uint8Array(pcm16.buffer);\n var binary = '';\n for (var j = 0; j < bytes.length; j++) {\n binary += String.fromCharCode(bytes[j]);\n }\n onChunk(btoa(binary), rms);\n };\n source.connect(processor);\n // Some browsers only fire onaudioprocess while the node is connected to a destination.\n processor.connect(audioContext.destination);\n return { audioContext: audioContext, source: source, processor: processor, stream: stream, sampleRate: 16000 };\n },\n _stopPcmCapture(capture) {\n if (!capture) {\n return;\n }\n try { if (capture.processor) { capture.processor.onaudioprocess = null; capture.processor.disconnect(); } } catch (e) { }\n try { if (capture.source) { capture.source.disconnect(); } } catch (e) { }\n try { if (capture.stream) { capture.stream.getTracks().forEach(function (t) { t.stop(); }); } } catch (e) { }\n try { if (capture.audioContext) { capture.audioContext.close(); } } catch (e) { }\n },\n // Converts a Float32 sample block to 16-bit PCM, resampling from srcRate to dstRate when needed.\n _downsampleToInt16(input, srcRate, dstRate) {\n var s, i;\n if (!(dstRate < srcRate)) {\n var same = new Int16Array(input.length);\n for (i = 0; i < input.length; i++) {\n s = Math.max(-1, Math.min(1, input[i]));\n same[i] = s < 0 ? s * 0x8000 : s * 0x7FFF;\n }\n return same;\n }\n var ratio = srcRate / dstRate;\n var newLen = Math.floor(input.length / ratio);\n var out = new Int16Array(newLen);\n for (var j = 0; j < newLen; j++) {\n var idx = j * ratio;\n var i0 = Math.floor(idx);\n var i1 = (i0 + 1 < input.length) ? i0 + 1 : input.length - 1;\n var frac = idx - i0;\n s = input[i0] * (1 - frac) + input[i1] * frac;\n s = Math.max(-1, Math.min(1, s));\n out[j] = s < 0 ? s * 0x8000 : s * 0x7FFF;\n }\n return out;\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 = '';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '';\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 renderMessageMedia(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 getErrorMessage(error) {\n var content = (typeof error === 'string' && error.trim())\n ? error\n : \"Something went wrong. Please try again.\";\n\n return {\n role: \"assistant\",\n content: content,\n htmlContent: \"\",\n };\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 renderMessageMedia(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\n button.classList.toggle('tts-playing', isPlaying);\n button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');\n });\n },\n updateCopyButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-copy-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-copy-message-index'));\n var isCopied = buttonIndex === this.copiedMessageIndex;\n var iconHtml = isCopied\n ? ''\n : '';\n\n button.classList.toggle('text-success', isCopied);\n button.classList.toggle('text-secondary', !isCopied);\n button.setAttribute('title', isCopied ? this.copiedTitle : this.copyTitle);\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\n });\n },\n setCopyButtonState(button, isCopied) {\n if (!button) {\n return;\n }\n\n var iconHtml = isCopied\n ? ''\n : '';\n\n button.classList.toggle('text-success', isCopied);\n button.classList.toggle('text-secondary', !isCopied);\n button.setAttribute('title', isCopied ? this.copiedTitle : this.copyTitle);\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\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 // A live voice session takes the message box away and puts the audio settings in its place; ending\n // the session gives it back. Sending a typed message already force-stopped the session, so the box\n // was never a way to say something *during* one -- hiding it only makes that honest, and frees the\n // row for the gear. Both transports land here: realtime through the module's onActivate, the\n // speech-to-text cascade through startConversationMode.\n // The realtime module inserts its settings popover directly after the button it was handed, and\n // hard-codes the element id. A page can host two chat clients at once -- this one and the admin\n // widget -- so that id is not unique and getElementById would hand the widget the page's gear.\n // Each client finds its own next to its own button.\n voiceSettingsElement() {\n var next = this.conversationButton && this.conversationButton.nextElementSibling;\n\n return next && next.id === 'realtime-audio-settings' ? next : null;\n },\n setVoiceSessionLive(live) {\n if (this.inputElement) {\n this.inputElement.hidden = live;\n }\n\n if (this.buttonElement) {\n this.buttonElement.hidden = live;\n }\n\n // With the message box gone the button would otherwise sit at its natural width in an empty\n // row, so it takes the space the box left behind and reads as the thing now in charge. The\n // settings popover does not grow, so it stays at the right-hand end.\n if (this.conversationButton) {\n this.conversationButton.classList.toggle('flex-grow-1', live);\n }\n\n // The gear is built by the realtime module next to its button, and only in realtime mode, so\n // it is absent on the cascade. It belongs to a live session rather than to the surface.\n var audioSettings = this.voiceSettingsElement();\n if (audioSettings) {\n audioSettings.hidden = !live;\n }\n\n var hint = this.realtimeHintElement;\n if (hint) {\n hint.classList.toggle('d-none', !live);\n }\n },\n toggleConversationMode() {\n if (this.realtimeEnabled) {\n // Realtime is driven by the shared module, which owns the button; this only exists for\n // callers that toggle programmatically.\n if (this.realtimeController) { this.realtimeController.toggle(); }\n\n return;\n }\n\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n // Force-stop any in-progress voice/realtime session (mic, playback, and the streamed audio),\n // e.g. before starting a new chat or switching sessions, so it never keeps running in the background.\n forceStopActiveVoice() {\n if (!this.isConversationMode) {\n return;\n }\n if (this.realtimeEnabled) {\n this.stopRealtimeConversation();\n } else {\n this.stopConversationMode();\n }\n },\n startRealtimeConversation() {\n if (this.realtimeController) { this.realtimeController.start(); }\n },\n stopRealtimeConversation() {\n if (this.realtimeController) { this.realtimeController.stop(); }\n },\n // Realtime (speech-to-speech) is the shared CoreAIRealtime module (realtime-audio.js): microphone\n // capture and gating, the WebRTC transport with its WebSocket fallback, playback, the settings\n // popover, push-to-talk, and the server-driven session lifecycle all live there, so this app and the\n // chat-interaction client cannot drift apart. What is wired here is only how the module reaches this\n // app's hub and transcript.\n setupRealtimeController(config) {\n if (this.realtimeController || !this.conversationButton) { return; }\n if (!window.CoreAIRealtime || typeof window.CoreAIRealtime.attach !== 'function') {\n console.error('realtime-audio.js is not loaded; realtime voice is unavailable on this page.');\n\n return;\n }\n\n var self = this;\n this.realtimeController = window.CoreAIRealtime.attach({\n connection: this.connection,\n ensureConnected: function () {\n return self.ensureConnectionStarted().then(function (connected) {\n if (!connected) { throw new Error('The chat connection is not available.'); }\n\n return connected;\n });\n },\n sendStart: function (subject, voice, language, silenceMs, vadThreshold, allowInterruption) {\n self.connection.send('StartRealtimeConversation', self.getProfileId(), self.getSessionId() || '', subject, voice, language, silenceMs, vadThreshold, allowInterruption);\n },\n webRtcEnabled: this.realtimeWebRtcEnabled,\n sendStartWebRtc: function (offerSdp, voice, language, silenceMs, vadThreshold, allowInterruption) {\n self.connection.send('StartRealtimeWebRtc', self.getProfileId(), self.getSessionId() || '', offerSdp, voice, language, silenceMs, vadThreshold, allowInterruption);\n },\n webRtcIceServers: this.realtimeWebRtcIceServers || undefined,\n voiceName: this.realtimeVoiceName || '',\n getVoiceName: function () { return self.realtimeVoiceName || ''; },\n realtimeEnabled: true,\n // The conversation button doubles as the realtime button on this host; the module owns its\n // click, label and state from here on.\n //\n // input and sendButton are deliberately not handed over. The module hides every control it\n // is given when realtime takes over, and typing has to stay available during a voice\n // conversation -- that is the whole feature.\n //\n // conversationButton is not handed over either. It is the same element as the realtime\n // button here, and the module hides the conversation button before showing the realtime\n // one -- naming it twice would ask it to hide the control it then has to show.\n selectors: {\n realtimeButton: config.conversationButtonElementSelector,\n micButton: config.micButtonElementSelector\n },\n // The module owns whether a session is live, so the message box follows its flag rather\n // than this app's copy of it. Losing one of these events used to leave the box hidden\n // under a button that had already gone back to \"Start speaking\".\n onSessionStateChanged: function (active) {\n self.setVoiceSessionLive(active);\n },\n onActivate: function () {\n self.isConversationMode = true;\n self._conversationAssistantMessage = null;\n self._conversationPartialMessage = null;\n self.removeNotification('conversation-ended');\n },\n onDeactivate: function () {\n self.isConversationMode = false;\n self.finishRealtimeConversationCleanup();\n },\n onUserTurnPending: function (turnId) { self.addRealtimePendingTurn(turnId); },\n onUserTurnDropped: function (turnId) { self.dropRealtimePendingTurn(turnId); }\n });\n },\n // Shared teardown tail: clears any in-flight streaming state and shows the conversation-ended\n // notification.\n finishRealtimeConversationCleanup() {\n if (this._conversationAssistantMessage) {\n var m = this.messages[this._conversationAssistantMessage.index];\n if (m) { m.isStreaming = false; }\n this._conversationAssistantMessage = null;\n }\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) { this.messages[i].isStreaming = false; }\n }\n\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 // The utterance has been captured but not transcribed yet. Showing a placeholder now puts the\n // prompt above the reply it produces: transcription lags the spoken answer, so a bubble added only\n // when the text arrives lands underneath its own reply.\n addRealtimePendingTurn(turnId) {\n if (!turnId) { return; }\n this._realtimePendingTurns = this._realtimePendingTurns || {};\n var index = this.messages.length;\n this.addMessage({ role: 'user', content: '', isPartial: true });\n this._realtimePendingTurns[turnId] = this.messages[index];\n },\n fillRealtimePendingTurn(pending, text) {\n if (!pending) { return; }\n if (!text) {\n var emptyAt = this.messages.indexOf(pending);\n if (emptyAt >= 0) { this.messages.splice(emptyAt, 1); }\n\n return;\n }\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n pending.content = text;\n pending.htmlContent = '

' + escaped + '

';\n pending.isPartial = false;\n },\n dropRealtimePendingTurn(turnId) {\n if (!turnId || !this._realtimePendingTurns) { return; }\n var dropped = this._realtimePendingTurns[turnId];\n if (!dropped) { return; }\n delete this._realtimePendingTurns[turnId];\n var at = this.messages.indexOf(dropped);\n if (at >= 0) { this.messages.splice(at, 1); }\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 this._conversationSubject = new signalR.Subject();\n this._conversationStream = stream;\n\n // RMS (0..1) above which speech during TTS playback counts as an interrupt.\n var interruptRmsThreshold = 0.12;\n\n // Capture raw 16 kHz PCM (16-bit mono) via Web Audio instead of MediaRecorder — see\n // startRecording for why WebM/Opus is avoided. The per-block RMS drives interrupt\n // detection during TTS playback, replacing the previous AnalyserNode.\n this._conversationCapture = this._createPcmCapture(stream, (base64, rms) => {\n if (this.isPlayingAudio && rms >= interruptRmsThreshold) {\n // User is speaking over TTS — interrupt playback.\n this.stopAudio();\n }\n try {\n this._conversationSubject.next(base64);\n } catch (err) {\n // Subject may have been completed already.\n }\n });\n\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var language = navigator.language || document.documentElement.lang || 'en-US';\n var rate = (this._conversationCapture && this._conversationCapture.sampleRate) || 16000;\n\n this.connection.send(\"StartConversation\", profileId, sessionId, this._conversationSubject, \"audio/pcm;rate=\" + rate, language);\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) {\n this._stopPcmCapture(this._conversationCapture);\n this._conversationCapture = null;\n if (this._conversationSubject) {\n try { this._conversationSubject.complete(); } catch (err) { /* already completed */ }\n }\n this.isRecording = false;\n }\n\n this.stopAudio();\n this._conversationPartialTranscript = '';\n this._conversationPartialMessage = null;\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 // Force-stop an in-progress voice/realtime conversation so it doesn't keep running under the new session.\n this.forceStopActiveVoice();\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\n // When an initial prompt is configured, show it as the first\n // assistant message instead of the generic placeholder.\n if (config.initialPrompt) {\n this.addMessage({\n role: 'assistant',\n content: config.initialPrompt\n });\n } else {\n this.showPlaceholder();\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 // Force-stop any live voice/realtime session before starting a new chat.\n this.forceStopActiveVoice();\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 }\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 const initialMessages = Array.isArray(config.messages) ? config.messages : [];\n\n for (let i = 0; i < initialMessages.length; i++) {\n this.addMessage(initialMessages[i]);\n }\n\n // When no messages were loaded and an initial prompt is configured,\n // display it as the first assistant message without invoking the AI.\n if (this.messages.length === 0 && config.initialPrompt) {\n this.addMessage({\n role: 'assistant',\n content: config.initialPrompt\n });\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 = ' ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '';\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 (used for both STT/TTS conversation and realtime).\n if ((this.conversationModeEnabled || this.realtimeEnabled) && config.conversationButtonElementSelector) {\n this.conversationButton = document.querySelector(config.conversationButtonElementSelector);\n if (this.conversationButton) {\n if (this.realtimeEnabled) {\n // The shared realtime module owns the button (click, label, state) and adds the\n // voice settings popover next to it.\n this.setupRealtimeController(config);\n\n // The module reveals the gear as soon as the surface enters realtime mode, but it\n // belongs to a live session. The watcher that would hide it only runs on a change,\n // so the idle state has to be stated once here.\n this.setVoiceSessionLive(false);\n } else {\n this.conversationButton.addEventListener('click', () => {\n this.toggleConversationMode();\n });\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(\"initializingSessionCoreAIChat\", { 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 // For non-widget pages, update the browser URL so that a page\n // refresh reloads the correct session instead of starting fresh.\n if (!hasWidgetConfig && sessionId && config.sessionUrlTemplate && typeof history !== 'undefined' && history.replaceState) {\n var sessionUrl = config.sessionUrlTemplate.replace('{sessionId}', encodeURIComponent(sessionId));\n history.replaceState(null, '', sessionUrl);\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 clearCopiedMessageState() {\n if (this.copyResetTimeoutId) {\n window.clearTimeout(this.copyResetTimeoutId);\n this.copyResetTimeoutId = null;\n }\n\n if (this.activeCopyButton) {\n this.setCopyButtonState(this.activeCopyButton, false);\n this.activeCopyButton = null;\n }\n\n this.copiedMessageIndex = -1;\n },\n copyResponse(message, index, event) {\n const text = message && typeof message === 'object'\n ? message.copyContent ?? message.content ?? ''\n : message ?? '';\n const button = event?.currentTarget || event?.target?.closest?.('[data-copy-message-index]') || null;\n\n navigator.clipboard.writeText(text)\n .then(() => {\n this.clearCopiedMessageState();\n this.copiedMessageIndex = typeof index === 'number' ? index : -1;\n this.activeCopyButton = button;\n\n if (button) {\n this.setCopyButtonState(button, true);\n } else {\n this.$nextTick(() => this.updateCopyButtons());\n }\n\n this.copyResetTimeoutId = window.setTimeout(() => {\n this.clearCopiedMessageState();\n this.$nextTick(() => this.updateCopyButtons());\n }, Number(config.copyResetDelayMs) || 2000);\n })\n .catch(err => console.error('Failed to copy response:', err));\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 copiedMessageIndex() {\n this.$nextTick(() => this.updateCopyButtons());\n },\n isConversationMode(active) {\n // The dictation microphone is hidden while a voice conversation runs: the conversation\n // already owns the microphone, and a second one would mean something different.\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n // The message box and the send button give way to the voice settings while the conversation\n // runs, and come back when it ends. Both kinds of turn still land in the same thread; what\n // they cannot do is overlap.\n //\n // Only the cascade is driven from here. Realtime follows the module's own session flag\n // (onSessionStateChanged), so the two never disagree about whether a session is live.\n if (!this.realtimeEnabled) {\n this.setVoiceSessionLive(active);\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 this.$nextTick(() => {\n this.updateCopyButtons();\n refreshFontAwesomeIcons(this.$el);\n this.fontAwesomeObserver = observeFontAwesomeIcons(this.$el);\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 if (this.fontAwesomeObserver) {\n this.fontAwesomeObserver.disconnect();\n this.fontAwesomeObserver = null;\n }\n\n this.clearCopiedMessageState();\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 const autoInitializeSelector = '[data-coreai-chat-config],[data-coreai-chat-app-element-selector]';\n\n function getAttributeValue(element, attributeName) {\n const value = element.getAttribute(attributeName);\n return value === null || value === '' ? null : value;\n }\n\n function parseBooleanAttributeValue(value) {\n if (value === null || value === undefined) {\n return null;\n }\n\n if (typeof value === 'boolean') {\n return value;\n }\n\n const normalized = String(value).trim().toLowerCase();\n if (normalized === 'true') {\n return true;\n }\n\n if (normalized === 'false') {\n return false;\n }\n\n return null;\n }\n\n function parseJsonAttribute(element, attributeName, description) {\n const rawValue = getAttributeValue(element, attributeName);\n if (!rawValue) {\n return null;\n }\n\n try {\n return JSON.parse(rawValue);\n } catch (error) {\n console.error('Failed to parse ' + description + ' JSON.', error);\n return null;\n }\n }\n\n function buildConfigFromDataAttributes(element, options) {\n const settings = options || {};\n\n if (element.hasAttribute('data-coreai-chat-widget-container-selector') && settings.allowWidgetHost !== true) {\n return null;\n }\n\n const appElementSelector = getAttributeValue(element, 'data-coreai-chat-app-element-selector');\n if (!appElementSelector) {\n return null;\n }\n\n const config = {\n signalRHubUrl: getAttributeValue(element, 'data-coreai-chat-signalr-hub-url'),\n appElementSelector: appElementSelector,\n chatContainerElementSelector: getAttributeValue(element, 'data-coreai-chat-container-element-selector'),\n inputElementSelector: getAttributeValue(element, 'data-coreai-chat-input-element-selector'),\n sendButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-send-button-element-selector'),\n placeholderElementSelector: getAttributeValue(element, 'data-coreai-chat-placeholder-element-selector'),\n messages: parseJsonAttribute(element, 'data-coreai-chat-messages', 'CoreAI chat messages') ?? undefined,\n chatMode: getAttributeValue(element, 'data-coreai-chat-mode'),\n micButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-mic-button-element-selector'),\n conversationButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-conversation-button-element-selector'),\n realtimeHintElementSelector: getAttributeValue(element, 'data-coreai-chat-realtime-hint-element-selector'),\n ttsVoiceName: getAttributeValue(element, 'data-coreai-chat-tts-voice-name'),\n realtimeVoiceName: getAttributeValue(element, 'data-coreai-chat-realtime-voice-name'),\n documentBarSelector: getAttributeValue(element, 'data-coreai-chat-document-bar-selector'),\n uploadDocumentUrl: getAttributeValue(element, 'data-coreai-chat-upload-document-url'),\n removeDocumentUrl: getAttributeValue(element, 'data-coreai-chat-remove-document-url'),\n allowedExtensions: getAttributeValue(element, 'data-coreai-chat-allowed-extensions'),\n supportedExtensionsText: getAttributeValue(element, 'data-coreai-chat-supported-extensions-text'),\n existingDocuments: parseJsonAttribute(element, 'data-coreai-chat-existing-documents', 'CoreAI chat existing documents') ?? undefined,\n initialPrompt: getAttributeValue(element, 'data-coreai-chat-initial-prompt'),\n sessionUrlTemplate: getAttributeValue(element, 'data-coreai-chat-session-url-template'),\n userLabel: getAttributeValue(element, 'data-coreai-chat-user-label'),\n assistantLabel: getAttributeValue(element, 'data-coreai-chat-assistant-label'),\n copyTitle: getAttributeValue(element, 'data-coreai-chat-copy-title'),\n copiedTitle: getAttributeValue(element, 'data-coreai-chat-copied-title'),\n };\n\n const booleanAttributes = {\n metricsEnabled: 'data-coreai-chat-metrics-enabled',\n textToSpeechEnabled: 'data-coreai-chat-text-to-speech-enabled',\n sessionDocumentsEnabled: 'data-coreai-chat-session-documents-enabled',\n singleResponseMode: 'data-coreai-chat-single-response-mode',\n realtimeEnabled: 'data-coreai-chat-realtime-enabled',\n realtimeWebRtcEnabled: 'data-coreai-chat-realtime-webrtc-enabled',\n };\n\n Object.keys(booleanAttributes).forEach(key => {\n const parsed = parseBooleanAttributeValue(getAttributeValue(element, booleanAttributes[key]));\n if (parsed !== null) {\n config[key] = parsed;\n }\n });\n\n return compactObject(config);\n }\n\n function buildConfigFromElement(element, options) {\n const jsonConfig = parseJsonAttribute(element, 'data-coreai-chat-config', 'CoreAI chat config');\n const attributeConfig = buildConfigFromDataAttributes(element, options);\n\n if (!jsonConfig && !attributeConfig) {\n return null;\n }\n\n return Object.assign({}, jsonConfig || {}, attributeConfig || {});\n }\n\n function initializeFromElement(element) {\n if (!element || element.dataset.coreAiChatInitialized === 'true') {\n return element ? element.__coreAIChatApp || null : null;\n }\n\n const config = buildConfigFromElement(element);\n if (!config) {\n return null;\n }\n\n const app = initialize(config);\n if (!app) {\n return null;\n }\n\n element.dataset.coreAiChatInitialized = 'true';\n element.__coreAIChatApp = app;\n\n return app;\n }\n\n function scanForAutoInitialization(root) {\n if (!root || typeof root.querySelectorAll !== 'function') {\n return;\n }\n\n if (typeof root.matches === 'function' && root.matches(autoInitializeSelector)) {\n initializeFromElement(root);\n }\n\n root.querySelectorAll(autoInitializeSelector).forEach(initializeFromElement);\n }\n\n function startAutoInitialization() {\n scanForAutoInitialization(document);\n\n if (typeof MutationObserver === 'undefined') {\n return;\n }\n\n const observer = new MutationObserver(mutations => {\n mutations.forEach(mutation => {\n mutation.addedNodes.forEach(node => {\n if (node && node.nodeType === 1) {\n scanForAutoInitialization(node);\n }\n });\n });\n });\n\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n });\n }\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', startAutoInitialization, { once: true });\n } else {\n startAutoInitialization();\n }\n\n return {\n initialize: initialize,\n initializeFromElement: initializeFromElement,\n buildConfigFromElement: buildConfigFromElement,\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 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"]} +{"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","_toConsumableArray","_arrayWithoutHoles","_iterableToArray","_unsupportedIterableToArray","_nonIterableSpread","Array","from","isArray","_arrayLikeToArray","_objectWithoutProperties","_objectWithoutPropertiesLoose","getOwnPropertySymbols","indexOf","propertyIsEnumerable","hasOwnProperty","_createForOfIteratorHelper","_n","F","s","next","asyncGeneratorStep","Promise","resolve","then","_asyncToGenerator","arguments","apply","_next","_throw","_slicedToArray","_arrayWithHoles","_iterableToArrayLimit","_nonIterableRest","toString","slice","constructor","name","test","push","_typeof","window","coreAIChatManager","_window$CoreAIChatMar","_window$CoreAIChatMar2","_window$CoreAIChatMar3","_window$CoreAIChatMar4","_window$CoreAIChatMar5","_window$CoreAIChatMar6","_window$CoreAIChatMar7","_window$CoreAIChatMar8","_window$CoreAIChatMar9","_window$CoreAIChatMar0","defaultConfig","generatedImageAltText","generatedImageMaxWidth","downloadImageTitle","downloadChartTitle","downloadChartButtonText","userLabel","assistantLabel","thumbsUpTitle","thumbsDownTitle","copyTitle","copiedTitle","codeCopiedText","copyResetDelayMs","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","refreshFontAwesomeIcons","root","fontAwesome","FontAwesome","nodeType","selector","matches","querySelector","containsFontAwesomePlaceholders","dom","i2svg","node","observeFontAwesomeIcons","MutationObserver","observer","mutations","forEach","mutation","addedNodes","observe","childList","subtree","normalizeReference","reference","_ref","_normalized$index","_ref2","_normalized$text","_ref3","_normalized$title","_ref4","_normalized$link","_ref5","_normalized$reference","_normalized$isGenerat","_normalized$isImage","normalized","assign","index","Index","Text","title","Title","link","Link","referenceType","ReferenceType","isGenerated","IsGenerated","isImage","IsImage","isDownloadCitationReference","toLowerCase","normalizeReferences","references","_i","_Object$entries","entries","_normalizeReference","_Object$entries$_i","key","readJsonResponse","_x","_x2","_readJsonResponse","_callee0","response","fallbackMessage","message","_t6","_context0","headers","get","redirected","ok","data","json","expandImageMarkers","CoreAIChatMarkers","getCitationLabel","unmergedCitationCount","citationIdentity","concat","splitCombinedCitations","content","collapseRepeatedCitations","html","separateAdjacentCitations","citationMarkerHtml","displayIndex","updateMessagePresentation","messageReferences","rawContent","displayContent","citationDisplay","processedContent","referenceEntries","citations","citedRefs","filter","_ref6","includes","generatedRefs","_ref8","_ref9","sort","_ref0","_ref1","b","_ref12","_ref13","_step","citationsByIdentity","Map","placeholders","_iterator","_step$value","label","identity","citation","referenceKey","referenceKeys","isDownload","set","placeholder","replaceAll","err","_i2","_placeholders","entry","_step2","_iterator2","_step2$value","map","_ref16","buildCitationDisplay","citationReferences","copyContent","_step3","_iterator3","_citation$referenceKe","_step5","_iterator5","_step4","_iterator4","trimEnd","buildCopyContent","htmlContent","parseMarkdownContent","renderer","marked","Renderer","href","code","lang","highlighted","hljs","getLanguage","highlight","language","_","highlightAuto","langDisplay","image","src","alt","maxWidth","chartCounter","_pendingCharts","__chartConfigs","findChartMarker","wireImageZoom","mediumZoom","images","querySelectorAll","_step6","_iterator6","setAttribute","margin","background","wireBrokenImageHandlers","_step7","_iterator7","_loop","addEventListener","container","closest","dataset","brokenHandled","hidden","note","className","insertAdjacentElement","once","renderMessageMedia","requestAnimationFrame","charts","_step8","_iterator8","renderChartOnCanvas","chartId","config","canvas","getElementById","Chart","console","warn","offsetParent","_cfg$options","_cfg$options2","_cfg$options2$aspectR","_chartInstance","destroy","cfg","JSON","parse","options","responsive","maintainAspectRatio","aspectRatio","error","replace","styleMarkdownTables","DOMPurify","sanitize","ADD_TAGS","ADD_ATTR","compactObject","source","fromEntries","_ref17","undefined","use","extensions","level","start","idx","tokenizer","extracted","startIndex","type","raw","substring","endIndex","token","renderPendingCharts","configs","_i3","_Object$keys","keys","initialize","instanceConfig","normalizedInstanceConfig","normalizedWidgetConfig","template","encodedAssistantLabel","resolveIndicatorTemplate","hasWidgetConfig","widgetBehavior","coreAIChatWidgetBehavior","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","realtimeEnabled","chatMode","textToSpeechEnabled","ttsVoiceName","audioChunks","audioPlayQueue","isPlayingAudio","currentAudioElement","currentAudioUrl","ttsButton","ttsPlayingMessageIndex","ttsAudioCache","ttsInstanceId","Math","random","singleResponseMode","conversationModeEnabled","realtimeWebRtcEnabled","RTCPeerConnection","realtimeWebRtcIceServers","realtimeVoiceName","conversationButton","realtimeHintElement","realtimeHintElementSelector","isConversationMode","notificationDismissTimers","pendingSessionPromise","pendingSessionResolver","pendingSessionRejector","pendingSessionTimeoutId","copiedMessageIndex","copyResetTimeoutId","activeCopyButton","computed","lastAssistantIndex","role","methods","handleBeforeUnload","handleDragOver","sessionDocumentsEnabled","preventDefault","stopPropagation","inputArea","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","errorText","uploadError","parsed","result","_t","_t2","_context2","getSessionId","getProfileId","ensureSessionForDocuments","fileName","renderDocumentBar","FormData","append","fetch","method","body","extractReadableErrorMessage","status","initializeSession","uploaded","failed","reloadCurrentSession","removeDocument","doc","_this2","_callee5","_context5","removeDocumentUrl","_callee4","secondParsed","removeError","_t3","_context4","stringify","itemId","documentId","splice","formatFileSize","bytes","toFixed","escapeHtml","failedItem","errorMsg","supportedExtensionsText","replaceChildren","RETURN_DOM_FRAGMENT","closeButtons","j","docToRemove","parseInt","getAttribute","errorCloseButtons","addBtn","div","startsWith","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","forceStopActiveVoice","msg","addMessage","$nextTick","refreshAllFeedbackIcons","initialPrompt","stopRecording","rejectPendingSessionRequest","hideTypingIndicator","handleReceiveError","getErrorMessage","reason","messageId","userRating","find","id","isFinal","_conversationPartialTranscript","_conversationPartialMessage","hidePlaceholder","isPartial","scrollToBottom","_audioInputSent","dispatchEvent","Event","turnId","_realtimePendingTurns","pending","stopAudio","fillRealtimePendingTurn","escaped","_conversationAssistantMessage","at","userMsg","responseId","_conversationAssistantResponseId","prev","msgIndex","newMessage","base64Audio","contentType","binaryString","atob","Uint8Array","charCodeAt","realtimeController","receivePcm","playCollectedAudio","notification","receiveNotification","updateNotification","notificationType","removeNotification","onreconnecting","stopRealtimeConversation","onreconnected","info","onclose","ensureConnectionStarted","_this4","_callee7","states","_t5","_context7","HubConnectionState","state","Connected","Disconnected","settle","clearTimeout","timeoutId","clearInterval","intervalId","setTimeout","setInterval","addMessageInternal","_this5","fireEvent","CustomEvent","_message$rawContent","_this6","addMessages","_this7","showPlaceholder","isOrchestratorAvailable","applyOrchestratorAvailability","unavailableMessage","orchestratorUnavailableMessage","disabled","micButtonElement","style","display","conversationButtonElement","event","isIndicator","sendMessage","trimmedPrompt","streamMessage","startRecording","_this8","navigator","mediaDevices","getUserMedia","audio","echoCancellation","noiseSuppression","autoGainControl","subject","Subject","_sttCapture","_createPcmCapture","base64","_sttSubject","rate","sampleRate","documentElement","send","updateMicButton","_stopPcmCapture","complete","onChunk","audioContext","AudioCtx","AudioContext","webkitAudioContext","srcRate","createMediaStreamSource","processor","createScriptProcessor","onaudioprocess","input","inputBuffer","getChannelData","pcm16","_downsampleToInt16","sum","rms","sqrt","buffer","binary","String","fromCharCode","btoa","connect","destination","capture","disconnect","getTracks","stop","close","dstRate","same","Int16Array","max","min","ratio","newLen","floor","out","i0","i1","frac","toggleRecording","sessionProfileId","_this9","dispose","streamingStarted","showTypingIndicator","lastResponseId","messageIndex","currentSessionId","subscribe","chunk","_i4","_Object$entries2","_normalizeReference2","_Object$entries2$_i","_this9$stream","processReferences","streamingFinished","synthesizeSpeech","_this9$stream2","getServiceDownMessage","_this0","_ref22","_message$rawContent2","stopIcon","startIcon","removeAttribute","focus","icons","handleExternalTtsStop","_e$detail","sourceId","updateTtsPlaybackButtons","_this1","button","isPlaying","Number","toggle","updateCopyButtons","_this10","isCopied","iconHtml","setCopyButtonState","cacheIndex","_this11","_ttsCacheIndex","invoke","toggleMessageTts","_this12","playAudioBlob","_this13","_step9","totalLength","reduce","combined","offset","_iterator9","blob","Blob","_this14","URL","createObjectURL","Audio","revokeObjectURL","playNextInQueue","play","_this15","nextBlob","shift","conversationModeOnAudioEnded","_this16","pause","currentTime","voiceSettingsElement","nextElementSibling","setVoiceSessionLive","live","audioSettings","hint","toggleConversationMode","stopConversationMode","startConversationMode","startRealtimeConversation","setupRealtimeController","CoreAIRealtime","attach","ensureConnected","connected","Error","sendStart","voice","silenceMs","vadThreshold","allowInterruption","webRtcEnabled","sendStartWebRtc","offerSdp","webRtcIceServers","voiceName","getVoiceName","selectors","realtimeButton","conversationButtonElementSelector","micButtonElementSelector","onSessionStateChanged","active","onActivate","onDeactivate","finishRealtimeConversationCleanup","onUserTurnPending","addRealtimePendingTurn","onUserTurnDropped","dropRealtimePendingTurn","dismissible","autoDismissMs","emptyAt","dropped","_this17","updateConversationButton","_conversationSubject","_conversationStream","_conversationCapture","endHtml","blur","startHtml","conversationModeSendPrompt","generatePrompt","element","templateProfileId","createSessionUrl","baseUrl","param","fullUrl","location","origin","searchParams","originalLength","_this18","clearNotificationDismiss","existingIndex","findIndex","scheduleNotificationDismiss","_this19","timerId","dismissNotification","handleNotificationAction","actionName","_this20","scrollTop","scrollHeight","clientHeight","handleUserInput","setSessionId","resetSession","sessionRating","onSessionReset","startNewSession","requestNewSession","_this21","_callee8","_context8","_this22","reject","resolvePendingSessionRequest","clearPendingSessionRequest","initializeApp","_this23","placeholderElementSelector","loadSession","documentBarSelector","multiple","allowedExtensions","accept","parentElement","appendChild","atBottom","shiftKey","lastMsg","pop","promptGenerators","getElementsByClassName","chatSessions","showChatScreen","initialMessages","btn","block","codeEl","clipboard","writeText","copiedText","force","onSessionInitialized","sessionUrlTemplate","history","replaceState","sessionUrl","encodeURIComponent","resolveSessionId","clearCopiedMessageState","copyResponse","_ref23","_message$copyContent","_event$target","_event$target$closest","_this24","currentTarget","updateFeedbackIcons","upBtn","downBtn","upClass","upIcon","fontSize","downClass","downIcon","containers","$el","msgId","rateMessage","isPositive","newRating","feedbackContainer","btnClass","offsetWidth","onEnd","removeEventListener","watch","handler","onDocumentsChanged","deep","_this25","mounted","_this26","_callee9","_context9","onMounted","fontAwesomeObserver","beforeUnmount","onBeforeUnmount","app","Vue","createApp","mount","autoInitializeSelector","getAttributeValue","attributeName","parseJsonAttribute","description","rawValue","buildConfigFromDataAttributes","_parseJsonAttribute","_parseJsonAttribute2","settings","hasAttribute","allowWidgetHost","booleanAttributes","parseBooleanAttributeValue","buildConfigFromElement","jsonConfig","attributeConfig","initializeFromElement","coreAiChatInitialized","__coreAIChatApp","scanForAutoInitialization","startAutoInitialization","readyState","download","toDataURL","img","res","removeChild"],"mappings":"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","file":"ai-chat.min.js","sourcesContent":["/*\n * Figure markers: the short labels the model writes, turned into pictures by the host.\n *\n * Retrieval hands the model a label -- [fig:1] -- and keeps the picture's real link in the message's reference\n * map, the same way a text citation keeps its source behind \"[doc:1]\". A model asked to reproduce a long opaque\n * identifier does not reproduce it: it copies the shape and substitutes ordinals, so links to figures that were\n * never in the results came back as 404s. A label short enough to be written exactly, with the link put back\n * here where the model cannot reach it, is what stops that.\n *\n * It sits on window rather than inside the manager below so the host can reach it, and so its rules can be\n * exercised in a bare sandbox with no browser and no DOM -- see tests/realtime-client/figure-markers.test.js --\n * exactly as window.CoreAIRealtime exposes the microphone gate's rules.\n *\n * The same block sits at the top of chat-interaction.js: the two chat clients are separate bundles that share no\n * module of their own, and both render the same markdown. Change one, change the other.\n */\n// CoreAIChatMarkers lives in chat-markers.js, which every chat surface loads before this file.\n\nwindow.coreAIChatManager = 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 copiedTitle: 'Response copied to clipboard.',\n codeCopiedText: 'Copied!',\n copyResetDelayMs: 2000,\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
\n \n
\n
\n \n {{ notification.content }}\n \n
\n
\n \n
\n
\n
\n `,\n indicatorTemplate: `\n
\n
\n \n Assistant\n
\n
\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 containsFontAwesomePlaceholders(root) {\n if (!root || root.nodeType !== 1) {\n return false;\n }\n\n var selector = 'i[class*=\"fa-\"],i.fa,i.fas,i.far,i.fab';\n if (typeof root.matches === 'function' && root.matches(selector)) {\n return true;\n }\n\n return typeof root.querySelector === 'function' && !!root.querySelector(selector);\n }\n\n function refreshFontAwesomeIcons(root) {\n var fontAwesome = window.FontAwesome;\n if (!containsFontAwesomePlaceholders(root) || !fontAwesome || !fontAwesome.dom || typeof fontAwesome.dom.i2svg !== 'function') {\n return;\n }\n\n fontAwesome.dom.i2svg({ node: root });\n }\n\n function observeFontAwesomeIcons(root) {\n if (!root || typeof MutationObserver === 'undefined') {\n return null;\n }\n\n var observer = new MutationObserver(function (mutations) {\n mutations.forEach(function (mutation) {\n mutation.addedNodes.forEach(function (node) {\n refreshFontAwesomeIcons(node);\n });\n });\n });\n\n observer.observe(root, {\n childList: true,\n subtree: true\n });\n\n return observer;\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 normalized.isGenerated = (normalized.isGenerated ?? normalized.IsGenerated) === true;\n normalized.isImage = (normalized.isImage ?? normalized.IsImage) === true;\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 // Installed at the top of this file so it can be unit tested without a browser; see the comment there.\n\n /*\n * Reads a JSON response body, or explains why it is not JSON.\n *\n * fetch follows a redirect silently and reports the page it landed on as a success, so an endpoint that\n * answers \"forbidden\" with a redirect to a sign-in page arrives here as response.ok with HTML in it.\n * Calling response.json() on that throws \"unexpected character at line 1 column 1\", which is what the\n * reader was shown instead of being told they are not allowed to upload.\n *\n * Returns { ok, data, message }. A caller shows message when ok is false; it is never a parser error.\n */\n async function readJsonResponse(response, fallbackMessage) {\n const contentType = (response.headers && response.headers.get('content-type')) || '';\n\n if (contentType.toLowerCase().indexOf('json') < 0) {\n // A redirect that landed somewhere else is the common case and worth naming, because the endpoint\n // did not refuse -- something in front of it did.\n const message = response.redirected\n ? 'You may not be signed in, or you do not have permission for this. Please reload and try again.'\n : fallbackMessage;\n\n return { ok: false, data: null, message: message };\n }\n\n try {\n return { ok: true, data: await response.json(), message: null };\n } catch (error) {\n return { ok: false, data: null, message: fallbackMessage };\n }\n }\n\n const expandImageMarkers = window.CoreAIChatMarkers.expandImageMarkers;\n\n function getCitationLabel(reference, key) {\n return reference.title || reference.text || key;\n }\n\n // Which references are one citation, and how a repeated marker reads, are statements about strings and\n // live in chat-markers.js so every chat surface numbers them the same way. Without the module each\n // reference keeps an identity of its own and nothing merges, which is the numbering this script had\n // before it.\n let unmergedCitationCount = 0;\n const citationIdentity = window.CoreAIChatMarkers?.citationIdentity\n ?? (() => `unmerged-${++unmergedCitationCount}`);\n const splitCombinedCitations = window.CoreAIChatMarkers?.splitCombinedCitations\n ?? (content => content);\n const collapseRepeatedCitations = window.CoreAIChatMarkers?.collapseRepeatedCitations\n ?? (html => html);\n const separateAdjacentCitations = window.CoreAIChatMarkers?.separateAdjacentCitations\n ?? (html => html);\n const citationMarkerHtml = window.CoreAIChatMarkers?.citationMarkerHtml\n ?? (displayIndex => `${displayIndex}`);\n\n function buildCitationDisplay(content, references) {\n // Before anything looks for a reference key, the combined form the model tends to write is split into\n // the keys it means. A key that is not found is not replaced, and an unreplaced key reaches the reader\n // as a raw marker mid-sentence.\n let processedContent = splitCombinedCitations((content || '').trim());\n const messageReferences = normalizeReferences(references);\n const referenceEntries = Object.entries(messageReferences);\n\n if (!referenceEntries.length) {\n return { content: processedContent, citations: [] };\n }\n\n const citedRefs = referenceEntries.filter(([key]) => processedContent.includes(key));\n const generatedRefs = referenceEntries.filter(([key, value]) => value.isGenerated && !processedContent.includes(key));\n\n if (!citedRefs.length && !generatedRefs.length) {\n return { content: processedContent, citations: [] };\n }\n\n citedRefs.sort(([, a], [, b]) => a.index - b.index);\n generatedRefs.sort(([, a], [, b]) => a.index - b.index);\n\n const citations = [];\n const citationsByIdentity = new Map();\n const placeholders = [];\n let displayIndex = 1;\n\n for (const [key, value] of citedRefs) {\n const label = getCitationLabel(value, key);\n const link = value.link || null;\n const identity = citationIdentity(label, link);\n let citation = citationsByIdentity.get(identity);\n\n // Every reference still has its key replaced, so the text never keeps a raw key; what the merge\n // changes is only how many numbers the reader is given for them.\n if (!citation) {\n citation = {\n referenceKey: key,\n referenceKeys: [],\n displayIndex: displayIndex++,\n label: label,\n link: link,\n isDownload: isDownloadCitationReference(value),\n };\n\n citationsByIdentity.set(identity, citation);\n citations.push(citation);\n }\n\n citation.referenceKeys.push(key);\n\n const placeholder = `__CITE_${citation.displayIndex}_${value.index || citation.displayIndex}__`;\n processedContent = processedContent.replaceAll(key, placeholder);\n placeholders.push({ placeholder, displayIndex: citation.displayIndex, label: citation.label });\n }\n\n for (const entry of placeholders) {\n processedContent = processedContent.replaceAll(entry.placeholder, citationMarkerHtml(entry.displayIndex, entry.label));\n }\n\n // Merged citations can leave the same number twice over a sentence; that is collapsed before the\n // commas go in, or the reader is given \"1,1\".\n processedContent = collapseRepeatedCitations(processedContent);\n processedContent = separateAdjacentCitations(processedContent);\n\n // Generated files (such as exported tabular data) are always offered as a download even when\n // the model does not cite them inline, so the user never loses access to the produced file.\n for (const [key, value] of generatedRefs) {\n citations.push({\n referenceKey: key,\n referenceKeys: [key],\n displayIndex: displayIndex,\n label: getCitationLabel(value, key),\n link: value.link || null,\n isDownload: true,\n placeholder: null,\n });\n\n displayIndex++;\n }\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 // Every key the citation absorbed is replaced, not just the first: a merged key left behind would\n // reach the clipboard as the raw reference token the reader never saw on the page.\n for (const citation of citations) {\n for (const key of (citation.referenceKeys?.length ? citation.referenceKeys : [citation.referenceKey])) {\n copyContent = copyContent.replaceAll(key, `[${citation.displayIndex}]`);\n }\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 // Figure markers become images before anything else reads the content: the citation pass looks for its\n // own keys in what is left, and the markdown parser then sees an ordinary image.\n const displayContent = expandImageMarkers(rawContent, messageReferences);\n const citationDisplay = buildCitationDisplay(displayContent, 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 // Copied from the expanded content, so a copied answer carries the picture's link rather than a label\n // that means nothing outside this page.\n // Split here too: the copy is built from the expanded content rather than the display path's output,\n // so a combined marker would otherwise survive into the clipboard as a raw key.\n message.copyContent = buildCopyContent(splitCombinedCitations(displayContent), 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 `${data.text}`;\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 `
${langDisplay}
${highlighted}
`;\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 // Spans, not divs. A figure marker is often written mid-sentence -- \"Figures [fig:1], [fig:2] and\n // [fig:3] show...\" -- and a block element cannot sit inside a paragraph: the browser closes the

\n // at the first one, so the sentence is torn into fragments and the commas between the markers are\n // left stranded on their own lines. Inline-block keeps the figure looking exactly the same while\n // remaining something a paragraph can legally contain.\n // The download sits over the picture's lower corner rather than on a line of its own beneath it.\n // A row of its own cost a band of vertical space under every figure, which a conversation full of\n // them pays for once per figure. The link itself is unchanged -- same address, same download\n // attribute, same behaviour -- only where it is drawn.\n return `\n \"${alt}\"\n \n \n \n `;\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 `

`\n + ``\n + `
`\n + `
`\n + ``\n + `
`;\n }\n\n // The marker itself is read by chat-markers.js, shared with every other chat surface, so the three of them\n // cannot disagree about what a marker is. Everything below -- the container, the id scheme, the Chart.js\n // call -- is this surface's own and legitimately differs from the others.\n const findChartMarker = window.CoreAIChatMarkers.findChartMarker;\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 = findChartMarker(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 // An image the assistant named but the server will not serve. The address is written by a language\n // model from what retrieval handed it, so a mistyped or invented one is possible, and the browser's\n // default for that is a broken-image icon captioned with the alt text -- which reads as a real picture\n // that failed to arrive. Saying plainly that it could not be loaded is both truer and quieter.\n //\n // Wired here rather than as an inline onerror attribute because message bodies go through DOMPurify,\n // which strips event-handler attributes.\n function markBrokenImagesInMessage() {\n // Scanning the document rather than one message, because the value threaded through the render\n // path is the message DATA object -- the thing carrying content, references and pending charts --\n // and not the element it was rendered into. Wiring is idempotent via the data-broken-wired mark,\n // so re-scanning after each render costs a query over the handful of images already handled.\n if (typeof document === 'undefined' || typeof requestAnimationFrame !== 'function') {\n return;\n }\n\n // Deferred for the same reason the charts below are: the render that produced these elements has\n // not necessarily been flushed to the DOM when this runs.\n requestAnimationFrame(wireBrokenImageHandlers);\n requestAnimationFrame(wireImageZoom);\n }\n\n // A picture arrives after the markdown is handed back -- the view writes it, and a streamed answer\n // rewrites it on every chunk -- so zooming cannot be attached once at load. It is attached on the same\n // pass as the broken-image handler above, and the attribute marks a picture already attached so a\n // re-render does not bind it a second time.\n function wireImageZoom() {\n // The library is the host's to load. Without it the picture is still shown and still downloadable;\n // only the enlarging is missing, so this is not worth failing a render over.\n if (typeof mediumZoom !== 'function') {\n return;\n }\n\n const images = document.querySelectorAll('.generated-image-container img:not([data-zoom-wired])');\n\n if (images.length === 0) {\n return;\n }\n\n for (const image of images) {\n image.setAttribute('data-zoom-wired', 'true');\n }\n\n mediumZoom(images, {\n // The drawing is bounded by the window rather than by this margin, so the margin is kept\n // small: an ingested figure is read detail by detail, and every pixel given away here comes\n // off the size it is read at.\n margin: 16,\n background: 'rgba(15, 15, 15, 0.92)',\n });\n }\n\n function wireBrokenImageHandlers() {\n const images = document.querySelectorAll('.generated-image-container img:not([data-broken-wired])');\n\n for (const image of images) {\n image.setAttribute('data-broken-wired', 'true');\n image.addEventListener('error', function () {\n const container = image.closest('.generated-image-container');\n\n if (!container || container.dataset.brokenHandled) {\n return;\n }\n\n container.dataset.brokenHandled = 'true';\n container.hidden = true;\n\n const note = document.createElement('p');\n note.className = 'text-muted small fst-italic mb-2';\n note.textContent = image.alt\n ? `(the picture \"${image.alt}\" could not be loaded)`\n : '(that picture could not be loaded)';\n container.insertAdjacentElement('afterend', note);\n }, { once: true });\n }\n }\n\n function renderMessageMedia(message) {\n markBrokenImagesInMessage();\n\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., ).');\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 // A markdown table becomes a bare , which Bootstrap leaves completely unstyled: it renders\n // as cramped, borderless text that reads as plain output rather than a table. Adding the framework's\n // own classes styles it wherever Bootstrap is loaded, and the wrapper lets a wide table scroll on\n // its own instead of stretching the conversation. Markdown tables cannot nest, so the plain\n // replacement is safe.\n function styleMarkdownTables(html) {\n return html\n .replace(/
/g, '
')\n .replace(/<\\/table>/g, '
');\n }\n\n function parseMarkdownContent(content, message) {\n _pendingCharts = [];\n const html = styleMarkdownTables(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 function compactObject(source) {\n if (!source || typeof source !== 'object') {\n return {};\n }\n\n return Object.fromEntries(\n Object.entries(source).filter(([, value]) => value !== undefined)\n );\n }\n\n function resolveIndicatorTemplate(template, assistantLabel) {\n if (!template) {\n return template;\n }\n\n const encodedAssistantLabel = escapeHtmlEntities(assistantLabel || 'Assistant');\n return template.replace(/\\{\\{\\s*assistantLabel\\s*\\}\\}/g, encodedAssistantLabel);\n }\n\n const initialize = (instanceConfig) => {\n const normalizedInstanceConfig = compactObject(instanceConfig);\n const normalizedWidgetConfig = compactObject(normalizedInstanceConfig.widget);\n const config = Object.assign({}, defaultConfig, normalizedInstanceConfig);\n config.widget = Object.assign({}, defaultConfig.widget || {}, normalizedWidgetConfig);\n config.indicatorTemplate = resolveIndicatorTemplate(config.indicatorTemplate, config.assistantLabel);\n const hasWidgetConfig = !!(normalizedWidgetConfig.chatWidgetContainer && normalizedWidgetConfig.chatWidgetStateName);\n const widgetBehavior = window.coreAIChatWidgetBehavior || 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 copiedTitle: config.copiedTitle,\n isRecording: false,\n mediaRecorder: null,\n preRecordingPrompt: '',\n micButton: null,\n // Conversation mode is carried either by a realtime session or by the speech-to-text plus\n // text-to-speech cascade, never both. Dictation and spoken playback belong to the cascade.\n speechToTextEnabled: !config.realtimeEnabled && (config.chatMode === 'AudioInput' || config.chatMode === 'Conversation'),\n textToSpeechEnabled: (!config.realtimeEnabled && 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 realtimeEnabled: !!config.realtimeEnabled,\n // Server-relay WebRTC transport: primary when advertised and supported; the client falls back\n // to the WebSocket path below if the peer cannot connect.\n realtimeWebRtcEnabled: config.realtimeWebRtcEnabled === true && typeof window.RTCPeerConnection === 'function',\n // A host-supplied override. Normally the servers are fetched from the hub right before the\n // peer is created (resolveRealtimeIceServers) so configured TURN relays — and their\n // short-lived credentials — are actually used instead of a public STUN server.\n realtimeWebRtcIceServers: (Array.isArray(config.realtimeWebRtcIceServers) && config.realtimeWebRtcIceServers.length)\n ? config.realtimeWebRtcIceServers\n : null,\n realtimeVoiceName: config.realtimeVoiceName || null,\n conversationButton: null,\n realtimeHintElement: config.realtimeHintElementSelector\n ? document.querySelector(config.realtimeHintElementSelector)\n : null,\n isConversationMode: false,\n notificationDismissTimers: {},\n pendingSessionPromise: null,\n pendingSessionResolver: null,\n pendingSessionRejector: null,\n pendingSessionTimeoutId: null,\n copiedMessageIndex: -1,\n copyResetTimeoutId: null,\n activeCopyButton: 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 parsed = await readJsonResponse(response, 'Upload failed. Please try again.');\n\n if (!parsed.ok) {\n console.error('Upload failed: response was not JSON.', { status: response.status, redirected: response.redirected });\n this.uploadErrors = [{ fileName: '', error: parsed.message }];\n\n return;\n }\n\n var result = parsed.data;\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 secondParsed = await readJsonResponse(response, 'The request could not be completed.');\n\n if (!secondParsed.ok) {\n console.error('Response was not JSON.', { status: response.status, redirected: response.redirected });\n\n return;\n }\n\n var result = secondParsed.data;\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 = '
';\n html += '
';\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 += '';\n html += ' ';\n html += this.escapeHtml(name);\n html += ' ';\n html += '';\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 // The reason is shown, not hidden behind a tooltip. A pill reading \"quarterly-report-2...\"\n // tells a reader their upload failed and nothing about why, and a title attribute is\n // unreachable on a touch device -- so the one sentence that tells them what to do next\n // was the one thing the widget would not display.\n html += '';\n html += '';\n html += '';\n\n if (failedItem.fileName) {\n html += '' + this.escapeHtml(failedItem.fileName) + ': ';\n }\n\n html += this.escapeHtml(errorMsg);\n html += '';\n html += '';\n html += '';\n }\n\n if (this.isUploading) {\n html += '';\n html += ' Uploading...';\n html += '';\n }\n\n html += '';\n html += '
';\n if (config.supportedExtensionsText) {\n html += '
Supported formats: ' + this.escapeHtml(config.supportedExtensionsText) + '
';\n }\n\n html += '
';\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 // Switching to another session must not leave a prior realtime/voice session running.\n this.forceStopActiveVoice();\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 renderMessageMedia(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 // display it as the first assistant message without invoking the AI.\n if (this.messages.length === 0 && config.initialPrompt) {\n this.addMessage({\n role: 'assistant',\n content: config.initialPrompt\n });\n }\n });\n\n // Realtime lifecycle events (ReceiveRealtimeEvent, and ReceiveError while a voice session is\n // live) are handled by the shared CoreAIRealtime module — see setupRealtimeController.\n\n this.connection.on(\"ReceiveError\", (error) => {\n console.error(\"SignalR Error: \", error);\n\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // A server-side error (for example a session-start rate-limit rejection) ends the\n // in-flight request. Reject any pending new-session promise so the UI stops waiting\n // until it times out, and clear the typing indicator that a send may have shown.\n this.rejectPendingSessionRequest(error);\n this.hideTypingIndicator();\n\n if (widgetBehavior && typeof widgetBehavior.handleReceiveError === 'function') {\n widgetBehavior.handleReceiveError(this, error, config);\n } else if (!this.isNavigatingAway) {\n // Surface the message to the user instead of failing silently.\n this.addMessage(this.getErrorMessage(error));\n }\n });\n\n this.connection.on(\"ReceiveSessionStartRejected\", (reason) => {\n // A rate-limit rejection is a definitive \"wait and retry\", not a recoverable\n // session/connection error. Unblock any pending new-session request, clear the\n // typing indicator, and show the message for every host (main app and widget)\n // without triggering the widget's clear-and-retry recovery, which would wipe the\n // visitor's state and fire another throttled StartSession.\n this.rejectPendingSessionRequest(reason);\n this.hideTypingIndicator();\n\n if (!this.isNavigatingAway) {\n this.addMessage(this.getErrorMessage(reason));\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, '>');\n var html = '

' + escaped + '

';\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, turnId, text) => {\n // Realtime creates the chat session server-side; adopt its id (and update the page URL)\n // on the first turn so a refresh reloads the conversation instead of starting fresh.\n if (sessionId && this.getSessionId() !== sessionId) {\n this.initializeSession(sessionId);\n }\n\n // Realtime: a placeholder for this turn was already inserted in the right position when\n // the utterance was captured (see user_turn_pending), so just fill in its text.\n if (turnId && this._realtimePendingTurns && this._realtimePendingTurns[turnId]) {\n var pending = this._realtimePendingTurns[turnId];\n delete this._realtimePendingTurns[turnId];\n this.stopAudio();\n this.fillRealtimePendingTurn(pending, text);\n\n return;\n }\n\n if (text) {\n this.stopAudio();\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '

' + escaped + '

';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else if (this._conversationAssistantMessage) {\n // Realtime: the user's transcript lags the assistant's reply for the SAME turn (the\n // model answers the audio before speech-to-text finishes). Insert the user message\n // just before the streaming assistant message so the order stays You -> Assistant,\n // and keep that message streaming — ending it here split one reply into two bubbles\n // above the prompt.\n var at = this._conversationAssistantMessage.index;\n var userMsg = { role: 'user', content: text, rawContent: text, userRating: null, references: {} };\n updateMessagePresentation(userMsg, userMsg.references);\n this.messages.splice(at, 0, userMsg);\n this._conversationAssistantMessage.index = at + 1;\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 // A new response id means a new turn — finalize the previous assistant message so two replies\n // never merge into one bubble (also covers barge-in, which starts a fresh response).\n if (this._conversationAssistantMessage && this._conversationAssistantResponseId && responseId && this._conversationAssistantResponseId !== responseId) {\n var prev = this.messages[this._conversationAssistantMessage.index];\n if (prev) { prev.isStreaming = false; }\n this._conversationAssistantMessage = null;\n }\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 this._conversationAssistantResponseId = responseId;\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 renderMessageMedia(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 this._conversationAssistantResponseId = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (sessionId, base64Audio, contentType) => {\n if (!base64Audio) {\n return;\n }\n\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\n // Realtime audio arrives as raw PCM16 (WebSocket transport) and is scheduled for immediate\n // playback by the shared module; conversation/TTS audio (mp3/wav) is collected and played on\n // complete.\n if (contentType === 'audio/pcm') {\n if (this.realtimeController) { this.realtimeController.receivePcm(bytes); }\n } else {\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 // The realtime session lived inside the dropped connection; it cannot survive a reconnect.\n if (this.realtimeEnabled && this.isConversationMode) {\n this.stopRealtimeConversation();\n }\n });\n\n this.connection.onreconnected(() => {\n console.info(\"SignalR: reconnected.\");\n\n if (this.isSessionStarted) {\n this.reloadCurrentSession();\n }\n });\n\n this.connection.onclose((error) => {\n if (this.isNavigatingAway) {\n return;\n }\n\n if (this.realtimeEnabled && this.isConversationMode) {\n this.stopRealtimeConversation();\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 async ensureConnectionStarted() {\n if (!this.connection) {\n return false;\n }\n\n var states = signalR.HubConnectionState;\n if (this.connection.state === states.Connected) {\n return true;\n }\n\n // If the initial start failed or has not begun, start it now.\n if (this.connection.state === states.Disconnected) {\n try {\n await this.connection.start();\n } catch (err) {\n console.error(\"SignalR Connection Error: \", err);\n }\n\n return this.connection.state === states.Connected;\n }\n\n // The connection is still Connecting or Reconnecting: wait for it to settle so callers\n // (e.g. starting a realtime session) do not send before the socket is ready.\n return await new Promise((resolve) => {\n var settle = (value) => {\n clearTimeout(timeoutId);\n clearInterval(intervalId);\n resolve(value);\n };\n var timeoutId = setTimeout(() => settle(this.connection.state === states.Connected), 10000);\n var intervalId = setInterval(() => {\n if (this.connection.state === states.Connected) {\n settle(true);\n } else if (this.connection.state === states.Disconnected) {\n settle(false);\n }\n }, 100);\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(\"addingCoreAIPromotMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedCoreAIPromotMessage\", { 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 renderMessageMedia(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 // A live voice session and a typed turn are two writers into one chat session, and they\n // would interleave. End the session first; the turns it already produced are persisted, so\n // the typed message simply continues the same thread.\n this.forceStopActiveVoice();\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 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\n // Capture raw 16 kHz PCM (16-bit mono) via Web Audio instead of MediaRecorder.\n // Browsers only agree on WebM/Opus for MediaRecorder, and Azure's speech SDK cannot\n // demux that container from a streaming push (it fails inside GStreamer). Raw PCM is\n // decoded natively with no GStreamer and is produced identically by every browser.\n this._sttCapture = this._createPcmCapture(stream, (base64) => {\n try { subject.next(base64); } catch (err) { /* completed */ }\n });\n this._sttSubject = subject;\n\n var rate = (this._sttCapture && this._sttCapture.sampleRate) || 16000;\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"SendAudioStream\", profileId, sessionId, subject, \"audio/pcm;rate=\" + rate, language);\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) {\n return;\n }\n\n this._stopPcmCapture(this._sttCapture);\n this._sttCapture = null;\n if (this._sttSubject) {\n try { this._sttSubject.complete(); } catch (err) { /* already completed */ }\n this._sttSubject = null;\n }\n this.isRecording = false;\n this.updateMicButton();\n },\n // Captures microphone audio as raw 16 kHz, 16-bit mono PCM using Web Audio and invokes\n // onChunk(base64Pcm, rms) for each block. Returns a handle for _stopPcmCapture. This replaces\n // MediaRecorder so every browser streams a format Azure decodes without GStreamer.\n _createPcmCapture(stream, onChunk) {\n var AudioCtx = window.AudioContext || window.webkitAudioContext;\n // Ask the browser to resample the mic to 16 kHz; fall back to manual resampling if it will not.\n var audioContext;\n try {\n audioContext = new AudioCtx({ sampleRate: 16000 });\n } catch (e) {\n audioContext = new AudioCtx();\n }\n var srcRate = audioContext.sampleRate;\n var source = audioContext.createMediaStreamSource(stream);\n var processor = audioContext.createScriptProcessor(4096, 1, 1);\n var self = this;\n processor.onaudioprocess = function (e) {\n var input = e.inputBuffer.getChannelData(0);\n var pcm16 = self._downsampleToInt16(input, srcRate, 16000);\n if (!pcm16 || pcm16.length === 0) {\n return;\n }\n var sum = 0;\n for (var i = 0; i < pcm16.length; i++) {\n var v = pcm16[i] / 32768;\n sum += v * v;\n }\n var rms = Math.sqrt(sum / pcm16.length);\n var bytes = new Uint8Array(pcm16.buffer);\n var binary = '';\n for (var j = 0; j < bytes.length; j++) {\n binary += String.fromCharCode(bytes[j]);\n }\n onChunk(btoa(binary), rms);\n };\n source.connect(processor);\n // Some browsers only fire onaudioprocess while the node is connected to a destination.\n processor.connect(audioContext.destination);\n return { audioContext: audioContext, source: source, processor: processor, stream: stream, sampleRate: 16000 };\n },\n _stopPcmCapture(capture) {\n if (!capture) {\n return;\n }\n try { if (capture.processor) { capture.processor.onaudioprocess = null; capture.processor.disconnect(); } } catch (e) { }\n try { if (capture.source) { capture.source.disconnect(); } } catch (e) { }\n try { if (capture.stream) { capture.stream.getTracks().forEach(function (t) { t.stop(); }); } } catch (e) { }\n try { if (capture.audioContext) { capture.audioContext.close(); } } catch (e) { }\n },\n // Converts a Float32 sample block to 16-bit PCM, resampling from srcRate to dstRate when needed.\n _downsampleToInt16(input, srcRate, dstRate) {\n var s, i;\n if (!(dstRate < srcRate)) {\n var same = new Int16Array(input.length);\n for (i = 0; i < input.length; i++) {\n s = Math.max(-1, Math.min(1, input[i]));\n same[i] = s < 0 ? s * 0x8000 : s * 0x7FFF;\n }\n return same;\n }\n var ratio = srcRate / dstRate;\n var newLen = Math.floor(input.length / ratio);\n var out = new Int16Array(newLen);\n for (var j = 0; j < newLen; j++) {\n var idx = j * ratio;\n var i0 = Math.floor(idx);\n var i1 = (i0 + 1 < input.length) ? i0 + 1 : input.length - 1;\n var frac = idx - i0;\n s = input[i0] * (1 - frac) + input[i1] * frac;\n s = Math.max(-1, Math.min(1, s));\n out[j] = s < 0 ? s * 0x8000 : s * 0x7FFF;\n }\n return out;\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 = '';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '';\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 renderMessageMedia(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 getErrorMessage(error) {\n var content = (typeof error === 'string' && error.trim())\n ? error\n : \"Something went wrong. Please try again.\";\n\n return {\n role: \"assistant\",\n content: content,\n htmlContent: \"\",\n };\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 renderMessageMedia(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\n button.classList.toggle('tts-playing', isPlaying);\n button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');\n });\n },\n updateCopyButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-copy-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-copy-message-index'));\n var isCopied = buttonIndex === this.copiedMessageIndex;\n var iconHtml = isCopied\n ? ''\n : '';\n\n button.classList.toggle('text-success', isCopied);\n button.classList.toggle('text-secondary', !isCopied);\n button.setAttribute('title', isCopied ? this.copiedTitle : this.copyTitle);\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\n });\n },\n setCopyButtonState(button, isCopied) {\n if (!button) {\n return;\n }\n\n var iconHtml = isCopied\n ? ''\n : '';\n\n button.classList.toggle('text-success', isCopied);\n button.classList.toggle('text-secondary', !isCopied);\n button.setAttribute('title', isCopied ? this.copiedTitle : this.copyTitle);\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\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 // A live voice session takes the message box away and puts the audio settings in its place; ending\n // the session gives it back. Sending a typed message already force-stopped the session, so the box\n // was never a way to say something *during* one -- hiding it only makes that honest, and frees the\n // row for the gear. Both transports land here: realtime through the module's onActivate, the\n // speech-to-text cascade through startConversationMode.\n // The realtime module inserts its settings popover directly after the button it was handed, and\n // hard-codes the element id. A page can host two chat clients at once -- this one and the admin\n // widget -- so that id is not unique and getElementById would hand the widget the page's gear.\n // Each client finds its own next to its own button.\n voiceSettingsElement() {\n var next = this.conversationButton && this.conversationButton.nextElementSibling;\n\n return next && next.id === 'realtime-audio-settings' ? next : null;\n },\n setVoiceSessionLive(live) {\n if (this.inputElement) {\n this.inputElement.hidden = live;\n }\n\n if (this.buttonElement) {\n this.buttonElement.hidden = live;\n }\n\n // With the message box gone the button would otherwise sit at its natural width in an empty\n // row, so it takes the space the box left behind and reads as the thing now in charge. The\n // settings popover does not grow, so it stays at the right-hand end.\n if (this.conversationButton) {\n this.conversationButton.classList.toggle('flex-grow-1', live);\n }\n\n // The gear is built by the realtime module next to its button, and only in realtime mode, so\n // it is absent on the cascade. It belongs to a live session rather than to the surface.\n var audioSettings = this.voiceSettingsElement();\n if (audioSettings) {\n audioSettings.hidden = !live;\n }\n\n var hint = this.realtimeHintElement;\n if (hint) {\n hint.classList.toggle('d-none', !live);\n }\n },\n toggleConversationMode() {\n if (this.realtimeEnabled) {\n // Realtime is driven by the shared module, which owns the button; this only exists for\n // callers that toggle programmatically.\n if (this.realtimeController) { this.realtimeController.toggle(); }\n\n return;\n }\n\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n // Force-stop any in-progress voice/realtime session (mic, playback, and the streamed audio),\n // e.g. before starting a new chat or switching sessions, so it never keeps running in the background.\n forceStopActiveVoice() {\n if (!this.isConversationMode) {\n return;\n }\n if (this.realtimeEnabled) {\n this.stopRealtimeConversation();\n } else {\n this.stopConversationMode();\n }\n },\n startRealtimeConversation() {\n if (this.realtimeController) { this.realtimeController.start(); }\n },\n stopRealtimeConversation() {\n if (this.realtimeController) { this.realtimeController.stop(); }\n },\n // Realtime (speech-to-speech) is the shared CoreAIRealtime module (realtime-audio.js): microphone\n // capture and gating, the WebRTC transport with its WebSocket fallback, playback, the settings\n // popover, push-to-talk, and the server-driven session lifecycle all live there, so this app and the\n // chat-interaction client cannot drift apart. What is wired here is only how the module reaches this\n // app's hub and transcript.\n setupRealtimeController(config) {\n if (this.realtimeController || !this.conversationButton) { return; }\n if (!window.CoreAIRealtime || typeof window.CoreAIRealtime.attach !== 'function') {\n console.error('realtime-audio.js is not loaded; realtime voice is unavailable on this page.');\n\n return;\n }\n\n var self = this;\n this.realtimeController = window.CoreAIRealtime.attach({\n connection: this.connection,\n ensureConnected: function () {\n return self.ensureConnectionStarted().then(function (connected) {\n if (!connected) { throw new Error('The chat connection is not available.'); }\n\n return connected;\n });\n },\n sendStart: function (subject, voice, language, silenceMs, vadThreshold, allowInterruption) {\n self.connection.send('StartRealtimeConversation', self.getProfileId(), self.getSessionId() || '', subject, voice, language, silenceMs, vadThreshold, allowInterruption);\n },\n webRtcEnabled: this.realtimeWebRtcEnabled,\n sendStartWebRtc: function (offerSdp, voice, language, silenceMs, vadThreshold, allowInterruption) {\n self.connection.send('StartRealtimeWebRtc', self.getProfileId(), self.getSessionId() || '', offerSdp, voice, language, silenceMs, vadThreshold, allowInterruption);\n },\n webRtcIceServers: this.realtimeWebRtcIceServers || undefined,\n voiceName: this.realtimeVoiceName || '',\n getVoiceName: function () { return self.realtimeVoiceName || ''; },\n realtimeEnabled: true,\n // The conversation button doubles as the realtime button on this host; the module owns its\n // click, label and state from here on.\n //\n // input and sendButton are deliberately not handed over. The module hides every control it\n // is given when realtime takes over, and typing has to stay available during a voice\n // conversation -- that is the whole feature.\n //\n // conversationButton is not handed over either. It is the same element as the realtime\n // button here, and the module hides the conversation button before showing the realtime\n // one -- naming it twice would ask it to hide the control it then has to show.\n selectors: {\n realtimeButton: config.conversationButtonElementSelector,\n micButton: config.micButtonElementSelector\n },\n // The module owns whether a session is live, so the message box follows its flag rather\n // than this app's copy of it. Losing one of these events used to leave the box hidden\n // under a button that had already gone back to \"Start speaking\".\n onSessionStateChanged: function (active) {\n self.setVoiceSessionLive(active);\n },\n onActivate: function () {\n self.isConversationMode = true;\n self._conversationAssistantMessage = null;\n self._conversationPartialMessage = null;\n self.removeNotification('conversation-ended');\n },\n onDeactivate: function () {\n self.isConversationMode = false;\n self.finishRealtimeConversationCleanup();\n },\n onUserTurnPending: function (turnId) { self.addRealtimePendingTurn(turnId); },\n onUserTurnDropped: function (turnId) { self.dropRealtimePendingTurn(turnId); }\n });\n },\n // Shared teardown tail: clears any in-flight streaming state and shows the conversation-ended\n // notification.\n finishRealtimeConversationCleanup() {\n if (this._conversationAssistantMessage) {\n var m = this.messages[this._conversationAssistantMessage.index];\n if (m) { m.isStreaming = false; }\n this._conversationAssistantMessage = null;\n }\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) { this.messages[i].isStreaming = false; }\n }\n\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 // The utterance has been captured but not transcribed yet. Showing a placeholder now puts the\n // prompt above the reply it produces: transcription lags the spoken answer, so a bubble added only\n // when the text arrives lands underneath its own reply.\n addRealtimePendingTurn(turnId) {\n if (!turnId) { return; }\n this._realtimePendingTurns = this._realtimePendingTurns || {};\n var index = this.messages.length;\n this.addMessage({ role: 'user', content: '', isPartial: true });\n this._realtimePendingTurns[turnId] = this.messages[index];\n },\n fillRealtimePendingTurn(pending, text) {\n if (!pending) { return; }\n if (!text) {\n var emptyAt = this.messages.indexOf(pending);\n if (emptyAt >= 0) { this.messages.splice(emptyAt, 1); }\n\n return;\n }\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n pending.content = text;\n pending.htmlContent = '

' + escaped + '

';\n pending.isPartial = false;\n },\n dropRealtimePendingTurn(turnId) {\n if (!turnId || !this._realtimePendingTurns) { return; }\n var dropped = this._realtimePendingTurns[turnId];\n if (!dropped) { return; }\n delete this._realtimePendingTurns[turnId];\n var at = this.messages.indexOf(dropped);\n if (at >= 0) { this.messages.splice(at, 1); }\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 this._conversationSubject = new signalR.Subject();\n this._conversationStream = stream;\n\n // RMS (0..1) above which speech during TTS playback counts as an interrupt.\n var interruptRmsThreshold = 0.12;\n\n // Capture raw 16 kHz PCM (16-bit mono) via Web Audio instead of MediaRecorder — see\n // startRecording for why WebM/Opus is avoided. The per-block RMS drives interrupt\n // detection during TTS playback, replacing the previous AnalyserNode.\n this._conversationCapture = this._createPcmCapture(stream, (base64, rms) => {\n if (this.isPlayingAudio && rms >= interruptRmsThreshold) {\n // User is speaking over TTS — interrupt playback.\n this.stopAudio();\n }\n try {\n this._conversationSubject.next(base64);\n } catch (err) {\n // Subject may have been completed already.\n }\n });\n\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var language = navigator.language || document.documentElement.lang || 'en-US';\n var rate = (this._conversationCapture && this._conversationCapture.sampleRate) || 16000;\n\n this.connection.send(\"StartConversation\", profileId, sessionId, this._conversationSubject, \"audio/pcm;rate=\" + rate, language);\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) {\n this._stopPcmCapture(this._conversationCapture);\n this._conversationCapture = null;\n if (this._conversationSubject) {\n try { this._conversationSubject.complete(); } catch (err) { /* already completed */ }\n }\n this.isRecording = false;\n }\n\n this.stopAudio();\n this._conversationPartialTranscript = '';\n this._conversationPartialMessage = null;\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 // Force-stop an in-progress voice/realtime conversation so it doesn't keep running under the new session.\n this.forceStopActiveVoice();\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\n // When an initial prompt is configured, show it as the first\n // assistant message instead of the generic placeholder.\n if (config.initialPrompt) {\n this.addMessage({\n role: 'assistant',\n content: config.initialPrompt\n });\n } else {\n this.showPlaceholder();\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 // Force-stop any live voice/realtime session before starting a new chat.\n this.forceStopActiveVoice();\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 }\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 const initialMessages = Array.isArray(config.messages) ? config.messages : [];\n\n for (let i = 0; i < initialMessages.length; i++) {\n this.addMessage(initialMessages[i]);\n }\n\n // When no messages were loaded and an initial prompt is configured,\n // display it as the first assistant message without invoking the AI.\n if (this.messages.length === 0 && config.initialPrompt) {\n this.addMessage({\n role: 'assistant',\n content: config.initialPrompt\n });\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 = ' ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '';\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 (used for both STT/TTS conversation and realtime).\n if ((this.conversationModeEnabled || this.realtimeEnabled) && config.conversationButtonElementSelector) {\n this.conversationButton = document.querySelector(config.conversationButtonElementSelector);\n if (this.conversationButton) {\n if (this.realtimeEnabled) {\n // The shared realtime module owns the button (click, label, state) and adds the\n // voice settings popover next to it.\n this.setupRealtimeController(config);\n\n // The module reveals the gear as soon as the surface enters realtime mode, but it\n // belongs to a live session. The watcher that would hide it only runs on a change,\n // so the idle state has to be stated once here.\n this.setVoiceSessionLive(false);\n } else {\n this.conversationButton.addEventListener('click', () => {\n this.toggleConversationMode();\n });\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(\"initializingSessionCoreAIChat\", { 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 // For non-widget pages, update the browser URL so that a page\n // refresh reloads the correct session instead of starting fresh.\n if (!hasWidgetConfig && sessionId && config.sessionUrlTemplate && typeof history !== 'undefined' && history.replaceState) {\n var sessionUrl = config.sessionUrlTemplate.replace('{sessionId}', encodeURIComponent(sessionId));\n history.replaceState(null, '', sessionUrl);\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 clearCopiedMessageState() {\n if (this.copyResetTimeoutId) {\n window.clearTimeout(this.copyResetTimeoutId);\n this.copyResetTimeoutId = null;\n }\n\n if (this.activeCopyButton) {\n this.setCopyButtonState(this.activeCopyButton, false);\n this.activeCopyButton = null;\n }\n\n this.copiedMessageIndex = -1;\n },\n copyResponse(message, index, event) {\n const text = message && typeof message === 'object'\n ? message.copyContent ?? message.content ?? ''\n : message ?? '';\n const button = event?.currentTarget || event?.target?.closest?.('[data-copy-message-index]') || null;\n\n navigator.clipboard.writeText(text)\n .then(() => {\n this.clearCopiedMessageState();\n this.copiedMessageIndex = typeof index === 'number' ? index : -1;\n this.activeCopyButton = button;\n\n if (button) {\n this.setCopyButtonState(button, true);\n } else {\n this.$nextTick(() => this.updateCopyButtons());\n }\n\n this.copyResetTimeoutId = window.setTimeout(() => {\n this.clearCopiedMessageState();\n this.$nextTick(() => this.updateCopyButtons());\n }, Number(config.copyResetDelayMs) || 2000);\n })\n .catch(err => console.error('Failed to copy response:', err));\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 copiedMessageIndex() {\n this.$nextTick(() => this.updateCopyButtons());\n },\n isConversationMode(active) {\n // The dictation microphone is hidden while a voice conversation runs: the conversation\n // already owns the microphone, and a second one would mean something different.\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n // The message box and the send button give way to the voice settings while the conversation\n // runs, and come back when it ends. Both kinds of turn still land in the same thread; what\n // they cannot do is overlap.\n //\n // Only the cascade is driven from here. Realtime follows the module's own session flag\n // (onSessionStateChanged), so the two never disagree about whether a session is live.\n if (!this.realtimeEnabled) {\n this.setVoiceSessionLive(active);\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 this.$nextTick(() => {\n this.updateCopyButtons();\n refreshFontAwesomeIcons(this.$el);\n this.fontAwesomeObserver = observeFontAwesomeIcons(this.$el);\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 if (this.fontAwesomeObserver) {\n this.fontAwesomeObserver.disconnect();\n this.fontAwesomeObserver = null;\n }\n\n this.clearCopiedMessageState();\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 const autoInitializeSelector = '[data-coreai-chat-config],[data-coreai-chat-app-element-selector]';\n\n function getAttributeValue(element, attributeName) {\n const value = element.getAttribute(attributeName);\n return value === null || value === '' ? null : value;\n }\n\n function parseBooleanAttributeValue(value) {\n if (value === null || value === undefined) {\n return null;\n }\n\n if (typeof value === 'boolean') {\n return value;\n }\n\n const normalized = String(value).trim().toLowerCase();\n if (normalized === 'true') {\n return true;\n }\n\n if (normalized === 'false') {\n return false;\n }\n\n return null;\n }\n\n function parseJsonAttribute(element, attributeName, description) {\n const rawValue = getAttributeValue(element, attributeName);\n if (!rawValue) {\n return null;\n }\n\n try {\n return JSON.parse(rawValue);\n } catch (error) {\n console.error('Failed to parse ' + description + ' JSON.', error);\n return null;\n }\n }\n\n function buildConfigFromDataAttributes(element, options) {\n const settings = options || {};\n\n if (element.hasAttribute('data-coreai-chat-widget-container-selector') && settings.allowWidgetHost !== true) {\n return null;\n }\n\n const appElementSelector = getAttributeValue(element, 'data-coreai-chat-app-element-selector');\n if (!appElementSelector) {\n return null;\n }\n\n const config = {\n signalRHubUrl: getAttributeValue(element, 'data-coreai-chat-signalr-hub-url'),\n appElementSelector: appElementSelector,\n chatContainerElementSelector: getAttributeValue(element, 'data-coreai-chat-container-element-selector'),\n inputElementSelector: getAttributeValue(element, 'data-coreai-chat-input-element-selector'),\n sendButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-send-button-element-selector'),\n placeholderElementSelector: getAttributeValue(element, 'data-coreai-chat-placeholder-element-selector'),\n messages: parseJsonAttribute(element, 'data-coreai-chat-messages', 'CoreAI chat messages') ?? undefined,\n chatMode: getAttributeValue(element, 'data-coreai-chat-mode'),\n micButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-mic-button-element-selector'),\n conversationButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-conversation-button-element-selector'),\n realtimeHintElementSelector: getAttributeValue(element, 'data-coreai-chat-realtime-hint-element-selector'),\n ttsVoiceName: getAttributeValue(element, 'data-coreai-chat-tts-voice-name'),\n realtimeVoiceName: getAttributeValue(element, 'data-coreai-chat-realtime-voice-name'),\n documentBarSelector: getAttributeValue(element, 'data-coreai-chat-document-bar-selector'),\n uploadDocumentUrl: getAttributeValue(element, 'data-coreai-chat-upload-document-url'),\n removeDocumentUrl: getAttributeValue(element, 'data-coreai-chat-remove-document-url'),\n allowedExtensions: getAttributeValue(element, 'data-coreai-chat-allowed-extensions'),\n supportedExtensionsText: getAttributeValue(element, 'data-coreai-chat-supported-extensions-text'),\n existingDocuments: parseJsonAttribute(element, 'data-coreai-chat-existing-documents', 'CoreAI chat existing documents') ?? undefined,\n initialPrompt: getAttributeValue(element, 'data-coreai-chat-initial-prompt'),\n sessionUrlTemplate: getAttributeValue(element, 'data-coreai-chat-session-url-template'),\n userLabel: getAttributeValue(element, 'data-coreai-chat-user-label'),\n assistantLabel: getAttributeValue(element, 'data-coreai-chat-assistant-label'),\n copyTitle: getAttributeValue(element, 'data-coreai-chat-copy-title'),\n copiedTitle: getAttributeValue(element, 'data-coreai-chat-copied-title'),\n };\n\n const booleanAttributes = {\n metricsEnabled: 'data-coreai-chat-metrics-enabled',\n textToSpeechEnabled: 'data-coreai-chat-text-to-speech-enabled',\n sessionDocumentsEnabled: 'data-coreai-chat-session-documents-enabled',\n singleResponseMode: 'data-coreai-chat-single-response-mode',\n realtimeEnabled: 'data-coreai-chat-realtime-enabled',\n realtimeWebRtcEnabled: 'data-coreai-chat-realtime-webrtc-enabled',\n };\n\n Object.keys(booleanAttributes).forEach(key => {\n const parsed = parseBooleanAttributeValue(getAttributeValue(element, booleanAttributes[key]));\n if (parsed !== null) {\n config[key] = parsed;\n }\n });\n\n return compactObject(config);\n }\n\n function buildConfigFromElement(element, options) {\n const jsonConfig = parseJsonAttribute(element, 'data-coreai-chat-config', 'CoreAI chat config');\n const attributeConfig = buildConfigFromDataAttributes(element, options);\n\n if (!jsonConfig && !attributeConfig) {\n return null;\n }\n\n return Object.assign({}, jsonConfig || {}, attributeConfig || {});\n }\n\n function initializeFromElement(element) {\n if (!element || element.dataset.coreAiChatInitialized === 'true') {\n return element ? element.__coreAIChatApp || null : null;\n }\n\n const config = buildConfigFromElement(element);\n if (!config) {\n return null;\n }\n\n const app = initialize(config);\n if (!app) {\n return null;\n }\n\n element.dataset.coreAiChatInitialized = 'true';\n element.__coreAIChatApp = app;\n\n return app;\n }\n\n function scanForAutoInitialization(root) {\n if (!root || typeof root.querySelectorAll !== 'function') {\n return;\n }\n\n if (typeof root.matches === 'function' && root.matches(autoInitializeSelector)) {\n initializeFromElement(root);\n }\n\n root.querySelectorAll(autoInitializeSelector).forEach(initializeFromElement);\n }\n\n function startAutoInitialization() {\n scanForAutoInitialization(document);\n\n if (typeof MutationObserver === 'undefined') {\n return;\n }\n\n const observer = new MutationObserver(mutations => {\n mutations.forEach(mutation => {\n mutation.addedNodes.forEach(node => {\n if (node && node.nodeType === 1) {\n scanForAutoInitialization(node);\n }\n });\n });\n });\n\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n });\n }\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', startAutoInitialization, { once: true });\n } else {\n startAutoInitialization();\n }\n\n return {\n initialize: initialize,\n initializeFromElement: initializeFromElement,\n buildConfigFromElement: buildConfigFromElement,\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 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"]} diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/chat-interaction.js b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/chat-interaction.js index eba1c671..2107d3f9 100644 --- a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/chat-interaction.js +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/chat-interaction.js @@ -432,7 +432,11 @@ window.chatInteractionManager = function (_window$CoreAIChatMar, _window$CoreAIC // at the first one, so the sentence is torn into fragments and the commas between the markers are // left stranded on their own lines. Inline-block keeps the figure looking exactly the same while // remaining something a paragraph can legally contain. - return "\n \"").concat(alt,\n \n \n \n \n \n "); + // The download sits over the picture's lower corner rather than on a line of its own beneath it. + // A row of its own cost a band of vertical space under every figure, which a conversation full of + // them pays for once per figure. The link itself is unchanged -- same address, same download + // attribute, same behaviour -- only where it is drawn. + return "\n \"").concat(alt,\n \n \n \n "); }; // Chart counter for unique IDs @@ -505,14 +509,50 @@ window.chatInteractionManager = function (_window$CoreAIChatMar, _window$CoreAIC // Deferred for the same reason the charts below are: the render that produced these elements has // not necessarily been flushed to the DOM when this runs. requestAnimationFrame(wireBrokenImageHandlers); + requestAnimationFrame(wireImageZoom); } - function wireBrokenImageHandlers() { - var images = document.querySelectorAll('.generated-image-container img:not([data-broken-wired])'); + + // A picture arrives after the markdown is handed back -- the view writes it, and a streamed answer + // rewrites it on every chunk -- so zooming cannot be attached once at load. It is attached on the same + // pass as the broken-image handler above, and the attribute marks a picture already attached so a + // re-render does not bind it a second time. + function wireImageZoom() { + // The library is the host's to load. Without it the picture is still shown and still downloadable; + // only the enlarging is missing, so this is not worth failing a render over. + if (typeof mediumZoom !== 'function') { + return; + } + var images = document.querySelectorAll('.generated-image-container img:not([data-zoom-wired])'); + if (images.length === 0) { + return; + } var _iterator6 = _createForOfIteratorHelper(images), _step6; try { - var _loop = function _loop() { + for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) { var image = _step6.value; + image.setAttribute('data-zoom-wired', 'true'); + } + } catch (err) { + _iterator6.e(err); + } finally { + _iterator6.f(); + } + mediumZoom(images, { + // The drawing is bounded by the window rather than by this margin, so the margin is kept + // small: an ingested figure is read detail by detail, and every pixel given away here comes + // off the size it is read at. + margin: 16, + background: 'rgba(15, 15, 15, 0.92)' + }); + } + function wireBrokenImageHandlers() { + var images = document.querySelectorAll('.generated-image-container img:not([data-broken-wired])'); + var _iterator7 = _createForOfIteratorHelper(images), + _step7; + try { + var _loop = function _loop() { + var image = _step7.value; image.setAttribute('data-broken-wired', 'true'); image.addEventListener('error', function () { var container = image.closest('.generated-image-container'); @@ -529,13 +569,13 @@ window.chatInteractionManager = function (_window$CoreAIChatMar, _window$CoreAIC once: true }); }; - for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) { + for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) { _loop(); } } catch (err) { - _iterator6.e(err); + _iterator7.e(err); } finally { - _iterator6.f(); + _iterator7.f(); } } function renderMessageMedia(message) { @@ -551,11 +591,11 @@ window.chatInteractionManager = function (_window$CoreAIChatMar, _window$CoreAIC // Defer to requestAnimationFrame so the browser has fully laid out the // canvas elements before Chart.js reads their dimensions. requestAnimationFrame(function () { - var _iterator7 = _createForOfIteratorHelper(charts), - _step7; + var _iterator8 = _createForOfIteratorHelper(charts), + _step8; try { - for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) { - var c = _step7.value; + for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) { + var c = _step8.value; var canvas = document.getElementById(c.chartId); if (!canvas) { continue; @@ -588,9 +628,9 @@ window.chatInteractionManager = function (_window$CoreAIChatMar, _window$CoreAIC } } } catch (err) { - _iterator7.e(err); + _iterator8.e(err); } finally { - _iterator7.f(); + _iterator8.f(); } }); } @@ -1405,18 +1445,18 @@ window.chatInteractionManager = function (_window$CoreAIChatMar, _window$CoreAIC }, 0); var combined = new Uint8Array(totalLength); var offset = 0; - var _iterator8 = _createForOfIteratorHelper(this.audioChunks), - _step8; + var _iterator9 = _createForOfIteratorHelper(this.audioChunks), + _step9; try { - for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) { - var chunk = _step8.value; + for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) { + var chunk = _step9.value; combined.set(chunk, offset); offset += chunk.length; } } catch (err) { - _iterator8.e(err); + _iterator9.e(err); } finally { - _iterator8.f(); + _iterator9.f(); } this.audioChunks = []; var blob = new Blob([combined], { @@ -2328,7 +2368,7 @@ window.chatInteractionManager = function (_window$CoreAIChatMar, _window$CoreAIC } function _loadVoices() { _loadVoices = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() { - var deploymentName, realtime, response, contentType, result, grouped, _iterator9, _step9, voice, groupName, _t2; + var deploymentName, realtime, response, contentType, result, grouped, _iterator0, _step0, voice, groupName, _t2; return _regenerator().w(function (_context4) { while (1) switch (_context4.p = _context4.n) { case 0: @@ -2376,10 +2416,10 @@ window.chatInteractionManager = function (_window$CoreAIChatMar, _window$CoreAIC return _context4.a(2); case 6: grouped = new Map(); - _iterator9 = _createForOfIteratorHelper(result.voices); + _iterator0 = _createForOfIteratorHelper(result.voices); try { - for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) { - voice = _step9.value; + for (_iterator0.s(); !(_step0 = _iterator0.n()).done;) { + voice = _step0.value; groupName = voice.gender || 'Voices'; if (!grouped.has(groupName)) { grouped.set(groupName, []); @@ -2387,9 +2427,9 @@ window.chatInteractionManager = function (_window$CoreAIChatMar, _window$CoreAIC grouped.get(groupName).push(voice); } } catch (err) { - _iterator9.e(err); + _iterator0.e(err); } finally { - _iterator9.f(); + _iterator0.f(); } Array.from(grouped.keys()).sort(function (a, b) { return a.localeCompare(b); diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/chat-interaction.js.map b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/chat-interaction.js.map index 563c6d63..5c6a8e8a 100644 --- a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/chat-interaction.js.map +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/chat-interaction.js.map @@ -1 +1 @@ -{"version":3,"sources":["chat-interaction.js"],"names":["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","setPrototypeOf","__proto__","displayName","_regenerator","w","m","defineProperty","_regeneratorDefine","_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","chatInteractionManager","_window$CoreAIChatMar","_window$CoreAIChatMar2","_window$CoreAIChatMar3","_window$CoreAIChatMar4","_window$CoreAIChatMar5","_window$CoreAIChatMar6","_window$CoreAIChatMar7","_window$CoreAIChatMar8","_window$CoreAIChatMar9","_window$CoreAIChatMar0","defaultConfig","generatedImageAltText","generatedImageMaxWidth","downloadImageTitle","downloadChartTitle","downloadChartButtonText","codeCopiedText","copyTitle","copiedTitle","copyResetDelayMs","assistantLabel","messageTemplate","indicatorTemplate","untitledText","clearHistoryTitle","clearHistoryMessage","clearHistoryOkText","clearHistoryCancelText","sanitizeUrl","url","trimmed","trim","escapeHtmlEntities","text","span","document","createElement","textContent","innerHTML","containsFontAwesomePlaceholders","root","nodeType","selector","matches","querySelector","refreshFontAwesomeIcons","fontAwesome","FontAwesome","dom","i2svg","node","observeFontAwesomeIcons","MutationObserver","observer","mutations","forEach","mutation","addedNodes","observe","childList","subtree","normalizeReference","reference","_ref","_normalized$index","_ref2","_normalized$text","_ref3","_normalized$title","_ref4","_normalized$link","_ref5","_normalized$reference","_normalized$isGenerat","_normalized$isImage","normalized","assign","index","Index","Text","title","Title","link","Link","referenceType","ReferenceType","isGenerated","IsGenerated","isImage","IsImage","isDownloadCitationReference","toLowerCase","normalizeReferences","references","_i","_Object$entries","entries","_normalizeReference","_Object$entries$_i","key","expandImageMarkers","CoreAIChatMarkers","getCitationLabel","unmergedCitationCount","citationIdentity","concat","splitCombinedCitations","content","collapseRepeatedCitations","html","separateAdjacentCitations","citationMarkerHtml","displayIndex","buildCitationDisplay","processedContent","messageReferences","referenceEntries","citations","citedRefs","filter","_ref6","_ref7","includes","generatedRefs","_ref8","_ref9","sort","_ref0","_ref1","_ref10","_ref11","b","_ref12","_ref13","_ref14","_ref15","citationsByIdentity","Map","placeholders","_iterator","_step","_step$value","label","identity","citation","get","referenceKey","referenceKeys","isDownload","set","placeholder","replaceAll","err","_i2","_placeholders","entry","_iterator2","_step2","_step2$value","map","_ref16","_excluded","buildCopyContent","copyContent","_iterator3","_step3","_citation$referenceKe","_iterator5","_step5","_iterator4","_step4","trimEnd","updateMessagePresentation","message","rawContent","displayContent","citationDisplay","citationReferences","htmlContent","parseMarkdownContent","renderer","marked","Renderer","data","href","code","lang","highlighted","hljs","getLanguage","highlight","language","_","highlightAuto","langDisplay","image","src","alt","maxWidth","chartCounter","_pendingCharts","__chartConfigs","createChartHtml","chartId","findChartMarker","use","extensions","level","start","idx","undefined","tokenizer","extracted","startIndex","type","raw","substring","endIndex","json","token","config","markBrokenImagesInMessage","requestAnimationFrame","wireBrokenImageHandlers","images","querySelectorAll","_iterator6","_step6","_loop","setAttribute","addEventListener","container","closest","dataset","brokenHandled","hidden","note","className","insertAdjacentElement","once","renderMessageMedia","charts","_iterator7","_step7","canvas","getElementById","Chart","console","warn","offsetParent","_cfg$options","_cfg$options2","_cfg$options2$aspectR","_chartInstance","destroy","cfg","JSON","parse","options","responsive","maintainAspectRatio","aspectRatio","error","styleMarkdownTables","replace","DOMPurify","sanitize","ADD_TAGS","ADD_ATTR","compactObject","source","fromEntries","_ref17","_ref18","initialize","instanceConfig","signalRHubUrl","appElementSelector","chatContainerElementSelector","inputElementSelector","sendButtonElementSelector","app","Vue","createApp","inputElement","buttonElement","chatContainer","isInteractionStarted","isPlaceholderVisible","isStreaming","isNavigatingAway","autoScroll","stream","messages","prompt","initialFieldValues","settingsDirty","saveSettingsTimeout","saveIndicatorTimeout","isRecording","mediaRecorder","preRecordingPrompt","micButton","speechToTextEnabled","chatMode","textToSpeechEnabled","ttsVoiceName","audioChunks","audioPlayQueue","isPlayingAudio","currentAudioElement","currentAudioUrl","ttsPlayingMessageIndex","ttsAudioCache","ttsInstanceId","Math","random","conversationModeEnabled","conversationButton","isConversationMode","realtimeController","realtimeButton","realtimeEnabled","notifications","notificationDismissTimers","copiedMessageIndex","copyResetTimeoutId","activeCopyButton","computed","lastAssistantIndex","role","methods","handleBeforeUnload","startConnection","_this","_callee","_t","_context","connection","signalR","HubConnectionBuilder","withUrl","withAutomaticReconnect","build","serverTimeoutInMilliseconds","keepAliveIntervalInMilliseconds","on","_data$messages","initializeInteraction","itemId","titleInput","msg","addMessage","$nextTick","historyItem","showSaveIndicator","stopRecording","isFinal","_conversationPartialTranscript","escaped","_conversationPartialMessage","hidePlaceholder","isPartial","scrollToBottom","_audioInputSent","dispatchEvent","Event","turnId","_realtimePendingTurns","pending","stopAudio","emptyIndex","splice","_conversationAssistantMessage","at","userMsg","messageId","responseId","appearance","_conversationAssistantResponseId","prev","hideTypingIndicator","j","msgIndex","newMessage","id","normalizeAssistantAppearance","base64Audio","contentType","binaryString","atob","bytes","Uint8Array","charCodeAt","receivePcm","playCollectedAudio","showPlaceholder","clearHistoryBtn","classList","add","notification","receiveNotification","updateNotification","notificationType","removeNotification","onreconnecting","onreconnected","info","reloadCurrentInteraction","onclose","addMessageInternal","_this2","fireEvent","CustomEvent","detail","_this3","_message$rawContent","remove","event","icon","cssClass","disableStreamingAnimation","getAssistantLabel","getAssistantRoleClasses","classes","getAssistantIconClasses","shouldAnimateAssistantIcon","getAssistantIcon","isIndicator","sendMessage","_this4","_callee2","trimmedPrompt","_context2","endActiveVoiceSession","flushPendingSave","streamMessage","_this5","dispose","streamingStarted","showTypingIndicator","lastResponseId","messageIndex","currentItemId","getItemId","subscribe","chunk","sessionId","setItemId","keys","_i3","_Object$entries2","_normalizeReference2","_Object$entries2$_i","complete","_this5$stream","processReferences","streamingFinished","synthesizeSpeech","_this5$stream2","getServiceDownMessage","_this6","_ref19","_message$rawContent2","stopIcon","getAttribute","replaceChildren","RETURN_DOM_FRAGMENT","startIcon","icons","debouncedSaveSettings","handleExternalTtsStop","_e$detail","sourceId","updateTtsPlaybackButtons","_this7","buttons","button","buttonIndex","Number","isPlaying","iconHtml","toggle","updateCopyButtons","_this8","isCopied","setCopyButtonState","cacheIndex","_this9","_ttsCacheIndex","invoke","toggleMessageTts","_this0","playAudioBlob","_this1","totalLength","reduce","sum","combined","offset","_iterator8","_step8","blob","Blob","_this10","URL","createObjectURL","audio","Audio","revokeObjectURL","playNextInQueue","play","_this11","nextBlob","shift","conversationModeOnAudioEnded","_this12","pause","currentTime","setVoiceSessionLive","live","nextElementSibling","audioSettings","toggleConversationMode","stopConversationMode","startConversationMode","isActive","stop","_this13","updateConversationButton","navigator","mediaDevices","getUserMedia","echoCancellation","noiseSuppression","autoGainControl","mimeType","MediaRecorder","isTypeSupported","audioBitsPerSecond","_conversationSubject","Subject","_conversationStream","AudioCtx","AudioContext","webkitAudioContext","_conversationAudioCtx","_conversationAnalyser","createAnalyser","fftSize","micSource","createMediaStreamSource","connect","pendingChunk","analyser","interruptVolumeThreshold","size","freqData","frequencyBinCount","getByteFrequencyData","k","avg","_callee3","uint8Array","base64","_context3","arrayBuffer","str","byte","String","fromCharCode","btoa","getTracks","track","documentElement","send","close","dismissible","autoDismissMs","endHtml","blur","startHtml","conversationModeSendPrompt","originalLength","removedCount","_this14","setTimeout","scrollTop","scrollHeight","clientHeight","handleUserInput","target","getSaveIndicatorElement","saveIndicatorElementSelector","_this15","indicator","clearTimeout","clearPendingSettingsSave","getFieldLabel","input","_input$closest","setting","getValidationFeedbackElement","feedback","contains","clearSettingValidationError","removeAttribute","setSettingValidationError","getSettingValidationMessage","disabled","number","fieldLabel","isNaN","min","max","validateSettingInput","validateSettings","_this16","isValid","getSettingInputs","queueSettingsSave","explicitInputs","getSelectedGroupValues","groupName","fallbackSelector","explicitSelections","values","checkbox","checkboxes","baseName","hiddenInput","getPromptTemplateSelections","promptTemplates","card","templateIdInput","promptParametersInput","templateId","promptParameters","clearNotificationDismiss","findIndex","scheduleNotificationDismiss","_this17","timerId","dismissNotification","handleNotificationAction","actionName","resetInteraction","initializeApp","_this18","placeholderElementSelector","loadInteraction","threshold","atBottom","shiftKey","click","lastMsg","pop","chatInteractionItems","getElementsByClassName","preventDefault","initialMessages","btn","block","codeEl","clipboard","writeText","copiedText","clearHistory","micButtonElementSelector","style","display","toggleRecording","conversationButtonElementSelector","CoreAIRealtime","realtimeButtonElementSelector","attach","ensureConnected","sendStart","subject","voice","silenceMs","vadThreshold","allowInterruption","webRtcEnabled","realtimeWebRtcEnabled","sendStartWebRtc","offerSdp","webRtcIceServers","realtimeWebRtcIceServers","voiceName","realtimeVoiceName","getVoiceName","el","realtimeVoiceSelectElementSelector","capableDeployments","realtimeCapableDeployments","selectors","onSessionStateChanged","active","onActivate","onDeactivate","onEnterRealtimeMode","onUserTurnPending","onUserTurnDropped","dropped","setupRealtimeVoicePicker","realtimeVoicesUrl","voiceSelect","voiceGroup","realtimeVoiceGroupElementSelector","conversationSelect","conversationDeploymentSelectElementSelector","capable","savedVoiceId","self","isRealtimeDeployment","resolveConversationDeployment","defaultRealtimeDeploymentName","loadVoices","_loadVoices","_callee4","deploymentName","realtime","response","result","grouped","_iterator9","_step9","_t2","_context4","applyMode","fetch","encodeURIComponent","credentials","headers","ok","voices","gender","has","localeCompare","optgroup","option","selected","appendChild","clearHistoryConfirmed","confirmDialog","okText","cancelText","callback","confirmed","confirm","_this19","saveSettings","getSelectedToolNames","getSelectedMcpConnectionIds","getSelectedA2AConnectionIds","getSelectedAgentNames","_this20","settings","inputs","match","checked","parseFloat","toolNames","mcpConnectionIds","a2aConnectionIds","agentNames","promptTemplateIds","template","force","clearCopiedMessageState","copyResponse","_ref21","_message$copyContent","_event$target","_event$target$closest","_this21","currentTarget","startRecording","_this22","_callee5","_context5","updateMicButton","watch","_this23","mounted","_this24","_callee6","_context6","$el","fontAwesomeObserver","beforeUnmount","removeEventListener","disconnect","mount","autoInitializeSelector","parseJsonAttribute","element","attributeName","description","rawValue","initializeFromElement","chatInteractionInitialized","__chatInteractionApp","scanForAutoInitialization","startAutoInitialization","body","readyState","chatInteractionDocumentManager","managerStateKey","normalizeDocumentInfo","documentId","DocumentId","fileName","FileName","fileSize","FileSize","formatFileSize","toFixed","getDocumentKey","isDuplicateFile","file","knownKeys","getDocumentsFromDom","chatDocumentId","chatDocumentName","chatDocumentSize","fileInput","documentsList","status","progressContainer","progressBar","uploadQueue","previousState","interactionDocuments","existingDocuments","uploadItems","isUploadingDocuments","createTextElement","tagName","renderDocuments","documentInfo","row","actions","downloadBaseUrl","downloadDocumentBaseUrl","downloadLink","downloadIcon","removeButton","removeIcon","removeDocument","details","prepend","showUploadStatus","showUploadProgress","progress","width","roundedProgress","round","getUploadStatePresentation","state","badgeClass","progressClass","formatUploadMessage","item","renderUploadQueue","presentation","header","fileDetails","badge","progressState","createUploadItem","lastModified","Date","now","updateUploadItem","updates","removeUploadItems","predicate","uploadSingleDocument","itemIdToUpdate","fileIndex","totalFiles","reject","formData","FormData","append","xhr","XMLHttpRequest","open","uploadDocumentUrl","upload","lengthComputable","fileProgress","loaded","total","overallProgress","responseText","Error","uploadDocuments","_x","_uploadDocuments","_callee7","files","filesToUpload","duplicateItems","knownDocumentKeys","pendingItems","uploadedCount","failedUploads","pendingItem","uploaded","failed","missingUploadMessage","failedMessage","errorMessage","_t3","_t4","_context7","Set","join","_x2","_removeDocument","_callee8","serverDocuments","_t5","_t6","_context8","removeDocumentUrl","method","stringify","redirected","documents","onFileInputChange","selectedFiles","chatInteractionDocumentManagerInitialized","download","toDataURL","img","startsWith","res","removeChild"],"mappings":"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","file":"chat-interaction.js","sourcesContent":["/*\n * Figure markers: the short labels the model writes, turned into pictures by the host.\n *\n * Retrieval hands the model a label -- [fig:1] -- and keeps the picture's real link in the message's reference\n * map, the same way a text citation keeps its source behind \"[doc:1]\". A model asked to reproduce a long opaque\n * identifier does not reproduce it: it copies the shape and substitutes ordinals, so links to figures that were\n * never in the results came back as 404s. A label short enough to be written exactly, with the link put back\n * here where the model cannot reach it, is what stops that.\n *\n * It sits on window rather than inside the manager below so the host can reach it, and so its rules can be\n * exercised in a bare sandbox with no browser and no DOM -- see tests/realtime-client/figure-markers.test.js --\n * exactly as window.CoreAIRealtime exposes the microphone gate's rules.\n *\n * The same block sits at the top of ai-chat.js: the two chat clients are separate bundles that share no\n * module of their own, and both render the same markdown. Change one, change the other.\n */\n// CoreAIChatMarkers lives in chat-markers.js, which every chat surface loads before this file.\n\nwindow.chatInteractionManager = 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 codeCopiedText: 'Copied!',\n copyTitle: 'Click here to copy response to clipboard.',\n copiedTitle: 'Response copied to clipboard.',\n copyResetDelayMs: 2000,\n assistantLabel: 'Assistant',\n\n messageTemplate: `\n
\n
\n
\n
You
\n
\n \n {{ getAssistantLabel(message) }}\n
\n
\n

{{ message.title }}

\n
\n
    \n
  1. \n {{ citation.label }}\n {{ citation.label }}\n
  2. \n
\n \n \n \n \n
\n
\n
\n
\n
\n \n {{ notification.content }}\n \n
\n
\n \n
\n
\n
\n `,\n indicatorTemplate: `\n
\n \n Assistant\n
\n `,\n // Localizable strings\n untitledText: 'Untitled',\n clearHistoryTitle: 'Clear History',\n clearHistoryMessage: 'Are you sure you want to clear the chat history? This action cannot be undone. Your documents, parameters, and tools will be preserved.',\n clearHistoryOkText: 'Yes',\n clearHistoryCancelText: 'Cancel'\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 containsFontAwesomePlaceholders(root) {\n if (!root || root.nodeType !== 1) {\n return false;\n }\n\n var selector = 'i[class*=\"fa-\"],i.fa,i.fas,i.far,i.fab';\n if (typeof root.matches === 'function' && root.matches(selector)) {\n return true;\n }\n\n return typeof root.querySelector === 'function' && !!root.querySelector(selector);\n }\n\n function refreshFontAwesomeIcons(root) {\n var fontAwesome = window.FontAwesome;\n if (!containsFontAwesomePlaceholders(root) || !fontAwesome || !fontAwesome.dom || typeof fontAwesome.dom.i2svg !== 'function') {\n return;\n }\n\n fontAwesome.dom.i2svg({ node: root });\n }\n\n function observeFontAwesomeIcons(root) {\n if (!root || typeof MutationObserver === 'undefined') {\n return null;\n }\n\n var observer = new MutationObserver(function (mutations) {\n mutations.forEach(function (mutation) {\n mutation.addedNodes.forEach(function (node) {\n refreshFontAwesomeIcons(node);\n });\n });\n });\n\n observer.observe(root, {\n childList: true,\n subtree: true\n });\n\n return observer;\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 normalized.isGenerated = (normalized.isGenerated ?? normalized.IsGenerated) === true;\n normalized.isImage = (normalized.isImage ?? normalized.IsImage) === true;\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 // Installed at the top of this file so it can be unit tested without a browser; see the comment there.\n const expandImageMarkers = window.CoreAIChatMarkers.expandImageMarkers;\n\n function getCitationLabel(reference, key) {\n return reference.title || reference.text || key;\n }\n\n // Which references are one citation, and how a repeated marker reads, are statements about strings and\n // live in chat-markers.js so every chat surface numbers them the same way. Without the module each\n // reference keeps an identity of its own and nothing merges, which is the numbering this script had\n // before it.\n let unmergedCitationCount = 0;\n const citationIdentity = window.CoreAIChatMarkers?.citationIdentity\n ?? (() => `unmerged-${++unmergedCitationCount}`);\n const splitCombinedCitations = window.CoreAIChatMarkers?.splitCombinedCitations\n ?? (content => content);\n const collapseRepeatedCitations = window.CoreAIChatMarkers?.collapseRepeatedCitations\n ?? (html => html);\n const separateAdjacentCitations = window.CoreAIChatMarkers?.separateAdjacentCitations\n ?? (html => html);\n const citationMarkerHtml = window.CoreAIChatMarkers?.citationMarkerHtml\n ?? (displayIndex => `${displayIndex}`);\n\n function buildCitationDisplay(content, references) {\n // Before anything looks for a reference key, the combined form the model tends to write is split into\n // the keys it means. A key that is not found is not replaced, and an unreplaced key reaches the reader\n // as a raw marker mid-sentence.\n let processedContent = splitCombinedCitations((content || '').trim());\n const messageReferences = normalizeReferences(references);\n const referenceEntries = Object.entries(messageReferences);\n\n if (!referenceEntries.length) {\n return { content: processedContent, citations: [] };\n }\n\n const citedRefs = referenceEntries.filter(([key]) => processedContent.includes(key));\n const generatedRefs = referenceEntries.filter(([key, value]) => value.isGenerated && !processedContent.includes(key));\n\n if (!citedRefs.length && !generatedRefs.length) {\n return { content: processedContent, citations: [] };\n }\n\n citedRefs.sort(([, a], [, b]) => a.index - b.index);\n generatedRefs.sort(([, a], [, b]) => a.index - b.index);\n\n const citations = [];\n const citationsByIdentity = new Map();\n const placeholders = [];\n let displayIndex = 1;\n\n for (const [key, value] of citedRefs) {\n const label = getCitationLabel(value, key);\n const link = value.link || null;\n const identity = citationIdentity(label, link);\n let citation = citationsByIdentity.get(identity);\n\n // Every reference still has its key replaced, so the text never keeps a raw key; what the merge\n // changes is only how many numbers the reader is given for them.\n if (!citation) {\n citation = {\n referenceKey: key,\n referenceKeys: [],\n displayIndex: displayIndex++,\n label: label,\n link: link,\n isDownload: isDownloadCitationReference(value),\n };\n\n citationsByIdentity.set(identity, citation);\n citations.push(citation);\n }\n\n citation.referenceKeys.push(key);\n\n const placeholder = `__CITE_${citation.displayIndex}_${value.index || citation.displayIndex}__`;\n processedContent = processedContent.replaceAll(key, placeholder);\n placeholders.push({ placeholder, displayIndex: citation.displayIndex, label: citation.label });\n }\n\n for (const entry of placeholders) {\n processedContent = processedContent.replaceAll(entry.placeholder, citationMarkerHtml(entry.displayIndex, entry.label));\n }\n\n // Merged citations can leave the same number twice over a sentence; that is collapsed before the\n // commas go in, or the reader is given \"1,1\".\n processedContent = collapseRepeatedCitations(processedContent);\n processedContent = separateAdjacentCitations(processedContent);\n\n // Generated files (such as exported tabular data) are always offered as a download even when\n // the model does not cite them inline, so the user never loses access to the produced file.\n for (const [key, value] of generatedRefs) {\n citations.push({\n referenceKey: key,\n referenceKeys: [key],\n displayIndex: displayIndex,\n label: getCitationLabel(value, key),\n link: value.link || null,\n isDownload: true,\n placeholder: null,\n });\n\n displayIndex++;\n }\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 // Every key the citation absorbed is replaced, not just the first: a merged key left behind would\n // reach the clipboard as the raw reference token the reader never saw on the page.\n for (const citation of citations) {\n for (const key of (citation.referenceKeys?.length ? citation.referenceKeys : [citation.referenceKey])) {\n copyContent = copyContent.replaceAll(key, `[${citation.displayIndex}]`);\n }\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 // Figure markers become images before anything else reads the content: the citation pass looks for its\n // own keys in what is left, and the markdown parser then sees an ordinary image.\n const displayContent = expandImageMarkers(rawContent, messageReferences);\n const citationDisplay = buildCitationDisplay(displayContent, 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 // Copied from the expanded content, so a copied answer carries the picture's link rather than a label\n // that means nothing outside this page.\n // Split here too: the copy is built from the expanded content rather than the display path's output,\n // so a combined marker would otherwise survive into the clipboard as a raw key.\n message.copyContent = buildCopyContent(splitCombinedCitations(displayContent), 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 `${data.text}`;\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 `
${langDisplay}
${highlighted}
`;\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 // Spans, not divs. A figure marker is often written mid-sentence -- \"Figures [fig:1], [fig:2] and\n // [fig:3] show...\" -- and a block element cannot sit inside a paragraph: the browser closes the

\n // at the first one, so the sentence is torn into fragments and the commas between the markers are\n // left stranded on their own lines. Inline-block keeps the figure looking exactly the same while\n // remaining something a paragraph can legally contain.\n return `\n \"${alt}\"\n \n \n \n \n \n `;\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 shared with ai-chat.js\n window.__chartConfigs = window.__chartConfigs || {};\n\n function createChartHtml(chartId) {\n return `

`\n + ``\n + `
`\n + `
`\n + ``\n + `
`;\n }\n\n // The marker itself is read by chat-markers.js, shared with every other chat surface, so the three of them\n // cannot disagree about what a marker is. Everything below -- the container, the id scheme, the Chart.js\n // call -- is this surface's own and legitimately differs from the others.\n const findChartMarker = window.CoreAIChatMarkers.findChartMarker;\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 = findChartMarker(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 // An image the assistant named but the server will not serve. The address is written by a language\n // model from what retrieval handed it, so a mistyped or invented one is possible, and the browser's\n // default for that is a broken-image icon captioned with the alt text -- which reads as a real picture\n // that failed to arrive. Saying plainly that it could not be loaded is both truer and quieter.\n //\n // Wired here rather than as an inline onerror attribute because message bodies go through DOMPurify,\n // which strips event-handler attributes.\n function markBrokenImagesInMessage() {\n // Scanning the document rather than one message, because the value threaded through the render\n // path is the message DATA object -- the thing carrying content, references and pending charts --\n // and not the element it was rendered into. Wiring is idempotent via the data-broken-wired mark,\n // so re-scanning after each render costs a query over the handful of images already handled.\n if (typeof document === 'undefined' || typeof requestAnimationFrame !== 'function') {\n return;\n }\n\n // Deferred for the same reason the charts below are: the render that produced these elements has\n // not necessarily been flushed to the DOM when this runs.\n requestAnimationFrame(wireBrokenImageHandlers);\n }\n\n function wireBrokenImageHandlers() {\n const images = document.querySelectorAll('.generated-image-container img:not([data-broken-wired])');\n\n for (const image of images) {\n image.setAttribute('data-broken-wired', 'true');\n image.addEventListener('error', function () {\n const container = image.closest('.generated-image-container');\n\n if (!container || container.dataset.brokenHandled) {\n return;\n }\n\n container.dataset.brokenHandled = 'true';\n container.hidden = true;\n\n const note = document.createElement('p');\n note.className = 'text-muted small fst-italic mb-2';\n note.textContent = image.alt\n ? `(the picture \"${image.alt}\" could not be loaded)`\n : '(that picture could not be loaded)';\n container.insertAdjacentElement('afterend', note);\n }, { once: true });\n }\n }\n\n function renderMessageMedia(message) {\n markBrokenImagesInMessage();\n\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 const canvas = document.getElementById(c.chartId);\n if (!canvas) {\n continue;\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., ).');\n continue;\n }\n\n // When the canvas is inside a hidden container (e.g., display:none),\n // it has zero dimensions. Keep the config for later rendering.\n if (canvas.offsetParent === null) {\n window.__chartConfigs[c.chartId] = c.config;\n continue;\n }\n\n try {\n // Destroy existing chart instance if re-rendering\n if (canvas._chartInstance) {\n canvas._chartInstance.destroy();\n }\n\n const cfg = typeof c.config === 'string' ? JSON.parse(c.config) : c.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 } catch (e) {\n console.error('Error creating chart:', e);\n }\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 // A markdown table becomes a bare , which Bootstrap leaves completely unstyled: it renders\n // as cramped, borderless text that reads as plain output rather than a table. Adding the framework's\n // own classes styles it wherever Bootstrap is loaded, and the wrapper lets a wide table scroll on\n // its own instead of stretching the conversation. Markdown tables cannot nest, so the plain\n // replacement is safe. This page renders markdown through its own pipeline, so the same treatment\n // is applied here as in the shared chat script.\n function styleMarkdownTables(html) {\n return html\n .replace(/
/g, '
')\n .replace(/<\\/table>/g, '
');\n }\n\n function parseMarkdownContent(content, message) {\n _pendingCharts = [];\n const html = styleMarkdownTables(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 function compactObject(source) {\n if (!source || typeof source !== 'object') {\n return {};\n }\n\n return Object.fromEntries(\n Object.entries(source).filter(([, value]) => value !== undefined)\n );\n }\n\n const initialize = (instanceConfig) => {\n const config = Object.assign({}, defaultConfig, compactObject(instanceConfig));\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 app = Vue.createApp({\n data() {\n return {\n inputElement: null,\n buttonElement: null,\n chatContainer: null,\n placeholder: null,\n isInteractionStarted: false,\n isPlaceholderVisible: true,\n isStreaming: false,\n isNavigatingAway: false,\n autoScroll: true,\n stream: null,\n messages: [],\n prompt: '',\n initialFieldValues: new Map(),\n settingsDirty: false,\n saveSettingsTimeout: null,\n saveIndicatorTimeout: null,\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 ttsPlayingMessageIndex: -1,\n ttsAudioCache: {},\n ttsInstanceId: 'chat-interaction-' + Math.random().toString(36).slice(2),\n conversationModeEnabled: config.chatMode === 'Conversation',\n conversationButton: null,\n isConversationMode: false,\n // Realtime (speech-to-speech) controller from the shared CoreAIRealtime module.\n realtimeController: null,\n realtimeButton: null,\n // Whether a realtime deployment actually resolved. The controller is attached whenever the\n // module is loaded, so its presence says nothing about which transport carries the\n // conversation -- only this flag does.\n realtimeEnabled: config.realtimeEnabled === true,\n notifications: [],\n notificationDismissTimers: {},\n copyTitle: config.copyTitle,\n copiedTitle: config.copiedTitle,\n copiedMessageIndex: -1,\n copyResetTimeoutId: null,\n activeCopyButton: 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 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(\"LoadInteraction\", (data) => {\n this.initializeInteraction(data.itemId, true);\n this.messages = [];// Update the title field if it exists\n const titleInput = document.querySelector('[data-chat-interaction-title], .setting-input[data-setting=\"title\"], input[name=\"ChatInteraction.Title\"], input[name=\"Title\"]');\n if (titleInput && data.title) {\n titleInput.value = data.title;\n }\n\n (data.messages ?? []).forEach(msg => {\n this.addMessage(msg);\n\n this.$nextTick(() => {\n renderMessageMedia(msg);\n });\n });\n });\n\n this.connection.on(\"SettingsSaved\", (itemId, title) => {\n // Update the history list item if it exists\n // Use a more specific selector to only target history list items, not other elements like the Clear History button\n const historyItem = document.querySelector(`.chat-interaction-history-item[data-interaction-id=\"${itemId}\"]`);\n if (historyItem) {\n historyItem.textContent = title || config.untitledText;\n }\n\n const titleInput = document.querySelector('[data-chat-interaction-title], .setting-input[data-setting=\"title\"], input[name=\"ChatInteraction.Title\"], input[name=\"Title\"]');\n if (titleInput && title) {\n titleInput.value = title;\n }\n\n this.showSaveIndicator('Saved', 'text-success');\n });\n\n this.connection.on(\"ReceiveError\", (error) => {\n console.error(\"SignalR Error: \", error);\n this.showSaveIndicator('Save failed', 'text-danger');\n\n if (this.isRecording) {\n this.stopRecording();\n }\n });\n\n this.connection.on(\"ReceiveTranscript\", (itemId, text, isFinal) => {\n if (this.isConversationMode) {\n if (!isFinal && text) {\n this._conversationPartialTranscript = text;\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n var html = '

' + escaped + '

';\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\", (itemId, turnId, text) => {\n // Realtime: a placeholder for this turn was already inserted in the right position when\n // the utterance was captured (see onUserTurnPending), so just fill in its text.\n if (turnId && this._realtimePendingTurns && this._realtimePendingTurns[turnId]) {\n var pending = this._realtimePendingTurns[turnId];\n delete this._realtimePendingTurns[turnId];\n this.stopAudio();\n if (text) {\n pending.content = text;\n pending.rawContent = text;\n pending.isPartial = false;\n updateMessagePresentation(pending, pending.references);\n } else {\n var emptyIndex = this.messages.indexOf(pending);\n if (emptyIndex >= 0) { this.messages.splice(emptyIndex, 1); }\n }\n\n return;\n }\n\n if (text) {\n this.stopAudio();\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '

' + escaped + '

';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else if (this._conversationAssistantMessage) {\n // Realtime: the user's transcript lags the assistant's reply for the SAME turn (the\n // model answers the audio before speech-to-text finishes). Insert the user message\n // just before the streaming assistant message so the order stays You -> Assistant,\n // and keep that message streaming — ending it here split one reply into two bubbles.\n var at = this._conversationAssistantMessage.index;\n var userMsg = { role: 'user', content: text, rawContent: text, references: {} };\n updateMessagePresentation(userMsg, userMsg.references);\n this.messages.splice(at, 0, userMsg);\n this._conversationAssistantMessage.index = at + 1;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (itemId, messageId, token, responseId, references, appearance) => {\n // A new response id means a new turn — finalize the previous assistant message so two replies\n // never merge into one bubble (also covers barge-in, which starts a fresh response).\n if (this._conversationAssistantMessage && this._conversationAssistantResponseId && responseId && this._conversationAssistantResponseId !== responseId) {\n var prev = this.messages[this._conversationAssistantMessage.index];\n if (prev) { prev.isStreaming = false; }\n this._conversationAssistantMessage = null;\n }\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 appearance: this.normalizeAssistantAppearance(appearance),\n references: {},\n };\n this.messages.push(newMessage);\n this._conversationAssistantMessage = { index: msgIndex, content: '' };\n this._conversationAssistantResponseId = responseId;\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 renderMessageMedia(msg);\n this.scrollToBottom();\n });\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantComplete\", (itemId, 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 this._conversationAssistantResponseId = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (itemId, 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 // Realtime PCM streams straight to the low-latency player; other formats (TTS) are buffered.\n if (contentType === 'audio/pcm' && this.realtimeController) {\n this.realtimeController.receivePcm(bytes);\n } else {\n this.audioChunks.push(bytes);\n }\n }\n });\n\n this.connection.on(\"ReceiveAudioComplete\", (itemId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"HistoryCleared\", (itemId) => {\n // Clear messages and show placeholder\n this.messages = [];\n this.showPlaceholder();\n\n // Hide the clear history button since there's no history now\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.classList.add('d-none');\n }\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 this.reloadCurrentInteraction();\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(\"addingChatInteractionMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedChatInteractionMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\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 renderMessageMedia(message);\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 fireEvent(event) {\n document.dispatchEvent(event);\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 : defaultConfig.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 isIndicator(message) {\n return message.role === 'indicator';\n },\n async sendMessage() {\n let trimmedPrompt = this.prompt.trim();\n\n if (!trimmedPrompt) {\n return;\n }\n\n // A live voice session and a typed turn are two writers into one interaction, and they\n // would interleave. End the session first; the turns it already produced are persisted, so\n // the typed message simply continues the same thread.\n this.endActiveVoiceSession();\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 // Flush any pending settings save before sending a message\n // to prevent concurrent hub calls that can cause database deadlocks.\n await this.flushPendingSave();\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n // Show the clear history button since we now have prompts\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.classList.remove('d-none');\n }\n\n this.streamMessage(trimmedPrompt);\n this.inputElement.value = '';\n this.prompt = '';\n },\n streamMessage(trimmedPrompt) {\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 var messageIndex = this.messages.length;\n var currentItemId = this.getItemId();\n\n this.stream = this.connection.stream(\"SendMessage\", currentItemId, trimmedPrompt)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n if (chunk.sessionId && !currentItemId) {\n this.setItemId(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n messageIndex = this.messages.length;\n let newMessage = {\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n };\n\n this.messages.push(newMessage);\n message = newMessage;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\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 message.rawContent = content;\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderMessageMedia(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 return {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\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 renderMessageMedia(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 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 // 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 // Save any settings that were deferred during streaming.\n if (this.settingsDirty) {\n this.debouncedSaveSettings();\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 ? ''\n : '';\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 updateCopyButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-copy-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-copy-message-index'));\n var isCopied = buttonIndex === this.copiedMessageIndex;\n var iconHtml = isCopied\n ? ''\n : '';\n\n button.classList.toggle('text-success', isCopied);\n button.classList.toggle('text-secondary', !isCopied);\n button.setAttribute('title', isCopied ? this.copiedTitle : this.copyTitle);\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\n });\n },\n setCopyButtonState(button, isCopied) {\n if (!button) {\n return;\n }\n\n var iconHtml = isCopied\n ? ''\n : '';\n\n button.classList.toggle('text-success', isCopied);\n button.classList.toggle('text-secondary', !isCopied);\n button.setAttribute('title', isCopied ? this.copiedTitle : this.copyTitle);\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\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.getItemId(), 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.isPlayingAudio && 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 currently playing, queue this blob for later.\n if (this.isPlayingAudio && 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 const 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 // A live voice session takes the message box away and puts the audio settings in its place; ending\n // the session gives it back. Sending a typed message already ends the session first, so the box was\n // never a way to say something *during* one -- hiding it only makes that honest, and frees the row\n // for the gear. Both transports land here: realtime through the module's onActivate, the\n // speech-to-text cascade through startConversationMode.\n setVoiceSessionLive(live) {\n if (this.inputElement) {\n this.inputElement.hidden = live;\n }\n\n if (this.buttonElement) {\n this.buttonElement.hidden = live;\n }\n\n // With the message box gone the live button would otherwise sit at its natural width in an\n // empty row, so it takes the space the box left behind. Whichever transport is carrying the\n // conversation owns a different button, and the hidden one is unaffected by the class.\n [this.realtimeButton, this.conversationButton].forEach(function (button) {\n if (button) { button.classList.toggle('flex-grow-1', live); }\n });\n\n // The gear is built by the realtime module directly after the button it was handed, and only\n // in realtime mode, so it is absent on the cascade. It belongs to a live session rather than\n // to the surface. The module hard-codes its element id and a page can host two chat clients\n // at once -- this one and the admin widget -- so it is found next to this client's own button\n // rather than by id.\n var next = this.realtimeButton && this.realtimeButton.nextElementSibling;\n var audioSettings = next && next.id === 'realtime-audio-settings' ? next : null;\n if (audioSettings) {\n audioSettings.hidden = !live;\n }\n },\n toggleConversationMode() {\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n // Two writers into one interaction would interleave, so the voice session ends before the typed\n // turn starts rather than running alongside it.\n endActiveVoiceSession() {\n if (this.realtimeController && this.realtimeController.isActive()) {\n this.realtimeController.stop();\n\n return;\n }\n\n if (this.isConversationMode) {\n this.stopConversationMode();\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\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 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 itemId = this.getItemId();\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"StartConversation\", itemId, 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, continuation is handled\n // by the persistent stream.\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 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 getItemId() {\n return this.inputElement.getAttribute('data-interaction-id')\n || this.inputElement.getAttribute('data-item-id');\n },\n getSaveIndicatorElement() {\n if (config.saveIndicatorElementSelector) {\n return document.querySelector(config.saveIndicatorElementSelector);\n }\n\n return document.querySelector('[data-chat-interaction-save-indicator]');\n },\n showSaveIndicator(text, className) {\n const indicator = this.getSaveIndicatorElement();\n if (!indicator) {\n return;\n }\n\n indicator.textContent = text || '';\n indicator.className = 'settings-save-indicator ' + (className || 'text-muted');\n\n if (this.saveIndicatorTimeout) {\n clearTimeout(this.saveIndicatorTimeout);\n this.saveIndicatorTimeout = null;\n }\n\n if (!text) {\n return;\n }\n\n this.saveIndicatorTimeout = setTimeout(() => {\n indicator.textContent = '';\n this.saveIndicatorTimeout = null;\n }, 3000);\n },\n clearPendingSettingsSave() {\n if (this.saveSettingsTimeout) {\n clearTimeout(this.saveSettingsTimeout);\n this.saveSettingsTimeout = null;\n }\n },\n getFieldLabel(input) {\n const label = input\n .closest('.mb-3, .col-6, .col, .form-group, .form-floating')\n ?.querySelector('label');\n\n if (!label) {\n return input.dataset.setting || 'This field';\n }\n\n return (label.textContent || '')\n .replace(/\\s+/g, ' ')\n .trim()\n || input.dataset.setting\n || 'This field';\n },\n getValidationFeedbackElement(input) {\n let feedback = input.nextElementSibling;\n if (feedback && feedback.classList.contains('invalid-feedback')) {\n return feedback;\n }\n\n feedback = document.createElement('div');\n feedback.className = 'invalid-feedback';\n input.insertAdjacentElement('afterend', feedback);\n\n return feedback;\n },\n clearSettingValidationError(input) {\n input.classList.remove('is-invalid');\n input.removeAttribute('aria-invalid');\n\n const feedback = input.nextElementSibling;\n if (feedback && feedback.classList.contains('invalid-feedback')) {\n feedback.textContent = '';\n }\n },\n setSettingValidationError(input, message) {\n const feedback = this.getValidationFeedbackElement(input);\n input.classList.add('is-invalid');\n input.setAttribute('aria-invalid', 'true');\n feedback.textContent = message;\n },\n getSettingValidationMessage(input) {\n if (!input || input.disabled || input.type !== 'number') {\n return null;\n }\n\n const value = (input.value || '').trim();\n if (!value) {\n return null;\n }\n\n const number = Number(value);\n const fieldLabel = this.getFieldLabel(input);\n\n if (Number.isNaN(number)) {\n return `${fieldLabel} must be a valid number.`;\n }\n\n const min = input.getAttribute('min');\n if (min !== null && number < Number(min)) {\n return `${fieldLabel} must be ${min} or greater.`;\n }\n\n const max = input.getAttribute('max');\n if (max !== null && number > Number(max)) {\n return `${fieldLabel} must be ${max} or less.`;\n }\n\n return null;\n },\n validateSettingInput(input) {\n const message = this.getSettingValidationMessage(input);\n if (!message) {\n this.clearSettingValidationError(input);\n return true;\n }\n\n this.setSettingValidationError(input, message);\n return false;\n },\n validateSettings() {\n let isValid = true;\n\n this.getSettingInputs().forEach(input => {\n isValid = this.validateSettingInput(input) && isValid;\n });\n\n return isValid;\n },\n queueSettingsSave() {\n if (!this.validateSettings()) {\n this.clearPendingSettingsSave();\n this.settingsDirty = false;\n this.showSaveIndicator('Fix errors', 'text-danger');\n return;\n }\n\n this.settingsDirty = true;\n this.showSaveIndicator('Saving...', 'text-warning');\n this.debouncedSaveSettings();\n },\n getSettingInputs() {\n const explicitInputs = document.querySelectorAll('.setting-input[data-setting]');\n if (explicitInputs.length > 0) {\n return explicitInputs;\n }\n\n return document.querySelectorAll(\n 'input[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"]), ' +\n 'select[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"]), ' +\n 'textarea[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"])'\n );\n },\n getSelectedGroupValues(groupName, fallbackSelector) {\n const explicitSelections = document.querySelectorAll(`.capability-checkbox[data-save-group=\"${groupName}\"]:checked, .capability-checkbox[data-group=\"${groupName}\"]:checked`);\n if (explicitSelections.length > 0) {\n const values = [];\n\n explicitSelections.forEach(checkbox => {\n const value = checkbox.getAttribute('data-item-id') || checkbox.value;\n if (value) {\n values.push(value);\n }\n });\n\n return values;\n }\n\n if (!fallbackSelector) {\n return [];\n }\n\n const values = [];\n const checkboxes = document.querySelectorAll(fallbackSelector);\n\n checkboxes.forEach(checkbox => {\n const baseName = checkbox.name.replace('.IsSelected', '.ItemId');\n const hiddenInput = document.querySelector(`input[type=\"hidden\"][name=\"${baseName}\"]`);\n\n if (hiddenInput && hiddenInput.value) {\n values.push(hiddenInput.value);\n }\n });\n\n return values;\n },\n getPromptTemplateSelections() {\n const promptTemplates = [];\n\n document.querySelectorAll('.prompt-template-card').forEach(card => {\n const templateIdInput = card.querySelector('.prompt-template-id-input');\n const promptParametersInput = card.querySelector('.prompt-template-parameters-input');\n const templateId = templateIdInput ? templateIdInput.value : card.getAttribute('data-template-id');\n\n if (!templateId) {\n return;\n }\n\n promptTemplates.push({\n templateId: templateId,\n promptParameters: promptParametersInput ? (promptParametersInput.value || '').trim() : ''\n });\n });\n\n return promptTemplates;\n },\n receiveNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n // Replace existing notification with same type, or add new one.\n var idx = this.notifications.findIndex(n => n.type === notification.type);\n if (idx >= 0) {\n this.notifications.splice(idx, 1, notification);\n } else {\n this.notifications.push(notification);\n }\n this.scheduleNotificationDismiss(notification);\n this.scrollToBottom();\n },\n updateNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var idx = this.notifications.findIndex(n => n.type === notification.type);\n if (idx >= 0) {\n this.notifications.splice(idx, 1, notification);\n this.scheduleNotificationDismiss(notification);\n this.scrollToBottom();\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 itemId = this.getItemId();\n this.connection.invoke('HandleNotificationAction', itemId, notificationType, actionName)\n .catch(err => console.error('Failed to handle notification action:', err));\n },\n setItemId(itemId) {\n this.inputElement.setAttribute('data-interaction-id', itemId || '');\n this.inputElement.setAttribute('data-item-id', itemId || '');\n },\n resetInteraction() {\n this.setItemId('');\n this.isInteractionStarted = false;\n this.messages = [];\n this.showPlaceholder();\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 const itemId = this.getItemId();\n if (itemId) {\n this.loadInteraction(itemId);\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('keyup', event => {\n if (this.stream != null) {\n return;\n }\n\n if (event.key === \"Enter\" && !event.shiftKey) {\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.inputElement.addEventListener('paste', (e) => {\n // Use setTimeout to allow the paste to complete before checking the value\n setTimeout(() => {\n this.prompt = this.inputElement.value;\n if (this.inputElement.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n }, 0);\n });\n\n this.buttonElement.addEventListener('click', () => {\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 chatInteractionItems = document.getElementsByClassName('chat-interaction-history-item');\n\n for (var i = 0; i < chatInteractionItems.length; i++) {\n chatInteractionItems[i].addEventListener('click', (e) => {\n e.preventDefault();\n\n var itemId = e.target.getAttribute('data-interaction-id');\n\n if (!itemId) {\n console.error('An element with the class chat-interaction-history-item with no data-interaction-id set.');\n return;\n }\n\n this.loadInteraction(itemId);\n });\n }\n\n const initialMessages = Array.isArray(config.messages) ? config.messages : [];\n\n for (let i = 0; i < initialMessages.length; i++) {\n this.addMessage(initialMessages[i]);\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 = ' ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '';\n }, 2000);\n }\n });\n }\n\n document.addEventListener('input', event => {\n if (event.target.matches('.setting-input[data-setting]')) {\n this.validateSettingInput(event.target);\n this.queueSettingsSave();\n }\n });\n\n document.addEventListener('change', event => {\n if (event.target.matches('.setting-input[data-setting], .capability-checkbox[data-save-group], .capability-checkbox[data-group], .group-toggle, .ci-agent-global-toggle')) {\n if (event.target.matches('.setting-input[data-setting]')) {\n this.validateSettingInput(event.target);\n }\n\n this.queueSettingsSave();\n return;\n }\n\n if (event.target.closest('.prompt-template-parameters-input, .prompt-template-id-input')) {\n this.queueSettingsSave();\n }\n });\n\n document.addEventListener('click', event => {\n if (!event.target.closest('.prompt-template-add-btn, .remove-prompt-template-btn')) {\n return;\n }\n\n setTimeout(() => {\n this.queueSettingsSave();\n }, 0);\n });\n\n // Add event listener for clear history button\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.addEventListener('click', () => {\n const itemId = clearHistoryBtn.getAttribute('data-interaction-id');\n if (itemId) {\n this.clearHistory(itemId);\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 // Initialize realtime (speech-to-speech) mode via the shared CoreAIRealtime module. The\n // module owns the mic capture, playback, echo guard, push-to-talk and audio settings; the\n // callbacks below plug it into this app's connection and conversation-transcript display.\n if (window.CoreAIRealtime && config.realtimeButtonElementSelector) {\n // Kept so the voice settings popover can be found next to this client's own button.\n this.realtimeButton = document.querySelector(config.realtimeButtonElementSelector);\n this.realtimeController = window.CoreAIRealtime.attach({\n connection: this.connection,\n ensureConnected: () => Promise.resolve(this.connection),\n sendStart: (subject, voice, language, silenceMs, vadThreshold, allowInterruption) => {\n this.connection.send('StartRealtimeConversation', this.getItemId(), subject, voice, language, silenceMs, vadThreshold, allowInterruption);\n },\n // Prefer WebRTC (server-relay) when the server advertises it; the shared module falls back\n // to the WebSocket sendStart above if the peer cannot connect.\n webRtcEnabled: config.realtimeWebRtcEnabled === true,\n sendStartWebRtc: (offerSdp, voice, language, silenceMs, vadThreshold, allowInterruption) => {\n this.connection.send('StartRealtimeWebRtc', this.getItemId(), offerSdp, voice, language, silenceMs, vadThreshold, allowInterruption);\n },\n webRtcIceServers: Array.isArray(config.realtimeWebRtcIceServers) ? config.realtimeWebRtcIceServers : undefined,\n voiceName: config.realtimeVoiceName || '',\n getVoiceName: () => {\n var el = config.realtimeVoiceSelectElementSelector ? document.querySelector(config.realtimeVoiceSelectElementSelector) : null;\n return el ? el.value : '';\n },\n capableDeployments: config.realtimeCapableDeployments || [],\n realtimeEnabled: config.realtimeEnabled === true,\n // input and sendButton are deliberately not handed over. The module hides every\n // control it is given when realtime takes over, and typing has to stay available\n // during a voice conversation -- that is the whole feature.\n //\n // deploymentSelect is not handed over either: it would read the raw select value,\n // and an empty conversation deployment means \"use the site default\", which still\n // resolves. The host resolves it and calls applyMode itself (see below).\n selectors: {\n realtimeButton: config.realtimeButtonElementSelector,\n micButton: config.micButtonElementSelector,\n conversationButton: config.conversationButtonElementSelector\n },\n // The module owns whether a session is live, so the message box follows its flag\n // rather than this app's copy of it. Losing one of these events used to leave the\n // box hidden under a button that had already gone back to \"Start speaking\".\n onSessionStateChanged: (active) => {\n this.setVoiceSessionLive(active);\n },\n onActivate: () => {\n this.isConversationMode = true;\n this._conversationPartialMessage = null;\n this._conversationAssistantMessage = null;\n },\n onDeactivate: () => {\n this.isConversationMode = false;\n if (this._conversationAssistantMessage) {\n var m = this.messages[this._conversationAssistantMessage.index];\n if (m) { m.isStreaming = false; }\n this._conversationAssistantMessage = null;\n }\n },\n onEnterRealtimeMode: () => {\n if (this.isRecording) { this.stopRecording(); }\n if (this.isConversationMode && (!this.realtimeController || !this.realtimeController.isActive())) { this.stopConversationMode(); }\n },\n // The utterance has been captured but not transcribed yet. Showing a placeholder now\n // puts the prompt above the reply it produces: transcription lags the spoken answer, so\n // a bubble added only when the text arrives lands underneath its own reply.\n onUserTurnPending: (turnId) => {\n if (!turnId) { return; }\n var placeholder = { role: 'user', content: '', rawContent: '', references: {}, isPartial: true };\n updateMessagePresentation(placeholder, placeholder.references);\n this._realtimePendingTurns = this._realtimePendingTurns || {};\n this._realtimePendingTurns[turnId] = placeholder;\n this.messages.push(placeholder);\n this.scrollToBottom();\n },\n onUserTurnDropped: (turnId) => {\n if (!turnId || !this._realtimePendingTurns) { return; }\n var dropped = this._realtimePendingTurns[turnId];\n if (!dropped) { return; }\n delete this._realtimePendingTurns[turnId];\n var at = this.messages.indexOf(dropped);\n if (at >= 0) { this.messages.splice(at, 1); }\n }\n });\n\n this.setupRealtimeVoicePicker(config);\n\n // The module reveals the gear as soon as the surface enters realtime mode, but it belongs\n // to a live session. The watcher that would hide it only runs on a change, so the idle\n // state has to be stated once here.\n this.setVoiceSessionLive(false);\n }\n },\n // Populates the per-interaction realtime voice picker from the selected realtime deployment's\n // voices (via the realtime-voices endpoint), and shows it only for realtime-capable deployments.\n setupRealtimeVoicePicker(config) {\n if (!config.realtimeVoiceSelectElementSelector || !config.realtimeVoicesUrl) {\n return;\n }\n\n var voiceSelect = document.querySelector(config.realtimeVoiceSelectElementSelector);\n if (!voiceSelect) {\n return;\n }\n\n var voiceGroup = config.realtimeVoiceGroupElementSelector ? document.querySelector(config.realtimeVoiceGroupElementSelector) : null;\n var conversationSelect = config.conversationDeploymentSelectElementSelector\n ? document.querySelector(config.conversationDeploymentSelectElementSelector)\n : null;\n var capable = (config.realtimeCapableDeployments || []).map(function (n) { return (n || '').toLowerCase(); });\n var savedVoiceId = config.realtimeVoiceName || '';\n var self = this;\n\n function isRealtimeDeployment(name) {\n return name && capable.indexOf(name.toLowerCase()) !== -1;\n }\n\n // Mirrors the realtime slot's chain on the server: the interaction's own choice, then the\n // site default, then the first realtime-capable deployment. Only conversation mode reaches\n // it -- an interaction that is not in conversation mode never speaks.\n function resolveConversationDeployment() {\n if (!self.conversationModeEnabled) {\n return '';\n }\n\n var name = (conversationSelect && conversationSelect.value)\n || config.defaultRealtimeDeploymentName\n || (capable.length ? capable[0] : '');\n\n return isRealtimeDeployment(name) ? name : '';\n }\n\n async function loadVoices() {\n var deploymentName = resolveConversationDeployment();\n var realtime = !!deploymentName;\n if (voiceGroup) {\n voiceGroup.classList.toggle('d-none', !realtime);\n }\n\n // Changing the conversation deployment switches the voice toggle on or off without a\n // reload.\n if (self.realtimeController) {\n self.realtimeController.applyMode(realtime);\n }\n\n if (!realtime) {\n return;\n }\n\n voiceSelect.innerHTML = '';\n\n try {\n const response = await fetch(config.realtimeVoicesUrl + '?deploymentName=' + encodeURIComponent(deploymentName), { credentials: 'same-origin' });\n const contentType = (response.headers.get('content-type') || '').toLowerCase();\n\n // A sign-in redirect answers with HTML and response.ok, so this has to be checked\n // rather than parsed: the default voice is a fine outcome, a parser error is not.\n if (!response.ok || contentType.indexOf('json') < 0) {\n return;\n }\n\n const result = await response.json();\n if (!result || !Array.isArray(result.voices)) {\n return;\n }\n\n const grouped = new Map();\n for (const voice of result.voices) {\n const groupName = voice.gender || 'Voices';\n if (!grouped.has(groupName)) {\n grouped.set(groupName, []);\n }\n grouped.get(groupName).push(voice);\n }\n\n Array.from(grouped.keys()).sort((a, b) => a.localeCompare(b)).forEach(function (groupName) {\n const optgroup = document.createElement('optgroup');\n optgroup.label = groupName;\n grouped.get(groupName).forEach(function (voice) {\n const option = document.createElement('option');\n option.value = voice.id;\n option.textContent = voice.name;\n option.selected = voice.id === savedVoiceId;\n optgroup.appendChild(option);\n });\n voiceSelect.appendChild(optgroup);\n });\n } catch (err) {\n /* ignore voice load failures */\n }\n }\n\n if (conversationSelect) {\n conversationSelect.addEventListener('change', loadVoices);\n }\n loadVoices();\n },\n loadInteraction(itemId) {\n this.connection.invoke(\"LoadInteraction\", itemId).catch(err => console.error(err));\n },\n reloadCurrentInteraction() {\n const itemId = this.getItemId();\n if (itemId) {\n this.loadInteraction(itemId);\n }\n },\n clearHistory(itemId) {\n const self = this;\n const clearHistoryConfirmed = () => {\n // Force-stop any live realtime voice session before clearing history.\n if (self.realtimeController && self.realtimeController.isActive()) {\n self.realtimeController.stop();\n }\n\n // Cancel any active stream before clearing history.\n if (self.stream) {\n self.stream.dispose();\n self.stream = null;\n self.hideTypingIndicator();\n self.streamingFinished();\n }\n\n self.connection.invoke(\"ClearHistory\", itemId)\n .catch(err => console.error('Error clearing history:', err));\n };\n\n if (typeof confirmDialog === 'function') {\n confirmDialog({\n title: config.clearHistoryTitle,\n message: config.clearHistoryMessage,\n okText: config.clearHistoryOkText,\n cancelText: config.clearHistoryCancelText,\n callback: function (confirmed) {\n if (confirmed) {\n clearHistoryConfirmed();\n }\n }\n });\n\n return;\n }\n\n if (window.confirm(config.clearHistoryMessage || 'Clear all messages?')) {\n clearHistoryConfirmed();\n }\n },\n debouncedSaveSettings() {\n // Clear any existing timeout to reset the debounce timer\n this.clearPendingSettingsSave();\n\n // Don't save while streaming — it will be saved when streaming completes.\n if (this.stream) {\n return;\n }\n\n // Set a new timeout to save after 850ms of no changes\n this.saveSettingsTimeout = setTimeout(() => {\n if (this.settingsDirty) {\n this.saveSettings();\n this.settingsDirty = false;\n }\n this.saveSettingsTimeout = null;\n }, 850);\n },\n getSelectedToolNames() {\n return this.getSelectedGroupValues(\n 'toolNames',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Tools[\"]:checked'\n );\n },\n getSelectedMcpConnectionIds() {\n return this.getSelectedGroupValues(\n 'mcpConnectionIds',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Connections[\"]:checked'\n );\n },\n getSelectedA2AConnectionIds() {\n return this.getSelectedGroupValues('a2aConnectionIds');\n },\n getSelectedAgentNames() {\n return this.getSelectedGroupValues(\n 'agentNames',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Agents[\"]:checked'\n );\n },\n saveSettings() {\n const itemId = this.getItemId();\n if (!itemId) {\n return Promise.resolve();\n }\n\n if (!this.validateSettings()) {\n this.showSaveIndicator('Fix errors', 'text-danger');\n return Promise.resolve();\n }\n\n const settings = {};\n\n // Collect all form inputs with the \"ChatInteraction.\" prefix generically.\n // This avoids coupling the JS to specific field names — new fields added by\n // any module are automatically included.\n const inputs = this.getSettingInputs();\n\n inputs.forEach(input => {\n const key = input.dataset.setting\n || ((input.name || '').replace('ChatInteraction.', '').replace(/^[A-Z]/, match => match.toLowerCase()));\n\n if (!key) {\n return;\n }\n\n if (input.type === 'checkbox') {\n settings[key] = input.checked;\n } else if (input.type === 'number') {\n settings[key] = input.value ? parseFloat(input.value) : null;\n } else {\n settings[key] = input.value || null;\n }\n });\n\n // Add tool, MCP connection, and agent collections (special handling).\n settings.toolNames = this.getSelectedToolNames();\n settings.mcpConnectionIds = this.getSelectedMcpConnectionIds();\n settings.a2aConnectionIds = this.getSelectedA2AConnectionIds();\n settings.agentNames = this.getSelectedAgentNames();\n\n const promptTemplates = this.getPromptTemplateSelections();\n if (promptTemplates.length > 0) {\n settings.promptTemplates = promptTemplates;\n settings.promptTemplateIds = promptTemplates.map(template => template.templateId);\n }\n\n return this.connection.invoke(\"SaveSettings\", itemId, settings)\n .catch(err => {\n console.error('Error saving settings:', err);\n this.showSaveIndicator('Save failed', 'text-danger');\n });\n },\n flushPendingSave() {\n if (this.saveSettingsTimeout) {\n clearTimeout(this.saveSettingsTimeout);\n this.saveSettingsTimeout = null;\n }\n\n if (this.settingsDirty) {\n this.settingsDirty = false;\n return this.saveSettings();\n }\n\n return Promise.resolve();\n },\n initializeInteraction(itemId, force) {\n if (this.isInteractionStarted && !force) {\n return;\n }\n this.fireEvent(new CustomEvent(\"initializingChatInteraction\", { detail: { itemId: itemId } }));\n this.setItemId(itemId);\n this.isInteractionStarted = true;\n },\n clearCopiedMessageState() {\n if (this.copyResetTimeoutId) {\n window.clearTimeout(this.copyResetTimeoutId);\n this.copyResetTimeoutId = null;\n }\n\n if (this.activeCopyButton) {\n this.setCopyButtonState(this.activeCopyButton, false);\n this.activeCopyButton = null;\n }\n\n this.copiedMessageIndex = -1;\n },\n copyResponse(message, index, event) {\n const text = message && typeof message === 'object'\n ? message.copyContent ?? message.content ?? ''\n : message ?? '';\n const button = event?.currentTarget || event?.target?.closest?.('[data-copy-message-index]') || null;\n\n navigator.clipboard.writeText(text)\n .then(() => {\n this.clearCopiedMessageState();\n this.copiedMessageIndex = typeof index === 'number' ? index : -1;\n this.activeCopyButton = button;\n\n if (button) {\n this.setCopyButtonState(button, true);\n } else {\n this.$nextTick(() => this.updateCopyButtons());\n }\n\n this.copyResetTimeoutId = window.setTimeout(() => {\n this.clearCopiedMessageState();\n this.$nextTick(() => this.updateCopyButtons());\n }, Number(config.copyResetDelayMs) || 2000);\n })\n .catch(err => console.error('Failed to copy response:', err));\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 itemId = this.getItemId();\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\", itemId, 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 = '';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '';\n }\n }\n },\n watch: {\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 // The dictation microphone is hidden while a voice conversation runs: the conversation\n // already owns the microphone, and a second one would mean something different.\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n // The message box and the send button give way to the voice settings while the conversation\n // runs, and come back when it ends. Both kinds of turn still land in the same thread; what\n // they cannot do is overlap.\n //\n // Only the cascade is driven from here. Realtime follows the module's own session flag\n // (onSessionStateChanged), so the two never disagree about whether a session is live.\n if (!this.realtimeEnabled) {\n this.setVoiceSessionLive(active);\n }\n },\n copiedMessageIndex() {\n this.$nextTick(() => this.updateCopyButtons());\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n this.initializeApp();\n\n this.$nextTick(() => {\n this.updateCopyButtons();\n refreshFontAwesomeIcons(this.$el);\n this.fontAwesomeObserver = observeFontAwesomeIcons(this.$el);\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 if (this.fontAwesomeObserver) {\n this.fontAwesomeObserver.disconnect();\n this.fontAwesomeObserver = null;\n }\n\n this.clearCopiedMessageState();\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 template: config.messageTemplate\n }).mount(config.appElementSelector);\n\n return app;\n };\n\n const autoInitializeSelector = '[data-chat-interaction-config]';\n\n function parseJsonAttribute(element, attributeName, description) {\n const rawValue = element.getAttribute(attributeName);\n if (!rawValue) {\n return null;\n }\n\n try {\n return JSON.parse(rawValue);\n } catch (error) {\n console.error('Failed to parse ' + description + ' JSON.', error);\n return null;\n }\n }\n\n function initializeFromElement(element) {\n if (!element || element.dataset.chatInteractionInitialized === 'true') {\n return element ? element.__chatInteractionApp || null : null;\n }\n\n const config = parseJsonAttribute(element, 'data-chat-interaction-config', 'chat interaction config');\n if (!config) {\n return null;\n }\n\n const app = initialize(config);\n if (!app) {\n return null;\n }\n\n element.dataset.chatInteractionInitialized = 'true';\n element.__chatInteractionApp = app;\n\n return app;\n }\n\n function scanForAutoInitialization(root) {\n if (!root || typeof root.querySelectorAll !== 'function') {\n return;\n }\n\n if (typeof root.matches === 'function' && root.matches(autoInitializeSelector)) {\n initializeFromElement(root);\n }\n\n root.querySelectorAll(autoInitializeSelector).forEach(initializeFromElement);\n }\n\n function startAutoInitialization() {\n scanForAutoInitialization(document);\n\n if (typeof MutationObserver === 'undefined') {\n return;\n }\n\n const observer = new MutationObserver(mutations => {\n mutations.forEach(mutation => {\n mutation.addedNodes.forEach(node => {\n if (node && node.nodeType === 1) {\n scanForAutoInitialization(node);\n }\n });\n });\n });\n\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n });\n }\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', startAutoInitialization, { once: true });\n } else {\n startAutoInitialization();\n }\n\n return {\n initialize: initialize,\n initializeFromElement: initializeFromElement,\n };\n}();\n\nwindow.chatInteractionDocumentManager = function () {\n const managerStateKey = '__chatInteractionDocumentManagerState';\n\n function normalizeDocumentInfo(document) {\n if (!document || typeof document !== 'object') {\n return null;\n }\n\n return {\n documentId: document.documentId || document.DocumentId || '',\n fileName: document.fileName || document.FileName || '',\n fileSize: document.fileSize || document.FileSize || 0\n };\n }\n\n function formatFileSize(bytes) {\n if (!bytes || bytes < 1024) {\n return (bytes || 0) + ' B';\n }\n\n if (bytes < 1024 * 1024) {\n return (bytes / 1024).toFixed(1) + ' KB';\n }\n\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n }\n\n function getDocumentKey(fileName, fileSize) {\n return ((fileName || '').trim().toLowerCase()) + '::' + (fileSize || 0);\n }\n\n function isDuplicateFile(file, knownKeys) {\n return knownKeys.has(getDocumentKey(file.name, file.size));\n }\n\n function getDocumentsFromDom(container) {\n if (!container) {\n return [];\n }\n\n return Array.from(container.querySelectorAll('[data-chat-document-id]'))\n .map(element => normalizeDocumentInfo({\n documentId: element.dataset.chatDocumentId,\n fileName: element.dataset.chatDocumentName,\n fileSize: Number(element.dataset.chatDocumentSize || 0)\n }))\n .filter(document => document && document.documentId);\n }\n\n function initialize(config) {\n if (!config || !config.itemId) {\n return;\n }\n\n const fileInput = document.getElementById('chat-doc-upload');\n const documentsList = document.getElementById('chat-documents-list');\n const status = document.getElementById('chat-doc-upload-status');\n const progressContainer = document.getElementById('chat-doc-upload-progress');\n const progressBar = document.getElementById('chat-doc-upload-progress-bar');\n const uploadQueue = document.getElementById('chat-doc-upload-queue');\n\n if (!fileInput || !documentsList || !status || !progressContainer || !progressBar || !uploadQueue) {\n return;\n }\n\n const previousState = fileInput[managerStateKey];\n if (previousState && typeof previousState.dispose === 'function') {\n previousState.dispose();\n }\n\n let interactionDocuments = (Array.isArray(config.existingDocuments) ? config.existingDocuments : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n\n if (interactionDocuments.length === 0) {\n interactionDocuments = getDocumentsFromDom(documentsList);\n }\n\n let uploadItems = [];\n let isUploadingDocuments = false;\n\n function createTextElement(tagName, className, text) {\n const element = document.createElement(tagName);\n if (className) {\n element.className = className;\n }\n\n element.textContent = text;\n return element;\n }\n\n function renderDocuments() {\n documentsList.innerHTML = '';\n\n if (interactionDocuments.length === 0) {\n documentsList.appendChild(createTextElement('div', 'text-muted small', 'No documents uploaded yet.'));\n return;\n }\n\n interactionDocuments.forEach(documentInfo => {\n const row = window.document.createElement('div');\n row.className = 'd-flex align-items-center gap-2 border rounded px-2 py-2 bg-white chat-document-row';\n row.dataset.chatDocumentId = documentInfo.documentId;\n row.dataset.chatDocumentName = documentInfo.fileName;\n row.dataset.chatDocumentSize = documentInfo.fileSize;\n\n const actions = window.document.createElement('div');\n actions.className = 'd-flex gap-1';\n\n const downloadBaseUrl = config.downloadDocumentBaseUrl || '/ai/documents/';\n const downloadLink = createTextElement('a', 'btn btn-sm btn-outline-secondary', '');\n downloadLink.title = 'Download';\n downloadLink.href = downloadBaseUrl + encodeURIComponent(documentInfo.documentId) + '/download';\n const downloadIcon = window.document.createElement('i');\n downloadIcon.className = 'fa-solid fa-download';\n downloadLink.appendChild(downloadIcon);\n\n const removeButton = createTextElement('button', 'btn btn-sm btn-outline-danger remove-chat-document-btn', '');\n removeButton.type = 'button';\n removeButton.title = 'Remove';\n removeButton.dataset.documentId = documentInfo.documentId;\n const removeIcon = window.document.createElement('i');\n removeIcon.className = 'fa-solid fa-trash';\n removeButton.appendChild(removeIcon);\n removeButton.addEventListener('click', () => removeDocument(documentInfo.documentId));\n\n actions.appendChild(downloadLink);\n actions.appendChild(removeButton);\n\n const details = window.document.createElement('div');\n details.className = 'min-w-0';\n\n const name = createTextElement('div', 'fw-semibold small text-truncate', documentInfo.fileName || 'Document');\n const icon = window.document.createElement('i');\n icon.className = 'fa-solid fa-file-lines me-1';\n name.prepend(icon);\n\n const size = createTextElement('div', 'text-muted small', formatFileSize(documentInfo.fileSize));\n\n details.appendChild(name);\n details.appendChild(size);\n\n row.appendChild(actions);\n row.appendChild(details);\n documentsList.appendChild(row);\n });\n }\n\n function showUploadStatus(message, cssClass) {\n if (!message) {\n status.textContent = '';\n status.className = 'small mt-2 d-none';\n return;\n }\n\n status.textContent = message;\n status.className = 'small mt-2 ' + (cssClass || 'text-muted');\n }\n\n function showUploadProgress(progress, message, cssClass) {\n if (progress === null || progress === undefined) {\n progressContainer.className = 'progress mt-2 d-none';\n progressContainer.setAttribute('aria-valuenow', '0');\n progressBar.className = 'progress-bar progress-bar-striped progress-bar-animated';\n progressBar.style.width = '0%';\n progressBar.textContent = '0%';\n return;\n }\n\n const roundedProgress = Math.max(0, Math.min(100, Math.round(progress)));\n progressContainer.className = 'progress mt-2';\n progressContainer.setAttribute('aria-valuenow', roundedProgress.toString());\n progressBar.className = 'progress-bar ' + (cssClass || 'progress-bar-striped progress-bar-animated');\n progressBar.style.width = roundedProgress + '%';\n progressBar.textContent = message || (roundedProgress + '%');\n }\n\n function getUploadStatePresentation(state) {\n switch (state) {\n case 'uploaded':\n return { label: 'Uploaded', badgeClass: 'text-bg-success', progressClass: 'bg-success' };\n case 'failed':\n return { label: 'Failed', badgeClass: 'text-bg-danger', progressClass: 'bg-danger' };\n case 'uploading':\n return { label: 'Uploading', badgeClass: 'text-bg-warning', progressClass: 'bg-warning progress-bar-striped progress-bar-animated' };\n default:\n return { label: 'Queued', badgeClass: 'text-bg-secondary', progressClass: 'bg-secondary progress-bar-striped progress-bar-animated' };\n }\n }\n\n function formatUploadMessage(item) {\n if (item.status === 'failed' && item.error) {\n return item.error;\n }\n\n if (item.status === 'uploaded') {\n return 'Upload completed successfully.';\n }\n\n if (item.status === 'uploading') {\n return item.progress + '% uploaded';\n }\n\n return 'Waiting to upload...';\n }\n\n function renderUploadQueue() {\n uploadQueue.innerHTML = '';\n\n uploadItems.forEach(item => {\n const presentation = getUploadStatePresentation(item.status);\n const card = document.createElement('div');\n card.className = 'border rounded px-2 py-2 bg-white';\n\n const header = document.createElement('div');\n header.className = 'd-flex justify-content-between align-items-start gap-2';\n\n const fileDetails = document.createElement('div');\n fileDetails.className = 'flex-grow-1 min-w-0';\n fileDetails.appendChild(createTextElement('div', 'fw-semibold small', item.fileName));\n fileDetails.appendChild(createTextElement('div', 'text-muted small', formatFileSize(item.fileSize)));\n\n const badge = createTextElement('span', 'badge ' + presentation.badgeClass, presentation.label);\n\n header.appendChild(fileDetails);\n header.appendChild(badge);\n\n const progress = document.createElement('div');\n progress.className = 'progress mt-2';\n progress.setAttribute('role', 'progressbar');\n progress.setAttribute('aria-valuemin', '0');\n progress.setAttribute('aria-valuemax', '100');\n progress.setAttribute('aria-valuenow', item.progress.toString());\n\n const progressState = document.createElement('div');\n progressState.className = 'progress-bar ' + presentation.progressClass;\n progressState.style.width = item.progress + '%';\n progressState.textContent = item.progress + '%';\n progress.appendChild(progressState);\n\n const message = createTextElement('div', item.status === 'failed' ? 'small text-danger mt-2' : 'small text-muted mt-2', formatUploadMessage(item));\n\n card.appendChild(header);\n card.appendChild(progress);\n card.appendChild(message);\n uploadQueue.appendChild(card);\n });\n }\n\n function createUploadItem(file, index) {\n return {\n id: file.name + '::' + file.size + '::' + file.lastModified + '::' + index + '::' + Date.now(),\n fileName: file.name,\n fileSize: file.size,\n status: 'queued',\n progress: 0,\n error: null\n };\n }\n\n function updateUploadItem(itemId, updates) {\n uploadItems = uploadItems.map(item => item.id === itemId ? Object.assign({}, item, updates) : item);\n renderUploadQueue();\n }\n\n function removeUploadItems(predicate) {\n uploadItems = uploadItems.filter(item => !predicate(item));\n renderUploadQueue();\n }\n\n function uploadSingleDocument(file, itemIdToUpdate, fileIndex, totalFiles) {\n return new Promise((resolve, reject) => {\n const formData = new FormData();\n formData.append('chatInteractionId', config.itemId);\n formData.append('files', file);\n\n const xhr = new XMLHttpRequest();\n xhr.open('POST', config.uploadDocumentUrl, true);\n\n xhr.upload.addEventListener('progress', event => {\n if (!event.lengthComputable) {\n return;\n }\n\n const fileProgress = Math.round((event.loaded / event.total) * 100);\n updateUploadItem(itemIdToUpdate, {\n status: 'uploading',\n progress: fileProgress\n });\n\n const overallProgress = ((fileIndex + (event.loaded / event.total)) / totalFiles) * 100;\n showUploadProgress(overallProgress, 'Uploading ' + (fileIndex + 1) + ' of ' + totalFiles, 'progress-bar-striped progress-bar-animated');\n });\n\n xhr.addEventListener('load', () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n resolve(JSON.parse(xhr.responseText));\n } catch (error) {\n reject(new Error('Upload failed: invalid server response.'));\n }\n\n return;\n }\n\n reject(new Error((xhr.responseText || 'Upload failed.').trim()));\n });\n\n xhr.addEventListener('error', () => {\n reject(new Error('Upload failed. Please check your connection and try again.'));\n });\n\n xhr.send(formData);\n });\n }\n\n async function uploadDocuments(files) {\n if (!config.uploadDocumentUrl || !files || files.length === 0) {\n return;\n }\n\n if (isUploadingDocuments) {\n showUploadStatus('A document upload is already in progress.', 'text-warning');\n return;\n }\n\n isUploadingDocuments = true;\n\n const filesToUpload = [];\n const duplicateItems = [];\n const knownDocumentKeys = new Set(interactionDocuments.map(document => getDocumentKey(document.fileName, document.fileSize)));\n\n Array.from(files).forEach(file => {\n if (isDuplicateFile(file, knownDocumentKeys)) {\n duplicateItems.push(file);\n return;\n }\n\n knownDocumentKeys.add(getDocumentKey(file.name, file.size));\n filesToUpload.push(file);\n });\n\n if (duplicateItems.length > 0) {\n uploadItems = uploadItems.concat(duplicateItems.map((file, index) => Object.assign(createUploadItem(file, index), {\n status: 'failed',\n progress: 100,\n error: 'This document is already attached.'\n })));\n renderUploadQueue();\n }\n\n if (filesToUpload.length === 0) {\n isUploadingDocuments = false;\n showUploadStatus(duplicateItems.map(file => file.name + ': This document is already attached.').join(' | '), 'text-warning');\n showUploadProgress(null);\n return;\n }\n\n const pendingItems = filesToUpload.map(createUploadItem);\n uploadItems = uploadItems.concat(pendingItems);\n renderUploadQueue();\n showUploadProgress(0, 'Preparing upload...', 'progress-bar-striped progress-bar-animated');\n fileInput.disabled = true;\n\n try {\n let uploadedCount = 0;\n const failedUploads = duplicateItems.map(file => file.name + ': This document is already attached.');\n\n for (let i = 0; i < filesToUpload.length; i++) {\n const file = filesToUpload[i];\n const pendingItem = pendingItems[i];\n\n updateUploadItem(pendingItem.id, {\n status: 'uploading',\n progress: 0,\n error: null\n });\n\n showUploadStatus('Uploading ' + (i + 1) + ' of ' + filesToUpload.length + ' document(s)...', 'text-warning');\n\n try {\n const result = await uploadSingleDocument(file, pendingItem.id, i, filesToUpload.length);\n const uploaded = (Array.isArray(result.uploaded) ? result.uploaded : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n const failed = Array.isArray(result.failed) ? result.failed : [];\n\n if (uploaded.length > 0) {\n uploadedCount += uploaded.length;\n interactionDocuments = interactionDocuments.concat(uploaded);\n updateUploadItem(pendingItem.id, {\n status: 'uploaded',\n progress: 100,\n error: null\n });\n } else {\n const missingUploadMessage = failed.length > 0\n ? failed.map(entry => entry.fileName + ': ' + entry.error).join(' | ')\n : 'The server did not confirm that the file was uploaded.';\n if (failed.length === 0) {\n failedUploads.push(missingUploadMessage);\n }\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: 100,\n error: missingUploadMessage\n });\n }\n\n if (failed.length > 0) {\n const failedMessage = failed.map(entry => entry.fileName + ': ' + entry.error).join(' | ');\n failedUploads.push(failedMessage);\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: 100,\n error: failedMessage\n });\n }\n } catch (error) {\n const errorMessage = error && error.message\n ? error.message\n : 'Upload failed. Please try again.';\n console.error('Upload failed:', error);\n failedUploads.push(file.name + ': ' + errorMessage);\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: pendingItem.progress || 0,\n error: errorMessage\n });\n }\n }\n\n renderDocuments();\n\n if (failedUploads.length > 0) {\n removeUploadItems(item => item.status === 'uploaded');\n showUploadStatus(\n (uploadedCount > 0 ? ('Uploaded ' + uploadedCount + ' document(s). ') : '') + failedUploads.join(' | '),\n uploadedCount > 0 ? 'text-warning' : 'text-danger');\n showUploadProgress(null);\n return;\n }\n\n removeUploadItems(() => true);\n showUploadStatus('Uploaded ' + uploadedCount + ' document(s).', 'text-success');\n showUploadProgress(null);\n } catch (error) {\n console.error('Upload failed:', error);\n showUploadStatus('Upload failed. Please try again.', 'text-danger');\n showUploadProgress(null);\n } finally {\n isUploadingDocuments = false;\n fileInput.disabled = false;\n fileInput.value = '';\n }\n }\n\n async function removeDocument(documentId) {\n if (!config.removeDocumentUrl || !documentId || !window.confirm('Remove this document?')) {\n return;\n }\n\n try {\n const response = await fetch(config.removeDocumentUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n itemId: config.itemId,\n documentId: documentId\n })\n });\n\n if (!response.ok) {\n console.error('Failed to remove document:', await response.text());\n showUploadStatus('Failed to remove document.', 'text-danger');\n return;\n }\n\n if ((response.headers.get('content-type') || '').toLowerCase().indexOf('json') < 0) {\n console.error('Remove document: response was not JSON.', { status: response.status, redirected: response.redirected });\n showUploadStatus(response.redirected\n ? 'You may not be signed in, or you do not have permission for this. Please reload and try again.'\n : 'Failed to remove document.', 'text-danger');\n\n return;\n }\n\n const result = await response.json();\n const serverDocuments = (Array.isArray(result.documents) ? result.documents : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n\n interactionDocuments = serverDocuments.length > 0\n ? serverDocuments\n : interactionDocuments.filter(document => document.documentId !== documentId);\n renderDocuments();\n showUploadStatus('Document removed.', 'text-success');\n } catch (error) {\n console.error('Remove failed:', error);\n showUploadStatus('Failed to remove document.', 'text-danger');\n }\n }\n\n const onFileInputChange = event => {\n const selectedFiles = event.target.files ? Array.from(event.target.files) : [];\n uploadDocuments(selectedFiles);\n };\n\n fileInput.addEventListener('change', onFileInputChange);\n fileInput[managerStateKey] = {\n dispose: () => {\n fileInput.removeEventListener('change', onFileInputChange);\n }\n };\n\n renderDocuments();\n renderUploadQueue();\n showUploadStatus(null);\n showUploadProgress(null);\n\n return fileInput[managerStateKey];\n }\n\n function parseJsonAttribute(element, attributeName, description) {\n const rawValue = element.getAttribute(attributeName);\n if (!rawValue) {\n return null;\n }\n\n try {\n return JSON.parse(rawValue);\n } catch (error) {\n console.error('Failed to parse ' + description + ' JSON.', error);\n return null;\n }\n }\n\n function initializeFromElement(element) {\n if (!element || element.dataset.chatInteractionDocumentManagerInitialized === 'true') {\n return element ? element[managerStateKey] || null : null;\n }\n\n const config = parseJsonAttribute(element, 'data-chat-interaction-document-manager-config', 'chat interaction document manager config');\n if (!config) {\n return null;\n }\n\n const state = initialize(config);\n if (!state) {\n return null;\n }\n\n element.dataset.chatInteractionDocumentManagerInitialized = 'true';\n\n return state;\n }\n\n function scanForAutoInitialization(root) {\n if (!root || typeof root.querySelectorAll !== 'function') {\n return;\n }\n\n if (typeof root.matches === 'function' && root.matches('[data-chat-interaction-document-manager-config]')) {\n initializeFromElement(root);\n }\n\n root.querySelectorAll('[data-chat-interaction-document-manager-config]').forEach(initializeFromElement);\n }\n\n function startAutoInitialization() {\n scanForAutoInitialization(document);\n\n if (typeof MutationObserver === 'undefined') {\n return;\n }\n\n const observer = new MutationObserver(mutations => {\n mutations.forEach(mutation => {\n mutation.addedNodes.forEach(node => {\n if (node && node.nodeType === 1) {\n scanForAutoInitialization(node);\n }\n });\n });\n });\n\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n });\n }\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', startAutoInitialization, { once: true });\n } else {\n startAutoInitialization();\n }\n\n return {\n initialize: initialize,\n initializeFromElement: initializeFromElement,\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 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"]} +{"version":3,"sources":["chat-interaction.js"],"names":["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","setPrototypeOf","__proto__","displayName","_regenerator","w","m","defineProperty","_regeneratorDefine","_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","chatInteractionManager","_window$CoreAIChatMar","_window$CoreAIChatMar2","_window$CoreAIChatMar3","_window$CoreAIChatMar4","_window$CoreAIChatMar5","_window$CoreAIChatMar6","_window$CoreAIChatMar7","_window$CoreAIChatMar8","_window$CoreAIChatMar9","_window$CoreAIChatMar0","defaultConfig","generatedImageAltText","generatedImageMaxWidth","downloadImageTitle","downloadChartTitle","downloadChartButtonText","codeCopiedText","copyTitle","copiedTitle","copyResetDelayMs","assistantLabel","messageTemplate","indicatorTemplate","untitledText","clearHistoryTitle","clearHistoryMessage","clearHistoryOkText","clearHistoryCancelText","sanitizeUrl","url","trimmed","trim","escapeHtmlEntities","text","span","document","createElement","textContent","innerHTML","containsFontAwesomePlaceholders","root","nodeType","selector","matches","querySelector","refreshFontAwesomeIcons","fontAwesome","FontAwesome","dom","i2svg","node","observeFontAwesomeIcons","MutationObserver","observer","mutations","forEach","mutation","addedNodes","observe","childList","subtree","normalizeReference","reference","_ref","_normalized$index","_ref2","_normalized$text","_ref3","_normalized$title","_ref4","_normalized$link","_ref5","_normalized$reference","_normalized$isGenerat","_normalized$isImage","normalized","assign","index","Index","Text","title","Title","link","Link","referenceType","ReferenceType","isGenerated","IsGenerated","isImage","IsImage","isDownloadCitationReference","toLowerCase","normalizeReferences","references","_i","_Object$entries","entries","_normalizeReference","_Object$entries$_i","key","expandImageMarkers","CoreAIChatMarkers","getCitationLabel","unmergedCitationCount","citationIdentity","concat","splitCombinedCitations","content","collapseRepeatedCitations","html","separateAdjacentCitations","citationMarkerHtml","displayIndex","buildCitationDisplay","processedContent","messageReferences","referenceEntries","citations","citedRefs","filter","_ref6","_ref7","includes","generatedRefs","_ref8","_ref9","sort","_ref0","_ref1","_ref10","_ref11","b","_ref12","_ref13","_ref14","_ref15","citationsByIdentity","Map","placeholders","_iterator","_step","_step$value","label","identity","citation","get","referenceKey","referenceKeys","isDownload","set","placeholder","replaceAll","err","_i2","_placeholders","entry","_iterator2","_step2","_step2$value","map","_ref16","_excluded","buildCopyContent","copyContent","_iterator3","_step3","_citation$referenceKe","_iterator5","_step5","_iterator4","_step4","trimEnd","updateMessagePresentation","message","rawContent","displayContent","citationDisplay","citationReferences","htmlContent","parseMarkdownContent","renderer","marked","Renderer","data","href","code","lang","highlighted","hljs","getLanguage","highlight","language","_","highlightAuto","langDisplay","image","src","alt","maxWidth","chartCounter","_pendingCharts","__chartConfigs","createChartHtml","chartId","findChartMarker","use","extensions","level","start","idx","undefined","tokenizer","extracted","startIndex","type","raw","substring","endIndex","json","token","config","markBrokenImagesInMessage","requestAnimationFrame","wireBrokenImageHandlers","wireImageZoom","mediumZoom","images","querySelectorAll","_iterator6","_step6","setAttribute","margin","background","_iterator7","_step7","_loop","addEventListener","container","closest","dataset","brokenHandled","hidden","note","className","insertAdjacentElement","once","renderMessageMedia","charts","_iterator8","_step8","canvas","getElementById","Chart","console","warn","offsetParent","_cfg$options","_cfg$options2","_cfg$options2$aspectR","_chartInstance","destroy","cfg","JSON","parse","options","responsive","maintainAspectRatio","aspectRatio","error","styleMarkdownTables","replace","DOMPurify","sanitize","ADD_TAGS","ADD_ATTR","compactObject","source","fromEntries","_ref17","_ref18","initialize","instanceConfig","signalRHubUrl","appElementSelector","chatContainerElementSelector","inputElementSelector","sendButtonElementSelector","app","Vue","createApp","inputElement","buttonElement","chatContainer","isInteractionStarted","isPlaceholderVisible","isStreaming","isNavigatingAway","autoScroll","stream","messages","prompt","initialFieldValues","settingsDirty","saveSettingsTimeout","saveIndicatorTimeout","isRecording","mediaRecorder","preRecordingPrompt","micButton","speechToTextEnabled","chatMode","textToSpeechEnabled","ttsVoiceName","audioChunks","audioPlayQueue","isPlayingAudio","currentAudioElement","currentAudioUrl","ttsPlayingMessageIndex","ttsAudioCache","ttsInstanceId","Math","random","conversationModeEnabled","conversationButton","isConversationMode","realtimeController","realtimeButton","realtimeEnabled","notifications","notificationDismissTimers","copiedMessageIndex","copyResetTimeoutId","activeCopyButton","computed","lastAssistantIndex","role","methods","handleBeforeUnload","startConnection","_this","_callee","_t","_context","connection","signalR","HubConnectionBuilder","withUrl","withAutomaticReconnect","build","serverTimeoutInMilliseconds","keepAliveIntervalInMilliseconds","on","_data$messages","initializeInteraction","itemId","titleInput","msg","addMessage","$nextTick","historyItem","showSaveIndicator","stopRecording","isFinal","_conversationPartialTranscript","escaped","_conversationPartialMessage","hidePlaceholder","isPartial","scrollToBottom","_audioInputSent","dispatchEvent","Event","turnId","_realtimePendingTurns","pending","stopAudio","emptyIndex","splice","_conversationAssistantMessage","at","userMsg","messageId","responseId","appearance","_conversationAssistantResponseId","prev","hideTypingIndicator","j","msgIndex","newMessage","id","normalizeAssistantAppearance","base64Audio","contentType","binaryString","atob","bytes","Uint8Array","charCodeAt","receivePcm","playCollectedAudio","showPlaceholder","clearHistoryBtn","classList","add","notification","receiveNotification","updateNotification","notificationType","removeNotification","onreconnecting","onreconnected","info","reloadCurrentInteraction","onclose","addMessageInternal","_this2","fireEvent","CustomEvent","detail","_this3","_message$rawContent","remove","event","icon","cssClass","disableStreamingAnimation","getAssistantLabel","getAssistantRoleClasses","classes","getAssistantIconClasses","shouldAnimateAssistantIcon","getAssistantIcon","isIndicator","sendMessage","_this4","_callee2","trimmedPrompt","_context2","endActiveVoiceSession","flushPendingSave","streamMessage","_this5","dispose","streamingStarted","showTypingIndicator","lastResponseId","messageIndex","currentItemId","getItemId","subscribe","chunk","sessionId","setItemId","keys","_i3","_Object$entries2","_normalizeReference2","_Object$entries2$_i","complete","_this5$stream","processReferences","streamingFinished","synthesizeSpeech","_this5$stream2","getServiceDownMessage","_this6","_ref19","_message$rawContent2","stopIcon","getAttribute","replaceChildren","RETURN_DOM_FRAGMENT","startIcon","icons","debouncedSaveSettings","handleExternalTtsStop","_e$detail","sourceId","updateTtsPlaybackButtons","_this7","buttons","button","buttonIndex","Number","isPlaying","iconHtml","toggle","updateCopyButtons","_this8","isCopied","setCopyButtonState","cacheIndex","_this9","_ttsCacheIndex","invoke","toggleMessageTts","_this0","playAudioBlob","_this1","totalLength","reduce","sum","combined","offset","_iterator9","_step9","blob","Blob","_this10","URL","createObjectURL","audio","Audio","revokeObjectURL","playNextInQueue","play","_this11","nextBlob","shift","conversationModeOnAudioEnded","_this12","pause","currentTime","setVoiceSessionLive","live","nextElementSibling","audioSettings","toggleConversationMode","stopConversationMode","startConversationMode","isActive","stop","_this13","updateConversationButton","navigator","mediaDevices","getUserMedia","echoCancellation","noiseSuppression","autoGainControl","mimeType","MediaRecorder","isTypeSupported","audioBitsPerSecond","_conversationSubject","Subject","_conversationStream","AudioCtx","AudioContext","webkitAudioContext","_conversationAudioCtx","_conversationAnalyser","createAnalyser","fftSize","micSource","createMediaStreamSource","connect","pendingChunk","analyser","interruptVolumeThreshold","size","freqData","frequencyBinCount","getByteFrequencyData","k","avg","_callee3","uint8Array","base64","_context3","arrayBuffer","str","byte","String","fromCharCode","btoa","getTracks","track","documentElement","send","close","dismissible","autoDismissMs","endHtml","blur","startHtml","conversationModeSendPrompt","originalLength","removedCount","_this14","setTimeout","scrollTop","scrollHeight","clientHeight","handleUserInput","target","getSaveIndicatorElement","saveIndicatorElementSelector","_this15","indicator","clearTimeout","clearPendingSettingsSave","getFieldLabel","input","_input$closest","setting","getValidationFeedbackElement","feedback","contains","clearSettingValidationError","removeAttribute","setSettingValidationError","getSettingValidationMessage","disabled","number","fieldLabel","isNaN","min","max","validateSettingInput","validateSettings","_this16","isValid","getSettingInputs","queueSettingsSave","explicitInputs","getSelectedGroupValues","groupName","fallbackSelector","explicitSelections","values","checkbox","checkboxes","baseName","hiddenInput","getPromptTemplateSelections","promptTemplates","card","templateIdInput","promptParametersInput","templateId","promptParameters","clearNotificationDismiss","findIndex","scheduleNotificationDismiss","_this17","timerId","dismissNotification","handleNotificationAction","actionName","resetInteraction","initializeApp","_this18","placeholderElementSelector","loadInteraction","threshold","atBottom","shiftKey","click","lastMsg","pop","chatInteractionItems","getElementsByClassName","preventDefault","initialMessages","btn","block","codeEl","clipboard","writeText","copiedText","clearHistory","micButtonElementSelector","style","display","toggleRecording","conversationButtonElementSelector","CoreAIRealtime","realtimeButtonElementSelector","attach","ensureConnected","sendStart","subject","voice","silenceMs","vadThreshold","allowInterruption","webRtcEnabled","realtimeWebRtcEnabled","sendStartWebRtc","offerSdp","webRtcIceServers","realtimeWebRtcIceServers","voiceName","realtimeVoiceName","getVoiceName","el","realtimeVoiceSelectElementSelector","capableDeployments","realtimeCapableDeployments","selectors","onSessionStateChanged","active","onActivate","onDeactivate","onEnterRealtimeMode","onUserTurnPending","onUserTurnDropped","dropped","setupRealtimeVoicePicker","realtimeVoicesUrl","voiceSelect","voiceGroup","realtimeVoiceGroupElementSelector","conversationSelect","conversationDeploymentSelectElementSelector","capable","savedVoiceId","self","isRealtimeDeployment","resolveConversationDeployment","defaultRealtimeDeploymentName","loadVoices","_loadVoices","_callee4","deploymentName","realtime","response","result","grouped","_iterator0","_step0","_t2","_context4","applyMode","fetch","encodeURIComponent","credentials","headers","ok","voices","gender","has","localeCompare","optgroup","option","selected","appendChild","clearHistoryConfirmed","confirmDialog","okText","cancelText","callback","confirmed","confirm","_this19","saveSettings","getSelectedToolNames","getSelectedMcpConnectionIds","getSelectedA2AConnectionIds","getSelectedAgentNames","_this20","settings","inputs","match","checked","parseFloat","toolNames","mcpConnectionIds","a2aConnectionIds","agentNames","promptTemplateIds","template","force","clearCopiedMessageState","copyResponse","_ref21","_message$copyContent","_event$target","_event$target$closest","_this21","currentTarget","startRecording","_this22","_callee5","_context5","updateMicButton","watch","_this23","mounted","_this24","_callee6","_context6","$el","fontAwesomeObserver","beforeUnmount","removeEventListener","disconnect","mount","autoInitializeSelector","parseJsonAttribute","element","attributeName","description","rawValue","initializeFromElement","chatInteractionInitialized","__chatInteractionApp","scanForAutoInitialization","startAutoInitialization","body","readyState","chatInteractionDocumentManager","managerStateKey","normalizeDocumentInfo","documentId","DocumentId","fileName","FileName","fileSize","FileSize","formatFileSize","toFixed","getDocumentKey","isDuplicateFile","file","knownKeys","getDocumentsFromDom","chatDocumentId","chatDocumentName","chatDocumentSize","fileInput","documentsList","status","progressContainer","progressBar","uploadQueue","previousState","interactionDocuments","existingDocuments","uploadItems","isUploadingDocuments","createTextElement","tagName","renderDocuments","documentInfo","row","actions","downloadBaseUrl","downloadDocumentBaseUrl","downloadLink","downloadIcon","removeButton","removeIcon","removeDocument","details","prepend","showUploadStatus","showUploadProgress","progress","width","roundedProgress","round","getUploadStatePresentation","state","badgeClass","progressClass","formatUploadMessage","item","renderUploadQueue","presentation","header","fileDetails","badge","progressState","createUploadItem","lastModified","Date","now","updateUploadItem","updates","removeUploadItems","predicate","uploadSingleDocument","itemIdToUpdate","fileIndex","totalFiles","reject","formData","FormData","append","xhr","XMLHttpRequest","open","uploadDocumentUrl","upload","lengthComputable","fileProgress","loaded","total","overallProgress","responseText","Error","uploadDocuments","_x","_uploadDocuments","_callee7","files","filesToUpload","duplicateItems","knownDocumentKeys","pendingItems","uploadedCount","failedUploads","pendingItem","uploaded","failed","missingUploadMessage","failedMessage","errorMessage","_t3","_t4","_context7","Set","join","_x2","_removeDocument","_callee8","serverDocuments","_t5","_t6","_context8","removeDocumentUrl","method","stringify","redirected","documents","onFileInputChange","selectedFiles","chatInteractionDocumentManagerInitialized","download","toDataURL","img","startsWith","res","removeChild"],"mappings":"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","file":"chat-interaction.js","sourcesContent":["/*\n * Figure markers: the short labels the model writes, turned into pictures by the host.\n *\n * Retrieval hands the model a label -- [fig:1] -- and keeps the picture's real link in the message's reference\n * map, the same way a text citation keeps its source behind \"[doc:1]\". A model asked to reproduce a long opaque\n * identifier does not reproduce it: it copies the shape and substitutes ordinals, so links to figures that were\n * never in the results came back as 404s. A label short enough to be written exactly, with the link put back\n * here where the model cannot reach it, is what stops that.\n *\n * It sits on window rather than inside the manager below so the host can reach it, and so its rules can be\n * exercised in a bare sandbox with no browser and no DOM -- see tests/realtime-client/figure-markers.test.js --\n * exactly as window.CoreAIRealtime exposes the microphone gate's rules.\n *\n * The same block sits at the top of ai-chat.js: the two chat clients are separate bundles that share no\n * module of their own, and both render the same markdown. Change one, change the other.\n */\n// CoreAIChatMarkers lives in chat-markers.js, which every chat surface loads before this file.\n\nwindow.chatInteractionManager = 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 codeCopiedText: 'Copied!',\n copyTitle: 'Click here to copy response to clipboard.',\n copiedTitle: 'Response copied to clipboard.',\n copyResetDelayMs: 2000,\n assistantLabel: 'Assistant',\n\n messageTemplate: `\n
\n \n
\n
\n \n {{ notification.content }}\n \n
\n
\n \n
\n
\n
\n `,\n indicatorTemplate: `\n
\n \n Assistant\n
\n `,\n // Localizable strings\n untitledText: 'Untitled',\n clearHistoryTitle: 'Clear History',\n clearHistoryMessage: 'Are you sure you want to clear the chat history? This action cannot be undone. Your documents, parameters, and tools will be preserved.',\n clearHistoryOkText: 'Yes',\n clearHistoryCancelText: 'Cancel'\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 containsFontAwesomePlaceholders(root) {\n if (!root || root.nodeType !== 1) {\n return false;\n }\n\n var selector = 'i[class*=\"fa-\"],i.fa,i.fas,i.far,i.fab';\n if (typeof root.matches === 'function' && root.matches(selector)) {\n return true;\n }\n\n return typeof root.querySelector === 'function' && !!root.querySelector(selector);\n }\n\n function refreshFontAwesomeIcons(root) {\n var fontAwesome = window.FontAwesome;\n if (!containsFontAwesomePlaceholders(root) || !fontAwesome || !fontAwesome.dom || typeof fontAwesome.dom.i2svg !== 'function') {\n return;\n }\n\n fontAwesome.dom.i2svg({ node: root });\n }\n\n function observeFontAwesomeIcons(root) {\n if (!root || typeof MutationObserver === 'undefined') {\n return null;\n }\n\n var observer = new MutationObserver(function (mutations) {\n mutations.forEach(function (mutation) {\n mutation.addedNodes.forEach(function (node) {\n refreshFontAwesomeIcons(node);\n });\n });\n });\n\n observer.observe(root, {\n childList: true,\n subtree: true\n });\n\n return observer;\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 normalized.isGenerated = (normalized.isGenerated ?? normalized.IsGenerated) === true;\n normalized.isImage = (normalized.isImage ?? normalized.IsImage) === true;\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 // Installed at the top of this file so it can be unit tested without a browser; see the comment there.\n const expandImageMarkers = window.CoreAIChatMarkers.expandImageMarkers;\n\n function getCitationLabel(reference, key) {\n return reference.title || reference.text || key;\n }\n\n // Which references are one citation, and how a repeated marker reads, are statements about strings and\n // live in chat-markers.js so every chat surface numbers them the same way. Without the module each\n // reference keeps an identity of its own and nothing merges, which is the numbering this script had\n // before it.\n let unmergedCitationCount = 0;\n const citationIdentity = window.CoreAIChatMarkers?.citationIdentity\n ?? (() => `unmerged-${++unmergedCitationCount}`);\n const splitCombinedCitations = window.CoreAIChatMarkers?.splitCombinedCitations\n ?? (content => content);\n const collapseRepeatedCitations = window.CoreAIChatMarkers?.collapseRepeatedCitations\n ?? (html => html);\n const separateAdjacentCitations = window.CoreAIChatMarkers?.separateAdjacentCitations\n ?? (html => html);\n const citationMarkerHtml = window.CoreAIChatMarkers?.citationMarkerHtml\n ?? (displayIndex => `${displayIndex}`);\n\n function buildCitationDisplay(content, references) {\n // Before anything looks for a reference key, the combined form the model tends to write is split into\n // the keys it means. A key that is not found is not replaced, and an unreplaced key reaches the reader\n // as a raw marker mid-sentence.\n let processedContent = splitCombinedCitations((content || '').trim());\n const messageReferences = normalizeReferences(references);\n const referenceEntries = Object.entries(messageReferences);\n\n if (!referenceEntries.length) {\n return { content: processedContent, citations: [] };\n }\n\n const citedRefs = referenceEntries.filter(([key]) => processedContent.includes(key));\n const generatedRefs = referenceEntries.filter(([key, value]) => value.isGenerated && !processedContent.includes(key));\n\n if (!citedRefs.length && !generatedRefs.length) {\n return { content: processedContent, citations: [] };\n }\n\n citedRefs.sort(([, a], [, b]) => a.index - b.index);\n generatedRefs.sort(([, a], [, b]) => a.index - b.index);\n\n const citations = [];\n const citationsByIdentity = new Map();\n const placeholders = [];\n let displayIndex = 1;\n\n for (const [key, value] of citedRefs) {\n const label = getCitationLabel(value, key);\n const link = value.link || null;\n const identity = citationIdentity(label, link);\n let citation = citationsByIdentity.get(identity);\n\n // Every reference still has its key replaced, so the text never keeps a raw key; what the merge\n // changes is only how many numbers the reader is given for them.\n if (!citation) {\n citation = {\n referenceKey: key,\n referenceKeys: [],\n displayIndex: displayIndex++,\n label: label,\n link: link,\n isDownload: isDownloadCitationReference(value),\n };\n\n citationsByIdentity.set(identity, citation);\n citations.push(citation);\n }\n\n citation.referenceKeys.push(key);\n\n const placeholder = `__CITE_${citation.displayIndex}_${value.index || citation.displayIndex}__`;\n processedContent = processedContent.replaceAll(key, placeholder);\n placeholders.push({ placeholder, displayIndex: citation.displayIndex, label: citation.label });\n }\n\n for (const entry of placeholders) {\n processedContent = processedContent.replaceAll(entry.placeholder, citationMarkerHtml(entry.displayIndex, entry.label));\n }\n\n // Merged citations can leave the same number twice over a sentence; that is collapsed before the\n // commas go in, or the reader is given \"1,1\".\n processedContent = collapseRepeatedCitations(processedContent);\n processedContent = separateAdjacentCitations(processedContent);\n\n // Generated files (such as exported tabular data) are always offered as a download even when\n // the model does not cite them inline, so the user never loses access to the produced file.\n for (const [key, value] of generatedRefs) {\n citations.push({\n referenceKey: key,\n referenceKeys: [key],\n displayIndex: displayIndex,\n label: getCitationLabel(value, key),\n link: value.link || null,\n isDownload: true,\n placeholder: null,\n });\n\n displayIndex++;\n }\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 // Every key the citation absorbed is replaced, not just the first: a merged key left behind would\n // reach the clipboard as the raw reference token the reader never saw on the page.\n for (const citation of citations) {\n for (const key of (citation.referenceKeys?.length ? citation.referenceKeys : [citation.referenceKey])) {\n copyContent = copyContent.replaceAll(key, `[${citation.displayIndex}]`);\n }\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 // Figure markers become images before anything else reads the content: the citation pass looks for its\n // own keys in what is left, and the markdown parser then sees an ordinary image.\n const displayContent = expandImageMarkers(rawContent, messageReferences);\n const citationDisplay = buildCitationDisplay(displayContent, 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 // Copied from the expanded content, so a copied answer carries the picture's link rather than a label\n // that means nothing outside this page.\n // Split here too: the copy is built from the expanded content rather than the display path's output,\n // so a combined marker would otherwise survive into the clipboard as a raw key.\n message.copyContent = buildCopyContent(splitCombinedCitations(displayContent), 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 `${data.text}`;\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 `
${langDisplay}
${highlighted}
`;\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 // Spans, not divs. A figure marker is often written mid-sentence -- \"Figures [fig:1], [fig:2] and\n // [fig:3] show...\" -- and a block element cannot sit inside a paragraph: the browser closes the

\n // at the first one, so the sentence is torn into fragments and the commas between the markers are\n // left stranded on their own lines. Inline-block keeps the figure looking exactly the same while\n // remaining something a paragraph can legally contain.\n // The download sits over the picture's lower corner rather than on a line of its own beneath it.\n // A row of its own cost a band of vertical space under every figure, which a conversation full of\n // them pays for once per figure. The link itself is unchanged -- same address, same download\n // attribute, same behaviour -- only where it is drawn.\n return `\n \"${alt}\"\n \n \n \n `;\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 shared with ai-chat.js\n window.__chartConfigs = window.__chartConfigs || {};\n\n function createChartHtml(chartId) {\n return `

`\n + ``\n + `
`\n + `
`\n + ``\n + `
`;\n }\n\n // The marker itself is read by chat-markers.js, shared with every other chat surface, so the three of them\n // cannot disagree about what a marker is. Everything below -- the container, the id scheme, the Chart.js\n // call -- is this surface's own and legitimately differs from the others.\n const findChartMarker = window.CoreAIChatMarkers.findChartMarker;\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 = findChartMarker(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 // An image the assistant named but the server will not serve. The address is written by a language\n // model from what retrieval handed it, so a mistyped or invented one is possible, and the browser's\n // default for that is a broken-image icon captioned with the alt text -- which reads as a real picture\n // that failed to arrive. Saying plainly that it could not be loaded is both truer and quieter.\n //\n // Wired here rather than as an inline onerror attribute because message bodies go through DOMPurify,\n // which strips event-handler attributes.\n function markBrokenImagesInMessage() {\n // Scanning the document rather than one message, because the value threaded through the render\n // path is the message DATA object -- the thing carrying content, references and pending charts --\n // and not the element it was rendered into. Wiring is idempotent via the data-broken-wired mark,\n // so re-scanning after each render costs a query over the handful of images already handled.\n if (typeof document === 'undefined' || typeof requestAnimationFrame !== 'function') {\n return;\n }\n\n // Deferred for the same reason the charts below are: the render that produced these elements has\n // not necessarily been flushed to the DOM when this runs.\n requestAnimationFrame(wireBrokenImageHandlers);\n requestAnimationFrame(wireImageZoom);\n }\n\n // A picture arrives after the markdown is handed back -- the view writes it, and a streamed answer\n // rewrites it on every chunk -- so zooming cannot be attached once at load. It is attached on the same\n // pass as the broken-image handler above, and the attribute marks a picture already attached so a\n // re-render does not bind it a second time.\n function wireImageZoom() {\n // The library is the host's to load. Without it the picture is still shown and still downloadable;\n // only the enlarging is missing, so this is not worth failing a render over.\n if (typeof mediumZoom !== 'function') {\n return;\n }\n\n const images = document.querySelectorAll('.generated-image-container img:not([data-zoom-wired])');\n\n if (images.length === 0) {\n return;\n }\n\n for (const image of images) {\n image.setAttribute('data-zoom-wired', 'true');\n }\n\n mediumZoom(images, {\n // The drawing is bounded by the window rather than by this margin, so the margin is kept\n // small: an ingested figure is read detail by detail, and every pixel given away here comes\n // off the size it is read at.\n margin: 16,\n background: 'rgba(15, 15, 15, 0.92)',\n });\n }\n\n function wireBrokenImageHandlers() {\n const images = document.querySelectorAll('.generated-image-container img:not([data-broken-wired])');\n\n for (const image of images) {\n image.setAttribute('data-broken-wired', 'true');\n image.addEventListener('error', function () {\n const container = image.closest('.generated-image-container');\n\n if (!container || container.dataset.brokenHandled) {\n return;\n }\n\n container.dataset.brokenHandled = 'true';\n container.hidden = true;\n\n const note = document.createElement('p');\n note.className = 'text-muted small fst-italic mb-2';\n note.textContent = image.alt\n ? `(the picture \"${image.alt}\" could not be loaded)`\n : '(that picture could not be loaded)';\n container.insertAdjacentElement('afterend', note);\n }, { once: true });\n }\n }\n\n function renderMessageMedia(message) {\n markBrokenImagesInMessage();\n\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 const canvas = document.getElementById(c.chartId);\n if (!canvas) {\n continue;\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., ).');\n continue;\n }\n\n // When the canvas is inside a hidden container (e.g., display:none),\n // it has zero dimensions. Keep the config for later rendering.\n if (canvas.offsetParent === null) {\n window.__chartConfigs[c.chartId] = c.config;\n continue;\n }\n\n try {\n // Destroy existing chart instance if re-rendering\n if (canvas._chartInstance) {\n canvas._chartInstance.destroy();\n }\n\n const cfg = typeof c.config === 'string' ? JSON.parse(c.config) : c.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 } catch (e) {\n console.error('Error creating chart:', e);\n }\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 // A markdown table becomes a bare , which Bootstrap leaves completely unstyled: it renders\n // as cramped, borderless text that reads as plain output rather than a table. Adding the framework's\n // own classes styles it wherever Bootstrap is loaded, and the wrapper lets a wide table scroll on\n // its own instead of stretching the conversation. Markdown tables cannot nest, so the plain\n // replacement is safe. This page renders markdown through its own pipeline, so the same treatment\n // is applied here as in the shared chat script.\n function styleMarkdownTables(html) {\n return html\n .replace(/
/g, '
')\n .replace(/<\\/table>/g, '
');\n }\n\n function parseMarkdownContent(content, message) {\n _pendingCharts = [];\n const html = styleMarkdownTables(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 function compactObject(source) {\n if (!source || typeof source !== 'object') {\n return {};\n }\n\n return Object.fromEntries(\n Object.entries(source).filter(([, value]) => value !== undefined)\n );\n }\n\n const initialize = (instanceConfig) => {\n const config = Object.assign({}, defaultConfig, compactObject(instanceConfig));\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 app = Vue.createApp({\n data() {\n return {\n inputElement: null,\n buttonElement: null,\n chatContainer: null,\n placeholder: null,\n isInteractionStarted: false,\n isPlaceholderVisible: true,\n isStreaming: false,\n isNavigatingAway: false,\n autoScroll: true,\n stream: null,\n messages: [],\n prompt: '',\n initialFieldValues: new Map(),\n settingsDirty: false,\n saveSettingsTimeout: null,\n saveIndicatorTimeout: null,\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 ttsPlayingMessageIndex: -1,\n ttsAudioCache: {},\n ttsInstanceId: 'chat-interaction-' + Math.random().toString(36).slice(2),\n conversationModeEnabled: config.chatMode === 'Conversation',\n conversationButton: null,\n isConversationMode: false,\n // Realtime (speech-to-speech) controller from the shared CoreAIRealtime module.\n realtimeController: null,\n realtimeButton: null,\n // Whether a realtime deployment actually resolved. The controller is attached whenever the\n // module is loaded, so its presence says nothing about which transport carries the\n // conversation -- only this flag does.\n realtimeEnabled: config.realtimeEnabled === true,\n notifications: [],\n notificationDismissTimers: {},\n copyTitle: config.copyTitle,\n copiedTitle: config.copiedTitle,\n copiedMessageIndex: -1,\n copyResetTimeoutId: null,\n activeCopyButton: 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 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(\"LoadInteraction\", (data) => {\n this.initializeInteraction(data.itemId, true);\n this.messages = [];// Update the title field if it exists\n const titleInput = document.querySelector('[data-chat-interaction-title], .setting-input[data-setting=\"title\"], input[name=\"ChatInteraction.Title\"], input[name=\"Title\"]');\n if (titleInput && data.title) {\n titleInput.value = data.title;\n }\n\n (data.messages ?? []).forEach(msg => {\n this.addMessage(msg);\n\n this.$nextTick(() => {\n renderMessageMedia(msg);\n });\n });\n });\n\n this.connection.on(\"SettingsSaved\", (itemId, title) => {\n // Update the history list item if it exists\n // Use a more specific selector to only target history list items, not other elements like the Clear History button\n const historyItem = document.querySelector(`.chat-interaction-history-item[data-interaction-id=\"${itemId}\"]`);\n if (historyItem) {\n historyItem.textContent = title || config.untitledText;\n }\n\n const titleInput = document.querySelector('[data-chat-interaction-title], .setting-input[data-setting=\"title\"], input[name=\"ChatInteraction.Title\"], input[name=\"Title\"]');\n if (titleInput && title) {\n titleInput.value = title;\n }\n\n this.showSaveIndicator('Saved', 'text-success');\n });\n\n this.connection.on(\"ReceiveError\", (error) => {\n console.error(\"SignalR Error: \", error);\n this.showSaveIndicator('Save failed', 'text-danger');\n\n if (this.isRecording) {\n this.stopRecording();\n }\n });\n\n this.connection.on(\"ReceiveTranscript\", (itemId, text, isFinal) => {\n if (this.isConversationMode) {\n if (!isFinal && text) {\n this._conversationPartialTranscript = text;\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n var html = '

' + escaped + '

';\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\", (itemId, turnId, text) => {\n // Realtime: a placeholder for this turn was already inserted in the right position when\n // the utterance was captured (see onUserTurnPending), so just fill in its text.\n if (turnId && this._realtimePendingTurns && this._realtimePendingTurns[turnId]) {\n var pending = this._realtimePendingTurns[turnId];\n delete this._realtimePendingTurns[turnId];\n this.stopAudio();\n if (text) {\n pending.content = text;\n pending.rawContent = text;\n pending.isPartial = false;\n updateMessagePresentation(pending, pending.references);\n } else {\n var emptyIndex = this.messages.indexOf(pending);\n if (emptyIndex >= 0) { this.messages.splice(emptyIndex, 1); }\n }\n\n return;\n }\n\n if (text) {\n this.stopAudio();\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '

' + escaped + '

';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else if (this._conversationAssistantMessage) {\n // Realtime: the user's transcript lags the assistant's reply for the SAME turn (the\n // model answers the audio before speech-to-text finishes). Insert the user message\n // just before the streaming assistant message so the order stays You -> Assistant,\n // and keep that message streaming — ending it here split one reply into two bubbles.\n var at = this._conversationAssistantMessage.index;\n var userMsg = { role: 'user', content: text, rawContent: text, references: {} };\n updateMessagePresentation(userMsg, userMsg.references);\n this.messages.splice(at, 0, userMsg);\n this._conversationAssistantMessage.index = at + 1;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (itemId, messageId, token, responseId, references, appearance) => {\n // A new response id means a new turn — finalize the previous assistant message so two replies\n // never merge into one bubble (also covers barge-in, which starts a fresh response).\n if (this._conversationAssistantMessage && this._conversationAssistantResponseId && responseId && this._conversationAssistantResponseId !== responseId) {\n var prev = this.messages[this._conversationAssistantMessage.index];\n if (prev) { prev.isStreaming = false; }\n this._conversationAssistantMessage = null;\n }\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 appearance: this.normalizeAssistantAppearance(appearance),\n references: {},\n };\n this.messages.push(newMessage);\n this._conversationAssistantMessage = { index: msgIndex, content: '' };\n this._conversationAssistantResponseId = responseId;\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 renderMessageMedia(msg);\n this.scrollToBottom();\n });\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantComplete\", (itemId, 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 this._conversationAssistantResponseId = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (itemId, 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 // Realtime PCM streams straight to the low-latency player; other formats (TTS) are buffered.\n if (contentType === 'audio/pcm' && this.realtimeController) {\n this.realtimeController.receivePcm(bytes);\n } else {\n this.audioChunks.push(bytes);\n }\n }\n });\n\n this.connection.on(\"ReceiveAudioComplete\", (itemId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"HistoryCleared\", (itemId) => {\n // Clear messages and show placeholder\n this.messages = [];\n this.showPlaceholder();\n\n // Hide the clear history button since there's no history now\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.classList.add('d-none');\n }\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 this.reloadCurrentInteraction();\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(\"addingChatInteractionMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedChatInteractionMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\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 renderMessageMedia(message);\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 fireEvent(event) {\n document.dispatchEvent(event);\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 : defaultConfig.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 isIndicator(message) {\n return message.role === 'indicator';\n },\n async sendMessage() {\n let trimmedPrompt = this.prompt.trim();\n\n if (!trimmedPrompt) {\n return;\n }\n\n // A live voice session and a typed turn are two writers into one interaction, and they\n // would interleave. End the session first; the turns it already produced are persisted, so\n // the typed message simply continues the same thread.\n this.endActiveVoiceSession();\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 // Flush any pending settings save before sending a message\n // to prevent concurrent hub calls that can cause database deadlocks.\n await this.flushPendingSave();\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n // Show the clear history button since we now have prompts\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.classList.remove('d-none');\n }\n\n this.streamMessage(trimmedPrompt);\n this.inputElement.value = '';\n this.prompt = '';\n },\n streamMessage(trimmedPrompt) {\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 var messageIndex = this.messages.length;\n var currentItemId = this.getItemId();\n\n this.stream = this.connection.stream(\"SendMessage\", currentItemId, trimmedPrompt)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n if (chunk.sessionId && !currentItemId) {\n this.setItemId(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n messageIndex = this.messages.length;\n let newMessage = {\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n };\n\n this.messages.push(newMessage);\n message = newMessage;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\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 message.rawContent = content;\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderMessageMedia(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 return {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\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 renderMessageMedia(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 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 // 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 // Save any settings that were deferred during streaming.\n if (this.settingsDirty) {\n this.debouncedSaveSettings();\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 ? ''\n : '';\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 updateCopyButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-copy-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-copy-message-index'));\n var isCopied = buttonIndex === this.copiedMessageIndex;\n var iconHtml = isCopied\n ? ''\n : '';\n\n button.classList.toggle('text-success', isCopied);\n button.classList.toggle('text-secondary', !isCopied);\n button.setAttribute('title', isCopied ? this.copiedTitle : this.copyTitle);\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\n });\n },\n setCopyButtonState(button, isCopied) {\n if (!button) {\n return;\n }\n\n var iconHtml = isCopied\n ? ''\n : '';\n\n button.classList.toggle('text-success', isCopied);\n button.classList.toggle('text-secondary', !isCopied);\n button.setAttribute('title', isCopied ? this.copiedTitle : this.copyTitle);\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\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.getItemId(), 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.isPlayingAudio && 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 currently playing, queue this blob for later.\n if (this.isPlayingAudio && 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 const 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 // A live voice session takes the message box away and puts the audio settings in its place; ending\n // the session gives it back. Sending a typed message already ends the session first, so the box was\n // never a way to say something *during* one -- hiding it only makes that honest, and frees the row\n // for the gear. Both transports land here: realtime through the module's onActivate, the\n // speech-to-text cascade through startConversationMode.\n setVoiceSessionLive(live) {\n if (this.inputElement) {\n this.inputElement.hidden = live;\n }\n\n if (this.buttonElement) {\n this.buttonElement.hidden = live;\n }\n\n // With the message box gone the live button would otherwise sit at its natural width in an\n // empty row, so it takes the space the box left behind. Whichever transport is carrying the\n // conversation owns a different button, and the hidden one is unaffected by the class.\n [this.realtimeButton, this.conversationButton].forEach(function (button) {\n if (button) { button.classList.toggle('flex-grow-1', live); }\n });\n\n // The gear is built by the realtime module directly after the button it was handed, and only\n // in realtime mode, so it is absent on the cascade. It belongs to a live session rather than\n // to the surface. The module hard-codes its element id and a page can host two chat clients\n // at once -- this one and the admin widget -- so it is found next to this client's own button\n // rather than by id.\n var next = this.realtimeButton && this.realtimeButton.nextElementSibling;\n var audioSettings = next && next.id === 'realtime-audio-settings' ? next : null;\n if (audioSettings) {\n audioSettings.hidden = !live;\n }\n },\n toggleConversationMode() {\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n // Two writers into one interaction would interleave, so the voice session ends before the typed\n // turn starts rather than running alongside it.\n endActiveVoiceSession() {\n if (this.realtimeController && this.realtimeController.isActive()) {\n this.realtimeController.stop();\n\n return;\n }\n\n if (this.isConversationMode) {\n this.stopConversationMode();\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\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 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 itemId = this.getItemId();\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"StartConversation\", itemId, 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, continuation is handled\n // by the persistent stream.\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 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 getItemId() {\n return this.inputElement.getAttribute('data-interaction-id')\n || this.inputElement.getAttribute('data-item-id');\n },\n getSaveIndicatorElement() {\n if (config.saveIndicatorElementSelector) {\n return document.querySelector(config.saveIndicatorElementSelector);\n }\n\n return document.querySelector('[data-chat-interaction-save-indicator]');\n },\n showSaveIndicator(text, className) {\n const indicator = this.getSaveIndicatorElement();\n if (!indicator) {\n return;\n }\n\n indicator.textContent = text || '';\n indicator.className = 'settings-save-indicator ' + (className || 'text-muted');\n\n if (this.saveIndicatorTimeout) {\n clearTimeout(this.saveIndicatorTimeout);\n this.saveIndicatorTimeout = null;\n }\n\n if (!text) {\n return;\n }\n\n this.saveIndicatorTimeout = setTimeout(() => {\n indicator.textContent = '';\n this.saveIndicatorTimeout = null;\n }, 3000);\n },\n clearPendingSettingsSave() {\n if (this.saveSettingsTimeout) {\n clearTimeout(this.saveSettingsTimeout);\n this.saveSettingsTimeout = null;\n }\n },\n getFieldLabel(input) {\n const label = input\n .closest('.mb-3, .col-6, .col, .form-group, .form-floating')\n ?.querySelector('label');\n\n if (!label) {\n return input.dataset.setting || 'This field';\n }\n\n return (label.textContent || '')\n .replace(/\\s+/g, ' ')\n .trim()\n || input.dataset.setting\n || 'This field';\n },\n getValidationFeedbackElement(input) {\n let feedback = input.nextElementSibling;\n if (feedback && feedback.classList.contains('invalid-feedback')) {\n return feedback;\n }\n\n feedback = document.createElement('div');\n feedback.className = 'invalid-feedback';\n input.insertAdjacentElement('afterend', feedback);\n\n return feedback;\n },\n clearSettingValidationError(input) {\n input.classList.remove('is-invalid');\n input.removeAttribute('aria-invalid');\n\n const feedback = input.nextElementSibling;\n if (feedback && feedback.classList.contains('invalid-feedback')) {\n feedback.textContent = '';\n }\n },\n setSettingValidationError(input, message) {\n const feedback = this.getValidationFeedbackElement(input);\n input.classList.add('is-invalid');\n input.setAttribute('aria-invalid', 'true');\n feedback.textContent = message;\n },\n getSettingValidationMessage(input) {\n if (!input || input.disabled || input.type !== 'number') {\n return null;\n }\n\n const value = (input.value || '').trim();\n if (!value) {\n return null;\n }\n\n const number = Number(value);\n const fieldLabel = this.getFieldLabel(input);\n\n if (Number.isNaN(number)) {\n return `${fieldLabel} must be a valid number.`;\n }\n\n const min = input.getAttribute('min');\n if (min !== null && number < Number(min)) {\n return `${fieldLabel} must be ${min} or greater.`;\n }\n\n const max = input.getAttribute('max');\n if (max !== null && number > Number(max)) {\n return `${fieldLabel} must be ${max} or less.`;\n }\n\n return null;\n },\n validateSettingInput(input) {\n const message = this.getSettingValidationMessage(input);\n if (!message) {\n this.clearSettingValidationError(input);\n return true;\n }\n\n this.setSettingValidationError(input, message);\n return false;\n },\n validateSettings() {\n let isValid = true;\n\n this.getSettingInputs().forEach(input => {\n isValid = this.validateSettingInput(input) && isValid;\n });\n\n return isValid;\n },\n queueSettingsSave() {\n if (!this.validateSettings()) {\n this.clearPendingSettingsSave();\n this.settingsDirty = false;\n this.showSaveIndicator('Fix errors', 'text-danger');\n return;\n }\n\n this.settingsDirty = true;\n this.showSaveIndicator('Saving...', 'text-warning');\n this.debouncedSaveSettings();\n },\n getSettingInputs() {\n const explicitInputs = document.querySelectorAll('.setting-input[data-setting]');\n if (explicitInputs.length > 0) {\n return explicitInputs;\n }\n\n return document.querySelectorAll(\n 'input[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"]), ' +\n 'select[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"]), ' +\n 'textarea[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"])'\n );\n },\n getSelectedGroupValues(groupName, fallbackSelector) {\n const explicitSelections = document.querySelectorAll(`.capability-checkbox[data-save-group=\"${groupName}\"]:checked, .capability-checkbox[data-group=\"${groupName}\"]:checked`);\n if (explicitSelections.length > 0) {\n const values = [];\n\n explicitSelections.forEach(checkbox => {\n const value = checkbox.getAttribute('data-item-id') || checkbox.value;\n if (value) {\n values.push(value);\n }\n });\n\n return values;\n }\n\n if (!fallbackSelector) {\n return [];\n }\n\n const values = [];\n const checkboxes = document.querySelectorAll(fallbackSelector);\n\n checkboxes.forEach(checkbox => {\n const baseName = checkbox.name.replace('.IsSelected', '.ItemId');\n const hiddenInput = document.querySelector(`input[type=\"hidden\"][name=\"${baseName}\"]`);\n\n if (hiddenInput && hiddenInput.value) {\n values.push(hiddenInput.value);\n }\n });\n\n return values;\n },\n getPromptTemplateSelections() {\n const promptTemplates = [];\n\n document.querySelectorAll('.prompt-template-card').forEach(card => {\n const templateIdInput = card.querySelector('.prompt-template-id-input');\n const promptParametersInput = card.querySelector('.prompt-template-parameters-input');\n const templateId = templateIdInput ? templateIdInput.value : card.getAttribute('data-template-id');\n\n if (!templateId) {\n return;\n }\n\n promptTemplates.push({\n templateId: templateId,\n promptParameters: promptParametersInput ? (promptParametersInput.value || '').trim() : ''\n });\n });\n\n return promptTemplates;\n },\n receiveNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n // Replace existing notification with same type, or add new one.\n var idx = this.notifications.findIndex(n => n.type === notification.type);\n if (idx >= 0) {\n this.notifications.splice(idx, 1, notification);\n } else {\n this.notifications.push(notification);\n }\n this.scheduleNotificationDismiss(notification);\n this.scrollToBottom();\n },\n updateNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var idx = this.notifications.findIndex(n => n.type === notification.type);\n if (idx >= 0) {\n this.notifications.splice(idx, 1, notification);\n this.scheduleNotificationDismiss(notification);\n this.scrollToBottom();\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 itemId = this.getItemId();\n this.connection.invoke('HandleNotificationAction', itemId, notificationType, actionName)\n .catch(err => console.error('Failed to handle notification action:', err));\n },\n setItemId(itemId) {\n this.inputElement.setAttribute('data-interaction-id', itemId || '');\n this.inputElement.setAttribute('data-item-id', itemId || '');\n },\n resetInteraction() {\n this.setItemId('');\n this.isInteractionStarted = false;\n this.messages = [];\n this.showPlaceholder();\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 const itemId = this.getItemId();\n if (itemId) {\n this.loadInteraction(itemId);\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('keyup', event => {\n if (this.stream != null) {\n return;\n }\n\n if (event.key === \"Enter\" && !event.shiftKey) {\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.inputElement.addEventListener('paste', (e) => {\n // Use setTimeout to allow the paste to complete before checking the value\n setTimeout(() => {\n this.prompt = this.inputElement.value;\n if (this.inputElement.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n }, 0);\n });\n\n this.buttonElement.addEventListener('click', () => {\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 chatInteractionItems = document.getElementsByClassName('chat-interaction-history-item');\n\n for (var i = 0; i < chatInteractionItems.length; i++) {\n chatInteractionItems[i].addEventListener('click', (e) => {\n e.preventDefault();\n\n var itemId = e.target.getAttribute('data-interaction-id');\n\n if (!itemId) {\n console.error('An element with the class chat-interaction-history-item with no data-interaction-id set.');\n return;\n }\n\n this.loadInteraction(itemId);\n });\n }\n\n const initialMessages = Array.isArray(config.messages) ? config.messages : [];\n\n for (let i = 0; i < initialMessages.length; i++) {\n this.addMessage(initialMessages[i]);\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 = ' ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '';\n }, 2000);\n }\n });\n }\n\n document.addEventListener('input', event => {\n if (event.target.matches('.setting-input[data-setting]')) {\n this.validateSettingInput(event.target);\n this.queueSettingsSave();\n }\n });\n\n document.addEventListener('change', event => {\n if (event.target.matches('.setting-input[data-setting], .capability-checkbox[data-save-group], .capability-checkbox[data-group], .group-toggle, .ci-agent-global-toggle')) {\n if (event.target.matches('.setting-input[data-setting]')) {\n this.validateSettingInput(event.target);\n }\n\n this.queueSettingsSave();\n return;\n }\n\n if (event.target.closest('.prompt-template-parameters-input, .prompt-template-id-input')) {\n this.queueSettingsSave();\n }\n });\n\n document.addEventListener('click', event => {\n if (!event.target.closest('.prompt-template-add-btn, .remove-prompt-template-btn')) {\n return;\n }\n\n setTimeout(() => {\n this.queueSettingsSave();\n }, 0);\n });\n\n // Add event listener for clear history button\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.addEventListener('click', () => {\n const itemId = clearHistoryBtn.getAttribute('data-interaction-id');\n if (itemId) {\n this.clearHistory(itemId);\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 // Initialize realtime (speech-to-speech) mode via the shared CoreAIRealtime module. The\n // module owns the mic capture, playback, echo guard, push-to-talk and audio settings; the\n // callbacks below plug it into this app's connection and conversation-transcript display.\n if (window.CoreAIRealtime && config.realtimeButtonElementSelector) {\n // Kept so the voice settings popover can be found next to this client's own button.\n this.realtimeButton = document.querySelector(config.realtimeButtonElementSelector);\n this.realtimeController = window.CoreAIRealtime.attach({\n connection: this.connection,\n ensureConnected: () => Promise.resolve(this.connection),\n sendStart: (subject, voice, language, silenceMs, vadThreshold, allowInterruption) => {\n this.connection.send('StartRealtimeConversation', this.getItemId(), subject, voice, language, silenceMs, vadThreshold, allowInterruption);\n },\n // Prefer WebRTC (server-relay) when the server advertises it; the shared module falls back\n // to the WebSocket sendStart above if the peer cannot connect.\n webRtcEnabled: config.realtimeWebRtcEnabled === true,\n sendStartWebRtc: (offerSdp, voice, language, silenceMs, vadThreshold, allowInterruption) => {\n this.connection.send('StartRealtimeWebRtc', this.getItemId(), offerSdp, voice, language, silenceMs, vadThreshold, allowInterruption);\n },\n webRtcIceServers: Array.isArray(config.realtimeWebRtcIceServers) ? config.realtimeWebRtcIceServers : undefined,\n voiceName: config.realtimeVoiceName || '',\n getVoiceName: () => {\n var el = config.realtimeVoiceSelectElementSelector ? document.querySelector(config.realtimeVoiceSelectElementSelector) : null;\n return el ? el.value : '';\n },\n capableDeployments: config.realtimeCapableDeployments || [],\n realtimeEnabled: config.realtimeEnabled === true,\n // input and sendButton are deliberately not handed over. The module hides every\n // control it is given when realtime takes over, and typing has to stay available\n // during a voice conversation -- that is the whole feature.\n //\n // deploymentSelect is not handed over either: it would read the raw select value,\n // and an empty conversation deployment means \"use the site default\", which still\n // resolves. The host resolves it and calls applyMode itself (see below).\n selectors: {\n realtimeButton: config.realtimeButtonElementSelector,\n micButton: config.micButtonElementSelector,\n conversationButton: config.conversationButtonElementSelector\n },\n // The module owns whether a session is live, so the message box follows its flag\n // rather than this app's copy of it. Losing one of these events used to leave the\n // box hidden under a button that had already gone back to \"Start speaking\".\n onSessionStateChanged: (active) => {\n this.setVoiceSessionLive(active);\n },\n onActivate: () => {\n this.isConversationMode = true;\n this._conversationPartialMessage = null;\n this._conversationAssistantMessage = null;\n },\n onDeactivate: () => {\n this.isConversationMode = false;\n if (this._conversationAssistantMessage) {\n var m = this.messages[this._conversationAssistantMessage.index];\n if (m) { m.isStreaming = false; }\n this._conversationAssistantMessage = null;\n }\n },\n onEnterRealtimeMode: () => {\n if (this.isRecording) { this.stopRecording(); }\n if (this.isConversationMode && (!this.realtimeController || !this.realtimeController.isActive())) { this.stopConversationMode(); }\n },\n // The utterance has been captured but not transcribed yet. Showing a placeholder now\n // puts the prompt above the reply it produces: transcription lags the spoken answer, so\n // a bubble added only when the text arrives lands underneath its own reply.\n onUserTurnPending: (turnId) => {\n if (!turnId) { return; }\n var placeholder = { role: 'user', content: '', rawContent: '', references: {}, isPartial: true };\n updateMessagePresentation(placeholder, placeholder.references);\n this._realtimePendingTurns = this._realtimePendingTurns || {};\n this._realtimePendingTurns[turnId] = placeholder;\n this.messages.push(placeholder);\n this.scrollToBottom();\n },\n onUserTurnDropped: (turnId) => {\n if (!turnId || !this._realtimePendingTurns) { return; }\n var dropped = this._realtimePendingTurns[turnId];\n if (!dropped) { return; }\n delete this._realtimePendingTurns[turnId];\n var at = this.messages.indexOf(dropped);\n if (at >= 0) { this.messages.splice(at, 1); }\n }\n });\n\n this.setupRealtimeVoicePicker(config);\n\n // The module reveals the gear as soon as the surface enters realtime mode, but it belongs\n // to a live session. The watcher that would hide it only runs on a change, so the idle\n // state has to be stated once here.\n this.setVoiceSessionLive(false);\n }\n },\n // Populates the per-interaction realtime voice picker from the selected realtime deployment's\n // voices (via the realtime-voices endpoint), and shows it only for realtime-capable deployments.\n setupRealtimeVoicePicker(config) {\n if (!config.realtimeVoiceSelectElementSelector || !config.realtimeVoicesUrl) {\n return;\n }\n\n var voiceSelect = document.querySelector(config.realtimeVoiceSelectElementSelector);\n if (!voiceSelect) {\n return;\n }\n\n var voiceGroup = config.realtimeVoiceGroupElementSelector ? document.querySelector(config.realtimeVoiceGroupElementSelector) : null;\n var conversationSelect = config.conversationDeploymentSelectElementSelector\n ? document.querySelector(config.conversationDeploymentSelectElementSelector)\n : null;\n var capable = (config.realtimeCapableDeployments || []).map(function (n) { return (n || '').toLowerCase(); });\n var savedVoiceId = config.realtimeVoiceName || '';\n var self = this;\n\n function isRealtimeDeployment(name) {\n return name && capable.indexOf(name.toLowerCase()) !== -1;\n }\n\n // Mirrors the realtime slot's chain on the server: the interaction's own choice, then the\n // site default, then the first realtime-capable deployment. Only conversation mode reaches\n // it -- an interaction that is not in conversation mode never speaks.\n function resolveConversationDeployment() {\n if (!self.conversationModeEnabled) {\n return '';\n }\n\n var name = (conversationSelect && conversationSelect.value)\n || config.defaultRealtimeDeploymentName\n || (capable.length ? capable[0] : '');\n\n return isRealtimeDeployment(name) ? name : '';\n }\n\n async function loadVoices() {\n var deploymentName = resolveConversationDeployment();\n var realtime = !!deploymentName;\n if (voiceGroup) {\n voiceGroup.classList.toggle('d-none', !realtime);\n }\n\n // Changing the conversation deployment switches the voice toggle on or off without a\n // reload.\n if (self.realtimeController) {\n self.realtimeController.applyMode(realtime);\n }\n\n if (!realtime) {\n return;\n }\n\n voiceSelect.innerHTML = '';\n\n try {\n const response = await fetch(config.realtimeVoicesUrl + '?deploymentName=' + encodeURIComponent(deploymentName), { credentials: 'same-origin' });\n const contentType = (response.headers.get('content-type') || '').toLowerCase();\n\n // A sign-in redirect answers with HTML and response.ok, so this has to be checked\n // rather than parsed: the default voice is a fine outcome, a parser error is not.\n if (!response.ok || contentType.indexOf('json') < 0) {\n return;\n }\n\n const result = await response.json();\n if (!result || !Array.isArray(result.voices)) {\n return;\n }\n\n const grouped = new Map();\n for (const voice of result.voices) {\n const groupName = voice.gender || 'Voices';\n if (!grouped.has(groupName)) {\n grouped.set(groupName, []);\n }\n grouped.get(groupName).push(voice);\n }\n\n Array.from(grouped.keys()).sort((a, b) => a.localeCompare(b)).forEach(function (groupName) {\n const optgroup = document.createElement('optgroup');\n optgroup.label = groupName;\n grouped.get(groupName).forEach(function (voice) {\n const option = document.createElement('option');\n option.value = voice.id;\n option.textContent = voice.name;\n option.selected = voice.id === savedVoiceId;\n optgroup.appendChild(option);\n });\n voiceSelect.appendChild(optgroup);\n });\n } catch (err) {\n /* ignore voice load failures */\n }\n }\n\n if (conversationSelect) {\n conversationSelect.addEventListener('change', loadVoices);\n }\n loadVoices();\n },\n loadInteraction(itemId) {\n this.connection.invoke(\"LoadInteraction\", itemId).catch(err => console.error(err));\n },\n reloadCurrentInteraction() {\n const itemId = this.getItemId();\n if (itemId) {\n this.loadInteraction(itemId);\n }\n },\n clearHistory(itemId) {\n const self = this;\n const clearHistoryConfirmed = () => {\n // Force-stop any live realtime voice session before clearing history.\n if (self.realtimeController && self.realtimeController.isActive()) {\n self.realtimeController.stop();\n }\n\n // Cancel any active stream before clearing history.\n if (self.stream) {\n self.stream.dispose();\n self.stream = null;\n self.hideTypingIndicator();\n self.streamingFinished();\n }\n\n self.connection.invoke(\"ClearHistory\", itemId)\n .catch(err => console.error('Error clearing history:', err));\n };\n\n if (typeof confirmDialog === 'function') {\n confirmDialog({\n title: config.clearHistoryTitle,\n message: config.clearHistoryMessage,\n okText: config.clearHistoryOkText,\n cancelText: config.clearHistoryCancelText,\n callback: function (confirmed) {\n if (confirmed) {\n clearHistoryConfirmed();\n }\n }\n });\n\n return;\n }\n\n if (window.confirm(config.clearHistoryMessage || 'Clear all messages?')) {\n clearHistoryConfirmed();\n }\n },\n debouncedSaveSettings() {\n // Clear any existing timeout to reset the debounce timer\n this.clearPendingSettingsSave();\n\n // Don't save while streaming — it will be saved when streaming completes.\n if (this.stream) {\n return;\n }\n\n // Set a new timeout to save after 850ms of no changes\n this.saveSettingsTimeout = setTimeout(() => {\n if (this.settingsDirty) {\n this.saveSettings();\n this.settingsDirty = false;\n }\n this.saveSettingsTimeout = null;\n }, 850);\n },\n getSelectedToolNames() {\n return this.getSelectedGroupValues(\n 'toolNames',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Tools[\"]:checked'\n );\n },\n getSelectedMcpConnectionIds() {\n return this.getSelectedGroupValues(\n 'mcpConnectionIds',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Connections[\"]:checked'\n );\n },\n getSelectedA2AConnectionIds() {\n return this.getSelectedGroupValues('a2aConnectionIds');\n },\n getSelectedAgentNames() {\n return this.getSelectedGroupValues(\n 'agentNames',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Agents[\"]:checked'\n );\n },\n saveSettings() {\n const itemId = this.getItemId();\n if (!itemId) {\n return Promise.resolve();\n }\n\n if (!this.validateSettings()) {\n this.showSaveIndicator('Fix errors', 'text-danger');\n return Promise.resolve();\n }\n\n const settings = {};\n\n // Collect all form inputs with the \"ChatInteraction.\" prefix generically.\n // This avoids coupling the JS to specific field names — new fields added by\n // any module are automatically included.\n const inputs = this.getSettingInputs();\n\n inputs.forEach(input => {\n const key = input.dataset.setting\n || ((input.name || '').replace('ChatInteraction.', '').replace(/^[A-Z]/, match => match.toLowerCase()));\n\n if (!key) {\n return;\n }\n\n if (input.type === 'checkbox') {\n settings[key] = input.checked;\n } else if (input.type === 'number') {\n settings[key] = input.value ? parseFloat(input.value) : null;\n } else {\n settings[key] = input.value || null;\n }\n });\n\n // Add tool, MCP connection, and agent collections (special handling).\n settings.toolNames = this.getSelectedToolNames();\n settings.mcpConnectionIds = this.getSelectedMcpConnectionIds();\n settings.a2aConnectionIds = this.getSelectedA2AConnectionIds();\n settings.agentNames = this.getSelectedAgentNames();\n\n const promptTemplates = this.getPromptTemplateSelections();\n if (promptTemplates.length > 0) {\n settings.promptTemplates = promptTemplates;\n settings.promptTemplateIds = promptTemplates.map(template => template.templateId);\n }\n\n return this.connection.invoke(\"SaveSettings\", itemId, settings)\n .catch(err => {\n console.error('Error saving settings:', err);\n this.showSaveIndicator('Save failed', 'text-danger');\n });\n },\n flushPendingSave() {\n if (this.saveSettingsTimeout) {\n clearTimeout(this.saveSettingsTimeout);\n this.saveSettingsTimeout = null;\n }\n\n if (this.settingsDirty) {\n this.settingsDirty = false;\n return this.saveSettings();\n }\n\n return Promise.resolve();\n },\n initializeInteraction(itemId, force) {\n if (this.isInteractionStarted && !force) {\n return;\n }\n this.fireEvent(new CustomEvent(\"initializingChatInteraction\", { detail: { itemId: itemId } }));\n this.setItemId(itemId);\n this.isInteractionStarted = true;\n },\n clearCopiedMessageState() {\n if (this.copyResetTimeoutId) {\n window.clearTimeout(this.copyResetTimeoutId);\n this.copyResetTimeoutId = null;\n }\n\n if (this.activeCopyButton) {\n this.setCopyButtonState(this.activeCopyButton, false);\n this.activeCopyButton = null;\n }\n\n this.copiedMessageIndex = -1;\n },\n copyResponse(message, index, event) {\n const text = message && typeof message === 'object'\n ? message.copyContent ?? message.content ?? ''\n : message ?? '';\n const button = event?.currentTarget || event?.target?.closest?.('[data-copy-message-index]') || null;\n\n navigator.clipboard.writeText(text)\n .then(() => {\n this.clearCopiedMessageState();\n this.copiedMessageIndex = typeof index === 'number' ? index : -1;\n this.activeCopyButton = button;\n\n if (button) {\n this.setCopyButtonState(button, true);\n } else {\n this.$nextTick(() => this.updateCopyButtons());\n }\n\n this.copyResetTimeoutId = window.setTimeout(() => {\n this.clearCopiedMessageState();\n this.$nextTick(() => this.updateCopyButtons());\n }, Number(config.copyResetDelayMs) || 2000);\n })\n .catch(err => console.error('Failed to copy response:', err));\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 itemId = this.getItemId();\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\", itemId, 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 = '';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '';\n }\n }\n },\n watch: {\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 // The dictation microphone is hidden while a voice conversation runs: the conversation\n // already owns the microphone, and a second one would mean something different.\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n // The message box and the send button give way to the voice settings while the conversation\n // runs, and come back when it ends. Both kinds of turn still land in the same thread; what\n // they cannot do is overlap.\n //\n // Only the cascade is driven from here. Realtime follows the module's own session flag\n // (onSessionStateChanged), so the two never disagree about whether a session is live.\n if (!this.realtimeEnabled) {\n this.setVoiceSessionLive(active);\n }\n },\n copiedMessageIndex() {\n this.$nextTick(() => this.updateCopyButtons());\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n this.initializeApp();\n\n this.$nextTick(() => {\n this.updateCopyButtons();\n refreshFontAwesomeIcons(this.$el);\n this.fontAwesomeObserver = observeFontAwesomeIcons(this.$el);\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 if (this.fontAwesomeObserver) {\n this.fontAwesomeObserver.disconnect();\n this.fontAwesomeObserver = null;\n }\n\n this.clearCopiedMessageState();\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 template: config.messageTemplate\n }).mount(config.appElementSelector);\n\n return app;\n };\n\n const autoInitializeSelector = '[data-chat-interaction-config]';\n\n function parseJsonAttribute(element, attributeName, description) {\n const rawValue = element.getAttribute(attributeName);\n if (!rawValue) {\n return null;\n }\n\n try {\n return JSON.parse(rawValue);\n } catch (error) {\n console.error('Failed to parse ' + description + ' JSON.', error);\n return null;\n }\n }\n\n function initializeFromElement(element) {\n if (!element || element.dataset.chatInteractionInitialized === 'true') {\n return element ? element.__chatInteractionApp || null : null;\n }\n\n const config = parseJsonAttribute(element, 'data-chat-interaction-config', 'chat interaction config');\n if (!config) {\n return null;\n }\n\n const app = initialize(config);\n if (!app) {\n return null;\n }\n\n element.dataset.chatInteractionInitialized = 'true';\n element.__chatInteractionApp = app;\n\n return app;\n }\n\n function scanForAutoInitialization(root) {\n if (!root || typeof root.querySelectorAll !== 'function') {\n return;\n }\n\n if (typeof root.matches === 'function' && root.matches(autoInitializeSelector)) {\n initializeFromElement(root);\n }\n\n root.querySelectorAll(autoInitializeSelector).forEach(initializeFromElement);\n }\n\n function startAutoInitialization() {\n scanForAutoInitialization(document);\n\n if (typeof MutationObserver === 'undefined') {\n return;\n }\n\n const observer = new MutationObserver(mutations => {\n mutations.forEach(mutation => {\n mutation.addedNodes.forEach(node => {\n if (node && node.nodeType === 1) {\n scanForAutoInitialization(node);\n }\n });\n });\n });\n\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n });\n }\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', startAutoInitialization, { once: true });\n } else {\n startAutoInitialization();\n }\n\n return {\n initialize: initialize,\n initializeFromElement: initializeFromElement,\n };\n}();\n\nwindow.chatInteractionDocumentManager = function () {\n const managerStateKey = '__chatInteractionDocumentManagerState';\n\n function normalizeDocumentInfo(document) {\n if (!document || typeof document !== 'object') {\n return null;\n }\n\n return {\n documentId: document.documentId || document.DocumentId || '',\n fileName: document.fileName || document.FileName || '',\n fileSize: document.fileSize || document.FileSize || 0\n };\n }\n\n function formatFileSize(bytes) {\n if (!bytes || bytes < 1024) {\n return (bytes || 0) + ' B';\n }\n\n if (bytes < 1024 * 1024) {\n return (bytes / 1024).toFixed(1) + ' KB';\n }\n\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n }\n\n function getDocumentKey(fileName, fileSize) {\n return ((fileName || '').trim().toLowerCase()) + '::' + (fileSize || 0);\n }\n\n function isDuplicateFile(file, knownKeys) {\n return knownKeys.has(getDocumentKey(file.name, file.size));\n }\n\n function getDocumentsFromDom(container) {\n if (!container) {\n return [];\n }\n\n return Array.from(container.querySelectorAll('[data-chat-document-id]'))\n .map(element => normalizeDocumentInfo({\n documentId: element.dataset.chatDocumentId,\n fileName: element.dataset.chatDocumentName,\n fileSize: Number(element.dataset.chatDocumentSize || 0)\n }))\n .filter(document => document && document.documentId);\n }\n\n function initialize(config) {\n if (!config || !config.itemId) {\n return;\n }\n\n const fileInput = document.getElementById('chat-doc-upload');\n const documentsList = document.getElementById('chat-documents-list');\n const status = document.getElementById('chat-doc-upload-status');\n const progressContainer = document.getElementById('chat-doc-upload-progress');\n const progressBar = document.getElementById('chat-doc-upload-progress-bar');\n const uploadQueue = document.getElementById('chat-doc-upload-queue');\n\n if (!fileInput || !documentsList || !status || !progressContainer || !progressBar || !uploadQueue) {\n return;\n }\n\n const previousState = fileInput[managerStateKey];\n if (previousState && typeof previousState.dispose === 'function') {\n previousState.dispose();\n }\n\n let interactionDocuments = (Array.isArray(config.existingDocuments) ? config.existingDocuments : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n\n if (interactionDocuments.length === 0) {\n interactionDocuments = getDocumentsFromDom(documentsList);\n }\n\n let uploadItems = [];\n let isUploadingDocuments = false;\n\n function createTextElement(tagName, className, text) {\n const element = document.createElement(tagName);\n if (className) {\n element.className = className;\n }\n\n element.textContent = text;\n return element;\n }\n\n function renderDocuments() {\n documentsList.innerHTML = '';\n\n if (interactionDocuments.length === 0) {\n documentsList.appendChild(createTextElement('div', 'text-muted small', 'No documents uploaded yet.'));\n return;\n }\n\n interactionDocuments.forEach(documentInfo => {\n const row = window.document.createElement('div');\n row.className = 'd-flex align-items-center gap-2 border rounded px-2 py-2 bg-white chat-document-row';\n row.dataset.chatDocumentId = documentInfo.documentId;\n row.dataset.chatDocumentName = documentInfo.fileName;\n row.dataset.chatDocumentSize = documentInfo.fileSize;\n\n const actions = window.document.createElement('div');\n actions.className = 'd-flex gap-1';\n\n const downloadBaseUrl = config.downloadDocumentBaseUrl || '/ai/documents/';\n const downloadLink = createTextElement('a', 'btn btn-sm btn-outline-secondary', '');\n downloadLink.title = 'Download';\n downloadLink.href = downloadBaseUrl + encodeURIComponent(documentInfo.documentId) + '/download';\n const downloadIcon = window.document.createElement('i');\n downloadIcon.className = 'fa-solid fa-download';\n downloadLink.appendChild(downloadIcon);\n\n const removeButton = createTextElement('button', 'btn btn-sm btn-outline-danger remove-chat-document-btn', '');\n removeButton.type = 'button';\n removeButton.title = 'Remove';\n removeButton.dataset.documentId = documentInfo.documentId;\n const removeIcon = window.document.createElement('i');\n removeIcon.className = 'fa-solid fa-trash';\n removeButton.appendChild(removeIcon);\n removeButton.addEventListener('click', () => removeDocument(documentInfo.documentId));\n\n actions.appendChild(downloadLink);\n actions.appendChild(removeButton);\n\n const details = window.document.createElement('div');\n details.className = 'min-w-0';\n\n const name = createTextElement('div', 'fw-semibold small text-truncate', documentInfo.fileName || 'Document');\n const icon = window.document.createElement('i');\n icon.className = 'fa-solid fa-file-lines me-1';\n name.prepend(icon);\n\n const size = createTextElement('div', 'text-muted small', formatFileSize(documentInfo.fileSize));\n\n details.appendChild(name);\n details.appendChild(size);\n\n row.appendChild(actions);\n row.appendChild(details);\n documentsList.appendChild(row);\n });\n }\n\n function showUploadStatus(message, cssClass) {\n if (!message) {\n status.textContent = '';\n status.className = 'small mt-2 d-none';\n return;\n }\n\n status.textContent = message;\n status.className = 'small mt-2 ' + (cssClass || 'text-muted');\n }\n\n function showUploadProgress(progress, message, cssClass) {\n if (progress === null || progress === undefined) {\n progressContainer.className = 'progress mt-2 d-none';\n progressContainer.setAttribute('aria-valuenow', '0');\n progressBar.className = 'progress-bar progress-bar-striped progress-bar-animated';\n progressBar.style.width = '0%';\n progressBar.textContent = '0%';\n return;\n }\n\n const roundedProgress = Math.max(0, Math.min(100, Math.round(progress)));\n progressContainer.className = 'progress mt-2';\n progressContainer.setAttribute('aria-valuenow', roundedProgress.toString());\n progressBar.className = 'progress-bar ' + (cssClass || 'progress-bar-striped progress-bar-animated');\n progressBar.style.width = roundedProgress + '%';\n progressBar.textContent = message || (roundedProgress + '%');\n }\n\n function getUploadStatePresentation(state) {\n switch (state) {\n case 'uploaded':\n return { label: 'Uploaded', badgeClass: 'text-bg-success', progressClass: 'bg-success' };\n case 'failed':\n return { label: 'Failed', badgeClass: 'text-bg-danger', progressClass: 'bg-danger' };\n case 'uploading':\n return { label: 'Uploading', badgeClass: 'text-bg-warning', progressClass: 'bg-warning progress-bar-striped progress-bar-animated' };\n default:\n return { label: 'Queued', badgeClass: 'text-bg-secondary', progressClass: 'bg-secondary progress-bar-striped progress-bar-animated' };\n }\n }\n\n function formatUploadMessage(item) {\n if (item.status === 'failed' && item.error) {\n return item.error;\n }\n\n if (item.status === 'uploaded') {\n return 'Upload completed successfully.';\n }\n\n if (item.status === 'uploading') {\n return item.progress + '% uploaded';\n }\n\n return 'Waiting to upload...';\n }\n\n function renderUploadQueue() {\n uploadQueue.innerHTML = '';\n\n uploadItems.forEach(item => {\n const presentation = getUploadStatePresentation(item.status);\n const card = document.createElement('div');\n card.className = 'border rounded px-2 py-2 bg-white';\n\n const header = document.createElement('div');\n header.className = 'd-flex justify-content-between align-items-start gap-2';\n\n const fileDetails = document.createElement('div');\n fileDetails.className = 'flex-grow-1 min-w-0';\n fileDetails.appendChild(createTextElement('div', 'fw-semibold small', item.fileName));\n fileDetails.appendChild(createTextElement('div', 'text-muted small', formatFileSize(item.fileSize)));\n\n const badge = createTextElement('span', 'badge ' + presentation.badgeClass, presentation.label);\n\n header.appendChild(fileDetails);\n header.appendChild(badge);\n\n const progress = document.createElement('div');\n progress.className = 'progress mt-2';\n progress.setAttribute('role', 'progressbar');\n progress.setAttribute('aria-valuemin', '0');\n progress.setAttribute('aria-valuemax', '100');\n progress.setAttribute('aria-valuenow', item.progress.toString());\n\n const progressState = document.createElement('div');\n progressState.className = 'progress-bar ' + presentation.progressClass;\n progressState.style.width = item.progress + '%';\n progressState.textContent = item.progress + '%';\n progress.appendChild(progressState);\n\n const message = createTextElement('div', item.status === 'failed' ? 'small text-danger mt-2' : 'small text-muted mt-2', formatUploadMessage(item));\n\n card.appendChild(header);\n card.appendChild(progress);\n card.appendChild(message);\n uploadQueue.appendChild(card);\n });\n }\n\n function createUploadItem(file, index) {\n return {\n id: file.name + '::' + file.size + '::' + file.lastModified + '::' + index + '::' + Date.now(),\n fileName: file.name,\n fileSize: file.size,\n status: 'queued',\n progress: 0,\n error: null\n };\n }\n\n function updateUploadItem(itemId, updates) {\n uploadItems = uploadItems.map(item => item.id === itemId ? Object.assign({}, item, updates) : item);\n renderUploadQueue();\n }\n\n function removeUploadItems(predicate) {\n uploadItems = uploadItems.filter(item => !predicate(item));\n renderUploadQueue();\n }\n\n function uploadSingleDocument(file, itemIdToUpdate, fileIndex, totalFiles) {\n return new Promise((resolve, reject) => {\n const formData = new FormData();\n formData.append('chatInteractionId', config.itemId);\n formData.append('files', file);\n\n const xhr = new XMLHttpRequest();\n xhr.open('POST', config.uploadDocumentUrl, true);\n\n xhr.upload.addEventListener('progress', event => {\n if (!event.lengthComputable) {\n return;\n }\n\n const fileProgress = Math.round((event.loaded / event.total) * 100);\n updateUploadItem(itemIdToUpdate, {\n status: 'uploading',\n progress: fileProgress\n });\n\n const overallProgress = ((fileIndex + (event.loaded / event.total)) / totalFiles) * 100;\n showUploadProgress(overallProgress, 'Uploading ' + (fileIndex + 1) + ' of ' + totalFiles, 'progress-bar-striped progress-bar-animated');\n });\n\n xhr.addEventListener('load', () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n resolve(JSON.parse(xhr.responseText));\n } catch (error) {\n reject(new Error('Upload failed: invalid server response.'));\n }\n\n return;\n }\n\n reject(new Error((xhr.responseText || 'Upload failed.').trim()));\n });\n\n xhr.addEventListener('error', () => {\n reject(new Error('Upload failed. Please check your connection and try again.'));\n });\n\n xhr.send(formData);\n });\n }\n\n async function uploadDocuments(files) {\n if (!config.uploadDocumentUrl || !files || files.length === 0) {\n return;\n }\n\n if (isUploadingDocuments) {\n showUploadStatus('A document upload is already in progress.', 'text-warning');\n return;\n }\n\n isUploadingDocuments = true;\n\n const filesToUpload = [];\n const duplicateItems = [];\n const knownDocumentKeys = new Set(interactionDocuments.map(document => getDocumentKey(document.fileName, document.fileSize)));\n\n Array.from(files).forEach(file => {\n if (isDuplicateFile(file, knownDocumentKeys)) {\n duplicateItems.push(file);\n return;\n }\n\n knownDocumentKeys.add(getDocumentKey(file.name, file.size));\n filesToUpload.push(file);\n });\n\n if (duplicateItems.length > 0) {\n uploadItems = uploadItems.concat(duplicateItems.map((file, index) => Object.assign(createUploadItem(file, index), {\n status: 'failed',\n progress: 100,\n error: 'This document is already attached.'\n })));\n renderUploadQueue();\n }\n\n if (filesToUpload.length === 0) {\n isUploadingDocuments = false;\n showUploadStatus(duplicateItems.map(file => file.name + ': This document is already attached.').join(' | '), 'text-warning');\n showUploadProgress(null);\n return;\n }\n\n const pendingItems = filesToUpload.map(createUploadItem);\n uploadItems = uploadItems.concat(pendingItems);\n renderUploadQueue();\n showUploadProgress(0, 'Preparing upload...', 'progress-bar-striped progress-bar-animated');\n fileInput.disabled = true;\n\n try {\n let uploadedCount = 0;\n const failedUploads = duplicateItems.map(file => file.name + ': This document is already attached.');\n\n for (let i = 0; i < filesToUpload.length; i++) {\n const file = filesToUpload[i];\n const pendingItem = pendingItems[i];\n\n updateUploadItem(pendingItem.id, {\n status: 'uploading',\n progress: 0,\n error: null\n });\n\n showUploadStatus('Uploading ' + (i + 1) + ' of ' + filesToUpload.length + ' document(s)...', 'text-warning');\n\n try {\n const result = await uploadSingleDocument(file, pendingItem.id, i, filesToUpload.length);\n const uploaded = (Array.isArray(result.uploaded) ? result.uploaded : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n const failed = Array.isArray(result.failed) ? result.failed : [];\n\n if (uploaded.length > 0) {\n uploadedCount += uploaded.length;\n interactionDocuments = interactionDocuments.concat(uploaded);\n updateUploadItem(pendingItem.id, {\n status: 'uploaded',\n progress: 100,\n error: null\n });\n } else {\n const missingUploadMessage = failed.length > 0\n ? failed.map(entry => entry.fileName + ': ' + entry.error).join(' | ')\n : 'The server did not confirm that the file was uploaded.';\n if (failed.length === 0) {\n failedUploads.push(missingUploadMessage);\n }\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: 100,\n error: missingUploadMessage\n });\n }\n\n if (failed.length > 0) {\n const failedMessage = failed.map(entry => entry.fileName + ': ' + entry.error).join(' | ');\n failedUploads.push(failedMessage);\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: 100,\n error: failedMessage\n });\n }\n } catch (error) {\n const errorMessage = error && error.message\n ? error.message\n : 'Upload failed. Please try again.';\n console.error('Upload failed:', error);\n failedUploads.push(file.name + ': ' + errorMessage);\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: pendingItem.progress || 0,\n error: errorMessage\n });\n }\n }\n\n renderDocuments();\n\n if (failedUploads.length > 0) {\n removeUploadItems(item => item.status === 'uploaded');\n showUploadStatus(\n (uploadedCount > 0 ? ('Uploaded ' + uploadedCount + ' document(s). ') : '') + failedUploads.join(' | '),\n uploadedCount > 0 ? 'text-warning' : 'text-danger');\n showUploadProgress(null);\n return;\n }\n\n removeUploadItems(() => true);\n showUploadStatus('Uploaded ' + uploadedCount + ' document(s).', 'text-success');\n showUploadProgress(null);\n } catch (error) {\n console.error('Upload failed:', error);\n showUploadStatus('Upload failed. Please try again.', 'text-danger');\n showUploadProgress(null);\n } finally {\n isUploadingDocuments = false;\n fileInput.disabled = false;\n fileInput.value = '';\n }\n }\n\n async function removeDocument(documentId) {\n if (!config.removeDocumentUrl || !documentId || !window.confirm('Remove this document?')) {\n return;\n }\n\n try {\n const response = await fetch(config.removeDocumentUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n itemId: config.itemId,\n documentId: documentId\n })\n });\n\n if (!response.ok) {\n console.error('Failed to remove document:', await response.text());\n showUploadStatus('Failed to remove document.', 'text-danger');\n return;\n }\n\n if ((response.headers.get('content-type') || '').toLowerCase().indexOf('json') < 0) {\n console.error('Remove document: response was not JSON.', { status: response.status, redirected: response.redirected });\n showUploadStatus(response.redirected\n ? 'You may not be signed in, or you do not have permission for this. Please reload and try again.'\n : 'Failed to remove document.', 'text-danger');\n\n return;\n }\n\n const result = await response.json();\n const serverDocuments = (Array.isArray(result.documents) ? result.documents : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n\n interactionDocuments = serverDocuments.length > 0\n ? serverDocuments\n : interactionDocuments.filter(document => document.documentId !== documentId);\n renderDocuments();\n showUploadStatus('Document removed.', 'text-success');\n } catch (error) {\n console.error('Remove failed:', error);\n showUploadStatus('Failed to remove document.', 'text-danger');\n }\n }\n\n const onFileInputChange = event => {\n const selectedFiles = event.target.files ? Array.from(event.target.files) : [];\n uploadDocuments(selectedFiles);\n };\n\n fileInput.addEventListener('change', onFileInputChange);\n fileInput[managerStateKey] = {\n dispose: () => {\n fileInput.removeEventListener('change', onFileInputChange);\n }\n };\n\n renderDocuments();\n renderUploadQueue();\n showUploadStatus(null);\n showUploadProgress(null);\n\n return fileInput[managerStateKey];\n }\n\n function parseJsonAttribute(element, attributeName, description) {\n const rawValue = element.getAttribute(attributeName);\n if (!rawValue) {\n return null;\n }\n\n try {\n return JSON.parse(rawValue);\n } catch (error) {\n console.error('Failed to parse ' + description + ' JSON.', error);\n return null;\n }\n }\n\n function initializeFromElement(element) {\n if (!element || element.dataset.chatInteractionDocumentManagerInitialized === 'true') {\n return element ? element[managerStateKey] || null : null;\n }\n\n const config = parseJsonAttribute(element, 'data-chat-interaction-document-manager-config', 'chat interaction document manager config');\n if (!config) {\n return null;\n }\n\n const state = initialize(config);\n if (!state) {\n return null;\n }\n\n element.dataset.chatInteractionDocumentManagerInitialized = 'true';\n\n return state;\n }\n\n function scanForAutoInitialization(root) {\n if (!root || typeof root.querySelectorAll !== 'function') {\n return;\n }\n\n if (typeof root.matches === 'function' && root.matches('[data-chat-interaction-document-manager-config]')) {\n initializeFromElement(root);\n }\n\n root.querySelectorAll('[data-chat-interaction-document-manager-config]').forEach(initializeFromElement);\n }\n\n function startAutoInitialization() {\n scanForAutoInitialization(document);\n\n if (typeof MutationObserver === 'undefined') {\n return;\n }\n\n const observer = new MutationObserver(mutations => {\n mutations.forEach(mutation => {\n mutation.addedNodes.forEach(node => {\n if (node && node.nodeType === 1) {\n scanForAutoInitialization(node);\n }\n });\n });\n });\n\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n });\n }\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', startAutoInitialization, { once: true });\n } else {\n startAutoInitialization();\n }\n\n return {\n initialize: initialize,\n initializeFromElement: initializeFromElement,\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 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"]} diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/chat-interaction.min.js b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/chat-interaction.min.js index dec32108..e947358f 100644 --- a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/chat-interaction.min.js +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/chat-interaction.min.js @@ -1,2 +1,2 @@ -var _excluded=["placeholder"];function _regenerator(){/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */var e,t,n="function"==typeof Symbol?Symbol:{},i=n.iterator||"@@iterator",a=n.toStringTag||"@@toStringTag";function o(n,i,a,o){var c=i&&i.prototype instanceof s?i:s,l=Object.create(c.prototype);return _regeneratorDefine2(l,"_invoke",function(n,i,a){var o,s,c,l=0,u=a||[],d=!1,m={p:0,n:0,v:e,a:f,f:f.bind(e,4),d:function(t,n){return o=t,s=0,c=e,m.n=n,r}};function f(n,i){for(s=n,c=i,t=0;!d&&l&&!a&&t3?(a=h===i)&&(c=o[(s=o[4])?5:(s=3,3)],o[4]=o[5]=e):o[0]<=f&&((a=n<2&&fi||i>h)&&(o[4]=n,o[5]=i,m.n=h,s=0))}if(a||n>1)return r;throw d=!0,i}return function(a,u,h){if(l>1)throw TypeError("Generator is already running");for(d&&1===u&&f(u,h),s=u,c=h;(t=s<2?e:c)||!d;){o||(s?s<3?(s>1&&(m.n=-1),f(s,c)):m.n=c:m.v=c);try{if(l=2,o){if(s||(a="next"),t=o[a]){if(!(t=t.call(o,c)))throw TypeError("iterator result is not an object");if(!t.done)return t;c=t.value,s<2&&(s=0)}else 1===s&&(t=o.return)&&t.call(o),s<2&&(c=TypeError("The iterator does not provide a '"+a+"' method"),s=1);o=e}else if((t=(d=m.n<0)?c:n.call(i,m))!==r)break}catch(t){o=e,s=1,c=t}finally{l=1}}return{value:t,done:d}}}(n,a,o),!0),l}var r={};function s(){}function c(){}function l(){}t=Object.getPrototypeOf;var u=[][i]?t(t([][i]())):(_regeneratorDefine2(t={},i,function(){return this}),t),d=l.prototype=s.prototype=Object.create(u);function m(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,l):(e.__proto__=l,_regeneratorDefine2(e,a,"GeneratorFunction")),e.prototype=Object.create(d),e}return c.prototype=l,_regeneratorDefine2(d,"constructor",l),_regeneratorDefine2(l,"constructor",c),c.displayName="GeneratorFunction",_regeneratorDefine2(l,a,"GeneratorFunction"),_regeneratorDefine2(d),_regeneratorDefine2(d,a,"Generator"),_regeneratorDefine2(d,i,function(){return this}),_regeneratorDefine2(d,"toString",function(){return"[object Generator]"}),(_regenerator=function(){return{w:o,m:m}})()}function _regeneratorDefine2(e,t,n,i){var a=Object.defineProperty;try{a({},"",{})}catch(e){a=0}_regeneratorDefine2=function(e,t,n,i){function o(t,n){_regeneratorDefine2(e,t,function(e){return this._invoke(t,n,e)})}t?a?a(e,t,{value:n,enumerable:!i,configurable:!i,writable:!i}):e[t]=n:(o("next",0),o("throw",1),o("return",2))},_regeneratorDefine2(e,t,n,i)}function asyncGeneratorStep(e,t,n,i,a,o,r){try{var s=e[o](r),c=s.value}catch(e){return void n(e)}s.done?t(c):Promise.resolve(c).then(i,a)}function _asyncToGenerator(e){return function(){var t=this,n=arguments;return new Promise(function(i,a){var o=e.apply(t,n);function r(e){asyncGeneratorStep(o,i,a,r,s,"next",e)}function s(e){asyncGeneratorStep(o,i,a,r,s,"throw",e)}r(void 0)})}}function _toConsumableArray(e){return _arrayWithoutHoles(e)||_iterableToArray(e)||_unsupportedIterableToArray(e)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _iterableToArray(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}function _arrayWithoutHoles(e){if(Array.isArray(e))return _arrayLikeToArray(e)}function _objectWithoutProperties(e,t){if(null==e)return{};var n,i,a=_objectWithoutPropertiesLoose(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=e.length?{done:!0}:{done:!1,value:e[i++]}},e:function(e){throw e},f:a}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,r=!0,s=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return r=e.done,e},e:function(e){s=!0,o=e},f:function(){try{r||null==n.return||n.return()}finally{if(s)throw o}}}}function _slicedToArray(e,t){return _arrayWithHoles(e)||_iterableToArrayLimit(e,t)||_unsupportedIterableToArray(e,t)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(e,t){if(e){if("string"==typeof e)return _arrayLikeToArray(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_arrayLikeToArray(e,t):void 0}}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,i=Array(t);n\n \n
\n
\n \n {{ notification.content }}\n \n
\n
\n \n
\n
\n \n ',indicatorTemplate:'\n
\n \n Assistant\n
\n ',untitledText:"Untitled",clearHistoryTitle:"Clear History",clearHistoryMessage:"Are you sure you want to clear the chat history? This action cannot be undone. Your documents, parameters, and tools will be preserved.",clearHistoryOkText:"Yes",clearHistoryCancelText:"Cancel"};function d(e){if(!e)return"";var t=e.trim();return/^javascript:/i.test(t)||/^vbscript:/i.test(t)||/^data:text\/html/i.test(t)?"":e}function m(e){var t=document.createElement("span");return t.textContent=e,t.innerHTML}function f(e){var t=window.FontAwesome;(function(e){if(!e||1!==e.nodeType)return!1;var t='i[class*="fa-"],i.fa,i.fas,i.far,i.fab';return!("function"!=typeof e.matches||!e.matches(t))||"function"==typeof e.querySelector&&!!e.querySelector(t)})(e)&&t&&t.dom&&"function"==typeof t.dom.i2svg&&t.dom.i2svg({node:e})}function h(e){if(!e||"undefined"==typeof MutationObserver)return null;var t=new MutationObserver(function(e){e.forEach(function(e){e.addedNodes.forEach(function(e){f(e)})})});return t.observe(e,{childList:!0,subtree:!0}),t}function p(e){var t,n,i,a,o,r,s,c,l,u,m,f;if(!e||"object"!==_typeof(e))return null;var h=Object.assign({},e);return h.index=null!==(t=null!==(n=h.index)&&void 0!==n?n:h.Index)&&void 0!==t?t:0,h.text=null!==(i=null!==(a=h.text)&&void 0!==a?a:h.Text)&&void 0!==i?i:null,h.title=null!==(o=null!==(r=h.title)&&void 0!==r?r:h.Title)&&void 0!==o?o:null,h.link=d(null!==(s=null!==(c=h.link)&&void 0!==c?c:h.Link)&&void 0!==s?s:null),h.referenceType=null!==(l=null!==(u=h.referenceType)&&void 0!==u?u:h.ReferenceType)&&void 0!==l?l:null,h.isGenerated=!0===(null!==(m=h.isGenerated)&&void 0!==m?m:h.IsGenerated),h.isImage=!0===(null!==(f=h.isImage)&&void 0!==f?f:h.IsImage),h}function g(e){return!(!e||"object"!==_typeof(e))&&("string"==typeof e.referenceType&&"document"===e.referenceType.toLowerCase()||!("string"!=typeof e.link||!/\/ai\/documents\/.+\/download(?:$|\?)/i.test(e.link)))}function v(e){if(!e||"object"!==_typeof(e))return{};for(var t={},n=0,i=Object.entries(e);n".concat(e,"")};function x(e,t){var n=v(null!=t?t:e.references),i="string"==typeof e.rawContent?e.rawContent:"string"==typeof e.content?e.content:"",a=y(i,n),o=function(e,t){var n=A((e||"").trim()),i=v(t),a=Object.entries(i);if(!a.length)return{content:n,citations:[]};var o=a.filter(function(e){var t=_slicedToArray(e,1)[0];return n.includes(t)}),r=a.filter(function(e){var t=_slicedToArray(e,2),i=t[0];return t[1].isGenerated&&!n.includes(i)});if(!o.length&&!r.length)return{content:n,citations:[]};o.sort(function(e,t){var n=_slicedToArray(e,2)[1],i=_slicedToArray(t,2)[1];return n.index-i.index}),r.sort(function(e,t){var n=_slicedToArray(e,2)[1],i=_slicedToArray(t,2)[1];return n.index-i.index});var s,c=[],l=new Map,u=[],d=1,m=_createForOfIteratorHelper(o);try{for(m.s();!(s=m.n()).done;){var f=_slicedToArray(s.value,2),h=f[0],p=f[1],y=b(p,h),C=p.link||null,x=S(y,C),E=l.get(x);E||(E={referenceKey:h,referenceKeys:[],displayIndex:d++,label:y,link:C,isDownload:g(p)},l.set(x,E),c.push(E)),E.referenceKeys.push(h);var _="__CITE_".concat(E.displayIndex,"_").concat(p.index||E.displayIndex,"__");n=n.replaceAll(h,_),u.push({placeholder:_,displayIndex:E.displayIndex,label:E.label})}}catch(e){m.e(e)}finally{m.f()}for(var M=0,k=u;M').concat(e.text,""):e.text||""},E.code=function(e){var t=e.text||"",n=(e.lang||"").trim(),i=t;if("undefined"!=typeof hljs)if(n&&hljs.getLanguage(n))try{i=hljs.highlight(t,{language:n}).value}catch(e){}else try{i=hljs.highlightAuto(t).value}catch(e){}else i=m(t);var a=n?m(n):"code";return'
'.concat(a,'
').concat(i,"
")},E.image=function(e){var t=d(e.href);if(!t)return"";var n=e.text||u.generatedImageAltText,i=u.generatedImageMaxWidth;return'\n ').concat(n,'\n \n \n \n \n \n ')};var _=0,M=[];window.__chartConfigs=window.__chartConfigs||{};var k=window.CoreAIChatMarkers.findChartMarker;function R(){var e,t=_createForOfIteratorHelper(document.querySelectorAll(".generated-image-container img:not([data-broken-wired])"));try{var n=function(){var t=e.value;t.setAttribute("data-broken-wired","true"),t.addEventListener("error",function(){var e=t.closest(".generated-image-container");if(e&&!e.dataset.brokenHandled){e.dataset.brokenHandled="true",e.hidden=!0;var n=document.createElement("p");n.className="text-muted small fst-italic mb-2",n.textContent=t.alt?'(the picture "'.concat(t.alt,'" could not be loaded)'):"(that picture could not be loaded)",e.insertAdjacentElement("afterend",n)}},{once:!0})};for(t.s();!(e=t.n()).done;)n()}catch(e){t.e(e)}finally{t.f()}}function P(e){if("undefined"!=typeof document&&"function"==typeof requestAnimationFrame&&requestAnimationFrame(R),e&&e._pendingCharts&&e._pendingCharts.length){var t=_toConsumableArray(e._pendingCharts);e._pendingCharts=[],requestAnimationFrame(function(){var e,n=_createForOfIteratorHelper(t);try{for(n.s();!(e=n.n()).done;){var i=e.value,a=document.getElementById(i.chartId);if(a)if("undefined"!=typeof Chart)if(null!==a.offsetParent)try{var o,r,s;a._chartInstance&&a._chartInstance.destroy();var c="string"==typeof i.config?JSON.parse(i.config):i.config;null!==(o=c.options)&&void 0!==o||(c.options={}),c.options.responsive=!0,c.options.maintainAspectRatio=!0,null!==(s=(r=c.options).aspectRatio)&&void 0!==s||(r.aspectRatio=4/3),a._chartInstance=new Chart(a,c)}catch(e){console.error("Error creating chart:",e)}else window.__chartConfigs[i.chartId]=i.config;else console.warn('Chart.js is not loaded. To render interactive charts, include the Chart.js library on the page (e.g., ).');\n continue;\n }\n\n // When the canvas is inside a hidden container (e.g., display:none),\n // it has zero dimensions. Keep the config for later rendering.\n if (canvas.offsetParent === null) {\n window.__chartConfigs[c.chartId] = c.config;\n continue;\n }\n\n try {\n // Destroy existing chart instance if re-rendering\n if (canvas._chartInstance) {\n canvas._chartInstance.destroy();\n }\n\n const cfg = typeof c.config === 'string' ? JSON.parse(c.config) : c.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 } catch (e) {\n console.error('Error creating chart:', e);\n }\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 // A markdown table becomes a bare , which Bootstrap leaves completely unstyled: it renders\n // as cramped, borderless text that reads as plain output rather than a table. Adding the framework's\n // own classes styles it wherever Bootstrap is loaded, and the wrapper lets a wide table scroll on\n // its own instead of stretching the conversation. Markdown tables cannot nest, so the plain\n // replacement is safe. This page renders markdown through its own pipeline, so the same treatment\n // is applied here as in the shared chat script.\n function styleMarkdownTables(html) {\n return html\n .replace(/
/g, '
')\n .replace(/<\\/table>/g, '
');\n }\n\n function parseMarkdownContent(content, message) {\n _pendingCharts = [];\n const html = styleMarkdownTables(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 function compactObject(source) {\n if (!source || typeof source !== 'object') {\n return {};\n }\n\n return Object.fromEntries(\n Object.entries(source).filter(([, value]) => value !== undefined)\n );\n }\n\n const initialize = (instanceConfig) => {\n const config = Object.assign({}, defaultConfig, compactObject(instanceConfig));\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 app = Vue.createApp({\n data() {\n return {\n inputElement: null,\n buttonElement: null,\n chatContainer: null,\n placeholder: null,\n isInteractionStarted: false,\n isPlaceholderVisible: true,\n isStreaming: false,\n isNavigatingAway: false,\n autoScroll: true,\n stream: null,\n messages: [],\n prompt: '',\n initialFieldValues: new Map(),\n settingsDirty: false,\n saveSettingsTimeout: null,\n saveIndicatorTimeout: null,\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 ttsPlayingMessageIndex: -1,\n ttsAudioCache: {},\n ttsInstanceId: 'chat-interaction-' + Math.random().toString(36).slice(2),\n conversationModeEnabled: config.chatMode === 'Conversation',\n conversationButton: null,\n isConversationMode: false,\n // Realtime (speech-to-speech) controller from the shared CoreAIRealtime module.\n realtimeController: null,\n realtimeButton: null,\n // Whether a realtime deployment actually resolved. The controller is attached whenever the\n // module is loaded, so its presence says nothing about which transport carries the\n // conversation -- only this flag does.\n realtimeEnabled: config.realtimeEnabled === true,\n notifications: [],\n notificationDismissTimers: {},\n copyTitle: config.copyTitle,\n copiedTitle: config.copiedTitle,\n copiedMessageIndex: -1,\n copyResetTimeoutId: null,\n activeCopyButton: 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 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(\"LoadInteraction\", (data) => {\n this.initializeInteraction(data.itemId, true);\n this.messages = [];// Update the title field if it exists\n const titleInput = document.querySelector('[data-chat-interaction-title], .setting-input[data-setting=\"title\"], input[name=\"ChatInteraction.Title\"], input[name=\"Title\"]');\n if (titleInput && data.title) {\n titleInput.value = data.title;\n }\n\n (data.messages ?? []).forEach(msg => {\n this.addMessage(msg);\n\n this.$nextTick(() => {\n renderMessageMedia(msg);\n });\n });\n });\n\n this.connection.on(\"SettingsSaved\", (itemId, title) => {\n // Update the history list item if it exists\n // Use a more specific selector to only target history list items, not other elements like the Clear History button\n const historyItem = document.querySelector(`.chat-interaction-history-item[data-interaction-id=\"${itemId}\"]`);\n if (historyItem) {\n historyItem.textContent = title || config.untitledText;\n }\n\n const titleInput = document.querySelector('[data-chat-interaction-title], .setting-input[data-setting=\"title\"], input[name=\"ChatInteraction.Title\"], input[name=\"Title\"]');\n if (titleInput && title) {\n titleInput.value = title;\n }\n\n this.showSaveIndicator('Saved', 'text-success');\n });\n\n this.connection.on(\"ReceiveError\", (error) => {\n console.error(\"SignalR Error: \", error);\n this.showSaveIndicator('Save failed', 'text-danger');\n\n if (this.isRecording) {\n this.stopRecording();\n }\n });\n\n this.connection.on(\"ReceiveTranscript\", (itemId, text, isFinal) => {\n if (this.isConversationMode) {\n if (!isFinal && text) {\n this._conversationPartialTranscript = text;\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n var html = '

' + escaped + '

';\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\", (itemId, turnId, text) => {\n // Realtime: a placeholder for this turn was already inserted in the right position when\n // the utterance was captured (see onUserTurnPending), so just fill in its text.\n if (turnId && this._realtimePendingTurns && this._realtimePendingTurns[turnId]) {\n var pending = this._realtimePendingTurns[turnId];\n delete this._realtimePendingTurns[turnId];\n this.stopAudio();\n if (text) {\n pending.content = text;\n pending.rawContent = text;\n pending.isPartial = false;\n updateMessagePresentation(pending, pending.references);\n } else {\n var emptyIndex = this.messages.indexOf(pending);\n if (emptyIndex >= 0) { this.messages.splice(emptyIndex, 1); }\n }\n\n return;\n }\n\n if (text) {\n this.stopAudio();\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '

' + escaped + '

';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else if (this._conversationAssistantMessage) {\n // Realtime: the user's transcript lags the assistant's reply for the SAME turn (the\n // model answers the audio before speech-to-text finishes). Insert the user message\n // just before the streaming assistant message so the order stays You -> Assistant,\n // and keep that message streaming — ending it here split one reply into two bubbles.\n var at = this._conversationAssistantMessage.index;\n var userMsg = { role: 'user', content: text, rawContent: text, references: {} };\n updateMessagePresentation(userMsg, userMsg.references);\n this.messages.splice(at, 0, userMsg);\n this._conversationAssistantMessage.index = at + 1;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (itemId, messageId, token, responseId, references, appearance) => {\n // A new response id means a new turn — finalize the previous assistant message so two replies\n // never merge into one bubble (also covers barge-in, which starts a fresh response).\n if (this._conversationAssistantMessage && this._conversationAssistantResponseId && responseId && this._conversationAssistantResponseId !== responseId) {\n var prev = this.messages[this._conversationAssistantMessage.index];\n if (prev) { prev.isStreaming = false; }\n this._conversationAssistantMessage = null;\n }\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 appearance: this.normalizeAssistantAppearance(appearance),\n references: {},\n };\n this.messages.push(newMessage);\n this._conversationAssistantMessage = { index: msgIndex, content: '' };\n this._conversationAssistantResponseId = responseId;\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 renderMessageMedia(msg);\n this.scrollToBottom();\n });\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantComplete\", (itemId, 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 this._conversationAssistantResponseId = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (itemId, 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 // Realtime PCM streams straight to the low-latency player; other formats (TTS) are buffered.\n if (contentType === 'audio/pcm' && this.realtimeController) {\n this.realtimeController.receivePcm(bytes);\n } else {\n this.audioChunks.push(bytes);\n }\n }\n });\n\n this.connection.on(\"ReceiveAudioComplete\", (itemId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"HistoryCleared\", (itemId) => {\n // Clear messages and show placeholder\n this.messages = [];\n this.showPlaceholder();\n\n // Hide the clear history button since there's no history now\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.classList.add('d-none');\n }\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 this.reloadCurrentInteraction();\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(\"addingChatInteractionMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedChatInteractionMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\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 renderMessageMedia(message);\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 fireEvent(event) {\n document.dispatchEvent(event);\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 : defaultConfig.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 isIndicator(message) {\n return message.role === 'indicator';\n },\n async sendMessage() {\n let trimmedPrompt = this.prompt.trim();\n\n if (!trimmedPrompt) {\n return;\n }\n\n // A live voice session and a typed turn are two writers into one interaction, and they\n // would interleave. End the session first; the turns it already produced are persisted, so\n // the typed message simply continues the same thread.\n this.endActiveVoiceSession();\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 // Flush any pending settings save before sending a message\n // to prevent concurrent hub calls that can cause database deadlocks.\n await this.flushPendingSave();\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n // Show the clear history button since we now have prompts\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.classList.remove('d-none');\n }\n\n this.streamMessage(trimmedPrompt);\n this.inputElement.value = '';\n this.prompt = '';\n },\n streamMessage(trimmedPrompt) {\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 var messageIndex = this.messages.length;\n var currentItemId = this.getItemId();\n\n this.stream = this.connection.stream(\"SendMessage\", currentItemId, trimmedPrompt)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n if (chunk.sessionId && !currentItemId) {\n this.setItemId(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n messageIndex = this.messages.length;\n let newMessage = {\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n };\n\n this.messages.push(newMessage);\n message = newMessage;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\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 message.rawContent = content;\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderMessageMedia(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 return {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\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 renderMessageMedia(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 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 // 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 // Save any settings that were deferred during streaming.\n if (this.settingsDirty) {\n this.debouncedSaveSettings();\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 ? ''\n : '';\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 updateCopyButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-copy-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-copy-message-index'));\n var isCopied = buttonIndex === this.copiedMessageIndex;\n var iconHtml = isCopied\n ? ''\n : '';\n\n button.classList.toggle('text-success', isCopied);\n button.classList.toggle('text-secondary', !isCopied);\n button.setAttribute('title', isCopied ? this.copiedTitle : this.copyTitle);\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\n });\n },\n setCopyButtonState(button, isCopied) {\n if (!button) {\n return;\n }\n\n var iconHtml = isCopied\n ? ''\n : '';\n\n button.classList.toggle('text-success', isCopied);\n button.classList.toggle('text-secondary', !isCopied);\n button.setAttribute('title', isCopied ? this.copiedTitle : this.copyTitle);\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\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.getItemId(), 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.isPlayingAudio && 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 currently playing, queue this blob for later.\n if (this.isPlayingAudio && 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 const 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 // A live voice session takes the message box away and puts the audio settings in its place; ending\n // the session gives it back. Sending a typed message already ends the session first, so the box was\n // never a way to say something *during* one -- hiding it only makes that honest, and frees the row\n // for the gear. Both transports land here: realtime through the module's onActivate, the\n // speech-to-text cascade through startConversationMode.\n setVoiceSessionLive(live) {\n if (this.inputElement) {\n this.inputElement.hidden = live;\n }\n\n if (this.buttonElement) {\n this.buttonElement.hidden = live;\n }\n\n // With the message box gone the live button would otherwise sit at its natural width in an\n // empty row, so it takes the space the box left behind. Whichever transport is carrying the\n // conversation owns a different button, and the hidden one is unaffected by the class.\n [this.realtimeButton, this.conversationButton].forEach(function (button) {\n if (button) { button.classList.toggle('flex-grow-1', live); }\n });\n\n // The gear is built by the realtime module directly after the button it was handed, and only\n // in realtime mode, so it is absent on the cascade. It belongs to a live session rather than\n // to the surface. The module hard-codes its element id and a page can host two chat clients\n // at once -- this one and the admin widget -- so it is found next to this client's own button\n // rather than by id.\n var next = this.realtimeButton && this.realtimeButton.nextElementSibling;\n var audioSettings = next && next.id === 'realtime-audio-settings' ? next : null;\n if (audioSettings) {\n audioSettings.hidden = !live;\n }\n },\n toggleConversationMode() {\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n // Two writers into one interaction would interleave, so the voice session ends before the typed\n // turn starts rather than running alongside it.\n endActiveVoiceSession() {\n if (this.realtimeController && this.realtimeController.isActive()) {\n this.realtimeController.stop();\n\n return;\n }\n\n if (this.isConversationMode) {\n this.stopConversationMode();\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\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 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 itemId = this.getItemId();\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"StartConversation\", itemId, 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, continuation is handled\n // by the persistent stream.\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 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 getItemId() {\n return this.inputElement.getAttribute('data-interaction-id')\n || this.inputElement.getAttribute('data-item-id');\n },\n getSaveIndicatorElement() {\n if (config.saveIndicatorElementSelector) {\n return document.querySelector(config.saveIndicatorElementSelector);\n }\n\n return document.querySelector('[data-chat-interaction-save-indicator]');\n },\n showSaveIndicator(text, className) {\n const indicator = this.getSaveIndicatorElement();\n if (!indicator) {\n return;\n }\n\n indicator.textContent = text || '';\n indicator.className = 'settings-save-indicator ' + (className || 'text-muted');\n\n if (this.saveIndicatorTimeout) {\n clearTimeout(this.saveIndicatorTimeout);\n this.saveIndicatorTimeout = null;\n }\n\n if (!text) {\n return;\n }\n\n this.saveIndicatorTimeout = setTimeout(() => {\n indicator.textContent = '';\n this.saveIndicatorTimeout = null;\n }, 3000);\n },\n clearPendingSettingsSave() {\n if (this.saveSettingsTimeout) {\n clearTimeout(this.saveSettingsTimeout);\n this.saveSettingsTimeout = null;\n }\n },\n getFieldLabel(input) {\n const label = input\n .closest('.mb-3, .col-6, .col, .form-group, .form-floating')\n ?.querySelector('label');\n\n if (!label) {\n return input.dataset.setting || 'This field';\n }\n\n return (label.textContent || '')\n .replace(/\\s+/g, ' ')\n .trim()\n || input.dataset.setting\n || 'This field';\n },\n getValidationFeedbackElement(input) {\n let feedback = input.nextElementSibling;\n if (feedback && feedback.classList.contains('invalid-feedback')) {\n return feedback;\n }\n\n feedback = document.createElement('div');\n feedback.className = 'invalid-feedback';\n input.insertAdjacentElement('afterend', feedback);\n\n return feedback;\n },\n clearSettingValidationError(input) {\n input.classList.remove('is-invalid');\n input.removeAttribute('aria-invalid');\n\n const feedback = input.nextElementSibling;\n if (feedback && feedback.classList.contains('invalid-feedback')) {\n feedback.textContent = '';\n }\n },\n setSettingValidationError(input, message) {\n const feedback = this.getValidationFeedbackElement(input);\n input.classList.add('is-invalid');\n input.setAttribute('aria-invalid', 'true');\n feedback.textContent = message;\n },\n getSettingValidationMessage(input) {\n if (!input || input.disabled || input.type !== 'number') {\n return null;\n }\n\n const value = (input.value || '').trim();\n if (!value) {\n return null;\n }\n\n const number = Number(value);\n const fieldLabel = this.getFieldLabel(input);\n\n if (Number.isNaN(number)) {\n return `${fieldLabel} must be a valid number.`;\n }\n\n const min = input.getAttribute('min');\n if (min !== null && number < Number(min)) {\n return `${fieldLabel} must be ${min} or greater.`;\n }\n\n const max = input.getAttribute('max');\n if (max !== null && number > Number(max)) {\n return `${fieldLabel} must be ${max} or less.`;\n }\n\n return null;\n },\n validateSettingInput(input) {\n const message = this.getSettingValidationMessage(input);\n if (!message) {\n this.clearSettingValidationError(input);\n return true;\n }\n\n this.setSettingValidationError(input, message);\n return false;\n },\n validateSettings() {\n let isValid = true;\n\n this.getSettingInputs().forEach(input => {\n isValid = this.validateSettingInput(input) && isValid;\n });\n\n return isValid;\n },\n queueSettingsSave() {\n if (!this.validateSettings()) {\n this.clearPendingSettingsSave();\n this.settingsDirty = false;\n this.showSaveIndicator('Fix errors', 'text-danger');\n return;\n }\n\n this.settingsDirty = true;\n this.showSaveIndicator('Saving...', 'text-warning');\n this.debouncedSaveSettings();\n },\n getSettingInputs() {\n const explicitInputs = document.querySelectorAll('.setting-input[data-setting]');\n if (explicitInputs.length > 0) {\n return explicitInputs;\n }\n\n return document.querySelectorAll(\n 'input[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"]), ' +\n 'select[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"]), ' +\n 'textarea[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"])'\n );\n },\n getSelectedGroupValues(groupName, fallbackSelector) {\n const explicitSelections = document.querySelectorAll(`.capability-checkbox[data-save-group=\"${groupName}\"]:checked, .capability-checkbox[data-group=\"${groupName}\"]:checked`);\n if (explicitSelections.length > 0) {\n const values = [];\n\n explicitSelections.forEach(checkbox => {\n const value = checkbox.getAttribute('data-item-id') || checkbox.value;\n if (value) {\n values.push(value);\n }\n });\n\n return values;\n }\n\n if (!fallbackSelector) {\n return [];\n }\n\n const values = [];\n const checkboxes = document.querySelectorAll(fallbackSelector);\n\n checkboxes.forEach(checkbox => {\n const baseName = checkbox.name.replace('.IsSelected', '.ItemId');\n const hiddenInput = document.querySelector(`input[type=\"hidden\"][name=\"${baseName}\"]`);\n\n if (hiddenInput && hiddenInput.value) {\n values.push(hiddenInput.value);\n }\n });\n\n return values;\n },\n getPromptTemplateSelections() {\n const promptTemplates = [];\n\n document.querySelectorAll('.prompt-template-card').forEach(card => {\n const templateIdInput = card.querySelector('.prompt-template-id-input');\n const promptParametersInput = card.querySelector('.prompt-template-parameters-input');\n const templateId = templateIdInput ? templateIdInput.value : card.getAttribute('data-template-id');\n\n if (!templateId) {\n return;\n }\n\n promptTemplates.push({\n templateId: templateId,\n promptParameters: promptParametersInput ? (promptParametersInput.value || '').trim() : ''\n });\n });\n\n return promptTemplates;\n },\n receiveNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n // Replace existing notification with same type, or add new one.\n var idx = this.notifications.findIndex(n => n.type === notification.type);\n if (idx >= 0) {\n this.notifications.splice(idx, 1, notification);\n } else {\n this.notifications.push(notification);\n }\n this.scheduleNotificationDismiss(notification);\n this.scrollToBottom();\n },\n updateNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var idx = this.notifications.findIndex(n => n.type === notification.type);\n if (idx >= 0) {\n this.notifications.splice(idx, 1, notification);\n this.scheduleNotificationDismiss(notification);\n this.scrollToBottom();\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 itemId = this.getItemId();\n this.connection.invoke('HandleNotificationAction', itemId, notificationType, actionName)\n .catch(err => console.error('Failed to handle notification action:', err));\n },\n setItemId(itemId) {\n this.inputElement.setAttribute('data-interaction-id', itemId || '');\n this.inputElement.setAttribute('data-item-id', itemId || '');\n },\n resetInteraction() {\n this.setItemId('');\n this.isInteractionStarted = false;\n this.messages = [];\n this.showPlaceholder();\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 const itemId = this.getItemId();\n if (itemId) {\n this.loadInteraction(itemId);\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('keyup', event => {\n if (this.stream != null) {\n return;\n }\n\n if (event.key === \"Enter\" && !event.shiftKey) {\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.inputElement.addEventListener('paste', (e) => {\n // Use setTimeout to allow the paste to complete before checking the value\n setTimeout(() => {\n this.prompt = this.inputElement.value;\n if (this.inputElement.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n }, 0);\n });\n\n this.buttonElement.addEventListener('click', () => {\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 chatInteractionItems = document.getElementsByClassName('chat-interaction-history-item');\n\n for (var i = 0; i < chatInteractionItems.length; i++) {\n chatInteractionItems[i].addEventListener('click', (e) => {\n e.preventDefault();\n\n var itemId = e.target.getAttribute('data-interaction-id');\n\n if (!itemId) {\n console.error('An element with the class chat-interaction-history-item with no data-interaction-id set.');\n return;\n }\n\n this.loadInteraction(itemId);\n });\n }\n\n const initialMessages = Array.isArray(config.messages) ? config.messages : [];\n\n for (let i = 0; i < initialMessages.length; i++) {\n this.addMessage(initialMessages[i]);\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 = ' ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '';\n }, 2000);\n }\n });\n }\n\n document.addEventListener('input', event => {\n if (event.target.matches('.setting-input[data-setting]')) {\n this.validateSettingInput(event.target);\n this.queueSettingsSave();\n }\n });\n\n document.addEventListener('change', event => {\n if (event.target.matches('.setting-input[data-setting], .capability-checkbox[data-save-group], .capability-checkbox[data-group], .group-toggle, .ci-agent-global-toggle')) {\n if (event.target.matches('.setting-input[data-setting]')) {\n this.validateSettingInput(event.target);\n }\n\n this.queueSettingsSave();\n return;\n }\n\n if (event.target.closest('.prompt-template-parameters-input, .prompt-template-id-input')) {\n this.queueSettingsSave();\n }\n });\n\n document.addEventListener('click', event => {\n if (!event.target.closest('.prompt-template-add-btn, .remove-prompt-template-btn')) {\n return;\n }\n\n setTimeout(() => {\n this.queueSettingsSave();\n }, 0);\n });\n\n // Add event listener for clear history button\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.addEventListener('click', () => {\n const itemId = clearHistoryBtn.getAttribute('data-interaction-id');\n if (itemId) {\n this.clearHistory(itemId);\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 // Initialize realtime (speech-to-speech) mode via the shared CoreAIRealtime module. The\n // module owns the mic capture, playback, echo guard, push-to-talk and audio settings; the\n // callbacks below plug it into this app's connection and conversation-transcript display.\n if (window.CoreAIRealtime && config.realtimeButtonElementSelector) {\n // Kept so the voice settings popover can be found next to this client's own button.\n this.realtimeButton = document.querySelector(config.realtimeButtonElementSelector);\n this.realtimeController = window.CoreAIRealtime.attach({\n connection: this.connection,\n ensureConnected: () => Promise.resolve(this.connection),\n sendStart: (subject, voice, language, silenceMs, vadThreshold, allowInterruption) => {\n this.connection.send('StartRealtimeConversation', this.getItemId(), subject, voice, language, silenceMs, vadThreshold, allowInterruption);\n },\n // Prefer WebRTC (server-relay) when the server advertises it; the shared module falls back\n // to the WebSocket sendStart above if the peer cannot connect.\n webRtcEnabled: config.realtimeWebRtcEnabled === true,\n sendStartWebRtc: (offerSdp, voice, language, silenceMs, vadThreshold, allowInterruption) => {\n this.connection.send('StartRealtimeWebRtc', this.getItemId(), offerSdp, voice, language, silenceMs, vadThreshold, allowInterruption);\n },\n webRtcIceServers: Array.isArray(config.realtimeWebRtcIceServers) ? config.realtimeWebRtcIceServers : undefined,\n voiceName: config.realtimeVoiceName || '',\n getVoiceName: () => {\n var el = config.realtimeVoiceSelectElementSelector ? document.querySelector(config.realtimeVoiceSelectElementSelector) : null;\n return el ? el.value : '';\n },\n capableDeployments: config.realtimeCapableDeployments || [],\n realtimeEnabled: config.realtimeEnabled === true,\n // input and sendButton are deliberately not handed over. The module hides every\n // control it is given when realtime takes over, and typing has to stay available\n // during a voice conversation -- that is the whole feature.\n //\n // deploymentSelect is not handed over either: it would read the raw select value,\n // and an empty conversation deployment means \"use the site default\", which still\n // resolves. The host resolves it and calls applyMode itself (see below).\n selectors: {\n realtimeButton: config.realtimeButtonElementSelector,\n micButton: config.micButtonElementSelector,\n conversationButton: config.conversationButtonElementSelector\n },\n // The module owns whether a session is live, so the message box follows its flag\n // rather than this app's copy of it. Losing one of these events used to leave the\n // box hidden under a button that had already gone back to \"Start speaking\".\n onSessionStateChanged: (active) => {\n this.setVoiceSessionLive(active);\n },\n onActivate: () => {\n this.isConversationMode = true;\n this._conversationPartialMessage = null;\n this._conversationAssistantMessage = null;\n },\n onDeactivate: () => {\n this.isConversationMode = false;\n if (this._conversationAssistantMessage) {\n var m = this.messages[this._conversationAssistantMessage.index];\n if (m) { m.isStreaming = false; }\n this._conversationAssistantMessage = null;\n }\n },\n onEnterRealtimeMode: () => {\n if (this.isRecording) { this.stopRecording(); }\n if (this.isConversationMode && (!this.realtimeController || !this.realtimeController.isActive())) { this.stopConversationMode(); }\n },\n // The utterance has been captured but not transcribed yet. Showing a placeholder now\n // puts the prompt above the reply it produces: transcription lags the spoken answer, so\n // a bubble added only when the text arrives lands underneath its own reply.\n onUserTurnPending: (turnId) => {\n if (!turnId) { return; }\n var placeholder = { role: 'user', content: '', rawContent: '', references: {}, isPartial: true };\n updateMessagePresentation(placeholder, placeholder.references);\n this._realtimePendingTurns = this._realtimePendingTurns || {};\n this._realtimePendingTurns[turnId] = placeholder;\n this.messages.push(placeholder);\n this.scrollToBottom();\n },\n onUserTurnDropped: (turnId) => {\n if (!turnId || !this._realtimePendingTurns) { return; }\n var dropped = this._realtimePendingTurns[turnId];\n if (!dropped) { return; }\n delete this._realtimePendingTurns[turnId];\n var at = this.messages.indexOf(dropped);\n if (at >= 0) { this.messages.splice(at, 1); }\n }\n });\n\n this.setupRealtimeVoicePicker(config);\n\n // The module reveals the gear as soon as the surface enters realtime mode, but it belongs\n // to a live session. The watcher that would hide it only runs on a change, so the idle\n // state has to be stated once here.\n this.setVoiceSessionLive(false);\n }\n },\n // Populates the per-interaction realtime voice picker from the selected realtime deployment's\n // voices (via the realtime-voices endpoint), and shows it only for realtime-capable deployments.\n setupRealtimeVoicePicker(config) {\n if (!config.realtimeVoiceSelectElementSelector || !config.realtimeVoicesUrl) {\n return;\n }\n\n var voiceSelect = document.querySelector(config.realtimeVoiceSelectElementSelector);\n if (!voiceSelect) {\n return;\n }\n\n var voiceGroup = config.realtimeVoiceGroupElementSelector ? document.querySelector(config.realtimeVoiceGroupElementSelector) : null;\n var conversationSelect = config.conversationDeploymentSelectElementSelector\n ? document.querySelector(config.conversationDeploymentSelectElementSelector)\n : null;\n var capable = (config.realtimeCapableDeployments || []).map(function (n) { return (n || '').toLowerCase(); });\n var savedVoiceId = config.realtimeVoiceName || '';\n var self = this;\n\n function isRealtimeDeployment(name) {\n return name && capable.indexOf(name.toLowerCase()) !== -1;\n }\n\n // Mirrors the realtime slot's chain on the server: the interaction's own choice, then the\n // site default, then the first realtime-capable deployment. Only conversation mode reaches\n // it -- an interaction that is not in conversation mode never speaks.\n function resolveConversationDeployment() {\n if (!self.conversationModeEnabled) {\n return '';\n }\n\n var name = (conversationSelect && conversationSelect.value)\n || config.defaultRealtimeDeploymentName\n || (capable.length ? capable[0] : '');\n\n return isRealtimeDeployment(name) ? name : '';\n }\n\n async function loadVoices() {\n var deploymentName = resolveConversationDeployment();\n var realtime = !!deploymentName;\n if (voiceGroup) {\n voiceGroup.classList.toggle('d-none', !realtime);\n }\n\n // Changing the conversation deployment switches the voice toggle on or off without a\n // reload.\n if (self.realtimeController) {\n self.realtimeController.applyMode(realtime);\n }\n\n if (!realtime) {\n return;\n }\n\n voiceSelect.innerHTML = '';\n\n try {\n const response = await fetch(config.realtimeVoicesUrl + '?deploymentName=' + encodeURIComponent(deploymentName), { credentials: 'same-origin' });\n const contentType = (response.headers.get('content-type') || '').toLowerCase();\n\n // A sign-in redirect answers with HTML and response.ok, so this has to be checked\n // rather than parsed: the default voice is a fine outcome, a parser error is not.\n if (!response.ok || contentType.indexOf('json') < 0) {\n return;\n }\n\n const result = await response.json();\n if (!result || !Array.isArray(result.voices)) {\n return;\n }\n\n const grouped = new Map();\n for (const voice of result.voices) {\n const groupName = voice.gender || 'Voices';\n if (!grouped.has(groupName)) {\n grouped.set(groupName, []);\n }\n grouped.get(groupName).push(voice);\n }\n\n Array.from(grouped.keys()).sort((a, b) => a.localeCompare(b)).forEach(function (groupName) {\n const optgroup = document.createElement('optgroup');\n optgroup.label = groupName;\n grouped.get(groupName).forEach(function (voice) {\n const option = document.createElement('option');\n option.value = voice.id;\n option.textContent = voice.name;\n option.selected = voice.id === savedVoiceId;\n optgroup.appendChild(option);\n });\n voiceSelect.appendChild(optgroup);\n });\n } catch (err) {\n /* ignore voice load failures */\n }\n }\n\n if (conversationSelect) {\n conversationSelect.addEventListener('change', loadVoices);\n }\n loadVoices();\n },\n loadInteraction(itemId) {\n this.connection.invoke(\"LoadInteraction\", itemId).catch(err => console.error(err));\n },\n reloadCurrentInteraction() {\n const itemId = this.getItemId();\n if (itemId) {\n this.loadInteraction(itemId);\n }\n },\n clearHistory(itemId) {\n const self = this;\n const clearHistoryConfirmed = () => {\n // Force-stop any live realtime voice session before clearing history.\n if (self.realtimeController && self.realtimeController.isActive()) {\n self.realtimeController.stop();\n }\n\n // Cancel any active stream before clearing history.\n if (self.stream) {\n self.stream.dispose();\n self.stream = null;\n self.hideTypingIndicator();\n self.streamingFinished();\n }\n\n self.connection.invoke(\"ClearHistory\", itemId)\n .catch(err => console.error('Error clearing history:', err));\n };\n\n if (typeof confirmDialog === 'function') {\n confirmDialog({\n title: config.clearHistoryTitle,\n message: config.clearHistoryMessage,\n okText: config.clearHistoryOkText,\n cancelText: config.clearHistoryCancelText,\n callback: function (confirmed) {\n if (confirmed) {\n clearHistoryConfirmed();\n }\n }\n });\n\n return;\n }\n\n if (window.confirm(config.clearHistoryMessage || 'Clear all messages?')) {\n clearHistoryConfirmed();\n }\n },\n debouncedSaveSettings() {\n // Clear any existing timeout to reset the debounce timer\n this.clearPendingSettingsSave();\n\n // Don't save while streaming — it will be saved when streaming completes.\n if (this.stream) {\n return;\n }\n\n // Set a new timeout to save after 850ms of no changes\n this.saveSettingsTimeout = setTimeout(() => {\n if (this.settingsDirty) {\n this.saveSettings();\n this.settingsDirty = false;\n }\n this.saveSettingsTimeout = null;\n }, 850);\n },\n getSelectedToolNames() {\n return this.getSelectedGroupValues(\n 'toolNames',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Tools[\"]:checked'\n );\n },\n getSelectedMcpConnectionIds() {\n return this.getSelectedGroupValues(\n 'mcpConnectionIds',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Connections[\"]:checked'\n );\n },\n getSelectedA2AConnectionIds() {\n return this.getSelectedGroupValues('a2aConnectionIds');\n },\n getSelectedAgentNames() {\n return this.getSelectedGroupValues(\n 'agentNames',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Agents[\"]:checked'\n );\n },\n saveSettings() {\n const itemId = this.getItemId();\n if (!itemId) {\n return Promise.resolve();\n }\n\n if (!this.validateSettings()) {\n this.showSaveIndicator('Fix errors', 'text-danger');\n return Promise.resolve();\n }\n\n const settings = {};\n\n // Collect all form inputs with the \"ChatInteraction.\" prefix generically.\n // This avoids coupling the JS to specific field names — new fields added by\n // any module are automatically included.\n const inputs = this.getSettingInputs();\n\n inputs.forEach(input => {\n const key = input.dataset.setting\n || ((input.name || '').replace('ChatInteraction.', '').replace(/^[A-Z]/, match => match.toLowerCase()));\n\n if (!key) {\n return;\n }\n\n if (input.type === 'checkbox') {\n settings[key] = input.checked;\n } else if (input.type === 'number') {\n settings[key] = input.value ? parseFloat(input.value) : null;\n } else {\n settings[key] = input.value || null;\n }\n });\n\n // Add tool, MCP connection, and agent collections (special handling).\n settings.toolNames = this.getSelectedToolNames();\n settings.mcpConnectionIds = this.getSelectedMcpConnectionIds();\n settings.a2aConnectionIds = this.getSelectedA2AConnectionIds();\n settings.agentNames = this.getSelectedAgentNames();\n\n const promptTemplates = this.getPromptTemplateSelections();\n if (promptTemplates.length > 0) {\n settings.promptTemplates = promptTemplates;\n settings.promptTemplateIds = promptTemplates.map(template => template.templateId);\n }\n\n return this.connection.invoke(\"SaveSettings\", itemId, settings)\n .catch(err => {\n console.error('Error saving settings:', err);\n this.showSaveIndicator('Save failed', 'text-danger');\n });\n },\n flushPendingSave() {\n if (this.saveSettingsTimeout) {\n clearTimeout(this.saveSettingsTimeout);\n this.saveSettingsTimeout = null;\n }\n\n if (this.settingsDirty) {\n this.settingsDirty = false;\n return this.saveSettings();\n }\n\n return Promise.resolve();\n },\n initializeInteraction(itemId, force) {\n if (this.isInteractionStarted && !force) {\n return;\n }\n this.fireEvent(new CustomEvent(\"initializingChatInteraction\", { detail: { itemId: itemId } }));\n this.setItemId(itemId);\n this.isInteractionStarted = true;\n },\n clearCopiedMessageState() {\n if (this.copyResetTimeoutId) {\n window.clearTimeout(this.copyResetTimeoutId);\n this.copyResetTimeoutId = null;\n }\n\n if (this.activeCopyButton) {\n this.setCopyButtonState(this.activeCopyButton, false);\n this.activeCopyButton = null;\n }\n\n this.copiedMessageIndex = -1;\n },\n copyResponse(message, index, event) {\n const text = message && typeof message === 'object'\n ? message.copyContent ?? message.content ?? ''\n : message ?? '';\n const button = event?.currentTarget || event?.target?.closest?.('[data-copy-message-index]') || null;\n\n navigator.clipboard.writeText(text)\n .then(() => {\n this.clearCopiedMessageState();\n this.copiedMessageIndex = typeof index === 'number' ? index : -1;\n this.activeCopyButton = button;\n\n if (button) {\n this.setCopyButtonState(button, true);\n } else {\n this.$nextTick(() => this.updateCopyButtons());\n }\n\n this.copyResetTimeoutId = window.setTimeout(() => {\n this.clearCopiedMessageState();\n this.$nextTick(() => this.updateCopyButtons());\n }, Number(config.copyResetDelayMs) || 2000);\n })\n .catch(err => console.error('Failed to copy response:', err));\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 itemId = this.getItemId();\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\", itemId, 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 = '';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '';\n }\n }\n },\n watch: {\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 // The dictation microphone is hidden while a voice conversation runs: the conversation\n // already owns the microphone, and a second one would mean something different.\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n // The message box and the send button give way to the voice settings while the conversation\n // runs, and come back when it ends. Both kinds of turn still land in the same thread; what\n // they cannot do is overlap.\n //\n // Only the cascade is driven from here. Realtime follows the module's own session flag\n // (onSessionStateChanged), so the two never disagree about whether a session is live.\n if (!this.realtimeEnabled) {\n this.setVoiceSessionLive(active);\n }\n },\n copiedMessageIndex() {\n this.$nextTick(() => this.updateCopyButtons());\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n this.initializeApp();\n\n this.$nextTick(() => {\n this.updateCopyButtons();\n refreshFontAwesomeIcons(this.$el);\n this.fontAwesomeObserver = observeFontAwesomeIcons(this.$el);\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 if (this.fontAwesomeObserver) {\n this.fontAwesomeObserver.disconnect();\n this.fontAwesomeObserver = null;\n }\n\n this.clearCopiedMessageState();\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 template: config.messageTemplate\n }).mount(config.appElementSelector);\n\n return app;\n };\n\n const autoInitializeSelector = '[data-chat-interaction-config]';\n\n function parseJsonAttribute(element, attributeName, description) {\n const rawValue = element.getAttribute(attributeName);\n if (!rawValue) {\n return null;\n }\n\n try {\n return JSON.parse(rawValue);\n } catch (error) {\n console.error('Failed to parse ' + description + ' JSON.', error);\n return null;\n }\n }\n\n function initializeFromElement(element) {\n if (!element || element.dataset.chatInteractionInitialized === 'true') {\n return element ? element.__chatInteractionApp || null : null;\n }\n\n const config = parseJsonAttribute(element, 'data-chat-interaction-config', 'chat interaction config');\n if (!config) {\n return null;\n }\n\n const app = initialize(config);\n if (!app) {\n return null;\n }\n\n element.dataset.chatInteractionInitialized = 'true';\n element.__chatInteractionApp = app;\n\n return app;\n }\n\n function scanForAutoInitialization(root) {\n if (!root || typeof root.querySelectorAll !== 'function') {\n return;\n }\n\n if (typeof root.matches === 'function' && root.matches(autoInitializeSelector)) {\n initializeFromElement(root);\n }\n\n root.querySelectorAll(autoInitializeSelector).forEach(initializeFromElement);\n }\n\n function startAutoInitialization() {\n scanForAutoInitialization(document);\n\n if (typeof MutationObserver === 'undefined') {\n return;\n }\n\n const observer = new MutationObserver(mutations => {\n mutations.forEach(mutation => {\n mutation.addedNodes.forEach(node => {\n if (node && node.nodeType === 1) {\n scanForAutoInitialization(node);\n }\n });\n });\n });\n\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n });\n }\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', startAutoInitialization, { once: true });\n } else {\n startAutoInitialization();\n }\n\n return {\n initialize: initialize,\n initializeFromElement: initializeFromElement,\n };\n}();\n\nwindow.chatInteractionDocumentManager = function () {\n const managerStateKey = '__chatInteractionDocumentManagerState';\n\n function normalizeDocumentInfo(document) {\n if (!document || typeof document !== 'object') {\n return null;\n }\n\n return {\n documentId: document.documentId || document.DocumentId || '',\n fileName: document.fileName || document.FileName || '',\n fileSize: document.fileSize || document.FileSize || 0\n };\n }\n\n function formatFileSize(bytes) {\n if (!bytes || bytes < 1024) {\n return (bytes || 0) + ' B';\n }\n\n if (bytes < 1024 * 1024) {\n return (bytes / 1024).toFixed(1) + ' KB';\n }\n\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n }\n\n function getDocumentKey(fileName, fileSize) {\n return ((fileName || '').trim().toLowerCase()) + '::' + (fileSize || 0);\n }\n\n function isDuplicateFile(file, knownKeys) {\n return knownKeys.has(getDocumentKey(file.name, file.size));\n }\n\n function getDocumentsFromDom(container) {\n if (!container) {\n return [];\n }\n\n return Array.from(container.querySelectorAll('[data-chat-document-id]'))\n .map(element => normalizeDocumentInfo({\n documentId: element.dataset.chatDocumentId,\n fileName: element.dataset.chatDocumentName,\n fileSize: Number(element.dataset.chatDocumentSize || 0)\n }))\n .filter(document => document && document.documentId);\n }\n\n function initialize(config) {\n if (!config || !config.itemId) {\n return;\n }\n\n const fileInput = document.getElementById('chat-doc-upload');\n const documentsList = document.getElementById('chat-documents-list');\n const status = document.getElementById('chat-doc-upload-status');\n const progressContainer = document.getElementById('chat-doc-upload-progress');\n const progressBar = document.getElementById('chat-doc-upload-progress-bar');\n const uploadQueue = document.getElementById('chat-doc-upload-queue');\n\n if (!fileInput || !documentsList || !status || !progressContainer || !progressBar || !uploadQueue) {\n return;\n }\n\n const previousState = fileInput[managerStateKey];\n if (previousState && typeof previousState.dispose === 'function') {\n previousState.dispose();\n }\n\n let interactionDocuments = (Array.isArray(config.existingDocuments) ? config.existingDocuments : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n\n if (interactionDocuments.length === 0) {\n interactionDocuments = getDocumentsFromDom(documentsList);\n }\n\n let uploadItems = [];\n let isUploadingDocuments = false;\n\n function createTextElement(tagName, className, text) {\n const element = document.createElement(tagName);\n if (className) {\n element.className = className;\n }\n\n element.textContent = text;\n return element;\n }\n\n function renderDocuments() {\n documentsList.innerHTML = '';\n\n if (interactionDocuments.length === 0) {\n documentsList.appendChild(createTextElement('div', 'text-muted small', 'No documents uploaded yet.'));\n return;\n }\n\n interactionDocuments.forEach(documentInfo => {\n const row = window.document.createElement('div');\n row.className = 'd-flex align-items-center gap-2 border rounded px-2 py-2 bg-white chat-document-row';\n row.dataset.chatDocumentId = documentInfo.documentId;\n row.dataset.chatDocumentName = documentInfo.fileName;\n row.dataset.chatDocumentSize = documentInfo.fileSize;\n\n const actions = window.document.createElement('div');\n actions.className = 'd-flex gap-1';\n\n const downloadBaseUrl = config.downloadDocumentBaseUrl || '/ai/documents/';\n const downloadLink = createTextElement('a', 'btn btn-sm btn-outline-secondary', '');\n downloadLink.title = 'Download';\n downloadLink.href = downloadBaseUrl + encodeURIComponent(documentInfo.documentId) + '/download';\n const downloadIcon = window.document.createElement('i');\n downloadIcon.className = 'fa-solid fa-download';\n downloadLink.appendChild(downloadIcon);\n\n const removeButton = createTextElement('button', 'btn btn-sm btn-outline-danger remove-chat-document-btn', '');\n removeButton.type = 'button';\n removeButton.title = 'Remove';\n removeButton.dataset.documentId = documentInfo.documentId;\n const removeIcon = window.document.createElement('i');\n removeIcon.className = 'fa-solid fa-trash';\n removeButton.appendChild(removeIcon);\n removeButton.addEventListener('click', () => removeDocument(documentInfo.documentId));\n\n actions.appendChild(downloadLink);\n actions.appendChild(removeButton);\n\n const details = window.document.createElement('div');\n details.className = 'min-w-0';\n\n const name = createTextElement('div', 'fw-semibold small text-truncate', documentInfo.fileName || 'Document');\n const icon = window.document.createElement('i');\n icon.className = 'fa-solid fa-file-lines me-1';\n name.prepend(icon);\n\n const size = createTextElement('div', 'text-muted small', formatFileSize(documentInfo.fileSize));\n\n details.appendChild(name);\n details.appendChild(size);\n\n row.appendChild(actions);\n row.appendChild(details);\n documentsList.appendChild(row);\n });\n }\n\n function showUploadStatus(message, cssClass) {\n if (!message) {\n status.textContent = '';\n status.className = 'small mt-2 d-none';\n return;\n }\n\n status.textContent = message;\n status.className = 'small mt-2 ' + (cssClass || 'text-muted');\n }\n\n function showUploadProgress(progress, message, cssClass) {\n if (progress === null || progress === undefined) {\n progressContainer.className = 'progress mt-2 d-none';\n progressContainer.setAttribute('aria-valuenow', '0');\n progressBar.className = 'progress-bar progress-bar-striped progress-bar-animated';\n progressBar.style.width = '0%';\n progressBar.textContent = '0%';\n return;\n }\n\n const roundedProgress = Math.max(0, Math.min(100, Math.round(progress)));\n progressContainer.className = 'progress mt-2';\n progressContainer.setAttribute('aria-valuenow', roundedProgress.toString());\n progressBar.className = 'progress-bar ' + (cssClass || 'progress-bar-striped progress-bar-animated');\n progressBar.style.width = roundedProgress + '%';\n progressBar.textContent = message || (roundedProgress + '%');\n }\n\n function getUploadStatePresentation(state) {\n switch (state) {\n case 'uploaded':\n return { label: 'Uploaded', badgeClass: 'text-bg-success', progressClass: 'bg-success' };\n case 'failed':\n return { label: 'Failed', badgeClass: 'text-bg-danger', progressClass: 'bg-danger' };\n case 'uploading':\n return { label: 'Uploading', badgeClass: 'text-bg-warning', progressClass: 'bg-warning progress-bar-striped progress-bar-animated' };\n default:\n return { label: 'Queued', badgeClass: 'text-bg-secondary', progressClass: 'bg-secondary progress-bar-striped progress-bar-animated' };\n }\n }\n\n function formatUploadMessage(item) {\n if (item.status === 'failed' && item.error) {\n return item.error;\n }\n\n if (item.status === 'uploaded') {\n return 'Upload completed successfully.';\n }\n\n if (item.status === 'uploading') {\n return item.progress + '% uploaded';\n }\n\n return 'Waiting to upload...';\n }\n\n function renderUploadQueue() {\n uploadQueue.innerHTML = '';\n\n uploadItems.forEach(item => {\n const presentation = getUploadStatePresentation(item.status);\n const card = document.createElement('div');\n card.className = 'border rounded px-2 py-2 bg-white';\n\n const header = document.createElement('div');\n header.className = 'd-flex justify-content-between align-items-start gap-2';\n\n const fileDetails = document.createElement('div');\n fileDetails.className = 'flex-grow-1 min-w-0';\n fileDetails.appendChild(createTextElement('div', 'fw-semibold small', item.fileName));\n fileDetails.appendChild(createTextElement('div', 'text-muted small', formatFileSize(item.fileSize)));\n\n const badge = createTextElement('span', 'badge ' + presentation.badgeClass, presentation.label);\n\n header.appendChild(fileDetails);\n header.appendChild(badge);\n\n const progress = document.createElement('div');\n progress.className = 'progress mt-2';\n progress.setAttribute('role', 'progressbar');\n progress.setAttribute('aria-valuemin', '0');\n progress.setAttribute('aria-valuemax', '100');\n progress.setAttribute('aria-valuenow', item.progress.toString());\n\n const progressState = document.createElement('div');\n progressState.className = 'progress-bar ' + presentation.progressClass;\n progressState.style.width = item.progress + '%';\n progressState.textContent = item.progress + '%';\n progress.appendChild(progressState);\n\n const message = createTextElement('div', item.status === 'failed' ? 'small text-danger mt-2' : 'small text-muted mt-2', formatUploadMessage(item));\n\n card.appendChild(header);\n card.appendChild(progress);\n card.appendChild(message);\n uploadQueue.appendChild(card);\n });\n }\n\n function createUploadItem(file, index) {\n return {\n id: file.name + '::' + file.size + '::' + file.lastModified + '::' + index + '::' + Date.now(),\n fileName: file.name,\n fileSize: file.size,\n status: 'queued',\n progress: 0,\n error: null\n };\n }\n\n function updateUploadItem(itemId, updates) {\n uploadItems = uploadItems.map(item => item.id === itemId ? Object.assign({}, item, updates) : item);\n renderUploadQueue();\n }\n\n function removeUploadItems(predicate) {\n uploadItems = uploadItems.filter(item => !predicate(item));\n renderUploadQueue();\n }\n\n function uploadSingleDocument(file, itemIdToUpdate, fileIndex, totalFiles) {\n return new Promise((resolve, reject) => {\n const formData = new FormData();\n formData.append('chatInteractionId', config.itemId);\n formData.append('files', file);\n\n const xhr = new XMLHttpRequest();\n xhr.open('POST', config.uploadDocumentUrl, true);\n\n xhr.upload.addEventListener('progress', event => {\n if (!event.lengthComputable) {\n return;\n }\n\n const fileProgress = Math.round((event.loaded / event.total) * 100);\n updateUploadItem(itemIdToUpdate, {\n status: 'uploading',\n progress: fileProgress\n });\n\n const overallProgress = ((fileIndex + (event.loaded / event.total)) / totalFiles) * 100;\n showUploadProgress(overallProgress, 'Uploading ' + (fileIndex + 1) + ' of ' + totalFiles, 'progress-bar-striped progress-bar-animated');\n });\n\n xhr.addEventListener('load', () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n resolve(JSON.parse(xhr.responseText));\n } catch (error) {\n reject(new Error('Upload failed: invalid server response.'));\n }\n\n return;\n }\n\n reject(new Error((xhr.responseText || 'Upload failed.').trim()));\n });\n\n xhr.addEventListener('error', () => {\n reject(new Error('Upload failed. Please check your connection and try again.'));\n });\n\n xhr.send(formData);\n });\n }\n\n async function uploadDocuments(files) {\n if (!config.uploadDocumentUrl || !files || files.length === 0) {\n return;\n }\n\n if (isUploadingDocuments) {\n showUploadStatus('A document upload is already in progress.', 'text-warning');\n return;\n }\n\n isUploadingDocuments = true;\n\n const filesToUpload = [];\n const duplicateItems = [];\n const knownDocumentKeys = new Set(interactionDocuments.map(document => getDocumentKey(document.fileName, document.fileSize)));\n\n Array.from(files).forEach(file => {\n if (isDuplicateFile(file, knownDocumentKeys)) {\n duplicateItems.push(file);\n return;\n }\n\n knownDocumentKeys.add(getDocumentKey(file.name, file.size));\n filesToUpload.push(file);\n });\n\n if (duplicateItems.length > 0) {\n uploadItems = uploadItems.concat(duplicateItems.map((file, index) => Object.assign(createUploadItem(file, index), {\n status: 'failed',\n progress: 100,\n error: 'This document is already attached.'\n })));\n renderUploadQueue();\n }\n\n if (filesToUpload.length === 0) {\n isUploadingDocuments = false;\n showUploadStatus(duplicateItems.map(file => file.name + ': This document is already attached.').join(' | '), 'text-warning');\n showUploadProgress(null);\n return;\n }\n\n const pendingItems = filesToUpload.map(createUploadItem);\n uploadItems = uploadItems.concat(pendingItems);\n renderUploadQueue();\n showUploadProgress(0, 'Preparing upload...', 'progress-bar-striped progress-bar-animated');\n fileInput.disabled = true;\n\n try {\n let uploadedCount = 0;\n const failedUploads = duplicateItems.map(file => file.name + ': This document is already attached.');\n\n for (let i = 0; i < filesToUpload.length; i++) {\n const file = filesToUpload[i];\n const pendingItem = pendingItems[i];\n\n updateUploadItem(pendingItem.id, {\n status: 'uploading',\n progress: 0,\n error: null\n });\n\n showUploadStatus('Uploading ' + (i + 1) + ' of ' + filesToUpload.length + ' document(s)...', 'text-warning');\n\n try {\n const result = await uploadSingleDocument(file, pendingItem.id, i, filesToUpload.length);\n const uploaded = (Array.isArray(result.uploaded) ? result.uploaded : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n const failed = Array.isArray(result.failed) ? result.failed : [];\n\n if (uploaded.length > 0) {\n uploadedCount += uploaded.length;\n interactionDocuments = interactionDocuments.concat(uploaded);\n updateUploadItem(pendingItem.id, {\n status: 'uploaded',\n progress: 100,\n error: null\n });\n } else {\n const missingUploadMessage = failed.length > 0\n ? failed.map(entry => entry.fileName + ': ' + entry.error).join(' | ')\n : 'The server did not confirm that the file was uploaded.';\n if (failed.length === 0) {\n failedUploads.push(missingUploadMessage);\n }\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: 100,\n error: missingUploadMessage\n });\n }\n\n if (failed.length > 0) {\n const failedMessage = failed.map(entry => entry.fileName + ': ' + entry.error).join(' | ');\n failedUploads.push(failedMessage);\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: 100,\n error: failedMessage\n });\n }\n } catch (error) {\n const errorMessage = error && error.message\n ? error.message\n : 'Upload failed. Please try again.';\n console.error('Upload failed:', error);\n failedUploads.push(file.name + ': ' + errorMessage);\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: pendingItem.progress || 0,\n error: errorMessage\n });\n }\n }\n\n renderDocuments();\n\n if (failedUploads.length > 0) {\n removeUploadItems(item => item.status === 'uploaded');\n showUploadStatus(\n (uploadedCount > 0 ? ('Uploaded ' + uploadedCount + ' document(s). ') : '') + failedUploads.join(' | '),\n uploadedCount > 0 ? 'text-warning' : 'text-danger');\n showUploadProgress(null);\n return;\n }\n\n removeUploadItems(() => true);\n showUploadStatus('Uploaded ' + uploadedCount + ' document(s).', 'text-success');\n showUploadProgress(null);\n } catch (error) {\n console.error('Upload failed:', error);\n showUploadStatus('Upload failed. Please try again.', 'text-danger');\n showUploadProgress(null);\n } finally {\n isUploadingDocuments = false;\n fileInput.disabled = false;\n fileInput.value = '';\n }\n }\n\n async function removeDocument(documentId) {\n if (!config.removeDocumentUrl || !documentId || !window.confirm('Remove this document?')) {\n return;\n }\n\n try {\n const response = await fetch(config.removeDocumentUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n itemId: config.itemId,\n documentId: documentId\n })\n });\n\n if (!response.ok) {\n console.error('Failed to remove document:', await response.text());\n showUploadStatus('Failed to remove document.', 'text-danger');\n return;\n }\n\n if ((response.headers.get('content-type') || '').toLowerCase().indexOf('json') < 0) {\n console.error('Remove document: response was not JSON.', { status: response.status, redirected: response.redirected });\n showUploadStatus(response.redirected\n ? 'You may not be signed in, or you do not have permission for this. Please reload and try again.'\n : 'Failed to remove document.', 'text-danger');\n\n return;\n }\n\n const result = await response.json();\n const serverDocuments = (Array.isArray(result.documents) ? result.documents : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n\n interactionDocuments = serverDocuments.length > 0\n ? serverDocuments\n : interactionDocuments.filter(document => document.documentId !== documentId);\n renderDocuments();\n showUploadStatus('Document removed.', 'text-success');\n } catch (error) {\n console.error('Remove failed:', error);\n showUploadStatus('Failed to remove document.', 'text-danger');\n }\n }\n\n const onFileInputChange = event => {\n const selectedFiles = event.target.files ? Array.from(event.target.files) : [];\n uploadDocuments(selectedFiles);\n };\n\n fileInput.addEventListener('change', onFileInputChange);\n fileInput[managerStateKey] = {\n dispose: () => {\n fileInput.removeEventListener('change', onFileInputChange);\n }\n };\n\n renderDocuments();\n renderUploadQueue();\n showUploadStatus(null);\n showUploadProgress(null);\n\n return fileInput[managerStateKey];\n }\n\n function parseJsonAttribute(element, attributeName, description) {\n const rawValue = element.getAttribute(attributeName);\n if (!rawValue) {\n return null;\n }\n\n try {\n return JSON.parse(rawValue);\n } catch (error) {\n console.error('Failed to parse ' + description + ' JSON.', error);\n return null;\n }\n }\n\n function initializeFromElement(element) {\n if (!element || element.dataset.chatInteractionDocumentManagerInitialized === 'true') {\n return element ? element[managerStateKey] || null : null;\n }\n\n const config = parseJsonAttribute(element, 'data-chat-interaction-document-manager-config', 'chat interaction document manager config');\n if (!config) {\n return null;\n }\n\n const state = initialize(config);\n if (!state) {\n return null;\n }\n\n element.dataset.chatInteractionDocumentManagerInitialized = 'true';\n\n return state;\n }\n\n function scanForAutoInitialization(root) {\n if (!root || typeof root.querySelectorAll !== 'function') {\n return;\n }\n\n if (typeof root.matches === 'function' && root.matches('[data-chat-interaction-document-manager-config]')) {\n initializeFromElement(root);\n }\n\n root.querySelectorAll('[data-chat-interaction-document-manager-config]').forEach(initializeFromElement);\n }\n\n function startAutoInitialization() {\n scanForAutoInitialization(document);\n\n if (typeof MutationObserver === 'undefined') {\n return;\n }\n\n const observer = new MutationObserver(mutations => {\n mutations.forEach(mutation => {\n mutation.addedNodes.forEach(node => {\n if (node && node.nodeType === 1) {\n scanForAutoInitialization(node);\n }\n });\n });\n });\n\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n });\n }\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', startAutoInitialization, { once: true });\n } else {\n startAutoInitialization();\n }\n\n return {\n initialize: initialize,\n initializeFromElement: initializeFromElement,\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 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"]} +{"version":3,"sources":["chat-interaction.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","chatInteractionManager","_window$CoreAIChatMar","_window$CoreAIChatMar2","_window$CoreAIChatMar3","_window$CoreAIChatMar4","_window$CoreAIChatMar5","_window$CoreAIChatMar6","_window$CoreAIChatMar7","_window$CoreAIChatMar8","_window$CoreAIChatMar9","_window$CoreAIChatMar0","defaultConfig","generatedImageAltText","generatedImageMaxWidth","downloadImageTitle","downloadChartTitle","downloadChartButtonText","codeCopiedText","copyTitle","copiedTitle","copyResetDelayMs","assistantLabel","messageTemplate","indicatorTemplate","untitledText","clearHistoryTitle","clearHistoryMessage","clearHistoryOkText","clearHistoryCancelText","sanitizeUrl","url","trimmed","trim","escapeHtmlEntities","text","span","document","createElement","textContent","innerHTML","refreshFontAwesomeIcons","root","fontAwesome","FontAwesome","nodeType","selector","matches","querySelector","containsFontAwesomePlaceholders","dom","i2svg","node","observeFontAwesomeIcons","MutationObserver","observer","mutations","forEach","mutation","addedNodes","observe","childList","subtree","normalizeReference","reference","_ref","_normalized$index","_ref2","_normalized$text","_ref3","_normalized$title","_ref4","_normalized$link","_ref5","_normalized$reference","_normalized$isGenerat","_normalized$isImage","normalized","assign","index","Index","Text","title","Title","link","Link","referenceType","ReferenceType","isGenerated","IsGenerated","isImage","IsImage","isDownloadCitationReference","toLowerCase","normalizeReferences","references","_i","_Object$entries","entries","_normalizeReference","_Object$entries$_i","key","expandImageMarkers","CoreAIChatMarkers","getCitationLabel","unmergedCitationCount","citationIdentity","concat","splitCombinedCitations","content","collapseRepeatedCitations","html","separateAdjacentCitations","citationMarkerHtml","displayIndex","updateMessagePresentation","message","messageReferences","rawContent","displayContent","citationDisplay","processedContent","referenceEntries","citations","citedRefs","filter","_ref6","includes","generatedRefs","_ref8","_ref9","sort","_ref0","_ref1","b","_ref12","_ref13","_step","citationsByIdentity","Map","placeholders","_iterator","_step$value","label","identity","citation","get","referenceKey","referenceKeys","isDownload","set","placeholder","replaceAll","err","_i2","_placeholders","entry","_step2","_iterator2","_step2$value","map","_ref16","buildCitationDisplay","citationReferences","copyContent","_step3","_iterator3","_citation$referenceKe","_step5","_iterator5","_step4","_iterator4","trimEnd","buildCopyContent","htmlContent","parseMarkdownContent","renderer","marked","Renderer","data","href","code","lang","highlighted","hljs","getLanguage","highlight","language","_","highlightAuto","langDisplay","image","src","alt","maxWidth","chartCounter","_pendingCharts","__chartConfigs","findChartMarker","wireImageZoom","mediumZoom","images","querySelectorAll","_step6","_iterator6","setAttribute","margin","background","wireBrokenImageHandlers","_step7","_iterator7","_loop","addEventListener","container","closest","dataset","brokenHandled","hidden","note","className","insertAdjacentElement","once","renderMessageMedia","requestAnimationFrame","charts","_step8","_iterator8","canvas","getElementById","chartId","Chart","offsetParent","_cfg$options","_cfg$options2","_cfg$options2$aspectR","_chartInstance","destroy","cfg","config","JSON","parse","options","responsive","maintainAspectRatio","aspectRatio","console","error","warn","replace","styleMarkdownTables","DOMPurify","sanitize","ADD_TAGS","ADD_ATTR","use","extensions","level","start","idx","undefined","tokenizer","extracted","startIndex","type","raw","substring","endIndex","json","token","initialize","instanceConfig","source","fromEntries","_ref17","signalRHubUrl","appElementSelector","chatContainerElementSelector","inputElementSelector","sendButtonElementSelector","app","Vue","createApp","inputElement","buttonElement","chatContainer","isInteractionStarted","isPlaceholderVisible","isStreaming","isNavigatingAway","autoScroll","stream","messages","prompt","initialFieldValues","settingsDirty","saveSettingsTimeout","saveIndicatorTimeout","isRecording","mediaRecorder","preRecordingPrompt","micButton","speechToTextEnabled","chatMode","textToSpeechEnabled","ttsVoiceName","audioChunks","audioPlayQueue","isPlayingAudio","currentAudioElement","currentAudioUrl","ttsPlayingMessageIndex","ttsAudioCache","ttsInstanceId","Math","random","conversationModeEnabled","conversationButton","isConversationMode","realtimeController","realtimeButton","realtimeEnabled","notifications","notificationDismissTimers","copiedMessageIndex","copyResetTimeoutId","activeCopyButton","computed","lastAssistantIndex","role","methods","handleBeforeUnload","startConnection","_this","_callee","_t","_context","connection","signalR","HubConnectionBuilder","withUrl","withAutomaticReconnect","build","serverTimeoutInMilliseconds","keepAliveIntervalInMilliseconds","on","_data$messages","initializeInteraction","itemId","titleInput","msg","addMessage","$nextTick","historyItem","showSaveIndicator","stopRecording","isFinal","_conversationPartialTranscript","_conversationPartialMessage","hidePlaceholder","isPartial","scrollToBottom","_audioInputSent","dispatchEvent","Event","turnId","_realtimePendingTurns","pending","stopAudio","emptyIndex","splice","escaped","_conversationAssistantMessage","at","userMsg","messageId","responseId","appearance","_conversationAssistantResponseId","prev","hideTypingIndicator","j","msgIndex","newMessage","id","normalizeAssistantAppearance","base64Audio","contentType","binaryString","atob","bytes","Uint8Array","charCodeAt","receivePcm","playCollectedAudio","showPlaceholder","clearHistoryBtn","classList","add","notification","receiveNotification","updateNotification","notificationType","removeNotification","onreconnecting","onreconnected","info","reloadCurrentInteraction","onclose","addMessageInternal","_this2","fireEvent","CustomEvent","detail","_message$rawContent","_this3","remove","event","icon","cssClass","disableStreamingAnimation","getAssistantLabel","getAssistantRoleClasses","classes","getAssistantIconClasses","shouldAnimateAssistantIcon","getAssistantIcon","isIndicator","sendMessage","_this4","_callee2","trimmedPrompt","_context2","endActiveVoiceSession","flushPendingSave","streamMessage","_this5","dispose","streamingStarted","showTypingIndicator","lastResponseId","messageIndex","currentItemId","getItemId","subscribe","chunk","sessionId","setItemId","keys","_i3","_Object$entries2","_normalizeReference2","_Object$entries2$_i","complete","_this5$stream","processReferences","streamingFinished","synthesizeSpeech","_this5$stream2","getServiceDownMessage","_this6","_ref19","_message$rawContent2","stopIcon","getAttribute","replaceChildren","RETURN_DOM_FRAGMENT","startIcon","icons","debouncedSaveSettings","handleExternalTtsStop","_e$detail","sourceId","updateTtsPlaybackButtons","_this7","button","isPlaying","Number","iconHtml","toggle","updateCopyButtons","_this8","isCopied","setCopyButtonState","cacheIndex","_this9","_ttsCacheIndex","invoke","toggleMessageTts","_this0","playAudioBlob","_this1","_step9","totalLength","reduce","sum","combined","offset","_iterator9","blob","Blob","_this10","URL","createObjectURL","audio","Audio","revokeObjectURL","playNextInQueue","play","_this11","nextBlob","shift","conversationModeOnAudioEnded","_this12","pause","currentTime","setVoiceSessionLive","live","nextElementSibling","audioSettings","toggleConversationMode","stopConversationMode","startConversationMode","isActive","stop","_this13","updateConversationButton","navigator","mediaDevices","getUserMedia","echoCancellation","noiseSuppression","autoGainControl","mimeType","MediaRecorder","isTypeSupported","audioBitsPerSecond","_conversationSubject","Subject","_conversationStream","AudioCtx","AudioContext","webkitAudioContext","_conversationAudioCtx","_conversationAnalyser","createAnalyser","fftSize","createMediaStreamSource","connect","pendingChunk","analyser","size","freqData","frequencyBinCount","getByteFrequencyData","k","_callee3","uint8Array","base64","_context3","arrayBuffer","str","byte","String","fromCharCode","btoa","getTracks","track","documentElement","send","close","dismissible","autoDismissMs","endHtml","blur","startHtml","conversationModeSendPrompt","originalLength","_this14","setTimeout","scrollTop","scrollHeight","clientHeight","handleUserInput","target","getSaveIndicatorElement","saveIndicatorElementSelector","_this15","indicator","clearTimeout","clearPendingSettingsSave","getFieldLabel","input","_input$closest","setting","getValidationFeedbackElement","feedback","contains","clearSettingValidationError","removeAttribute","setSettingValidationError","getSettingValidationMessage","disabled","number","fieldLabel","isNaN","min","max","validateSettingInput","validateSettings","_this16","isValid","getSettingInputs","queueSettingsSave","explicitInputs","getSelectedGroupValues","groupName","fallbackSelector","explicitSelections","values","checkbox","baseName","hiddenInput","getPromptTemplateSelections","promptTemplates","card","templateIdInput","promptParametersInput","templateId","promptParameters","clearNotificationDismiss","findIndex","scheduleNotificationDismiss","_this17","timerId","dismissNotification","handleNotificationAction","actionName","resetInteraction","initializeApp","_this18","placeholderElementSelector","loadInteraction","atBottom","shiftKey","click","lastMsg","pop","chatInteractionItems","getElementsByClassName","preventDefault","initialMessages","btn","block","codeEl","clipboard","writeText","copiedText","clearHistory","micButtonElementSelector","style","display","toggleRecording","conversationButtonElementSelector","CoreAIRealtime","realtimeButtonElementSelector","attach","ensureConnected","sendStart","subject","voice","silenceMs","vadThreshold","allowInterruption","webRtcEnabled","realtimeWebRtcEnabled","sendStartWebRtc","offerSdp","webRtcIceServers","realtimeWebRtcIceServers","voiceName","realtimeVoiceName","getVoiceName","el","realtimeVoiceSelectElementSelector","capableDeployments","realtimeCapableDeployments","selectors","onSessionStateChanged","active","onActivate","onDeactivate","onEnterRealtimeMode","onUserTurnPending","onUserTurnDropped","dropped","setupRealtimeVoicePicker","realtimeVoicesUrl","voiceSelect","voiceGroup","realtimeVoiceGroupElementSelector","conversationSelect","conversationDeploymentSelectElementSelector","capable","savedVoiceId","self","loadVoices","resolveConversationDeployment","defaultRealtimeDeploymentName","isRealtimeDeployment","_loadVoices","_callee4","deploymentName","realtime","response","result","grouped","_iterator0","_step0","_context4","applyMode","fetch","encodeURIComponent","credentials","headers","ok","voices","gender","has","localeCompare","optgroup","option","selected","appendChild","clearHistoryConfirmed","confirmDialog","confirm","okText","cancelText","callback","confirmed","_this19","saveSettings","getSelectedToolNames","getSelectedMcpConnectionIds","getSelectedA2AConnectionIds","getSelectedAgentNames","_this20","settings","match","checked","parseFloat","toolNames","mcpConnectionIds","a2aConnectionIds","agentNames","promptTemplateIds","template","force","clearCopiedMessageState","copyResponse","_ref21","_message$copyContent","_event$target","_event$target$closest","_this21","currentTarget","startRecording","_this22","_callee5","_context5","updateMicButton","watch","_this23","mounted","_this24","_callee6","_context6","$el","fontAwesomeObserver","beforeUnmount","removeEventListener","disconnect","mount","autoInitializeSelector","initializeFromElement","element","chatInteractionInitialized","__chatInteractionApp","attributeName","description","rawValue","parseJsonAttribute","scanForAutoInitialization","startAutoInitialization","body","readyState","chatInteractionDocumentManager","managerStateKey","normalizeDocumentInfo","documentId","DocumentId","fileName","FileName","fileSize","FileSize","formatFileSize","toFixed","getDocumentKey","isDuplicateFile","file","knownKeys","fileInput","documentsList","status","progressContainer","progressBar","uploadQueue","previousState","interactionDocuments","existingDocuments","chatDocumentId","chatDocumentName","chatDocumentSize","uploadItems","isUploadingDocuments","onFileInputChange","_x","_uploadDocuments","uploadDocuments","files","renderDocuments","renderUploadQueue","showUploadStatus","showUploadProgress","createTextElement","tagName","documentInfo","row","actions","downloadBaseUrl","downloadDocumentBaseUrl","downloadLink","downloadIcon","removeButton","removeIcon","_x2","_removeDocument","removeDocument","details","prepend","progress","width","roundedProgress","round","item","presentation","state","badgeClass","progressClass","getUploadStatePresentation","header","fileDetails","badge","progressState","formatUploadMessage","createUploadItem","lastModified","Date","now","updateUploadItem","updates","removeUploadItems","predicate","uploadSingleDocument","itemIdToUpdate","fileIndex","totalFiles","reject","formData","FormData","append","xhr","XMLHttpRequest","open","uploadDocumentUrl","upload","lengthComputable","fileProgress","loaded","total","responseText","Error","_callee7","filesToUpload","duplicateItems","knownDocumentKeys","pendingItems","uploadedCount","failedUploads","pendingItem","uploaded","failed","missingUploadMessage","failedMessage","errorMessage","_t3","_t4","_context7","Set","join","_callee8","serverDocuments","_t5","_t6","_context8","removeDocumentUrl","method","stringify","redirected","documents","chatInteractionDocumentManagerInitialized","download","toDataURL","img","startsWith","res","removeChild"],"mappings":"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","file":"chat-interaction.min.js","sourcesContent":["/*\n * Figure markers: the short labels the model writes, turned into pictures by the host.\n *\n * Retrieval hands the model a label -- [fig:1] -- and keeps the picture's real link in the message's reference\n * map, the same way a text citation keeps its source behind \"[doc:1]\". A model asked to reproduce a long opaque\n * identifier does not reproduce it: it copies the shape and substitutes ordinals, so links to figures that were\n * never in the results came back as 404s. A label short enough to be written exactly, with the link put back\n * here where the model cannot reach it, is what stops that.\n *\n * It sits on window rather than inside the manager below so the host can reach it, and so its rules can be\n * exercised in a bare sandbox with no browser and no DOM -- see tests/realtime-client/figure-markers.test.js --\n * exactly as window.CoreAIRealtime exposes the microphone gate's rules.\n *\n * The same block sits at the top of ai-chat.js: the two chat clients are separate bundles that share no\n * module of their own, and both render the same markdown. Change one, change the other.\n */\n// CoreAIChatMarkers lives in chat-markers.js, which every chat surface loads before this file.\n\nwindow.chatInteractionManager = 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 codeCopiedText: 'Copied!',\n copyTitle: 'Click here to copy response to clipboard.',\n copiedTitle: 'Response copied to clipboard.',\n copyResetDelayMs: 2000,\n assistantLabel: 'Assistant',\n\n messageTemplate: `\n
\n \n
\n
\n \n {{ notification.content }}\n \n
\n
\n \n
\n
\n
\n `,\n indicatorTemplate: `\n
\n \n Assistant\n
\n `,\n // Localizable strings\n untitledText: 'Untitled',\n clearHistoryTitle: 'Clear History',\n clearHistoryMessage: 'Are you sure you want to clear the chat history? This action cannot be undone. Your documents, parameters, and tools will be preserved.',\n clearHistoryOkText: 'Yes',\n clearHistoryCancelText: 'Cancel'\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 containsFontAwesomePlaceholders(root) {\n if (!root || root.nodeType !== 1) {\n return false;\n }\n\n var selector = 'i[class*=\"fa-\"],i.fa,i.fas,i.far,i.fab';\n if (typeof root.matches === 'function' && root.matches(selector)) {\n return true;\n }\n\n return typeof root.querySelector === 'function' && !!root.querySelector(selector);\n }\n\n function refreshFontAwesomeIcons(root) {\n var fontAwesome = window.FontAwesome;\n if (!containsFontAwesomePlaceholders(root) || !fontAwesome || !fontAwesome.dom || typeof fontAwesome.dom.i2svg !== 'function') {\n return;\n }\n\n fontAwesome.dom.i2svg({ node: root });\n }\n\n function observeFontAwesomeIcons(root) {\n if (!root || typeof MutationObserver === 'undefined') {\n return null;\n }\n\n var observer = new MutationObserver(function (mutations) {\n mutations.forEach(function (mutation) {\n mutation.addedNodes.forEach(function (node) {\n refreshFontAwesomeIcons(node);\n });\n });\n });\n\n observer.observe(root, {\n childList: true,\n subtree: true\n });\n\n return observer;\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 normalized.isGenerated = (normalized.isGenerated ?? normalized.IsGenerated) === true;\n normalized.isImage = (normalized.isImage ?? normalized.IsImage) === true;\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 // Installed at the top of this file so it can be unit tested without a browser; see the comment there.\n const expandImageMarkers = window.CoreAIChatMarkers.expandImageMarkers;\n\n function getCitationLabel(reference, key) {\n return reference.title || reference.text || key;\n }\n\n // Which references are one citation, and how a repeated marker reads, are statements about strings and\n // live in chat-markers.js so every chat surface numbers them the same way. Without the module each\n // reference keeps an identity of its own and nothing merges, which is the numbering this script had\n // before it.\n let unmergedCitationCount = 0;\n const citationIdentity = window.CoreAIChatMarkers?.citationIdentity\n ?? (() => `unmerged-${++unmergedCitationCount}`);\n const splitCombinedCitations = window.CoreAIChatMarkers?.splitCombinedCitations\n ?? (content => content);\n const collapseRepeatedCitations = window.CoreAIChatMarkers?.collapseRepeatedCitations\n ?? (html => html);\n const separateAdjacentCitations = window.CoreAIChatMarkers?.separateAdjacentCitations\n ?? (html => html);\n const citationMarkerHtml = window.CoreAIChatMarkers?.citationMarkerHtml\n ?? (displayIndex => `${displayIndex}`);\n\n function buildCitationDisplay(content, references) {\n // Before anything looks for a reference key, the combined form the model tends to write is split into\n // the keys it means. A key that is not found is not replaced, and an unreplaced key reaches the reader\n // as a raw marker mid-sentence.\n let processedContent = splitCombinedCitations((content || '').trim());\n const messageReferences = normalizeReferences(references);\n const referenceEntries = Object.entries(messageReferences);\n\n if (!referenceEntries.length) {\n return { content: processedContent, citations: [] };\n }\n\n const citedRefs = referenceEntries.filter(([key]) => processedContent.includes(key));\n const generatedRefs = referenceEntries.filter(([key, value]) => value.isGenerated && !processedContent.includes(key));\n\n if (!citedRefs.length && !generatedRefs.length) {\n return { content: processedContent, citations: [] };\n }\n\n citedRefs.sort(([, a], [, b]) => a.index - b.index);\n generatedRefs.sort(([, a], [, b]) => a.index - b.index);\n\n const citations = [];\n const citationsByIdentity = new Map();\n const placeholders = [];\n let displayIndex = 1;\n\n for (const [key, value] of citedRefs) {\n const label = getCitationLabel(value, key);\n const link = value.link || null;\n const identity = citationIdentity(label, link);\n let citation = citationsByIdentity.get(identity);\n\n // Every reference still has its key replaced, so the text never keeps a raw key; what the merge\n // changes is only how many numbers the reader is given for them.\n if (!citation) {\n citation = {\n referenceKey: key,\n referenceKeys: [],\n displayIndex: displayIndex++,\n label: label,\n link: link,\n isDownload: isDownloadCitationReference(value),\n };\n\n citationsByIdentity.set(identity, citation);\n citations.push(citation);\n }\n\n citation.referenceKeys.push(key);\n\n const placeholder = `__CITE_${citation.displayIndex}_${value.index || citation.displayIndex}__`;\n processedContent = processedContent.replaceAll(key, placeholder);\n placeholders.push({ placeholder, displayIndex: citation.displayIndex, label: citation.label });\n }\n\n for (const entry of placeholders) {\n processedContent = processedContent.replaceAll(entry.placeholder, citationMarkerHtml(entry.displayIndex, entry.label));\n }\n\n // Merged citations can leave the same number twice over a sentence; that is collapsed before the\n // commas go in, or the reader is given \"1,1\".\n processedContent = collapseRepeatedCitations(processedContent);\n processedContent = separateAdjacentCitations(processedContent);\n\n // Generated files (such as exported tabular data) are always offered as a download even when\n // the model does not cite them inline, so the user never loses access to the produced file.\n for (const [key, value] of generatedRefs) {\n citations.push({\n referenceKey: key,\n referenceKeys: [key],\n displayIndex: displayIndex,\n label: getCitationLabel(value, key),\n link: value.link || null,\n isDownload: true,\n placeholder: null,\n });\n\n displayIndex++;\n }\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 // Every key the citation absorbed is replaced, not just the first: a merged key left behind would\n // reach the clipboard as the raw reference token the reader never saw on the page.\n for (const citation of citations) {\n for (const key of (citation.referenceKeys?.length ? citation.referenceKeys : [citation.referenceKey])) {\n copyContent = copyContent.replaceAll(key, `[${citation.displayIndex}]`);\n }\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 // Figure markers become images before anything else reads the content: the citation pass looks for its\n // own keys in what is left, and the markdown parser then sees an ordinary image.\n const displayContent = expandImageMarkers(rawContent, messageReferences);\n const citationDisplay = buildCitationDisplay(displayContent, 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 // Copied from the expanded content, so a copied answer carries the picture's link rather than a label\n // that means nothing outside this page.\n // Split here too: the copy is built from the expanded content rather than the display path's output,\n // so a combined marker would otherwise survive into the clipboard as a raw key.\n message.copyContent = buildCopyContent(splitCombinedCitations(displayContent), 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 `${data.text}`;\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 `
${langDisplay}
${highlighted}
`;\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 // Spans, not divs. A figure marker is often written mid-sentence -- \"Figures [fig:1], [fig:2] and\n // [fig:3] show...\" -- and a block element cannot sit inside a paragraph: the browser closes the

\n // at the first one, so the sentence is torn into fragments and the commas between the markers are\n // left stranded on their own lines. Inline-block keeps the figure looking exactly the same while\n // remaining something a paragraph can legally contain.\n // The download sits over the picture's lower corner rather than on a line of its own beneath it.\n // A row of its own cost a band of vertical space under every figure, which a conversation full of\n // them pays for once per figure. The link itself is unchanged -- same address, same download\n // attribute, same behaviour -- only where it is drawn.\n return `\n \"${alt}\"\n \n \n \n `;\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 shared with ai-chat.js\n window.__chartConfigs = window.__chartConfigs || {};\n\n function createChartHtml(chartId) {\n return `

`\n + ``\n + `
`\n + `
`\n + ``\n + `
`;\n }\n\n // The marker itself is read by chat-markers.js, shared with every other chat surface, so the three of them\n // cannot disagree about what a marker is. Everything below -- the container, the id scheme, the Chart.js\n // call -- is this surface's own and legitimately differs from the others.\n const findChartMarker = window.CoreAIChatMarkers.findChartMarker;\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 = findChartMarker(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 // An image the assistant named but the server will not serve. The address is written by a language\n // model from what retrieval handed it, so a mistyped or invented one is possible, and the browser's\n // default for that is a broken-image icon captioned with the alt text -- which reads as a real picture\n // that failed to arrive. Saying plainly that it could not be loaded is both truer and quieter.\n //\n // Wired here rather than as an inline onerror attribute because message bodies go through DOMPurify,\n // which strips event-handler attributes.\n function markBrokenImagesInMessage() {\n // Scanning the document rather than one message, because the value threaded through the render\n // path is the message DATA object -- the thing carrying content, references and pending charts --\n // and not the element it was rendered into. Wiring is idempotent via the data-broken-wired mark,\n // so re-scanning after each render costs a query over the handful of images already handled.\n if (typeof document === 'undefined' || typeof requestAnimationFrame !== 'function') {\n return;\n }\n\n // Deferred for the same reason the charts below are: the render that produced these elements has\n // not necessarily been flushed to the DOM when this runs.\n requestAnimationFrame(wireBrokenImageHandlers);\n requestAnimationFrame(wireImageZoom);\n }\n\n // A picture arrives after the markdown is handed back -- the view writes it, and a streamed answer\n // rewrites it on every chunk -- so zooming cannot be attached once at load. It is attached on the same\n // pass as the broken-image handler above, and the attribute marks a picture already attached so a\n // re-render does not bind it a second time.\n function wireImageZoom() {\n // The library is the host's to load. Without it the picture is still shown and still downloadable;\n // only the enlarging is missing, so this is not worth failing a render over.\n if (typeof mediumZoom !== 'function') {\n return;\n }\n\n const images = document.querySelectorAll('.generated-image-container img:not([data-zoom-wired])');\n\n if (images.length === 0) {\n return;\n }\n\n for (const image of images) {\n image.setAttribute('data-zoom-wired', 'true');\n }\n\n mediumZoom(images, {\n // The drawing is bounded by the window rather than by this margin, so the margin is kept\n // small: an ingested figure is read detail by detail, and every pixel given away here comes\n // off the size it is read at.\n margin: 16,\n background: 'rgba(15, 15, 15, 0.92)',\n });\n }\n\n function wireBrokenImageHandlers() {\n const images = document.querySelectorAll('.generated-image-container img:not([data-broken-wired])');\n\n for (const image of images) {\n image.setAttribute('data-broken-wired', 'true');\n image.addEventListener('error', function () {\n const container = image.closest('.generated-image-container');\n\n if (!container || container.dataset.brokenHandled) {\n return;\n }\n\n container.dataset.brokenHandled = 'true';\n container.hidden = true;\n\n const note = document.createElement('p');\n note.className = 'text-muted small fst-italic mb-2';\n note.textContent = image.alt\n ? `(the picture \"${image.alt}\" could not be loaded)`\n : '(that picture could not be loaded)';\n container.insertAdjacentElement('afterend', note);\n }, { once: true });\n }\n }\n\n function renderMessageMedia(message) {\n markBrokenImagesInMessage();\n\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 const canvas = document.getElementById(c.chartId);\n if (!canvas) {\n continue;\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., ).');\n continue;\n }\n\n // When the canvas is inside a hidden container (e.g., display:none),\n // it has zero dimensions. Keep the config for later rendering.\n if (canvas.offsetParent === null) {\n window.__chartConfigs[c.chartId] = c.config;\n continue;\n }\n\n try {\n // Destroy existing chart instance if re-rendering\n if (canvas._chartInstance) {\n canvas._chartInstance.destroy();\n }\n\n const cfg = typeof c.config === 'string' ? JSON.parse(c.config) : c.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 } catch (e) {\n console.error('Error creating chart:', e);\n }\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 // A markdown table becomes a bare , which Bootstrap leaves completely unstyled: it renders\n // as cramped, borderless text that reads as plain output rather than a table. Adding the framework's\n // own classes styles it wherever Bootstrap is loaded, and the wrapper lets a wide table scroll on\n // its own instead of stretching the conversation. Markdown tables cannot nest, so the plain\n // replacement is safe. This page renders markdown through its own pipeline, so the same treatment\n // is applied here as in the shared chat script.\n function styleMarkdownTables(html) {\n return html\n .replace(/
/g, '
')\n .replace(/<\\/table>/g, '
');\n }\n\n function parseMarkdownContent(content, message) {\n _pendingCharts = [];\n const html = styleMarkdownTables(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 function compactObject(source) {\n if (!source || typeof source !== 'object') {\n return {};\n }\n\n return Object.fromEntries(\n Object.entries(source).filter(([, value]) => value !== undefined)\n );\n }\n\n const initialize = (instanceConfig) => {\n const config = Object.assign({}, defaultConfig, compactObject(instanceConfig));\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 app = Vue.createApp({\n data() {\n return {\n inputElement: null,\n buttonElement: null,\n chatContainer: null,\n placeholder: null,\n isInteractionStarted: false,\n isPlaceholderVisible: true,\n isStreaming: false,\n isNavigatingAway: false,\n autoScroll: true,\n stream: null,\n messages: [],\n prompt: '',\n initialFieldValues: new Map(),\n settingsDirty: false,\n saveSettingsTimeout: null,\n saveIndicatorTimeout: null,\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 ttsPlayingMessageIndex: -1,\n ttsAudioCache: {},\n ttsInstanceId: 'chat-interaction-' + Math.random().toString(36).slice(2),\n conversationModeEnabled: config.chatMode === 'Conversation',\n conversationButton: null,\n isConversationMode: false,\n // Realtime (speech-to-speech) controller from the shared CoreAIRealtime module.\n realtimeController: null,\n realtimeButton: null,\n // Whether a realtime deployment actually resolved. The controller is attached whenever the\n // module is loaded, so its presence says nothing about which transport carries the\n // conversation -- only this flag does.\n realtimeEnabled: config.realtimeEnabled === true,\n notifications: [],\n notificationDismissTimers: {},\n copyTitle: config.copyTitle,\n copiedTitle: config.copiedTitle,\n copiedMessageIndex: -1,\n copyResetTimeoutId: null,\n activeCopyButton: 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 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(\"LoadInteraction\", (data) => {\n this.initializeInteraction(data.itemId, true);\n this.messages = [];// Update the title field if it exists\n const titleInput = document.querySelector('[data-chat-interaction-title], .setting-input[data-setting=\"title\"], input[name=\"ChatInteraction.Title\"], input[name=\"Title\"]');\n if (titleInput && data.title) {\n titleInput.value = data.title;\n }\n\n (data.messages ?? []).forEach(msg => {\n this.addMessage(msg);\n\n this.$nextTick(() => {\n renderMessageMedia(msg);\n });\n });\n });\n\n this.connection.on(\"SettingsSaved\", (itemId, title) => {\n // Update the history list item if it exists\n // Use a more specific selector to only target history list items, not other elements like the Clear History button\n const historyItem = document.querySelector(`.chat-interaction-history-item[data-interaction-id=\"${itemId}\"]`);\n if (historyItem) {\n historyItem.textContent = title || config.untitledText;\n }\n\n const titleInput = document.querySelector('[data-chat-interaction-title], .setting-input[data-setting=\"title\"], input[name=\"ChatInteraction.Title\"], input[name=\"Title\"]');\n if (titleInput && title) {\n titleInput.value = title;\n }\n\n this.showSaveIndicator('Saved', 'text-success');\n });\n\n this.connection.on(\"ReceiveError\", (error) => {\n console.error(\"SignalR Error: \", error);\n this.showSaveIndicator('Save failed', 'text-danger');\n\n if (this.isRecording) {\n this.stopRecording();\n }\n });\n\n this.connection.on(\"ReceiveTranscript\", (itemId, text, isFinal) => {\n if (this.isConversationMode) {\n if (!isFinal && text) {\n this._conversationPartialTranscript = text;\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n var html = '

' + escaped + '

';\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\", (itemId, turnId, text) => {\n // Realtime: a placeholder for this turn was already inserted in the right position when\n // the utterance was captured (see onUserTurnPending), so just fill in its text.\n if (turnId && this._realtimePendingTurns && this._realtimePendingTurns[turnId]) {\n var pending = this._realtimePendingTurns[turnId];\n delete this._realtimePendingTurns[turnId];\n this.stopAudio();\n if (text) {\n pending.content = text;\n pending.rawContent = text;\n pending.isPartial = false;\n updateMessagePresentation(pending, pending.references);\n } else {\n var emptyIndex = this.messages.indexOf(pending);\n if (emptyIndex >= 0) { this.messages.splice(emptyIndex, 1); }\n }\n\n return;\n }\n\n if (text) {\n this.stopAudio();\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '

' + escaped + '

';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else if (this._conversationAssistantMessage) {\n // Realtime: the user's transcript lags the assistant's reply for the SAME turn (the\n // model answers the audio before speech-to-text finishes). Insert the user message\n // just before the streaming assistant message so the order stays You -> Assistant,\n // and keep that message streaming — ending it here split one reply into two bubbles.\n var at = this._conversationAssistantMessage.index;\n var userMsg = { role: 'user', content: text, rawContent: text, references: {} };\n updateMessagePresentation(userMsg, userMsg.references);\n this.messages.splice(at, 0, userMsg);\n this._conversationAssistantMessage.index = at + 1;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (itemId, messageId, token, responseId, references, appearance) => {\n // A new response id means a new turn — finalize the previous assistant message so two replies\n // never merge into one bubble (also covers barge-in, which starts a fresh response).\n if (this._conversationAssistantMessage && this._conversationAssistantResponseId && responseId && this._conversationAssistantResponseId !== responseId) {\n var prev = this.messages[this._conversationAssistantMessage.index];\n if (prev) { prev.isStreaming = false; }\n this._conversationAssistantMessage = null;\n }\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 appearance: this.normalizeAssistantAppearance(appearance),\n references: {},\n };\n this.messages.push(newMessage);\n this._conversationAssistantMessage = { index: msgIndex, content: '' };\n this._conversationAssistantResponseId = responseId;\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 renderMessageMedia(msg);\n this.scrollToBottom();\n });\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantComplete\", (itemId, 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 this._conversationAssistantResponseId = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (itemId, 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 // Realtime PCM streams straight to the low-latency player; other formats (TTS) are buffered.\n if (contentType === 'audio/pcm' && this.realtimeController) {\n this.realtimeController.receivePcm(bytes);\n } else {\n this.audioChunks.push(bytes);\n }\n }\n });\n\n this.connection.on(\"ReceiveAudioComplete\", (itemId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"HistoryCleared\", (itemId) => {\n // Clear messages and show placeholder\n this.messages = [];\n this.showPlaceholder();\n\n // Hide the clear history button since there's no history now\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.classList.add('d-none');\n }\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 this.reloadCurrentInteraction();\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(\"addingChatInteractionMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedChatInteractionMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\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 renderMessageMedia(message);\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 fireEvent(event) {\n document.dispatchEvent(event);\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 : defaultConfig.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 isIndicator(message) {\n return message.role === 'indicator';\n },\n async sendMessage() {\n let trimmedPrompt = this.prompt.trim();\n\n if (!trimmedPrompt) {\n return;\n }\n\n // A live voice session and a typed turn are two writers into one interaction, and they\n // would interleave. End the session first; the turns it already produced are persisted, so\n // the typed message simply continues the same thread.\n this.endActiveVoiceSession();\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 // Flush any pending settings save before sending a message\n // to prevent concurrent hub calls that can cause database deadlocks.\n await this.flushPendingSave();\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n // Show the clear history button since we now have prompts\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.classList.remove('d-none');\n }\n\n this.streamMessage(trimmedPrompt);\n this.inputElement.value = '';\n this.prompt = '';\n },\n streamMessage(trimmedPrompt) {\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 var messageIndex = this.messages.length;\n var currentItemId = this.getItemId();\n\n this.stream = this.connection.stream(\"SendMessage\", currentItemId, trimmedPrompt)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n if (chunk.sessionId && !currentItemId) {\n this.setItemId(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n messageIndex = this.messages.length;\n let newMessage = {\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n };\n\n this.messages.push(newMessage);\n message = newMessage;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\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 message.rawContent = content;\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderMessageMedia(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 return {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\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 renderMessageMedia(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 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 // 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 // Save any settings that were deferred during streaming.\n if (this.settingsDirty) {\n this.debouncedSaveSettings();\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 ? ''\n : '';\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 updateCopyButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-copy-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-copy-message-index'));\n var isCopied = buttonIndex === this.copiedMessageIndex;\n var iconHtml = isCopied\n ? ''\n : '';\n\n button.classList.toggle('text-success', isCopied);\n button.classList.toggle('text-secondary', !isCopied);\n button.setAttribute('title', isCopied ? this.copiedTitle : this.copyTitle);\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\n });\n },\n setCopyButtonState(button, isCopied) {\n if (!button) {\n return;\n }\n\n var iconHtml = isCopied\n ? ''\n : '';\n\n button.classList.toggle('text-success', isCopied);\n button.classList.toggle('text-secondary', !isCopied);\n button.setAttribute('title', isCopied ? this.copiedTitle : this.copyTitle);\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\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.getItemId(), 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.isPlayingAudio && 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 currently playing, queue this blob for later.\n if (this.isPlayingAudio && 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 const 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 // A live voice session takes the message box away and puts the audio settings in its place; ending\n // the session gives it back. Sending a typed message already ends the session first, so the box was\n // never a way to say something *during* one -- hiding it only makes that honest, and frees the row\n // for the gear. Both transports land here: realtime through the module's onActivate, the\n // speech-to-text cascade through startConversationMode.\n setVoiceSessionLive(live) {\n if (this.inputElement) {\n this.inputElement.hidden = live;\n }\n\n if (this.buttonElement) {\n this.buttonElement.hidden = live;\n }\n\n // With the message box gone the live button would otherwise sit at its natural width in an\n // empty row, so it takes the space the box left behind. Whichever transport is carrying the\n // conversation owns a different button, and the hidden one is unaffected by the class.\n [this.realtimeButton, this.conversationButton].forEach(function (button) {\n if (button) { button.classList.toggle('flex-grow-1', live); }\n });\n\n // The gear is built by the realtime module directly after the button it was handed, and only\n // in realtime mode, so it is absent on the cascade. It belongs to a live session rather than\n // to the surface. The module hard-codes its element id and a page can host two chat clients\n // at once -- this one and the admin widget -- so it is found next to this client's own button\n // rather than by id.\n var next = this.realtimeButton && this.realtimeButton.nextElementSibling;\n var audioSettings = next && next.id === 'realtime-audio-settings' ? next : null;\n if (audioSettings) {\n audioSettings.hidden = !live;\n }\n },\n toggleConversationMode() {\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n // Two writers into one interaction would interleave, so the voice session ends before the typed\n // turn starts rather than running alongside it.\n endActiveVoiceSession() {\n if (this.realtimeController && this.realtimeController.isActive()) {\n this.realtimeController.stop();\n\n return;\n }\n\n if (this.isConversationMode) {\n this.stopConversationMode();\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\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 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 itemId = this.getItemId();\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"StartConversation\", itemId, 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, continuation is handled\n // by the persistent stream.\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 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 getItemId() {\n return this.inputElement.getAttribute('data-interaction-id')\n || this.inputElement.getAttribute('data-item-id');\n },\n getSaveIndicatorElement() {\n if (config.saveIndicatorElementSelector) {\n return document.querySelector(config.saveIndicatorElementSelector);\n }\n\n return document.querySelector('[data-chat-interaction-save-indicator]');\n },\n showSaveIndicator(text, className) {\n const indicator = this.getSaveIndicatorElement();\n if (!indicator) {\n return;\n }\n\n indicator.textContent = text || '';\n indicator.className = 'settings-save-indicator ' + (className || 'text-muted');\n\n if (this.saveIndicatorTimeout) {\n clearTimeout(this.saveIndicatorTimeout);\n this.saveIndicatorTimeout = null;\n }\n\n if (!text) {\n return;\n }\n\n this.saveIndicatorTimeout = setTimeout(() => {\n indicator.textContent = '';\n this.saveIndicatorTimeout = null;\n }, 3000);\n },\n clearPendingSettingsSave() {\n if (this.saveSettingsTimeout) {\n clearTimeout(this.saveSettingsTimeout);\n this.saveSettingsTimeout = null;\n }\n },\n getFieldLabel(input) {\n const label = input\n .closest('.mb-3, .col-6, .col, .form-group, .form-floating')\n ?.querySelector('label');\n\n if (!label) {\n return input.dataset.setting || 'This field';\n }\n\n return (label.textContent || '')\n .replace(/\\s+/g, ' ')\n .trim()\n || input.dataset.setting\n || 'This field';\n },\n getValidationFeedbackElement(input) {\n let feedback = input.nextElementSibling;\n if (feedback && feedback.classList.contains('invalid-feedback')) {\n return feedback;\n }\n\n feedback = document.createElement('div');\n feedback.className = 'invalid-feedback';\n input.insertAdjacentElement('afterend', feedback);\n\n return feedback;\n },\n clearSettingValidationError(input) {\n input.classList.remove('is-invalid');\n input.removeAttribute('aria-invalid');\n\n const feedback = input.nextElementSibling;\n if (feedback && feedback.classList.contains('invalid-feedback')) {\n feedback.textContent = '';\n }\n },\n setSettingValidationError(input, message) {\n const feedback = this.getValidationFeedbackElement(input);\n input.classList.add('is-invalid');\n input.setAttribute('aria-invalid', 'true');\n feedback.textContent = message;\n },\n getSettingValidationMessage(input) {\n if (!input || input.disabled || input.type !== 'number') {\n return null;\n }\n\n const value = (input.value || '').trim();\n if (!value) {\n return null;\n }\n\n const number = Number(value);\n const fieldLabel = this.getFieldLabel(input);\n\n if (Number.isNaN(number)) {\n return `${fieldLabel} must be a valid number.`;\n }\n\n const min = input.getAttribute('min');\n if (min !== null && number < Number(min)) {\n return `${fieldLabel} must be ${min} or greater.`;\n }\n\n const max = input.getAttribute('max');\n if (max !== null && number > Number(max)) {\n return `${fieldLabel} must be ${max} or less.`;\n }\n\n return null;\n },\n validateSettingInput(input) {\n const message = this.getSettingValidationMessage(input);\n if (!message) {\n this.clearSettingValidationError(input);\n return true;\n }\n\n this.setSettingValidationError(input, message);\n return false;\n },\n validateSettings() {\n let isValid = true;\n\n this.getSettingInputs().forEach(input => {\n isValid = this.validateSettingInput(input) && isValid;\n });\n\n return isValid;\n },\n queueSettingsSave() {\n if (!this.validateSettings()) {\n this.clearPendingSettingsSave();\n this.settingsDirty = false;\n this.showSaveIndicator('Fix errors', 'text-danger');\n return;\n }\n\n this.settingsDirty = true;\n this.showSaveIndicator('Saving...', 'text-warning');\n this.debouncedSaveSettings();\n },\n getSettingInputs() {\n const explicitInputs = document.querySelectorAll('.setting-input[data-setting]');\n if (explicitInputs.length > 0) {\n return explicitInputs;\n }\n\n return document.querySelectorAll(\n 'input[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"]), ' +\n 'select[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"]), ' +\n 'textarea[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"])'\n );\n },\n getSelectedGroupValues(groupName, fallbackSelector) {\n const explicitSelections = document.querySelectorAll(`.capability-checkbox[data-save-group=\"${groupName}\"]:checked, .capability-checkbox[data-group=\"${groupName}\"]:checked`);\n if (explicitSelections.length > 0) {\n const values = [];\n\n explicitSelections.forEach(checkbox => {\n const value = checkbox.getAttribute('data-item-id') || checkbox.value;\n if (value) {\n values.push(value);\n }\n });\n\n return values;\n }\n\n if (!fallbackSelector) {\n return [];\n }\n\n const values = [];\n const checkboxes = document.querySelectorAll(fallbackSelector);\n\n checkboxes.forEach(checkbox => {\n const baseName = checkbox.name.replace('.IsSelected', '.ItemId');\n const hiddenInput = document.querySelector(`input[type=\"hidden\"][name=\"${baseName}\"]`);\n\n if (hiddenInput && hiddenInput.value) {\n values.push(hiddenInput.value);\n }\n });\n\n return values;\n },\n getPromptTemplateSelections() {\n const promptTemplates = [];\n\n document.querySelectorAll('.prompt-template-card').forEach(card => {\n const templateIdInput = card.querySelector('.prompt-template-id-input');\n const promptParametersInput = card.querySelector('.prompt-template-parameters-input');\n const templateId = templateIdInput ? templateIdInput.value : card.getAttribute('data-template-id');\n\n if (!templateId) {\n return;\n }\n\n promptTemplates.push({\n templateId: templateId,\n promptParameters: promptParametersInput ? (promptParametersInput.value || '').trim() : ''\n });\n });\n\n return promptTemplates;\n },\n receiveNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n // Replace existing notification with same type, or add new one.\n var idx = this.notifications.findIndex(n => n.type === notification.type);\n if (idx >= 0) {\n this.notifications.splice(idx, 1, notification);\n } else {\n this.notifications.push(notification);\n }\n this.scheduleNotificationDismiss(notification);\n this.scrollToBottom();\n },\n updateNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var idx = this.notifications.findIndex(n => n.type === notification.type);\n if (idx >= 0) {\n this.notifications.splice(idx, 1, notification);\n this.scheduleNotificationDismiss(notification);\n this.scrollToBottom();\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 itemId = this.getItemId();\n this.connection.invoke('HandleNotificationAction', itemId, notificationType, actionName)\n .catch(err => console.error('Failed to handle notification action:', err));\n },\n setItemId(itemId) {\n this.inputElement.setAttribute('data-interaction-id', itemId || '');\n this.inputElement.setAttribute('data-item-id', itemId || '');\n },\n resetInteraction() {\n this.setItemId('');\n this.isInteractionStarted = false;\n this.messages = [];\n this.showPlaceholder();\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 const itemId = this.getItemId();\n if (itemId) {\n this.loadInteraction(itemId);\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('keyup', event => {\n if (this.stream != null) {\n return;\n }\n\n if (event.key === \"Enter\" && !event.shiftKey) {\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.inputElement.addEventListener('paste', (e) => {\n // Use setTimeout to allow the paste to complete before checking the value\n setTimeout(() => {\n this.prompt = this.inputElement.value;\n if (this.inputElement.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n }, 0);\n });\n\n this.buttonElement.addEventListener('click', () => {\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 chatInteractionItems = document.getElementsByClassName('chat-interaction-history-item');\n\n for (var i = 0; i < chatInteractionItems.length; i++) {\n chatInteractionItems[i].addEventListener('click', (e) => {\n e.preventDefault();\n\n var itemId = e.target.getAttribute('data-interaction-id');\n\n if (!itemId) {\n console.error('An element with the class chat-interaction-history-item with no data-interaction-id set.');\n return;\n }\n\n this.loadInteraction(itemId);\n });\n }\n\n const initialMessages = Array.isArray(config.messages) ? config.messages : [];\n\n for (let i = 0; i < initialMessages.length; i++) {\n this.addMessage(initialMessages[i]);\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 = ' ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '';\n }, 2000);\n }\n });\n }\n\n document.addEventListener('input', event => {\n if (event.target.matches('.setting-input[data-setting]')) {\n this.validateSettingInput(event.target);\n this.queueSettingsSave();\n }\n });\n\n document.addEventListener('change', event => {\n if (event.target.matches('.setting-input[data-setting], .capability-checkbox[data-save-group], .capability-checkbox[data-group], .group-toggle, .ci-agent-global-toggle')) {\n if (event.target.matches('.setting-input[data-setting]')) {\n this.validateSettingInput(event.target);\n }\n\n this.queueSettingsSave();\n return;\n }\n\n if (event.target.closest('.prompt-template-parameters-input, .prompt-template-id-input')) {\n this.queueSettingsSave();\n }\n });\n\n document.addEventListener('click', event => {\n if (!event.target.closest('.prompt-template-add-btn, .remove-prompt-template-btn')) {\n return;\n }\n\n setTimeout(() => {\n this.queueSettingsSave();\n }, 0);\n });\n\n // Add event listener for clear history button\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.addEventListener('click', () => {\n const itemId = clearHistoryBtn.getAttribute('data-interaction-id');\n if (itemId) {\n this.clearHistory(itemId);\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 // Initialize realtime (speech-to-speech) mode via the shared CoreAIRealtime module. The\n // module owns the mic capture, playback, echo guard, push-to-talk and audio settings; the\n // callbacks below plug it into this app's connection and conversation-transcript display.\n if (window.CoreAIRealtime && config.realtimeButtonElementSelector) {\n // Kept so the voice settings popover can be found next to this client's own button.\n this.realtimeButton = document.querySelector(config.realtimeButtonElementSelector);\n this.realtimeController = window.CoreAIRealtime.attach({\n connection: this.connection,\n ensureConnected: () => Promise.resolve(this.connection),\n sendStart: (subject, voice, language, silenceMs, vadThreshold, allowInterruption) => {\n this.connection.send('StartRealtimeConversation', this.getItemId(), subject, voice, language, silenceMs, vadThreshold, allowInterruption);\n },\n // Prefer WebRTC (server-relay) when the server advertises it; the shared module falls back\n // to the WebSocket sendStart above if the peer cannot connect.\n webRtcEnabled: config.realtimeWebRtcEnabled === true,\n sendStartWebRtc: (offerSdp, voice, language, silenceMs, vadThreshold, allowInterruption) => {\n this.connection.send('StartRealtimeWebRtc', this.getItemId(), offerSdp, voice, language, silenceMs, vadThreshold, allowInterruption);\n },\n webRtcIceServers: Array.isArray(config.realtimeWebRtcIceServers) ? config.realtimeWebRtcIceServers : undefined,\n voiceName: config.realtimeVoiceName || '',\n getVoiceName: () => {\n var el = config.realtimeVoiceSelectElementSelector ? document.querySelector(config.realtimeVoiceSelectElementSelector) : null;\n return el ? el.value : '';\n },\n capableDeployments: config.realtimeCapableDeployments || [],\n realtimeEnabled: config.realtimeEnabled === true,\n // input and sendButton are deliberately not handed over. The module hides every\n // control it is given when realtime takes over, and typing has to stay available\n // during a voice conversation -- that is the whole feature.\n //\n // deploymentSelect is not handed over either: it would read the raw select value,\n // and an empty conversation deployment means \"use the site default\", which still\n // resolves. The host resolves it and calls applyMode itself (see below).\n selectors: {\n realtimeButton: config.realtimeButtonElementSelector,\n micButton: config.micButtonElementSelector,\n conversationButton: config.conversationButtonElementSelector\n },\n // The module owns whether a session is live, so the message box follows its flag\n // rather than this app's copy of it. Losing one of these events used to leave the\n // box hidden under a button that had already gone back to \"Start speaking\".\n onSessionStateChanged: (active) => {\n this.setVoiceSessionLive(active);\n },\n onActivate: () => {\n this.isConversationMode = true;\n this._conversationPartialMessage = null;\n this._conversationAssistantMessage = null;\n },\n onDeactivate: () => {\n this.isConversationMode = false;\n if (this._conversationAssistantMessage) {\n var m = this.messages[this._conversationAssistantMessage.index];\n if (m) { m.isStreaming = false; }\n this._conversationAssistantMessage = null;\n }\n },\n onEnterRealtimeMode: () => {\n if (this.isRecording) { this.stopRecording(); }\n if (this.isConversationMode && (!this.realtimeController || !this.realtimeController.isActive())) { this.stopConversationMode(); }\n },\n // The utterance has been captured but not transcribed yet. Showing a placeholder now\n // puts the prompt above the reply it produces: transcription lags the spoken answer, so\n // a bubble added only when the text arrives lands underneath its own reply.\n onUserTurnPending: (turnId) => {\n if (!turnId) { return; }\n var placeholder = { role: 'user', content: '', rawContent: '', references: {}, isPartial: true };\n updateMessagePresentation(placeholder, placeholder.references);\n this._realtimePendingTurns = this._realtimePendingTurns || {};\n this._realtimePendingTurns[turnId] = placeholder;\n this.messages.push(placeholder);\n this.scrollToBottom();\n },\n onUserTurnDropped: (turnId) => {\n if (!turnId || !this._realtimePendingTurns) { return; }\n var dropped = this._realtimePendingTurns[turnId];\n if (!dropped) { return; }\n delete this._realtimePendingTurns[turnId];\n var at = this.messages.indexOf(dropped);\n if (at >= 0) { this.messages.splice(at, 1); }\n }\n });\n\n this.setupRealtimeVoicePicker(config);\n\n // The module reveals the gear as soon as the surface enters realtime mode, but it belongs\n // to a live session. The watcher that would hide it only runs on a change, so the idle\n // state has to be stated once here.\n this.setVoiceSessionLive(false);\n }\n },\n // Populates the per-interaction realtime voice picker from the selected realtime deployment's\n // voices (via the realtime-voices endpoint), and shows it only for realtime-capable deployments.\n setupRealtimeVoicePicker(config) {\n if (!config.realtimeVoiceSelectElementSelector || !config.realtimeVoicesUrl) {\n return;\n }\n\n var voiceSelect = document.querySelector(config.realtimeVoiceSelectElementSelector);\n if (!voiceSelect) {\n return;\n }\n\n var voiceGroup = config.realtimeVoiceGroupElementSelector ? document.querySelector(config.realtimeVoiceGroupElementSelector) : null;\n var conversationSelect = config.conversationDeploymentSelectElementSelector\n ? document.querySelector(config.conversationDeploymentSelectElementSelector)\n : null;\n var capable = (config.realtimeCapableDeployments || []).map(function (n) { return (n || '').toLowerCase(); });\n var savedVoiceId = config.realtimeVoiceName || '';\n var self = this;\n\n function isRealtimeDeployment(name) {\n return name && capable.indexOf(name.toLowerCase()) !== -1;\n }\n\n // Mirrors the realtime slot's chain on the server: the interaction's own choice, then the\n // site default, then the first realtime-capable deployment. Only conversation mode reaches\n // it -- an interaction that is not in conversation mode never speaks.\n function resolveConversationDeployment() {\n if (!self.conversationModeEnabled) {\n return '';\n }\n\n var name = (conversationSelect && conversationSelect.value)\n || config.defaultRealtimeDeploymentName\n || (capable.length ? capable[0] : '');\n\n return isRealtimeDeployment(name) ? name : '';\n }\n\n async function loadVoices() {\n var deploymentName = resolveConversationDeployment();\n var realtime = !!deploymentName;\n if (voiceGroup) {\n voiceGroup.classList.toggle('d-none', !realtime);\n }\n\n // Changing the conversation deployment switches the voice toggle on or off without a\n // reload.\n if (self.realtimeController) {\n self.realtimeController.applyMode(realtime);\n }\n\n if (!realtime) {\n return;\n }\n\n voiceSelect.innerHTML = '';\n\n try {\n const response = await fetch(config.realtimeVoicesUrl + '?deploymentName=' + encodeURIComponent(deploymentName), { credentials: 'same-origin' });\n const contentType = (response.headers.get('content-type') || '').toLowerCase();\n\n // A sign-in redirect answers with HTML and response.ok, so this has to be checked\n // rather than parsed: the default voice is a fine outcome, a parser error is not.\n if (!response.ok || contentType.indexOf('json') < 0) {\n return;\n }\n\n const result = await response.json();\n if (!result || !Array.isArray(result.voices)) {\n return;\n }\n\n const grouped = new Map();\n for (const voice of result.voices) {\n const groupName = voice.gender || 'Voices';\n if (!grouped.has(groupName)) {\n grouped.set(groupName, []);\n }\n grouped.get(groupName).push(voice);\n }\n\n Array.from(grouped.keys()).sort((a, b) => a.localeCompare(b)).forEach(function (groupName) {\n const optgroup = document.createElement('optgroup');\n optgroup.label = groupName;\n grouped.get(groupName).forEach(function (voice) {\n const option = document.createElement('option');\n option.value = voice.id;\n option.textContent = voice.name;\n option.selected = voice.id === savedVoiceId;\n optgroup.appendChild(option);\n });\n voiceSelect.appendChild(optgroup);\n });\n } catch (err) {\n /* ignore voice load failures */\n }\n }\n\n if (conversationSelect) {\n conversationSelect.addEventListener('change', loadVoices);\n }\n loadVoices();\n },\n loadInteraction(itemId) {\n this.connection.invoke(\"LoadInteraction\", itemId).catch(err => console.error(err));\n },\n reloadCurrentInteraction() {\n const itemId = this.getItemId();\n if (itemId) {\n this.loadInteraction(itemId);\n }\n },\n clearHistory(itemId) {\n const self = this;\n const clearHistoryConfirmed = () => {\n // Force-stop any live realtime voice session before clearing history.\n if (self.realtimeController && self.realtimeController.isActive()) {\n self.realtimeController.stop();\n }\n\n // Cancel any active stream before clearing history.\n if (self.stream) {\n self.stream.dispose();\n self.stream = null;\n self.hideTypingIndicator();\n self.streamingFinished();\n }\n\n self.connection.invoke(\"ClearHistory\", itemId)\n .catch(err => console.error('Error clearing history:', err));\n };\n\n if (typeof confirmDialog === 'function') {\n confirmDialog({\n title: config.clearHistoryTitle,\n message: config.clearHistoryMessage,\n okText: config.clearHistoryOkText,\n cancelText: config.clearHistoryCancelText,\n callback: function (confirmed) {\n if (confirmed) {\n clearHistoryConfirmed();\n }\n }\n });\n\n return;\n }\n\n if (window.confirm(config.clearHistoryMessage || 'Clear all messages?')) {\n clearHistoryConfirmed();\n }\n },\n debouncedSaveSettings() {\n // Clear any existing timeout to reset the debounce timer\n this.clearPendingSettingsSave();\n\n // Don't save while streaming — it will be saved when streaming completes.\n if (this.stream) {\n return;\n }\n\n // Set a new timeout to save after 850ms of no changes\n this.saveSettingsTimeout = setTimeout(() => {\n if (this.settingsDirty) {\n this.saveSettings();\n this.settingsDirty = false;\n }\n this.saveSettingsTimeout = null;\n }, 850);\n },\n getSelectedToolNames() {\n return this.getSelectedGroupValues(\n 'toolNames',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Tools[\"]:checked'\n );\n },\n getSelectedMcpConnectionIds() {\n return this.getSelectedGroupValues(\n 'mcpConnectionIds',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Connections[\"]:checked'\n );\n },\n getSelectedA2AConnectionIds() {\n return this.getSelectedGroupValues('a2aConnectionIds');\n },\n getSelectedAgentNames() {\n return this.getSelectedGroupValues(\n 'agentNames',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Agents[\"]:checked'\n );\n },\n saveSettings() {\n const itemId = this.getItemId();\n if (!itemId) {\n return Promise.resolve();\n }\n\n if (!this.validateSettings()) {\n this.showSaveIndicator('Fix errors', 'text-danger');\n return Promise.resolve();\n }\n\n const settings = {};\n\n // Collect all form inputs with the \"ChatInteraction.\" prefix generically.\n // This avoids coupling the JS to specific field names — new fields added by\n // any module are automatically included.\n const inputs = this.getSettingInputs();\n\n inputs.forEach(input => {\n const key = input.dataset.setting\n || ((input.name || '').replace('ChatInteraction.', '').replace(/^[A-Z]/, match => match.toLowerCase()));\n\n if (!key) {\n return;\n }\n\n if (input.type === 'checkbox') {\n settings[key] = input.checked;\n } else if (input.type === 'number') {\n settings[key] = input.value ? parseFloat(input.value) : null;\n } else {\n settings[key] = input.value || null;\n }\n });\n\n // Add tool, MCP connection, and agent collections (special handling).\n settings.toolNames = this.getSelectedToolNames();\n settings.mcpConnectionIds = this.getSelectedMcpConnectionIds();\n settings.a2aConnectionIds = this.getSelectedA2AConnectionIds();\n settings.agentNames = this.getSelectedAgentNames();\n\n const promptTemplates = this.getPromptTemplateSelections();\n if (promptTemplates.length > 0) {\n settings.promptTemplates = promptTemplates;\n settings.promptTemplateIds = promptTemplates.map(template => template.templateId);\n }\n\n return this.connection.invoke(\"SaveSettings\", itemId, settings)\n .catch(err => {\n console.error('Error saving settings:', err);\n this.showSaveIndicator('Save failed', 'text-danger');\n });\n },\n flushPendingSave() {\n if (this.saveSettingsTimeout) {\n clearTimeout(this.saveSettingsTimeout);\n this.saveSettingsTimeout = null;\n }\n\n if (this.settingsDirty) {\n this.settingsDirty = false;\n return this.saveSettings();\n }\n\n return Promise.resolve();\n },\n initializeInteraction(itemId, force) {\n if (this.isInteractionStarted && !force) {\n return;\n }\n this.fireEvent(new CustomEvent(\"initializingChatInteraction\", { detail: { itemId: itemId } }));\n this.setItemId(itemId);\n this.isInteractionStarted = true;\n },\n clearCopiedMessageState() {\n if (this.copyResetTimeoutId) {\n window.clearTimeout(this.copyResetTimeoutId);\n this.copyResetTimeoutId = null;\n }\n\n if (this.activeCopyButton) {\n this.setCopyButtonState(this.activeCopyButton, false);\n this.activeCopyButton = null;\n }\n\n this.copiedMessageIndex = -1;\n },\n copyResponse(message, index, event) {\n const text = message && typeof message === 'object'\n ? message.copyContent ?? message.content ?? ''\n : message ?? '';\n const button = event?.currentTarget || event?.target?.closest?.('[data-copy-message-index]') || null;\n\n navigator.clipboard.writeText(text)\n .then(() => {\n this.clearCopiedMessageState();\n this.copiedMessageIndex = typeof index === 'number' ? index : -1;\n this.activeCopyButton = button;\n\n if (button) {\n this.setCopyButtonState(button, true);\n } else {\n this.$nextTick(() => this.updateCopyButtons());\n }\n\n this.copyResetTimeoutId = window.setTimeout(() => {\n this.clearCopiedMessageState();\n this.$nextTick(() => this.updateCopyButtons());\n }, Number(config.copyResetDelayMs) || 2000);\n })\n .catch(err => console.error('Failed to copy response:', err));\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 itemId = this.getItemId();\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\", itemId, 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 = '';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '';\n }\n }\n },\n watch: {\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 // The dictation microphone is hidden while a voice conversation runs: the conversation\n // already owns the microphone, and a second one would mean something different.\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n // The message box and the send button give way to the voice settings while the conversation\n // runs, and come back when it ends. Both kinds of turn still land in the same thread; what\n // they cannot do is overlap.\n //\n // Only the cascade is driven from here. Realtime follows the module's own session flag\n // (onSessionStateChanged), so the two never disagree about whether a session is live.\n if (!this.realtimeEnabled) {\n this.setVoiceSessionLive(active);\n }\n },\n copiedMessageIndex() {\n this.$nextTick(() => this.updateCopyButtons());\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n this.initializeApp();\n\n this.$nextTick(() => {\n this.updateCopyButtons();\n refreshFontAwesomeIcons(this.$el);\n this.fontAwesomeObserver = observeFontAwesomeIcons(this.$el);\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 if (this.fontAwesomeObserver) {\n this.fontAwesomeObserver.disconnect();\n this.fontAwesomeObserver = null;\n }\n\n this.clearCopiedMessageState();\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 template: config.messageTemplate\n }).mount(config.appElementSelector);\n\n return app;\n };\n\n const autoInitializeSelector = '[data-chat-interaction-config]';\n\n function parseJsonAttribute(element, attributeName, description) {\n const rawValue = element.getAttribute(attributeName);\n if (!rawValue) {\n return null;\n }\n\n try {\n return JSON.parse(rawValue);\n } catch (error) {\n console.error('Failed to parse ' + description + ' JSON.', error);\n return null;\n }\n }\n\n function initializeFromElement(element) {\n if (!element || element.dataset.chatInteractionInitialized === 'true') {\n return element ? element.__chatInteractionApp || null : null;\n }\n\n const config = parseJsonAttribute(element, 'data-chat-interaction-config', 'chat interaction config');\n if (!config) {\n return null;\n }\n\n const app = initialize(config);\n if (!app) {\n return null;\n }\n\n element.dataset.chatInteractionInitialized = 'true';\n element.__chatInteractionApp = app;\n\n return app;\n }\n\n function scanForAutoInitialization(root) {\n if (!root || typeof root.querySelectorAll !== 'function') {\n return;\n }\n\n if (typeof root.matches === 'function' && root.matches(autoInitializeSelector)) {\n initializeFromElement(root);\n }\n\n root.querySelectorAll(autoInitializeSelector).forEach(initializeFromElement);\n }\n\n function startAutoInitialization() {\n scanForAutoInitialization(document);\n\n if (typeof MutationObserver === 'undefined') {\n return;\n }\n\n const observer = new MutationObserver(mutations => {\n mutations.forEach(mutation => {\n mutation.addedNodes.forEach(node => {\n if (node && node.nodeType === 1) {\n scanForAutoInitialization(node);\n }\n });\n });\n });\n\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n });\n }\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', startAutoInitialization, { once: true });\n } else {\n startAutoInitialization();\n }\n\n return {\n initialize: initialize,\n initializeFromElement: initializeFromElement,\n };\n}();\n\nwindow.chatInteractionDocumentManager = function () {\n const managerStateKey = '__chatInteractionDocumentManagerState';\n\n function normalizeDocumentInfo(document) {\n if (!document || typeof document !== 'object') {\n return null;\n }\n\n return {\n documentId: document.documentId || document.DocumentId || '',\n fileName: document.fileName || document.FileName || '',\n fileSize: document.fileSize || document.FileSize || 0\n };\n }\n\n function formatFileSize(bytes) {\n if (!bytes || bytes < 1024) {\n return (bytes || 0) + ' B';\n }\n\n if (bytes < 1024 * 1024) {\n return (bytes / 1024).toFixed(1) + ' KB';\n }\n\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n }\n\n function getDocumentKey(fileName, fileSize) {\n return ((fileName || '').trim().toLowerCase()) + '::' + (fileSize || 0);\n }\n\n function isDuplicateFile(file, knownKeys) {\n return knownKeys.has(getDocumentKey(file.name, file.size));\n }\n\n function getDocumentsFromDom(container) {\n if (!container) {\n return [];\n }\n\n return Array.from(container.querySelectorAll('[data-chat-document-id]'))\n .map(element => normalizeDocumentInfo({\n documentId: element.dataset.chatDocumentId,\n fileName: element.dataset.chatDocumentName,\n fileSize: Number(element.dataset.chatDocumentSize || 0)\n }))\n .filter(document => document && document.documentId);\n }\n\n function initialize(config) {\n if (!config || !config.itemId) {\n return;\n }\n\n const fileInput = document.getElementById('chat-doc-upload');\n const documentsList = document.getElementById('chat-documents-list');\n const status = document.getElementById('chat-doc-upload-status');\n const progressContainer = document.getElementById('chat-doc-upload-progress');\n const progressBar = document.getElementById('chat-doc-upload-progress-bar');\n const uploadQueue = document.getElementById('chat-doc-upload-queue');\n\n if (!fileInput || !documentsList || !status || !progressContainer || !progressBar || !uploadQueue) {\n return;\n }\n\n const previousState = fileInput[managerStateKey];\n if (previousState && typeof previousState.dispose === 'function') {\n previousState.dispose();\n }\n\n let interactionDocuments = (Array.isArray(config.existingDocuments) ? config.existingDocuments : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n\n if (interactionDocuments.length === 0) {\n interactionDocuments = getDocumentsFromDom(documentsList);\n }\n\n let uploadItems = [];\n let isUploadingDocuments = false;\n\n function createTextElement(tagName, className, text) {\n const element = document.createElement(tagName);\n if (className) {\n element.className = className;\n }\n\n element.textContent = text;\n return element;\n }\n\n function renderDocuments() {\n documentsList.innerHTML = '';\n\n if (interactionDocuments.length === 0) {\n documentsList.appendChild(createTextElement('div', 'text-muted small', 'No documents uploaded yet.'));\n return;\n }\n\n interactionDocuments.forEach(documentInfo => {\n const row = window.document.createElement('div');\n row.className = 'd-flex align-items-center gap-2 border rounded px-2 py-2 bg-white chat-document-row';\n row.dataset.chatDocumentId = documentInfo.documentId;\n row.dataset.chatDocumentName = documentInfo.fileName;\n row.dataset.chatDocumentSize = documentInfo.fileSize;\n\n const actions = window.document.createElement('div');\n actions.className = 'd-flex gap-1';\n\n const downloadBaseUrl = config.downloadDocumentBaseUrl || '/ai/documents/';\n const downloadLink = createTextElement('a', 'btn btn-sm btn-outline-secondary', '');\n downloadLink.title = 'Download';\n downloadLink.href = downloadBaseUrl + encodeURIComponent(documentInfo.documentId) + '/download';\n const downloadIcon = window.document.createElement('i');\n downloadIcon.className = 'fa-solid fa-download';\n downloadLink.appendChild(downloadIcon);\n\n const removeButton = createTextElement('button', 'btn btn-sm btn-outline-danger remove-chat-document-btn', '');\n removeButton.type = 'button';\n removeButton.title = 'Remove';\n removeButton.dataset.documentId = documentInfo.documentId;\n const removeIcon = window.document.createElement('i');\n removeIcon.className = 'fa-solid fa-trash';\n removeButton.appendChild(removeIcon);\n removeButton.addEventListener('click', () => removeDocument(documentInfo.documentId));\n\n actions.appendChild(downloadLink);\n actions.appendChild(removeButton);\n\n const details = window.document.createElement('div');\n details.className = 'min-w-0';\n\n const name = createTextElement('div', 'fw-semibold small text-truncate', documentInfo.fileName || 'Document');\n const icon = window.document.createElement('i');\n icon.className = 'fa-solid fa-file-lines me-1';\n name.prepend(icon);\n\n const size = createTextElement('div', 'text-muted small', formatFileSize(documentInfo.fileSize));\n\n details.appendChild(name);\n details.appendChild(size);\n\n row.appendChild(actions);\n row.appendChild(details);\n documentsList.appendChild(row);\n });\n }\n\n function showUploadStatus(message, cssClass) {\n if (!message) {\n status.textContent = '';\n status.className = 'small mt-2 d-none';\n return;\n }\n\n status.textContent = message;\n status.className = 'small mt-2 ' + (cssClass || 'text-muted');\n }\n\n function showUploadProgress(progress, message, cssClass) {\n if (progress === null || progress === undefined) {\n progressContainer.className = 'progress mt-2 d-none';\n progressContainer.setAttribute('aria-valuenow', '0');\n progressBar.className = 'progress-bar progress-bar-striped progress-bar-animated';\n progressBar.style.width = '0%';\n progressBar.textContent = '0%';\n return;\n }\n\n const roundedProgress = Math.max(0, Math.min(100, Math.round(progress)));\n progressContainer.className = 'progress mt-2';\n progressContainer.setAttribute('aria-valuenow', roundedProgress.toString());\n progressBar.className = 'progress-bar ' + (cssClass || 'progress-bar-striped progress-bar-animated');\n progressBar.style.width = roundedProgress + '%';\n progressBar.textContent = message || (roundedProgress + '%');\n }\n\n function getUploadStatePresentation(state) {\n switch (state) {\n case 'uploaded':\n return { label: 'Uploaded', badgeClass: 'text-bg-success', progressClass: 'bg-success' };\n case 'failed':\n return { label: 'Failed', badgeClass: 'text-bg-danger', progressClass: 'bg-danger' };\n case 'uploading':\n return { label: 'Uploading', badgeClass: 'text-bg-warning', progressClass: 'bg-warning progress-bar-striped progress-bar-animated' };\n default:\n return { label: 'Queued', badgeClass: 'text-bg-secondary', progressClass: 'bg-secondary progress-bar-striped progress-bar-animated' };\n }\n }\n\n function formatUploadMessage(item) {\n if (item.status === 'failed' && item.error) {\n return item.error;\n }\n\n if (item.status === 'uploaded') {\n return 'Upload completed successfully.';\n }\n\n if (item.status === 'uploading') {\n return item.progress + '% uploaded';\n }\n\n return 'Waiting to upload...';\n }\n\n function renderUploadQueue() {\n uploadQueue.innerHTML = '';\n\n uploadItems.forEach(item => {\n const presentation = getUploadStatePresentation(item.status);\n const card = document.createElement('div');\n card.className = 'border rounded px-2 py-2 bg-white';\n\n const header = document.createElement('div');\n header.className = 'd-flex justify-content-between align-items-start gap-2';\n\n const fileDetails = document.createElement('div');\n fileDetails.className = 'flex-grow-1 min-w-0';\n fileDetails.appendChild(createTextElement('div', 'fw-semibold small', item.fileName));\n fileDetails.appendChild(createTextElement('div', 'text-muted small', formatFileSize(item.fileSize)));\n\n const badge = createTextElement('span', 'badge ' + presentation.badgeClass, presentation.label);\n\n header.appendChild(fileDetails);\n header.appendChild(badge);\n\n const progress = document.createElement('div');\n progress.className = 'progress mt-2';\n progress.setAttribute('role', 'progressbar');\n progress.setAttribute('aria-valuemin', '0');\n progress.setAttribute('aria-valuemax', '100');\n progress.setAttribute('aria-valuenow', item.progress.toString());\n\n const progressState = document.createElement('div');\n progressState.className = 'progress-bar ' + presentation.progressClass;\n progressState.style.width = item.progress + '%';\n progressState.textContent = item.progress + '%';\n progress.appendChild(progressState);\n\n const message = createTextElement('div', item.status === 'failed' ? 'small text-danger mt-2' : 'small text-muted mt-2', formatUploadMessage(item));\n\n card.appendChild(header);\n card.appendChild(progress);\n card.appendChild(message);\n uploadQueue.appendChild(card);\n });\n }\n\n function createUploadItem(file, index) {\n return {\n id: file.name + '::' + file.size + '::' + file.lastModified + '::' + index + '::' + Date.now(),\n fileName: file.name,\n fileSize: file.size,\n status: 'queued',\n progress: 0,\n error: null\n };\n }\n\n function updateUploadItem(itemId, updates) {\n uploadItems = uploadItems.map(item => item.id === itemId ? Object.assign({}, item, updates) : item);\n renderUploadQueue();\n }\n\n function removeUploadItems(predicate) {\n uploadItems = uploadItems.filter(item => !predicate(item));\n renderUploadQueue();\n }\n\n function uploadSingleDocument(file, itemIdToUpdate, fileIndex, totalFiles) {\n return new Promise((resolve, reject) => {\n const formData = new FormData();\n formData.append('chatInteractionId', config.itemId);\n formData.append('files', file);\n\n const xhr = new XMLHttpRequest();\n xhr.open('POST', config.uploadDocumentUrl, true);\n\n xhr.upload.addEventListener('progress', event => {\n if (!event.lengthComputable) {\n return;\n }\n\n const fileProgress = Math.round((event.loaded / event.total) * 100);\n updateUploadItem(itemIdToUpdate, {\n status: 'uploading',\n progress: fileProgress\n });\n\n const overallProgress = ((fileIndex + (event.loaded / event.total)) / totalFiles) * 100;\n showUploadProgress(overallProgress, 'Uploading ' + (fileIndex + 1) + ' of ' + totalFiles, 'progress-bar-striped progress-bar-animated');\n });\n\n xhr.addEventListener('load', () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n resolve(JSON.parse(xhr.responseText));\n } catch (error) {\n reject(new Error('Upload failed: invalid server response.'));\n }\n\n return;\n }\n\n reject(new Error((xhr.responseText || 'Upload failed.').trim()));\n });\n\n xhr.addEventListener('error', () => {\n reject(new Error('Upload failed. Please check your connection and try again.'));\n });\n\n xhr.send(formData);\n });\n }\n\n async function uploadDocuments(files) {\n if (!config.uploadDocumentUrl || !files || files.length === 0) {\n return;\n }\n\n if (isUploadingDocuments) {\n showUploadStatus('A document upload is already in progress.', 'text-warning');\n return;\n }\n\n isUploadingDocuments = true;\n\n const filesToUpload = [];\n const duplicateItems = [];\n const knownDocumentKeys = new Set(interactionDocuments.map(document => getDocumentKey(document.fileName, document.fileSize)));\n\n Array.from(files).forEach(file => {\n if (isDuplicateFile(file, knownDocumentKeys)) {\n duplicateItems.push(file);\n return;\n }\n\n knownDocumentKeys.add(getDocumentKey(file.name, file.size));\n filesToUpload.push(file);\n });\n\n if (duplicateItems.length > 0) {\n uploadItems = uploadItems.concat(duplicateItems.map((file, index) => Object.assign(createUploadItem(file, index), {\n status: 'failed',\n progress: 100,\n error: 'This document is already attached.'\n })));\n renderUploadQueue();\n }\n\n if (filesToUpload.length === 0) {\n isUploadingDocuments = false;\n showUploadStatus(duplicateItems.map(file => file.name + ': This document is already attached.').join(' | '), 'text-warning');\n showUploadProgress(null);\n return;\n }\n\n const pendingItems = filesToUpload.map(createUploadItem);\n uploadItems = uploadItems.concat(pendingItems);\n renderUploadQueue();\n showUploadProgress(0, 'Preparing upload...', 'progress-bar-striped progress-bar-animated');\n fileInput.disabled = true;\n\n try {\n let uploadedCount = 0;\n const failedUploads = duplicateItems.map(file => file.name + ': This document is already attached.');\n\n for (let i = 0; i < filesToUpload.length; i++) {\n const file = filesToUpload[i];\n const pendingItem = pendingItems[i];\n\n updateUploadItem(pendingItem.id, {\n status: 'uploading',\n progress: 0,\n error: null\n });\n\n showUploadStatus('Uploading ' + (i + 1) + ' of ' + filesToUpload.length + ' document(s)...', 'text-warning');\n\n try {\n const result = await uploadSingleDocument(file, pendingItem.id, i, filesToUpload.length);\n const uploaded = (Array.isArray(result.uploaded) ? result.uploaded : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n const failed = Array.isArray(result.failed) ? result.failed : [];\n\n if (uploaded.length > 0) {\n uploadedCount += uploaded.length;\n interactionDocuments = interactionDocuments.concat(uploaded);\n updateUploadItem(pendingItem.id, {\n status: 'uploaded',\n progress: 100,\n error: null\n });\n } else {\n const missingUploadMessage = failed.length > 0\n ? failed.map(entry => entry.fileName + ': ' + entry.error).join(' | ')\n : 'The server did not confirm that the file was uploaded.';\n if (failed.length === 0) {\n failedUploads.push(missingUploadMessage);\n }\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: 100,\n error: missingUploadMessage\n });\n }\n\n if (failed.length > 0) {\n const failedMessage = failed.map(entry => entry.fileName + ': ' + entry.error).join(' | ');\n failedUploads.push(failedMessage);\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: 100,\n error: failedMessage\n });\n }\n } catch (error) {\n const errorMessage = error && error.message\n ? error.message\n : 'Upload failed. Please try again.';\n console.error('Upload failed:', error);\n failedUploads.push(file.name + ': ' + errorMessage);\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: pendingItem.progress || 0,\n error: errorMessage\n });\n }\n }\n\n renderDocuments();\n\n if (failedUploads.length > 0) {\n removeUploadItems(item => item.status === 'uploaded');\n showUploadStatus(\n (uploadedCount > 0 ? ('Uploaded ' + uploadedCount + ' document(s). ') : '') + failedUploads.join(' | '),\n uploadedCount > 0 ? 'text-warning' : 'text-danger');\n showUploadProgress(null);\n return;\n }\n\n removeUploadItems(() => true);\n showUploadStatus('Uploaded ' + uploadedCount + ' document(s).', 'text-success');\n showUploadProgress(null);\n } catch (error) {\n console.error('Upload failed:', error);\n showUploadStatus('Upload failed. Please try again.', 'text-danger');\n showUploadProgress(null);\n } finally {\n isUploadingDocuments = false;\n fileInput.disabled = false;\n fileInput.value = '';\n }\n }\n\n async function removeDocument(documentId) {\n if (!config.removeDocumentUrl || !documentId || !window.confirm('Remove this document?')) {\n return;\n }\n\n try {\n const response = await fetch(config.removeDocumentUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n itemId: config.itemId,\n documentId: documentId\n })\n });\n\n if (!response.ok) {\n console.error('Failed to remove document:', await response.text());\n showUploadStatus('Failed to remove document.', 'text-danger');\n return;\n }\n\n if ((response.headers.get('content-type') || '').toLowerCase().indexOf('json') < 0) {\n console.error('Remove document: response was not JSON.', { status: response.status, redirected: response.redirected });\n showUploadStatus(response.redirected\n ? 'You may not be signed in, or you do not have permission for this. Please reload and try again.'\n : 'Failed to remove document.', 'text-danger');\n\n return;\n }\n\n const result = await response.json();\n const serverDocuments = (Array.isArray(result.documents) ? result.documents : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n\n interactionDocuments = serverDocuments.length > 0\n ? serverDocuments\n : interactionDocuments.filter(document => document.documentId !== documentId);\n renderDocuments();\n showUploadStatus('Document removed.', 'text-success');\n } catch (error) {\n console.error('Remove failed:', error);\n showUploadStatus('Failed to remove document.', 'text-danger');\n }\n }\n\n const onFileInputChange = event => {\n const selectedFiles = event.target.files ? Array.from(event.target.files) : [];\n uploadDocuments(selectedFiles);\n };\n\n fileInput.addEventListener('change', onFileInputChange);\n fileInput[managerStateKey] = {\n dispose: () => {\n fileInput.removeEventListener('change', onFileInputChange);\n }\n };\n\n renderDocuments();\n renderUploadQueue();\n showUploadStatus(null);\n showUploadProgress(null);\n\n return fileInput[managerStateKey];\n }\n\n function parseJsonAttribute(element, attributeName, description) {\n const rawValue = element.getAttribute(attributeName);\n if (!rawValue) {\n return null;\n }\n\n try {\n return JSON.parse(rawValue);\n } catch (error) {\n console.error('Failed to parse ' + description + ' JSON.', error);\n return null;\n }\n }\n\n function initializeFromElement(element) {\n if (!element || element.dataset.chatInteractionDocumentManagerInitialized === 'true') {\n return element ? element[managerStateKey] || null : null;\n }\n\n const config = parseJsonAttribute(element, 'data-chat-interaction-document-manager-config', 'chat interaction document manager config');\n if (!config) {\n return null;\n }\n\n const state = initialize(config);\n if (!state) {\n return null;\n }\n\n element.dataset.chatInteractionDocumentManagerInitialized = 'true';\n\n return state;\n }\n\n function scanForAutoInitialization(root) {\n if (!root || typeof root.querySelectorAll !== 'function') {\n return;\n }\n\n if (typeof root.matches === 'function' && root.matches('[data-chat-interaction-document-manager-config]')) {\n initializeFromElement(root);\n }\n\n root.querySelectorAll('[data-chat-interaction-document-manager-config]').forEach(initializeFromElement);\n }\n\n function startAutoInitialization() {\n scanForAutoInitialization(document);\n\n if (typeof MutationObserver === 'undefined') {\n return;\n }\n\n const observer = new MutationObserver(mutations => {\n mutations.forEach(mutation => {\n mutation.addedNodes.forEach(node => {\n if (node && node.nodeType === 1) {\n scanForAutoInitialization(node);\n }\n });\n });\n });\n\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n });\n }\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', startAutoInitialization, { once: true });\n } else {\n startAutoInitialization();\n }\n\n return {\n initialize: initialize,\n initializeFromElement: initializeFromElement,\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 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"]} diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/styles/ai-chat.css b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/ai-chat.css index f05ce511..e6318226 100644 --- a/src/Resources/CrestApps.AI.Resources/wwwroot/styles/ai-chat.css +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/ai-chat.css @@ -448,6 +448,8 @@ display: inline-block; vertical-align: top; margin-top: 0.5rem; + /* The positioning context for the download that sits inside it. */ + position: relative; } .generated-image-container img { @@ -455,6 +457,66 @@ max-height: 60vh; height: auto; object-fit: contain; + /* The cap above is what makes a figure a thumbnail: an ingested diagram lands at roughly half size, + legible as a picture but not as a drawing. Pointing at it says it can be opened. */ + cursor: zoom-in; +} + +/* The opened picture is a copy the library appends outside the figure, so it is matched on its own class + rather than through the container -- a rule written as a descendant of the figure never reaches it. The + copy carries the thumbnail's classes, so the frame is taken off here: its padding and white ground are + scaled up with the drawing and would otherwise ring the picture with a broad white border. The cap is + lifted for the same reason, and only here, so the thumbnail sitting in the conversation is left exactly + as it was. */ +img.medium-zoom-image--opened { + max-width: none !important; + max-height: none !important; + padding: 0; + border: 0; + background: none; +} + +/* Over the picture's lower corner rather than below it, so a figure costs only the height of the picture. + It is drawn on a ground of its own because it sits on whatever the drawing happens to put in that + corner. */ +.generated-image-container .ai-download-image { + position: absolute; + right: 0.5rem; + bottom: 0.5rem; + z-index: 2; + opacity: 0; + color: #1f2933; + background-color: rgba(255, 255, 255, 0.92); + border-color: rgba(0, 0, 0, 0.15); + transition: opacity 0.15s ease-in-out; +} + +/* The outline button this is built from inverts on hover: it fills itself with its own colour and turns + its label white. Against the pale ground kept here that leaves a white icon on white -- the button is + still there and still works, but there is nothing to see. Both colours are therefore stated for every + state the button can be in rather than only the resting one. */ +.generated-image-container .ai-download-image:hover, +.generated-image-container .ai-download-image:focus, +.generated-image-container .ai-download-image:focus-visible, +.generated-image-container .ai-download-image:active { + color: #1f2933; + background-color: #ffffff; + border-color: rgba(0, 0, 0, 0.35); +} + +/* Revealed by pointing at the figure. focus-within is what keeps it reachable by keyboard: the button is + invisible until it takes focus, and an invisible control that cannot be brought into view cannot be + used at all. */ +.generated-image-container:hover .ai-download-image, +.generated-image-container:focus-within .ai-download-image { + opacity: 1; +} + +/* A touch screen has no hover to reveal it with, so there it is simply always shown. */ +@media (hover: none) { + .generated-image-container .ai-download-image { + opacity: 1; + } } /* ── Tables ── */ diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/styles/ai-chat.css.map b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/ai-chat.css.map index 3093e1b7..5b2f47f6 100644 --- a/src/Resources/CrestApps.AI.Resources/wwwroot/styles/ai-chat.css.map +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/ai-chat.css.map @@ -1 +1 @@ -{"version":3,"sources":["ai-chat.css"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"ai-chat.css","sourcesContent":[".ai-chat-message-heading {\n font-size: 0.75rem;\n margin-bottom: 0.35rem;\n}\n\n.ai-chat-message-heading .ai-chat-msg-role {\n margin-bottom: 0;\n letter-spacing: 0.03em;\n}\n\n.ai-chat-message-heading-assistant .ai-chat-msg-role {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.ai-chat-message-role-label {\n display: inline-block;\n text-transform: inherit;\n}\n\n.ai-chat-msg-role {\n font-weight: 600;\n margin-bottom: 0.35rem;\n text-transform: uppercase;\n}\n\n.ai-chat-msg-role-user {\n color: var(--bs-primary, #0d6efd);\n}\n\n.ai-chat-msg-role-assistant {\n color: var(--ai-chat-primary, var(--bs-success, #198754));\n}\n\n.ai-chat-messages .ai-chat-message-item {\n position: relative;\n padding: 0.25rem 0;\n}\n\n.ai-chat-messages .ai-chat-message-item + .ai-chat-message-item::before {\n content: '';\n display: block;\n width: 100%;\n margin: 0.5rem auto 0.75rem;\n border-top: 1px solid var(--bs-border-color, #dee2e6);\n}\n\n.ai-chat-messages .ai-chat-message-item p:last-child {\n margin-bottom: 0;\n}\n\n.ai-chat-messages .ai-chat-message-body {\n position: relative;\n padding: 0;\n overflow-wrap: break-word;\n word-break: break-word;\n min-width: 0;\n}\n\n.ai-chat-messages .ai-chat-message-body sup {\n font-size: 0.75em;\n line-height: 0;\n}\n\n/* A markdown table is rendered with the host framework's table classes, which do the bulk of the\n styling. These rules only add what those classes leave out, and are scoped to the message list\n rather than to a wrapper element, because a table is emitted as a direct child of the message. */\n.ai-chat-messages table {\n margin: 0.75rem 0;\n font-size: 0.9em;\n}\n\n.ai-chat-messages table th,\n.ai-chat-messages table td {\n vertical-align: top;\n white-space: nowrap;\n}\n\n/* A right-aligned column in the source markdown is almost always numeric, so the alignment the author\n asked for is honored rather than flattened to the default. */\n.ai-chat-messages table th[align=\"right\"],\n.ai-chat-messages table td[align=\"right\"] {\n text-align: right;\n}\n\n.ai-chat-messages table th[align=\"center\"],\n.ai-chat-messages table td[align=\"center\"] {\n text-align: center;\n}\n\n.ai-chat-messages .ai-chat-citation-list {\n margin: 0.75rem 0 0;\n padding-left: 1.25rem;\n}\n\n.ai-chat-messages .ai-chat-citation-item + .ai-chat-citation-item {\n margin-top: 0.25rem;\n}\n\n.ai-chat-messages .ai-chat-citation-item a {\n word-break: break-word;\n}\n\n.ai-partial-transcript {\n font-style: italic;\n opacity: 0.7;\n}\n\n.ai-chat-messages .message-buttons-container {\n position: absolute;\n right: 0.1rem;\n bottom: 0;\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n width: auto;\n max-width: max-content;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s ease-in-out;\n background: rgba(var(--bs-body-bg-rgb, 255, 255, 255), 0.96);\n padding: 0.2rem 0.35rem;\n border-radius: 999px;\n box-shadow: 0 1px 3px rgba(var(--bs-body-color-rgb, 33, 37, 41), 0.08);\n margin-bottom: 1rem;\n transform: translateY(50%);\n z-index: 1;\n}\n\n.ai-chat-messages .ai-chat-message-item:hover .message-buttons-container,\n.ai-chat-messages .ai-chat-message-item:focus-within .message-buttons-container {\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-messages .message-buttons-container:has(.tts-playing) {\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-messages .message-buttons-container > .button-message-toolbox {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n width: 1.75rem;\n height: 1.75rem;\n margin: 0 !important;\n padding: 0 !important;\n border-radius: 50%;\n color: var(--bs-secondary-color, #6c757d) !important;\n text-decoration: none;\n}\n\n.ai-chat-messages .message-buttons-container .ai-chat-message-assistant-feedback {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.ai-chat-messages .message-buttons-container > .button-message-toolbox:hover,\n.ai-chat-messages .message-buttons-container > .button-message-toolbox:focus {\n color: var(--bs-body-color, #212529) !important;\n text-decoration: none;\n}\n\n.ai-chat-messages .message-buttons-container > .button-message-toolbox.text-success,\n.ai-chat-messages .message-buttons-container > .button-message-toolbox.text-success:hover,\n.ai-chat-messages .message-buttons-container > .button-message-toolbox.text-success:focus {\n color: var(--bs-success, #198754) !important;\n text-decoration: none;\n}\n\n.ai-chat-messages .message-buttons-container > .button-message-toolbox.text-success svg {\n color: inherit !important;\n fill: currentColor;\n}\n\n.ai-chat-messages .message-buttons-container .tts-playing {\n color: var(--ai-chat-primary, var(--bs-success, #198754));\n}\n\n@keyframes spark-burst {\n 0% {\n transform: scale(1);\n opacity: 1;\n }\n 20% {\n transform: scale(1.8);\n opacity: 0.7;\n }\n 40% {\n transform: scale(0.9);\n opacity: 1;\n }\n 60% {\n transform: scale(1.3);\n }\n 100% {\n transform: scale(1);\n }\n}\n\n.spark-effect i,\n.spark-effect svg {\n display: inline-block;\n animation: spark-burst 0.5s ease-out;\n}\n\n.ai-chat-messages .ai-bot-icon {\n color: currentColor;\n display: inline-block;\n animation: none;\n}\n\n@keyframes ai-chat-streaming-effect {\n 0% { opacity: 1; transform: rotate(0deg); }\n 10% { opacity: 0.3; transform: rotate(0deg); }\n 20% { opacity: 1; transform: rotate(0deg); }\n 30% { opacity: 0.3; transform: rotate(0deg); }\n 40% { opacity: 1; transform: rotate(0deg); }\n 50% { opacity: 0.3; transform: rotate(0deg); }\n 60% { opacity: 1; transform: rotate(0deg); }\n 80% { opacity: 1; transform: rotate(360deg); }\n 100% { opacity: 1; transform: rotate(360deg); }\n}\n\n.ai-chat-messages .ai-streaming-icon {\n color: currentColor;\n display: inline-block;\n animation: ai-chat-streaming-effect 4s ease-in-out infinite;\n}\n\n.ai-chat-messages pre {\n position: relative;\n margin: 0;\n}\n\n.ai-chat-messages .ai-code-block {\n border: 1px solid var(--bs-border-color, #dee2e6);\n border-radius: 0.5rem;\n overflow: hidden;\n margin: 0.75rem 0;\n background: var(--bs-body-bg, #fff);\n}\n\n.ai-chat-messages .ai-code-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.5rem 1rem;\n font-size: 0.8rem;\n min-height: 2rem;\n}\n\n.ai-chat-messages .ai-code-lang {\n font-weight: 600;\n color: var(--bs-body-color, #212529);\n text-transform: capitalize;\n}\n\n.ai-chat-messages .ai-code-lang i {\n color: var(--bs-secondary-color, #6c757d);\n margin-right: 0.25rem;\n}\n\n.ai-chat-messages .ai-code-copy-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.3rem;\n padding: 0.2rem;\n font-size: 0.8rem;\n background: transparent;\n border: none;\n cursor: pointer;\n color: var(--bs-secondary-color, #6c757d);\n transition: color 0.15s;\n white-space: nowrap;\n}\n\n.ai-chat-messages .ai-code-copy-btn:hover {\n color: var(--bs-body-color, #212529);\n}\n\n.ai-chat-messages .ai-code-block pre {\n margin: 0;\n background: transparent !important;\n}\n\n.ai-chat-messages .ai-code-block pre code.hljs {\n background: transparent !important;\n padding: 0.75rem 1rem 1rem;\n}\n\n.ai-chat-messages pre code.hljs {\n white-space: pre-wrap;\n word-wrap: break-word;\n overflow-wrap: break-word;\n border-radius: 0.375rem;\n}\n\n.ai-chat-doc-bar {\n border-bottom: 1px solid var(--bs-border-color, #dee2e6);\n}\n\n.ai-chat-drag-over {\n outline: 2px dashed var(--bs-primary, #0d6efd) !important;\n outline-offset: -2px;\n background-color: rgba(var(--bs-primary-rgb, 13, 110, 253), 0.05) !important;\n}\n\n.ai-chat-notification {\n margin: 0.75rem 0 0.25rem;\n padding: 0.625rem 0.875rem;\n border-radius: 0.5rem;\n border: 1px solid var(--bs-border-color, #dee2e6);\n background-color: var(--bs-tertiary-bg, #f8f9fa);\n font-size: 0.875rem;\n line-height: 1.4;\n}\n\n.ai-chat-notification-content {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.ai-chat-notification-icon {\n flex-shrink: 0;\n font-size: 1rem;\n opacity: 0.8;\n}\n\n.ai-chat-notification-text {\n flex: 1;\n}\n\n.ai-chat-notification-dismiss {\n flex-shrink: 0;\n opacity: 0.5;\n transition: opacity 0.15s;\n}\n\n.ai-chat-notification-dismiss:hover {\n opacity: 1;\n}\n\n.ai-chat-notification-actions {\n display: flex;\n gap: 0.375rem;\n margin-top: 0.5rem;\n padding-top: 0.5rem;\n border-top: 1px solid var(--bs-border-color, #dee2e6);\n}\n\n.ai-chat-notification-actions .btn {\n font-size: 0.8125rem;\n padding: 0.1875rem 0.625rem;\n}\n\n.ai-chat-notification-typing {\n border-color: var(--ai-chat-primary, var(--bs-success, #198754));\n background-color: rgba(var(--ai-chat-primary-rgb, var(--bs-success-rgb, 25, 135, 84)), 0.05);\n}\n\n.ai-chat-notification-typing .ai-chat-notification-icon {\n color: var(--ai-chat-primary, var(--bs-success, #198754));\n animation: ai-chat-typing-pulse 1.5s ease-in-out infinite;\n}\n\n@keyframes ai-chat-typing-pulse {\n 0%, 100% { opacity: 0.4; }\n 50% { opacity: 1; }\n}\n\n.ai-chat-notification-transfer {\n border-color: var(--bs-warning, #ffc107);\n background-color: rgba(var(--bs-warning-rgb, 255, 193, 7), 0.06);\n}\n\n.ai-chat-notification-transfer .ai-chat-notification-icon {\n color: var(--bs-warning, #ffc107);\n animation: ai-chat-transfer-pulse 2s ease-in-out infinite;\n}\n\n@keyframes ai-chat-transfer-pulse {\n 0%, 100% { transform: scale(1); opacity: 0.7; }\n 50% { transform: scale(1.1); opacity: 1; }\n}\n\n.ai-chat-notification-ended,\n.ai-chat-notification-session-ended,\n.ai-chat-notification-conversation-ended {\n border-color: var(--bs-secondary, #6c757d);\n background-color: rgba(var(--bs-secondary-rgb, 108, 117, 125), 0.05);\n}\n\n.ai-chat-notification-ended .ai-chat-notification-icon,\n.ai-chat-notification-session-ended .ai-chat-notification-icon,\n.ai-chat-notification-conversation-ended .ai-chat-notification-icon {\n color: var(--bs-secondary, #6c757d);\n}\n\n.ai-chat-notification-info,\n.ai-chat-notification-agent-connected {\n border-color: var(--bs-info, #0dcaf0);\n background-color: rgba(var(--bs-info-rgb, 13, 202, 240), 0.05);\n}\n\n.ai-chat-notification-info .ai-chat-notification-icon,\n.ai-chat-notification-agent-connected .ai-chat-notification-icon {\n color: var(--bs-info, #0dcaf0);\n}\n\n.ai-chat-notification-warning,\n.ai-chat-notification-agent-reconnecting {\n border-color: var(--bs-warning, #ffc107);\n background-color: rgba(var(--bs-warning-rgb, 255, 193, 7), 0.06);\n}\n\n.ai-chat-notification-warning .ai-chat-notification-icon,\n.ai-chat-notification-agent-reconnecting .ai-chat-notification-icon {\n color: var(--bs-warning, #ffc107);\n}\n\n.ai-chat-notification-error,\n.ai-chat-notification-connection-lost {\n border-color: var(--bs-danger, #dc3545);\n background-color: rgba(var(--bs-danger-rgb, 220, 53, 69), 0.05);\n}\n\n.ai-chat-notification-error .ai-chat-notification-icon,\n.ai-chat-notification-connection-lost .ai-chat-notification-icon {\n color: var(--bs-danger, #dc3545);\n}\n\n/* ── Embedded and generated images ── */\n/* The renderer writes an inline max-width in pixels, which bounds a picture across but not down: an\n ingested page scan stays inside that width and still runs thousands of pixels tall, pushing the rest\n of the conversation off screen. A pixel width also overflows any panel narrower than it. Both axes are\n capped relative to the container instead, so a picture is bounded whatever its proportions and\n wherever it is shown. !important is needed because the width it overrides is written inline. */\n.generated-image-container {\n /* The wrapper is a span so a figure marker written mid-sentence does not close the paragraph it\n sits in. Inline-block restores the box behaviour the layout below assumes, and a top margin\n keeps a figure off the line of text it follows. */\n display: inline-block;\n vertical-align: top;\n margin-top: 0.5rem;\n}\n\n.generated-image-container img {\n max-width: 100% !important;\n max-height: 60vh;\n height: auto;\n object-fit: contain;\n}\n\n/* ── Tables ── */\n/* Scoped to .ai-chat-message-item rather than the message body, because the surfaces disagree on\n the body: the shared script renders .ai-chat-message-body while the MVC chat-interaction page\n renders a bare .lh-base. The item wrapper is the one element all of them share. */\n/* A markdown table arrives as a bare with no classes, so by default it has no rules, no padding\n and a width that shrinks to its content -- an ingested table renders as run-together text. The width\n trio is the responsive-table idiom rather than a plain width: max-content lets a wide table keep its\n columns legible, min-width fills the message when it is narrow, and max-width with overflow-x means a\n table wider than the panel scrolls itself instead of stretching the conversation sideways. Colours come\n from Bootstrap's variables so the table follows the host's theme, with literal fallbacks for a host that\n does not define them. */\n.ai-chat-message-item table {\n display: block;\n width: max-content;\n min-width: 100%;\n max-width: 100%;\n overflow-x: auto;\n margin-bottom: 1rem;\n border-collapse: collapse;\n font-size: 0.9375rem;\n}\n\n.ai-chat-message-item table th,\n.ai-chat-message-item table td {\n padding: 0.4rem 0.75rem;\n border: 1px solid var(--bs-border-color, #dee2e6);\n text-align: left;\n vertical-align: top;\n}\n\n.ai-chat-message-item table thead th {\n background-color: var(--bs-secondary-bg, #e9ecef);\n font-weight: 600;\n border-bottom: 2px solid var(--bs-border-color, #dee2e6);\n white-space: nowrap;\n}\n\n/* Banding earns its place on an ingested table, which is often twenty-odd rows of similar-looking numbers\n where losing your place costs the reader the row. */\n.ai-chat-message-item table tbody tr:nth-child(even) {\n background-color: var(--bs-tertiary-bg, #f8f9fa);\n}\n"]} +{"version":3,"sources":["ai-chat.css"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"ai-chat.css","sourcesContent":[".ai-chat-message-heading {\n font-size: 0.75rem;\n margin-bottom: 0.35rem;\n}\n\n.ai-chat-message-heading .ai-chat-msg-role {\n margin-bottom: 0;\n letter-spacing: 0.03em;\n}\n\n.ai-chat-message-heading-assistant .ai-chat-msg-role {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.ai-chat-message-role-label {\n display: inline-block;\n text-transform: inherit;\n}\n\n.ai-chat-msg-role {\n font-weight: 600;\n margin-bottom: 0.35rem;\n text-transform: uppercase;\n}\n\n.ai-chat-msg-role-user {\n color: var(--bs-primary, #0d6efd);\n}\n\n.ai-chat-msg-role-assistant {\n color: var(--ai-chat-primary, var(--bs-success, #198754));\n}\n\n.ai-chat-messages .ai-chat-message-item {\n position: relative;\n padding: 0.25rem 0;\n}\n\n.ai-chat-messages .ai-chat-message-item + .ai-chat-message-item::before {\n content: '';\n display: block;\n width: 100%;\n margin: 0.5rem auto 0.75rem;\n border-top: 1px solid var(--bs-border-color, #dee2e6);\n}\n\n.ai-chat-messages .ai-chat-message-item p:last-child {\n margin-bottom: 0;\n}\n\n.ai-chat-messages .ai-chat-message-body {\n position: relative;\n padding: 0;\n overflow-wrap: break-word;\n word-break: break-word;\n min-width: 0;\n}\n\n.ai-chat-messages .ai-chat-message-body sup {\n font-size: 0.75em;\n line-height: 0;\n}\n\n/* A markdown table is rendered with the host framework's table classes, which do the bulk of the\n styling. These rules only add what those classes leave out, and are scoped to the message list\n rather than to a wrapper element, because a table is emitted as a direct child of the message. */\n.ai-chat-messages table {\n margin: 0.75rem 0;\n font-size: 0.9em;\n}\n\n.ai-chat-messages table th,\n.ai-chat-messages table td {\n vertical-align: top;\n white-space: nowrap;\n}\n\n/* A right-aligned column in the source markdown is almost always numeric, so the alignment the author\n asked for is honored rather than flattened to the default. */\n.ai-chat-messages table th[align=\"right\"],\n.ai-chat-messages table td[align=\"right\"] {\n text-align: right;\n}\n\n.ai-chat-messages table th[align=\"center\"],\n.ai-chat-messages table td[align=\"center\"] {\n text-align: center;\n}\n\n.ai-chat-messages .ai-chat-citation-list {\n margin: 0.75rem 0 0;\n padding-left: 1.25rem;\n}\n\n.ai-chat-messages .ai-chat-citation-item + .ai-chat-citation-item {\n margin-top: 0.25rem;\n}\n\n.ai-chat-messages .ai-chat-citation-item a {\n word-break: break-word;\n}\n\n.ai-partial-transcript {\n font-style: italic;\n opacity: 0.7;\n}\n\n.ai-chat-messages .message-buttons-container {\n position: absolute;\n right: 0.1rem;\n bottom: 0;\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n width: auto;\n max-width: max-content;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s ease-in-out;\n background: rgba(var(--bs-body-bg-rgb, 255, 255, 255), 0.96);\n padding: 0.2rem 0.35rem;\n border-radius: 999px;\n box-shadow: 0 1px 3px rgba(var(--bs-body-color-rgb, 33, 37, 41), 0.08);\n margin-bottom: 1rem;\n transform: translateY(50%);\n z-index: 1;\n}\n\n.ai-chat-messages .ai-chat-message-item:hover .message-buttons-container,\n.ai-chat-messages .ai-chat-message-item:focus-within .message-buttons-container {\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-messages .message-buttons-container:has(.tts-playing) {\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-messages .message-buttons-container > .button-message-toolbox {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n width: 1.75rem;\n height: 1.75rem;\n margin: 0 !important;\n padding: 0 !important;\n border-radius: 50%;\n color: var(--bs-secondary-color, #6c757d) !important;\n text-decoration: none;\n}\n\n.ai-chat-messages .message-buttons-container .ai-chat-message-assistant-feedback {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.ai-chat-messages .message-buttons-container > .button-message-toolbox:hover,\n.ai-chat-messages .message-buttons-container > .button-message-toolbox:focus {\n color: var(--bs-body-color, #212529) !important;\n text-decoration: none;\n}\n\n.ai-chat-messages .message-buttons-container > .button-message-toolbox.text-success,\n.ai-chat-messages .message-buttons-container > .button-message-toolbox.text-success:hover,\n.ai-chat-messages .message-buttons-container > .button-message-toolbox.text-success:focus {\n color: var(--bs-success, #198754) !important;\n text-decoration: none;\n}\n\n.ai-chat-messages .message-buttons-container > .button-message-toolbox.text-success svg {\n color: inherit !important;\n fill: currentColor;\n}\n\n.ai-chat-messages .message-buttons-container .tts-playing {\n color: var(--ai-chat-primary, var(--bs-success, #198754));\n}\n\n@keyframes spark-burst {\n 0% {\n transform: scale(1);\n opacity: 1;\n }\n 20% {\n transform: scale(1.8);\n opacity: 0.7;\n }\n 40% {\n transform: scale(0.9);\n opacity: 1;\n }\n 60% {\n transform: scale(1.3);\n }\n 100% {\n transform: scale(1);\n }\n}\n\n.spark-effect i,\n.spark-effect svg {\n display: inline-block;\n animation: spark-burst 0.5s ease-out;\n}\n\n.ai-chat-messages .ai-bot-icon {\n color: currentColor;\n display: inline-block;\n animation: none;\n}\n\n@keyframes ai-chat-streaming-effect {\n 0% { opacity: 1; transform: rotate(0deg); }\n 10% { opacity: 0.3; transform: rotate(0deg); }\n 20% { opacity: 1; transform: rotate(0deg); }\n 30% { opacity: 0.3; transform: rotate(0deg); }\n 40% { opacity: 1; transform: rotate(0deg); }\n 50% { opacity: 0.3; transform: rotate(0deg); }\n 60% { opacity: 1; transform: rotate(0deg); }\n 80% { opacity: 1; transform: rotate(360deg); }\n 100% { opacity: 1; transform: rotate(360deg); }\n}\n\n.ai-chat-messages .ai-streaming-icon {\n color: currentColor;\n display: inline-block;\n animation: ai-chat-streaming-effect 4s ease-in-out infinite;\n}\n\n.ai-chat-messages pre {\n position: relative;\n margin: 0;\n}\n\n.ai-chat-messages .ai-code-block {\n border: 1px solid var(--bs-border-color, #dee2e6);\n border-radius: 0.5rem;\n overflow: hidden;\n margin: 0.75rem 0;\n background: var(--bs-body-bg, #fff);\n}\n\n.ai-chat-messages .ai-code-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.5rem 1rem;\n font-size: 0.8rem;\n min-height: 2rem;\n}\n\n.ai-chat-messages .ai-code-lang {\n font-weight: 600;\n color: var(--bs-body-color, #212529);\n text-transform: capitalize;\n}\n\n.ai-chat-messages .ai-code-lang i {\n color: var(--bs-secondary-color, #6c757d);\n margin-right: 0.25rem;\n}\n\n.ai-chat-messages .ai-code-copy-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.3rem;\n padding: 0.2rem;\n font-size: 0.8rem;\n background: transparent;\n border: none;\n cursor: pointer;\n color: var(--bs-secondary-color, #6c757d);\n transition: color 0.15s;\n white-space: nowrap;\n}\n\n.ai-chat-messages .ai-code-copy-btn:hover {\n color: var(--bs-body-color, #212529);\n}\n\n.ai-chat-messages .ai-code-block pre {\n margin: 0;\n background: transparent !important;\n}\n\n.ai-chat-messages .ai-code-block pre code.hljs {\n background: transparent !important;\n padding: 0.75rem 1rem 1rem;\n}\n\n.ai-chat-messages pre code.hljs {\n white-space: pre-wrap;\n word-wrap: break-word;\n overflow-wrap: break-word;\n border-radius: 0.375rem;\n}\n\n.ai-chat-doc-bar {\n border-bottom: 1px solid var(--bs-border-color, #dee2e6);\n}\n\n.ai-chat-drag-over {\n outline: 2px dashed var(--bs-primary, #0d6efd) !important;\n outline-offset: -2px;\n background-color: rgba(var(--bs-primary-rgb, 13, 110, 253), 0.05) !important;\n}\n\n.ai-chat-notification {\n margin: 0.75rem 0 0.25rem;\n padding: 0.625rem 0.875rem;\n border-radius: 0.5rem;\n border: 1px solid var(--bs-border-color, #dee2e6);\n background-color: var(--bs-tertiary-bg, #f8f9fa);\n font-size: 0.875rem;\n line-height: 1.4;\n}\n\n.ai-chat-notification-content {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.ai-chat-notification-icon {\n flex-shrink: 0;\n font-size: 1rem;\n opacity: 0.8;\n}\n\n.ai-chat-notification-text {\n flex: 1;\n}\n\n.ai-chat-notification-dismiss {\n flex-shrink: 0;\n opacity: 0.5;\n transition: opacity 0.15s;\n}\n\n.ai-chat-notification-dismiss:hover {\n opacity: 1;\n}\n\n.ai-chat-notification-actions {\n display: flex;\n gap: 0.375rem;\n margin-top: 0.5rem;\n padding-top: 0.5rem;\n border-top: 1px solid var(--bs-border-color, #dee2e6);\n}\n\n.ai-chat-notification-actions .btn {\n font-size: 0.8125rem;\n padding: 0.1875rem 0.625rem;\n}\n\n.ai-chat-notification-typing {\n border-color: var(--ai-chat-primary, var(--bs-success, #198754));\n background-color: rgba(var(--ai-chat-primary-rgb, var(--bs-success-rgb, 25, 135, 84)), 0.05);\n}\n\n.ai-chat-notification-typing .ai-chat-notification-icon {\n color: var(--ai-chat-primary, var(--bs-success, #198754));\n animation: ai-chat-typing-pulse 1.5s ease-in-out infinite;\n}\n\n@keyframes ai-chat-typing-pulse {\n 0%, 100% { opacity: 0.4; }\n 50% { opacity: 1; }\n}\n\n.ai-chat-notification-transfer {\n border-color: var(--bs-warning, #ffc107);\n background-color: rgba(var(--bs-warning-rgb, 255, 193, 7), 0.06);\n}\n\n.ai-chat-notification-transfer .ai-chat-notification-icon {\n color: var(--bs-warning, #ffc107);\n animation: ai-chat-transfer-pulse 2s ease-in-out infinite;\n}\n\n@keyframes ai-chat-transfer-pulse {\n 0%, 100% { transform: scale(1); opacity: 0.7; }\n 50% { transform: scale(1.1); opacity: 1; }\n}\n\n.ai-chat-notification-ended,\n.ai-chat-notification-session-ended,\n.ai-chat-notification-conversation-ended {\n border-color: var(--bs-secondary, #6c757d);\n background-color: rgba(var(--bs-secondary-rgb, 108, 117, 125), 0.05);\n}\n\n.ai-chat-notification-ended .ai-chat-notification-icon,\n.ai-chat-notification-session-ended .ai-chat-notification-icon,\n.ai-chat-notification-conversation-ended .ai-chat-notification-icon {\n color: var(--bs-secondary, #6c757d);\n}\n\n.ai-chat-notification-info,\n.ai-chat-notification-agent-connected {\n border-color: var(--bs-info, #0dcaf0);\n background-color: rgba(var(--bs-info-rgb, 13, 202, 240), 0.05);\n}\n\n.ai-chat-notification-info .ai-chat-notification-icon,\n.ai-chat-notification-agent-connected .ai-chat-notification-icon {\n color: var(--bs-info, #0dcaf0);\n}\n\n.ai-chat-notification-warning,\n.ai-chat-notification-agent-reconnecting {\n border-color: var(--bs-warning, #ffc107);\n background-color: rgba(var(--bs-warning-rgb, 255, 193, 7), 0.06);\n}\n\n.ai-chat-notification-warning .ai-chat-notification-icon,\n.ai-chat-notification-agent-reconnecting .ai-chat-notification-icon {\n color: var(--bs-warning, #ffc107);\n}\n\n.ai-chat-notification-error,\n.ai-chat-notification-connection-lost {\n border-color: var(--bs-danger, #dc3545);\n background-color: rgba(var(--bs-danger-rgb, 220, 53, 69), 0.05);\n}\n\n.ai-chat-notification-error .ai-chat-notification-icon,\n.ai-chat-notification-connection-lost .ai-chat-notification-icon {\n color: var(--bs-danger, #dc3545);\n}\n\n/* ── Embedded and generated images ── */\n/* The renderer writes an inline max-width in pixels, which bounds a picture across but not down: an\n ingested page scan stays inside that width and still runs thousands of pixels tall, pushing the rest\n of the conversation off screen. A pixel width also overflows any panel narrower than it. Both axes are\n capped relative to the container instead, so a picture is bounded whatever its proportions and\n wherever it is shown. !important is needed because the width it overrides is written inline. */\n.generated-image-container {\n /* The wrapper is a span so a figure marker written mid-sentence does not close the paragraph it\n sits in. Inline-block restores the box behaviour the layout below assumes, and a top margin\n keeps a figure off the line of text it follows. */\n display: inline-block;\n vertical-align: top;\n margin-top: 0.5rem;\n /* The positioning context for the download that sits inside it. */\n position: relative;\n}\n\n.generated-image-container img {\n max-width: 100% !important;\n max-height: 60vh;\n height: auto;\n object-fit: contain;\n /* The cap above is what makes a figure a thumbnail: an ingested diagram lands at roughly half size,\n legible as a picture but not as a drawing. Pointing at it says it can be opened. */\n cursor: zoom-in;\n}\n\n/* The opened picture is a copy the library appends outside the figure, so it is matched on its own class\n rather than through the container -- a rule written as a descendant of the figure never reaches it. The\n copy carries the thumbnail's classes, so the frame is taken off here: its padding and white ground are\n scaled up with the drawing and would otherwise ring the picture with a broad white border. The cap is\n lifted for the same reason, and only here, so the thumbnail sitting in the conversation is left exactly\n as it was. */\nimg.medium-zoom-image--opened {\n max-width: none !important;\n max-height: none !important;\n padding: 0;\n border: 0;\n background: none;\n}\n\n/* Over the picture's lower corner rather than below it, so a figure costs only the height of the picture.\n It is drawn on a ground of its own because it sits on whatever the drawing happens to put in that\n corner. */\n.generated-image-container .ai-download-image {\n position: absolute;\n right: 0.5rem;\n bottom: 0.5rem;\n z-index: 2;\n opacity: 0;\n color: #1f2933;\n background-color: rgba(255, 255, 255, 0.92);\n border-color: rgba(0, 0, 0, 0.15);\n transition: opacity 0.15s ease-in-out;\n}\n\n/* The outline button this is built from inverts on hover: it fills itself with its own colour and turns\n its label white. Against the pale ground kept here that leaves a white icon on white -- the button is\n still there and still works, but there is nothing to see. Both colours are therefore stated for every\n state the button can be in rather than only the resting one. */\n.generated-image-container .ai-download-image:hover,\n.generated-image-container .ai-download-image:focus,\n.generated-image-container .ai-download-image:focus-visible,\n.generated-image-container .ai-download-image:active {\n color: #1f2933;\n background-color: #ffffff;\n border-color: rgba(0, 0, 0, 0.35);\n}\n\n/* Revealed by pointing at the figure. focus-within is what keeps it reachable by keyboard: the button is\n invisible until it takes focus, and an invisible control that cannot be brought into view cannot be\n used at all. */\n.generated-image-container:hover .ai-download-image,\n.generated-image-container:focus-within .ai-download-image {\n opacity: 1;\n}\n\n/* A touch screen has no hover to reveal it with, so there it is simply always shown. */\n@media (hover: none) {\n .generated-image-container .ai-download-image {\n opacity: 1;\n }\n}\n\n/* ── Tables ── */\n/* Scoped to .ai-chat-message-item rather than the message body, because the surfaces disagree on\n the body: the shared script renders .ai-chat-message-body while the MVC chat-interaction page\n renders a bare .lh-base. The item wrapper is the one element all of them share. */\n/* A markdown table arrives as a bare
with no classes, so by default it has no rules, no padding\n and a width that shrinks to its content -- an ingested table renders as run-together text. The width\n trio is the responsive-table idiom rather than a plain width: max-content lets a wide table keep its\n columns legible, min-width fills the message when it is narrow, and max-width with overflow-x means a\n table wider than the panel scrolls itself instead of stretching the conversation sideways. Colours come\n from Bootstrap's variables so the table follows the host's theme, with literal fallbacks for a host that\n does not define them. */\n.ai-chat-message-item table {\n display: block;\n width: max-content;\n min-width: 100%;\n max-width: 100%;\n overflow-x: auto;\n margin-bottom: 1rem;\n border-collapse: collapse;\n font-size: 0.9375rem;\n}\n\n.ai-chat-message-item table th,\n.ai-chat-message-item table td {\n padding: 0.4rem 0.75rem;\n border: 1px solid var(--bs-border-color, #dee2e6);\n text-align: left;\n vertical-align: top;\n}\n\n.ai-chat-message-item table thead th {\n background-color: var(--bs-secondary-bg, #e9ecef);\n font-weight: 600;\n border-bottom: 2px solid var(--bs-border-color, #dee2e6);\n white-space: nowrap;\n}\n\n/* Banding earns its place on an ingested table, which is often twenty-odd rows of similar-looking numbers\n where losing your place costs the reader the row. */\n.ai-chat-message-item table tbody tr:nth-child(even) {\n background-color: var(--bs-tertiary-bg, #f8f9fa);\n}\n"]} diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/styles/ai-chat.min.css b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/ai-chat.min.css index 936d18e1..7a6ff927 100644 --- a/src/Resources/CrestApps.AI.Resources/wwwroot/styles/ai-chat.min.css +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/ai-chat.min.css @@ -1 +1 @@ -.ai-chat-message-heading{font-size:.75rem;margin-bottom:.35rem}.ai-chat-message-heading .ai-chat-msg-role{margin-bottom:0;letter-spacing:.03em}.ai-chat-message-heading-assistant .ai-chat-msg-role{display:inline-flex;align-items:center;gap:.35rem}.ai-chat-message-role-label{display:inline-block;text-transform:inherit}.ai-chat-msg-role{font-weight:600;margin-bottom:.35rem;text-transform:uppercase}.ai-chat-msg-role-user{color:var(--bs-primary,#0d6efd)}.ai-chat-msg-role-assistant{color:var(--ai-chat-primary,var(--bs-success,#198754))}.ai-chat-messages .ai-chat-message-item{position:relative;padding:.25rem 0}.ai-chat-messages .ai-chat-message-item+.ai-chat-message-item::before{content:'';display:block;width:100%;margin:.5rem auto .75rem;border-top:1px solid var(--bs-border-color,#dee2e6)}.ai-chat-messages .ai-chat-message-item p:last-child{margin-bottom:0}.ai-chat-messages .ai-chat-message-body{position:relative;padding:0;overflow-wrap:break-word;word-break:break-word;min-width:0}.ai-chat-messages .ai-chat-message-body sup{font-size:.75em;line-height:0}.ai-chat-messages table{margin:.75rem 0;font-size:.9em}.ai-chat-messages table td,.ai-chat-messages table th{vertical-align:top;white-space:nowrap}.ai-chat-messages table td[align=right],.ai-chat-messages table th[align=right]{text-align:right}.ai-chat-messages table td[align=center],.ai-chat-messages table th[align=center]{text-align:center}.ai-chat-messages .ai-chat-citation-list{margin:.75rem 0 0;padding-left:1.25rem}.ai-chat-messages .ai-chat-citation-item+.ai-chat-citation-item{margin-top:.25rem}.ai-chat-messages .ai-chat-citation-item a{word-break:break-word}.ai-partial-transcript{font-style:italic;opacity:.7}.ai-chat-messages .message-buttons-container{position:absolute;right:.1rem;bottom:0;display:inline-flex;align-items:center;gap:.35rem;width:auto;max-width:max-content;opacity:0;pointer-events:none;transition:opacity .15s ease-in-out;background:rgba(var(--bs-body-bg-rgb,255,255,255),.96);padding:.2rem .35rem;border-radius:999px;box-shadow:0 1px 3px rgba(var(--bs-body-color-rgb,33,37,41),.08);margin-bottom:1rem;transform:translateY(50%);z-index:1}.ai-chat-messages .ai-chat-message-item:focus-within .message-buttons-container,.ai-chat-messages .ai-chat-message-item:hover .message-buttons-container{opacity:1;pointer-events:auto}.ai-chat-messages .message-buttons-container:has(.tts-playing){opacity:1;pointer-events:auto}.ai-chat-messages .message-buttons-container>.button-message-toolbox{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:1.75rem;height:1.75rem;margin:0!important;padding:0!important;border-radius:50%;color:var(--bs-secondary-color,#6c757d)!important;text-decoration:none}.ai-chat-messages .message-buttons-container .ai-chat-message-assistant-feedback{display:inline-flex;align-items:center;gap:.35rem}.ai-chat-messages .message-buttons-container>.button-message-toolbox:focus,.ai-chat-messages .message-buttons-container>.button-message-toolbox:hover{color:var(--bs-body-color,#212529)!important;text-decoration:none}.ai-chat-messages .message-buttons-container>.button-message-toolbox.text-success,.ai-chat-messages .message-buttons-container>.button-message-toolbox.text-success:focus,.ai-chat-messages .message-buttons-container>.button-message-toolbox.text-success:hover{color:var(--bs-success,#198754)!important;text-decoration:none}.ai-chat-messages .message-buttons-container>.button-message-toolbox.text-success svg{color:inherit!important;fill:currentColor}.ai-chat-messages .message-buttons-container .tts-playing{color:var(--ai-chat-primary,var(--bs-success,#198754))}@keyframes spark-burst{0%{transform:scale(1);opacity:1}20%{transform:scale(1.8);opacity:.7}40%{transform:scale(.9);opacity:1}60%{transform:scale(1.3)}100%{transform:scale(1)}}.spark-effect i,.spark-effect svg{display:inline-block;animation:spark-burst .5s ease-out}.ai-chat-messages .ai-bot-icon{color:currentColor;display:inline-block;animation:none}@keyframes ai-chat-streaming-effect{0%{opacity:1;transform:rotate(0)}10%{opacity:.3;transform:rotate(0)}20%{opacity:1;transform:rotate(0)}30%{opacity:.3;transform:rotate(0)}40%{opacity:1;transform:rotate(0)}50%{opacity:.3;transform:rotate(0)}60%{opacity:1;transform:rotate(0)}80%{opacity:1;transform:rotate(360deg)}100%{opacity:1;transform:rotate(360deg)}}.ai-chat-messages .ai-streaming-icon{color:currentColor;display:inline-block;animation:ai-chat-streaming-effect 4s ease-in-out infinite}.ai-chat-messages pre{position:relative;margin:0}.ai-chat-messages .ai-code-block{border:1px solid var(--bs-border-color,#dee2e6);border-radius:.5rem;overflow:hidden;margin:.75rem 0;background:var(--bs-body-bg,#fff)}.ai-chat-messages .ai-code-header{display:flex;align-items:center;justify-content:space-between;padding:.5rem 1rem;font-size:.8rem;min-height:2rem}.ai-chat-messages .ai-code-lang{font-weight:600;color:var(--bs-body-color,#212529);text-transform:capitalize}.ai-chat-messages .ai-code-lang i{color:var(--bs-secondary-color,#6c757d);margin-right:.25rem}.ai-chat-messages .ai-code-copy-btn{display:inline-flex;align-items:center;gap:.3rem;padding:.2rem;font-size:.8rem;background:0 0;border:none;cursor:pointer;color:var(--bs-secondary-color,#6c757d);transition:color .15s;white-space:nowrap}.ai-chat-messages .ai-code-copy-btn:hover{color:var(--bs-body-color,#212529)}.ai-chat-messages .ai-code-block pre{margin:0;background:0 0!important}.ai-chat-messages .ai-code-block pre code.hljs{background:0 0!important;padding:.75rem 1rem 1rem}.ai-chat-messages pre code.hljs{white-space:pre-wrap;word-wrap:break-word;overflow-wrap:break-word;border-radius:.375rem}.ai-chat-doc-bar{border-bottom:1px solid var(--bs-border-color,#dee2e6)}.ai-chat-drag-over{outline:2px dashed var(--bs-primary,#0d6efd)!important;outline-offset:-2px;background-color:rgba(var(--bs-primary-rgb,13,110,253),.05)!important}.ai-chat-notification{margin:.75rem 0 .25rem;padding:.625rem .875rem;border-radius:.5rem;border:1px solid var(--bs-border-color,#dee2e6);background-color:var(--bs-tertiary-bg,#f8f9fa);font-size:.875rem;line-height:1.4}.ai-chat-notification-content{display:flex;align-items:center;gap:.5rem}.ai-chat-notification-icon{flex-shrink:0;font-size:1rem;opacity:.8}.ai-chat-notification-text{flex:1}.ai-chat-notification-dismiss{flex-shrink:0;opacity:.5;transition:opacity .15s}.ai-chat-notification-dismiss:hover{opacity:1}.ai-chat-notification-actions{display:flex;gap:.375rem;margin-top:.5rem;padding-top:.5rem;border-top:1px solid var(--bs-border-color,#dee2e6)}.ai-chat-notification-actions .btn{font-size:.8125rem;padding:.1875rem .625rem}.ai-chat-notification-typing{border-color:var(--ai-chat-primary,var(--bs-success,#198754));background-color:rgba(var(--ai-chat-primary-rgb,var(--bs-success-rgb,25,135,84)),.05)}.ai-chat-notification-typing .ai-chat-notification-icon{color:var(--ai-chat-primary,var(--bs-success,#198754));animation:ai-chat-typing-pulse 1.5s ease-in-out infinite}@keyframes ai-chat-typing-pulse{0%,100%{opacity:.4}50%{opacity:1}}.ai-chat-notification-transfer{border-color:var(--bs-warning,#ffc107);background-color:rgba(var(--bs-warning-rgb,255,193,7),.06)}.ai-chat-notification-transfer .ai-chat-notification-icon{color:var(--bs-warning,#ffc107);animation:ai-chat-transfer-pulse 2s ease-in-out infinite}@keyframes ai-chat-transfer-pulse{0%,100%{transform:scale(1);opacity:.7}50%{transform:scale(1.1);opacity:1}}.ai-chat-notification-conversation-ended,.ai-chat-notification-ended,.ai-chat-notification-session-ended{border-color:var(--bs-secondary,#6c757d);background-color:rgba(var(--bs-secondary-rgb,108,117,125),.05)}.ai-chat-notification-conversation-ended .ai-chat-notification-icon,.ai-chat-notification-ended .ai-chat-notification-icon,.ai-chat-notification-session-ended .ai-chat-notification-icon{color:var(--bs-secondary,#6c757d)}.ai-chat-notification-agent-connected,.ai-chat-notification-info{border-color:var(--bs-info,#0dcaf0);background-color:rgba(var(--bs-info-rgb,13,202,240),.05)}.ai-chat-notification-agent-connected .ai-chat-notification-icon,.ai-chat-notification-info .ai-chat-notification-icon{color:var(--bs-info,#0dcaf0)}.ai-chat-notification-agent-reconnecting,.ai-chat-notification-warning{border-color:var(--bs-warning,#ffc107);background-color:rgba(var(--bs-warning-rgb,255,193,7),.06)}.ai-chat-notification-agent-reconnecting .ai-chat-notification-icon,.ai-chat-notification-warning .ai-chat-notification-icon{color:var(--bs-warning,#ffc107)}.ai-chat-notification-connection-lost,.ai-chat-notification-error{border-color:var(--bs-danger,#dc3545);background-color:rgba(var(--bs-danger-rgb,220,53,69),.05)}.ai-chat-notification-connection-lost .ai-chat-notification-icon,.ai-chat-notification-error .ai-chat-notification-icon{color:var(--bs-danger,#dc3545)}.generated-image-container{display:inline-block;vertical-align:top;margin-top:.5rem}.generated-image-container img{max-width:100%!important;max-height:60vh;height:auto;object-fit:contain}.ai-chat-message-item table{display:block;width:max-content;min-width:100%;max-width:100%;overflow-x:auto;margin-bottom:1rem;border-collapse:collapse;font-size:.9375rem}.ai-chat-message-item table td,.ai-chat-message-item table th{padding:.4rem .75rem;border:1px solid var(--bs-border-color,#dee2e6);text-align:left;vertical-align:top}.ai-chat-message-item table thead th{background-color:var(--bs-secondary-bg,#e9ecef);font-weight:600;border-bottom:2px solid var(--bs-border-color,#dee2e6);white-space:nowrap}.ai-chat-message-item table tbody tr:nth-child(even){background-color:var(--bs-tertiary-bg,#f8f9fa)} +.ai-chat-message-heading{font-size:.75rem;margin-bottom:.35rem}.ai-chat-message-heading .ai-chat-msg-role{margin-bottom:0;letter-spacing:.03em}.ai-chat-message-heading-assistant .ai-chat-msg-role{display:inline-flex;align-items:center;gap:.35rem}.ai-chat-message-role-label{display:inline-block;text-transform:inherit}.ai-chat-msg-role{font-weight:600;margin-bottom:.35rem;text-transform:uppercase}.ai-chat-msg-role-user{color:var(--bs-primary,#0d6efd)}.ai-chat-msg-role-assistant{color:var(--ai-chat-primary,var(--bs-success,#198754))}.ai-chat-messages .ai-chat-message-item{position:relative;padding:.25rem 0}.ai-chat-messages .ai-chat-message-item+.ai-chat-message-item::before{content:'';display:block;width:100%;margin:.5rem auto .75rem;border-top:1px solid var(--bs-border-color,#dee2e6)}.ai-chat-messages .ai-chat-message-item p:last-child{margin-bottom:0}.ai-chat-messages .ai-chat-message-body{position:relative;padding:0;overflow-wrap:break-word;word-break:break-word;min-width:0}.ai-chat-messages .ai-chat-message-body sup{font-size:.75em;line-height:0}.ai-chat-messages table{margin:.75rem 0;font-size:.9em}.ai-chat-messages table td,.ai-chat-messages table th{vertical-align:top;white-space:nowrap}.ai-chat-messages table td[align=right],.ai-chat-messages table th[align=right]{text-align:right}.ai-chat-messages table td[align=center],.ai-chat-messages table th[align=center]{text-align:center}.ai-chat-messages .ai-chat-citation-list{margin:.75rem 0 0;padding-left:1.25rem}.ai-chat-messages .ai-chat-citation-item+.ai-chat-citation-item{margin-top:.25rem}.ai-chat-messages .ai-chat-citation-item a{word-break:break-word}.ai-partial-transcript{font-style:italic;opacity:.7}.ai-chat-messages .message-buttons-container{position:absolute;right:.1rem;bottom:0;display:inline-flex;align-items:center;gap:.35rem;width:auto;max-width:max-content;opacity:0;pointer-events:none;transition:opacity .15s ease-in-out;background:rgba(var(--bs-body-bg-rgb,255,255,255),.96);padding:.2rem .35rem;border-radius:999px;box-shadow:0 1px 3px rgba(var(--bs-body-color-rgb,33,37,41),.08);margin-bottom:1rem;transform:translateY(50%);z-index:1}.ai-chat-messages .ai-chat-message-item:focus-within .message-buttons-container,.ai-chat-messages .ai-chat-message-item:hover .message-buttons-container{opacity:1;pointer-events:auto}.ai-chat-messages .message-buttons-container:has(.tts-playing){opacity:1;pointer-events:auto}.ai-chat-messages .message-buttons-container>.button-message-toolbox{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:1.75rem;height:1.75rem;margin:0!important;padding:0!important;border-radius:50%;color:var(--bs-secondary-color,#6c757d)!important;text-decoration:none}.ai-chat-messages .message-buttons-container .ai-chat-message-assistant-feedback{display:inline-flex;align-items:center;gap:.35rem}.ai-chat-messages .message-buttons-container>.button-message-toolbox:focus,.ai-chat-messages .message-buttons-container>.button-message-toolbox:hover{color:var(--bs-body-color,#212529)!important;text-decoration:none}.ai-chat-messages .message-buttons-container>.button-message-toolbox.text-success,.ai-chat-messages .message-buttons-container>.button-message-toolbox.text-success:focus,.ai-chat-messages .message-buttons-container>.button-message-toolbox.text-success:hover{color:var(--bs-success,#198754)!important;text-decoration:none}.ai-chat-messages .message-buttons-container>.button-message-toolbox.text-success svg{color:inherit!important;fill:currentColor}.ai-chat-messages .message-buttons-container .tts-playing{color:var(--ai-chat-primary,var(--bs-success,#198754))}@keyframes spark-burst{0%{transform:scale(1);opacity:1}20%{transform:scale(1.8);opacity:.7}40%{transform:scale(.9);opacity:1}60%{transform:scale(1.3)}100%{transform:scale(1)}}.spark-effect i,.spark-effect svg{display:inline-block;animation:spark-burst .5s ease-out}.ai-chat-messages .ai-bot-icon{color:currentColor;display:inline-block;animation:none}@keyframes ai-chat-streaming-effect{0%{opacity:1;transform:rotate(0)}10%{opacity:.3;transform:rotate(0)}20%{opacity:1;transform:rotate(0)}30%{opacity:.3;transform:rotate(0)}40%{opacity:1;transform:rotate(0)}50%{opacity:.3;transform:rotate(0)}60%{opacity:1;transform:rotate(0)}80%{opacity:1;transform:rotate(360deg)}100%{opacity:1;transform:rotate(360deg)}}.ai-chat-messages .ai-streaming-icon{color:currentColor;display:inline-block;animation:ai-chat-streaming-effect 4s ease-in-out infinite}.ai-chat-messages pre{position:relative;margin:0}.ai-chat-messages .ai-code-block{border:1px solid var(--bs-border-color,#dee2e6);border-radius:.5rem;overflow:hidden;margin:.75rem 0;background:var(--bs-body-bg,#fff)}.ai-chat-messages .ai-code-header{display:flex;align-items:center;justify-content:space-between;padding:.5rem 1rem;font-size:.8rem;min-height:2rem}.ai-chat-messages .ai-code-lang{font-weight:600;color:var(--bs-body-color,#212529);text-transform:capitalize}.ai-chat-messages .ai-code-lang i{color:var(--bs-secondary-color,#6c757d);margin-right:.25rem}.ai-chat-messages .ai-code-copy-btn{display:inline-flex;align-items:center;gap:.3rem;padding:.2rem;font-size:.8rem;background:0 0;border:none;cursor:pointer;color:var(--bs-secondary-color,#6c757d);transition:color .15s;white-space:nowrap}.ai-chat-messages .ai-code-copy-btn:hover{color:var(--bs-body-color,#212529)}.ai-chat-messages .ai-code-block pre{margin:0;background:0 0!important}.ai-chat-messages .ai-code-block pre code.hljs{background:0 0!important;padding:.75rem 1rem 1rem}.ai-chat-messages pre code.hljs{white-space:pre-wrap;word-wrap:break-word;overflow-wrap:break-word;border-radius:.375rem}.ai-chat-doc-bar{border-bottom:1px solid var(--bs-border-color,#dee2e6)}.ai-chat-drag-over{outline:2px dashed var(--bs-primary,#0d6efd)!important;outline-offset:-2px;background-color:rgba(var(--bs-primary-rgb,13,110,253),.05)!important}.ai-chat-notification{margin:.75rem 0 .25rem;padding:.625rem .875rem;border-radius:.5rem;border:1px solid var(--bs-border-color,#dee2e6);background-color:var(--bs-tertiary-bg,#f8f9fa);font-size:.875rem;line-height:1.4}.ai-chat-notification-content{display:flex;align-items:center;gap:.5rem}.ai-chat-notification-icon{flex-shrink:0;font-size:1rem;opacity:.8}.ai-chat-notification-text{flex:1}.ai-chat-notification-dismiss{flex-shrink:0;opacity:.5;transition:opacity .15s}.ai-chat-notification-dismiss:hover{opacity:1}.ai-chat-notification-actions{display:flex;gap:.375rem;margin-top:.5rem;padding-top:.5rem;border-top:1px solid var(--bs-border-color,#dee2e6)}.ai-chat-notification-actions .btn{font-size:.8125rem;padding:.1875rem .625rem}.ai-chat-notification-typing{border-color:var(--ai-chat-primary,var(--bs-success,#198754));background-color:rgba(var(--ai-chat-primary-rgb,var(--bs-success-rgb,25,135,84)),.05)}.ai-chat-notification-typing .ai-chat-notification-icon{color:var(--ai-chat-primary,var(--bs-success,#198754));animation:ai-chat-typing-pulse 1.5s ease-in-out infinite}@keyframes ai-chat-typing-pulse{0%,100%{opacity:.4}50%{opacity:1}}.ai-chat-notification-transfer{border-color:var(--bs-warning,#ffc107);background-color:rgba(var(--bs-warning-rgb,255,193,7),.06)}.ai-chat-notification-transfer .ai-chat-notification-icon{color:var(--bs-warning,#ffc107);animation:ai-chat-transfer-pulse 2s ease-in-out infinite}@keyframes ai-chat-transfer-pulse{0%,100%{transform:scale(1);opacity:.7}50%{transform:scale(1.1);opacity:1}}.ai-chat-notification-conversation-ended,.ai-chat-notification-ended,.ai-chat-notification-session-ended{border-color:var(--bs-secondary,#6c757d);background-color:rgba(var(--bs-secondary-rgb,108,117,125),.05)}.ai-chat-notification-conversation-ended .ai-chat-notification-icon,.ai-chat-notification-ended .ai-chat-notification-icon,.ai-chat-notification-session-ended .ai-chat-notification-icon{color:var(--bs-secondary,#6c757d)}.ai-chat-notification-agent-connected,.ai-chat-notification-info{border-color:var(--bs-info,#0dcaf0);background-color:rgba(var(--bs-info-rgb,13,202,240),.05)}.ai-chat-notification-agent-connected .ai-chat-notification-icon,.ai-chat-notification-info .ai-chat-notification-icon{color:var(--bs-info,#0dcaf0)}.ai-chat-notification-agent-reconnecting,.ai-chat-notification-warning{border-color:var(--bs-warning,#ffc107);background-color:rgba(var(--bs-warning-rgb,255,193,7),.06)}.ai-chat-notification-agent-reconnecting .ai-chat-notification-icon,.ai-chat-notification-warning .ai-chat-notification-icon{color:var(--bs-warning,#ffc107)}.ai-chat-notification-connection-lost,.ai-chat-notification-error{border-color:var(--bs-danger,#dc3545);background-color:rgba(var(--bs-danger-rgb,220,53,69),.05)}.ai-chat-notification-connection-lost .ai-chat-notification-icon,.ai-chat-notification-error .ai-chat-notification-icon{color:var(--bs-danger,#dc3545)}.generated-image-container{display:inline-block;vertical-align:top;margin-top:.5rem;position:relative}.generated-image-container img{max-width:100%!important;max-height:60vh;height:auto;object-fit:contain;cursor:zoom-in}img.medium-zoom-image--opened{max-width:none!important;max-height:none!important;padding:0;border:0;background:0 0}.generated-image-container .ai-download-image{position:absolute;right:.5rem;bottom:.5rem;z-index:2;opacity:0;color:#1f2933;background-color:rgba(255,255,255,.92);border-color:rgba(0,0,0,.15);transition:opacity .15s ease-in-out}.generated-image-container .ai-download-image:active,.generated-image-container .ai-download-image:focus,.generated-image-container .ai-download-image:focus-visible,.generated-image-container .ai-download-image:hover{color:#1f2933;background-color:#fff;border-color:rgba(0,0,0,.35)}.generated-image-container:focus-within .ai-download-image,.generated-image-container:hover .ai-download-image{opacity:1}@media (hover:none){.generated-image-container .ai-download-image{opacity:1}}.ai-chat-message-item table{display:block;width:max-content;min-width:100%;max-width:100%;overflow-x:auto;margin-bottom:1rem;border-collapse:collapse;font-size:.9375rem}.ai-chat-message-item table td,.ai-chat-message-item table th{padding:.4rem .75rem;border:1px solid var(--bs-border-color,#dee2e6);text-align:left;vertical-align:top}.ai-chat-message-item table thead th{background-color:var(--bs-secondary-bg,#e9ecef);font-weight:600;border-bottom:2px solid var(--bs-border-color,#dee2e6);white-space:nowrap}.ai-chat-message-item table tbody tr:nth-child(even){background-color:var(--bs-tertiary-bg,#f8f9fa)} diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.css b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.css index 0046994e..8f3294a3 100644 --- a/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.css +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.css @@ -419,12 +419,73 @@ display: inline-block; vertical-align: top; margin-top: 0.5rem; + /* The positioning context for the download that sits inside it. */ + position: relative; } .ai-chat-widget-messages .generated-image-container img { max-width: 100% !important; max-height: 50vh; object-fit: contain; + /* The panel is 380px wide, so a figure in it is a thumbnail whatever it was drawn at. Pointing at it + says it can be opened to the size of the window. */ + cursor: zoom-in; +} + +/* Deliberately not scoped to the panel. The opened picture is a copy the library appends to the document + body, which is outside the widget entirely, so a rule under .ai-chat-widget-messages never reaches it. + It is repeated from ai-chat.css because a page that mounts only the widget loads only this file. The + copy carries the thumbnail's classes, so the frame and the cap are taken off here -- both are scaled up + with the drawing and would otherwise ring the picture with a broad white border. */ +img.medium-zoom-image--opened { + max-width: none !important; + max-height: none !important; + padding: 0; + border: 0; + background: none; +} + +/* Over the picture's lower corner rather than below it. In a panel this narrow a row of its own cost a + band of vertical space per figure, which a conversation full of them pays for once each. */ +.ai-chat-widget-messages .generated-image-container .ai-download-image { + position: absolute; + right: 0.5rem; + bottom: 0.5rem; + z-index: 2; + opacity: 0; + color: #1f2933; + background-color: rgba(255, 255, 255, 0.92); + border-color: rgba(0, 0, 0, 0.15); + transition: opacity 0.15s ease-in-out; +} + +/* The outline button this is built from inverts on hover: it fills itself with its own colour and turns + its label white. Against the pale ground kept here that leaves a white icon on white -- the button is + still there and still works, but there is nothing to see. Both colours are therefore stated for every + state the button can be in rather than only the resting one. */ +.ai-chat-widget-messages .generated-image-container .ai-download-image:hover, +.ai-chat-widget-messages .generated-image-container .ai-download-image:focus, +.ai-chat-widget-messages .generated-image-container .ai-download-image:focus-visible, +.ai-chat-widget-messages .generated-image-container .ai-download-image:active { + color: #1f2933; + background-color: #ffffff; + border-color: rgba(0, 0, 0, 0.35); +} + +/* Revealed by pointing at the figure. focus-within is what keeps it reachable by keyboard: the button is + invisible until it takes focus, and an invisible control that cannot be brought into view cannot be + used at all. */ +.ai-chat-widget-messages .generated-image-container:hover .ai-download-image, +.ai-chat-widget-messages .generated-image-container:focus-within .ai-download-image { + opacity: 1; +} + +/* A touch screen has no hover to reveal it with, so there it is simply always shown. The widget is the + surface most likely to be read on one. */ +@media (hover: none) { + .ai-chat-widget-messages .generated-image-container .ai-download-image { + opacity: 1; + } } /* ── Tables inside widget ── */ diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.css.map b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.css.map index 0640a5d2..09aadc7d 100644 --- a/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.css.map +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.css.map @@ -1 +1 @@ -{"version":3,"sources":["chat-widget.css"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"chat-widget.css","sourcesContent":["/* CrestApps AI Chat Widget */\n:root {\n --ai-widget-primary: var(--bs-secondary, #6c757d);\n --ai-widget-primary-rgb: var(--bs-secondary-rgb, 108, 117, 125);\n --ai-widget-width: 380px;\n --ai-widget-height: 520px;\n}\n\n.ai-chat-widget-toggle {\n position: fixed;\n bottom: 1.25rem;\n right: 1.25rem;\n z-index: 10000;\n width: 52px;\n height: 52px;\n border-radius: 50%;\n background: var(--ai-widget-primary);\n color: var(--bs-white, #fff);\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n box-shadow: 0 4px 12px rgba(var(--bs-body-color-rgb, 33, 37, 41), 0.2);\n transition: transform 0.2s, box-shadow 0.2s;\n}\n\n.ai-chat-widget-toggle:hover {\n transform: scale(1.1);\n box-shadow: 0 6px 16px rgba(var(--bs-body-color-rgb, 33, 37, 41), 0.3);\n}\n\n.ai-chat-widget-container {\n position: fixed;\n bottom: 5rem;\n right: 1.25rem;\n z-index: 10001;\n width: var(--ai-widget-width);\n height: var(--ai-widget-height);\n background: var(--bs-body-bg, #fff);\n color: var(--bs-body-color, #212529);\n border: 1px solid var(--bs-border-color, #dee2e6);\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(var(--bs-body-color-rgb, 33, 37, 41), 0.18);\n display: none;\n flex-direction: column;\n overflow: hidden;\n}\n\n.ai-chat-widget-container.ai-chat-widget-resizable {\n resize: both;\n min-width: 320px;\n min-height: 420px;\n max-width: min(90vw, 960px);\n max-height: min(90vh, 960px);\n}\n\n.ai-chat-widget-container.open {\n display: flex;\n}\n\n.ai-chat-widget-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.75rem 1rem;\n background: var(--ai-widget-primary);\n color: var(--bs-white, #fff);\n}\n\n.ai-chat-widget-header.ai-chat-widget-drag-handle {\n cursor: move;\n user-select: none;\n touch-action: none;\n}\n\n.ai-chat-widget-header-actions {\n display: flex;\n align-items: center;\n gap: 0.15rem;\n}\n\n.ai-chat-widget-toggle.ai-chat-widget-draggable {\n touch-action: none;\n}\n\n.ai-chat-widget-container.ai-chat-widget-dragging,\n.ai-chat-widget-toggle.ai-chat-widget-dragging {\n transition: none;\n}\n\n.ai-chat-widget-toggle.ai-chat-widget-dragging:hover {\n transform: none;\n}\n\n.ai-chat-widget-header .title {\n font-weight: 600;\n font-size: 0.95rem;\n}\n\n.ai-chat-widget-header button {\n background: none;\n border: none;\n color: var(--bs-white, #fff);\n cursor: pointer;\n font-size: 1rem;\n padding: 0 0.25rem;\n opacity: 0.8;\n}\n\n.ai-chat-widget-header button:hover {\n opacity: 1;\n}\n\n.ai-chat-widget-profile-select {\n padding: 0.5rem 0.75rem;\n border-bottom: 1px solid var(--bs-border-color, #dee2e6);\n background: var(--bs-tertiary-bg, #f8f9fa);\n}\n\n.ai-chat-widget-profile-select select {\n width: 100%;\n padding: 0.35rem 0.5rem;\n color: var(--bs-body-color, #212529);\n background-color: var(--bs-body-bg, #fff);\n border: 1px solid var(--bs-border-color, #ced4da);\n border-radius: 6px;\n font-size: 0.85rem;\n}\n\n.ai-chat-widget-messages {\n flex: 1;\n overflow-y: auto;\n padding: 0.75rem;\n font-size: 0.9rem;\n}\n\n/* ── Widget message items (ai-chat.js Vue template) ── */\n.ai-chat-widget-messages .ai-chat-messages {\n padding: 0.5rem;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item {\n position: relative;\n padding: 0.5rem 0;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item + .ai-chat-message-item::before {\n content: '';\n display: block;\n width: 100%;\n margin-bottom: 0.5rem;\n border-top: 1px solid rgba(var(--bs-body-color-rgb, 33, 37, 41), 0.08);\n}\n\n.ai-chat-widget-messages .ai-chat-message-heading {\n margin-bottom: 0.35rem;\n}\n\n.ai-chat-widget-messages .ai-chat-message-heading .ai-chat-msg-role {\n margin-bottom: 0;\n letter-spacing: 0.03em;\n}\n\n.ai-chat-widget-messages .ai-chat-message-heading-assistant .ai-chat-msg-role {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.ai-chat-widget-messages .ai-chat-message-role-label {\n display: inline-block;\n text-transform: inherit;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role {\n font-weight: 600;\n margin-bottom: 2px;\n text-transform: uppercase;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-user {\n color: var(--bs-primary, #0d6efd);\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-assistant {\n color: var(--ai-widget-primary, #6f42c1);\n}\n\n.ai-chat-widget-messages .ai-bot-icon {\n color: currentColor;\n display: inline-block;\n animation: none;\n}\n\n@keyframes ai-widget-streaming-effect {\n 0% { opacity: 1; transform: rotate(0deg); }\n 10% { opacity: 0.3; transform: rotate(0deg); }\n 20% { opacity: 1; transform: rotate(0deg); }\n 30% { opacity: 0.3; transform: rotate(0deg); }\n 40% { opacity: 1; transform: rotate(0deg); }\n 50% { opacity: 0.3; transform: rotate(0deg); }\n 60% { opacity: 1; transform: rotate(0deg); }\n 80% { opacity: 1; transform: rotate(360deg); }\n 100% { opacity: 1; transform: rotate(360deg); }\n}\n\n.ai-chat-widget-messages .ai-streaming-icon {\n color: currentColor;\n display: inline-block;\n animation: ai-widget-streaming-effect 4s ease-in-out infinite;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body {\n position: relative;\n padding: 0;\n overflow-wrap: break-word;\n word-break: break-word;\n min-width: 0;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body p:last-child {\n margin-bottom: 0;\n}\n\n/* ── Message action buttons (copy, thumbs up/down) ── */\n.ai-chat-widget-messages .message-buttons-container {\n position: absolute;\n right: 0.1rem;\n bottom: 0;\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n width: auto;\n max-width: max-content;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s ease-in-out;\n background: rgba(var(--bs-body-bg-rgb, 255, 255, 255), 0.96);\n padding: 0.2rem 0.35rem;\n border-radius: 999px;\n box-shadow: 0 1px 3px rgba(var(--bs-body-color-rgb, 33, 37, 41), 0.08);\n margin-bottom: 1rem;\n transform: translateY(50%);\n z-index: 1;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item:hover .message-buttons-container,\n.ai-chat-widget-messages .ai-chat-message-item:focus-within .message-buttons-container {\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-widget-messages .message-buttons-container:has(.tts-playing) {\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n width: 1.75rem;\n height: 1.75rem;\n margin: 0 !important;\n padding: 0 !important;\n border-radius: 50%;\n color: var(--bs-secondary-color, #6c757d) !important;\n text-decoration: none;\n}\n\n.ai-chat-widget-messages .message-buttons-container .ai-chat-message-assistant-feedback {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox:hover,\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox:focus {\n color: var(--bs-body-color, #212529) !important;\n text-decoration: none;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox.text-success,\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox.text-success:hover,\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox.text-success:focus {\n color: var(--bs-success, #198754) !important;\n text-decoration: none;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox.text-success svg {\n color: inherit !important;\n fill: currentColor;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox.tts-playing {\n color: var(--ai-widget-primary, #6f42c1) !important;\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-widget-history-panel {\n position: absolute;\n top: 3.5rem;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--bs-body-bg, #fff);\n padding: 1rem;\n z-index: 10;\n display: none;\n overflow-y: auto;\n flex-direction: column;\n}\n\n.ai-chat-widget-history-panel.show {\n display: flex;\n}\n\n.ai-chat-widget-history-panel .history-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 0.75rem;\n flex-shrink: 0;\n}\n\n.ai-chat-widget-history-panel .history-header h5 {\n margin: 0;\n font-size: 1rem;\n}\n\n.ai-chat-widget-history-list {\n list-style: none;\n padding: 0;\n margin: 0;\n overflow-y: auto;\n flex: 1 1 auto;\n}\n\n.ai-chat-widget-history-list li {\n margin-bottom: 0;\n}\n\n.ai-chat-widget-history-list .chat-session-history-item {\n display: block;\n padding: 0.5rem 0.75rem;\n text-decoration: none;\n color: var(--bs-body-color, #212529);\n font-size: 0.85rem;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n transition: background 0.15s;\n cursor: pointer;\n border-bottom: 1px solid var(--bs-border-color, #dee2e6);\n}\n\n.ai-chat-widget-history-list li:last-child .chat-session-history-item {\n border-bottom: none;\n}\n\n.ai-chat-widget-history-list .chat-session-history-item:hover {\n background: var(--bs-tertiary-bg, #f8f9fa);\n}\n\n/* ── Notifications ── */\n.ai-chat-widget-messages .ai-chat-notification {\n margin: 0.75rem 0.5rem 0;\n padding: 0.625rem 0.75rem;\n border: 1px solid rgba(var(--bs-body-color-rgb, 33, 37, 41), 0.12);\n border-radius: 0.5rem;\n background: rgba(var(--bs-tertiary-bg-rgb, 248, 249, 250), 0.98);\n}\n\n.ai-chat-widget-messages .ai-chat-notification-content {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-icon {\n margin-top: 0.1rem;\n color: var(--bs-secondary-color, #6c757d);\n}\n\n.ai-chat-widget-messages .ai-chat-notification-text {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-dismiss {\n margin-left: auto !important;\n color: var(--bs-secondary-color, #6c757d) !important;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-actions {\n display: flex;\n gap: 0.5rem;\n margin-top: 0.5rem;\n}\n\n/* ── Chart containers inside widget ── */\n.ai-chat-widget-messages .chart-container {\n width: 100%;\n max-width: 100% !important;\n min-height: 280px;\n}\n\n/* ── Embedded images inside widget ── */\n/* The panel is narrower than the renderer's inline pixel cap, so an image overflows it horizontally\n without this. The chart container above is bounded the same way and for the same reason. */\n.ai-chat-widget-messages .generated-image-container {\n /* The wrapper is a span so a figure marker written mid-sentence does not close the paragraph it\n sits in. Inline-block restores the box behaviour the layout below assumes, and a top margin\n keeps a figure off the line of text it follows. */\n display: inline-block;\n vertical-align: top;\n margin-top: 0.5rem;\n}\n\n.ai-chat-widget-messages .generated-image-container img {\n max-width: 100% !important;\n max-height: 50vh;\n object-fit: contain;\n}\n\n/* ── Tables inside widget ── */\n/* The panel is 380px wide, so an ingested table almost always exceeds it. Scrolling the table itself keeps\n the conversation column intact; the alternative is a sideways-scrolling chat. */\n.ai-chat-widget-messages table {\n display: block;\n width: max-content;\n min-width: 100%;\n max-width: 100%;\n overflow-x: auto;\n margin-bottom: 0.75rem;\n border-collapse: collapse;\n font-size: 0.8125rem;\n}\n\n.ai-chat-widget-messages table th,\n.ai-chat-widget-messages table td {\n padding: 0.3rem 0.5rem;\n border: 1px solid var(--bs-border-color, #dee2e6);\n text-align: left;\n vertical-align: top;\n}\n\n.ai-chat-widget-messages table thead th {\n background-color: var(--bs-secondary-bg, #e9ecef);\n font-weight: 600;\n white-space: nowrap;\n}\n\n.ai-chat-widget-messages table tbody tr:nth-child(even) {\n background-color: var(--bs-tertiary-bg, #f8f9fa);\n}\n\n/* ── Code blocks & inline code ── */\n.ai-chat-widget-messages .ai-chat-message-body pre {\n background: var(--bs-dark-bg-subtle, #2d2d2d);\n color: var(--bs-emphasis-color, #f8f8f2);\n padding: 0.5rem;\n border-radius: 4px;\n overflow-x: auto;\n font-size: 0.8rem;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body code {\n font-size: 0.85em;\n}\n\n.ai-chat-widget-input {\n border-top: 1px solid var(--bs-border-color, #dee2e6);\n padding: 0.5rem 0.75rem;\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n align-items: flex-end;\n}\n\n.ai-chat-widget-input .ai-chat-doc-bar {\n flex: 0 0 100%;\n margin: -0.5rem -0.75rem 0.5rem;\n padding: 0.5rem 0.75rem;\n max-height: 4.5rem;\n overflow-y: auto;\n}\n\n.ai-chat-widget-input textarea {\n flex: 1;\n min-width: 0;\n color: var(--bs-body-color, #212529);\n background-color: var(--bs-body-bg, #fff);\n border: 1px solid var(--bs-border-color, #ced4da);\n border-radius: 8px;\n padding: 0.4rem 0.6rem;\n font-size: 0.9rem;\n resize: none;\n max-height: 80px;\n min-height: 36px;\n line-height: 1.4;\n outline: none;\n}\n\n.ai-chat-widget-input textarea:focus {\n border-color: var(--ai-widget-primary);\n box-shadow: 0 0 0 2px rgba(var(--ai-widget-primary-rgb, 108, 117, 125), 0.15);\n}\n\n.ai-chat-widget-input button {\n background: var(--ai-widget-primary);\n color: var(--bs-white, #fff);\n border: none;\n border-radius: 8px;\n padding: 0.4rem 0.75rem;\n cursor: pointer;\n font-size: 0.9rem;\n white-space: nowrap;\n}\n\n.ai-chat-widget-input .btn {\n background: var(--bs-body-bg, #fff);\n color: var(--bs-body-color, #212529);\n border: 1px solid var(--bs-border-color, #ced4da);\n}\n\n.ai-chat-widget-input .btn.btn-link {\n background: transparent;\n color: var(--bs-secondary-color, #6c757d);\n border: none;\n padding: 0.4rem;\n}\n\n.ai-chat-widget-input .btn.btn-outline-dark {\n background: var(--bs-dark, #212529);\n color: var(--bs-white, #fff);\n border-color: var(--bs-dark, #212529);\n}\n\n.ai-chat-widget-input .btn.btn-outline-secondary {\n color: var(--bs-secondary-color, #6c757d);\n}\n\n.ai-chat-widget-input button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.ai-chat-widget-status {\n padding: 0.25rem 0.75rem;\n font-size: 0.8rem;\n color: var(--bs-secondary-color, #6c757d);\n display: none;\n}\n\n.ai-chat-widget-status.visible {\n display: block;\n}\n\n.ai-chat-widget-welcome {\n text-align: center;\n color: var(--bs-secondary-color, #6c757d);\n padding: 2rem 1rem;\n font-size: 0.9rem;\n}\n\n@media (max-width: 576px) {\n .ai-chat-widget-container {\n width: calc(100vw - 1rem);\n height: calc(100vh - 6rem);\n right: 0.5rem;\n bottom: 4.5rem;\n }\n}\n"]} +{"version":3,"sources":["chat-widget.css"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"chat-widget.css","sourcesContent":["/* CrestApps AI Chat Widget */\n:root {\n --ai-widget-primary: var(--bs-secondary, #6c757d);\n --ai-widget-primary-rgb: var(--bs-secondary-rgb, 108, 117, 125);\n --ai-widget-width: 380px;\n --ai-widget-height: 520px;\n}\n\n.ai-chat-widget-toggle {\n position: fixed;\n bottom: 1.25rem;\n right: 1.25rem;\n z-index: 10000;\n width: 52px;\n height: 52px;\n border-radius: 50%;\n background: var(--ai-widget-primary);\n color: var(--bs-white, #fff);\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n box-shadow: 0 4px 12px rgba(var(--bs-body-color-rgb, 33, 37, 41), 0.2);\n transition: transform 0.2s, box-shadow 0.2s;\n}\n\n.ai-chat-widget-toggle:hover {\n transform: scale(1.1);\n box-shadow: 0 6px 16px rgba(var(--bs-body-color-rgb, 33, 37, 41), 0.3);\n}\n\n.ai-chat-widget-container {\n position: fixed;\n bottom: 5rem;\n right: 1.25rem;\n z-index: 10001;\n width: var(--ai-widget-width);\n height: var(--ai-widget-height);\n background: var(--bs-body-bg, #fff);\n color: var(--bs-body-color, #212529);\n border: 1px solid var(--bs-border-color, #dee2e6);\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(var(--bs-body-color-rgb, 33, 37, 41), 0.18);\n display: none;\n flex-direction: column;\n overflow: hidden;\n}\n\n.ai-chat-widget-container.ai-chat-widget-resizable {\n resize: both;\n min-width: 320px;\n min-height: 420px;\n max-width: min(90vw, 960px);\n max-height: min(90vh, 960px);\n}\n\n.ai-chat-widget-container.open {\n display: flex;\n}\n\n.ai-chat-widget-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.75rem 1rem;\n background: var(--ai-widget-primary);\n color: var(--bs-white, #fff);\n}\n\n.ai-chat-widget-header.ai-chat-widget-drag-handle {\n cursor: move;\n user-select: none;\n touch-action: none;\n}\n\n.ai-chat-widget-header-actions {\n display: flex;\n align-items: center;\n gap: 0.15rem;\n}\n\n.ai-chat-widget-toggle.ai-chat-widget-draggable {\n touch-action: none;\n}\n\n.ai-chat-widget-container.ai-chat-widget-dragging,\n.ai-chat-widget-toggle.ai-chat-widget-dragging {\n transition: none;\n}\n\n.ai-chat-widget-toggle.ai-chat-widget-dragging:hover {\n transform: none;\n}\n\n.ai-chat-widget-header .title {\n font-weight: 600;\n font-size: 0.95rem;\n}\n\n.ai-chat-widget-header button {\n background: none;\n border: none;\n color: var(--bs-white, #fff);\n cursor: pointer;\n font-size: 1rem;\n padding: 0 0.25rem;\n opacity: 0.8;\n}\n\n.ai-chat-widget-header button:hover {\n opacity: 1;\n}\n\n.ai-chat-widget-profile-select {\n padding: 0.5rem 0.75rem;\n border-bottom: 1px solid var(--bs-border-color, #dee2e6);\n background: var(--bs-tertiary-bg, #f8f9fa);\n}\n\n.ai-chat-widget-profile-select select {\n width: 100%;\n padding: 0.35rem 0.5rem;\n color: var(--bs-body-color, #212529);\n background-color: var(--bs-body-bg, #fff);\n border: 1px solid var(--bs-border-color, #ced4da);\n border-radius: 6px;\n font-size: 0.85rem;\n}\n\n.ai-chat-widget-messages {\n flex: 1;\n overflow-y: auto;\n padding: 0.75rem;\n font-size: 0.9rem;\n}\n\n/* ── Widget message items (ai-chat.js Vue template) ── */\n.ai-chat-widget-messages .ai-chat-messages {\n padding: 0.5rem;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item {\n position: relative;\n padding: 0.5rem 0;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item + .ai-chat-message-item::before {\n content: '';\n display: block;\n width: 100%;\n margin-bottom: 0.5rem;\n border-top: 1px solid rgba(var(--bs-body-color-rgb, 33, 37, 41), 0.08);\n}\n\n.ai-chat-widget-messages .ai-chat-message-heading {\n margin-bottom: 0.35rem;\n}\n\n.ai-chat-widget-messages .ai-chat-message-heading .ai-chat-msg-role {\n margin-bottom: 0;\n letter-spacing: 0.03em;\n}\n\n.ai-chat-widget-messages .ai-chat-message-heading-assistant .ai-chat-msg-role {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.ai-chat-widget-messages .ai-chat-message-role-label {\n display: inline-block;\n text-transform: inherit;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role {\n font-weight: 600;\n margin-bottom: 2px;\n text-transform: uppercase;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-user {\n color: var(--bs-primary, #0d6efd);\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-assistant {\n color: var(--ai-widget-primary, #6f42c1);\n}\n\n.ai-chat-widget-messages .ai-bot-icon {\n color: currentColor;\n display: inline-block;\n animation: none;\n}\n\n@keyframes ai-widget-streaming-effect {\n 0% { opacity: 1; transform: rotate(0deg); }\n 10% { opacity: 0.3; transform: rotate(0deg); }\n 20% { opacity: 1; transform: rotate(0deg); }\n 30% { opacity: 0.3; transform: rotate(0deg); }\n 40% { opacity: 1; transform: rotate(0deg); }\n 50% { opacity: 0.3; transform: rotate(0deg); }\n 60% { opacity: 1; transform: rotate(0deg); }\n 80% { opacity: 1; transform: rotate(360deg); }\n 100% { opacity: 1; transform: rotate(360deg); }\n}\n\n.ai-chat-widget-messages .ai-streaming-icon {\n color: currentColor;\n display: inline-block;\n animation: ai-widget-streaming-effect 4s ease-in-out infinite;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body {\n position: relative;\n padding: 0;\n overflow-wrap: break-word;\n word-break: break-word;\n min-width: 0;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body p:last-child {\n margin-bottom: 0;\n}\n\n/* ── Message action buttons (copy, thumbs up/down) ── */\n.ai-chat-widget-messages .message-buttons-container {\n position: absolute;\n right: 0.1rem;\n bottom: 0;\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n width: auto;\n max-width: max-content;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s ease-in-out;\n background: rgba(var(--bs-body-bg-rgb, 255, 255, 255), 0.96);\n padding: 0.2rem 0.35rem;\n border-radius: 999px;\n box-shadow: 0 1px 3px rgba(var(--bs-body-color-rgb, 33, 37, 41), 0.08);\n margin-bottom: 1rem;\n transform: translateY(50%);\n z-index: 1;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item:hover .message-buttons-container,\n.ai-chat-widget-messages .ai-chat-message-item:focus-within .message-buttons-container {\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-widget-messages .message-buttons-container:has(.tts-playing) {\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n width: 1.75rem;\n height: 1.75rem;\n margin: 0 !important;\n padding: 0 !important;\n border-radius: 50%;\n color: var(--bs-secondary-color, #6c757d) !important;\n text-decoration: none;\n}\n\n.ai-chat-widget-messages .message-buttons-container .ai-chat-message-assistant-feedback {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox:hover,\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox:focus {\n color: var(--bs-body-color, #212529) !important;\n text-decoration: none;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox.text-success,\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox.text-success:hover,\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox.text-success:focus {\n color: var(--bs-success, #198754) !important;\n text-decoration: none;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox.text-success svg {\n color: inherit !important;\n fill: currentColor;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox.tts-playing {\n color: var(--ai-widget-primary, #6f42c1) !important;\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-widget-history-panel {\n position: absolute;\n top: 3.5rem;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--bs-body-bg, #fff);\n padding: 1rem;\n z-index: 10;\n display: none;\n overflow-y: auto;\n flex-direction: column;\n}\n\n.ai-chat-widget-history-panel.show {\n display: flex;\n}\n\n.ai-chat-widget-history-panel .history-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 0.75rem;\n flex-shrink: 0;\n}\n\n.ai-chat-widget-history-panel .history-header h5 {\n margin: 0;\n font-size: 1rem;\n}\n\n.ai-chat-widget-history-list {\n list-style: none;\n padding: 0;\n margin: 0;\n overflow-y: auto;\n flex: 1 1 auto;\n}\n\n.ai-chat-widget-history-list li {\n margin-bottom: 0;\n}\n\n.ai-chat-widget-history-list .chat-session-history-item {\n display: block;\n padding: 0.5rem 0.75rem;\n text-decoration: none;\n color: var(--bs-body-color, #212529);\n font-size: 0.85rem;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n transition: background 0.15s;\n cursor: pointer;\n border-bottom: 1px solid var(--bs-border-color, #dee2e6);\n}\n\n.ai-chat-widget-history-list li:last-child .chat-session-history-item {\n border-bottom: none;\n}\n\n.ai-chat-widget-history-list .chat-session-history-item:hover {\n background: var(--bs-tertiary-bg, #f8f9fa);\n}\n\n/* ── Notifications ── */\n.ai-chat-widget-messages .ai-chat-notification {\n margin: 0.75rem 0.5rem 0;\n padding: 0.625rem 0.75rem;\n border: 1px solid rgba(var(--bs-body-color-rgb, 33, 37, 41), 0.12);\n border-radius: 0.5rem;\n background: rgba(var(--bs-tertiary-bg-rgb, 248, 249, 250), 0.98);\n}\n\n.ai-chat-widget-messages .ai-chat-notification-content {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-icon {\n margin-top: 0.1rem;\n color: var(--bs-secondary-color, #6c757d);\n}\n\n.ai-chat-widget-messages .ai-chat-notification-text {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-dismiss {\n margin-left: auto !important;\n color: var(--bs-secondary-color, #6c757d) !important;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-actions {\n display: flex;\n gap: 0.5rem;\n margin-top: 0.5rem;\n}\n\n/* ── Chart containers inside widget ── */\n.ai-chat-widget-messages .chart-container {\n width: 100%;\n max-width: 100% !important;\n min-height: 280px;\n}\n\n/* ── Embedded images inside widget ── */\n/* The panel is narrower than the renderer's inline pixel cap, so an image overflows it horizontally\n without this. The chart container above is bounded the same way and for the same reason. */\n.ai-chat-widget-messages .generated-image-container {\n /* The wrapper is a span so a figure marker written mid-sentence does not close the paragraph it\n sits in. Inline-block restores the box behaviour the layout below assumes, and a top margin\n keeps a figure off the line of text it follows. */\n display: inline-block;\n vertical-align: top;\n margin-top: 0.5rem;\n /* The positioning context for the download that sits inside it. */\n position: relative;\n}\n\n.ai-chat-widget-messages .generated-image-container img {\n max-width: 100% !important;\n max-height: 50vh;\n object-fit: contain;\n /* The panel is 380px wide, so a figure in it is a thumbnail whatever it was drawn at. Pointing at it\n says it can be opened to the size of the window. */\n cursor: zoom-in;\n}\n\n/* Deliberately not scoped to the panel. The opened picture is a copy the library appends to the document\n body, which is outside the widget entirely, so a rule under .ai-chat-widget-messages never reaches it.\n It is repeated from ai-chat.css because a page that mounts only the widget loads only this file. The\n copy carries the thumbnail's classes, so the frame and the cap are taken off here -- both are scaled up\n with the drawing and would otherwise ring the picture with a broad white border. */\nimg.medium-zoom-image--opened {\n max-width: none !important;\n max-height: none !important;\n padding: 0;\n border: 0;\n background: none;\n}\n\n/* Over the picture's lower corner rather than below it. In a panel this narrow a row of its own cost a\n band of vertical space per figure, which a conversation full of them pays for once each. */\n.ai-chat-widget-messages .generated-image-container .ai-download-image {\n position: absolute;\n right: 0.5rem;\n bottom: 0.5rem;\n z-index: 2;\n opacity: 0;\n color: #1f2933;\n background-color: rgba(255, 255, 255, 0.92);\n border-color: rgba(0, 0, 0, 0.15);\n transition: opacity 0.15s ease-in-out;\n}\n\n/* The outline button this is built from inverts on hover: it fills itself with its own colour and turns\n its label white. Against the pale ground kept here that leaves a white icon on white -- the button is\n still there and still works, but there is nothing to see. Both colours are therefore stated for every\n state the button can be in rather than only the resting one. */\n.ai-chat-widget-messages .generated-image-container .ai-download-image:hover,\n.ai-chat-widget-messages .generated-image-container .ai-download-image:focus,\n.ai-chat-widget-messages .generated-image-container .ai-download-image:focus-visible,\n.ai-chat-widget-messages .generated-image-container .ai-download-image:active {\n color: #1f2933;\n background-color: #ffffff;\n border-color: rgba(0, 0, 0, 0.35);\n}\n\n/* Revealed by pointing at the figure. focus-within is what keeps it reachable by keyboard: the button is\n invisible until it takes focus, and an invisible control that cannot be brought into view cannot be\n used at all. */\n.ai-chat-widget-messages .generated-image-container:hover .ai-download-image,\n.ai-chat-widget-messages .generated-image-container:focus-within .ai-download-image {\n opacity: 1;\n}\n\n/* A touch screen has no hover to reveal it with, so there it is simply always shown. The widget is the\n surface most likely to be read on one. */\n@media (hover: none) {\n .ai-chat-widget-messages .generated-image-container .ai-download-image {\n opacity: 1;\n }\n}\n\n/* ── Tables inside widget ── */\n/* The panel is 380px wide, so an ingested table almost always exceeds it. Scrolling the table itself keeps\n the conversation column intact; the alternative is a sideways-scrolling chat. */\n.ai-chat-widget-messages table {\n display: block;\n width: max-content;\n min-width: 100%;\n max-width: 100%;\n overflow-x: auto;\n margin-bottom: 0.75rem;\n border-collapse: collapse;\n font-size: 0.8125rem;\n}\n\n.ai-chat-widget-messages table th,\n.ai-chat-widget-messages table td {\n padding: 0.3rem 0.5rem;\n border: 1px solid var(--bs-border-color, #dee2e6);\n text-align: left;\n vertical-align: top;\n}\n\n.ai-chat-widget-messages table thead th {\n background-color: var(--bs-secondary-bg, #e9ecef);\n font-weight: 600;\n white-space: nowrap;\n}\n\n.ai-chat-widget-messages table tbody tr:nth-child(even) {\n background-color: var(--bs-tertiary-bg, #f8f9fa);\n}\n\n/* ── Code blocks & inline code ── */\n.ai-chat-widget-messages .ai-chat-message-body pre {\n background: var(--bs-dark-bg-subtle, #2d2d2d);\n color: var(--bs-emphasis-color, #f8f8f2);\n padding: 0.5rem;\n border-radius: 4px;\n overflow-x: auto;\n font-size: 0.8rem;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body code {\n font-size: 0.85em;\n}\n\n.ai-chat-widget-input {\n border-top: 1px solid var(--bs-border-color, #dee2e6);\n padding: 0.5rem 0.75rem;\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n align-items: flex-end;\n}\n\n.ai-chat-widget-input .ai-chat-doc-bar {\n flex: 0 0 100%;\n margin: -0.5rem -0.75rem 0.5rem;\n padding: 0.5rem 0.75rem;\n max-height: 4.5rem;\n overflow-y: auto;\n}\n\n.ai-chat-widget-input textarea {\n flex: 1;\n min-width: 0;\n color: var(--bs-body-color, #212529);\n background-color: var(--bs-body-bg, #fff);\n border: 1px solid var(--bs-border-color, #ced4da);\n border-radius: 8px;\n padding: 0.4rem 0.6rem;\n font-size: 0.9rem;\n resize: none;\n max-height: 80px;\n min-height: 36px;\n line-height: 1.4;\n outline: none;\n}\n\n.ai-chat-widget-input textarea:focus {\n border-color: var(--ai-widget-primary);\n box-shadow: 0 0 0 2px rgba(var(--ai-widget-primary-rgb, 108, 117, 125), 0.15);\n}\n\n.ai-chat-widget-input button {\n background: var(--ai-widget-primary);\n color: var(--bs-white, #fff);\n border: none;\n border-radius: 8px;\n padding: 0.4rem 0.75rem;\n cursor: pointer;\n font-size: 0.9rem;\n white-space: nowrap;\n}\n\n.ai-chat-widget-input .btn {\n background: var(--bs-body-bg, #fff);\n color: var(--bs-body-color, #212529);\n border: 1px solid var(--bs-border-color, #ced4da);\n}\n\n.ai-chat-widget-input .btn.btn-link {\n background: transparent;\n color: var(--bs-secondary-color, #6c757d);\n border: none;\n padding: 0.4rem;\n}\n\n.ai-chat-widget-input .btn.btn-outline-dark {\n background: var(--bs-dark, #212529);\n color: var(--bs-white, #fff);\n border-color: var(--bs-dark, #212529);\n}\n\n.ai-chat-widget-input .btn.btn-outline-secondary {\n color: var(--bs-secondary-color, #6c757d);\n}\n\n.ai-chat-widget-input button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.ai-chat-widget-status {\n padding: 0.25rem 0.75rem;\n font-size: 0.8rem;\n color: var(--bs-secondary-color, #6c757d);\n display: none;\n}\n\n.ai-chat-widget-status.visible {\n display: block;\n}\n\n.ai-chat-widget-welcome {\n text-align: center;\n color: var(--bs-secondary-color, #6c757d);\n padding: 2rem 1rem;\n font-size: 0.9rem;\n}\n\n@media (max-width: 576px) {\n .ai-chat-widget-container {\n width: calc(100vw - 1rem);\n height: calc(100vh - 6rem);\n right: 0.5rem;\n bottom: 4.5rem;\n }\n}\n"]} diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.min.css b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.min.css index cf33850f..4eda1f51 100644 --- a/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.min.css +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.min.css @@ -1 +1 @@ -:root{--ai-widget-primary:var(--bs-secondary, #6c757d);--ai-widget-primary-rgb:var(--bs-secondary-rgb, 108, 117, 125);--ai-widget-width:380px;--ai-widget-height:520px}.ai-chat-widget-toggle{position:fixed;bottom:1.25rem;right:1.25rem;z-index:10000;width:52px;height:52px;border-radius:50%;background:var(--ai-widget-primary);color:var(--bs-white,#fff);border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:1.5rem;box-shadow:0 4px 12px rgba(var(--bs-body-color-rgb,33,37,41),.2);transition:transform .2s,box-shadow .2s}.ai-chat-widget-toggle:hover{transform:scale(1.1);box-shadow:0 6px 16px rgba(var(--bs-body-color-rgb,33,37,41),.3)}.ai-chat-widget-container{position:fixed;bottom:5rem;right:1.25rem;z-index:10001;width:var(--ai-widget-width);height:var(--ai-widget-height);background:var(--bs-body-bg,#fff);color:var(--bs-body-color,#212529);border:1px solid var(--bs-border-color,#dee2e6);border-radius:12px;box-shadow:0 8px 32px rgba(var(--bs-body-color-rgb,33,37,41),.18);display:none;flex-direction:column;overflow:hidden}.ai-chat-widget-container.ai-chat-widget-resizable{resize:both;min-width:320px;min-height:420px;max-width:min(90vw,960px);max-height:min(90vh,960px)}.ai-chat-widget-container.open{display:flex}.ai-chat-widget-header{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;background:var(--ai-widget-primary);color:var(--bs-white,#fff)}.ai-chat-widget-header.ai-chat-widget-drag-handle{cursor:move;user-select:none;touch-action:none}.ai-chat-widget-header-actions{display:flex;align-items:center;gap:.15rem}.ai-chat-widget-toggle.ai-chat-widget-draggable{touch-action:none}.ai-chat-widget-container.ai-chat-widget-dragging,.ai-chat-widget-toggle.ai-chat-widget-dragging{transition:none}.ai-chat-widget-toggle.ai-chat-widget-dragging:hover{transform:none}.ai-chat-widget-header .title{font-weight:600;font-size:.95rem}.ai-chat-widget-header button{background:0 0;border:none;color:var(--bs-white,#fff);cursor:pointer;font-size:1rem;padding:0 .25rem;opacity:.8}.ai-chat-widget-header button:hover{opacity:1}.ai-chat-widget-profile-select{padding:.5rem .75rem;border-bottom:1px solid var(--bs-border-color,#dee2e6);background:var(--bs-tertiary-bg,#f8f9fa)}.ai-chat-widget-profile-select select{width:100%;padding:.35rem .5rem;color:var(--bs-body-color,#212529);background-color:var(--bs-body-bg,#fff);border:1px solid var(--bs-border-color,#ced4da);border-radius:6px;font-size:.85rem}.ai-chat-widget-messages{flex:1;overflow-y:auto;padding:.75rem;font-size:.9rem}.ai-chat-widget-messages .ai-chat-messages{padding:.5rem}.ai-chat-widget-messages .ai-chat-message-item{position:relative;padding:.5rem 0}.ai-chat-widget-messages .ai-chat-message-item+.ai-chat-message-item::before{content:'';display:block;width:100%;margin-bottom:.5rem;border-top:1px solid rgba(var(--bs-body-color-rgb,33,37,41),.08)}.ai-chat-widget-messages .ai-chat-message-heading{margin-bottom:.35rem}.ai-chat-widget-messages .ai-chat-message-heading .ai-chat-msg-role{margin-bottom:0;letter-spacing:.03em}.ai-chat-widget-messages .ai-chat-message-heading-assistant .ai-chat-msg-role{display:inline-flex;align-items:center;gap:.35rem}.ai-chat-widget-messages .ai-chat-message-role-label{display:inline-block;text-transform:inherit}.ai-chat-widget-messages .ai-chat-msg-role{font-weight:600;margin-bottom:2px;text-transform:uppercase}.ai-chat-widget-messages .ai-chat-msg-role-user{color:var(--bs-primary,#0d6efd)}.ai-chat-widget-messages .ai-chat-msg-role-assistant{color:var(--ai-widget-primary,#6f42c1)}.ai-chat-widget-messages .ai-bot-icon{color:currentColor;display:inline-block;animation:none}@keyframes ai-widget-streaming-effect{0%{opacity:1;transform:rotate(0)}10%{opacity:.3;transform:rotate(0)}20%{opacity:1;transform:rotate(0)}30%{opacity:.3;transform:rotate(0)}40%{opacity:1;transform:rotate(0)}50%{opacity:.3;transform:rotate(0)}60%{opacity:1;transform:rotate(0)}80%{opacity:1;transform:rotate(360deg)}100%{opacity:1;transform:rotate(360deg)}}.ai-chat-widget-messages .ai-streaming-icon{color:currentColor;display:inline-block;animation:ai-widget-streaming-effect 4s ease-in-out infinite}.ai-chat-widget-messages .ai-chat-message-body{position:relative;padding:0;overflow-wrap:break-word;word-break:break-word;min-width:0}.ai-chat-widget-messages .ai-chat-message-body p:last-child{margin-bottom:0}.ai-chat-widget-messages .message-buttons-container{position:absolute;right:.1rem;bottom:0;display:inline-flex;align-items:center;gap:.35rem;width:auto;max-width:max-content;opacity:0;pointer-events:none;transition:opacity .15s ease-in-out;background:rgba(var(--bs-body-bg-rgb,255,255,255),.96);padding:.2rem .35rem;border-radius:999px;box-shadow:0 1px 3px rgba(var(--bs-body-color-rgb,33,37,41),.08);margin-bottom:1rem;transform:translateY(50%);z-index:1}.ai-chat-widget-messages .ai-chat-message-item:focus-within .message-buttons-container,.ai-chat-widget-messages .ai-chat-message-item:hover .message-buttons-container{opacity:1;pointer-events:auto}.ai-chat-widget-messages .message-buttons-container:has(.tts-playing){opacity:1;pointer-events:auto}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:1.75rem;height:1.75rem;margin:0!important;padding:0!important;border-radius:50%;color:var(--bs-secondary-color,#6c757d)!important;text-decoration:none}.ai-chat-widget-messages .message-buttons-container .ai-chat-message-assistant-feedback{display:inline-flex;align-items:center;gap:.35rem}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox:focus,.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox:hover{color:var(--bs-body-color,#212529)!important;text-decoration:none}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox.text-success,.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox.text-success:focus,.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox.text-success:hover{color:var(--bs-success,#198754)!important;text-decoration:none}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox.text-success svg{color:inherit!important;fill:currentColor}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox.tts-playing{color:var(--ai-widget-primary,#6f42c1)!important;opacity:1;pointer-events:auto}.ai-chat-widget-history-panel{position:absolute;top:3.5rem;left:0;right:0;bottom:0;background:var(--bs-body-bg,#fff);padding:1rem;z-index:10;display:none;overflow-y:auto;flex-direction:column}.ai-chat-widget-history-panel.show{display:flex}.ai-chat-widget-history-panel .history-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.75rem;flex-shrink:0}.ai-chat-widget-history-panel .history-header h5{margin:0;font-size:1rem}.ai-chat-widget-history-list{list-style:none;padding:0;margin:0;overflow-y:auto;flex:1 1 auto}.ai-chat-widget-history-list li{margin-bottom:0}.ai-chat-widget-history-list .chat-session-history-item{display:block;padding:.5rem .75rem;text-decoration:none;color:var(--bs-body-color,#212529);font-size:.85rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:background .15s;cursor:pointer;border-bottom:1px solid var(--bs-border-color,#dee2e6)}.ai-chat-widget-history-list li:last-child .chat-session-history-item{border-bottom:none}.ai-chat-widget-history-list .chat-session-history-item:hover{background:var(--bs-tertiary-bg,#f8f9fa)}.ai-chat-widget-messages .ai-chat-notification{margin:.75rem .5rem 0;padding:.625rem .75rem;border:1px solid rgba(var(--bs-body-color-rgb,33,37,41),.12);border-radius:.5rem;background:rgba(var(--bs-tertiary-bg-rgb,248,249,250),.98)}.ai-chat-widget-messages .ai-chat-notification-content{display:flex;align-items:flex-start;gap:.5rem}.ai-chat-widget-messages .ai-chat-notification-icon{margin-top:.1rem;color:var(--bs-secondary-color,#6c757d)}.ai-chat-widget-messages .ai-chat-notification-text{flex:1 1 auto;min-width:0}.ai-chat-widget-messages .ai-chat-notification-dismiss{margin-left:auto!important;color:var(--bs-secondary-color,#6c757d)!important}.ai-chat-widget-messages .ai-chat-notification-actions{display:flex;gap:.5rem;margin-top:.5rem}.ai-chat-widget-messages .chart-container{width:100%;max-width:100%!important;min-height:280px}.ai-chat-widget-messages .generated-image-container{display:inline-block;vertical-align:top;margin-top:.5rem}.ai-chat-widget-messages .generated-image-container img{max-width:100%!important;max-height:50vh;object-fit:contain}.ai-chat-widget-messages table{display:block;width:max-content;min-width:100%;max-width:100%;overflow-x:auto;margin-bottom:.75rem;border-collapse:collapse;font-size:.8125rem}.ai-chat-widget-messages table td,.ai-chat-widget-messages table th{padding:.3rem .5rem;border:1px solid var(--bs-border-color,#dee2e6);text-align:left;vertical-align:top}.ai-chat-widget-messages table thead th{background-color:var(--bs-secondary-bg,#e9ecef);font-weight:600;white-space:nowrap}.ai-chat-widget-messages table tbody tr:nth-child(even){background-color:var(--bs-tertiary-bg,#f8f9fa)}.ai-chat-widget-messages .ai-chat-message-body pre{background:var(--bs-dark-bg-subtle,#2d2d2d);color:var(--bs-emphasis-color,#f8f8f2);padding:.5rem;border-radius:4px;overflow-x:auto;font-size:.8rem}.ai-chat-widget-messages .ai-chat-message-body code{font-size:.85em}.ai-chat-widget-input{border-top:1px solid var(--bs-border-color,#dee2e6);padding:.5rem .75rem;display:flex;flex-wrap:wrap;gap:.5rem;align-items:flex-end}.ai-chat-widget-input .ai-chat-doc-bar{flex:0 0 100%;margin:-.5rem -.75rem .5rem;padding:.5rem .75rem;max-height:4.5rem;overflow-y:auto}.ai-chat-widget-input textarea{flex:1;min-width:0;color:var(--bs-body-color,#212529);background-color:var(--bs-body-bg,#fff);border:1px solid var(--bs-border-color,#ced4da);border-radius:8px;padding:.4rem .6rem;font-size:.9rem;resize:none;max-height:80px;min-height:36px;line-height:1.4;outline:0}.ai-chat-widget-input textarea:focus{border-color:var(--ai-widget-primary);box-shadow:0 0 0 2px rgba(var(--ai-widget-primary-rgb,108,117,125),.15)}.ai-chat-widget-input button{background:var(--ai-widget-primary);color:var(--bs-white,#fff);border:none;border-radius:8px;padding:.4rem .75rem;cursor:pointer;font-size:.9rem;white-space:nowrap}.ai-chat-widget-input .btn{background:var(--bs-body-bg,#fff);color:var(--bs-body-color,#212529);border:1px solid var(--bs-border-color,#ced4da)}.ai-chat-widget-input .btn.btn-link{background:0 0;color:var(--bs-secondary-color,#6c757d);border:none;padding:.4rem}.ai-chat-widget-input .btn.btn-outline-dark{background:var(--bs-dark,#212529);color:var(--bs-white,#fff);border-color:var(--bs-dark,#212529)}.ai-chat-widget-input .btn.btn-outline-secondary{color:var(--bs-secondary-color,#6c757d)}.ai-chat-widget-input button:disabled{opacity:.5;cursor:not-allowed}.ai-chat-widget-status{padding:.25rem .75rem;font-size:.8rem;color:var(--bs-secondary-color,#6c757d);display:none}.ai-chat-widget-status.visible{display:block}.ai-chat-widget-welcome{text-align:center;color:var(--bs-secondary-color,#6c757d);padding:2rem 1rem;font-size:.9rem}@media (max-width:576px){.ai-chat-widget-container{width:calc(100vw - 1rem);height:calc(100vh - 6rem);right:.5rem;bottom:4.5rem}} +:root{--ai-widget-primary:var(--bs-secondary, #6c757d);--ai-widget-primary-rgb:var(--bs-secondary-rgb, 108, 117, 125);--ai-widget-width:380px;--ai-widget-height:520px}.ai-chat-widget-toggle{position:fixed;bottom:1.25rem;right:1.25rem;z-index:10000;width:52px;height:52px;border-radius:50%;background:var(--ai-widget-primary);color:var(--bs-white,#fff);border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:1.5rem;box-shadow:0 4px 12px rgba(var(--bs-body-color-rgb,33,37,41),.2);transition:transform .2s,box-shadow .2s}.ai-chat-widget-toggle:hover{transform:scale(1.1);box-shadow:0 6px 16px rgba(var(--bs-body-color-rgb,33,37,41),.3)}.ai-chat-widget-container{position:fixed;bottom:5rem;right:1.25rem;z-index:10001;width:var(--ai-widget-width);height:var(--ai-widget-height);background:var(--bs-body-bg,#fff);color:var(--bs-body-color,#212529);border:1px solid var(--bs-border-color,#dee2e6);border-radius:12px;box-shadow:0 8px 32px rgba(var(--bs-body-color-rgb,33,37,41),.18);display:none;flex-direction:column;overflow:hidden}.ai-chat-widget-container.ai-chat-widget-resizable{resize:both;min-width:320px;min-height:420px;max-width:min(90vw,960px);max-height:min(90vh,960px)}.ai-chat-widget-container.open{display:flex}.ai-chat-widget-header{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;background:var(--ai-widget-primary);color:var(--bs-white,#fff)}.ai-chat-widget-header.ai-chat-widget-drag-handle{cursor:move;user-select:none;touch-action:none}.ai-chat-widget-header-actions{display:flex;align-items:center;gap:.15rem}.ai-chat-widget-toggle.ai-chat-widget-draggable{touch-action:none}.ai-chat-widget-container.ai-chat-widget-dragging,.ai-chat-widget-toggle.ai-chat-widget-dragging{transition:none}.ai-chat-widget-toggle.ai-chat-widget-dragging:hover{transform:none}.ai-chat-widget-header .title{font-weight:600;font-size:.95rem}.ai-chat-widget-header button{background:0 0;border:none;color:var(--bs-white,#fff);cursor:pointer;font-size:1rem;padding:0 .25rem;opacity:.8}.ai-chat-widget-header button:hover{opacity:1}.ai-chat-widget-profile-select{padding:.5rem .75rem;border-bottom:1px solid var(--bs-border-color,#dee2e6);background:var(--bs-tertiary-bg,#f8f9fa)}.ai-chat-widget-profile-select select{width:100%;padding:.35rem .5rem;color:var(--bs-body-color,#212529);background-color:var(--bs-body-bg,#fff);border:1px solid var(--bs-border-color,#ced4da);border-radius:6px;font-size:.85rem}.ai-chat-widget-messages{flex:1;overflow-y:auto;padding:.75rem;font-size:.9rem}.ai-chat-widget-messages .ai-chat-messages{padding:.5rem}.ai-chat-widget-messages .ai-chat-message-item{position:relative;padding:.5rem 0}.ai-chat-widget-messages .ai-chat-message-item+.ai-chat-message-item::before{content:'';display:block;width:100%;margin-bottom:.5rem;border-top:1px solid rgba(var(--bs-body-color-rgb,33,37,41),.08)}.ai-chat-widget-messages .ai-chat-message-heading{margin-bottom:.35rem}.ai-chat-widget-messages .ai-chat-message-heading .ai-chat-msg-role{margin-bottom:0;letter-spacing:.03em}.ai-chat-widget-messages .ai-chat-message-heading-assistant .ai-chat-msg-role{display:inline-flex;align-items:center;gap:.35rem}.ai-chat-widget-messages .ai-chat-message-role-label{display:inline-block;text-transform:inherit}.ai-chat-widget-messages .ai-chat-msg-role{font-weight:600;margin-bottom:2px;text-transform:uppercase}.ai-chat-widget-messages .ai-chat-msg-role-user{color:var(--bs-primary,#0d6efd)}.ai-chat-widget-messages .ai-chat-msg-role-assistant{color:var(--ai-widget-primary,#6f42c1)}.ai-chat-widget-messages .ai-bot-icon{color:currentColor;display:inline-block;animation:none}@keyframes ai-widget-streaming-effect{0%{opacity:1;transform:rotate(0)}10%{opacity:.3;transform:rotate(0)}20%{opacity:1;transform:rotate(0)}30%{opacity:.3;transform:rotate(0)}40%{opacity:1;transform:rotate(0)}50%{opacity:.3;transform:rotate(0)}60%{opacity:1;transform:rotate(0)}80%{opacity:1;transform:rotate(360deg)}100%{opacity:1;transform:rotate(360deg)}}.ai-chat-widget-messages .ai-streaming-icon{color:currentColor;display:inline-block;animation:ai-widget-streaming-effect 4s ease-in-out infinite}.ai-chat-widget-messages .ai-chat-message-body{position:relative;padding:0;overflow-wrap:break-word;word-break:break-word;min-width:0}.ai-chat-widget-messages .ai-chat-message-body p:last-child{margin-bottom:0}.ai-chat-widget-messages .message-buttons-container{position:absolute;right:.1rem;bottom:0;display:inline-flex;align-items:center;gap:.35rem;width:auto;max-width:max-content;opacity:0;pointer-events:none;transition:opacity .15s ease-in-out;background:rgba(var(--bs-body-bg-rgb,255,255,255),.96);padding:.2rem .35rem;border-radius:999px;box-shadow:0 1px 3px rgba(var(--bs-body-color-rgb,33,37,41),.08);margin-bottom:1rem;transform:translateY(50%);z-index:1}.ai-chat-widget-messages .ai-chat-message-item:focus-within .message-buttons-container,.ai-chat-widget-messages .ai-chat-message-item:hover .message-buttons-container{opacity:1;pointer-events:auto}.ai-chat-widget-messages .message-buttons-container:has(.tts-playing){opacity:1;pointer-events:auto}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:1.75rem;height:1.75rem;margin:0!important;padding:0!important;border-radius:50%;color:var(--bs-secondary-color,#6c757d)!important;text-decoration:none}.ai-chat-widget-messages .message-buttons-container .ai-chat-message-assistant-feedback{display:inline-flex;align-items:center;gap:.35rem}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox:focus,.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox:hover{color:var(--bs-body-color,#212529)!important;text-decoration:none}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox.text-success,.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox.text-success:focus,.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox.text-success:hover{color:var(--bs-success,#198754)!important;text-decoration:none}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox.text-success svg{color:inherit!important;fill:currentColor}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox.tts-playing{color:var(--ai-widget-primary,#6f42c1)!important;opacity:1;pointer-events:auto}.ai-chat-widget-history-panel{position:absolute;top:3.5rem;left:0;right:0;bottom:0;background:var(--bs-body-bg,#fff);padding:1rem;z-index:10;display:none;overflow-y:auto;flex-direction:column}.ai-chat-widget-history-panel.show{display:flex}.ai-chat-widget-history-panel .history-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.75rem;flex-shrink:0}.ai-chat-widget-history-panel .history-header h5{margin:0;font-size:1rem}.ai-chat-widget-history-list{list-style:none;padding:0;margin:0;overflow-y:auto;flex:1 1 auto}.ai-chat-widget-history-list li{margin-bottom:0}.ai-chat-widget-history-list .chat-session-history-item{display:block;padding:.5rem .75rem;text-decoration:none;color:var(--bs-body-color,#212529);font-size:.85rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:background .15s;cursor:pointer;border-bottom:1px solid var(--bs-border-color,#dee2e6)}.ai-chat-widget-history-list li:last-child .chat-session-history-item{border-bottom:none}.ai-chat-widget-history-list .chat-session-history-item:hover{background:var(--bs-tertiary-bg,#f8f9fa)}.ai-chat-widget-messages .ai-chat-notification{margin:.75rem .5rem 0;padding:.625rem .75rem;border:1px solid rgba(var(--bs-body-color-rgb,33,37,41),.12);border-radius:.5rem;background:rgba(var(--bs-tertiary-bg-rgb,248,249,250),.98)}.ai-chat-widget-messages .ai-chat-notification-content{display:flex;align-items:flex-start;gap:.5rem}.ai-chat-widget-messages .ai-chat-notification-icon{margin-top:.1rem;color:var(--bs-secondary-color,#6c757d)}.ai-chat-widget-messages .ai-chat-notification-text{flex:1 1 auto;min-width:0}.ai-chat-widget-messages .ai-chat-notification-dismiss{margin-left:auto!important;color:var(--bs-secondary-color,#6c757d)!important}.ai-chat-widget-messages .ai-chat-notification-actions{display:flex;gap:.5rem;margin-top:.5rem}.ai-chat-widget-messages .chart-container{width:100%;max-width:100%!important;min-height:280px}.ai-chat-widget-messages .generated-image-container{display:inline-block;vertical-align:top;margin-top:.5rem;position:relative}.ai-chat-widget-messages .generated-image-container img{max-width:100%!important;max-height:50vh;object-fit:contain;cursor:zoom-in}img.medium-zoom-image--opened{max-width:none!important;max-height:none!important;padding:0;border:0;background:0 0}.ai-chat-widget-messages .generated-image-container .ai-download-image{position:absolute;right:.5rem;bottom:.5rem;z-index:2;opacity:0;color:#1f2933;background-color:rgba(255,255,255,.92);border-color:rgba(0,0,0,.15);transition:opacity .15s ease-in-out}.ai-chat-widget-messages .generated-image-container .ai-download-image:active,.ai-chat-widget-messages .generated-image-container .ai-download-image:focus,.ai-chat-widget-messages .generated-image-container .ai-download-image:focus-visible,.ai-chat-widget-messages .generated-image-container .ai-download-image:hover{color:#1f2933;background-color:#fff;border-color:rgba(0,0,0,.35)}.ai-chat-widget-messages .generated-image-container:focus-within .ai-download-image,.ai-chat-widget-messages .generated-image-container:hover .ai-download-image{opacity:1}@media (hover:none){.ai-chat-widget-messages .generated-image-container .ai-download-image{opacity:1}}.ai-chat-widget-messages table{display:block;width:max-content;min-width:100%;max-width:100%;overflow-x:auto;margin-bottom:.75rem;border-collapse:collapse;font-size:.8125rem}.ai-chat-widget-messages table td,.ai-chat-widget-messages table th{padding:.3rem .5rem;border:1px solid var(--bs-border-color,#dee2e6);text-align:left;vertical-align:top}.ai-chat-widget-messages table thead th{background-color:var(--bs-secondary-bg,#e9ecef);font-weight:600;white-space:nowrap}.ai-chat-widget-messages table tbody tr:nth-child(even){background-color:var(--bs-tertiary-bg,#f8f9fa)}.ai-chat-widget-messages .ai-chat-message-body pre{background:var(--bs-dark-bg-subtle,#2d2d2d);color:var(--bs-emphasis-color,#f8f8f2);padding:.5rem;border-radius:4px;overflow-x:auto;font-size:.8rem}.ai-chat-widget-messages .ai-chat-message-body code{font-size:.85em}.ai-chat-widget-input{border-top:1px solid var(--bs-border-color,#dee2e6);padding:.5rem .75rem;display:flex;flex-wrap:wrap;gap:.5rem;align-items:flex-end}.ai-chat-widget-input .ai-chat-doc-bar{flex:0 0 100%;margin:-.5rem -.75rem .5rem;padding:.5rem .75rem;max-height:4.5rem;overflow-y:auto}.ai-chat-widget-input textarea{flex:1;min-width:0;color:var(--bs-body-color,#212529);background-color:var(--bs-body-bg,#fff);border:1px solid var(--bs-border-color,#ced4da);border-radius:8px;padding:.4rem .6rem;font-size:.9rem;resize:none;max-height:80px;min-height:36px;line-height:1.4;outline:0}.ai-chat-widget-input textarea:focus{border-color:var(--ai-widget-primary);box-shadow:0 0 0 2px rgba(var(--ai-widget-primary-rgb,108,117,125),.15)}.ai-chat-widget-input button{background:var(--ai-widget-primary);color:var(--bs-white,#fff);border:none;border-radius:8px;padding:.4rem .75rem;cursor:pointer;font-size:.9rem;white-space:nowrap}.ai-chat-widget-input .btn{background:var(--bs-body-bg,#fff);color:var(--bs-body-color,#212529);border:1px solid var(--bs-border-color,#ced4da)}.ai-chat-widget-input .btn.btn-link{background:0 0;color:var(--bs-secondary-color,#6c757d);border:none;padding:.4rem}.ai-chat-widget-input .btn.btn-outline-dark{background:var(--bs-dark,#212529);color:var(--bs-white,#fff);border-color:var(--bs-dark,#212529)}.ai-chat-widget-input .btn.btn-outline-secondary{color:var(--bs-secondary-color,#6c757d)}.ai-chat-widget-input button:disabled{opacity:.5;cursor:not-allowed}.ai-chat-widget-status{padding:.25rem .75rem;font-size:.8rem;color:var(--bs-secondary-color,#6c757d);display:none}.ai-chat-widget-status.visible{display:block}.ai-chat-widget-welcome{text-align:center;color:var(--bs-secondary-color,#6c757d);padding:2rem 1rem;font-size:.9rem}@media (max-width:576px){.ai-chat-widget-container{width:calc(100vw - 1rem);height:calc(100vh - 6rem);right:.5rem;bottom:4.5rem}}