# Project export: Real Time Hurricane Prediction

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: Cal Hacks 11.0
- Tagline: Empowering Early Detection: Predicting Hurricanes and Weather Disturbances for Safer Communities
- Devpost: https://devpost.com/software/pre-hurricane-alarm
- GitHub: https://github.com/kru2710shna/Pre_Hurricane/
- Team: 3 GitHub contributor(s) — Krushna Thakkar (16 commits), Codingjackking (6 commits), Akshar Gothi (2 commits)

## Devpost submission (written by the team)

### Inspiration

The increasing frequency and intensity of hurricanes and other natural calamities inspired us to build a system that could provide timely and accurate predictions, helping communities prepare and respond more effectively. We wanted to leverage machine learning and real-time data tracking to create a tool that can forecast not just hurricanes but a variety of topological disturbances like cyclones, gale winds, and more.

### What it does

The system predicts and tracks hurricane activities and other weather-related disturbances in real time, using machine learning to analyze data such as wind speed, pressure, and proximity to land. It provides early warnings and alerts, allowing at-risk regions to prepare for potential disasters. The tool also includes bot assistance, which delivers real-time notifications and updates to users.

### How we built it

We used data from NOAA, IBTrACS, and the NCDC Storm Events Database, combined with real-time data from APIs like Google Earth. Machine learning models like Random Forest were used to predict weather disturbances. We integrated the system with Flask for a web-based interface and APIs for real-time updates. The entire model was built with Python, leveraging libraries like pandas, scikit-learn, and geopy for data processing and analysis.

### Challenges we ran into

One of the biggest challenges was dealing with inconsistencies and missing data in historical datasets. Integrating real-time data with older datasets required significant preprocessing. Managing large datasets and ensuring efficient data manipulation without performance bottlenecks was another hurdle. Additionally, handling class imbalances in multi-class prediction proved to be challenging for some machine learning models.

### Accomplishments we're proud of

We successfully built a robust prediction system that can forecast not only hurricanes but a wide range of weather disturbances. Achieving high model accuracy and recall, especially for minority classes, was a significant accomplishment. Integrating real-time data and creating a user-friendly alert system with bot assistance is another feature we’re proud of.

### What we learned

We learned how to efficiently handle and manipulate large, complex datasets, as well as how to tackle class imbalance issues in multi-class prediction. Our team gained valuable experience in integrating machine learning models into real-time systems and ensuring that predictions remain accurate and up-to-date.

### What's next

for Pre-Hurricane Alarm We plan to expand the system’s capabilities to cover more geographic regions and incorporate additional types of environmental data, such as satellite imagery and ocean temperature data. We also aim to enhance the bot assistance feature, making it more interactive and responsive to user needs.

## README (from the GitHub repository)

# Pre-Hurricane Alarm

## Project Description
Developed a machine learning model to predict topological disorder from Northern Atlantic waves, which is essential in detecting and forecasting hurricane activities. Utilizing data from the Google Earth API, the model analyzes key parameters such as wind speed, pressure, and proximity to land. This model is integrated into a real-time alert system, enhancing disaster preparedness for regions at risk of hurricanes. The project showcases advanced pattern recognition and predictive modeling, aiming to improve environmental safety through early detection and alerts.

## Background on Hurricanes
Hurricanes are some of the most devastating natural disasters, causing massive damage to coastal areas around the globe. These powerful storms form over warm ocean waters and are defined by violent winds, heavy rain, and storm surges. The Northern Atlantic region regularly experiences hurricane activity, often leading to the loss of life, damage to property, and disruption of ecosystems.

The increasing frequency and intensity of hurricanes, largely driven by climate change, make them a major global concern. Rising sea temperatures provide more energy for storm formation, resulting in stronger storms. As coastal areas become more vulnerable, millions of people are at risk. Predictive systems and early warning tools are critical in reducing hurricane impact by giving governments and individuals time to prepare and respond effectively.

## Datasets

