@cnt-dev/chat-ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/AGENTS.md +202 -0
  2. package/LICENSE +21 -0
  3. package/README.md +303 -0
  4. package/index.d.ts +23 -0
  5. package/package.json +41 -0
  6. package/resources/chatui/.library +14 -0
  7. package/resources/chatui/ChatBox-dbg.js +1099 -0
  8. package/resources/chatui/ChatBox-dbg.js.map +1 -0
  9. package/resources/chatui/ChatBox.d.ts +308 -0
  10. package/resources/chatui/ChatBox.d.ts.map +1 -0
  11. package/resources/chatui/ChatBox.gen.d.ts +545 -0
  12. package/resources/chatui/ChatBox.js +5 -0
  13. package/resources/chatui/ChatBox.js.map +1 -0
  14. package/resources/chatui/ChatBox.ts +1153 -0
  15. package/resources/chatui/library-dbg.js +28 -0
  16. package/resources/chatui/library-dbg.js.map +1 -0
  17. package/resources/chatui/library-preload.js +17 -0
  18. package/resources/chatui/library-preload.js.map +1 -0
  19. package/resources/chatui/library.d.ts +3 -0
  20. package/resources/chatui/library.d.ts.map +1 -0
  21. package/resources/chatui/library.js +5 -0
  22. package/resources/chatui/library.js.map +1 -0
  23. package/resources/chatui/library.ts +30 -0
  24. package/resources/chatui/manifest.json +52 -0
  25. package/resources/chatui/markdown-dbg.js +116 -0
  26. package/resources/chatui/markdown-dbg.js.map +1 -0
  27. package/resources/chatui/markdown.d.ts +21 -0
  28. package/resources/chatui/markdown.d.ts.map +1 -0
  29. package/resources/chatui/markdown.js +5 -0
  30. package/resources/chatui/markdown.js.map +1 -0
  31. package/resources/chatui/markdown.ts +140 -0
  32. package/resources/chatui/messagebundle.properties +20 -0
  33. package/resources/chatui/messagebundle_en.properties +20 -0
  34. package/resources/chatui/themes/base/ChatBox.less +702 -0
  35. package/resources/chatui/themes/base/library-RTL.css +3 -0
  36. package/resources/chatui/themes/base/library-parameters.json +1 -0
  37. package/resources/chatui/themes/base/library.css +3 -0
  38. package/resources/chatui/themes/base/library.source.less +4 -0
  39. package/resources/chatui/themes/sap_fiori_3/library-RTL.css +3 -0
  40. package/resources/chatui/themes/sap_fiori_3/library-parameters.json +1 -0
  41. package/resources/chatui/themes/sap_fiori_3/library.css +3 -0
  42. package/resources/chatui/themes/sap_fiori_3/library.source.less +3 -0
  43. package/resources/chatui/themes/sap_fiori_3_dark/library-RTL.css +3 -0
  44. package/resources/chatui/themes/sap_fiori_3_dark/library-parameters.json +1 -0
  45. package/resources/chatui/themes/sap_fiori_3_dark/library.css +3 -0
  46. package/resources/chatui/themes/sap_fiori_3_dark/library.source.less +3 -0
  47. package/resources/chatui/themes/sap_fiori_3_hcb/library-RTL.css +3 -0
  48. package/resources/chatui/themes/sap_fiori_3_hcb/library-parameters.json +1 -0
  49. package/resources/chatui/themes/sap_fiori_3_hcb/library.css +3 -0
  50. package/resources/chatui/themes/sap_fiori_3_hcb/library.source.less +3 -0
  51. package/resources/chatui/themes/sap_fiori_3_hcw/library-RTL.css +3 -0
  52. package/resources/chatui/themes/sap_fiori_3_hcw/library-parameters.json +1 -0
  53. package/resources/chatui/themes/sap_fiori_3_hcw/library.css +3 -0
  54. package/resources/chatui/themes/sap_fiori_3_hcw/library.source.less +3 -0
  55. package/ui5.yaml +15 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatBox.js","names":["sap","ui","define","Control","IconPool","Lib","Localization","__markdownToHtml","_interopRequireDefault","obj","__esModule","default","markdownToHtml","ChatBox","extend","renderer","apiVersion","render","rm","control","sendIcon","getIconInfo","newChatIcon","attachIcon","i18n","_i18n","placeholder","getPlaceholder","getText","allowAttachments","getAllowAttachments","openStart","class","style","getWidth","getHeight","openEnd","text","close","getId","attr","fontFamily","content","getBusy","voidStart","getAttachmentAccept","voidEnd","metadata","library","properties","type","group","defaultValue","busy","width","height","attachmentAccept","conversations","activeConversationId","events","send","parameters","message","files","conversationId","newChat","conversationSelect","id","conversationDelete","constructor","_constructor","settings","Control.prototype.constructor.call","this","_messages","_pendingAttachments","_conversations","_initialised","_onLocaleChange","invalidate","init","_init","attachChange","exit","_exit","detachChange","onAfterRendering","_onAfterRendering","textarea","_dom","sendBtn","newChatBtn","addEventListener","Math","min","scrollHeight","e","key","shiftKey","preventDefault","_submit","_startNewChat","_wireAttachments","_renderSidebar","_renderHeaderTitle","_restoreMessages","_renderPending","addAssistantMessage","_addAssistantMessage","push","role","_appendMessageDom","length","appendToLastAssistantMessage","_appendToLastAssistantMessage","chunk","last","_updateBubble","addAssistantControl","_addAssistantControl","addDependent","clear","_clear","destroyDependents","getMessages","_getMessages","slice","setMessages","_setMessages","messages","_sanitiseMessages","setConversations","_setConversations","list","_sanitiseConversations","setProperty","getActiveConversationId","first","getConversations","_getConversations","setActiveConversationId","_setActiveConversationId","next","conv","find","c","getResourceBundleFor","suffix","document","getElementById","_messagesContainer","clean","Array","isArray","raw","msg","title","updatedAt","undefined","value","trim","fireEvent","_selectConversation","_requestDeleteConversation","_buildMessageDom","index","div","createElement","isAssistant","className","bubble","_renderBubble","appendChild","actions","_buildActions","_buildCopyButton","_buildEditButton","_buildIconButton","iconName","label","fallback","icon","btn","setAttribute","iconSpan","textContent","_copyMessage","_enterEditMode","async","ok","_writeClipboard","original","getAttribute","done","classList","add","window","setTimeout","remove","wrapper","children","querySelector","actionsRow","display","_buildAttachmentList","editor","rows","editBar","cancelBtn","saveBtn","_cancelEdit","_commitEdit","focus","setSelectionRange","newText","trimmed","unchanged","empty","i","later","destroy","navigator","clipboard","writeText","ta","position","opacity","body","select","execCommand","removeChild","innerHTML","placeAt","variant","wrap","_buildAttachmentItem","file","pendingIndex","isImage","startsWith","item","img","alt","name","src","URL","createObjectURL","iconInfo","removeLabel","_removePending","container","scrollTop","atBottom","clientHeight","hint","active","_buildConversationItem","isActive","tabIndex","_conversationTitle","snippet","_conversationSnippet","time","_formatTimestamp","del","stopPropagation","msgs","m","_truncate","prefix","replace","max","trimEnd","d","Date","isNaN","getTime","now","sameDay","toDateString","yesterday","setDate","getDate","wasYesterday","locale","getLanguage","toLocaleTimeString","hour","minute","weekDelta","toLocaleDateString","weekday","day","month","year","target","attachBtn","fileInput","root","getDomRef","click","_addPending","from","dragDepth","_hasFiles","dataTransfer","dropEffect","types","concat","splice"],"sources":["ChatBox.ts"],"sourcesContent":["/*!\n * ${copyright}\n */\n\nimport Control from \"sap/ui/core/Control\";\nimport RenderManager from \"sap/ui/core/RenderManager\";\nimport IconPool from \"sap/ui/core/IconPool\";\nimport Lib from \"sap/ui/core/Lib\";\nimport Localization from \"sap/base/i18n/Localization\";\nimport ResourceBundle from \"sap/base/i18n/ResourceBundle\";\nimport markdownToHtml from \"./markdown\";\n\ninterface IconInfo {\n fontFamily: string;\n content: string;\n}\n\nexport interface Message {\n role: \"user\" | \"assistant\";\n content: string;\n files?: File[];\n control?: Control;\n}\n\nexport interface Conversation {\n id: string;\n title?: string;\n messages?: ReadonlyArray<Message>;\n updatedAt?: number | string | Date;\n}\n\n/**\n * Constructor for a new <code>chatui.ChatBox</code> control.\n *\n * A flexible chat UI block that can be embedded into any UI5 application.\n * It renders a conversation sidebar, a scrollable message list, an\n * auto-growing input textarea and a send button. The control is\n * intentionally transport-agnostic: it fires a <code>send</code> event with\n * the user's message and expects the embedding application to feed the\n * assistant's reply back via {@link #addAssistantMessage} /\n * {@link #appendToLastAssistantMessage}.\n *\n * The control fills the space provided by its parent. For standalone use\n * a sensible default size is applied via CSS.\n *\n * @extends sap.ui.core.Control\n *\n * @author CONET\n * @version 0.1.0\n *\n * @constructor\n * @public\n * @name chatui.ChatBox\n */\nexport default class ChatBox extends Control {\n\n // The following three lines were generated and should remain as-is to make TypeScript aware of the constructor signatures\n constructor(id?: string | $ChatBoxSettings);\n constructor(id?: string, settings?: $ChatBoxSettings);\n constructor(id?: string, settings?: $ChatBoxSettings) { super(id, settings); }\n\n static readonly metadata = {\n library: \"chatui\",\n properties: {\n /**\n * Placeholder shown in the empty input field. If empty, a\n * localised default is used.\n */\n placeholder: { type: \"string\", group: \"Appearance\", defaultValue: \"\" },\n /**\n * When true, the input and buttons are disabled — typically set\n * while the assistant is producing a reply.\n */\n busy: { type: \"boolean\", group: \"Behavior\", defaultValue: false },\n /**\n * CSS width of the control. Defaults to <code>100%</code> so the\n * chat adapts to its parent; override for a fixed size.\n */\n width: { type: \"sap.ui.core.CSSSize\", group: \"Dimension\", defaultValue: \"100%\" },\n /**\n * CSS height of the control. Defaults to <code>100%</code>; falls\n * back to a sensible min-height when the parent has no explicit\n * height.\n */\n height: { type: \"sap.ui.core.CSSSize\", group: \"Dimension\", defaultValue: \"100%\" },\n /**\n * When true (default), the user can attach files via the paperclip\n * button and drag-and-drop. Uploaded <code>File</code> objects are\n * handed to the consumer via the <code>files</code> parameter of\n * the <code>send</code> event — the library never performs any\n * network transfer itself.\n */\n allowAttachments: { type: \"boolean\", group: \"Behavior\", defaultValue: true },\n /**\n * Value passed to the underlying <code>&lt;input type=\"file\"&gt;</code>\n * as its <code>accept</code> attribute (e.g. <code>\"image/*\"</code>\n * or <code>\".pdf,.docx\"</code>). Empty string means \"any file\".\n */\n attachmentAccept: { type: \"string\", group: \"Behavior\", defaultValue: \"\" },\n /**\n * The list of conversations shown in the sidebar. Each entry has\n * an <code>id</code>, an optional <code>title</code>, an optional\n * ordered array of <code>messages</code>, and an optional\n * <code>updatedAt</code> timestamp (number, ISO string or Date).\n * Passed in by the embedding application and never mutated by\n * the library. When set for the first time, the library\n * automatically selects and displays the first conversation. If\n * the property is empty or unset, an empty new-chat view is\n * shown.\n */\n conversations: { type: \"object\", group: \"Data\", defaultValue: [] },\n /**\n * The id of the currently displayed conversation. Empty string\n * means \"new chat draft\" — no history is shown, and the next\n * <code>send</code> event carries an empty <code>conversationId</code>\n * so the consumer can allocate a fresh id. When set to a value\n * that matches an entry in {@link #getConversations}, that\n * conversation's messages are loaded into the transcript.\n */\n activeConversationId: { type: \"string\", group: \"Data\", defaultValue: \"\" }\n },\n events: {\n /**\n * Fired when the user submits a prompt. The embedding\n * application should produce an assistant response and feed it\n * back via {@link #addAssistantMessage} or\n * {@link #appendToLastAssistantMessage}.\n */\n send: {\n parameters: {\n /** The prompt the user submitted (trimmed; empty when only files are sent). */\n message: { type: \"string\" },\n /** File objects the user attached; empty array if none. Not transferred by the library — the consumer is responsible for upload/transport. */\n files: { type: \"object\" },\n /** Id of the conversation the message belongs to. Empty string when the user is composing in a new-chat draft — the consumer typically allocates a fresh id and pushes an updated conversation list back. */\n conversationId: { type: \"string\" }\n }\n },\n /**\n * Fired when the user clicks the \"Neue Konversation\" button.\n * The transcript view has already been cleared and\n * <code>activeConversationId</code> reset to <code>\"\"</code> by\n * the time the event fires — listeners typically use this to\n * reset any server-side session state.\n */\n newChat: {},\n /**\n * Fired when the user picks a conversation from the sidebar.\n * The library has already switched the transcript view to that\n * conversation and updated <code>activeConversationId</code>.\n */\n conversationSelect: {\n parameters: {\n /** Id of the conversation the user selected. */\n id: { type: \"string\" }\n }\n },\n /**\n * Fired when the user clicks the × on a conversation in the\n * sidebar. The library does not mutate the conversations\n * property itself — the consumer is expected to drop the entry\n * from its store and push an updated list back via\n * {@link #setConversations}.\n */\n conversationDelete: {\n parameters: {\n /** Id of the conversation the user asked to delete. */\n id: { type: \"string\" }\n }\n }\n }\n };\n\n private _messages: Message[] = [];\n private _pendingAttachments: File[] = [];\n private _conversations: Conversation[] = [];\n private _initialised = false;\n private _onLocaleChange = (): void => { this.invalidate(); };\n\n override init(): void {\n Localization.attachChange(this._onLocaleChange);\n }\n\n override exit(): void {\n Localization.detachChange(this._onLocaleChange);\n }\n\n static renderer = {\n apiVersion: 2,\n render(rm: RenderManager, control: ChatBox): void {\n const sendIcon = IconPool.getIconInfo(\"sap-icon://paper-plane\") as IconInfo | undefined;\n const newChatIcon = IconPool.getIconInfo(\"sap-icon://add\") as IconInfo | undefined;\n const attachIcon = IconPool.getIconInfo(\"sap-icon://attachment\") as IconInfo | undefined;\n const i18n = control._i18n();\n const placeholder = control.getPlaceholder() || i18n.getText(\"chatbox.placeholder\") || \"\";\n const allowAttachments = control.getAllowAttachments();\n\n rm.openStart(\"div\", control);\n rm.class(\"cnetChatBox\");\n rm.style(\"width\", control.getWidth());\n rm.style(\"height\", control.getHeight());\n rm.openEnd();\n\n // ---- Sidebar ----\n rm.openStart(\"aside\");\n rm.class(\"cnetChatBox-sidebar\");\n rm.openEnd();\n rm.openStart(\"div\");\n rm.class(\"cnetChatBox-sidebar-header\");\n rm.openEnd();\n rm.openStart(\"span\");\n rm.class(\"cnetChatBox-sidebar-title\");\n rm.openEnd();\n rm.text(i18n.getText(\"chatbox.conversations\") ?? \"\");\n rm.close(\"span\");\n rm.close(\"div\");\n rm.openStart(\"div\", control.getId() + \"-conversations\");\n rm.class(\"cnetChatBox-conversations\");\n rm.openEnd();\n rm.close(\"div\");\n rm.close(\"aside\");\n\n // ---- Main column ----\n rm.openStart(\"div\");\n rm.class(\"cnetChatBox-main\");\n rm.openEnd();\n\n // Header\n rm.openStart(\"div\");\n rm.class(\"cnetChatBox-header\");\n rm.openEnd();\n rm.openStart(\"div\", control.getId() + \"-headerTitle\");\n rm.class(\"cnetChatBox-header-title\");\n rm.openEnd();\n rm.close(\"div\");\n rm.openStart(\"button\", control.getId() + \"-newChat\");\n rm.class(\"cnetChatBox-newChatButton\");\n rm.attr(\"type\", \"button\");\n rm.attr(\"title\", i18n.getText(\"chatbox.newConversation\") ?? \"\");\n rm.openEnd();\n rm.openStart(\"span\");\n rm.class(\"cnetChatBox-icon\");\n if (newChatIcon) rm.style(\"font-family\", newChatIcon.fontFamily);\n rm.openEnd();\n rm.text(newChatIcon?.content ?? \"+\");\n rm.close(\"span\");\n rm.openStart(\"span\");\n rm.class(\"cnetChatBox-newChatButton-label\");\n rm.openEnd();\n rm.text(i18n.getText(\"chatbox.newConversation\") ?? \"\");\n rm.close(\"span\");\n rm.close(\"button\");\n rm.close(\"div\");\n\n // Messages\n rm.openStart(\"div\", control.getId() + \"-messages\");\n rm.class(\"cnetChatBox-messages\");\n rm.openEnd();\n rm.openStart(\"div\");\n rm.class(\"cnetChatBox-empty\");\n rm.openEnd();\n rm.text(i18n.getText(\"chatbox.emptyHint\") ?? \"\");\n rm.close(\"div\");\n rm.close(\"div\");\n\n // Input area\n rm.openStart(\"div\");\n rm.class(\"cnetChatBox-inputArea\");\n rm.openEnd();\n\n rm.openStart(\"div\");\n rm.class(\"cnetChatBox-composer\");\n rm.openEnd();\n\n rm.openStart(\"div\", control.getId() + \"-pending\");\n rm.class(\"cnetChatBox-attachmentsPending\");\n rm.openEnd();\n rm.close(\"div\");\n\n rm.openStart(\"textarea\", control.getId() + \"-input\");\n rm.class(\"cnetChatBox-textarea\");\n rm.attr(\"placeholder\", placeholder);\n rm.attr(\"rows\", \"1\");\n if (control.getBusy()) rm.attr(\"disabled\", \"disabled\");\n rm.openEnd();\n rm.close(\"textarea\");\n\n rm.openStart(\"div\");\n rm.class(\"cnetChatBox-composerBar\");\n rm.openEnd();\n\n rm.openStart(\"div\");\n rm.class(\"cnetChatBox-composerBar-left\");\n rm.openEnd();\n\n if (allowAttachments) {\n rm.openStart(\"button\", control.getId() + \"-attach\");\n rm.class(\"cnetChatBox-toolButton\");\n rm.class(\"cnetChatBox-attach\");\n rm.attr(\"type\", \"button\");\n rm.attr(\"title\", i18n.getText(\"chatbox.attach\") ?? \"\");\n rm.attr(\"aria-label\", i18n.getText(\"chatbox.attach\") ?? \"\");\n rm.openEnd();\n rm.openStart(\"span\");\n rm.class(\"cnetChatBox-icon\");\n if (attachIcon) rm.style(\"font-family\", attachIcon.fontFamily);\n rm.openEnd();\n rm.text(attachIcon?.content ?? \"📎\");\n rm.close(\"span\");\n rm.close(\"button\");\n\n rm.voidStart(\"input\", control.getId() + \"-fileinput\");\n rm.class(\"cnetChatBox-fileinput\");\n rm.attr(\"type\", \"file\");\n rm.attr(\"multiple\", \"multiple\");\n if (control.getAttachmentAccept()) rm.attr(\"accept\", control.getAttachmentAccept());\n rm.voidEnd();\n }\n\n rm.close(\"div\");\n\n rm.openStart(\"button\", control.getId() + \"-send\");\n rm.class(\"cnetChatBox-send\");\n rm.attr(\"type\", \"button\");\n rm.attr(\"title\", i18n.getText(\"chatbox.send\") ?? \"\");\n rm.attr(\"aria-label\", i18n.getText(\"chatbox.send\") ?? \"\");\n rm.openEnd();\n rm.openStart(\"span\");\n rm.class(\"cnetChatBox-icon\");\n if (sendIcon) rm.style(\"font-family\", sendIcon.fontFamily);\n rm.openEnd();\n rm.text(sendIcon?.content ?? \"➤\");\n rm.close(\"span\");\n rm.close(\"button\");\n\n rm.close(\"div\");\n rm.close(\"div\");\n rm.close(\"div\");\n\n rm.close(\"div\"); // main\n\n if (allowAttachments) {\n rm.openStart(\"div\", control.getId() + \"-drop\");\n rm.class(\"cnetChatBox-dropOverlay\");\n rm.openEnd();\n rm.openStart(\"span\");\n rm.class(\"cnetChatBox-dropLabel\");\n rm.openEnd();\n rm.text(i18n.getText(\"chatbox.dropHere\") ?? \"\");\n rm.close(\"span\");\n rm.close(\"div\");\n }\n\n rm.close(\"div\");\n }\n };\n\n override onAfterRendering(): void {\n const textarea = this._dom(\"input\") as HTMLTextAreaElement | null;\n const sendBtn = this._dom(\"send\");\n const newChatBtn = this._dom(\"newChat\");\n\n textarea?.addEventListener(\"input\", () => {\n textarea.style.height = \"auto\";\n textarea.style.height = Math.min(textarea.scrollHeight, 160) + \"px\";\n });\n\n textarea?.addEventListener(\"keydown\", (e: KeyboardEvent) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n this._submit();\n }\n });\n\n sendBtn?.addEventListener(\"click\", () => this._submit());\n newChatBtn?.addEventListener(\"click\", () => this._startNewChat());\n\n if (this.getAllowAttachments()) {\n this._wireAttachments();\n }\n\n this._renderSidebar();\n this._renderHeaderTitle();\n this._restoreMessages();\n this._renderPending();\n }\n\n /**\n * Append an assistant message to the transcript. Pass an empty string\n * to open a \"pending\" bubble that can then be filled incrementally via\n * {@link #appendToLastAssistantMessage}.\n *\n * @public\n */\n addAssistantMessage(text: string): this {\n this._messages.push({ role: \"assistant\", content: text ?? \"\" });\n this._appendMessageDom(this._messages.length - 1);\n return this;\n }\n\n /**\n * Append a chunk to the last assistant message. Useful when streaming\n * tokens from a language model. If the last message is not a plain\n * assistant text message, a new one is started.\n *\n * @public\n */\n appendToLastAssistantMessage(chunk: string): this {\n if (!chunk) return this;\n const last = this._messages[this._messages.length - 1];\n if (!last || last.role !== \"assistant\" || last.control) {\n return this.addAssistantMessage(chunk);\n }\n last.content += chunk;\n this._updateBubble(this._messages.length - 1);\n return this;\n }\n\n /**\n * Attach an arbitrary UI5 control as a stand-alone assistant bubble\n * (e.g. a <code>sap.viz.ui5.controls.VizFrame</code>, an\n * <code>sap.ui.integration.widgets.Card</code>, or any custom\n * control). The library owns the control's lifecycle from here on —\n * it is destroyed together with the ChatBox as well as on\n * {@link #clear}, {@link #setMessages}, or the user-driven new-chat\n * action. Do not add the same control twice.\n *\n * @public\n */\n addAssistantControl(control: Control): this {\n this.addDependent(control);\n this._messages.push({ role: \"assistant\", content: \"\", control });\n this._appendMessageDom(this._messages.length - 1);\n return this;\n }\n\n /**\n * Remove all messages from the transcript. Does not fire\n * <code>newChat</code> — that event is reserved for the user-driven\n * clear action. Does not touch the conversations list.\n *\n * @public\n */\n clear(): this {\n this._messages = [];\n this._pendingAttachments = [];\n this.destroyDependents();\n this._restoreMessages();\n this._renderPending();\n return this;\n }\n\n /**\n * Read-only snapshot of the current transcript. Intended for\n * persistence — do not mutate.\n *\n * @public\n */\n getMessages(): ReadonlyArray<Message> {\n return this._messages.slice();\n }\n\n /**\n * Replace the transcript with the given messages. Intended as a\n * restore path — the consumer stores {@link #getMessages} somewhere\n * (localStorage, backend, …) and hands it back after a reload. Does\n * not fire <code>newChat</code> or <code>send</code>. Pending\n * attachments (a possibly ongoing draft) are left untouched. Invalid\n * entries (missing/unknown <code>role</code> or non-string\n * <code>content</code>) are silently skipped.\n *\n * @public\n */\n setMessages(messages: ReadonlyArray<Message>): this {\n this._messages = this._sanitiseMessages(messages);\n this.destroyDependents();\n this._restoreMessages();\n return this;\n }\n\n /**\n * Replace the conversations list shown in the sidebar. On the first\n * call with a non-empty list, the first entry is automatically\n * selected and its messages are loaded into the transcript. Later\n * calls only update the sidebar — call {@link #setActiveConversationId}\n * to switch the visible transcript.\n *\n * @public\n */\n setConversations(conversations: ReadonlyArray<Conversation> | null | undefined): this {\n const list = this._sanitiseConversations(conversations);\n this._conversations = list;\n this.setProperty(\"conversations\", list, true);\n\n if (!this._initialised && list.length > 0 && !this.getActiveConversationId()) {\n const first = list[0];\n this.setProperty(\"activeConversationId\", first.id, true);\n this._messages = this._sanitiseMessages(first.messages ?? []);\n this.destroyDependents();\n this._restoreMessages();\n this._renderHeaderTitle();\n }\n this._initialised = true;\n this._renderSidebar();\n return this;\n }\n\n /**\n * Read-only snapshot of the conversations currently shown in the\n * sidebar.\n *\n * @public\n */\n getConversations(): ReadonlyArray<Conversation> {\n return this._conversations.slice();\n }\n\n /**\n * Switch the transcript view to the given conversation. If the id\n * does not match any conversation (including the empty string), the\n * transcript is cleared — that is the \"new chat draft\" state.\n *\n * @public\n */\n setActiveConversationId(id: string): this {\n const next = typeof id === \"string\" ? id : \"\";\n if (next === this.getActiveConversationId()) return this;\n this.setProperty(\"activeConversationId\", next, true);\n const list = this._conversations ?? [];\n const conv = list.find((c) => c.id === next);\n this._messages = conv ? this._sanitiseMessages(conv.messages ?? []) : [];\n this._pendingAttachments = [];\n this.destroyDependents();\n this._renderSidebar();\n this._renderHeaderTitle();\n this._restoreMessages();\n this._renderPending();\n return this;\n }\n\n private _i18n(): ResourceBundle {\n return Lib.getResourceBundleFor(\"chatui\") as ResourceBundle;\n }\n\n private _dom(suffix: string): HTMLElement | null {\n return document.getElementById(this.getId() + \"-\" + suffix);\n }\n\n private _messagesContainer(): HTMLElement | null {\n return this._dom(\"messages\");\n }\n\n private _sanitiseMessages(messages: ReadonlyArray<Message> | null | undefined): Message[] {\n const clean: Message[] = [];\n if (!Array.isArray(messages)) return clean;\n for (const raw of messages) {\n if (!raw || (raw.role !== \"user\" && raw.role !== \"assistant\")) continue;\n if (typeof raw.content !== \"string\") continue;\n if (raw.control) continue;\n const msg: Message = { role: raw.role, content: raw.content };\n if (Array.isArray(raw.files) && raw.files.length > 0) {\n msg.files = raw.files.slice();\n }\n clean.push(msg);\n }\n return clean;\n }\n\n private _sanitiseConversations(conversations: ReadonlyArray<Conversation> | null | undefined): Conversation[] {\n const clean: Conversation[] = [];\n if (!Array.isArray(conversations)) return clean;\n for (const raw of conversations) {\n if (!raw || typeof raw.id !== \"string\" || !raw.id) continue;\n const conv: Conversation = { id: raw.id };\n if (typeof raw.title === \"string\") conv.title = raw.title;\n if (Array.isArray(raw.messages)) conv.messages = this._sanitiseMessages(raw.messages);\n if (raw.updatedAt !== undefined && raw.updatedAt !== null) conv.updatedAt = raw.updatedAt;\n clean.push(conv);\n }\n return clean;\n }\n\n private _submit(): void {\n if (this.getBusy()) return;\n const textarea = this._dom(\"input\") as HTMLTextAreaElement | null;\n const text = textarea?.value.trim() ?? \"\";\n const files = this._pendingAttachments.slice();\n if (!text && files.length === 0) return;\n\n if (textarea) {\n textarea.value = \"\";\n textarea.style.height = \"auto\";\n }\n\n const message: Message = { role: \"user\", content: text };\n if (files.length > 0) message.files = files;\n this._messages.push(message);\n this._pendingAttachments = [];\n this._appendMessageDom(this._messages.length - 1);\n this._renderPending();\n\n this.fireEvent(\"send\", { message: text, files, conversationId: this.getActiveConversationId() });\n }\n\n private _startNewChat(): void {\n if (this.getBusy()) return;\n this._messages = [];\n this._pendingAttachments = [];\n this.destroyDependents();\n this.setProperty(\"activeConversationId\", \"\", true);\n this._renderSidebar();\n this._renderHeaderTitle();\n this._restoreMessages();\n this._renderPending();\n this.fireEvent(\"newChat\");\n }\n\n private _selectConversation(id: string): void {\n if (this.getBusy()) return;\n if (id === this.getActiveConversationId()) return;\n this.setActiveConversationId(id);\n this.fireEvent(\"conversationSelect\", { id });\n }\n\n private _requestDeleteConversation(id: string): void {\n if (this.getBusy()) return;\n this.fireEvent(\"conversationDelete\", { id });\n }\n\n private _buildMessageDom(index: number): HTMLDivElement {\n const msg = this._messages[index];\n const div = document.createElement(\"div\");\n const isAssistant = msg.role === \"assistant\";\n div.className = `cnetChatBox-message cnetChatBox-message--${isAssistant ? \"assistant\" : \"user\"}`;\n\n const bubble = document.createElement(\"div\");\n bubble.className = \"cnetChatBox-bubble\";\n this._renderBubble(bubble, msg);\n div.appendChild(bubble);\n\n if (!msg.control) {\n const actions = this._buildActions(index, msg);\n if (actions) div.appendChild(actions);\n }\n return div;\n }\n\n private _buildActions(index: number, msg: Message): HTMLDivElement | null {\n const actions = document.createElement(\"div\");\n actions.className = \"cnetChatBox-actions\";\n if (msg.role === \"assistant\") {\n actions.appendChild(this._buildCopyButton(index));\n } else {\n actions.appendChild(this._buildEditButton(index));\n }\n return actions;\n }\n\n private _buildIconButton(iconName: string, className: string, label: string, fallback: string): HTMLButtonElement {\n const icon = IconPool.getIconInfo(iconName) as IconInfo | undefined;\n const btn = document.createElement(\"button\");\n btn.type = \"button\";\n btn.className = `cnetChatBox-action ${className}`;\n btn.title = label;\n btn.setAttribute(\"aria-label\", label);\n\n const iconSpan = document.createElement(\"span\");\n iconSpan.className = \"cnetChatBox-icon\";\n if (icon) iconSpan.style.fontFamily = icon.fontFamily;\n iconSpan.textContent = icon?.content ?? fallback;\n btn.appendChild(iconSpan);\n return btn;\n }\n\n private _buildCopyButton(index: number): HTMLButtonElement {\n const label = this._i18n().getText(\"chatbox.copy\") ?? \"Copy\";\n const btn = this._buildIconButton(\"sap-icon://copy\", \"cnetChatBox-copy\", label, \"⎘\");\n btn.addEventListener(\"click\", () => {\n const msg = this._messages[index];\n if (!msg || !msg.content) return;\n void this._copyMessage(msg.content, btn);\n });\n return btn;\n }\n\n private _buildEditButton(index: number): HTMLButtonElement {\n const label = this._i18n().getText(\"chatbox.edit\") ?? \"Edit\";\n const btn = this._buildIconButton(\"sap-icon://edit\", \"cnetChatBox-edit\", label, \"✎\");\n btn.addEventListener(\"click\", () => this._enterEditMode(index));\n return btn;\n }\n\n private async _copyMessage(text: string, btn: HTMLButtonElement): Promise<void> {\n const ok = await this._writeClipboard(text);\n if (!ok) return;\n\n const i18n = this._i18n();\n const original = btn.getAttribute(\"aria-label\") ?? \"\";\n const done = i18n.getText(\"chatbox.copied\") ?? \"Copied\";\n btn.classList.add(\"cnetChatBox-action--done\");\n btn.title = done;\n window.setTimeout(() => {\n btn.classList.remove(\"cnetChatBox-action--done\");\n btn.title = original;\n }, 1200);\n }\n\n private _enterEditMode(index: number): void {\n if (this.getBusy()) return;\n const wrapper = this._messagesContainer()?.children[index] as HTMLDivElement | undefined;\n const msg = this._messages[index];\n if (!wrapper || !msg || msg.role !== \"user\") return;\n\n const bubble = wrapper.querySelector<HTMLElement>(\".cnetChatBox-bubble\");\n if (!bubble) return;\n\n const actionsRow = wrapper.querySelector<HTMLElement>(\".cnetChatBox-actions\");\n if (actionsRow) actionsRow.style.display = \"none\";\n\n bubble.textContent = \"\";\n bubble.classList.add(\"cnetChatBox-bubble--editing\");\n if (msg.files && msg.files.length > 0) {\n bubble.appendChild(this._buildAttachmentList(msg.files, \"sent\"));\n }\n\n const editor = document.createElement(\"textarea\");\n editor.className = \"cnetChatBox-editTextarea\";\n editor.value = msg.content;\n editor.rows = 2;\n bubble.appendChild(editor);\n\n const editBar = document.createElement(\"div\");\n editBar.className = \"cnetChatBox-editActions\";\n const i18n = this._i18n();\n\n const cancelBtn = document.createElement(\"button\");\n cancelBtn.type = \"button\";\n cancelBtn.className = \"cnetChatBox-editCancel\";\n cancelBtn.textContent = i18n.getText(\"chatbox.cancel\") ?? \"Cancel\";\n\n const saveBtn = document.createElement(\"button\");\n saveBtn.type = \"button\";\n saveBtn.className = \"cnetChatBox-editSave\";\n saveBtn.textContent = i18n.getText(\"chatbox.save\") ?? \"Save\";\n\n cancelBtn.addEventListener(\"click\", () => this._cancelEdit(index));\n saveBtn.addEventListener(\"click\", () => this._commitEdit(index, editor.value));\n\n editor.addEventListener(\"keydown\", (e: KeyboardEvent) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n this._commitEdit(index, editor.value);\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n this._cancelEdit(index);\n }\n });\n\n editBar.appendChild(cancelBtn);\n editBar.appendChild(saveBtn);\n bubble.appendChild(editBar);\n\n editor.focus();\n editor.setSelectionRange(editor.value.length, editor.value.length);\n }\n\n private _cancelEdit(index: number): void {\n const wrapper = this._messagesContainer()?.children[index] as HTMLDivElement | undefined;\n const msg = this._messages[index];\n if (!wrapper || !msg) return;\n const bubble = wrapper.querySelector<HTMLElement>(\".cnetChatBox-bubble\");\n if (!bubble) return;\n bubble.classList.remove(\"cnetChatBox-bubble--editing\");\n this._renderBubble(bubble, msg);\n const actionsRow = wrapper.querySelector<HTMLElement>(\".cnetChatBox-actions\");\n if (actionsRow) actionsRow.style.display = \"\";\n }\n\n private _commitEdit(index: number, newText: string): void {\n if (this.getBusy()) return;\n const msg = this._messages[index];\n if (!msg || msg.role !== \"user\") return;\n\n const trimmed = newText.trim();\n const files = msg.files ? msg.files.slice() : [];\n const unchanged = trimmed === msg.content;\n const empty = !trimmed && files.length === 0;\n\n if (unchanged || empty) {\n this._cancelEdit(index);\n return;\n }\n\n for (let i = index + 1; i < this._messages.length; i++) {\n const later = this._messages[i];\n if (later.control) later.control.destroy();\n }\n this._messages.length = index + 1;\n msg.content = trimmed;\n\n this._restoreMessages();\n this.fireEvent(\"send\", { message: trimmed, files, conversationId: this.getActiveConversationId() });\n }\n\n private async _writeClipboard(text: string): Promise<boolean> {\n try {\n if (navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(text);\n return true;\n }\n } catch {\n // fall through to legacy path\n }\n try {\n const ta = document.createElement(\"textarea\");\n ta.value = text;\n ta.setAttribute(\"readonly\", \"\");\n ta.style.position = \"fixed\";\n ta.style.opacity = \"0\";\n document.body.appendChild(ta);\n ta.select();\n const ok = document.execCommand(\"copy\");\n document.body.removeChild(ta);\n return ok;\n } catch {\n return false;\n }\n }\n\n private _renderBubble(bubble: HTMLElement, msg: Message): void {\n if (msg.role === \"assistant\") {\n if (msg.control) {\n bubble.classList.remove(\"cnetChatBox-bubble--pending\");\n bubble.classList.add(\"cnetChatBox-bubble--rich\");\n bubble.innerHTML = \"\";\n msg.control.placeAt(bubble);\n return;\n }\n bubble.classList.remove(\"cnetChatBox-bubble--rich\");\n if (!msg.content) {\n bubble.classList.add(\"cnetChatBox-bubble--pending\");\n bubble.innerHTML = '<span class=\"cnetChatBox-dots\"><span></span><span></span><span></span></span>';\n return;\n }\n bubble.classList.remove(\"cnetChatBox-bubble--pending\");\n bubble.innerHTML = markdownToHtml(msg.content);\n return;\n }\n\n bubble.textContent = \"\";\n if (msg.files && msg.files.length > 0) {\n bubble.appendChild(this._buildAttachmentList(msg.files, \"sent\"));\n }\n if (msg.content) {\n const text = document.createElement(\"div\");\n text.className = \"cnetChatBox-bubble-text\";\n text.textContent = msg.content;\n bubble.appendChild(text);\n }\n }\n\n private _buildAttachmentList(files: File[], variant: \"sent\" | \"pending\"): HTMLDivElement {\n const wrap = document.createElement(\"div\");\n wrap.className = `cnetChatBox-attachments cnetChatBox-attachments--${variant}`;\n for (let i = 0; i < files.length; i++) {\n wrap.appendChild(this._buildAttachmentItem(files[i], variant === \"pending\" ? i : -1));\n }\n return wrap;\n }\n\n private _buildAttachmentItem(file: File, pendingIndex: number): HTMLDivElement {\n const isImage = file.type.startsWith(\"image/\");\n const item = document.createElement(\"div\");\n item.className = `cnetChatBox-attachment cnetChatBox-attachment--${isImage ? \"image\" : \"file\"}`;\n\n if (isImage) {\n const img = document.createElement(\"img\");\n img.className = \"cnetChatBox-attachment-thumb\";\n img.alt = file.name;\n img.src = URL.createObjectURL(file);\n item.appendChild(img);\n } else {\n const iconInfo = IconPool.getIconInfo(\"sap-icon://document\") as IconInfo | undefined;\n const iconSpan = document.createElement(\"span\");\n iconSpan.className = \"cnetChatBox-icon cnetChatBox-attachment-icon\";\n if (iconInfo) iconSpan.style.fontFamily = iconInfo.fontFamily;\n iconSpan.textContent = iconInfo?.content ?? \"📄\";\n item.appendChild(iconSpan);\n }\n\n const name = document.createElement(\"span\");\n name.className = \"cnetChatBox-attachment-name\";\n name.textContent = file.name;\n name.title = file.name;\n item.appendChild(name);\n\n if (pendingIndex >= 0) {\n const i18n = this._i18n();\n const removeLabel = i18n.getText(\"chatbox.removeAttachment\") ?? \"Remove\";\n const btn = document.createElement(\"button\");\n btn.type = \"button\";\n btn.className = \"cnetChatBox-attachment-remove\";\n btn.title = removeLabel;\n btn.setAttribute(\"aria-label\", removeLabel);\n btn.textContent = \"×\";\n btn.addEventListener(\"click\", () => this._removePending(pendingIndex));\n item.appendChild(btn);\n }\n return item;\n }\n\n private _appendMessageDom(index: number): void {\n const container = this._messagesContainer();\n if (!container) return;\n container.querySelector(\".cnetChatBox-empty\")?.remove();\n container.appendChild(this._buildMessageDom(index));\n container.scrollTop = container.scrollHeight;\n }\n\n private _updateBubble(index: number): void {\n const container = this._messagesContainer();\n const wrapper = container?.children[index] as HTMLElement | undefined;\n const bubble = wrapper?.querySelector(\".cnetChatBox-bubble\") as HTMLElement | null;\n if (!bubble || !container) return;\n\n this._renderBubble(bubble, this._messages[index]);\n\n const atBottom = container.scrollHeight - container.scrollTop - container.clientHeight < 80;\n if (atBottom) container.scrollTop = container.scrollHeight;\n }\n\n private _restoreMessages(): void {\n const container = this._messagesContainer();\n if (!container) return;\n container.innerHTML = \"\";\n\n if (this._messages.length === 0) {\n const hint = document.createElement(\"div\");\n hint.className = \"cnetChatBox-empty\";\n hint.textContent = this._i18n().getText(\"chatbox.emptyHint\") ?? \"\";\n container.appendChild(hint);\n return;\n }\n\n for (let i = 0; i < this._messages.length; i++) {\n container.appendChild(this._buildMessageDom(i));\n }\n container.scrollTop = container.scrollHeight;\n }\n\n private _renderSidebar(): void {\n const container = this._dom(\"conversations\");\n if (!container) return;\n container.innerHTML = \"\";\n\n if (this._conversations.length === 0) {\n const empty = document.createElement(\"div\");\n empty.className = \"cnetChatBox-conversations-empty\";\n empty.textContent = this._i18n().getText(\"chatbox.noConversations\") ?? \"\";\n container.appendChild(empty);\n return;\n }\n\n const active = this.getActiveConversationId();\n for (const conv of this._conversations) {\n container.appendChild(this._buildConversationItem(conv, conv.id === active));\n }\n }\n\n private _buildConversationItem(conv: Conversation, isActive: boolean): HTMLDivElement {\n const i18n = this._i18n();\n const item = document.createElement(\"div\");\n item.className = \"cnetChatBox-conversation\" + (isActive ? \" cnetChatBox-conversation--active\" : \"\");\n item.setAttribute(\"role\", \"button\");\n item.tabIndex = 0;\n\n const body = document.createElement(\"div\");\n body.className = \"cnetChatBox-conversation-body\";\n\n const title = document.createElement(\"div\");\n title.className = \"cnetChatBox-conversation-title\";\n title.textContent = this._conversationTitle(conv);\n body.appendChild(title);\n\n const snippet = document.createElement(\"div\");\n snippet.className = \"cnetChatBox-conversation-snippet\";\n snippet.textContent = this._conversationSnippet(conv);\n body.appendChild(snippet);\n\n const time = document.createElement(\"div\");\n time.className = \"cnetChatBox-conversation-time\";\n time.textContent = this._formatTimestamp(conv.updatedAt);\n body.appendChild(time);\n\n item.appendChild(body);\n\n const removeLabel = i18n.getText(\"chatbox.deleteConversation\") ?? \"Delete conversation\";\n const del = document.createElement(\"button\");\n del.type = \"button\";\n del.className = \"cnetChatBox-conversation-remove\";\n del.title = removeLabel;\n del.setAttribute(\"aria-label\", removeLabel);\n del.textContent = \"×\";\n del.addEventListener(\"click\", (e: MouseEvent) => {\n e.stopPropagation();\n this._requestDeleteConversation(conv.id);\n });\n item.appendChild(del);\n\n item.addEventListener(\"click\", () => this._selectConversation(conv.id));\n item.addEventListener(\"keydown\", (e: KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n this._selectConversation(conv.id);\n }\n });\n\n return item;\n }\n\n private _conversationTitle(conv: Conversation): string {\n if (conv.title && conv.title.trim()) return conv.title.trim();\n const msgs = conv.messages ?? [];\n for (const m of msgs) {\n if (m.role === \"user\" && m.content && m.content.trim()) {\n return this._truncate(m.content.trim(), 40);\n }\n }\n return this._i18n().getText(\"chatbox.untitledConversation\") ?? \"Neue Konversation\";\n }\n\n private _conversationSnippet(conv: Conversation): string {\n const msgs = conv.messages ?? [];\n for (let i = msgs.length - 1; i >= 0; i--) {\n const m = msgs[i];\n if (m.content && m.content.trim()) {\n const prefix = m.role === \"user\" ? (this._i18n().getText(\"chatbox.youPrefix\") ?? \"Du:\") + \" \" : \"\";\n return this._truncate(prefix + m.content.trim().replace(/\\s+/g, \" \"), 60);\n }\n }\n return \"\";\n }\n\n private _truncate(text: string, max: number): string {\n return text.length > max ? text.slice(0, max - 1).trimEnd() + \"…\" : text;\n }\n\n private _formatTimestamp(raw: number | string | Date | undefined): string {\n if (raw === undefined || raw === null) return \"\";\n const d = raw instanceof Date ? raw : new Date(raw);\n if (isNaN(d.getTime())) return \"\";\n const now = new Date();\n const sameDay = d.toDateString() === now.toDateString();\n const yesterday = new Date(now);\n yesterday.setDate(now.getDate() - 1);\n const wasYesterday = d.toDateString() === yesterday.toDateString();\n const locale = Localization.getLanguage() || undefined;\n if (sameDay) {\n return d.toLocaleTimeString(locale, { hour: \"2-digit\", minute: \"2-digit\" });\n }\n if (wasYesterday) {\n return this._i18n().getText(\"chatbox.yesterday\") ?? \"Gestern\";\n }\n const weekDelta = (now.getTime() - d.getTime()) / (1000 * 60 * 60 * 24);\n if (weekDelta < 7) {\n return d.toLocaleDateString(locale, { weekday: \"short\" });\n }\n return d.toLocaleDateString(locale, { day: \"2-digit\", month: \"2-digit\", year: \"2-digit\" });\n }\n\n private _renderHeaderTitle(): void {\n const target = this._dom(\"headerTitle\");\n if (!target) return;\n const active = this.getActiveConversationId();\n const conv = active ? this._conversations.find((c) => c.id === active) : undefined;\n target.textContent = conv ? this._conversationTitle(conv) : \"\";\n }\n\n private _wireAttachments(): void {\n const attachBtn = this._dom(\"attach\");\n const fileInput = this._dom(\"fileinput\") as HTMLInputElement | null;\n const root = this.getDomRef() as HTMLElement | null;\n\n attachBtn?.addEventListener(\"click\", () => fileInput?.click());\n fileInput?.addEventListener(\"change\", () => {\n if (!fileInput.files) return;\n this._addPending(Array.from(fileInput.files));\n fileInput.value = \"\";\n });\n\n if (!root) return;\n\n let dragDepth = 0;\n root.addEventListener(\"dragenter\", (e: DragEvent) => {\n if (!this._hasFiles(e)) return;\n e.preventDefault();\n dragDepth++;\n root.classList.add(\"cnetChatBox--dragOver\");\n });\n root.addEventListener(\"dragover\", (e: DragEvent) => {\n if (!this._hasFiles(e)) return;\n e.preventDefault();\n if (e.dataTransfer) e.dataTransfer.dropEffect = \"copy\";\n });\n root.addEventListener(\"dragleave\", () => {\n dragDepth = Math.max(0, dragDepth - 1);\n if (dragDepth === 0) root.classList.remove(\"cnetChatBox--dragOver\");\n });\n root.addEventListener(\"drop\", (e: DragEvent) => {\n if (!this._hasFiles(e)) return;\n e.preventDefault();\n dragDepth = 0;\n root.classList.remove(\"cnetChatBox--dragOver\");\n const files = e.dataTransfer?.files;\n if (!files || files.length === 0) return;\n this._addPending(Array.from(files));\n });\n }\n\n private _hasFiles(e: DragEvent): boolean {\n const types = e.dataTransfer?.types;\n if (!types) return false;\n for (let i = 0; i < types.length; i++) {\n if (types[i] === \"Files\") return true;\n }\n return false;\n }\n\n private _addPending(files: File[]): void {\n if (this.getBusy()) return;\n if (files.length === 0) return;\n this._pendingAttachments = this._pendingAttachments.concat(files);\n this._renderPending();\n }\n\n private _removePending(index: number): void {\n if (index < 0 || index >= this._pendingAttachments.length) return;\n this._pendingAttachments.splice(index, 1);\n this._renderPending();\n }\n\n private _renderPending(): void {\n const container = this._dom(\"pending\");\n if (!container) return;\n container.innerHTML = \"\";\n if (this._pendingAttachments.length === 0) {\n container.classList.remove(\"cnetChatBox-attachmentsPending--hasItems\");\n return;\n }\n container.classList.add(\"cnetChatBox-attachmentsPending--hasItems\");\n container.appendChild(this._buildAttachmentList(this._pendingAttachments, \"pending\"));\n }\n}\n"],"mappings":"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","ignoreList":[]}