<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://www.muenster4you.de/w/index.php?action=history&amp;feed=atom&amp;title=Widget%3AChatBox</id>
	<title>Widget:ChatBox - Versionsgeschichte</title>
	<link rel="self" type="application/atom+xml" href="https://www.muenster4you.de/w/index.php?action=history&amp;feed=atom&amp;title=Widget%3AChatBox"/>
	<link rel="alternate" type="text/html" href="https://www.muenster4you.de/w/index.php?title=Widget:ChatBox&amp;action=history"/>
	<updated>2026-05-27T21:19:58Z</updated>
	<subtitle>Versionsgeschichte dieser Seite in MediaWiki</subtitle>
	<generator>MediaWiki 1.44.0</generator>
	<entry>
		<id>https://www.muenster4you.de/w/index.php?title=Widget:ChatBox&amp;diff=1080&amp;oldid=prev</id>
		<title>Alex: fix: avoid &amp;&amp; and &amp;middot; entities that MediaWiki HTML-encodes</title>
		<link rel="alternate" type="text/html" href="https://www.muenster4you.de/w/index.php?title=Widget:ChatBox&amp;diff=1080&amp;oldid=prev"/>
		<updated>2026-04-23T13:37:10Z</updated>

		<summary type="html">&lt;p&gt;fix: avoid &amp;amp;&amp;amp; and · entities that MediaWiki HTML-encodes&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;de&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Nächstältere Version&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Version vom 23. April 2026, 13:37 Uhr&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l318&quot;&gt;Zeile 318:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Zeile 318:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         + &amp;#039;&amp;lt;h5&amp;gt;&amp;lt;a href=&amp;quot;&amp;#039; + wikiUrl + &amp;#039;&amp;quot;&amp;gt;&amp;#039; + escapeHtml(s.page_title || &amp;#039;&amp;#039;) + &amp;#039;&amp;lt;/a&amp;gt;&amp;lt;/h5&amp;gt;&amp;#039;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         + &amp;#039;&amp;lt;h5&amp;gt;&amp;lt;a href=&amp;quot;&amp;#039; + wikiUrl + &amp;#039;&amp;quot;&amp;gt;&amp;#039; + escapeHtml(s.page_title || &amp;#039;&amp;#039;) + &amp;#039;&amp;lt;/a&amp;gt;&amp;lt;/h5&amp;gt;&amp;#039;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         + &amp;#039;&amp;lt;p class=&amp;quot;chat-source-snippet&amp;quot;&amp;gt;&amp;#039; + escapeHtml(truncate(s.content_text || &amp;#039;&amp;#039;, 150)) + &amp;#039;&amp;lt;/p&amp;gt;&amp;#039;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         + &amp;#039;&amp;lt;p class=&amp;quot;chat-source-snippet&amp;quot;&amp;gt;&amp;#039; + escapeHtml(truncate(s.content_text || &amp;#039;&amp;#039;, 150)) + &amp;#039;&amp;lt;/p&amp;gt;&amp;#039;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         + &#039;&amp;lt;div class=&quot;chat-source-meta&quot;&amp;gt;Relevanz: &#039; + pct + &#039;% &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;amp;middot; &lt;/del&gt;&#039; + escapeHtml(s.source || &#039;&#039;) + &#039;&amp;lt;/div&amp;gt;&#039;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         + &#039;&amp;lt;div class=&quot;chat-source-meta&quot;&amp;gt;Relevanz: &#039; + pct + &#039;% &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;· &lt;/ins&gt;&#039; + escapeHtml(s.source || &#039;&#039;) + &#039;&amp;lt;/div&amp;gt;&#039;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         + &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         + &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     });&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     });&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l339&quot;&gt;Zeile 339:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Zeile 339:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     if (remaining &amp;gt; 0) {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     if (remaining &amp;gt; 0) {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       statusEl.textContent = remaining + &amp;#039; R\u00fcckfrage&amp;#039; + (remaining !== 1 ? &amp;#039;n&amp;#039; : &amp;#039;&amp;#039;) + &amp;#039; verbleibend&amp;#039;;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       statusEl.textContent = remaining + &amp;#039; R\u00fcckfrage&amp;#039; + (remaining !== 1 ? &amp;#039;n&amp;#039; : &amp;#039;&amp;#039;) + &amp;#039; verbleibend&amp;#039;;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     } else if (remaining === 0 &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;amp;&amp;amp; &lt;/del&gt;conversationId) {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     } else if (remaining === 0&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;) { if (&lt;/ins&gt;conversationId) {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       statusEl.textContent = &amp;#039;Keine R\u00fcckfragen mehr m\u00f6glich&amp;#039;;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       statusEl.textContent = &amp;#039;Keine R\u00fcckfragen mehr m\u00f6glich&amp;#039;;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       input.disabled = true;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       input.disabled = true;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       sendBtn.disabled = true;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       sendBtn.disabled = true;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       input.placeholder = &amp;#039;Starte eine neue Unterhaltung&amp;#039;;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;       input.placeholder = &amp;#039;Starte eine neue Unterhaltung&amp;#039;;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;} &lt;/ins&gt;}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     newBtn.className = conversationId ? &amp;#039;visible&amp;#039; : &amp;#039;&amp;#039;;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     newBtn.className = conversationId ? &amp;#039;visible&amp;#039; : &amp;#039;&amp;#039;;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;   }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key my_wiki:diff:1.41:old-1077:rev-1080:php=table --&gt;
