今天改的是这位: https://linux.do/t/topic/186209?u=stellafortuna
声明:服务作者限定为二级用户可用,本帖不限制,但想使用需获取密码,鼓励大家更加活跃冲二级~
根据原作者的初代demo站源码改的
也是相当方便的
不过改成一坨了![]()
更新日志
发帖时:目前尝试支持了两个gpt模型,都是可以用的
二十八日凌晨1点:进行一波小更新,目前支持了v1和v2调用,优化了页面显示,支持i18n! 更多细节,请各位佬友自行发现~
29日凌晨1点:重磅更新,继续优化UI,优化暗色模式,添加语言切换选项,添加查询余额功能 新加了一个日期分隔符 最重要的是什么?现在支持所有已知可用模型啦!
演示站稍后更新
30日18点:演示站更新…
31日17点:再次宣布更新~ 该版本修复了查询额度失败的问题,更新了支持模型表,更换了字体,避免需魔法
的困境,优化部分文案提示,支持复制信息和重新回答(复制手机用不了
) ,现在支持一键清除聊天记录了,添加了一个欢迎信息(请不要试图让他重新回答…)演示站同步更新
我们让老伙计websim来优化一下UI,并免费提供专属域名~
演示站(20240831):https://websim.ai/@Stella/aiduihuawebui
代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>星缘AI助手 - 智能对话体验</title>
<style>
:root {
--primary-color: #4a90e2;
--secondary-color: #50c878;
--text-color: #333;
--background-color: #f6f9fc;
--chat-background: #ffffff;
--input-background: #f0f4f8;
--button-hover: #3a7bd5;
--shadow-color: rgba(74, 144, 226, 0.1);
--message-user: linear-gradient(135deg, #4a90e2 0%, #50c878 100%);
--message-bot: linear-gradient(135deg, #e0e3e8 0%, #c7d2fe 100%);
--input-border: #d1d9e6;
--scrollbar-thumb: #c1c1c1;
--scrollbar-track: #f1f1f1;
}
.dark-mode {
--primary-color: #6a8caf;
--secondary-color: #68b88e;
--text-color: #e0e0e0;
--background-color: #1a1a2e;
--chat-background: #16213e;
--input-background: #0f3460;
--button-hover: #5a72a3;
--shadow-color: rgba(106, 140, 175, 0.2);
--message-user: linear-gradient(135deg, #6a8caf 0%, #68b88e 100%);
--message-bot: linear-gradient(135deg, #2c3e50 0%, #34495e 100%);
--input-border: #2c3e50;
--scrollbar-thumb: #4a4a4a;
--scrollbar-track: #2a2a2a;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
background: var(--background-color);
color: var(--text-color);
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
padding: 20px;
transition: all 0.3s ease;
}
.chat-container {
width: 100%;
max-width: 1000px;
background-color: var(--chat-background);
border-radius: 20px;
box-shadow: 0 10px 50px var(--shadow-color);
display: flex;
flex-direction: column;
overflow: hidden;
}
.chat-header {
padding: 20px;
background: var(--message-user);
color: #fff;
text-align: center;
font-size: 24px;
font-weight: 500;
display: flex;
justify-content: space-between;
align-items: center;
}
.header-controls {
display: flex;
align-items: center;
gap: 10px;
}
#channelSelect, #modelSelect, #languageSelect {
padding: 8px;
border-radius: 5px;
border: 1px solid var(--input-border);
background-color: var(--input-background);
color: var(--text-color);
font-size: 14px;
}
.btn {
background: rgba(255,255,255,0.2);
border: none;
color: white;
font-size: 20px;
cursor: pointer;
transition: all 0.3s ease;
padding: 8px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.btn:hover {
background: rgba(255,255,255,0.4);
transform: scale(1.1);
}
.chat-messages {
padding: 30px;
flex-grow: 1;
overflow-y: auto;
max-height: 60vh;
scroll-behavior: smooth;
}
.chat-messages::-webkit-scrollbar {
width: 10px;
}
.chat-messages::-webkit-scrollbar-thumb {
background-color: var(--scrollbar-thumb);
border-radius: 5px;
}
.chat-messages::-webkit-scrollbar-track {
background-color: var(--scrollbar-track);
}
.message {
margin-bottom: 20px;
display: flex;
flex-direction: column;
max-width: 80%;
animation: fadeIn 0.5s ease-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.message.user {
align-items: flex-end;
align-self: flex-end;
}
.message.bot {
align-items: flex-start;
}
.message p {
padding: 15px 20px;
border-radius: 20px;
margin: 0;
line-height: 1.5;
position: relative;
box-shadow: 0 5px 15px var(--shadow-color);
color: #fff;
font-size: 16px;
}
.message.user p {
background: var(--message-user);
border-bottom-right-radius: 0;
}
.message.bot p {
background: var(--message-bot);
border-bottom-left-radius: 0;
color: var(--text-color);
}
.timestamp {
font-size: 0.75em;
color: #888;
margin-top: 5px;
}
.chat-input-container {
padding: 20px;
background-color: var(--input-background);
display: flex;
align-items: center;
gap: 10px;
}
.chat-input {
flex-grow: 1;
padding: 15px;
border: 2px solid var(--input-border);
border-radius: 30px;
outline: none;
font-size: 16px;
resize: none;
overflow-y: auto;
max-height: 150px;
background: var(--chat-background);
color: var(--text-color);
transition: all 0.3s ease;
}
.chat-input:focus {
border-color: var(--secondary-color);
box-shadow: 0 0 15px rgba(80, 200, 120, 0.1);
}
.chat-send-btn {
padding: 15px 30px;
background: var(--message-user);
color: white;
border: none;
border-radius: 30px;
cursor: pointer;
font-size: 16px;
font-weight: 600;
transition: all 0.3s ease;
box-shadow: 0 5px 15px var(--shadow-color);
}
.chat-send-btn:hover {
transform: translateY(-2px);
box-shadow: 0 7px 20px var(--shadow-color);
}
.modal {
display: none;
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0,0,0,0.4);
animation: fadeIn 0.3s;
}
.modal-content {
background: var(--chat-background);
margin: 10% auto;
padding: 40px;
border: 1px solid var(--input-border);
width: 80%;
max-width: 500px;
border-radius: 20px;
box-shadow: 0 10px 50px rgba(0,0,0,0.1);
color: var(--text-color);
}
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
cursor: pointer;
transition: color 0.3s ease;
}
.close:hover,
.close:focus {
color: var(--primary-color);
}
#authorizationInput {
width: 100%;
padding: 15px;
margin: 15px 0;
border: 2px solid var(--input-border);
border-radius: 10px;
font-size: 16px;
background-color: var(--input-background);
color: var(--text-color);
transition: all 0.3s ease;
}
#authorizationInput:focus {
border-color: var(--secondary-color);
box-shadow: 0 0 15px rgba(80, 200, 120, 0.1);
outline: none;
}
#saveSettings {
background: var(--message-user);
color: white;
border: none;
padding: 15px 25px;
border-radius: 10px;
cursor: pointer;
font-size: 16px;
font-weight: 600;
transition: all 0.3s ease;
width: 100%;
margin-top: 20px;
box-shadow: 0 5px 15px var(--shadow-color);
}
#saveSettings:hover {
transform: translateY(-2px);
box-shadow: 0 7px 20px var(--shadow-color);
}
.theme-switch {
display: flex;
align-items: center;
margin-top: 20px;
}
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
margin-right: 10px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
transition: .4s;
border-radius: 34px;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
transition: .4s;
border-radius: 50%;
}
input:checked + .slider {
background: var(--message-user);
}
input:checked + .slider:before {
transform: translateX(26px);
}
.loading-overlay {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 1000;
justify-content: center;
align-items: center;
}
.loading-spinner {
width: 50px;
height: 50px;
border: 3px solid #fff;
border-top: 3px solid var(--primary-color);
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.tooltip {
position: relative;
display: inline-block;
}
.tooltip .tooltiptext {
visibility: hidden;
width: 120px;
background-color: var(--primary-color);
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px 0;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
margin-left: -60px;
opacity: 0;
transition: opacity 0.3s;
}
.tooltip:hover .tooltiptext {
visibility: visible;
opacity: 1;
}
.date-divider {
text-align: center;
margin: 20px 0;
color: var(--text-color);
font-size: 0.9em;
opacity: 0.7;
}
.message-actions {
display: flex;
justify-content: flex-end;
margin-top: 5px;
}
.message-action {
background: none;
border: none;
color: var(--text-color);
cursor: pointer;
font-size: 0.8em;
margin-left: 10px;
opacity: 0.6;
transition: opacity 0.3s ease;
}
.message-action:hover {
opacity: 1;
}
@media (max-width: 768px) {
.chat-container {
height: 100vh;
border-radius: 0;
}
.chat-header {
font-size: 20px;
padding: 15px;
}
.header-controls {
flex-direction: column;
align-items: flex-end;
}
#channelSelect, #modelSelect, #languageSelect {
margin-bottom: 10px;
}
.chat-input, .chat-send-btn {
font-size: 14px;
}
.modal-content {
width: 90%;
margin: 20% auto;
}
}
</style>
</head>
<body>
<div class="chat-container">
<div class="chat-header">
<span data-i18n="title">星缘AI助手</span>
<div class="header-controls">
<select id="languageSelect" aria-label="选择语言">
<option value="zh">中文</option>
<option value="en">English</option>
</select>
<select id="channelSelect" aria-label="选择 API 渠道">
<option value="v1" data-i18n="v1">V1极速(支持GPT全家桶)</option>
<option value="v2" data-i18n="v2">V2包容(慢,可用三大家族)</option>
</select>
<select id="modelSelect" aria-label="选择模型"></select>
<button class="btn tooltip" id="checkBalanceBtn" aria-label="查询请求余额">
💰
<span class="tooltiptext" data-i18n="checkBalance">查询请求余额</span>
</button>
<button class="btn tooltip" id="settingsBtn" aria-label="设置">
⚙️
<span class="tooltiptext" data-i18n="settings">设置</span>
</button>
</div>
</div>
<div class="chat-messages" id="chat-messages">
<!-- 消息将显示在这里 -->
</div>
<div class="chat-input-container">
<textarea id="chat-input" class="chat-input" placeholder="输入你的消息..." rows="1" data-i18n-placeholder="inputPlaceholder"></textarea>
<button id="chat-send-btn" class="chat-send-btn" data-i18n="send">发送</button>
</div>
</div>
<div id="settingsModal" class="modal">
<div class="modal-content">
<span class="close">×</span>
<h2 data-i18n="settings">设置</h2>
<input type="text" id="authorizationInput" placeholder="输入 Authorization">
<div class="theme-switch">
<label class="switch">
<input type="checkbox" id="themeSwitch">
<span class="slider"></span>
</label>
<span data-i18n="darkMode">暗色模式</span>
</div>
<button id="saveSettings" data-i18n="saveSettings">保存设置</button>
</div>
</div>
<div id="loadingOverlay" class="loading-overlay">
<div class="loading-spinner"></div>
</div>
<script>
const chatMessages = document.getElementById('chat-messages');
const chatInput = document.getElementById('chat-input');
const chatSendBtn = document.getElementById('chat-send-btn');
const settingsBtn = document.getElementById('settingsBtn');
const settingsModal = document.getElementById('settingsModal');
const closeBtn = document.getElementsByClassName('close')[0];
const saveSettingsBtn = document.getElementById('saveSettings');
const authorizationInput = document.getElementById('authorizationInput');
const modelSelect = document.getElementById('modelSelect');
const themeSwitch = document.getElementById('themeSwitch');
const channelSelect = document.getElementById('channelSelect');
const loadingOverlay = document.getElementById('loadingOverlay');
const checkBalanceBtn = document.getElementById('checkBalanceBtn');
const languageSelect = document.getElementById('languageSelect');
const chatHistory = [];
let userScrolled = false;
let authorization = localStorage.getItem('authorization') || '';
let selectedModel = localStorage.getItem('selectedModel') || 'gpt-3.5-turbo-0125';
let selectedChannel = localStorage.getItem('selectedChannel') || 'v1';
// 获取URL查询字符串
const queryString = window.location.search;
// 使用URLSearchParams解析查询字符串
const urlParams = new URLSearchParams(queryString);
// 提取token参数
let urlParamsToken = urlParams.get('token');
// 如果URL中有token,则保存到localStorage
if (urlParamsToken) {
localStorage.setItem('authorization', urlParamsToken);
authorization = urlParamsToken;
// 清除URL中的token参数
window.history.replaceState({}, document.title, window.location.pathname);
}
function showLoading() {
loadingOverlay.style.display = 'flex';
}
function hideLoading() {
loadingOverlay.style.display = 'none';
}
function appendMessage(content, sender) {
const message = document.createElement('div');
message.classList.add('message', sender);
const timestamp = new Date().toLocaleTimeString();
message.innerHTML = `
<p>${content}</p>
<span class="timestamp">${timestamp}</span>
<div class="message-actions">
<button class="message-action copy-btn">复制</button>
${sender === 'bot' ? '<button class="message-action regenerate-btn">重新生成</button>' : ''}
</div>
`;
const lastMessage = chatMessages.lastElementChild;
if (lastMessage && !lastMessage.classList.contains('date-divider')) {
const lastDate = new Date(lastMessage.querySelector('.timestamp').textContent);
const currentDate = new Date();
if (lastDate.toDateString() !== currentDate.toDateString()) {
const dateDivider = document.createElement('div');
dateDivider.classList.add('date-divider');
dateDivider.textContent = currentDate.toLocaleDateString();
chatMessages.appendChild(dateDivider);
}
}
chatMessages.appendChild(message);
if (!userScrolled) {
chatMessages.scrollTop = chatMessages.scrollHeight;
}
// 添加复制和重新生成功能
message.querySelector('.copy-btn').addEventListener('click', () => copyMessage(content));
if (sender === 'bot') {
message.querySelector('.regenerate-btn').addEventListener('click', () => regenerateResponse());
}
return message;
}
function copyMessage(content) {
navigator.clipboard.writeText(content).then(() => {
alert('消息已复制到剪贴板');
}).catch(err => {
console.error('复制失败:', err);
});
}
function regenerateResponse() {
// 移除最后一条bot消息
chatHistory.pop();
chatMessages.removeChild(chatMessages.lastElementChild);
// 重新生成响应
getBotResponse(chatHistory[chatHistory.length - 1].content);
}
async function getBotResponse(userMessage) {
try {
showLoading();
const botMessageElement = appendMessage("", 'bot');
const loadingSpinner = document.createElement('div');
loadingSpinner.classList.add('loading');
botMessageElement.prepend(loadingSpinner);
chatHistory.push({
"role": "user",
"content": userMessage
});
const apiUrl = selectedChannel === 'v1' ? 'https://i-i.win/v1/v1/chat/completions' : 'https://i-i.win/v2/v1/chat/completions';
const response = await fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': authorization,
},
body: JSON.stringify({
"messages": chatHistory,
"stream": "true",
"model": selectedModel
})
});
const reader = response.body.getReader();
const decoder = new TextDecoder('utf-8');
let partialContent = "";
while (true) {
const {done, value} = await reader.read();
if (done) break;
const chunk = decoder.decode(value, {stream: true});
partialContent += chunk;
const lines = partialContent.split('\n');
for (let line of lines) {
if (line.trim().startsWith("data:")) {
const jsonStr = line.replace("data:", "").trim();
if (jsonStr === "[DONE]" || jsonStr === "") continue;
try {
const jsonData = JSON.parse(jsonStr);
const content = jsonData.choices[0].delta.content;
if (content) {
loadingSpinner.remove();
botMessageElement.querySelector('p').textContent += content;
if (!userScrolled) {
chatMessages.scrollTop = chatMessages.scrollHeight;
}
}
} catch (error) {
console.error("解析JSON时出错: ", error);
}
}
}
partialContent = lines[lines.length - 1];
}
const botResponse = botMessageElement.querySelector('p').textContent;
chatHistory.push({
"role": "assistant",
"content": botResponse
});
return botResponse;
} catch (error) {
console.error('获取机器人响应时出错:', error);
return "抱歉,连接服务器时出现错误。";
} finally {
hideLoading();
}
}
function adjustTextareaHeight() {
chatInput.style.height = 'auto';
chatInput.style.height = (chatInput.scrollHeight) + 'px';
}
function updateTheme() {
const isDarkMode = localStorage.getItem('darkMode') === 'true';
document.body.classList.toggle('dark-mode', isDarkMode);
themeSwitch.checked = isDarkMode;
}
function updateModelOptions() {
const v1Models = [
"gpt-3.5-turbo-0125", "gpt-4o-mini-2024-07-18", "gpt-4-0314", "gpt-4-32k-0314",
"gpt-4-0613", "gpt-4-1106-preview", "gpt-4-1106-vision-preview", "gpt-4-0125-preview",
"gpt-4-turbo-2024-04-09", "gpt-4o-2024-05-13", "gpt-4o-2024-08-06", "chatgpt-4o-latest"
];
const v2Models = [
"gpt-3.5-turbo", "gpt-4o-mini-2024-07-18", "gpt-4o", "gpt-4o-2024-08-06", "chatgpt-4o-latest",
"claude-2", "claude-2.0", "claude-2.1", "claude-3-sonnet-20240229", "claude-3-haiku-20240307",
"claude-3-opus-20240229", "claude-3-5-sonnet-20240620",
"gemini-pro", "gemini-1.0-pro", "gemini-1.0-pro-latest", "gemini-1.5-pro", "gemini-1.5-flash",
"mixtral-8x7b-32768"
];
const models = selectedChannel === 'v1' ? v1Models : v2Models;
modelSelect.innerHTML = models.map(model => `<option value="${model}">${model}</option>`).join('');
modelSelect.value = selectedModel;
}
async function checkBalance() {
try {
showLoading();
const response = await fetch('https://i-i.win/getTimes', {
method: 'POST',
headers: {
'Authorization': authorization
}
});
const data = await response.json();
hideLoading();
alert(`剩余额度:${data.remainingTimes}\n\n注意:此额度为两种渠道共用。如果额度用完,请联系原作者添加。`);
} catch (error) {
console.error('查询余额时出错:', error);
hideLoading();
alert('查询余额失败,请稍后重试');
}
}
chatMessages.addEventListener('scroll', () => {
const isAtBottom = chatMessages.scrollTop + chatMessages.clientHeight >= chatMessages.scrollHeight - 10;
userScrolled = !isAtBottom;
});
chatSendBtn.addEventListener('click', async () => {
const userMessage = chatInput.value.trim();
if (userMessage !== "") {
appendMessage(userMessage, 'user');
chatInput.value = '';
adjustTextareaHeight();
await getBotResponse(userMessage);
}
});
chatInput.addEventListener('keydown', (e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
chatSendBtn.click();
}
});
chatInput.addEventListener('input', adjustTextareaHeight);
settingsBtn.onclick = () => {
settingsModal.style.display = "block";
authorizationInput.value = authorization;
}
closeBtn.onclick = () => {
settingsModal.style.display = "none";
}
window.onclick = (event) => {
if (event.target == settingsModal) {
settingsModal.style.display = "none";
}
}
saveSettingsBtn.onclick = () => {
authorization = authorizationInput.value;
localStorage.setItem('authorization', authorization);
settingsModal.style.display = "none";
}
themeSwitch.addEventListener('change', () => {
localStorage.setItem('darkMode', themeSwitch.checked);
updateTheme();
});
channelSelect.addEventListener('change', (e) => {
selectedChannel = e.target.value;
localStorage.setItem('selectedChannel', selectedChannel);
updateModelOptions();
});
modelSelect.addEventListener('change', (e) => {
selectedModel = e.target.value;
localStorage.setItem('selectedModel', selectedModel);
});
checkBalanceBtn.addEventListener('click', checkBalance);
// 多语言支持
const translations = {
'zh': {
'title': '星缘AI助手',
'v1': 'V1极速(支持GPT全家桶)',
'v2': 'V2包容(慢,可用三大家族)',
'settings': '设置',
'send': '发送',
'inputPlaceholder': '输入你的消息...',
'saveSettings': '保存设置',
'checkBalance': '查询余额',
'darkMode': '暗色模式'
},
'en': {
'title': 'AI Chat Assistant',
'v1': 'V1 Channel (Fast, Fewer Models)',
'v2': 'V2 Channel (Slower, More Models)',
'settings': 'Settings',
'send': 'Send',
'inputPlaceholder': 'Enter your message...',
'saveSettings': 'Save Settings',
'checkBalance': 'Check Balance',
'darkMode': 'Dark Mode'
}
};
function setLanguage(lang) {
document.querySelectorAll('[data-i18n]').forEach(element => {
const key = element.getAttribute('data-i18n');
if (translations[lang] && translations[lang][key]) {
element.textContent = translations[lang][key];
}
});
document.querySelectorAll('[data-i18n-placeholder]').forEach(element => {
const key = element.getAttribute('data-i18n-placeholder');
if (translations[lang] && translations[lang][key]) {
element.placeholder = translations[lang][key];
}
});
document.documentElement.lang = lang;
}
languageSelect.addEventListener('change', (e) => {
setLanguage(e.target.value);
localStorage.setItem('language', e.target.value);
});
document.addEventListener('DOMContentLoaded', () => {
channelSelect.value = selectedChannel;
updateModelOptions();
updateTheme();
const savedLanguage = localStorage.getItem('language') || 'zh';
languageSelect.value = savedLanguage;
setLanguage(savedLanguage);
// 添加欢迎消息
appendMessage("欢迎使用星缘AI助手!我是您的智能对话伙伴,随时准备回答您的问题和提供帮助。请问有什么我可以为您做的吗?", 'bot');
});
// 添加自动保存聊天记录功能
function saveChat() {
localStorage.setItem('chatHistory', JSON.stringify(chatHistory));
}
function loadChat() {
const savedChat = localStorage.getItem('chatHistory');
if (savedChat) {
const parsedChat = JSON.parse(savedChat);
parsedChat.forEach(msg => {
appendMessage(msg.content, msg.role === 'user' ? 'user' : 'bot');
});
chatHistory.push(...parsedChat);
}
}
// 在页面加载时加载聊天记录
loadChat();
// 在每次发送消息后保存聊天记录
chatSendBtn.addEventListener('click', saveChat);
// 添加清除聊天记录功能
function clearChat() {
chatHistory.length = 0;
chatMessages.innerHTML = '';
localStorage.removeItem('chatHistory');
appendMessage("聊天记录已清除。有什么新的问题我可以帮您解答吗?", 'bot');
}
// 添加清除聊天记录按钮
const clearChatBtn = document.createElement('button');
clearChatBtn.textContent = '清除聊天';
clearChatBtn.classList.add('btn', 'tooltip');
clearChatBtn.innerHTML = '🗑️ <span class="tooltiptext">清除聊天记录</span>';
clearChatBtn.addEventListener('click', clearChat);
document.querySelector('.header-controls').appendChild(clearChatBtn);
</script>
</body>
</html>


