diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/README.md b/README.md index 2773c22..a36934d 100644 --- a/README.md +++ b/README.md @@ -1,146 +1,16 @@ -# DevStakes (Axios Web Wing) +# React + Vite +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. -**[Register Here →](https://forms.gle/yrQVjSU84b2Wk47Q8)** +Currently, two official plugins are available: ---- +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs) +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) -## Event Overview +## React Compiler -| Detail | Info | -|---|---| -| Duration | 3.5 days (84 hours) | -| Team Size | 4-5 members (at least 1 girl mandatory) | -| Primary Focus | React (Frontend) | -| Bonus Points | Up to +20 for backend, ML integration, or strong system design | +The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation). ---- +## Expanding the ESLint configuration -## Timeline - -### Day-0 - -| Time | Activity | -|---|---| -| 12:00 PM | Ideas revealed — teams choosing from the given set can start coding immediately | -| 12:00 PM – 6:00 PM | Custom Idea Submission Window | -| 10:00 PM | Idea approval results announced — event officially starts for all teams | - -### Day-1, Day-2, Day-3 — Coding Period - -- Coding stops at the **end of Day-3** -- The **top 5 teams** may be called for an **offline pitch** to explain their codebase and demonstrate understanding -- Top 3 winners are decided from the offline pitch - ---- - -## Scoring Criteria - -| Criterion | Description | Points | -|---|---|---| -| Core Functionality | Does it actually work end-to-end? | 30 | -| UI / UX Quality | Visual polish, responsiveness, usability | 20 | -| Performance | Lighthouse score — speed, accessibility, SEO | 15 | -| Clean Code & Structure | Readable, modular, no spaghetti | 15 | -| Git Practices | Commits, branching, PRs with descriptions | 10 | -| Deployed & Live Link | Vercel / Netlify, accessible URL submitted | 5 | -| Idea Bonus *(custom only)* | Originality & quality of self-proposed idea | 0–5 | -| **Total** | | **100** | - -> **+20 bonus points** available for implementing a backend, integrating ML models, or demonstrating strong system design. - ---- - -## Ideas - -You may choose **one** of the ideas below, or propose your **own custom idea** (subject to approval, eligible for up to 5 bonus points). - ---- - -### 1. Real-Time "Auction/Bidding" Portal - -A high-adrenaline platform where unique items are put up for timed, live auctions, requiring instant feedback and a seamless user experience. - -- **Frontend Challenge:** Handling race conditions and state synchronization. When two users bid at the exact same millisecond, the frontend must handle "Optimistic Updates" (showing the user's bid immediately for a snappy UX) while simultaneously validating against the server clock to handle rejections gracefully. -- **Practical Use:** E-commerce, charity fundraisers, or digital asset trading. - ---- - -### 2. Smart "Expense Splitter" - -A comprehensive financial utility to manage group expenses, track shared bills, and "settle up" debts among friends or roommates. - -- **Frontend Challenge:** Building intuitive, dynamic forms for complex splits (e.g., "A paid 70%, B and C split the rest, but D owes for drinks"). Managing complex localized state without lagging the UI. -- **Algorithmic Complexity:** The "Simplifying Debts" algorithm (often solved using graph theory/flow networks). If A owes B $10 and B owes C $10, the system should suggest A pays C $10 directly. Handling math precision and multi-currency conversions locally in the browser. -- **Practical Use:** Essential for university students living in hostels, shared flats, or group travel. - ---- - -### 3. Dynamic Team Builder - -An intelligent matching platform where users input their skills, and the system automatically forms balanced, highly functional teams based on specific event constraints. - -- **Frontend Challenge:** Creating a rich, interactive drag-and-drop interface (similar to a Kanban board) where organizers can visually tweak the auto-generated teams. Visualizing skill distributions using charts (e.g., radar charts for team stats). -- **Algorithmic Complexity:** Constraint satisfaction. If 80% of users are frontend developers and 20% are designers, the system must still create fair teams without perfect combinations, distributing the rare skills evenly. -- **Practical Use:** Automating team formation for hackathons, college projects, or corporate workshops. - ---- - -### 4. Smart "Exam Preparation Planner" - -An adaptive study schedule generator that takes a student's syllabus, available hours, and target grades to map out a day-by-day learning journey. - -- **Frontend Challenge:** Building interactive calendars, Gantt charts, or timeline views from scratch in React. Handling complex date/time logic and allowing users to drag, drop, and resize study blocks. -- **Algorithmic Complexity:** Priority-based time allocation. What happens when time is insufficient for full syllabus coverage? The system must dynamically recalculate and prioritize high-weightage topics over minor ones. -- **Practical Use:** Helping students manage time efficiently and reduce pre-exam anxiety. - ---- - -### 5. Visual Node-Based Learning Roadmap Builder - -A platform where educators or seniors can create interactive, branching "tech trees" (like in video games) for learning new skills (e.g., "How to learn Web Dev"). - -- **Frontend Challenge:** Heavy manipulation of the DOM and Canvas/SVG. Using libraries like React Flow to let users drag nodes, connect them with animated edges, zoom, pan, and handle complex graph state management in the browser. -- **Practical Use:** Replacing static PDF roadmaps with interactive, trackable learning journeys for college clubs or online courses. - ---- - -### 6. Offline-First Markdown Note-Taking App - -A distraction-free, highly performant note-taking application designed for developers and students, capable of working entirely offline. - -- **Frontend Challenge:** Building a rich text editor that parses Markdown to HTML in real-time. Implementing an "Offline-First" architecture using IndexedDB/Service Workers in React, ensuring the user can close the tab, lose internet, and never lose a keystroke. -- **Practical Use:** A lightweight Notion/Obsidian alternative tailored for rapid class notes or code snippets. - ---- - -### 7. Custom Idea *(Bonus: up to 5 points)* - -Have a unique idea not listed above? Propose it! - -- Each team can submit **at most 2 custom ideas** during the Day-0 submission window (12PM–6PM). -- Approved ideas earn an **idea bonus of 0–5 points** based on originality and quality. -- Approval results are announced at **10PM on Day-0**. - ---- - -## Rules - -1. Teams must have **4 to 5 members**, with **at least 1 girl**. -2. The primary tech stack must be **React based** (frontend-first). -3. Each team must choose **one idea** — either from the given set or a custom approved idea. -4. Teams submitting a custom idea can submit a **maximum of 2 ideas** for review. -5. Teams selecting from the given set may **begin coding at 12PM on Day-0**. -6. Custom idea teams may begin coding (for custom idea) only after **approval at 10PM on Day-0**. -7. All code must be pushed to a **Git repository** with clear commit history, branching, and PR descriptions. -8. A **deployed live link** (Vercel/Netlify) must be submitted for full scoring. -9. Coding officially **stops at the end of Day-3**. -10. Top 5 teams may be invited for an **offline pitch** to verify codebase understanding. - ---- - -## Registration - -**[Fill the Registration Form →](https://forms.gle/yrQVjSU84b2Wk47Q8)** - ---- +If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project. diff --git a/SUB.md b/SUB.md deleted file mode 100644 index a00b344..0000000 --- a/SUB.md +++ /dev/null @@ -1,127 +0,0 @@ -# Submission Guide — DevStakes - -Follow the steps below carefully to submit your project. Incorrect submissions may not be considered for judging. - ---- - -## Step-by-Step Submission Process - -### 1. Fork this Repository - -Click the **Fork** button at the top-right of this repository to create a copy under your GitHub account. - -### 2. Clone your Fork - -```bash -git clone https://github.com//devstakes.git -cd devstakes -``` - -### 3. Create a Folder for your Team - -Inside the repo root, create a folder named exactly after your team name. Use lowercase letters and hyphens — no spaces. - -``` -devstakes/ -└── teams/ - └── your-team-name/ - ├── README.md ← required - └── ... (your project files) -``` - -> All your project files must live inside `teams/your-team-name/`. Do not place files outside this folder. - -### 4. Add a README inside your Team Folder - -Your team folder **must** contain a `README.md` with the following details: - -```markdown -# Project Name - -## Team Name -Your team name here - -## Team Members -- Name 1 (GitHub: @username) -- Name 2 (GitHub: @username) -- Name 3 (GitHub: @username) -- Name 4 (GitHub: @username) -- Name 5 (GitHub: @username) — optional - -## Idea Chosen -(Name of the idea — e.g., "Smart Expense Splitter" or "Custom: ") - -## Problem Statement -Brief description of the problem you are solving. - -## Tech Stack -- React -- (any other libraries/frameworks/tools used) - -## Implementation Details -Describe your approach — architecture decisions, key features, algorithms used, state management strategy, etc. - -## How to Run Locally -Steps to clone and run the project on a local machine. - -## Live Demo -Link to deployed app (Vercel / Netlify / etc.) - -## Screenshots / Demo -(Include a demo video or screenshots showcasing your app's features) -``` - -### 5. Commit and Push to your Fork - -```bash -git add teams/your-team-name/ -git commit -m "feat: add submission for " -git push origin main -``` - -### 6. Open a Pull Request - -1. Go to your forked repository on GitHub. -2. Click **"Contribute" → "Open pull request"**. -3. Set the **base repository** to the original `devstakes` repo and **base branch** to `main`. -4. Use the following PR title format: - - ``` - [Submission] - ``` - - Example: - ``` - [Submission] Team Nebula — Smart Expense Splitter - ``` - -5. In the PR description, include: - - Team name and members - - Idea chosen - - Live demo link - - Any notes for judges - -6. Submit the pull request. - ---- - -## Checklist Before Submitting - -- [ ] Forked the repo and created `teams/your-team-name/` folder -- [ ] All project code is inside your team folder -- [ ] `README.md` inside the team folder is complete with all required sections -- [ ] Live deployment link is working and included -- [ ] PR title follows the `[Submission] Team Name — Idea Name` format -- [ ] PR description includes team members and demo link -- [ ] Git history has meaningful commit messages - ---- - -## Important Notes - -- Only **one PR per team** is allowed. If you need to update your submission, push additional commits to the same branch — do not open a new PR. -- The PR must be opened **before the end of Day-3** to be considered. -- PRs that do not follow the folder structure or are missing the team README will be disqualified from judging. - ---- - diff --git a/backend/__pycache__/main.cpython-314.pyc b/backend/__pycache__/main.cpython-314.pyc new file mode 100644 index 0000000..e0674f8 Binary files /dev/null and b/backend/__pycache__/main.cpython-314.pyc differ diff --git a/backend/main.py b/backend/main.py new file mode 100644 index 0000000..db38890 --- /dev/null +++ b/backend/main.py @@ -0,0 +1,101 @@ +""" +Farm2City ML Backend — FastAPI entry point. +Start with: uvicorn main:app --reload +""" + +from fastapi import FastAPI, Query, HTTPException +from fastapi.middleware.cors import CORSMiddleware +from pydantic import BaseModel + +from ml.model import ml_models # singleton loaded once at import time + +app = FastAPI( + title="Farm2City ML API", + description="ML-powered price prediction, crop recommendation, and chatbot", + version="2.0.0", +) + +# ── CORS (allow all origins for local dev) ───────────────────────────────────── +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + + +# ── Models ───────────────────────────────────────────────────────────────────── +class ChatRequest(BaseModel): + query: str + + +# ── Health check ─────────────────────────────────────────────────────────────── +@app.get("/", tags=["Health"]) +def root(): + return { + "status": "ok", + "message": "Farm2City ML API is running 🌾", + "models_loaded": ml_models.ready, + } + + +# ── Price Prediction ─────────────────────────────────────────────────────────── +@app.get("/predict-price", tags=["ML"]) +def predict_price( + category: str = Query(..., description="Crop type, e.g. tomatoes, wheat"), + month: int = Query(..., ge=1, le=12, description="Month number 1-12"), + rainfall: float = Query(..., description="Expected rainfall in mm"), +): + """Predict market price per kg for a given crop, month and rainfall.""" + predicted = ml_models.predict_price(category, month, rainfall) + + if predicted is None: + # Return a sensible default so UI never breaks + known = list(ml_models.le_crop.classes_) if ml_models.ready else [] + return { + "predicted_price": 50.0, + "currency": "₹", + "unit": "kg", + "note": f"Unknown category '{category}'. Known: {known}. Showing default price.", + } + + return { + "predicted_price": predicted, + "currency": "₹", + "unit": "kg", + "category": category, + "month": month, + "rainfall": rainfall, + } + + +# ── Crop Recommendation ──────────────────────────────────────────────────────── +@app.get("/recommend-crop", tags=["ML"]) +def recommend_crop( + soil: str = Query(..., description="Soil type, e.g. loamy, black, red"), + season: str = Query(..., description="Season: summer | winter | monsoon"), +): + """Recommend the best crop to grow for a given soil type and season.""" + recommendation = ml_models.recommend_crop(soil, season) + return { + "recommended_crop": recommendation, + "soil_type": soil, + "season": season, + } + + +# ── Chatbot ──────────────────────────────────────────────────────────────────── +@app.post("/chat", tags=["Chatbot"]) +def chat(req: ChatRequest): + """ML-enhanced chatbot: keyword intent classification + model-backed replies.""" + if not req.query.strip(): + raise HTTPException(status_code=400, detail="Query cannot be empty.") + reply = ml_models.get_chat_response(req.query) + return {"reply": reply} + + +# ── Dev runner ───────────────────────────────────────────────────────────────── +if __name__ == "__main__": + import uvicorn + uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True) diff --git a/backend/ml/__init__.py b/backend/ml/__init__.py new file mode 100644 index 0000000..712beea --- /dev/null +++ b/backend/ml/__init__.py @@ -0,0 +1 @@ +# ML package for Farm2City diff --git a/backend/ml/__pycache__/__init__.cpython-314.pyc b/backend/ml/__pycache__/__init__.cpython-314.pyc new file mode 100644 index 0000000..929397e Binary files /dev/null and b/backend/ml/__pycache__/__init__.cpython-314.pyc differ diff --git a/backend/ml/__pycache__/model.cpython-314.pyc b/backend/ml/__pycache__/model.cpython-314.pyc new file mode 100644 index 0000000..797651d Binary files /dev/null and b/backend/ml/__pycache__/model.cpython-314.pyc differ diff --git a/backend/ml/__pycache__/train.cpython-314.pyc b/backend/ml/__pycache__/train.cpython-314.pyc new file mode 100644 index 0000000..7e56947 Binary files /dev/null and b/backend/ml/__pycache__/train.cpython-314.pyc differ diff --git a/backend/ml/__pycache__/utils.cpython-314.pyc b/backend/ml/__pycache__/utils.cpython-314.pyc new file mode 100644 index 0000000..c86cdf9 Binary files /dev/null and b/backend/ml/__pycache__/utils.cpython-314.pyc differ diff --git a/backend/ml/model.py b/backend/ml/model.py new file mode 100644 index 0000000..6a16132 --- /dev/null +++ b/backend/ml/model.py @@ -0,0 +1,148 @@ +""" +Singleton ML model wrapper loaded once at FastAPI startup. +""" + +import os +import joblib +import numpy as np + +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +MODELS_DIR = os.path.join(BASE_DIR, "models") + +# ── Intent keyword sets ──────────────────────────────────────────────────────── +_PRICE_WORDS = {"price", "cost", "rate", "how much", "expensive", "cheap", "worth"} +_REC_WORDS = {"grow", "suggest", "recommend", "crop", "soil", "season", "plant", "sow"} +_HELP_WORDS = {"help", "support", "navigate", "how to", "where", "what is", "can i"} +_TIPS_WORDS = {"tip", "advice", "trick", "fertilizer", "water", "irrigation", "pest", "disease"} + +# ── Model singleton ──────────────────────────────────────────────────────────── +class MLModels: + def __init__(self): + self.price_model = None + self.le_crop = None + self.rec_model = None + self.le_soil = None + self.le_season = None + self.le_rec = None + self._load() + + # ── Loader ──────────────────────────────────────────────────────────────── + def _load(self): + try: + self.price_model = joblib.load(os.path.join(MODELS_DIR, "price_model.joblib")) + self.le_crop = joblib.load(os.path.join(MODELS_DIR, "le_crop.joblib")) + self.rec_model = joblib.load(os.path.join(MODELS_DIR, "rec_model.joblib")) + self.le_soil = joblib.load(os.path.join(MODELS_DIR, "le_soil.joblib")) + self.le_season = joblib.load(os.path.join(MODELS_DIR, "le_season.joblib")) + self.le_rec = joblib.load(os.path.join(MODELS_DIR, "le_rec.joblib")) + print("✓ All ML models loaded successfully.") + except FileNotFoundError as e: + print(f"⚠ Model file missing: {e} — run `python -m ml.train` first.") + except Exception as e: + print(f"⚠ Could not load models: {e}") + + @property + def ready(self) -> bool: + return all([self.price_model, self.le_crop, + self.rec_model, self.le_soil, + self.le_season, self.le_rec]) + + # ── Price prediction ────────────────────────────────────────────────────── + def predict_price(self, category: str, month: int, rainfall: float) -> float | None: + if not self.ready: + return None + cat = category.lower().strip() + if cat not in self.le_crop.classes_: + # Unknown crop — return average-ish fallback + return None + crop_enc = int(self.le_crop.transform([cat])[0]) + X = np.array([[crop_enc, month, rainfall]]) # plain ndarray + prediction = self.price_model.predict(X)[0] + return round(float(prediction), 2) + + # ── Crop recommendation ─────────────────────────────────────────────────── + def recommend_crop(self, soil: str, season: str) -> str: + if not self.ready: + return "Millets" + soil_l = soil.lower().strip() + season_l = season.lower().strip() + + if soil_l not in self.le_soil.classes_: + return "Millets" + if season_l not in self.le_season.classes_: + return "Millets" + + soil_enc = int(self.le_soil.transform([soil_l])[0]) + season_enc = int(self.le_season.transform([season_l])[0]) + X = np.array([[soil_enc, season_enc]]) + rec_enc = int(self.rec_model.predict(X)[0]) + return str(self.le_rec.inverse_transform([rec_enc])[0]) + + # ── Chatbot intent response ─────────────────────────────────────────────── + def get_chat_response(self, query: str) -> str: + q = query.lower() + + # Check for crop+soil recommendation intent first (most specific) + if any(w in q for w in _REC_WORDS): + found_soil = next((s for s in self.le_soil.classes_ if s in q), None) if self.ready else None + found_season = next((s for s in self.le_season.classes_ if s in q), None) if self.ready else None + + if found_soil and found_season: + crop = self.recommend_crop(found_soil, found_season) + return ( + f"🌱 Based on our ML model, I recommend growing **{crop}** " + f"for {found_soil.title()} soil during {found_season.title()}. " + f"It's predicted to give the best yield and market demand!" + ) + return ( + "🌾 I can recommend crops! Tell me your soil type " + "(loamy, clay, sandy, alluvial, black, red, laterite) and " + "season (summer, winter, monsoon). " + "Example: *'What should I grow in black soil during monsoon?'*" + ) + + elif any(w in q for w in _PRICE_WORDS): + knowncrops = list(self.le_crop.classes_) if self.ready else ["tomatoes", "wheat", "mangoes"] + return ( + f"💰 Our AI models predict prices based on crop type, month and rainfall. " + f"Currently supported crops: {', '.join(knowncrops)}. " + f"Head to your **Dashboard → Add Product** and hit **AI Suggest** to get the predicted price!" + ) + + elif any(w in q for w in _TIPS_WORDS): + return ( + "🌿 Farming Tips: \n" + "• Water crops early morning to reduce evaporation.\n" + "• Rotate crops to maintain soil health.\n" + "• Use organic fertilizers to improve long-term yields.\n" + "• Monitor pests weekly and act early for best results." + ) + + elif any(w in q for w in _HELP_WORDS): + return ( + "🤖 I'm AgriBot, your AI farming assistant! Here's what I can do:\n" + "• **Price Predictions** — ask 'What is the price of tomatoes?'\n" + "• **Crop Recommendations** — ask 'What should I grow in loamy soil this summer?'\n" + "• **Farming Tips** — ask 'Any tips for irrigation?'\n" + "• **Platform Help** — navigate the Dashboard to add products & view AI insights." + ) + + elif any(w in q for w in {"farm2city", "platform", "marketplace", "app", "site"}): + return ( + "🏪 Farm2City connects farmers directly with city buyers, removing middlemen. " + "Farmers get fair prices; buyers get fresh produce. " + "Use the Dashboard to list your products with AI-suggested prices!" + ) + + else: + return ( + "I'm not quite sure about that. Try asking me:\n" + "• 'What should I grow in black soil in summer?'\n" + "• 'What is the price of wheat?'\n" + "• 'Give me farming tips'\n" + "• 'Help me use the platform'" + ) + + +# Global singleton — loaded once when FastAPI starts +ml_models = MLModels() diff --git a/backend/ml/models/le_crop.joblib b/backend/ml/models/le_crop.joblib new file mode 100644 index 0000000..a1e6f44 Binary files /dev/null and b/backend/ml/models/le_crop.joblib differ diff --git a/backend/ml/models/le_rec.joblib b/backend/ml/models/le_rec.joblib new file mode 100644 index 0000000..62a7515 Binary files /dev/null and b/backend/ml/models/le_rec.joblib differ diff --git a/backend/ml/models/le_season.joblib b/backend/ml/models/le_season.joblib new file mode 100644 index 0000000..ad7efae Binary files /dev/null and b/backend/ml/models/le_season.joblib differ diff --git a/backend/ml/models/le_soil.joblib b/backend/ml/models/le_soil.joblib new file mode 100644 index 0000000..1762323 Binary files /dev/null and b/backend/ml/models/le_soil.joblib differ diff --git a/backend/ml/models/price_model.joblib b/backend/ml/models/price_model.joblib new file mode 100644 index 0000000..e8e7995 Binary files /dev/null and b/backend/ml/models/price_model.joblib differ diff --git a/backend/ml/models/rec_model.joblib b/backend/ml/models/rec_model.joblib new file mode 100644 index 0000000..1ba0f5f Binary files /dev/null and b/backend/ml/models/rec_model.joblib differ diff --git a/backend/ml/price_data.csv b/backend/ml/price_data.csv new file mode 100644 index 0000000..c6568a7 --- /dev/null +++ b/backend/ml/price_data.csv @@ -0,0 +1,1001 @@ +category,month,rainfall,predicted_price +vegetable,4,287.67857660247904,51.88392883012395 +potatoes,8,199.66462104925915,26.48323105246296 +vegetable,10,88.99863008405066,50.94993150420253 +potatoes,11,266.5440364437338,25.827201822186687 +corn,8,227.01814444901137,27.85090722245057 +mangoes,5,292.4774630404986,103.12387315202493 +corn,6,50.19469146025358,15.009734573012679 +corn,5,204.37037740692912,22.718518870346458 +apples,6,51.76657630492935,95.08832881524647 +tomatoes,1,181.1936650645973,31.559683253229863 +vegetable,10,61.66641580340386,49.58332079017019 +corn,3,145.61549781679068,19.780774890839535 +corn,9,61.61260317999943,19.580630158999973 +potatoes,7,92.63103092182288,21.131551546091146 +vegetable,2,287.2213843133333,51.86106921566667 +corn,2,146.35412563497903,19.81770628174895 +apples,5,107.72345640553725,97.88617282027687 +corn,12,80.5095587111947,16.525477935559735 +wheat,8,58.5971302788046,43.42985651394023 +mangoes,1,114.69499540000423,118.2347497700002 +corn,2,156.28896862281118,20.31444843114056 +mangoes,10,191.92508195499786,146.0962540977499 +wheat,2,243.78320584027864,44.68916029201393 +apples,10,273.7068376069122,126.1853418803456 +mangoes,8,192.61099360134986,146.1305496800675 +corn,9,290.2930060873373,31.014650304366864 +wheat,2,184.92303309726995,41.746151654863496 +apples,9,120.23362742184518,118.51168137109227 +corn,9,124.06837642602059,22.703418821301028 +wheat,1,53.90910168529848,35.19545508426492 +tomatoes,8,148.72037954389242,35.93601897719462 +vegetable,11,99.71060102220129,42.48553005111006 +potatoes,3,242.81758667148642,24.640879333574322 +wheat,10,139.61643213606814,47.48082160680341 +tomatoes,12,265.7758564688984,35.78879282344492 +corn,2,73.85252912260283,16.192626456130142 +vegetable,7,217.21031316590182,57.36051565829509 +wheat,3,197.82444692693178,42.39122234634659 +mangoes,11,190.31085646192528,122.01554282309627 +potatoes,5,292.92802384727594,27.146401192363797 +potatoes,1,230.4323802912183,24.021619014560915 +vegetable,7,60.108397384607834,49.505419869230394 +vegetable,10,56.3547816860238,49.31773908430119 +wheat,3,57.857296421683564,35.39286482108418 +vegetable,1,128.58899526908166,43.92944976345408 +corn,5,112.32305728721873,18.116152864360938 +wheat,11,100.76530618369235,37.53826530918462 +wheat,7,122.43786322844201,46.6218931614221 +mangoes,12,282.42441308564327,126.62122065428217 +wheat,9,76.37356495756765,44.31867824787838 +corn,12,104.6101093042084,17.73050546521042 +corn,11,131.08625525131848,19.054312762565925 +vegetable,12,139.07445951924373,44.45372297596219 +mangoes,1,118.03306234615883,118.40165311730794 +potatoes,9,254.50369148062327,29.225184574031164 +tomatoes,3,51.738032632797676,40.08690163163988 +potatoes,9,171.2074928397458,25.06037464198729 +tomatoes,3,117.35308344963038,43.36765417248152 +vegetable,11,130.80073300518882,44.04003665025944 +tomatoes,4,140.90740059482349,44.54537002974117 +tomatoes,10,290.6118237355278,43.03059118677639 +mangoes,7,174.31212647309636,145.2156063236548 +tomatoes,5,121.2101235943669,43.560506179718345 +tomatoes,11,202.39108349497423,32.619554174748714 +apples,12,62.86968781249734,85.64348439062486 +wheat,1,208.58783617534095,42.92939180876705 +mangoes,2,182.7336458292841,121.63668229146421 +apples,6,110.5138178778751,98.02569089389375 +corn,7,240.4049038321794,28.52024519160897 +potatoes,1,232.05408715296488,24.102704357648243 +wheat,4,295.8557852237107,47.29278926118553 +mangoes,11,254.10796830484597,125.2053984152423 +tomatoes,9,130.19501624293395,35.0097508121467 +mangoes,3,197.72323579706045,98.38616178985302 +potatoes,4,54.14695723196404,15.207347861598201 +potatoes,3,137.16649682293234,19.35832484114662 +vegetable,4,285.130816122401,51.75654080612005 +vegetable,2,259.427526476832,50.471376323841596 +potatoes,12,233.80402981019304,24.19020149050965 +apples,7,185.36199345689147,121.76809967284457 +apples,3,107.13750544932492,97.85687527246624 +apples,9,179.15897281775358,121.45794864088768 +tomatoes,2,299.0634249394811,37.45317124697405 +mangoes,12,189.5733634017744,121.97866817008872 +potatoes,7,134.75744776217516,23.23787238810876 +potatoes,3,231.48891971755984,24.074445985877993 +potatoes,4,271.77160606627933,26.088580303313968 +tomatoes,8,262.7321121918782,41.63660560959391 +tomatoes,8,246.33516277848588,40.81675813892429 +corn,3,143.07069164043577,19.653534582021788 +tomatoes,3,293.41595918882933,52.170797959441465 +apples,2,171.40343839655665,91.07017191982783 +potatoes,9,93.98131316933635,21.199065658466818 +corn,1,173.47342879585867,21.173671439792933 +corn,8,212.40822476180367,27.120411238090185 +vegetable,3,214.40322307508583,48.22016115375429 +tomatoes,12,177.20351920969,31.3601759604845 +mangoes,7,112.61545465139604,142.1307727325698 +mangoes,6,294.72321456875227,103.23616072843761 +potatoes,6,276.5246969296385,26.326234846481924 +potatoes,2,137.51960192366892,19.375980096183447 +tomatoes,12,217.23101491577492,33.36155074578875 +tomatoes,5,107.54631706038882,42.87731585301944 +potatoes,4,56.07899160786346,15.303949580393173 +tomatoes,1,298.63762769933527,37.431881384966765 +mangoes,5,270.87350556656475,102.04367527832824 +corn,9,288.2679617559883,30.913398087799415 +wheat,1,188.19124170887247,41.909562085443625 +vegetable,3,295.08289592901144,52.254144796450575 +corn,5,97.72775778758651,17.386387889379325 +tomatoes,3,92.37318667152311,42.118659333576154 +tomatoes,10,284.03869354019525,42.70193467700976 +apples,3,192.51529252234124,102.12576462611706 +apples,6,139.66169532404098,99.48308476620205 +vegetable,11,123.82264710473468,43.69113235523673 +apples,1,262.16744873116863,95.60837243655843 +tomatoes,11,227.22774922752964,33.86138746137648 +vegetable,10,252.3402888696284,59.11701444348142 +potatoes,2,266.7680796450259,25.838403982251297 +wheat,12,177.83559971523445,41.39177998576172 +tomatoes,4,249.5737947416938,49.97868973708469 +tomatoes,8,225.49171931442584,39.77458596572129 +mangoes,12,271.65428723766496,126.08271436188325 +vegetable,12,194.71622387688967,47.235811193844484 +vegetable,6,132.038166868683,44.10190834343415 +apples,6,197.7083151422527,102.38541575711264 +mangoes,1,59.337047187303604,115.46685235936518 +mangoes,6,184.27060679916386,97.7135303399582 +wheat,1,256.96725094689714,45.348362547344855 +corn,12,291.31295759769245,27.065647879884622 +vegetable,4,260.5057687529953,50.52528843764976 +corn,3,209.35747537455163,22.967873768727582 +corn,2,179.07508707529882,21.453754353764943 +mangoes,3,248.79654869217592,100.9398274346088 +vegetable,3,159.74285517640902,45.487142758820454 +vegetable,10,56.33768585386438,49.31688429269322 +wheat,7,157.07861873502694,48.35393093675135 +corn,5,64.5483988771109,15.727419943855544 +apples,1,160.5880574327761,90.52940287163881 +mangoes,6,228.6489806750156,99.93244903375079 +wheat,5,209.5676484608376,42.97838242304188 +wheat,7,214.2778321250417,51.21389160625208 +wheat,6,232.50982914045463,44.12549145702273 +potatoes,12,191.50930262351906,22.075465131175953 +potatoes,5,80.04116195141054,16.502058097570526 +wheat,12,61.50066050543819,35.57503302527191 +tomatoes,4,93.83256747233463,42.19162837361673 +apples,10,172.9039687792081,121.1451984389604 +vegetable,4,93.3004674775038,42.16502337387519 +mangoes,5,149.62618359934336,95.98130917996717 +apples,6,208.77341271691094,102.93867063584554 +apples,4,143.6531536566178,99.6826576828309 +apples,3,175.7840646450219,101.2892032322511 +tomatoes,8,214.67340790473625,39.233670395236814 +corn,8,285.97290114018926,30.798645057009463 +apples,1,266.79973338875095,95.83998666943755 +potatoes,4,193.86854446896973,22.193427223448488 +apples,3,210.82205461058828,103.04110273052942 +tomatoes,3,255.15986893598884,50.257993446799446 +corn,3,255.10671094281702,25.255335547140852 +apples,11,98.94778369732411,87.44738918486621 +wheat,12,75.19450034435667,36.25972501721783 +apples,3,204.5634710844732,102.72817355422366 +vegetable,1,213.93065884518555,48.196532942259275 +wheat,10,220.40341724319742,51.52017086215987 +mangoes,2,115.17363205897578,118.25868160294878 +vegetable,4,223.22258967298484,48.66112948364924 +apples,11,269.36800338176323,95.96840016908816 +corn,9,250.87023259621213,29.043511629810606 +tomatoes,4,94.35988594493071,42.217994297246534 +tomatoes,8,251.708684816816,41.0854342408408 +tomatoes,3,153.1544192278566,45.15772096139283 +apples,1,244.1032401854992,94.70516200927496 +vegetable,5,109.64921494758505,42.98246074737925 +vegetable,7,238.6357185211706,58.43178592605853 +tomatoes,1,183.58186838264086,31.679093419132045 +corn,9,130.01240025765293,23.000620012882646 +potatoes,3,147.30041968354078,19.86502098417704 +corn,9,261.78578602389746,29.589289301194874 +tomatoes,7,289.20022128161406,42.9600110640807 +vegetable,4,193.35947203082154,47.16797360154108 +vegetable,5,72.92603681462028,41.14630184073101 +corn,9,188.4257630864502,25.92128815432251 +wheat,4,286.54863572042257,46.82743178602113 +tomatoes,7,72.80152576217259,32.14007628810863 +apples,10,64.38969000416107,115.71948450020805 +vegetable,10,160.38262534334424,54.51913126716721 +vegetable,11,226.45787096967365,48.822893548483684 +vegetable,12,222.00750254375976,48.60037512718799 +apples,12,266.7171763277103,95.83585881638551 +mangoes,7,156.52286876173528,144.32614343808677 +apples,9,255.46501482258904,125.27325074112946 +apples,2,70.33719516047495,86.01685975802374 +wheat,6,296.6598946252939,47.33299473126469 +wheat,1,270.0899921596042,46.00449960798021 +tomatoes,7,296.50026595571774,43.32501329778589 +corn,4,144.06489638272893,19.703244819136447 +vegetable,3,244.2867289818592,49.71433644909296 +mangoes,7,156.05550231174408,144.3027751155872 +apples,3,77.79937057653784,96.3899685288269 +potatoes,2,167.16516049853158,20.858258024926577 +apples,4,79.70447906701799,96.4852239533509 +wheat,9,236.0529142358245,52.30264571179122 +potatoes,12,290.54313711863546,27.02715685593177 +vegetable,12,121.42802157046518,43.57140107852326 +tomatoes,6,159.083957901639,45.45419789508195 +apples,12,294.4751671885677,97.22375835942839 +wheat,5,60.85019582454319,35.54250979122716 +wheat,11,279.7789288196649,46.48894644098324 +corn,3,223.8527807766619,23.692639038833093 +tomatoes,2,91.55385797731323,27.07769289886566 +tomatoes,1,206.88952002101587,32.84447600105079 +mangoes,3,275.28950262274725,102.26447513113736 +tomatoes,11,120.24079739805758,28.51203986990288 +mangoes,12,76.6890164839711,116.33445082419856 +wheat,8,92.41997597389138,45.12099879869457 +corn,10,147.06709599746804,23.8533547998734 +corn,2,116.48448124105974,18.324224062052988 +wheat,9,114.98746571356567,46.24937328567828 +potatoes,6,58.078987777412614,15.403949388870629 +tomatoes,1,152.80168021804656,30.140084010902328 +wheat,12,117.73941062878247,38.386970531439125 +wheat,3,255.63431073079224,45.281715536539615 +apples,3,231.42987709708999,104.0714938548545 +vegetable,9,154.56075907265472,54.228037953632736 +mangoes,2,187.8969681360175,121.89484840680088 +wheat,7,152.81377914634226,48.14068895731711 +mangoes,1,170.09252046658867,121.00462602332944 +vegetable,1,144.18474248448518,44.70923712422426 +apples,9,292.4785994536508,127.12392997268255 +potatoes,1,259.58217617778445,25.479108808889222 +apples,9,153.7048755844163,120.18524377922081 +tomatoes,5,64.09387416273178,40.70469370813659 +mangoes,12,253.2252522825194,125.16126261412597 +vegetable,5,299.15920926847633,52.45796046342382 +wheat,7,242.24685379512763,52.61234268975638 +wheat,10,262.4118476693529,53.620592383467645 +tomatoes,5,162.6360338275234,45.63180169137617 +mangoes,1,288.5127568146806,126.92563784073403 +wheat,4,107.16070137586568,37.858035068793285 +tomatoes,8,204.53206011447395,38.726603005723696 +corn,8,55.54618550757541,19.27730927537877 +apples,2,169.05267419725354,90.95263370986268 +potatoes,11,126.94430994276236,18.84721549713812 +tomatoes,6,291.99344135995574,52.09967206799779 +mangoes,11,150.87071655309927,120.04353582765496 +vegetable,7,238.78431391840476,58.43921569592024 +wheat,2,251.26116687984046,45.063058343992026 +vegetable,6,204.315928024323,47.71579640121615 +apples,6,202.0219623854713,102.60109811927356 +apples,11,72.75052276283257,86.13752613814162 +apples,4,186.86157672477788,101.84307883623889 +tomatoes,8,277.6178196008183,42.38089098004092 +mangoes,7,180.9005690037528,145.54502845018763 +tomatoes,5,249.1179439184693,49.95589719592347 +apples,8,260.52285375467744,125.52614268773387 +tomatoes,12,66.55899446296647,25.827949723148322 +wheat,2,205.20142110552283,42.76007105527614 +apples,11,194.9124836179346,92.24562418089673 +potatoes,3,184.31585417851753,21.715792708925875 +vegetable,7,196.19152648728843,56.30957632436442 +potatoes,6,224.41689342423294,23.720844671211648 +corn,8,224.12536655676973,27.706268327838487 +tomatoes,3,268.5794012136043,50.928970060680214 +potatoes,2,200.48384888524006,22.524192444262003 +potatoes,3,255.4476592111123,25.272382960555614 +apples,12,136.9048036206709,89.34524018103355 +mangoes,5,187.17882730185215,97.8589413650926 +wheat,9,138.99787106799653,47.449893553399825 +mangoes,2,82.18709957491097,116.60935497874554 +apples,11,59.828034960274735,85.49140174801374 +tomatoes,9,221.94617927402075,39.59730896370104 +mangoes,11,280.2181001329533,126.51090500664766 +wheat,1,119.21941203680093,38.460970601840046 +tomatoes,8,237.0649225959146,40.35324612979573 +wheat,4,102.33733083417758,37.61686654170888 +vegetable,8,171.13074629775534,55.05653731488777 +apples,12,142.2284098924431,89.61142049462215 +apples,10,59.170800722649474,115.45854003613248 +potatoes,7,221.79137635083276,27.58956881754164 +vegetable,11,183.0283713163289,46.65141856581644 +wheat,2,161.85309170586365,40.59265458529318 +potatoes,3,110.61762590868241,18.03088129543412 +tomatoes,7,144.32104077615566,35.71605203880778 +apples,7,130.51979139579458,119.02598956978973 +vegetable,6,131.87433804447866,44.09371690222393 +corn,9,272.6318201849737,30.131591009248687 +corn,9,219.7755797861224,27.48877898930612 +potatoes,9,174.61054973226433,25.230527486613216 +vegetable,4,184.27663545463693,46.713831772731844 +apples,8,196.63385866518976,122.33169293325949 +corn,3,144.69315648782234,19.734657824391117 +wheat,6,274.9118492862531,46.24559246431265 +apples,11,139.02418147446156,89.45120907372308 +wheat,6,201.4437048392218,42.57218524196109 +tomatoes,5,75.44561815510093,41.27228090775505 +mangoes,6,111.48943209612703,94.07447160480635 +corn,11,71.97190613503597,16.098595306751797 +mangoes,8,274.1913561566063,150.20956780783033 +vegetable,3,181.12784739256367,46.556392369628185 +wheat,4,299.3138836920986,47.46569418460493 +mangoes,2,193.999604451415,122.19998022257074 +potatoes,4,51.325001599401354,15.066250079970068 +mangoes,1,172.6871948146961,121.13435974073481 +mangoes,3,255.21536828833814,101.2607684144169 +apples,11,192.90317236747495,92.14515861837374 +potatoes,12,101.26939003736477,17.563469501868237 +apples,6,227.73811970918706,103.88690598545935 +corn,1,234.06179592462203,24.2030897962311 +corn,1,202.65501061040814,22.632750530520408 +mangoes,5,176.52598908983674,97.32629945449183 +vegetable,4,130.16054803987856,44.00802740199393 +potatoes,1,142.30762037747402,19.615381018873702 +apples,5,65.84374261819194,95.7921871309096 +corn,2,130.58846124368074,19.029423062184037 +apples,4,113.66016369094096,98.18300818454705 +wheat,9,240.05696497242164,52.502848248621085 +potatoes,8,201.52547026395965,26.576273513197982 +potatoes,1,262.68186500411366,25.634093250205684 +corn,12,152.12957323397922,20.10647866169896 +wheat,8,297.73236911434765,55.38661845571738 +apples,12,144.8071462409501,89.74035731204751 +tomatoes,8,230.3991376878193,40.019956884390965 +corn,8,256.985221794373,29.34926108971865 +wheat,12,90.91398571642613,37.04569928582131 +wheat,5,253.64368005784553,45.18218400289228 +potatoes,10,276.966532615629,30.34832663078145 +tomatoes,10,148.11127685565884,35.90556384278294 +vegetable,8,144.23610735622688,53.711805367811344 +potatoes,6,184.94526547865826,21.747263273932912 +vegetable,1,108.05317378670432,42.90265868933522 +tomatoes,7,182.9643699220435,37.648218496102174 +wheat,8,107.25634773119909,45.86281738655995 +vegetable,3,157.88203578411066,45.394101789205536 +potatoes,7,232.63728420232536,28.13186421011627 +apples,4,248.506297317574,104.9253148658787 +wheat,1,183.36527299408039,41.668263649704016 +vegetable,11,247.14930280613268,49.85746514030664 +mangoes,9,127.93051694888706,142.89652584744437 +wheat,11,235.98657314316924,44.29932865715846 +mangoes,4,192.47242121782912,98.12362106089145 +apples,5,269.19140919043735,105.95957045952187 +tomatoes,6,255.31432616800322,50.26571630840016 +vegetable,4,164.2500548204196,45.71250274102098 +corn,8,175.57208686563254,25.27860434328163 +wheat,4,230.56314209826658,44.028157104913326 +apples,11,210.28690822132432,93.01434541106622 +potatoes,4,185.68111083689905,21.784055541844953 +potatoes,11,136.42399837597986,19.321199918798992 +potatoes,10,135.63106429463585,23.281553214731794 +mangoes,8,155.89921560512073,144.29496078025605 +apples,11,88.33785077902004,86.916892538951 +wheat,8,176.4721697211165,49.323608486055825 +tomatoes,1,54.52754595521013,25.226377297760507 +corn,11,283.0295706209031,26.651478531045154 +corn,4,247.52115928102168,24.876057964051085 +wheat,8,212.84180274706154,51.14209013735308 +tomatoes,12,143.6088424301055,29.680442121505276 +tomatoes,6,69.33026637219682,40.96651331860984 +mangoes,8,260.10990799510574,149.5054953997553 +potatoes,7,80.70269546143345,20.535134773071672 +wheat,5,91.38012759182244,37.06900637959112 +corn,6,259.372697250623,25.46863486253115 +tomatoes,6,179.70951428151804,46.4854757140759 +vegetable,5,144.8264245963872,44.74132122981936 +wheat,9,101.39495209390937,45.569747604695465 +tomatoes,5,200.93038293253474,47.546519146626736 +potatoes,4,184.3489007344807,21.717445036724037 +potatoes,6,136.5864985914903,19.329324929574515 +apples,11,234.3753120274371,94.21876560137186 +tomatoes,11,58.21166756085959,25.41058337804298 +potatoes,3,112.05661068928798,18.1028305344644 +tomatoes,7,91.37832935699345,33.068916467849675 +wheat,8,127.86829278318935,46.89341463915947 +wheat,11,208.0660719798826,42.90330359899413 +corn,2,215.88434300417765,23.294217150208883 +vegetable,1,290.2675793673638,52.01337896836819 +tomatoes,4,153.65603093175594,45.1828015465878 +corn,8,175.54875258281064,25.277437629140532 +tomatoes,7,156.69722633418735,36.334861316709365 +potatoes,1,59.13741696202372,15.456870848101186 +mangoes,8,196.86340105851858,146.34317005292593 +tomatoes,3,163.3222086870069,45.666110434350344 +apples,6,160.19068673455703,100.50953433672785 +apples,6,241.33907026656016,104.566953513328 +corn,1,133.59070282762053,19.179535141381027 +vegetable,7,238.3115551868627,58.41557775934314 +apples,10,274.3576024547211,126.21788012273605 +apples,12,250.18744287153027,95.00937214357651 +vegetable,12,259.94721486414267,50.49736074320713 +vegetable,8,56.773998125870875,49.33869990629354 +vegetable,3,107.76869914701786,42.888434957350896 +potatoes,8,76.02714549614346,20.301357274807174 +vegetable,5,94.6361655135834,42.23180827567917 +tomatoes,12,109.54569526168163,27.977284763084082 +apples,3,110.79304774986352,98.03965238749318 +mangoes,8,251.7125372406465,149.0856268620323 +corn,4,217.02128414266153,23.351064207133078 +wheat,7,274.08395463027995,54.204197731514 +vegetable,10,71.37713271361702,50.06885663568085 +vegetable,5,56.63305096845493,40.331652548422745 +wheat,3,195.76039024242306,42.28801951212115 +corn,2,273.1679277692437,26.158396388462187 +vegetable,5,135.454337924469,44.27271689622345 +apples,2,140.76480304877262,89.53824015243863 +vegetable,12,257.6636266413124,50.38318133206562 +wheat,6,243.45863080033507,44.672931540016755 +tomatoes,2,265.2670049936804,35.763350249684024 +potatoes,4,293.63681629971745,27.181840814985872 +corn,8,78.55948148009921,20.42797407400496 +mangoes,8,296.34182806043367,151.3170914030217 +vegetable,1,171.19459178758655,46.05972958937933 +tomatoes,9,185.40855366521674,37.770427683260834 +wheat,9,114.47192135830058,46.223596067915025 +mangoes,6,258.7325591998248,101.43662795999124 +corn,10,181.42254557567145,25.57112727878357 +wheat,2,118.07683162984223,38.40384158149211 +potatoes,6,278.5747016401248,26.428735082006238 +wheat,10,194.1291188785634,50.20645594392817 +mangoes,2,188.54450062894836,121.92722503144742 +tomatoes,6,257.4354509268004,50.37177254634002 +vegetable,5,52.74895716462012,40.137447858231006 +wheat,11,275.00466046202627,46.250233023101316 +mangoes,11,199.35327554257708,122.46766377712885 +corn,9,173.56846253456786,25.178423126728394 +apples,1,154.69263122301828,90.23463156115092 +corn,10,155.50901488767184,24.27545074438359 +apples,12,289.6567943283051,96.98283971641526 +tomatoes,3,72.58424014440197,41.1292120072201 +potatoes,10,67.0624263385229,19.853121316926146 +potatoes,8,159.29834908931088,24.464917454465542 +corn,1,230.3832152804764,24.01916076402382 +potatoes,6,169.0126005497749,20.950630027488746 +vegetable,8,284.2074348311895,60.71037174155948 +wheat,8,103.7350946476892,45.68675473238446 +corn,4,90.50346947289616,17.025173473644806 +corn,11,261.60196232863933,25.580098116431966 +potatoes,11,133.5609727042402,19.17804863521201 +apples,2,76.64956328344294,86.33247816417214 +tomatoes,8,232.04718905090084,40.102359452545045 +tomatoes,11,199.57151456703866,32.478575728351935 +tomatoes,7,68.98335259240552,31.949167629620277 +apples,5,50.584847656444566,95.02924238282223 +potatoes,6,197.5576667172718,22.37788333586359 +potatoes,5,72.89551833165854,16.144775916582926 +potatoes,1,84.20465772974035,16.710232886487017 +apples,9,161.50144323948894,120.57507216197445 +vegetable,12,185.47523684458955,46.773761842229476 +potatoes,8,209.73734633356545,26.98686731667827 +tomatoes,7,231.02583231828464,40.05129161591423 +mangoes,8,112.41700221479648,142.12085011073984 +tomatoes,12,105.30236045490055,27.76511802274503 +apples,9,286.0148349216533,126.80074174608266 +vegetable,10,197.06593924248276,56.35329696212414 +tomatoes,7,188.9516453592949,37.94758226796475 +mangoes,10,128.2137141263969,142.91068570631984 +vegetable,5,232.7559178645704,49.13779589322852 +potatoes,8,292.7645612913419,31.138228064567095 +vegetable,2,236.2661370300551,49.31330685150275 +corn,7,163.78592125903901,24.68929606295195 +potatoes,10,211.13666265645554,27.056833132822778 +mangoes,8,107.50220932192576,141.8751104660963 +corn,2,271.24958913082025,26.062479456541013 +potatoes,8,160.2580404370404,24.51290202185202 +vegetable,12,193.10693985836642,47.15534699291832 +tomatoes,4,247.68079120974087,49.88403956048705 +tomatoes,2,180.04202746968298,31.502101373484148 +wheat,10,269.1663444656124,53.958317223280616 +apples,7,165.4857126438969,120.77428563219485 +apples,11,268.67541817104984,95.93377090855249 +wheat,2,284.76692462822405,46.7383462314112 +potatoes,11,299.48352763333435,27.474176381666716 +corn,1,150.48272840231053,20.024136420115525 +wheat,12,206.87636580459252,42.84381829022963 +corn,9,242.06835346612954,28.603417673306478 +tomatoes,7,180.62979790863076,37.53148989543154 +tomatoes,1,77.61852828284866,26.380926414142433 +mangoes,8,121.80974791352044,142.59048739567604 +corn,2,108.40193776247749,17.920096888123876 +tomatoes,1,277.5847755143836,36.37923877571918 +vegetable,9,77.36689966977879,50.36834498348894 +tomatoes,8,81.10938932421409,32.5554694662107 +potatoes,10,249.49733053584583,28.97486652679229 +wheat,11,197.13855724331134,42.35692786216557 +vegetable,8,271.04974453287576,60.05248722664379 +potatoes,2,91.7584865230188,17.08792432615094 +corn,4,107.91792534586085,17.895896267293043 +corn,6,201.93419871971477,22.59670993598574 +wheat,10,61.73633928695325,43.58681696434766 +tomatoes,10,59.18298435665341,31.45914921783267 +apples,3,256.55142394849145,105.32757119742458 +wheat,5,207.44448074903826,42.872224037451915 +vegetable,1,179.56509166909805,46.478254583454905 +corn,10,181.25787521506703,25.56289376075335 +potatoes,10,178.81198107868147,25.440599053934072 +apples,1,88.47397658496376,86.9236988292482 +potatoes,6,205.73434573377966,22.786717286688983 +wheat,9,198.23498371042578,50.41174918552129 +mangoes,5,72.87170934943872,92.14358546747194 +tomatoes,8,116.40001064717652,34.320000532358826 +corn,9,61.094165883309195,19.554708294165458 +apples,12,58.855592104636266,85.4427796052318 +vegetable,8,282.89737207974747,60.644868603987376 +potatoes,11,120.34774014438169,18.517387007219085 +corn,6,114.93844594008155,18.246922297004076 +wheat,10,183.1506298501905,49.65753149250953 +wheat,12,77.36721501361347,36.36836075068067 +corn,5,297.86883378626203,27.3934416893131 +apples,8,270.72656728436533,126.03632836421826 +mangoes,3,256.1702414812873,101.30851207406437 +apples,8,191.43299099894776,122.07164954994738 +wheat,1,269.6574965887895,45.982874829439474 +potatoes,8,111.32138306383364,22.06606915319168 +potatoes,11,90.10002633251803,17.0050013166259 +wheat,11,109.67250782525439,37.98362539126272 +wheat,10,76.458523457146,44.3229261728573 +potatoes,6,97.30538494625148,17.365269247312575 +wheat,11,290.32882204622683,47.01644110231134 +tomatoes,3,269.7678700570329,50.98839350285164 +apples,10,254.98672935202504,125.24933646760125 +wheat,7,90.18997401207704,45.00949870060385 +corn,2,258.0335444894355,25.401677224471776 +wheat,12,51.596467929208394,35.07982339646042 +wheat,11,295.29654450685587,47.26482722534279 +tomatoes,8,114.95089526603995,34.247544763301995 +corn,8,254.66985512496043,29.233492756248022 +mangoes,3,240.256975625507,100.51284878127535 +apples,9,290.74800096474866,127.03740004823743 +vegetable,12,208.15547328348703,47.90777366417435 +mangoes,5,75.62743199766982,92.28137159988349 +corn,4,221.97143057520333,23.598571528760168 +apples,4,125.24089173670406,98.7620445868352 +tomatoes,12,66.83765036719292,25.841882518359647 +apples,6,136.47076423823918,99.32353821191197 +apples,8,61.435508453128215,115.57177542265642 +apples,12,237.41295793573119,94.37064789678656 +potatoes,4,239.56579898225564,24.47828994911278 +vegetable,11,255.37823685186024,50.26891184259301 +vegetable,3,113.12718742209556,43.15635937110478 +vegetable,10,89.73457081918913,50.986728540959454 +apples,4,156.54532555899323,100.32726627794966 +wheat,9,90.9059552979173,45.045297764895864 +vegetable,11,105.1924031971901,42.75962015985951 +apples,4,213.62780357028382,103.18139017851419 +potatoes,3,287.71589056260257,26.885794528130127 +corn,8,158.0837002606505,24.404185013032524 +wheat,5,209.63148691602137,42.98157434580107 +mangoes,3,118.5538005871675,94.42769002935837 +potatoes,11,152.33350157876075,20.116675078938037 +corn,6,107.48865147277155,17.87443257363858 +wheat,3,57.78352072112784,35.38917603605639 +tomatoes,8,142.13158593094028,35.60657929654701 +vegetable,12,168.3024766728893,45.915123833644465 +corn,9,267.1557919889027,29.857789599445134 +wheat,8,242.730461161013,52.63652305805065 +mangoes,2,240.25599773574973,124.51279988678749 +potatoes,12,58.13154487281298,15.406577243640648 +corn,10,204.1625786301845,26.708128931509226 +mangoes,9,50.307958791606474,139.0153979395803 +vegetable,1,201.8266120656678,47.59133060328339 +corn,4,189.6031681457995,21.980158407289974 +tomatoes,12,66.05223426878352,25.802611713439177 +mangoes,5,117.24835110877441,94.36241755543873 +potatoes,1,52.905134977025156,15.145256748851256 +apples,2,169.98470867928089,90.99923543396405 +vegetable,6,122.91564467732582,43.64578223386629 +wheat,9,265.03059929730114,53.75152996486506 +mangoes,9,59.90470633708929,139.49523531685446 +mangoes,3,76.23254460454372,92.31162723022719 +tomatoes,12,296.6656483167866,37.33328241583933 +vegetable,6,204.53893357952978,47.72694667897649 +corn,1,189.91217087172853,21.995608543586428 +apples,12,68.10406803658537,85.90520340182927 +tomatoes,1,270.6333714549,36.031668572745 +mangoes,1,256.12851172420847,125.30642558621042 +apples,6,130.52367555483383,99.02618377774169 +mangoes,7,100.21477246557355,141.51073862327868 +apples,2,255.36018200246662,95.26800910012334 +apples,7,217.59636458860305,123.37981822943016 +potatoes,3,274.0553256712596,26.20276628356298 +tomatoes,6,204.1511454656185,47.707557273280926 +vegetable,9,227.2651298627291,57.863256493136454 +apples,12,250.43202076744797,95.0216010383724 +mangoes,11,171.09961189351014,121.05498059467551 +potatoes,4,188.25036314798962,21.912518157399482 +mangoes,10,245.9581383547155,148.7979069177358 +vegetable,3,60.18852652311819,40.50942632615591 +corn,10,159.6518041223846,24.48259020611923 +apples,6,198.31966207754468,102.41598310387724 +corn,9,267.9458916480504,29.89729458240252 +apples,3,293.96631395478283,107.19831569773915 +corn,8,267.9581947432803,29.897909737164014 +wheat,7,60.9154144268403,43.545770721342016 +corn,2,55.21528482288453,15.260764241144226 +potatoes,6,133.07865633877722,19.153932816938863 +tomatoes,11,212.58142158673422,33.12907107933671 +apples,3,220.05706060782282,103.50285303039114 +wheat,6,57.663125551451515,35.383156277572574 +tomatoes,7,165.6557391848291,36.782786959241456 +mangoes,5,231.792267441577,100.08961337207884 +wheat,8,156.37333361201883,48.31866668060094 +corn,12,142.75969074615068,19.637984537307535 +corn,12,60.02729785312062,15.501364892656031 +tomatoes,3,194.66885214309835,47.23344260715492 +corn,10,231.3144151037841,28.065720755189204 +corn,2,199.43089131396607,22.471544565698302 +corn,6,213.75233470802715,23.187616735401356 +potatoes,3,120.96363215216125,18.54818160760806 +wheat,12,145.96178796694906,39.79808939834745 +apples,8,258.99951594530233,125.44997579726511 +tomatoes,3,244.00005175885738,49.70000258794287 +corn,7,208.13513330657653,26.906756665328828 +mangoes,2,95.24423817737244,117.26221190886862 +wheat,6,173.0694641120087,41.153473205600434 +mangoes,6,267.68747531812784,101.88437376590639 +vegetable,8,194.8537248358752,56.24268624179376 +corn,2,73.81537698865657,16.19076884943283 +tomatoes,11,128.03701417411176,28.901850708705588 +corn,2,264.49656348067646,25.724828174033824 +wheat,1,243.36828142165015,44.66841407108251 +corn,7,163.44738534590982,24.67236926729549 +potatoes,10,68.37418683250317,19.91870934162516 +mangoes,10,162.19439345785077,144.60971967289254 +corn,9,157.7218809154515,24.386094045772573 +corn,8,204.2862466510075,26.714312332550374 +tomatoes,9,91.76047697523747,33.08802384876187 +corn,12,59.16785673338574,15.458392836669287 +wheat,5,183.3779813249239,41.6688990662462 +tomatoes,1,226.34639852805088,33.81731992640255 +corn,6,101.46030250919206,17.5730151254596 +wheat,4,117.4374028792474,38.37187014396237 +apples,9,182.79238200025802,121.63961910001291 +corn,10,59.835885167127415,19.49179425835637 +vegetable,3,163.04975707085882,45.652487853542944 +wheat,11,129.03902624418762,38.95195131220938 +tomatoes,3,60.39321476259802,40.5196607381299 +apples,4,296.6575307397117,107.33287653698558 +potatoes,11,54.34494754636991,15.217247377318495 +tomatoes,2,293.2744370175866,37.16372185087933 +vegetable,8,178.89900714481257,55.44495035724063 +apples,7,216.71606438652609,123.33580321932631 +corn,7,57.49339746816949,19.374669873408475 +wheat,4,226.17019068416167,43.808509534208085 +apples,12,218.35810833122932,93.41790541656147 +apples,5,73.47517894735459,96.17375894736773 +wheat,6,267.03556359437636,45.85177817971882 +mangoes,2,215.4080875927867,123.27040437963933 +vegetable,10,143.57419178494817,53.67870958924741 +mangoes,2,111.03682260559357,118.05184113027968 +apples,8,266.1522089887592,125.80761044943796 +tomatoes,12,78.27745476914326,26.41387273845716 +tomatoes,4,219.12834644431163,48.45641732221558 +potatoes,5,216.74287924772682,23.337143962386342 +tomatoes,10,137.14341681049262,35.35717084052463 +apples,2,201.2384806726352,92.56192403363175 +vegetable,9,266.6096668819114,59.83048334409557 +tomatoes,9,72.62042382176269,32.13102119108814 +vegetable,9,77.27740794143743,50.36387039707187 +apples,6,131.75829039080966,99.08791451954048 +mangoes,3,251.96148548531465,101.09807427426573 +apples,9,129.29892919134966,118.96494645956749 +wheat,11,143.91806297043163,39.69590314852158 +mangoes,6,212.26866469859826,99.11343323492991 +wheat,1,141.61538371784948,39.58076918589247 +vegetable,5,145.10492605819942,44.755246302909974 +wheat,9,199.1213687463554,50.45606843731777 +tomatoes,3,106.81740681578786,42.840870340789394 +apples,11,200.86214834534448,92.54310741726722 +mangoes,10,239.8360819807165,148.49180409903582 +tomatoes,3,185.5909162449346,46.77954581224673 +apples,6,278.5591289878675,106.42795644939338 +wheat,10,77.22958546168286,44.36147927308414 +wheat,2,181.6559493172399,41.582797465861994 +vegetable,12,169.1738687602898,45.95869343801449 +potatoes,7,253.24643467902337,29.162321733951167 +apples,12,288.8809239887337,96.94404619943668 +wheat,5,98.94449642088652,37.44722482104433 +vegetable,5,274.50763723749674,51.22538186187484 +tomatoes,4,281.75863619907665,51.58793180995383 +vegetable,4,283.6090067013786,51.680450335068926 +mangoes,3,75.35520711230413,92.26776035561521 +wheat,4,114.19414193012699,38.20970709650635 +corn,11,282.4014693554973,26.620073467774866 +corn,3,195.23301331569942,22.26165066578497 +apples,4,229.40894647715737,103.97044732385787 +apples,1,294.18130966564473,97.20906548328223 +apples,9,180.6202601290296,121.53101300645147 +vegetable,12,95.35958692390673,42.26797934619534 +wheat,7,123.81957230507751,46.690978615253876 +tomatoes,10,96.30711163685241,33.315355581842624 +corn,4,170.8864116799812,21.04432058399906 +vegetable,6,187.55663553906544,46.87783177695327 +wheat,10,78.0760861028048,44.40380430514024 +wheat,7,209.4963014483244,50.97481507241622 +wheat,6,198.3846422807868,42.41923211403934 +apples,9,211.65147835571503,123.08257391778575 +apples,9,259.96532571668007,125.498266285834 +tomatoes,10,113.91124945231807,34.195562472615904 +corn,2,232.98951689640865,24.149475844820433 +corn,12,217.8561673826536,23.39280836913268 +tomatoes,2,241.6640338001015,34.583201690005076 +apples,1,155.9862032283255,90.29931016141627 +wheat,1,234.21843623604553,44.21092181180228 +apples,1,104.18495002269391,87.7092475011347 +tomatoes,6,55.9096465115841,40.29548232557921 +vegetable,3,201.77350902219519,47.58867545110976 +potatoes,10,114.2209619114287,22.211048095571435 +wheat,9,174.19171471479234,49.209585735739616 +apples,3,199.2617292239229,102.46308646119614 +apples,3,160.67924169488177,100.53396208474409 +wheat,7,231.12921284965452,52.056460642482726 +potatoes,7,135.27250611855513,23.263625305927757 +mangoes,3,200.80485255334307,98.54024262766715 +mangoes,10,276.38119808241845,150.31905990412093 +wheat,4,71.41456239910764,36.07072811995538 +tomatoes,4,97.96683117968573,42.398341558984285 +tomatoes,11,135.89011869392598,29.2945059346963 +vegetable,4,160.6024841201674,45.53012420600837 +corn,2,217.40065403349047,23.370032701674525 +corn,11,210.04205595704153,23.002102797852075 +mangoes,8,212.71934226179854,147.13596711308992 +mangoes,12,131.08343827884391,119.0541719139422 +potatoes,6,217.37173879954753,23.368586939977376 +vegetable,12,215.45979746234465,48.27298987311723 +tomatoes,3,232.6626275598115,49.13313137799057 +mangoes,4,65.03558565019631,91.75177928250982 +corn,10,289.40632112634506,30.97031605631725 +wheat,9,92.61948454347939,45.13097422717397 +apples,9,255.4516109752717,125.27258054876359 +corn,1,125.21327708831377,18.76066385441569 +corn,3,281.79445486986316,26.58972274349316 +wheat,7,149.82897895232705,47.991448947616355 +mangoes,5,234.2950562518108,100.21475281259055 +corn,1,260.5083235941053,25.525416179705267 +wheat,4,205.89642200068994,42.7948211000345 +apples,8,238.81760512420198,124.4408802562101 +tomatoes,5,256.5169075631321,50.32584537815661 +mangoes,4,227.1861744357441,99.8593087217872 +mangoes,4,125.78208898633216,94.78910444931661 +apples,2,145.2273813777468,89.76136906888735 +apples,11,109.7638330493164,87.98819165246582 +tomatoes,11,256.3215270582242,35.31607635291121 +mangoes,7,285.5967547755583,150.77983773877793 +apples,7,90.4410528380274,117.02205264190137 +mangoes,11,193.64684557944165,122.18234227897209 +corn,5,147.7606907645436,19.88803453822718 +corn,1,79.09159947136902,16.45457997356845 +apples,3,218.5759516022621,103.4287975801131 +apples,6,85.31951231887645,96.76597561594382 +vegetable,4,254.68375101856753,50.234187550928375 +vegetable,5,55.72345624403006,40.2861728122015 +potatoes,2,105.9036086240778,17.79518043120389 +mangoes,4,193.26035723271232,98.16301786163561 +apples,9,193.79083762415624,122.18954188120782 +wheat,6,128.431922798524,38.9215961399262 +vegetable,1,201.56323443774437,47.57816172188722 +mangoes,4,175.6415191158606,97.28207595579303 +tomatoes,6,86.59349804056228,41.82967490202812 +wheat,2,67.0430773463734,35.85215386731867 +apples,4,83.7915722887057,96.68957861443529 +corn,12,244.18090761792317,24.709045380896157 +corn,4,159.87792215822753,20.493896107911375 +corn,6,50.08312653012235,15.004156326506116 +potatoes,2,212.55027309953834,23.127513654976916 +potatoes,3,191.11027266972062,22.05551363348603 +apples,10,102.9388376663696,117.64694188331848 +mangoes,11,238.56338608596576,124.4281693042983 +vegetable,8,124.33876205920973,52.71693810296048 +vegetable,3,92.6661896374996,42.13330948187498 +wheat,9,245.6740101860373,52.783700509301866 +mangoes,3,94.44159696281206,93.22207984814061 +corn,1,177.35553203744743,21.36777660187237 +vegetable,8,253.4925673765047,59.17462836882524 +vegetable,12,126.56340519665292,43.828170259832646 +corn,4,181.7603659779129,21.588018298895644 +vegetable,2,82.67759418504987,41.6338797092525 +corn,3,141.9398377193224,19.59699188596612 +corn,6,256.8844738917186,25.344223694585928 +wheat,6,290.95556887058774,47.04777844352939 +vegetable,2,83.45093406987218,41.67254670349361 +wheat,6,247.58443396503702,44.879221698251854 +wheat,10,220.24370680956113,51.512185340478055 +vegetable,5,103.80046800430938,42.690023400215466 +wheat,10,110.30036439988537,46.01501821999427 +wheat,5,250.3842779707474,45.01921389853737 +wheat,4,142.8521419125352,39.64260709562676 +tomatoes,12,211.522530865627,33.07612654328135 +wheat,4,116.50481950134518,38.32524097506726 +wheat,10,81.7999406718624,44.58999703359312 +apples,4,110.8694921012168,98.04347460506084 +apples,8,252.67148199656657,125.13357409982832 +wheat,4,264.8913079117364,45.74456539558682 +apples,5,289.0555476622371,106.95277738311185 +tomatoes,9,75.53738241438452,32.276869120719226 +tomatoes,9,222.03367652163553,39.601683826081775 +corn,1,260.21789485648065,25.510894742824032 +apples,12,245.29260594672982,94.7646302973365 +corn,11,173.86302586524545,21.19315129326227 +potatoes,6,209.16742054180182,22.95837102709009 +vegetable,1,66.66301014017249,40.833150507008625 +wheat,3,76.42336997656852,36.32116849882843 +corn,1,160.81827186090456,20.54091359304523 +wheat,8,71.1980040114508,44.05990020057254 +potatoes,1,68.02108399966833,15.901054199983417 +potatoes,8,58.89271675888709,19.444635837944354 +corn,5,146.8988078706924,19.84494039353462 +vegetable,4,137.42580743646238,44.37129037182312 +vegetable,3,215.3426527676036,48.26713263838018 +corn,3,93.52733383352108,17.176366691676055 +wheat,5,215.07567992533453,43.253783996266726 +apples,6,70.65441586481717,96.03272079324086 +corn,1,123.86119436935506,18.693059718467754 +tomatoes,9,145.484909913224,35.7742454956612 +apples,3,80.34660453985161,96.51733022699258 +mangoes,4,243.65844515944698,100.68292225797235 +tomatoes,9,182.57553331228956,37.62877666561448 +mangoes,2,130.55387586115708,119.02769379305785 +corn,12,168.58402747655347,20.929201373827674 +apples,6,171.50387574438497,101.07519378721925 +vegetable,12,89.15960924345208,41.95798046217261 +apples,1,282.02091008151245,96.60104550407563 +vegetable,9,143.04175595937832,53.65208779796892 +potatoes,12,147.16319965746175,19.858159982873087 +apples,6,118.44782687852663,98.42239134392634 +corn,5,218.99556889658885,23.44977844482944 +potatoes,1,211.45270316380152,23.072635158190074 +potatoes,10,253.9867347421543,29.199336737107714 +vegetable,7,261.6285846725695,59.58142923362848 +tomatoes,2,209.01769093245628,32.95088454662282 +mangoes,5,294.59931970014895,103.22996598500745 +mangoes,8,189.4533063777675,145.97266531888837 +vegetable,12,63.46455174950653,40.673227587475324 +mangoes,6,296.16743488112706,103.30837174405636 +mangoes,12,60.793433949252915,115.53967169746265 +apples,2,82.93219336364048,86.64660966818202 +vegetable,4,254.44633246423626,50.22231662321181 +vegetable,3,87.66902692746935,41.88345134637347 +corn,6,185.55930137296207,21.777965068648104 +wheat,1,177.09013672907,41.3545068364535 +vegetable,6,191.25549821475403,47.0627749107377 +wheat,7,194.2931958218875,50.21465979109438 +tomatoes,5,90.01790873864324,42.00089543693216 +apples,10,52.332904956773326,115.11664524783866 +tomatoes,12,231.61542877825121,34.080771438912564 +tomatoes,4,74.79452489680398,41.2397262448402 +apples,2,101.00890865722471,87.55044543286124 +apples,5,233.2678240074187,104.16339120037094 +vegetable,11,97.00618365385404,42.350309182692705 +tomatoes,9,188.55662853300416,37.92783142665021 +mangoes,10,240.24769000702346,148.51238450035117 +mangoes,12,236.43344568280804,124.3216722841404 +mangoes,9,289.5183700298451,150.97591850149226 +tomatoes,4,131.7329040845198,44.08664520422599 +potatoes,7,167.57976352544642,24.878988176272323 +potatoes,5,81.17851422784761,16.55892571139238 +vegetable,4,230.51773455068425,49.025886727534214 +mangoes,3,84.45572478980885,92.72278623949045 +mangoes,5,50.46997088122766,91.02349854406138 +vegetable,5,57.267845085988434,40.36339225429942 +mangoes,4,95.3298199813763,93.26649099906882 +wheat,4,150.581781171639,40.02908905858195 +vegetable,4,177.5274281247063,46.376371406235315 +potatoes,8,76.03433948007186,20.301716974003593 +apples,7,225.7358602446692,123.78679301223346 +mangoes,8,219.11698430659055,147.45584921532952 +apples,3,117.45518003205359,98.37275900160267 +corn,3,174.5639205658634,21.22819602829317 +mangoes,3,64.6377323109948,91.73188661554974 +wheat,12,246.2242442778669,44.81121221389334 +mangoes,5,247.15374116810162,100.85768705840508 +potatoes,4,80.59418933129449,16.529709466564725 +tomatoes,7,108.96439978592177,33.94821998929609 +vegetable,4,65.63555672434211,40.7817778362171 +corn,11,241.64713099291083,24.582356549645542 +tomatoes,12,124.86087762297167,28.743043881148584 +tomatoes,1,209.38831611755745,32.96941580587787 +corn,11,221.47781776246592,23.573890888123294 +vegetable,12,145.958237983261,44.79791189916305 +tomatoes,10,196.94234021554956,38.34711701077748 +tomatoes,4,140.5588604130721,44.5279430206536 +apples,3,56.5491771330162,95.32745885665081 +tomatoes,6,118.2677024932031,43.41338512466015 +tomatoes,11,124.68139339719326,28.734069669859664 +wheat,3,114.82418971644344,38.241209485822175 +mangoes,10,268.18256262115045,149.9091281310575 +wheat,5,170.2265001882674,41.01132500941337 +wheat,10,284.3383235539661,54.71691617769831 +corn,6,207.7926614891766,22.88963307445883 +mangoes,7,275.9783325650937,150.2989166282547 +potatoes,1,245.0532658575256,24.752663292876278 +corn,6,64.32006276940584,15.716003138470292 +mangoes,12,82.83735203622668,116.64186760181133 +tomatoes,4,214.23878906678488,48.21193945333924 +corn,5,67.2395040891053,15.861975204455264 +corn,10,120.54676867330004,22.527338433665 +corn,7,111.74469976799996,22.0872349884 +corn,8,293.708663195278,31.1854331597639 +mangoes,10,261.19735907150533,149.55986795357526 +mangoes,12,89.095451100862,116.95477255504309 +corn,8,61.62514661001637,19.58125733050082 +apples,10,190.4982118667017,122.02491059333508 +wheat,4,128.79738027433976,38.93986901371699 +potatoes,7,71.60615269063662,20.08030763453183 +vegetable,2,233.11218295952244,49.15560914797612 +potatoes,4,81.9970521333966,16.599852606669828 +vegetable,5,63.064469821505945,40.653223491075295 +corn,8,115.03944774051278,22.25197238702564 +tomatoes,5,295.3242726243117,52.266213631215585 +apples,5,213.54365036851863,103.17718251842594 +apples,5,191.33256364290247,102.06662818214512 +potatoes,3,293.00133240788426,27.150066620394213 +corn,9,95.75386105868179,21.287693052934088 +tomatoes,2,230.00200991577827,34.000100495788914 +vegetable,10,72.21006127189109,50.11050306359456 +mangoes,7,186.27638206517491,145.81381910325874 +wheat,2,150.99446908163705,40.04972345408185 +potatoes,9,247.92499711333792,28.896249855666895 +tomatoes,1,203.2250402154873,32.66125201077436 +mangoes,6,261.72968202213997,101.586484101107 +apples,5,85.23990688044232,96.76199534402211 +mangoes,9,217.25558433227707,147.36277921661386 +apples,3,212.74336678773855,103.13716833938693 +mangoes,12,65.5682764704714,115.77841382352356 +mangoes,12,138.99334344871318,119.44966717243565 +potatoes,3,246.56954984600827,24.828477492300415 +vegetable,5,91.17658835807397,42.058829417903695 +vegetable,4,239.18787642215875,49.45939382110794 +mangoes,8,81.56344569815336,140.57817228490768 +vegetable,6,90.40495282146786,42.0202476410734 +mangoes,11,286.65948854990177,126.83297442749509 +apples,12,243.0031190774976,94.65015595387487 +vegetable,2,66.30114781512302,40.81505739075615 +mangoes,3,277.30505146539,102.3652525732695 +tomatoes,10,174.45312700857255,37.22265635042863 +mangoes,7,214.1950261810735,147.20975130905367 +tomatoes,11,145.10500187689058,29.75525009384453 +potatoes,5,291.1191634752029,27.055958173760146 +corn,10,73.50902610856659,20.17545130542833 +corn,12,239.37047119735433,24.468523559867716 +wheat,5,128.0872754713784,38.90436377356892 +tomatoes,8,180.04763081288863,37.50238154064443 +corn,4,189.45504798230036,21.972752399115016 +apples,7,203.36828465979409,122.6684142329897 +wheat,3,274.29658524115473,46.214829262057734 +potatoes,8,176.76277596636027,25.338138798318013 +corn,1,58.34590044659531,15.417295022329764 +wheat,12,255.09437686224334,45.254718843112165 +wheat,4,249.6483180956878,44.98241590478439 +mangoes,6,264.21848401877355,101.71092420093868 +tomatoes,12,234.93258302138514,34.24662915106926 +vegetable,1,154.44024481877491,45.222012240938746 +vegetable,5,216.97999970090677,48.34899998504534 +wheat,2,91.48872382394624,37.074436191197314 +mangoes,10,156.87242198015377,144.3436210990077 +vegetable,11,221.71524941875725,48.585762470937865 +potatoes,1,57.34103977559808,15.367051988779902 +corn,2,102.43823692092035,17.621911846046018 +mangoes,5,293.3643474940433,103.16821737470217 +corn,9,254.76587846541403,29.238293923270703 +apples,6,227.56069965582788,103.87803498279139 +corn,9,167.79197473320366,24.889598736660183 +vegetable,12,164.81629929330347,45.74081496466518 +wheat,8,173.55311181257497,49.177655590628746 +potatoes,12,133.80201184271817,19.19010059213591 +apples,5,78.23580210279339,96.41179010513967 +apples,1,109.96852818898618,87.99842640944931 +corn,2,136.98535289554167,19.349267644777083 +vegetable,2,237.20658424082663,49.36032921204133 +tomatoes,7,205.2321418696078,38.76160709348039 +mangoes,1,260.36188827118997,125.5180944135595 +potatoes,11,208.5355345739342,22.92677672869671 +corn,2,131.27600385792474,19.063800192896238 +corn,7,91.78300286780531,21.089150143390263 +corn,12,297.93565429195974,27.396782714597986 +vegetable,7,69.26950298786517,49.96347514939326 +potatoes,4,266.5966285628355,25.829831428141777 +vegetable,6,140.09445498258688,44.50472274912934 +wheat,3,240.78882281472235,44.539441140736116 +wheat,4,284.57620461212065,46.72881023060603 +corn,1,241.51619413382565,24.57580970669128 +potatoes,12,216.2462258689988,23.31231129344994 +apples,3,276.79875767645746,106.33993788382287 +potatoes,11,190.11015774510997,22.005507887255497 +potatoes,2,161.76388595160637,20.58819429758032 +mangoes,4,145.40298496680003,95.77014924834 +mangoes,3,153.1902823165065,96.15951411582533 +vegetable,11,155.63710707798614,45.28185535389931 +tomatoes,8,234.97603019173258,40.24880150958663 +apples,6,120.00933238762236,98.50046661938111 +tomatoes,3,293.19408072302144,52.15970403615107 +potatoes,10,224.82884378155092,27.741442189077546 +corn,4,295.44967331515693,27.272483665757846 +mangoes,9,126.18777384653333,142.80938869232668 +vegetable,9,120.38029960373248,52.519014980186626 +vegetable,4,78.14509760298425,41.40725488014921 +mangoes,5,185.17461916122758,97.75873095806138 +tomatoes,9,53.1010090693287,31.155050453466433 +corn,9,256.13370202175804,29.3066851010879 +wheat,3,106.58787358537148,37.82939367926858 +mangoes,9,62.03570899458836,139.60178544972942 diff --git a/backend/ml/rec_data.csv b/backend/ml/rec_data.csv new file mode 100644 index 0000000..4f2aaeb --- /dev/null +++ b/backend/ml/rec_data.csv @@ -0,0 +1,501 @@ +soil,season,recommended_crop +laterite,summer,Cashew +laterite,monsoon,Rubber +black,summer,Cotton +laterite,winter,Tea +sandy,monsoon,Millets +sandy,monsoon,Millets +black,monsoon,Soybean +red,summer,Groundnut +clay,winter,Barley +red,winter,Tobacco +alluvial,summer,Rice +loamy,winter,Wheat +red,summer,Groundnut +alluvial,summer,Rice +loamy,monsoon,Paddy +sandy,monsoon,Millets +clay,monsoon,Jute +red,winter,Tobacco +laterite,winter,Tea +sandy,monsoon,Millets +alluvial,summer,Rice +sandy,summer,Groundnut +sandy,monsoon,Millets +black,summer,Cotton +laterite,winter,Tea +alluvial,summer,Rice +alluvial,winter,Wheat +clay,winter,Barley +loamy,winter,Wheat +black,winter,Linseed +alluvial,monsoon,Jute +alluvial,monsoon,Jute +alluvial,summer,Rice +laterite,monsoon,Rubber +red,summer,Groundnut +alluvial,winter,Wheat +alluvial,winter,Wheat +red,winter,Tobacco +red,winter,Tobacco +alluvial,winter,Wheat +black,monsoon,Soybean +clay,winter,Barley +alluvial,winter,Wheat +clay,winter,Barley +alluvial,winter,Wheat +laterite,monsoon,Rubber +red,monsoon,Ragi +alluvial,summer,Rice +red,summer,Groundnut +black,winter,Linseed +laterite,summer,Cashew +clay,summer,Rice +alluvial,summer,Rice +loamy,summer,Corn +laterite,summer,Cashew +loamy,summer,Corn +laterite,summer,Cashew +loamy,monsoon,Paddy +sandy,monsoon,Millets +loamy,monsoon,Paddy +sandy,summer,Groundnut +sandy,summer,Groundnut +clay,monsoon,Jute +clay,summer,Rice +alluvial,monsoon,Jute +loamy,winter,Wheat +loamy,monsoon,Paddy +laterite,winter,Tea +black,monsoon,Soybean +alluvial,winter,Wheat +sandy,monsoon,Millets +loamy,monsoon,Paddy +black,monsoon,Soybean +red,monsoon,Ragi +loamy,summer,Corn +clay,monsoon,Jute +laterite,winter,Tea +laterite,monsoon,Rubber +loamy,monsoon,Paddy +laterite,winter,Tea +clay,summer,Rice +sandy,monsoon,Millets +laterite,summer,Cashew +alluvial,summer,Rice +alluvial,winter,Wheat +black,monsoon,Soybean +laterite,summer,Cashew +laterite,monsoon,Rubber +black,summer,Cotton +laterite,monsoon,Rubber +sandy,winter,Mustard +alluvial,winter,Wheat +clay,summer,Rice +red,summer,Groundnut +black,winter,Linseed +alluvial,winter,Wheat +red,monsoon,Ragi +clay,monsoon,Jute +alluvial,summer,Rice +laterite,winter,Tea +loamy,summer,Corn +loamy,monsoon,Paddy +red,summer,Groundnut +alluvial,summer,Rice +loamy,monsoon,Paddy +laterite,winter,Tea +sandy,summer,Groundnut +red,summer,Groundnut +loamy,monsoon,Paddy +clay,monsoon,Jute +sandy,winter,Mustard +loamy,summer,Corn +red,summer,Groundnut +clay,winter,Barley +laterite,winter,Tea +sandy,summer,Groundnut +black,summer,Cotton +loamy,monsoon,Paddy +loamy,winter,Wheat +clay,winter,Barley +laterite,summer,Cashew +loamy,summer,Corn +sandy,winter,Mustard +clay,summer,Rice +alluvial,winter,Wheat +red,monsoon,Ragi +alluvial,monsoon,Jute +sandy,monsoon,Millets +loamy,monsoon,Paddy +red,summer,Groundnut +alluvial,winter,Wheat +red,winter,Tobacco +sandy,monsoon,Millets +loamy,summer,Corn +alluvial,monsoon,Jute +red,summer,Groundnut +sandy,monsoon,Millets +alluvial,monsoon,Jute +clay,monsoon,Jute +laterite,monsoon,Rubber +alluvial,monsoon,Jute +alluvial,summer,Rice +loamy,monsoon,Paddy +clay,summer,Rice +sandy,summer,Groundnut +loamy,winter,Wheat +laterite,monsoon,Rubber +red,winter,Tobacco +sandy,monsoon,Millets +alluvial,winter,Wheat +loamy,summer,Corn +clay,summer,Rice +red,summer,Groundnut +black,monsoon,Soybean +laterite,summer,Cashew +loamy,monsoon,Paddy +sandy,monsoon,Millets +alluvial,winter,Wheat +loamy,monsoon,Paddy +loamy,winter,Wheat +alluvial,winter,Wheat +sandy,winter,Mustard +loamy,monsoon,Paddy +loamy,summer,Corn +clay,winter,Barley +clay,winter,Barley +red,monsoon,Ragi +black,summer,Cotton +alluvial,summer,Rice +alluvial,summer,Rice +red,summer,Groundnut +alluvial,monsoon,Jute +sandy,summer,Groundnut +loamy,monsoon,Paddy +sandy,winter,Mustard +laterite,winter,Tea +red,winter,Tobacco +red,winter,Tobacco +black,monsoon,Soybean +red,monsoon,Ragi +sandy,winter,Mustard +black,winter,Linseed +loamy,monsoon,Paddy +loamy,summer,Corn +alluvial,summer,Rice +sandy,monsoon,Millets +loamy,summer,Corn +alluvial,winter,Wheat +black,winter,Linseed +black,winter,Linseed +sandy,summer,Groundnut +black,summer,Cotton +loamy,winter,Wheat +black,monsoon,Soybean +sandy,summer,Groundnut +alluvial,monsoon,Jute +black,summer,Cotton +laterite,summer,Cashew +sandy,winter,Mustard +loamy,winter,Wheat +laterite,winter,Tea +clay,monsoon,Jute +red,winter,Tobacco +laterite,winter,Tea +laterite,winter,Tea +laterite,monsoon,Rubber +clay,winter,Barley +clay,summer,Rice +loamy,summer,Corn +sandy,winter,Mustard +laterite,summer,Cashew +clay,monsoon,Jute +clay,monsoon,Jute +clay,summer,Rice +black,winter,Linseed +laterite,summer,Cashew +alluvial,summer,Rice +alluvial,summer,Rice +red,winter,Tobacco +alluvial,monsoon,Jute +laterite,monsoon,Rubber +alluvial,winter,Wheat +clay,monsoon,Jute +laterite,winter,Tea +sandy,summer,Groundnut +clay,monsoon,Jute +red,summer,Groundnut +red,winter,Tobacco +clay,winter,Barley +loamy,winter,Wheat +red,monsoon,Ragi +red,monsoon,Ragi +alluvial,summer,Rice +loamy,summer,Corn +alluvial,summer,Rice +laterite,winter,Tea +black,winter,Linseed +laterite,monsoon,Rubber +laterite,summer,Cashew +clay,winter,Barley +red,monsoon,Ragi +loamy,monsoon,Paddy +sandy,winter,Mustard +laterite,winter,Tea +black,winter,Linseed +black,winter,Linseed +laterite,monsoon,Rubber +loamy,summer,Corn +loamy,winter,Wheat +clay,summer,Rice +laterite,winter,Tea +red,winter,Tobacco +loamy,summer,Corn +black,summer,Cotton +black,monsoon,Soybean +laterite,summer,Cashew +red,summer,Groundnut +laterite,monsoon,Rubber +alluvial,winter,Wheat +sandy,summer,Groundnut +red,summer,Groundnut +black,winter,Linseed +alluvial,summer,Rice +laterite,summer,Cashew +red,winter,Tobacco +red,summer,Groundnut +alluvial,winter,Wheat +clay,summer,Rice +laterite,summer,Cashew +red,winter,Tobacco +black,monsoon,Soybean +clay,winter,Barley +red,summer,Groundnut +alluvial,winter,Wheat +alluvial,monsoon,Jute +clay,winter,Barley +sandy,winter,Mustard +loamy,summer,Corn +black,monsoon,Soybean +clay,summer,Rice +alluvial,monsoon,Jute +alluvial,winter,Wheat +sandy,summer,Groundnut +loamy,summer,Corn +sandy,monsoon,Millets +black,monsoon,Soybean +loamy,summer,Corn +clay,monsoon,Jute +alluvial,summer,Rice +black,monsoon,Soybean +red,winter,Tobacco +black,monsoon,Soybean +clay,monsoon,Jute +laterite,summer,Cashew +clay,summer,Rice +clay,winter,Barley +clay,winter,Barley +clay,monsoon,Jute +loamy,monsoon,Paddy +alluvial,winter,Wheat +black,winter,Linseed +black,monsoon,Soybean +black,summer,Cotton +black,summer,Cotton +loamy,winter,Wheat +black,summer,Cotton +sandy,summer,Groundnut +sandy,winter,Mustard +loamy,monsoon,Paddy +laterite,winter,Tea +black,summer,Cotton +laterite,summer,Cashew +laterite,summer,Cashew +sandy,summer,Groundnut +red,summer,Groundnut +loamy,winter,Wheat +alluvial,summer,Rice +red,summer,Groundnut +sandy,monsoon,Millets +loamy,summer,Corn +loamy,monsoon,Paddy +alluvial,summer,Rice +laterite,winter,Tea +laterite,monsoon,Rubber +clay,monsoon,Jute +black,summer,Cotton +sandy,summer,Groundnut +alluvial,monsoon,Jute +black,summer,Cotton +laterite,summer,Cashew +laterite,summer,Cashew +black,winter,Linseed +clay,monsoon,Jute +red,monsoon,Ragi +clay,summer,Rice +sandy,monsoon,Millets +black,monsoon,Soybean +sandy,winter,Mustard +laterite,summer,Cashew +clay,winter,Barley +alluvial,summer,Rice +black,winter,Linseed +laterite,winter,Tea +black,winter,Linseed +loamy,winter,Wheat +sandy,winter,Mustard +clay,summer,Rice +black,summer,Cotton +red,monsoon,Ragi +black,summer,Cotton +red,summer,Groundnut +laterite,monsoon,Rubber +loamy,summer,Corn +alluvial,winter,Wheat +alluvial,monsoon,Jute +sandy,summer,Groundnut +alluvial,winter,Wheat +laterite,monsoon,Rubber +clay,winter,Barley +sandy,monsoon,Millets +red,monsoon,Ragi +black,summer,Cotton +clay,winter,Barley +clay,summer,Rice +laterite,summer,Cashew +laterite,summer,Cashew +sandy,summer,Groundnut +alluvial,winter,Wheat +loamy,monsoon,Paddy +alluvial,summer,Rice +loamy,summer,Corn +red,summer,Groundnut +red,winter,Tobacco +alluvial,summer,Rice +black,summer,Cotton +laterite,summer,Cashew +red,summer,Groundnut +sandy,summer,Groundnut +alluvial,monsoon,Jute +sandy,summer,Groundnut +clay,monsoon,Jute +loamy,summer,Corn +red,monsoon,Ragi +laterite,summer,Cashew +black,winter,Linseed +red,monsoon,Ragi +laterite,summer,Cashew +sandy,winter,Mustard +red,summer,Groundnut +clay,winter,Barley +clay,winter,Barley +alluvial,summer,Rice +loamy,monsoon,Paddy +red,monsoon,Ragi +loamy,summer,Corn +loamy,summer,Corn +alluvial,summer,Rice +alluvial,summer,Rice +black,winter,Linseed +sandy,summer,Groundnut +red,winter,Tobacco +sandy,summer,Groundnut +laterite,summer,Cashew +clay,winter,Barley +red,winter,Tobacco +sandy,summer,Groundnut +black,monsoon,Soybean +loamy,winter,Wheat +loamy,winter,Wheat +laterite,summer,Cashew +sandy,summer,Groundnut +clay,monsoon,Jute +loamy,winter,Wheat +sandy,monsoon,Millets +loamy,summer,Corn +loamy,winter,Wheat +loamy,monsoon,Paddy +laterite,summer,Cashew +black,monsoon,Soybean +red,summer,Groundnut +black,monsoon,Soybean +black,winter,Linseed +sandy,summer,Groundnut +laterite,summer,Cashew +black,summer,Cotton +clay,winter,Barley +sandy,summer,Groundnut +black,winter,Linseed +loamy,winter,Wheat +loamy,monsoon,Paddy +black,summer,Cotton +alluvial,winter,Wheat +loamy,summer,Corn +clay,monsoon,Jute +laterite,winter,Tea +clay,winter,Barley +red,winter,Tobacco +sandy,monsoon,Millets +clay,summer,Rice +red,summer,Groundnut +red,winter,Tobacco +sandy,summer,Groundnut +loamy,monsoon,Paddy +laterite,monsoon,Rubber +laterite,summer,Cashew +black,winter,Linseed +clay,monsoon,Jute +sandy,monsoon,Millets +red,winter,Tobacco +red,winter,Tobacco +clay,winter,Barley +red,monsoon,Ragi +sandy,monsoon,Millets +laterite,winter,Tea +alluvial,summer,Rice +red,summer,Groundnut +laterite,winter,Tea +laterite,winter,Tea +sandy,summer,Groundnut +black,summer,Cotton +alluvial,winter,Wheat +loamy,winter,Wheat +loamy,summer,Corn +clay,winter,Barley +black,winter,Linseed +black,winter,Linseed +sandy,monsoon,Millets +sandy,monsoon,Millets +laterite,summer,Cashew +laterite,monsoon,Rubber +laterite,monsoon,Rubber +red,summer,Groundnut +sandy,monsoon,Millets +sandy,summer,Groundnut +clay,summer,Rice +clay,monsoon,Jute +sandy,summer,Groundnut +black,winter,Linseed +alluvial,winter,Wheat +black,winter,Linseed +black,winter,Linseed +loamy,summer,Corn +loamy,winter,Wheat +red,winter,Tobacco +loamy,winter,Wheat +clay,summer,Rice +sandy,summer,Groundnut +clay,summer,Rice +laterite,summer,Cashew +red,monsoon,Ragi +red,monsoon,Ragi +laterite,summer,Cashew +loamy,winter,Wheat +alluvial,summer,Rice +loamy,monsoon,Paddy +black,monsoon,Soybean +laterite,monsoon,Rubber +red,winter,Tobacco +clay,monsoon,Jute +red,winter,Tobacco diff --git a/backend/ml/train.py b/backend/ml/train.py new file mode 100644 index 0000000..49f2997 --- /dev/null +++ b/backend/ml/train.py @@ -0,0 +1,67 @@ +""" +Train ML models for Farm2City price prediction and crop recommendation. +Run from the backend/ directory: + python -m ml.train +""" + +import os +import joblib +import pandas as pd +from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier +from sklearn.preprocessing import LabelEncoder + +from ml.utils import generate_price_data, generate_rec_data + +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +MODELS_DIR = os.path.join(BASE_DIR, "models") +os.makedirs(MODELS_DIR, exist_ok=True) + + +def train_price_model(): + csv_path = os.path.join(BASE_DIR, "price_data.csv") + df = generate_price_data(csv_path) + + le_crop = LabelEncoder() + df["category_enc"] = le_crop.fit_transform(df["category"].str.lower()) + + X = df[["category_enc", "month", "rainfall"]].values # plain numpy → no feature-name warning + y = df["predicted_price"].values + + model = RandomForestRegressor(n_estimators=100, random_state=42) + model.fit(X, y) + + joblib.dump(model, os.path.join(MODELS_DIR, "price_model.joblib")) + joblib.dump(le_crop, os.path.join(MODELS_DIR, "le_crop.joblib")) + print("✓ Price model trained and saved.") + return le_crop.classes_.tolist() + + +def train_rec_model(): + csv_path = os.path.join(BASE_DIR, "rec_data.csv") + df = generate_rec_data(csv_path) + + le_soil = LabelEncoder() + le_season = LabelEncoder() + le_rec = LabelEncoder() + + df["soil_enc"] = le_soil.fit_transform(df["soil"].str.lower()) + df["season_enc"] = le_season.fit_transform(df["season"].str.lower()) + df["rec_enc"] = le_rec.fit_transform(df["recommended_crop"]) + + X = df[["soil_enc", "season_enc"]].values # plain numpy + y = df["rec_enc"].values + + model = RandomForestClassifier(n_estimators=100, random_state=42) + model.fit(X, y) + + joblib.dump(model, os.path.join(MODELS_DIR, "rec_model.joblib")) + joblib.dump(le_soil, os.path.join(MODELS_DIR, "le_soil.joblib")) + joblib.dump(le_season, os.path.join(MODELS_DIR, "le_season.joblib")) + joblib.dump(le_rec, os.path.join(MODELS_DIR, "le_rec.joblib")) + print("✓ Recommendation model trained and saved.") + + +if __name__ == "__main__": + train_price_model() + train_rec_model() + print("All models ready.") diff --git a/backend/ml/utils.py b/backend/ml/utils.py new file mode 100644 index 0000000..9f4644d --- /dev/null +++ b/backend/ml/utils.py @@ -0,0 +1,84 @@ +import pandas as pd +import numpy as np +import os + + +def generate_price_data(file_path): + """Generate synthetic price training data.""" + np.random.seed(42) + crops = ['tomatoes', 'apples', 'potatoes', 'corn', 'wheat', 'mangoes', 'vegetable'] + months = list(range(1, 13)) + + data_price = [] + for _ in range(1000): + crop = np.random.choice(crops) + month = np.random.choice(months) + rainfall = np.random.uniform(50, 300) + + base_prices = { + 'tomatoes': 30, 'apples': 100, 'potatoes': 20, + 'corn': 20, 'wheat': 40, 'mangoes': 120, 'vegetable': 45 + } + + price = base_prices[crop] + if month in [3, 4, 5, 6]: # Summer + if crop == 'mangoes': + price *= 0.8 # Peak mango season → cheaper + if crop == 'tomatoes': + price *= 1.5 + elif month in [7, 8, 9, 10]: # Monsoon + price *= 1.2 + else: # Winter + if crop == 'apples': + price *= 0.9 + + price += (rainfall - 150) * 0.05 + data_price.append([crop, month, rainfall, price]) + + df_price = pd.DataFrame(data_price, columns=['category', 'month', 'rainfall', 'predicted_price']) + os.makedirs(os.path.dirname(file_path), exist_ok=True) + df_price.to_csv(file_path, index=False) + return df_price + + +def generate_rec_data(file_path): + """Generate synthetic crop recommendation training data.""" + np.random.seed(42) + soil_types = ['loamy', 'clay', 'sandy', 'alluvial', 'black', 'red', 'laterite'] + seasons = ['summer', 'winter', 'monsoon'] + + recommendations = { + ('loamy', 'summer'): 'Corn', + ('loamy', 'winter'): 'Wheat', + ('loamy', 'monsoon'): 'Paddy', + ('clay', 'summer'): 'Rice', + ('clay', 'winter'): 'Barley', + ('clay', 'monsoon'): 'Jute', + ('sandy', 'summer'): 'Groundnut', + ('sandy', 'winter'): 'Mustard', + ('sandy', 'monsoon'): 'Millets', + ('alluvial', 'summer'): 'Rice', + ('alluvial', 'winter'): 'Wheat', + ('alluvial', 'monsoon'): 'Jute', + ('black', 'summer'): 'Cotton', + ('black', 'winter'): 'Linseed', + ('black', 'monsoon'): 'Soybean', + ('red', 'summer'): 'Groundnut', + ('red', 'winter'): 'Tobacco', + ('red', 'monsoon'): 'Ragi', + ('laterite', 'summer'): 'Cashew', + ('laterite', 'winter'): 'Tea', + ('laterite', 'monsoon'): 'Rubber', + } + + data_rec = [] + for _ in range(500): + soil = np.random.choice(soil_types) + season = np.random.choice(seasons) + rec = recommendations.get((soil.lower(), season.lower()), 'Millets') + data_rec.append([soil, season, rec]) + + df_rec = pd.DataFrame(data_rec, columns=['soil', 'season', 'recommended_crop']) + os.makedirs(os.path.dirname(file_path), exist_ok=True) + df_rec.to_csv(file_path, index=False) + return df_rec diff --git a/backend/requirements.txt b/backend/requirements.txt new file mode 100644 index 0000000..e7c6f3b --- /dev/null +++ b/backend/requirements.txt @@ -0,0 +1,7 @@ + +fastapi +uvicorn +pandas +scikit-learn +joblib +numpy diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..4fa125d --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,29 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import { defineConfig, globalIgnores } from 'eslint/config' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{js,jsx}'], + extends: [ + js.configs.recommended, + reactHooks.configs.flat.recommended, + reactRefresh.configs.vite, + ], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + parserOptions: { + ecmaVersion: 'latest', + ecmaFeatures: { jsx: true }, + sourceType: 'module', + }, + }, + rules: { + 'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }], + }, + }, +]) diff --git a/index.html b/index.html new file mode 100644 index 0000000..ee1120e --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + devstakes + + +
+ + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..dad2d97 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2991 @@ +{ + "name": "devstakes", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "devstakes", + "version": "0.0.0", + "dependencies": { + "axios": "^1.15.0", + "lucide-react": "^1.7.0", + "react": "^19.2.4", + "react-dom": "^19.2.4", + "react-router-dom": "^7.14.0" + }, + "devDependencies": { + "@eslint/js": "^9.39.4", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^6.0.1", + "eslint": "^9.39.4", + "eslint-plugin-react-hooks": "^7.0.1", + "eslint-plugin-react-refresh": "^0.5.2", + "globals": "^17.4.0", + "vite": "^8.0.4" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz", + "integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz", + "integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.5" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", + "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.3.tgz", + "integrity": "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.123.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.123.0.tgz", + "integrity": "sha512-YtECP/y8Mj1lSHiUWGSRzy/C6teUKlS87dEfuVKT09LgQbUsBW1rNg+MiJ4buGu3yuADV60gbIvo9/HplA56Ew==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.13.tgz", + "integrity": "sha512-5ZiiecKH2DXAVJTNN13gNMUcCDg4Jy8ZjbXEsPnqa248wgOVeYRX0iqXXD5Jz4bI9BFHgKsI2qmyJynstbmr+g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.13.tgz", + "integrity": "sha512-tz/v/8G77seu8zAB3A5sK3UFoOl06zcshEzhUO62sAEtrEuW/H1CcyoupOrD+NbQJytYgA4CppXPzlrmp4JZKA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.13.tgz", + "integrity": "sha512-8DakphqOz8JrMYWTJmWA+vDJxut6LijZ8Xcdc4flOlAhU7PNVwo2MaWBF9iXjJAPo5rC/IxEFZDhJ3GC7NHvug==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.13.tgz", + "integrity": "sha512-4wBQFfjDuXYN/SVI8inBF3Aa+isq40rc6VMFbk5jcpolUBTe5cYnMsHZ51nFWsx3PVyyNN3vgoESki0Hmr/4BA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.13.tgz", + "integrity": "sha512-JW/e4yPIXLms+jmnbwwy5LA/LxVwZUWLN8xug+V200wzaVi5TEGIWQlh8o91gWYFxW609euI98OCCemmWGuPrw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.13.tgz", + "integrity": "sha512-ZfKWpXiUymDnavepCaM6KG/uGydJ4l2nBmMxg60Ci4CbeefpqjPWpfaZM7PThOhk2dssqBAcwLc6rAyr0uTdXg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.13.tgz", + "integrity": "sha512-bmRg3O6Z0gq9yodKKWCIpnlH051sEfdVwt+6m5UDffAQMUUqU0xjnQqqAUm+Gu7ofAAly9DqiQDtKu2nPDEABA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.13.tgz", + "integrity": "sha512-8Wtnbw4k7pMYN9B/mOEAsQ8HOiq7AZ31Ig4M9BKn2So4xRaFEhtCSa4ZJaOutOWq50zpgR4N5+L/opnlaCx8wQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.13.tgz", + "integrity": "sha512-D/0Nlo8mQuxSMohNJUF2lDXWRsFDsHldfRRgD9bRgktj+EndGPj4DOV37LqDKPYS+osdyhZEH7fTakTAEcW7qg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.13.tgz", + "integrity": "sha512-eRrPvat2YaVQcwwKi/JzOP6MKf1WRnOCr+VaI3cTWz3ZoLcP/654z90lVCJ4dAuMEpPdke0n+qyAqXDZdIC4rA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.13.tgz", + "integrity": "sha512-PsdONiFRp8hR8KgVjTWjZ9s7uA3uueWL0t74/cKHfM4dR5zXYv4AjB8BvA+QDToqxAFg4ZkcVEqeu5F7inoz5w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.13.tgz", + "integrity": "sha512-hCNXgC5dI3TVOLrPT++PKFNZ+1EtS0mLQwfXXXSUD/+rGlB65gZDwN/IDuxLpQP4x8RYYHqGomlUXzpO8aVI2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.13.tgz", + "integrity": "sha512-viLS5C5et8NFtLWw9Sw3M/w4vvnVkbWkO7wSNh3C+7G1+uCkGpr6PcjNDSFcNtmXY/4trjPBqUfcOL+P3sWy/g==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.9.1", + "@emnapi/runtime": "1.9.1", + "@napi-rs/wasm-runtime": "^1.1.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.1.tgz", + "integrity": "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.1.tgz", + "integrity": "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.0.tgz", + "integrity": "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.13.tgz", + "integrity": "sha512-Fqa3Tlt1xL4wzmAYxGNFV36Hb+VfPc9PYU+E25DAnswXv3ODDu/yyWjQDbXMo5AGWkQVjLgQExuVu8I/UaZhPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.13.tgz", + "integrity": "sha512-/pLI5kPkGEi44TDlnbio3St/5gUFeN51YWNAk/Gnv6mEQBOahRBh52qVFVBpmrnU01n2yysvBML9Ynu7K4kGAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.7", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.7.tgz", + "integrity": "sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", + "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.1.tgz", + "integrity": "sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "1.0.0-rc.7" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", + "babel-plugin-react-compiler": "^1.0.0", + "vite": "^8.0.0" + }, + "peerDependenciesMeta": { + "@rolldown/plugin-babel": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + } + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.0.tgz", + "integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", + "proxy-from-env": "^2.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.16", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.16.tgz", + "integrity": "sha512-Lyf3aK28zpsD1yQMiiHD4RvVb6UdMoo8xzG2XzFIfR9luPzOpcBlAsT/qfB1XWS1bxWT+UtE4WmQgsp297FYOA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001787", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001787.tgz", + "integrity": "sha512-mNcrMN9KeI68u7muanUpEejSLghOKlVhRqS/Za2IeyGllJ9I9otGpR9g3nsw7n4W378TE/LyIteA0+/FOZm4Kg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.334", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.334.tgz", + "integrity": "sha512-mgjZAz7Jyx1SRCwEpy9wefDS7GvNPazLthHg8eQMJ76wBdGQQDW33TCrUTvQ4wzpmOrv2zrFoD3oNufMdyMpog==", + "dev": true, + "license": "ISC" + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", + "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.5", + "@eslint/js": "9.39.4", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.5", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.0.1.tgz", + "integrity": "sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.24.4", + "@babel/parser": "^7.24.4", + "hermes-parser": "^0.25.1", + "zod": "^3.25.0 || ^4.0.0", + "zod-validation-error": "^3.5.0 || ^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.5.2.tgz", + "integrity": "sha512-hmgTH57GfzoTFjVN0yBwTggnsVUF2tcqi7RJZHqi9lIezSs4eFyAMktA68YD4r5kNw1mxyY4dmkyoFDb3FIqrA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": "^9 || ^10" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.4.0.tgz", + "integrity": "sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hermes-estree": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", + "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==", + "dev": true, + "license": "MIT" + }, + "node_modules/hermes-parser": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", + "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hermes-estree": "0.25.1" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lucide-react": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.7.0.tgz", + "integrity": "sha512-yI7BeItCLZJTXikmK4KNUGCKoGzSvbKlfCvw44bU4fXAL6v3gYS4uHD1jzsLkfwODYwI6Drw5Tu9Z5ulDe0TSg==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.37", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.37.tgz", + "integrity": "sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==", + "dev": true, + "license": "MIT" + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.9", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.9.tgz", + "integrity": "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/react": { + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", + "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", + "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.4" + } + }, + "node_modules/react-router": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.14.0.tgz", + "integrity": "sha512-m/xR9N4LQLmAS0ZhkY2nkPA1N7gQ5TUVa5n8TgANuDTARbn1gt+zLPXEm7W0XDTbrQ2AJSJKhoa6yx1D8BcpxQ==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.14.0.tgz", + "integrity": "sha512-2G3ajSVSZMEtmTjIklRWlNvo8wICEpLihfD/0YMDxbWK2UyP5EGfnoIn9AIQGnF3G/FX0MRbHXdFcD+rL1ZreQ==", + "license": "MIT", + "dependencies": { + "react-router": "7.14.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/rolldown": { + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.13.tgz", + "integrity": "sha512-bvVj8YJmf0rq4pSFmH7laLa6pYrhghv3PRzrCdRAr23g66zOKVJ4wkvFtgohtPLWmthgg8/rkaqRHrpUEh0Zbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.123.0", + "@rolldown/pluginutils": "1.0.0-rc.13" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.0-rc.13", + "@rolldown/binding-darwin-arm64": "1.0.0-rc.13", + "@rolldown/binding-darwin-x64": "1.0.0-rc.13", + "@rolldown/binding-freebsd-x64": "1.0.0-rc.13", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.13", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.13", + "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.13", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.13", + "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.13", + "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.13", + "@rolldown/binding-linux-x64-musl": "1.0.0-rc.13", + "@rolldown/binding-openharmony-arm64": "1.0.0-rc.13", + "@rolldown/binding-wasm32-wasi": "1.0.0-rc.13", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.13", + "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.13" + } + }, + "node_modules/rolldown/node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.13", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.13.tgz", + "integrity": "sha512-3ngTAv6F/Py35BsYbeeLeecvhMKdsKm4AoOETVhAA+Qc8nrA2I0kF7oa93mE9qnIurngOSpMnQ0x2nQY2FPviA==", + "dev": true, + "license": "MIT" + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/vite": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.7.tgz", + "integrity": "sha512-P1PbweD+2/udplnThz3btF4cf6AgPky7kk23RtHUkJIU5BIxwPprhRGmOAHs6FTI7UiGbTNrgNP6jSYD6JaRnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.32.0", + "picomatch": "^4.0.4", + "postcss": "^8.5.8", + "rolldown": "1.0.0-rc.13", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.1.0", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", + "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-validation-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz", + "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..6a1b614 --- /dev/null +++ b/package.json @@ -0,0 +1,30 @@ +{ + "name": "devstakes", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "axios": "^1.15.0", + "lucide-react": "^1.7.0", + "react": "^19.2.4", + "react-dom": "^19.2.4", + "react-router-dom": "^7.14.0" + }, + "devDependencies": { + "@eslint/js": "^9.39.4", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^6.0.1", + "eslint": "^9.39.4", + "eslint-plugin-react-hooks": "^7.0.1", + "eslint-plugin-react-refresh": "^0.5.2", + "globals": "^17.4.0", + "vite": "^8.0.4" + } +} diff --git a/public/assets/apples.png b/public/assets/apples.png new file mode 100644 index 0000000..d64ab16 Binary files /dev/null and b/public/assets/apples.png differ diff --git a/public/assets/corn.png b/public/assets/corn.png new file mode 100644 index 0000000..277d4ea Binary files /dev/null and b/public/assets/corn.png differ diff --git a/public/assets/mango.png b/public/assets/mango.png new file mode 100644 index 0000000..f0616d6 Binary files /dev/null and b/public/assets/mango.png differ diff --git a/public/assets/potatoes.png b/public/assets/potatoes.png new file mode 100644 index 0000000..88199d8 Binary files /dev/null and b/public/assets/potatoes.png differ diff --git a/public/assets/tomatoes.png b/public/assets/tomatoes.png new file mode 100644 index 0000000..d9ef545 Binary files /dev/null and b/public/assets/tomatoes.png differ diff --git a/public/assets/wheat.png b/public/assets/wheat.png new file mode 100644 index 0000000..8827d24 Binary files /dev/null and b/public/assets/wheat.png differ diff --git a/public/favicon.svg b/public/favicon.svg new file mode 100644 index 0000000..6893eb1 --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons.svg b/public/icons.svg new file mode 100644 index 0000000..e952219 --- /dev/null +++ b/public/icons.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/readme2.md b/readme2.md new file mode 100644 index 0000000..2fa1c77 --- /dev/null +++ b/readme2.md @@ -0,0 +1,252 @@ +# 🌾 Farm2City – Direct Farmer Marketplace (AI + ML Powered) + +Link -- https://devstakes-1.onrender.com/ + + +A modern, full-stack web application that connects farmers directly with buyers, eliminating middlemen and enabling fair pricing using AI and Machine Learning. + +--- + +## 🚀 Overview + +**Farm2City** is a responsive and intelligent marketplace platform where: + +* Farmers can list and manage their products +* Buyers can browse, filter, and purchase items +* AI assists with price prediction, recommendations, and chatbot support + +Built with: + +* **Frontend:** React +* **Backend:** FastAPI +* **Machine Learning:** scikit-learn + +--- + +## ✨ Features + +### 🔐 Authentication + +* Login / Signup system +* Role-based access: + + * Farmer + * Buyer + +--- + +### 🌾 Farmer Dashboard + +* Add products (name, price, quantity, image, category) +* AI-based **price prediction** +* View, update, delete products +* Crop recommendation system + +--- + +### 🛒 Buyer Marketplace + +* Browse products in modern card layout +* Filter by category and price +* View product details +* Add to cart and place orders + +--- + +### 🤖 AI Chatbot + +* Floating chatbot UI +* Answers: + + * Crop prices + * Farming tips + * Platform help + +--- + +### 🧠 Machine Learning Features + +#### 1. Smart Price Prediction + +* Predicts product price based on: + + * category + * month + * rainfall (dummy/real) +* Built using regression model + +#### 2. Crop Recommendation + +* Suggests crops based on: + + * soil type + * season + +#### 3. Intelligent Chatbot + +* Uses keyword-based NLP logic + +--- + +### 💬 Negotiation Chat + +* Simulated chat between buyer and farmer +* No real-time backend required + +--- + +### 📦 Order System + +* Add to cart +* Place order +* Order confirmation + +--- + +### 🎨 UI/UX Highlights + +* Dark gradient theme (black → purple/blue) +* Glassmorphism cards +* Smooth animations +* Responsive design +* Clean and modern layout + +--- + +## 🧱 Tech Stack + +| Layer | Technology | +| --------- | ------------- | +| Frontend | React | +| Backend | FastAPI | +| ML | scikit-learn | +| Database | SQLite / JSON | +| API Calls | Axios | + +--- + +## 📁 Project Structure + +``` +farm2city/ +│ +├── frontend/ (React) +│ ├── src/ +│ ├── components/ +│ ├── pages/ +│ └── App.js +│ +├── backend/ (FastAPI) +│ ├── main.py +│ ├── routes/ +│ ├── models/ +│ ├── ml/ +│ │ ├── train.py +│ │ ├── model.pkl +│ │ └── utils.py +│ +└── README.md +``` + +--- + +## ⚙️ Installation & Setup + +### 🔹 Backend (FastAPI) + +```bash +cd backend +pip install -r requirements.txt +uvicorn main:app --reload +``` + +--- + +### 🔹 Frontend (React) + +```bash +cd frontend +npm install +npm start +``` + +--- + +## 🔗 API Endpoints + +### Auth + +* `POST /signup` +* `POST /login` + +### Products + +* `GET /products` +* `POST /products` +* `PUT /products/{id}` +* `DELETE /products/{id}` + +### ML APIs + +* `GET /predict-price` +* `GET /recommend-crop` + +### Orders + +* `POST /orders` +* `GET /orders` + +### Chatbot + +* `POST /chat` + +--- + +## 📊 Machine Learning Workflow + +1. Train model using CSV dataset +2. Save model using joblib +3. Load model in FastAPI +4. Serve predictions via API +5. Display results in React UI + +--- + +## ⚡ Performance + +* Fast API responses (<500ms) +* Optimized React rendering +* Minimal loading states +* Smooth UX across devices + +--- + +## ❌ Constraints + +* No heavy deep learning frameworks +* No overcomplicated architecture +* Focus on usability and speed + +--- + +## 🌟 Future Improvements + +* Real-time chat (WebSockets) +* Payment gateway integration +* Advanced ML models +* Location-based recommendations + +--- + + +## 💡 Inspiration + +Bridging the gap between farmers and consumers using technology, AI, and data-driven insights. + +--- + +## ⭐ Final Note + +This project demonstrates how a **simple idea + clean execution + AI integration** can create a powerful real-world solution. + +--- diff --git a/src/App.jsx b/src/App.jsx new file mode 100644 index 0000000..6f58be5 --- /dev/null +++ b/src/App.jsx @@ -0,0 +1,54 @@ +import { useState } from 'react' +import { Routes, Route, Navigate } from 'react-router-dom' +import Navbar from './components/Navbar' +import Home from './pages/Home' +import Marketplace from './pages/Marketplace' +import ProductDetails from './pages/ProductDetails' +import Cart from './pages/Cart' +import Profile from './pages/Profile' +import Dashboard from './pages/Dashboard' +import Chat from './pages/Chat' +import Login from './pages/Login' +import AIChatbot from './components/AIChatbot' + +function App() { + const [cart, setCart] = useState([]) + const [user, setUser] = useState(null) + + const addToCart = (product) => { + setCart((prev) => { + const existing = prev.find(item => item.id === product.id) + if (existing) { + return prev.map(item => item.id === product.id ? { ...item, quantity: item.quantity + 1 } : item) + } + return [...prev, { ...product, quantity: 1 }] + }) + } + + const removeFromCart = (id) => { + setCart(prev => prev.filter(item => item.id !== id)) + } + + return ( +
+ acc + item.quantity, 0)} user={user} setUser={setUser} /> + +
+ + } /> + } /> + } /> + } /> + } /> + : } /> + : } /> + : } /> + +
+ + +
+ ) +} + +export default App diff --git a/src/components/AIChatbot.jsx b/src/components/AIChatbot.jsx new file mode 100644 index 0000000..7daffab --- /dev/null +++ b/src/components/AIChatbot.jsx @@ -0,0 +1,210 @@ +import { useState, useEffect, useRef } from 'react' +import { MessageCircle, X, Send, Bot } from 'lucide-react' +import axios from 'axios' + +const API = 'http://localhost:8000' + +const SUGGESTIONS = [ + 'What should I grow in black soil in monsoon?', + 'What is the price of tomatoes?', + 'Give me farming tips', + 'How do I use the platform?', +] + +export default function AIChatbot() { + const [isOpen, setIsOpen] = useState(false) + const [messages, setMessages] = useState([ + { + text: "Hi! 👋 I'm AgriBot, your AI farming assistant. Ask me about crop prices, recommendations, farming tips, or how to use Farm2City!", + isBot: true, + }, + ]) + const [input, setInput] = useState('') + const [isTyping, setIsTyping] = useState(false) + const bottomRef = useRef(null) + + // Auto-scroll to latest message + useEffect(() => { + if (bottomRef.current) bottomRef.current.scrollIntoView({ behavior: 'smooth' }) + }, [messages, isTyping]) + + const sendMessage = async (text) => { + const query = (text || input).trim() + if (!query) return + + setMessages(prev => [...prev, { text: query, isBot: false }]) + setInput('') + setIsTyping(true) + + try { + const { data } = await axios.post(`${API}/chat`, { query }) + setMessages(prev => [...prev, { text: data.reply, isBot: true }]) + } catch { + setMessages(prev => [...prev, { + text: '⚠️ Unable to connect to the AI server. Please make sure the backend is running.', + isBot: true, + }]) + } finally { + setIsTyping(false) + } + } + + return ( + <> + {/* Floating toggle button */} + + + {/* Chat panel */} + {isOpen && ( +
+ {/* Header */} +
+
+ +
+
+
AgriBot AI
+
+ + Online · ML-powered +
+
+
+ + {/* Messages */} +
+ {messages.map((msg, i) => ( +
+ {msg.text} +
+ ))} + + {/* Typing indicator */} + {isTyping && ( +
+ {[0, 0.2, 0.4].map((delay, i) => ( + + ))} +
+ )} +
+
+ + {/* Quick suggestions (shown when empty) */} + {messages.length === 1 && ( +
+ {SUGGESTIONS.map((s, i) => ( + + ))} +
+ )} + + {/* Input */} +
+ setInput(e.target.value)} + onKeyDown={e => e.key === 'Enter' && sendMessage()} + placeholder="Ask AgriBot…" + style={{ + flex: 1, background: 'rgba(0,0,0,0.25)', border: '1px solid var(--glass-border)', + borderRadius: '20px', padding: '0.65rem 1rem', color: 'white', outline: 'none', + fontSize: '0.9rem', + }} + /> + +
+
+ )} + + ) +} diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx new file mode 100644 index 0000000..98d8c10 --- /dev/null +++ b/src/components/Navbar.jsx @@ -0,0 +1,113 @@ +import { Link, useLocation, useNavigate } from 'react-router-dom' +import { ShoppingCart, User, Sprout, LayoutDashboard, MessageSquare, LogOut } from 'lucide-react' + +export default function Navbar({ cartCount, user, setUser }) { + const location = useLocation() + const navigate = useNavigate() + + const isActive = (path) => location.pathname === path + + const handleSignOut = () => { + setUser(null) + navigate('/') + } + + return ( + + ) +} + +const navLinkStyle = { + display: 'flex', + alignItems: 'center', + gap: '0.5rem', + textDecoration: 'none', + fontWeight: 500, + transition: 'color 0.3s ease' +} diff --git a/src/components/ProductCard.jsx b/src/components/ProductCard.jsx new file mode 100644 index 0000000..bc9dc23 --- /dev/null +++ b/src/components/ProductCard.jsx @@ -0,0 +1,60 @@ +import { ShoppingCart, Heart, Star } from 'lucide-react' +import { Link } from 'react-router-dom' + +export default function ProductCard({ product, addToCart }) { + return ( +
+
+ {product.name} +
+ +
+
+ +
+
+

{product.name}

+
+ {product.rating} +
+
+ +

+ By {product.farmer} +

+ +
+
+ ₹{product.price.toFixed(2)}/{product.unit} +
+
+ + Details + + +
+
+
+
+ ) +} diff --git a/src/data/mockData.js b/src/data/mockData.js new file mode 100644 index 0000000..805c37f --- /dev/null +++ b/src/data/mockData.js @@ -0,0 +1,70 @@ +export const products = [ + { + id: 1, + name: 'Organic Red Tomatoes', + price: 40, + unit: 'kg', + farmer: 'Green Valley Farm', + rating: 4.8, + category: 'Vegetables', + image: '/assets/tomatoes.png', + description: 'Fresh, vine-ripened organic tomatoes packed with flavor. Grown without synthetic pesticides.' + }, + { + id: 2, + name: 'Crisp Orchard Apples', + price: 120, + unit: 'kg', + farmer: 'Sunny Hill Orchards', + rating: 4.9, + category: 'Fruits', + image: '/assets/apples.png', + description: 'Hand-picked, perfectly crisp apples directly from our orchard.' + }, + { + id: 3, + name: 'Rustic Farm Potatoes', + price: 30, + unit: 'kg', + farmer: 'Earth Roots Co.', + rating: 4.6, + category: 'Vegetables', + image: '/assets/potatoes.png', + description: 'Freshly harvested organic potatoes, perfect for mashing, roasting, or boiling.' + }, + { + id: 4, + name: 'Golden Sweet Corn', + price: 25, + unit: 'kg', + farmer: 'Sunshine Acres', + rating: 4.7, + category: 'Vegetables', + image: '/assets/corn.png', + description: 'Freshly harvested organic golden sweet corn perfect for roasting or boiling.' + }, + { + id: 5, + name: 'Organic Golden Wheat', + price: 55, + unit: 'kg', + farmer: 'Amber Waves Farm', + rating: 4.5, + category: 'Grains', + image: '/assets/wheat.png', + description: 'High quality golden organic wheat stalks harvested with care.' + }, + { + id: 6, + name: 'Ripe Yellow Mangoes', + price: 150, + unit: 'kg', + farmer: 'Tropical Harvest', + rating: 4.9, + category: 'Fruits', + image: '/assets/mango.png', + description: 'Fresh, sweet, and juicy hand-picked tropical organic yellow mangoes.' + } +] + +export const heroImage = 'https://images.unsplash.com/photo-1500937386664-56d1dfef3854?q=80&w=2070&auto=format&fit=crop' diff --git a/src/index.css b/src/index.css new file mode 100644 index 0000000..d47d4da --- /dev/null +++ b/src/index.css @@ -0,0 +1,161 @@ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&family=Poppins:wght@400;500;600;700&display=swap'); + +:root { + --bg-gradient: #ffffff; + --glass-bg: #f7fdf0; + --glass-border: #d4eeb5; + --glass-shadow: 0 4px 15px rgba(0, 0, 0, 0.05); + --text-primary: #1b3a0a; + --text-secondary: #4a7d25; + --accent-color: #6fb526; + --accent-hover: #5d971e; + --success-color: #10b981; + --danger-color: #ef4444; +} + +* { + box-sizing: border-box; + margin: 0; + padding: 0; + font-family: 'Inter', sans-serif; +} + +h1, h2, h3, h4, h5, h6, .poppins { + font-family: 'Poppins', sans-serif; +} + +body { + background: var(--bg-gradient); + background-attachment: fixed; + color: var(--text-primary); + min-height: 100vh; + overflow-x: hidden; +} + +/* Glassmorphism Utilities */ +.glass-panel { + background: var(--glass-bg); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + border: 1px solid var(--glass-border); + box-shadow: var(--glass-shadow); + border-radius: 16px; +} + +.glass-card { + background: var(--glass-bg); + backdrop-filter: blur(8px); + -webkit-backdrop-filter: blur(8px); + border: 1px solid var(--glass-border); + border-radius: 16px; + transition: transform 0.3s ease, box-shadow 0.3s ease, background 0.3s ease; + overflow: hidden; +} + +.glass-card:hover { + transform: translateY(-5px); + box-shadow: 0 15px 35px rgba(0, 0, 0, 0.5); + background: rgba(255, 255, 255, 0.08); +} + +/* Buttons */ +.btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + padding: 0.75rem 1.5rem; + border-radius: 8px; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + border: none; + font-family: 'Poppins', sans-serif; +} + +.btn-primary { + background: linear-gradient(135deg, #8ad33b, #65a822); + color: white; + box-shadow: 0 4px 15px rgba(101, 168, 34, 0.3); +} + +.btn-primary:hover { + background: linear-gradient(135deg, #74b82d, #528c19); + box-shadow: 0 6px 20px rgba(101, 168, 34, 0.5); + transform: translateY(-2px); +} + +.btn-secondary { + background: transparent; + color: var(--text-primary); + border: 1px solid var(--accent-color); +} + +.btn-secondary:hover { + background: rgba(111, 181, 38, 0.1); + border-color: var(--accent-hover); +} + +/* Animations */ +@keyframes fadeIn { + from { opacity: 0; transform: translateY(20px); } + to { opacity: 1; transform: translateY(0); } +} + +.animate-fade-in { + animation: fadeIn 0.6s ease-out forwards; +} + +@keyframes pulse-glow { + 0% { box-shadow: 0 0 0 0 rgba(114, 184, 38, 0.4); } + 70% { box-shadow: 0 0 0 15px rgba(114, 184, 38, 0); } + 100% { box-shadow: 0 0 0 0 rgba(114, 184, 38, 0); } +} + +/* Layout */ +.container { + max-width: 1280px; + margin: 0 auto; + padding: 0 1.5rem; +} + +/* Utilities */ +.text-gradient { + background: linear-gradient(to right, #b4f177, #72b826, #40750e); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.floating-dots { + display: flex; + gap: 4px; +} +.floating-dots span { + width: 6px; + height: 6px; + background: currentColor; + border-radius: 50%; + animation: bounce 1.4s infinite ease-in-out both; +} +.floating-dots span:nth-child(1) { animation-delay: -0.32s; } +.floating-dots span:nth-child(2) { animation-delay: -0.16s; } + +@keyframes bounce { + 0%, 80%, 100% { transform: scale(0); } + 40% { transform: scale(1); } +} + +::-webkit-scrollbar { + width: 8px; +} +::-webkit-scrollbar-track { + background: #f7fdf0; +} +::-webkit-scrollbar-thumb { + background: #d4eeb5; + border-radius: 4px; +} +::-webkit-scrollbar-thumb:hover { + background: #6fb526; +} diff --git a/src/main.jsx b/src/main.jsx new file mode 100644 index 0000000..f4fa3e5 --- /dev/null +++ b/src/main.jsx @@ -0,0 +1,13 @@ +import React from 'react' +import ReactDOM from 'react-dom/client' +import { BrowserRouter } from 'react-router-dom' +import App from './App.jsx' +import './index.css' + +ReactDOM.createRoot(document.getElementById('root')).render( + + + + + , +) diff --git a/src/pages/Cart.jsx b/src/pages/Cart.jsx new file mode 100644 index 0000000..596cbca --- /dev/null +++ b/src/pages/Cart.jsx @@ -0,0 +1,129 @@ +import { useState } from 'react' +import { Link } from 'react-router-dom' +import { Trash2, ArrowRight, CheckCircle } from 'lucide-react' + +export default function Cart({ cart, removeFromCart, setCart }) { + const [success, setSuccess] = useState(false) + + const total = cart.reduce((acc, item) => acc + (item.price * item.quantity), 0) + + const updateQuantity = (id, delta) => { + setCart(prev => prev.map(item => { + if (item.id === id) { + const newQ = item.quantity + delta; + return { ...item, quantity: newQ > 0 ? newQ : 1 } + } + return item + })) + } + + if (success) { + return ( +
+
+ +

