diff --git a/AKSHAT_YADAV/CHAT-APP/.env.example b/AKSHAT_YADAV/CHAT-APP/.env.example
new file mode 100644
index 0000000..76390d6
--- /dev/null
+++ b/AKSHAT_YADAV/CHAT-APP/.env.example
@@ -0,0 +1,15 @@
+# .env.example
+
+# LLM Keys
+OPENROUTER_API_KEY=
+
+# Firebase
+FIREBASE_API_KEY=
+FIREBASE_PROJECT_ID=
+FIREBASE_AUTH_DOMAIN=
+
+# PostgreSQL
+POSTGRES_URL=postgresql://username:password@localhost:5432/llm_chat_db
+
+# App
+SECRET_KEY=
\ No newline at end of file
diff --git a/AKSHAT_YADAV/CHAT-APP/.gitignore b/AKSHAT_YADAV/CHAT-APP/.gitignore
new file mode 100644
index 0000000..781240c
--- /dev/null
+++ b/AKSHAT_YADAV/CHAT-APP/.gitignore
@@ -0,0 +1,14 @@
+.env
+__pycache__/
+venv/
+*.pyc
+*.pyo
+*.pyd
+.DS_Store
+*.sqlite3
+*.log
+node_modules/
+FRONTEND/__pycache__/
+BACKEND/__pycache__/
+FRONTEND/venv/
+BACKEND/venv/
\ No newline at end of file
diff --git a/AKSHAT_YADAV/CHAT-APP/BACKEND/.gitignore b/AKSHAT_YADAV/CHAT-APP/BACKEND/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/AKSHAT_YADAV/CHAT-APP/BACKEND/db.py b/AKSHAT_YADAV/CHAT-APP/BACKEND/db.py
new file mode 100644
index 0000000..83a229d
--- /dev/null
+++ b/AKSHAT_YADAV/CHAT-APP/BACKEND/db.py
@@ -0,0 +1,9 @@
+import os
+import psycopg2
+from dotenv import load_dotenv
+
+load_dotenv()
+
+def get_db_connection():
+ conn = psycopg2.connect(os.getenv("POSTGRES_URL"))
+ return conn
\ No newline at end of file
diff --git a/AKSHAT_YADAV/CHAT-APP/BACKEND/main.py b/AKSHAT_YADAV/CHAT-APP/BACKEND/main.py
new file mode 100644
index 0000000..a64ae2f
--- /dev/null
+++ b/AKSHAT_YADAV/CHAT-APP/BACKEND/main.py
@@ -0,0 +1,126 @@
+# backend/main.py
+from fastapi import FastAPI, HTTPException, Body
+from fastapi.middleware.cors import CORSMiddleware
+from db import get_db_connection
+from pydantic import BaseModel
+from models.openrouter import call_openrouter
+import uuid
+import os
+import psycopg2
+from typing import List
+from dotenv import load_dotenv
+
+# Load environment variables
+load_dotenv()
+
+app = FastAPI()
+
+# Add CORS middleware
+app.add_middleware(
+ CORSMiddleware,
+ allow_origins=["*"], # Allows all origins
+ allow_credentials=True,
+ allow_methods=["*"], # Allows all methods
+ allow_headers=["*"], # Allows all headers
+)
+
+@app.get("/")
+def read_root():
+ return {"msg": "LLM Chat Backend is running"}
+
+
+# Pydantic models
+class SessionRequest(BaseModel):
+ user_id: str = None # Optional, but not required anymore
+
+class SessionResponse(BaseModel):
+ session_id: str
+
+class ChatMessage(BaseModel):
+ role: str # "user" or "assistant"
+ content: str
+
+class ChatRequest(BaseModel):
+ session_id: str
+ model: str
+ message: str
+
+class ChatResponse(BaseModel):
+ response: str
+
+class ChatHistoryResponse(BaseModel):
+ history: List[ChatMessage]
+
+@app.get("/db-test")
+def db_test():
+ try:
+ conn = get_db_connection()
+ cur = conn.cursor()
+ cur.execute("SELECT 1;")
+ result = cur.fetchone()
+ cur.close()
+ conn.close()
+ return {"db_connection": "success", "result": result}
+ except Exception as e:
+ return {"db_connection": "failed", "error": str(e)}
+
+
+# /chat/session endpoint
+@app.post("/chat/session", response_model=SessionResponse)
+def chat_session(payload: SessionRequest):
+ conn = get_db_connection()
+ cur = conn.cursor()
+ # Create new session (no user required)
+ session_id = str(uuid.uuid4())
+ cur.execute("INSERT INTO sessions (session_id) VALUES (%s)", (session_id,))
+ conn.commit()
+ cur.close()
+ conn.close()
+ return SessionResponse(session_id=session_id)
+
+@app.post("/chat", response_model=ChatResponse)
+def chat(request: ChatRequest):
+ conn = get_db_connection()
+ cur = conn.cursor()
+ # Get previous messages for context
+ cur.execute("SELECT role, message FROM chat_messages WHERE session_id = %s ORDER BY timestamp ASC", (request.session_id,))
+ history = [{"role": row[0], "content": row[1]} for row in cur.fetchall()]
+ # Add the new user message
+ history.append({"role": "user", "content": request.message})
+ # Call the LLM
+ response = call_openrouter(request.model, history)
+ # Save user message
+ cur.execute(
+ "INSERT INTO chat_messages (id, session_id, role, message, model) VALUES (%s, %s, %s, %s, %s)",
+ (str(uuid.uuid4()), request.session_id, "user", request.message, request.model)
+ )
+ # Save assistant message
+ cur.execute(
+ "INSERT INTO chat_messages (id, session_id, role, message, model) VALUES (%s, %s, %s, %s, %s)",
+ (str(uuid.uuid4()), request.session_id, "assistant", response, request.model)
+ )
+ conn.commit()
+ cur.close()
+ conn.close()
+ return ChatResponse(response=response)
+
+@app.get("/chat/history", response_model=ChatHistoryResponse)
+def chat_history(session_id: str):
+ conn = get_db_connection()
+ cur = conn.cursor()
+ cur.execute("SELECT role, message FROM chat_messages WHERE session_id = %s ORDER BY timestamp ASC", (session_id,))
+ history = [ChatMessage(role=row[0], content=row[1]) for row in cur.fetchall()]
+ cur.close()
+ conn.close()
+ return ChatHistoryResponse(history=history)
+
+# --- New endpoint to list all sessions (for sidebar)
+@app.get("/chat/sessions")
+def list_sessions():
+ conn = get_db_connection()
+ cur = conn.cursor()
+ cur.execute("SELECT session_id FROM sessions ORDER BY session_id DESC")
+ sessions = [row[0] for row in cur.fetchall()]
+ cur.close()
+ conn.close()
+ return {"sessions": sessions}
\ No newline at end of file
diff --git a/AKSHAT_YADAV/CHAT-APP/BACKEND/models/openrouter.py b/AKSHAT_YADAV/CHAT-APP/BACKEND/models/openrouter.py
new file mode 100644
index 0000000..5821c06
--- /dev/null
+++ b/AKSHAT_YADAV/CHAT-APP/BACKEND/models/openrouter.py
@@ -0,0 +1,32 @@
+import os
+import requests
+import json
+
+OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY")
+OPENROUTER_API_URL = "https://openrouter.ai/api/v1/chat/completions"
+
+def call_openrouter(model: str, messages: list):
+ if not OPENROUTER_API_KEY:
+ raise ValueError("OPENROUTER_API_KEY not found in environment variables")
+
+ headers = {
+ "Authorization": f"Bearer {OPENROUTER_API_KEY}",
+ "Content-Type": "application/json",
+ "HTTP-Referer": "http://localhost:3000", # Optional: your site URL
+ "X-Title": "LLM Chat App" # Optional: your app name
+ }
+ data = {
+ "model": model,
+ "messages": messages
+ }
+
+ try:
+ response = requests.post(OPENROUTER_API_URL, headers=headers, json=data)
+ print(f"OpenRouter response status: {response.status_code}")
+ print(f"OpenRouter response: {response.text}")
+ response.raise_for_status()
+ return response.json()["choices"][0]["message"]["content"]
+ except requests.exceptions.HTTPError as e:
+ print(f"OpenRouter API Error: {e}")
+ print(f"Request data: {json.dumps(data, indent=2)}")
+ raise e
\ No newline at end of file
diff --git a/AKSHAT_YADAV/CHAT-APP/BACKEND/requirements.txt b/AKSHAT_YADAV/CHAT-APP/BACKEND/requirements.txt
new file mode 100644
index 0000000..07a754f
Binary files /dev/null and b/AKSHAT_YADAV/CHAT-APP/BACKEND/requirements.txt differ
diff --git a/AKSHAT_YADAV/CHAT-APP/FRONTEND/.gitignore b/AKSHAT_YADAV/CHAT-APP/FRONTEND/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/AKSHAT_YADAV/CHAT-APP/FRONTEND/README.md b/AKSHAT_YADAV/CHAT-APP/FRONTEND/README.md
new file mode 100644
index 0000000..c79cb0d
--- /dev/null
+++ b/AKSHAT_YADAV/CHAT-APP/FRONTEND/README.md
@@ -0,0 +1,152 @@
+# LLM Chat App - Frontend
+
+A modern web-based chat interface for interacting with Large Language Models through OpenRouter API.
+
+## Features
+
+- **Modern UI**: Clean, responsive design inspired by ChatGPT
+- **Multiple Models**: Support for 5 different LLM models
+- **Session Management**: Create new chats and browse chat history
+- **Real-time Chat**: Instant messaging with typing indicators
+- **Responsive Design**: Works on desktop and mobile devices
+- **Auto-save**: All conversations are automatically saved
+
+## How to Run
+
+### Prerequisites
+- Backend server running on `http://localhost:8000`
+- Modern web browser (Chrome, Firefox, Safari, Edge)
+
+### Running the Frontend
+
+1. **Simple Method**: Just open `index.html` in your web browser
+ - Double-click the `index.html` file
+ - Or right-click and select "Open with browser"
+
+2. **Local Server Method** (recommended for development):
+ ```bash
+ # Using Python (if you have Python installed)
+ python -m http.server 8080
+
+ # Or using Node.js live-server (if you have Node.js)
+ npx live-server --port=8080
+
+ # Then open http://localhost:8080 in your browser
+ ```
+
+3. **VS Code Live Server Extension**:
+ - Install "Live Server" extension in VS Code
+ - Right-click on `index.html` and select "Open with Live Server"
+
+### Backend Setup
+Make sure your FastAPI backend is running:
+```bash
+cd ../BACKEND
+uvicorn main:app --reload
+```
+
+## File Structure
+
+```
+FRONTEND/
+├── index.html # Main HTML structure
+├── styles.css # All CSS styling
+├── script.js # JavaScript functionality
+└── README.md # This file
+```
+
+## Features Overview
+
+### Chat Interface
+- Clean, modern design with user and AI message bubbles
+- Typing indicators when AI is responding
+- Auto-scroll to latest messages
+- Timestamp for each message
+
+### Model Selection
+- Dropdown to choose between 5 LLM models:
+ - Mistral 7B Instruct
+ - OpenChat 3.5
+ - NeuralBeagle 7B
+ - Meta LLaMA 3 8B Instruct
+ - HuggingFace Zephyr 7B Beta
+
+### Session Management
+- Create new chat sessions
+- View all previous sessions in sidebar
+- Click on any session to load its history
+- Sessions are automatically saved in the database
+
+### User Experience
+- **Enter key** to send messages
+- **Shift+Enter** for new lines
+- Auto-resizing text input
+- Loading states and error handling
+- Connection status indicator
+- Mobile-responsive design
+
+## Browser Compatibility
+
+- Chrome 60+
+- Firefox 55+
+- Safari 12+
+- Edge 79+
+
+## Troubleshooting
+
+### Common Issues
+
+1. **"Failed to connect to backend"**
+ - Make sure the backend server is running on `http://localhost:8000`
+ - Check if there are any CORS issues in the browser console
+
+2. **Messages not sending**
+ - Verify your OpenRouter API key is set in the backend `.env` file
+ - Check browser console for JavaScript errors
+
+3. **Sessions not loading**
+ - Ensure PostgreSQL database is running
+ - Check if the database tables exist
+
+4. **Styling issues**
+ - Make sure all three files (HTML, CSS, JS) are in the same directory
+ - Check browser console for any file loading errors
+
+### Development Tips
+
+- Open browser Developer Tools (F12) to debug issues
+- Check the Network tab for API call failures
+- Console tab will show JavaScript errors
+- Use the responsive design mode to test mobile layout
+
+## API Endpoints Used
+
+The frontend communicates with these backend endpoints:
+
+- `GET /` - Health check
+- `POST /chat/session` - Create new session
+- `GET /chat/sessions` - Get all sessions
+- `POST /chat` - Send message
+- `GET /chat/history` - Get chat history
+
+## Customization
+
+### Styling
+Edit `styles.css` to customize:
+- Colors and themes
+- Layout and spacing
+- Animation effects
+- Mobile responsiveness
+
+### Functionality
+Edit `script.js` to modify:
+- API endpoints
+- Message formatting
+- User interactions
+- Error handling
+
+### Layout
+Edit `index.html` to change:
+- Page structure
+- UI components
+- Meta tags and title
diff --git a/AKSHAT_YADAV/CHAT-APP/FRONTEND/index.html b/AKSHAT_YADAV/CHAT-APP/FRONTEND/index.html
new file mode 100644
index 0000000..d49e731
--- /dev/null
+++ b/AKSHAT_YADAV/CHAT-APP/FRONTEND/index.html
@@ -0,0 +1,89 @@
+
+
+
+
+
+ LLM Chat App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Welcome to LLM Chat!
+
Select a model and start chatting. Your conversations are automatically saved.
+
+
+
+
+
+
+
+
+
+
+
+
+
Connecting to backend...
+
+
+
+
+
+
+
+
+
diff --git a/AKSHAT_YADAV/CHAT-APP/FRONTEND/requirements.txt b/AKSHAT_YADAV/CHAT-APP/FRONTEND/requirements.txt
new file mode 100644
index 0000000..f1c47e6
--- /dev/null
+++ b/AKSHAT_YADAV/CHAT-APP/FRONTEND/requirements.txt
@@ -0,0 +1,2 @@
+streamlit
+requests
\ No newline at end of file
diff --git a/AKSHAT_YADAV/CHAT-APP/FRONTEND/script.js b/AKSHAT_YADAV/CHAT-APP/FRONTEND/script.js
new file mode 100644
index 0000000..acf6857
--- /dev/null
+++ b/AKSHAT_YADAV/CHAT-APP/FRONTEND/script.js
@@ -0,0 +1,342 @@
+class ChatApp {
+ constructor() {
+ this.API_URL = 'http://localhost:8000';
+ this.currentSessionId = null;
+ this.currentModel = 'mistralai/mistral-7b-instruct';
+ this.isTyping = false;
+ this.sessions = [];
+
+ this.initializeElements();
+ this.setupEventListeners();
+ this.initialize();
+ }
+
+ initializeElements() {
+ this.loadingOverlay = document.getElementById('loading-overlay');
+ this.errorToast = document.getElementById('error-toast');
+ this.newChatBtn = document.getElementById('new-chat-btn');
+ this.modelSelect = document.getElementById('model-select');
+ this.currentModelSpan = document.getElementById('current-model');
+ this.sessionsList = document.getElementById('sessions-list');
+ this.chatMessages = document.getElementById('chat-messages');
+ this.messageInput = document.getElementById('message-input');
+ this.sendBtn = document.getElementById('send-btn');
+ this.connectionStatus = document.getElementById('connection-status');
+ }
+
+ setupEventListeners() {
+ this.newChatBtn.addEventListener('click', () => this.createNewSession());
+ this.modelSelect.addEventListener('change', (e) => {
+ this.currentModel = e.target.value;
+ this.updateModelDisplay();
+ });
+ this.sendBtn.addEventListener('click', () => this.sendMessage());
+ this.messageInput.addEventListener('keydown', (e) => {
+ if (e.key === 'Enter' && !e.shiftKey) {
+ e.preventDefault();
+ this.sendMessage();
+ }
+ });
+ this.messageInput.addEventListener('focus', () => {
+ this.messageInput.parentElement.classList.add('focused');
+ });
+ this.messageInput.addEventListener('blur', () => {
+ this.messageInput.parentElement.classList.remove('focused');
+ });
+ this.messageInput.addEventListener('input', () => {
+ this.autoResizeTextarea();
+ });
+ const toastClose = document.querySelector('.toast-close');
+ toastClose.addEventListener('click', () => this.hideError());
+ }
+
+ async initialize() {
+ try {
+ this.showLoading('Connecting to backend...');
+ await this.testConnection();
+ console.log('Backend connection successful');
+ this.updateConnectionStatus(true);
+ this.enableInterface();
+ try {
+ await this.loadSessions();
+ console.log('Sessions loaded:', this.sessions.length);
+ if (this.sessions.length == 0) {
+ console.log('Please Create a new session');
+ await this.createNewSession();
+ } else {
+ console.log('Loading most recent session');
+ await this.selectSession(this.sessions[0]);
+ }
+ } catch (sessionError) {
+ console.warn('Session loading failed, creating new session:', sessionError);
+ await this.createNewSession();
+ }
+
+ console.log('Initialization complete');
+
+ } catch (error) {
+ console.error('Backend connection failed:', error);
+ this.showError('Failed to connect to backend. Please make sure the server is running.');
+ this.updateConnectionStatus(false);
+ this.enableInterface();
+ } finally {
+ this.hideLoading();
+ }
+ }
+ async testConnection() {
+ const response = await fetch(`${this.API_URL}/`);
+ if (!response.ok) {
+ throw new Error('Backend connection failed');
+ }
+ return response.json();
+ }
+ async loadSessions() {
+ try {
+ const response = await fetch(`${this.API_URL}/chat/sessions`);
+ if (!response.ok) throw new Error('Failed to load sessions');
+
+ const data = await response.json();
+ this.sessions = data.sessions || [];
+ this.renderSessions();
+
+ } catch (error) {
+ console.error('Failed to load sessions:', error);
+ }
+ }
+
+ async createNewSession() {
+ try {
+ console.log('Creating new session...');
+ const response = await fetch(`${this.API_URL}/chat/session`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({}),
+ });
+
+ if (!response.ok) throw new Error('Failed to create session');
+
+ const data = await response.json();
+ this.currentSessionId = data.session_id;
+ console.log('New session created:', this.currentSessionId);
+ this.sessions.unshift(data.session_id);
+ this.renderSessions();
+ this.clearMessages();
+ this.showWelcomeMessage();
+ } catch (error) {
+ console.error('Failed to create session:', error);
+ this.showError('Failed to create new chat session');
+ }
+ }
+ async selectSession(sessionId) {
+ try {
+ this.currentSessionId = sessionId;
+ this.renderSessions();
+ await this.loadChatHistory(sessionId);
+ } catch (error) {
+ console.error('Failed to select session:', error);
+ this.showError('Failed to load chat history');
+ }
+ }
+ async loadChatHistory(sessionId) {
+ try {
+ const response = await fetch(`${this.API_URL}/chat/history?session_id=${sessionId}`);
+ if (!response.ok) throw new Error('Failed to load history');
+
+ const data = await response.json();
+ this.renderMessages(data.history || []);
+ } catch (error) {
+ console.error('Failed to load chat history:', error);
+ this.showError('Failed to load chat history');
+ }
+ }
+
+ async sendMessage() {
+ const message = this.messageInput.value.trim();
+ if (!message || this.isTyping || !this.currentSessionId) return;
+
+ try {
+ this.isTyping = true;
+ this.updateSendButton(false);
+ this.addMessage('user', message);
+ this.messageInput.value = '';
+ this.autoResizeTextarea();
+ this.showTypingIndicator();
+ const response = await fetch(`${this.API_URL}/chat`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ session_id: this.currentSessionId,
+ model: this.currentModel,
+ message: message,
+ }),
+ });
+
+ if (!response.ok) throw new Error('Failed to send message');
+
+ const data = await response.json();
+ this.hideTypingIndicator();
+ this.addMessage('assistant', data.response);
+
+ } catch (error) {
+ console.error('Failed to send message:', error);
+ this.hideTypingIndicator();
+ this.showError('Failed to send message. Please try again.');
+ } finally {
+ this.isTyping = false;
+ this.updateSendButton(true);
+ }
+ }
+ renderSessions() {
+ this.sessionsList.innerHTML = '';
+ this.sessions.forEach(sessionId => {
+ const sessionItem = document.createElement('div');
+ sessionItem.className = 'session-item';
+ if (sessionId == this.currentSessionId) {
+ sessionItem.classList.add('active');
+ }
+ sessionItem.innerHTML = `
+ Chat Session
+ ${sessionId.substring(0, 8)}...
+ `;
+
+ sessionItem.addEventListener('click', () => this.selectSession(sessionId));
+ this.sessionsList.appendChild(sessionItem);
+ });
+ }
+
+ renderMessages(messages) {
+ this.clearMessages();
+
+ if (messages.length === 0) {
+ this.showWelcomeMessage();
+ return;
+ }
+
+ messages.forEach(message => {
+ this.addMessage(message.role, message.content, false);
+ });
+ }
+
+ addMessage(role, content, animate = true) {
+ const messageDiv = document.createElement('div');
+ messageDiv.className = `message ${role}`;
+ if (animate) messageDiv.style.animation = 'slideIn 0.3s ease';
+
+ const time = new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
+
+ messageDiv.innerHTML = `
+
+ ${this.formatMessage(content)}
+
+ ${time}
+ `;
+
+ this.chatMessages.appendChild(messageDiv);
+ this.scrollToBottom();
+ }
+
+ formatMessage(content) {
+ return content.replace(/\n/g, '
');
+ }
+ showTypingIndicator() {
+ const typingDiv = document.createElement('div');
+ typingDiv.className = 'typing-indicator';
+ typingDiv.id = 'typing-indicator';
+ typingDiv.innerHTML = `
+
+ `;
+ this.chatMessages.appendChild(typingDiv);
+ this.scrollToBottom();
+ }
+
+ hideTypingIndicator() {
+ const typingIndicator = document.getElementById('typing-indicator');
+ if (typingIndicator) {
+ typingIndicator.remove();
+ }
+ }
+ clearMessages() {
+ this.chatMessages.innerHTML = '';
+ }
+ showWelcomeMessage() {
+ this.chatMessages.innerHTML = `
+
+
LLM Chat
+
Select a model and start chatting. Your conversations are automatically saved.
+
+ `;
+ }
+
+ scrollToBottom() {
+ this.chatMessages.scrollTop = this.chatMessages.scrollHeight;
+ }
+
+ autoResizeTextarea() {
+ const textarea = this.messageInput;
+ textarea.style.height = 'auto';
+ textarea.style.height = Math.min(textarea.scrollHeight, 120) + 'px';
+ }
+
+ updateModelDisplay() {
+ const modelName = this.modelSelect.options[this.modelSelect.selectedIndex].text;
+ this.currentModelSpan.textContent = modelName;
+ }
+
+ updateSendButton(enabled) {
+ this.sendBtn.disabled = !enabled;
+ this.messageInput.disabled = !enabled;
+ }
+
+ updateConnectionStatus(connected) {
+ const statusDot = document.querySelector('.status-dot');
+ const statusText = document.querySelector('.status-text');
+
+ if (connected) {
+ statusDot.classList.remove('disconnected');
+ statusText.textContent = 'Connected';
+ } else {
+ statusDot.classList.add('disconnected');
+ statusText.textContent = 'Disconnected';
+ }
+ }
+
+ enableInterface() {
+ this.messageInput.disabled = false;
+ this.sendBtn.disabled = false;
+ this.newChatBtn.disabled = false;
+ this.modelSelect.disabled = false;
+ }
+
+ showLoading(message = 'Loading...') {
+ this.loadingOverlay.querySelector('p').textContent = message;
+ this.loadingOverlay.classList.remove('hidden');
+ }
+
+ hideLoading() {
+ this.loadingOverlay.classList.add('hidden');
+ }
+
+ showError(message) {
+ const toastMessage = this.errorToast.querySelector('.toast-message');
+ toastMessage.textContent = message;
+ this.errorToast.classList.add('show');
+ setTimeout(() => {
+ this.hideError();
+ }, 5000);
+ }
+
+ hideError() {
+ this.errorToast.classList.remove('show');
+ }
+}
+document.addEventListener('DOMContentLoaded', () => {
+ new ChatApp();
+});
diff --git a/AKSHAT_YADAV/CHAT-APP/FRONTEND/styles.css b/AKSHAT_YADAV/CHAT-APP/FRONTEND/styles.css
new file mode 100644
index 0000000..c0d34db
--- /dev/null
+++ b/AKSHAT_YADAV/CHAT-APP/FRONTEND/styles.css
@@ -0,0 +1,388 @@
+/* Clean Basic Chat App Styles */
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+body {
+ font-family: Arial, sans-serif;
+ background: #f8f9fa;
+ color: #333;
+ height: 100vh;
+ overflow: hidden;
+}
+
+.hidden {
+ display: none !important;
+}
+
+.app-container {
+ display: flex;
+ height: 100vh;
+ width: 100vw;
+ background: white;
+}
+
+/* Sidebar */
+.sidebar {
+ width: 300px;
+ background: #ffffff;
+ border-right: 1px solid #dee2e6;
+ display: flex;
+ flex-direction: column;
+ height: 100vh;
+}
+
+.sidebar-header {
+ padding: 20px;
+ border-bottom: 1px solid #dee2e6;
+ background: #f8f9fa;
+}
+
+.sidebar-header h2 {
+ font-size: 20px;
+ font-weight: 600;
+ color: #212529;
+ margin-bottom: 15px;
+}
+
+.new-chat-btn {
+ width: 100%;
+ padding: 12px 16px;
+ background: #007bff;
+ color: white;
+ border: none;
+ cursor: pointer;
+ font-size: 14px;
+ font-weight: 500;
+}
+
+.new-chat-btn:hover {
+ background: #0056b3;
+}
+
+.sessions-list {
+ flex: 1;
+ overflow-y: auto;
+ padding: 15px;
+}
+
+.session-item {
+ padding: 12px 16px;
+ margin-bottom: 8px;
+ background: #f8f9fa;
+ border: 1px solid #dee2e6;
+ cursor: pointer;
+ font-size: 14px;
+ color: #495057;
+}
+
+.session-item:hover {
+ background: #e9ecef;
+}
+
+.session-item.active {
+ background: #007bff;
+ color: white;
+ border-color: #007bff;
+}
+
+/* Main Content */
+.main-content {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ height: 100vh;
+ background: white;
+}
+
+.chat-header {
+ padding: 20px;
+ border-bottom: 1px solid #dee2e6;
+ background: #f8f9fa;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.model-select {
+ padding: 10px 15px;
+ border: 1px solid #ced4da;
+ background: white;
+ font-size: 14px;
+ cursor: pointer;
+ outline: none;
+ min-width: 200px;
+}
+
+.model-select:focus {
+ border-color: #007bff;
+}
+
+.connection-status {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ font-size: 14px;
+ color: #6c757d;
+}
+
+.status-dot {
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ background: #28a745;
+}
+
+.status-dot.disconnected {
+ background: #dc3545;
+}
+
+/* Chat Messages */
+.chat-messages {
+ flex: 1;
+ overflow-y: auto;
+ padding: 20px;
+ background: #ffffff;
+}
+
+.welcome-message {
+ text-align: center;
+ color: #6c757d;
+ padding: 60px 20px;
+}
+
+.welcome-message h3 {
+ font-size: 24px;
+ margin-bottom: 10px;
+ color: #495057;
+}
+
+.welcome-message p {
+ font-size: 16px;
+}
+
+.message {
+ margin-bottom: 20px;
+ max-width: 70%;
+}
+
+.message.user {
+ margin-left: auto;
+}
+
+.message.assistant {
+ margin-right: auto;
+}
+
+.message-content {
+ padding: 15px 20px;
+ border: 1px solid #dee2e6;
+ background: #f8f9fa;
+ font-size: 15px;
+ line-height: 1.5;
+}
+
+.message.user .message-content {
+ background: #007bff;
+ color: white;
+ border-color: #007bff;
+}
+
+.message.assistant .message-content {
+ background: #ffffff;
+ color: #212529;
+ border-color: #dee2e6;
+}
+
+.message-time {
+ font-size: 12px;
+ color: #6c757d;
+ margin-top: 5px;
+}
+
+.message.user .message-time {
+ text-align: right;
+}
+
+.message.assistant .message-time {
+ text-align: left;
+}
+
+.typing-indicator {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ padding: 15px 20px;
+ background: #ffffff;
+ border: 1px solid #dee2e6;
+ margin-bottom: 20px;
+ max-width: 70%;
+}
+
+.typing-dots {
+ display: flex;
+ gap: 4px;
+}
+
+.typing-dot {
+ width: 6px;
+ height: 6px;
+ border-radius: 50%;
+ background: #6c757d;
+}
+
+/* Input Area */
+.input-area {
+ padding: 20px;
+ border-top: 1px solid #dee2e6;
+ background: #f8f9fa;
+}
+
+.input-container {
+ display: flex;
+ gap: 10px;
+ align-items: flex-end;
+ background: white;
+ border: 1px solid #ced4da;
+ padding: 12px;
+}
+
+.input-container.focused {
+ border-color: #007bff;
+}
+
+#message-input {
+ flex: 1;
+ border: none;
+ background: transparent;
+ resize: none;
+ outline: none;
+ font-size: 15px;
+ line-height: 1.5;
+ max-height: 120px;
+ font-family: Arial, sans-serif;
+}
+
+#message-input:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+.send-btn {
+ width: 40px;
+ height: 40px;
+ border: none;
+ background: #007bff;
+ color: white;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.send-btn:hover:not(:disabled) {
+ background: #0056b3;
+}
+
+.send-btn:disabled {
+ background: #6c757d;
+ cursor: not-allowed;
+}
+
+.input-footer {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-top: 10px;
+ font-size: 13px;
+ color: #6c757d;
+}
+
+.model-info {
+ font-weight: 500;
+}
+
+.hint {
+ opacity: 0.8;
+}
+
+/* Loading Overlay */
+.loading-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: rgba(255, 255, 255, 0.95);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 1000;
+}
+
+.loading-overlay.hidden {
+ display: none;
+}
+
+.loading-spinner {
+ text-align: center;
+}
+
+.spinner {
+ width: 40px;
+ height: 40px;
+ border: 4px solid #f3f3f3;
+ border-top: 4px solid #007bff;
+ border-radius: 50%;
+ margin: 0 auto 20px;
+}
+
+.loading-spinner p {
+ font-size: 16px;
+ color: #495057;
+}
+
+/* Error Toast */
+.error-toast {
+ position: fixed;
+ top: 20px;
+ right: 20px;
+ background: #dc3545;
+ color: white;
+ padding: 15px 20px;
+ border: 1px solid #dc3545;
+ z-index: 1001;
+ display: none;
+ max-width: 400px;
+}
+
+.error-toast.show {
+ display: block;
+}
+
+.toast-content {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+}
+
+.toast-message {
+ font-size: 14px;
+ line-height: 1.4;
+}
+
+.toast-close {
+ background: none;
+ border: none;
+ color: white;
+ font-size: 18px;
+ cursor: pointer;
+ padding: 0;
+ width: 20px;
+ height: 20px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
\ No newline at end of file
diff --git a/AKSHAT_YADAV/CHAT-APP/README.md b/AKSHAT_YADAV/CHAT-APP/README.md
new file mode 100644
index 0000000..5567981
--- /dev/null
+++ b/AKSHAT_YADAV/CHAT-APP/README.md
@@ -0,0 +1,330 @@
+# LLM Chat Application
+
+A full-stack chat application that allows users to interact with multiple Large Language Models (LLMs) through a clean, responsive web interface. The application supports multiple chat sessions, model selection, and persistent conversation history.
+
+## Features
+
+- 🤖 **Multiple LLM Models**: Support for 5 different models via OpenRouter API
+ - Mistral 7B Instruct
+ - OpenChat 3.5
+ - NeuralBeagle 14B
+ - Meta LLaMA 3.1 8B
+ - HuggingFace Zephyr 7B
+
+- 💬 **Session Management**: Create, switch between, and manage multiple chat sessions
+- 🔄 **Persistent History**: Conversations are saved and can be resumed
+- ⚡ **Real-time Chat**: Instant messaging with typing indicators
+- 📱 **Responsive Design**: Clean, modern UI that works on all devices
+- 🔌 **Connection Monitoring**: Real-time backend connection status
+- 🎨 **Clean Interface**: Simple, distraction-free design
+
+## Technology Stack
+
+### Backend
+- **FastAPI**: High-performance Python web framework
+- **PostgreSQL**: Robust relational database for data persistence
+- **OpenRouter API**: Access to multiple LLM models
+- **Pydantic**: Data validation and settings management
+- **CORS**: Cross-Origin Resource Sharing support
+
+### Frontend
+- **Vanilla JavaScript**: No frameworks, pure JS for maximum performance
+- **HTML5 & CSS3**: Modern web standards
+- **Responsive Design**: Mobile-first approach
+
+## Prerequisites
+
+Before setting up the application, ensure you have the following installed:
+
+- **Python 3.8+**: [Download Python](https://www.python.org/downloads/)
+- **PostgreSQL 12+**: [Download PostgreSQL](https://www.postgresql.org/download/)
+- **Git**: [Download Git](https://git-scm.com/downloads/)
+- **OpenRouter API Key**: [Get API Key](https://openrouter.ai/keys)
+
+## Installation & Setup
+
+### 1. Clone the Repository
+
+```bash
+git clone https://github.com/Akshat1276/JS-Assignment-2025.git
+cd JS-Assignment-2025/AKSHAT_YADAV/CHAT-APP
+```
+
+### 2. Database Setup
+
+#### Start PostgreSQL Service
+```bash
+# Windows (Command Prompt as Administrator)
+net start postgresql-x64-12
+
+# macOS (using Homebrew)
+brew services start postgresql
+
+# Linux (Ubuntu/Debian)
+sudo systemctl start postgresql
+```
+
+#### Create Database
+```bash
+# Connect to PostgreSQL
+psql -U postgres
+
+# Create database
+CREATE DATABASE llm_chat_db;
+
+# Create user (optional, for security)
+CREATE USER chat_user WITH PASSWORD 'your_password';
+GRANT ALL PRIVILEGES ON DATABASE llm_chat_db TO chat_user;
+
+# Exit PostgreSQL
+\q
+```
+
+### 3. Backend Setup
+
+#### Navigate to Backend Directory
+```bash
+cd BACKEND
+```
+
+#### Create Virtual Environment
+```bash
+# Windows
+python -m venv venv
+venv\Scripts\activate
+
+# macOS/Linux
+python3 -m venv venv
+source venv/bin/activate
+```
+
+#### Install Dependencies
+```bash
+pip install -r requirements.txt
+```
+
+#### Configure Environment Variables
+Create a `.env` file in the `BACKEND` directory:
+
+```bash
+# Copy the example and edit
+cp .env.example .env
+```
+
+Edit the `.env` file with your configurations:
+
+```properties
+# Database Configuration
+POSTGRES_URL=postgresql://postgres:user123@localhost:5432/llm_chat_db
+
+# OpenRouter API Configuration
+OPENROUTER_API_KEY=your_openrouter_api_key_here
+
+# Note: Replace 'your_openrouter_api_key_here' with your actual OpenRouter API key
+# You can get an API key from: https://openrouter.ai/keys
+```
+
+**Important**: Replace the following values:
+- `user123`: Your PostgreSQL password
+- `your_openrouter_api_key_here`: Your actual OpenRouter API key
+
+#### Initialize Database Tables
+```bash
+python -c "from db import init_db; init_db()"
+```
+
+### 4. Frontend Setup
+
+#### Navigate to Frontend Directory
+```bash
+cd ../FRONTEND
+```
+
+The frontend uses vanilla JavaScript and doesn't require any build process or dependencies.
+
+## Running the Application
+
+### 1. Start the Backend Server
+
+```bash
+# Navigate to backend directory (if not already there)
+cd BACKEND
+
+# Activate virtual environment
+# Windows
+venv\Scripts\activate
+# macOS/Linux
+source venv/bin/activate
+
+# Start the FastAPI server
+uvicorn main:app --reload --host 0.0.0.0 --port 8000
+```
+
+The backend will be available at: `http://localhost:8000`
+
+### 2. Start the Frontend
+
+#### Option A: Using Live Server (Recommended)
+If you have VS Code with Live Server extension:
+1. Open the `FRONTEND` folder in VS Code
+2. Right-click on `index.html`
+3. Select "Open with Live Server"
+
+#### Option B: Using Python HTTP Server
+```bash
+# Navigate to frontend directory
+cd FRONTEND
+
+# Start a simple HTTP server
+# Python 3
+python -m http.server 3000
+
+# Python 2 (if you have it)
+python -m SimpleHTTPServer 3000
+```
+
+#### Option C: Using Node.js (if you have it)
+```bash
+# Install a simple HTTP server globally
+npm install -g http-server
+
+# Navigate to frontend directory
+cd FRONTEND
+
+# Start the server
+http-server -p 3000
+```
+
+The frontend will be available at: `http://localhost:3000`
+
+## API Endpoints
+
+### Backend API Documentation
+
+Once the backend is running, you can access the interactive API documentation at:
+- **Swagger UI**: `http://localhost:8000/docs`
+- **ReDoc**: `http://localhost:8000/redoc`
+
+### Main Endpoints
+
+| Method | Endpoint | Description |
+|--------|----------|-------------|
+| GET | `/` | Health check |
+| POST | `/chat/session` | Create new chat session |
+| GET | `/chat/sessions` | Get all chat sessions |
+| POST | `/chat` | Send message to LLM |
+| GET | `/chat/history` | Get chat history for session |
+
+## Configuration
+
+### Environment Variables
+
+| Variable | Description | Example |
+|----------|-------------|---------|
+| `POSTGRES_URL` | PostgreSQL connection string | `postgresql://user:pass@localhost:5432/db` |
+| `OPENROUTER_API_KEY` | OpenRouter API key | `sk-or-v1-...` |
+
+### Model Configuration
+
+The application supports these models (configured in `models/openrouter.py`):
+
+1. **mistralai/mistral-7b-instruct** - Fast and efficient
+2. **openchat/openchat-3.5-1210** - Great for conversations
+3. **cognitivecomputations/dolphin-2.6-mixtral-8x7b** - High quality responses
+4. **meta-llama/llama-3.1-8b-instruct** - Meta's latest model
+5. **huggingfaceh4/zephyr-7b-beta** - Fine-tuned for helpfulness
+
+## Troubleshooting
+
+### Common Issues
+
+#### 1. Database Connection Error
+```
+Error: could not connect to server: Connection refused
+```
+**Solution**: Make sure PostgreSQL is running and the connection string in `.env` is correct.
+
+#### 2. Missing API Key Error
+```
+Error: OpenRouter API key not found
+```
+**Solution**: Ensure you have set `OPENROUTER_API_KEY` in your `.env` file.
+
+#### 3. CORS Error in Browser
+```
+Access to fetch at 'http://localhost:8000' from origin 'http://localhost:3000' has been blocked by CORS policy
+```
+**Solution**: The backend already includes CORS middleware. Make sure the backend is running on port 8000.
+
+#### 4. Virtual Environment Issues
+```
+'venv' is not recognized as an internal or external command
+```
+**Solution**:
+- Windows: Use `python -m venv venv` instead of `venv`
+- Make sure Python is in your PATH
+
+#### 5. Port Already in Use
+```
+Error: [Errno 48] Address already in use
+```
+**Solution**: Either stop the process using the port or use a different port:
+```bash
+# Use different port
+uvicorn main:app --reload --port 8001
+```
+
+### Debug Mode
+
+To run the backend in debug mode with detailed logging:
+
+```bash
+uvicorn main:app --reload --log-level debug
+```
+
+### Database Reset
+
+If you need to reset the database:
+
+```bash
+# Connect to PostgreSQL
+psql -U postgres
+
+# Drop and recreate database
+DROP DATABASE llm_chat_db;
+CREATE DATABASE llm_chat_db;
+
+# Exit and reinitialize
+\q
+python -c "from db import init_db; init_db()"
+```
+
+## Development
+
+### Project Structure
+```
+CHAT-APP/
+├── BACKEND/
+│ ├── main.py # FastAPI application
+│ ├── db.py # Database connection and models
+│ ├── models/
+│ │ └── openrouter.py # LLM model integration
+│ ├── requirements.txt # Python dependencies
+│ ├── .env # Environment variables
+│ ├── .gitignore # Git ignore rules
+│ └── venv/ # Virtual environment
+├── FRONTEND/
+│ ├── index.html # Main HTML file
+│ ├── script.js # JavaScript application
+│ ├── styles.css # CSS styles
+│ └── .gitignore # Git ignore rules
+└── README.md # This file
+```
+
+### Adding New Models
+
+To add a new LLM model:
+
+1. Edit `models/openrouter.py`
+2. Add the model to the `AVAILABLE_MODELS` dictionary
+3. Update the frontend model selector in `index.html`
diff --git a/AKSHAT_YADAV/ECOMMERCE-WEBSITE/app.js b/AKSHAT_YADAV/ECOMMERCE-WEBSITE/app.js
new file mode 100644
index 0000000..2f41246
--- /dev/null
+++ b/AKSHAT_YADAV/ECOMMERCE-WEBSITE/app.js
@@ -0,0 +1,102 @@
+const API_BASE = 'http://43.205.110.71:8000';
+
+let categories = [];
+let items = [];
+let itemsByCategory = {};
+
+const loadingDiv = document.getElementById('loading');
+const itemsGrid = document.getElementById('items-grid');
+const categoryTabs = document.getElementById('category-tabs');
+
+function getRandomImage() {
+ return `https://source.unsplash.com/collection/190727/200x200?sig=${Math.floor(Math.random() * 10000)}`;
+}
+
+async function fetchCategories() {
+ const response = await fetch(`${API_BASE}/categories`);
+ return response.json();
+}
+
+async function fetchAllItems() {
+ const all = [];
+ let page = 1;
+ const size = 1000;
+
+ while (true) {
+ const res = await fetch(`${API_BASE}/items?page=${page}&size=${size}`);
+ const data = await res.json();
+ const batch = Array.isArray(data) ? data : data.items;
+ if (!batch || batch.length === 0) break;
+ all.push(...batch);
+ if (batch.length < size) break;
+ page++;
+ }
+
+ return all;
+}
+
+function renderCategoryTabs() {
+ categoryTabs.innerHTML = '';
+
+ const allBtn = document.createElement('button');
+ allBtn.textContent = 'All';
+ allBtn.classList.add('active');
+ allBtn.onclick = () => renderItems('all');
+ categoryTabs.appendChild(allBtn);
+
+ categories.forEach(cat => {
+ const name = cat.name || cat.category || cat.title;
+ const btn = document.createElement('button');
+ btn.textContent = name;
+ btn.onclick = () => renderItems(name);
+ categoryTabs.appendChild(btn);
+ });
+}
+
+function renderItems(category) {
+ Array.from(categoryTabs.children).forEach(btn => {
+ btn.classList.toggle('active', btn.textContent === category);
+ });
+
+ itemsGrid.innerHTML = '';
+ const list = category === 'all' ? items : (itemsByCategory[category] || []);
+
+ list.forEach(item => {
+ const card = document.createElement('div');
+ card.className = 'item-card';
+ card.innerHTML = `
+
+ ${item.name || item.title}
+ ₹${item.price}
+ `;
+ itemsGrid.appendChild(card);
+ });
+}
+
+async function main() {
+ loadingDiv.classList.remove('hidden');
+ itemsGrid.classList.add('hidden');
+
+ const [cats, allItems] = await Promise.all([
+ fetchCategories(),
+ fetchAllItems()
+ ]);
+
+ categories = cats;
+ items = allItems;
+
+ itemsByCategory = {};
+ items.forEach(item => {
+ const cat = item.category?.name || item.category || 'Uncategorized';
+ if (!itemsByCategory[cat]) itemsByCategory[cat] = [];
+ itemsByCategory[cat].push(item);
+ });
+
+ renderCategoryTabs();
+ renderItems('all');
+
+ loadingDiv.classList.add('hidden');
+ itemsGrid.classList.remove('hidden');
+}
+
+main();
diff --git a/AKSHAT_YADAV/ECOMMERCE-WEBSITE/index.html b/AKSHAT_YADAV/ECOMMERCE-WEBSITE/index.html
new file mode 100644
index 0000000..8158654
--- /dev/null
+++ b/AKSHAT_YADAV/ECOMMERCE-WEBSITE/index.html
@@ -0,0 +1,23 @@
+
+
+
+
+
+ Snappy E-Commerce Platform
+
+
+
+
+
+
+ Loading data...
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AKSHAT_YADAV/ECOMMERCE-WEBSITE/style.css b/AKSHAT_YADAV/ECOMMERCE-WEBSITE/style.css
new file mode 100644
index 0000000..af20558
--- /dev/null
+++ b/AKSHAT_YADAV/ECOMMERCE-WEBSITE/style.css
@@ -0,0 +1,86 @@
+body {
+ font-family: 'Segoe UI', Arial, sans-serif;
+ margin: 0;
+ background: #f8f9fa;
+ color: #222;
+}
+header {
+ background: #222;
+ color: #fff;
+ padding: 1rem 2rem;
+ text-align: center;
+}
+#category-tabs {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5rem;
+ background: #fff;
+ padding: 1rem 2rem;
+ border-bottom: 1px solid #eee;
+}
+#category-tabs button {
+ background: #e0e0e0;
+ border: none;
+ padding: 0.5rem 1rem;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 1rem;
+ transition: background 0.2s;
+}
+#category-tabs button.active {
+ background: #0078d7;
+ color: #fff;
+}
+main {
+ max-width: 1200px;
+ margin: 2rem auto;
+ padding: 0 1rem;
+}
+#loading {
+ text-align: center;
+ font-size: 1.2rem;
+ margin: 2rem 0;
+}
+#items-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
+ gap: 1.5rem;
+}
+.item-card {
+ background: #fff;
+ border-radius: 8px;
+ box-shadow: 0 2px 8px rgba(0,0,0,0.06);
+ padding: 1rem;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ transition: box-shadow 0.2s;
+}
+.item-card:hover {
+ box-shadow: 0 4px 16px rgba(0,0,0,0.12);
+}
+.item-card img {
+ width: 120px;
+ height: 120px;
+ object-fit: cover;
+ border-radius: 6px;
+ margin-bottom: 0.5rem;
+ background: #eee;
+}
+.item-card h3 {
+ margin: 0.5rem 0 0.2rem 0;
+ font-size: 1.1rem;
+}
+.item-card .price {
+ color: #0078d7;
+ font-weight: bold;
+ margin-bottom: 0.5rem;
+}
+.item-card .tags {
+ font-size: 0.9rem;
+ color: #888;
+ margin-top: 0.3rem;
+}
+.hidden {
+ display: none;
+}
diff --git a/AKSHAT_YADAV/SHOOT-THE-TARGET/game.js b/AKSHAT_YADAV/SHOOT-THE-TARGET/game.js
new file mode 100644
index 0000000..7789ce9
--- /dev/null
+++ b/AKSHAT_YADAV/SHOOT-THE-TARGET/game.js
@@ -0,0 +1,330 @@
+console.log("Script start");
+window.addEventListener("DOMContentLoaded", () => {
+ try {
+ const select = document.createElement("select");
+ select.id = "levelSelect";
+ select.style.position = "absolute";
+ select.style.top = "10px";
+ select.style.left = "10px";
+ ["Level 1", "Level 2", "Level 3"].forEach((name, i) => {
+ const opt = document.createElement("option");
+ opt.value = i;
+ opt.text = name;
+ select.appendChild(opt);
+ });
+ document.body.appendChild(select);
+
+ const resetBtn = document.createElement("button");
+ resetBtn.textContent = "Reset Level";
+ resetBtn.style.position = "absolute";
+ resetBtn.style.top = "140px";
+ resetBtn.style.left = "714px";
+ resetBtn.style.display = "none";
+ document.body.appendChild(resetBtn);
+ resetBtn.addEventListener("click", () => resetLevel());
+
+ const canvas = document.getElementById("gameCanvas");
+ if (!canvas) throw new Error("#gameCanvas not found");
+ const ctx = canvas.getContext("2d");
+
+ const GRAVITY = 0.35,
+ BOUNCE = -0.6;
+ const groundFrac = 0.2,
+ BALL_RADIUS = 15;
+ const LOCKOUT_MS = 4500,
+ MAX_SHOTS = 7,
+ HITS_TO_WIN = 3;
+
+ const levels = [
+ {
+ walls: [
+ { x: 400, y: 300, w: 20, h: 200 },
+ { x: 420, y: 380, w: 150, h: 20, isFloor: true },
+ { x: 550, y: 370, w: 20, h: 110 },
+ ],
+ bombs: [
+ { x: 550, y: 340, w: 20, h: 20 },
+ ],
+ target: { x: 700, y: 330, w: 40, h: 40 },
+ shape: "circle",
+ },
+ {
+ walls: [
+ { x: 580, y: 240, w: 40, h: 200 },
+ { x: 450, y: 380, w: 50, h: 20, isFloor: true },
+ { x: 500, y: 400, w: 50, h: 20 },
+ { x: 550, y: 420, w: 50, h: 20 },
+ { x: 700, y: 420, w: 50, h: 20, isFloor: true },
+ { x: 650, y: 400, w: 50, h: 20 },
+ { x: 600, y: 380, w: 50, h: 20 },
+ { x: 550, y: 300, w: 200, h: 20, isFloor: true },
+ { x: 550, y: 260, w: 20, h: 40 },
+ { x: 730, y: 220, w: 20, h: 100 },
+ ],
+ bombs: [{ x: 540, y: 220, w: 30, h: 30 }],
+ target: { x: 640, y: 280, w: 20, h: 20 },
+ shape: "square",
+ },
+ {
+ walls: [
+ { x: 500, y: 420, w: 300, h: 20, isFloor: true },
+ { x: 520, y: 400, w: 40, h: 20 },
+ { x: 560, y: 380, w: 40, h: 20 },
+ { x: 600, y: 360, w: 40, h: 20 },
+ { x: 640, y: 340, w: 40, h: 20 },
+ { x: 680, y: 320, w: 40, h: 20 },
+ { x: 780, y: 280, w: 20, h: 160 },
+ ],
+ bombs: [{ x: 750, y: 260, w: 30, h: 30 }],
+ target: { x: 720, y: 380, w: 30, h: 30 },
+ shape: "triangle",
+ },
+ ];
+
+ let groundY, slingStart;
+ let projectile = null;
+ let lastShotTime = 0,
+ allowShoot = true;
+ let shotsTaken = 0,
+ gameOver = false,
+ targetHit = false;
+ let currentLevel = 0,
+ hitCount = 0;
+
+ class Vector {
+ constructor(x = 0, y = 0) {
+ this.x = x;
+ this.y = y;
+ }
+ clone() {
+ return new Vector(this.x, this.y);
+ }
+ add(v) {
+ this.x += v.x;
+ this.y += v.y;
+ return this;
+ }
+ length() {
+ return Math.hypot(this.x, this.y);
+ }
+ normalize() {
+ let l = this.length();
+ if (l > 0) {
+ this.x /= l;
+ this.y /= l;
+ }
+ return this;
+ }
+ scale(s) {
+ this.x *= s;
+ this.y *= s;
+ return this;
+ }
+ static fromPoints(a, b) {
+ return new Vector(b.x - a.x, b.y - a.y);
+ }
+ }
+
+ const circleVsAABB = (c, r) => {
+ const cx = Math.max(r.x, Math.min(c.x, r.x + r.w)),
+ cy = Math.max(r.y, Math.min(c.y, r.y + r.h)),
+ dx = c.x - cx,
+ dy = c.y - cy;
+ return dx * dx + dy * dy <= c.r * c.r;
+ };
+
+ function resizeCanvas() {
+ canvas.width = innerWidth;
+ canvas.height = innerHeight;
+ groundY = canvas.height * (1 - groundFrac);
+ slingStart = new Vector(150, groundY - BALL_RADIUS);
+ }
+ window.addEventListener("resize", resizeCanvas);
+ resizeCanvas();
+
+ select.addEventListener("change", () => {
+ currentLevel = +select.value;
+ resetLevel();
+ });
+
+ function resetLevel() {
+ projectile = null;
+ shotsTaken = 0;
+ gameOver = false;
+ targetHit = false;
+ allowShoot = true;
+ hitCount = 0;
+ resetBtn.style.display = "none";
+ }
+ resetLevel();
+
+ let isDragging = false,
+ dragEnd = null;
+ canvas.addEventListener("pointerdown", (e) => {
+ if (!allowShoot || shotsTaken >= MAX_SHOTS || gameOver) return;
+ isDragging = true;
+ dragEnd = new Vector(e.offsetX, e.offsetY);
+ });
+ canvas.addEventListener("pointermove", (e) => {
+ if (isDragging) dragEnd = new Vector(e.offsetX, e.offsetY);
+ });
+ canvas.addEventListener("pointerup", (e) => {
+ if (!isDragging || !allowShoot) return;
+ isDragging = false;
+ const launch = Vector.fromPoints(dragEnd, slingStart);
+ const power = Math.min(launch.length(), 150);
+ const vel = launch.clone().normalize().scale(power * 0.25);
+ projectile = {
+ pos: slingStart.clone(),
+ vel,
+ trail: [slingStart.clone()],
+ angle: 0,
+ };
+ lastShotTime = performance.now();
+ allowShoot = false;
+ shotsTaken++;
+ });
+
+ function renderShape(ctx, x, y, radius, angle, shape) {
+ ctx.save();
+ ctx.translate(x, y);
+ ctx.rotate(angle);
+ ctx.beginPath();
+ if (shape === "circle") {
+ ctx.arc(0, 0, radius, 0, Math.PI * 2);
+ } else if (shape === "square") {
+ ctx.rect(-radius, -radius, radius * 2, radius * 2);
+ } else if (shape === "triangle") {
+ ctx.moveTo(0, -radius);
+ ctx.lineTo(radius, radius);
+ ctx.lineTo(-radius, radius);
+ ctx.closePath();
+ }
+ ctx.fillStyle = "#ffeb3b";
+ ctx.fill();
+ ctx.lineWidth = 3;
+ ctx.strokeStyle = "#fbc02d";
+ ctx.stroke();
+ ctx.restore();
+ }
+
+ function render() {
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ ctx.fillStyle = "#795548";
+ ctx.fillRect(0, groundY, canvas.width, canvas.height - groundY);
+ const lvl = levels[currentLevel];
+ lvl.walls.forEach((w) => {
+ ctx.fillStyle = "#8d6e63";
+ ctx.fillRect(w.x, w.y, w.w, w.h);
+ });
+ lvl.bombs.forEach((b) => {
+ ctx.fillStyle = "#d32f2f";
+ ctx.beginPath();
+ ctx.arc(b.x + b.w / 2, b.y + b.h / 2, Math.min(b.w, b.h) / 2, 0, Math.PI * 2);
+ ctx.fill();
+ });
+ const tgt = lvl.target;
+ ctx.fillStyle = targetHit ? "#4caf50" : "#ffffff";
+ ctx.fillRect(tgt.x, tgt.y, tgt.w, tgt.h);
+ if (projectile) {
+ if (projectile.trail.length > 1) {
+ ctx.save();
+ ctx.strokeStyle = "#888";
+ ctx.setLineDash([4, 8]);
+ ctx.beginPath();
+ ctx.moveTo(projectile.trail[0].x, projectile.trail[0].y);
+ projectile.trail.forEach((p) => ctx.lineTo(p.x, p.y));
+ ctx.stroke();
+ ctx.restore();
+ }
+ renderShape(ctx, projectile.pos.x, projectile.pos.y, BALL_RADIUS, projectile.angle, lvl.shape);
+ }
+ if (allowShoot && shotsTaken < MAX_SHOTS && !gameOver) {
+ renderShape(ctx, slingStart.x, slingStart.y, BALL_RADIUS, 0, lvl.shape);
+ }
+ if (isDragging && dragEnd) {
+ ctx.save();
+ ctx.strokeStyle = "#d32f2f";
+ ctx.lineWidth = 3;
+ ctx.beginPath();
+ ctx.moveTo(slingStart.x, slingStart.y);
+ ctx.lineTo(dragEnd.x, dragEnd.y);
+ ctx.stroke();
+ ctx.restore();
+ }
+ ctx.fillStyle = "#000";
+ ctx.font = "16px sans-serif";
+ ctx.fillText(`Shots: ${shotsTaken}/${MAX_SHOTS}`, 110, 40);
+ ctx.fillText(`Hits: ${hitCount}/${HITS_TO_WIN}`, 110, 60);
+ if (gameOver) {
+ ctx.fillStyle = targetHit ? "#4caf50" : "#f44336";
+ ctx.font = "24px sans-serif";
+ ctx.fillText(
+ targetHit ? "You Win!" : "You Lost!",
+ canvas.width / 2 - 60,
+ 50
+ );
+ resetBtn.style.display = "block";
+ }
+ }
+
+ function update() {
+ const now = performance.now();
+ if (!projectile || projectile.vel.length() < 0.1 || now - lastShotTime > LOCKOUT_MS)
+ allowShoot = true;
+ const lvl = levels[currentLevel];
+ if (projectile && !gameOver) {
+ projectile.vel.y += GRAVITY;
+ projectile.pos.add(projectile.vel);
+ projectile.angle += projectile.vel.length() * 0.05;
+ if (projectile.pos.y + BALL_RADIUS > groundY) {
+ projectile.pos.y = groundY - BALL_RADIUS;
+ projectile.vel.y *= BOUNCE;
+ projectile.vel.x *= Math.abs(BOUNCE);
+ }
+ for (const bomb of lvl.bombs) {
+ if (circleVsAABB({ x: projectile.pos.x, y: projectile.pos.y, r: BALL_RADIUS }, bomb)) {
+ gameOver = true;
+ projectile = null;
+ return;
+ }
+ }
+ lvl.walls.forEach((w) => {
+ if (circleVsAABB({ x: projectile.pos.x, y: projectile.pos.y, r: BALL_RADIUS }, w)) {
+ if (w.isFloor) {
+ projectile.pos.y = w.y - BALL_RADIUS;
+ projectile.vel.y *= BOUNCE;
+ projectile.vel.x *= Math.abs(BOUNCE);
+ } else {
+ projectile.vel.x *= -1;
+ projectile.vel.y *= BOUNCE;
+ if (projectile.pos.x < w.x) projectile.pos.x = w.x - BALL_RADIUS;
+ else projectile.pos.x = w.x + w.w + BALL_RADIUS;
+ }
+ }
+ });
+ const tgt = lvl.target;
+ if (circleVsAABB({ x: projectile.pos.x, y: projectile.pos.y, r: BALL_RADIUS }, tgt)) {
+ hitCount++;
+ if (hitCount >= HITS_TO_WIN) {
+ targetHit = true;
+ gameOver = true;
+ }
+ projectile = null;
+ return;
+ }
+ projectile.trail.push(projectile.pos.clone());
+ if (projectile.pos.x < 0 || projectile.pos.x > canvas.width || projectile.pos.y > canvas.height)
+ projectile = null;
+ }
+ }
+
+ (function loop() {
+ update();
+ render();
+ requestAnimationFrame(loop);
+ })();
+ } catch (err) {
+ console.error("Init error:", err);
+ }
+});
\ No newline at end of file
diff --git a/AKSHAT_YADAV/SHOOT-THE-TARGET/index.html b/AKSHAT_YADAV/SHOOT-THE-TARGET/index.html
new file mode 100644
index 0000000..b311ded
--- /dev/null
+++ b/AKSHAT_YADAV/SHOOT-THE-TARGET/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+ Blast 'em
+
+
+
+
+
+
+
diff --git a/AKSHAT_YADAV/SHOOT-THE-TARGET/style.css b/AKSHAT_YADAV/SHOOT-THE-TARGET/style.css
new file mode 100644
index 0000000..b96cf41
--- /dev/null
+++ b/AKSHAT_YADAV/SHOOT-THE-TARGET/style.css
@@ -0,0 +1,16 @@
+html, body {
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ overflow: hidden;
+}
+body {
+ background: #87ceeb;
+}
+#gameCanvas {
+ display: block;
+ width: 100vw;
+ height: 100vh;
+ background: #e0f7fa;
+ cursor: crosshair;
+}