&lt;/table&gt;</summary>
		<author><name>Alex</name></author>
	</entry>
	<entry>
		<id>https://www.muenster4you.de/w/index.php?title=Widget:ChatBox&amp;diff=1077&amp;oldid=prev</id>
		<title>Alex: Create ChatBox widget for multi-turn RAG chat</title>
		<link rel="alternate" type="text/html" href="https://www.muenster4you.de/w/index.php?title=Widget:ChatBox&amp;diff=1077&amp;oldid=prev"/>
		<updated>2026-04-23T13:31:00Z</updated>

		<summary type="html">&lt;p&gt;Create ChatBox widget for multi-turn RAG chat&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Neue Seite&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;includeonly&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;chat-widget&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;chat-messages&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;chat-sources-panel&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;form id=&amp;quot;chat-form&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;chat-input&amp;quot; placeholder=&amp;quot;Stelle eine Frage über Münster …&amp;quot; autocomplete=&amp;quot;off&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;button type=&amp;quot;submit&amp;quot; id=&amp;quot;chat-send&amp;quot;&amp;gt;Fragen&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;chat-footer&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;span id=&amp;quot;chat-status&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
    &amp;lt;button id=&amp;quot;chat-new&amp;quot; type=&amp;quot;button&amp;quot;&amp;gt;Neue Unterhaltung&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
