From 80865cf52a5a13e7f871bf48018d03a2c2df9eb4 Mon Sep 17 00:00:00 2001 From: Piyush Acharya Date: Thu, 20 Feb 2025 01:25:52 -0800 Subject: [PATCH 01/19] Update index.html Signed-off-by: Piyush Acharya --- web/index.html | 1 - 1 file changed, 1 deletion(-) diff --git a/web/index.html b/web/index.html index efa831b7..987222f3 100644 --- a/web/index.html +++ b/web/index.html @@ -26,7 +26,6 @@

DNAnalyzer

A highly efficient, powerful, and feature-rich algorithm for analyzing DNA sequences

- DNAnalyzer Interface
From 0d2b2fbbc078aebfcd2ed358b9cd41a007831752 Mon Sep 17 00:00:00 2001 From: Piyush Acharya Date: Thu, 20 Feb 2025 01:48:58 -0800 Subject: [PATCH 02/19] remove .html from index --- implementation_plan.md | 2 +- web/about/about.html | 2 +- web/analyzer/analyzer.html | 2 +- web/docs/docs.html | 4 ++-- web/features/features.html | 2 +- web/server/server.html | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/implementation_plan.md b/implementation_plan.md index 3b7ad235..45b0d5a3 100644 --- a/implementation_plan.md +++ b/implementation_plan.md @@ -19,7 +19,7 @@ ## 2. Updating the Website for Local DNA Analyzer Integration ### 2.1. UI Updates -- Modify `web/index.html` to include: +- Modify `web/` to include: - An input field for the user to provide the file path of the DNA file to analyze. - A set of checkboxes for selecting command line features (e.g., "Verbose Mode", "Detailed Report", "Quick Analysis"). - A "Run Analysis" button to initiate the process. diff --git a/web/about/about.html b/web/about/about.html index 03a5f76b..611d9c5b 100644 --- a/web/about/about.html +++ b/web/about/about.html @@ -14,7 +14,7 @@
+
+

Copyright © Piyush Acharya 2025. DNAnalyzer is a fiscally sponsored 501(c)(3) nonprofit (EIN: 81-2908499). MIT License.