Order Placed!

+

+ Your order has been sent to the farmers. They will prepare your fresh produce for pick-up/delivery. +

+ + Continue Shopping + +
+
+ ) + } + + if (cart.length === 0) { + return ( +
+

Your Cart is Empty

+

Looks like you haven't added any fresh produce yet.

+ Browse Marketplace +
+ ) + } + + return ( +
+

Your Cart

+ +
+
+ {cart.map(item => ( +
+ {item.name} +
+

{item.name}

+

{item.farmer}

+
₹{item.price.toFixed(2)} / {item.unit}
+
+ +
+ + {item.quantity} + +
+ +
+ ₹{(item.price * item.quantity).toFixed(2)} +
+ + +
+ ))} +
+ +
+
+

Order Summary

+ +
+ Subtotal + ₹{total.toFixed(2)} +
+
+ Platform Fee + ₹{(total * 0.05).toFixed(2)} +
+ +
+ Total + ₹{(total * 1.05).toFixed(2)} +
+ + +
+
+
+
+ ) +} + +const qtyBtnStyle = { + background: 'transparent', + border: 'none', + color: 'white', + fontSize: '1.25rem', + cursor: 'pointer', + width: '30px', + height: '30px', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + borderRadius: '4px' +} diff --git a/src/pages/Chat.jsx b/src/pages/Chat.jsx new file mode 100644 index 0000000..b508482 --- /dev/null +++ b/src/pages/Chat.jsx @@ -0,0 +1,110 @@ +import { useState } from 'react' +import { Send, PhoneCall, Video } from 'lucide-react' + +export default function Chat() { + const [messages, setMessages] = useState([ + { text: "Hi, I'm interested in the organic tomatoes.", isMine: true }, + { text: "Hello! They are fresh out of the field today. How many kg do you need?", isMine: false, sender: "Green Valley Farm" }, + { text: "I need around 10 kg. Can we do ₹380 total?", isMine: true } + ]) + const [input, setInput] = useState('') + + const handleSend = () => { + if (!input.trim()) return + setMessages([...messages, { text: input, isMine: true }]) + setInput('') + + // Mock response + setTimeout(() => { + setMessages(prev => [...prev, { text: "Sure, I can do ₹380 for 10 kg. I'll update the price for you to checkout.", isMine: false, sender: "Green Valley Farm" }]) + }, 1500) + } + + return ( +
+ +
+ + {/* Contact List Sidebar */} +
+
+

Messages

+
+ +
+
+
Green Valley Farm
+
+ Sure, I can do $22 for 10 lbs... +
+
+ {/* Add more mock contacts as needed */} +
+
+ + {/* Chat Window */} +
+ +
+
+
+ GV +
+
+

Green Valley Farm

+ Online +
+
+
+ + +
+
+ +
+ {messages.map((msg, i) => ( +
+ {!msg.isMine &&
{msg.sender}
} +
+ {msg.text} +
+
+ ))} +
+ +
+ setInput(e.target.value)} + onKeyDown={(e) => e.key === 'Enter' && handleSend()} + placeholder="Type your message..." + style={{ + flex: 1, + background: 'rgba(0,0,0,0.2)', + border: '1px solid var(--glass-border)', + borderRadius: '8px', + padding: '0 1.5rem', + color: 'white', + outline: 'none' + }} + /> + +
+ +
+ +
+
+ ) +} diff --git a/src/pages/Dashboard.jsx b/src/pages/Dashboard.jsx new file mode 100644 index 0000000..6e95b31 --- /dev/null +++ b/src/pages/Dashboard.jsx @@ -0,0 +1,318 @@ +import { useState } from 'react' +import { + PlusCircle, + Package as PkgIcon, + DollarSign, + Activity, + Image as ImageIcon, + Sparkles, + Droplets, + Calendar, + Leaf, +} from 'lucide-react' +import axios from 'axios' +import { products } from '../data/mockData' + +const API = 'http://localhost:8000' + +export default function Dashboard() { + const [activeTab, setActiveTab] = useState('add') + + // ── Add Product state ────────────────────────────────────────────────────── + const [cropType, setCropType] = useState('tomatoes') + const [month, setMonth] = useState(new Date().getMonth() + 1) + const [rainfall, setRainfall] = useState(150) + const [price, setPrice] = useState('') + const [suggestedPrice, setSuggestedPrice] = useState(null) + const [priceLoading, setPriceLoading] = useState(false) + const [priceError, setPriceError] = useState(null) + + // ── Crop Recommendation state ────────────────────────────────────────────── + const [soilType, setSoilType] = useState('loamy') + const [season, setSeason] = useState('summer') + const [recommendation, setRecommendation] = useState(null) + const [recLoading, setRecLoading] = useState(false) + const [recError, setRecError] = useState(null) + + // ── Handlers ─────────────────────────────────────────────────────────────── + const handleSuggest = async () => { + setPriceLoading(true) + setSuggestedPrice(null) + setPriceError(null) + try { + const { data } = await axios.get(`${API}/predict-price`, { + params: { category: cropType, month: Number(month), rainfall: Number(rainfall) }, + }) + setSuggestedPrice(data.predicted_price) + } catch { + setPriceError('Could not reach the AI server. Is the backend running?') + } finally { + setPriceLoading(false) + } + } + + const handleRecommend = async () => { + setRecLoading(true) + setRecommendation(null) + setRecError(null) + try { + const { data } = await axios.get(`${API}/recommend-crop`, { + params: { soil: soilType, season }, + }) + setRecommendation(data.recommended_crop) + } catch { + setRecError('Could not reach the AI server. Is the backend running?') + } finally { + setRecLoading(false) + } + } + + // ── Render ───────────────────────────────────────────────────────────────── + return ( +
+ {/* Header */} +
+

Farmer Dashboard

+
+ + Status: Active +
+
+ +
+ + {/* ── Sidebar ── */} +
+ {[ + { key: 'add', icon: , label: 'Add Product' }, + { key: 'manage', icon: , label: 'My Products' }, + { key: 'ai', icon: , label: 'AI Insights' }, + ].map(({ key, icon, label }) => ( + + ))} +
+ + {/* ── Content ── */} +
+ + {/* ── Add Product Tab ── */} + {activeTab === 'add' && ( +
+

Add New Product

+ +
+ {/* Left column */} +
+ + {/* Crop type */} +
+ + +
+ + {/* Month + Rainfall */} +
+
+ + setMonth(e.target.value)} style={inputStyle} /> +
+
+ + setRainfall(e.target.value)} style={inputStyle} /> +
+
+ + {/* Price + AI Suggest */} +
+ +
+
+ + setPrice(e.target.value)} + placeholder="0.00" + style={{ ...inputStyle, paddingLeft: '2.5rem' }} + /> +
+ +
+
+ + {/* Price result */} + {suggestedPrice !== null && ( +
+
+
AI Suggested Price
+
₹{suggestedPrice} / kg
+
+ +
+ )} + {priceError &&
{priceError}
} + + +
+ + {/* Right column — image upload */} +
+ +
+ +