### 1. [Google Earth Engine - International Best Track Archive for Climate Stewardship (IBTrACS)](https://www.ncei.noaa.gov/products/international-best-track-archive)
IBTrACS provides historical data on the location and intensity of global tropical cyclones, dating back to the 1840s. This dataset includes key information such as wind speed, minimum central pressure, and proximity to land. It is available in 3-hour intervals and is critical for understanding hurricane patterns.

### 2. [NOAA Hurricane Data](https://coast.noaa.gov/hurricanes/)
NOAA's extensive historical hurricane data spans over 150 years, providing a comprehensive look at hurricane tracks, wind speeds, and storm intensities. This dataset is essential for modeling storm behavior and predicting future activities.

### 3. [Kaggle - Hurricanes and Typhoons, 1851-2014](https://www.kaggle.com/datasets/noaa/hurricanes-and-typhoons)
The National Hurricane Center (NHC) conducts post-storm analysis of tropical cyclones in the Atlantic and Pacific Oceans. This dataset includes retrospective storm analysis to improve prediction models, with detailed storm information dating from 1851.

## Real-Life Impact

### Hurricane Katrina (2005)
- Affected Louisiana, Mississippi, and Alabama, causing catastrophic flooding, primarily in New Orleans.
- Resulted in over 1,800 deaths and $125 billion in damages.
  
### Hurricane Maria (2017)
- Devastated Puerto Rico with winds up to 175 mph, leading to the destruction of the power grid and over 3,000 deaths.
  
### Hurricane Harvey (2017)
- Brought unprecedented rainfall and flooding to Texas, with damages exceeding $125 billion.

### Hurricane Sandy (2012)
- Affected the northeastern U.S., causing $70 billion in damages and extensive flooding in New York City.

### Hurricane Dorian (2019)
- Struck the Bahamas as a Category 5 storm, with winds reaching 185 mph, causing widespread destruction and highlighting the vulnerability of small island nations.

## Conclusion
The Pre-Hurricane Alarm system provides a crucial tool for early detection and disaster preparedness. By leveraging advanced machine learning techniques and rich hurricane datasets, this project aims to minimize the catastrophic impact of hurricanes, safeguarding lives and infrastructure.


STEPS: 

=> Open your terminal and clone the repository using:
```bash
git clone <repository_url>
cd <project_directory>
```

=> Create the virtual environment:
```bash
python -m venv venv
```

=> Activate the virtual environment:

Windows:
```bash
venv\Scripts\activate
```

macOS/Linux:
```bash
source venv/bin/activate
```

=> Run the following to install all the required packages:

```bash
pip install -r requirements.txt
```

=> Create a .env file in the project root:

```bash
touch .env
```
=> .env file variables
```bash
GEMINI_API_KEY = {GEMINI API KEY}
OPENWEATHER_API_KEY = {OPENWEATHER API KEY}
GOOGLE_MAPS_API_KEY = {GOOGLE MAPS API KEY}
DB_HOST = {GCP CLOUD PUBLIC IP}
DB_USER = {GCP CLOUD DB USER}
DB_PASSWORD = {GCP CLOUD DATABASE PASSWORD}
DB_NAME = {GCP CLOUD DATABASE NAME}
CLOUD_SQL_CONNECTION_NAME = {GCP CLOUD CONNECTION NAME}
```

=> Run python file

```bash
python app.py
```

Thank you so much! 



## Detected evidence (automated analysis)

Indexed codebase: 7 recognized source files, 53 KB.
- CSS (language) — detected in the code
- Flask (technology) — detected in the code
- HTML (language) — detected in the code
- Python (language) — detected in the code

## Codebase structure (from repository index)

### Files (15 of 15)

```
.gcloudignore
.gitignore
app.py
app.yaml
Models/best_random_forest_model4.pkl
Models/preprocessor4.pkl
package.json
Procfile
README.md
requirements.txt
static/css/styles.css
templates/index.html
Untitled14-2.ipynb
utils/email_templates.py
utils/gemini.py
```

### Dependencies

- package.json: @vapi-ai/web@^2.1.4
- requirements.txt: Flask@==3.0.3, Flask-Mail, geopy@==2.3.0, google-generativeai@==0.2.0, gunicorn@==21.2.0, joblib@==1.4.0, mysql-connector-python@==8.1.0, numpy@==1.26.0, pandas@==2.1.2, python-dotenv@==1.0.0, requests@==2.31.0