+
+ diff --git a/web/docs/docs.css b/web/docs/docs.css index 575ba918..30c70315 100644 --- a/web/docs/docs.css +++ b/web/docs/docs.css @@ -6,17 +6,28 @@ } .doc-section { - background: #f5f5f5; + background: rgba(255, 255, 255, 0.05); padding: 1.5rem; - border-radius: 8px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + border-radius: 12px; + border: 1px solid rgba(255, 255, 255, 0.1); + backdrop-filter: blur(10px); + transition: all 0.3s ease; +} + +.doc-section:hover { + transform: translateY(-2px); + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2); + border-color: var(--gradient-end); } .doc-section h2 { margin-top: 0; - color: #333; + color: var(--gradient-end); font-size: 1.5rem; margin-bottom: 1rem; + background: linear-gradient(45deg, var(--gradient-start), var(--gradient-end)); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; } .doc-section ul { @@ -30,67 +41,90 @@ } .doc-section a { - color: #007bff; + color: var(--text-color); text-decoration: none; display: block; - padding: 0.5rem; - border-radius: 4px; - transition: background-color 0.2s; + padding: 0.75rem; + border-radius: 8px; + transition: all 0.3s ease; + background: rgba(255, 255, 255, 0.05); } .doc-section a:hover { - background-color: #e9ecef; + background: rgba(255, 255, 255, 0.1); + transform: translateY(-2px); +} + +.doc-section a.active { + background: linear-gradient(135deg, var(--gradient-start), var(--gradient-end)); + color: white; } .doc-content { margin: 2rem 0; padding: 2rem; - background: white; - border-radius: 8px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + background: rgba(26, 28, 42, 0.95); + border-radius: 12px; + border: 1px solid rgba(255, 255, 255, 0.1); + backdrop-filter: blur(10px); + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2); } .doc-content h1 { margin-top: 0; - color: #333; + color: var(--gradient-end); + background: linear-gradient(45deg, var(--gradient-start), var(--gradient-end)); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; } .doc-content h2 { margin-top: 2rem; - color: #444; + color: var(--gradient-end); } .doc-content p { line-height: 1.6; - color: #666; + color: rgba(255, 255, 255, 0.9); } .doc-content code { - background: #f8f9fa; + background: rgba(0, 0, 0, 0.2); padding: 0.2rem 0.4rem; border-radius: 4px; font-family: 'IBM Plex Mono', monospace; + color: #10B981; } .doc-content pre { - background: #f8f9fa; + background: rgba(0, 0, 0, 0.2); padding: 1rem; - border-radius: 4px; + border-radius: 8px; overflow-x: auto; + border: 1px solid rgba(255, 255, 255, 0.1); } #documentation { max-width: 1200px; - margin: 0 auto; - padding: 2rem; + margin: 6rem auto 2rem; + padding: 0 2rem; } @media (max-width: 768px) { .docs-grid { grid-template-columns: 1fr; } - - #documentation { + + .doc-section { padding: 1rem; } + + .doc-content { + padding: 1.5rem; + margin: 1rem 0; + } + + #documentation { + padding: 0 1rem; + } } \ No newline at end of file diff --git a/web/docs/docs.html b/web/docs/docs.html index 2efc829e..a79c66f0 100644 --- a/web/docs/docs.html +++ b/web/docs/docs.html @@ -1,8 +1,6 @@ - DNAnalyzer Documentation @@ -10,16 +8,23 @@ - +
+ +
+ +
@@ -54,6 +59,10 @@

Research & Analysis

+
+

Copyright © Piyush Acharya 2025. DNAnalyzer is a fiscally sponsored 501(c)(3) nonprofit (EIN: 81-2908499). MIT License.

+
+ \ No newline at end of file diff --git a/web/features/features.css b/web/features/features.css index f7c176d8..45bbc3c0 100644 --- a/web/features/features.css +++ b/web/features/features.css @@ -6,11 +6,17 @@ text-align: center; padding: 2rem; margin-bottom: 2rem; + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 12px; + backdrop-filter: blur(10px); transition: transform 0.3s ease; } .feature-card:hover { transform: translateY(-5px); + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2); + border-color: var(--gradient-end); } .grid { @@ -31,6 +37,7 @@ border-radius: 8px; margin: 1.5rem 0; transition: transform 0.3s ease; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); } .feature-preview:hover { @@ -38,7 +45,7 @@ } .feature-card h3 { - color: #ffffff; + color: var(--gradient-end); margin-bottom: 1rem; font-size: 1.5rem; background: linear-gradient(45deg, var(--gradient-start), var(--gradient-end)); @@ -48,7 +55,7 @@ .feature-card p { color: rgba(255, 255, 255, 0.9); - line-height: 1.6; + line-height: 1.8; margin-bottom: 1.5rem; } @@ -71,6 +78,11 @@ } @media (max-width: 768px) { + .grid { + grid-template-columns: 1fr; + gap: 1rem; + } + .feature-card { padding: 1.5rem; } diff --git a/web/features/features.html b/web/features/features.html index 5e652b3d..0f68c5a3 100644 --- a/web/features/features.html +++ b/web/features/features.html @@ -1,8 +1,6 @@ - Features - DNAnalyzer @@ -16,19 +14,18 @@
-
- - -
diff --git a/web/index.html b/web/index.html index 18322f4d..67b75a6e 100644 --- a/web/index.html +++ b/web/index.html @@ -1,8 +1,6 @@ - DNAnalyzer - DNA Sequence Analysis Tool @@ -10,24 +8,29 @@ - +
+ +
+ +

DNAnalyzer

A highly efficient, powerful, and feature-rich algorithm for analyzing DNA sequences

+ DNA Sequence Analysis Visualization
@@ -61,6 +64,10 @@

Local Processing

+
+

Copyright © Piyush Acharya 2025. DNAnalyzer is a fiscally sponsored 501(c)(3) nonprofit (EIN: 81-2908499). MIT License.

+
+ diff --git a/web/server/server.html b/web/server/server.html index ce58115a..09c8cda2 100644 --- a/web/server/server.html +++ b/web/server/server.html @@ -1,8 +1,6 @@ - Server Setup - DNAnalyzer @@ -16,19 +14,18 @@
-
- - -
@@ -38,6 +35,13 @@

Server Setup

Quick Start Guide

    +
  1. +

    Clone and navigate to the repository:

    +
    + git clone https://github.com/VerisimilitudeX/DNAnalyzer.git && cd DNAnalyzer + +
    +
  2. Make the Gradle wrapper executable:

    @@ -65,6 +69,7 @@

    Quick Start Guide

    • Java 17 or higher
    • Port 8080 must be available
    • +
    • Git installed
    • At least 2GB of free RAM
    diff --git a/web/server/server.js b/web/server/server.js index 36fa8ea7..2e7d92de 100644 --- a/web/server/server.js +++ b/web/server/server.js @@ -1,74 +1,135 @@ // Server page specific functionality document.addEventListener('DOMContentLoaded', function() { const serverStatusElement = document.getElementById('server-status'); + let statusCheckInterval; + let retryCount = 0; + const MAX_RETRIES = 3; - // Copy command functionality for chmod command - function copyChmodCommand() { - const command = 'chmod +x ./gradlew'; - copyToClipboardWithFeedback(command, 0); - } - - // Copy command functionality for build command - function copyBuildCommand() { - const command = './gradlew clean bootJar'; - copyToClipboardWithFeedback(command, 1); - } - - // Copy command functionality for run command - function copyRunCommand() { - const command = 'java -jar build/libs/DNAnalyzer.jar'; - copyToClipboardWithFeedback(command, 2); - } - - // Helper function to copy and show feedback + // Copy commands functionality function copyToClipboardWithFeedback(command, buttonIndex) { navigator.clipboard.writeText(command).then(() => { - const copyButton = document.querySelectorAll('.copy-button')[buttonIndex]; - copyButton.textContent = 'Copied!'; + const button = document.getElementsByClassName('copy-button')[buttonIndex]; + button.textContent = 'Copied!'; + button.classList.add('success'); + setTimeout(() => { + button.textContent = 'Copy'; + button.classList.remove('success'); + }, 2000); + }).catch(() => { + const button = document.getElementsByClassName('copy-button')[buttonIndex]; + button.textContent = 'Failed!'; + button.classList.add('error'); setTimeout(() => { - copyButton.textContent = 'Copy'; + button.textContent = 'Copy'; + button.classList.remove('error'); }, 2000); }); } - - // Make copy functions available globally for the onclick handlers - window.copyChmodCommand = copyChmodCommand; - window.copyBuildCommand = copyBuildCommand; - window.copyRunCommand = copyRunCommand; - // Server status check functionality - async function checkServerStatus() { + window.copyCloneCommand = () => copyToClipboardWithFeedback('git clone https://github.com/VerisimilitudeX/DNAnalyzer.git && cd DNAnalyzer', 0); + window.copyChmodCommand = () => copyToClipboardWithFeedback('chmod +x ./gradlew', 1); + window.copyBuildCommand = () => copyToClipboardWithFeedback('./gradlew clean bootJar', 2); + window.copyRunCommand = () => copyToClipboardWithFeedback('java -jar build/libs/DNAnalyzer.jar', 3); + + // Server status check with retry logic + async function checkServerStatus(isInitialCheck = false) { try { - const response = await fetch('http://localhost:8080/api/status'); + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), 5000); + + const response = await fetch('http://localhost:8080/health', { + method: 'GET', + signal: controller.signal, + headers: { + 'Accept': 'application/json', + } + }); + + clearTimeout(timeoutId); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const data = await response.json(); + retryCount = 0; // Reset retry count on success - if (data.status === 'online') { - serverStatusElement.innerHTML = ` -
    - ● Server Online -
    - Last checked: ${new Date().toLocaleTimeString()} -
    - Version: ${data.version} + serverStatusElement.innerHTML = ` +
    +
    +
    +
    Server Online
    +
    + Status: Running + Last checked: ${new Date().toLocaleTimeString()} + Ready to process DNA sequences +
    - `; - } else { - throw new Error('Server offline'); - } +
    + `; + return true; + } catch (error) { + retryCount++; + const isMaxRetries = retryCount >= MAX_RETRIES; + serverStatusElement.innerHTML = ` -
    - ● Server Offline -
    - Last checked: ${new Date().toLocaleTimeString()} -
    - Follow the setup steps above to start the server +
    +
    +
    +
    Server Offline
    +
    + Last checked: ${new Date().toLocaleTimeString()} + ${isInitialCheck ? 'Follow the setup steps above to start the server' : ''} + ${!isInitialCheck && !isMaxRetries ? `Retrying... (${retryCount}/${MAX_RETRIES})` : ''} + ${isMaxRetries ? 'Max retries reached. Check server setup instructions above.' : ''} +
    +
    `; + + if (isMaxRetries) { + clearInterval(statusCheckInterval); + showTroubleshooting(); + } + return false; } } - // Check status immediately and then every 30 seconds - checkServerStatus(); - setInterval(checkServerStatus, 30000); + function showTroubleshooting() { + const troubleshootingSection = document.querySelector('.troubleshooting'); + if (troubleshootingSection) { + troubleshootingSection.classList.add('active'); + troubleshootingSection.scrollIntoView({ behavior: 'smooth', block: 'start' }); + } + } + + // Initialize status checking + async function initializeStatusCheck() { + const isOnline = await checkServerStatus(true); + + if (!isOnline) { + // If offline on first check, start checking more frequently initially + statusCheckInterval = setInterval(() => checkServerStatus(), 5000); + + // After 30 seconds, switch to normal interval if server is still offline + setTimeout(() => { + clearInterval(statusCheckInterval); + statusCheckInterval = setInterval(() => checkServerStatus(), 30000); + }, 30000); + } else { + // If online, check every 30 seconds + statusCheckInterval = setInterval(() => checkServerStatus(), 30000); + } + } + + // Start status checking + initializeStatusCheck(); + + // Cleanup on page unload + window.addEventListener('unload', () => { + if (statusCheckInterval) { + clearInterval(statusCheckInterval); + } + }); }); \ No newline at end of file diff --git a/web/style.css b/web/style.css index 82157d87..acdb04ba 100644 --- a/web/style.css +++ b/web/style.css @@ -24,6 +24,9 @@ body { background-color: var(--background-color); color: var(--text-color); line-height: 1.6; + min-height: 100vh; + display: flex; + flex-direction: column; } nav { @@ -80,6 +83,8 @@ nav a:hover { main { padding-top: 4rem; + flex: 1; + margin-bottom: 2rem; } section { @@ -427,6 +432,177 @@ select::placeholder, input[type="number"]::placeholder { line-height: 1.6; } +.error-boundary { + background: rgba(220, 53, 69, 0.1); + border: 1px solid rgba(220, 53, 69, 0.3); + border-radius: 12px; + padding: 2rem; + margin: 1rem 0; + animation: shake 0.5s ease-in-out; +} + +.error-boundary h3 { + color: var(--error-color); + margin-bottom: 1rem; +} + +.error-boundary p { + color: rgba(255, 255, 255, 0.9); + margin-bottom: 1rem; +} + +.error-stack { + background: rgba(0, 0, 0, 0.2); + padding: 1rem; + border-radius: 6px; + font-family: 'IBM Plex Mono', monospace; + font-size: 0.9rem; + color: rgba(255, 255, 255, 0.7); + margin-bottom: 1rem; + overflow-x: auto; +} + +.retry-button { + background: linear-gradient(135deg, var(--gradient-start), var(--gradient-end)); + color: white; + border: none; + padding: 0.75rem 1.5rem; + border-radius: 8px; + cursor: pointer; + transition: all 0.3s ease; +} + +.retry-button:hover { + transform: translateY(-2px); + filter: brightness(1.1); +} + +.global-error { + position: fixed; + top: 1rem; + right: 1rem; + max-width: 400px; + z-index: 1000; + animation: slideIn 0.3s ease-out; +} + +.loading-overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.8); + backdrop-filter: blur(5px); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + z-index: 1000; +} + +.loading-spinner { + width: 40px; + height: 40px; + border: 3px solid rgba(255, 255, 255, 0.1); + border-top-color: var(--gradient-end); + border-radius: 50%; + animation: spin 1s linear infinite; + margin-bottom: 1rem; +} + +.loading-overlay p { + color: white; + font-size: 0.95rem; +} + +.error-message { + color: var(--error-color); + font-size: 0.9rem; + margin-top: 0.25rem; + animation: fadeIn 0.3s ease-out; +} + +input.error { + border-color: var(--error-color) !important; +} + +.dark-mode { + --background-color: #000; + --surface-color: #1a1c2a; + --text-color: #ffffff; + --border-color: #2a2c3a; +} + +.floating-header { + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 1000; + background: rgba(26, 28, 42, 0.95); + backdrop-filter: blur(10px); + box-shadow: 0 2px 20px rgba(0, 0, 0, 0.2); +} + +.floating-nav { + max-width: 1200px; + margin: 0 auto; + padding: 1rem 2rem; + display: flex; + align-items: center; +} + +.nav-link { + color: var(--text-color); + text-decoration: none; + padding: 0.5rem 1rem; + border-radius: 8px; + transition: all 0.3s ease; + display: flex; + align-items: center; + gap: 0.5rem; +} + +.nav-link:hover, .nav-link.active { + color: var(--gradient-end); + background: rgba(255, 255, 255, 0.05); +} + +.nav-logo { + height: 24px; +} + +.right-links { + margin-left: auto; + display: flex; + gap: 0.5rem; +} + +@media (max-width: 768px) { + .floating-nav { + flex-direction: column; + padding: 0.5rem; + } + + .nav-link { + width: 100%; + justify-content: center; + margin: 0.25rem 0; + } + + .right-links { + width: 100%; + flex-direction: column; + margin: 0.5rem 0 0; + } + + .right-links .glass-button { + width: 100%; + text-align: center; + } +} + @keyframes spin { to { transform: rotate(360deg); @@ -439,6 +615,17 @@ select::placeholder, input[type="number"]::placeholder { 75% { transform: translateX(5px); } } +@keyframes slideIn { + from { + opacity: 0; + transform: translateX(20px); + } + to { + opacity: 1; + transform: translateX(0); + } +} + @media (max-width: 768px) { nav { padding: 1rem; @@ -469,3 +656,21 @@ select::placeholder, input[type="number"]::placeholder { flex-direction: column; } } + +.glass-footer { + position: relative; + margin-top: auto; + width: 100%; + background: rgba(26, 28, 42, 0.95); + backdrop-filter: blur(10px); + border-top: 1px solid rgba(255, 255, 255, 0.1); + padding: 2rem; + text-align: center; +} + +.glass-footer p { + max-width: 800px; + margin: 0 auto; + color: rgba(255, 255, 255, 0.7); + font-size: 0.9rem; +} From 3fd5646b60b921d4de7923f5232b70d267dec8f6 Mon Sep 17 00:00:00 2001 From: Piyush Acharya Date: Thu, 20 Feb 2025 20:52:53 -0800 Subject: [PATCH 06/19] Update index.html Signed-off-by: Piyush Acharya --- web/index.html | 1 - 1 file changed, 1 deletion(-) diff --git a/web/index.html b/web/index.html index 67b75a6e..705f83e3 100644 --- a/web/index.html +++ b/web/index.html @@ -30,7 +30,6 @@

    DNAnalyzer

    A highly efficient, powerful, and feature-rich algorithm for analyzing DNA sequences

    - DNA Sequence Analysis Visualization
    From fc9a8ecd2aac983824fdde355de7b1025f0523c8 Mon Sep 17 00:00:00 2001 From: Piyush Acharya Date: Fri, 21 Feb 2025 05:23:18 +0000 Subject: [PATCH 07/19] fix about page --- web/about/about.css | 187 +------------ web/about/about.html | 2 +- web/index.html | 2 +- web/server/server.css | 58 ++-- web/style.css | 628 +++++++----------------------------------- 5 files changed, 146 insertions(+), 731 deletions(-) diff --git a/web/about/about.css b/web/about/about.css index b8b0f060..f69c6316 100644 --- a/web/about/about.css +++ b/web/about/about.css @@ -1,58 +1,5 @@ -/* - * Copyright © 2025 Piyush Acharya. Some rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * You are entirely responsible for the use of this application, including any and all activities that occur. - * While DNAnalyzer strives to fix all major bugs that may be either reported by a user or discovered while debugging, - * they will not be held liable for any loss that the user may incur as a result of using this application, under any circumstances. - * - * For further inquiries, please reach out to contact@dnanalyzer.live - */ - -@import url('https://fonts.googleapis.com/css2?family=Poppins&display=swap'); - -* > * { - font-family: "Poppins", cursive; -} - -body { - --text-light: rgba(243, 244, 246, 0.9); - --primary-dark: rgba(55, 65, 81, 1); - --secondary-dark: rgba(55, 65, 81, 0.7); - --bg-light: rgba(243, 244, 246, 0.3); - --bg-btn: rgba(67, 56, 202, 0.8); - background-color: var(--text-light); -} - -body.dark { - --text-light: rgba(55, 65, 81, 1); - --primary-dark: rgba(243, 244, 246, 1); - --secondary-dark: rgba(255, 255, 255); - --bg-btn: rgba(219, 233, 29, 0.897); - --bg-light: rgba(45, 49, 54, 0.5); -} - -.btn { - background-color: #4CAF50; - border: none; - color: white; - padding: 15px 32px; - text-align: center; - text-decoration: none; - display: inline-block; - font-size: 16px; -} - -p { - margin: 0; -} - +/* About page specific styles */ .container { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - margin: 0; max-width: 1200px; margin: 6rem auto 2rem; padding: 2rem; @@ -62,11 +9,6 @@ p { margin-bottom: 4rem; } -.text-center { - text-align: center; - padding: 10px 15px; -} - .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); @@ -74,95 +16,6 @@ p { padding: 2rem 0; } -.grid .flex { - display: flex; - flex-direction: column; - align-items: center; - padding: 4em 0; -} - -.grid .icon > span { - font-size: 4em; - color: var(--bg-btn); -} - -.primary-dark { - color: var(--primary-dark); -} - -.secondary-dark { - color: var(--secondary-dark); - padding: 20px 30px; -} - -.bg-light { - background-color: var(--bg-light); - box-shadow: 1px 5px 20px rgba(55, 65, 81, 0.1); - border-radius: 20px; -} - -.btn { - width: 250px; - height: 30px; - background-color: #f44336; - border: none; - font-size: 18px; - color: #fff; - border-radius: 50px; - cursor: pointer; - font-weight: bold; - margin: auto -} - -img { - width: 120px; - padding: 10px; - border-radius: 50%; - background-color: #f44336; - margin-top: 250px; -} - -input[type="checkbox"] { - -webkit-appearance: none; - appearance: none; - position: relative; - width: 80px; - height: 40px; - border-radius: 50px; - outline: none; - /* background-color: yellow; */ - background-image: url(https://i.postimg.cc/857jHw2q/Screenshot-2020-04-16-at-1-07-06-PM.png); - background-size: cover; -} - -input[type="checkbox"]::before { - content: ""; - position: absolute; - top: 0; - left: 0; - height: 40px; - width: 40px; - background-color: var(--primary-dark); - border-radius: 50px; -} - -input[type="checkbox"]:checked:before { - transform: translate(100%); -} - -input[type="checkbox"]:checked { - background-image: url(https://i.postimg.cc/Hn0nstVK/Screenshot-2020-04-16-at-1-07-19-PM.png); -} - -img { - width: 130px; - padding: 10px; - border-radius: 50%; - background-color: #f44336; - margin-top: 100px; -} - -/* About page specific styles */ .glass-card { background: rgba(255, 255, 255, 0.05); padding: 2rem; @@ -189,6 +42,10 @@ img { .card-icon { width: 32px; height: 32px; + padding: 0; + background: none; + border-radius: 0; + margin: 0; } .glass-card h2 { @@ -207,29 +64,19 @@ img { .feature-image { width: 100%; + height: auto; border-radius: 8px; margin-top: 1.5rem; transition: transform 0.3s ease; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); + padding: 0; + background: none; } .feature-image:hover { transform: scale(1.02); } -.glass-footer { - background: rgba(255, 255, 255, 0.05); - backdrop-filter: blur(10px); - padding: 1.5rem; - text-align: center; - border-top: 1px solid rgba(255, 255, 255, 0.1); -} - -.glass-footer p { - color: rgba(255, 255, 255, 0.7); - font-size: 0.9rem; -} - .glass-button { background: rgba(255, 255, 255, 0.1); color: white; @@ -250,10 +97,12 @@ img { @media (max-width: 768px) { .container { padding: 1rem; + margin-top: 5rem; } .grid { grid-template-columns: 1fr; + gap: 1.5rem; } .glass-card { @@ -263,17 +112,9 @@ img { .feature-image { margin: 1rem 0; } -} -.glass-card h2 { - margin-bottom: 1rem; - color: #ffffff; -} - -/* Remove unused styles */ -body.dark, -.btn, -input[type="checkbox"], -img.icon { - display: none; + h1 { + font-size: 2rem; + text-align: center; + } } \ No newline at end of file diff --git a/web/about/about.html b/web/about/about.html index 3788928f..616cc909 100644 --- a/web/about/about.html +++ b/web/about/about.html @@ -15,7 +15,7 @@
    -
    -
    -
    -
    +
    @@ -54,7 +52,7 @@

    DNAnalyzer

-
+
99.9%
@@ -75,15 +73,13 @@

DNAnalyzer

-
+

Why Choose DNAnalyzer?

- +

Advanced Analysis

@@ -100,7 +96,7 @@

Advanced Analysis

-
+

How It Works

@@ -108,25 +104,25 @@

How It Works

01

Upload

Upload your DNA sequence file in FASTA or FASTQ format

-
+
02

Analyze

Our ML algorithms process and analyze your sequence

-
+
03

Results

Get comprehensive analysis results and insights

-
+
-
+
@@ -134,68 +130,43 @@

Privacy & Security

Your genetic data never leaves your device. All computations are performed locally using our advanced on-device ML models.

  • -
    + Local Processing
  • -
    + End-to-End Encryption
  • -
    + Data Privacy
-
+
-
+

Ready to Start?

Join thousands of researchers and scientists using DNAnalyzer for their genetic analysis needs.

- - + Start Analyzing + Read Documentation
-
- +
diff --git a/web/index.js b/web/index.js index 336d923f..dc2463db 100644 --- a/web/index.js +++ b/web/index.js @@ -1,164 +1,108 @@ document.addEventListener('DOMContentLoaded', function() { - // Intersection Observer for scroll animations - const observer = new IntersectionObserver((entries) => { - entries.forEach(entry => { - if (entry.isIntersecting) { - entry.target.classList.add('visible'); - - // Animate stats when they come into view - if (entry.target.id === 'stats') { - animateStats(); - } - } - }); - }, { - threshold: 0.1 - }); + // DNA Helix Animation + const dnaHelix = document.querySelector('.dna-helix'); + const numBases = 20; + const baseTypes = ['A', 'T', 'C', 'G']; + + // Create base pairs + for (let i = 0; i < numBases; i++) { + const baseIndex = Math.floor(Math.random() * baseTypes.length); + const complementaryIndex = baseIndex % 2 === 0 ? baseIndex + 1 : baseIndex - 1; + + const leftBase = document.createElement('div'); + leftBase.className = 'base left-base'; + leftBase.textContent = baseTypes[baseIndex]; + leftBase.style.animationDelay = `${i * 0.2}s`; + + const rightBase = document.createElement('div'); + rightBase.className = 'base right-base'; + rightBase.textContent = baseTypes[complementaryIndex]; + rightBase.style.animationDelay = `${i * 0.2}s`; + + const connector = document.createElement('div'); + connector.className = 'base-connector'; + connector.style.animationDelay = `${i * 0.2}s`; + + const basePair = document.createElement('div'); + basePair.className = 'base-pair'; + basePair.style.top = `${i * 30}px`; + + basePair.appendChild(leftBase); + basePair.appendChild(connector); + basePair.appendChild(rightBase); + dnaHelix.appendChild(basePair); + } - // Observe all scroll sections - document.querySelectorAll('.scroll-section').forEach(section => { - observer.observe(section); + // Scroll Indicator + const scrollIndicator = document.querySelector('.scroll-indicator'); + let lastScrollTop = 0; + + window.addEventListener('scroll', () => { + const st = window.pageYOffset || document.documentElement.scrollTop; + + if (st > lastScrollTop) { + // Scrolling down + scrollIndicator.style.opacity = '0'; + } else if (st === 0) { + // At top + scrollIndicator.style.opacity = '1'; + } + + lastScrollTop = st <= 0 ? 0 : st; }); - // Stats animation - function animateStats() { - document.querySelectorAll('.stat-number').forEach(stat => { - const target = parseInt(stat.textContent); - let current = 0; - const increment = target / 100; - const duration = 2000; // 2 seconds - const steps = 100; - const stepTime = duration / steps; + // Stats Animation + const stats = document.querySelectorAll('.stat-number'); + const statsSection = document.querySelector('#stats'); + let animated = false; - const timer = setInterval(() => { - current += increment; - if (current >= target) { - stat.textContent = target + (stat.textContent.includes('%') ? '%' : '+'); - clearInterval(timer); - } else { - stat.textContent = Math.floor(current) + (stat.textContent.includes('%') ? '%' : '+'); + function animateStats() { + if (animated) return; + + stats.forEach(stat => { + const value = stat.textContent; + const isPercentage = value.includes('%'); + const number = parseFloat(value); + let start = 0; + + const increment = number / 50; // Animate over 50 steps + const interval = setInterval(() => { + start += increment; + if (start >= number) { + start = number; + clearInterval(interval); } - }, stepTime); + stat.textContent = isPercentage ? + start.toFixed(1) + '%' : + Math.round(start).toLocaleString(); + }, 30); }); + + animated = true; } - // Parallax effect for gradient spheres - document.addEventListener('mousemove', (e) => { - const spheres = document.querySelectorAll('.gradient-sphere'); - const mouseX = e.clientX / window.innerWidth; - const mouseY = e.clientY / window.innerHeight; - - spheres.forEach((sphere, index) => { - const depth = index === 0 ? 20 : 10; - const translateX = (mouseX - 0.5) * depth; - const translateY = (mouseY - 0.5) * depth; - sphere.style.transform = `translate(${translateX}px, ${translateY}px)`; + // Intersection Observer for stats animation + const observer = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + animateStats(); + } }); - }); + }, { threshold: 0.5 }); + + observer.observe(statsSection); // Smooth scroll for navigation document.querySelectorAll('a[href^="#"]').forEach(anchor => { - anchor.addEventListener('click', function(e) { + anchor.addEventListener('click', function (e) { e.preventDefault(); - const targetId = this.getAttribute('href').substring(1); - const targetElement = document.getElementById(targetId); - - if (targetElement) { - const headerOffset = 80; - const elementPosition = targetElement.getBoundingClientRect().top; - const offsetPosition = elementPosition + window.pageYOffset - headerOffset; - - window.scrollTo({ - top: offsetPosition, - behavior: 'smooth' + const target = document.querySelector(this.getAttribute('href')); + if (target) { + target.scrollIntoView({ + behavior: 'smooth', + block: 'start' }); } }); }); - - // DNA Helix Animation - const dnaHelix = document.querySelector('.dna-helix'); - if (dnaHelix) { - const numBases = 20; - for (let i = 0; i < numBases; i++) { - const base = document.createElement('div'); - base.className = 'dna-base'; - base.style.top = `${(i / numBases) * 100}%`; - base.style.animationDelay = `${i * 0.1}s`; - dnaHelix.appendChild(base); - } - } - - // Feature list animation - document.querySelectorAll('.feature-list li').forEach((item, index) => { - item.style.opacity = '0'; - item.style.transform = 'translateX(-20px)'; - setTimeout(() => { - item.style.transition = 'all 0.5s ease'; - item.style.opacity = '1'; - item.style.transform = 'translateX(0)'; - }, index * 200); - }); - - // Security features animation - document.querySelectorAll('.security-features li').forEach((item, index) => { - item.style.opacity = '0'; - item.style.transform = 'translateY(20px)'; - const observer = new IntersectionObserver(entries => { - entries.forEach(entry => { - if (entry.isIntersecting) { - setTimeout(() => { - item.style.transition = 'all 0.5s ease'; - item.style.opacity = '1'; - item.style.transform = 'translateY(0)'; - }, index * 200); - observer.unobserve(item); - } - }); - }); - observer.observe(item); - }); - - // Workflow steps animation - document.querySelectorAll('.step').forEach((step, index) => { - step.style.opacity = '0'; - step.style.transform = 'translateY(20px)'; - const observer = new IntersectionObserver(entries => { - entries.forEach(entry => { - if (entry.isIntersecting) { - setTimeout(() => { - step.style.transition = 'all 0.5s ease'; - step.style.opacity = '1'; - step.style.transform = 'translateY(0)'; - }, index * 200); - observer.unobserve(step); - } - }); - }); - observer.observe(step); - }); - - // Scroll indicator fade out - const scrollIndicator = document.querySelector('.scroll-indicator'); - if (scrollIndicator) { - window.addEventListener('scroll', () => { - const scrollPosition = window.scrollY; - if (scrollPosition > 100) { - scrollIndicator.style.opacity = '0'; - } else { - scrollIndicator.style.opacity = '1'; - } - }); - } - - // Initial check for visible sections - document.querySelectorAll('.scroll-section').forEach(section => { - const rect = section.getBoundingClientRect(); - if (rect.top < window.innerHeight) { - section.classList.add('visible'); - if (section.id === 'stats') { - animateStats(); - } - } - }); }); \ No newline at end of file diff --git a/web/server/server.css b/web/server/server.css index 649a4dc7..907f546a 100644 --- a/web/server/server.css +++ b/web/server/server.css @@ -1,214 +1,276 @@ -/* Server page specific styles */ .container { max-width: 1200px; margin: 6rem auto 2rem; padding: 2rem; } -.server-setup-section { +/* Hero Section */ +.hero { + text-align: center; + margin-bottom: 4rem; +} + +.hero h1 { + font-size: 3.5rem; + margin-bottom: 1.5rem; + background: linear-gradient(45deg, var(--gradient-start), var(--gradient-end)); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; +} + +.hero p { + font-size: 1.2rem; + color: rgba(255, 255, 255, 0.9); + max-width: 800px; + margin: 0 auto; + line-height: 1.8; +} + +/* Server Status Section */ +.status-section { + margin: 4rem 0; + padding: 2rem; + background: rgba(0, 0, 0, 0.2); + border-radius: 12px; + border: 1px solid rgba(255, 255, 255, 0.1); +} + +.status-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 2rem; margin-top: 2rem; } -.glass-card { +.status-card { background: rgba(255, 255, 255, 0.05); - padding: 2rem; - margin-bottom: 2rem; border-radius: 12px; + padding: 2rem; + text-align: center; border: 1px solid rgba(255, 255, 255, 0.1); - backdrop-filter: blur(10px); transition: all 0.3s ease; } -.glass-card:hover { - transform: translateY(-2px); - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2); +.status-card:hover { + transform: translateY(-5px); border-color: var(--gradient-end); + box-shadow: 0 4px 20px rgba(0, 122, 255, 0.2); } -.glass-card h2 { - font-size: 1.8rem; - margin-bottom: 1.5rem; - background: linear-gradient(45deg, var(--gradient-start), var(--gradient-end)); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - text-align: left; +.status-icon { + font-size: 2.5rem; + margin-bottom: 1rem; + color: var(--gradient-end); } -#server-status { - margin-top: 1rem; - padding: 1.5rem; - border-radius: 8px; +.status-card h3 { + font-size: 1.5rem; + margin-bottom: 1rem; + color: var(--gradient-end); +} + +.status-value { + font-size: 2rem; + font-weight: 600; + margin-bottom: 0.5rem; +} + +.status-label { + color: rgba(255, 255, 255, 0.7); + font-size: 1.1rem; +} + +/* API Key Section */ +.api-section { + margin: 4rem 0; + padding: 2rem; background: rgba(0, 0, 0, 0.2); - font-family: 'IBM Plex Mono', monospace; + border-radius: 12px; + border: 1px solid rgba(255, 255, 255, 0.1); } -#server-status small { +.api-section h2 { + font-size: 2rem; + margin-bottom: 1.5rem; + color: var(--gradient-end); +} + +.api-form { + max-width: 600px; + margin: 0 auto; +} + +.form-group { + margin-bottom: 1.5rem; +} + +.form-group label { display: block; - margin-top: 0.5rem; - color: rgba(255, 255, 255, 0.6); + margin-bottom: 0.5rem; + color: rgba(255, 255, 255, 0.9); + font-size: 1.1rem; } -.command-box { - display: flex; - align-items: center; +.form-group input { + width: 100%; + padding: 1rem; background: rgba(0, 0, 0, 0.3); - padding: 1rem 1.2rem; + border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 8px; - margin: 0.5rem 0; - border: 1px solid rgba(255, 255, 255, 0.1); - gap: 1rem; + color: white; + font-size: 1rem; + font-family: 'IBM Plex Mono', monospace; } -.command-box code { - flex-grow: 1; - font-family: 'IBM Plex Mono', monospace; - color: #10B981; - font-size: 0.9rem; - overflow-x: auto; - white-space: nowrap; +.form-group input:focus { + outline: none; + border-color: var(--gradient-start); + box-shadow: 0 0 0 3px rgba(0, 122, 255, 0.2); } -.copy-button { - background: rgba(255, 255, 255, 0.1); - border: 1px solid rgba(255, 255, 255, 0.2); - color: white; - padding: 0.5rem 1rem; - border-radius: 6px; - cursor: pointer; +/* Documentation Section */ +.docs-section { + margin: 4rem 0; +} + +.endpoint-list { + display: grid; + gap: 2rem; +} + +.endpoint-card { + background: rgba(255, 255, 255, 0.05); + border-radius: 12px; + padding: 2rem; + border: 1px solid rgba(255, 255, 255, 0.1); transition: all 0.3s ease; - font-size: 0.9rem; } -.copy-button:hover { - background: rgba(255, 255, 255, 0.15); - transform: translateY(-1px); - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); +.endpoint-card:hover { + transform: translateY(-5px); + border-color: var(--gradient-end); + box-shadow: 0 4px 20px rgba(0, 122, 255, 0.2); } -.copy-button:active { - transform: translateY(0); +.endpoint-method { + display: inline-block; + padding: 0.5rem 1rem; + border-radius: 6px; + font-size: 0.9rem; + font-weight: 600; + margin-bottom: 1rem; } -.setup-steps { - list-style-position: inside; - padding: 0; - margin: 1.5rem 0; - counter-reset: step; +.method-get { + background: rgba(0, 200, 83, 0.2); + color: #00c853; } -.setup-steps li { - margin-bottom: 2rem; - position: relative; - padding-left: 2.5rem; +.method-post { + background: rgba(0, 122, 255, 0.2); + color: #007bff; } -.setup-steps li::before { - counter-increment: step; - content: counter(step); - position: absolute; - left: 0; - top: 0; - width: 1.8rem; - height: 1.8rem; - background: linear-gradient(135deg, var(--gradient-start), var(--gradient-end)); - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - font-size: 0.9rem; - color: white; +.endpoint-url { + font-family: 'IBM Plex Mono', monospace; + font-size: 1.1rem; + color: rgba(255, 255, 255, 0.9); + margin-bottom: 1rem; + padding: 1rem; + background: rgba(0, 0, 0, 0.3); + border-radius: 6px; + overflow-x: auto; } -.setup-steps li p { - margin-bottom: 0.5rem; +.endpoint-description { color: rgba(255, 255, 255, 0.9); + font-size: 1rem; + line-height: 1.6; + margin-bottom: 1.5rem; } -.troubleshooting { - margin-top: 2rem; - padding-top: 1.5rem; - border-top: 1px solid rgba(255, 255, 255, 0.1); +.endpoint-params { + margin-top: 1.5rem; } -.issue-item { - margin-bottom: 2rem; +.param-table { + width: 100%; + border-collapse: collapse; + margin-top: 1rem; } -.issue-item h4 { - color: var(--gradient-end); - margin-bottom: 0.8rem; - font-size: 1.1rem; +.param-table th, +.param-table td { + padding: 1rem; + text-align: left; + border-bottom: 1px solid rgba(255, 255, 255, 0.1); } -.issue-item ul { - list-style: disc; - padding-left: 1.2rem; - margin: 0.8rem 0; +.param-table th { + color: var(--gradient-end); + font-weight: 600; } -.issue-item ul li { - color: rgba(255, 255, 255, 0.8); - margin: 0.4rem 0; +.param-required { + color: #dc3545; + font-weight: 600; } -.requirements-note { +/* Response Section */ +.response-example { margin-top: 1.5rem; padding: 1.5rem; - background: rgba(0, 0, 0, 0.2); + background: rgba(0, 0, 0, 0.3); border-radius: 8px; - border: 1px solid rgba(255, 255, 255, 0.1); + font-family: 'IBM Plex Mono', monospace; + overflow-x: auto; } -.requirements-note ul { - list-style: none; - padding: 0; - margin: 0.8rem 0; +.response-example pre { + margin: 0; + color: rgba(255, 255, 255, 0.9); } -.requirements-note ul li { - color: rgba(255, 255, 255, 0.9); - margin: 0.4rem 0; - display: flex; - align-items: center; +/* Buttons */ +.submit-btn { + background: linear-gradient(135deg, var(--gradient-start), var(--gradient-end)); + color: white; + border: none; + padding: 1rem 2rem; + border-radius: 8px; + font-size: 1.1rem; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + width: 100%; } -.requirements-note ul li::before { - content: '✓'; - color: var(--success-color); - margin-right: 0.5rem; +.submit-btn:hover { + transform: translateY(-2px); + box-shadow: 0 4px 15px rgba(0, 122, 255, 0.3); } -@media (max-width: 768px) { +/* Responsive Design */ +@media screen and (max-width: 768px) { .container { margin: 4rem 1rem 2rem; padding: 1rem; } - .glass-card { - padding: 1.5rem; - } - - .command-box { - flex-direction: column; - align-items: stretch; - gap: 0.5rem; - } - - .command-box code { - padding: 0.5rem; - background: rgba(0, 0, 0, 0.2); - border-radius: 4px; + .hero h1 { + font-size: 2.5rem; } - .copy-button { - width: 100%; + .status-grid { + grid-template-columns: 1fr; } - .setup-steps li { - padding-left: 2rem; + .endpoint-url { + font-size: 0.9rem; } - .glass-card h2 { - font-size: 1.5rem; + .param-table { + display: block; + overflow-x: auto; } } \ No newline at end of file diff --git a/web/server/server.html b/web/server/server.html index 311cec85..6e5bada8 100644 --- a/web/server/server.html +++ b/web/server/server.html @@ -6,11 +6,14 @@ Server Setup - DNAnalyzer - + +
+
+
-
+

Server Setup

- -
-

Quick Start Guide

-
    -
  1. -

    Clone and navigate to the repository:

    -
    - git clone https://github.com/VerisimilitudeX/DNAnalyzer.git && cd DNAnalyzer - -
    -
  2. -
  3. -

    Make the Gradle wrapper executable:

    -
    - chmod +x ./gradlew - -
    -
  4. -
  5. -

    Build the project (this may take a few minutes):

    -
    - ./gradlew clean bootJar - -
    -
  6. -
  7. -

    Start the local server:

    -
    - java -jar build/libs/DNAnalyzer.jar - -
    -
  8. -
-
-

Requirements:

-
    -
  • Java 17 or higher
  • -
  • Port 8080 must be available
  • -
  • Git installed
  • -
  • At least 2GB of free RAM
  • -
+

Get started with DNAnalyzer's local server deployment

+
+ +
+
+
+ +

Server Status

+
Checking...
+

Local Server

+
+
+ +

System Requirements

+
2GB+
+

Minimum RAM

+
+
+ +

Version

+
Java 17+
+

Required Runtime

+
-
-

Server Status

-
- Checking server status... +
+

Quick Start Guide

+
+
+ Step 1 +
+ git clone https://github.com/VerisimilitudeX/DNAnalyzer.git && cd DNAnalyzer +
+

Clone and navigate to the repository

-
-
-

Troubleshooting

-
-

Common Issues

-
-

Port Already in Use

-

If port 8080 is already in use, you may see an error like "Address already in use". To fix this:

-
    -
  • Close any other applications using port 8080
  • -
  • Or modify the port in application.yml
  • -
+
+ Step 2 +
+ chmod +x ./gradlew
-
-

Java Version

-

If you see "UnsupportedClassVersionError", make sure you have Java 17+ installed:

-
- java -version -
+

Make the Gradle wrapper executable

+
+ +
+ Step 3 +
+ ./gradlew clean bootJar
-
-

Build Failures

-

For build errors, try:

-
    -
  • Running './gradlew clean' first
  • -
  • Checking your Java installation
  • -
  • Ensuring you have write permissions in the directory
  • -
+

Build the project (this may take a few minutes)

+
+ +
+ Step 4 +
+ java -jar build/libs/DNAnalyzer.jar
+

Start the local server

+
+
+
+ +
+

Troubleshooting

+
+
+

Port Already in Use

+

+ If port 8080 is already in use, you may see an error like "Address already in use". To fix this: +

+
    +
  • Close any other applications using port 8080
  • +
  • Or modify the port in application.yml
  • +
+
+ +
+

Java Version

+

+ If you see "UnsupportedClassVersionError", make sure you have Java 17+ installed: +

+
java -version
+
+ +
+

Build Failures

+

For build errors, try:

+
    +
  • Running './gradlew clean' first
  • +
  • Checking your Java installation
  • +
  • Ensuring you have write permissions in the directory
  • +
-
-

Copyright © Piyush Acharya 2025. DNAnalyzer is a fiscally sponsored 501(c)(3) nonprofit (EIN: 81-2908499). MIT License.

+
+
diff --git a/web/style.css b/web/style.css index 7bb13abc..a6a0ff88 100644 --- a/web/style.css +++ b/web/style.css @@ -54,7 +54,6 @@ body { right: -200px; z-index: -1; filter: blur(50px); - animation: float 20s infinite ease-in-out; } .gradient-sphere.secondary { @@ -65,7 +64,6 @@ body { left: -100px; top: auto; right: auto; - animation-delay: -10s; } /* Navbar */ @@ -138,12 +136,12 @@ body { font-size: 0.95rem; cursor: pointer; transition: all 0.3s ease; + text-decoration: none; } .glass-button:hover { background: rgba(255, 255, 255, 0.15); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); - transform: translateY(-2px); } .primary-btn, .secondary-btn { @@ -156,6 +154,9 @@ body { text-transform: uppercase; letter-spacing: 1px; min-width: 200px; + text-decoration: none; + text-align: center; + display: inline-block; } .primary-btn { @@ -172,13 +173,11 @@ body { } .primary-btn:hover { - transform: translateY(-2px); box-shadow: 0 8px 25px rgba(0, 122, 255, 0.4); filter: brightness(1.1); } .secondary-btn:hover { - transform: translateY(-2px); background: rgba(255, 255, 255, 0.15); box-shadow: 0 4px 15px rgba(255, 255, 255, 0.1); } @@ -190,7 +189,6 @@ body { flex-direction: column; justify-content: center; align-items: center; - text-align: center; padding: 2rem; position: relative; overflow: hidden; @@ -208,6 +206,7 @@ body { .hero-text { z-index: 1; + text-align: left; } .hero-text h1 { @@ -217,7 +216,6 @@ body { background: linear-gradient(45deg, var(--gradient-start), var(--gradient-end)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; - text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); } .hero-subtitle { @@ -231,61 +229,80 @@ body { .cta-buttons { display: flex; gap: 1.5rem; - margin-top: 2rem; } -/* Scroll Sections */ -.scroll-section { - padding: 6rem 2rem; - opacity: 0; - transform: translateY(20px); - transition: all 0.6s ease; +/* DNA Helix Animation */ +.hero-visual { + position: relative; + width: 100%; + height: 400px; + display: flex; + justify-content: center; + align-items: center; } -.scroll-section.visible { - opacity: 1; - transform: translateY(0); +.dna-helix { + position: relative; + width: 100%; + height: 100%; + perspective: 1000px; } -/* Stats Section */ -#stats { - background: rgba(0, 0, 0, 0.2); +.base-pair { + position: absolute; + width: 100%; + height: 20px; + display: flex; + justify-content: center; + align-items: center; } -.stats-grid { - max-width: 1200px; - margin: 0 auto; - display: grid; - grid-template-columns: repeat(4, 1fr); - gap: 2rem; +.base { + width: 30px; + height: 30px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-family: 'IBM Plex Mono', monospace; + font-weight: bold; + color: white; + position: absolute; } -.stat-item { - text-align: center; - padding: 2rem; - background: rgba(255, 255, 255, 0.05); - border-radius: 12px; - border: 1px solid rgba(255, 255, 255, 0.1); - transition: all 0.3s ease; +.left-base { + background: var(--gradient-start); + left: calc(50% - 100px); + animation: moveLeft 4s ease-in-out infinite; } -.stat-item:hover { - transform: translateY(-5px); - border-color: var(--gradient-end); +.right-base { + background: var(--gradient-end); + right: calc(50% - 100px); + animation: moveRight 4s ease-in-out infinite; } -.stat-number { - font-size: 3rem; - font-weight: 600; - background: linear-gradient(45deg, var(--gradient-start), var(--gradient-end)); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - margin-bottom: 0.5rem; +.base-connector { + width: 160px; + height: 2px; + background: linear-gradient(90deg, var(--gradient-start), var(--gradient-end)); + position: absolute; + animation: stretch 4s ease-in-out infinite; } -.stat-label { - color: rgba(255, 255, 255, 0.7); - font-size: 1.1rem; +@keyframes moveLeft { + 0%, 100% { transform: translateX(-20px); } + 50% { transform: translateX(20px); } +} + +@keyframes moveRight { + 0%, 100% { transform: translateX(20px); } + 50% { transform: translateX(-20px); } +} + +@keyframes stretch { + 0%, 100% { width: 160px; } + 50% { width: 200px; } } /* Scroll Indicator */ @@ -300,6 +317,7 @@ body { gap: 1rem; color: rgba(255, 255, 255, 0.7); transition: opacity 0.3s ease; + z-index: 10; } .mouse { @@ -323,83 +341,294 @@ body { animation: scroll 2s infinite; } -/* Footer */ -.footer-content { +@keyframes scroll { + 0% { + transform: translate(-50%, 0); + opacity: 1; + } + 100% { + transform: translate(-50%, 20px); + opacity: 0; + } +} + +/* Stats Section */ +#stats { + background: rgba(0, 0, 0, 0.2); + padding: 6rem 2rem; +} + +.stats-grid { max-width: 1200px; margin: 0 auto; display: grid; grid-template-columns: repeat(4, 1fr); + gap: 2rem; +} + +.stat-item { + text-align: center; + padding: 2rem; + background: rgba(255, 255, 255, 0.05); + border-radius: 12px; + border: 1px solid rgba(255, 255, 255, 0.1); + transition: all 0.3s ease; +} + +.stat-item:hover { + border-color: var(--gradient-end); +} + +.stat-number { + font-size: 3rem; + font-weight: 600; + background: linear-gradient(45deg, var(--gradient-start), var(--gradient-end)); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + margin-bottom: 0.5rem; +} + +.stat-label { + color: rgba(255, 255, 255, 0.7); + font-size: 1.1rem; +} + +/* Features Overview */ +#features-overview { + padding: 6rem 2rem; +} + +.content-wrapper { + max-width: 1200px; + margin: 0 auto; +} + +.content-wrapper h2 { + font-size: 2.5rem; + margin-bottom: 3rem; + text-align: center; + color: var(--gradient-end); +} + +.features-showcase { + display: grid; + gap: 4rem; +} + +.feature-highlight { + display: grid; + grid-template-columns: 1fr 1fr; gap: 4rem; - padding: 4rem 2rem; + align-items: center; } -.footer-section h4 { +.feature-visual { + display: flex; + justify-content: center; + align-items: center; + font-size: 5rem; color: var(--gradient-end); - margin-bottom: 1rem; } -.footer-section a { - display: block; - color: rgba(255, 255, 255, 0.7); - text-decoration: none; - margin: 0.5rem 0; - transition: color 0.3s ease; +.feature-content h3 { + font-size: 2rem; + margin-bottom: 1.5rem; + color: var(--gradient-end); } -.footer-section a:hover { +.feature-content p { + font-size: 1.1rem; + color: rgba(255, 255, 255, 0.9); + margin-bottom: 2rem; + line-height: 1.8; +} + +.feature-list { + list-style: none; +} + +.feature-list li { + margin-bottom: 1rem; + padding-left: 2rem; + position: relative; + color: rgba(255, 255, 255, 0.9); +} + +.feature-list li::before { + content: '•'; + position: absolute; + left: 0; color: var(--gradient-end); + font-size: 1.5rem; + line-height: 1; } -.footer-bottom { +/* Workflow Section */ +#workflow { + padding: 6rem 2rem; + background: rgba(0, 0, 0, 0.2); +} + +.workflow-steps { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 2rem; + margin-top: 4rem; +} + +.step { text-align: center; padding: 2rem; - border-top: 1px solid rgba(255, 255, 255, 0.1); + background: rgba(255, 255, 255, 0.05); + border-radius: 12px; + border: 1px solid rgba(255, 255, 255, 0.1); } -/* Animations */ -@keyframes float { - 0%, 100% { - transform: translate(0, 0); - } - 50% { - transform: translate(30px, -30px); - } +.step i { + font-size: 3rem; + color: var(--gradient-end); + margin: 1.5rem 0; } -@keyframes scroll { - 0% { - transform: translate(-50%, 0); - opacity: 1; - } - 100% { - transform: translate(-50%, 20px); - opacity: 0; - } +.step-number { + font-size: 3rem; + font-weight: 700; + color: var(--gradient-end); + margin-bottom: 1.5rem; +} + +.step h3 { + font-size: 1.5rem; + margin-bottom: 1rem; + color: var(--gradient-end); +} + +.step p { + color: rgba(255, 255, 255, 0.9); +} + +/* Security Section */ +#security { + padding: 6rem 2rem; +} + +.security-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 4rem; + align-items: center; +} + +.security-content h2 { + text-align: left; + margin-bottom: 2rem; +} + +.security-content p { + font-size: 1.1rem; + color: rgba(255, 255, 255, 0.9); + margin-bottom: 2rem; + line-height: 1.8; +} + +.security-features { + list-style: none; +} + +.security-features li { + display: flex; + align-items: center; + gap: 1rem; + margin-bottom: 1.5rem; + color: rgba(255, 255, 255, 0.9); +} + +.security-features i { + font-size: 1.5rem; + color: var(--gradient-end); +} + +.security-visual { + display: flex; + justify-content: center; + align-items: center; + font-size: 8rem; + color: var(--gradient-end); +} + +/* CTA Section */ +#cta { + padding: 6rem 2rem; + background: rgba(0, 0, 0, 0.2); +} + +.cta-container { + text-align: center; + max-width: 800px; + margin: 0 auto; +} + +.cta-container h2 { + font-size: 2.5rem; + margin-bottom: 1.5rem; + color: var(--gradient-end); +} + +.cta-container p { + font-size: 1.2rem; + color: rgba(255, 255, 255, 0.9); + margin-bottom: 2rem; + line-height: 1.8; +} + +/* Footer */ +.footer-content { + text-align: center; + padding: 2rem; + background: rgba(0, 0, 0, 0.2); + border-top: 1px solid rgba(255, 255, 255, 0.1); } /* Responsive Design */ -@media (max-width: 1024px) { +@media screen and (max-width: 1024px) { .hero-content { grid-template-columns: 1fr; text-align: center; gap: 2rem; } - .hero-text h1 { - font-size: 3.5rem; + .hero-text { + text-align: center; + } + + .hero-subtitle { + margin: 1.5rem auto 2rem; + } + + .cta-buttons { + justify-content: center; } .stats-grid { grid-template-columns: repeat(2, 1fr); } - .footer-content { - grid-template-columns: repeat(2, 1fr); + .feature-highlight { + grid-template-columns: 1fr; + gap: 2rem; + } + + .workflow-steps { + grid-template-columns: 1fr; + } + + .security-grid { + grid-template-columns: 1fr; gap: 2rem; } } -@media (max-width: 768px) { +@media screen and (max-width: 768px) { .floating-nav { flex-direction: column; padding: 0.5rem; @@ -426,7 +655,7 @@ body { .cta-buttons { flex-direction: column; - width: 100%; + gap: 1rem; } .primary-btn, .secondary-btn { @@ -436,12 +665,4 @@ body { .stats-grid { grid-template-columns: 1fr; } - - .footer-content { - grid-template-columns: 1fr; - } - - .scroll-section { - padding: 3rem 1rem; - } } From be652f68caffc65d295c93a5ae150f461dfb7152 Mon Sep 17 00:00:00 2001 From: Piyush Acharya Date: Fri, 21 Feb 2025 07:58:29 +0000 Subject: [PATCH 14/19] real website revamp --- web/analyzer/analyzer.css | 429 +++++++++++++++++++------------------ web/analyzer/analyzer.html | 214 +++++++++--------- web/analyzer/analyzer.js | 250 +++++++++------------ web/docs/docs.html | 355 ++++++++++++------------------ web/style.css | 305 ++++---------------------- 5 files changed, 601 insertions(+), 952 deletions(-) diff --git a/web/analyzer/analyzer.css b/web/analyzer/analyzer.css index 6514d510..174817ca 100644 --- a/web/analyzer/analyzer.css +++ b/web/analyzer/analyzer.css @@ -1,9 +1,4 @@ -.container { - max-width: 1200px; - margin: 6rem auto 2rem; - padding: 2rem; -} - +/* Hero Section */ .hero { text-align: center; margin-bottom: 3rem; @@ -24,99 +19,166 @@ /* Analysis Container */ .analysis-container { + display: grid; + grid-template-columns: 280px 1fr; + gap: 2rem; + margin: 2rem 0; + min-height: calc(100vh - 400px); +} + +/* Sidebar */ +.analysis-sidebar { background: rgba(0, 0, 0, 0.2); border-radius: 12px; border: 1px solid rgba(255, 255, 255, 0.1); padding: 2rem; - margin-bottom: 3rem; + position: sticky; + top: 6rem; + height: fit-content; } -/* Tabs */ -.analysis-tabs { - display: flex; - gap: 1rem; +.sidebar-section { margin-bottom: 2rem; + padding-bottom: 2rem; border-bottom: 1px solid rgba(255, 255, 255, 0.1); - padding-bottom: 1rem; } -.tab-button { +.sidebar-section:last-child { + border-bottom: none; + margin-bottom: 0; + padding-bottom: 0; +} + +.sidebar-section h3 { + color: var(--gradient-end); + margin-bottom: 1rem; + font-size: 1.2rem; +} + +/* History List */ +.history-list { + background: rgba(0, 0, 0, 0.2); + border-radius: 8px; + padding: 1rem; +} + +.history-item { + display: flex; + align-items: center; + gap: 0.75rem; + color: rgba(255, 255, 255, 0.7); + padding: 0.75rem; + border-radius: 6px; + transition: all 0.3s ease; +} + +.history-item:hover { + background: rgba(255, 255, 255, 0.05); +} + +/* Quick Actions */ +.quick-actions { + display: flex; + flex-direction: column; + gap: 0.75rem; +} + +.action-btn { background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); - color: rgba(255, 255, 255, 0.8); - padding: 1rem 2rem; - border-radius: 8px; + color: rgba(255, 255, 255, 0.9); + padding: 0.75rem 1rem; + border-radius: 6px; cursor: pointer; transition: all 0.3s ease; display: flex; align-items: center; - gap: 0.5rem; - font-size: 1.1rem; + gap: 0.75rem; + width: 100%; + font-size: 0.95rem; } -.tab-button i { - font-size: 1.2rem; +.action-btn:hover { + background: rgba(255, 255, 255, 0.1); + transform: translateY(-2px); } -.tab-button:hover { - background: rgba(255, 255, 255, 0.1); +.action-btn i { + color: var(--gradient-end); } -.tab-button.active { - background: linear-gradient(135deg, var(--gradient-start), var(--gradient-end)); - border-color: transparent; - color: white; +/* Resource Links */ +.resource-links { + display: flex; + flex-direction: column; + gap: 0.75rem; } -.tab-content { - display: none; +.resource-link { + color: rgba(255, 255, 255, 0.9); + text-decoration: none; + padding: 0.75rem 1rem; + border-radius: 6px; + display: flex; + align-items: center; + gap: 0.75rem; + transition: all 0.3s ease; } -.tab-content.active { - display: block; +.resource-link:hover { + background: rgba(255, 255, 255, 0.05); + transform: translateX(5px); } -/* Input Methods */ -.input-methods { +.resource-link i { + color: var(--gradient-end); +} + +/* Analysis Tabs */ +.analysis-tabs { display: flex; gap: 1rem; margin-bottom: 2rem; + border-bottom: 1px solid rgba(255, 255, 255, 0.1); + padding-bottom: 1rem; } -.method-button { +.tab-button { background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); color: rgba(255, 255, 255, 0.8); - padding: 0.75rem 1.5rem; + padding: 1rem 2rem; border-radius: 8px; cursor: pointer; transition: all 0.3s ease; display: flex; align-items: center; - gap: 0.5rem; + gap: 0.75rem; + font-size: 1.1rem; + flex: 1; + justify-content: center; } -.method-button i { - font-size: 1.1rem; +.tab-button i { + font-size: 1.2rem; } -.method-button:hover { +.tab-button:hover { background: rgba(255, 255, 255, 0.1); + transform: translateY(-2px); } -.method-button.active { +.tab-button.active { background: linear-gradient(135deg, var(--gradient-start), var(--gradient-end)); border-color: transparent; color: white; } -/* Input Areas */ -.input-area { +.tab-content { display: none; - margin-bottom: 2rem; } -.input-area.active { +.tab-content.active { display: block; } @@ -124,100 +186,58 @@ .file-drop-zone { border: 2px dashed rgba(255, 255, 255, 0.2); border-radius: 12px; - padding: 3rem; + padding: 4rem 2rem; text-align: center; transition: all 0.3s ease; cursor: pointer; + background: rgba(0, 0, 0, 0.2); + margin-bottom: 2rem; } .file-drop-zone:hover, .file-drop-zone.drag-active { border-color: var(--gradient-end); background: rgba(255, 255, 255, 0.05); + transform: translateY(-2px); } .file-drop-zone i { - font-size: 3rem; + font-size: 4rem; color: var(--gradient-end); + margin-bottom: 1.5rem; +} + +.file-drop-zone h3 { + font-size: 1.5rem; margin-bottom: 1rem; + color: var(--gradient-end); } .file-drop-zone p { - margin: 0.5rem 0; color: rgba(255, 255, 255, 0.9); -} - -.file-drop-zone .sub-text { - color: rgba(255, 255, 255, 0.6); - font-size: 0.9rem; -} - -.upload-button { - display: inline-block; - background: linear-gradient(135deg, var(--gradient-start), var(--gradient-end)); - color: white; - padding: 0.75rem 1.5rem; - border-radius: 8px; - cursor: pointer; - margin: 1rem 0; -} - -.file-info { - font-size: 0.9rem; - color: rgba(255, 255, 255, 0.6); -} - -/* URL Input */ -.url-input-container { - display: flex; - gap: 1rem; -} - -.url-field { - flex: 1; - background: rgba(0, 0, 0, 0.3); - border: 1px solid rgba(255, 255, 255, 0.1); - color: white; - padding: 1rem; - border-radius: 8px; - font-family: inherit; -} - -.fetch-button { - background: linear-gradient(135deg, var(--gradient-start), var(--gradient-end)); - color: white; - border: none; - padding: 0 2rem; - border-radius: 8px; - cursor: pointer; -} - -/* Text Input */ -.sequence-input { - width: 100%; - height: 200px; - background: rgba(0, 0, 0, 0.3); - border: 1px solid rgba(255, 255, 255, 0.1); - color: white; - padding: 1rem; - border-radius: 8px; - font-family: 'IBM Plex Mono', monospace; - resize: vertical; + margin-bottom: 1rem; } /* Analysis Options */ -.options-grid { +.analysis-options { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.5rem; - margin-bottom: 2rem; + margin: 2rem 0; } .option-card { background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 8px; + border-radius: 12px; padding: 1.5rem; + transition: all 0.3s ease; +} + +.option-card:hover { + transform: translateY(-2px); + border-color: var(--gradient-end); + box-shadow: 0 4px 20px rgba(0, 122, 255, 0.2); } .option-header { @@ -241,74 +261,43 @@ .checkbox-container { display: flex; align-items: center; - gap: 0.5rem; + gap: 0.75rem; margin-bottom: 1rem; cursor: pointer; color: rgba(255, 255, 255, 0.9); + padding: 0.5rem; + border-radius: 6px; + transition: all 0.3s ease; } -.checkbox-container input { - width: 18px; - height: 18px; -} - -/* Advanced Settings */ -.advanced-settings { +.checkbox-container:hover { background: rgba(255, 255, 255, 0.05); - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 8px; - margin-bottom: 2rem; -} - -.settings-header { - padding: 1.5rem; - display: flex; - justify-content: space-between; - align-items: center; - border-bottom: 1px solid rgba(255, 255, 255, 0.1); -} - -.settings-header h3 { - margin: 0; - color: var(--gradient-end); } -.toggle-settings { - background: none; - border: none; - color: rgba(255, 255, 255, 0.8); +.checkbox-container input[type="checkbox"] { + width: 18px; + height: 18px; + border-radius: 4px; + border: 2px solid rgba(255, 255, 255, 0.2); + appearance: none; cursor: pointer; - font-size: 1.2rem; -} - -.settings-content { - display: none; - padding: 1.5rem; -} - -.settings-content.show { - display: block; -} - -.setting-group { - margin-bottom: 1.5rem; + position: relative; + transition: all 0.3s ease; } -.setting-group label { - display: block; - margin-bottom: 0.5rem; - color: rgba(255, 255, 255, 0.9); +.checkbox-container input[type="checkbox"]:checked { + background: var(--gradient-end); + border-color: var(--gradient-end); } -.setting-group input, -.setting-group select { - width: 100%; - background: rgba(0, 0, 0, 0.3); - border: 1px solid rgba(255, 255, 255, 0.1); +.checkbox-container input[type="checkbox"]:checked::after { + content: '✓'; + position: absolute; color: white; - padding: 0.75rem; - border-radius: 6px; - font-family: inherit; + font-size: 12px; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); } /* Analyze Button */ @@ -318,7 +307,7 @@ color: white; border: none; padding: 1.25rem; - border-radius: 8px; + border-radius: 12px; font-size: 1.2rem; font-weight: 600; cursor: pointer; @@ -326,15 +315,14 @@ align-items: center; justify-content: center; gap: 0.75rem; + margin-top: 2rem; + transition: all 0.3s ease; } -.analyze-btn i { - font-size: 1.2rem; -} - -.analyze-btn:disabled { - opacity: 0.7; - cursor: not-allowed; +.analyze-btn:hover { + transform: translateY(-2px); + box-shadow: 0 8px 25px rgba(0, 122, 255, 0.4); + filter: brightness(1.1); } /* Results Section */ @@ -342,95 +330,108 @@ background: rgba(0, 0, 0, 0.2); border-radius: 12px; border: 1px solid rgba(255, 255, 255, 0.1); - padding: 2rem; - margin-top: 3rem; + margin-top: 2rem; } -.results-section h2 { +.results-header { + padding: 1.5rem 2rem; + border-bottom: 1px solid rgba(255, 255, 255, 0.1); + display: flex; + justify-content: space-between; + align-items: center; +} + +.results-header h2 { color: var(--gradient-end); - margin-bottom: 2rem; + margin: 0; } -.result-tabs { - display: flex; - gap: 1rem; - margin-bottom: 2rem; +.result-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 1.5rem; + padding: 2rem; } -.result-tab { +.result-card { background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); - color: rgba(255, 255, 255, 0.8); - padding: 0.75rem 1.5rem; border-radius: 8px; - cursor: pointer; + padding: 1.5rem; + text-align: center; + transition: all 0.3s ease; } -.result-tab.active { - background: linear-gradient(135deg, var(--gradient-start), var(--gradient-end)); - border-color: transparent; - color: white; +.result-card:hover { + transform: translateY(-2px); + border-color: var(--gradient-end); +} + +.result-value { + font-size: 2.5rem; + font-weight: 600; + color: var(--gradient-end); + margin-bottom: 0.5rem; +} + +.result-label { + color: rgba(255, 255, 255, 0.7); + font-size: 1rem; } /* Coming Soon */ .coming-soon { text-align: center; - padding: 4rem 2rem; + padding: 6rem 2rem; + color: rgba(255, 255, 255, 0.7); } .coming-soon i { - font-size: 3rem; + font-size: 4rem; color: var(--gradient-end); - margin-bottom: 1.5rem; + margin-bottom: 2rem; } .coming-soon h2 { - color: var(--gradient-end); + font-size: 2rem; margin-bottom: 1rem; -} - -.coming-soon p { - color: rgba(255, 255, 255, 0.9); + color: var(--gradient-end); } /* Responsive Design */ -@media screen and (max-width: 768px) { - .container { - padding: 1rem; +@media screen and (max-width: 1024px) { + .analysis-container { + grid-template-columns: 1fr; } - .hero h1 { - font-size: 2.5rem; + .analysis-sidebar { + position: static; + width: 100%; + height: auto; + margin-bottom: 2rem; } +} +@media screen and (max-width: 768px) { .analysis-tabs { flex-direction: column; } .tab-button { width: 100%; - justify-content: center; } - .input-methods { - flex-direction: column; + .analysis-options { + grid-template-columns: 1fr; } - .method-button { - width: 100%; - justify-content: center; + .result-grid { + grid-template-columns: 1fr; } - .url-input-container { + .results-header { flex-direction: column; - } - - .fetch-button { - width: 100%; - padding: 1rem; - } - - .options-grid { - grid-template-columns: 1fr; + gap: 1rem; + text-align: center; } } \ No newline at end of file diff --git a/web/analyzer/analyzer.html b/web/analyzer/analyzer.html index 5b6ff543..07e9c4e1 100644 --- a/web/analyzer/analyzer.html +++ b/web/analyzer/analyzer.html @@ -39,67 +39,80 @@

DNA Sequence Analysis

-
- - - -
+ -
-
- - -
-
+
+
+ + + +
-
- +
+
+ +

Upload DNA Sequence

+

Drag and drop your sequence file here or click to browse

+ +

Supported formats: .fa, .fasta, .fastq

-
-
-

Analysis Options

-
+
@@ -173,67 +186,62 @@

Advanced Features

-
-
-

Advanced Settings

- -
-
-
- - -
-
- - + + + - -
- -
-
- -

Genetic Testing

-

Advanced genetic testing features coming soon!

-
-
- -
-
- -

Batch Analysis

-

Batch processing capabilities coming soon!

+
+
+ +

Genetic Testing

+

Advanced genetic testing features coming soon!

+
-
-
- + +

Available Options

+ + + + + + + + + diff --git a/web/style.css b/web/style.css index a6a0ff88..d12aff95 100644 --- a/web/style.css +++ b/web/style.css @@ -66,6 +66,14 @@ body { right: auto; } +/* Container */ +.container { + max-width: 1200px; + margin: 0 auto; + padding: 2rem; + flex: 1; +} + /* Navbar */ .floating-header { position: fixed; @@ -255,11 +263,13 @@ body { display: flex; justify-content: center; align-items: center; + transform-style: preserve-3d; + animation: rotate3D 20s linear infinite; } .base { - width: 30px; - height: 30px; + width: 40px; + height: 40px; border-radius: 50%; display: flex; align-items: center; @@ -268,41 +278,49 @@ body { font-weight: bold; color: white; position: absolute; + transform-style: preserve-3d; } .left-base { background: var(--gradient-start); - left: calc(50% - 100px); - animation: moveLeft 4s ease-in-out infinite; + left: calc(50% - 120px); + animation: moveLeft3D 4s ease-in-out infinite; } .right-base { background: var(--gradient-end); - right: calc(50% - 100px); - animation: moveRight 4s ease-in-out infinite; + right: calc(50% - 120px); + animation: moveRight3D 4s ease-in-out infinite; } .base-connector { - width: 160px; - height: 2px; + width: 200px; + height: 3px; background: linear-gradient(90deg, var(--gradient-start), var(--gradient-end)); position: absolute; - animation: stretch 4s ease-in-out infinite; + transform-origin: center; + animation: stretch3D 4s ease-in-out infinite; } -@keyframes moveLeft { - 0%, 100% { transform: translateX(-20px); } - 50% { transform: translateX(20px); } +@keyframes rotate3D { + 0% { transform: rotateY(0deg) rotateX(0deg); } + 50% { transform: rotateY(180deg) rotateX(10deg); } + 100% { transform: rotateY(360deg) rotateX(0deg); } } -@keyframes moveRight { - 0%, 100% { transform: translateX(20px); } - 50% { transform: translateX(-20px); } +@keyframes moveLeft3D { + 0%, 100% { transform: translateX(-30px) translateZ(20px); } + 50% { transform: translateX(30px) translateZ(-20px); } } -@keyframes stretch { - 0%, 100% { width: 160px; } - 50% { width: 200px; } +@keyframes moveRight3D { + 0%, 100% { transform: translateX(30px) translateZ(-20px); } + 50% { transform: translateX(-30px) translateZ(20px); } +} + +@keyframes stretch3D { + 0%, 100% { width: 200px; transform: rotateY(0deg); } + 50% { width: 240px; transform: rotateY(180deg); } } /* Scroll Indicator */ @@ -352,235 +370,6 @@ body { } } -/* Stats Section */ -#stats { - background: rgba(0, 0, 0, 0.2); - padding: 6rem 2rem; -} - -.stats-grid { - max-width: 1200px; - margin: 0 auto; - display: grid; - grid-template-columns: repeat(4, 1fr); - gap: 2rem; -} - -.stat-item { - text-align: center; - padding: 2rem; - background: rgba(255, 255, 255, 0.05); - border-radius: 12px; - border: 1px solid rgba(255, 255, 255, 0.1); - transition: all 0.3s ease; -} - -.stat-item:hover { - border-color: var(--gradient-end); -} - -.stat-number { - font-size: 3rem; - font-weight: 600; - background: linear-gradient(45deg, var(--gradient-start), var(--gradient-end)); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - margin-bottom: 0.5rem; -} - -.stat-label { - color: rgba(255, 255, 255, 0.7); - font-size: 1.1rem; -} - -/* Features Overview */ -#features-overview { - padding: 6rem 2rem; -} - -.content-wrapper { - max-width: 1200px; - margin: 0 auto; -} - -.content-wrapper h2 { - font-size: 2.5rem; - margin-bottom: 3rem; - text-align: center; - color: var(--gradient-end); -} - -.features-showcase { - display: grid; - gap: 4rem; -} - -.feature-highlight { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 4rem; - align-items: center; -} - -.feature-visual { - display: flex; - justify-content: center; - align-items: center; - font-size: 5rem; - color: var(--gradient-end); -} - -.feature-content h3 { - font-size: 2rem; - margin-bottom: 1.5rem; - color: var(--gradient-end); -} - -.feature-content p { - font-size: 1.1rem; - color: rgba(255, 255, 255, 0.9); - margin-bottom: 2rem; - line-height: 1.8; -} - -.feature-list { - list-style: none; -} - -.feature-list li { - margin-bottom: 1rem; - padding-left: 2rem; - position: relative; - color: rgba(255, 255, 255, 0.9); -} - -.feature-list li::before { - content: '•'; - position: absolute; - left: 0; - color: var(--gradient-end); - font-size: 1.5rem; - line-height: 1; -} - -/* Workflow Section */ -#workflow { - padding: 6rem 2rem; - background: rgba(0, 0, 0, 0.2); -} - -.workflow-steps { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 2rem; - margin-top: 4rem; -} - -.step { - text-align: center; - padding: 2rem; - background: rgba(255, 255, 255, 0.05); - border-radius: 12px; - border: 1px solid rgba(255, 255, 255, 0.1); -} - -.step i { - font-size: 3rem; - color: var(--gradient-end); - margin: 1.5rem 0; -} - -.step-number { - font-size: 3rem; - font-weight: 700; - color: var(--gradient-end); - margin-bottom: 1.5rem; -} - -.step h3 { - font-size: 1.5rem; - margin-bottom: 1rem; - color: var(--gradient-end); -} - -.step p { - color: rgba(255, 255, 255, 0.9); -} - -/* Security Section */ -#security { - padding: 6rem 2rem; -} - -.security-grid { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 4rem; - align-items: center; -} - -.security-content h2 { - text-align: left; - margin-bottom: 2rem; -} - -.security-content p { - font-size: 1.1rem; - color: rgba(255, 255, 255, 0.9); - margin-bottom: 2rem; - line-height: 1.8; -} - -.security-features { - list-style: none; -} - -.security-features li { - display: flex; - align-items: center; - gap: 1rem; - margin-bottom: 1.5rem; - color: rgba(255, 255, 255, 0.9); -} - -.security-features i { - font-size: 1.5rem; - color: var(--gradient-end); -} - -.security-visual { - display: flex; - justify-content: center; - align-items: center; - font-size: 8rem; - color: var(--gradient-end); -} - -/* CTA Section */ -#cta { - padding: 6rem 2rem; - background: rgba(0, 0, 0, 0.2); -} - -.cta-container { - text-align: center; - max-width: 800px; - margin: 0 auto; -} - -.cta-container h2 { - font-size: 2.5rem; - margin-bottom: 1.5rem; - color: var(--gradient-end); -} - -.cta-container p { - font-size: 1.2rem; - color: rgba(255, 255, 255, 0.9); - margin-bottom: 2rem; - line-height: 1.8; -} - /* Footer */ .footer-content { text-align: center; @@ -608,24 +397,6 @@ body { .cta-buttons { justify-content: center; } - - .stats-grid { - grid-template-columns: repeat(2, 1fr); - } - - .feature-highlight { - grid-template-columns: 1fr; - gap: 2rem; - } - - .workflow-steps { - grid-template-columns: 1fr; - } - - .security-grid { - grid-template-columns: 1fr; - gap: 2rem; - } } @media screen and (max-width: 768px) { @@ -661,8 +432,4 @@ body { .primary-btn, .secondary-btn { width: 100%; } - - .stats-grid { - grid-template-columns: 1fr; - } } From 25b69dd0a328e48384a1d2294b5b90b9875c2985 Mon Sep 17 00:00:00 2001 From: Piyush Acharya Date: Fri, 21 Feb 2025 08:24:17 +0000 Subject: [PATCH 15/19] working copy --- web/docs/docs.css | 271 ++++++++++++++++++++++++--------------------- web/docs/docs.html | 85 ++++++++++++++ web/docs/docs.js | 154 +++++++++++++++++--------- web/index.html | 30 ++++- web/index.js | 44 +++++--- 5 files changed, 378 insertions(+), 206 deletions(-) diff --git a/web/docs/docs.css b/web/docs/docs.css index 0322bab2..1fbc1021 100644 --- a/web/docs/docs.css +++ b/web/docs/docs.css @@ -1,87 +1,124 @@ +/* Documentation Layout */ .container { - max-width: 1200px; - margin: 6rem auto 2rem; + display: grid; + grid-template-columns: 280px 1fr; + gap: 2rem; + padding-top: 2rem; +} + +/* Sidebar */ +.docs-sidebar { + background: rgba(0, 0, 0, 0.2); + border-radius: 12px; + border: 1px solid rgba(255, 255, 255, 0.1); padding: 2rem; + position: sticky; + top: 6rem; + height: calc(100vh - 8rem); + overflow-y: auto; } -/* Hero Section */ -.hero { - text-align: center; - margin-bottom: 4rem; +.docs-sidebar::-webkit-scrollbar { + width: 6px; } -.hero h1 { - font-size: 3.5rem; - margin-bottom: 1.5rem; - background: linear-gradient(45deg, var(--gradient-start), var(--gradient-end)); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; +.docs-sidebar::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0.1); + border-radius: 3px; } -.hero p { - font-size: 1.2rem; - color: rgba(255, 255, 255, 0.9); - max-width: 800px; - margin: 0 auto; - line-height: 1.8; +.docs-sidebar::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.1); + border-radius: 3px; } -/* Documentation Navigation */ -.docs-nav { - position: fixed; - top: 6rem; - left: 0; - width: 280px; - height: calc(100vh - 6rem); - padding: 2rem; - background: rgba(0, 0, 0, 0.2); - border-right: 1px solid rgba(255, 255, 255, 0.1); - overflow-y: auto; +.docs-sidebar::-webkit-scrollbar-thumb:hover { + background: rgba(255, 255, 255, 0.2); } +/* Navigation */ .nav-section { margin-bottom: 2rem; + padding-bottom: 2rem; + border-bottom: 1px solid rgba(255, 255, 255, 0.1); +} + +.nav-section:last-child { + border-bottom: none; + margin-bottom: 0; + padding-bottom: 0; } .nav-section h3 { color: var(--gradient-end); - font-size: 1.2rem; margin-bottom: 1rem; - padding-bottom: 0.5rem; - border-bottom: 1px solid rgba(255, 255, 255, 0.1); + font-size: 1.2rem; } .nav-links { list-style: none; + margin: 0; + padding: 0; } -.nav-link { - display: block; - padding: 0.5rem 0; +.nav-links li { + margin-bottom: 0.5rem; +} + +.nav-links .nav-link { color: rgba(255, 255, 255, 0.8); text-decoration: none; - font-size: 1rem; + padding: 0.5rem 1rem; + border-radius: 6px; + display: block; transition: all 0.3s ease; } -.nav-link:hover { +.nav-links .nav-link:hover, +.nav-links .nav-link.active { + background: rgba(255, 255, 255, 0.05); color: var(--gradient-end); transform: translateX(5px); } -.nav-link.active { - color: var(--gradient-end); - font-weight: 500; +/* Search */ +.search-container { + margin-bottom: 2rem; } -/* Main Content */ +.search-input { + width: 100%; + padding: 1rem; + background: rgba(0, 0, 0, 0.3); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 8px; + color: white; + font-size: 1rem; + font-family: inherit; +} + +.search-input:focus { + outline: none; + border-color: var(--gradient-start); + box-shadow: 0 0 0 3px rgba(0, 122, 255, 0.2); +} + +/* Content */ .docs-content { - margin-left: 280px; + background: rgba(0, 0, 0, 0.2); + border-radius: 12px; + border: 1px solid rgba(255, 255, 255, 0.1); padding: 2rem; + min-height: calc(100vh - 8rem); } .content-section { margin-bottom: 4rem; + scroll-margin-top: 6rem; +} + +.content-section:last-child { + margin-bottom: 0; } .content-section h2 { @@ -97,60 +134,59 @@ } .content-section p { - color: rgba(255, 255, 255, 0.9); - font-size: 1.1rem; - line-height: 1.8; margin-bottom: 1.5rem; + line-height: 1.8; + color: rgba(255, 255, 255, 0.9); } /* Code Blocks */ .code-block { background: rgba(0, 0, 0, 0.3); border-radius: 8px; - padding: 1.5rem; margin: 1.5rem 0; - overflow-x: auto; -} - -.code-block pre { - margin: 0; - font-family: 'IBM Plex Mono', monospace; - font-size: 0.95rem; - line-height: 1.5; - color: rgba(255, 255, 255, 0.9); + overflow: hidden; } .code-header { + background: rgba(255, 255, 255, 0.05); + padding: 0.75rem 1rem; display: flex; justify-content: space-between; align-items: center; - padding: 0.75rem 1.5rem; - background: rgba(255, 255, 255, 0.05); - border-top-left-radius: 8px; - border-top-right-radius: 8px; border-bottom: 1px solid rgba(255, 255, 255, 0.1); } .code-language { color: var(--gradient-end); font-size: 0.9rem; - font-weight: 500; } .copy-button { - background: transparent; - border: 1px solid rgba(255, 255, 255, 0.2); + background: rgba(255, 255, 255, 0.1); + border: none; color: rgba(255, 255, 255, 0.8); - padding: 0.5rem 1rem; + padding: 0.25rem 0.75rem; border-radius: 4px; - font-size: 0.9rem; cursor: pointer; + font-size: 0.9rem; transition: all 0.3s ease; } .copy-button:hover { - background: rgba(255, 255, 255, 0.1); - border-color: var(--gradient-end); + background: rgba(255, 255, 255, 0.2); +} + +pre { + margin: 0; + padding: 1.5rem; + overflow-x: auto; +} + +code { + font-family: 'IBM Plex Mono', monospace; + font-size: 0.9rem; + line-height: 1.5; + color: rgba(255, 255, 255, 0.9); } /* Tables */ @@ -171,102 +207,81 @@ } .docs-table th { - background: rgba(0, 0, 0, 0.3); + background: rgba(255, 255, 255, 0.05); color: var(--gradient-end); font-weight: 600; } -.docs-table tr:hover { - background: rgba(255, 255, 255, 0.05); -} - -/* Lists */ -.content-section ul, -.content-section ol { - margin: 1.5rem 0; - padding-left: 2rem; - color: rgba(255, 255, 255, 0.9); +.docs-table tr:last-child td { + border-bottom: none; } -.content-section li { - margin-bottom: 0.75rem; - line-height: 1.6; +.docs-table tr:hover td { + background: rgba(255, 255, 255, 0.02); } -/* Notes and Warnings */ +/* Note Blocks */ .note-block { + background: rgba(0, 0, 0, 0.2); + border-radius: 8px; padding: 1.5rem; margin: 1.5rem 0; - border-radius: 8px; - border-left: 4px solid; + border-left: 4px solid var(--gradient-end); } -.note-info { - background: rgba(0, 122, 255, 0.1); - border-left-color: var(--gradient-end); +.note-block h4 { + color: var(--gradient-end); + margin-bottom: 1rem; + font-size: 1.2rem; } -.note-warning { - background: rgba(255, 149, 0, 0.1); - border-left-color: #ff9500; +.note-block.note-warning { + border-left-color: #ffc107; } -.note-block h4 { - color: var(--gradient-end); - margin-bottom: 0.75rem; - font-size: 1.2rem; +.note-block.note-warning h4 { + color: #ffc107; } -/* Search Bar */ -.search-container { - margin-bottom: 2rem; +.note-block ul, +.note-block ol { + margin: 1rem 0; + padding-left: 1.5rem; + color: rgba(255, 255, 255, 0.9); } -.search-input { - width: 100%; - padding: 1rem; - background: rgba(0, 0, 0, 0.3); - border: 1px solid rgba(255, 255, 255, 0.2); - border-radius: 8px; - color: white; - font-size: 1rem; - font-family: inherit; +.note-block li { + margin-bottom: 0.5rem; } -.search-input:focus { - outline: none; - border-color: var(--gradient-start); - box-shadow: 0 0 0 3px rgba(0, 122, 255, 0.2); +/* Search Highlighting */ +mark { + background: rgba(0, 122, 255, 0.3); + color: white; + padding: 0.1rem 0.3rem; + border-radius: 3px; } /* Responsive Design */ @media screen and (max-width: 1024px) { - .docs-nav { - width: 240px; + .container { + grid-template-columns: 1fr; } - .docs-content { - margin-left: 240px; + .docs-sidebar { + position: static; + height: auto; + margin-bottom: 2rem; } -} -@media screen and (max-width: 768px) { - .docs-nav { - display: none; + .content-section { + scroll-margin-top: 2rem; } +} +@media screen and (max-width: 768px) { .docs-content { - margin-left: 0; - padding: 1rem; - } - - .container { - margin: 4rem 1rem 2rem; - padding: 1rem; - } - - .hero h1 { - font-size: 2.5rem; + padding: 1.5rem; } .content-section h2 { diff --git a/web/docs/docs.html b/web/docs/docs.html index dfb6ec93..4ae955a1 100644 --- a/web/docs/docs.html +++ b/web/docs/docs.html @@ -185,3 +185,88 @@

Available Options

+ + + + + + + + + + + + + + + + + + + + + +
OptionDescriptionExample
--amino=XSpecify start amino acid--amino=ser
--min=XMinimum sequence length--min=100
--max=XMaximum sequence length--max=1000
-rReverse sequence analysis-r
+
+ +
+

API Reference

+

Core classes and their functionalities:

+ +
+
+ java + +
+
// Initialize analyzer
+DNAAnalysis analyzer = new DNAAnalysis();
+
+// Analyze sequence
+AnalysisResult result = analyzer.analyze(sequence);
+
+// Get specific metrics
+double gcContent = result.getGCContent();
+List codons = result.getCodons();
+
+ +

Core Classes

+
    +
  • DNAAnalysis - Main analysis class
  • +
  • DNAMutation - Handles sequence mutations
  • +
  • DNADataUploader - Manages file uploads
  • +
+
+ +
+

Contributing

+

We welcome contributions! Here's how to get started:

+ +
    +
  1. Fork the repository
  2. +
  3. Create a feature branch (git checkout -b feature/amazing-feature)
  4. +
  5. Commit your changes (git commit -m 'Add amazing feature')
  6. +
  7. Push to the branch (git push origin feature/amazing-feature)
  8. +
  9. Open a Pull Request
  10. +
+ +
+

Development Setup

+
+
./gradlew clean build
+./gradlew test
+
+
+
+ + + + +
+ +
+ + + + \ No newline at end of file diff --git a/web/docs/docs.js b/web/docs/docs.js index 42fff4af..c1375cbb 100644 --- a/web/docs/docs.js +++ b/web/docs/docs.js @@ -1,77 +1,123 @@ document.addEventListener('DOMContentLoaded', function() { - const searchInput = document.querySelector('.search-input'); - const navLinks = document.querySelectorAll('.nav-link'); - const contentSections = document.querySelectorAll('.content-section'); + // Handle navigation links + const navLinks = document.querySelectorAll('.nav-links .nav-link'); + const sections = document.querySelectorAll('.content-section'); - // Search functionality - searchInput.addEventListener('input', function(e) { - const searchTerm = e.target.value.toLowerCase(); - - // Search through all content sections - contentSections.forEach(section => { - const text = section.textContent.toLowerCase(); - const matches = text.includes(searchTerm); - section.style.display = matches || searchTerm === '' ? 'block' : 'none'; - - // If section is visible, also highlight the corresponding nav link - const id = section.getAttribute('id'); - const navLink = document.querySelector(`.nav-link[href="#${id}"]`); - if (navLink) { - navLink.style.display = matches || searchTerm === '' ? 'block' : 'none'; + function updateActiveLink() { + const scrollPosition = window.scrollY; + + sections.forEach(section => { + const sectionTop = section.offsetTop - 100; + const sectionBottom = sectionTop + section.offsetHeight; + const sectionId = section.getAttribute('id'); + + if (scrollPosition >= sectionTop && scrollPosition < sectionBottom) { + navLinks.forEach(link => { + link.classList.remove('active'); + if (link.getAttribute('href') === `#${sectionId}`) { + link.classList.add('active'); + } + }); } }); + } - // If search is empty, show all sections - if (searchTerm === '') { - contentSections.forEach(section => section.style.display = 'block'); - navLinks.forEach(link => link.style.display = 'block'); - } - }); + window.addEventListener('scroll', updateActiveLink); + updateActiveLink(); - // Smooth scrolling for navigation links + // Smooth scroll for navigation navLinks.forEach(link => { link.addEventListener('click', function(e) { e.preventDefault(); - const targetId = this.getAttribute('href').substring(1); - const targetSection = document.getElementById(targetId); + const targetId = this.getAttribute('href'); + const targetSection = document.querySelector(targetId); if (targetSection) { - // Remove active class from all links - navLinks.forEach(link => link.classList.remove('active')); - // Add active class to clicked link - this.classList.add('active'); - - // Smooth scroll to section - targetSection.scrollIntoView({ - behavior: 'smooth', - block: 'start' + window.scrollTo({ + top: targetSection.offsetTop - 80, + behavior: 'smooth' }); } }); }); - // Highlight current section in navigation based on scroll position - window.addEventListener('scroll', function() { - let currentSection = ''; - - contentSections.forEach(section => { - const sectionTop = section.offsetTop; - const sectionHeight = section.clientHeight; - if (window.pageYOffset >= sectionTop - 100) { - currentSection = section.getAttribute('id'); + // Handle search functionality + const searchInput = document.querySelector('.search-input'); + const contentSections = document.querySelectorAll('.content-section'); + let searchTimeout; + + searchInput.addEventListener('input', function(e) { + clearTimeout(searchTimeout); + searchTimeout = setTimeout(() => { + const searchTerm = e.target.value.toLowerCase(); + + if (searchTerm.length > 2) { + contentSections.forEach(section => { + const text = section.textContent.toLowerCase(); + const match = text.includes(searchTerm); + + if (match) { + section.style.display = 'block'; + // Highlight matches + const regex = new RegExp(searchTerm, 'gi'); + section.innerHTML = section.innerHTML.replace(regex, match => `${match}`); + } else { + section.style.display = 'none'; + } + }); + } else { + // Show all sections if search term is too short + contentSections.forEach(section => { + section.style.display = 'block'; + // Remove highlights + section.innerHTML = section.innerHTML.replace(/(.*?)<\/mark>/g, '$1'); + }); } + }, 300); + }); + + // Handle code copy buttons + const copyButtons = document.querySelectorAll('.copy-button'); + + copyButtons.forEach(button => { + button.addEventListener('click', function() { + const codeBlock = this.closest('.code-block').querySelector('code'); + const text = codeBlock.textContent; + + navigator.clipboard.writeText(text).then(() => { + const originalText = this.textContent; + this.textContent = 'Copied!'; + this.style.background = 'var(--gradient-end)'; + + setTimeout(() => { + this.textContent = originalText; + this.style.background = ''; + }, 2000); + }); }); + }); + + // Handle table of contents highlighting + const tocLinks = document.querySelectorAll('.nav-links .nav-link'); + const observerOptions = { + rootMargin: '-100px 0px -50%', + threshold: 0 + }; - navLinks.forEach(link => { - link.classList.remove('active'); - if (link.getAttribute('href') === `#${currentSection}`) { - link.classList.add('active'); + const observerCallback = (entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + const id = entry.target.getAttribute('id'); + tocLinks.forEach(link => { + link.classList.remove('active'); + if (link.getAttribute('href') === `#${id}`) { + link.classList.add('active'); + } + }); } }); - }); + }; - // Initial highlight of the first nav link - if (navLinks.length > 0) { - navLinks[0].classList.add('active'); - } + const observer = new IntersectionObserver(observerCallback, observerOptions); + sections.forEach(section => observer.observe(section)); }); diff --git a/web/index.html b/web/index.html index c8eadb54..69497d68 100644 --- a/web/index.html +++ b/web/index.html @@ -25,8 +25,14 @@ Server Docs @@ -38,8 +44,14 @@

