diff --git a/.gitignore b/.gitignore
index b30cf7c..f6f0715 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,8 @@ templates/style.css
.gitignore
/python
.vscode/settings.json
+static/resource/20241126011143_Notification-and-Programme-for-BTech-RIST-Odd-Semester-December-2024.pdf
+static/resource/an-old-hope.min.css
+/.gitignore
+from ollama import chat.py
+demo.html
diff --git a/index.py b/index.py
index 09bd970..296d1f6 100644
--- a/index.py
+++ b/index.py
@@ -6,52 +6,86 @@
import datetime
import threading
from queue import Queue
-
+import uuid
con_path = ""
-app = Flask(__name__, template_folder='templates')
-
+date_str = ""
conversation = []
clients = []
chat_history = []
clients_lock = threading.Lock()
stream_flow = False
-date_time = datetime.datetime.now()
-
-# Save conversation in a new file
-def save_conversation():
- global con_path # Use the global variable to store the file path across calls
+chat_title = "Starting New chat"
+app = Flask(__name__, template_folder='templates')
+def getId():
+ global date_str
+ current_time = datetime.datetime.now()
+ formatted_time = current_time.strftime("%Y%m%d_%H%M%S")
+ date_str = formatted_time
+ print(date_str)
+getId()
+def save_conversation(create_new_file=False):
+ global con_path, date_str,chat_title # Use the global variables to store the file path and date_str across calls
# Define the folder where logs are stored
folder_name = 'log_data/conversation_logs'
if not os.path.exists(folder_name):
os.makedirs(folder_name)
-
- # Get the current date (without time) to use as part of the filename
- date_str = datetime.datetime.now().strftime("%Y-%m-%d-%h-%m")
-
- # If `con_path` is None or if it doesn't match today's date, create a new file path
- if not con_path or date_str not in con_path:
+ if create_new_file or not con_path or date_str not in con_path:
filename = f'conversation_{date_str}.json'
con_path = os.path.join(folder_name, filename)
+ elif not create_new_file and con_path:
+ pass
+ if not date_str:
+ date_str = str(uuid.uuid4()) # Generate a unique date_str for the conversation
+
+ # Prepare the data structure with only the conversation array for subsequent saves
+ conversation_data = {
+ "chat_title" : chat_title,
+ "chat_id": date_str,
+ "conversation": conversation # Assume `conversation` is a list holding conversation data
+ }
# Save or update the conversation data in the JSON file
if os.path.exists(con_path):
- # Load existing data and append new data to it
+ # Load existing data
with open(con_path, 'r+') as f:
try:
existing_data = json.load(f)
except json.JSONDecodeError:
existing_data = []
- existing_data.extend(conversation)
+
+ # Check if the file already contains the conversation with the same chat_id
+ existing_chat_ids = [entry["chat_id"] for entry in existing_data]
+ if date_str in existing_chat_ids:
+ # If the chat_id already exists, just update the existing conversation array
+ for entry in existing_data:
+ if entry["chat_id"] == date_str:
+ entry["conversation"] = conversation # Overwrite the conversation data
+ break
+ else:
+ # Add new conversation if chat_id doesn't exist
+ existing_data.append(conversation_data)
+
+ # Save the updated conversation data back to the file
f.seek(0)
json.dump(existing_data, f, indent=4)
+
else:
# Create new file if it doesn't exist
with open(con_path, 'w') as f:
- json.dump(conversation, f, indent=4)
+ json.dump([conversation_data], f, indent=4) # Wrap in a list to store multiple conversations
print(f"Conversation saved to {con_path}")
+def new_chat(title,create_new_file=False):
+ print("Request for new chat.")
+ global conversation, con_path, chat_title
+ conversation = []
+ con_path = ""
+ chat_title = title
+ getId()
+ save_conversation(create_new_file=True)
+
def client(data):
"""Send data to all connected clients."""
with clients_lock:
@@ -59,10 +93,14 @@ def client(data):
client.put(data)
# Generate LLM response
-def generate_response(prompt, model):
- print(prompt, model)
+def generate_response(prompt, model,chat_request):
+ print(prompt, model,chat_request)
if prompt == "":
return
+ if chat_request == True:
+ print("true")
+ new_chat(prompt[:20])
+
user_rep_st = "[|/__USER_START__/|]"
client(user_rep_st)
client(f"{prompt}")
@@ -98,18 +136,17 @@ def generate_response(prompt, model):
save_conversation()
client(done_marker)
-
def process(message_chunk):
- match message_chunk:
- case _ if "\n" in message_chunk or message_chunk == "":
- message_chunk = "
"
- case _ if "\n\n\n" in message_chunk:
- message_chunk = "
Model: | +${model} | +
Size (Decimal): | +${sizeInGB} | +
Parameter Size: | +${parameter_size} | +
Family: | +${family} | +
Format: | +${format} | +
Quantization Level: | +${quantization_level} | +
`;
+ } else {
+ // End of a code block
+ inCodeBlock = false;
+ result += '
$1') // Blockquotes + .replace(/^\-\-\-$/gm, '
blocks
+ const tempDiv = document.createElement('div');
+ tempDiv.innerHTML = text; // Set the text as HTML content
+
+ // Get all the elements inside the temporary element
+ const codeElements = tempDiv.querySelectorAll('code');
+
+ // If no blocks are found, return the original text
+ if (codeElements.length === 0) {
+ console.log("No code blocks found.");
+ return text; // Return the text as-is if no elements are present
+ }
+
+ // Process each element if present
+ codeElements.forEach(el => {
+
+ // Highlight each code element using the Highlight.js library
+ hljs.highlightElement(el);
+ });
+
+ // Return the modified HTML text with highlighted blocks
+ return tempDiv.innerHTML;
+}
diff --git a/static/resource/marked.min.js b/static/resource/marked.min.js
deleted file mode 100644
index 52c443c..0000000
--- a/static/resource/marked.min.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * marked v6.0.0 - a markdown parser
- * Copyright (c) 2011-2023, Christopher Jeffrey. (MIT Licensed)
- * https://github.com/markedjs/marked
- */
-"use strict"; var marked = (() => {
- var e, t = Object.defineProperty, j = Object.getOwnPropertyDescriptor, L = Object.getOwnPropertyNames, D = Object.prototype.hasOwnProperty, n = (e, t, n) => { if (t.has(e)) throw TypeError("Cannot add the same private member more than once"); t instanceof WeakSet ? t.add(e) : t.set(e, n) }, p = (e, t, n) => { var s = "access private method"; if (t.has(e)) return n; throw TypeError("Cannot " + s) }, s = {}, C = s, r = { Hooks: () => I, Lexer: () => v, Marked: () => J, Parser: () => A, Renderer: () => S, Slugger: () => R, TextRenderer: () => T, Tokenizer: () => w, defaults: () => l, getDefaults: () => i, lexer: () => oe, marked: () => O, options: () => te, parse: () => le, parseInline: () => ie, parser: () => ae, setOptions: () => ne, use: () => se, walkTokens: () => re }; for (e in r) t(C, e, { get: r[e], enumerable: !0 }); function i() { return { async: !1, baseUrl: null, breaks: !1, extensions: null, gfm: !0, headerIds: !0, headerPrefix: "", highlight: null, hooks: null, langPrefix: "language-", mangle: !0, pedantic: !1, renderer: null, sanitize: !1, sanitizer: null, silent: !1, smartypants: !1, tokenizer: null, walkTokens: null, xhtml: !1 } } var l = i(); function a(e) { l = e } var o = /[&<>"']/, B = new RegExp(o.source, "g"), h = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/, U = new RegExp(h.source, "g"), Q = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }, c = e => Q[e]; function u(e, t) { if (t) { if (o.test(e)) return e.replace(B, c) } else if (h.test(e)) return e.replace(U, c); return e } var M = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi; function z(e) { return e.replace(M, (e, t) => "colon" === (t = t.toLowerCase()) ? ":" : "#" === t.charAt(0) ? "x" === t.charAt(1) ? String.fromCharCode(parseInt(t.substring(2), 16)) : String.fromCharCode(+t.substring(1)) : "") } var N = /(^|[^\[])\^/g; function g(n, e) { n = "string" == typeof n ? n : n.source, e = e || ""; const s = { replace: (e, t) => (t = (t = "object" == typeof t && "source" in t ? t.source : t).replace(N, "$1"), n = n.replace(e, t), s), getRegex: () => new RegExp(n, e) }; return s } var H = /[^\w:]/g, F = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i; function d(e, t, n) { if (e) { let e; try { e = decodeURIComponent(z(n)).replace(H, "").toLowerCase() } catch (e) { return null } if (0 === e.indexOf("javascript:") || 0 === e.indexOf("vbscript:") || 0 === e.indexOf("data:")) return null } var s; t && !F.test(n) && (e = n, k[" " + (t = t)] || (W.test(t) ? k[" " + t] = t + "/" : k[" " + t] = m(t, "/", !0)), s = -1 === (t = k[" " + t]).indexOf(":"), n = "//" === e.substring(0, 2) ? s ? e : t.replace(X, "$1") + e : "/" === e.charAt(0) ? s ? e : t.replace(G, "$1") + e : t + e); try { n = encodeURI(n).replace(/%25/g, "%") } catch (e) { return null } return n } var k = {}, W = /^[^:]+:\/*[^/]*$/, X = /^([^:]+:)[\s\S]*$/, G = /^([^:]+:\/*[^/]*)[\s\S]*$/; var f = { exec: () => null }; function x(e, t) { var n = e.replace(/\|/g, (e, t, n) => { let s = !1, r = t; for (; 0 <= --r && "\\" === n[r];)s = !s; return s ? "|" : " |" }).split(/ \|/); let s = 0; if (n[0].trim() || n.shift(), 0 < n.length && !n[n.length - 1].trim() && n.pop(), n.length > t) n.splice(t); else for (; n.length < t;)n.push(""); for (; s < n.length; s++)n[s] = n[s].trim().replace(/\\\|/g, "|"); return n } function m(e, t, n) { var s = e.length; if (0 === s) return ""; let r = 0; for (; r < s;) { var i = e.charAt(s - r - 1); if ((i !== t || n) && (i === t || !n)) break; r++ } return e.slice(0, s - r) } function b(e, t, n, s) { var r = t.href, t = t.title ? u(t.title) : null, i = e[1].replace(/\\([\[\]])/g, "$1"); return "!" !== e[0].charAt(0) ? (s.state.inLink = !0, e = { type: "link", raw: n, href: r, title: t, text: i, tokens: s.inlineTokens(i) }, s.state.inLink = !1, e) : { type: "image", raw: n, href: r, title: t, text: u(i) } } var w = class { constructor(e) { this.options = e || l } space(e) { e = this.rules.block.newline.exec(e); if (e && 0 < e[0].length) return { type: "space", raw: e[0] } } code(e) { var t, e = this.rules.block.code.exec(e); if (e) return t = e[0].replace(/^ {1,4}/gm, ""), { type: "code", raw: e[0], codeBlockStyle: "indented", text: this.options.pedantic ? t : m(t, "\n") } } fences(e) { var t, n, e = this.rules.block.fences.exec(e); if (e) return n = function (e, t) { if (null === (e = e.match(/^(\s+)(?:```)/))) return t; const n = e[1]; return t.split("\n").map(e => { var t = e.match(/^\s+/); return null !== t && ([t] = t, t.length >= n.length) ? e.slice(n.length) : e }).join("\n") }(t = e[0], e[3] || ""), { type: "code", raw: t, lang: e[2] && e[2].trim().replace(this.rules.inline._escapes, "$1"), text: n } } heading(t) { var n, t = this.rules.block.heading.exec(t); if (t) { let e = t[2].trim(); return /#$/.test(e) && (n = m(e, "#"), !this.options.pedantic && n && !/ $/.test(n) || (e = n.trim())), { type: "heading", raw: t[0], depth: t[1].length, text: e, tokens: this.lexer.inline(e) } } } hr(e) { e = this.rules.block.hr.exec(e); if (e) return { type: "hr", raw: e[0] } } blockquote(e) { var t, n, s, e = this.rules.block.blockquote.exec(e); if (e) return t = e[0].replace(/^ *>[ \t]?/gm, ""), n = this.lexer.state.top, this.lexer.state.top = !0, s = this.lexer.blockTokens(t), this.lexer.state.top = n, { type: "blockquote", raw: e[0], tokens: s, text: t } } list(g) { let d = this.rules.block.list.exec(g); if (d) { let e, t, n, s, r, i, l, a, o, h, c, p, u = d[1].trim(); for (var k = 1 < u.length, f = { type: "list", raw: "", ordered: k, start: k ? +u.slice(0, -1) : "", loose: !1, items: [] }, x = (u = k ? "\\d{1,9}\\" + u.slice(-1) : "\\" + u, this.options.pedantic && (u = k ? u : "[*+-]"), new RegExp(`^( {0,3}${u})((?:[ ][^\\n]*)?(?:\\n|$))`)); g && (p = !1, d = x.exec(g)) && !this.rules.block.hr.test(g);) { if (e = d[0], g = g.substring(e.length), a = d[2].split("\n", 1)[0].replace(/^\t+/, e => " ".repeat(3 * e.length)), o = g.split("\n", 1)[0], this.options.pedantic ? (s = 2, c = a.trimLeft()) : (s = 4 < (s = d[2].search(/[^ ]/)) ? 1 : s, c = a.slice(s), s += d[1].length), i = !1, !a && /^ *$/.test(o) && (e += o + "\n", g = g.substring(o.length + 1), p = !0), !p) for (var m = new RegExp(`^ {0,${Math.min(3, s - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`), b = new RegExp(`^ {0,${Math.min(3, s - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`), w = new RegExp(`^ {0,${Math.min(3, s - 1)}}(?:\`\`\`|~~~)`), y = new RegExp(`^ {0,${Math.min(3, s - 1)}}#`); g && (h = g.split("\n", 1)[0], o = h, this.options.pedantic && (o = o.replace(/^ {1,4}(?=( {4})*[^ ])/g, " ")), !w.test(o)) && !y.test(o) && !m.test(o) && !b.test(g);) { if (o.search(/[^ ]/) >= s || !o.trim()) c += "\n" + o.slice(s); else { if (i) break; if (4 <= a.search(/[^ ]/)) break; if (w.test(a)) break; if (y.test(a)) break; if (b.test(a)) break; c += "\n" + o } i || o.trim() || (i = !0), e += h + "\n", g = g.substring(h.length + 1), a = o.slice(s) } f.loose || (l ? f.loose = !0 : /\n *\n *$/.test(e) && (l = !0)), this.options.gfm && (t = /^\[[ xX]\] /.exec(c)) && (n = "[ ] " !== t[0], c = c.replace(/^\[[ xX]\] +/, "")), f.items.push({ type: "list_item", raw: e, task: !!t, checked: n, loose: !1, text: c }), f.raw += e } f.items[f.items.length - 1].raw = e.trimRight(), f.items[f.items.length - 1].text = c.trimRight(), f.raw = f.raw.trimRight(); var _, $ = f.items.length; for (r = 0; r < $; r++)this.lexer.state.top = !1, f.items[r].tokens = this.lexer.blockTokens(f.items[r].text, []), f.loose || (_ = 0 < (_ = f.items[r].tokens.filter(e => "space" === e.type)).length && _.some(e => /\n.*\n/.test(e.raw)), f.loose = _); if (f.loose) for (r = 0; r < $; r++)f.items[r].loose = !0; return f } } html(e) { var t, n, e = this.rules.block.html.exec(e); if (e) return t = { type: "html", block: !0, raw: e[0], pre: !this.options.sanitizer && ("pre" === e[1] || "script" === e[1] || "style" === e[1]), text: e[0] }, this.options.sanitize && (e = this.options.sanitizer ? this.options.sanitizer(e[0]) : u(e[0]), (n = t).type = "paragraph", n.text = e, n.tokens = this.lexer.inline(e)), t } def(e) { var t, n, s, e = this.rules.block.def.exec(e); if (e) return t = e[1].toLowerCase().replace(/\s+/g, " "), n = e[2] ? e[2].replace(/^<(.*)>$/, "$1").replace(this.rules.inline._escapes, "$1") : "", s = e[3] && e[3].substring(1, e[3].length - 1).replace(this.rules.inline._escapes, "$1"), { type: "def", tag: t, raw: e[0], href: n, title: s } } table(i) { i = this.rules.block.table.exec(i); if (i) { var l = { type: "table", header: x(i[1]).map(e => ({ text: e })), align: i[2].replace(/^ *|\| *$/g, "").split(/ *\| */), rows: i[3] && i[3].trim() ? i[3].replace(/\n[ \t]*$/, "").split("\n") : [] }; if (l.header.length === l.align.length) { l.raw = i[0]; let e = l.align.length, t, n, s, r; for (t = 0; t < e; t++)/^ *-+: *$/.test(l.align[t]) ? l.align[t] = "right" : /^ *:-+: *$/.test(l.align[t]) ? l.align[t] = "center" : /^ *:-+ *$/.test(l.align[t]) ? l.align[t] = "left" : l.align[t] = null; for (e = l.rows.length, t = 0; t < e; t++)l.rows[t] = x(l.rows[t], l.header.length).map(e => ({ text: e })); for (e = l.header.length, n = 0; n < e; n++)l.header[n].tokens = this.lexer.inline(l.header[n].text); for (e = l.rows.length, n = 0; n < e; n++)for (r = l.rows[n], s = 0; s < r.length; s++)r[s].tokens = this.lexer.inline(r[s].text); return l } } } lheading(e) { e = this.rules.block.lheading.exec(e); if (e) return { type: "heading", raw: e[0], depth: "=" === e[2].charAt(0) ? 1 : 2, text: e[1], tokens: this.lexer.inline(e[1]) } } paragraph(e) { var t, e = this.rules.block.paragraph.exec(e); if (e) return t = "\n" === e[1].charAt(e[1].length - 1) ? e[1].slice(0, -1) : e[1], { type: "paragraph", raw: e[0], text: t, tokens: this.lexer.inline(t) } } text(e) { e = this.rules.block.text.exec(e); if (e) return { type: "text", raw: e[0], text: e[0], tokens: this.lexer.inline(e[0]) } } escape(e) { e = this.rules.inline.escape.exec(e); if (e) return { type: "escape", raw: e[0], text: u(e[1]) } } tag(e) { e = this.rules.inline.tag.exec(e); if (e) return !this.lexer.state.inLink && /^/i.test(e[0]) && (this.lexer.state.inLink = !1), !this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(e[0]) ? this.lexer.state.inRawBlock = !0 : this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(e[0]) && (this.lexer.state.inRawBlock = !1), { type: this.options.sanitize ? "text" : "html", raw: e[0], inLink: this.lexer.state.inLink, inRawBlock: this.lexer.state.inRawBlock, block: !1, text: this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(e[0]) : u(e[0]) : e[0] } } link(n) { n = this.rules.inline.link.exec(n); if (n) { var s = n[2].trim(); if (!this.options.pedantic && /^$/.test(s)) return; var r = m(s.slice(0, -1), "\\"); if ((s.length - r.length) % 2 == 0) return } else { var i, r = function (n, s) { if (-1 !== n.indexOf(s[1])) { var r = n.length; let e = 0, t = 0; for (; t < r; t++)if ("\\" === n[t]) t++; else if (n[t] === s[0]) e++; else if (n[t] === s[1] && --e < 0) return t } return -1 }(n[2], "()"); -1 < r && (i = (0 === n[0].indexOf("!") ? 5 : 4) + n[1].length + r, n[2] = n[2].substring(0, r), n[0] = n[0].substring(0, i).trim(), n[3] = "") } let e = n[2], t = ""; return this.options.pedantic ? (r = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(e)) && (e = r[1], t = r[3]) : t = n[3] ? n[3].slice(1, -1) : "", e = e.trim(), b(n, { href: (e = /^$/.test(s) ? e.slice(1) : e.slice(1, -1) : e) && e.replace(this.rules.inline._escapes, "$1"), title: t && t.replace(this.rules.inline._escapes, "$1") }, n[0], this.lexer) } } reflink(t, n) { let s; if (s = (s = this.rules.inline.reflink.exec(t)) || this.rules.inline.nolink.exec(t)) { let e = (s[2] || s[1]).replace(/\s+/g, " "); return (e = n[e.toLowerCase()]) ? b(s, e, s[0], this.lexer) : { type: "text", raw: t = s[0].charAt(0), text: t } } } emStrong(r, i, e = "") { let l = this.rules.inline.emStrong.lDelim.exec(r); if (l && ((!l[3] || !e.match(/[\p{L}\p{N}]/u)) && (!(l[1] || l[2] || "") || !e || this.rules.inline.punctuation.exec(e)))) { var a = l[0].length - 1; let e, t, n = a, s = 0; var o, h, c = "*" === l[0][0] ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd; for (c.lastIndex = 0, i = i.slice(-1 * r.length + a); null != (l = c.exec(i));)if (e = l[1] || l[2] || l[3] || l[4] || l[5] || l[6]) if (t = e.length, l[3] || l[4]) n += t; else if ((l[5] || l[6]) && a % 3 && !((a + t) % 3)) s += t; else if (!(0 < (n -= t))) return t = Math.min(t, t + n + s), o = r.slice(0, a + l.index + t + 1), Math.min(a, t) % 2 ? (h = o.slice(1, -1), { type: "em", raw: o, text: h, tokens: this.lexer.inlineTokens(h) }) : (h = o.slice(2, -2), { type: "strong", raw: o, text: h, tokens: this.lexer.inlineTokens(h) }) } } codespan(t) { t = this.rules.inline.code.exec(t); if (t) { let e = t[2].replace(/\n/g, " "); var n = /[^ ]/.test(e), s = /^ /.test(e) && / $/.test(e); return e = u(e = n && s ? e.substring(1, e.length - 1) : e, !0), { type: "codespan", raw: t[0], text: e } } } br(e) { e = this.rules.inline.br.exec(e); if (e) return { type: "br", raw: e[0] } } del(e) { e = this.rules.inline.del.exec(e); if (e) return { type: "del", raw: e[0], text: e[2], tokens: this.lexer.inlineTokens(e[2]) } } autolink(n, s) { n = this.rules.inline.autolink.exec(n); if (n) { let e, t; return t = "@" === n[2] ? "mailto:" + (e = u(this.options.mangle ? s(n[1]) : n[1])) : e = u(n[1]), { type: "link", raw: n[0], text: e, href: t, tokens: [{ type: "text", raw: e, text: e }] } } } url(e, n) { var s, r; if (s = this.rules.inline.url.exec(e)) { let e, t; if ("@" === s[2]) e = u(this.options.mangle ? n(s[0]) : s[0]), t = "mailto:" + e; else { for (; r = s[0], s[0] = this.rules.inline._backpedal.exec(s[0])[0], r !== s[0];); e = u(s[0]), t = "www." === s[1] ? "http://" + s[0] : s[0] } return { type: "link", raw: s[0], text: e, href: t, tokens: [{ type: "text", raw: e, text: e }] } } } inlineText(t, n) { t = this.rules.inline.text.exec(t); if (t) { let e; return e = this.lexer.state.inRawBlock ? this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(t[0]) : u(t[0]) : t[0] : u(this.options.smartypants ? n(t[0]) : t[0]), { type: "text", raw: t[0], text: e } } } }, y = { newline: /^(?: *(?:\n|$))+/, code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/, fences: /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/, hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/, heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/, blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/, list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/, html: "^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)|(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$))", def: /^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/, table: f, lheading: /^((?:(?!^bull ).|\n(?!\n|bull ))+?)\n {0,3}(=+|-+) *(?:\n+|$)/, _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/, text: /^[^\n]+/, _label: /(?!\s*\])(?:\\.|[^\[\]\\])+/, _title: /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/ }, _ = (y.def = g(y.def).replace("label", y._label).replace("title", y._title).getRegex(), y.bullet = /(?:[*+-]|\d{1,9}[.)])/, y.listItemStart = g(/^( *)(bull) */).replace("bull", y.bullet).getRegex(), y.list = g(y.list).replace(/bull/g, y.bullet).replace("hr", "\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def", "\\n+(?=" + y.def.source + ")").getRegex(), y._tag = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul", y._comment = /|$)/, y.html = g(y.html, "i").replace("comment", y._comment).replace("tag", y._tag).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(), y.lheading = g(y.lheading).replace(/bull/g, y.bullet).getRegex(), y.paragraph = g(y._paragraph).replace("hr", y.hr).replace("heading", " {0,3}#{1,6} ").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", y._tag).getRegex(), y.blockquote = g(y.blockquote).replace("paragraph", y.paragraph).getRegex(), y.normal = { ...y }, y.gfm = { ...y.normal, table: "^ *([^\\n ].*\\|.*)\\n {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)" }, y.gfm.table = g(y.gfm.table).replace("hr", y.hr).replace("heading", " {0,3}#{1,6} ").replace("blockquote", " {0,3}>").replace("code", " {4}[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", y._tag).getRegex(), y.gfm.paragraph = g(y._paragraph).replace("hr", y.hr).replace("heading", " {0,3}#{1,6} ").replace("|lheading", "").replace("table", y.gfm.table).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", y._tag).getRegex(), y.pedantic = { ...y.normal, html: g(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?\\1> *(?:\\n{2,}|\\s*$)| \\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", y._comment).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(), def: /^ *\[([^\]]+)\]: *([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, heading: /^(#{1,6})(.*)(?:\n+|$)/, fences: f, lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, paragraph: g(y.normal._paragraph).replace("hr", y.hr).replace("heading", " *#{1,6} *[^\n]").replace("lheading", y.lheading).replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").getRegex() }, { escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/, autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/, url: f, tag: "^comment|^[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^", link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/, reflink: /^!?\[(label)\]\[(ref)\]/, nolink: /^!?\[(ref)\](?:\[\])?/, reflinkSearch: "reflink|nolink(?!\\()", emStrong: { lDelim: /^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/, rDelimAst: /^[^_*]*?__[^_*]*?\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\*)[punct](\*+)(?=[\s]|$)|[^punct\s](\*+)(?!\*)(?=[punct\s]|$)|(?!\*)[punct\s](\*+)(?=[^punct\s])|[\s](\*+)(?!\*)(?=[punct])|(?!\*)[punct](\*+)(?!\*)(?=[punct])|[^punct\s](\*+)(?=[^punct\s])/, rDelimUnd: /^[^_*]*?\*\*[^_*]*?_[^_*]*?(?=\*\*)|[^_]+(?=[^_])|(?!_)[punct](_+)(?=[\s]|$)|[^punct\s](_+)(?!_)(?=[punct\s]|$)|(?!_)[punct\s](_+)(?=[^punct\s])|[\s](_+)(?!_)(?=[punct])|(?!_)[punct](_+)(?!_)(?=[punct])/ }, code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/, br: /^( {2,}|\\)\n(?!\s*$)/, del: f, text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\`^|~", _.punctuation = g(_.punctuation, "u").replace(/punctuation/g, _._punctuation).getRegex(), _.blockSkip = /\[[^[\]]*?\]\([^\(\)]*?\)|`[^`]*?`|<[^<>]*?>/g, _.anyPunctuation = /\\[punct]/g, _._escapes = /\\([punct])/g, _._comment = g(y._comment).replace("(?:--\x3e|$)", "--\x3e").getRegex(), _.emStrong.lDelim = g(_.emStrong.lDelim, "u").replace(/punct/g, _._punctuation).getRegex(), _.emStrong.rDelimAst = g(_.emStrong.rDelimAst, "gu").replace(/punct/g, _._punctuation).getRegex(), _.emStrong.rDelimUnd = g(_.emStrong.rDelimUnd, "gu").replace(/punct/g, _._punctuation).getRegex(), _.anyPunctuation = g(_.anyPunctuation, "gu").replace(/punct/g, _._punctuation).getRegex(), _._escapes = g(_._escapes, "gu").replace(/punct/g, _._punctuation).getRegex(), _._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/, _._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/, _.autolink = g(_.autolink).replace("scheme", _._scheme).replace("email", _._email).getRegex(), _._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/, _.tag = g(_.tag).replace("comment", _._comment).replace("attribute", _._attribute).getRegex(), _._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/, _._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/, _._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/, _.link = g(_.link).replace("label", _._label).replace("href", _._href).replace("title", _._title).getRegex(), _.reflink = g(_.reflink).replace("label", _._label).replace("ref", y._label).getRegex(), _.nolink = g(_.nolink).replace("ref", y._label).getRegex(), _.reflinkSearch = g(_.reflinkSearch, "g").replace("reflink", _.reflink).replace("nolink", _.nolink).getRegex(), _.normal = { ..._ }, _.pedantic = { ..._.normal, strong: { start: /^__|\*\*/, middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/, endAst: /\*\*(?!\*)/g, endUnd: /__(?!_)/g }, em: { start: /^_|\*/, middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/, endAst: /\*(?!\*)/g, endUnd: /_(?!_)/g }, link: g(/^!?\[(label)\]\((.*?)\)/).replace("label", _._label).getRegex(), reflink: g(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", _._label).getRegex() }, _.gfm = { ..._.normal, escape: g(_.escape).replace("])", "~|])").getRegex(), _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/, url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/, del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/, text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\ t + " ".repeat(n.length)); let n, e, r, i; for (; s;)if (!(this.options.extensions && this.options.extensions.block && this.options.extensions.block.some(e => !!(n = e.call({ lexer: this }, s, t)) && (s = s.substring(n.raw.length), t.push(n), !0)))) if (n = this.tokenizer.space(s)) s = s.substring(n.raw.length), 1 === n.raw.length && 0 < t.length ? t[t.length - 1].raw += "\n" : t.push(n); else if (n = this.tokenizer.code(s)) s = s.substring(n.raw.length), !(e = t[t.length - 1]) || "paragraph" !== e.type && "text" !== e.type ? t.push(n) : (e.raw += "\n" + n.raw, e.text += "\n" + n.text, this.inlineQueue[this.inlineQueue.length - 1].src = e.text); else if (n = this.tokenizer.fences(s)) s = s.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.heading(s)) s = s.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.hr(s)) s = s.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.blockquote(s)) s = s.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.list(s)) s = s.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.html(s)) s = s.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.def(s)) s = s.substring(n.raw.length), !(e = t[t.length - 1]) || "paragraph" !== e.type && "text" !== e.type ? this.tokens.links[n.tag] || (this.tokens.links[n.tag] = { href: n.href, title: n.title }) : (e.raw += "\n" + n.raw, e.text += "\n" + n.raw, this.inlineQueue[this.inlineQueue.length - 1].src = e.text); else if (n = this.tokenizer.table(s)) s = s.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.lheading(s)) s = s.substring(n.raw.length), t.push(n); else { if (r = s, this.options.extensions && this.options.extensions.startBlock) { let t = 1 / 0; const a = s.slice(1); let n; this.options.extensions.startBlock.forEach(e => { "number" == typeof (n = e.call({ lexer: this }, a)) && 0 <= n && (t = Math.min(t, n)) }), t < 1 / 0 && 0 <= t && (r = s.substring(0, t + 1)) } if (this.state.top && (n = this.tokenizer.paragraph(r))) e = t[t.length - 1], i && "paragraph" === e.type ? (e.raw += "\n" + n.raw, e.text += "\n" + n.text, this.inlineQueue.pop(), this.inlineQueue[this.inlineQueue.length - 1].src = e.text) : t.push(n), i = r.length !== s.length, s = s.substring(n.raw.length); else if (n = this.tokenizer.text(s)) s = s.substring(n.raw.length), (e = t[t.length - 1]) && "text" === e.type ? (e.raw += "\n" + n.raw, e.text += "\n" + n.text, this.inlineQueue.pop(), this.inlineQueue[this.inlineQueue.length - 1].src = e.text) : t.push(n); else if (s) { var l = "Infinite loop on byte: " + s.charCodeAt(0); if (this.options.silent) { console.error(l); break } throw new Error(l) } } return this.state.top = !0, t } inline(e, t = []) { return this.inlineQueue.push({ src: e, tokens: t }), t } inlineTokens(s, t = []) { let n, e, r, i = s, l, a, o; if (this.tokens.links) { var h = Object.keys(this.tokens.links); if (0 < h.length) for (; null != (l = this.tokenizer.rules.inline.reflinkSearch.exec(i));)h.includes(l[0].slice(l[0].lastIndexOf("[") + 1, -1)) && (i = i.slice(0, l.index) + "[" + "a".repeat(l[0].length - 2) + "]" + i.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex)) } for (; null != (l = this.tokenizer.rules.inline.blockSkip.exec(i));)i = i.slice(0, l.index) + "[" + "a".repeat(l[0].length - 2) + "]" + i.slice(this.tokenizer.rules.inline.blockSkip.lastIndex); for (; null != (l = this.tokenizer.rules.inline.anyPunctuation.exec(i));)i = i.slice(0, l.index) + "++" + i.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex); for (; s;)if (a || (o = ""), a = !1, !(this.options.extensions && this.options.extensions.inline && this.options.extensions.inline.some(e => !!(n = e.call({ lexer: this }, s, t)) && (s = s.substring(n.raw.length), t.push(n), !0)))) if (n = this.tokenizer.escape(s)) s = s.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.tag(s)) s = s.substring(n.raw.length), (e = t[t.length - 1]) && "text" === n.type && "text" === e.type ? (e.raw += n.raw, e.text += n.text) : t.push(n); else if (n = this.tokenizer.link(s)) s = s.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.reflink(s, this.tokens.links)) s = s.substring(n.raw.length), (e = t[t.length - 1]) && "text" === n.type && "text" === e.type ? (e.raw += n.raw, e.text += n.text) : t.push(n); else if (n = this.tokenizer.emStrong(s, i, o)) s = s.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.codespan(s)) s = s.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.br(s)) s = s.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.del(s)) s = s.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.autolink(s, $)) s = s.substring(n.raw.length), t.push(n); else if (!this.state.inLink && (n = this.tokenizer.url(s, $))) s = s.substring(n.raw.length), t.push(n); else { if (r = s, this.options.extensions && this.options.extensions.startInline) { let t = 1 / 0; const p = s.slice(1); let n; this.options.extensions.startInline.forEach(e => { "number" == typeof (n = e.call({ lexer: this }, p)) && 0 <= n && (t = Math.min(t, n)) }), t < 1 / 0 && 0 <= t && (r = s.substring(0, t + 1)) } if (n = this.tokenizer.inlineText(r, V)) s = s.substring(n.raw.length), "_" !== n.raw.slice(-1) && (o = n.raw.slice(-1)), a = !0, (e = t[t.length - 1]) && "text" === e.type ? (e.raw += n.raw, e.text += n.text) : t.push(n); else if (s) { var c = "Infinite loop on byte: " + s.charCodeAt(0); if (this.options.silent) { console.error(c); break } throw new Error(c) } } return t } }, S = class {
- constructor(e) { this.options = e || l } code(e, t, n) { var s, t = (t || "").match(/\S*/)[0]; return this.options.highlight && null != (s = this.options.highlight(e, t)) && s !== e && (n = !0, e = s), e = e.replace(/\n$/, "") + "\n", t ? '' + (n ? e : u(e, !0)) + "
\n" : "" + (n ? e : u(e, !0)) + "
\n" } blockquote(e) {
- return `
-${e}
-`} html(e, t) { return e } heading(e, t, n, s) {
- return this.options.headerIds ? `${e}
-`: `${e}
-`} hr() { return this.options.xhtml ? "
\n" : "
\n" } list(e, t, n) { var s = t ? "ol" : "ul"; return "<" + s + (t && 1 !== n ? ' start="' + n + '"' : "") + ">\n" + e + "" + s + ">\n" } listitem(e, t, n) {
- return `- ${e}
-`} checkbox(e) { return " " } paragraph(e) {
- return `${e}
-`} table(e, t) { return "\n\n" + e + "\n" + (t = t && `${t}`) + "
\n" } tablerow(e) {
- return `
-${e}
-`} tablecell(e, t) {
- var n = t.header ? "th" : "td"; return (t.align ? `<${n} align="${t.align}">` : `<${n}>`) + e + `${n}>
-`} strong(e) { return `${e}` } em(e) { return `${e}` } codespan(e) { return `${e}
` } br() { return this.options.xhtml ? "
" : "
" } del(e) { return `${e}` } link(e, t, n) { if (null === (e = d(this.options.sanitize, this.options.baseUrl, e))) return n; let s = '" + n + "" } image(e, t, n) { if (null === (e = d(this.options.sanitize, this.options.baseUrl, e))) return n; let s = `" : ">" } text(e) { return e }
- }, T = class { strong(e) { return e } em(e) { return e } codespan(e) { return e } del(e) { return e } html(e) { return e } text(e) { return e } link(e, t, n) { return "" + n } image(e, t, n) { return "" + n } br() { return "" } }, R = class { constructor() { this.seen = {} } serialize(e) { return e.toLowerCase().trim().replace(/<[!\/a-z].*?>/gi, "").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, "").replace(/\s/g, "-") } getNextSafeSlug(e, t) { let n = e, s = 0; if (this.seen.hasOwnProperty(n)) for (s = this.seen[e]; s++, n = e + "-" + s, this.seen.hasOwnProperty(n);); return t || (this.seen[e] = s, this.seen[n] = 0), n } slug(e, t = {}) { e = this.serialize(e); return this.getNextSafeSlug(e, t.dryrun) } }, A = class { constructor(e) { this.options = e || l, this.options.renderer = this.options.renderer || new S, this.renderer = this.options.renderer, this.renderer.options = this.options, this.textRenderer = new T, this.slugger = new R } static parse(e, t) { return new A(t).parse(e) } static parseInline(e, t) { return new A(t).parseInline(e) } parse(e, t = !0) { let n = "", s, r, i, l, a, o, h, c, p, u, g, d, k, f, x, m, b, w, y; var _ = e.length; for (s = 0; s < _; s++)if (u = e[s], this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[u.type] && (!1 !== (y = this.options.extensions.renderers[u.type].call({ parser: this }, u)) || !["space", "hr", "heading", "code", "table", "blockquote", "list", "html", "paragraph", "text"].includes(u.type))) n += y || ""; else switch (u.type) { case "space": continue; case "hr": n += this.renderer.hr(); continue; case "heading": n += this.renderer.heading(this.parseInline(u.tokens), u.depth, z(this.parseInline(u.tokens, this.textRenderer)), this.slugger); continue; case "code": n += this.renderer.code(u.text, u.lang, !!u.escaped); continue; case "table": for (c = "", h = "", l = u.header.length, r = 0; r < l; r++)h += this.renderer.tablecell(this.parseInline(u.header[r].tokens), { header: !0, align: u.align[r] }); for (c += this.renderer.tablerow(h), p = "", l = u.rows.length, r = 0; r < l; r++) { for (o = u.rows[r], h = "", a = o.length, i = 0; i < a; i++)h += this.renderer.tablecell(this.parseInline(o[i].tokens), { header: !1, align: u.align[i] }); p += this.renderer.tablerow(h) } n += this.renderer.table(c, p); continue; case "blockquote": p = this.parse(u.tokens), n += this.renderer.blockquote(p); continue; case "list": for (g = u.ordered, d = u.start, k = u.loose, l = u.items.length, p = "", r = 0; r < l; r++)m = (x = u.items[r]).checked, b = x.task, f = "", x.task && (w = this.renderer.checkbox(!!m), k ? 0 < x.tokens.length && "paragraph" === x.tokens[0].type ? (x.tokens[0].text = w + " " + x.tokens[0].text, x.tokens[0].tokens && 0 < x.tokens[0].tokens.length && "text" === x.tokens[0].tokens[0].type && (x.tokens[0].tokens[0].text = w + " " + x.tokens[0].tokens[0].text)) : x.tokens.unshift({ type: "text", text: w }) : f += w), f += this.parse(x.tokens, k), p += this.renderer.listitem(f, b, !!m); n += this.renderer.list(p, g, d); continue; case "html": n += this.renderer.html(u.text, u.block); continue; case "paragraph": n += this.renderer.paragraph(this.parseInline(u.tokens)); continue; case "text": for (p = u.tokens ? this.parseInline(u.tokens) : u.text; s + 1 < _ && "text" === e[s + 1].type;)u = e[++s], p += "\n" + (u.tokens ? this.parseInline(u.tokens) : u.text); n += t ? this.renderer.paragraph(p) : p; continue; default: var $ = 'Token with "' + u.type + '" type was not found.'; if (this.options.silent) return console.error($), ""; throw new Error($) }return n } parseInline(e, t) { t = t || this.renderer; let n = "", s, r, i; var l = e.length; for (s = 0; s < l; s++)if (r = e[s], this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[r.type] && (!1 !== (i = this.options.extensions.renderers[r.type].call({ parser: this }, r)) || !["escape", "html", "link", "image", "strong", "em", "codespan", "br", "del", "text"].includes(r.type))) n += i || ""; else switch (r.type) { case "escape": n += t.text(r.text); break; case "html": n += t.html(r.text); break; case "link": n += t.link(r.href, r.title, this.parseInline(r.tokens, t)); break; case "image": n += t.image(r.href, r.title, r.text); break; case "strong": n += t.strong(this.parseInline(r.tokens, t)); break; case "em": n += t.em(this.parseInline(r.tokens, t)); break; case "codespan": n += t.codespan(r.text); break; case "br": n += t.br(); break; case "del": n += t.del(this.parseInline(r.tokens, t)); break; case "text": n += t.text(r.text); break; default: var a = 'Token with "' + r.type + '" type was not found.'; if (this.options.silent) return console.error(a), ""; throw new Error(a) }return n } }, I = class { constructor(e) { this.options = e || l } preprocess(e) { return e } postprocess(e) { return e } }, J = (I.passThroughHooks = new Set(["preprocess", "postprocess"]), class { constructor(...e) { n(this, P), n(this, Y), this.defaults = i(), this.options = this.setOptions, this.parse = p(this, P, K).call(this, v.lex, A.parse), this.parseInline = p(this, P, K).call(this, v.lexInline, A.parseInline), this.Parser = A, this.parser = A.parse, this.Renderer = S, this.TextRenderer = T, this.Lexer = v, this.lexer = v.lex, this.Tokenizer = w, this.Slugger = R, this.Hooks = I, this.use(...e) } walkTokens(e, t) { let n = []; for (const s of e) switch (n = n.concat(t.call(this, s)), s.type) { case "table": for (const r of s.header) n = n.concat(this.walkTokens(r.tokens, t)); for (const i of s.rows) for (const l of i) n = n.concat(this.walkTokens(l.tokens, t)); break; case "list": n = n.concat(this.walkTokens(s.items, t)); break; default: this.defaults.extensions && this.defaults.extensions.childTokens && this.defaults.extensions.childTokens[s.type] ? this.defaults.extensions.childTokens[s.type].forEach(e => { n = n.concat(this.walkTokens(s[e], t)) }) : s.tokens && (n = n.concat(this.walkTokens(s.tokens, t))) }return n } use(...e) { const t = this.defaults.extensions || { renderers: {}, childTokens: {} }; return e.forEach(n => { var e = { ...n }; if (e.async = this.defaults.async || e.async || !1, n.extensions && (n.extensions.forEach(n => { if (!n.name) throw new Error("extension name required"); if ("renderer" in n) { const s = t.renderers[n.name]; s ? t.renderers[n.name] = function (...e) { let t = n.renderer.apply(this, e); return t = !1 === t ? s.apply(this, e) : t } : t.renderers[n.name] = n.renderer } if ("tokenizer" in n) { if (!n.level || "block" !== n.level && "inline" !== n.level) throw new Error("extension level must be 'block' or 'inline'"); t[n.level] ? t[n.level].unshift(n.tokenizer) : t[n.level] = [n.tokenizer], n.start && ("block" === n.level ? t.startBlock ? t.startBlock.push(n.start) : t.startBlock = [n.start] : "inline" === n.level && (t.startInline ? t.startInline.push(n.start) : t.startInline = [n.start])) } "childTokens" in n && n.childTokens && (t.childTokens[n.name] = n.childTokens) }), e.extensions = t), n.renderer) { const s = this.defaults.renderer || new S(this.defaults); for (const r in n.renderer) { const i = s[r]; s[r] = (...e) => { let t = n.renderer[r].apply(s, e); return t = !1 === t ? i.apply(s, e) : t } } e.renderer = s } if (n.tokenizer) { const l = this.defaults.tokenizer || new w(this.defaults); for (const a in n.tokenizer) { const o = l[a]; l[a] = (...e) => { let t = n.tokenizer[a].apply(l, e); return t = !1 === t ? o.apply(l, e) : t } } e.tokenizer = l } if (n.hooks) { const h = this.defaults.hooks || new I; for (const c in n.hooks) { const p = h[c]; I.passThroughHooks.has(c) ? h[c] = e => { return this.defaults.async ? Promise.resolve(n.hooks[c].call(h, e)).then(e => p.call(h, e)) : (e = n.hooks[c].call(h, e), p.call(h, e)) } : h[c] = (...e) => { let t = n.hooks[c].apply(h, e); return t = !1 === t ? p.apply(h, e) : t } } e.hooks = h } if (n.walkTokens) { const u = this.defaults.walkTokens; e.walkTokens = function (e) { let t = []; return t.push(n.walkTokens.call(this, e)), t = u ? t.concat(u.call(this, e)) : t } } this.defaults = { ...this.defaults, ...e } }), this } setOptions(e) { return this.defaults = { ...this.defaults, ...e }, this } }), P = new WeakSet, K = function (h, c) { return (t, e, r) => { "function" == typeof e && (r = e, e = null); var n, e = { ...e }; const i = { ...this.defaults, ...e }, l = p(this, Y, ee).call(this, !!i.silent, !!i.async, r); if (null == t) return l(new Error("marked(): input parameter is undefined or null")); if ("string" != typeof t) return l(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(t) + ", string expected")); if (e = i, n = r, e && !e.silent && (n && console.warn("marked(): callback is deprecated since version 5.0.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/using_pro#async"), (e.sanitize || e.sanitizer) && console.warn("marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options"), !e.highlight && "language-" === e.langPrefix || console.warn("marked(): highlight and langPrefix parameters are deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-highlight."), e.mangle && console.warn("marked(): mangle parameter is enabled by default, but is deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install https://www.npmjs.com/package/marked-mangle, or disable by setting `{mangle: false}`."), e.baseUrl && console.warn("marked(): baseUrl parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-base-url."), e.smartypants && console.warn("marked(): smartypants parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-smartypants."), e.xhtml && console.warn("marked(): xhtml parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-xhtml."), e.headerIds || e.headerPrefix) && console.warn("marked(): headerIds and headerPrefix parameters enabled by default, but are deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install https://www.npmjs.com/package/marked-gfm-heading-id, or disable by setting `{headerIds: false}`."), i.hooks && (i.hooks.options = i), r) { const a = i.highlight; let n; try { i.hooks && (t = i.hooks.preprocess(t)), n = h(t, i) } catch (e) { return l(e) } const o = t => { let e; if (!t) try { i.walkTokens && this.walkTokens(n, i.walkTokens), e = c(n, i), i.hooks && (e = i.hooks.postprocess(e)) } catch (e) { t = e } return i.highlight = a, t ? l(t) : r(null, e) }; if (!a || a.length < 3) return o(); if (delete i.highlight, !n.length) return o(); let s = 0; this.walkTokens(n, n => { "code" === n.type && (s++, setTimeout(() => { a(n.text, n.lang, (e, t) => { if (e) return o(e); null != t && t !== n.text && (n.text = t, n.escaped = !0), 0 === --s && o() }) }, 0)) }), void (0 === s && o()) } else { if (i.async) return Promise.resolve(i.hooks ? i.hooks.preprocess(t) : t).then(e => h(e, i)).then(e => i.walkTokens ? Promise.all(this.walkTokens(e, i.walkTokens)).then(() => e) : e).then(e => c(e, i)).then(e => i.hooks ? i.hooks.postprocess(e) : e).catch(l); try { i.hooks && (t = i.hooks.preprocess(t)); var s = h(t, i); i.walkTokens && this.walkTokens(s, i.walkTokens); let e = c(s, i); return e = i.hooks ? i.hooks.postprocess(e) : e } catch (e) { return l(e) } } } }, Y = new WeakSet, ee = function (n, s, r) { return e => { var t; if (e.message += "\nPlease report this to https://github.com/markedjs/marked.", n) return t = "An error occurred:
" + u(e.message + "", !0) + "
", s ? Promise.resolve(t) : r ? void r(null, t) : t; if (s) return Promise.reject(e); if (!r) throw e; r(e) } }, E = new J; function O(e, t, n) { return E.parse(e, t, n) } O.options = O.setOptions = function (e) { return E.setOptions(e), a(O.defaults = E.defaults), O }, O.getDefaults = i, O.defaults = l, O.use = function (...e) { return E.use(...e), a(O.defaults = E.defaults), O }, O.walkTokens = function (e, t) { return E.walkTokens(e, t) }, O.parseInline = E.parseInline, O.Parser = A, O.parser = A.parse, O.Renderer = S, O.TextRenderer = T, O.Lexer = v, O.lexer = v.lex, O.Tokenizer = w, O.Slugger = R, O.Hooks = I; var te = (O.parse = O).options, ne = O.setOptions, se = O.use, re = O.walkTokens, ie = O.parseInline, le = O, ae = A.parse, oe = v.lex, f = s, Z = t({}, "__esModule", { value: !0 }), q = f, he = void 0, ce = void 0; if (q && "object" == typeof q || "function" == typeof q) for (let e of L(q)) D.call(Z, e) || e === he || t(Z, e, { get: () => q[e], enumerable: !(ce = j(q, e)) || ce.enumerable }); return Z
-})();
\ No newline at end of file
diff --git a/static/script.js b/static/script.js
index ba0fc4f..98dfcc9 100644
--- a/static/script.js
+++ b/static/script.js
@@ -6,12 +6,49 @@ let code_block = true;
let flow = false;
const sentences = [];
let currentSentence = "";
-marked.use({
- mangle: false,
- headerIds: false,
+let new_chat = false
+const callButton = document.getElementById('CallButton');
+const speechContent = document.getElementById('speech_content');
+
+// Add click event listener to the button
+callButton.addEventListener('click', () => {
+ // Toggle the 'none' class
+ speechContent.classList.toggle('none');
+
});
+const new_chat_btn = document.getElementById('new_model_chat_container');
// Initialize the page and populate model list on load
+document.addEventListener("DOMContentLoaded", get_chats);
document.addEventListener("DOMContentLoaded", get_list);
+const selectElement = document.getElementById("select_model_btn");
+selectElement.addEventListener("change", (event) => {
+ console.log('Change detected!');
+ localStorage.setItem("selectedModel", event.target.value);
+});
+function setModel() {
+ const selectElement = document.getElementById("select_model_btn");
+ if (!selectElement) {
+ console.error('Select element not found in DOM!');
+ return;
+ }
+ const savedModel = localStorage.getItem("selectedModel");
+ if (savedModel) {
+ console.log('Using saved model');
+ selectElement.value = savedModel;
+ localStorage.setItem("selectedModel", savedModel);
+ } else {
+ console.log('No saved model found');
+ const currentModel = selectElement.value;
+ console.log(`Current select element value: ${currentModel}`);
+ localStorage.setItem("selectedModel", currentModel);
+ }
+ console.log('Adding event listener for changes...');
+ const originalChangeHandler = selectElement.addEventListener("change", (event) => {
+ console.log(`Change detected!`);
+ console.log(`Event target value: ${event.target.value}`);
+ localStorage.setItem("selectedModel", event.target.value);
+ });
+}
// Function to start a new message
function startMessage(speaker) {
const modelName = document.getElementById("select_model_btn").value || "Model";
@@ -60,23 +97,17 @@ function startMessage(speaker) {
if (speaker === "bot" && loadingIndicator) {
loadingIndicator.remove();
console.log("loadingremoved");
-
+
}
}
// Function to add content to the current message
function addContent(content) {
if (content !== undefined && content !== "") {
response_content += content; // Append chunk to the response content
-
- // If marked.parse was async, you would await it like this:
- const new_response = DOMPurify.sanitize(marked.parse(response_content));
-
+ var new_response = DOMPurify.sanitize(convertMarkdownToHTML(response_content));
messageContent.innerHTML = new_response; // Update message display
messageDiv.scrollHeight;
- // console.log(new_response);
-
if (currentSpeaker == "bot") {
-
if (need_speaker) {
text += content; // Buffer the content to form a sentence
// Check if the sentence is complete
@@ -90,176 +121,209 @@ function addContent(content) {
}
}
}
-function highlightAll() {
- // Get the last child div of the element with id 'new_msg'
- const last_div = document.querySelector('#new_msg > div:last-child');
-
- if (last_div) {
- // Find all 'code' elements within the last div
- last_div.querySelectorAll('code').forEach(el => {
- console.log("Before sanitizing:", el.innerHTML);
-
- // Sanitize the code bloc
- // Highlight each code element
- hljs.highlightElement(el);
- });
- } else {
- console.warn('No divs found inside #new_msg');
- }
-}
- // Function to determine if a sentence is complete
- function isSentenceComplete(text) {
- return /[.?]\s*$/.test(text.trim()); // Ends in a sentence-terminating punctuation
- }
+// Function to determine if a sentence is complete
+function isSentenceComplete(text) {
+ return /[.?]\s*$/.test(text.trim()); // Ends in a sentence-terminating punctuation
+}
- function processQueue() {
- if (!isSpeaking && textQueue.length > 0) {
- sentence = textQueue.shift(); // Get the next sentence from the queue
- cleanText(sentence); // Prepare the text and start TTS
- isSpeaking = true; // Set speaking status to true while TTS is active
- }
+function processQueue() {
+ if (!isSpeaking && textQueue.length > 0) {
+ sentence = textQueue.shift(); // Get the next sentence from the queue
+ cleanText(sentence); // Prepare the text and start TTS
+ isSpeaking = true; // Set speaking status to true while TTS is active
}
- function endMessage() {
- highlightAll();
- cleanText(text);
- text = "";
- response_content = "";
- flow = false;
- if (currentSpeaker === "user") {
- console.log("user");
- showLoadingIndicator("Thinking...")
- }
- currentSpeaker = null;
+}
+function endMessage() {
+ highlightAll();
+ cleanText(text);
+ text = "";
+ response_content = "";
+ flow = false;
+ if (currentSpeaker === "user") {
+ console.log("user");
+ showLoadingIndicator("Thinking...")
}
- function showLoadingIndicator(text) {
- // Create the loading indicator element
- loadingIndicator = document.createElement("div");
- loadingIndicator.className = "loading";
- loadingIndicator.innerHTML = text;
- // Ensure messageContent is defined and append the loading indicator
- if (messageContent) {
- messageDiv.appendChild(loadingIndicator);
- console.log(messageDiv, loadingIndicator);
-
- } else {
- console.error("messageContent is not defined");
- }
+ currentSpeaker = null;
}
+function showLoadingIndicator(text) {
+ // Create the loading indicator element
+ loadingIndicator = document.createElement("div");
+ loadingIndicator.className = "loading";
+ loadingIndicator.innerHTML = text;
+ // Ensure messageContent is defined and append the loading indicator
+ if (messageContent) {
+ messageDiv.appendChild(loadingIndicator);
+ console.log(messageDiv, loadingIndicator);
-function set_model(){
- const modelSelected = document.getElementById("select_model_btn").value;
-
+ } else {
+ console.error("messageContent is not defined");
+ }
}
- // Function to handle user input and send it to the server
- function sendUserInput() {
- const inputField = document.getElementById("userInput");
- const userPrompt = inputField.value.trim();
- const modelSelected = document.getElementById("select_model_btn").value;
-
- if (!modelSelected) {
- alert("Please select a model");
- return;
- }
- if (userPrompt) {
- fetch("/get_response", {
- method: "POST",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify({ prompt: userPrompt, model_need: modelSelected }),
- })
- .then((response) => response.json())
- .then((data) => {
- console.log("Response received:", data.response);
- })
- .catch((error) => console.error("Error:", error));
+function set_model() {
+ const modelSelected = document.getElementById("select_model_btn").value;
- inputField.value = ""; // Clear input field
- }
- }
+}
+// Function to handle user input and send it to the server
+function sendUserInput() {
+ const inputField = document.getElementById("userInput");
+ const userPrompt = inputField.value.trim();
+ const modelSelected = localStorage.getItem("selectedModel");
- // Function to create options for the model selection dropdown
- function createModelOption(name) {
- const selectElement = document.getElementById("select_model_btn");
- const option = document.createElement("option");
- option.value = name;
- option.textContent = name;
- selectElement.appendChild(option);
+ if (!modelSelected) {
+ alert("Please select a model");
+ return;
}
- // Fetch the list of models from the server and populate the dropdown
- function get_list() {
- fetch("/list_request", {
+ if (userPrompt) {
+ fetch("/get_response", {
method: "POST",
headers: { "Content-Type": "application/json" },
- body: JSON.stringify({ request: "list_of_llm" }),
+ body: JSON.stringify({ prompt: userPrompt, model_need: modelSelected, new_chat: new_chat }),
})
.then((response) => response.json())
.then((data) => {
- localStorage.setItem("list", JSON.stringify(data));
- data.list.models.forEach((model) => createModelOption(model.name));
- data.list.models.forEach((model) => createModalList(model.name));
- showNotification("List fetched successfully");
- save_log("List fetched successfully");
+ console.log("Response received:", data.response);
})
- .catch((error) => console.error("Fetch error:", error));
+ .catch((error) => console.error("Error:", error));
+
+ inputField.value = ""; // Clear input field
+ new_chat = false;
}
+}
- // Event listeners for submitting input
- document.getElementById("submitButton").onclick = sendUserInput;
- document.getElementById("userInput").addEventListener("keypress", (event) => {
- if (!flow && event.key === "Enter") sendUserInput();
- });
+// Function to create options for the model selection dropdown
+function createModelOption(name) {
+ const selectElement = document.getElementById("select_model_btn");
+ const option = document.createElement("option");
+ option.value = name;
+ option.textContent = name;
+ selectElement.appendChild(option);
+}
- // Function to enable or disable input based on action
- function action(isProcessing) {
- flow = isProcessing;
- document.getElementById("submitButton").disabled = isProcessing;
- console.log(isProcessing ? "Disabled" : "Enabled");
- }
+// Fetch the list of models from the server and populate the dropdown
+function get_list() {
+ fetch("/list_request", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ request: "list_of_llm" }),
+ })
+ .then((response) => response.json())
+ .then((data) => {
+ localStorage.setItem("list", JSON.stringify(data));
+ data.list.models.forEach((model) => createModelOption(model.name));
+ data.list.models.forEach((model) => createModalList(model.name, model.model, model.size, model.details.parameter_size, model.details.family, model.details.format, model.details.quantization_level));
+ showNotification("List fetched successfully");
+ save_log("List fetched successfully");
+ setModel()
+ })
+ .catch((error) => console.error("Fetch error:", error));
+}
+function get_chats() {
+ fetch("/get_chats", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ request: "list_of_llm" }),
+ })
+ .then((response) => response.json())
+ .then((data) => {
+ localStorage.setItem("chats", JSON.stringify(data));
+ console.log(data);
+ data.response.forEach(chat => {
+ model_chat_list(chat);
+ });
- // Event listener for receiving server messages
- const eventSource = new EventSource("/stream_response");
- eventSource.onmessage = function (event) {
- const response = event.data;
- switch (response) {
- case "[|/__USER_START__/|]":
- startMessage("user");
- break;
- case "[|/__USER_END__/|]":
- text = "";
- endMessage();
- break;
- case "[|/__START__/|]":
- text = "";
- action(true);
- startMessage("bot");
-
- break;
- case "[|/__DONE__/|]":
- endMessage();
- action(false);
- break;
- default:
- addContent(response);
- break;
- }
- };
-
- // Function to copy text to clipboard
- function copyToClipboard(text) {
- const textArea = document.createElement("textarea");
- textArea.value = text;
- document.body.appendChild(textArea);
- textArea.select();
- document.execCommand("copy");
- showNotification("Copied");
- save_log("coppied : " + text)
- document.body.removeChild(textArea);
- // alert("Copied to clipboard!");
- }
- const lastMessage = messageDiv.lastElementChild;
- if (lastMessage) {
- lastMessage.scrollIntoView({ behavior: "smooth" });
+
+ })
+ .catch((error) => console.error("Fetch error:", error));
+}
+
+// Event listeners for submitting input
+document.getElementById("submitButton").onclick = sendUserInput;
+document.getElementById("userInput").addEventListener("keypress", (event) => {
+ if (!flow && event.key === "Enter") sendUserInput();
+});
+
+function model_chat_list(modal_name) {
+ var continaer_of_all = document.getElementById('section_a_chats_holder');
+ // continaer_of_all.innerHTML = ""
+ var div = document.createElement("div");
+ var div1 = document.createElement("div");
+ var span = document.createElement("span");
+ var span1 = document.createElement("span");
+ var div2 = document.createElement("div");
+ var span2 = document.createElement("span");
+
+ div.className = "section_a_chats";
+ div1.className = "chat_title";
+ div2.className = "chat_option";
+
+ span.className = "chat_model_title";
+ span1.className = "time_of-active";
+ span2.className = "status_icons";
+
+ span.innerText = modal_name;
+ span2.innerHTML = '';
+
+
+ div1.appendChild(span);
+ div1.appendChild(span1);
+ div2.appendChild(span2);
+ div.appendChild(div1);
+ div.appendChild(div2);
+ continaer_of_all.append(div);
+
+}
+// Function to enable or disable input based on action
+function action(isProcessing) {
+ flow = isProcessing;
+ document.getElementById("submitButton").disabled = isProcessing;
+ console.log(isProcessing ? "Disabled" : "Enabled");
+}
+
+// Event listener for receiving server messages
+const eventSource = new EventSource("/stream_response");
+eventSource.onmessage = function (event) {
+ const response = event.data;
+ switch (response) {
+ case "[|/__USER_START__/|]":
+ startMessage("user");
+ break;
+ case "[|/__USER_END__/|]":
+ text = "";
+ endMessage();
+ break;
+ case "[|/__START__/|]":
+ text = "";
+ action(true);
+ startMessage("bot");
+
+ break;
+ case "[|/__DONE__/|]":
+ endMessage();
+ action(false);
+ break;
+ default:
+ addContent(response);
+ break;
}
+};
+
+// Function to copy text to clipboard
+function copyToClipboard(text) {
+ const textArea = document.createElement("textarea");
+ textArea.value = text;
+ document.body.appendChild(textArea);
+ textArea.select();
+ document.execCommand("copy");
+ showNotification("Copied");
+ save_log("coppied : " + text)
+ document.body.removeChild(textArea);
+ // alert("Copied to clipboard!");
+}
+const lastMessage = messageDiv.lastElementChild;
+if (lastMessage) {
+ lastMessage.scrollIntoView({ behavior: "smooth" });
+}
diff --git a/static/styles.css b/static/styles.css
index a67d3b8..dae3682 100644
--- a/static/styles.css
+++ b/static/styles.css
@@ -172,7 +172,7 @@ body {
.section_a_chats {
display: flex;
justify-content: space-between;
- background-color: var(--base_secondary);
+ background-color: #29233c;
border-radius: 10px;
cursor: pointer;
padding: 2px 10px;
@@ -181,12 +181,14 @@ body {
.section_a_chat_breif_container {
margin: 2px 1px;
}
-
+.section_a_chats:hover{
+ background-color: var(--base_secondary);
+}
/* Main Container */
.container_n {
width: 100%;
max-width: 1000px;
- padding: 20px;
+ padding: 5px;
border-radius: 12px;
display: flex;
flex-direction: column;
@@ -265,7 +267,7 @@ body {
/* Message Bubbles */
.message {
display: inline-block;
- padding: 10px 15px;
+ /* padding: 10px 15px; */
border-radius: 18px;
margin: 6px 0;
max-width: 75%;
@@ -442,16 +444,16 @@ select::after {
}
/* Scrollbar Styles */
-#new_msg::-webkit-scrollbar {
+::-webkit-scrollbar {
width: 8px;
}
-#new_msg::-webkit-scrollbar-thumb {
- background-color: #bb86fc;
+::-webkit-scrollbar-thumb {
+ background-color: #bb86fc63;
border-radius: 4px;
}
-#new_msg::-webkit-scrollbar-thumb:hover {
+::-webkit-scrollbar-thumb:hover {
background-color: #9f62e8;
}
diff --git a/templates/index.html b/templates/index.html
index be16689..179cd49 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -4,7 +4,6 @@
-
@@ -16,7 +15,6 @@
Ollama Chat
-
@@ -114,7 +112,7 @@
-
+
@@ -129,16 +127,7 @@
-->
-
-
-
- Mistral
-
-
-
-
-
-
+
@@ -181,12 +170,12 @@ Ollama Chat
-
+
-
+
@@ -311,10 +300,10 @@ Teminal
-