<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>LM Studio Chat</title>
<!-- Google Font -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet" />
<!-- Font Awesome Icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" integrity="sha512-Evv84Mr4kqVGRNSgIGL/F/aIDqQb7xQ2vcrdIwxfjThSH8CSR7PBEakCr51Ck+w+/U6swU2Im1vVX0SVk9ABhg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<!-- Highlight.js CSS for code blocks -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/atom-one-dark.min.css" />
<link rel="stylesheet" href="styles.css">
<!-- Markdown rendering library -->
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script>
marked.setOptions({
gfm: true,
breaks: true,
smartypants: true,
headerIds: false,
highlight: function(code, lang) {
if (lang && hljs.getLanguage(lang)) {
return hljs.highlight(code, { language: lang }).value;
}
return code;
}
});
</script>
<!-- Highlight.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
<!-- MathJax configuration for LaTeX support -->
<script>
window.MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']],
displayMath: [['$$', '$$'], ['\\[', '\\]']],
processEscapes: true,
packages: {'[+]': ['noerrors', 'noundefined']}
},
options: {
skipHtmlTags: ['script', 'noscript', 'style', 'textarea', 'pre'],
ignoreHtmlClass: 'tex2jax_ignore',
processHtmlClass: 'tex2jax_process'
},
svg: { fontCache: 'global' }
};
</script>
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" async></script>
</head>
<body>
<div id="app">
<div id="server-url-container">
<select id="server-type-select">
<option value="">Select Server Type...</option>
<option value="ollama">Ollama Local</option>
<option value="lmstudio">LM Studio Local</option>
<option value="openrouter">OpenRouter</option>
<option value="custom">Custom...</option>
</select>
<input type="text" id="custom-url" placeholder="Or enter custom URL..." style="display:none;" />
<input type="password" id="api-key" placeholder="API Key (if required)" style="display:none;" />
<input type="hidden" id="server-url-input" />
<select id="model-select" disabled>
<option value="">Select a model</option>
</select>
<button id="connect-button"><i class="fas fa-plug"></i> Connect</button>
</div>
<div id="connection-status">Disconnected</div>
<div id="main-content">
<!-- Chat Sidebar -->
<div id="chat-sidebar">
<button id="toggle-sidebar"><i class="fas fa-bars"></i></button>
<div class="sidebar-content">
<div id="chat-sidebar-header"><span>Chats</span></div>
<div id="system-prompt-container">
<label id="system-prompt-label" for="system-prompt-input">System Prompt:</label>
<textarea id="system-prompt-input" placeholder="Enter custom system prompt..."></textarea>
<button id="reset-system-prompt">Reset to Default</button>
</div>
<button id="new-chat-button"><i class="fas fa-plus"></i> New Chat</button>
<ul id="chat-list"></ul>
</div>
</div>
<!-- Chat Section -->
<div id="chat-section">
<div id="chat-container"></div>
<div id="input-container">
<button id="upload-button"><i class="fas fa-image"></i></button>
<input type="file" id="image-upload" accept="image/*" style="display:none;" />
<div id="image-preview"></div>
<input type="text" id="user-input" placeholder="Type a message..." disabled />
<button id="send-button"><i class="fas fa-paper-plane"></i></button>
</div>
</div>
</div>
</div>
<!-- Custom context menu for deleting chats -->
<div id="context-menu">Delete Chat</div>
<!-- Lightbox for image zoom -->
<div class="lightbox" id="lightbox">
<span class="lightbox-close">×</span>
<img id="lightbox-image" src="" alt="Agrandir" />
</div>
<script src="main.js"></script>
</body>
</html>