### Recent commits (newest first)

- Code Updated
- Files and Folder Restructure
- UI Updated
- Merge branch 'main' of https://github.com/kru2710shna/Pre_Hurricane
- Message Feature Added
- Merge branch 'main' of https://github.com/kru2710shna/Pre_Hurricane
- model
- Update README.md
- Update README.md
- Update README.md
- Merge branch 'main' of https://github.com/kru2710shna/Pre_Hurricane
- Yaml file added
- Documentation
- Model Working
- UI Updated
- UI Updated
- PkL file and Model added
- Pikl file added
- Model Working
- Merge branch 'main' of https://github.com/kru2710shna/Pre_Hurricane

## Key source files (fetched from GitHub, selected and truncated for size)

### package.json

```
{
  "dependencies": {
    "@vapi-ai/web": "^2.1.4"
  }
}

```

### requirements.txt

```
Flask==3.0.3
python-dotenv==1.0.0
google-generativeai==0.2.0
requests==2.31.0
numpy==1.26.0
joblib==1.4.0
geopy==2.3.0
pandas==2.1.2
mysql-connector-python==8.1.0
gunicorn==21.2.0  
Flask-Mail
```

### app.py

```python
from flask import Flask, render_template, request, redirect, jsonify
from dotenv import load_dotenv
import google.generativeai as genai
import requests
from datetime import datetime, timedelta
import os
import numpy as np
import joblib
from geopy.distance import geodesic
import pandas as pd
import mysql.connector
from flask_mail import Mail, Message
from utils.email_templates import subscription_thank_you_message


   
app = Flask(__name__)
# Load environment variables from .env
load_dotenv()
    
    
model = joblib.load("Models/best_random_forest_model4.pkl")
preprocessor = joblib.load("Models/preprocessor4.pkl")
# Configure Flask-Mail
app.config["MAIL_SERVER"] = os.getenv("MAIL_SERVER")
app.config["MAIL_PORT"] = os.getenv("MAIL_PORT")
app.config["MAIL_USE_TLS"] = os.getenv("MAIL_USE_TLS") == "True"
app.config["MAIL_USERNAME"] = os.getenv("MAIL_USERNAME")
app.config["MAIL_PASSWORD"] = os.getenv("MAIL_PASSWORD")
mail = Mail(app)



GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
openweather_api_key = os.getenv("openweather_api_key")
GOOGLE_MAPS_API_KEY = os.getenv("GOOGLE_MAPS_API_KEY")


# Check if GEMINI_API_KEY is set
if GEMINI_API_KEY:
    genai.configure(api_key=GEMINI_API_KEY)
else:
    raise ValueError("GEMINI_API_KEY environment variable not set.")


# Route for the index page
@app.route("/")
def index():
    # Handle missing API keys for weather and maps gracefully
    if not openweather_api_key or not GOOGLE_MAPS_API_KEY:
        return "API keys missing. Please check your .env file.", 500
    return render_template(
        "index.html",
        openweather_api_key=openweather_api_key,
        google_maps_api_key=GOOGLE_MAPS_API_KEY,
    )


# Route for Gemini chatbot to give hurricane tips
@app.route("/gemini_chatbot", methods=["POST"])
def gemini_chatbot():
    data = request.get_json()
    question = data.get("question", "").strip()

    if not question:
        return jsonify({"response": "Please ask a valid question."}), 400

    try:
        model = genai.GenerativeModel("gemini-1.5-flash")
        response = model.generate_content(
            question,
            generation_config=genai.types.GenerationConfig(
                candidate_count=1,
                stop_sequences=["."],
                max_output_tokens=100,
                temperature=1.0,
            ),
        )

        # Directly access candidates in the response
        candidates = response.candidates if hasattr(response, "candidates") else []

        if candidates and len(candidates) > 0:
            chatbot_response = candidates[0].content.parts[0].text
        else:
            chatbot_response = "Sorry, I couldn't find an answer."

        return jsonify({"response": chatbot_response})

    except Exception as e:
        print(f"Error with Gemini API: {e}")
        return jsonify(
            {"response": "Sorry, something went wrong with the chatbot."}
        ), 500
    



@app.route("/predict_status", methods=["POST"])
def predict_status():
    label_mapping = {
        0: "Disturbance (0-20 mph) - A weak, disorganized system with minimal wind, often the early stage of a developing storm.",
        1: "Extratropical Cyclone (30-60 mph) - Storms formed outside the tropics, often bringing heavy rain and strong winds.",
        2: "Hurricane (74+ mph) - A powerful tropical storm with sustained winds above 74 mph, causing significant damage and heavy rainfall.",
        3: "Gale Winds (39-54 mph) - Strong winds that can cause minor damage, but are not part of a tropical storm or hurricane.",
        4: "Subtropical Depression (0-38 mph) - A weaker subtropical system with lower wind speeds, a mix of tropical and extratropical characteristics.",
        5: "Subtropical Storm (39-73 mph) - A storm with both tropical and extratropical characteristics, typically less organized than a hurricane.",
        6: "Tropical Depression (0-38 mph) - A tropical system with winds below 39 mph, often a precursor to a tropical storm.",
        7: "Tropical Storm (39-73 mph) - A well-developed tropical system with winds between 39 and 73 mph, less intense than a hurricane.",
        8: "Clear Sky (0 mph) - Calm weather with no active storm or disturbance.",
        9: "Tropical Wave (10-30 mph) - A tropical disturbance with low wind speeds, which could develop into a stronger system.",
    }
    try:
        # Create the encoded number to label mapping
        # Get the JSON data from the request
        data = request.get_json()
        print("Received request data:", data)

        # Extract the input values from the JSON payload
        lat = data.get("latitude")
        lng = data.get("longitude")
        wind_speed = data.get("windSpeed")
        pressure = data.get("pressure")
        distance_to_land = data.get("distanceToLand")
        day_night = data.get("day_night")

        # Convert to floats and handle potential missing values
        wind_speed = float(wind_speed)
        pressure = float(pressure)
        distance_to_land = float(distance_to_land)
        lat = float(lat)
        lng = float(lng)
        wind_pressure_ratio = float(wind_speed / pressure)
        day_night = float(day_night)

        # Prepare the input data as a pandas DataFrame
        input_data_df = pd.DataFrame(
            {
                "USA_WIND": [wind_speed],
                "USA_PRES": [pressure],
                "DIST2LAND": [distance_to_land],
                "USA_LAT": [lat],
                "USA_LON": [lng],
                "wind_pressure_ratio": [wind_pressure_ratio],
                "Day_Night_encoded": [day_night],
            }
        )

        print(f"Input DataFrame:\n{input_data_df}")

        # Preprocess the input data using the loaded preprocessor
        processed_input_data = preprocessor.transform(input_data_df)
        print(f"Processed input data:\n{processed_input_data}")

        # Perform prediction using the loaded model
        prediction = model.predict(processed_input_data)

        predicted
[truncated — 4758 more characters]
```