#chat-widget {&lt;br /&gt;
  max-width: 800px;&lt;br /&gt;
  margin: 0 auto;&lt;br /&gt;
  font-family: -apple-system, &amp;quot;system-ui&amp;quot;, &amp;quot;Segoe UI&amp;quot;, Roboto, &amp;quot;Helvetica Neue&amp;quot;, Arial, sans-serif;&lt;br /&gt;
  color: #212529;&lt;br /&gt;
  display: flex;&lt;br /&gt;
  flex-direction: column;&lt;br /&gt;
}&lt;br /&gt;
#chat-messages {&lt;br /&gt;
  min-height: 120px;&lt;br /&gt;
  max-height: 500px;&lt;br /&gt;
  overflow-y: auto;&lt;br /&gt;
  padding: 8px 0;&lt;br /&gt;
  display: flex;&lt;br /&gt;
  flex-direction: column;&lt;br /&gt;
  gap: 12px;&lt;br /&gt;
}&lt;br /&gt;
#chat-messages:empty::before {&lt;br /&gt;
  content: &amp;quot;Stelle eine Frage und erhalte Antworten basierend auf dem Münster Wiki.&amp;quot;;&lt;br /&gt;
  display: block;&lt;br /&gt;
  text-align: center;&lt;br /&gt;
  color: #999;&lt;br /&gt;
  font-size: 14px;&lt;br /&gt;
  padding: 40px 16px;&lt;br /&gt;
}&lt;br /&gt;
.chat-msg {&lt;br /&gt;
  max-width: 85%;&lt;br /&gt;
  padding: 10px 14px;&lt;br /&gt;
  border-radius: 10px;&lt;br /&gt;
  font-size: 14.5px;&lt;br /&gt;
  line-height: 1.55;&lt;br /&gt;
  word-wrap: break-word;&lt;br /&gt;
}&lt;br /&gt;
.chat-msg-user {&lt;br /&gt;
  align-self: flex-end;&lt;br /&gt;
  background: #00308D;&lt;br /&gt;
  color: #fff;&lt;br /&gt;
  border-bottom-right-radius: 3px;&lt;br /&gt;
}&lt;br /&gt;
.chat-msg-assistant {&lt;br /&gt;
  align-self: flex-start;&lt;br /&gt;
  background: #f0f2f5;&lt;br /&gt;
  color: #212529;&lt;br /&gt;
  border-bottom-left-radius: 3px;&lt;br /&gt;
}&lt;br /&gt;
.chat-msg-assistant p {&lt;br /&gt;
  margin: 0 0 8px 0;&lt;br /&gt;
}&lt;br /&gt;
.chat-msg-assistant p:last-child {&lt;br /&gt;
  margin-bottom: 0;&lt;br /&gt;
}&lt;br /&gt;
@keyframes chatDots {&lt;br /&gt;
  0%, 80%, 100% { opacity: 0.3; }&lt;br /&gt;
  40% { opacity: 1; }&lt;br /&gt;
}&lt;br /&gt;
.chat-loading-dots span {&lt;br /&gt;
  display: inline-block;&lt;br /&gt;
  width: 7px;&lt;br /&gt;
  height: 7px;&lt;br /&gt;
  margin: 0 2px;&lt;br /&gt;
  background: #999;&lt;br /&gt;
  border-radius: 50%;&lt;br /&gt;
  animation: chatDots 1.2s ease-in-out infinite;&lt;br /&gt;
}&lt;br /&gt;
.chat-loading-dots span:nth-child(2) { animation-delay: 0.15s; }&lt;br /&gt;
.chat-loading-dots span:nth-child(3) { animation-delay: 0.3s; }&lt;br /&gt;
#chat-sources-panel {&lt;br /&gt;
  display: none;&lt;br /&gt;
}&lt;br /&gt;
#chat-sources-panel.visible {&lt;br /&gt;
  display: block;&lt;br /&gt;
  margin: 4px 0 8px 0;&lt;br /&gt;
}&lt;br /&gt;
.chat-sources-toggle {&lt;br /&gt;
  background: none;&lt;br /&gt;
  border: 1px solid #ddd;&lt;br /&gt;
  border-radius: 6px;&lt;br /&gt;
  padding: 6px 12px;&lt;br /&gt;
  font-size: 12px;&lt;br /&gt;
  color: #555;&lt;br /&gt;
  cursor: pointer;&lt;br /&gt;
  transition: background 0.15s;&lt;br /&gt;
}&lt;br /&gt;
.chat-sources-toggle:hover {&lt;br /&gt;
  background: #f5f5f5;&lt;br /&gt;
}&lt;br /&gt;
.chat-sources-list {&lt;br /&gt;
  display: none;&lt;br /&gt;
  margin-top: 8px;&lt;br /&gt;
}&lt;br /&gt;
.chat-sources-list.open {&lt;br /&gt;
  display: block;&lt;br /&gt;
}&lt;br /&gt;
.chat-source-item {&lt;br /&gt;
  padding: 10px 12px;&lt;br /&gt;
  margin-bottom: 6px;&lt;br /&gt;
  border: 1px solid #e0e0e0;&lt;br /&gt;
  border-radius: 6px;&lt;br /&gt;
  background: #fff;&lt;br /&gt;
  transition: border-color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
.chat-source-item:hover {&lt;br /&gt;
  border-color: #b0b8c1;&lt;br /&gt;
}&lt;br /&gt;
.chat-source-item h5 {&lt;br /&gt;
  margin: 0 0 3px 0;&lt;br /&gt;
  font-size: 14px;&lt;br /&gt;
  font-weight: 600;&lt;br /&gt;
}&lt;br /&gt;
.chat-source-item h5 a {&lt;br /&gt;
  color: #00308D;&lt;br /&gt;
  text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
.chat-source-item h5 a:hover {&lt;br /&gt;
  text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
.chat-source-item .chat-source-snippet {&lt;br /&gt;
  font-size: 12.5px;&lt;br /&gt;
  line-height: 1.45;&lt;br /&gt;
  color: #666;&lt;br /&gt;
  margin: 0;&lt;br /&gt;
}&lt;br /&gt;
.chat-source-item .chat-source-meta {&lt;br /&gt;
  font-size: 11px;&lt;br /&gt;
  color: #999;&lt;br /&gt;
  margin-top: 3px;&lt;br /&gt;
}&lt;br /&gt;
#chat-form {&lt;br /&gt;
  display: flex;&lt;br /&gt;
  margin-top: 8px;&lt;br /&gt;
}&lt;br /&gt;
#chat-input {&lt;br /&gt;
  flex: 1;&lt;br /&gt;
  padding: 10px 14px;&lt;br /&gt;
  font-size: 15px;&lt;br /&gt;
  border: 1px solid #ccc;&lt;br /&gt;
  border-right: none;&lt;br /&gt;
  border-radius: 4px 0 0 4px;&lt;br /&gt;
  outline: none;&lt;br /&gt;
  transition: border-color 0.2s;&lt;br /&gt;
  color: #212529;&lt;br /&gt;
  background: #fff;&lt;br /&gt;
}&lt;br /&gt;
#chat-input:focus {&lt;br /&gt;
  border-color: #4CAF50;&lt;br /&gt;
}&lt;br /&gt;
#chat-input:disabled {&lt;br /&gt;
  background: #f5f5f5;&lt;br /&gt;
  color: #999;&lt;br /&gt;
}&lt;br /&gt;
#chat-send {&lt;br /&gt;
  padding: 10px 20px;&lt;br /&gt;
  font-size: 15px;&lt;br /&gt;
  font-weight: 500;&lt;br /&gt;
  cursor: pointer;&lt;br /&gt;
  background: #4CAF50;&lt;br /&gt;
  color: #fff;&lt;br /&gt;
  border: none;&lt;br /&gt;
  border-radius: 0 4px 4px 0;&lt;br /&gt;
  transition: background 0.2s;&lt;br /&gt;
  white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