Click or drag image to upload

+
+
+
+
+ )} + + {/* ── My Products Tab ── */} + {activeTab === 'manage' && ( +
+

My Listed Products

+ + + + {['Product', 'Category', 'Price', 'Status'].map(h => ( + + ))} + + + + {products.slice(0, 4).map((p, i) => ( + + + + + + + ))} + +
{h}
+ {p.name} + {p.name} + {p.category}₹{p.price.toFixed(2)} + Active +
+
+ )} + + {/* ── AI Insights Tab ── */} + {activeTab === 'ai' && ( +
+
+ +

AI Crop Suggestions

+
+

+ Get ML-powered recommendations on what to grow based on your soil type and the current season. +

+ +
+
+ + +
+
+ + +
+
+ + + + {recommendation && ( +
+

Best crop for {soilType} soil · {season}

+
{recommendation}
+

+ Our ML model predicts {recommendation} will yield + the best results and market demand for {soilType} soil during {season}. +

+
+ )} + {recError &&
{recError}
} +
+ )} + +
+
+
+ ) +} + +// ── Styles ───────────────────────────────────────────────────────────────────── +const tabStyle = { + width: '100%', padding: '1rem', background: 'transparent', border: 'none', + color: 'var(--text-secondary)', textAlign: 'left', borderRadius: '8px', + cursor: 'pointer', display: 'flex', alignItems: 'center', gap: '0.75rem', + fontSize: '1rem', marginBottom: '0.5rem', transition: 'all 0.2s', +} +const activeTabStyle = { ...tabStyle, background: 'rgba(114,184,38,0.15)', color: 'var(--text-primary)' } +const labelStyle = { display: 'block', marginBottom: '0.5rem', color: 'var(--text-secondary)', fontSize: '0.9rem' } +const inputStyle = { + width: '100%', background: 'var(--glass-bg)', border: '1px solid var(--glass-border)', + color: 'var(--text-primary)', padding: '0.75rem 1rem', borderRadius: '8px', outline: 'none', + boxSizing: 'border-box', +} +const tdStyle = { + padding: '1rem', borderBottom: '1px solid rgba(255,255,255,0.05)', + display: 'table-cell', verticalAlign: 'middle', +} +const suggestBoxStyle = { + padding: '1rem 1.25rem', background: 'rgba(114,184,38,0.1)', + border: '1px solid #72b826', borderRadius: '10px', + display: 'flex', justifyContent: 'space-between', alignItems: 'center', +} +const errorStyle = { + padding: '0.75rem 1rem', background: 'rgba(239,68,68,0.1)', + border: '1px solid rgba(239,68,68,0.4)', borderRadius: '8px', + color: '#fca5a5', fontSize: '0.9rem', +} +const dotStyle = { + display: 'inline-block', + animation: 'bounce 1s infinite', +} diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx new file mode 100644 index 0000000..17126ff --- /dev/null +++ b/src/pages/Home.jsx @@ -0,0 +1,91 @@ +import { Link } from 'react-router-dom' +import { ArrowRight, Leaf, ShieldCheck, TrendingDown } from 'lucide-react' +import { heroImage } from '../data/mockData' + +export default function Home() { + return ( +
+
+
+
+ +
+