### app.yaml

```yaml
runtime: python39  # Python 3.9
entrypoint: gunicorn -b :$PORT app:app

env_variables:
  OPENWEATHER_API_KEY: your_openweather_api_key
  GEMINI_API_KEY: your_gemini_api_key
  GOOGLE_MAPS_API_KEY: your_google_maps_api_key

handlers:
  - url: /.*
    script: auto

```

### utils/email_templates.py

```python
# email_templates.py

def subscription_thank_you_message(name):
    """
    Generate a personalized thank-you message for new subscribers.

    Parameters:
        name (str): The subscriber's name.

    Returns:
        str: A formatted thank-you message for the subscriber.
    """
    message = f"""
    Hello {name},

    Thank you for subscribing to Hurricane Prediction Alerts!

    You will receive real-time notifications and updates on hurricane activities 
    and related weather warnings based on your location and data from reliable 
    sources, including OpenWeather and Google Earth Engine.

    Here's what you can expect:
    - Timely alerts on hurricane patterns in your area.
    - Safety tips and recommendations during hurricane season.
    - Personalized assistance for disaster preparedness.

    Stay informed and stay safe!

    Best Regards,
    Hurricane Prediction Alert Team
    """
    return message

```

### utils/gemini.py

```python
# Here is a Python script `gemini.py` that can encapsulate all functionalities related to Google Gemini interactions.
# It will handle generating responses based on weather data, hurricane data, simulations, and any other 
# task Google Gemini is responsible for.

import google.generativeai as genai
import random
import os

# Configuration: Load the API key for Gemini from environment variables.
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")

# If the key isn't set, raise an error
if GEMINI_API_KEY:
    genai.configure(api_key=GEMINI_API_KEY)
else:
    raise ValueError("GEMINI_API_KEY environment variable not set.")

# Function to configure and ask Gemini questions related to hurricane simulation, weather analysis, and safety tips.
def ask_gemini(question, weather_data, hurricane_data):
    """
    Takes in user question, real-time weather data, and NOAA hurricane data
    to generate appropriate responses using Google Gemini.

    :param question: User query to ask Gemini.
    :param weather_data: Real-time weather data from OpenWeatherMap API.
    :param hurricane_data: Historical hurricane data from NOAA API.
    :return: Response from Google Gemini API.
    """
    prompts = generate_prompts(question, weather_data, hurricane_data)
    prompt = random.choice(prompts)

    try:
        model = genai.GenerativeModel("gemini-1.5-flash")
        response = model.generate_content(
            prompt,
            generation_config=genai.types.GenerationConfig(
                candidate_count=1,
                stop_sequences=["."],
                max_output_tokens=100,
                temperature=1.0
            )
        )

        # Directly access candidates in the response
        candidates = response.candidates if hasattr(response, 'candidates') else []
        if candidates and len(candidates) > 0:
            chatbot_response = candidates[0].content.parts[0].text
        else:
            chatbot_response = "Sorry, I couldn't find an answer."

        return chatbot_response

    except Exception as e:
        print(f"Error with Gemini API: {e}")
        return "Sorry, something went wrong with the chatbot."

# Function to create different prompt types for Gemini
def generate_prompts(question, weather_data, hurricane_data):
    """
    Generate multiple prompts for various scenarios like hurricane simulation,
    real-time narration, global context insight, and safety tips.

    :param question: User's question
    :param weather_data: Real-time weather data
    :param hurricane_data: Historical hurricane data from NOAA
    :return: List of prompts
    """
    prompts = []

    # # Add simulation prompt
    # prompts.append(f"Simulate a scenario where the wind speed reaches {weather_data['wind_speed']} m/s. What should we expect?")

    # # Add real-time narration prompt
    # prompts.append(f"Narrate the current weather condition. The temperature is {weather_data['temp']}°C, wind speed is {weather_data['wind_speed']} m/s, and the weather is described as {weather_data['description']}.")

    # # Add global context insight prompt
    # prompts.append(f"Compare the current hurricane's wind speed of {weather_data['wind_speed']} m/s to past hurricanes globally.")

    # # Add personalized safety recommendation based on the question
    # prompts.append(f"Provide safety tips based on the current weather, with wind speed {weather_data['wind_speed']} m/s and humidity {weather_data['humidity']}%. The user asked: {question}.")
    
    # General Hurricane Information Prompts
    prompts.extend([
        "What is a hurricane, and how does it form?",
        "What are the different categories of hurricanes, and how are they measured?",
        "What is the difference between a hurricane, a typhoon, and a cyclone?",
        "What are the deadliest hurricanes in history?",
        "How do hurricanes get their names?",
        "What is the structure of a hurricane, and how does the eye of the storm work?",
        "How long does a typical hurricane last?",
        "How are hurricanes monitored and tracked in real-time?",
        "How do scientists predict the path of a hurricane?",
        "What tools and technologies are used to predict hurricanes?"
    ])

    # Real-Time Hurricane Scenarios
    prompts.append(f"Simulate the impact of a Category 5 hurricane hitting a coastal city.")
    prompts.append(f"How does the current weather condition with wind speed of {weather_data['wind_speed']} m/s compare to previous hurricanes?")
    prompts.append(f"What safety measures should people take if wind speeds reach {weather_data['wind_speed']} m/s in this area?")
    prompts.append(f"Given the current hurricane path, what cities are at risk, and how should they prepare?")
    prompts.append(f"What impact will the current humidity of {weather_data['humidity']}% have on the strength of the hurricane?")

    # Safety and Evacuation Prompts
    prompts.append("What are the recommended safety measures during a hurricane?")
    prompts.append("How do I prepare for a hurricane when evacuation isn’t an option?")
    prompts.append(f"Based on the wind speed of {weather_data['wind_speed']} m/s, what is the best time to evacuate?")
    prompts.append("Recommend the safest evacuation routes based on the predicted hurricane path and real-time traffic conditions.")
    prompts.append("What should be included in an emergency kit for a hurricane evacuation?")
    prompts.append("What should people avoid doing during a hurricane?")

    # Hurricane Physics and Calculations
    prompts.append("What mathematical models are used to predict hurricane trajectories?")
    prompts.append(f"Given wind speeds of {weather_data['wind_speed']} m/s, calculate the possible damage in a coastal area.")
    prompts.append(f"How do pressure changes, such as a drop to {weather_data['pressure']} hPa, affect the intensity of a hurricane?")
    prompts.append(f"Given current wind speeds and pressure data, estimate the potential category of th
[truncated — 4602 more characters]
```