DNAnalyzer

Revolutionizing DNA analysis using ML-powered on-device computation for everyone.

@@ -156,8 +168,14 @@

Privacy & Security

Ready to Start?

Join thousands of researchers and scientists using DNAnalyzer for their genetic analysis needs.

diff --git a/web/index.js b/web/index.js index dc2463db..804bb929 100644 --- a/web/index.js +++ b/web/index.js @@ -2,34 +2,40 @@ document.addEventListener('DOMContentLoaded', function() { // DNA Helix Animation const dnaHelix = document.querySelector('.dna-helix'); const numBases = 20; - const baseTypes = ['A', 'T', 'C', 'G']; + const basePairs = [ + ['A', 'T'], + ['T', 'A'], + ['G', 'C'], + ['C', 'G'] + ]; // Create base pairs for (let i = 0; i < numBases; i++) { - const baseIndex = Math.floor(Math.random() * baseTypes.length); - const complementaryIndex = baseIndex % 2 === 0 ? baseIndex + 1 : baseIndex - 1; + const pairIndex = Math.floor(Math.random() * basePairs.length); + const [leftBase, rightBase] = basePairs[pairIndex]; - const leftBase = document.createElement('div'); - leftBase.className = 'base left-base'; - leftBase.textContent = baseTypes[baseIndex]; - leftBase.style.animationDelay = `${i * 0.2}s`; + const basePair = document.createElement('div'); + basePair.className = 'base-pair'; + basePair.style.top = `${i * 30}px`; + basePair.style.animationDelay = `${i * 0.2}s`; - const rightBase = document.createElement('div'); - rightBase.className = 'base right-base'; - rightBase.textContent = baseTypes[complementaryIndex]; - rightBase.style.animationDelay = `${i * 0.2}s`; + const leftBaseElem = document.createElement('div'); + leftBaseElem.className = 'base left-base'; + leftBaseElem.textContent = leftBase; + leftBaseElem.style.animationDelay = `${i * 0.2}s`; + + const rightBaseElem = document.createElement('div'); + rightBaseElem.className = 'base right-base'; + rightBaseElem.textContent = rightBase; + rightBaseElem.style.animationDelay = `${i * 0.2}s`; const connector = document.createElement('div'); connector.className = 'base-connector'; connector.style.animationDelay = `${i * 0.2}s`; - const basePair = document.createElement('div'); - basePair.className = 'base-pair'; - basePair.style.top = `${i * 30}px`; - - basePair.appendChild(leftBase); + basePair.appendChild(leftBaseElem); basePair.appendChild(connector); - basePair.appendChild(rightBase); + basePair.appendChild(rightBaseElem); dnaHelix.appendChild(basePair); } @@ -90,7 +96,9 @@ document.addEventListener('DOMContentLoaded', function() { }); }, { threshold: 0.5 }); - observer.observe(statsSection); + if (statsSection) { + observer.observe(statsSection); + } // Smooth scroll for navigation document.querySelectorAll('a[href^="#"]').forEach(anchor => { From f41b818c4df442cb05dcbc817961a6353d034e61 Mon Sep 17 00:00:00 2001 From: Piyush Acharya Date: Fri, 21 Feb 2025 09:36:24 +0000 Subject: [PATCH 16/19] some homepage fixes --- web/about/about.html | 38 +++ web/analyzer/analyzer.html | 38 +++ web/features/features.html | 38 +++ web/index.html | 44 +++- web/index.js | 106 ++++++-- web/server/server.html | 38 +++ web/style.css | 493 ++++++++++++++++++++++++++++++++----- 7 files changed, 710 insertions(+), 85 deletions(-) diff --git a/web/about/about.html b/web/about/about.html index 96be24a8..8d37a650 100644 --- a/web/about/about.html +++ b/web/about/about.html @@ -114,6 +114,44 @@

Get Involved