+ Connecting Farmers Direct to Consumers +

+

+ Bypass the middlemen. Buy fresh, organic produce directly from local farmers with AI-driven fair pricing and transparent sourcing. +

+
+ + Explore Marketplace + + + Get Started + +
+
+
+ +
+
+ +
+
+ +
+

Direct Buying

+

Get products directly from the farm to your table, ensuring maximum freshness.

+
+ +
+
+ +
+

AI Price Suggestions

+

Our smart algorithms suggest realistic, fair prices based on market trends.

+
+ +
+
+ +
+

Transparent Pricing

+

No hidden fees. Every transaction is 100% transparent and direct.

+
+ +
+
+ +
+
+

Thought of the Day

+

+ "The discovery of agriculture was the first big step toward a civilized life." +

+

— Arthur Keith

+
+
+
+ ) +} diff --git a/src/pages/Login.jsx b/src/pages/Login.jsx new file mode 100644 index 0000000..9d1bf21 --- /dev/null +++ b/src/pages/Login.jsx @@ -0,0 +1,91 @@ +import { useState } from 'react' +import { useNavigate } from 'react-router-dom' +import { User, Tractor, ShieldCheck } from 'lucide-react' + +export default function Login({ setUser }) { + const navigate = useNavigate() + const [role, setRole] = useState('buyer') // 'buyer' or 'farmer' + + const handleLogin = (e) => { + e.preventDefault() + // Mock login by setting user state + setUser({ + name: role === 'farmer' ? 'Green Valley Farm' : 'John Doe', + role: role + }) + + // Redirect based on role + if (role === 'farmer') { + navigate('/dashboard') + } else { + navigate('/marketplace') + } + } + + return ( +
+
+ + {/* Decorative elements */} +
+
+ +
+
+
+ +
+

Welcome Back

+

Sign in to continue to Farm2City

+
+ +
+ + +
+ +
+
+ + +
+
+ + +
+ + +
+ +

+ By signing in, you agree to our Terms of Service & Privacy Policy. +

+
+
+
+ ) +} diff --git a/src/pages/Marketplace.jsx b/src/pages/Marketplace.jsx new file mode 100644 index 0000000..11d4f29 --- /dev/null +++ b/src/pages/Marketplace.jsx @@ -0,0 +1,87 @@ +import { useState } from 'react' +import ProductCard from '../components/ProductCard' +import { products as mockProducts } from '../data/mockData' +import { Filter, Search } from 'lucide-react' + +export default function Marketplace({ addToCart }) { + const [filter, setFilter] = useState('All') + const [search, setSearch] = useState('') + + const categories = ['All', 'Vegetables', 'Fruits', 'Grains'] + + const filteredProducts = mockProducts.filter(p => { + const matchesFilter = filter === 'All' || p.category === filter + const matchesSearch = p.name.toLowerCase().includes(search.toLowerCase()) + return matchesFilter && matchesSearch + }) + + return ( +
+
+
+

Fresh Marketplace

+

Support local farmers directly.

+
+ +
+
+ + setSearch(e.target.value)} + style={{ + background: 'var(--glass-bg)', + border: '1px solid var(--glass-border)', + padding: '0.75rem 1rem 0.75rem 3rem', + borderRadius: '8px', + color: 'var(--text-primary)', + outline: 'none', + minWidth: '250px' + }} + /> +
+ +
+ + {categories.map(c => ( + + ))} +
+
+
+ + {filteredProducts.length > 0 ? ( +
+ {filteredProducts.map(product => ( + + ))} +
+ ) : ( +
+

No products found

+

Try adjusting your search or filters.

+
+ )} +
+ ) +} diff --git a/src/pages/ProductDetails.jsx b/src/pages/ProductDetails.jsx new file mode 100644 index 0000000..f0e14de --- /dev/null +++ b/src/pages/ProductDetails.jsx @@ -0,0 +1,72 @@ +import { useParams, Link } from 'react-router-dom' +import { ShoppingCart, MessageSquare, ArrowLeft, Star, ShieldCheck } from 'lucide-react' +import { products } from '../data/mockData' + +export default function ProductDetails({ addToCart }) { + const { id } = useParams() + const product = products.find(p => p.id === parseInt(id)) + + if (!product) return
Product not found.
+ + return ( +
+ + Back to Marketplace + + +
+ +
+ {product.name} +
+ +
+
+ {product.category} + + + {product.rating} Rating + +
+ +

{product.name}

+

{product.description}

+ +
+
+ {product.farmer.charAt(0)} +
+
+

Farmer / Seller

+

{product.farmer}

+
+
+ Verified +
+
+ +
+ ₹{product.price.toFixed(2)} / {product.unit} +
+ +
+ + + + Negotiate with Farmer + +
+
+ +
+
+ ) +} diff --git a/src/pages/Profile.jsx b/src/pages/Profile.jsx new file mode 100644 index 0000000..f30a5a8 --- /dev/null +++ b/src/pages/Profile.jsx @@ -0,0 +1,96 @@ +import { User, MapPin, Phone, Package, Calendar, LogOut } from 'lucide-react' + +export default function Profile({ user }) { + const mockOrders = [ + { id: 'ORD-29381', date: 'Oct 14, 2026', total: 1250.50, status: 'Delivered', items: 3 }, + { id: 'ORD-29302', date: 'Oct 02, 2026', total: 600.00, status: 'Delivered', items: 1 } + ] + + return ( +
+

My Profile

+ +
+ + {/* Profile Details Sidebar */} +
+
+
+ +
+

{user.name}

+ + {user.role} + +
+ +
+
+ + +1 (555) 123-4567 +
+
+ + 123 Market St, San Francisco, CA +
+
+ + +
+ + {/* Order History */} +
+

Order History

+ +
+ {mockOrders.map(order => ( +
+
+
+ {order.id} +
+ + {order.status} + +
+ +
+
+ {order.date} +
+
+ {order.items} Items +
+
+ ₹{order.total.toFixed(2)} +
+
+
+ ))} +
+
+ +
+
+ ) +} diff --git a/teams/.gitkeep b/teams/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..8b0f57b --- /dev/null +++ b/vite.config.js @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react()], +})