### static/css/styles.css

```css
/* styles.css */

/* Set the size of the map */
#map {
    height: 500px;
    width: 100%;
}

/* Center the title at the top */
h1 {
    text-align: center;
    margin-top: 20px;
}

/* Style for making the containers side by side */
.content-container {
    display: flex;
    justify-content: space-between;
    max-width: 1200px;
    margin: 0 auto;
}

.chatbot-container, .info-container {
    flex: 1;
    margin: 10px;
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 10px;
    box-shadow: 0px 0px 5px rgba(0,0,0,0.2);
    background-color: #f9f9f9;
}

/* Chatbot box inside the chatbot-container */
#chatbot {
    height: 300px;
    overflow-y: auto;
    background-color: #fff;
    border: 1px solid #bbb;
    border-radius: 8px;
    padding: 10px;
}

/* Style for the Vapi button inside the chatbot container */
#vapiButtonContainer {
    display: flex;
    justify-content: center;  /* Center horizontally */
    align-items: flex-end;    /* Align to the bottom of the container */
    width: 100%;
    height: 50px;             /* Same height as the button */
    position: relative;
    margin-bottom: 10px;      /* Margin to give space from the bottom */
}

/* Adjust the .vapi-btn to be centered at the bottom of the chatbot-container */
.vapi-btn {
    position: relative;
    margin-right: -25px;                /* Horizontally center it */
    width: 50px;              
    height: 50px;
    left: 70%;
    bottom: 40px;         
}

/*
Microphone styles
.microphone {
    margin-top: 10px;
    width: 50px;
    height: 50px;
    background-color: #ff4081;
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
    margin-left: 50%;
    transform: translateX(-50%);  /* Center the microphone horizontally */
/* } */

/* Active microphone style */
/* .microphone.active { */
    /* background-color: #32CD32;  Bright green to indicate active listening */
    /* box-shadow: 0px 0px 10px 2px rgba(50, 205, 50, 0.8);  Glowing effect */
/* } */

/* Vibration animation */
/* .microphone.vibrating { */
    /* animation: vibrate 0.3s linear infinite; */
/* } */

/* @keyframes vibrate {
    0% { transform: translate(1px, 1px) rotate(0deg); }
    10% { transform: translate(-1px, -2px) rotate(-1deg); }
    20% { transform: translate(-3px, 0px) rotate(1deg); }
    30% { transform: translate(3px, 2px) rotate(0deg); }
    40% { transform: translate(1px, -1px) rotate(1deg); }
    50% { transform: translate(-1px, 2px) rotate(-1deg); }
    60% { transform: translate(-3px, 1px) rotate(0deg); }
    70% { transform: translate(3px, 1px) rotate(-1deg); }
    80% { transform: translate(-1px, -1px) rotate(1deg); }
    90% { transform: translate(1px, 2px) rotate(0deg); }
    100% { transform: translate(1px, -2px) rotate(-1deg); }
} */
```