#chat-send:hover {&lt;br /&gt;
  background: #43A047;&lt;br /&gt;
}&lt;br /&gt;
#chat-send:disabled {&lt;br /&gt;
  background: #a5d6a7;&lt;br /&gt;
  cursor: not-allowed;&lt;br /&gt;
}&lt;br /&gt;
#chat-footer {&lt;br /&gt;
  display: flex;&lt;br /&gt;
  align-items: center;&lt;br /&gt;
  justify-content: space-between;&lt;br /&gt;
  margin-top: 8px;&lt;br /&gt;
  min-height: 28px;&lt;br /&gt;
}&lt;br /&gt;
#chat-status {&lt;br /&gt;
  font-size: 12px;&lt;br /&gt;
  color: #888;&lt;br /&gt;
}&lt;br /&gt;
#chat-new {&lt;br /&gt;
  display: none;&lt;br /&gt;
  background: none;&lt;br /&gt;
  border: 1px solid #ccc;&lt;br /&gt;
  border-radius: 4px;&lt;br /&gt;
  padding: 4px 12px;&lt;br /&gt;
  font-size: 12px;&lt;br /&gt;
  color: #555;&lt;br /&gt;
  cursor: pointer;&lt;br /&gt;
  transition: background 0.15s;&lt;br /&gt;
}&lt;br /&gt;
#chat-new:hover {&lt;br /&gt;
  background: #f5f5f5;&lt;br /&gt;
}&lt;br /&gt;
#chat-new.visible {&lt;br /&gt;
  display: inline-block;&lt;br /&gt;
}&lt;br /&gt;
.chat-msg-error {&lt;br /&gt;
  align-self: center;&lt;br /&gt;
  background: #fef2f2;&lt;br /&gt;
  color: #b00;&lt;br /&gt;
  border: 1px solid #fca5a5;&lt;br /&gt;
  font-size: 13px;&lt;br /&gt;
  padding: 8px 14px;&lt;br /&gt;
  border-radius: 6px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
(function() {&lt;br /&gt;
  var form = document.getElementById(&amp;#039;chat-form&amp;#039;);&lt;br /&gt;
  var input = document.getElementById(&amp;#039;chat-input&amp;#039;);&lt;br /&gt;
  var sendBtn = document.getElementById(&amp;#039;chat-send&amp;#039;);&lt;br /&gt;
  var messagesEl = document.getElementById(&amp;#039;chat-messages&amp;#039;);&lt;br /&gt;
  var sourcesPanel = document.getElementById(&amp;#039;chat-sources-panel&amp;#039;);&lt;br /&gt;
  var statusEl = document.getElementById(&amp;#039;chat-status&amp;#039;);&lt;br /&gt;
  var newBtn = document.getElementById(&amp;#039;chat-new&amp;#039;);&lt;br /&gt;
  var apiHost = &amp;#039;api.&amp;#039; + location.hostname.split(&amp;#039;.&amp;#039;).slice(1).join(&amp;#039;.&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
  var conversationId = null;&lt;br /&gt;
  var isLoading = false;&lt;br /&gt;
&lt;br /&gt;
  function escapeHtml(str) {&lt;br /&gt;
    var d = document.createElement(&amp;#039;div&amp;#039;);&lt;br /&gt;
    d.textContent = str;&lt;br /&gt;
    return d.innerHTML;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  function truncate(str, len) {&lt;br /&gt;
    if (str.length &amp;lt;= len) return str;&lt;br /&gt;
    return str.substring(0, len).replace(/\s+\S*$/, &amp;#039;&amp;#039;) + &amp;#039;\u2026&amp;#039;;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  function formatAnswer(text) {&lt;br /&gt;
    var html = escapeHtml(text);&lt;br /&gt;
    html = html.replace(/\*\*(.+?)\*\*/g, &amp;#039;&amp;lt;strong&amp;gt;$1&amp;lt;/strong&amp;gt;&amp;#039;);&lt;br /&gt;
    var paragraphs = html.split(/\n{2,}/);&lt;br /&gt;
    if (paragraphs.length &amp;gt; 1) {&lt;br /&gt;
      html = paragraphs.map(function(p) { return &amp;#039;&amp;lt;p&amp;gt;&amp;#039; + p.replace(/\n/g, &amp;#039;&amp;lt;br&amp;gt;&amp;#039;) + &amp;#039;&amp;lt;/p&amp;gt;&amp;#039;; }).join(&amp;#039;&amp;#039;);&lt;br /&gt;
    } else {&lt;br /&gt;
      html = html.replace(/\n/g, &amp;#039;&amp;lt;br&amp;gt;&amp;#039;);&lt;br /&gt;
    }&lt;br /&gt;
    return html;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  function addUserMessage(text) {&lt;br /&gt;
    var div = document.createElement(&amp;#039;div&amp;#039;);&lt;br /&gt;
    div.className = &amp;#039;chat-msg chat-msg-user&amp;#039;;&lt;br /&gt;
    div.textContent = text;&lt;br /&gt;
    messagesEl.appendChild(div);&lt;br /&gt;
    scrollToBottom();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  function addAssistantMessage(text) {&lt;br /&gt;
    var div = document.createElement(&amp;#039;div&amp;#039;);&lt;br /&gt;
    div.className = &amp;#039;chat-msg chat-msg-assistant&amp;#039;;&lt;br /&gt;
    div.innerHTML = formatAnswer(text);&lt;br /&gt;
    messagesEl.appendChild(div);&lt;br /&gt;
    scrollToBottom();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  function addLoadingIndicator() {&lt;br /&gt;
    var div = document.createElement(&amp;#039;div&amp;#039;);&lt;br /&gt;
    div.className = &amp;#039;chat-msg chat-msg-assistant chat-loading-dots&amp;#039;;&lt;br /&gt;
    div.id = &amp;#039;chat-loading&amp;#039;;&lt;br /&gt;
    div.innerHTML = &amp;#039;&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;#039;;&lt;br /&gt;
    messagesEl.appendChild(div);&lt;br /&gt;
    scrollToBottom();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  function removeLoadingIndicator() {&lt;br /&gt;
    var el = document.getElementById(&amp;#039;chat-loading&amp;#039;);&lt;br /&gt;
    if (el) el.remove();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  function addError(msg) {&lt;br /&gt;
    var div = document.createElement(&amp;#039;div&amp;#039;);&lt;br /&gt;
    div.className = &amp;#039;chat-msg chat-msg-error&amp;#039;;&lt;br /&gt;
    div.textContent = msg;&lt;br /&gt;
    messagesEl.appendChild(div);&lt;br /&gt;
    scrollToBottom();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  function scrollToBottom() {&lt;br /&gt;
    messagesEl.scrollTop = messagesEl.scrollHeight;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  function renderSources(sources) {&lt;br /&gt;
    if (!sources || sources.length === 0) {&lt;br /&gt;
      sourcesPanel.className = &amp;#039;&amp;#039;;&lt;br /&gt;
      sourcesPanel.innerHTML = &amp;#039;&amp;#039;;&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    sourcesPanel.className = &amp;#039;visible&amp;#039;;&lt;br /&gt;
    var listId = &amp;#039;src-list-&amp;#039; + Date.now();&lt;br /&gt;
    var html = &amp;#039;&amp;lt;button class=&amp;quot;chat-sources-toggle&amp;quot; onclick=&amp;quot;var l=document.getElementById(\&amp;#039;&amp;#039; + listId + &amp;#039;\&amp;#039;);l.classList.toggle(\&amp;#039;open\&amp;#039;);this.textContent=l.classList.contains(\&amp;#039;open\&amp;#039;)?\&amp;#039;▲ Quellen verbergen\&amp;#039;:\&amp;#039;▼ &amp;#039; + sources.length + &amp;#039; Quellen anzeigen\&amp;#039;&amp;quot;&amp;gt;&amp;#039;&lt;br /&gt;
      + &amp;#039;▼ &amp;#039; + sources.length + &amp;#039; Quellen anzeigen&amp;lt;/button&amp;gt;&amp;#039;;&lt;br /&gt;
    html += &amp;#039;&amp;lt;div class=&amp;quot;chat-sources-list&amp;quot; id=&amp;quot;&amp;#039; + listId + &amp;#039;&amp;quot;&amp;gt;&amp;#039;;&lt;br /&gt;
    sources.forEach(function(s) {&lt;br /&gt;
      var pct = Math.round((s.similarity_score || 0) * 100);&lt;br /&gt;
      var wikiUrl = &amp;#039;/wiki/&amp;#039; + encodeURIComponent((s.page_title || &amp;#039;&amp;#039;).replace(/ /g, &amp;#039;_&amp;#039;));&lt;br /&gt;
      html += &amp;#039;&amp;lt;div class=&amp;quot;chat-source-item&amp;quot;&amp;gt;&amp;#039;&lt;br /&gt;
        + &amp;#039;&amp;lt;h5&amp;gt;&amp;lt;a href=&amp;quot;&amp;#039; + wikiUrl + &amp;#039;&amp;quot;&amp;gt;&amp;#039; + escapeHtml(s.page_title || &amp;#039;&amp;#039;) + &amp;#039;&amp;lt;/a&amp;gt;&amp;lt;/h5&amp;gt;&amp;#039;&lt;br /&gt;
        + &amp;#039;&amp;lt;p class=&amp;quot;chat-source-snippet&amp;quot;&amp;gt;&amp;#039; + escapeHtml(truncate(s.content_text || &amp;#039;&amp;#039;, 150)) + &amp;#039;&amp;lt;/p&amp;gt;&amp;#039;&lt;br /&gt;
        + &amp;#039;&amp;lt;div class=&amp;quot;chat-source-meta&amp;quot;&amp;gt;Relevanz: &amp;#039; + pct + &amp;#039;% &amp;amp;middot; &amp;#039; + escapeHtml(s.source || &amp;#039;&amp;#039;) + &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;&lt;br /&gt;
        + &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;;&lt;br /&gt;
    });&lt;br /&gt;
    html += &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;;&lt;br /&gt;
    sourcesPanel.innerHTML = html;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  function setLoading(loading) {&lt;br /&gt;
    isLoading = loading;&lt;br /&gt;
    input.disabled = loading;&lt;br /&gt;
    sendBtn.disabled = loading;&lt;br /&gt;
    if (loading) {&lt;br /&gt;
      addLoadingIndicator();&lt;br /&gt;
    } else {&lt;br /&gt;
      removeLoadingIndicator();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  function updateStatus(remaining) {&lt;br /&gt;
    if (remaining &amp;gt; 0) {&lt;br /&gt;
      statusEl.textContent = remaining + &amp;#039; R\u00fcckfrage&amp;#039; + (remaining !== 1 ? &amp;#039;n&amp;#039; : &amp;#039;&amp;#039;) + &amp;#039; verbleibend&amp;#039;;&lt;br /&gt;
    } else if (remaining === 0 &amp;amp;&amp;amp; conversationId) {&lt;br /&gt;
      statusEl.textContent = &amp;#039;Keine R\u00fcckfragen mehr m\u00f6glich&amp;#039;;&lt;br /&gt;
      input.disabled = true;&lt;br /&gt;
      sendBtn.disabled = true;&lt;br /&gt;
      input.placeholder = &amp;#039;Starte eine neue Unterhaltung&amp;#039;;&lt;br /&gt;
    }&lt;br /&gt;
    newBtn.className = conversationId ? &amp;#039;visible&amp;#039; : &amp;#039;&amp;#039;;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  function resetConversation() {&lt;br /&gt;
    conversationId = null;&lt;br /&gt;
    messagesEl.innerHTML = &amp;#039;&amp;#039;;&lt;br /&gt;
    sourcesPanel.className = &amp;#039;&amp;#039;;&lt;br /&gt;
    sourcesPanel.innerHTML = &amp;#039;&amp;#039;;&lt;br /&gt;
    statusEl.textContent = &amp;#039;&amp;#039;;&lt;br /&gt;
    newBtn.className = &amp;#039;&amp;#039;;&lt;br /&gt;
    input.disabled = false;&lt;br /&gt;
    sendBtn.disabled = false;&lt;br /&gt;
    input.placeholder = &amp;#039;Stelle eine Frage \u00fcber M\u00fcnster \u2026&amp;#039;;&lt;br /&gt;
    input.focus();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  newBtn.addEventListener(&amp;#039;click&amp;#039;, resetConversation);&lt;br /&gt;
&lt;br /&gt;
  form.addEventListener(&amp;#039;submit&amp;#039;, function(e) {&lt;br /&gt;
    e.preventDefault();&lt;br /&gt;
    if (isLoading) return;&lt;br /&gt;
    var message = input.value.trim();&lt;br /&gt;
    if (!message) return;&lt;br /&gt;
&lt;br /&gt;
    input.value = &amp;#039;&amp;#039;;&lt;br /&gt;
    addUserMessage(message);&lt;br /&gt;
    setLoading(true);&lt;br /&gt;
&lt;br /&gt;
    var body = { message: message };&lt;br /&gt;
    if (conversationId) {&lt;br /&gt;
      body.conversation_id = conversationId;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var url = location.protocol + &amp;#039;//&amp;#039; + apiHost + &amp;#039;/chat&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
    fetch(url, {&lt;br /&gt;
      method: &amp;#039;POST&amp;#039;,&lt;br /&gt;
      headers: { &amp;#039;Content-Type&amp;#039;: &amp;#039;application/json&amp;#039; },&lt;br /&gt;
      body: JSON.stringify(body)&lt;br /&gt;
    })&lt;br /&gt;
      .then(function(res) {&lt;br /&gt;
        if (!res.ok) {&lt;br /&gt;
          return res.json().then(function(data) {&lt;br /&gt;
            throw new Error(data.detail || &amp;#039;HTTP &amp;#039; + res.status);&lt;br /&gt;
          });&lt;br /&gt;
        }&lt;br /&gt;
        return res.json();&lt;br /&gt;
      })&lt;br /&gt;
      .then(function(data) {&lt;br /&gt;
        setLoading(false);&lt;br /&gt;
        conversationId = data.conversation_id;&lt;br /&gt;
        addAssistantMessage(data.answer);&lt;br /&gt;
        renderSources(data.sources);&lt;br /&gt;
        updateStatus(data.remaining_followups);&lt;br /&gt;
        input.focus();&lt;br /&gt;
      })&lt;br /&gt;
      .catch(function(err) {&lt;br /&gt;
        setLoading(false);&lt;br /&gt;
        addError(&amp;#039;Fehler: &amp;#039; + err.message);&lt;br /&gt;
        input.focus();&lt;br /&gt;
      });&lt;br /&gt;
  });&lt;br /&gt;
})();&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Alex</name></author>
	</entry>
</feed>