### templates/index.html

```html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Real Time Hurricane Prediction</title>
        <!-- Bootstrap CSS -->
        <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
    
        <style>
            /* Inline custom CSS */
            #map {
                height: 400px;
                width: 100%;
            }
            #chatbot {
                height: 300px;
                border: 1px solid #ddd;
                padding: 10px;
                overflow-y: scroll;
                background-color: #f9f9f9;
            }
            body {
                width: 100%;
            }
            .description {
                text-align: center;
                margin-top: 10px;
                font-size: 1.1rem;
                color: #555;
            }
            .center-btn {
                display: flex;
                justify-content: center;
                margin-top: 20px;
            }
        </style>
    </head>
    

<body class="container">


    <!-- Navbar -->
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <a class="navbar-brand" href="#">Hurricane Tracker</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarNav">
            <ul class="navbar-nav ml-auto">
                <li class="nav-item">
                    <a class="nav-link" href="#" data-toggle="modal" data-target="#aboutModal">About</a>
                </li>
            </ul>
        </div>
    </nav>

    

    <!-- Step 1: Title and Map -->
    <h1 class="text-center mt-4">Real Time Hurricane Prediction</h1>
    
    <!-- Map Section -->
    <div id="map" class="mt-4"></div>

   

    <!-- Step 2: Button and Description -->
    <div class="center-btn">
        <button id="location-btn" class="btn btn-secondary mt-3">Get Connected</button>
    </div>

    <div class="description">Point on the MAP to fetch the information.</div>

    <!-- Weather Information Section -->
    <div id="weather" class="p-3 mt-4"></div>



    <!-- Chatbot Section -->
    <div class="row mt-4">
        <div class="col-md-12">
            <button id="ask-btn" class="btn btn-primary mt-2">Ask Gemini</button>
            <input type="text" id="question" class="form-control mt-2" placeholder="Trained on Hurricane Data">
            <div id="chatbot"></div>

        </div>
    </div>


    <div class="container mt-3">
        <button id="copy-info-btn" class="btn btn-info" style="display: none;">Copy Information</button> 
    </div>

    <!-- Weather Modal -->
    <div class="modal fade" id="weatherModal" tabindex="-1" role="dialog" aria-labelledby="weatherModalLabel" aria-hidden="true">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="weatherModalLabel">Weather Information</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body" id="modal-body">
                    <div id="weatherstatus"></div>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">No</button>
                    <button type="button" class="btn btn-primary" id="yes-btn">Yes</button>
                </div>
            </div>
        </div>
    </div>

    <!-- Notification Form Modal -->
    <div class="modal fade" id="notificationModal" tabindex="-1" role="dialog" aria-labelledby="notificationModalLabel" aria-hidden="true">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="notificationModalLabel">Subscribe for Notifications</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    <form id="subscribe-form" method="POST">
                        <div class="form-group">
                            <label for="name">Name:</label>
                            <input type="text" class="form-control" id="name" name="name" required>
                        </div>
                        <div class="form-group">
                            <label for="email">Email:</label>
                            <input type="email" class="form-control" id="email" name="email" required>
                        </div>
                        <div class="form-group">
                            <label for="phone">Phone Number:</label>
                            <input type="tel" class="form-control" id="phone" name="phone" required>
                        </div>
                        <button type="submit" class="btn btn-success">Submit</button>
                    </form>
                </div>
            </div>
        </div>
    </div>




    <!-- Weather Input Form -->
    <form class="row mt-4" id="hurricane-form">
        <div class="col-md-4">
            <input type="text" id="wind_speed" class="form-control" placeholder="Wind Speed (km/h)" required pattern="\d+(\.\d{1,2})?" title="Please enter a valid number for wind speed.">
        </div>
        <div class="col-md-4">
            <input type="text" id="pressure" class="form-control" pla
[truncated — 18223 more characters]
```