The backend seeds an asset universe, ingests public OHLCV history, collects public RSS news, deduplicates articles, links them to assets and persists all artifacts in PostgreSQL.
diff --git a/.gitattributes b/.gitattributes index c43b349449557572b7cb58547bb0d8e2e5e2d055..ddbf8383809572f2d0ce704529959e24eac3069b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -39,3 +39,28 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text .upload-venv/lib/python3.13/site-packages/pip/_vendor/distlib/w64-arm.exe filter=lfs diff=lfs merge=lfs -text .upload-venv/lib/python3.13/site-packages/pip/_vendor/distlib/w64.exe filter=lfs diff=lfs merge=lfs -text .upload-venv/lib/python3.13/site-packages/yaml/_yaml.cpython-313-darwin.so filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/client-production/0.pack filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/client-production/1.pack filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/client-production/10.pack filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/client-production/11.pack filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/client-production/12.pack filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/client-production/13.pack filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/client-production/2.pack filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/client-production/6.pack filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/client-production/7.pack filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/client-production/8.pack filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/client-production/9.pack filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/client-production/index.pack filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/client-production/index.pack.old filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/server-production/0.pack filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/server-production/1.pack filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/server-production/10.pack filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/server-production/2.pack filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/server-production/3.pack filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/server-production/4.pack filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/server-production/5.pack filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/server-production/6.pack filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/server-production/7.pack filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/server-production/8.pack filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/server-production/index.pack filter=lfs diff=lfs merge=lfs -text +frontend/.next/cache/webpack/server-production/index.pack.old filter=lfs diff=lfs merge=lfs -text diff --git a/.next/trace b/.next/trace index 1056db43aa6f77dc8efbbc8d32b3604cbce3a341..3dfc952fb661f9726bb3907ccaa0f3f998393ac3 100644 --- a/.next/trace +++ b/.next/trace @@ -1,2 +1 @@ [{"name":"generate-buildid","duration":134,"timestamp":87872497011,"id":4,"parentId":1,"tags":{},"startTime":1782192543160,"traceId":"74c71a2e401cebbb"},{"name":"load-custom-routes","duration":113,"timestamp":87872497220,"id":5,"parentId":1,"tags":{},"startTime":1782192543160,"traceId":"74c71a2e401cebbb"},{"name":"next-build","duration":48980,"timestamp":87872449545,"id":1,"tags":{"buildMode":"default","isTurboBuild":"false","version":"14.2.35","isTurbopack":false},"startTime":1782192543112,"traceId":"74c71a2e401cebbb"}] -[{"name":"generate-buildid","duration":139,"timestamp":107902785130,"id":4,"parentId":1,"tags":{},"startTime":1782212573555,"traceId":"5254ca5a348315b0"},{"name":"load-custom-routes","duration":121,"timestamp":107902785349,"id":5,"parentId":1,"tags":{},"startTime":1782212573555,"traceId":"5254ca5a348315b0"},{"name":"next-build","duration":41482,"timestamp":107902744802,"id":1,"tags":{"buildMode":"default","isTurboBuild":"false","version":"14.2.35","isTurbopack":false},"startTime":1782212573514,"traceId":"5254ca5a348315b0"}] diff --git a/backend/app/core/config.py b/backend/app/core/config.py index a31148931bedec4370712b07db4aba0d86e1d777..cf6905a1356d8bd6dca884d89b1755a0db79a582 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -5,7 +5,7 @@ from pydantic_settings import BaseSettings class Settings(BaseSettings): app_name: str = "Blum AI Financial Intelligence" - app_version: str = "0.20.0" + app_version: str = "2.1.0" environment: str = Field(default="demo", alias="ENVIRONMENT") database_url: str = Field( default="postgresql+psycopg2://postgres:postgres@127.0.0.1:5432/blum", @@ -31,6 +31,9 @@ class Settings(BaseSettings): max_update_assets: int = Field(default=160, alias="BLUM_MAX_UPDATE_ASSETS") enable_live_startup: bool = Field(default=True, alias="BLUM_ENABLE_LIVE_STARTUP") enable_autonomous_engine: bool = Field(default=True, alias="BLUM_ENABLE_AUTONOMOUS_ENGINE") + startup_run_full_autonomous: bool = Field(default=False, alias="BLUM_STARTUP_RUN_FULL_AUTONOMOUS") + blum_autonomous_max_seconds_per_job: int = Field(default=120, alias="BLUM_AUTONOMOUS_MAX_SECONDS_PER_JOB") + blum_autonomous_max_items_per_job: int = Field(default=50, alias="BLUM_AUTONOMOUS_MAX_ITEMS_PER_JOB") autonomous_cycle_minutes: int = Field(default=20, alias="BLUM_AUTONOMOUS_CYCLE_MINUTES") autonomous_repair_limit: int = Field(default=80, alias="BLUM_AUTONOMOUS_REPAIR_LIMIT") seed_historical_prices_on_startup: bool = Field(default=True, alias="BLUM_SEED_HISTORICAL_PRICES_ON_STARTUP") @@ -49,6 +52,13 @@ class Settings(BaseSettings): learning_min_history_years: int = Field(default=3, alias="LEARNING_MIN_HISTORY_YEARS") learning_asset_universe: str = Field(default="stocks,etfs", alias="LEARNING_ASSET_UNIVERSE") learning_evaluation_mode: str = Field(default="walk_forward", alias="LEARNING_EVALUATION_MODE") + learning_random_sample_ratio: float = Field(default=0.40, alias="LEARNING_RANDOM_SAMPLE_RATIO") + learning_alpha_loss_sample_ratio: float = Field(default=0.30, alias="LEARNING_ALPHA_LOSS_SAMPLE_RATIO") + learning_factor_focus_sample_ratio: float = Field(default=0.20, alias="LEARNING_FACTOR_FOCUS_SAMPLE_RATIO") + learning_capital_preservation_sample_ratio: float = Field(default=0.10, alias="LEARNING_CAPITAL_PRESERVATION_SAMPLE_RATIO") + professional_learning_enabled: bool = Field(default=True, alias="BLUM_PROFESSIONAL_LEARNING_ENABLED") + professional_learning_minutes: int = Field(default=30, alias="BLUM_PROFESSIONAL_LEARNING_MINUTES") + professional_learning_batch_size: int = Field(default=20, alias="BLUM_PROFESSIONAL_LEARNING_BATCH_SIZE") blum_model_cycle_minutes: int = Field(default=5, alias="BLUM_MODEL_CYCLE_MINUTES") blum_model_cycle_limit: int = Field(default=160, alias="BLUM_MODEL_CYCLE_LIMIT") fundamentals_refresh_minutes: int = Field(default=720, alias="BLUM_FUNDAMENTALS_REFRESH_MINUTES") @@ -62,6 +72,7 @@ class Settings(BaseSettings): refresh_price_period: str = Field(default="6mo", alias="BLUM_REFRESH_PRICE_PERIOD") sec_user_agent: str = Field(default="Blum-AI-Financial-Intelligence research demo", alias="BLUM_SEC_USER_AGENT") blum_model_repository: str = Field(default="Italianhype/Blum", alias="BLUM_MODEL_REPOSITORY") + blum_analyst_repository: str = Field(default="Italianhype/Blum-Analyst", alias="BLUM_ANALYST_REPOSITORY") training_export_dir: str = Field(default="/tmp/blum_training_exports", alias="BLUM_TRAINING_EXPORT_DIR") enable_hf_dataset_catalog: bool = Field(default=True, alias="BLUM_ENABLE_HF_DATASET_CATALOG") hf_dataset_refresh_hours: int = Field(default=24, alias="BLUM_HF_DATASET_REFRESH_HOURS") diff --git a/backend/app/main.py b/backend/app/main.py index 02c1f1d4bcab6135552fd2eea9912d3eaea264cd..b3207f40ff9466cf5ae65ba3534971975e6c5f9a 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -9,7 +9,15 @@ from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import FileResponse from fastapi.staticfiles import StaticFiles -from app.api.routes import router +from app.api.routers import ( + alpha_router, + analyst_router, + brain_router, + legacy_router, + paper_trading_router, + runtime_router, + training_router, +) from app.core.config import get_settings from app.core.database import SessionLocal from app.services.bootstrap import bootstrap_database @@ -38,7 +46,13 @@ app.add_middleware( allow_headers=["*"], ) -app.include_router(router) +app.include_router(brain_router) +app.include_router(training_router) +app.include_router(paper_trading_router) +app.include_router(alpha_router) +app.include_router(runtime_router) +app.include_router(analyst_router) +app.include_router(legacy_router) @app.middleware("http") @@ -67,6 +81,13 @@ async def performance_timing_middleware(request: Request, call_next): duration_ms, {"method": request.method, "path": request.url.path, "referer": request.headers.get("referer", "")[:180]}, ) + if request.method.upper() == "GET" and "persist=true" in request.url.query.lower(): + response.headers["X-BLUM-GET-SIDE-EFFECT-RISK"] = "true" + performance_recorder.record_dashboard_widget( + "performance.GET_ENDPOINT_SIDE_EFFECT_DETECTED", + duration_ms, + {"method": request.method, "path": request.url.path, "query": request.url.query[:180]}, + ) return response finally: duration_ms = (time.perf_counter() - started) * 1000 @@ -106,6 +127,13 @@ def is_heavy_recalculation_call(method: str, path: str) -> bool: "/business-quality/recalculate", "/decision-intelligence/superiority/recalculate", "/learning-intelligence/self-improvement/generate", + "/api/meta-cognition/recalculate", + "/api/meta-cognition/factor-importance/recalculate", + "/api/meta-cognition/evaluate", + "/api/meta-cognition/capital-preservation/evaluate", + "/api/meta-cognition/learning-focus/generate", + "/api/meta-cognition/noise/detect", + "/snapshots/produce", ) return any(fragment in path for fragment in heavy_fragments) diff --git a/backend/app/services/autonomous_engine.py b/backend/app/services/autonomous_engine.py index 94517a0a72618e032c10a6e2441e44be4d092947..f47a4a0e0c1c51a28b6285914a3eeb9f55384443 100644 --- a/backend/app/services/autonomous_engine.py +++ b/backend/app/services/autonomous_engine.py @@ -34,6 +34,7 @@ from app.services.macro import update_macro_snapshots from app.services.market_data import MarketDataService from app.services.market_sniper import MarketSniperEngine from app.services.persistence import backup_embedded_postgres_if_configured +from app.services.research_planner import AutonomousResearchPlanner from app.services.trading_game import TradingGameSimulator from app.signals.engine import SignalEngine @@ -85,6 +86,7 @@ class AutonomousResearchEngine: stage("etf_intelligence", lambda: update_etf_trends(db)) stage("ipo_radar", lambda: update_ipo_radar(db, limit_per_form=55)) stage("accuracy_audit", lambda: run_accuracy_audit(db, limit=settings.max_update_assets)) + stage("research_planner", lambda: AutonomousResearchPlanner().generate(db, persist=True)) if settings.enable_learning_loop: stage("blum_financial_model", lambda: run_model_learning_cycle(db, limit=settings.blum_model_cycle_limit)) stage("blum_learning_loop", lambda: LearningLoopService().run_batch(db, batch_size=settings.learning_batch_size, trigger="autonomous_engine")) diff --git a/backend/app/services/blum_financial_model.py b/backend/app/services/blum_financial_model.py index 7ac0b47ff89aedce689122b9aa80ee63b90cc63c..adcd30bdedf59d25b2936746d7dfd4d8cb756ec4 100644 --- a/backend/app/services/blum_financial_model.py +++ b/backend/app/services/blum_financial_model.py @@ -96,7 +96,7 @@ def model_status(db: Session) -> dict: } -def run_model_learning_cycle(db: Session, limit: int = 120) -> dict: +def run_model_learning_cycle(db: Session, limit: int = 120, backup: bool = True) -> dict: signals = db.scalars(select(SignalSnapshot).order_by(desc(SignalSnapshot.created_at)).limit(limit)).all() skipped = 0 before_count = count(db, BlumKnowledgeRecord.id) @@ -127,7 +127,11 @@ def run_model_learning_cycle(db: Session, limit: int = 120) -> dict: ) db.add(event) db.commit() - backup_result = backup_embedded_postgres_if_configured(reason="blum_model_autonomous_cycle") + backup_result = ( + backup_embedded_postgres_if_configured(reason="blum_model_autonomous_cycle") + if backup + else {"status": "skipped", "reason": "frequent professional learning cycles do not run full embedded database backups"} + ) return { "status": "ok", "signals_seen": len(signals), diff --git a/backend/app/services/bootstrap.py b/backend/app/services/bootstrap.py index bb32c1072678cdde561ac7ebc52dc73423854723..750627a522716b5041452269c24296c54b0a6ada 100644 --- a/backend/app/services/bootstrap.py +++ b/backend/app/services/bootstrap.py @@ -3,6 +3,7 @@ from __future__ import annotations import csv from datetime import date import gzip +from gzip import BadGzipFile from pathlib import Path from sqlalchemy import func, select @@ -67,31 +68,49 @@ def seed_historical_prices(db: Session) -> dict: "inserted_rows": 0, "message": "Historical price cache is not packaged in this build.", } + pointer = git_lfs_pointer_summary(HISTORICAL_PRICE_CACHE) + if pointer: + return invalid_historical_cache_response( + "git_lfs_pointer", + ( + "Historical price cache is a Git LFS pointer, not the resolved gzip payload. " + "Run `git lfs pull` in development or ensure the Space resolves LFS assets. " + "Startup continues without synthetic market data." + ), + pointer, + ) asset_ids = dict(db.execute(select(Asset.ticker, Asset.id)).all()) inserted = 0 skipped = 0 tickers: set[str] = set() rows: list[dict] = [] - with gzip.open(HISTORICAL_PRICE_CACHE, "rt", newline="", encoding="utf-8") as handle: - reader = csv.DictReader(handle) - for item in reader: - ticker = (item.get("ticker") or "").upper() - asset_id = asset_ids.get(ticker) - if not asset_id: - skipped += 1 - continue - row = price_row_from_cache(asset_id, item) - if not row: - skipped += 1 - continue - tickers.add(ticker) - rows.append(row) - if len(rows) >= 5000: - inserted += insert_price_rows(db, rows) - rows.clear() - if rows: - inserted += insert_price_rows(db, rows) - db.commit() + try: + with gzip.open(HISTORICAL_PRICE_CACHE, "rt", newline="", encoding="utf-8") as handle: + reader = csv.DictReader(handle) + for item in reader: + ticker = (item.get("ticker") or "").upper() + asset_id = asset_ids.get(ticker) + if not asset_id: + skipped += 1 + continue + row = price_row_from_cache(asset_id, item) + if not row: + skipped += 1 + continue + tickers.add(ticker) + rows.append(row) + if len(rows) >= 5000: + inserted += insert_price_rows(db, rows) + rows.clear() + if rows: + inserted += insert_price_rows(db, rows) + db.commit() + except (BadGzipFile, EOFError, OSError, UnicodeDecodeError, csv.Error) as exc: + db.rollback() + return invalid_historical_cache_response( + "invalid", + f"Historical price cache could not be loaded ({type(exc).__name__}). Startup continues without synthetic market data.", + ) return { "enabled": True, "cache_status": "loaded", @@ -121,6 +140,35 @@ def seed_startup_accuracy(db: Session) -> dict: return {"enabled": True, **run_accuracy_audit(db, limit=get_settings().max_update_assets)} +def git_lfs_pointer_summary(path: Path) -> dict | None: + try: + head = path.read_bytes()[:220] + except OSError: + return None + if not head.startswith(b"version https://git-lfs.github.com/spec/v1"): + return None + text = head.decode("utf-8", errors="replace") + summary = {"pointer_detected": True} + for line in text.splitlines(): + if line.startswith("oid "): + summary["oid"] = line.split(" ", 1)[1] + elif line.startswith("size "): + summary["expected_size"] = line.split(" ", 1)[1] + return summary + + +def invalid_historical_cache_response(cache_status: str, message: str, diagnostics: dict | None = None) -> dict: + return { + "enabled": True, + "cache_status": cache_status, + "cache_file": HISTORICAL_PRICE_CACHE.name, + "inserted_rows": 0, + "diagnostics": diagnostics or {}, + "message": message, + "data_policy": "No synthetic prices are created when packaged OHLCV cache is unavailable.", + } + + def price_row_from_cache(asset_id: int, item: dict) -> dict | None: try: close = float(item["close"]) diff --git a/backend/app/services/dashboard.py b/backend/app/services/dashboard.py index fbe0865c5fd2266a5ed0f06367005310cfea3930..bc8c4d62da50c488e0206ce21a8f840df55fc9a3 100644 --- a/backend/app/services/dashboard.py +++ b/backend/app/services/dashboard.py @@ -6,6 +6,7 @@ from sqlalchemy.orm import Session from app.models import Asset, ETFTrend, NewsArticle, PriceHistory, SentimentAnalysis, SignalSnapshot from app.services.accuracy import latest_accuracy_snapshot, market_accuracy_overview, signal_validation_report from app.services.data_continuity import data_coverage_report +from app.services.dashboard_snapshots import DashboardSnapshotService from app.services.macro import macro_overview from app.services.market_data import market_snapshot_for_asset from app.services.performance import performance_recorder @@ -14,6 +15,19 @@ from app.services.realtime import realtime_status def dashboard_overview(db: Session) -> dict: + with performance_recorder.dashboard_widget("dashboard.snapshot_lookup", snapshot_type="dashboard_overview_summary"): + snapshot = DashboardSnapshotService().latest(db, "dashboard_overview_summary") + if snapshot["payload"]: + payload = dict(snapshot["payload"]) + payload["snapshot_status"] = snapshot["status"] + payload["snapshot_created_at"] = snapshot.get("created_at") + payload["snapshot_warnings"] = snapshot.get("warnings", []) + payload["runtime_policy"] = "snapshot_first_no_live_recalculation" + return payload + return empty_dashboard_overview(snapshot) + + +def build_dashboard_overview_live(db: Session) -> dict: with performance_recorder.dashboard_widget("dashboard.load_signal_candidates"): signals = db.scalars(select(SignalSnapshot).order_by(desc(SignalSnapshot.created_at), desc(SignalSnapshot.blum_score)).limit(80)).all() with performance_recorder.dashboard_widget("dashboard.rank_latest_signals", signal_count=len(signals)): @@ -80,6 +94,35 @@ def dashboard_overview(db: Session) -> dict: } +def empty_dashboard_overview(snapshot: dict) -> dict: + return { + "snapshot_status": snapshot.get("status", "missing"), + "snapshot_created_at": snapshot.get("created_at"), + "snapshot_warnings": [snapshot.get("warning") or "dashboard_overview_summary snapshot is not ready"], + "runtime_policy": "snapshot_first_no_live_recalculation", + "market_pulse": { + "asset_count": 0, + "article_count": 0, + "average_sentiment": 0, + "signal_count": 0, + "classification_mix": {}, + "price_row_count": 0, + }, + "data_coverage": {"status": "missing_snapshot"}, + "accuracy": {"status": "missing_snapshot"}, + "macro": {"status": "missing_snapshot"}, + "validation": {"status": "missing_snapshot"}, + "readiness": {"status": "missing_snapshot"}, + "realtime": {"status": "unknown"}, + "todays_strongest_signals": [], + "narrative_breakouts": [], + "technical_breakouts": [], + "sentiment_divergence": [], + "watchlist_candidates": [], + "etf_rotation_leaders": [], + } + + def signal_payload(signal: SignalSnapshot, db: Session | None = None) -> dict: with performance_recorder.dashboard_widget("dashboard.signal_payload", ticker=signal.ticker): payload = { diff --git a/backend/app/services/dashboard_snapshots.py b/backend/app/services/dashboard_snapshots.py index ad95c2b56559670e1011066a6054bb9c88d14470..16d6528da48927a126c8dac0824951117cfa1db0 100644 --- a/backend/app/services/dashboard_snapshots.py +++ b/backend/app/services/dashboard_snapshots.py @@ -1,6 +1,6 @@ from __future__ import annotations -from datetime import datetime, timedelta +from datetime import date, datetime, timedelta import time from sqlalchemy import desc, select @@ -38,6 +38,7 @@ class DashboardSnapshotService: "is_stale": is_stale, "payload": row.payload_json or {}, "source_modules": row.source_modules_json or {}, + "missing_sections": getattr(row, "missing_sections_json", None) or [], "computation_duration_ms": row.computation_duration_ms, "warnings": row.warnings_json or [], } @@ -51,6 +52,7 @@ class DashboardSnapshotService: source_modules: dict | None = None, ttl_seconds: int = 300, warnings: list[str] | None = None, + missing_sections: list[str] | None = None, computation_duration_ms: float | None = None, ) -> dict: started = time.perf_counter() @@ -58,11 +60,12 @@ class DashboardSnapshotService: snapshot_type=snapshot_type, created_at=datetime.utcnow(), expires_at=datetime.utcnow() + timedelta(seconds=max(1, ttl_seconds)), - payload_json=payload, - source_modules_json=source_modules or {}, + payload_json=json_safe(payload), + source_modules_json=json_safe(source_modules or {}), + missing_sections_json=json_safe(missing_sections or []), is_stale=False, computation_duration_ms=computation_duration_ms, - warnings_json=warnings or [], + warnings_json=json_safe(warnings or []), ) if row.computation_duration_ms is None: row.computation_duration_ms = round((time.perf_counter() - started) * 1000, 3) @@ -82,3 +85,22 @@ def record_snapshot_cache(snapshot_type: str, *, hit: bool, status: str) -> None ) except Exception: pass + + +def json_safe(value): + if isinstance(value, (datetime, date)): + return value.isoformat() + if isinstance(value, dict): + return {str(key): json_safe(item) for key, item in value.items()} + if isinstance(value, list): + return [json_safe(item) for item in value] + if isinstance(value, tuple): + return [json_safe(item) for item in value] + try: + import numpy as np + + if isinstance(value, np.generic): + return json_safe(value.item()) + except Exception: + pass + return value diff --git a/backend/app/services/financial_chat.py b/backend/app/services/financial_chat.py index c3c65c796aa9098845f2d527bb89368169aa2a01..78042309aace5f69b6b1a7b1507f75d692d58345 100644 --- a/backend/app/services/financial_chat.py +++ b/backend/app/services/financial_chat.py @@ -33,6 +33,8 @@ from app.services.fundamentals import fundamentals_for_asset from app.services.live import market_sentiment from app.services.learning_loop import LearningDashboardService from app.services.learning_intelligence import LearningIntelligenceDashboardService +from app.services.alpha_recovery import AlphaRecoveryDashboardService +from app.services.meta_cognition import MetaCognitionEngine from app.services.capital_allocation import AdaptiveCapitalAllocationEngine from app.services.decision_intelligence import DecisionIntelligenceDashboardService from app.services.market_data import market_snapshot_for_asset @@ -487,6 +489,8 @@ def trading_game_context_for_chat(db: Session) -> dict: "learning_intelligence": LearningIntelligenceDashboardService().dashboard(db), "decision_intelligence": DecisionIntelligenceDashboardService().dashboard(db), "capital_allocation": AdaptiveCapitalAllocationEngine().dashboard(db), + "alpha_recovery": AlphaRecoveryDashboardService().dashboard(db), + "meta_cognition": MetaCognitionEngine().summary(db), "pnl_breakdown": PnLBreakdownService().game_breakdown(db), "reality_check": TradingGameRealityCheckService().evaluate(db), "failures": engine.failures(db, limit=12), @@ -1477,6 +1481,8 @@ def build_trading_game_response(language: str, context: dict) -> dict: learning_intelligence = context.get("learning_intelligence") or {} decision_intelligence = context.get("decision_intelligence") or {} capital_allocation = context.get("capital_allocation") or {} + alpha_recovery = context.get("alpha_recovery") or {} + meta_cognition = context.get("meta_cognition") or {} if not game: message = "BLUM non ha ancora un Trading Game persistito. Serve almeno un ciclo Sniper/Learning Loop per creare simulazioni P/L reali." if language == "it" else "BLUM does not have a persisted Trading Game yet. It needs at least one Sniper/Learning Loop cycle to create real P/L simulations." return build_error_response(language, message, []) @@ -1505,6 +1511,8 @@ def build_trading_game_response(language: str, context: dict) -> dict: {"key": "learning_intelligence", "title": "Learning Intelligence", "bullets": learning_intelligence_lines(learning_intelligence, language)}, {"key": "decision_intelligence", "title": "Decision Intelligence", "bullets": decision_intelligence_lines(decision_intelligence, language)}, {"key": "capital_allocation", "title": "Capital Allocation Intelligence", "bullets": capital_allocation_lines(capital_allocation, language)}, + {"key": "alpha_recovery", "title": "Alpha Recovery", "bullets": alpha_recovery_lines(alpha_recovery, language)}, + {"key": "meta_cognition", "title": "Meta-Cognition", "bullets": meta_cognition_lines(meta_cognition, language)}, {"key": "trade_ledger", "title": "Trade ledger", "bullets": trade_ledger_lines(ledger_rows, language)}, {"key": "intelligence_metrics", "title": "Trading intelligence", "bullets": intelligence_metric_lines(intelligence_metrics, rolling_metrics, metrics_by_setup, language)}, {"key": "live_forward", "title": "Storico vs live paper", "bullets": historical_live_lines(live_forward, historical_vs_live, language)}, @@ -1545,6 +1553,8 @@ def build_trading_game_response(language: str, context: dict) -> dict: {"key": "learning_intelligence", "title": "Learning Intelligence", "bullets": learning_intelligence_lines(learning_intelligence, language)}, {"key": "decision_intelligence", "title": "Decision Intelligence", "bullets": decision_intelligence_lines(decision_intelligence, language)}, {"key": "capital_allocation", "title": "Capital Allocation Intelligence", "bullets": capital_allocation_lines(capital_allocation, language)}, + {"key": "alpha_recovery", "title": "Alpha Recovery", "bullets": alpha_recovery_lines(alpha_recovery, language)}, + {"key": "meta_cognition", "title": "Meta-Cognition", "bullets": meta_cognition_lines(meta_cognition, language)}, {"key": "trade_ledger", "title": "Trade Ledger", "bullets": trade_ledger_lines(ledger_rows, language)}, {"key": "intelligence_metrics", "title": "Trading Intelligence", "bullets": intelligence_metric_lines(intelligence_metrics, rolling_metrics, metrics_by_setup, language)}, {"key": "live_forward", "title": "Historical vs Live Paper", "bullets": historical_live_lines(live_forward, historical_vs_live, language)}, @@ -1574,7 +1584,7 @@ def build_trading_game_response(language: str, context: dict) -> dict: "executive_view": summary, "risk_reward_view": f"Expectancy {format_number(game.get('expectancy_r'))}R, drawdown {format_signed(game.get('max_drawdown'))}%.", "data_quality": {"sample_warning": sample_warning, "trades": game.get("trade_count"), "reproducibility": reproducibility, "cycles": cycle_stats, "live_sample_warning": (historical_vs_live.get("sample_warning") if isinstance(historical_vs_live, dict) else None)}, - "learning_loop_memory": {"trading_game": game, "lessons": lessons[:6], "latest_trades": trades[:6], "ledger": ledger_rows[:8], "reality_check": reality_check, "cycles": cycle_stats, "intelligence_metrics": intelligence_metrics, "historical_vs_live": historical_vs_live, "learning_intelligence": learning_intelligence, "decision_intelligence": decision_intelligence, "capital_allocation": capital_allocation}, + "learning_loop_memory": {"trading_game": game, "lessons": lessons[:6], "latest_trades": trades[:6], "ledger": ledger_rows[:8], "reality_check": reality_check, "cycles": cycle_stats, "intelligence_metrics": intelligence_metrics, "historical_vs_live": historical_vs_live, "learning_intelligence": learning_intelligence, "decision_intelligence": decision_intelligence, "capital_allocation": capital_allocation, "alpha_recovery": alpha_recovery, "meta_cognition": meta_cognition}, "answer_to_user": summary, } @@ -1691,6 +1701,100 @@ def capital_allocation_lines(payload: dict, language: str) -> list[str]: return dedupe_warnings(lines) +def alpha_recovery_lines(payload: dict, language: str) -> list[str]: + if not payload or payload.get("status") == "unavailable": + return ["Alpha Recovery non disponibile: non invento perche BLUM perde o vince alpha." if language == "it" else "Alpha Recovery is unavailable; I will not invent why BLUM won or lost alpha."] + truth = (payload.get("truth_layer") or {}).get("lines") or [] + attribution = payload.get("latest_attribution") or {} + attribution_summary = attribution.get("summary") or {} + top_category = attribution_summary.get("top_category") + missed = ((payload.get("missed_winners") or {}).get("rows") or [])[:3] + actions = ((payload.get("recovery_actions") or {}).get("rows") or [])[:3] + methodology_rows = ((payload.get("latest_methodology") or {}).get("rows") or [])[:3] + invalid = [row for row in methodology_rows if not row.get("methodology_valid")] + if language == "it": + lines = list(truth[:3]) or ["Evidenza insufficiente: servono benchmark validati e trade ledger prima di attribuire perdita alpha."] + if invalid: + lines.append("Alcuni benchmark non sono validi per apprendimento: BLUM blocca conclusioni di recovery su quei confronti.") + if top_category: + lines.append(f"Causa misurata principale: {str(top_category).replace('_', ' ')}.") + if missed: + lines.append("Missed winners da replay: " + ", ".join(f"{row.get('ticker')} ({format_signed(row.get('benchmark_relative_return'))}%)" for row in missed)) + if actions: + lines.append(f"Azione recovery proposta: {actions[0].get('recommended_action')} | stato {actions[0].get('status')}.") + return dedupe_warnings(lines) + lines = list(truth[:3]) or ["Insufficient evidence: validated benchmarks and trade ledger data are required before attributing alpha loss."] + if invalid: + lines.append("Some benchmarks are not valid for learning; BLUM blocks recovery conclusions on those comparisons.") + if top_category: + lines.append(f"Main measured cause: {str(top_category).replace('_', ' ')}.") + if missed: + lines.append("Missed winners for replay: " + ", ".join(f"{row.get('ticker')} ({format_signed(row.get('benchmark_relative_return'))}%)" for row in missed)) + if actions: + lines.append(f"Recovery action proposed: {actions[0].get('recommended_action')} | status {actions[0].get('status')}.") + return dedupe_warnings(lines) + + +def meta_cognition_lines(payload: dict, language: str) -> list[str]: + if not payload or payload.get("status") == "unavailable": + return ["Meta-Cognition non disponibile: non invento quali fattori creano o distruggono alpha." if language == "it" else "Meta-Cognition is unavailable; I will not invent which factors create or destroy alpha."] + snapshot_payload = ((payload.get("snapshot") or {}).get("payload") or {}) if isinstance(payload.get("snapshot"), dict) else {} + factor_summary = ((payload.get("factor_importance") or {}).get("summary") or {}) + focus_rows = ((payload.get("learning_focus") or {}).get("rows") or []) + noise_rows = ((payload.get("noise") or {}).get("rows") or []) + preservation_summary = ((payload.get("capital_preservation") or {}).get("summary") or {}) + events_summary = ((payload.get("events") or {}).get("summary") or {}) + conclusion = payload.get("conclusion") or snapshot_payload.get("meta_cognition_conclusion") or {} + + top_alpha = snapshot_payload.get("top_alpha_factor") or first_payload(factor_summary.get("top_alpha_creators")) + top_destroyer = snapshot_payload.get("top_alpha_destroyer") or first_payload(factor_summary.get("top_alpha_destroyers")) + noisiest = snapshot_payload.get("noisiest_factor") or first_payload(factor_summary.get("noisiest_factors")) or first_payload(noise_rows) + focus = snapshot_payload.get("next_learning_focus") or first_payload(focus_rows) + preservation = snapshot_payload.get("strongest_capital_preservation_rule") or first_payload(preservation_summary.get("top_preservers")) + + if language == "it": + lines = [] + if top_alpha: + lines.append(f"Fattore che sta creando piu alpha misurabile: {top_alpha.get('factor_name', 'n/a')} | contributo {format_number(top_alpha.get('alpha_contribution'))} | campione {top_alpha.get('sample_size', 'n/a')}.") + if top_destroyer: + lines.append(f"Fattore che sta distruggendo piu alpha: {top_destroyer.get('factor_name', 'n/a')} | perdita {format_number(top_destroyer.get('alpha_loss_contribution'))} | azione {top_destroyer.get('recommended_weight_action', 'n/a')}.") + if noisiest: + lines.append(f"Fattore/modulo piu rumoroso: {noisiest.get('factor_name') or noisiest.get('module_name', 'n/a')} | noise {format_number(noisiest.get('noise_score'))}/100 | severita {noisiest.get('severity', 'n/a')}.") + if preservation: + lines.append(f"Regola no-trade piu utile: {preservation.get('ticker', preservation.get('factor_name', 'n/a'))} | capitale preservato {format_money(preservation.get('capital_preserved'))} | quality {format_number(preservation.get('quality_score'))}/100.") + if focus: + lines.append(f"Prossimo focus Learning Loop: {focus.get('priority_type', 'focus')} su {focus.get('target', 'n/a')} | valore atteso {format_number(focus.get('expected_learning_value'))}/100.") + if conclusion.get("summary"): + lines.append(str(conclusion.get("summary"))) + if events_summary.get("events"): + lines.append(f"Azioni di learning valutate: {events_summary.get('events')} | miglioramenti {events_summary.get('improvements', 0)} | peggioramenti {events_summary.get('degradations', 0)}.") + return dedupe_warnings(lines or ["Evidenza meta-cognitiva insufficiente: serve ledger, benchmark validi e piu campioni prima di attribuire alpha ai fattori."]) + + lines = [] + if top_alpha: + lines.append(f"Top measured alpha-creating factor: {top_alpha.get('factor_name', 'n/a')} | contribution {format_number(top_alpha.get('alpha_contribution'))} | sample {top_alpha.get('sample_size', 'n/a')}.") + if top_destroyer: + lines.append(f"Top measured alpha-destroying factor: {top_destroyer.get('factor_name', 'n/a')} | loss {format_number(top_destroyer.get('alpha_loss_contribution'))} | action {top_destroyer.get('recommended_weight_action', 'n/a')}.") + if noisiest: + lines.append(f"Noisiest factor/module: {noisiest.get('factor_name') or noisiest.get('module_name', 'n/a')} | noise {format_number(noisiest.get('noise_score'))}/100 | severity {noisiest.get('severity', 'n/a')}.") + if preservation: + lines.append(f"Strongest no-trade preservation rule: {preservation.get('ticker', preservation.get('factor_name', 'n/a'))} | preserved {format_money(preservation.get('capital_preserved'))} | quality {format_number(preservation.get('quality_score'))}/100.") + if focus: + lines.append(f"Next Learning Loop focus: {focus.get('priority_type', 'focus')} on {focus.get('target', 'n/a')} | expected value {format_number(focus.get('expected_learning_value'))}/100.") + if conclusion.get("summary"): + lines.append(str(conclusion.get("summary"))) + if events_summary.get("events"): + lines.append(f"Learning actions evaluated: {events_summary.get('events')} | improvements {events_summary.get('improvements', 0)} | degradations {events_summary.get('degradations', 0)}.") + return dedupe_warnings(lines or ["Insufficient meta-cognition evidence: BLUM needs a ledger, valid benchmarks and more samples before attributing alpha to factors."]) + + +def first_payload(value: object) -> dict: + if isinstance(value, list) and value: + first = value[0] + return first if isinstance(first, dict) else {} + return value if isinstance(value, dict) else {} + + def trade_ledger_lines(rows: list[dict], language: str) -> list[str]: if not rows: return ["BLUM ha metriche di gioco, ma il trade ledger dettagliato non e ancora disponibile." if language == "it" else "BLUM has game-level metrics, but the detailed trade ledger is not available yet."] @@ -2484,7 +2588,7 @@ def infer_intent(message: str, mode: str | None = None) -> str: return "fundamental_analysis" if any(term in normalized for term in ["tesi", "thesis", "convinzione", "conviction", "ancora valida", "still valid", "sopravviss", "survival", "decay", "decad", "bull bear neutral", "tesi bull", "tesi bear", "tesi neutral", "motore", "engine vote", "sta migliorando", "dove ha sbagliato", "reasoning core", "batte spy", "batte qqq", "vs spy", "vs qqq"]): return "reasoning_memory_question" - if any(term in normalized for term in ["capitale virtuale", "trading game", "sta battendo", "batte il mercato", "benchmark", "drawdown", "profit factor", "expectancy", "p/l", "pl ", "peggior errore", "andato a zero", "rischio per trade", "riproducibil", "reproducib", "win rate", "quali trade", "trade hanno", "dove e entrato", "dove e uscito", "entrato blum", "uscito blum", "per azione", "fortuna", "profitto arriva", "ledger", "trade piu importante", "100 eur", "10,000", "10000", "target cycle", "ciclo capitale", "cicli capitale", "quante volte", "live paper", "forward paper", "storico vs live", "historical vs live", "sta migliorando", "intelligence growth", "missed entry", "stop hit", "target hit", "trading power", "power score", "dove e scarso", "piu scarso", "weakness", "self improvement", "auto miglior", "prossima azione", "baseline semplice", "stiamo battendo spy", "stiamo battendo qqq", "best opportunity", "migliore opportunita", "opportunita migliore", "ha scelto il migliore", "decision superiority", "superiorita decisionale", "alpha capture", "opportunita mancata", "missed opportunity", "business quality", "qualita business", "moat", "management quality", "portfolio quality", "qualita portafoglio", "contribuisce piu alpha", "contribution", "concentrazione portfolio", "capital allocation", "cash allocation", "cash reserve", "quanto capitale", "quanto allocare", "peso capitale", "sizing logic", "logica di sizing"]): + if any(term in normalized for term in ["capitale virtuale", "trading game", "sta battendo", "batte il mercato", "benchmark", "drawdown", "profit factor", "expectancy", "p/l", "pl ", "peggior errore", "andato a zero", "rischio per trade", "riproducibil", "reproducib", "win rate", "quali trade", "trade hanno", "dove e entrato", "dove e uscito", "entrato blum", "uscito blum", "per azione", "fortuna", "profitto arriva", "ledger", "trade piu importante", "100 eur", "10,000", "10000", "target cycle", "ciclo capitale", "cicli capitale", "quante volte", "live paper", "forward paper", "storico vs live", "historical vs live", "sta migliorando", "intelligence growth", "missed entry", "stop hit", "target hit", "trading power", "power score", "dove e scarso", "piu scarso", "weakness", "self improvement", "auto miglior", "prossima azione", "baseline semplice", "stiamo battendo spy", "stiamo battendo qqq", "best opportunity", "migliore opportunita", "opportunita migliore", "ha scelto il migliore", "decision superiority", "superiorita decisionale", "alpha capture", "opportunita mancata", "missed opportunity", "business quality", "qualita business", "moat", "management quality", "portfolio quality", "qualita portafoglio", "contribuisce piu alpha", "contribution", "concentrazione portfolio", "capital allocation", "cash allocation", "cash reserve", "quanto capitale", "quanto allocare", "peso capitale", "sizing logic", "logica di sizing", "alpha loss", "alpha recovery", "perche perdiamo", "perché perdiamo", "perdiamo contro", "why are we losing", "why losing", "qqq", "spy", "missed winners", "winners mancati", "opportunita mancate", "opportunità mancate", "recovery action", "azioni recovery", "perdita alpha", "alpha perso", "lose alpha", "meta cognition", "meta-cognition", "meta cognizione", "meta-cognizione", "fattore alpha", "factor alpha", "quale fattore", "which factor", "fattore rumoroso", "noisy factor", "modulo rumoroso", "cosa deve imparare", "what should blum learn", "imparare adesso", "learn next", "trust technical", "fidarsi dei tecnici", "capital preservation", "preservazione capitale", "no-trade rule", "regola no trade"]): return "trading_game" if any(term in normalized for term in ["sniper", "entrabile", "meglio aspettare", "ingresso", "entry", "risk/reward", "uscita", "exit", "target", "invalidazione", "invalidation", "profitto", "take profit"]): return "market_sniper" diff --git a/backend/app/services/learning_loop.py b/backend/app/services/learning_loop.py index 4f1253d3aad6450484532095519eb3f12c0f3474..aa45d65daf8cea0e76d46693feddd1ff956d05e7 100644 --- a/backend/app/services/learning_loop.py +++ b/backend/app/services/learning_loop.py @@ -17,11 +17,15 @@ from app.core.config import get_settings from app.models import ( Asset, FundamentalSnapshot, + FeedbackLoopAudit, HistoricalPrediction, + CapitalPreservationAlpha, + LearningFocusPriority, LearningEvent, LearningMetric, LearningRun, MacroSnapshot, + MissedWinner, MistakeAnalysis, ModelVersion, NewsArticle, @@ -30,6 +34,7 @@ from app.models import ( PriceHistory, SignalPerformance, StrategyMemory, + TradingGameTrade, ) from app.services.technical_analysis_engine import TechnicalAnalysisEngine @@ -54,6 +59,10 @@ BASE_SIGNAL_WEIGHTS = { "regime": 0.05, } +MIN_MODEL_VERSION_OUTCOMES = 30 +MIN_MODEL_VERSION_SIGNAL_ROWS = 3 +MIN_MODEL_VERSION_SIGNAL_SAMPLE = 3 + ERROR_TYPES = { "technical_false_breakout", "overbought_signal_ignored", @@ -86,10 +95,17 @@ class LearningLoopService: self.memory = StrategyMemoryService() self.model_scores = ModelScoreService() - def run_batch(self, db: Session, batch_size: int | None = None, trigger: str = "manual") -> dict: + def run_batch( + self, + db: Session, + batch_size: int | None = None, + trigger: str = "manual", + sniper_simulation_limit: int | None = None, + ) -> dict: requested_batch = int(batch_size or settings.learning_batch_size) - batch = max(1, min(requested_batch, settings.learning_batch_size, 500)) - daily_guard = self.daily_guard(db, batch) + configured_batch = max(1, min(requested_batch, settings.learning_batch_size, 500)) + daily_guard = self.daily_guard(db, configured_batch) + batch = max(1, int(daily_guard.get("effective_batch", configured_batch) or configured_batch)) run_id = f"learn-{datetime.utcnow().strftime('%Y%m%d%H%M%S')}-{uuid4().hex[:8]}" run = LearningRun( run_id=run_id, @@ -104,26 +120,26 @@ class LearningLoopService: db.flush() if not daily_guard["allowed"]: - run.status = "skipped" + run.status = "budget_wait" run.completed_at = datetime.utcnow() - run.summary = {"reason": daily_guard["reason"], "requested_batch_size": requested_batch} + run.summary = {"reason": daily_guard["reason"], "requested_batch_size": requested_batch, "daily_guard": daily_guard} event = LearningEvent( - event_type="blum_learning_loop_skipped", + event_type="blum_learning_loop_budget_wait", severity="Warning", - title="BLUM Learning Loop skipped by daily guard", + title="BLUM Learning Loop waiting for daily budget", description=daily_guard["reason"], payload={"run_id": run_id, "guard": daily_guard}, ) db.add(event) db.commit() - return {"status": "skipped", "run_id": run_id, "guard": daily_guard} + return {"status": "budget_wait", "run_id": run_id, "guard": daily_guard} reports: list[dict] = [] errors: list[dict] = [] seen_samples: set[tuple[str, str]] = set() for _ in range(batch): try: - sample = self.sampler.random_sample(db, seen_samples=seen_samples) + sample = self.sampler.blended_sample(db, seen_samples=seen_samples, trigger=trigger) if not sample: errors.append({"stage": "sample", "error": "No eligible historical sample found."}) continue @@ -135,9 +151,16 @@ class LearningLoopService: sniper_learning = {"status": "skipped", "reason": "No reports created."} if reports: try: - from app.services.market_sniper import MarketSniperEngine - - sniper_learning = MarketSniperEngine().simulate(db, limit=min(300, max(60, len(reports) * len(TIMEFRAMES) * 6))) + limit = sniper_simulation_limit if sniper_simulation_limit is not None else min(300, max(60, len(reports) * len(TIMEFRAMES) * 6)) + if limit > 0: + from app.services.market_sniper import MarketSniperEngine + + sniper_learning = MarketSniperEngine().simulate(db, limit=limit) + else: + sniper_learning = { + "status": "deferred", + "reason": "Sniper R-multiple simulation is deferred for this bounded learning lane.", + } except Exception as exc: sniper_learning = {"status": "degraded", "error": f"{type(exc).__name__}: {exc}"} @@ -156,6 +179,7 @@ class LearningLoopService: "latest_reports": reports[-5:], "dashboard_metrics": metrics, "model_version": model_version, + "learning_mode": "alpha_loss_replay" if trigger == "alpha_loss_replay" else "random_point_in_time", "market_sniper_learning": sniper_learning, } run.anti_overfitting_report = anti_overfitting @@ -174,10 +198,13 @@ class LearningLoopService: "status": run.status, "run_id": run_id, "batch_size": batch, + "requested_batch_size": requested_batch, + "daily_guard": daily_guard, "reports_created": len(reports), "errors": errors[:8], "metrics": metrics, "model_version": model_version, + "learning_mode": "alpha_loss_replay" if trigger == "alpha_loss_replay" else "random_point_in_time", "market_sniper_learning": sniper_learning, "anti_overfitting": anti_overfitting, "disclaimer": "Research learning loop only. It improves calibration and robustness; it does not create guaranteed market predictions.", @@ -187,7 +214,12 @@ class LearningLoopService: context = self.point_in_time.context_for(db, sample["asset"], sample["analysis_date"]) prediction_context = dict(context) prediction_context.pop("future_prices", None) - prediction_payload = self.predictor.predict(prediction_context) + sample_metadata = dict(sample) + sample_metadata["run_trigger"] = run.trigger + sample_metadata["evaluation_mode"] = run.evaluation_mode + sample_metadata["learning_mode_metadata"] = learning_mode_metadata(run.trigger, sample_metadata) + prediction_payload = self.predictor.predict(prediction_context, db=db, sample_metadata=sample_metadata) + feedback_payload = prediction_payload.get("feedback_loop", {}) prediction = HistoricalPrediction( learning_run_id=run.id, asset_id=sample["asset"].id, @@ -203,7 +235,12 @@ class LearningLoopService: point_in_time_context=json_safe(context), expected_direction=prediction_payload["prediction"]["dominant_direction"], confidence=prediction_payload["prediction"]["aggregate_confidence"], - model_version="blum-learning-loop-v1", + model_version=feedback_payload.get("model_version_used") or "base-static", + model_version_used=feedback_payload.get("model_version_used") or "base-static", + weights_used=json_safe(feedback_payload.get("weights_used") or {}), + learning_memory_used=json_safe(feedback_payload.get("learning_memory_used") or {}), + strategy_memory_used=json_safe(feedback_payload.get("strategy_memory_used") or {}), + research_priority_used=json_safe(feedback_payload.get("research_priority_used") or {}), data_quality_score=context["data_quality_score"], ) db.add(prediction) @@ -264,6 +301,7 @@ class LearningLoopService: memory_updates.extend(self.memory.update_from_outcome(db, context, frame_prediction, outcome_payload, analysis)) self.memory.update_signal_performance(db, context, prediction_payload, outcomes) + feedback_audit = FeedbackLoopAuditService().record(db, prediction, prediction_payload, outcomes, memory_updates) report = { "asset": prediction.ticker, "analysis_date": prediction.analysis_date.isoformat(), @@ -280,20 +318,35 @@ class LearningLoopService: "mistakes": mistakes, "lessons_learned": [item["lesson"] for item in memory_updates], "memory_updates": memory_updates, + "feedback_loop_audit": feedback_audit, } return json_safe(report) def daily_guard(self, db: Session, requested_batch: int) -> dict: start = datetime.combine(datetime.utcnow().date(), time.min) today_predictions = int(db.scalar(select(func.coalesce(func.sum(LearningRun.predictions_created), 0)).where(LearningRun.started_at >= start)) or 0) - projected = today_predictions + requested_batch - allowed = projected <= settings.learning_max_daily_runs + max_daily = max(0, int(settings.learning_max_daily_runs)) + remaining = max(0, max_daily - today_predictions) + effective_batch = min(max(1, requested_batch), remaining) if remaining else 0 + projected = today_predictions + effective_batch + allowed = effective_batch > 0 + partial = allowed and effective_batch < requested_batch return { "allowed": allowed, "today_predictions": today_predictions, "requested_batch": requested_batch, - "max_daily_runs": settings.learning_max_daily_runs, - "reason": "within daily limit" if allowed else "Learning max daily run guard prevents overfitting and excessive repeated sampling.", + "effective_batch": effective_batch, + "remaining_daily_budget": remaining, + "projected_predictions": projected, + "max_daily_runs": max_daily, + "partial_batch": partial, + "reason": ( + "within daily limit" + if allowed and not partial + else "partial batch: using remaining daily learning budget to keep training without overfitting" + if partial + else "daily learning budget exhausted; waiting for next UTC window instead of oversampling the same day" + ), } @@ -301,6 +354,92 @@ class HistoricalSamplerService: def __init__(self) -> None: self.rng = random.Random(self.seed()) + def blended_sample(self, db: Session, seen_samples: set[tuple[str, str]] | None = None, trigger: str = "manual") -> dict | None: + if trigger == "alpha_loss_replay": + return self.alpha_loss_sample(db, seen_samples=seen_samples) or self.random_sample(db, seen_samples=seen_samples) + roll = self.rng.random() + random_ratio = clamp_ratio(settings.learning_random_sample_ratio) + alpha_ratio = clamp_ratio(settings.learning_alpha_loss_sample_ratio) + factor_ratio = clamp_ratio(settings.learning_factor_focus_sample_ratio) + preservation_ratio = clamp_ratio(settings.learning_capital_preservation_sample_ratio) + total = max(0.01, random_ratio + alpha_ratio + factor_ratio + preservation_ratio) + random_cut = random_ratio / total + alpha_cut = random_cut + alpha_ratio / total + factor_cut = alpha_cut + factor_ratio / total + if roll < random_cut: + return self.random_sample(db, seen_samples=seen_samples) + if roll < alpha_cut: + return self.alpha_loss_sample(db, seen_samples=seen_samples) or self.random_sample(db, seen_samples=seen_samples) + if roll < factor_cut: + return self.focus_priority_sample(db, seen_samples=seen_samples) or self.random_sample(db, seen_samples=seen_samples) + return self.capital_preservation_sample(db, seen_samples=seen_samples) or self.random_sample(db, seen_samples=seen_samples) + + def alpha_loss_sample(self, db: Session, seen_samples: set[tuple[str, str]] | None = None) -> dict | None: + missed = db.scalars( + select(MissedWinner) + .order_by(desc(MissedWinner.benchmark_relative_return), desc(MissedWinner.created_at)) + .limit(120) + ).all() + for row in missed: + asset = db.scalar(select(Asset).where(Asset.ticker == row.ticker, Asset.is_active.is_(True)).limit(1)) + if not asset: + continue + sample = self.sample_for_asset(db, asset, preferred_date=as_date(row.decision_date), seen_samples=seen_samples) + if sample: + sample["sampling_reason"] = "alpha_loss_replay" + sample["missed_winner_id"] = row.id + sample["benchmark_relative_return"] = row.benchmark_relative_return + return sample + return None + + def focus_priority_sample(self, db: Session, seen_samples: set[tuple[str, str]] | None = None) -> dict | None: + priorities = db.scalars( + select(LearningFocusPriority) + .where(LearningFocusPriority.status.in_(["proposed", "active"])) + .order_by(desc(LearningFocusPriority.expected_learning_value), desc(LearningFocusPriority.created_at)) + .limit(80) + ).all() + for priority in priorities: + target = str(priority.target or "").upper() + asset = db.scalar(select(Asset).where(Asset.ticker == target, Asset.is_active.is_(True)).limit(1)) + if not asset: + asset = db.scalar(select(Asset).where(Asset.sector.ilike(priority.target), Asset.is_active.is_(True)).limit(1)) + if not asset: + linked_trade = db.scalar( + select(TradingGameTrade) + .where(TradingGameTrade.setup_type == priority.target) + .order_by(desc(TradingGameTrade.created_at)) + .limit(1) + ) + asset = db.scalar(select(Asset).where(Asset.ticker == linked_trade.ticker, Asset.is_active.is_(True)).limit(1)) if linked_trade else None + if not asset: + continue + sample = self.sample_for_asset(db, asset, preferred_date=None, seen_samples=seen_samples) + if sample: + sample["sampling_reason"] = "learning_focus_priority" + sample["learning_focus_priority_id"] = priority.id + sample["priority_type"] = priority.priority_type + return sample + return None + + def capital_preservation_sample(self, db: Session, seen_samples: set[tuple[str, str]] | None = None) -> dict | None: + rows = db.scalars( + select(CapitalPreservationAlpha) + .where(CapitalPreservationAlpha.missed_gain > CapitalPreservationAlpha.avoided_loss) + .order_by(desc(CapitalPreservationAlpha.missed_gain), desc(CapitalPreservationAlpha.created_at)) + .limit(80) + ).all() + for row in rows: + asset = db.scalar(select(Asset).where(Asset.ticker == row.ticker, Asset.is_active.is_(True)).limit(1)) + if not asset: + continue + sample = self.sample_for_asset(db, asset, preferred_date=as_date(row.decision_date), seen_samples=seen_samples) + if sample: + sample["sampling_reason"] = "capital_preservation_replay" + sample["capital_preservation_alpha_id"] = row.id + return sample + return None + def random_sample(self, db: Session, seen_samples: set[tuple[str, str]] | None = None) -> dict | None: universe = {item.strip().lower() for item in settings.learning_asset_universe.split(",") if item.strip()} asset_types = [] @@ -313,32 +452,37 @@ class HistoricalSamplerService: candidates = db.scalars(select(Asset).where(Asset.is_active.is_(True), Asset.asset_type.in_(asset_types))).all() self.rng.shuffle(candidates) - min_rows = max(252, settings.learning_min_history_years * 252) for asset in candidates: - stats = db.execute( - select(func.count(PriceHistory.id), func.min(PriceHistory.date), func.max(PriceHistory.date)).where(PriceHistory.asset_id == asset.id) - ).one() - count, first_date, last_date = int(stats[0] or 0), as_date(stats[1]), as_date(stats[2]) - if count < min_rows or not first_date or not last_date: + sample = self.sample_for_asset(db, asset, preferred_date=None, seen_samples=seen_samples) + if sample: + return sample + return None + + def sample_for_asset(self, db: Session, asset: Asset, preferred_date: date | None, seen_samples: set[tuple[str, str]] | None = None) -> dict | None: + min_rows = max(252, settings.learning_min_history_years * 252) + stats = db.execute( + select(func.count(PriceHistory.id), func.min(PriceHistory.date), func.max(PriceHistory.date)).where(PriceHistory.asset_id == asset.id) + ).one() + count, first_date, last_date = int(stats[0] or 0), as_date(stats[1]), as_date(stats[2]) + if count < min_rows or not first_date or not last_date: + return None + earliest = first_date + timedelta(days=max(365, settings.learning_min_history_years * 365)) + latest = last_date - timedelta(days=TIMEFRAMES["long"]["horizon_days"] * 2 + 30) + if earliest >= latest: + return None + preferred_candidates: list[date] = [] + if preferred_date and earliest <= preferred_date <= latest: + preferred_candidates.extend([preferred_date, preferred_date - timedelta(days=3), preferred_date + timedelta(days=3)]) + span = (latest - earliest).days + preferred_candidates.extend(earliest + timedelta(days=self.rng.randint(0, max(1, span))) for _ in range(8)) + for candidate_date in preferred_candidates: + analysis_date = nearest_trading_date(db, asset, max(earliest, min(candidate_date, latest)), latest) + if not analysis_date: continue - earliest = first_date + timedelta(days=max(365, settings.learning_min_history_years * 365)) - latest = last_date - timedelta(days=TIMEFRAMES["long"]["horizon_days"] * 2 + 30) - if earliest >= latest: + key = (asset.ticker, analysis_date.isoformat()) + if seen_samples and key in seen_samples: continue - span = (latest - earliest).days - for _ in range(8): - analysis_date = nearest_trading_date( - db, - asset, - earliest + timedelta(days=self.rng.randint(0, max(1, span))), - latest, - ) - if not analysis_date: - continue - key = (asset.ticker, analysis_date.isoformat()) - if seen_samples and key in seen_samples: - continue - return {"asset": asset, "analysis_date": analysis_date, "first_price_date": first_date, "last_price_date": last_date, "sample_rows": count} + return {"asset": asset, "analysis_date": analysis_date, "first_price_date": first_date, "last_price_date": last_date, "sample_rows": count} return None def seed(self) -> int: @@ -480,12 +624,18 @@ class PointInTimeDataService: class PredictionEngine: - def predict(self, context: dict) -> dict: + def predict(self, context: dict, db: Session | None = None, sample_metadata: dict | None = None) -> dict: technical = context["technical"] signal_scores = self.signal_scores(context) - aggregate_score = weighted_score(signal_scores, BASE_SIGNAL_WEIGHTS) + sample_metadata = sample_metadata or {} + feedback = self.feedback_context(db, context, signal_scores, sample_metadata) + weights_used = feedback["weights_used"] + aggregate_score = weighted_score(signal_scores, weights_used) dominant_direction = direction_from_score(aggregate_score, technical) - confidence = confidence_from_evidence(aggregate_score, context["data_quality_score"], context["market_context"], technical) + base_confidence = confidence_from_evidence(aggregate_score, context["data_quality_score"], context["market_context"], technical) + confidence = round(clamp(base_confidence + feedback["confidence_adjustment"], 15, 88), 1) + feedback["base_confidence"] = base_confidence + feedback["final_confidence"] = confidence timeframes = { timeframe: self.timeframe_prediction(timeframe, config, context, signal_scores, aggregate_score, dominant_direction, confidence) for timeframe, config in TIMEFRAMES.items() @@ -502,9 +652,68 @@ class PredictionEngine: "reasoning": self.reasoning(context, signal_scores, dominant_direction), }, "timeframes": timeframes, + "feedback_loop": feedback, + "model_version_used": feedback["model_version_used"], + "weights_used": weights_used, + "learning_memory_used": feedback["learning_memory_used"], + "strategy_memory_used": feedback["strategy_memory_used"], + "research_priority_used": feedback["research_priority_used"], + "learning_mode_metadata": feedback["learning_mode_metadata"], "anti_leakage": context["point_in_time_policy"], } + def feedback_context(self, db: Session | None, context: dict, signal_scores: dict, sample_metadata: dict) -> dict: + model_version_used, weights_used, weight_source = active_weight_context(db) + signal_memory = signal_performance_context(db, context, signal_scores) + strategy_memory = strategy_memory_context(db, context) + research_priority = research_priority_context(db, sample_metadata) + mode_metadata = sample_metadata.get("learning_mode_metadata") or learning_mode_metadata(sample_metadata.get("run_trigger"), sample_metadata) + confidence_adjustment = round( + clamp( + signal_memory["confidence_delta"] + strategy_memory["confidence_delta"] + research_priority.get("confidence_delta", 0.0), + -14.0, + 14.0, + ), + 2, + ) + return { + "model_version_used": model_version_used, + "weight_source": weight_source, + "weights_used": weights_used, + "learning_memory_used": { + "signal_performance": signal_memory["rows"], + "confidence_delta": signal_memory["confidence_delta"], + "policy": "SignalPerformance reliability changes confidence only when enough outcome evidence exists.", + }, + "strategy_memory_used": { + "rows": strategy_memory["rows"], + "confidence_delta": strategy_memory["confidence_delta"], + "policy": "StrategyMemory lessons modify confidence when their stored conditions match the current point-in-time setup.", + }, + "research_priority_used": research_priority, + "learning_mode_metadata": mode_metadata, + "confidence_adjustment": confidence_adjustment, + "policy": "PredictionEngine uses active learned weights when available; otherwise BASE_SIGNAL_WEIGHTS. Learning memory changes confidence, not source code.", + } + + def baseline_prediction(self, context: dict) -> dict: + signal_scores = self.signal_scores(context) + weights = normalize_weights(BASE_SIGNAL_WEIGHTS) + aggregate_score = weighted_score(signal_scores, weights) + direction = direction_from_score(aggregate_score, context["technical"]) + confidence = confidence_from_evidence(aggregate_score, context["data_quality_score"], context["market_context"], context["technical"]) + return { + "model_version_used": "base-static", + "weights_used": weights, + "aggregate_score": round(aggregate_score, 2), + "aggregate_confidence": confidence, + "dominant_direction": direction, + "actionability": feedback_actionability(direction, confidence, aggregate_score), + "confidence_adjustment": 0.0, + "memory_adjustment_used": False, + "policy": "Counterfactual baseline uses BASE_SIGNAL_WEIGHTS and ignores learned memory/confidence adjustments.", + } + def signal_scores(self, context: dict) -> dict: technical = context["technical"] indicators = technical.get("technical_indicators") or {} @@ -775,19 +984,43 @@ class StrategyMemoryService: class ModelScoreService: def recalculate(self, db: Session) -> dict: rows = db.scalars(select(SignalPerformance).order_by(desc(SignalPerformance.updated_at)).limit(600)).all() - if not rows: - return {"status": "insufficient_sample", "version": None} previous = active_model_version(db) + anti = self.anti_overfitting_report(db) + eligible_rows = [row for row in rows if int(row.sample_count or 0) >= MIN_MODEL_VERSION_SIGNAL_SAMPLE] + if ( + int(anti.get("sample_count", 0) or 0) < MIN_MODEL_VERSION_OUTCOMES + or len(eligible_rows) < MIN_MODEL_VERSION_SIGNAL_ROWS + ): + return { + "status": "insufficient_evidence", + "version": previous.version if previous else None, + "active_version": previous.version if previous else None, + "thresholds": { + "min_outcomes": MIN_MODEL_VERSION_OUTCOMES, + "min_signal_rows": MIN_MODEL_VERSION_SIGNAL_ROWS, + "min_signal_sample": MIN_MODEL_VERSION_SIGNAL_SAMPLE, + }, + "evidence": {"outcomes": anti.get("sample_count", 0), "eligible_signal_rows": len(eligible_rows)}, + "anti_overfitting": anti, + "policy": "No ModelVersion is created until enough outcome and signal reliability evidence exists.", + } previous_weights = previous.weights if previous else BASE_SIGNAL_WEIGHTS new_weights = dict(BASE_SIGNAL_WEIGHTS) for signal_name in new_weights: - matching = [row for row in rows if row.signal_name == signal_name and row.sample_count >= 3] + matching = [row for row in rows if row.signal_name == signal_name and row.sample_count >= MIN_MODEL_VERSION_SIGNAL_SAMPLE] if not matching: continue avg_reliability = mean(row.reliability_score for row in matching) new_weights[signal_name] = max(0.03, new_weights[signal_name] + (avg_reliability - 50) / 1000) new_weights = normalize_weights(new_weights) - anti = self.anti_overfitting_report(db) + if previous and max(abs(safe_float(new_weights.get(key)) - safe_float((previous.weights or {}).get(key))) for key in BASE_SIGNAL_WEIGHTS) < 0.001: + return { + "status": "stable", + "version": previous.version, + "weights": previous.weights, + "anti_overfitting": anti, + "policy": "No new ModelVersion created because learned weights did not materially change.", + } version = f"learning-{datetime.utcnow().strftime('%Y%m%d%H%M%S')}" row = ModelVersion( version=version, @@ -844,6 +1077,181 @@ class ModelScoreService: } +class FeedbackLoopAuditService: + def record( + self, + db: Session, + prediction: HistoricalPrediction, + prediction_payload: dict, + outcomes: list[dict], + memory_updates: list[dict], + ) -> dict: + feedback = prediction_payload.get("feedback_loop", {}) + usable = [row for row in outcomes if row.get("outcome_label") in {"correct", "wrong", "neutral"}] + correct = sum(1 for row in usable if row.get("outcome_label") == "correct") + wrong = sum(1 for row in usable if row.get("outcome_label") == "wrong") + returns = [safe_float(row.get("realized_return")) for row in usable if row.get("realized_return") is not None] + evidence_grade = "medium" if len(usable) >= 3 else "low" if usable else "insufficient" + learned = { + "memory_updates": memory_updates[:12], + "signal_performance_used": (feedback.get("learning_memory_used") or {}).get("signal_performance", []), + "strategy_memory_used": (feedback.get("strategy_memory_used") or {}).get("rows", []), + } + counterfactual = self.counterfactual_audit(prediction, prediction_payload, outcomes) + comparison = counterfactual.get("outcome_comparison", {}) + changed_decision = bool( + (counterfactual.get("differences") or {}).get("direction_changed") + or (counterfactual.get("differences") or {}).get("actionability_changed") + or safe_float((counterfactual.get("differences") or {}).get("score_delta")) != 0.0 + or safe_float((counterfactual.get("differences") or {}).get("confidence_delta")) != 0.0 + ) + improved = bool(comparison.get("improvement_detected")) + changes = { + "model_version_used": feedback.get("model_version_used"), + "weights_used": feedback.get("weights_used"), + "confidence_adjustment": feedback.get("confidence_adjustment"), + "base_confidence": feedback.get("base_confidence"), + "final_confidence": feedback.get("final_confidence"), + "research_priority_used": feedback.get("research_priority_used"), + "learning_mode_metadata": feedback.get("learning_mode_metadata"), + "counterfactual_audit": counterfactual, + } + decision = { + "prediction_id": prediction.id, + "ticker": prediction.ticker, + "analysis_date": iso(prediction.analysis_date), + "direction": prediction.expected_direction, + "confidence": prediction.confidence, + "aggregate_score": (prediction_payload.get("prediction") or {}).get("aggregate_score"), + "actionability": counterfactual.get("learned_prediction", {}).get("actionability"), + } + outcome_payload = { + "correct": correct, + "wrong": wrong, + "neutral": sum(1 for row in usable if row.get("outcome_label") == "neutral"), + "average_realized_return": round(mean(returns), 4) if returns else None, + "outcomes": {row.get("timeframe"): row.get("outcome_label") for row in outcomes}, + "baseline_direction_correct": comparison.get("baseline_direction_correct"), + "learned_direction_correct": comparison.get("learned_direction_correct"), + "baseline_actionability": comparison.get("baseline_actionability"), + "learned_actionability": comparison.get("learned_actionability"), + "baseline_would_trade": comparison.get("baseline_would_trade"), + "learned_would_trade": comparison.get("learned_would_trade"), + "avoided_loss": comparison.get("avoided_loss"), + "missed_gain": comparison.get("missed_gain"), + "improvement_reason": comparison.get("improvement_reason"), + } + summary = ( + f"{prediction.ticker} used {feedback.get('model_version_used', 'base-static')} with " + f"confidence adjustment {safe_float(feedback.get('confidence_adjustment')):.2f}; " + f"changed_decision={changed_decision}, improved={improved}. " + f"reason={comparison.get('improvement_reason', 'counterfactual_not_available')}." + ) + row = FeedbackLoopAudit( + prediction_id=prediction.id, + ticker=prediction.ticker, + model_version_used=feedback.get("model_version_used") or "base-static", + learned_knowledge_json=json_safe(learned), + changes_applied_json=json_safe(changes), + future_decision_json=json_safe(decision), + outcome_json=json_safe(outcome_payload), + improvement_detected=improved, + evidence_grade=evidence_grade, + summary=summary, + ) + db.add(row) + return { + "status": "recorded", + "prediction_id": prediction.id, + "model_version_used": row.model_version_used, + "what_was_learned": learned, + "what_changed": changes, + "future_decision_used_change": decision, + "counterfactual_audit": counterfactual, + "outcome": outcome_payload, + "improvement_detected": improved, + "evidence_grade": evidence_grade, + "summary": summary, + } + + def counterfactual_audit(self, prediction: HistoricalPrediction, prediction_payload: dict, outcomes: list[dict]) -> dict: + context = dict(prediction.point_in_time_context or {}) + context.pop("future_prices", None) + baseline = PredictionEngine().baseline_prediction(context) if context else {} + learned_prediction = prediction_payload.get("prediction") or {} + baseline_actionability = baseline.get("actionability") + learned_actionability = feedback_actionability( + learned_prediction.get("dominant_direction"), + learned_prediction.get("aggregate_confidence"), + learned_prediction.get("aggregate_score"), + ) + learned = { + "model_version_used": (prediction_payload.get("feedback_loop") or {}).get("model_version_used") or "base-static", + "weights_used": prediction_payload.get("weights_used") or {}, + "aggregate_score": learned_prediction.get("aggregate_score"), + "aggregate_confidence": learned_prediction.get("aggregate_confidence"), + "dominant_direction": learned_prediction.get("dominant_direction"), + "actionability": learned_actionability, + "confidence_adjustment": (prediction_payload.get("feedback_loop") or {}).get("confidence_adjustment", 0.0), + "memory_adjustment_used": bool((prediction_payload.get("feedback_loop") or {}).get("confidence_adjustment")), + } + baseline_correct = direction_correctness_summary(baseline.get("dominant_direction"), outcomes) + learned_correct = direction_correctness_summary(learned.get("dominant_direction"), outcomes) + baseline_would_trade = feedback_would_trade(baseline_actionability) + learned_would_trade = feedback_would_trade(learned_actionability) + returns = [safe_float(row.get("realized_return")) for row in outcomes if row.get("realized_return") is not None] + average_return = mean(returns) if returns else 0.0 + avoided_loss = round(abs(average_return), 4) if baseline_would_trade and not learned_would_trade and average_return < 0 else 0.0 + missed_gain = round(average_return, 4) if baseline_would_trade and not learned_would_trade and average_return > 0 else 0.0 + improvement_detected, improvement_reason = counterfactual_improvement_reason( + baseline_correct, + learned_correct, + baseline_would_trade, + learned_would_trade, + average_return, + avoided_loss, + missed_gain, + ) + comparison = { + "score_delta": round(safe_float(learned.get("aggregate_score")) - safe_float(baseline.get("aggregate_score")), 4), + "confidence_delta": round(safe_float(learned.get("aggregate_confidence")) - safe_float(baseline.get("aggregate_confidence")), 4), + "direction_changed": baseline.get("dominant_direction") != learned.get("dominant_direction"), + "actionability_changed": baseline_actionability != learned_actionability, + } + return { + "baseline_prediction": baseline, + "learned_prediction": learned, + "differences": comparison, + "outcome_comparison": { + "outcome_labels": {row.get("timeframe"): row.get("outcome_label") for row in outcomes}, + "realized_returns": {row.get("timeframe"): row.get("realized_return") for row in outcomes}, + "learned_direction": learned.get("dominant_direction"), + "baseline_direction": baseline.get("dominant_direction"), + "baseline_direction_correct": baseline_correct["direction_correct"], + "learned_direction_correct": learned_correct["direction_correct"], + "baseline_correct_count": baseline_correct["correct_count"], + "learned_correct_count": learned_correct["correct_count"], + "baseline_actionability": baseline_actionability, + "learned_actionability": learned_actionability, + "baseline_would_trade": baseline_would_trade, + "learned_would_trade": learned_would_trade, + "avoided_loss": avoided_loss, + "missed_gain": missed_gain, + "improvement_detected": improvement_detected, + "improvement_reason": improvement_reason, + "policy": "Outcome is observed after prediction persistence; baseline is recomputed only from point-in-time context.", + }, + } + + def report(self, db: Session, limit: int = 20) -> dict: + rows = db.scalars(select(FeedbackLoopAudit).order_by(desc(FeedbackLoopAudit.created_at)).limit(limit)).all() + return { + "status": "ready" if rows else "insufficient_evidence", + "rows": [serialize_feedback_audit(row) for row in rows], + "policy": "FeedbackLoopAudit is persisted by background learning runs and never computed by GET page render.", + } + + class LearningDashboardService: def dashboard(self, db: Session) -> dict: latest_run = db.scalar(select(LearningRun).order_by(desc(LearningRun.started_at)).limit(1)) @@ -866,6 +1274,7 @@ class LearningDashboardService: "strategy_memory": self.strategy_memory(db), "mistakes": self.mistake_summary(db), "model_versions": [serialize_model_version(row) for row in db.scalars(select(ModelVersion).order_by(desc(ModelVersion.created_at)).limit(8)).all()], + "feedback_loop_audit": FeedbackLoopAuditService().report(db, limit=8), "trading_game": trading_game, "policy": "BLUM Learning Loop optimizes calibration and robustness, not artificial 100% winrate.", } @@ -1302,6 +1711,227 @@ def active_model_version(db: Session) -> ModelVersion | None: return db.scalar(select(ModelVersion).where(ModelVersion.is_active.is_(True)).order_by(desc(ModelVersion.created_at)).limit(1)) +def active_weight_context(db: Session | None) -> tuple[str, dict, str]: + if db is not None: + row = active_model_version(db) + if row and isinstance(row.weights, dict) and row.weights: + return row.version, model_weights_with_fallback(row.weights), "active_model_version" + return "base-static", normalize_weights(BASE_SIGNAL_WEIGHTS), "base_signal_weights" + + +def learning_mode_metadata(trigger: str | None, sample_metadata: dict | None = None) -> dict: + sample_metadata = sample_metadata or {} + sampling_reason = sample_metadata.get("sampling_reason") or "random_point_in_time" + mode = "training_replay" if sampling_reason in {"alpha_loss_replay", "learning_focus_priority", "capital_preservation_replay"} or trigger == "alpha_loss_replay" else "walk_forward_validation" + if trigger == "paper_forward" or sample_metadata.get("mode") == "paper_forward": + mode = "paper_forward" + return { + "mode": mode, + "training_replay": mode == "training_replay", + "walk_forward_validation": mode == "walk_forward_validation", + "paper_forward": mode == "paper_forward", + "trigger": trigger or sample_metadata.get("run_trigger") or "unknown", + "sampling_reason": sampling_reason, + "evaluation_mode": sample_metadata.get("evaluation_mode") or settings.learning_evaluation_mode, + "policy": "Mode metadata is descriptive. It changes audit traceability, not source code or frontend execution.", + } + + +def feedback_actionability(direction: str | None, confidence: float | None, score: float | None = None) -> str: + confidence_value = safe_float(confidence) + score_value = safe_float(score) + if direction == "neutral" or confidence_value < 35: + return "watch" + if confidence_value >= 68 and direction in {"bullish", "bearish"} and abs(score_value - 50) >= 10: + return "active_setup" + if confidence_value >= 54 and direction in {"bullish", "bearish"}: + return "wait_for_trigger" + return "watch" + + +def feedback_would_trade(actionability: str | None) -> bool: + return actionability in {"active_setup", "wait_for_trigger", "actionable_if_confirmed"} + + +def direction_correctness_summary(direction: str | None, outcomes: list[dict]) -> dict: + rows = [row for row in outcomes if row.get("realized_return") is not None] + if not rows: + return {"direction_correct": None, "correct_count": 0, "wrong_count": 0, "sample_count": 0} + correct = sum(1 for row in rows if direction_matches_return(direction, safe_float(row.get("realized_return")))) + wrong = len(rows) - correct + return { + "direction_correct": correct > wrong, + "correct_count": correct, + "wrong_count": wrong, + "sample_count": len(rows), + } + + +def direction_matches_return(direction: str | None, realized_return: float) -> bool: + if direction == "bullish": + return realized_return > 0 + if direction == "bearish": + return realized_return < 0 + if direction == "neutral": + return abs(realized_return) <= 1.0 + return False + + +def counterfactual_improvement_reason( + baseline_correct: dict, + learned_correct: dict, + baseline_would_trade: bool, + learned_would_trade: bool, + average_return: float, + avoided_loss: float, + missed_gain: float, +) -> tuple[bool, str]: + baseline_count = int(baseline_correct.get("correct_count") or 0) + learned_count = int(learned_correct.get("correct_count") or 0) + if learned_count > baseline_count: + return True, "learned_direction_more_correct_than_baseline" + if learned_count < baseline_count: + return False, "learned_direction_less_correct_than_baseline" + if avoided_loss > 0: + return True, "learned_actionability_avoided_baseline_loss" + if missed_gain > 0: + return False, "learned_actionability_missed_baseline_gain" + if learned_would_trade and not baseline_would_trade and average_return > 0: + return True, "learned_actionability_captured_gain_baseline_would_skip" + if learned_would_trade and not baseline_would_trade and average_return < 0: + return False, "learned_actionability_entered_losing_trade_baseline_would_skip" + return False, "no_counterfactual_improvement_detected" + + +def model_weights_with_fallback(weights: dict) -> dict: + merged = dict(BASE_SIGNAL_WEIGHTS) + for key in BASE_SIGNAL_WEIGHTS: + if key in weights: + merged[key] = safe_float(weights.get(key)) if weights.get(key) is not None else BASE_SIGNAL_WEIGHTS[key] + return normalize_weights(merged) + + +def signal_performance_context(db: Session | None, context: dict, signal_scores: dict) -> dict: + if db is None or not signal_scores: + return {"rows": [], "confidence_delta": 0.0} + regime = context.get("market_context", {}).get("market_regime", "Unknown") + rows = db.scalars( + select(SignalPerformance) + .where(SignalPerformance.signal_name.in_(list(signal_scores.keys())), SignalPerformance.market_regime == regime) + .order_by(desc(SignalPerformance.sample_count), desc(SignalPerformance.updated_at)) + .limit(80) + ).all() + grouped: dict[str, list[SignalPerformance]] = defaultdict(list) + for row in rows: + grouped[row.signal_name].append(row) + payloads = [] + deltas = [] + for signal_name, signal_rows in grouped.items(): + sample_count = sum(int(row.sample_count or 0) for row in signal_rows) + reliability = mean(float(row.reliability_score or 50.0) for row in signal_rows) + false_positives = sum(int(row.false_positive_count or 0) for row in signal_rows) + false_positive_rate = false_positives / max(1, sample_count) + enough_evidence = sample_count >= MIN_MODEL_VERSION_SIGNAL_SAMPLE + delta = clamp((reliability - 50.0) / 8.0 - false_positive_rate * 4.0, -5.0, 5.0) if enough_evidence else 0.0 + payloads.append( + { + "signal_name": signal_name, + "market_regime": regime, + "sample_count": sample_count, + "reliability_score": round(reliability, 2), + "false_positive_rate": round(false_positive_rate, 4), + "signal_score": signal_scores.get(signal_name), + "confidence_delta": round(delta, 3), + "used": enough_evidence, + } + ) + if enough_evidence: + deltas.append(delta) + total_delta = clamp(sum(deltas) / max(1, len(deltas)) * 1.4, -8.0, 8.0) if deltas else 0.0 + return {"rows": payloads[:16], "confidence_delta": round(total_delta, 3)} + + +def strategy_memory_context(db: Session | None, context: dict) -> dict: + if db is None: + return {"rows": [], "confidence_delta": 0.0} + rows = db.scalars(select(StrategyMemory).order_by(desc(StrategyMemory.reliability_score), desc(StrategyMemory.updated_at)).limit(120)).all() + applicable = [] + deltas = [] + for row in rows: + if not strategy_memory_matches(row, context): + continue + sample_count = int(row.sample_count or 0) + enough_evidence = sample_count >= 3 + positive = int(row.positive_count or 0) + negative = int(row.negative_count or 0) + reliability = safe_float(row.reliability_score) if row.reliability_score is not None else 50.0 + delta = clamp((reliability - 50.0) / 10.0, -4.0, 4.0) if enough_evidence else 0.0 + if negative > positive and enough_evidence: + delta = min(delta, -1.5) + applicable.append( + { + "memory_key": row.memory_key, + "category": row.category, + "lesson": row.lesson, + "sample_count": sample_count, + "positive_count": positive, + "negative_count": negative, + "reliability_score": reliability, + "confidence_delta": round(delta, 3), + "used": enough_evidence, + } + ) + if enough_evidence: + deltas.append(delta) + total_delta = clamp(sum(deltas), -6.0, 6.0) if deltas else 0.0 + return {"rows": applicable[:12], "confidence_delta": round(total_delta, 3)} + + +def strategy_memory_matches(row: StrategyMemory, context: dict) -> bool: + conditions = row.conditions or {} + technical = context.get("technical") or {} + indicators = technical.get("technical_indicators") or {} + volume = technical.get("volume") or {} + fundamentals = context.get("fundamentals") or {} + if "rsi_gt" in conditions and safe_float(indicators.get("rsi")) > safe_float(conditions.get("rsi_gt")): + return True + if "relative_volume_gt" in conditions and safe_float(volume.get("relative_volume")) > safe_float(conditions.get("relative_volume_gt")): + return True + if conditions.get("fundamentals") == "not_point_in_time_verified" and fundamentals.get("status") != "ready": + return True + if row.category in {"general_calibration", "volume_confirmation"}: + return True + return False + + +def research_priority_context(db: Session | None, sample_metadata: dict) -> dict: + priority_id = sample_metadata.get("learning_focus_priority_id") + if db is not None and priority_id: + row = db.get(LearningFocusPriority, priority_id) + if row: + return { + "status": "used", + "id": row.id, + "priority_type": row.priority_type, + "target": row.target, + "reason": row.reason, + "expected_learning_value": row.expected_learning_value, + "urgency": row.urgency, + "sample_gap": row.sample_gap, + "sampling_reason": sample_metadata.get("sampling_reason"), + "confidence_delta": 0.0, + } + if sample_metadata.get("sampling_reason"): + return { + "status": "used", + "sampling_reason": sample_metadata.get("sampling_reason"), + "priority_type": sample_metadata.get("priority_type"), + "missed_winner_id": sample_metadata.get("missed_winner_id"), + "confidence_delta": 0.0, + } + return {"status": "not_applicable", "confidence_delta": 0.0} + + def normalize_weights(weights: dict[str, float]) -> dict[str, float]: total = sum(max(0.0, float(value)) for value in weights.values()) or 1.0 return {key: round(max(0.0, float(value)) / total, 4) for key, value in weights.items()} @@ -1372,6 +2002,11 @@ def serialize_prediction(row: HistoricalPrediction) -> dict: "market_regime": row.market_regime, "volatility_regime": row.volatility_regime, "data_quality_score": row.data_quality_score, + "model_version_used": row.model_version_used, + "weights_used": row.weights_used, + "learning_memory_used": row.learning_memory_used, + "strategy_memory_used": row.strategy_memory_used, + "research_priority_used": row.research_priority_used, "prediction": row.prediction_payload.get("prediction", {}) if row.prediction_payload else {}, "timeframes": row.prediction_payload.get("timeframes", {}) if row.prediction_payload else {}, "created_at": iso(row.created_at), @@ -1423,6 +2058,24 @@ def serialize_model_version(row: ModelVersion) -> dict: } +def serialize_feedback_audit(row: FeedbackLoopAudit) -> dict: + return { + "id": row.id, + "prediction_id": row.prediction_id, + "ticker": row.ticker, + "model_version_used": row.model_version_used, + "what_was_learned": row.learned_knowledge_json, + "what_changed": row.changes_applied_json, + "counterfactual_audit": (row.changes_applied_json or {}).get("counterfactual_audit"), + "future_decision_used_change": row.future_decision_json, + "outcome": row.outcome_json, + "improvement_detected": row.improvement_detected, + "evidence_grade": row.evidence_grade, + "summary": row.summary, + "created_at": iso(row.created_at), + } + + def fundamental_reason(fundamentals: dict) -> str: if fundamentals.get("status") == "ready": return f"Point-in-time verified fundamentals available with quality score {fundamentals.get('quality_score')}." @@ -1509,6 +2162,10 @@ def clamp(value: float, low: float = 0.0, high: float = 100.0) -> float: return max(low, min(high, float(value))) +def clamp_ratio(value: float) -> float: + return max(0.0, min(1.0, safe_float(value))) + + def round_float(value) -> float | None: return round(safe_float(value), 4) if value is not None else None diff --git a/backend/app/services/learning_summary.py b/backend/app/services/learning_summary.py index 261c61c892326ece96a71477adab490ece8da60d..b59eda124ad88f9a01934362b8a2d2a20c0bac10 100644 --- a/backend/app/services/learning_summary.py +++ b/backend/app/services/learning_summary.py @@ -3,16 +3,23 @@ from __future__ import annotations from datetime import datetime import time -from sqlalchemy import desc, select +from sqlalchemy import desc, inspect, select from sqlalchemy.orm import Session from app.models import ( BlumTradingPowerScore, DashboardSnapshot, + CapitalPreservationAlpha, LearningBenchmarkComparison, + LearningFactorImportance, + LearningFocusPriority, LearningRun, + LearningStrengthWeaknessMap, + ReasoningNoiseFlag, TradingCapitalCycle, TradingGame, + TradingIntelligenceMetric, + TradeLearningEvidence, ) from app.services.dashboard_snapshots import DashboardSnapshotService from app.services.performance import performance_recorder @@ -30,6 +37,21 @@ class LearningSummaryService: started = time.perf_counter() missing_sections: list[str] = [] warnings: list[str] = [] + snapshot_types = [ + "learning_summary", + "trading_game_summary", + "benchmark_summary", + "intelligence_growth_summary", + "truth_panel_summary", + "meta_cognition_summary", + ] + snapshots = {snapshot_type: DashboardSnapshotService().latest(db, snapshot_type) for snapshot_type in snapshot_types} + stale_snapshots = [snapshot_type for snapshot_type, payload in snapshots.items() if payload.get("status") == "stale"] + missing_snapshots = [snapshot_type for snapshot_type, payload in snapshots.items() if payload.get("status") == "missing"] + if stale_snapshots: + warnings.append(f"Using stale dashboard snapshots for: {', '.join(stale_snapshots)}.") + if missing_snapshots: + warnings.append(f"Dashboard snapshots not available yet for: {', '.join(missing_snapshots)}.") power = db.scalar(select(BlumTradingPowerScore).order_by(desc(BlumTradingPowerScore.calculated_at)).limit(1)) if power is None: @@ -54,35 +76,63 @@ class LearningSummaryService: if latest_run is None: missing_sections.append("latest_learning_run") + latest_metric = db.scalar(select(TradingIntelligenceMetric).order_by(desc(TradingIntelligenceMetric.calculated_at)).limit(1)) + if latest_metric is None: + missing_sections.append("trading_intelligence_metrics") + + top_weakness = db.scalar(select(LearningStrengthWeaknessMap).order_by(desc(LearningStrengthWeaknessMap.weakness_score), desc(LearningStrengthWeaknessMap.calculated_at)).limit(1)) + latest_lesson = db.scalar(select(TradeLearningEvidence).order_by(desc(TradeLearningEvidence.created_at)).limit(1)) + benchmarks = list(db.scalars(select(LearningBenchmarkComparison).order_by(desc(LearningBenchmarkComparison.calculated_at)).limit(24)).all()) benchmark_summary = summarize_benchmarks(benchmarks) if not benchmarks: missing_sections.append("benchmark_summary") live_snapshot = DashboardSnapshotService().latest(db, "live_vs_historical_summary") + meta_snapshot = snapshots.get("meta_cognition_summary") or {} if live_snapshot["status"] == "missing": warnings.append("Live vs historical summary snapshot is missing.") + if meta_snapshot.get("status") == "missing": + warnings.append("Meta-Cognition summary snapshot is missing.") current_capital = getattr(current_cycle, "final_capital", None) if current_cycle else getattr(game, "current_capital", None) target_capital = getattr(current_cycle, "target_capital", None) if current_cycle else getattr(game, "target_capital", None) target_progress = safe_progress(current_capital, target_capital) + current_cycle_payload = serialize_cycle(current_cycle) truth_panel_lines = build_truth_panel(power, benchmark_summary, warnings, benchmarks) + truth_snapshot = snapshots.get("truth_panel_summary", {}) + truth_snapshot_payload = truth_snapshot.get("payload") or {} + if truth_snapshot_payload.get("truth_panel"): + truth_panel_lines = truth_snapshot_payload["truth_panel"] + last_snapshot_timestamp = latest_snapshot_timestamp(snapshots) + backend_training_status = training_status(latest_run, snapshots) payload = { "status": "initializing" if missing_sections else "ready", "generated_at": datetime.utcnow().isoformat(), "summary_duration_ms": round((time.perf_counter() - started) * 1000, 3), + "learning_loop_status": getattr(latest_run, "status", None) or "not_started", "trading_power_score": power.score if power else None, "trading_power_classification": power.classification if power else "initializing", + "current_capital_cycle": current_cycle_payload, "current_capital": current_capital, "target_capital": target_capital, "target_progress": target_progress, + "win_rate": first_not_none(getattr(latest_metric, "win_rate", None), getattr(game, "win_rate", None)), + "expectancy_r": first_not_none(getattr(latest_metric, "expectancy_r", None), getattr(current_cycle, "expectancy_r", None), getattr(game, "expectancy_r", None)), "completed_target_cycles": getattr(game, "target_cycles_completed", 0) if game else 0, "bankrupt_cycles": getattr(game, "bankrupt_cycles", 0) if game else 0, "latest_learning_run_status": getattr(latest_run, "status", None) or "not_started", "latest_learning_run_at": latest_run.started_at.isoformat() if latest_run and latest_run.started_at else None, "benchmark_summary": benchmark_summary, "live_vs_historical_summary": live_snapshot, + "live_vs_historical_status": live_snapshot.get("status", "missing"), + "top_weakness": serialize_weakness(top_weakness), + "latest_lesson_learned": serialize_lesson(latest_lesson), "truth_panel": truth_panel_lines, + "what_blum_should_learn_next": what_blum_should_learn_next(db, meta_snapshot), + "backend_training_status": backend_training_status, + "last_snapshot_timestamp": last_snapshot_timestamp, + "snapshots": summarize_snapshots(snapshots), "warnings": warnings, "missing_sections": missing_sections, "data_freshness": { @@ -90,13 +140,15 @@ class LearningSummaryService: "game_updated_at": game.updated_at.isoformat() if game and game.updated_at else None, "learning_run_started_at": latest_run.started_at.isoformat() if latest_run and latest_run.started_at else None, "benchmark_calculated_at": max((row.calculated_at for row in benchmarks if row.calculated_at), default=None).isoformat() if benchmarks else None, + "trading_intelligence_calculated_at": latest_metric.calculated_at.isoformat() if latest_metric and latest_metric.calculated_at else None, + "last_snapshot_timestamp": last_snapshot_timestamp, }, - "is_recalculation_running": False, + "is_recalculation_running": backend_training_status["is_recalculation_running"], "suggested_next_step": "Use background workers or explicit recalculation buttons to refresh missing summaries." if missing_sections else "Summary is ready.", "performance": { "budget_ms": 300, "duration_ms": round((time.perf_counter() - started) * 1000, 3), - "source": "latest_precomputed_rows_only", + "source": "snapshots_first_latest_precomputed_rows_only", }, } performance_recorder.record_dashboard_widget( @@ -150,6 +202,160 @@ def build_truth_panel(power: BlumTradingPowerScore | None, benchmark_summary: di return output[:7] +def what_blum_should_learn_next(db: Session, meta_snapshot: dict) -> dict: + snapshot_payload = meta_snapshot.get("payload") or {} + if snapshot_payload: + return { + "status": meta_snapshot.get("status", "ready"), + "top_alpha_creating_factor": compact_factor(snapshot_payload.get("top_alpha_factor")), + "top_alpha_destroying_factor": compact_factor(snapshot_payload.get("top_alpha_destroyer")), + "noisiest_factor": compact_factor(snapshot_payload.get("noisiest_factor")), + "most_undervalued_factor": compact_factor(snapshot_payload.get("most_undervalued_factor")), + "strongest_capital_preservation_rule": compact_preservation(snapshot_payload.get("strongest_capital_preservation_rule")), + "weakest_current_module": compact_noise(snapshot_payload.get("weakest_current_module")), + "next_learning_focus": compact_focus(snapshot_payload.get("next_learning_focus")), + "conclusion": snapshot_payload.get("meta_cognition_conclusion", {}).get("summary") or "Meta-Cognition snapshot available.", + "source": "snapshot", + } + if not all(table_exists(db, model.__tablename__) for model in [LearningFactorImportance, LearningFocusPriority, ReasoningNoiseFlag, CapitalPreservationAlpha]): + return { + "status": "missing", + "top_alpha_creating_factor": None, + "top_alpha_destroying_factor": None, + "noisiest_factor": None, + "most_undervalued_factor": None, + "strongest_capital_preservation_rule": None, + "weakest_current_module": None, + "next_learning_focus": None, + "conclusion": "Meta-Cognition tables are not available yet; showing the rest of the Learning snapshot without recalculation.", + "source": "schema_not_ready", + } + factor_rows = db.scalars(select(LearningFactorImportance).order_by(desc(LearningFactorImportance.calculated_at)).limit(40)).all() + focus = db.scalar( + select(LearningFocusPriority) + .where(LearningFocusPriority.status.in_(["proposed", "active"])) + .order_by(desc(LearningFocusPriority.expected_learning_value), desc(LearningFocusPriority.created_at)) + .limit(1) + ) + noise = db.scalar(select(ReasoningNoiseFlag).where(ReasoningNoiseFlag.status == "open").order_by(desc(ReasoningNoiseFlag.created_at)).limit(1)) + preservation = db.scalar(select(CapitalPreservationAlpha).order_by(desc(CapitalPreservationAlpha.capital_preserved), desc(CapitalPreservationAlpha.created_at)).limit(1)) + top_alpha = max(factor_rows, key=lambda row: row.alpha_contribution, default=None) + top_loss = max(factor_rows, key=lambda row: row.alpha_loss_contribution, default=None) + noisiest = max(factor_rows, key=lambda row: row.noise_score, default=None) + undervalued = max(factor_rows, key=lambda row: row.undervaluation_score, default=None) + return { + "status": "ready" if factor_rows or focus or noise or preservation else "missing", + "top_alpha_creating_factor": compact_factor_obj(top_alpha), + "top_alpha_destroying_factor": compact_factor_obj(top_loss), + "noisiest_factor": compact_factor_obj(noisiest), + "most_undervalued_factor": compact_factor_obj(undervalued), + "strongest_capital_preservation_rule": compact_preservation_obj(preservation), + "weakest_current_module": compact_noise_obj(noise), + "next_learning_focus": compact_focus_obj(focus), + "conclusion": "Meta-Cognition snapshot missing; showing latest stored evidence only." if factor_rows else "Meta-Cognition evidence is not available yet.", + "source": "latest_rows_no_recalculation", + } + + +def table_exists(db: Session, table_name: str) -> bool: + try: + return inspect(db.get_bind()).has_table(table_name) + except Exception: + return False + + +def compact_factor(item: dict | None) -> dict | None: + if not item: + return None + return { + "factor_name": item.get("factor_name"), + "sample_size": item.get("sample_size"), + "confidence": item.get("confidence"), + "recommended_weight_action": item.get("recommended_weight_action"), + "alpha_contribution": item.get("alpha_contribution"), + "alpha_loss_contribution": item.get("alpha_loss_contribution"), + "noise_score": item.get("noise_score"), + } + + +def compact_factor_obj(row: LearningFactorImportance | None) -> dict | None: + return compact_factor({ + "factor_name": row.factor_name, + "sample_size": row.sample_size, + "confidence": row.confidence, + "recommended_weight_action": row.recommended_weight_action, + "alpha_contribution": row.alpha_contribution, + "alpha_loss_contribution": row.alpha_loss_contribution, + "noise_score": row.noise_score, + }) if row else None + + +def compact_focus(item: dict | None) -> dict | None: + if not item: + return None + return { + "priority_type": item.get("priority_type"), + "target": item.get("target"), + "expected_learning_value": item.get("expected_learning_value"), + "urgency": item.get("urgency"), + "reason": item.get("reason"), + } + + +def compact_focus_obj(row: LearningFocusPriority | None) -> dict | None: + return compact_focus({ + "priority_type": row.priority_type, + "target": row.target, + "expected_learning_value": row.expected_learning_value, + "urgency": row.urgency, + "reason": row.reason, + }) if row else None + + +def compact_preservation(item: dict | None) -> dict | None: + if not item: + return None + return { + "ticker": item.get("ticker"), + "setup_type": item.get("setup_type"), + "capital_preserved": item.get("capital_preserved"), + "opportunity_cost": item.get("opportunity_cost"), + "quality_score": item.get("quality_score"), + } + + +def compact_preservation_obj(row: CapitalPreservationAlpha | None) -> dict | None: + return compact_preservation({ + "ticker": row.ticker, + "setup_type": row.setup_type, + "capital_preserved": row.capital_preserved, + "opportunity_cost": row.opportunity_cost, + "quality_score": row.quality_score, + }) if row else None + + +def compact_noise(item: dict | None) -> dict | None: + if not item: + return None + return { + "factor_name": item.get("factor_name"), + "module_name": item.get("module_name"), + "noise_type": item.get("noise_type"), + "severity": item.get("severity"), + "recommended_action": item.get("recommended_action"), + } + + +def compact_noise_obj(row: ReasoningNoiseFlag | None) -> dict | None: + return compact_noise({ + "factor_name": row.factor_name, + "module_name": row.module_name, + "noise_type": row.noise_type, + "severity": row.severity, + "recommended_action": row.recommended_action, + }) if row else None + + def safe_progress(capital: float | None, target: float | None) -> float | None: if capital is None or target is None or target <= 0: return None @@ -158,3 +364,98 @@ def safe_progress(capital: float | None, target: float | None) -> float | None: def format_number(value: float | None) -> str: return "n/a" if value is None else f"{value:.2f}" + + +def first_not_none(*values): + for value in values: + if value is not None: + return value + return None + + +def serialize_cycle(row: TradingCapitalCycle | None) -> dict | None: + if row is None: + return None + return { + "id": row.id, + "cycle_number": row.cycle_number, + "status": row.status, + "started_at": row.started_at.isoformat() if row.started_at else None, + "ended_at": row.ended_at.isoformat() if row.ended_at else None, + "start_capital": row.start_capital, + "target_capital": row.target_capital, + "final_capital": row.final_capital, + "trades_count": row.trades_count, + "wins": row.wins, + "losses": row.losses, + "missed_entries": row.missed_entries, + "target_hits": row.target_hits, + "stop_hits": row.stop_hits, + "expectancy_r": row.expectancy_r, + "excess_return_vs_benchmark": row.excess_return_vs_benchmark, + "updated_at": row.updated_at.isoformat() if row.updated_at else None, + } + + +def serialize_weakness(row: LearningStrengthWeaknessMap | None) -> dict | None: + if row is None: + return None + return { + "dimension": row.dimension, + "entity": row.entity, + "weakness_score": row.weakness_score, + "strength_score": row.strength_score, + "sample_size": row.sample_size, + "main_problem": row.main_problem, + "recommended_action": row.recommended_action, + "priority": row.priority, + "calculated_at": row.calculated_at.isoformat() if row.calculated_at else None, + } + + +def serialize_lesson(row: TradeLearningEvidence | None) -> dict | None: + if row is None: + return None + return { + "ticker": row.ticker, + "setup_type": row.setup_type, + "lesson_type": row.lesson_type, + "observation": row.observation, + "sample_size": row.sample_size, + "affected_module": row.affected_module, + "confidence": row.confidence, + "created_at": row.created_at.isoformat() if row.created_at else None, + } + + +def summarize_snapshots(snapshots: dict[str, dict]) -> dict: + output = {} + for snapshot_type, payload in snapshots.items(): + output[snapshot_type] = { + "status": payload.get("status"), + "created_at": payload.get("created_at"), + "expires_at": payload.get("expires_at"), + "is_stale": payload.get("is_stale"), + "warnings": payload.get("warnings") or ([payload.get("warning")] if payload.get("warning") else []), + } + return output + + +def latest_snapshot_timestamp(snapshots: dict[str, dict]) -> str | None: + timestamps = [payload.get("created_at") for payload in snapshots.values() if payload.get("created_at")] + return max(timestamps) if timestamps else None + + +def training_status(latest_run: LearningRun | None, snapshots: dict[str, dict]) -> dict: + running_statuses = {"running", "queued", "processing", "in_progress"} + status = getattr(latest_run, "status", None) or "not_started" + running = status in running_statuses + stale_count = sum(1 for payload in snapshots.values() if payload.get("status") == "stale") + return { + "mode": "backend_scheduler_independent", + "status": "running" if running else status, + "is_recalculation_running": running, + "frontend_policy": "read_only_snapshot_observer", + "stale_snapshot_count": stale_count, + "latest_run_id": getattr(latest_run, "run_id", None), + } diff --git a/backend/app/services/performance.py b/backend/app/services/performance.py index 16aa93d827ca2379026309dfd002e72b1a4b1baa..2ca05b981f7485860f1f6cc606206b1bc4a32ce1 100644 --- a/backend/app/services/performance.py +++ b/backend/app/services/performance.py @@ -424,7 +424,12 @@ def top_bottlenecks(api_events: list[dict[str, Any]], db_events: list[dict[str, def learning_page_load_summary(api_events: list[dict[str, Any]], widget_events: list[dict[str, Any]], frontend_widget_events: list[dict[str, Any]]) -> dict[str, Any]: - frontend_api_events = [event for event in frontend_widget_events if str(event.get("name", "")).startswith("frontend.api.")] + all_frontend_api_events = [event for event in frontend_widget_events if str(event.get("name", "")).startswith("frontend.api.")] + frontend_api_events = [ + event for event in all_frontend_api_events + if str((event.get("metadata") or {}).get("route") or "").startswith("/learning") + and bool((event.get("metadata") or {}).get("initial_learning_window")) + ] status_counts: dict[str, int] = defaultdict(int) for event in frontend_api_events: status_counts[str((event.get("metadata") or {}).get("status") or "unknown")] += 1 @@ -450,6 +455,7 @@ def learning_page_load_summary(api_events: list[dict[str, Any]], widget_events: ] return { "frontend_request_count": len(frontend_api_events), + "unscoped_frontend_request_count": len(all_frontend_api_events), "duplicate_request_count": status_counts.get("deduped", 0), "cache_hit_count": status_counts.get("cache_hit", 0) + status_counts.get("cache", 0), "status_counts": dict(status_counts), diff --git a/backend/app/services/trade_transparency.py b/backend/app/services/trade_transparency.py index efb66999210d5c7a05ecb96b8fab01e0e230af2b..4efb9f766eccbe28dafa5273ec16d143edfc9517 100644 --- a/backend/app/services/trade_transparency.py +++ b/backend/app/services/trade_transparency.py @@ -51,41 +51,79 @@ class TradeLedgerService: limit: int = 200, offset: int = 0, refresh: bool = True, + use_snapshot: bool = True, + include_trace: bool = False, ) -> dict: + if use_snapshot and self._can_use_ledger_snapshot( + ticker=ticker, + setup_type=setup_type, + outcome_label=outcome_label, + start_date=start_date, + end_date=end_date, + min_r=min_r, + max_r=max_r, + only_open=only_open, + only_closed=only_closed, + sort_by=sort_by, + ): + from app.services.trading_game_runtime import TradingGameRuntimeSnapshotService + + snapshot_payload = TradingGameRuntimeSnapshotService().ledger_from_snapshot(db, game_id=game_id, limit=limit, offset=offset) + if snapshot_payload is not None: + return snapshot_payload game = self.game(db, game_id) if not game: return {"status": "no_game", "rows": [], "summary": {}, "policy": TRANSPARENCY_POLICY} + from app.services.trading_game_runtime import RuntimeTrace, payload_size_bytes + + trace = RuntimeTrace("trading_game_ledger_live_read") if refresh: - self.refresh_game_transparency(db, game, commit=False, persist_reality=False) - query = select(TradingGameTrade).where(TradingGameTrade.game_id == game.id) - if ticker: - query = query.where(TradingGameTrade.ticker == ticker.upper()) - if setup_type: - query = query.where(TradingGameTrade.setup_type == setup_type) - if outcome_label: - query = query.where(TradingGameTrade.outcome_label == outcome_label) - parsed_start = parse_date(start_date) - parsed_end = parse_date(end_date) - if parsed_start: - query = query.where(TradingGameTrade.entry_date >= parsed_start) - if parsed_end: - query = query.where(TradingGameTrade.entry_date <= parsed_end) - if min_r is not None: - query = query.where(TradingGameTrade.realized_r_multiple >= min_r) - if max_r is not None: - query = query.where(TradingGameTrade.realized_r_multiple <= max_r) - if only_open: - query = query.where(TradingGameTrade.exit_date.is_(None)) - if only_closed: - query = query.where(TradingGameTrade.exit_date.is_not(None)) - total = int(db.scalar(select(func.count()).select_from(query.subquery())) or 0) - query = order_trade_query(query, sort_by).limit(limit).offset(offset) - rows = db.scalars(query).all() - return { + with trace.phase("refresh_transparency"): + self.refresh_game_transparency(db, game, commit=False, persist_reality=False) + with trace.phase("base_trade_query"): + query = select(TradingGameTrade).where(TradingGameTrade.game_id == game.id) + if ticker: + query = query.where(TradingGameTrade.ticker == ticker.upper()) + if setup_type: + query = query.where(TradingGameTrade.setup_type == setup_type) + if outcome_label: + query = query.where(TradingGameTrade.outcome_label == outcome_label) + parsed_start = parse_date(start_date) + parsed_end = parse_date(end_date) + if parsed_start: + query = query.where(TradingGameTrade.entry_date >= parsed_start) + if parsed_end: + query = query.where(TradingGameTrade.entry_date <= parsed_end) + if min_r is not None: + query = query.where(TradingGameTrade.realized_r_multiple >= min_r) + if max_r is not None: + query = query.where(TradingGameTrade.realized_r_multiple <= max_r) + if only_open: + query = query.where(TradingGameTrade.exit_date.is_(None)) + if only_closed: + query = query.where(TradingGameTrade.exit_date.is_not(None)) + total = int(db.scalar(select(func.count()).select_from(query.subquery())) or 0) + query = order_trade_query(query, sort_by).limit(limit).offset(offset) + rows = db.scalars(query).all() + with trace.phase("attribution_loading"): + attribution_count = 0 + with trace.phase("evidence_loading"): + evidence_count = 0 + with trace.phase("benchmark_loading"): + benchmark_count = sum(1 for row in rows if row.benchmark_return_same_period is not None or row.benchmark_return is not None) + with trace.phase("quality_loading"): + quality_count = sum(1 for row in rows if row.trade_quality_score is not None) + with trace.phase("prediction_loading"): + prediction_count = sum(1 for row in rows if row.thesis_id) + with trace.phase("serialization"): + serialized_rows = [self.serialize_trade(db, row) for row in rows] + summary = self.summary_for_game(db, game) + payload = { "status": "ok", + "snapshot_status": "miss", "game": serialize_game_header(game), - "summary": self.summary_for_game(db, game), - "rows": [self.serialize_trade(db, row) for row in rows], + "summary": summary, + "rows": serialized_rows, "total": total, "limit": limit, "offset": offset, @@ -104,6 +142,27 @@ class TradeLedgerService: }, "policy": TRANSPARENCY_POLICY, } + with trace.phase("json_generation"): + response_size = payload_size_bytes(payload) + trace.add( + snapshot_miss=True, + base_trade_query_count=2, + attribution_loading_queries=0, + evidence_loading_queries=0, + benchmark_loading_queries=0, + quality_loading_queries=0, + prediction_loading_queries=0, + attribution_rows=attribution_count, + evidence_rows=evidence_count, + benchmark_rows=benchmark_count, + quality_rows=quality_count, + prediction_links=prediction_count, + row_count=len(rows), + total_trades=total, + response_size_bytes=response_size, + ) + payload["runtime_trace"] = trace.payload() + return payload def detail(self, db: Session, trade_id: int) -> dict: trade = db.get(TradingGameTrade, trade_id) @@ -233,6 +292,33 @@ class TradeLedgerService: return db.get(TradingGame, game_id) return db.scalar(select(TradingGame).where(TradingGame.status == "active").order_by(desc(TradingGame.started_at)).limit(1)) or db.scalar(select(TradingGame).order_by(desc(TradingGame.started_at)).limit(1)) + def _can_use_ledger_snapshot( + self, + *, + ticker: str | None, + setup_type: str | None, + outcome_label: str | None, + start_date: str | None, + end_date: str | None, + min_r: float | None, + max_r: float | None, + only_open: bool, + only_closed: bool, + sort_by: str, + ) -> bool: + return ( + ticker is None + and setup_type is None + and outcome_label is None + and start_date is None + and end_date is None + and min_r is None + and max_r is None + and not only_open + and not only_closed + and sort_by == "created_at_desc" + ) + def serialize_trade(self, db: Session, trade: TradingGameTrade) -> dict: return { "trade_id": trade.id, @@ -430,22 +516,61 @@ class TradeQualityEvaluator: class EquityCurveAnnotationService: - def annotated_equity(self, db: Session, game_id: int | None = None, limit: int = 800) -> dict: + def annotated_equity( + self, + db: Session, + game_id: int | None = None, + limit: int = 800, + *, + refresh: bool = False, + use_snapshot: bool = True, + include_trace: bool = False, + ) -> dict: + if use_snapshot: + from app.services.trading_game_runtime import TradingGameRuntimeSnapshotService + + snapshot_payload = TradingGameRuntimeSnapshotService().equity_from_snapshot(db, game_id=game_id, limit=limit) + if snapshot_payload is not None: + return snapshot_payload game = TradeLedgerService().game(db, game_id) if not game: return {"status": "no_game", "equity_curve_points": [], "benchmark_curve_points": [], "annotations": []} - trades = db.scalars(select(TradingGameTrade).where(TradingGameTrade.game_id == game.id).order_by(TradingGameTrade.created_at)).all() - self.refresh(db, game, trades) - points = db.scalars(select(TradingGameEquityCurve).where(TradingGameEquityCurve.game_id == game.id).order_by(TradingGameEquityCurve.created_at).limit(limit)).all() - annotations = db.scalars(select(EquityCurveAnnotation).where(EquityCurveAnnotation.game_id == game.id).order_by(EquityCurveAnnotation.timestamp).limit(limit)).all() - return { - "status": "ok", - "game": serialize_game_header(game), - "equity_curve_points": [serialize_equity_point(row) for row in points], - "benchmark_curve_points": [{"timestamp": iso(row.equity_date or row.created_at), "value": row.benchmark_equity, "return": row.benchmark_return} for row in points], - "annotations": [serialize_annotation(row) for row in annotations], - "policy": "Markers connect equity movement to trade entries, exits, drawdowns, rule events and benchmark divergence when those events exist.", - } + from app.services.trading_game_runtime import RuntimeTrace, payload_size_bytes + + trace = RuntimeTrace("equity_curve_annotated_live_read") + if refresh: + with trace.phase("annotation_refresh"): + trades = db.scalars(select(TradingGameTrade).where(TradingGameTrade.game_id == game.id).order_by(TradingGameTrade.created_at)).all() + self.refresh(db, game, trades) + with trace.phase("equity_points_loading"): + points = db.scalars(select(TradingGameEquityCurve).where(TradingGameEquityCurve.game_id == game.id).order_by(TradingGameEquityCurve.created_at).limit(limit)).all() + with trace.phase("annotations_loading"): + annotations = db.scalars(select(EquityCurveAnnotation).where(EquityCurveAnnotation.game_id == game.id).order_by(EquityCurveAnnotation.timestamp).limit(limit)).all() + with trace.phase("benchmark_loading"): + benchmark_curve_points = [{"timestamp": iso(row.equity_date or row.created_at), "value": row.benchmark_equity, "return": row.benchmark_return} for row in points] + with trace.phase("serialization"): + payload = { + "status": "ok", + "snapshot_status": "miss", + "game": serialize_game_header(game), + "equity_curve_points": [serialize_equity_point(row) for row in points], + "benchmark_curve_points": benchmark_curve_points, + "annotations": [serialize_annotation(row) for row in annotations], + "policy": "Markers connect equity movement to trade entries, exits, drawdowns, rule events and benchmark divergence when those events exist.", + } + with trace.phase("json_generation"): + size = payload_size_bytes(payload) + trace.add( + snapshot_miss=True, + equity_points_queries=1, + annotations_queries=1, + benchmark_loading_queries=0, + point_count=len(points), + annotation_count=len(annotations), + response_size_bytes=size, + ) + payload["runtime_trace"] = trace.payload() + return payload def refresh(self, db: Session, game: TradingGame, trades: list[TradingGameTrade]) -> None: for trade in trades: diff --git a/backend/app/services/trading_game.py b/backend/app/services/trading_game.py index 1dbeb02016562ea2800f483a440e5ed9b0268d56..4a7b34291ddc9c561b47a320708bd1e234450fb8 100644 --- a/backend/app/services/trading_game.py +++ b/backend/app/services/trading_game.py @@ -428,6 +428,7 @@ class TradingGameSimulator: "simulation": simulation.simulation_payload, "prediction_id": prediction.id if prediction else None, "market_regime": prediction.market_regime if prediction else "unknown", + "feedback_loop": prediction_feedback_payload(prediction), "guardrails": guardrails(), }, ) @@ -624,6 +625,26 @@ def trade_reproducibility_score(simulation: ExecutionSimulation, prediction: His return round(clamp(score), 2) +def prediction_feedback_payload(prediction: HistoricalPrediction | None) -> dict: + if not prediction: + return { + "status": "missing_prediction", + "policy": "No HistoricalPrediction was linked to this simulated trade.", + } + feedback = (prediction.prediction_payload or {}).get("feedback_loop") or {} + return { + "status": "ready", + "model_version_used": prediction.model_version_used or prediction.model_version or "base-static", + "weights_used": prediction.weights_used or feedback.get("weights_used") or {}, + "confidence_adjustment": feedback.get("confidence_adjustment", 0.0), + "learning_memory_used": prediction.learning_memory_used or feedback.get("learning_memory_used") or {}, + "strategy_memory_used": prediction.strategy_memory_used or feedback.get("strategy_memory_used") or {}, + "research_priority_used": prediction.research_priority_used or feedback.get("research_priority_used") or {}, + "learning_mode_metadata": feedback.get("learning_mode_metadata") or (prediction.prediction_payload or {}).get("learning_mode_metadata") or {}, + "policy": "Paper trade payload records the prediction feedback loop metadata; it does not recalculate learning during trade rendering.", + } + + def decision_state_for(simulation: ExecutionSimulation, reproducibility: float) -> str: if reproducibility < 42: return "avoid" diff --git a/backend/tests/test_learning_performance_architecture.py b/backend/tests/test_learning_performance_architecture.py index 19f1424e568ae6e2aa088a6628a71ad5b6cd599c..d641bb2ef257b3e771c0e1c3687dcf7dc183e20a 100644 --- a/backend/tests/test_learning_performance_architecture.py +++ b/backend/tests/test_learning_performance_architecture.py @@ -9,8 +9,12 @@ from app.models import ( DashboardSnapshot, LearningBenchmarkComparison, LearningRun, + LearningStrengthWeaknessMap, TradingCapitalCycle, TradingGame, + TradingGameTrade, + TradingIntelligenceMetric, + TradeLearningEvidence, ) from app.services.dashboard_snapshots import DashboardSnapshotService from app.services.learning_summary import LearningSummaryService, build_truth_panel, safe_progress, summarize_benchmarks @@ -41,8 +45,12 @@ def test_learning_summary_returns_partial_payload_without_precomputed_rows(): DashboardSnapshot, LearningBenchmarkComparison, LearningRun, + LearningStrengthWeaknessMap, TradingCapitalCycle, TradingGame, + TradingGameTrade, + TradingIntelligenceMetric, + TradeLearningEvidence, ]: model.__table__.create(bind=engine) @@ -51,6 +59,9 @@ def test_learning_summary_returns_partial_payload_without_precomputed_rows(): assert payload["status"] == "initializing" assert "trading_power_score" in payload["missing_sections"] + assert "trading_intelligence_metrics" in payload["missing_sections"] + assert payload["backend_training_status"]["frontend_policy"] == "read_only_snapshot_observer" + assert "snapshots" in payload assert payload["truth_panel"][0].startswith("Not enough precomputed evidence") @@ -74,9 +85,69 @@ def test_learning_page_keeps_heavy_work_out_of_initial_render(): page = Path(__file__).resolve().parents[2] / "frontend" / "app" / "learning" / "page.tsx" text = page.read_text() - assert "setTimeout(loadVisibleTables" not in text - assert "IntersectionObserver" in text + assert text.strip() == 'export { default } from "../training-ground/page";' + + training_page = Path(__file__).resolve().parents[2] / "frontend" / "app" / "training-ground" / "page.tsx" + training_text = training_page.read_text() + initial_effect = training_text.split("useEffect(() => {", 1)[1].split("}, []);", 1)[0] + + assert "api.traderTrainingGround()" in initial_effect + assert initial_effect.count("api.") == 1 + assert "api.tradingGameLedger" not in training_text + assert "api.alphaRecoveryDashboard()" not in training_text + assert "api.metaCognitionSummary()" not in training_text assert "recalculateLearningTradingPower" not in text assert "recalculateDecisionSuperiority" not in text assert "recalculateBusinessQuality" not in text assert "recalculatePortfolioIntelligence" not in text + assert "recalculateAlphaRecovery" not in text + assert "metaCognitionRecalculate" not in text + + +def test_deep_diagnostics_uses_human_readable_renderer_not_raw_json_dump(): + page = Path(__file__).resolve().parents[2] / "frontend" / "components" / "DiagnosticPanelRenderer.tsx" + text = page.read_text() + + assert "compactPreview" not in text + assert "JSON.stringify(compactPreview" not in text + assert "DiagnosticPanelRenderer" in text + assert "Show raw JSON" in text + + +def test_diagnostic_panel_renderer_hides_raw_json_by_default(): + renderer = Path(__file__).resolve().parents[2] / "frontend" / "components" / "DiagnosticPanelRenderer.tsx" + text = renderer.read_text() + + assert "export function DiagnosticPanelRenderer" in text + assert "function ReliabilityByRegimeRenderer" in text + assert "function EnsembleStatusRenderer" in text + assert "export function SampleSizeWarning" in text + assert "export function WeightDistributionTable" in text + assert "Show raw JSON" in text + assert "Hide raw JSON" in text + assert "open &&
react-plotly.js": {
+ "id": 3506,
+ "files": [
+ "static/chunks/51e374df.e869da9a92d22819.js",
+ "static/chunks/54.5c9e84e15db88a9c.js"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/required-server-files.json b/frontend/.next/required-server-files.json
new file mode 100644
index 0000000000000000000000000000000000000000..b8e595d18d9d7919cc4b53d92e2c5ecbd2417af8
--- /dev/null
+++ b/frontend/.next/required-server-files.json
@@ -0,0 +1 @@
+{"version":1,"config":{"env":{},"webpack":null,"eslint":{"ignoreDuringBuilds":false},"typescript":{"ignoreBuildErrors":false,"tsconfigPath":"tsconfig.json"},"distDir":".next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.mjs","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"analyticsId":"","images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[16,32,48,64,96,128,256,384],"path":"/_next/image/","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":60,"formats":["image/webp"],"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"inline","remotePatterns":[],"unoptimized":true},"devIndicators":{"buildActivity":true,"buildActivityPosition":"bottom-right"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"amp":{"canonicalBase":""},"basePath":"","sassOptions":{},"trailingSlash":true,"i18n":null,"productionBrowserSourceMaps":false,"optimizeFonts":true,"excludeDefaultMomentLocales":true,"serverRuntimeConfig":{},"publicRuntimeConfig":{},"reactProductionProfiling":false,"reactStrictMode":null,"httpAgentOptions":{"keepAlive":true},"outputFileTracing":true,"staticPageGenerationTimeout":60,"swcMinify":true,"output":"export","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"experimental":{"multiZoneDraftMode":false,"prerenderEarlyExit":false,"serverMinification":true,"serverSourceMaps":false,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","middlewarePrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":10,"memoryBasedWorkersCount":false,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"outputFileTracingRoot":"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend","swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"adjustFontFallbacks":false,"adjustFontFallbacksWithSizeAdjust":false,"typedRoutes":false,"instrumentationHook":false,"bundlePagesExternals":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"missingSuspenseWithCSRBailout":true,"optimizeServerReact":true,"useEarlyImport":false,"staleTimes":{"dynamic":30,"static":300},"optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"configFileName":"next.config.mjs"},"appDir":"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend","relativeAppDir":"","files":[".next/routes-manifest.json",".next/server/pages-manifest.json",".next/build-manifest.json",".next/prerender-manifest.json",".next/server/middleware-manifest.json",".next/server/middleware-build-manifest.js",".next/server/middleware-react-loadable-manifest.js",".next/server/app-paths-manifest.json",".next/app-path-routes-manifest.json",".next/app-build-manifest.json",".next/server/server-reference-manifest.js",".next/server/server-reference-manifest.json",".next/react-loadable-manifest.json",".next/server/font-manifest.json",".next/BUILD_ID",".next/server/next-font-manifest.js",".next/server/next-font-manifest.json"],"ignore":["node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@ampproject/toolbox-optimizer/**/*"]}
\ No newline at end of file
diff --git a/frontend/.next/routes-manifest.json b/frontend/.next/routes-manifest.json
new file mode 100644
index 0000000000000000000000000000000000000000..068b893a8d0f8d64de03f06b7576f1f94452e590
--- /dev/null
+++ b/frontend/.next/routes-manifest.json
@@ -0,0 +1 @@
+{"version":3,"pages404":true,"caseSensitive":false,"basePath":"","redirects":[{"source":"/:file((?!\\.well-known(?:/.*)?)(?:[^/]+/)*[^/]+\\.\\w+)/","destination":"/:file","internal":true,"missing":[{"type":"header","key":"x-nextjs-data"}],"statusCode":308,"regex":"^(?:/((?!\\.well-known(?:/.*)?)(?:[^/]+/)*[^/]+\\.\\w+))/$"},{"source":"/:notfile((?!\\.well-known(?:/.*)?)(?:[^/]+/)*[^/\\.]+)","destination":"/:notfile/","internal":true,"statusCode":308,"regex":"^(?:/((?!\\.well-known(?:/.*)?)(?:[^/]+/)*[^/\\.]+))$"}],"headers":[],"dynamicRoutes":[{"page":"/assets/[ticker]","regex":"^/assets/([^/]+?)(?:/)?$","routeKeys":{"nxtPticker":"nxtPticker"},"namedRegex":"^/assets/(?[^/]+?)(?:/)?$"}],"staticRoutes":[{"page":"/","regex":"^/(?:/)?$","routeKeys":{},"namedRegex":"^/(?:/)?$"},{"page":"/_not-found","regex":"^/_not\\-found(?:/)?$","routeKeys":{},"namedRegex":"^/_not\\-found(?:/)?$"},{"page":"/backtest","regex":"^/backtest(?:/)?$","routeKeys":{},"namedRegex":"^/backtest(?:/)?$"},{"page":"/chart-analyst","regex":"^/chart\\-analyst(?:/)?$","routeKeys":{},"namedRegex":"^/chart\\-analyst(?:/)?$"},{"page":"/chat","regex":"^/chat(?:/)?$","routeKeys":{},"namedRegex":"^/chat(?:/)?$"},{"page":"/chatbot","regex":"^/chatbot(?:/)?$","routeKeys":{},"namedRegex":"^/chatbot(?:/)?$"},{"page":"/dashboard","regex":"^/dashboard(?:/)?$","routeKeys":{},"namedRegex":"^/dashboard(?:/)?$"},{"page":"/etf-radar","regex":"^/etf\\-radar(?:/)?$","routeKeys":{},"namedRegex":"^/etf\\-radar(?:/)?$"},{"page":"/ipo-radar","regex":"^/ipo\\-radar(?:/)?$","routeKeys":{},"namedRegex":"^/ipo\\-radar(?:/)?$"},{"page":"/learning","regex":"^/learning(?:/)?$","routeKeys":{},"namedRegex":"^/learning(?:/)?$"},{"page":"/market-brain","regex":"^/market\\-brain(?:/)?$","routeKeys":{},"namedRegex":"^/market\\-brain(?:/)?$"},{"page":"/methodology","regex":"^/methodology(?:/)?$","routeKeys":{},"namedRegex":"^/methodology(?:/)?$"},{"page":"/narratives","regex":"^/narratives(?:/)?$","routeKeys":{},"namedRegex":"^/narratives(?:/)?$"},{"page":"/performance","regex":"^/performance(?:/)?$","routeKeys":{},"namedRegex":"^/performance(?:/)?$"},{"page":"/signal-lab","regex":"^/signal\\-lab(?:/)?$","routeKeys":{},"namedRegex":"^/signal\\-lab(?:/)?$"},{"page":"/sniper","regex":"^/sniper(?:/)?$","routeKeys":{},"namedRegex":"^/sniper(?:/)?$"},{"page":"/stock-radar","regex":"^/stock\\-radar(?:/)?$","routeKeys":{},"namedRegex":"^/stock\\-radar(?:/)?$"},{"page":"/themes","regex":"^/themes(?:/)?$","routeKeys":{},"namedRegex":"^/themes(?:/)?$"}],"dataRoutes":[],"rsc":{"header":"RSC","varyHeader":"RSC, Next-Router-State-Tree, Next-Router-Prefetch","prefetchHeader":"Next-Router-Prefetch","didPostponeHeader":"x-nextjs-postponed","contentTypeHeader":"text/x-component","suffix":".rsc","prefetchSuffix":".prefetch.rsc"},"rewrites":[]}
\ No newline at end of file
diff --git a/frontend/.next/server/app-paths-manifest.json b/frontend/.next/server/app-paths-manifest.json
new file mode 100644
index 0000000000000000000000000000000000000000..baf504a44afaf685268a7cfc3c2abc1e9858d099
--- /dev/null
+++ b/frontend/.next/server/app-paths-manifest.json
@@ -0,0 +1,21 @@
+{
+ "/_not-found/page": "app/_not-found/page.js",
+ "/backtest/page": "app/backtest/page.js",
+ "/chart-analyst/page": "app/chart-analyst/page.js",
+ "/chat/page": "app/chat/page.js",
+ "/chatbot/page": "app/chatbot/page.js",
+ "/learning/page": "app/learning/page.js",
+ "/methodology/page": "app/methodology/page.js",
+ "/ipo-radar/page": "app/ipo-radar/page.js",
+ "/market-brain/page": "app/market-brain/page.js",
+ "/narratives/page": "app/narratives/page.js",
+ "/page": "app/page.js",
+ "/etf-radar/page": "app/etf-radar/page.js",
+ "/performance/page": "app/performance/page.js",
+ "/signal-lab/page": "app/signal-lab/page.js",
+ "/sniper/page": "app/sniper/page.js",
+ "/stock-radar/page": "app/stock-radar/page.js",
+ "/themes/page": "app/themes/page.js",
+ "/dashboard/page": "app/dashboard/page.js",
+ "/assets/[ticker]/page": "app/assets/[ticker]/page.js"
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/_not-found.html b/frontend/.next/server/app/_not-found.html
new file mode 100644
index 0000000000000000000000000000000000000000..c258a346726f06c8f5193fd77a2c9c4950c64554
--- /dev/null
+++ b/frontend/.next/server/app/_not-found.html
@@ -0,0 +1 @@
+404: This page could not be found. Blum AI Financial Intelligence 404
This page could not be found.
\ No newline at end of file
diff --git a/frontend/.next/server/app/_not-found.meta b/frontend/.next/server/app/_not-found.meta
new file mode 100644
index 0000000000000000000000000000000000000000..af19ee3e9e2ebbe56d0f288023f8016b08c4e93f
--- /dev/null
+++ b/frontend/.next/server/app/_not-found.meta
@@ -0,0 +1,6 @@
+{
+ "status": 404,
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/_not-found/layout,_N_T_/_not-found/page,_N_T_/_not-found/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/_not-found.rsc b/frontend/.next/server/app/_not-found.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..842c67610aaa303eaef910238d0f39d7c136d45d
--- /dev/null
+++ b/frontend/.next/server/app/_not-found.rsc
@@ -0,0 +1,10 @@
+2:I[176,[],""]
+3:I[9414,[],""]
+4:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+5:{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"}
+6:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"}
+7:{"display":"inline-block"}
+8:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0}
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["/_not-found",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["/_not-found",{"children":["__PAGE__",{},[["$L1",[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],null],null],null]},[null,["$","$L2",null,{"parallelRouterKey":"children","segmentPath":["children","/_not-found","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L4",null,{"children":["$","$L2",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$5","children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":"$6","children":"404"}],["$","div",null,{"style":"$7","children":["$","h2",null,{"style":"$8","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L9",["$","meta",null,{"name":"robots","content":"noindex"}]]]]]
+9:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/_not-found/index.html b/frontend/.next/server/app/_not-found/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..c258a346726f06c8f5193fd77a2c9c4950c64554
--- /dev/null
+++ b/frontend/.next/server/app/_not-found/index.html
@@ -0,0 +1 @@
+404: This page could not be found. Blum AI Financial Intelligence 404
This page could not be found.
\ No newline at end of file
diff --git a/frontend/.next/server/app/_not-found/index.meta b/frontend/.next/server/app/_not-found/index.meta
new file mode 100644
index 0000000000000000000000000000000000000000..af19ee3e9e2ebbe56d0f288023f8016b08c4e93f
--- /dev/null
+++ b/frontend/.next/server/app/_not-found/index.meta
@@ -0,0 +1,6 @@
+{
+ "status": 404,
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/_not-found/layout,_N_T_/_not-found/page,_N_T_/_not-found/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/_not-found/index.rsc b/frontend/.next/server/app/_not-found/index.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..842c67610aaa303eaef910238d0f39d7c136d45d
--- /dev/null
+++ b/frontend/.next/server/app/_not-found/index.rsc
@@ -0,0 +1,10 @@
+2:I[176,[],""]
+3:I[9414,[],""]
+4:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+5:{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"}
+6:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"}
+7:{"display":"inline-block"}
+8:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0}
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["/_not-found",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["/_not-found",{"children":["__PAGE__",{},[["$L1",[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],null],null],null]},[null,["$","$L2",null,{"parallelRouterKey":"children","segmentPath":["children","/_not-found","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L4",null,{"children":["$","$L2",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$5","children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":"$6","children":"404"}],["$","div",null,{"style":"$7","children":["$","h2",null,{"style":"$8","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L9",["$","meta",null,{"name":"robots","content":"noindex"}]]]]]
+9:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/_not-found/page.js b/frontend/.next/server/app/_not-found/page.js
new file mode 100644
index 0000000000000000000000000000000000000000..cd2de404729ae8b92b76b9740e989e171330e784
--- /dev/null
+++ b/frontend/.next/server/app/_not-found/page.js
@@ -0,0 +1 @@
+"use strict";(()=>{var e={};e.id=409,e.ids=[409],e.modules={2934:e=>{e.exports=require("next/dist/client/components/action-async-storage.external.js")},4580:e=>{e.exports=require("next/dist/client/components/request-async-storage.external.js")},5869:e=>{e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},399:e=>{e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},5741:(e,t,n)=>{n.r(t),n.d(t,{GlobalError:()=>a.a,__next_app__:()=>p,originalPathname:()=>f,pages:()=>s,routeModule:()=>c,tree:()=>d}),n(8793),n(311),n(8777);var o=n(9296),r=n(1650),u=n(7045),a=n.n(u),i=n(8184),l={};for(let e in i)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(l[e]=()=>i[e]);n.d(t,l);let d=["",{children:["/_not-found",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(n.t.bind(n,311,23)),"next/dist/client/components/not-found-error"]}]},{}]},{layout:[()=>Promise.resolve().then(n.bind(n,8777)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout.tsx"],"not-found":[()=>Promise.resolve().then(n.t.bind(n,311,23)),"next/dist/client/components/not-found-error"]}],s=[],f="/_not-found/page",p={require:n,loadChunk:()=>Promise.resolve()},c=new o.AppPageRouteModule({definition:{kind:r.x.APP_PAGE,page:"/_not-found/page",pathname:"/_not-found",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:d}})},1202:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var n in t)Object.defineProperty(e,n,{enumerable:!0,get:t[n]})}(t,{isNotFoundError:function(){return r},notFound:function(){return o}});let n="NEXT_NOT_FOUND";function o(){let e=Error(n);throw e.digest=n,e}function r(e){return"object"==typeof e&&null!==e&&"digest"in e&&e.digest===n}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},8793:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var n in t)Object.defineProperty(e,n,{enumerable:!0,get:t[n]})}(t,{PARALLEL_ROUTE_DEFAULT_PATH:function(){return r},default:function(){return u}});let o=n(1202),r="next/dist/client/components/parallel-route-default.js";function u(){(0,o.notFound)()}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)}};var t=require("../../webpack-runtime.js");t.C(e);var n=e=>t(t.s=e),o=t.X(0,[273,394],()=>n(5741));module.exports=o})();
\ No newline at end of file
diff --git a/frontend/.next/server/app/_not-found/page.js.nft.json b/frontend/.next/server/app/_not-found/page.js.nft.json
new file mode 100644
index 0000000000000000000000000000000000000000..bc0d09be27bbb4edc14fcf577a82bb6fb2b18cd4
--- /dev/null
+++ b/frontend/.next/server/app/_not-found/page.js.nft.json
@@ -0,0 +1 @@
+{"version":1,"files":["../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/package.json","../../../../node_modules/next","../../../package.json","../../chunks/273.js","../../chunks/394.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}
\ No newline at end of file
diff --git a/frontend/.next/server/app/_not-found/page_client-reference-manifest.js b/frontend/.next/server/app/_not-found/page_client-reference-manifest.js
new file mode 100644
index 0000000000000000000000000000000000000000..cc7e8babc2f3eb309d48605f84cab5962197d32a
--- /dev/null
+++ b/frontend/.next/server/app/_not-found/page_client-reference-manifest.js
@@ -0,0 +1 @@
+globalThis.__RSC_MANIFEST=(globalThis.__RSC_MANIFEST||{});globalThis.__RSC_MANIFEST["/_not-found/page"]={"moduleLoading":{"prefix":"/_next/","crossOrigin":null},"ssrModuleMapping":{"176":{"*":{"id":"6676","name":"*","chunks":[],"async":false}},"841":{"*":{"id":"9737","name":"*","chunks":[],"async":false}},"892":{"*":{"id":"5213","name":"*","chunks":[],"async":false}},"2010":{"*":{"id":"7619","name":"*","chunks":[],"async":false}},"2433":{"*":{"id":"6544","name":"*","chunks":[],"async":false}},"2651":{"*":{"id":"9645","name":"*","chunks":[],"async":false}},"2987":{"*":{"id":"1358","name":"*","chunks":[],"async":false}},"3713":{"*":{"id":"5210","name":"*","chunks":[],"async":false}},"4374":{"*":{"id":"9927","name":"*","chunks":[],"async":false}},"6056":{"*":{"id":"1309","name":"*","chunks":[],"async":false}},"6543":{"*":{"id":"9722","name":"*","chunks":[],"async":false}},"6813":{"*":{"id":"5877","name":"*","chunks":[],"async":false}},"7096":{"*":{"id":"1952","name":"*","chunks":[],"async":false}},"7413":{"*":{"id":"8052","name":"*","chunks":[],"async":false}},"7523":{"*":{"id":"3477","name":"*","chunks":[],"async":false}},"7768":{"*":{"id":"7663","name":"*","chunks":[],"async":false}},"8145":{"*":{"id":"8377","name":"*","chunks":[],"async":false}},"8528":{"*":{"id":"5116","name":"*","chunks":[],"async":false}},"8547":{"*":{"id":"5441","name":"*","chunks":[],"async":false}},"9135":{"*":{"id":"432","name":"*","chunks":[],"async":false}},"9239":{"*":{"id":"8132","name":"*","chunks":[],"async":false}},"9414":{"*":{"id":"8850","name":"*","chunks":[],"async":false}},"9570":{"*":{"id":"291","name":"*","chunks":[],"async":false}}},"edgeSSRModuleMapping":{},"clientModules":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/globals.css":{"id":4443,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/components/AppShell.tsx":{"id":6813,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/backtest/page.tsx":{"id":4374,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chart-analyst/page.tsx":{"id":6543,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chat/page.tsx":{"id":841,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chatbot/page.tsx":{"id":8145,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/learning/page.tsx":{"id":6056,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/methodology/page.tsx":{"id":7413,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/ipo-radar/page.tsx":{"id":9135,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/market-brain/page.tsx":{"id":2987,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page.tsx":{"id":892,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/dashboard/page.tsx":{"id":7096,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","96","static/chunks/96-ce8c57cd15d50941.js","931","static/chunks/app/page-d0db9a93fb4af9a5.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/etf-radar/page.tsx":{"id":9239,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/performance/page.tsx":{"id":8547,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/signal-lab/page.tsx":{"id":2010,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/sniper/page.tsx":{"id":7768,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/stock-radar/page.tsx":{"id":9570,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/assets/[ticker]/view.tsx":{"id":3713,"name":"*","chunks":[],"async":false}},"entryCSSFiles":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout":["static/css/02bd12e03544ea91.css"],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/page":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/_not-found/page":[]}}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/AAPL.html b/frontend/.next/server/app/assets/AAPL.html
new file mode 100644
index 0000000000000000000000000000000000000000..eb6811499004f4dac9dc204e7c1c9d02f9f086c2
--- /dev/null
+++ b/frontend/.next/server/app/assets/AAPL.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading AAPL
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/AAPL.meta b/frontend/.next/server/app/assets/AAPL.meta
new file mode 100644
index 0000000000000000000000000000000000000000..d194e4886b8a6d4323656f69d361e65d25240a20
--- /dev/null
+++ b/frontend/.next/server/app/assets/AAPL.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/AAPL/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/AAPL.rsc b/frontend/.next/server/app/assets/AAPL.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..966f08c7fba58b708130869628786185243497d4
--- /dev/null
+++ b/frontend/.next/server/app/assets/AAPL.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","AAPL","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","AAPL","d"],{"children":["__PAGE__?{\"ticker\":\"AAPL\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","AAPL","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"AAPL"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/AIR_PA.html b/frontend/.next/server/app/assets/AIR_PA.html
new file mode 100644
index 0000000000000000000000000000000000000000..a8988af772186cd0338afd98311cc8242e3109cf
--- /dev/null
+++ b/frontend/.next/server/app/assets/AIR_PA.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading AIR.PA
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/AIR_PA.meta b/frontend/.next/server/app/assets/AIR_PA.meta
new file mode 100644
index 0000000000000000000000000000000000000000..2ac0ce9b1932330c49a99d255a74c3ce2bfe1cf5
--- /dev/null
+++ b/frontend/.next/server/app/assets/AIR_PA.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/AIR_PA/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/AIR_PA.rsc b/frontend/.next/server/app/assets/AIR_PA.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..94c39e70c88bf4c2a19e8b10713542877d6ea9e6
--- /dev/null
+++ b/frontend/.next/server/app/assets/AIR_PA.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","AIR_PA","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","AIR_PA","d"],{"children":["__PAGE__?{\"ticker\":\"AIR_PA\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","AIR_PA","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"AIR.PA"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/AMD.html b/frontend/.next/server/app/assets/AMD.html
new file mode 100644
index 0000000000000000000000000000000000000000..7c509dfd0a4cda4417bae2aa1e5aef3c1daceadb
--- /dev/null
+++ b/frontend/.next/server/app/assets/AMD.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading AMD
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/AMD.meta b/frontend/.next/server/app/assets/AMD.meta
new file mode 100644
index 0000000000000000000000000000000000000000..57721f7ec1f625ab6a5fdb784c1b2f518e39bc00
--- /dev/null
+++ b/frontend/.next/server/app/assets/AMD.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/AMD/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/AMD.rsc b/frontend/.next/server/app/assets/AMD.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..70b01f118b4fc9cb5345267e6d59f493e9400965
--- /dev/null
+++ b/frontend/.next/server/app/assets/AMD.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","AMD","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","AMD","d"],{"children":["__PAGE__?{\"ticker\":\"AMD\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","AMD","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"AMD"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/AMZN.html b/frontend/.next/server/app/assets/AMZN.html
new file mode 100644
index 0000000000000000000000000000000000000000..31e6d2050ddfcefd0ef3d535a1efed927286a47e
--- /dev/null
+++ b/frontend/.next/server/app/assets/AMZN.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading AMZN
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/AMZN.meta b/frontend/.next/server/app/assets/AMZN.meta
new file mode 100644
index 0000000000000000000000000000000000000000..11a93b9c45b670512038e16292c449e3fde67168
--- /dev/null
+++ b/frontend/.next/server/app/assets/AMZN.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/AMZN/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/AMZN.rsc b/frontend/.next/server/app/assets/AMZN.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..126f6ad7a053d67b0dd2c82b7fe4f37a57e3d1ba
--- /dev/null
+++ b/frontend/.next/server/app/assets/AMZN.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","AMZN","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","AMZN","d"],{"children":["__PAGE__?{\"ticker\":\"AMZN\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","AMZN","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"AMZN"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/ASML.html b/frontend/.next/server/app/assets/ASML.html
new file mode 100644
index 0000000000000000000000000000000000000000..77b0f3c35e7c68a85b7af1bd03b095a50aac123e
--- /dev/null
+++ b/frontend/.next/server/app/assets/ASML.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading ASML
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/ASML.meta b/frontend/.next/server/app/assets/ASML.meta
new file mode 100644
index 0000000000000000000000000000000000000000..12b85e460b499dc52edbc33035379c8f2d126026
--- /dev/null
+++ b/frontend/.next/server/app/assets/ASML.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/ASML/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/ASML.rsc b/frontend/.next/server/app/assets/ASML.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..8cda5fb46d47aa30595bbc252e6674fcc2e704d2
--- /dev/null
+++ b/frontend/.next/server/app/assets/ASML.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","ASML","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","ASML","d"],{"children":["__PAGE__?{\"ticker\":\"ASML\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","ASML","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"ASML"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/AVGO.html b/frontend/.next/server/app/assets/AVGO.html
new file mode 100644
index 0000000000000000000000000000000000000000..0c47a63d672de4f365090926d873756cbf1de803
--- /dev/null
+++ b/frontend/.next/server/app/assets/AVGO.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading AVGO
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/AVGO.meta b/frontend/.next/server/app/assets/AVGO.meta
new file mode 100644
index 0000000000000000000000000000000000000000..5b341fcb4a52b82d992ca3d427fdc5ab3ed64987
--- /dev/null
+++ b/frontend/.next/server/app/assets/AVGO.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/AVGO/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/AVGO.rsc b/frontend/.next/server/app/assets/AVGO.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..4c11af04a5542a7c0284968d17359b5659ac695e
--- /dev/null
+++ b/frontend/.next/server/app/assets/AVGO.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","AVGO","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","AVGO","d"],{"children":["__PAGE__?{\"ticker\":\"AVGO\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","AVGO","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"AVGO"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/BOTZ.html b/frontend/.next/server/app/assets/BOTZ.html
new file mode 100644
index 0000000000000000000000000000000000000000..48e8703f67211ca90819ee72feed3b7eb2c8cc01
--- /dev/null
+++ b/frontend/.next/server/app/assets/BOTZ.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading BOTZ
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/BOTZ.meta b/frontend/.next/server/app/assets/BOTZ.meta
new file mode 100644
index 0000000000000000000000000000000000000000..312fb8016c4d0fad0220f106f735c4aee6c0cfb8
--- /dev/null
+++ b/frontend/.next/server/app/assets/BOTZ.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/BOTZ/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/BOTZ.rsc b/frontend/.next/server/app/assets/BOTZ.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..00bc3f252e67c8bdb0d3ab3ffc83ef9355971ab2
--- /dev/null
+++ b/frontend/.next/server/app/assets/BOTZ.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","BOTZ","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","BOTZ","d"],{"children":["__PAGE__?{\"ticker\":\"BOTZ\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","BOTZ","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"BOTZ"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/DIA.html b/frontend/.next/server/app/assets/DIA.html
new file mode 100644
index 0000000000000000000000000000000000000000..ec151a81b151e3cb37d9caef6744ac22fcbdf5f6
--- /dev/null
+++ b/frontend/.next/server/app/assets/DIA.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading DIA
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/DIA.meta b/frontend/.next/server/app/assets/DIA.meta
new file mode 100644
index 0000000000000000000000000000000000000000..93fc55dc5a3ce0c4fc2271f7bd194ee85bbf9fa4
--- /dev/null
+++ b/frontend/.next/server/app/assets/DIA.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/DIA/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/DIA.rsc b/frontend/.next/server/app/assets/DIA.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..9ffadff85a95c235db079dedb1317ef3e2c38a5e
--- /dev/null
+++ b/frontend/.next/server/app/assets/DIA.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","DIA","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","DIA","d"],{"children":["__PAGE__?{\"ticker\":\"DIA\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","DIA","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"DIA"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/ENR_DE.html b/frontend/.next/server/app/assets/ENR_DE.html
new file mode 100644
index 0000000000000000000000000000000000000000..286bfc58f536363a1156e774c88c0d6f55fbff20
--- /dev/null
+++ b/frontend/.next/server/app/assets/ENR_DE.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading ENR.DE
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/ENR_DE.meta b/frontend/.next/server/app/assets/ENR_DE.meta
new file mode 100644
index 0000000000000000000000000000000000000000..6cf0e62b3548eb7a42f786c19ae8e170ce1374c9
--- /dev/null
+++ b/frontend/.next/server/app/assets/ENR_DE.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/ENR_DE/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/ENR_DE.rsc b/frontend/.next/server/app/assets/ENR_DE.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..1aaf848e34317d493d07ebf5ea9c943c945f9134
--- /dev/null
+++ b/frontend/.next/server/app/assets/ENR_DE.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","ENR_DE","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","ENR_DE","d"],{"children":["__PAGE__?{\"ticker\":\"ENR_DE\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","ENR_DE","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"ENR.DE"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/GLD.html b/frontend/.next/server/app/assets/GLD.html
new file mode 100644
index 0000000000000000000000000000000000000000..23231f16e12eed5d957967b9d7be9809d001f8c7
--- /dev/null
+++ b/frontend/.next/server/app/assets/GLD.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading GLD
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/GLD.meta b/frontend/.next/server/app/assets/GLD.meta
new file mode 100644
index 0000000000000000000000000000000000000000..f082e19f93fe10217250309b45b6849eb8c0dc0c
--- /dev/null
+++ b/frontend/.next/server/app/assets/GLD.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/GLD/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/GLD.rsc b/frontend/.next/server/app/assets/GLD.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..a97c259f91b140fc412fcd12d69483370b321a71
--- /dev/null
+++ b/frontend/.next/server/app/assets/GLD.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","GLD","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","GLD","d"],{"children":["__PAGE__?{\"ticker\":\"GLD\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","GLD","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"GLD"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/GOOGL.html b/frontend/.next/server/app/assets/GOOGL.html
new file mode 100644
index 0000000000000000000000000000000000000000..7faab0fa4e916e21e4d46ee5a5811a42a36625c4
--- /dev/null
+++ b/frontend/.next/server/app/assets/GOOGL.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading GOOGL
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/GOOGL.meta b/frontend/.next/server/app/assets/GOOGL.meta
new file mode 100644
index 0000000000000000000000000000000000000000..ffeda4842e76f93a635e4161cd1936245650bba2
--- /dev/null
+++ b/frontend/.next/server/app/assets/GOOGL.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/GOOGL/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/GOOGL.rsc b/frontend/.next/server/app/assets/GOOGL.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..e81458f17a642d44dc6b2b51da5cc6981faca516
--- /dev/null
+++ b/frontend/.next/server/app/assets/GOOGL.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","GOOGL","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","GOOGL","d"],{"children":["__PAGE__?{\"ticker\":\"GOOGL\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","GOOGL","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"GOOGL"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/HACK.html b/frontend/.next/server/app/assets/HACK.html
new file mode 100644
index 0000000000000000000000000000000000000000..f5e76192a3f6a96ed4f201f7c36a4d28c590572c
--- /dev/null
+++ b/frontend/.next/server/app/assets/HACK.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading HACK
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/HACK.meta b/frontend/.next/server/app/assets/HACK.meta
new file mode 100644
index 0000000000000000000000000000000000000000..6e5deb5ac1e310d80e1ddc0a88143eda252bb21b
--- /dev/null
+++ b/frontend/.next/server/app/assets/HACK.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/HACK/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/HACK.rsc b/frontend/.next/server/app/assets/HACK.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..4e3c4e65b17b7fd5b1052ffc03f3a55947b3a158
--- /dev/null
+++ b/frontend/.next/server/app/assets/HACK.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","HACK","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","HACK","d"],{"children":["__PAGE__?{\"ticker\":\"HACK\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","HACK","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"HACK"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/ICLN.html b/frontend/.next/server/app/assets/ICLN.html
new file mode 100644
index 0000000000000000000000000000000000000000..da80422a6cebc794c4e7b981b1507baa9f60ca65
--- /dev/null
+++ b/frontend/.next/server/app/assets/ICLN.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading ICLN
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/ICLN.meta b/frontend/.next/server/app/assets/ICLN.meta
new file mode 100644
index 0000000000000000000000000000000000000000..1e91f05c2d1738673833f306a8427603a8223120
--- /dev/null
+++ b/frontend/.next/server/app/assets/ICLN.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/ICLN/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/ICLN.rsc b/frontend/.next/server/app/assets/ICLN.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..6e209bd0139d1df09d5396527ac2fb0610e4fad9
--- /dev/null
+++ b/frontend/.next/server/app/assets/ICLN.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","ICLN","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","ICLN","d"],{"children":["__PAGE__?{\"ticker\":\"ICLN\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","ICLN","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"ICLN"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/IWM.html b/frontend/.next/server/app/assets/IWM.html
new file mode 100644
index 0000000000000000000000000000000000000000..9298230be99375170187c38fd559a58416c973ba
--- /dev/null
+++ b/frontend/.next/server/app/assets/IWM.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading IWM
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/IWM.meta b/frontend/.next/server/app/assets/IWM.meta
new file mode 100644
index 0000000000000000000000000000000000000000..da9caf6e97f3384f8c94a30fdfea6d95676a5692
--- /dev/null
+++ b/frontend/.next/server/app/assets/IWM.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/IWM/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/IWM.rsc b/frontend/.next/server/app/assets/IWM.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..e3486e2eaf74604e732520231025c6376efbf01a
--- /dev/null
+++ b/frontend/.next/server/app/assets/IWM.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","IWM","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","IWM","d"],{"children":["__PAGE__?{\"ticker\":\"IWM\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","IWM","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"IWM"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/JPM.html b/frontend/.next/server/app/assets/JPM.html
new file mode 100644
index 0000000000000000000000000000000000000000..0e1ff60581c964c8e8efd71a9e732fddbf6a6dda
--- /dev/null
+++ b/frontend/.next/server/app/assets/JPM.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading JPM
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/JPM.meta b/frontend/.next/server/app/assets/JPM.meta
new file mode 100644
index 0000000000000000000000000000000000000000..e835093ef9cff0aa93a401c63ed5b1c5b3b3eab3
--- /dev/null
+++ b/frontend/.next/server/app/assets/JPM.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/JPM/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/JPM.rsc b/frontend/.next/server/app/assets/JPM.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..d9990b71b9ff1023efeb467ad408e7536124959d
--- /dev/null
+++ b/frontend/.next/server/app/assets/JPM.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","JPM","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","JPM","d"],{"children":["__PAGE__?{\"ticker\":\"JPM\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","JPM","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"JPM"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/LLY.html b/frontend/.next/server/app/assets/LLY.html
new file mode 100644
index 0000000000000000000000000000000000000000..a87432f506727aee6c3b9afaa95038b81fdd4fa6
--- /dev/null
+++ b/frontend/.next/server/app/assets/LLY.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading LLY
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/LLY.meta b/frontend/.next/server/app/assets/LLY.meta
new file mode 100644
index 0000000000000000000000000000000000000000..407304889eb3ca26d1f37fd42a9e80c3d6a9be1c
--- /dev/null
+++ b/frontend/.next/server/app/assets/LLY.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/LLY/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/LLY.rsc b/frontend/.next/server/app/assets/LLY.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..e141e925cc7691e83434887480cf49668d8aeeb1
--- /dev/null
+++ b/frontend/.next/server/app/assets/LLY.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","LLY","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","LLY","d"],{"children":["__PAGE__?{\"ticker\":\"LLY\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","LLY","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"LLY"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/MC_PA.html b/frontend/.next/server/app/assets/MC_PA.html
new file mode 100644
index 0000000000000000000000000000000000000000..0c374630a19eac0ab8b1cf914eda20c5e4dbe000
--- /dev/null
+++ b/frontend/.next/server/app/assets/MC_PA.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading MC.PA
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/MC_PA.meta b/frontend/.next/server/app/assets/MC_PA.meta
new file mode 100644
index 0000000000000000000000000000000000000000..7cfc76cb678c2a087ae1011b944bc0ab9cafe4c7
--- /dev/null
+++ b/frontend/.next/server/app/assets/MC_PA.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/MC_PA/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/MC_PA.rsc b/frontend/.next/server/app/assets/MC_PA.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..f5568450d4ff2165fc310233dbbf56ba4a2b91d7
--- /dev/null
+++ b/frontend/.next/server/app/assets/MC_PA.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","MC_PA","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","MC_PA","d"],{"children":["__PAGE__?{\"ticker\":\"MC_PA\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","MC_PA","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"MC.PA"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/META.html b/frontend/.next/server/app/assets/META.html
new file mode 100644
index 0000000000000000000000000000000000000000..e43a9e3e47936435693a20e37cf21684ce7e8171
--- /dev/null
+++ b/frontend/.next/server/app/assets/META.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading META
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/META.meta b/frontend/.next/server/app/assets/META.meta
new file mode 100644
index 0000000000000000000000000000000000000000..20889c9482e86d092fc9f6956be7d310fbe182f1
--- /dev/null
+++ b/frontend/.next/server/app/assets/META.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/META/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/META.rsc b/frontend/.next/server/app/assets/META.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..19b534b24673761f0173b6e208dbb8da16b94462
--- /dev/null
+++ b/frontend/.next/server/app/assets/META.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","META","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","META","d"],{"children":["__PAGE__?{\"ticker\":\"META\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","META","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"META"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/MSFT.html b/frontend/.next/server/app/assets/MSFT.html
new file mode 100644
index 0000000000000000000000000000000000000000..e7cf9d9678ee250ec1808b55e2d48b318b26ff0d
--- /dev/null
+++ b/frontend/.next/server/app/assets/MSFT.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading MSFT
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/MSFT.meta b/frontend/.next/server/app/assets/MSFT.meta
new file mode 100644
index 0000000000000000000000000000000000000000..7fbf5becd836044c6ba8e2bc8fc419ba772450c4
--- /dev/null
+++ b/frontend/.next/server/app/assets/MSFT.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/MSFT/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/MSFT.rsc b/frontend/.next/server/app/assets/MSFT.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..952da1a6d8356454472be3f483286ead6ec3b5d8
--- /dev/null
+++ b/frontend/.next/server/app/assets/MSFT.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","MSFT","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","MSFT","d"],{"children":["__PAGE__?{\"ticker\":\"MSFT\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","MSFT","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"MSFT"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/NVDA.html b/frontend/.next/server/app/assets/NVDA.html
new file mode 100644
index 0000000000000000000000000000000000000000..efb0bc602c70291a24e138fc4c65d87da2e916c1
--- /dev/null
+++ b/frontend/.next/server/app/assets/NVDA.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading NVDA
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/NVDA.meta b/frontend/.next/server/app/assets/NVDA.meta
new file mode 100644
index 0000000000000000000000000000000000000000..b8ca1ddd1a74da504876682b29f6c224e707bdcb
--- /dev/null
+++ b/frontend/.next/server/app/assets/NVDA.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/NVDA/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/NVDA.rsc b/frontend/.next/server/app/assets/NVDA.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..ec96ace9764910b2f751d611e4a1c7559b9cf75f
--- /dev/null
+++ b/frontend/.next/server/app/assets/NVDA.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","NVDA","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","NVDA","d"],{"children":["__PAGE__?{\"ticker\":\"NVDA\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","NVDA","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"NVDA"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/NVO.html b/frontend/.next/server/app/assets/NVO.html
new file mode 100644
index 0000000000000000000000000000000000000000..b2818b6b18f33d8e30a00f3474d568a1447cd173
--- /dev/null
+++ b/frontend/.next/server/app/assets/NVO.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading NVO
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/NVO.meta b/frontend/.next/server/app/assets/NVO.meta
new file mode 100644
index 0000000000000000000000000000000000000000..41eafec805f48ca67df33b133fd0304155834af2
--- /dev/null
+++ b/frontend/.next/server/app/assets/NVO.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/NVO/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/NVO.rsc b/frontend/.next/server/app/assets/NVO.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..8bfec78616c26d70e9f49921286984459842654f
--- /dev/null
+++ b/frontend/.next/server/app/assets/NVO.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","NVO","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","NVO","d"],{"children":["__PAGE__?{\"ticker\":\"NVO\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","NVO","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"NVO"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/QQQ.html b/frontend/.next/server/app/assets/QQQ.html
new file mode 100644
index 0000000000000000000000000000000000000000..2db90c278263c3238b09e96f358da75387edaa14
--- /dev/null
+++ b/frontend/.next/server/app/assets/QQQ.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading QQQ
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/QQQ.meta b/frontend/.next/server/app/assets/QQQ.meta
new file mode 100644
index 0000000000000000000000000000000000000000..d0b4eeb610240cbad326de551142cbd208015ee7
--- /dev/null
+++ b/frontend/.next/server/app/assets/QQQ.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/QQQ/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/QQQ.rsc b/frontend/.next/server/app/assets/QQQ.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..f83bfc4da63f6599e394cf689e844d6d308e2513
--- /dev/null
+++ b/frontend/.next/server/app/assets/QQQ.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","QQQ","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","QQQ","d"],{"children":["__PAGE__?{\"ticker\":\"QQQ\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","QQQ","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"QQQ"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/RHM_DE.html b/frontend/.next/server/app/assets/RHM_DE.html
new file mode 100644
index 0000000000000000000000000000000000000000..410b722d96337f90a328f54a96a05051fbc0a526
--- /dev/null
+++ b/frontend/.next/server/app/assets/RHM_DE.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading RHM.DE
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/RHM_DE.meta b/frontend/.next/server/app/assets/RHM_DE.meta
new file mode 100644
index 0000000000000000000000000000000000000000..fbcd9fe5e330d8ca799a4d22789af7c7acde7b5f
--- /dev/null
+++ b/frontend/.next/server/app/assets/RHM_DE.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/RHM_DE/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/RHM_DE.rsc b/frontend/.next/server/app/assets/RHM_DE.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..4526c16795b2ce891ee655236dd37f1530a63397
--- /dev/null
+++ b/frontend/.next/server/app/assets/RHM_DE.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","RHM_DE","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","RHM_DE","d"],{"children":["__PAGE__?{\"ticker\":\"RHM_DE\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","RHM_DE","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"RHM.DE"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/SAP.html b/frontend/.next/server/app/assets/SAP.html
new file mode 100644
index 0000000000000000000000000000000000000000..129e7cbff4d20aaf724b848d8b01103d93775fc9
--- /dev/null
+++ b/frontend/.next/server/app/assets/SAP.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading SAP
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/SAP.meta b/frontend/.next/server/app/assets/SAP.meta
new file mode 100644
index 0000000000000000000000000000000000000000..74064be2fb306572d68b33c505244dad00f36201
--- /dev/null
+++ b/frontend/.next/server/app/assets/SAP.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/SAP/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/SAP.rsc b/frontend/.next/server/app/assets/SAP.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..c89c41d5013452ddeaa557f3acd8ae9bfd08a000
--- /dev/null
+++ b/frontend/.next/server/app/assets/SAP.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","SAP","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","SAP","d"],{"children":["__PAGE__?{\"ticker\":\"SAP\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","SAP","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"SAP"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/SIE_DE.html b/frontend/.next/server/app/assets/SIE_DE.html
new file mode 100644
index 0000000000000000000000000000000000000000..6bd1f98922055fe00b0e0784f6dad67277cba6e9
--- /dev/null
+++ b/frontend/.next/server/app/assets/SIE_DE.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading SIE.DE
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/SIE_DE.meta b/frontend/.next/server/app/assets/SIE_DE.meta
new file mode 100644
index 0000000000000000000000000000000000000000..650c2062ca26d36766541d840a3910ad5aa99bd4
--- /dev/null
+++ b/frontend/.next/server/app/assets/SIE_DE.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/SIE_DE/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/SIE_DE.rsc b/frontend/.next/server/app/assets/SIE_DE.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..35a83e9cf96ab094ed4694ad50a5bc5434a35171
--- /dev/null
+++ b/frontend/.next/server/app/assets/SIE_DE.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","SIE_DE","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","SIE_DE","d"],{"children":["__PAGE__?{\"ticker\":\"SIE_DE\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","SIE_DE","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"SIE.DE"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/SMH.html b/frontend/.next/server/app/assets/SMH.html
new file mode 100644
index 0000000000000000000000000000000000000000..cbf4991cc059fbfaa9a603703867935c5e8d40c1
--- /dev/null
+++ b/frontend/.next/server/app/assets/SMH.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading SMH
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/SMH.meta b/frontend/.next/server/app/assets/SMH.meta
new file mode 100644
index 0000000000000000000000000000000000000000..3b9eb90a6a3ec5ecbd13756ec80655ef16ae3847
--- /dev/null
+++ b/frontend/.next/server/app/assets/SMH.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/SMH/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/SMH.rsc b/frontend/.next/server/app/assets/SMH.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..f784c9dbbda2b2a0cb347d2f0d398d91ff4e9374
--- /dev/null
+++ b/frontend/.next/server/app/assets/SMH.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","SMH","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","SMH","d"],{"children":["__PAGE__?{\"ticker\":\"SMH\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","SMH","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"SMH"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/SPY.html b/frontend/.next/server/app/assets/SPY.html
new file mode 100644
index 0000000000000000000000000000000000000000..d225beaabebee550d93f5b8f53d31cc824ffd418
--- /dev/null
+++ b/frontend/.next/server/app/assets/SPY.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading SPY
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/SPY.meta b/frontend/.next/server/app/assets/SPY.meta
new file mode 100644
index 0000000000000000000000000000000000000000..4bd4f6fcec462fb0b36d6c68c73353bfd6a8a926
--- /dev/null
+++ b/frontend/.next/server/app/assets/SPY.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/SPY/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/SPY.rsc b/frontend/.next/server/app/assets/SPY.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..9100f4b44d8b5ee3fce148601ee30d03c5f27151
--- /dev/null
+++ b/frontend/.next/server/app/assets/SPY.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","SPY","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","SPY","d"],{"children":["__PAGE__?{\"ticker\":\"SPY\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","SPY","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"SPY"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/TLT.html b/frontend/.next/server/app/assets/TLT.html
new file mode 100644
index 0000000000000000000000000000000000000000..c51d53e92d431304c100bd439960f6fe54bfa58d
--- /dev/null
+++ b/frontend/.next/server/app/assets/TLT.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading TLT
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/TLT.meta b/frontend/.next/server/app/assets/TLT.meta
new file mode 100644
index 0000000000000000000000000000000000000000..8f19f1b6a03fb7e913012afb983c3f20e2ad7384
--- /dev/null
+++ b/frontend/.next/server/app/assets/TLT.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/TLT/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/TLT.rsc b/frontend/.next/server/app/assets/TLT.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..910d5c241353003757e31e9ee42f5feff28d8214
--- /dev/null
+++ b/frontend/.next/server/app/assets/TLT.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","TLT","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","TLT","d"],{"children":["__PAGE__?{\"ticker\":\"TLT\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","TLT","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"TLT"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/TSLA.html b/frontend/.next/server/app/assets/TSLA.html
new file mode 100644
index 0000000000000000000000000000000000000000..1b3e10e551e81aff40c86be64f1ebd6401002bb2
--- /dev/null
+++ b/frontend/.next/server/app/assets/TSLA.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading TSLA
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/TSLA.meta b/frontend/.next/server/app/assets/TSLA.meta
new file mode 100644
index 0000000000000000000000000000000000000000..6134b6c744d20c05dfba738feadcbc42f934b3eb
--- /dev/null
+++ b/frontend/.next/server/app/assets/TSLA.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/TSLA/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/TSLA.rsc b/frontend/.next/server/app/assets/TSLA.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..95591e748884fe5a862ee60c82966f5acd1fc072
--- /dev/null
+++ b/frontend/.next/server/app/assets/TSLA.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","TSLA","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","TSLA","d"],{"children":["__PAGE__?{\"ticker\":\"TSLA\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","TSLA","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"TSLA"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/XAR.html b/frontend/.next/server/app/assets/XAR.html
new file mode 100644
index 0000000000000000000000000000000000000000..8ff9bd9525c91dbfefe7df69c1365ab1faf479be
--- /dev/null
+++ b/frontend/.next/server/app/assets/XAR.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading XAR
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/XAR.meta b/frontend/.next/server/app/assets/XAR.meta
new file mode 100644
index 0000000000000000000000000000000000000000..1c567295e0c1c5560ed4d3d20e949bf331edd3ff
--- /dev/null
+++ b/frontend/.next/server/app/assets/XAR.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/XAR/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/XAR.rsc b/frontend/.next/server/app/assets/XAR.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..a575f97d5309eaba533a8a8d46c576ed0dbaf2fc
--- /dev/null
+++ b/frontend/.next/server/app/assets/XAR.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","XAR","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","XAR","d"],{"children":["__PAGE__?{\"ticker\":\"XAR\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","XAR","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"XAR"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/XLE.html b/frontend/.next/server/app/assets/XLE.html
new file mode 100644
index 0000000000000000000000000000000000000000..160f4140f106529b92c3541b18cc7ca79e6270e0
--- /dev/null
+++ b/frontend/.next/server/app/assets/XLE.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading XLE
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/XLE.meta b/frontend/.next/server/app/assets/XLE.meta
new file mode 100644
index 0000000000000000000000000000000000000000..543a473ec8ae59f1d089e68d23295c92c14bb5cb
--- /dev/null
+++ b/frontend/.next/server/app/assets/XLE.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/XLE/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/XLE.rsc b/frontend/.next/server/app/assets/XLE.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..b4d863604512aeda8038a90b7014114e5496df76
--- /dev/null
+++ b/frontend/.next/server/app/assets/XLE.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","XLE","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","XLE","d"],{"children":["__PAGE__?{\"ticker\":\"XLE\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","XLE","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"XLE"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/XLF.html b/frontend/.next/server/app/assets/XLF.html
new file mode 100644
index 0000000000000000000000000000000000000000..d0a6847d730d9bdde980fad04b487fb9eea667e5
--- /dev/null
+++ b/frontend/.next/server/app/assets/XLF.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading XLF
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/XLF.meta b/frontend/.next/server/app/assets/XLF.meta
new file mode 100644
index 0000000000000000000000000000000000000000..10f41acec40b59620e0be37f60f7d42b77cbad0d
--- /dev/null
+++ b/frontend/.next/server/app/assets/XLF.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/XLF/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/XLF.rsc b/frontend/.next/server/app/assets/XLF.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..dcec26c2ac61b6b4060c11a79379e2f0a9ec151e
--- /dev/null
+++ b/frontend/.next/server/app/assets/XLF.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","XLF","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","XLF","d"],{"children":["__PAGE__?{\"ticker\":\"XLF\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","XLF","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"XLF"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/XLK.html b/frontend/.next/server/app/assets/XLK.html
new file mode 100644
index 0000000000000000000000000000000000000000..9a97cc5b264e8f96a7c7e701cf5731ec8b471426
--- /dev/null
+++ b/frontend/.next/server/app/assets/XLK.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading XLK
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/XLK.meta b/frontend/.next/server/app/assets/XLK.meta
new file mode 100644
index 0000000000000000000000000000000000000000..50bc95a378238108a59057014c0109ed32510072
--- /dev/null
+++ b/frontend/.next/server/app/assets/XLK.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/XLK/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/XLK.rsc b/frontend/.next/server/app/assets/XLK.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..780284ece579c13dfecf77024ab5b68f5c9fcb42
--- /dev/null
+++ b/frontend/.next/server/app/assets/XLK.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","XLK","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","XLK","d"],{"children":["__PAGE__?{\"ticker\":\"XLK\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","XLK","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"XLK"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/XLV.html b/frontend/.next/server/app/assets/XLV.html
new file mode 100644
index 0000000000000000000000000000000000000000..6a6bd24e90152309ac80a1abcec8dd24149f40e0
--- /dev/null
+++ b/frontend/.next/server/app/assets/XLV.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading XLV
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/XLV.meta b/frontend/.next/server/app/assets/XLV.meta
new file mode 100644
index 0000000000000000000000000000000000000000..9efc1a669d4465d7de94aebb84f6ad4481e64347
--- /dev/null
+++ b/frontend/.next/server/app/assets/XLV.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/XLV/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/XLV.rsc b/frontend/.next/server/app/assets/XLV.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..bf0ff52a87087c9f3cf210ace836b3584f06c087
--- /dev/null
+++ b/frontend/.next/server/app/assets/XLV.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","XLV","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","XLV","d"],{"children":["__PAGE__?{\"ticker\":\"XLV\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","XLV","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"XLV"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/XOM.html b/frontend/.next/server/app/assets/XOM.html
new file mode 100644
index 0000000000000000000000000000000000000000..ba589f701ce431355acda6d23dfd76d9222d1b43
--- /dev/null
+++ b/frontend/.next/server/app/assets/XOM.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading XOM
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/XOM.meta b/frontend/.next/server/app/assets/XOM.meta
new file mode 100644
index 0000000000000000000000000000000000000000..d7efccd9ffa9fc0e3c8080978680b6e6e11941c1
--- /dev/null
+++ b/frontend/.next/server/app/assets/XOM.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/assets/layout,_N_T_/assets/[ticker]/layout,_N_T_/assets/[ticker]/page,_N_T_/assets/XOM/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/XOM.rsc b/frontend/.next/server/app/assets/XOM.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..7e861b12cd412a415f06735bcd54fae69e454208
--- /dev/null
+++ b/frontend/.next/server/app/assets/XOM.rsc
@@ -0,0 +1,8 @@
+2:I[3713,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"AssetDetailClient"]
+3:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+4:["ticker","XOM","d"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["assets",{"children":[["ticker","XOM","d"],{"children":["__PAGE__?{\"ticker\":\"XOM\"}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["assets",{"children":[["ticker","XOM","d"],{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"ticker":"XOM"}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","assets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/assets/[ticker]/page.js b/frontend/.next/server/app/assets/[ticker]/page.js
new file mode 100644
index 0000000000000000000000000000000000000000..d2e8ed7ff16fd17e170065236859694a490376b7
--- /dev/null
+++ b/frontend/.next/server/app/assets/[ticker]/page.js
@@ -0,0 +1 @@
+(()=>{var e={};e.id=825,e.ids=[825],e.modules={2934:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external.js")},4580:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external.js")},5869:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},399:e=>{"use strict";e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},5758:(e,s,i)=>{"use strict";i.r(s),i.d(s,{GlobalError:()=>t.a,__next_app__:()=>m,originalPathname:()=>u,pages:()=>o,routeModule:()=>h,tree:()=>d}),i(1474),i(8777),i(311);var n=i(9296),r=i(1650),a=i(7045),t=i.n(a),l=i(8184),c={};for(let e in l)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(c[e]=()=>l[e]);i.d(s,c);let d=["",{children:["assets",{children:["[ticker]",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(i.bind(i,1474)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/assets/[ticker]/page.tsx"]}]},{}]},{}]},{layout:[()=>Promise.resolve().then(i.bind(i,8777)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout.tsx"],"not-found":[()=>Promise.resolve().then(i.t.bind(i,311,23)),"next/dist/client/components/not-found-error"]}],o=["/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/assets/[ticker]/page.tsx"],u="/assets/[ticker]/page",m={require:i,loadChunk:()=>Promise.resolve()},h=new n.AppPageRouteModule({definition:{kind:r.x.APP_PAGE,page:"/assets/[ticker]/page",pathname:"/assets/[ticker]",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:d}})},3376:(e,s,i)=>{Promise.resolve().then(i.bind(i,5210))},5210:(e,s,i)=>{"use strict";i.d(s,{AssetDetailClient:()=>p});var n=i(8924),r=i(3911);i(3789);var a=i(2522);function t({memory:e}){var s;if(!e)return(0,n.jsxs)("section",{className:"panel",style:{marginTop:12},children:[(0,n.jsxs)("div",{className:"panel-head",children:[n.jsx("span",{children:"Blum Memory"}),n.jsx("strong",{children:"Loading"})]}),n.jsx("div",{className:"empty-state",children:"Historical memory is loading for this instrument."})]});let i=e.historical_similarity;return(0,n.jsxs)("section",{className:"panel blum-memory-panel",style:{marginTop:12},children:[(0,n.jsxs)("div",{className:"panel-head",children:[n.jsx("span",{children:"Blum Memory"}),n.jsx("strong",{children:e.learning_state})]}),n.jsx("p",{children:e.blum_memory_summary}),(0,n.jsxs)("div",{className:"brain-status-grid",children:[n.jsx(l,{label:"Similar Cases",value:i.similar_cases_found}),n.jsx(l,{label:"Average Return",value:c(i.average_return)}),n.jsx(l,{label:"Success Rate",value:null==(s=i.success_rate)?"Pending":`${Math.round(100*Number(s))}%`}),n.jsx(l,{label:"Confidence Adjustment",value:`${Number(i.confidence_adjustment??0).toFixed(1)} pts`})]}),(0,n.jsxs)("div",{className:"brain-drift info",children:[n.jsx("strong",{children:"Historical Similarity"}),n.jsx("span",{children:i.explanation})]}),(0,n.jsxs)("div",{className:"brain-two-col",children:[(0,n.jsxs)("div",{children:[n.jsx("h3",{children:"Why Confidence Changed"}),n.jsx("div",{className:"learning-event-list",children:(e.why_confidence_changed.length?e.why_confidence_changed:["No confidence change has been recorded yet."]).slice(0,5).map(e=>n.jsx("span",{children:e},e))})]}),(0,n.jsxs)("div",{children:[n.jsx("h3",{children:"What Blum Learned"}),n.jsx("div",{className:"learning-event-list",children:e.what_blum_learned.slice(0,5).map(e=>n.jsx("span",{children:e},e))})]})]}),(0,n.jsxs)("div",{className:"brain-two-col",children:[(0,n.jsxs)("div",{children:[n.jsx("h3",{children:"Confidence Evolution"}),(0,n.jsxs)("div",{className:"confidence-timeline",children:[e.confidence_evolution.slice(0,8).map(e=>(0,n.jsxs)("div",{children:[n.jsx("strong",{children:Number(e.adjusted_confidence??0).toFixed(1)}),(0,n.jsxs)("span",{children:[Number(e.adjustment??0).toFixed(1)," pts | ",e.signal_type??"signal"]})]},e.id)),!e.confidence_evolution.length&&n.jsx("div",{className:"empty-state compact",children:"No confidence history yet."})]})]}),(0,n.jsxs)("div",{children:[n.jsx("h3",{children:"Signal Outcome History"}),(0,n.jsxs)("div",{className:"brain-performance-list",children:[e.signal_outcome_history.slice(0,8).map(e=>(0,n.jsxs)("div",{children:[(0,n.jsxs)("strong",{children:[e.horizon_days,"D ",e.outcome]}),(0,n.jsxs)("span",{children:[e.signal_type," | return ",c(e.realized_return)," | data ",e.data_quality_score.toFixed(0)]})]},e.id)),!e.signal_outcome_history.length&&n.jsx("div",{className:"empty-state compact",children:"No evaluated signal horizons yet."})]})]})]}),!!e.similar_historical_setups.length&&n.jsx("div",{className:"similar-case-strip",children:e.similar_historical_setups.slice(0,6).map(e=>(0,n.jsxs)("span",{children:[e.outcome_summary?.historical_ticker??"Case"," | ",Number(e.similarity_score??0).toFixed(0)," similarity | ",e.outcome_summary?.final_outcome??"pending"]},e.id))}),n.jsx("p",{children:e.governance_note})]})}function l({label:e,value:s}){return(0,n.jsxs)("div",{className:"brain-metric",children:[n.jsx("span",{children:e}),n.jsx("strong",{children:s})]})}function c(e){return null==e?"Pending":`${Number(e).toFixed(2)}%`}function d({breakdown:e}){let s=Object.entries(e??{});return s.length?n.jsx("div",{className:"breakdown-bars",children:s.map(([e,s])=>(0,n.jsxs)("div",{className:"breakdown-row",children:[n.jsx("span",{children:e.replaceAll("_"," ")}),n.jsx("div",{children:n.jsx("i",{style:{width:`${Math.max(4,Math.min(100,Number(s)))}%`}})}),n.jsx("strong",{children:Number(s).toFixed(1)})]},e))}):n.jsx("div",{className:"empty-state",children:"No score breakdown available."})}var o=i(905),u=i(6927),m=i(8117),h=i(7749),x=i(3081);function p({ticker:e}){var s;let[i,l]=(0,r.useState)(null),[c,p]=(0,r.useState)(null),[_,b]=(0,r.useState)(null),[y,N]=(0,r.useState)(null),[w,S]=(0,r.useState)(null),[T,P]=(0,r.useState)(null),[A,C]=(0,r.useState)(""),[M,F]=(0,r.useState)(!1),[D,R]=(0,r.useState)("");if(D)return(0,n.jsxs)("div",{className:"empty-state",children:["API error: ",D]});if(!i)return n.jsx(a.G,{label:`Loading ${e}`});let I=i.latest_signal,L=i.prices??[],z=i.market_snapshot??I?.market_snapshot??i.asset?.market_snapshot,$=T?.reason??I?.explanation??y?.why_in_radar,B=T?.thesis??y?.thesis??I?.narrative_summary?.thesis;return(0,n.jsxs)(n.Fragment,{children:[n.jsx(u.ft,{eyebrow:"Asset Intelligence Report",title:"Security research cockpit.",subtitle:"Price action, sentiment, technical evidence, news quality, Blum memory and AI explanation for a single stock or ETF.",statusItems:[{label:"Ticker",value:i.asset.ticker,tone:"attention"},{label:"Exchange",value:i.asset.exchange??"n/a"},{label:"Provider",value:z?.provider??"pending"},{label:"Updated",value:z?.date??"no price date",tone:z?.price?"positive":"attention"}]}),n.jsx(u.XK,{ticker:i.asset.ticker,name:i.asset.name,description:i.asset.description,sector:i.asset.sector,exchange:i.asset.exchange,assetType:i.asset.asset_type,price:z?.price,currency:z?.currency,changePercent:z?.perf_1d,blumScore:I?.blum_score,confidence:I?.confidence_score??c?.blum_confidence_score,narrative:$}),(0,n.jsxs)("section",{className:"terminal-command-grid",style:{marginTop:12},children:[n.jsx(u.i9,{label:"Last Price",value:(0,m.T4)(z?.price,z?.currency),subvalue:z?.date??"price date pending"}),n.jsx(u.i9,{label:"1D / 5D",value:`${(0,m.T3)(z?.perf_1d)} / ${(0,m.T3)(z?.perf_5d)}`,subvalue:`${(0,m.T3)(z?.perf_1m)} 1M`,tone:(z?.perf_1d??0)>=0?"positive":"negative"}),n.jsx(u.i9,{label:"Volume",value:(0,m.fP)(z?.volume),subvalue:"Latest stored market volume"}),n.jsx(u.i9,{label:"Blum Score",value:I?.blum_score?.toFixed(1)??"n/a",subvalue:I?.classification??"No active signal",tone:"attention"}),n.jsx(u.i9,{label:"Sentiment",value:k(I,"sentiment_score"),subvalue:"News-linked score"}),n.jsx(u.i9,{label:"Momentum",value:k(I,"momentum_score"),subvalue:"Price factor"}),n.jsx(u.i9,{label:"Volatility",value:k(I,"volatility_score"),subvalue:"Risk component"}),n.jsx(u.i9,{label:"AI Confidence",value:I?.confidence_score?.toFixed(0)??c?.blum_confidence_score?.toFixed(0)??"Pending",subvalue:c?.confidence_label??"Evidence layer"})]}),I&&n.jsx("section",{style:{marginTop:12},children:n.jsx(u.il,{signal:I})}),n.jsx(g,{thesis:B,fallbackReason:$}),(0,n.jsxs)("section",{className:"grid-2",style:{marginTop:12},children:[n.jsx(j,{accuracy:c}),n.jsx(v,{fundamentals:_,assetType:i.asset.asset_type})]}),y&&n.jsx(f,{report:y}),n.jsx(t,{memory:w}),n.jsx(o.P,{ticker:i.asset.ticker,prices:L}),(0,n.jsxs)("section",{className:"grid-2",style:{marginTop:12},children:[n.jsx(h.G,{title:"Historical Price",data:[{x:L.map(e=>e.date),y:L.map(e=>e.close),type:"scatter",mode:"lines",name:e,line:{color:"#ffb000",width:2}}]}),n.jsx(h.G,{title:"Volume",data:[{x:L.map(e=>e.date),y:L.map(e=>e.volume??0),type:"bar",name:"Volume",marker:{color:"#4dd8ff"}}]})]}),(0,n.jsxs)("section",{className:"grid-2",style:{marginTop:12},children:[n.jsx(u.Ez,{title:"Score Breakdown",value:I?.score_version??"Blum score",children:n.jsx(d,{breakdown:I?.score_breakdown??{}})}),(0,n.jsxs)(u.Ez,{title:"Why This Asset Matters Now",value:T?.evidence_status?String(T.evidence_status).replaceAll("_"," "):"Evidence",children:[M&&(0,n.jsxs)("div",{className:"loading-state",children:[n.jsx("div",{}),"Building explanation from real market and news evidence."]}),A&&n.jsx("div",{className:"empty-state",children:A}),n.jsx("p",{children:T?.reason??I?.explanation??"The backend is collecting verified evidence for this asset."}),n.jsx("ul",{children:(T?.watch_points??I?.watch_points?.items??[]).map(e=>n.jsx("li",{children:e},e))}),T?.data_diagnostics&&n.jsx(E,{diagnostics:T.data_diagnostics})]})]}),(0,n.jsxs)("section",{className:"professional-grid-2",style:{marginTop:12},children:[(0,n.jsxs)(u.Ez,{title:"Decision Box",value:"Monitor, do not advise",children:[(0,n.jsxs)("div",{className:"professional-grid-2",children:[n.jsx(u.i9,{label:"Primary Trigger",value:I?I.classification.toLowerCase().includes("breakout")?"Confirmed breakout with volume expansion":I.classification.toLowerCase().includes("divergence")?"Sentiment and price alignment":"Sustained score and evidence improvement":"Signal snapshot pending",subvalue:"Condition that would increase attention"}),n.jsx(u.i9,{label:"Invalidation",value:I?I.risk_level.toLowerCase().includes("high")?"Volatility expands while confidence falls":"Momentum decay, negative news reversal or support failure":"Missing price, news or signal evidence",subvalue:"Condition that weakens the setup",tone:"negative"}),n.jsx(u.i9,{label:"Main Risk",value:I?.risk_level??"Evidence pending",subvalue:y?.risk_review?.[0]??"Risk review pending"}),n.jsx(u.i9,{label:"Confidence",value:I?.confidence_score?.toFixed(0)??c?.blum_confidence_score?.toFixed(0)??"Pending",subvalue:"Adaptive confidence layer"})]}),n.jsx("div",{className:"issue-list",children:(T?.watch_points??I?.watch_points?.items??y?.risk_review??[]).slice(0,5).map(e=>n.jsx("span",{children:e},e))})]}),n.jsx(u.Ez,{title:"Risk and Signal State",value:I?n.jsx(u.en,{risk:I.risk_level,score:(s="volatility_score",I?.score_breakdown?.[s]===void 0?null:Number(I.score_breakdown[s]))}):"No signal",children:(0,n.jsxs)("div",{className:"professional-grid-2",children:[n.jsx(u.i9,{label:"Classification",value:I?n.jsx(x.O,{label:I.classification}):"No signal"}),n.jsx(u.i9,{label:"Time Horizon",value:I?.time_horizon??"n/a"}),n.jsx(u.i9,{label:"Lifecycle",value:I?.lifecycle_state??"n/a"}),n.jsx(u.i9,{label:"Evidence",value:n.jsx(u.Dk,{value:c?.blum_confidence_score,label:"Quality"})})]})})]}),n.jsx(u.Ez,{title:"Related News",value:`${i.related_news.length} articles`,subtitle:"Sorted by stored relevance and source quality",className:"asset-news-panel",children:n.jsx("div",{className:"news-list",children:i.related_news.map(e=>(0,n.jsxs)("a",{className:"news-item",href:e.url,target:"_blank",rel:"noreferrer",children:[n.jsx("strong",{children:e.title}),(0,n.jsxs)("span",{children:[e.source," | quality ",e.quality_score]}),n.jsx("span",{children:[...e.theme_tags.events??[],...e.theme_tags.themes??[]].slice(0,4).map(e=>e.replaceAll("_"," ")).join(" | ")||"event classification pending"})]},e.id))})})]})}function j({accuracy:e}){if(!e)return(0,n.jsxs)("div",{className:"panel",children:[(0,n.jsxs)("div",{className:"panel-head",children:[n.jsx("span",{children:"Evidence Confidence"}),n.jsx("strong",{children:"Pending"})]}),n.jsx("div",{className:"empty-state",children:"The 15-point accuracy profile is being built for this asset."})]});let s=Object.entries(e.components).map(([e,s])=>({key:e,score:Number(s?.score??0),issues:s?.issues?.length??0})).sort((e,s)=>e.score-s.score).slice(0,7);return(0,n.jsxs)("div",{className:"panel",children:[(0,n.jsxs)("div",{className:"panel-head",children:[n.jsx("span",{children:"Evidence Confidence"}),(0,n.jsxs)("strong",{children:[e.blum_confidence_score.toFixed(1)," / ",e.confidence_label]})]}),n.jsx("div",{className:"confidence-meter",children:n.jsx("i",{style:{width:`${Math.max(2,Math.min(100,e.blum_confidence_score))}%`}})}),n.jsx("div",{className:"macro-list",children:s.map(e=>(0,n.jsxs)("div",{children:[n.jsx("strong",{children:e.key.replaceAll("_"," ")}),(0,n.jsxs)("span",{children:[e.score.toFixed(1)," score | ",e.issues," issues"]})]},e.key))}),!!e.issues.length&&n.jsx("div",{className:"issue-list",children:e.issues.slice(0,6).map(e=>n.jsx("span",{children:e.code.replaceAll("_"," ")},`${e.code}-${e.message}`))})]})}function v({fundamentals:e,assetType:s}){let i=e?.latest_snapshot,r=i?.metrics??{};return(0,n.jsxs)("div",{className:"panel",children:[(0,n.jsxs)("div",{className:"panel-head",children:[n.jsx("span",{children:"Fundamental Context"}),n.jsx("strong",{children:"ETF"===s?"ETF not required":i?"SEC evidence":"Pending"})]}),"ETF"===s?n.jsx("p",{children:"ETF confidence is driven by holdings proxy, sector rotation, trend confirmation and macro context. Issuer fundamentals are not required."}):i?(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)("div",{className:"grid-4",children:[(0,n.jsxs)("div",{className:"metric-card",children:[n.jsx("span",{children:"Quality"}),n.jsx("strong",{children:Number(i.quality_score??0).toFixed(0)})]}),(0,n.jsxs)("div",{className:"metric-card",children:[n.jsx("span",{children:"Period"}),n.jsx("strong",{children:i.period_end??"n/a"})]}),(0,n.jsxs)("div",{className:"metric-card",children:[n.jsx("span",{children:"Revenue"}),n.jsx("strong",{children:y(N(r.revenue))})]}),(0,n.jsxs)("div",{className:"metric-card",children:[n.jsx("span",{children:"Net Income"}),n.jsx("strong",{children:y(N(r.net_income))})]})]}),(0,n.jsxs)("p",{children:["Provider: ",i.provider,". This context is sourced from public filings and is used as evidence quality, not as a recommendation."]})]}):n.jsx("div",{className:"empty-state",children:"No verified fundamental snapshot is stored yet for this asset."})]})}function g({thesis:e,fallbackReason:s}){if(!e)return n.jsx(u.Ez,{title:"Executive Thesis",value:"Building",subtitle:"Every asset requires a structured thesis before it can become a research candidate.",className:"asset-thesis-panel",children:n.jsx("div",{className:"empty-state",children:"Blum is collecting enough signal, news, technical, sentiment and memory evidence to create an explicit thesis. No placeholder thesis is displayed."})});let i=e.conviction??{},r=e.market_context??{},a=e.narrative_analysis??{},t=e.historical_similarity??{},l=e.causal_reasoning??{},c=Object.entries(i.components??{}).slice(0,7);return(0,n.jsxs)("section",{style:{marginTop:12},children:[(0,n.jsxs)(u.Ez,{title:"Executive Thesis",value:`${w(e.conviction_score??i.score)} conviction`,subtitle:"Thesis strength, not probability of profit. Evidence, inference and uncertainty are separated.",className:"asset-thesis-panel",children:[n.jsx("p",{children:e.executive_thesis??s??"The thesis is being assembled from stored evidence."}),(0,n.jsxs)("div",{className:"professional-grid-4",style:{marginTop:12},children:[n.jsx(u.i9,{label:"Market Regime",value:r.regime??"Sideways",subvalue:r.signal_regime_adjustment??"Context adjustment pending"}),n.jsx(u.i9,{label:"Narrative Stage",value:a.lifecycle??"n/a",subvalue:`Intensity ${w(a.intensity)} | crowding ${w(a.crowding)}`}),n.jsx(u.i9,{label:"Historical Cases",value:t.similar_cases_found??0,subvalue:t.reliability??t.status??"memory pending"}),n.jsx(u.i9,{label:"Conviction Label",value:i.label??"n/a",subvalue:i.meaning??"Thesis strength score",tone:(e.conviction_score??0)>=70?"positive":"attention"})]})]}),(0,n.jsxs)("section",{className:"professional-grid-2",style:{marginTop:12},children:[(0,n.jsxs)(u.Ez,{title:"What Is Happening",value:"Observed + inferred",children:[n.jsx("p",{children:e.what_is_happening}),n.jsx("h3",{children:"Causal read"}),n.jsx("p",{children:e.why_it_may_be_happening}),(0,n.jsxs)("div",{className:"macro-list",children:[(0,n.jsxs)("div",{children:[n.jsx("strong",{children:"Price caused sentiment"}),n.jsx("span",{children:l.price_caused_sentiment??"not established"})]}),(0,n.jsxs)("div",{children:[n.jsx("strong",{children:"Sentiment caused price"}),n.jsx("span",{children:l.sentiment_caused_price??"not established"})]}),(0,n.jsxs)("div",{children:[n.jsx("strong",{children:"External event explains both"}),n.jsx("span",{children:l.external_event_explains_both??"not observed"})]})]})]}),(0,n.jsxs)(u.Ez,{title:"Market Context",value:r.regime??"Regime",children:[n.jsx("p",{children:r.interpretation??"Market regime context is pending."}),n.jsx(_,{items:e.facts_observed,empty:"Observed facts are still being collected."})]})]}),(0,n.jsxs)("section",{className:"professional-grid-2",style:{marginTop:12},children:[n.jsx(u.Ez,{title:"Supporting Evidence",value:`${b(e.supporting_evidence).length} items`,children:n.jsx(_,{items:e.supporting_evidence,empty:"No strong independent support is available yet."})}),n.jsx(u.Ez,{title:"Contradicting Evidence",value:`${b(e.contradicting_evidence).length} items`,children:n.jsx(_,{items:e.contradicting_evidence,empty:"No contradiction was found, but this does not prove the thesis."})})]}),(0,n.jsxs)("section",{className:"professional-grid-3",style:{marginTop:12},children:[(0,n.jsxs)(u.Ez,{title:"Narrative Analysis",value:a.lifecycle??"n/a",dense:!0,children:[(0,n.jsxs)("div",{className:"macro-list",children:[(0,n.jsxs)("div",{children:[n.jsx("strong",{children:"Growth velocity"}),n.jsx("span",{children:w(a.growth_velocity)})]}),(0,n.jsxs)("div",{children:[n.jsx("strong",{children:"Saturation"}),n.jsx("span",{children:w(a.saturation)})]}),(0,n.jsxs)("div",{children:[n.jsx("strong",{children:"Most exposed"}),n.jsx("span",{children:(a.most_exposed_assets??[]).join(", ")||"n/a"})]})]}),n.jsx("p",{children:a.interpretation??"Narrative interpretation is pending."})]}),(0,n.jsxs)(u.Ez,{title:"Historical Similarity",value:t.status??"memory",dense:!0,children:[(0,n.jsxs)("div",{className:"macro-list",children:[(0,n.jsxs)("div",{children:[n.jsx("strong",{children:"20D average"}),(0,n.jsxs)("span",{children:[w(t.average_forward_return_20d),"%"]})]}),(0,n.jsxs)("div",{children:[n.jsx("strong",{children:"Success rate"}),n.jsx("span",{children:w(t.success_rate)})]}),(0,n.jsxs)("div",{children:[n.jsx("strong",{children:"Drawdown"}),(0,n.jsxs)("span",{children:[w(t.average_drawdown),"%"]})]})]}),n.jsx("p",{children:t.explanation??"No similar historical setup is available yet."})]}),n.jsx(u.Ez,{title:"Conviction Reducers",value:i.label??"n/a",dense:!0,children:n.jsx(_,{items:e.conviction_reducers??i.reducers,empty:"No major conviction reducer was detected."})})]}),(0,n.jsxs)("section",{className:"professional-grid-2",style:{marginTop:12},children:[n.jsx(u.Ez,{title:"What The Market May Be Missing",value:"Blind spots",children:n.jsx(_,{items:e.what_the_market_may_be_missing,empty:"No clear market blind spot is visible."})}),(0,n.jsxs)(u.Ez,{title:"Risks and Invalidation",value:"Governance",children:[n.jsx("h3",{children:"Risks"}),n.jsx(_,{items:e.risks,empty:"Risk evidence is still forming."}),n.jsx("h3",{children:"Invalidation conditions"}),n.jsx(_,{items:e.invalidation_conditions,empty:"Invalidation conditions are not available yet."})]})]}),(0,n.jsxs)("section",{className:"professional-grid-2",style:{marginTop:12},children:[(0,n.jsxs)(u.Ez,{title:"Final Blum View",value:"Research stance",children:[n.jsx("p",{children:e.final_blum_view??"Final view pending."}),n.jsx("h3",{children:"Intellectual honesty"}),n.jsx(_,{items:e.intellectual_honesty,empty:"No specific limitation was recorded."})]}),n.jsx(u.Ez,{title:"Conviction Components",value:w(e.conviction_score),children:n.jsx("div",{className:"macro-list",children:c.map(([e,s])=>(0,n.jsxs)("div",{children:[n.jsx("strong",{children:e.replaceAll("_"," ")}),n.jsx("span",{children:w(s)})]},e))})})]})]})}function _({items:e,empty:s}){let i=b(e);return i.length?n.jsx("ul",{children:i.map((e,s)=>n.jsx("li",{children:e},`${e}-${s}`))}):n.jsx("div",{className:"empty-state",children:s})}function b(e){return e?(Array.isArray(e)?e:[e]).map(e=>null==e?"":"string"==typeof e?e:"number"==typeof e||"boolean"==typeof e?String(e):e.explanation??e.reason??e.summary??JSON.stringify(e)).filter(Boolean):[]}function f({report:e}){let s=e.similar_signal_history??{};return(0,n.jsxs)("section",{className:"panel",style:{marginTop:12},children:[(0,n.jsxs)("div",{className:"panel-head",children:[n.jsx("span",{children:"Asset Intelligence Report"}),n.jsx("strong",{children:String(e.data_mode??"evidence").replaceAll("_"," ")})]}),(0,n.jsxs)("div",{className:"grid-2",children:[(0,n.jsxs)("div",{children:[n.jsx("h3",{children:"Why it surfaced"}),n.jsx("p",{children:e.why_in_radar}),n.jsx("h3",{children:"Bullish scenario"}),n.jsx("p",{children:e.bullish_scenario}),n.jsx("h3",{children:"Bearish scenario"}),n.jsx("p",{children:e.bearish_scenario})]}),(0,n.jsxs)("div",{className:"macro-list",children:[(0,n.jsxs)("div",{children:[n.jsx("strong",{children:"Similar cases"}),(0,n.jsxs)("span",{children:[s.case_count??0," / ",s.data_mode??"n/a"]})]}),(0,n.jsxs)("div",{children:[n.jsx("strong",{children:"5D avg"}),(0,n.jsxs)("span",{children:[w(s.avg_forward_return_5d),"%"]})]}),(0,n.jsxs)("div",{children:[n.jsx("strong",{children:"20D avg"}),(0,n.jsxs)("span",{children:[w(s.avg_forward_return_20d),"%"]})]}),(0,n.jsxs)("div",{children:[n.jsx("strong",{children:"Positive 20D"}),n.jsx("span",{children:w(s.positive_outcome_probability_20d)})]}),(0,n.jsxs)("div",{children:[n.jsx("strong",{children:"Avg drawdown"}),(0,n.jsxs)("span",{children:[w(s.average_drawdown),"%"]})]}),(0,n.jsxs)("div",{children:[n.jsx("strong",{children:"Reliability"}),n.jsx("span",{children:s.statistical_reliability??"n/a"})]})]})]}),n.jsx("div",{className:"issue-list",children:(e.risk_review??[]).slice(0,5).map(e=>n.jsx("span",{children:e},e))}),(0,n.jsxs)("p",{children:[n.jsx("strong",{children:"AI conclusion:"})," ",e.ai_conclusion]}),n.jsx("p",{children:e.disclaimer})]})}function y(e){return null==e||Number.isNaN(Number(e))?"n/a":new Intl.NumberFormat("en",{notation:"compact",maximumFractionDigits:1}).format(Number(e))}function N(e){return"number"==typeof e?e:e&&"number"==typeof e.value?e.value:null}function w(e){return null==e||Number.isNaN(Number(e))?"n/a":Number(e).toFixed(2)}function k(e,s){return e?.score_breakdown?.[s]===void 0?"n/a":Number(e.score_breakdown[s]).toFixed(0)}function E({diagnostics:e}){let s=e.market_update??{},i=e.news_update??{};return(0,n.jsxs)("div",{className:"diagnostic-grid",children:[(0,n.jsxs)("div",{children:[n.jsx("span",{children:"Market evidence"}),(0,n.jsxs)("strong",{children:[e.price_rows??0," stored rows"]}),(0,n.jsxs)("p",{children:[s.updated_assets??0," assets updated | ",s.price_rows??0," rows fetched"]}),!!s.missing_assets?.length&&(0,n.jsxs)("p",{children:["Missing public prices: ",s.missing_assets.slice(0,6).join(", ")]})]}),(0,n.jsxs)("div",{children:[n.jsx("span",{children:"News evidence"}),(0,n.jsxs)("strong",{children:[e.linked_news??0," linked articles"]}),(0,n.jsxs)("p",{children:[i.sources_ok??0,"/",i.sources_requested??0," public sources ok | ",i.linked_assets??0," asset links"]})]})]})}},8117:(e,s,i)=>{"use strict";i.d(s,{Ku:()=>r,T3:()=>t,T4:()=>a,fP:()=>l});var n=i(8924);function r({snapshot:e,compact:s=!1}){return e&&"ready"===e.data_status&&null!=e.price?(0,n.jsxs)("div",{className:s?"market-strip compact":"market-strip",children:[(0,n.jsxs)("div",{children:[n.jsx("span",{children:"Last Price"}),n.jsx("strong",{children:a(e.price,e.currency)})]}),(0,n.jsxs)("div",{children:[n.jsx("span",{children:"1D"}),n.jsx("strong",{className:c(e.perf_1d),children:t(e.perf_1d)})]}),!s&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)("div",{children:[n.jsx("span",{children:"5D"}),n.jsx("strong",{className:c(e.perf_5d),children:t(e.perf_5d)})]}),(0,n.jsxs)("div",{children:[n.jsx("span",{children:"1M"}),n.jsx("strong",{className:c(e.perf_1m),children:t(e.perf_1m)})]})]}),(0,n.jsxs)("div",{children:[n.jsx("span",{children:e.provider??"Provider"}),n.jsx("strong",{children:e.date??"n/a"})]})]}):(0,n.jsxs)("div",{className:s?"market-strip compact":"market-strip",children:[(0,n.jsxs)("div",{children:[n.jsx("span",{children:"Price"}),n.jsx("strong",{children:"Real price pending"})]}),(0,n.jsxs)("div",{children:[n.jsx("span",{children:"Provider"}),n.jsx("strong",{children:"n/a"})]})]})}function a(e,s="USD"){return null==e||Number.isNaN(Number(e))?"n/a":new Intl.NumberFormat("en",{style:"currency",currency:s||"USD",maximumFractionDigits:e>=100?2:4}).format(Number(e))}function t(e){return null==e||Number.isNaN(Number(e))?"n/a":`${e>0?"+":""}${Number(e).toFixed(2)}%`}function l(e){return null==e||Number.isNaN(Number(e))?"n/a":new Intl.NumberFormat("en",{notation:"compact",maximumFractionDigits:2}).format(Number(e))}function c(e){return null==e?"":e>0?"positive-text":e<0?"negative-text":""}},3081:(e,s,i)=>{"use strict";i.d(s,{O:()=>a});var n=i(8924),r=i(9779);function a({label:e}){let s=e.includes("Breakout")||e.includes("Strong")?"positive":e.includes("Risk")||e.includes("Avoid")?"negative":e.includes("Divergence")||e.includes("Contrarian")?"warning":"neutral";return n.jsx("span",{className:(0,r.Z)("status-badge",s),children:e})}},1474:(e,s,i)=>{"use strict";i.r(s),i.d(s,{default:()=>l,generateStaticParams:()=>t});var n=i(5886);let r=(0,i(6691).createProxy)(String.raw`/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/assets/[ticker]/view.tsx#AssetDetailClient`),a=["SPY","QQQ","IWM","DIA","SMH","XLK","XLF","XLE","XLV","XAR","BOTZ","HACK","ICLN","TLT","GLD","AAPL","MSFT","NVDA","AMD","AVGO","AMZN","GOOGL","META","TSLA","JPM","XOM","LLY","NVO","ASML","SAP","SIE.DE","AIR.PA","RHM.DE","MC.PA","ENR.DE"];function t(){return a.map(e=>({ticker:encodeURIComponent(e.toUpperCase().replaceAll(".","_"))}))}function l({params:e}){return n.jsx(r,{ticker:decodeURIComponent(e.ticker).replaceAll("_",".").toUpperCase()})}}};var s=require("../../../webpack-runtime.js");s.C(e);var i=e=>s(s.s=e),n=s.X(0,[273,394,927,640],()=>i(5758));module.exports=n})();
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/[ticker]/page.js.nft.json b/frontend/.next/server/app/assets/[ticker]/page.js.nft.json
new file mode 100644
index 0000000000000000000000000000000000000000..a23cb1be3bb658c840b2cb6bcf01e0d7bee095be
--- /dev/null
+++ b/frontend/.next/server/app/assets/[ticker]/page.js.nft.json
@@ -0,0 +1 @@
+{"version":1,"files":["../../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage.external.js","../../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/async-local-storage.js","../../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage.external.js","../../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/constants.js","../../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/tracer.js","../../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/package.json","../../../../../node_modules/next","../../../../../package.json","../../../../package.json","../../../chunks/273.js","../../../chunks/394.js","../../../chunks/640.js","../../../chunks/927.js","../../../webpack-runtime.js","page_client-reference-manifest.js"]}
\ No newline at end of file
diff --git a/frontend/.next/server/app/assets/[ticker]/page_client-reference-manifest.js b/frontend/.next/server/app/assets/[ticker]/page_client-reference-manifest.js
new file mode 100644
index 0000000000000000000000000000000000000000..df0e423f7cc111a3df25f74a0b4cc1235c55c594
--- /dev/null
+++ b/frontend/.next/server/app/assets/[ticker]/page_client-reference-manifest.js
@@ -0,0 +1 @@
+globalThis.__RSC_MANIFEST=(globalThis.__RSC_MANIFEST||{});globalThis.__RSC_MANIFEST["/assets/[ticker]/page"]={"moduleLoading":{"prefix":"/_next/","crossOrigin":null},"ssrModuleMapping":{"176":{"*":{"id":"6676","name":"*","chunks":[],"async":false}},"841":{"*":{"id":"9737","name":"*","chunks":[],"async":false}},"892":{"*":{"id":"5213","name":"*","chunks":[],"async":false}},"2010":{"*":{"id":"7619","name":"*","chunks":[],"async":false}},"2433":{"*":{"id":"6544","name":"*","chunks":[],"async":false}},"2651":{"*":{"id":"9645","name":"*","chunks":[],"async":false}},"2987":{"*":{"id":"1358","name":"*","chunks":[],"async":false}},"3713":{"*":{"id":"5210","name":"*","chunks":[],"async":false}},"4374":{"*":{"id":"9927","name":"*","chunks":[],"async":false}},"6056":{"*":{"id":"1309","name":"*","chunks":[],"async":false}},"6543":{"*":{"id":"9722","name":"*","chunks":[],"async":false}},"6813":{"*":{"id":"5877","name":"*","chunks":[],"async":false}},"7096":{"*":{"id":"1952","name":"*","chunks":[],"async":false}},"7413":{"*":{"id":"8052","name":"*","chunks":[],"async":false}},"7523":{"*":{"id":"3477","name":"*","chunks":[],"async":false}},"7768":{"*":{"id":"7663","name":"*","chunks":[],"async":false}},"8145":{"*":{"id":"8377","name":"*","chunks":[],"async":false}},"8528":{"*":{"id":"5116","name":"*","chunks":[],"async":false}},"8547":{"*":{"id":"5441","name":"*","chunks":[],"async":false}},"9135":{"*":{"id":"432","name":"*","chunks":[],"async":false}},"9239":{"*":{"id":"8132","name":"*","chunks":[],"async":false}},"9414":{"*":{"id":"8850","name":"*","chunks":[],"async":false}},"9570":{"*":{"id":"291","name":"*","chunks":[],"async":false}}},"edgeSSRModuleMapping":{},"clientModules":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/globals.css":{"id":4443,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/components/AppShell.tsx":{"id":6813,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/backtest/page.tsx":{"id":4374,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chart-analyst/page.tsx":{"id":6543,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chat/page.tsx":{"id":841,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chatbot/page.tsx":{"id":8145,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/learning/page.tsx":{"id":6056,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/methodology/page.tsx":{"id":7413,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/ipo-radar/page.tsx":{"id":9135,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/market-brain/page.tsx":{"id":2987,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page.tsx":{"id":892,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/dashboard/page.tsx":{"id":7096,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","96","static/chunks/96-ce8c57cd15d50941.js","931","static/chunks/app/page-d0db9a93fb4af9a5.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/etf-radar/page.tsx":{"id":9239,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/performance/page.tsx":{"id":8547,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/signal-lab/page.tsx":{"id":2010,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/sniper/page.tsx":{"id":7768,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/stock-radar/page.tsx":{"id":9570,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/assets/[ticker]/view.tsx":{"id":3713,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","75","static/chunks/75-8c48549bc3f12b00.js","825","static/chunks/app/assets/%5Bticker%5D/page-3687f8c7fa1ef7c8.js"],"async":false}},"entryCSSFiles":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout":["static/css/02bd12e03544ea91.css"],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/page":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/assets/[ticker]/page":[]}}
\ No newline at end of file
diff --git a/frontend/.next/server/app/backtest.html b/frontend/.next/server/app/backtest.html
new file mode 100644
index 0000000000000000000000000000000000000000..7e204e869bc486724c53bc9ee2d69a4c5fdcffcf
--- /dev/null
+++ b/frontend/.next/server/app/backtest.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence BacktestHistorical validation, not performance prediction.
\ No newline at end of file
diff --git a/frontend/.next/server/app/backtest.meta b/frontend/.next/server/app/backtest.meta
new file mode 100644
index 0000000000000000000000000000000000000000..3a29b6d0d107dc66774cad952fc3594f985f86e7
--- /dev/null
+++ b/frontend/.next/server/app/backtest.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/backtest/layout,_N_T_/backtest/page,_N_T_/backtest/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/backtest.rsc b/frontend/.next/server/app/backtest.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..1790cbdedd105927072131f6990ad4a6587488a6
--- /dev/null
+++ b/frontend/.next/server/app/backtest.rsc
@@ -0,0 +1,8 @@
+2:I[7523,[],"ClientPageRoot"]
+3:I[4374,["651","static/chunks/651-5689242ae9b0ffc6.js","103","static/chunks/app/backtest/page-60b494c3f5caeab7.js"],"default",1]
+4:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["backtest",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["backtest",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","backtest","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/backtest/page.js b/frontend/.next/server/app/backtest/page.js
new file mode 100644
index 0000000000000000000000000000000000000000..1896e9131183cb9c99b29fc8bbf13d6c6bfee467
--- /dev/null
+++ b/frontend/.next/server/app/backtest/page.js
@@ -0,0 +1 @@
+(()=>{var e={};e.id=103,e.ids=[103],e.modules={2934:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external.js")},4580:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external.js")},5869:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},399:e=>{"use strict";e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},2890:(e,t,r)=>{"use strict";r.r(t),r.d(t,{GlobalError:()=>l.a,__next_app__:()=>p,originalPathname:()=>c,pages:()=>u,routeModule:()=>f,tree:()=>d}),r(5771),r(8777),r(311);var s=r(9296),a=r(1650),n=r(7045),l=r.n(n),i=r(8184),o={};for(let e in i)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(o[e]=()=>i[e]);r.d(t,o);let d=["",{children:["backtest",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(r.bind(r,5771)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/backtest/page.tsx"]}]},{}]},{layout:[()=>Promise.resolve().then(r.bind(r,8777)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout.tsx"],"not-found":[()=>Promise.resolve().then(r.t.bind(r,311,23)),"next/dist/client/components/not-found-error"]}],u=["/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/backtest/page.tsx"],c="/backtest/page",p={require:r,loadChunk:()=>Promise.resolve()},f=new s.AppPageRouteModule({definition:{kind:a.x.APP_PAGE,page:"/backtest/page",pathname:"/backtest",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:d}})},6541:(e,t,r)=>{Promise.resolve().then(r.bind(r,9927))},9927:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>i});var s=r(8924),a=r(3911),n=r(3789),l=r(7749);function i(){let[e,t]=(0,a.useState)("NVDA"),[r,i]=(0,a.useState)(null),[d,u]=(0,a.useState)(!1),c=async()=>{u(!0);try{i(await n.h.backtest(e.toUpperCase()))}finally{u(!1)}},p=r?.metrics??{};return(0,s.jsxs)(s.Fragment,{children:[s.jsx("div",{className:"page-header",children:(0,s.jsxs)("div",{children:[s.jsx("div",{className:"kicker",children:"Backtest"}),s.jsx("h1",{children:"Historical validation, not performance prediction."})]})}),(0,s.jsxs)("div",{className:"control-row",children:[s.jsx("input",{className:"input",value:e,onChange:e=>t(e.target.value)}),s.jsx("button",{className:"button primary",onClick:c,children:d?"Running...":"Run validation"})]}),r&&(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)("section",{className:"grid-4",children:[s.jsx(o,{label:"Signals",value:p.signal_count??0}),s.jsx(o,{label:"Hit Rate 20D",value:`${((p.hit_rate_20d??0)*100).toFixed(1)}%`}),s.jsx(o,{label:"Avg Forward 20D",value:`${(p.average_forward_return_20d??0).toFixed(2)}%`}),s.jsx(o,{label:"False Positive 20D",value:`${((p.false_positive_rate_20d??0)*100).toFixed(1)}%`})]}),(0,s.jsxs)("section",{className:"grid-2",style:{marginTop:12},children:[s.jsx(l.G,{title:"Best Signals",data:[{x:(r.best_signals??[]).map(e=>e.date),y:(r.best_signals??[]).map(e=>e.forward_return_20d),type:"bar",marker:{color:"#20e070"}}]}),s.jsx(l.G,{title:"Worst Signals",data:[{x:(r.worst_signals??[]).map(e=>e.date),y:(r.worst_signals??[]).map(e=>e.forward_return_20d),type:"bar",marker:{color:"#ff4d5e"}}]})]}),s.jsx("p",{children:r.disclaimer})]})]})}function o({label:e,value:t}){return(0,s.jsxs)("div",{className:"metric-card",children:[s.jsx("span",{children:e}),s.jsx("strong",{children:t})]})}},7749:(e,t,r)=>{"use strict";r.d(t,{G:()=>o});var s=r(8924),a=r(1328),n=r.n(a),l=r(3911);let i=n()(async()=>{},{loadableGenerated:{modules:["components/PlotPanel.tsx -> react-plotly.js"]},ssr:!1});function o({title:e,data:t,layout:r={},height:a=360,emptyMessage:n="Waiting for real data series."}){let o=t.some(e=>[e?.x,e?.y,e?.z,e?.values,e?.labels].filter(Array.isArray).some(e=>!!e.length&&(!Array.isArray(e[0])||e.some(e=>Array.isArray(e)&&e.length>0)))),d={data:t,layout:{autosize:!0,height:a,paper_bgcolor:"#07090d",plot_bgcolor:"#090d13",font:{color:"#e7edf6",family:"Inter, system-ui, sans-serif"},margin:{l:42,r:18,t:18,b:36},xaxis:{gridcolor:"rgba(255,255,255,.06)",zeroline:!1},yaxis:{gridcolor:"rgba(255,255,255,.06)",zeroline:!1},...r},config:{displayModeBar:!1,responsive:!0},useResizeHandler:!0,style:{width:"100%"}};return(0,s.jsxs)("section",{className:"panel",children:[s.jsx("div",{className:"panel-head",children:s.jsx("span",{children:e})}),o?(0,l.createElement)(i,d):s.jsx("div",{className:"plot-empty",children:n})]})}},1328:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return n}});let s=r(1607);r(8924),r(3911);let a=s._(r(4737));function n(e,t){var r;let s={loading:e=>{let{error:t,isLoading:r,pastDelay:s}=e;return null}};"function"==typeof e&&(s.loader=e);let n={...s,...t};return(0,a.default)({...n,modules:null==(r=n.loadableGenerated)?void 0:r.modules})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},3880:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"BailoutToCSR",{enumerable:!0,get:function(){return a}});let s=r(6483);function a(e){let{reason:t,children:r}=e;throw new s.BailoutToCSRError(t)}},4737:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return d}});let s=r(8924),a=r(3911),n=r(3880),l=r(7083);function i(e){return{default:e&&"default"in e?e.default:e}}let o={loader:()=>Promise.resolve(i(()=>null)),loading:null,ssr:!0},d=function(e){let t={...o,...e},r=(0,a.lazy)(()=>t.loader().then(i)),d=t.loading;function u(e){let i=d?(0,s.jsx)(d,{isLoading:!0,pastDelay:!0,error:null}):null,o=t.ssr?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(l.PreloadCss,{moduleIds:t.modules}),(0,s.jsx)(r,{...e})]}):(0,s.jsx)(n.BailoutToCSR,{reason:"next/dynamic",children:(0,s.jsx)(r,{...e})});return(0,s.jsx)(a.Suspense,{fallback:i,children:o})}return u.displayName="LoadableComponent",u}},7083:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"PreloadCss",{enumerable:!0,get:function(){return n}});let s=r(8924),a=r(4580);function n(e){let{moduleIds:t}=e,r=(0,a.getExpectedRequestStore)("next/dynamic css"),n=[];if(r.reactLoadableManifest&&t){let e=r.reactLoadableManifest;for(let r of t){if(!e[r])continue;let t=e[r].files.filter(e=>e.endsWith(".css"));n.push(...t)}}return 0===n.length?null:(0,s.jsx)(s.Fragment,{children:n.map(e=>(0,s.jsx)("link",{precedence:"dynamic",rel:"stylesheet",href:r.assetPrefix+"/_next/"+encodeURI(e),as:"style"},e))})}},5771:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>s});let s=(0,r(6691).createProxy)(String.raw`/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/backtest/page.tsx#default`)}};var t=require("../../webpack-runtime.js");t.C(e);var r=e=>t(t.s=e),s=t.X(0,[273,394],()=>r(2890));module.exports=s})();
\ No newline at end of file
diff --git a/frontend/.next/server/app/backtest/page.js.nft.json b/frontend/.next/server/app/backtest/page.js.nft.json
new file mode 100644
index 0000000000000000000000000000000000000000..877e4e935689e2063c7f370e14175cea6de0d164
--- /dev/null
+++ b/frontend/.next/server/app/backtest/page.js.nft.json
@@ -0,0 +1 @@
+{"version":1,"files":["../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/package.json","../../../../node_modules/next","../../../../package.json","../../../package.json","../../chunks/273.js","../../chunks/394.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}
\ No newline at end of file
diff --git a/frontend/.next/server/app/backtest/page_client-reference-manifest.js b/frontend/.next/server/app/backtest/page_client-reference-manifest.js
new file mode 100644
index 0000000000000000000000000000000000000000..3e36229833b59f396ebf3a53376a2efbfff62278
--- /dev/null
+++ b/frontend/.next/server/app/backtest/page_client-reference-manifest.js
@@ -0,0 +1 @@
+globalThis.__RSC_MANIFEST=(globalThis.__RSC_MANIFEST||{});globalThis.__RSC_MANIFEST["/backtest/page"]={"moduleLoading":{"prefix":"/_next/","crossOrigin":null},"ssrModuleMapping":{"176":{"*":{"id":"6676","name":"*","chunks":[],"async":false}},"841":{"*":{"id":"9737","name":"*","chunks":[],"async":false}},"892":{"*":{"id":"5213","name":"*","chunks":[],"async":false}},"2010":{"*":{"id":"7619","name":"*","chunks":[],"async":false}},"2433":{"*":{"id":"6544","name":"*","chunks":[],"async":false}},"2651":{"*":{"id":"9645","name":"*","chunks":[],"async":false}},"2987":{"*":{"id":"1358","name":"*","chunks":[],"async":false}},"3713":{"*":{"id":"5210","name":"*","chunks":[],"async":false}},"4374":{"*":{"id":"9927","name":"*","chunks":[],"async":false}},"6056":{"*":{"id":"1309","name":"*","chunks":[],"async":false}},"6543":{"*":{"id":"9722","name":"*","chunks":[],"async":false}},"6813":{"*":{"id":"5877","name":"*","chunks":[],"async":false}},"7096":{"*":{"id":"1952","name":"*","chunks":[],"async":false}},"7413":{"*":{"id":"8052","name":"*","chunks":[],"async":false}},"7523":{"*":{"id":"3477","name":"*","chunks":[],"async":false}},"7768":{"*":{"id":"7663","name":"*","chunks":[],"async":false}},"8145":{"*":{"id":"8377","name":"*","chunks":[],"async":false}},"8528":{"*":{"id":"5116","name":"*","chunks":[],"async":false}},"8547":{"*":{"id":"5441","name":"*","chunks":[],"async":false}},"9135":{"*":{"id":"432","name":"*","chunks":[],"async":false}},"9239":{"*":{"id":"8132","name":"*","chunks":[],"async":false}},"9414":{"*":{"id":"8850","name":"*","chunks":[],"async":false}},"9570":{"*":{"id":"291","name":"*","chunks":[],"async":false}}},"edgeSSRModuleMapping":{},"clientModules":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/globals.css":{"id":4443,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/components/AppShell.tsx":{"id":6813,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/backtest/page.tsx":{"id":4374,"name":"*","chunks":["651","static/chunks/651-5689242ae9b0ffc6.js","103","static/chunks/app/backtest/page-60b494c3f5caeab7.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chart-analyst/page.tsx":{"id":6543,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chat/page.tsx":{"id":841,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chatbot/page.tsx":{"id":8145,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/learning/page.tsx":{"id":6056,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/methodology/page.tsx":{"id":7413,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/ipo-radar/page.tsx":{"id":9135,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/market-brain/page.tsx":{"id":2987,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page.tsx":{"id":892,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/dashboard/page.tsx":{"id":7096,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","96","static/chunks/96-ce8c57cd15d50941.js","931","static/chunks/app/page-d0db9a93fb4af9a5.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/etf-radar/page.tsx":{"id":9239,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/performance/page.tsx":{"id":8547,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/signal-lab/page.tsx":{"id":2010,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/sniper/page.tsx":{"id":7768,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/stock-radar/page.tsx":{"id":9570,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/assets/[ticker]/view.tsx":{"id":3713,"name":"*","chunks":[],"async":false}},"entryCSSFiles":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout":["static/css/02bd12e03544ea91.css"],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/page":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/backtest/page":[]}}
\ No newline at end of file
diff --git a/frontend/.next/server/app/chart-analyst.html b/frontend/.next/server/app/chart-analyst.html
new file mode 100644
index 0000000000000000000000000000000000000000..bdaf15c92d5f217fc00d6a11b0876df27c74b71e
--- /dev/null
+++ b/frontend/.next/server/app/chart-analyst.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading chart analyst
\ No newline at end of file
diff --git a/frontend/.next/server/app/chart-analyst.meta b/frontend/.next/server/app/chart-analyst.meta
new file mode 100644
index 0000000000000000000000000000000000000000..fc35e764d2d87bce418f4f10c96bf149016f6cec
--- /dev/null
+++ b/frontend/.next/server/app/chart-analyst.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/chart-analyst/layout,_N_T_/chart-analyst/page,_N_T_/chart-analyst/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/chart-analyst.rsc b/frontend/.next/server/app/chart-analyst.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..c065505b0aa6437b4d27534fb9464bc52b17393b
--- /dev/null
+++ b/frontend/.next/server/app/chart-analyst.rsc
@@ -0,0 +1,8 @@
+2:I[7523,[],"ClientPageRoot"]
+3:I[6543,["651","static/chunks/651-5689242ae9b0ffc6.js","75","static/chunks/75-8c48549bc3f12b00.js","441","static/chunks/app/chart-analyst/page-422122938e79d615.js"],"default",1]
+4:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["chart-analyst",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["chart-analyst",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","chart-analyst","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/chart-analyst/page.js b/frontend/.next/server/app/chart-analyst/page.js
new file mode 100644
index 0000000000000000000000000000000000000000..eb3913b88e8c08f43e4f6ac01741494070a1ce32
--- /dev/null
+++ b/frontend/.next/server/app/chart-analyst/page.js
@@ -0,0 +1 @@
+(()=>{var e={};e.id=441,e.ids=[441],e.modules={2934:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external.js")},4580:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external.js")},5869:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},399:e=>{"use strict";e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},5067:(e,t,r)=>{"use strict";r.r(t),r.d(t,{GlobalError:()=>i.a,__next_app__:()=>u,originalPathname:()=>p,pages:()=>d,routeModule:()=>h,tree:()=>c}),r(1102),r(8777),r(311);var s=r(9296),n=r(1650),a=r(7045),i=r.n(a),o=r(8184),l={};for(let e in o)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(l[e]=()=>o[e]);r.d(t,l);let c=["",{children:["chart-analyst",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(r.bind(r,1102)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chart-analyst/page.tsx"]}]},{}]},{layout:[()=>Promise.resolve().then(r.bind(r,8777)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout.tsx"],"not-found":[()=>Promise.resolve().then(r.t.bind(r,311,23)),"next/dist/client/components/not-found-error"]}],d=["/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chart-analyst/page.tsx"],p="/chart-analyst/page",u={require:r,loadChunk:()=>Promise.resolve()},h=new s.AppPageRouteModule({definition:{kind:n.x.APP_PAGE,page:"/chart-analyst/page",pathname:"/chart-analyst",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:c}})},6034:(e,t,r)=>{Promise.resolve().then(r.bind(r,9722))},9722:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>o});var s=r(8924),n=r(3911);r(3789);var a=r(905),i=r(2522);function o(){let[e,t]=(0,n.useState)(null),[r,o]=(0,n.useState)("NVDA"),[l,c]=(0,n.useState)([]),[d,p]=(0,n.useState)(""),u=(0,n.useMemo)(()=>e?.find(e=>e.ticker===r),[e,r]);return d?(0,s.jsxs)("div",{className:"empty-state",children:["API error: ",d]}):e?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)("div",{className:"page-header",children:[(0,s.jsxs)("div",{children:[s.jsx("div",{className:"kicker",children:"Chart Analyst"}),s.jsx("h1",{children:"Institutional technical chart intelligence."}),s.jsx("p",{children:"Hybrid analysis from deterministic OHLCV indicators, optional Qwen3-VL chart vision, sentiment context and Blum memory."})]}),s.jsx("select",{className:"input",value:r,onChange:e=>o(e.target.value),children:e.map(e=>(0,s.jsxs)("option",{value:e.ticker,children:[e.ticker," | ",e.name]},e.ticker))})]}),u&&(0,s.jsxs)("section",{className:"instrument-card",style:{marginBottom:12},children:[(0,s.jsxs)("div",{children:[s.jsx("span",{children:"Instrument"}),(0,s.jsxs)("strong",{children:[u.ticker," | ",u.sector]}),(0,s.jsxs)("p",{children:[u.name," | ",u.asset_type," | ",u.exchange," | ",u.country]})]}),(0,s.jsxs)("div",{className:"market-strip compact",children:[(0,s.jsxs)("div",{children:[s.jsx("span",{children:"Price"}),s.jsx("strong",{children:u.market_snapshot?.price??"n/a"})]}),(0,s.jsxs)("div",{children:[s.jsx("span",{children:"1D"}),(0,s.jsxs)("strong",{children:[u.market_snapshot?.perf_1d??"n/a","%"]})]}),(0,s.jsxs)("div",{children:[s.jsx("span",{children:"Provider"}),s.jsx("strong",{children:u.market_snapshot?.provider??"pending"})]})]})]}),s.jsx(a.P,{ticker:r,prices:l})]}):s.jsx(i.G,{label:"Loading chart analyst"})}},1102:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>s});let s=(0,r(6691).createProxy)(String.raw`/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chart-analyst/page.tsx#default`)}};var t=require("../../webpack-runtime.js");t.C(e);var r=e=>t(t.s=e),s=t.X(0,[273,394,640],()=>r(5067));module.exports=s})();
\ No newline at end of file
diff --git a/frontend/.next/server/app/chart-analyst/page.js.nft.json b/frontend/.next/server/app/chart-analyst/page.js.nft.json
new file mode 100644
index 0000000000000000000000000000000000000000..e7482b470b58d70bdbdb5247c4e7fade7c4d1a3a
--- /dev/null
+++ b/frontend/.next/server/app/chart-analyst/page.js.nft.json
@@ -0,0 +1 @@
+{"version":1,"files":["../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/package.json","../../../../node_modules/next","../../../../package.json","../../../package.json","../../chunks/273.js","../../chunks/394.js","../../chunks/640.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}
\ No newline at end of file
diff --git a/frontend/.next/server/app/chart-analyst/page_client-reference-manifest.js b/frontend/.next/server/app/chart-analyst/page_client-reference-manifest.js
new file mode 100644
index 0000000000000000000000000000000000000000..38eafd6e45a9538f626bdd0d92cd19d97a3e1318
--- /dev/null
+++ b/frontend/.next/server/app/chart-analyst/page_client-reference-manifest.js
@@ -0,0 +1 @@
+globalThis.__RSC_MANIFEST=(globalThis.__RSC_MANIFEST||{});globalThis.__RSC_MANIFEST["/chart-analyst/page"]={"moduleLoading":{"prefix":"/_next/","crossOrigin":null},"ssrModuleMapping":{"176":{"*":{"id":"6676","name":"*","chunks":[],"async":false}},"841":{"*":{"id":"9737","name":"*","chunks":[],"async":false}},"892":{"*":{"id":"5213","name":"*","chunks":[],"async":false}},"2010":{"*":{"id":"7619","name":"*","chunks":[],"async":false}},"2433":{"*":{"id":"6544","name":"*","chunks":[],"async":false}},"2651":{"*":{"id":"9645","name":"*","chunks":[],"async":false}},"2987":{"*":{"id":"1358","name":"*","chunks":[],"async":false}},"3713":{"*":{"id":"5210","name":"*","chunks":[],"async":false}},"4374":{"*":{"id":"9927","name":"*","chunks":[],"async":false}},"6056":{"*":{"id":"1309","name":"*","chunks":[],"async":false}},"6543":{"*":{"id":"9722","name":"*","chunks":[],"async":false}},"6813":{"*":{"id":"5877","name":"*","chunks":[],"async":false}},"7096":{"*":{"id":"1952","name":"*","chunks":[],"async":false}},"7413":{"*":{"id":"8052","name":"*","chunks":[],"async":false}},"7523":{"*":{"id":"3477","name":"*","chunks":[],"async":false}},"7768":{"*":{"id":"7663","name":"*","chunks":[],"async":false}},"8145":{"*":{"id":"8377","name":"*","chunks":[],"async":false}},"8528":{"*":{"id":"5116","name":"*","chunks":[],"async":false}},"8547":{"*":{"id":"5441","name":"*","chunks":[],"async":false}},"9135":{"*":{"id":"432","name":"*","chunks":[],"async":false}},"9239":{"*":{"id":"8132","name":"*","chunks":[],"async":false}},"9414":{"*":{"id":"8850","name":"*","chunks":[],"async":false}},"9570":{"*":{"id":"291","name":"*","chunks":[],"async":false}}},"edgeSSRModuleMapping":{},"clientModules":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/globals.css":{"id":4443,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/components/AppShell.tsx":{"id":6813,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/backtest/page.tsx":{"id":4374,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chart-analyst/page.tsx":{"id":6543,"name":"*","chunks":["651","static/chunks/651-5689242ae9b0ffc6.js","75","static/chunks/75-8c48549bc3f12b00.js","441","static/chunks/app/chart-analyst/page-422122938e79d615.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chat/page.tsx":{"id":841,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chatbot/page.tsx":{"id":8145,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/learning/page.tsx":{"id":6056,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/methodology/page.tsx":{"id":7413,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/ipo-radar/page.tsx":{"id":9135,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/market-brain/page.tsx":{"id":2987,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page.tsx":{"id":892,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/dashboard/page.tsx":{"id":7096,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","96","static/chunks/96-ce8c57cd15d50941.js","931","static/chunks/app/page-d0db9a93fb4af9a5.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/etf-radar/page.tsx":{"id":9239,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/performance/page.tsx":{"id":8547,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/signal-lab/page.tsx":{"id":2010,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/sniper/page.tsx":{"id":7768,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/stock-radar/page.tsx":{"id":9570,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/assets/[ticker]/view.tsx":{"id":3713,"name":"*","chunks":[],"async":false}},"entryCSSFiles":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout":["static/css/02bd12e03544ea91.css"],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/page":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chart-analyst/page":[]}}
\ No newline at end of file
diff --git a/frontend/.next/server/app/chat.html b/frontend/.next/server/app/chat.html
new file mode 100644
index 0000000000000000000000000000000000000000..b52910feab2cb7ba466496431bb53310f373efb8
--- /dev/null
+++ b/frontend/.next/server/app/chat.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence BLUM ChatFinancial intelligence conversation.
Multilingual market assistant connected to Blum signals, narratives, technical analysis, fundamentals, memory, backtests and evidence controls.
ModeRAG analystLanguageautoRiskbalancedEvidence0 news B
\ No newline at end of file
diff --git a/frontend/.next/server/app/chat.meta b/frontend/.next/server/app/chat.meta
new file mode 100644
index 0000000000000000000000000000000000000000..d76e0e4f84014be7e0d4099bb5ae43d561980e42
--- /dev/null
+++ b/frontend/.next/server/app/chat.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/chat/layout,_N_T_/chat/page,_N_T_/chat/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/chat.rsc b/frontend/.next/server/app/chat.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..e349837bf8181cef0c4e8eb7a32c21920af7664b
--- /dev/null
+++ b/frontend/.next/server/app/chat.rsc
@@ -0,0 +1,8 @@
+2:I[7523,[],"ClientPageRoot"]
+3:I[841,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","145","static/chunks/145-04bdfe555d73caf0.js","929","static/chunks/app/chat/page-01bb723eea532598.js"],"default",1]
+4:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["chat",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["chat",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","chat","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/chat/page.js b/frontend/.next/server/app/chat/page.js
new file mode 100644
index 0000000000000000000000000000000000000000..6a3d4285f8af93fe17567cf324460646e80a419d
--- /dev/null
+++ b/frontend/.next/server/app/chat/page.js
@@ -0,0 +1 @@
+(()=>{var e={};e.id=929,e.ids=[929],e.modules={2934:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external.js")},4580:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external.js")},5869:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},399:e=>{"use strict";e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},9228:(e,t,r)=>{"use strict";r.r(t),r.d(t,{GlobalError:()=>o.a,__next_app__:()=>c,originalPathname:()=>d,pages:()=>u,routeModule:()=>m,tree:()=>l}),r(9992),r(8777),r(311);var n=r(9296),a=r(1650),s=r(7045),o=r.n(s),i=r(8184),p={};for(let e in i)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(p[e]=()=>i[e]);r.d(t,p);let l=["",{children:["chat",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(r.bind(r,9992)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chat/page.tsx"]}]},{}]},{layout:[()=>Promise.resolve().then(r.bind(r,8777)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout.tsx"],"not-found":[()=>Promise.resolve().then(r.t.bind(r,311,23)),"next/dist/client/components/not-found-error"]}],u=["/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chat/page.tsx"],d="/chat/page",c={require:r,loadChunk:()=>Promise.resolve()},m=new n.AppPageRouteModule({definition:{kind:a.x.APP_PAGE,page:"/chat/page",pathname:"/chat",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:l}})},4377:(e,t,r)=>{Promise.resolve().then(r.bind(r,9737))},9737:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>n});let n=r(8377).default},9992:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>n});let n=(0,r(6691).createProxy)(String.raw`/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chat/page.tsx#default`)}};var t=require("../../webpack-runtime.js");t.C(e);var r=e=>t(t.s=e),n=t.X(0,[273,394,927,377],()=>r(9228));module.exports=n})();
\ No newline at end of file
diff --git a/frontend/.next/server/app/chat/page.js.nft.json b/frontend/.next/server/app/chat/page.js.nft.json
new file mode 100644
index 0000000000000000000000000000000000000000..3dc9c67f58e44ff0b598c6958e6b2498f5d22c18
--- /dev/null
+++ b/frontend/.next/server/app/chat/page.js.nft.json
@@ -0,0 +1 @@
+{"version":1,"files":["../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/package.json","../../../../node_modules/next","../../../../package.json","../../../package.json","../../chunks/273.js","../../chunks/377.js","../../chunks/394.js","../../chunks/927.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}
\ No newline at end of file
diff --git a/frontend/.next/server/app/chat/page_client-reference-manifest.js b/frontend/.next/server/app/chat/page_client-reference-manifest.js
new file mode 100644
index 0000000000000000000000000000000000000000..191f930e9009f8da63088637c7d50b4e345b2485
--- /dev/null
+++ b/frontend/.next/server/app/chat/page_client-reference-manifest.js
@@ -0,0 +1 @@
+globalThis.__RSC_MANIFEST=(globalThis.__RSC_MANIFEST||{});globalThis.__RSC_MANIFEST["/chat/page"]={"moduleLoading":{"prefix":"/_next/","crossOrigin":null},"ssrModuleMapping":{"176":{"*":{"id":"6676","name":"*","chunks":[],"async":false}},"841":{"*":{"id":"9737","name":"*","chunks":[],"async":false}},"892":{"*":{"id":"5213","name":"*","chunks":[],"async":false}},"2010":{"*":{"id":"7619","name":"*","chunks":[],"async":false}},"2433":{"*":{"id":"6544","name":"*","chunks":[],"async":false}},"2651":{"*":{"id":"9645","name":"*","chunks":[],"async":false}},"2987":{"*":{"id":"1358","name":"*","chunks":[],"async":false}},"3713":{"*":{"id":"5210","name":"*","chunks":[],"async":false}},"4374":{"*":{"id":"9927","name":"*","chunks":[],"async":false}},"6056":{"*":{"id":"1309","name":"*","chunks":[],"async":false}},"6543":{"*":{"id":"9722","name":"*","chunks":[],"async":false}},"6813":{"*":{"id":"5877","name":"*","chunks":[],"async":false}},"7096":{"*":{"id":"1952","name":"*","chunks":[],"async":false}},"7413":{"*":{"id":"8052","name":"*","chunks":[],"async":false}},"7523":{"*":{"id":"3477","name":"*","chunks":[],"async":false}},"7768":{"*":{"id":"7663","name":"*","chunks":[],"async":false}},"8145":{"*":{"id":"8377","name":"*","chunks":[],"async":false}},"8528":{"*":{"id":"5116","name":"*","chunks":[],"async":false}},"8547":{"*":{"id":"5441","name":"*","chunks":[],"async":false}},"9135":{"*":{"id":"432","name":"*","chunks":[],"async":false}},"9239":{"*":{"id":"8132","name":"*","chunks":[],"async":false}},"9414":{"*":{"id":"8850","name":"*","chunks":[],"async":false}},"9570":{"*":{"id":"291","name":"*","chunks":[],"async":false}}},"edgeSSRModuleMapping":{},"clientModules":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/globals.css":{"id":4443,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/components/AppShell.tsx":{"id":6813,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/backtest/page.tsx":{"id":4374,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chart-analyst/page.tsx":{"id":6543,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chat/page.tsx":{"id":841,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","145","static/chunks/145-04bdfe555d73caf0.js","929","static/chunks/app/chat/page-01bb723eea532598.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chatbot/page.tsx":{"id":8145,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/learning/page.tsx":{"id":6056,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/methodology/page.tsx":{"id":7413,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/ipo-radar/page.tsx":{"id":9135,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/market-brain/page.tsx":{"id":2987,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page.tsx":{"id":892,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/dashboard/page.tsx":{"id":7096,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","96","static/chunks/96-ce8c57cd15d50941.js","931","static/chunks/app/page-d0db9a93fb4af9a5.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/etf-radar/page.tsx":{"id":9239,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/performance/page.tsx":{"id":8547,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/signal-lab/page.tsx":{"id":2010,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/sniper/page.tsx":{"id":7768,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/stock-radar/page.tsx":{"id":9570,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/assets/[ticker]/view.tsx":{"id":3713,"name":"*","chunks":[],"async":false}},"entryCSSFiles":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout":["static/css/02bd12e03544ea91.css"],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/page":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chat/page":[]}}
\ No newline at end of file
diff --git a/frontend/.next/server/app/chatbot.html b/frontend/.next/server/app/chatbot.html
new file mode 100644
index 0000000000000000000000000000000000000000..f110f79e98b62e961acc2a2fe809a87ef33f998c
--- /dev/null
+++ b/frontend/.next/server/app/chatbot.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence BLUM ChatFinancial intelligence conversation.
Multilingual market assistant connected to Blum signals, narratives, technical analysis, fundamentals, memory, backtests and evidence controls.
ModeRAG analystLanguageautoRiskbalancedEvidence0 news B
\ No newline at end of file
diff --git a/frontend/.next/server/app/chatbot.meta b/frontend/.next/server/app/chatbot.meta
new file mode 100644
index 0000000000000000000000000000000000000000..5cb6571e01fbd54e2fe736ec91dba6e1626994b2
--- /dev/null
+++ b/frontend/.next/server/app/chatbot.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/chatbot/layout,_N_T_/chatbot/page,_N_T_/chatbot/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/chatbot.rsc b/frontend/.next/server/app/chatbot.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..9bd5e5175737cb942baafae90720e0515f79a29e
--- /dev/null
+++ b/frontend/.next/server/app/chatbot.rsc
@@ -0,0 +1,8 @@
+2:I[7523,[],"ClientPageRoot"]
+3:I[8145,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","145","static/chunks/145-04bdfe555d73caf0.js","278","static/chunks/app/chatbot/page-ec86bf53c052af5b.js"],"default",1]
+4:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["chatbot",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["chatbot",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","chatbot","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/chatbot/page.js b/frontend/.next/server/app/chatbot/page.js
new file mode 100644
index 0000000000000000000000000000000000000000..0cb6f3661778bafb7213835630f24b820f81bf8a
--- /dev/null
+++ b/frontend/.next/server/app/chatbot/page.js
@@ -0,0 +1 @@
+(()=>{var e={};e.id=278,e.ids=[278],e.modules={2934:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external.js")},4580:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external.js")},5869:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},399:e=>{"use strict";e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},5674:(e,t,r)=>{"use strict";r.r(t),r.d(t,{GlobalError:()=>s.a,__next_app__:()=>d,originalPathname:()=>c,pages:()=>u,routeModule:()=>m,tree:()=>l}),r(8289),r(8777),r(311);var n=r(9296),o=r(1650),a=r(7045),s=r.n(a),i=r(8184),p={};for(let e in i)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(p[e]=()=>i[e]);r.d(t,p);let l=["",{children:["chatbot",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(r.bind(r,8289)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chatbot/page.tsx"]}]},{}]},{layout:[()=>Promise.resolve().then(r.bind(r,8777)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout.tsx"],"not-found":[()=>Promise.resolve().then(r.t.bind(r,311,23)),"next/dist/client/components/not-found-error"]}],u=["/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chatbot/page.tsx"],c="/chatbot/page",d={require:r,loadChunk:()=>Promise.resolve()},m=new n.AppPageRouteModule({definition:{kind:o.x.APP_PAGE,page:"/chatbot/page",pathname:"/chatbot",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:l}})},5450:(e,t,r)=>{Promise.resolve().then(r.bind(r,8377))},8289:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>n});let n=(0,r(6691).createProxy)(String.raw`/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chatbot/page.tsx#default`)}};var t=require("../../webpack-runtime.js");t.C(e);var r=e=>t(t.s=e),n=t.X(0,[273,394,927,377],()=>r(5674));module.exports=n})();
\ No newline at end of file
diff --git a/frontend/.next/server/app/chatbot/page.js.nft.json b/frontend/.next/server/app/chatbot/page.js.nft.json
new file mode 100644
index 0000000000000000000000000000000000000000..3dc9c67f58e44ff0b598c6958e6b2498f5d22c18
--- /dev/null
+++ b/frontend/.next/server/app/chatbot/page.js.nft.json
@@ -0,0 +1 @@
+{"version":1,"files":["../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/package.json","../../../../node_modules/next","../../../../package.json","../../../package.json","../../chunks/273.js","../../chunks/377.js","../../chunks/394.js","../../chunks/927.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}
\ No newline at end of file
diff --git a/frontend/.next/server/app/chatbot/page_client-reference-manifest.js b/frontend/.next/server/app/chatbot/page_client-reference-manifest.js
new file mode 100644
index 0000000000000000000000000000000000000000..47d7b935125b4a1d269395263a73278de0204a25
--- /dev/null
+++ b/frontend/.next/server/app/chatbot/page_client-reference-manifest.js
@@ -0,0 +1 @@
+globalThis.__RSC_MANIFEST=(globalThis.__RSC_MANIFEST||{});globalThis.__RSC_MANIFEST["/chatbot/page"]={"moduleLoading":{"prefix":"/_next/","crossOrigin":null},"ssrModuleMapping":{"176":{"*":{"id":"6676","name":"*","chunks":[],"async":false}},"841":{"*":{"id":"9737","name":"*","chunks":[],"async":false}},"892":{"*":{"id":"5213","name":"*","chunks":[],"async":false}},"2010":{"*":{"id":"7619","name":"*","chunks":[],"async":false}},"2433":{"*":{"id":"6544","name":"*","chunks":[],"async":false}},"2651":{"*":{"id":"9645","name":"*","chunks":[],"async":false}},"2987":{"*":{"id":"1358","name":"*","chunks":[],"async":false}},"3713":{"*":{"id":"5210","name":"*","chunks":[],"async":false}},"4374":{"*":{"id":"9927","name":"*","chunks":[],"async":false}},"6056":{"*":{"id":"1309","name":"*","chunks":[],"async":false}},"6543":{"*":{"id":"9722","name":"*","chunks":[],"async":false}},"6813":{"*":{"id":"5877","name":"*","chunks":[],"async":false}},"7096":{"*":{"id":"1952","name":"*","chunks":[],"async":false}},"7413":{"*":{"id":"8052","name":"*","chunks":[],"async":false}},"7523":{"*":{"id":"3477","name":"*","chunks":[],"async":false}},"7768":{"*":{"id":"7663","name":"*","chunks":[],"async":false}},"8145":{"*":{"id":"8377","name":"*","chunks":[],"async":false}},"8528":{"*":{"id":"5116","name":"*","chunks":[],"async":false}},"8547":{"*":{"id":"5441","name":"*","chunks":[],"async":false}},"9135":{"*":{"id":"432","name":"*","chunks":[],"async":false}},"9239":{"*":{"id":"8132","name":"*","chunks":[],"async":false}},"9414":{"*":{"id":"8850","name":"*","chunks":[],"async":false}},"9570":{"*":{"id":"291","name":"*","chunks":[],"async":false}}},"edgeSSRModuleMapping":{},"clientModules":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/globals.css":{"id":4443,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/components/AppShell.tsx":{"id":6813,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/backtest/page.tsx":{"id":4374,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chart-analyst/page.tsx":{"id":6543,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chat/page.tsx":{"id":841,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chatbot/page.tsx":{"id":8145,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","145","static/chunks/145-04bdfe555d73caf0.js","278","static/chunks/app/chatbot/page-ec86bf53c052af5b.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/learning/page.tsx":{"id":6056,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/methodology/page.tsx":{"id":7413,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/ipo-radar/page.tsx":{"id":9135,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/market-brain/page.tsx":{"id":2987,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page.tsx":{"id":892,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/dashboard/page.tsx":{"id":7096,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","96","static/chunks/96-ce8c57cd15d50941.js","931","static/chunks/app/page-d0db9a93fb4af9a5.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/etf-radar/page.tsx":{"id":9239,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/performance/page.tsx":{"id":8547,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/signal-lab/page.tsx":{"id":2010,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/sniper/page.tsx":{"id":7768,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/stock-radar/page.tsx":{"id":9570,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/assets/[ticker]/view.tsx":{"id":3713,"name":"*","chunks":[],"async":false}},"entryCSSFiles":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout":["static/css/02bd12e03544ea91.css"],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/page":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chatbot/page":[]}}
\ No newline at end of file
diff --git a/frontend/.next/server/app/dashboard.html b/frontend/.next/server/app/dashboard.html
new file mode 100644
index 0000000000000000000000000000000000000000..c1e52e872d125c67a7dae97dfba990ff8f8ce88c
--- /dev/null
+++ b/frontend/.next/server/app/dashboard.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading Blum Command Center
\ No newline at end of file
diff --git a/frontend/.next/server/app/dashboard.meta b/frontend/.next/server/app/dashboard.meta
new file mode 100644
index 0000000000000000000000000000000000000000..130958b45199274c9c7c40c183b1985e1801328e
--- /dev/null
+++ b/frontend/.next/server/app/dashboard.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/dashboard/layout,_N_T_/dashboard/page,_N_T_/dashboard/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/dashboard.rsc b/frontend/.next/server/app/dashboard.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..10766036d18cbce5f0a0932b9a5e77c826fcccaf
--- /dev/null
+++ b/frontend/.next/server/app/dashboard.rsc
@@ -0,0 +1,8 @@
+2:I[7523,[],"ClientPageRoot"]
+3:I[7096,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","96","static/chunks/96-ce8c57cd15d50941.js","702","static/chunks/app/dashboard/page-d9577bde4b3301c9.js"],"default",1]
+4:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["dashboard",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["dashboard",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","dashboard","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/dashboard/page.js b/frontend/.next/server/app/dashboard/page.js
new file mode 100644
index 0000000000000000000000000000000000000000..691e87f59a50ee3d005a1fb0e68bbf18487173c0
--- /dev/null
+++ b/frontend/.next/server/app/dashboard/page.js
@@ -0,0 +1 @@
+(()=>{var e={};e.id=702,e.ids=[702],e.modules={2934:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external.js")},4580:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external.js")},5869:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},399:e=>{"use strict";e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},4815:(e,r,t)=>{"use strict";t.r(r),t.d(r,{GlobalError:()=>a.a,__next_app__:()=>c,originalPathname:()=>u,pages:()=>l,routeModule:()=>m,tree:()=>p}),t(8666),t(8777),t(311);var n=t(9296),o=t(1650),s=t(7045),a=t.n(s),i=t(8184),d={};for(let e in i)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(d[e]=()=>i[e]);t.d(r,d);let p=["",{children:["dashboard",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(t.bind(t,8666)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/dashboard/page.tsx"]}]},{}]},{layout:[()=>Promise.resolve().then(t.bind(t,8777)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout.tsx"],"not-found":[()=>Promise.resolve().then(t.t.bind(t,311,23)),"next/dist/client/components/not-found-error"]}],l=["/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/dashboard/page.tsx"],u="/dashboard/page",c={require:t,loadChunk:()=>Promise.resolve()},m=new n.AppPageRouteModule({definition:{kind:o.x.APP_PAGE,page:"/dashboard/page",pathname:"/dashboard",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:p}})},3229:(e,r,t)=>{Promise.resolve().then(t.bind(t,1952))}};var r=require("../../webpack-runtime.js");r.C(e);var t=e=>r(r.s=e),n=r.X(0,[273,394,927,965],()=>t(4815));module.exports=n})();
\ No newline at end of file
diff --git a/frontend/.next/server/app/dashboard/page.js.nft.json b/frontend/.next/server/app/dashboard/page.js.nft.json
new file mode 100644
index 0000000000000000000000000000000000000000..c8c43de61e1e0773716c663ba2455c7e52b2e463
--- /dev/null
+++ b/frontend/.next/server/app/dashboard/page.js.nft.json
@@ -0,0 +1 @@
+{"version":1,"files":["../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/package.json","../../../../node_modules/next","../../../../package.json","../../../package.json","../../chunks/273.js","../../chunks/394.js","../../chunks/927.js","../../chunks/965.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}
\ No newline at end of file
diff --git a/frontend/.next/server/app/dashboard/page_client-reference-manifest.js b/frontend/.next/server/app/dashboard/page_client-reference-manifest.js
new file mode 100644
index 0000000000000000000000000000000000000000..f1624b6363b4890a71aee4c5356510a55d0363d6
--- /dev/null
+++ b/frontend/.next/server/app/dashboard/page_client-reference-manifest.js
@@ -0,0 +1 @@
+globalThis.__RSC_MANIFEST=(globalThis.__RSC_MANIFEST||{});globalThis.__RSC_MANIFEST["/dashboard/page"]={"moduleLoading":{"prefix":"/_next/","crossOrigin":null},"ssrModuleMapping":{"176":{"*":{"id":"6676","name":"*","chunks":[],"async":false}},"841":{"*":{"id":"9737","name":"*","chunks":[],"async":false}},"892":{"*":{"id":"5213","name":"*","chunks":[],"async":false}},"2010":{"*":{"id":"7619","name":"*","chunks":[],"async":false}},"2433":{"*":{"id":"6544","name":"*","chunks":[],"async":false}},"2651":{"*":{"id":"9645","name":"*","chunks":[],"async":false}},"2987":{"*":{"id":"1358","name":"*","chunks":[],"async":false}},"3713":{"*":{"id":"5210","name":"*","chunks":[],"async":false}},"4374":{"*":{"id":"9927","name":"*","chunks":[],"async":false}},"6056":{"*":{"id":"1309","name":"*","chunks":[],"async":false}},"6543":{"*":{"id":"9722","name":"*","chunks":[],"async":false}},"6813":{"*":{"id":"5877","name":"*","chunks":[],"async":false}},"7096":{"*":{"id":"1952","name":"*","chunks":[],"async":false}},"7413":{"*":{"id":"8052","name":"*","chunks":[],"async":false}},"7523":{"*":{"id":"3477","name":"*","chunks":[],"async":false}},"7768":{"*":{"id":"7663","name":"*","chunks":[],"async":false}},"8145":{"*":{"id":"8377","name":"*","chunks":[],"async":false}},"8528":{"*":{"id":"5116","name":"*","chunks":[],"async":false}},"8547":{"*":{"id":"5441","name":"*","chunks":[],"async":false}},"9135":{"*":{"id":"432","name":"*","chunks":[],"async":false}},"9239":{"*":{"id":"8132","name":"*","chunks":[],"async":false}},"9414":{"*":{"id":"8850","name":"*","chunks":[],"async":false}},"9570":{"*":{"id":"291","name":"*","chunks":[],"async":false}}},"edgeSSRModuleMapping":{},"clientModules":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/globals.css":{"id":4443,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/components/AppShell.tsx":{"id":6813,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/backtest/page.tsx":{"id":4374,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chart-analyst/page.tsx":{"id":6543,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chat/page.tsx":{"id":841,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chatbot/page.tsx":{"id":8145,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/learning/page.tsx":{"id":6056,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/methodology/page.tsx":{"id":7413,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/ipo-radar/page.tsx":{"id":9135,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/market-brain/page.tsx":{"id":2987,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page.tsx":{"id":892,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/dashboard/page.tsx":{"id":7096,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","96","static/chunks/96-ce8c57cd15d50941.js","702","static/chunks/app/dashboard/page-d9577bde4b3301c9.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/etf-radar/page.tsx":{"id":9239,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/performance/page.tsx":{"id":8547,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/signal-lab/page.tsx":{"id":2010,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/sniper/page.tsx":{"id":7768,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/stock-radar/page.tsx":{"id":9570,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/assets/[ticker]/view.tsx":{"id":3713,"name":"*","chunks":[],"async":false}},"entryCSSFiles":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout":["static/css/02bd12e03544ea91.css"],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/page":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/dashboard/page":[]}}
\ No newline at end of file
diff --git a/frontend/.next/server/app/etf-radar.html b/frontend/.next/server/app/etf-radar.html
new file mode 100644
index 0000000000000000000000000000000000000000..2bf1df9cdcf326d11979a2639f57e34d316259f0
--- /dev/null
+++ b/frontend/.next/server/app/etf-radar.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading ETF radar
\ No newline at end of file
diff --git a/frontend/.next/server/app/etf-radar.meta b/frontend/.next/server/app/etf-radar.meta
new file mode 100644
index 0000000000000000000000000000000000000000..80c4cf8873d5fe3a4130ad0510b07bea5060ad40
--- /dev/null
+++ b/frontend/.next/server/app/etf-radar.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/etf-radar/layout,_N_T_/etf-radar/page,_N_T_/etf-radar/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/etf-radar.rsc b/frontend/.next/server/app/etf-radar.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..fe56cfcaad5bb8e367477b1b50ad208aa787a9cd
--- /dev/null
+++ b/frontend/.next/server/app/etf-radar.rsc
@@ -0,0 +1,8 @@
+2:I[7523,[],"ClientPageRoot"]
+3:I[9239,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","429","static/chunks/app/etf-radar/page-cb504f6343d399db.js"],"default",1]
+4:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["etf-radar",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["etf-radar",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","etf-radar","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/etf-radar/page.js b/frontend/.next/server/app/etf-radar/page.js
new file mode 100644
index 0000000000000000000000000000000000000000..36f00f3a669382aa343aabdb95795b4b6b5c362c
--- /dev/null
+++ b/frontend/.next/server/app/etf-radar/page.js
@@ -0,0 +1 @@
+(()=>{var e={};e.id=429,e.ids=[429],e.modules={2934:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external.js")},4580:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external.js")},5869:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},399:e=>{"use strict";e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},3803:(e,t,r)=>{"use strict";r.r(t),r.d(t,{GlobalError:()=>i.a,__next_app__:()=>m,originalPathname:()=>u,pages:()=>d,routeModule:()=>h,tree:()=>c}),r(7637),r(8777),r(311);var s=r(9296),n=r(1650),a=r(7045),i=r.n(a),l=r(8184),o={};for(let e in l)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(o[e]=()=>l[e]);r.d(t,o);let c=["",{children:["etf-radar",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(r.bind(r,7637)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/etf-radar/page.tsx"]}]},{}]},{layout:[()=>Promise.resolve().then(r.bind(r,8777)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout.tsx"],"not-found":[()=>Promise.resolve().then(r.t.bind(r,311,23)),"next/dist/client/components/not-found-error"]}],d=["/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/etf-radar/page.tsx"],u="/etf-radar/page",m={require:r,loadChunk:()=>Promise.resolve()},h=new s.AppPageRouteModule({definition:{kind:n.x.APP_PAGE,page:"/etf-radar/page",pathname:"/etf-radar",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:c}})},7098:(e,t,r)=>{Promise.resolve().then(r.bind(r,8132))},8132:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>c});var s=r(8924),n=r(3911);r(3789);var a=r(6927),i=r(2522),l=r(8117),o=r(7749);function c(){let[e,t]=(0,n.useState)(null),[r,c]=(0,n.useState)("");if(r)return(0,s.jsxs)("div",{className:"empty-state",children:["API error: ",r]});if(!e)return s.jsx(i.G,{label:"Loading ETF radar"});let d=e.length?e.reduce((e,t)=>e+Number(t.confirmation_score??0),0)/e.length:0;return(0,s.jsxs)(s.Fragment,{children:[s.jsx(a.ft,{eyebrow:"ETF Radar",title:"ETF rotation and sector confirmation.",subtitle:"ETF intelligence monitors thematic breadth, sector confirmation and rotation leaders behind stock-level signals.",statusItems:[{label:"ETF rows",value:String(e.length),tone:e.length?"positive":"attention"},{label:"Avg confirm",value:d.toFixed(1),tone:"attention"},{label:"Top ETF",value:e[0]?.ticker??"pending"},{label:"Mode",value:"Evidence only"}]}),!e.length&&(0,s.jsxs)("section",{className:"panel readiness-panel",style:{marginBottom:12},children:[(0,s.jsxs)("div",{className:"panel-head",children:[s.jsx("span",{children:"ETF readiness"}),s.jsx("strong",{children:"No ETF trends yet"})]}),s.jsx("p",{children:"ETF rotation appears after the real-data pipeline stores prices and signal context for ETF instruments. No synthetic ETF confirmation scores are displayed."})]}),(0,s.jsxs)("section",{className:"terminal-command-grid",children:[s.jsx(a.i9,{label:"ETF Count",value:e.length,subvalue:"Rotation universe"}),s.jsx(a.i9,{label:"Average Confirmation",value:d.toFixed(1),subvalue:"ETF trend support",tone:"attention"}),s.jsx(a.i9,{label:"Top Momentum",value:e[0]?.momentum_score??"n/a",subvalue:e[0]?.ticker??"pending"}),s.jsx(a.i9,{label:"Top Theme",value:e[0]?.thematic_score??"n/a",subvalue:e[0]?.category??"category pending"})]}),s.jsx("section",{className:"grid-3",style:{marginBottom:12},children:e.slice(0,6).map(e=>(0,s.jsxs)("article",{className:"score-card",children:[(0,s.jsxs)("div",{className:"score-card-top",children:[(0,s.jsxs)("div",{children:[(0,s.jsxs)("span",{children:["ETF | ",e.asset?.sector??e.category]}),s.jsx("h3",{children:e.ticker}),s.jsx("p",{className:"asset-subtitle",children:e.asset?.name??e.category})]}),s.jsx("div",{className:"score-ring",style:{"--score":e.confirmation_score},children:s.jsx("strong",{children:Math.round(e.confirmation_score)})})]}),s.jsx(l.Ku,{snapshot:e.market_snapshot,compact:!0}),(0,s.jsxs)("div",{className:"mini-metrics",children:[(0,s.jsxs)("div",{children:[s.jsx("span",{children:"Category"}),s.jsx("strong",{children:e.category})]}),(0,s.jsxs)("div",{children:[s.jsx("span",{children:"Exchange"}),s.jsx("strong",{children:e.asset?.exchange??"n/a"})]}),(0,s.jsxs)("div",{children:[s.jsx("span",{children:"Momentum"}),s.jsx("strong",{children:e.momentum_score})]}),(0,s.jsxs)("div",{children:[s.jsx("span",{children:"Theme"}),s.jsx("strong",{children:e.thematic_score})]})]})]},`etf-card-${e.ticker}-${e.created_at}`))}),(0,s.jsxs)("section",{className:"grid-2",children:[s.jsx(o.G,{title:"ETF Confirmation Ranking",data:[{x:e.map(e=>e.confirmation_score),y:e.map(e=>e.ticker),type:"bar",orientation:"h",marker:{color:"#20e070"}}],layout:{xaxis:{range:[0,100]}},emptyMessage:"ETF confirmation ranking appears after ETF trend snapshots are available."}),s.jsx(o.G,{title:"Momentum vs Theme",data:[{x:e.map(e=>e.momentum_score),y:e.map(e=>e.thematic_score),text:e.map(e=>e.ticker),type:"scatter",mode:"markers+text",marker:{size:13,color:"#ffb000"}}],emptyMessage:"Momentum/theme scatter requires real ETF trend rows."})]}),s.jsx(a.Ez,{title:"ETF Rotation Leaders",value:`${e.length} ETFs`,subtitle:"Confirmation layer for sector and thematic narratives",className:"radar-core-panel",children:e.length?s.jsx("div",{className:"table-shell",children:(0,s.jsxs)("table",{className:"intel-table",children:[s.jsx("thead",{children:(0,s.jsxs)("tr",{children:[s.jsx("th",{children:"ETF"}),s.jsx("th",{children:"Price"}),s.jsx("th",{children:"Category"}),s.jsx("th",{children:"Momentum"}),s.jsx("th",{children:"Theme"}),s.jsx("th",{children:"Confirmation"}),s.jsx("th",{children:"Read-through"})]})}),s.jsx("tbody",{children:e.map(e=>(0,s.jsxs)("tr",{children:[(0,s.jsxs)("td",{children:[s.jsx("span",{className:"asset-link",children:e.ticker}),s.jsx("span",{children:e.asset?.name??"ETF metadata pending"}),(0,s.jsxs)("span",{children:[e.asset?.exchange??"Exchange n/a"," | ",e.asset?.country??"Country n/a"]})]}),(0,s.jsxs)("td",{children:[s.jsx("strong",{children:(0,l.T4)(e.market_snapshot?.price,e.market_snapshot?.currency)}),(0,s.jsxs)("span",{children:[e.market_snapshot?.date??"date n/a"," | ",e.market_snapshot?.provider??"provider n/a"]})]}),s.jsx("td",{children:e.category}),s.jsx("td",{children:e.momentum_score}),s.jsx("td",{children:e.thematic_score}),s.jsx("td",{children:s.jsx("strong",{className:"score-number",children:e.confirmation_score})}),s.jsx("td",{children:e.details?.classification??"ETF trend confirmation"})]},`${e.ticker}-${e.created_at}`))})]})}):s.jsx("div",{className:"empty-state",children:"No ETF trend rows are available yet. The autonomous engine is building ETF rotation evidence in the background."})})]})}},2522:(e,t,r)=>{"use strict";r.d(t,{G:()=>n});var s=r(8924);function n({label:e="Loading intelligence snapshot"}){return(0,s.jsxs)("div",{className:"loading-state",children:[s.jsx("div",{}),s.jsx("span",{children:e})]})}},8117:(e,t,r)=>{"use strict";r.d(t,{Ku:()=>n,T3:()=>i,T4:()=>a,fP:()=>l});var s=r(8924);function n({snapshot:e,compact:t=!1}){return e&&"ready"===e.data_status&&null!=e.price?(0,s.jsxs)("div",{className:t?"market-strip compact":"market-strip",children:[(0,s.jsxs)("div",{children:[s.jsx("span",{children:"Last Price"}),s.jsx("strong",{children:a(e.price,e.currency)})]}),(0,s.jsxs)("div",{children:[s.jsx("span",{children:"1D"}),s.jsx("strong",{className:o(e.perf_1d),children:i(e.perf_1d)})]}),!t&&(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)("div",{children:[s.jsx("span",{children:"5D"}),s.jsx("strong",{className:o(e.perf_5d),children:i(e.perf_5d)})]}),(0,s.jsxs)("div",{children:[s.jsx("span",{children:"1M"}),s.jsx("strong",{className:o(e.perf_1m),children:i(e.perf_1m)})]})]}),(0,s.jsxs)("div",{children:[s.jsx("span",{children:e.provider??"Provider"}),s.jsx("strong",{children:e.date??"n/a"})]})]}):(0,s.jsxs)("div",{className:t?"market-strip compact":"market-strip",children:[(0,s.jsxs)("div",{children:[s.jsx("span",{children:"Price"}),s.jsx("strong",{children:"Real price pending"})]}),(0,s.jsxs)("div",{children:[s.jsx("span",{children:"Provider"}),s.jsx("strong",{children:"n/a"})]})]})}function a(e,t="USD"){return null==e||Number.isNaN(Number(e))?"n/a":new Intl.NumberFormat("en",{style:"currency",currency:t||"USD",maximumFractionDigits:e>=100?2:4}).format(Number(e))}function i(e){return null==e||Number.isNaN(Number(e))?"n/a":`${e>0?"+":""}${Number(e).toFixed(2)}%`}function l(e){return null==e||Number.isNaN(Number(e))?"n/a":new Intl.NumberFormat("en",{notation:"compact",maximumFractionDigits:2}).format(Number(e))}function o(e){return null==e?"":e>0?"positive-text":e<0?"negative-text":""}},7749:(e,t,r)=>{"use strict";r.d(t,{G:()=>o});var s=r(8924),n=r(1328),a=r.n(n),i=r(3911);let l=a()(async()=>{},{loadableGenerated:{modules:["components/PlotPanel.tsx -> react-plotly.js"]},ssr:!1});function o({title:e,data:t,layout:r={},height:n=360,emptyMessage:a="Waiting for real data series."}){let o=t.some(e=>[e?.x,e?.y,e?.z,e?.values,e?.labels].filter(Array.isArray).some(e=>!!e.length&&(!Array.isArray(e[0])||e.some(e=>Array.isArray(e)&&e.length>0)))),c={data:t,layout:{autosize:!0,height:n,paper_bgcolor:"#07090d",plot_bgcolor:"#090d13",font:{color:"#e7edf6",family:"Inter, system-ui, sans-serif"},margin:{l:42,r:18,t:18,b:36},xaxis:{gridcolor:"rgba(255,255,255,.06)",zeroline:!1},yaxis:{gridcolor:"rgba(255,255,255,.06)",zeroline:!1},...r},config:{displayModeBar:!1,responsive:!0},useResizeHandler:!0,style:{width:"100%"}};return(0,s.jsxs)("section",{className:"panel",children:[s.jsx("div",{className:"panel-head",children:s.jsx("span",{children:e})}),o?(0,i.createElement)(l,c):s.jsx("div",{className:"plot-empty",children:a})]})}},1328:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return a}});let s=r(1607);r(8924),r(3911);let n=s._(r(4737));function a(e,t){var r;let s={loading:e=>{let{error:t,isLoading:r,pastDelay:s}=e;return null}};"function"==typeof e&&(s.loader=e);let a={...s,...t};return(0,n.default)({...a,modules:null==(r=a.loadableGenerated)?void 0:r.modules})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},3880:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"BailoutToCSR",{enumerable:!0,get:function(){return n}});let s=r(6483);function n(e){let{reason:t,children:r}=e;throw new s.BailoutToCSRError(t)}},4737:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return c}});let s=r(8924),n=r(3911),a=r(3880),i=r(7083);function l(e){return{default:e&&"default"in e?e.default:e}}let o={loader:()=>Promise.resolve(l(()=>null)),loading:null,ssr:!0},c=function(e){let t={...o,...e},r=(0,n.lazy)(()=>t.loader().then(l)),c=t.loading;function d(e){let l=c?(0,s.jsx)(c,{isLoading:!0,pastDelay:!0,error:null}):null,o=t.ssr?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i.PreloadCss,{moduleIds:t.modules}),(0,s.jsx)(r,{...e})]}):(0,s.jsx)(a.BailoutToCSR,{reason:"next/dynamic",children:(0,s.jsx)(r,{...e})});return(0,s.jsx)(n.Suspense,{fallback:l,children:o})}return d.displayName="LoadableComponent",d}},7083:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"PreloadCss",{enumerable:!0,get:function(){return a}});let s=r(8924),n=r(4580);function a(e){let{moduleIds:t}=e,r=(0,n.getExpectedRequestStore)("next/dynamic css"),a=[];if(r.reactLoadableManifest&&t){let e=r.reactLoadableManifest;for(let r of t){if(!e[r])continue;let t=e[r].files.filter(e=>e.endsWith(".css"));a.push(...t)}}return 0===a.length?null:(0,s.jsx)(s.Fragment,{children:a.map(e=>(0,s.jsx)("link",{precedence:"dynamic",rel:"stylesheet",href:r.assetPrefix+"/_next/"+encodeURI(e),as:"style"},e))})}},7637:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>s});let s=(0,r(6691).createProxy)(String.raw`/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/etf-radar/page.tsx#default`)}};var t=require("../../webpack-runtime.js");t.C(e);var r=e=>t(t.s=e),s=t.X(0,[273,394,927],()=>r(3803));module.exports=s})();
\ No newline at end of file
diff --git a/frontend/.next/server/app/etf-radar/page.js.nft.json b/frontend/.next/server/app/etf-radar/page.js.nft.json
new file mode 100644
index 0000000000000000000000000000000000000000..77578a3c1517e5a73d13826b0254aea2983bdd03
--- /dev/null
+++ b/frontend/.next/server/app/etf-radar/page.js.nft.json
@@ -0,0 +1 @@
+{"version":1,"files":["../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/package.json","../../../../node_modules/next","../../../../package.json","../../../package.json","../../chunks/273.js","../../chunks/394.js","../../chunks/927.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}
\ No newline at end of file
diff --git a/frontend/.next/server/app/etf-radar/page_client-reference-manifest.js b/frontend/.next/server/app/etf-radar/page_client-reference-manifest.js
new file mode 100644
index 0000000000000000000000000000000000000000..6a17e6b6d7d8d24df367fff8a027bb012a18a664
--- /dev/null
+++ b/frontend/.next/server/app/etf-radar/page_client-reference-manifest.js
@@ -0,0 +1 @@
+globalThis.__RSC_MANIFEST=(globalThis.__RSC_MANIFEST||{});globalThis.__RSC_MANIFEST["/etf-radar/page"]={"moduleLoading":{"prefix":"/_next/","crossOrigin":null},"ssrModuleMapping":{"176":{"*":{"id":"6676","name":"*","chunks":[],"async":false}},"841":{"*":{"id":"9737","name":"*","chunks":[],"async":false}},"892":{"*":{"id":"5213","name":"*","chunks":[],"async":false}},"2010":{"*":{"id":"7619","name":"*","chunks":[],"async":false}},"2433":{"*":{"id":"6544","name":"*","chunks":[],"async":false}},"2651":{"*":{"id":"9645","name":"*","chunks":[],"async":false}},"2987":{"*":{"id":"1358","name":"*","chunks":[],"async":false}},"3713":{"*":{"id":"5210","name":"*","chunks":[],"async":false}},"4374":{"*":{"id":"9927","name":"*","chunks":[],"async":false}},"6056":{"*":{"id":"1309","name":"*","chunks":[],"async":false}},"6543":{"*":{"id":"9722","name":"*","chunks":[],"async":false}},"6813":{"*":{"id":"5877","name":"*","chunks":[],"async":false}},"7096":{"*":{"id":"1952","name":"*","chunks":[],"async":false}},"7413":{"*":{"id":"8052","name":"*","chunks":[],"async":false}},"7523":{"*":{"id":"3477","name":"*","chunks":[],"async":false}},"7768":{"*":{"id":"7663","name":"*","chunks":[],"async":false}},"8145":{"*":{"id":"8377","name":"*","chunks":[],"async":false}},"8528":{"*":{"id":"5116","name":"*","chunks":[],"async":false}},"8547":{"*":{"id":"5441","name":"*","chunks":[],"async":false}},"9135":{"*":{"id":"432","name":"*","chunks":[],"async":false}},"9239":{"*":{"id":"8132","name":"*","chunks":[],"async":false}},"9414":{"*":{"id":"8850","name":"*","chunks":[],"async":false}},"9570":{"*":{"id":"291","name":"*","chunks":[],"async":false}}},"edgeSSRModuleMapping":{},"clientModules":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/globals.css":{"id":4443,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/components/AppShell.tsx":{"id":6813,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/backtest/page.tsx":{"id":4374,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chart-analyst/page.tsx":{"id":6543,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chat/page.tsx":{"id":841,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chatbot/page.tsx":{"id":8145,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/learning/page.tsx":{"id":6056,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/methodology/page.tsx":{"id":7413,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/ipo-radar/page.tsx":{"id":9135,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/market-brain/page.tsx":{"id":2987,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page.tsx":{"id":892,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/dashboard/page.tsx":{"id":7096,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","96","static/chunks/96-ce8c57cd15d50941.js","931","static/chunks/app/page-d0db9a93fb4af9a5.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/etf-radar/page.tsx":{"id":9239,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","429","static/chunks/app/etf-radar/page-cb504f6343d399db.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/performance/page.tsx":{"id":8547,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/signal-lab/page.tsx":{"id":2010,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/sniper/page.tsx":{"id":7768,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/stock-radar/page.tsx":{"id":9570,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/assets/[ticker]/view.tsx":{"id":3713,"name":"*","chunks":[],"async":false}},"entryCSSFiles":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout":["static/css/02bd12e03544ea91.css"],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/page":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/etf-radar/page":[]}}
\ No newline at end of file
diff --git a/frontend/.next/server/app/index.html b/frontend/.next/server/app/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..553eae5da026e8b836e89489cb731b0e2d9dcee7
--- /dev/null
+++ b/frontend/.next/server/app/index.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading Blum Command Center
\ No newline at end of file
diff --git a/frontend/.next/server/app/index.meta b/frontend/.next/server/app/index.meta
new file mode 100644
index 0000000000000000000000000000000000000000..4bb667622e0bb5eb9b84b2e0ad9938bdcbdb15a6
--- /dev/null
+++ b/frontend/.next/server/app/index.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/page,_N_T_/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/index.rsc b/frontend/.next/server/app/index.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..1aa749c48e8521e43e3e5713f11da70d5ae249a1
--- /dev/null
+++ b/frontend/.next/server/app/index.rsc
@@ -0,0 +1,8 @@
+2:I[7523,[],"ClientPageRoot"]
+3:I[7096,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","96","static/chunks/96-ce8c57cd15d50941.js","931","static/chunks/app/page-d0db9a93fb4af9a5.js"],"default",1]
+4:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+5:I[176,[],""]
+6:I[9414,[],""]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L4",null,{"children":["$","$L5",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L6",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/ipo-radar.html b/frontend/.next/server/app/ipo-radar.html
new file mode 100644
index 0000000000000000000000000000000000000000..9ef7da8230ee94f2586d6e959efd80f49a5c70a1
--- /dev/null
+++ b/frontend/.next/server/app/ipo-radar.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading IPO Radar
\ No newline at end of file
diff --git a/frontend/.next/server/app/ipo-radar.meta b/frontend/.next/server/app/ipo-radar.meta
new file mode 100644
index 0000000000000000000000000000000000000000..4275fea4b39cdddfdf2255ecf96c240132e92817
--- /dev/null
+++ b/frontend/.next/server/app/ipo-radar.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/ipo-radar/layout,_N_T_/ipo-radar/page,_N_T_/ipo-radar/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/ipo-radar.rsc b/frontend/.next/server/app/ipo-radar.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..64d55cd877e80df6a25af87505737e5dbdedd1ce
--- /dev/null
+++ b/frontend/.next/server/app/ipo-radar.rsc
@@ -0,0 +1,8 @@
+2:I[7523,[],"ClientPageRoot"]
+3:I[9135,["651","static/chunks/651-5689242ae9b0ffc6.js","405","static/chunks/app/ipo-radar/page-37bfbd97573d6050.js"],"default",1]
+4:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["ipo-radar",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["ipo-radar",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","ipo-radar","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/ipo-radar/page.js b/frontend/.next/server/app/ipo-radar/page.js
new file mode 100644
index 0000000000000000000000000000000000000000..0123451b2da49fc353d8d34b947cc892d5e421f0
--- /dev/null
+++ b/frontend/.next/server/app/ipo-radar/page.js
@@ -0,0 +1 @@
+(()=>{var e={};e.id=405,e.ids=[405],e.modules={2934:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external.js")},4580:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external.js")},5869:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},399:e=>{"use strict";e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},3307:(e,s,n)=>{"use strict";n.r(s),n.d(s,{GlobalError:()=>t.a,__next_app__:()=>u,originalPathname:()=>p,pages:()=>d,routeModule:()=>h,tree:()=>c}),n(3272),n(8777),n(311);var r=n(9296),i=n(1650),a=n(7045),t=n.n(a),l=n(8184),o={};for(let e in l)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(o[e]=()=>l[e]);n.d(s,o);let c=["",{children:["ipo-radar",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(n.bind(n,3272)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/ipo-radar/page.tsx"]}]},{}]},{layout:[()=>Promise.resolve().then(n.bind(n,8777)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout.tsx"],"not-found":[()=>Promise.resolve().then(n.t.bind(n,311,23)),"next/dist/client/components/not-found-error"]}],d=["/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/ipo-radar/page.tsx"],p="/ipo-radar/page",u={require:n,loadChunk:()=>Promise.resolve()},h=new r.AppPageRouteModule({definition:{kind:i.x.APP_PAGE,page:"/ipo-radar/page",pathname:"/ipo-radar",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:c}})},7988:(e,s,n)=>{Promise.resolve().then(n.bind(n,432))},432:(e,s,n)=>{"use strict";n.r(s),n.d(s,{default:()=>d});var r=n(8924),i=n(3911),a=n(3789),t=n(2522),l=n(7749),o=n(3081);let c=[["highest_opportunity","Highest Opportunity"],["final_prospectus_watch","Final Prospectus"],["advanced_filing_watch","Advanced Filing"],["narrative_watch","Narrative Watch"],["early_filing_watch","Early Filing"]];function d(){let[e,s]=(0,i.useState)(null),[n,o]=(0,i.useState)("highest_opportunity"),[d,x]=(0,i.useState)(""),[j,g]=(0,i.useState)(""),[f,y]=(0,i.useState)(""),[_,v]=(0,i.useState)(""),[b,N]=(0,i.useState)(null),P=async()=>{v("");try{s(await a.h.ipoRadar(120))}catch(e){v(e.message)}},k=async(e,s)=>{if(e.company.cik){y(e.company.cik),v("");try{let n=await a.h.secSubmissions(e.company.cik,s);N(n),s&&await P()}catch(e){v(e.message)}finally{y("")}}},w=(0,i.useMemo)(()=>{let s=d.trim().toLowerCase();return(e?.sections?.[n]??e?.rows??[]).filter(e=>(!j||e.score.classification===j)&&(!s||`${e.company.name} ${e.company.cik??""} ${e.latest_filing?.form_type??""}`.toLowerCase().includes(s)))},[e,n,d,j]);if(_)return(0,r.jsxs)("div",{className:"empty-state",children:["API error: ",_]});if(!e)return r.jsx(t.G,{label:"Loading IPO Radar"});let S=Array.from(new Set(e.rows.map(e=>e.score.classification))).sort(),C=e.rows.slice(0,36);return(0,r.jsxs)(r.Fragment,{children:[r.jsx("div",{className:"page-header",children:(0,r.jsxs)("div",{children:[r.jsx("div",{className:"kicker",children:"IPO Radar"}),r.jsx("h1",{children:"SEC filing and pre-listing intelligence."}),r.jsx("p",{children:"Autonomous public filing surveillance for newly listed and pre-listing opportunities. No generated listing dates, valuations or tickers are displayed."})]})}),(0,r.jsxs)("section",{className:"grid-4",children:[r.jsx(h,{label:"Companies",value:e.summary.companies_observed}),r.jsx(h,{label:"Filings",value:e.summary.filings_observed}),r.jsx(h,{label:"Scored",value:e.summary.scored_companies}),r.jsx(h,{label:"Top Score",value:e.summary.top_opportunity_score.toFixed(1)})]}),!e.rows.length&&(0,r.jsxs)("section",{className:"panel readiness-panel",style:{marginTop:12},children:[(0,r.jsxs)("div",{className:"panel-head",children:[r.jsx("span",{children:"SEC readiness"}),r.jsx("strong",{children:"No IPO rows yet"})]}),r.jsx("p",{children:"IPO Radar only displays observed SEC filings and public pre-listing narratives. The autonomous engine keeps hydrating this table in the background."})]}),r.jsx("section",{className:"radar-tabs",style:{marginTop:12},children:c.map(([s,i])=>(0,r.jsxs)("button",{className:n===s?"active":"",onClick:()=>o(s),children:[i,r.jsx("span",{children:e.sections[s]?.length??0})]},s))}),(0,r.jsxs)("section",{className:"grid-2",style:{marginTop:12},children:[r.jsx(l.G,{title:"IPO Opportunity Score",data:[{x:C.map(e=>e.score.opportunity_score),y:C.map(e=>e.company.name.slice(0,32)),type:"bar",orientation:"h",marker:{color:"#ffb000"}}],layout:{xaxis:{range:[0,100]}},emptyMessage:"IPO opportunity scores appear after SEC filing rows are stored."}),r.jsx(l.G,{title:"Readiness vs Listing Probability",data:[{x:C.map(e=>e.score.readiness_score),y:C.map(e=>e.score.listing_probability_score),text:C.map(e=>e.company.name),type:"scatter",mode:"markers+text",marker:{size:C.map(e=>Math.max(9,e.score.opportunity_score/5)),color:"#4dd8ff"}}],layout:{xaxis:{range:[0,100],title:"Readiness"},yaxis:{range:[0,100],title:"Listing probability proxy"}},emptyMessage:"Readiness/listing probability requires scored SEC filing evidence."})]}),r.jsx("section",{className:"grid-3",style:{marginTop:12},children:w.slice(0,6).map(e=>r.jsx(p,{row:e,onLoadSec:s=>k(e,s),secBusy:f===e.company.cik},`${e.company.id}-${e.latest_filing?.accession_number??e.company.name}`))}),b&&(0,r.jsxs)("section",{className:"panel",style:{marginTop:12},children:[(0,r.jsxs)("div",{className:"panel-head",children:[r.jsx("span",{children:"SEC company submissions"}),r.jsx("strong",{children:b.name??b.cik})]}),(0,r.jsxs)("div",{className:"diagnostic-grid",children:[(0,r.jsxs)("div",{children:[r.jsx("span",{children:"Official filing history"}),(0,r.jsxs)("strong",{children:[b.filing_count," filings | ",b.ipo_related_filing_count," IPO-related"]}),(0,r.jsxs)("p",{children:[(b.tickers??[]).join(" | ")||"No public ticker in SEC payload"," | ",(b.exchanges??[]).join(" | ")||"No exchange in SEC payload"]})]}),(0,r.jsxs)("div",{children:[r.jsx("span",{children:"Persistence"}),(0,r.jsxs)("strong",{children:[b.persisted_new_ipo_filings??0," new filings stored"]}),r.jsx("p",{children:b.data_policy})]})]}),r.jsx("div",{className:"table-shell",style:{marginTop:12},children:(0,r.jsxs)("table",{className:"intel-table",children:[r.jsx("thead",{children:(0,r.jsxs)("tr",{children:[r.jsx("th",{children:"Form"}),r.jsx("th",{children:"Date"}),r.jsx("th",{children:"Description"}),r.jsx("th",{children:"Document"})]})}),r.jsx("tbody",{children:(b.ipo_related_filings??[]).slice(0,20).map(e=>(0,r.jsxs)("tr",{children:[r.jsx("td",{children:r.jsx("strong",{children:e.form_type})}),r.jsx("td",{children:r.jsx("span",{children:m(e.filing_date)})}),r.jsx("td",{children:r.jsx("span",{children:e.description??"n/a"})}),r.jsx("td",{children:e.url?r.jsx("a",{className:"asset-link",href:e.url,target:"_blank",rel:"noreferrer",children:"Open"}):r.jsx("span",{children:"n/a"})})]},e.accession_number))})]})})]}),(0,r.jsxs)("section",{className:"panel",style:{marginTop:12},children:[(0,r.jsxs)("div",{className:"panel-head",children:[r.jsx("span",{children:"IPO radar table"}),(0,r.jsxs)("strong",{children:[w.length," companies"]})]}),(0,r.jsxs)("div",{className:"control-row",children:[r.jsx("input",{className:"input",placeholder:"Search company, CIK, form",value:d,onChange:e=>x(e.target.value)}),(0,r.jsxs)("select",{className:"input",value:j,onChange:e=>g(e.target.value),children:[r.jsx("option",{value:"",children:"All classifications"}),S.map(e=>r.jsx("option",{children:e},e))]})]}),r.jsx(u,{rows:w})]}),(0,r.jsxs)("section",{className:"panel",style:{marginTop:12},children:[(0,r.jsxs)("div",{className:"panel-head",children:[r.jsx("span",{children:"Public pre-listing narratives"}),r.jsx("strong",{children:e.prelisting_narratives.length})]}),!e.prelisting_narratives.length&&r.jsx("div",{className:"empty-state",children:"No IPO/listing headlines are stored yet from the public news tape."}),r.jsx("div",{className:"news-list",children:e.prelisting_narratives.slice(0,12).map(e=>(0,r.jsxs)("a",{className:"news-item",href:e.url,target:"_blank",rel:"noreferrer",children:[r.jsx("strong",{children:e.title}),(0,r.jsxs)("span",{children:[e.source," | ",m(e.published_at)," | quality ",e.quality_score.toFixed(1)]})]},e.id))})]}),(0,r.jsxs)("section",{className:"panel",style:{marginTop:12},children:[(0,r.jsxs)("div",{className:"panel-head",children:[r.jsx("span",{children:"Source policy"}),r.jsx("strong",{children:e.data_mode})]}),r.jsx("p",{children:e.source_diagnostics.data_policy}),(0,r.jsxs)("p",{children:["Tracked forms: ",(e.source_diagnostics.forms_tracked??[]).join(" | ")]})]})]})}function p({row:e,onLoadSec:s,secBusy:n}){return(0,r.jsxs)("article",{className:"score-card ipo-card",children:[(0,r.jsxs)("div",{className:"score-card-top",children:[(0,r.jsxs)("div",{children:[(0,r.jsxs)("span",{children:[e.latest_filing?.form_type??"SEC filing"," | ",m(e.latest_filing?.filing_date??null)]}),r.jsx("h3",{children:e.company.name}),(0,r.jsxs)("p",{className:"asset-subtitle",children:["CIK ",e.company.cik??"n/a"," | ",e.company.sector]})]}),r.jsx("div",{className:"score-ring",style:{"--score":e.score.opportunity_score},children:r.jsx("strong",{children:Math.round(e.score.opportunity_score)})})]}),r.jsx(o.O,{label:e.score.classification}),r.jsx("p",{children:e.score.explanation}),(0,r.jsxs)("div",{className:"mini-metrics",children:[(0,r.jsxs)("div",{children:[r.jsx("span",{children:"Readiness"}),r.jsx("strong",{children:e.score.readiness_score.toFixed(0)})]}),(0,r.jsxs)("div",{children:[r.jsx("span",{children:"Listing proxy"}),r.jsx("strong",{children:e.score.listing_probability_score.toFixed(0)})]}),(0,r.jsxs)("div",{children:[r.jsx("span",{children:"Narrative"}),r.jsx("strong",{children:e.score.narrative_heat_score.toFixed(0)})]}),(0,r.jsxs)("div",{children:[r.jsx("span",{children:"Risk terms"}),r.jsx("strong",{children:e.score.valuation_risk_score.toFixed(0)})]})]}),(0,r.jsxs)("div",{className:"control-row",style:{marginTop:12,marginBottom:0},children:[e.latest_filing?.url&&r.jsx("a",{className:"button",href:e.latest_filing.url,target:"_blank",rel:"noreferrer",children:"Open SEC filing"}),e.company.cik&&r.jsx("button",{className:"button",onClick:()=>s(!1),disabled:n,children:n?"Loading SEC...":"SEC history"}),e.company.cik&&r.jsx("button",{className:"button",onClick:()=>s(!0),disabled:n,children:n?"Syncing...":"Sync filings"})]})]})}function u({rows:e}){return e.length?r.jsx("div",{className:"table-shell",children:(0,r.jsxs)("table",{className:"intel-table",children:[r.jsx("thead",{children:(0,r.jsxs)("tr",{children:[r.jsx("th",{children:"Company"}),r.jsx("th",{children:"Filing"}),r.jsx("th",{children:"Classification"}),r.jsx("th",{children:"Scores"}),r.jsx("th",{children:"Evidence"}),r.jsx("th",{children:"Reason"})]})}),r.jsx("tbody",{children:e.map(e=>(0,r.jsxs)("tr",{children:[(0,r.jsxs)("td",{children:[r.jsx("strong",{children:e.company.name}),(0,r.jsxs)("span",{children:["CIK ",e.company.cik??"n/a"," | ",e.company.sector," | ",e.company.country]})]}),(0,r.jsxs)("td",{children:[e.latest_filing?.url?r.jsx("a",{className:"asset-link",href:e.latest_filing.url,target:"_blank",rel:"noreferrer",children:e.latest_filing.form_type}):r.jsx("strong",{children:"n/a"}),r.jsx("span",{children:m(e.latest_filing?.filing_date??null)}),r.jsx("span",{children:e.latest_filing?.accession_number??"accession n/a"})]}),(0,r.jsxs)("td",{children:[r.jsx(o.O,{label:e.score.classification}),r.jsx("span",{children:e.score.time_horizon})]}),(0,r.jsxs)("td",{children:[r.jsx("strong",{className:"score-number",children:e.score.opportunity_score.toFixed(1)}),(0,r.jsxs)("span",{children:["Ready ",e.score.readiness_score.toFixed(0)," | Prob ",e.score.listing_probability_score.toFixed(0)]}),(0,r.jsxs)("span",{children:["Narr ",e.score.narrative_heat_score.toFixed(0)," | Quality ",e.score.quality_score.toFixed(0)," | Risk ",e.score.valuation_risk_score.toFixed(0)]})]}),(0,r.jsxs)("td",{children:[(0,r.jsxs)("span",{children:["Forms ",(e.score.evidence.forms_observed??[]).join(" | ")]}),(0,r.jsxs)("span",{children:["Filings ",e.score.evidence.filing_count??0," | Amendments ",e.score.evidence.amendment_count??0]}),(0,r.jsxs)("span",{children:["Themes ",(e.score.evidence.themes??[]).join(" | ")||"n/a"]})]}),r.jsx("td",{className:"why",children:e.score.explanation})]},`${e.company.id}-${e.score.created_at}`))})]})}):r.jsx("div",{className:"empty-state",children:"No IPO radar rows match the current filters."})}function h({label:e,value:s}){return(0,r.jsxs)("div",{className:"metric-card",children:[r.jsx("span",{children:e}),r.jsx("strong",{children:s})]})}function m(e){return e?new Intl.DateTimeFormat("en",{month:"short",day:"2-digit",hour:"2-digit",minute:"2-digit"}).format(new Date(e)):"Pending"}},2522:(e,s,n)=>{"use strict";n.d(s,{G:()=>i});var r=n(8924);function i({label:e="Loading intelligence snapshot"}){return(0,r.jsxs)("div",{className:"loading-state",children:[r.jsx("div",{}),r.jsx("span",{children:e})]})}},7749:(e,s,n)=>{"use strict";n.d(s,{G:()=>o});var r=n(8924),i=n(1328),a=n.n(i),t=n(3911);let l=a()(async()=>{},{loadableGenerated:{modules:["components/PlotPanel.tsx -> react-plotly.js"]},ssr:!1});function o({title:e,data:s,layout:n={},height:i=360,emptyMessage:a="Waiting for real data series."}){let o=s.some(e=>[e?.x,e?.y,e?.z,e?.values,e?.labels].filter(Array.isArray).some(e=>!!e.length&&(!Array.isArray(e[0])||e.some(e=>Array.isArray(e)&&e.length>0)))),c={data:s,layout:{autosize:!0,height:i,paper_bgcolor:"#07090d",plot_bgcolor:"#090d13",font:{color:"#e7edf6",family:"Inter, system-ui, sans-serif"},margin:{l:42,r:18,t:18,b:36},xaxis:{gridcolor:"rgba(255,255,255,.06)",zeroline:!1},yaxis:{gridcolor:"rgba(255,255,255,.06)",zeroline:!1},...n},config:{displayModeBar:!1,responsive:!0},useResizeHandler:!0,style:{width:"100%"}};return(0,r.jsxs)("section",{className:"panel",children:[r.jsx("div",{className:"panel-head",children:r.jsx("span",{children:e})}),o?(0,t.createElement)(l,c):r.jsx("div",{className:"plot-empty",children:a})]})}},3081:(e,s,n)=>{"use strict";n.d(s,{O:()=>a});var r=n(8924),i=n(9779);function a({label:e}){let s=e.includes("Breakout")||e.includes("Strong")?"positive":e.includes("Risk")||e.includes("Avoid")?"negative":e.includes("Divergence")||e.includes("Contrarian")?"warning":"neutral";return r.jsx("span",{className:(0,i.Z)("status-badge",s),children:e})}},1328:(e,s,n)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0}),Object.defineProperty(s,"default",{enumerable:!0,get:function(){return a}});let r=n(1607);n(8924),n(3911);let i=r._(n(4737));function a(e,s){var n;let r={loading:e=>{let{error:s,isLoading:n,pastDelay:r}=e;return null}};"function"==typeof e&&(r.loader=e);let a={...r,...s};return(0,i.default)({...a,modules:null==(n=a.loadableGenerated)?void 0:n.modules})}("function"==typeof s.default||"object"==typeof s.default&&null!==s.default)&&void 0===s.default.__esModule&&(Object.defineProperty(s.default,"__esModule",{value:!0}),Object.assign(s.default,s),e.exports=s.default)},3880:(e,s,n)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0}),Object.defineProperty(s,"BailoutToCSR",{enumerable:!0,get:function(){return i}});let r=n(6483);function i(e){let{reason:s,children:n}=e;throw new r.BailoutToCSRError(s)}},4737:(e,s,n)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0}),Object.defineProperty(s,"default",{enumerable:!0,get:function(){return c}});let r=n(8924),i=n(3911),a=n(3880),t=n(7083);function l(e){return{default:e&&"default"in e?e.default:e}}let o={loader:()=>Promise.resolve(l(()=>null)),loading:null,ssr:!0},c=function(e){let s={...o,...e},n=(0,i.lazy)(()=>s.loader().then(l)),c=s.loading;function d(e){let l=c?(0,r.jsx)(c,{isLoading:!0,pastDelay:!0,error:null}):null,o=s.ssr?(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.PreloadCss,{moduleIds:s.modules}),(0,r.jsx)(n,{...e})]}):(0,r.jsx)(a.BailoutToCSR,{reason:"next/dynamic",children:(0,r.jsx)(n,{...e})});return(0,r.jsx)(i.Suspense,{fallback:l,children:o})}return d.displayName="LoadableComponent",d}},7083:(e,s,n)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0}),Object.defineProperty(s,"PreloadCss",{enumerable:!0,get:function(){return a}});let r=n(8924),i=n(4580);function a(e){let{moduleIds:s}=e,n=(0,i.getExpectedRequestStore)("next/dynamic css"),a=[];if(n.reactLoadableManifest&&s){let e=n.reactLoadableManifest;for(let n of s){if(!e[n])continue;let s=e[n].files.filter(e=>e.endsWith(".css"));a.push(...s)}}return 0===a.length?null:(0,r.jsx)(r.Fragment,{children:a.map(e=>(0,r.jsx)("link",{precedence:"dynamic",rel:"stylesheet",href:n.assetPrefix+"/_next/"+encodeURI(e),as:"style"},e))})}},3272:(e,s,n)=>{"use strict";n.r(s),n.d(s,{default:()=>r});let r=(0,n(6691).createProxy)(String.raw`/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/ipo-radar/page.tsx#default`)}};var s=require("../../webpack-runtime.js");s.C(e);var n=e=>s(s.s=e),r=s.X(0,[273,394],()=>n(3307));module.exports=r})();
\ No newline at end of file
diff --git a/frontend/.next/server/app/ipo-radar/page.js.nft.json b/frontend/.next/server/app/ipo-radar/page.js.nft.json
new file mode 100644
index 0000000000000000000000000000000000000000..877e4e935689e2063c7f370e14175cea6de0d164
--- /dev/null
+++ b/frontend/.next/server/app/ipo-radar/page.js.nft.json
@@ -0,0 +1 @@
+{"version":1,"files":["../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/package.json","../../../../node_modules/next","../../../../package.json","../../../package.json","../../chunks/273.js","../../chunks/394.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}
\ No newline at end of file
diff --git a/frontend/.next/server/app/ipo-radar/page_client-reference-manifest.js b/frontend/.next/server/app/ipo-radar/page_client-reference-manifest.js
new file mode 100644
index 0000000000000000000000000000000000000000..e6ac7b7843eb9aa7e47e31a14afed2dafc68db4a
--- /dev/null
+++ b/frontend/.next/server/app/ipo-radar/page_client-reference-manifest.js
@@ -0,0 +1 @@
+globalThis.__RSC_MANIFEST=(globalThis.__RSC_MANIFEST||{});globalThis.__RSC_MANIFEST["/ipo-radar/page"]={"moduleLoading":{"prefix":"/_next/","crossOrigin":null},"ssrModuleMapping":{"176":{"*":{"id":"6676","name":"*","chunks":[],"async":false}},"841":{"*":{"id":"9737","name":"*","chunks":[],"async":false}},"892":{"*":{"id":"5213","name":"*","chunks":[],"async":false}},"2010":{"*":{"id":"7619","name":"*","chunks":[],"async":false}},"2433":{"*":{"id":"6544","name":"*","chunks":[],"async":false}},"2651":{"*":{"id":"9645","name":"*","chunks":[],"async":false}},"2987":{"*":{"id":"1358","name":"*","chunks":[],"async":false}},"3713":{"*":{"id":"5210","name":"*","chunks":[],"async":false}},"4374":{"*":{"id":"9927","name":"*","chunks":[],"async":false}},"6056":{"*":{"id":"1309","name":"*","chunks":[],"async":false}},"6543":{"*":{"id":"9722","name":"*","chunks":[],"async":false}},"6813":{"*":{"id":"5877","name":"*","chunks":[],"async":false}},"7096":{"*":{"id":"1952","name":"*","chunks":[],"async":false}},"7413":{"*":{"id":"8052","name":"*","chunks":[],"async":false}},"7523":{"*":{"id":"3477","name":"*","chunks":[],"async":false}},"7768":{"*":{"id":"7663","name":"*","chunks":[],"async":false}},"8145":{"*":{"id":"8377","name":"*","chunks":[],"async":false}},"8528":{"*":{"id":"5116","name":"*","chunks":[],"async":false}},"8547":{"*":{"id":"5441","name":"*","chunks":[],"async":false}},"9135":{"*":{"id":"432","name":"*","chunks":[],"async":false}},"9239":{"*":{"id":"8132","name":"*","chunks":[],"async":false}},"9414":{"*":{"id":"8850","name":"*","chunks":[],"async":false}},"9570":{"*":{"id":"291","name":"*","chunks":[],"async":false}}},"edgeSSRModuleMapping":{},"clientModules":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/globals.css":{"id":4443,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/components/AppShell.tsx":{"id":6813,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/backtest/page.tsx":{"id":4374,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chart-analyst/page.tsx":{"id":6543,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chat/page.tsx":{"id":841,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chatbot/page.tsx":{"id":8145,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/learning/page.tsx":{"id":6056,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/methodology/page.tsx":{"id":7413,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/ipo-radar/page.tsx":{"id":9135,"name":"*","chunks":["651","static/chunks/651-5689242ae9b0ffc6.js","405","static/chunks/app/ipo-radar/page-37bfbd97573d6050.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/market-brain/page.tsx":{"id":2987,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page.tsx":{"id":892,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/dashboard/page.tsx":{"id":7096,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","96","static/chunks/96-ce8c57cd15d50941.js","931","static/chunks/app/page-d0db9a93fb4af9a5.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/etf-radar/page.tsx":{"id":9239,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/performance/page.tsx":{"id":8547,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/signal-lab/page.tsx":{"id":2010,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/sniper/page.tsx":{"id":7768,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/stock-radar/page.tsx":{"id":9570,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/assets/[ticker]/view.tsx":{"id":3713,"name":"*","chunks":[],"async":false}},"entryCSSFiles":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout":["static/css/02bd12e03544ea91.css"],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/page":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/ipo-radar/page":[]}}
\ No newline at end of file
diff --git a/frontend/.next/server/app/learning.html b/frontend/.next/server/app/learning.html
new file mode 100644
index 0000000000000000000000000000000000000000..ad91687633d95b300c467499e61d28b42b30c25c
--- /dev/null
+++ b/frontend/.next/server/app/learning.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence BLUM Trading Intelligence LabAuditable paper trading intelligence.
Capital cycles, advanced trade ledger, live forward paper mode and intelligence-growth metrics. Built to measure whether BLUM is improving entries, exits, risk control and benchmark-relative decision quality.
Loading snapshotprogressive loading0 evaluated horizons
n/a5-20 trading days
n/a1-3 months
n/ainsufficient sample
Tier 1 Critical SnapshotloadingLoading lightweight summary Tier 2 Main ChartsreadyEquity curve, benchmark comparison and rolling intelligence metrics load after the critical snapshot.
Tier 3 TablesreadyTrade ledgers, cycles, predictions and learning evidence use safe default limits and load only when this section becomes visible or when requested.
BLUM Trading Power Scoren/a/100Classificationnot calculatedEvidencen/aSample0Live sample0Benchmark scoren/aLive validationn/aThe score appears after the Trading Intelligence ledger has evidence to evaluate.
Truth Panelno hypecurrent stateNot enough evidence yet.Learning ProgressinconclusiveGrowth Scoren/a/100Current Trades0Win Raten/aExpectancyn/aRMissed Entryn/aBenchmark Excessn/aBLUM cannot claim improvement until rolling windows and live validation are meaningful.
Decision Superiorityn/a/100Classificationinsufficient evidenceRecalln/aPrecisionn/aAlpha Capturen/aRankingn/aComparable Decisions0BLUM needs comparable decision snapshots before it can claim it selected superior opportunities.
Business Quality Lab0No business-quality evidence yet. Stored fundamental snapshots are required.Portfolio Intelligencen/a/100Diversificationn/aConcentration Riskn/aDrawdown Controln/aAlpha Generationn/aContributors0Correlations0BLUM needs portfolio trade evidence before contribution, concentration and portfolio-alpha quality can be measured.
Benchmark Arena0BenchmarkTypeResultExcessSampleEvidenceNo benchmark comparison is available yet.Strength / Weakness Map0No weakness map yet. BLUM needs trade outcomes and attribution samples.Self-Improvement Queue0No self-improvement action has been proposed yet. Capital Cycleno cycleCycle Capitaln/aTargetn/aProgress0.0%Cycle #n/aTargets Hit0Bankrupt Cycles0Capital growth is capped into 100 EUR to target cycles. When target or bankruptcy is reached, the cycle is recorded and the active bankroll restarts from 100 EUR.
Trading Intelligence Metricsn/a/100Win Raten/aMissed Entryn/aTarget Hitn/aStop Hitn/aExpectancyn/aRBenchmark Excessn/aThese metrics measure decision quality, not only P/L. High numbers still require sample-size and realism checks before they mean anything.
Historical vs Live ForwardloadingLive Capitaln/aOpen Positions0Live Trades0Historical Trades0Live Expectancyn/aRHistorical Expectancyn/aRLive forward paper evidence starts weak and becomes meaningful only after enough timestamp-frozen trades close.
Tier 4 Deep Reasoning PanelsThesis survival, conviction decay, regime-aware reliability, thesis competitions, ensemble status and training quality are intentionally lazy-loaded. They no longer block the Learning dashboard first render.
Full Trade Ledger0 visible / 0 totalDetailed ledgers are lazy-loaded. Scroll here or use the Tier 3 button to fetch paginated trade evidence.Wins0Losses0Missed Entries0Target Hits0Stop Hits0No-Trade Correct0TickerSetupModeCycleEntryExitP/L EURP/L/shareROutcomeQualityExcessNo detailed trade ledger is available yet. The next Trading Game run will enrich persisted trades with entry, exit, attribution, P/L and learning evidence. Reality Checkn/aTrades0Tickers0Sectors0Regimes0Samplen/a/100Realismn/a/100Reality check will appear after trade transparency runs.
P/L Breakdownn/aNo setup-level P/L breakdown yet.Learning Evidence Log0No trade learning evidence has been persisted yet. Capital Cycle History0No capital cycle has been recorded yet.Setup Development0No setup intelligence metrics yet.Regime / Sector Learning0No regime or sector learning metrics yet. Trading Game Equity CurveWaiting for real data series. Paper P/L and capital disciplineNo gameCapitaln/aRealized P/Ln/aMax Drawdownn/a%Expectancyn/aRProfit Factorn/aRisk of Ruinn/a%Benchmark Alphan/a%Reproducibilityn/a/100BLUM starts each paper game at 100 EUR, risks fractionally, rejects non-reproducible setups and compares the equity curve against . Small samples never qualify as proof of outperformance.
Recent reproducible trade decisions0TickerSetupDecisionRP/LCapitalNo P/L decisions yet. BLUM needs stored execution simulations before the game can score trades.Capital management lessons0No capital management lessons yet. Walk-forward Accuracy by Horizon Latest autonomous runNo run yetThe scheduler is active but no point-in-time learning run has been persisted yet.Signal reliability memory0FactorTFRegimeSamplesReliabilityFalse +No signal reliability rows yet. The first learning batches will populate this table.Mistake taxonomy0No classified mistakes yet. This is expected before enough simulated outcomes mature. Strategy memory0No strategy memory has been learned yet.Recent point-in-time predictions0TickerDateRegimeDirectionConfidenceQualityNo historical predictions persisted yet. Governance and anti-overfittingResearch onlyAsset Universestocks,etfsMin Historyn/a yearsDaily Guardn/aBatch Sizen/aProgressive loading is active. Deep learning details load after the lightweight summary and visible tables.
Every prediction stores the simulated date, hidden future policy, horizons, confidence, outcomes and mistake analysis. The loop updates parameters and memory only; it does not execute trades and does not self-modify source code.
\ No newline at end of file
diff --git a/frontend/.next/server/app/learning.meta b/frontend/.next/server/app/learning.meta
new file mode 100644
index 0000000000000000000000000000000000000000..4b1cf75c538b2e64fe2ad5f6d1458fcf744d07d1
--- /dev/null
+++ b/frontend/.next/server/app/learning.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/learning/layout,_N_T_/learning/page,_N_T_/learning/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/learning.rsc b/frontend/.next/server/app/learning.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..67e85f77e385421e8a943c38131b3c1186f9a260
--- /dev/null
+++ b/frontend/.next/server/app/learning.rsc
@@ -0,0 +1,8 @@
+2:I[7523,[],"ClientPageRoot"]
+3:I[6056,["651","static/chunks/651-5689242ae9b0ffc6.js","934","static/chunks/app/learning/page-fb9d9a3de58b413d.js"],"default",1]
+4:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["learning",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["learning",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","learning","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/learning/page.js b/frontend/.next/server/app/learning/page.js
new file mode 100644
index 0000000000000000000000000000000000000000..f6b4c400b377c9e74aef4f71683107ce131e547a
--- /dev/null
+++ b/frontend/.next/server/app/learning/page.js
@@ -0,0 +1 @@
+(()=>{var e={};e.id=649,e.ids=[649],e.modules={2934:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external.js")},4580:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external.js")},5869:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},399:e=>{"use strict";e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},6050:(e,s,a)=>{"use strict";a.r(s),a.d(s,{GlobalError:()=>r.a,__next_app__:()=>h,originalPathname:()=>p,pages:()=>o,routeModule:()=>m,tree:()=>d}),a(2071),a(8777),a(311);var l=a(9296),n=a(1650),i=a(7045),r=a.n(i),t=a(8184),c={};for(let e in t)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(c[e]=()=>t[e]);a.d(s,c);let d=["",{children:["learning",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(a.bind(a,2071)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/learning/page.tsx"]}]},{}]},{layout:[()=>Promise.resolve().then(a.bind(a,8777)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout.tsx"],"not-found":[()=>Promise.resolve().then(a.t.bind(a,311,23)),"next/dist/client/components/not-found-error"]}],o=["/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/learning/page.tsx"],p="/learning/page",h={require:a,loadChunk:()=>Promise.resolve()},m=new l.AppPageRouteModule({definition:{kind:n.x.APP_PAGE,page:"/learning/page",pathname:"/learning",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:d}})},2338:(e,s,a)=>{Promise.resolve().then(a.bind(a,1309))},1309:(e,s,a)=>{"use strict";a.r(s),a.d(s,{default:()=>m});var l=a(8924),n=a(3911),i=a(7993),r=a(9773),t=a(2567),c=a(741),d=a(3789);function o({title:e,loading:s,error:a,stale:n,updatedAt:i,onRetry:r,children:t,fallback:c="Loading panel"}){return(0,l.jsxs)("section",{className:"panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:e}),l.jsx("strong",{children:n?"stale":i?new Date(i).toLocaleTimeString():s?"loading":"ready"})]}),s&&l.jsx("div",{className:"empty-state compact",children:c}),a&&(0,l.jsxs)("div",{className:"empty-state compact",children:[a,r&&l.jsx("button",{className:"button compact",onClick:r,children:"Retry"})]}),!s&&!a&&t]})}var p=a(7749),h=a(3081);function m(){let[e,s]=(0,n.useState)(null),[a,m]=(0,n.useState)(null),[N,f]=(0,n.useState)([]),[k,w]=(0,n.useState)([]),[S,T]=(0,n.useState)(null),[R,L]=(0,n.useState)(null),[P,C]=(0,n.useState)(null),[q,M]=(0,n.useState)(null),[A,$]=(0,n.useState)(""),[E,B]=(0,n.useState)(""),[O,z]=(0,n.useState)(""),[U,D]=(0,n.useState)(!1),[F,G]=(0,n.useState)(!1),[H,I]=(0,n.useState)(!1),[Q,W]=(0,n.useState)(!1),[Z,V]=(0,n.useState)(!1),[X,J]=(0,n.useState)(!1),K=(0,n.useRef)(null);async function Y(){V(!0);let[e,s,a,l,n,i,r,t]=await Promise.allSettled([d.h.reasoningCoreStatus(),d.h.thesisSurvival(16),d.h.convictionDecay(16),d.h.reliabilityByRegime(16),d.h.thesisCompetitions(12),d.h.ensembleStatus(),d.h.benchmarkRelative(16),d.h.trainingQuality(16)]);C({status:"fulfilled"===e.status?e.value:null,survival:"fulfilled"===s.status?s.value:null,conviction:"fulfilled"===a.status?a.value:null,reliability:"fulfilled"===l.status?l.value:null,competitions:"fulfilled"===n.status?n.value:null,ensemble:"fulfilled"===i.status?i.value:null,benchmark:"fulfilled"===r.status?r.value:null,trainingQuality:"fulfilled"===t.status?t.value:null}),J(!0),V(!1)}let ee=a?.metrics??{},es=ee.by_timeframe??{},ea=S?.signal_performance??a?.signal_performance??[],el=S?.strategy_memory??a?.strategy_memory??[],en=S?.mistakes??a?.mistakes??[],ei=a?.latest_run,er=R?.status?.current_game??a?.trading_game?.current_game??{current_capital:e?.current_capital,target_capital:e?.target_capital,target_cycles_completed:e?.completed_target_cycles,bankrupt_cycles:e?.bankrupt_cycles,status:e?.status},et=R?.equity??[],ec=R?.annotatedEquity?.equity_curve_points??et,ed=R?.annotatedEquity?.annotations??[],eo=R?.trades??[],ep=R?.ledger?.rows??[],eh=R?.ledgerSummary?.summary??R?.ledger?.summary??{},em=R?.cycles?.cycles??[],eu=R?.currentCycle?.cycle??{},ex=R?.cycleStats?.stats??R?.cycles?.stats??{},ej=R?.intelligenceMetrics?.metrics??{};R?.rollingMetrics?.windows;let eg=R?.metricsBySetup?.rows??[],ev=R?.metricsByRegime?.rows??[],e_=R?.metricsBySector?.rows??[],ey=R?.historicalVsLive??{},eb=R?.liveStatus??{},eN=eb?.game??{},ef=R?.livePositions?.positions??eb?.open_positions??[],ek=Array.isArray(ef)?ef:[],ew=R?.liveMetrics?.metrics??{},eS=R?.learningIntelligence??{},eT=R?.decisionIntelligence??{},eR=eT?.decision?.decision_superiority??{},eL=eT?.decision?.top_missed_opportunities??[],eP=eT?.business_quality?.highest_quality_companies??[],eC=eT?.portfolio?.portfolio_quality??{},eq=eT?.portfolio?.contributions??[],eM=eT?.portfolio?.correlations??[],eA=eS?.trading_power??{score:e?.trading_power_score,classification:e?.trading_power_classification,truth_panel:e?.truth_panel,warnings:e?.warnings,explanation:e?.suggested_next_step,statistical_confidence:e?.benchmark_summary?.status},e$=eA?.components??{},eE=eS?.benchmarks?.rows??Object.entries(e?.benchmark_summary?.major_benchmarks??{}).map(([e,s])=>({benchmark_name:e,benchmark_type:"market",result_label:s.result_label,excess_return:s.excess_return,sample_size:s.sample_size,statistical_confidence:s.statistical_confidence})),eB=eS?.progress??{},eO=eS?.weakness_map?.rows??[],ez=eS?.self_improvement?.actions??[],eU=eS?.truth_panel??eA?.truth_panel??e?.truth_panel??[],eD=R?.learningEvidence?.rows??[],eF=R?.realityCheck??{},eG=R?.pnlBreakdown??{},eH=R?.lessons??[],eI=R?.benchmark??{},eQ=R?.reproducibility??{},eW=P?.status?.precision_core?.counts??{},eZ=P?.survival?.rows??[],eV=P?.conviction?.rows??[],eX=P?.reliability?.rows??[],eJ=P?.competitions?.rows??[],eK=P?.trainingQuality?.rows??[],eY=(0,n.useMemo)(()=>{let e=["short","mid","long"];return[{x:e,y:e.map(e=>{var s;return null==(s=es[e]?.accuracy)?0:100*Number(s)}),type:"bar",marker:{color:["#55aaff","#20e070","#ffb000"]}}]},[es]),e0=(0,n.useMemo)(()=>{let e=ec.map(e=>e.timestamp||e.equity_date||e.created_at),s=ed.filter(e=>"trade_entry"!==e.event_type);return[{x:e,y:ec.map(e=>e.equity),type:"scatter",mode:"lines",name:"BLUM",line:{color:"#ffb000",width:3}},{x:e,y:ec.map(e=>e.benchmark_equity),type:"scatter",mode:"lines",name:"Benchmark",line:{color:"#55aaff",width:2}},{x:s.map(e=>e.timestamp),y:s.map(e=>e.capital_after_event),type:"scatter",mode:"markers",name:"Events",marker:{color:s.map(e=>e.pnl_impact>=0?"#20e070":"#ff4d5e"),size:9,symbol:"diamond"},text:s.map(e=>e.label),hovertemplate:"%{text} "}]},[ec,ed]);async function e1(e){$("");try{let s=await d.h.tradingGameTradeDetail(e);M(s)}catch(e){$(e instanceof Error?e.message:String(e))}}return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsxs)("header",{className:"page-header",children:[(0,l.jsxs)("div",{children:[l.jsx("div",{className:"kicker",children:"BLUM Trading Intelligence Lab"}),l.jsx("h1",{children:"Auditable paper trading intelligence."}),l.jsx("p",{children:"Capital cycles, advanced trade ledger, live forward paper mode and intelligence-growth metrics. Built to measure whether BLUM is improving entries, exits, risk control and benchmark-relative decision quality."})]}),(0,l.jsxs)("div",{className:"header-actions",children:[l.jsx(h.O,{label:e?.status==="ready"||a?.status==="active"?"Learning snapshot ready":"Loading snapshot"}),l.jsx(h.O,{label:a?.configuration?.evaluation_mode??"progressive"}),U&&l.jsx(h.O,{label:"charts loading"}),F&&l.jsx(h.O,{label:"tables loading"})]})]}),O&&(0,l.jsxs)("div",{className:"empty-state",style:{marginBottom:12},children:["Summary warning: ",O]}),E&&(0,l.jsxs)("div",{className:"empty-state",style:{marginBottom:12},children:["Deferred widget warning: ",E]}),(0,l.jsxs)("section",{className:"grid-4",children:[l.jsx(u,{icon:l.jsx(i.Z,{size:18}),label:"Simulations",value:ee.simulations??"loading",subvalue:`${ee.outcomes??0} evaluated horizons`}),l.jsx(u,{icon:l.jsx(r.Z,{size:18}),label:"Short Accuracy",value:j(es.short?.accuracy),subvalue:"5-20 trading days"}),l.jsx(u,{icon:l.jsx(t.Z,{size:18}),label:"Mid Accuracy",value:j(es.mid?.accuracy),subvalue:"1-3 months"}),l.jsx(u,{icon:l.jsx(c.Z,{size:18}),label:"Calibration Error",value:_(ee.confidence_calibration?.mean_absolute_error),subvalue:ee.confidence_calibration?.status??"insufficient sample"})]}),(0,l.jsxs)("section",{className:"grid-3",style:{marginTop:12},children:[l.jsx(o,{title:"Tier 1 Critical Snapshot",loading:!e&&!O,error:O,updatedAt:e?.generated_at,fallback:"Loading lightweight summary",children:(0,l.jsxs)("div",{className:"evidence-grid",children:[l.jsx(x,{label:"Capital",value:y(e?.current_capital)}),l.jsx(x,{label:"Target Progress",value:e?.target_progress===null||e?.target_progress===void 0?"n/a":j(e.target_progress)}),l.jsx(x,{label:"Power Score",value:e?.trading_power_score===null||e?.trading_power_score===void 0?"n/a":`${_(e.trading_power_score)}/100`}),l.jsx(x,{label:"Benchmarks",value:e?.benchmark_summary?.status??"loading"}),l.jsx(x,{label:"Latest Run",value:e?.latest_learning_run_status??"loading"}),l.jsx(x,{label:"Freshness",value:b(e?.generated_at)})]})}),l.jsx(o,{title:"Tier 2 Main Charts",loading:U,error:"",updatedAt:e?.generated_at,fallback:"Loading charts without blocking the page",children:l.jsx("p",{children:"Equity curve, benchmark comparison and rolling intelligence metrics load after the critical snapshot."})}),(0,l.jsxs)(o,{title:"Tier 3 Tables",loading:F,error:"",updatedAt:H?e?.generated_at:null,fallback:"Loading ledgers and memory tables progressively",children:[l.jsx("p",{children:"Trade ledgers, cycles, predictions and learning evidence use safe default limits and load only when this section becomes visible or when requested."}),!H&&l.jsx("button",{className:"button compact",onClick:()=>W(!0),disabled:F,children:F?"Loading details...":"Load detailed tables"})]})]}),(0,l.jsxs)("section",{className:"grid-3",style:{marginTop:12},children:[(0,l.jsxs)("div",{className:"panel lab-command-panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"BLUM Trading Power Score"}),(0,l.jsxs)("strong",{children:[_(eA?.score),"/100"]})]}),l.jsx("div",{className:"cycle-progress-track",children:l.jsx("span",{style:{width:`${Math.max(0,Math.min(100,Number(eA?.score??0)))}%`}})}),(0,l.jsxs)("div",{className:"evidence-grid",children:[l.jsx(x,{label:"Classification",value:eA?.classification??"not calculated"}),l.jsx(x,{label:"Evidence",value:eA?.statistical_confidence??"n/a"}),l.jsx(x,{label:"Sample",value:eA?.sample_size??0}),l.jsx(x,{label:"Live sample",value:eA?.live_sample_size??0}),l.jsx(x,{label:"Benchmark score",value:_(e$?.benchmark_relative_score)}),l.jsx(x,{label:"Live validation",value:_(e$?.live_forward_validation_score)})]}),l.jsx("p",{children:eA?.explanation??"The score appears after the Trading Intelligence ledger has evidence to evaluate."}),(eA?.warnings??[]).length>0&&l.jsx("div",{className:"tag-row",children:eA.warnings.slice(0,5).map(e=>l.jsx("span",{children:e},e))})]}),(0,l.jsxs)("div",{className:"panel lab-command-panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Truth Panel"}),l.jsx("strong",{children:"no hype"})]}),l.jsx("div",{className:"brain-list dense",children:(eU.length?eU:["Not enough evidence yet."]).slice(0,6).map((e,s)=>(0,l.jsxs)("div",{children:[l.jsx(h.O,{label:0===s?"current state":"evidence"}),l.jsx("strong",{children:e})]},`${s}-${e}`))})]}),(0,l.jsxs)("div",{className:"panel lab-command-panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Learning Progress"}),l.jsx("strong",{children:eB?.trend_label??"inconclusive"})]}),(0,l.jsxs)("div",{className:"evidence-grid",children:[l.jsx(x,{label:"Growth Score",value:`${_(eB?.intelligence_growth_score)}/100`}),l.jsx(x,{label:"Current Trades",value:eB?.current?.trades_count??0}),l.jsx(x,{label:"Win Rate",value:j(eB?.current?.win_rate)}),l.jsx(x,{label:"Expectancy",value:`${_(eB?.current?.expectancy_r)}R`}),l.jsx(x,{label:"Missed Entry",value:j(eB?.current?.missed_entry_rate)}),l.jsx(x,{label:"Benchmark Excess",value:g(eB?.current?.benchmark_excess)})]}),l.jsx("p",{children:eB?.summary??"BLUM cannot claim improvement until rolling windows and live validation are meaningful."})]})]}),(0,l.jsxs)("section",{className:"grid-3",style:{marginTop:12},children:[(0,l.jsxs)("div",{className:"panel lab-command-panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Decision Superiority"}),(0,l.jsxs)("strong",{children:[_(eR?.score),"/100"]})]}),l.jsx("div",{className:"cycle-progress-track",children:l.jsx("span",{style:{width:`${Math.max(0,Math.min(100,Number(eR?.score??0)))}%`}})}),(0,l.jsxs)("div",{className:"evidence-grid",children:[l.jsx(x,{label:"Classification",value:eR?.classification??"insufficient evidence"}),l.jsx(x,{label:"Recall",value:j(eR?.metrics?.opportunity_recall)}),l.jsx(x,{label:"Precision",value:j(eR?.metrics?.opportunity_precision)}),l.jsx(x,{label:"Alpha Capture",value:j(eR?.metrics?.alpha_capture_rate)}),l.jsx(x,{label:"Ranking",value:j(eR?.metrics?.ranking_accuracy)}),l.jsx(x,{label:"Comparable Decisions",value:eR?.sample_size??0})]}),l.jsx("p",{children:eR?.explanation??"BLUM needs comparable decision snapshots before it can claim it selected superior opportunities."}),eL.length>0&&l.jsx("div",{className:"tag-row",children:eL.slice(0,4).map(e=>(0,l.jsxs)("span",{children:["Missed ",e.best_available_ticker," vs ",e.ticker]},`${e.trade_id}-${e.best_available_ticker}`))})]}),(0,l.jsxs)("div",{className:"panel lab-command-panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Business Quality Lab"}),l.jsx("strong",{children:eP.length})]}),(0,l.jsxs)("div",{className:"brain-list dense",children:[(eP.length?eP:[]).slice(0,5).map(e=>(0,l.jsxs)("div",{children:[l.jsx(h.O,{label:`${e.ticker} | ${e.status}`}),(0,l.jsxs)("div",{className:"opportunity-line",children:[l.jsx("strong",{children:e.name}),(0,l.jsxs)("span",{children:[_(e.business_quality_score),"/100"]})]}),(0,l.jsxs)("p",{children:["Growth ",_(e.growth_quality)," | FCF ",_(e.cash_flow_quality)," | moat ",_(e.moat_quality)," | data ",_(e.data_quality_score)]})]},e.ticker)),0===eP.length&&l.jsx("div",{className:"empty-state compact",children:"No business-quality evidence yet. Stored fundamental snapshots are required."})]})]}),(0,l.jsxs)("div",{className:"panel lab-command-panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Portfolio Intelligence"}),(0,l.jsxs)("strong",{children:[_(eC?.score),"/100"]})]}),(0,l.jsxs)("div",{className:"evidence-grid",children:[l.jsx(x,{label:"Diversification",value:_(eC?.components?.diversification)}),l.jsx(x,{label:"Concentration Risk",value:_(eC?.components?.concentration_risk)}),l.jsx(x,{label:"Drawdown Control",value:_(eC?.components?.drawdown_control)}),l.jsx(x,{label:"Alpha Generation",value:_(eC?.components?.alpha_generation)}),l.jsx(x,{label:"Contributors",value:eq.length}),l.jsx(x,{label:"Correlations",value:eM.length})]}),l.jsx("p",{children:eC?.explanation??"BLUM needs portfolio trade evidence before contribution, concentration and portfolio-alpha quality can be measured."}),(eC?.warnings??[]).length>0&&l.jsx("div",{className:"tag-row",children:eC.warnings.slice(0,4).map(e=>l.jsx("span",{children:e},e))})]})]}),(0,l.jsxs)("section",{className:"grid-3",style:{marginTop:12},children:[(0,l.jsxs)("div",{className:"panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Benchmark Arena"}),l.jsx("strong",{children:eE.length})]}),(0,l.jsxs)("div",{className:"learning-table",children:[(0,l.jsxs)("div",{className:"learning-row head",children:[l.jsx("span",{children:"Benchmark"}),l.jsx("span",{children:"Type"}),l.jsx("span",{children:"Result"}),l.jsx("span",{children:"Excess"}),l.jsx("span",{children:"Sample"}),l.jsx("span",{children:"Evidence"})]}),eE.slice(0,10).map(e=>(0,l.jsxs)("div",{className:"learning-row",children:[l.jsx("strong",{children:e.benchmark_name}),l.jsx("span",{children:e.benchmark_type}),l.jsx("span",{className:function(e){let s=String(e??"");return"outperforming"===s?"positive-text":"underperforming"===s?"negative-text":""}(e.result_label),children:String(e.result_label).replaceAll("_"," ")}),l.jsx("span",{className:Number(e.excess_return)>=0?"positive-text":"negative-text",children:g(e.excess_return)}),l.jsx("span",{children:e.sample_size}),l.jsx("span",{children:e.statistical_confidence})]},`${e.benchmark_name}-${e.benchmark_type}`)),0===eE.length&&l.jsx("div",{className:"empty-state",children:"No benchmark comparison is available yet."})]})]}),(0,l.jsxs)("div",{className:"panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Strength / Weakness Map"}),l.jsx("strong",{children:eO.length})]}),(0,l.jsxs)("div",{className:"brain-list dense",children:[eO.slice(0,6).map(e=>(0,l.jsxs)("div",{children:[l.jsx(h.O,{label:`${e.dimension}: ${String(e.entity).replaceAll("_"," ")}`}),(0,l.jsxs)("div",{className:"opportunity-line",children:[l.jsx("strong",{children:e.main_problem}),(0,l.jsxs)("span",{children:[_(e.weakness_score),"/100 weak"]})]}),l.jsx("p",{children:e.recommended_action}),(0,l.jsxs)("p",{children:["Samples ",e.sample_size," | strength ",_(e.strength_score)," | priority ",e.priority]})]},`${e.dimension}-${e.entity}`)),0===eO.length&&l.jsx("div",{className:"empty-state compact",children:"No weakness map yet. BLUM needs trade outcomes and attribution samples."})]})]}),(0,l.jsxs)("div",{className:"panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Self-Improvement Queue"}),l.jsx("strong",{children:ez.length})]}),(0,l.jsxs)("div",{className:"brain-list dense",children:[ez.slice(0,6).map(e=>(0,l.jsxs)("div",{children:[l.jsx(h.O,{label:`${e.priority} | ${e.status}`}),l.jsx("strong",{children:e.detected_problem}),l.jsx("p",{children:e.recommended_action}),(0,l.jsxs)("p",{children:["Module ",e.affected_module," | impact: ",e.expected_impact]})]},e.id??`${e.source_dimension}-${e.affected_module}`)),0===ez.length&&l.jsx("div",{className:"empty-state compact",children:"No self-improvement action has been proposed yet."})]})]})]}),(0,l.jsxs)("section",{className:"grid-3",style:{marginTop:12},children:[(0,l.jsxs)("div",{className:"panel lab-command-panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Capital Cycle"}),l.jsx("strong",{children:eu?.status??"no cycle"})]}),l.jsx("div",{className:"cycle-progress-track",children:l.jsx("span",{style:{width:`${v(eu)}%`}})}),(0,l.jsxs)("div",{className:"evidence-grid",children:[l.jsx(x,{label:"Cycle Capital",value:y(eu?.final_capital??er?.current_capital)}),l.jsx(x,{label:"Target",value:y(eu?.target_capital??er?.target_capital)}),l.jsx(x,{label:"Progress",value:`${v(eu).toFixed(1)}%`}),l.jsx(x,{label:"Cycle #",value:eu?.cycle_number??"n/a"}),l.jsx(x,{label:"Targets Hit",value:ex?.target_cycles_completed??er?.target_cycles_completed??0}),l.jsx(x,{label:"Bankrupt Cycles",value:ex?.bankrupt_cycles??er?.bankrupt_cycles??0})]}),l.jsx("p",{children:"Capital growth is capped into 100 EUR to target cycles. When target or bankruptcy is reached, the cycle is recorded and the active bankroll restarts from 100 EUR."})]}),(0,l.jsxs)("div",{className:"panel lab-command-panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Trading Intelligence Metrics"}),(0,l.jsxs)("strong",{children:[_(ej?.intelligence_growth_score),"/100"]})]}),(0,l.jsxs)("div",{className:"evidence-grid",children:[l.jsx(x,{label:"Win Rate",value:j(ej?.win_rate)}),l.jsx(x,{label:"Missed Entry",value:j(ej?.missed_entry_rate)}),l.jsx(x,{label:"Target Hit",value:j(ej?.target_hit_rate)}),l.jsx(x,{label:"Stop Hit",value:j(ej?.stop_hit_rate)}),l.jsx(x,{label:"Expectancy",value:`${_(ej?.expectancy_r)}R`}),l.jsx(x,{label:"Benchmark Excess",value:g(ej?.benchmark_excess)})]}),l.jsx("p",{children:"These metrics measure decision quality, not only P/L. High numbers still require sample-size and realism checks before they mean anything."})]}),(0,l.jsxs)("div",{className:"panel lab-command-panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Historical vs Live Forward"}),l.jsx("strong",{children:eb?.status??"loading"})]}),(0,l.jsxs)("div",{className:"evidence-grid",children:[l.jsx(x,{label:"Live Capital",value:y(eN?.current_capital)}),l.jsx(x,{label:"Open Positions",value:ek.length??eN?.open_positions??0}),l.jsx(x,{label:"Live Trades",value:ew?.trades_count??ey?.live?.trades_count??0}),l.jsx(x,{label:"Historical Trades",value:ey?.historical?.trades_count??0}),l.jsx(x,{label:"Live Expectancy",value:`${_(ew?.expectancy_r??ey?.live?.expectancy_r)}R`}),l.jsx(x,{label:"Historical Expectancy",value:`${_(ey?.historical?.expectancy_r)}R`})]}),l.jsx("p",{children:ey?.sample_warning??"Live forward paper evidence starts weak and becomes meaningful only after enough timestamp-frozen trades close."})]})]}),X?(0,l.jsxs)("section",{className:"grid-2",style:{marginTop:12},children:[(0,l.jsxs)("div",{className:"panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Reasoning Precision Core"}),l.jsx("strong",{children:P?.status?.precision_core?.status??"Loading"})]}),(0,l.jsxs)("div",{className:"evidence-grid",children:[l.jsx(x,{label:"Survival Metrics",value:eW.thesis_survival_metrics??0}),l.jsx(x,{label:"Conviction Rows",value:eW.conviction_history_rows??0}),l.jsx(x,{label:"Regime Reliability",value:eW.reliability_by_regime_rows??0}),l.jsx(x,{label:"Thesis Competitions",value:eW.thesis_competitions??0}),l.jsx(x,{label:"Engine Votes",value:eW.engine_votes??0}),l.jsx(x,{label:"Benchmark Outcomes",value:eW.benchmark_relative_outcomes??0})]}),l.jsx("p",{children:"These panels measure thesis durability, confidence decay, benchmark-relative evidence and engine disagreement. They update database memory only; no source code is self-modified."})]}),(0,l.jsxs)("div",{className:"panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Thesis survival and decay"}),(0,l.jsxs)("strong",{children:[eZ.length," / ",eV.length]})]}),(0,l.jsxs)("div",{className:"learning-table",children:[(0,l.jsxs)("div",{className:"learning-row head",children:[l.jsx("span",{children:"Ticker"}),l.jsx("span",{children:"Status"}),l.jsx("span",{children:"Age"}),l.jsx("span",{children:"Confidence"}),l.jsx("span",{children:"Excess"}),l.jsx("span",{children:"Quality"})]}),eZ.slice(0,8).map(e=>{var s;return(0,l.jsxs)("div",{className:"learning-row",children:[l.jsx("strong",{children:e.ticker}),l.jsx("span",{children:e.survival_status}),(0,l.jsxs)("span",{children:[_(e.survival_days),"d"]}),l.jsx("span",{children:_(e.current_confidence)}),l.jsx("span",{className:Number(e.excess_return)>=0?"positive-text":"negative-text",children:null==(s=e.excess_return)||Number.isNaN(Number(s))?"n/a":`${(100*Number(s)).toFixed(2)}%`}),l.jsx("span",{children:_(e.survival_quality_score)})]},e.id)}),0===eZ.length&&l.jsx("div",{className:"empty-state",children:"No thesis survival rows yet. The autonomous model cycle will create them after stored theses exist."})]})]})]}):(0,l.jsxs)("section",{className:"panel",style:{marginTop:12},children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Tier 4 Deep Reasoning Panels"}),l.jsx("button",{className:"button compact",onClick:Y,disabled:Z,children:Z?"Loading...":"Load deep reasoning panels"})]}),l.jsx("p",{children:"Thesis survival, conviction decay, regime-aware reliability, thesis competitions, ensemble status and training quality are intentionally lazy-loaded. They no longer block the Learning dashboard first render."})]}),(0,l.jsxs)("section",{className:"panel",style:{marginTop:12},ref:K,children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Full Trade Ledger"}),(0,l.jsxs)("strong",{children:[ep.length," visible / ",R?.ledger?.total??0," total"]})]}),!Q&&!H&&l.jsx("div",{className:"empty-state compact",style:{marginBottom:12},children:"Detailed ledgers are lazy-loaded. Scroll here or use the Tier 3 button to fetch paginated trade evidence."}),(0,l.jsxs)("div",{className:"evidence-grid",style:{marginBottom:12},children:[l.jsx(x,{label:"Wins",value:eh?.wins??0}),l.jsx(x,{label:"Losses",value:eh?.losses??0}),l.jsx(x,{label:"Missed Entries",value:eh?.missed_entries??0}),l.jsx(x,{label:"Target Hits",value:eh?.target_hits??0}),l.jsx(x,{label:"Stop Hits",value:eh?.stop_hits??0}),l.jsx(x,{label:"No-Trade Correct",value:eh?.no_trade_correct??0})]}),(0,l.jsxs)("div",{className:"learning-table trade-ledger-table",children:[(0,l.jsxs)("div",{className:"learning-row trade-ledger-row head",children:[l.jsx("span",{children:"Ticker"}),l.jsx("span",{children:"Setup"}),l.jsx("span",{children:"Mode"}),l.jsx("span",{children:"Cycle"}),l.jsx("span",{children:"Entry"}),l.jsx("span",{children:"Exit"}),l.jsx("span",{children:"P/L EUR"}),l.jsx("span",{children:"P/L/share"}),l.jsx("span",{children:"R"}),l.jsx("span",{children:"Outcome"}),l.jsx("span",{children:"Quality"}),l.jsx("span",{children:"Excess"})]}),ep.slice(0,18).map(e=>(0,l.jsxs)("button",{className:"learning-row trade-ledger-row clickable",onClick:()=>e1(e.trade_id),children:[l.jsx("strong",{children:e.ticker}),l.jsx("span",{children:String(e.setup_type).replaceAll("_"," ")}),l.jsx("span",{children:String(e.mode??"historical").replaceAll("_"," ")}),l.jsx("span",{children:e.capital_cycle_id??"n/a"}),(0,l.jsxs)("span",{children:[e.entry_date,l.jsx("br",{}),_(e.entry_price)]}),(0,l.jsxs)("span",{children:[e.exit_date??"open",l.jsx("br",{}),_(e.exit_price)]}),l.jsx("span",{className:Number(e.net_pnl_eur)>=0?"positive-text":"negative-text",children:y(e.net_pnl_eur)}),l.jsx("span",{className:Number(e.pnl_per_share)>=0?"positive-text":"negative-text",children:_(e.pnl_per_share)}),l.jsx("span",{className:Number(e.r_multiple)>=0?"positive-text":"negative-text",children:_(e.r_multiple)}),l.jsx("span",{children:String(e.outcome_label??e.decision_state).replaceAll("_"," ")}),l.jsx("span",{children:_(e.trade_quality_score)}),l.jsx("span",{className:Number(e.excess_return_vs_benchmark)>=0?"positive-text":"negative-text",children:g(e.excess_return_vs_benchmark)})]},e.trade_id)),0===ep.length&&l.jsx("div",{className:"empty-state",children:"No detailed trade ledger is available yet. The next Trading Game run will enrich persisted trades with entry, exit, attribution, P/L and learning evidence."})]})]}),A&&(0,l.jsxs)("div",{className:"empty-state",style:{marginTop:12},children:["Trade detail error: ",A]}),q&&(0,l.jsxs)("section",{className:"panel trade-detail-panel",style:{marginTop:12},children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Trade Replay"}),l.jsx("button",{className:"button compact",onClick:()=>M(null),children:"Close"})]}),(0,l.jsxs)("div",{className:"grid-3",children:[(0,l.jsxs)("div",{className:"observed-model-panel",children:[l.jsx("span",{children:"Trade"}),(0,l.jsxs)("h3",{children:[q.trade?.ticker," / ",String(q.trade?.setup_type).replaceAll("_"," ")]}),l.jsx("p",{children:q.replay?.entry_decision?.why_considered}),l.jsx("p",{children:q.replay?.exit_decision?.reason})]}),(0,l.jsxs)("div",{className:"observed-model-panel",children:[l.jsx("span",{children:"P/L Breakdown"}),(0,l.jsxs)("div",{className:"evidence-grid",children:[l.jsx(x,{label:"Net P/L",value:y(q.pnl_breakdown?.net_pnl_eur)}),l.jsx(x,{label:"Per Share",value:_(q.pnl_breakdown?.pnl_per_share)}),l.jsx(x,{label:"R Multiple",value:_(q.pnl_breakdown?.r_multiple)}),l.jsx(x,{label:"Benchmark Excess",value:g(q.pnl_breakdown?.benchmark_relative_pnl)}),l.jsx(x,{label:"Fees",value:y(q.pnl_breakdown?.fees_estimate)}),l.jsx(x,{label:"Slippage",value:y(q.pnl_breakdown?.slippage_estimate)})]})]}),(0,l.jsxs)("div",{className:"observed-model-panel",children:[l.jsx("span",{children:"Risk Plan"}),(0,l.jsxs)("div",{className:"evidence-grid",children:[l.jsx(x,{label:"Capital Before",value:y(q.replay?.risk_management?.capital_before)}),l.jsx(x,{label:"Risk EUR",value:y(q.replay?.risk_management?.risk_amount_eur)}),l.jsx(x,{label:"Risk %",value:g(q.replay?.risk_management?.risk_percent)}),l.jsx(x,{label:"Size",value:_(q.replay?.risk_management?.position_size)}),l.jsx(x,{label:"Invalidation",value:_(q.replay?.risk_management?.invalidation_level)}),l.jsx(x,{label:"Max Loss",value:y(q.replay?.risk_management?.max_expected_loss)})]})]})]}),(0,l.jsxs)("section",{className:"grid-3",style:{marginTop:12},children:[(0,l.jsxs)("div",{className:"panel-inner",children:[l.jsx("span",{children:"Engine Attribution"}),l.jsx("div",{className:"brain-list dense",children:(q.attribution??[]).slice(0,6).map(e=>(0,l.jsxs)("div",{children:[l.jsx(h.O,{label:e.engine_name}),(0,l.jsxs)("strong",{children:[e.vote," | contribution ",_(e.contribution_score)]}),l.jsx("p",{children:e.explanation})]},e.id??e.engine_name))})]}),(0,l.jsxs)("div",{className:"panel-inner",children:[l.jsx("span",{children:"Trade Quality"}),l.jsx("p",{children:q.quality?.explanation}),(0,l.jsxs)("div",{className:"evidence-grid",children:[l.jsx(x,{label:"Final",value:_(q.quality?.final_trade_quality_score)}),l.jsx(x,{label:"Entry",value:_(q.quality?.entry_quality)}),l.jsx(x,{label:"Exit",value:_(q.quality?.exit_quality)}),l.jsx(x,{label:"Risk/Reward",value:_(q.quality?.risk_reward_quality)}),l.jsx(x,{label:"Rule",value:_(q.quality?.rule_compliance)}),l.jsx(x,{label:"Luck",value:_(q.quality?.luck_factor)})]})]}),(0,l.jsxs)("div",{className:"panel-inner",children:[l.jsx("span",{children:"Learning Outcome"}),(0,l.jsxs)("div",{className:"brain-list dense",children:[(q.learning_outcome??[]).slice(0,4).map(e=>(0,l.jsxs)("div",{children:[l.jsx(h.O,{label:String(e.lesson_type).replaceAll("_"," ")}),l.jsx("strong",{children:e.affected_module}),l.jsx("p",{children:e.observation})]},e.id)),(!q.learning_outcome||0===q.learning_outcome.length)&&l.jsx("div",{className:"empty-state compact",children:"No learning evidence is linked to this trade yet."})]})]})]})]}),(0,l.jsxs)("section",{className:"grid-3",style:{marginTop:12},children:[(0,l.jsxs)("div",{className:"panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Reality Check"}),l.jsx("strong",{children:eF?.statistical_confidence??"n/a"})]}),(0,l.jsxs)("div",{className:"evidence-grid",children:[l.jsx(x,{label:"Trades",value:eF?.trades_count??0}),l.jsx(x,{label:"Tickers",value:eF?.unique_tickers??0}),l.jsx(x,{label:"Sectors",value:eF?.unique_sectors??0}),l.jsx(x,{label:"Regimes",value:eF?.unique_regimes??0}),l.jsx(x,{label:"Sample",value:`${_(eF?.sample_quality_score)}/100`}),l.jsx(x,{label:"Realism",value:`${_(eF?.realism_score)}/100`})]}),l.jsx("p",{children:eF?.explanation??"Reality check will appear after trade transparency runs."}),(eF?.warnings??[]).length>0&&l.jsx("div",{className:"tag-row",children:eF.warnings.slice(0,8).map(e=>l.jsx("span",{children:e.replaceAll("_"," ")},e))})]}),(0,l.jsxs)("div",{className:"panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"P/L Breakdown"}),l.jsx("strong",{children:y(eG?.total_realized_pnl)})]}),(0,l.jsxs)("div",{className:"brain-list dense",children:[Object.entries(eG?.pnl_by_setup??{}).slice(0,5).map(([e,s])=>(0,l.jsxs)("div",{children:[(0,l.jsxs)("div",{className:"opportunity-line",children:[l.jsx("strong",{children:e.replaceAll("_"," ")}),l.jsx("span",{className:Number(s.pnl)>=0?"positive-text":"negative-text",children:y(s.pnl)})]}),(0,l.jsxs)("p",{children:["Count ",s.count," | average ",_(s.average_r),"R"]})]},e)),0===Object.keys(eG?.pnl_by_setup??{}).length&&l.jsx("div",{className:"empty-state compact",children:"No setup-level P/L breakdown yet."})]})]}),(0,l.jsxs)("div",{className:"panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Learning Evidence Log"}),l.jsx("strong",{children:eD.length})]}),(0,l.jsxs)("div",{className:"brain-list dense",children:[eD.slice(0,6).map(e=>(0,l.jsxs)("div",{children:[l.jsx(h.O,{label:String(e.lesson_type).replaceAll("_"," ")}),(0,l.jsxs)("strong",{children:[e.ticker," | ",String(e.setup_type).replaceAll("_"," ")]}),l.jsx("p",{children:e.observation})]},e.id)),0===eD.length&&l.jsx("div",{className:"empty-state compact",children:"No trade learning evidence has been persisted yet."})]})]})]}),(0,l.jsxs)("section",{className:"grid-3",style:{marginTop:12},children:[(0,l.jsxs)("div",{className:"panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Capital Cycle History"}),l.jsx("strong",{children:em.length})]}),(0,l.jsxs)("div",{className:"brain-list dense",children:[em.slice(0,6).map(e=>(0,l.jsxs)("div",{children:[l.jsx(h.O,{label:`Cycle ${e.cycle_number}`}),(0,l.jsxs)("div",{className:"opportunity-line",children:[l.jsx("strong",{children:String(e.status).replaceAll("_"," ")}),l.jsx("span",{children:y(e.final_capital)})]}),(0,l.jsxs)("p",{children:["Target ",y(e.target_capital)," | trades ",e.trades_count," | return ",g(e.return_percent)," | expectancy ",_(e.expectancy_r),"R"]})]},e.id)),0===em.length&&l.jsx("div",{className:"empty-state compact",children:"No capital cycle has been recorded yet."})]})]}),(0,l.jsxs)("div",{className:"panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Setup Development"}),l.jsx("strong",{children:eg.length})]}),(0,l.jsxs)("div",{className:"brain-list dense",children:[eg.slice(0,6).map(e=>(0,l.jsxs)("div",{children:[l.jsx(h.O,{label:String(e.scope_id).replaceAll("_"," ")}),(0,l.jsxs)("div",{className:"opportunity-line",children:[(0,l.jsxs)("strong",{children:[_(e.intelligence_growth_score),"/100 growth"]}),(0,l.jsxs)("span",{children:[_(e.expectancy_r),"R"]})]}),(0,l.jsxs)("p",{children:["Win ",j(e.win_rate)," | missed ",j(e.missed_entry_rate)," | quality ",_(e.trade_quality_score)]})]},e.scope_id)),0===eg.length&&l.jsx("div",{className:"empty-state compact",children:"No setup intelligence metrics yet."})]})]}),(0,l.jsxs)("div",{className:"panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Regime / Sector Learning"}),l.jsx("strong",{children:ev.length+e_.length})]}),(0,l.jsxs)("div",{className:"brain-list dense",children:[ev.slice(0,3).map(e=>(0,l.jsxs)("div",{children:[l.jsx(h.O,{label:`Regime ${e.scope_id}`}),(0,l.jsxs)("strong",{children:[_(e.intelligence_growth_score),"/100 | ",_(e.expectancy_r),"R"]}),(0,l.jsxs)("p",{children:["Benchmark excess ",g(e.benchmark_excess)," | trades ",e.trades_count]})]},`regime-${e.scope_id}`)),e_.slice(0,3).map(e=>(0,l.jsxs)("div",{children:[l.jsx(h.O,{label:`Sector ${e.scope_id}`}),(0,l.jsxs)("strong",{children:[_(e.intelligence_growth_score),"/100 | ",_(e.expectancy_r),"R"]}),(0,l.jsxs)("p",{children:["Benchmark excess ",g(e.benchmark_excess)," | trades ",e.trades_count]})]},`sector-${e.scope_id}`)),ev.length+e_.length===0&&l.jsx("div",{className:"empty-state compact",children:"No regime or sector learning metrics yet."})]})]})]}),X&&(0,l.jsxs)("section",{className:"grid-2",style:{marginTop:12},children:[(0,l.jsxs)("div",{className:"panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Regime-aware reliability"}),l.jsx("strong",{children:eX.length})]}),(0,l.jsxs)("div",{className:"learning-table",children:[(0,l.jsxs)("div",{className:"learning-row head",children:[l.jsx("span",{children:"Engine"}),l.jsx("span",{children:"Setup"}),l.jsx("span",{children:"Regime"}),l.jsx("span",{children:"Samples"}),l.jsx("span",{children:"Hit"}),l.jsx("span",{children:"Penalty"})]}),eX.slice(0,8).map(e=>(0,l.jsxs)("div",{className:"learning-row",children:[l.jsx("strong",{children:String(e.engine_name).replaceAll("_"," ")}),l.jsx("span",{children:String(e.setup_type).replaceAll("_"," ")}),l.jsx("span",{children:e.market_regime}),l.jsx("span",{children:e.sample_size}),l.jsx("span",{children:j(e.hit_rate)}),l.jsx("span",{children:_(e.confidence_penalty)})]},e.id)),0===eX.length&&l.jsx("div",{className:"empty-state",children:"No regime-specific reliability rows yet. BLUM needs matured thesis outcomes first."})]})]}),(0,l.jsxs)("div",{className:"panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Thesis competition and training quality"}),l.jsx("strong",{children:eJ.length})]}),(0,l.jsxs)("div",{className:"brain-list dense",children:[eJ.slice(0,5).map(e=>(0,l.jsxs)("div",{children:[l.jsx(h.O,{label:e.ticker}),l.jsx("strong",{children:e.judge_summary||"Competition pending"}),(0,l.jsxs)("p",{children:["Uncertainty ",_(e.uncertainty_score),"/100 | theses ",e.theses?.length??0]})]},e.id)),0===eJ.length&&l.jsx("div",{className:"empty-state",children:"No bull/bear/neutral thesis competitions yet."}),eK.slice(0,3).map(e=>(0,l.jsxs)("div",{children:[l.jsx(h.O,{label:"Training gate"}),(0,l.jsxs)("strong",{children:["Training value ",_(e.final_training_value_score),"/100"]}),(0,l.jsxs)("p",{children:["SFT ",String(e.include_in_sft)," | preference ",String(e.include_in_preference_training)," | DPO ",String(e.include_in_dpo)]})]},`quality-${e.id}`))]})]})]}),(0,l.jsxs)("section",{className:"grid-2",style:{marginTop:12},children:[l.jsx(p.G,{title:"Trading Game Equity Curve",data:e0,layout:{yaxis:{title:"Capital EUR"},xaxis:{title:"Simulation date"}}}),(0,l.jsxs)("div",{className:"panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Paper P/L and capital discipline"}),l.jsx("strong",{children:er?.status??"No game"})]}),er?(0,l.jsxs)("div",{className:"brain-list dense",children:[(0,l.jsxs)("div",{className:"evidence-grid",children:[l.jsx(x,{label:"Capital",value:y(er.current_capital)}),l.jsx(x,{label:"Realized P/L",value:y(er.realized_pl)}),l.jsx(x,{label:"Max Drawdown",value:`${_(er.max_drawdown)}%`}),l.jsx(x,{label:"Expectancy",value:`${_(er.expectancy_r)}R`}),l.jsx(x,{label:"Profit Factor",value:_(er.profit_factor)}),l.jsx(x,{label:"Risk of Ruin",value:`${_(er.risk_of_ruin)}%`}),l.jsx(x,{label:"Benchmark Alpha",value:`${_(eI?.alpha)}%`}),l.jsx(x,{label:"Reproducibility",value:`${_(eQ?.average_reproducibility)}/100`})]}),(0,l.jsxs)("p",{children:["BLUM starts each paper game at 100 EUR, risks fractionally, rejects non-reproducible setups and compares the equity curve against ",eI?.benchmark??er.benchmark_ticker,". Small samples never qualify as proof of outperformance."]})]}):l.jsx("div",{className:"empty-state",children:"No trading game has been created yet. The autonomous engine will start it after Sniper simulations are available."})]})]}),(0,l.jsxs)("section",{className:"grid-2",style:{marginTop:12},children:[(0,l.jsxs)("div",{className:"panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Recent reproducible trade decisions"}),l.jsx("strong",{children:eo.length})]}),(0,l.jsxs)("div",{className:"learning-table",children:[(0,l.jsxs)("div",{className:"learning-row head",children:[l.jsx("span",{children:"Ticker"}),l.jsx("span",{children:"Setup"}),l.jsx("span",{children:"Decision"}),l.jsx("span",{children:"R"}),l.jsx("span",{children:"P/L"}),l.jsx("span",{children:"Capital"})]}),eo.slice(0,12).map(e=>(0,l.jsxs)("div",{className:"learning-row",children:[l.jsx("strong",{children:e.ticker}),l.jsx("span",{children:String(e.setup_type).replaceAll("_"," ")}),l.jsx("span",{children:String(e.decision_state).replaceAll("_"," ")}),l.jsx("span",{className:Number(e.realized_r_multiple)>=0?"positive-text":"negative-text",children:_(e.realized_r_multiple)}),l.jsx("span",{className:Number(e.realized_pl)>=0?"positive-text":"negative-text",children:y(e.realized_pl)}),l.jsx("span",{children:y(e.capital_after)})]},e.id)),0===eo.length&&l.jsx("div",{className:"empty-state",children:"No P/L decisions yet. BLUM needs stored execution simulations before the game can score trades."})]})]}),(0,l.jsxs)("div",{className:"panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Capital management lessons"}),l.jsx("strong",{children:eH.length})]}),(0,l.jsxs)("div",{className:"brain-list dense",children:[eH.slice(0,8).map(e=>(0,l.jsxs)("div",{children:[l.jsx(h.O,{label:String(e.category).replaceAll("_"," ")}),l.jsx("strong",{children:e.lesson}),(0,l.jsxs)("p",{children:["Reliability ",_(e.reliability_score),"/100 | samples ",e.sample_count]})]},e.id)),0===eH.length&&l.jsx("div",{className:"empty-state",children:"No capital management lessons yet."})]})]})]}),(0,l.jsxs)("section",{className:"grid-2",style:{marginTop:12},children:[l.jsx(p.G,{title:"Walk-forward Accuracy by Horizon",data:eY,layout:{yaxis:{range:[0,100],title:"Accuracy %"},xaxis:{title:"Prediction horizon"}}}),(0,l.jsxs)("div",{className:"panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Latest autonomous run"}),l.jsx("strong",{children:ei?.status??"No run yet"})]}),ei?(0,l.jsxs)("div",{className:"brain-list dense",children:[(0,l.jsxs)("div",{children:[l.jsx(h.O,{label:ei.trigger??"scheduled"}),l.jsx("strong",{children:ei.run_id}),(0,l.jsxs)("p",{children:[b(ei.started_at)," to ",b(ei.completed_at)]})]}),(0,l.jsxs)("div",{className:"evidence-grid",children:[l.jsx(x,{label:"Predictions",value:ei.predictions_created}),l.jsx(x,{label:"Outcomes",value:ei.outcomes_evaluated}),l.jsx(x,{label:"Mistakes",value:ei.mistakes_found}),l.jsx(x,{label:"Memory Updates",value:ei.memory_updates})]}),l.jsx("p",{children:ei.anti_overfitting_report?.policy??a?.policy??"Learning Loop policy will appear after the dashboard snapshot loads."})]}):l.jsx("div",{className:"empty-state",children:"The scheduler is active but no point-in-time learning run has been persisted yet."})]})]}),(0,l.jsxs)("section",{className:"grid-2",style:{marginTop:12},children:[(0,l.jsxs)("div",{className:"panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Signal reliability memory"}),l.jsx("strong",{children:ea.length})]}),(0,l.jsxs)("div",{className:"learning-table",children:[(0,l.jsxs)("div",{className:"learning-row head",children:[l.jsx("span",{children:"Factor"}),l.jsx("span",{children:"TF"}),l.jsx("span",{children:"Regime"}),l.jsx("span",{children:"Samples"}),l.jsx("span",{children:"Reliability"}),l.jsx("span",{children:"False +"})]}),ea.slice(0,12).map(e=>(0,l.jsxs)("div",{className:"learning-row",children:[l.jsx("strong",{children:e.signal_name?.replaceAll("_"," ")}),l.jsx("span",{children:e.timeframe}),l.jsx("span",{children:e.market_regime}),l.jsx("span",{children:e.sample_count}),l.jsx("span",{className:function(e){let s=Number(e);return s>=65?"positive-text":s<=42?"negative-text":""}(e.reliability_score),children:_(e.reliability_score)}),l.jsx("span",{children:e.false_positive_count})]},`${e.signal_name}-${e.timeframe}-${e.market_regime}`)),0===ea.length&&l.jsx("div",{className:"empty-state",children:"No signal reliability rows yet. The first learning batches will populate this table."})]})]}),(0,l.jsxs)("div",{className:"panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Mistake taxonomy"}),l.jsx("strong",{children:en.length})]}),(0,l.jsxs)("div",{className:"brain-list dense",children:[en.slice(0,12).map(e=>(0,l.jsxs)("div",{children:[(0,l.jsxs)("div",{className:"opportunity-line",children:[l.jsx("strong",{children:String(e.error_type).replaceAll("_"," ")}),l.jsx("span",{children:e.count})]}),l.jsx("p",{children:"Repeated error class used to reduce future overconfidence and improve factor weighting."})]},e.error_type)),0===en.length&&l.jsx("div",{className:"empty-state",children:"No classified mistakes yet. This is expected before enough simulated outcomes mature."})]})]})]}),(0,l.jsxs)("section",{className:"grid-2",style:{marginTop:12},children:[(0,l.jsxs)("div",{className:"panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Strategy memory"}),l.jsx("strong",{children:el.length})]}),(0,l.jsxs)("div",{className:"brain-list",children:[el.slice(0,10).map(e=>(0,l.jsxs)("div",{children:[l.jsx(h.O,{label:e.category}),l.jsx("strong",{children:e.lesson}),(0,l.jsxs)("p",{children:["Reliability ",_(e.reliability_score),"/100 | samples ",e.sample_count," | positive ",e.positive_count," | negative ",e.negative_count]})]},e.memory_key)),0===el.length&&l.jsx("div",{className:"empty-state",children:"No strategy memory has been learned yet."})]})]}),(0,l.jsxs)("div",{className:"panel",children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Recent point-in-time predictions"}),l.jsx("strong",{children:k.length})]}),(0,l.jsxs)("div",{className:"learning-table predictions",children:[(0,l.jsxs)("div",{className:"learning-row head",children:[l.jsx("span",{children:"Ticker"}),l.jsx("span",{children:"Date"}),l.jsx("span",{children:"Regime"}),l.jsx("span",{children:"Direction"}),l.jsx("span",{children:"Confidence"}),l.jsx("span",{children:"Quality"})]}),k.slice(0,14).map(e=>(0,l.jsxs)("div",{className:"learning-row",children:[l.jsx("strong",{children:e.ticker}),l.jsx("span",{children:e.analysis_date}),l.jsx("span",{children:e.market_regime}),l.jsx("span",{children:e.expected_direction}),l.jsx("span",{children:_(e.confidence)}),l.jsx("span",{children:_(e.data_quality_score)})]},e.id)),0===k.length&&l.jsx("div",{className:"empty-state",children:"No historical predictions persisted yet."})]})]})]}),(0,l.jsxs)("section",{className:"panel",style:{marginTop:12},children:[(0,l.jsxs)("div",{className:"panel-head",children:[l.jsx("span",{children:"Governance and anti-overfitting"}),l.jsx("strong",{children:"Research only"})]}),(0,l.jsxs)("div",{className:"method-grid",children:[l.jsx(x,{label:"Asset Universe",value:a?.configuration?.asset_universe??"stocks,etfs"}),l.jsx(x,{label:"Min History",value:`${a?.configuration?.min_history_years??"n/a"} years`}),l.jsx(x,{label:"Daily Guard",value:a?.configuration?.max_daily_runs??"n/a"}),l.jsx(x,{label:"Batch Size",value:a?.configuration?.batch_size??"n/a"})]}),l.jsx("p",{children:a?.policy??"Progressive loading is active. Deep learning details load after the lightweight summary and visible tables."}),l.jsx("p",{children:"Every prediction stores the simulated date, hidden future policy, horizons, confidence, outcomes and mistake analysis. The loop updates parameters and memory only; it does not execute trades and does not self-modify source code."})]})]})}function u({icon:e,label:s,value:a,subvalue:n}){return(0,l.jsxs)("div",{className:"metric-card",children:[(0,l.jsxs)("span",{className:"metric-label-icon",children:[e,s]}),l.jsx("strong",{children:a}),l.jsx("p",{children:n})]})}function x({label:e,value:s}){return(0,l.jsxs)("div",{children:[l.jsx("span",{children:e}),l.jsx("strong",{children:s??"n/a"})]})}function j(e){return null==e?"n/a":`${(100*Number(e)).toFixed(1)}%`}function g(e){return null==e||Number.isNaN(Number(e))?"n/a":`${Number(e).toFixed(2)}%`}function v(e){let s=Number(e?.final_capital??0),a=Number(e?.target_capital??0);return Number.isFinite(s)&&Number.isFinite(a)&&!(a<=0)?Math.max(0,Math.min(100,s/a*100)):0}function _(e){return null==e||Number.isNaN(Number(e))?"n/a":Number(e).toFixed(2)}function y(e){return null==e||Number.isNaN(Number(e))?"n/a":`${Number(e).toFixed(2)} EUR`}function b(e){return e?new Date(e).toLocaleString():"n/a"}},7749:(e,s,a)=>{"use strict";a.d(s,{G:()=>c});var l=a(8924),n=a(1328),i=a.n(n),r=a(3911);let t=i()(async()=>{},{loadableGenerated:{modules:["components/PlotPanel.tsx -> react-plotly.js"]},ssr:!1});function c({title:e,data:s,layout:a={},height:n=360,emptyMessage:i="Waiting for real data series."}){let c=s.some(e=>[e?.x,e?.y,e?.z,e?.values,e?.labels].filter(Array.isArray).some(e=>!!e.length&&(!Array.isArray(e[0])||e.some(e=>Array.isArray(e)&&e.length>0)))),d={data:s,layout:{autosize:!0,height:n,paper_bgcolor:"#07090d",plot_bgcolor:"#090d13",font:{color:"#e7edf6",family:"Inter, system-ui, sans-serif"},margin:{l:42,r:18,t:18,b:36},xaxis:{gridcolor:"rgba(255,255,255,.06)",zeroline:!1},yaxis:{gridcolor:"rgba(255,255,255,.06)",zeroline:!1},...a},config:{displayModeBar:!1,responsive:!0},useResizeHandler:!0,style:{width:"100%"}};return(0,l.jsxs)("section",{className:"panel",children:[l.jsx("div",{className:"panel-head",children:l.jsx("span",{children:e})}),c?(0,r.createElement)(t,d):l.jsx("div",{className:"plot-empty",children:i})]})}},3081:(e,s,a)=>{"use strict";a.d(s,{O:()=>i});var l=a(8924),n=a(9779);function i({label:e}){let s=e.includes("Breakout")||e.includes("Strong")?"positive":e.includes("Risk")||e.includes("Avoid")?"negative":e.includes("Divergence")||e.includes("Contrarian")?"warning":"neutral";return l.jsx("span",{className:(0,n.Z)("status-badge",s),children:e})}},741:(e,s,a)=>{"use strict";a.d(s,{Z:()=>l});let l=(0,a(6745).Z)("TriangleAlert",[["path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",key:"wmoenq"}],["path",{d:"M12 9v4",key:"juzpu7"}],["path",{d:"M12 17h.01",key:"p32p05"}]])},1328:(e,s,a)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0}),Object.defineProperty(s,"default",{enumerable:!0,get:function(){return i}});let l=a(1607);a(8924),a(3911);let n=l._(a(4737));function i(e,s){var a;let l={loading:e=>{let{error:s,isLoading:a,pastDelay:l}=e;return null}};"function"==typeof e&&(l.loader=e);let i={...l,...s};return(0,n.default)({...i,modules:null==(a=i.loadableGenerated)?void 0:a.modules})}("function"==typeof s.default||"object"==typeof s.default&&null!==s.default)&&void 0===s.default.__esModule&&(Object.defineProperty(s.default,"__esModule",{value:!0}),Object.assign(s.default,s),e.exports=s.default)},3880:(e,s,a)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0}),Object.defineProperty(s,"BailoutToCSR",{enumerable:!0,get:function(){return n}});let l=a(6483);function n(e){let{reason:s,children:a}=e;throw new l.BailoutToCSRError(s)}},4737:(e,s,a)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0}),Object.defineProperty(s,"default",{enumerable:!0,get:function(){return d}});let l=a(8924),n=a(3911),i=a(3880),r=a(7083);function t(e){return{default:e&&"default"in e?e.default:e}}let c={loader:()=>Promise.resolve(t(()=>null)),loading:null,ssr:!0},d=function(e){let s={...c,...e},a=(0,n.lazy)(()=>s.loader().then(t)),d=s.loading;function o(e){let t=d?(0,l.jsx)(d,{isLoading:!0,pastDelay:!0,error:null}):null,c=s.ssr?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(r.PreloadCss,{moduleIds:s.modules}),(0,l.jsx)(a,{...e})]}):(0,l.jsx)(i.BailoutToCSR,{reason:"next/dynamic",children:(0,l.jsx)(a,{...e})});return(0,l.jsx)(n.Suspense,{fallback:t,children:c})}return o.displayName="LoadableComponent",o}},7083:(e,s,a)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0}),Object.defineProperty(s,"PreloadCss",{enumerable:!0,get:function(){return i}});let l=a(8924),n=a(4580);function i(e){let{moduleIds:s}=e,a=(0,n.getExpectedRequestStore)("next/dynamic css"),i=[];if(a.reactLoadableManifest&&s){let e=a.reactLoadableManifest;for(let a of s){if(!e[a])continue;let s=e[a].files.filter(e=>e.endsWith(".css"));i.push(...s)}}return 0===i.length?null:(0,l.jsx)(l.Fragment,{children:i.map(e=>(0,l.jsx)("link",{precedence:"dynamic",rel:"stylesheet",href:a.assetPrefix+"/_next/"+encodeURI(e),as:"style"},e))})}},2071:(e,s,a)=>{"use strict";a.r(s),a.d(s,{default:()=>l});let l=(0,a(6691).createProxy)(String.raw`/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/learning/page.tsx#default`)}};var s=require("../../webpack-runtime.js");s.C(e);var a=e=>s(s.s=e),l=s.X(0,[273,394],()=>a(6050));module.exports=l})();
\ No newline at end of file
diff --git a/frontend/.next/server/app/learning/page.js.nft.json b/frontend/.next/server/app/learning/page.js.nft.json
new file mode 100644
index 0000000000000000000000000000000000000000..877e4e935689e2063c7f370e14175cea6de0d164
--- /dev/null
+++ b/frontend/.next/server/app/learning/page.js.nft.json
@@ -0,0 +1 @@
+{"version":1,"files":["../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/package.json","../../../../node_modules/next","../../../../package.json","../../../package.json","../../chunks/273.js","../../chunks/394.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}
\ No newline at end of file
diff --git a/frontend/.next/server/app/learning/page_client-reference-manifest.js b/frontend/.next/server/app/learning/page_client-reference-manifest.js
new file mode 100644
index 0000000000000000000000000000000000000000..d3bb52366ed8a0deca81a884b8a3dce3965dc681
--- /dev/null
+++ b/frontend/.next/server/app/learning/page_client-reference-manifest.js
@@ -0,0 +1 @@
+globalThis.__RSC_MANIFEST=(globalThis.__RSC_MANIFEST||{});globalThis.__RSC_MANIFEST["/learning/page"]={"moduleLoading":{"prefix":"/_next/","crossOrigin":null},"ssrModuleMapping":{"176":{"*":{"id":"6676","name":"*","chunks":[],"async":false}},"841":{"*":{"id":"9737","name":"*","chunks":[],"async":false}},"892":{"*":{"id":"5213","name":"*","chunks":[],"async":false}},"2010":{"*":{"id":"7619","name":"*","chunks":[],"async":false}},"2433":{"*":{"id":"6544","name":"*","chunks":[],"async":false}},"2651":{"*":{"id":"9645","name":"*","chunks":[],"async":false}},"2987":{"*":{"id":"1358","name":"*","chunks":[],"async":false}},"3713":{"*":{"id":"5210","name":"*","chunks":[],"async":false}},"4374":{"*":{"id":"9927","name":"*","chunks":[],"async":false}},"6056":{"*":{"id":"1309","name":"*","chunks":[],"async":false}},"6543":{"*":{"id":"9722","name":"*","chunks":[],"async":false}},"6813":{"*":{"id":"5877","name":"*","chunks":[],"async":false}},"7096":{"*":{"id":"1952","name":"*","chunks":[],"async":false}},"7413":{"*":{"id":"8052","name":"*","chunks":[],"async":false}},"7523":{"*":{"id":"3477","name":"*","chunks":[],"async":false}},"7768":{"*":{"id":"7663","name":"*","chunks":[],"async":false}},"8145":{"*":{"id":"8377","name":"*","chunks":[],"async":false}},"8528":{"*":{"id":"5116","name":"*","chunks":[],"async":false}},"8547":{"*":{"id":"5441","name":"*","chunks":[],"async":false}},"9135":{"*":{"id":"432","name":"*","chunks":[],"async":false}},"9239":{"*":{"id":"8132","name":"*","chunks":[],"async":false}},"9414":{"*":{"id":"8850","name":"*","chunks":[],"async":false}},"9570":{"*":{"id":"291","name":"*","chunks":[],"async":false}}},"edgeSSRModuleMapping":{},"clientModules":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/globals.css":{"id":4443,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/components/AppShell.tsx":{"id":6813,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/backtest/page.tsx":{"id":4374,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chart-analyst/page.tsx":{"id":6543,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chat/page.tsx":{"id":841,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chatbot/page.tsx":{"id":8145,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/learning/page.tsx":{"id":6056,"name":"*","chunks":["651","static/chunks/651-5689242ae9b0ffc6.js","934","static/chunks/app/learning/page-fb9d9a3de58b413d.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/methodology/page.tsx":{"id":7413,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/ipo-radar/page.tsx":{"id":9135,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/market-brain/page.tsx":{"id":2987,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page.tsx":{"id":892,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/dashboard/page.tsx":{"id":7096,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","96","static/chunks/96-ce8c57cd15d50941.js","931","static/chunks/app/page-d0db9a93fb4af9a5.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/etf-radar/page.tsx":{"id":9239,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/performance/page.tsx":{"id":8547,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/signal-lab/page.tsx":{"id":2010,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/sniper/page.tsx":{"id":7768,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/stock-radar/page.tsx":{"id":9570,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/assets/[ticker]/view.tsx":{"id":3713,"name":"*","chunks":[],"async":false}},"entryCSSFiles":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout":["static/css/02bd12e03544ea91.css"],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/page":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/learning/page":[]}}
\ No newline at end of file
diff --git a/frontend/.next/server/app/market-brain.html b/frontend/.next/server/app/market-brain.html
new file mode 100644
index 0000000000000000000000000000000000000000..1527f99635c7f2cd3c2e26eed34807d7cfd9660c
--- /dev/null
+++ b/frontend/.next/server/app/market-brain.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading Market Brain
\ No newline at end of file
diff --git a/frontend/.next/server/app/market-brain.meta b/frontend/.next/server/app/market-brain.meta
new file mode 100644
index 0000000000000000000000000000000000000000..f2a3387ca9f892bca284b5714fcfa438ca0a2cf8
--- /dev/null
+++ b/frontend/.next/server/app/market-brain.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/market-brain/layout,_N_T_/market-brain/page,_N_T_/market-brain/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/market-brain.rsc b/frontend/.next/server/app/market-brain.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..d70803a5e25be5fbd002e8805181c0e6d1c16d65
--- /dev/null
+++ b/frontend/.next/server/app/market-brain.rsc
@@ -0,0 +1,8 @@
+2:I[7523,[],"ClientPageRoot"]
+3:I[2987,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","653","static/chunks/app/market-brain/page-a3c75d13701833bc.js"],"default",1]
+4:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["market-brain",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["market-brain",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","market-brain","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/market-brain/page.js b/frontend/.next/server/app/market-brain/page.js
new file mode 100644
index 0000000000000000000000000000000000000000..8b84f9601978294ee00aa7957e52ddacd82d653a
--- /dev/null
+++ b/frontend/.next/server/app/market-brain/page.js
@@ -0,0 +1 @@
+(()=>{var e={};e.id=653,e.ids=[653],e.modules={2934:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external.js")},4580:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external.js")},5869:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},399:e=>{"use strict";e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},4123:(e,s,n)=>{"use strict";n.r(s),n.d(s,{GlobalError:()=>t.a,__next_app__:()=>h,originalPathname:()=>p,pages:()=>o,routeModule:()=>m,tree:()=>d}),n(3733),n(8777),n(311);var i=n(9296),a=n(1650),r=n(7045),t=n.n(r),l=n(8184),c={};for(let e in l)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(c[e]=()=>l[e]);n.d(s,c);let d=["",{children:["market-brain",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(n.bind(n,3733)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/market-brain/page.tsx"]}]},{}]},{layout:[()=>Promise.resolve().then(n.bind(n,8777)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout.tsx"],"not-found":[()=>Promise.resolve().then(n.t.bind(n,311,23)),"next/dist/client/components/not-found-error"]}],o=["/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/market-brain/page.tsx"],p="/market-brain/page",h={require:n,loadChunk:()=>Promise.resolve()},m=new i.AppPageRouteModule({definition:{kind:a.x.APP_PAGE,page:"/market-brain/page",pathname:"/market-brain",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:d}})},3489:(e,s,n)=>{Promise.resolve().then(n.bind(n,1358))},1358:(e,s,n)=>{"use strict";n.r(s),n.d(s,{default:()=>p});var i=n(8924),a=n(2828),r=n(3911);n(3789);var t=n(398),l=n(6927),c=n(2522),d=n(7749),o=n(3081);function p(){let[e,s]=(0,r.useState)(null),[n,a]=(0,r.useState)([]),[t,p]=(0,r.useState)("");if(t)return(0,i.jsxs)("div",{className:"empty-state",children:["API error: ",t]});if(!e)return i.jsx(c.G,{label:"Loading Market Brain"});let j=e.opportunity_stack,g=e.forward_scenarios.map(e=>e.name.replace(/^.*?:\s*/,"")),v=e.forward_scenarios.map(e=>e.probability_proxy);return(0,i.jsxs)(i.Fragment,{children:[i.jsx(l.ft,{eyebrow:"Market Brain",title:"System intelligence and reasoning layer.",subtitle:"A task-routed AI engine that separates market data, sentiment, technical evidence, memory, confidence and explanations.",statusItems:[{label:"Regime",value:e.regime,tone:"attention"},{label:"Brain score",value:e.brain_score.toFixed(1),tone:"positive"},{label:"Mode",value:e.data_mode},{label:"Snapshot",value:u(e.created_at),tone:"info"}]}),(0,i.jsxs)("section",{className:"brain-hero",children:[(0,i.jsxs)("div",{children:[i.jsx("span",{children:"Current regime"}),i.jsx("h2",{children:i.jsx(l.VL,{regime:e.regime})}),i.jsx("p",{children:e.summary}),(0,i.jsxs)("div",{className:"tag-row",children:[i.jsx("span",{children:e.data_mode}),i.jsx("span",{children:e.horizon}),i.jsx("span",{children:u(e.created_at)})]})]}),(0,i.jsxs)("div",{className:"brain-score",children:[i.jsx("span",{children:"Blum Market Brain Score"}),i.jsx("strong",{children:e.brain_score.toFixed(1)}),i.jsx("p",{children:"Composite evidence score derived from signals, sentiment, coverage, news intensity and IPO/pre-listing evidence."})]})]}),(0,i.jsxs)("section",{className:"market-brain-system-grid",style:{marginTop:12},children:[(0,i.jsxs)(l.Ez,{title:"AI Reasoning Layer",value:e.financial_brain?.model_status??"configured",subtitle:e.financial_brain?.configured_model??"Financial model",children:[i.jsx("p",{children:e.financial_brain?.thesis??"Financial Brain analysis is waiting for a Market Brain packet."}),i.jsx(l.IL,{value:e.financial_brain?.confidence?.score,label:e.financial_brain?.confidence?.label??"Reasoning confidence"})]}),i.jsx(l.i9,{label:"Evidence Coverage",value:e.evidence_ledger.price_rows??"n/a",subvalue:"Stored OHLCV rows"}),i.jsx(l.i9,{label:"News Coverage",value:e.market_now.news_count_48h,subvalue:"48h public evidence"}),i.jsx(l.i9,{label:"Fallback Mode",value:e.financial_brain?.model_status?.includes("fallback")?"Active":"Standby",subvalue:e.financial_brain?.evidence_policy??"Evidence-bound generation",tone:e.financial_brain?.model_status?.includes("fallback")?"attention":"positive"})]}),(0,i.jsxs)("section",{className:"grid-4",style:{marginTop:12},children:[i.jsx(m,{label:"Assets",value:e.market_now.asset_count}),i.jsx(m,{label:"Signals",value:e.market_now.signal_count}),i.jsx(m,{label:"48h News",value:e.market_now.news_count_48h}),i.jsx(m,{label:"Sentiment",value:e.market_now.average_sentiment.toFixed(2)})]}),(0,i.jsxs)("section",{className:"grid-2",style:{marginTop:12},children:[i.jsx(d.G,{title:"Forward Scenario Weights",data:[{x:v,y:g,type:"bar",orientation:"h",marker:{color:["#55aaff","#20e070","#ff4d5e"]}}],layout:{xaxis:{range:[0,100],title:"Probability proxy"}}}),i.jsx(d.G,{title:"Theme Sentiment Map",data:[{x:e.market_now.top_themes.map(e=>e.headline_count),y:e.market_now.top_themes.map(e=>e.avg_sentiment),text:e.market_now.top_themes.map(e=>e.theme),type:"scatter",mode:"markers+text",marker:{size:e.market_now.top_themes.map(e=>Math.max(10,3*e.headline_count)),color:"#ffb000"}}],layout:{xaxis:{title:"Headline count"},yaxis:{title:"Avg sentiment"}}})]}),i.jsx("section",{className:"scenario-grid",style:{marginTop:12},children:e.forward_scenarios.map(e=>(0,i.jsxs)("article",{className:"panel scenario-card",children:[(0,i.jsxs)("div",{className:"panel-head",children:[i.jsx("span",{children:e.time_horizon}),(0,i.jsxs)("strong",{children:[e.probability_proxy,"%"]})]}),i.jsx("h3",{children:e.name}),i.jsx("div",{className:"scenario-list",children:e.drivers.map(e=>i.jsx("p",{children:e},e))}),i.jsx("div",{className:"tag-row",children:e.watch_points.slice(0,3).map(e=>i.jsx("span",{children:e},e))})]},e.name))}),(0,i.jsxs)("section",{className:"panel",style:{marginTop:12},children:[(0,i.jsxs)("div",{className:"panel-head",children:[i.jsx("span",{children:"Blum Financial Brain"}),i.jsx("strong",{children:e.financial_brain?.model_name??e.financial_brain?.configured_model??"financial brain"})]}),(0,i.jsxs)("div",{className:"financial-brain-grid",children:[(0,i.jsxs)("div",{className:"financial-brain-thesis",children:[i.jsx("span",{children:e.financial_brain?.model_status??"model status pending"}),(0,i.jsxs)("h3",{children:[e.financial_brain?.confidence?.label??"Evidence"," Confidence ",e.financial_brain?.confidence?.score??"n/a"]}),i.jsx("p",{children:e.financial_brain?.thesis??"Financial Brain analysis is waiting for a Market Brain packet."}),i.jsx("p",{children:e.financial_brain?.evidence_policy})]}),i.jsx(h,{title:"Opportunity hypotheses",rows:e.financial_brain?.opportunity_hypotheses??[]}),i.jsx(h,{title:"Risk hypotheses",rows:e.financial_brain?.risk_hypotheses??[]}),i.jsx(h,{title:"Monitoring plan",rows:e.financial_brain?.monitoring_plan??[]})]})]}),(0,i.jsxs)("section",{className:"grid-2",style:{marginTop:12},children:[(0,i.jsxs)("div",{className:"panel",children:[(0,i.jsxs)("div",{className:"panel-head",children:[i.jsx("span",{children:"Brain changelog"}),i.jsx("strong",{children:e.change_log.length})]}),i.jsx("div",{className:"brain-list",children:e.change_log.map(e=>(0,i.jsxs)("div",{children:[i.jsx(o.O,{label:e.severity}),i.jsx("strong",{children:e.type.replaceAll("_"," ")}),i.jsx("p",{children:e.message})]},`${e.type}-${e.message}`))})]}),(0,i.jsxs)("div",{className:"panel",children:[(0,i.jsxs)("div",{className:"panel-head",children:[i.jsx("span",{children:"Contradiction engine"}),i.jsx("strong",{children:e.contradictions.length})]}),(0,i.jsxs)("div",{className:"brain-list",children:[0===e.contradictions.length&&i.jsx("div",{className:"empty-state",children:"No material price, sentiment or risk contradictions detected."}),e.contradictions.slice(0,8).map(e=>(0,i.jsxs)("div",{children:[i.jsx(o.O,{label:e.severity}),i.jsx("strong",{children:e.title}),i.jsx("span",{children:Object.entries(e.evidence).map(([e,s])=>`${e} ${s}`).join(" | ")})]},`${e.type}-${e.ticker}-${e.title}`))]})]})]}),(0,i.jsxs)("section",{className:"grid-3",style:{marginTop:12},children:[i.jsx(x,{title:"Stock research priorities",rows:j.stock_research_priorities,kind:"stock"}),i.jsx(x,{title:"ETF rotation leaders",rows:j.etf_rotation_leaders,kind:"etf"}),i.jsx(x,{title:"IPO / pre-listing watch",rows:j.ipo_watch,kind:"ipo"})]}),(0,i.jsxs)("section",{className:"grid-2",style:{marginTop:12},children:[(0,i.jsxs)("div",{className:"panel",children:[(0,i.jsxs)("div",{className:"panel-head",children:[i.jsx("span",{children:"Event graph"}),(0,i.jsxs)("strong",{children:[e.event_graph.nodes.length," nodes"]})]}),i.jsx("div",{className:"event-graph",children:e.event_graph.nodes.slice(0,28).map(e=>(0,i.jsxs)("div",{className:`event-node ${e.type}`,children:[i.jsx("span",{children:e.type}),i.jsx("strong",{children:e.label}),void 0!==e.score&&null!==e.score&&i.jsx("em",{children:Number(e.score).toFixed(1)})]},e.id))})]}),(0,i.jsxs)("div",{className:"panel",children:[(0,i.jsxs)("div",{className:"panel-head",children:[i.jsx("span",{children:"Snapshot history"}),i.jsx("strong",{children:n.length})]}),(0,i.jsxs)("div",{className:"brain-list dense",children:[0===n.length&&i.jsx("div",{className:"empty-state",children:"No persisted Market Brain snapshots yet. The autonomous reasoning cycle is building the first durable snapshot."}),n.map(e=>(0,i.jsxs)("div",{children:[(0,i.jsxs)("div",{className:"opportunity-line",children:[i.jsx("strong",{children:e.regime}),i.jsx("span",{children:Number(e.brain_score).toFixed(1)})]}),(0,i.jsxs)("p",{children:[u(e.created_at)," | risk ",e.risk_alert_count," | contradictions ",e.contradiction_count]}),(0,i.jsxs)("span",{children:["Top: ",e.top_stock??"n/a"," | ETF ",e.top_etf??"n/a"," | IPO ",e.top_ipo??"n/a"]})]},e.run_id))]})]})]}),(0,i.jsxs)("section",{className:"grid-2",style:{marginTop:12},children:[(0,i.jsxs)("div",{className:"panel",children:[(0,i.jsxs)("div",{className:"panel-head",children:[i.jsx("span",{children:"Risk alerts"}),i.jsx("strong",{children:e.risk_alerts.length})]}),(0,i.jsxs)("div",{className:"brain-list",children:[0===e.risk_alerts.length&&i.jsx("div",{className:"empty-state",children:"No active risk alerts from the stored evidence set."}),e.risk_alerts.map(e=>(0,i.jsxs)("div",{children:[i.jsx(o.O,{label:e.severity}),i.jsx("strong",{children:e.title}),i.jsx("p",{children:e.detail}),!!e.tickers.length&&i.jsx("span",{children:e.tickers.join(" | ")})]},`${e.title}-${e.severity}`))]})]}),(0,i.jsxs)("div",{className:"panel",children:[(0,i.jsxs)("div",{className:"panel-head",children:[i.jsx("span",{children:"Evidence ledger"}),i.jsx("strong",{children:"Audit trail"})]}),i.jsx("div",{className:"evidence-grid",children:Object.entries(e.evidence_ledger).map(([e,s])=>(0,i.jsxs)("div",{children:[i.jsx("span",{children:e.replaceAll("_"," ")}),i.jsx("strong",{children:String(s)})]},e))}),i.jsx("p",{children:e.disclaimer})]})]}),(0,i.jsxs)("section",{className:"panel",style:{marginTop:12},children:[(0,i.jsxs)("div",{className:"panel-head",children:[i.jsx("span",{children:"Model stack"}),i.jsx("strong",{children:"Task-routed AI"})]}),i.jsx("div",{className:"method-grid",children:Object.entries(e.model_stack).map(([e,s])=>(0,i.jsxs)("div",{children:[i.jsx("span",{children:e}),i.jsx("strong",{children:s})]},e))})]})]})}function h({title:e,rows:s}){return(0,i.jsxs)("div",{className:"observed-model-panel",children:[(0,i.jsxs)("div",{className:"panel-head",children:[i.jsx("span",{children:e}),i.jsx("strong",{children:s.length})]}),(0,i.jsxs)("div",{className:"brain-list dense",children:[!s.length&&i.jsx("div",{className:"empty-state",children:"No rows generated yet."}),s.slice(0,5).map((s,n)=>(0,i.jsxs)("div",{children:[i.jsx("strong",{children:s.title??s.item??s.metric??"Evidence row"}),i.jsx("p",{children:s.why_it_matters??s.metric??s.cadence??""}),s.evidence_refs&&i.jsx("span",{children:s.evidence_refs.join(" | ")})]},`${e}-${n}`))]})]})}function m({label:e,value:s}){return(0,i.jsxs)("div",{className:"metric-card",children:[i.jsx("span",{children:e}),i.jsx("strong",{children:s})]})}function x({title:e,rows:s,kind:n}){return(0,i.jsxs)("div",{className:"panel opportunity-panel",children:[(0,i.jsxs)("div",{className:"panel-head",children:[i.jsx("span",{children:e}),i.jsx("strong",{children:s.length})]}),(0,i.jsxs)("div",{className:"brain-list dense",children:[0===s.length&&i.jsx("div",{className:"empty-state",children:"No evidence-backed rows are available yet."}),s.slice(0,8).map((s,r)=>{var l;return(0,i.jsxs)("div",{children:[(0,i.jsxs)("div",{className:"opportunity-line",children:["stock"===n&&s.ticker?i.jsx(a.default,{href:(0,t.up)(s.ticker),children:s.ticker}):i.jsx("strong",{children:s.ticker??s.name}),i.jsx("span",{children:null==(l=s.score??s.confirmation_score??s.opportunity_score)?"n/a":Number(l).toFixed(1)})]}),i.jsx("p",{children:s.name??s.category??s.classification}),(0,i.jsxs)("div",{className:"tag-row",children:[s.classification&&i.jsx("span",{children:s.classification}),s.research_priority&&i.jsx("span",{children:s.research_priority}),s.risk_level&&i.jsx("span",{children:s.risk_level}),s.latest_form&&i.jsx("span",{children:s.latest_form})]})]},`${e}-${s.ticker??s.name}-${r}`)})]})]})}function u(e){return e?new Intl.DateTimeFormat("en",{month:"short",day:"2-digit",hour:"2-digit",minute:"2-digit"}).format(new Date(e)):"Pending"}},2522:(e,s,n)=>{"use strict";n.d(s,{G:()=>a});var i=n(8924);function a({label:e="Loading intelligence snapshot"}){return(0,i.jsxs)("div",{className:"loading-state",children:[i.jsx("div",{}),i.jsx("span",{children:e})]})}},7749:(e,s,n)=>{"use strict";n.d(s,{G:()=>c});var i=n(8924),a=n(1328),r=n.n(a),t=n(3911);let l=r()(async()=>{},{loadableGenerated:{modules:["components/PlotPanel.tsx -> react-plotly.js"]},ssr:!1});function c({title:e,data:s,layout:n={},height:a=360,emptyMessage:r="Waiting for real data series."}){let c=s.some(e=>[e?.x,e?.y,e?.z,e?.values,e?.labels].filter(Array.isArray).some(e=>!!e.length&&(!Array.isArray(e[0])||e.some(e=>Array.isArray(e)&&e.length>0)))),d={data:s,layout:{autosize:!0,height:a,paper_bgcolor:"#07090d",plot_bgcolor:"#090d13",font:{color:"#e7edf6",family:"Inter, system-ui, sans-serif"},margin:{l:42,r:18,t:18,b:36},xaxis:{gridcolor:"rgba(255,255,255,.06)",zeroline:!1},yaxis:{gridcolor:"rgba(255,255,255,.06)",zeroline:!1},...n},config:{displayModeBar:!1,responsive:!0},useResizeHandler:!0,style:{width:"100%"}};return(0,i.jsxs)("section",{className:"panel",children:[i.jsx("div",{className:"panel-head",children:i.jsx("span",{children:e})}),c?(0,t.createElement)(l,d):i.jsx("div",{className:"plot-empty",children:r})]})}},3081:(e,s,n)=>{"use strict";n.d(s,{O:()=>r});var i=n(8924),a=n(9779);function r({label:e}){let s=e.includes("Breakout")||e.includes("Strong")?"positive":e.includes("Risk")||e.includes("Avoid")?"negative":e.includes("Divergence")||e.includes("Contrarian")?"warning":"neutral";return i.jsx("span",{className:(0,a.Z)("status-badge",s),children:e})}},1328:(e,s,n)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0}),Object.defineProperty(s,"default",{enumerable:!0,get:function(){return r}});let i=n(1607);n(8924),n(3911);let a=i._(n(4737));function r(e,s){var n;let i={loading:e=>{let{error:s,isLoading:n,pastDelay:i}=e;return null}};"function"==typeof e&&(i.loader=e);let r={...i,...s};return(0,a.default)({...r,modules:null==(n=r.loadableGenerated)?void 0:n.modules})}("function"==typeof s.default||"object"==typeof s.default&&null!==s.default)&&void 0===s.default.__esModule&&(Object.defineProperty(s.default,"__esModule",{value:!0}),Object.assign(s.default,s),e.exports=s.default)},3880:(e,s,n)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0}),Object.defineProperty(s,"BailoutToCSR",{enumerable:!0,get:function(){return a}});let i=n(6483);function a(e){let{reason:s,children:n}=e;throw new i.BailoutToCSRError(s)}},4737:(e,s,n)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0}),Object.defineProperty(s,"default",{enumerable:!0,get:function(){return d}});let i=n(8924),a=n(3911),r=n(3880),t=n(7083);function l(e){return{default:e&&"default"in e?e.default:e}}let c={loader:()=>Promise.resolve(l(()=>null)),loading:null,ssr:!0},d=function(e){let s={...c,...e},n=(0,a.lazy)(()=>s.loader().then(l)),d=s.loading;function o(e){let l=d?(0,i.jsx)(d,{isLoading:!0,pastDelay:!0,error:null}):null,c=s.ssr?(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.PreloadCss,{moduleIds:s.modules}),(0,i.jsx)(n,{...e})]}):(0,i.jsx)(r.BailoutToCSR,{reason:"next/dynamic",children:(0,i.jsx)(n,{...e})});return(0,i.jsx)(a.Suspense,{fallback:l,children:c})}return o.displayName="LoadableComponent",o}},7083:(e,s,n)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0}),Object.defineProperty(s,"PreloadCss",{enumerable:!0,get:function(){return r}});let i=n(8924),a=n(4580);function r(e){let{moduleIds:s}=e,n=(0,a.getExpectedRequestStore)("next/dynamic css"),r=[];if(n.reactLoadableManifest&&s){let e=n.reactLoadableManifest;for(let n of s){if(!e[n])continue;let s=e[n].files.filter(e=>e.endsWith(".css"));r.push(...s)}}return 0===r.length?null:(0,i.jsx)(i.Fragment,{children:r.map(e=>(0,i.jsx)("link",{precedence:"dynamic",rel:"stylesheet",href:n.assetPrefix+"/_next/"+encodeURI(e),as:"style"},e))})}},3733:(e,s,n)=>{"use strict";n.r(s),n.d(s,{default:()=>i});let i=(0,n(6691).createProxy)(String.raw`/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/market-brain/page.tsx#default`)}};var s=require("../../webpack-runtime.js");s.C(e);var n=e=>s(s.s=e),i=s.X(0,[273,394,927],()=>n(4123));module.exports=i})();
\ No newline at end of file
diff --git a/frontend/.next/server/app/market-brain/page.js.nft.json b/frontend/.next/server/app/market-brain/page.js.nft.json
new file mode 100644
index 0000000000000000000000000000000000000000..77578a3c1517e5a73d13826b0254aea2983bdd03
--- /dev/null
+++ b/frontend/.next/server/app/market-brain/page.js.nft.json
@@ -0,0 +1 @@
+{"version":1,"files":["../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/package.json","../../../../node_modules/next","../../../../package.json","../../../package.json","../../chunks/273.js","../../chunks/394.js","../../chunks/927.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}
\ No newline at end of file
diff --git a/frontend/.next/server/app/market-brain/page_client-reference-manifest.js b/frontend/.next/server/app/market-brain/page_client-reference-manifest.js
new file mode 100644
index 0000000000000000000000000000000000000000..9a4efab1cc34749dd9770948222a51c98017a27e
--- /dev/null
+++ b/frontend/.next/server/app/market-brain/page_client-reference-manifest.js
@@ -0,0 +1 @@
+globalThis.__RSC_MANIFEST=(globalThis.__RSC_MANIFEST||{});globalThis.__RSC_MANIFEST["/market-brain/page"]={"moduleLoading":{"prefix":"/_next/","crossOrigin":null},"ssrModuleMapping":{"176":{"*":{"id":"6676","name":"*","chunks":[],"async":false}},"841":{"*":{"id":"9737","name":"*","chunks":[],"async":false}},"892":{"*":{"id":"5213","name":"*","chunks":[],"async":false}},"2010":{"*":{"id":"7619","name":"*","chunks":[],"async":false}},"2433":{"*":{"id":"6544","name":"*","chunks":[],"async":false}},"2651":{"*":{"id":"9645","name":"*","chunks":[],"async":false}},"2987":{"*":{"id":"1358","name":"*","chunks":[],"async":false}},"3713":{"*":{"id":"5210","name":"*","chunks":[],"async":false}},"4374":{"*":{"id":"9927","name":"*","chunks":[],"async":false}},"6056":{"*":{"id":"1309","name":"*","chunks":[],"async":false}},"6543":{"*":{"id":"9722","name":"*","chunks":[],"async":false}},"6813":{"*":{"id":"5877","name":"*","chunks":[],"async":false}},"7096":{"*":{"id":"1952","name":"*","chunks":[],"async":false}},"7413":{"*":{"id":"8052","name":"*","chunks":[],"async":false}},"7523":{"*":{"id":"3477","name":"*","chunks":[],"async":false}},"7768":{"*":{"id":"7663","name":"*","chunks":[],"async":false}},"8145":{"*":{"id":"8377","name":"*","chunks":[],"async":false}},"8528":{"*":{"id":"5116","name":"*","chunks":[],"async":false}},"8547":{"*":{"id":"5441","name":"*","chunks":[],"async":false}},"9135":{"*":{"id":"432","name":"*","chunks":[],"async":false}},"9239":{"*":{"id":"8132","name":"*","chunks":[],"async":false}},"9414":{"*":{"id":"8850","name":"*","chunks":[],"async":false}},"9570":{"*":{"id":"291","name":"*","chunks":[],"async":false}}},"edgeSSRModuleMapping":{},"clientModules":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/globals.css":{"id":4443,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/components/AppShell.tsx":{"id":6813,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/backtest/page.tsx":{"id":4374,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chart-analyst/page.tsx":{"id":6543,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chat/page.tsx":{"id":841,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chatbot/page.tsx":{"id":8145,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/learning/page.tsx":{"id":6056,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/methodology/page.tsx":{"id":7413,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/ipo-radar/page.tsx":{"id":9135,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/market-brain/page.tsx":{"id":2987,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","653","static/chunks/app/market-brain/page-a3c75d13701833bc.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page.tsx":{"id":892,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/dashboard/page.tsx":{"id":7096,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","96","static/chunks/96-ce8c57cd15d50941.js","931","static/chunks/app/page-d0db9a93fb4af9a5.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/etf-radar/page.tsx":{"id":9239,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/performance/page.tsx":{"id":8547,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/signal-lab/page.tsx":{"id":2010,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/sniper/page.tsx":{"id":7768,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/stock-radar/page.tsx":{"id":9570,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/assets/[ticker]/view.tsx":{"id":3713,"name":"*","chunks":[],"async":false}},"entryCSSFiles":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout":["static/css/02bd12e03544ea91.css"],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/page":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/market-brain/page":[]}}
\ No newline at end of file
diff --git a/frontend/.next/server/app/methodology.html b/frontend/.next/server/app/methodology.html
new file mode 100644
index 0000000000000000000000000000000000000000..b6273bebe1bb76275188d28b4ffa7a2d6cac2ee5
--- /dev/null
+++ b/frontend/.next/server/app/methodology.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence MethodologyTransparent architecture and scoring rules.
Data workflowThe backend seeds an asset universe, ingests public OHLCV history, collects public RSS news, deduplicates articles, links them to assets and persists all artifacts in PostgreSQL.
AI orchestrationFinBERT handles financial sentiment, sentence-transformers handles embeddings and semantic search, a lightweight LLM creates evidence-only explanations, and the time-series layer computes anomalies, volatility regimes and scenarios.
Market BrainThe Market Brain combines stock signals, ETF rotation, live news, sentiment, SEC filing evidence, forward scenarios, contradictions, risk alerts and change logs into one evidence-bound operating view.
Self-learning financial memoryBlum evaluates signal outcomes after 1D, 3D, 7D, 14D and 30D, then stores accuracy memory, confidence adjustments, source reliability and reversible model weight versions. It updates parameters, not source code, and never executes trades.
Chart Vision Technical AnalystChart analysis combines deterministic OHLCV calculations with optional Qwen3-VL visual interpretation and InternVL3 fallback. If vision is unavailable, Blum clearly switches to deterministic technical analysis and does not invent visual levels.
IPO intelligenceIPO Radar uses SEC EDGAR current filings and company submissions data for S-1, F-1 and 424B prospectus evidence. It never fabricates listing dates, valuations or tickers.
Signal scoringThe Blum Intelligence Score combines momentum, trend quality, technical indicators, volatility/risk, sentiment trend, semantic intensity, ETF confirmation and anomaly pressure.
ExplainabilityEach surfaced asset must expose why it appeared, which technical and narrative data support it, what contradicts it, what to monitor, and which risks limit confidence.
BacktestingHistorical validation reports hit rate, forward returns, max adverse excursion, max favorable excursion, false positives and methodology limits. It does not promise future performance.
Provider architectureThe first provider is yfinance. The backend isolates providers so future integrations can add licensed market data, estimates, filings, transcripts, ownership and portfolio systems.
AI model statusfallback-readyModel status is not available yet. Financial disclaimerThis project is for educational, research and technical case-study purposes only. It is not financial advice, an investment recommendation, a trading signal, or a substitute for regulated research, due diligence, valuation work, risk management or professional advice.
\ No newline at end of file
diff --git a/frontend/.next/server/app/methodology.meta b/frontend/.next/server/app/methodology.meta
new file mode 100644
index 0000000000000000000000000000000000000000..71491fc513e08c451271a61d49f976a56dbfd10c
--- /dev/null
+++ b/frontend/.next/server/app/methodology.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/methodology/layout,_N_T_/methodology/page,_N_T_/methodology/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/methodology.rsc b/frontend/.next/server/app/methodology.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..22eff93bb47410fdfd5550b3c503802af6599b2d
--- /dev/null
+++ b/frontend/.next/server/app/methodology.rsc
@@ -0,0 +1,8 @@
+2:I[7523,[],"ClientPageRoot"]
+3:I[7413,["651","static/chunks/651-5689242ae9b0ffc6.js","949","static/chunks/app/methodology/page-f0ef96f8ef7d3450.js"],"default",1]
+4:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["methodology",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["methodology",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","methodology","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/methodology/page.js b/frontend/.next/server/app/methodology/page.js
new file mode 100644
index 0000000000000000000000000000000000000000..d7e896e1f914f3d292ddbe6539f2591858ed1a5a
--- /dev/null
+++ b/frontend/.next/server/app/methodology/page.js
@@ -0,0 +1 @@
+(()=>{var e={};e.id=949,e.ids=[949],e.modules={2934:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external.js")},4580:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external.js")},5869:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},399:e=>{"use strict";e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},8353:(e,s,t)=>{"use strict";t.r(s),t.d(s,{GlobalError:()=>r.a,__next_app__:()=>h,originalPathname:()=>m,pages:()=>c,routeModule:()=>p,tree:()=>d}),t(1378),t(8777),t(311);var n=t(9296),i=t(1650),a=t(7045),r=t.n(a),o=t(8184),l={};for(let e in o)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(l[e]=()=>o[e]);t.d(s,l);let d=["",{children:["methodology",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(t.bind(t,1378)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/methodology/page.tsx"]}]},{}]},{layout:[()=>Promise.resolve().then(t.bind(t,8777)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout.tsx"],"not-found":[()=>Promise.resolve().then(t.t.bind(t,311,23)),"next/dist/client/components/not-found-error"]}],c=["/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/methodology/page.tsx"],m="/methodology/page",h={require:t,loadChunk:()=>Promise.resolve()},p=new n.AppPageRouteModule({definition:{kind:i.x.APP_PAGE,page:"/methodology/page",pathname:"/methodology",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:d}})},8043:(e,s,t)=>{Promise.resolve().then(t.bind(t,8052))},8052:(e,s,t)=>{"use strict";t.r(s),t.d(s,{default:()=>a});var n=t(8924),i=t(3911);function a(){let[e,s]=(0,i.useState)(null);return(0,n.jsxs)(n.Fragment,{children:[n.jsx("div",{className:"page-header",children:(0,n.jsxs)("div",{children:[n.jsx("div",{className:"kicker",children:"Methodology"}),n.jsx("h1",{children:"Transparent architecture and scoring rules."})]})}),n.jsx("section",{className:"grid-2",children:o.map(e=>(0,n.jsxs)("article",{className:"panel",children:[n.jsx("div",{className:"panel-head",children:n.jsx("span",{children:e.title})}),n.jsx("p",{children:e.body})]},e.title))}),(0,n.jsxs)("section",{className:"panel",style:{marginTop:12},children:[(0,n.jsxs)("div",{className:"panel-head",children:[n.jsx("span",{children:"AI model status"}),n.jsx("strong",{children:e?.model_loading_enabled?"model loading enabled":"fallback-ready"})]}),!e&&n.jsx("div",{className:"empty-state",children:"Model status is not available yet."}),e&&(0,n.jsxs)(n.Fragment,{children:[n.jsx("div",{className:"method-grid",children:Object.entries(e.configured_models).map(([e,s])=>(0,n.jsxs)("div",{children:[n.jsx("span",{children:e.replaceAll("_"," ")}),n.jsx("strong",{children:String(s)})]},e))}),(0,n.jsxs)("div",{className:"grid-3",style:{marginTop:10},children:[n.jsx(r,{title:"Sentiment records",rows:e.observed_models.sentiment}),n.jsx(r,{title:"Embedding records",rows:e.observed_models.embeddings}),n.jsx(r,{title:"Insight records",rows:e.observed_models.insights})]})]})]}),(0,n.jsxs)("section",{className:"panel",style:{marginTop:12},children:[n.jsx("div",{className:"panel-head",children:n.jsx("span",{children:"Financial disclaimer"})}),n.jsx("p",{children:"This project is for educational, research and technical case-study purposes only. It is not financial advice, an investment recommendation, a trading signal, or a substitute for regulated research, due diligence, valuation work, risk management or professional advice."})]})]})}function r({title:e,rows:s}){return(0,n.jsxs)("div",{className:"observed-model-panel",children:[(0,n.jsxs)("div",{className:"panel-head",children:[n.jsx("span",{children:e}),n.jsx("strong",{children:s?.length??0})]}),(0,n.jsxs)("div",{className:"brain-list dense",children:[!s?.length&&n.jsx("div",{className:"empty-state",children:"No records observed yet."}),s?.map(e=>n.jsxs("div",{children:[n.jsx("strong",{children:e.model_name}),n.jsxs("span",{children:[e.records," records"]})]},e.model_name))]})]})}t(3789);let o=[{title:"Data workflow",body:"The backend seeds an asset universe, ingests public OHLCV history, collects public RSS news, deduplicates articles, links them to assets and persists all artifacts in PostgreSQL."},{title:"AI orchestration",body:"FinBERT handles financial sentiment, sentence-transformers handles embeddings and semantic search, a lightweight LLM creates evidence-only explanations, and the time-series layer computes anomalies, volatility regimes and scenarios."},{title:"Market Brain",body:"The Market Brain combines stock signals, ETF rotation, live news, sentiment, SEC filing evidence, forward scenarios, contradictions, risk alerts and change logs into one evidence-bound operating view."},{title:"Self-learning financial memory",body:"Blum evaluates signal outcomes after 1D, 3D, 7D, 14D and 30D, then stores accuracy memory, confidence adjustments, source reliability and reversible model weight versions. It updates parameters, not source code, and never executes trades."},{title:"Chart Vision Technical Analyst",body:"Chart analysis combines deterministic OHLCV calculations with optional Qwen3-VL visual interpretation and InternVL3 fallback. If vision is unavailable, Blum clearly switches to deterministic technical analysis and does not invent visual levels."},{title:"IPO intelligence",body:"IPO Radar uses SEC EDGAR current filings and company submissions data for S-1, F-1 and 424B prospectus evidence. It never fabricates listing dates, valuations or tickers."},{title:"Signal scoring",body:"The Blum Intelligence Score combines momentum, trend quality, technical indicators, volatility/risk, sentiment trend, semantic intensity, ETF confirmation and anomaly pressure."},{title:"Explainability",body:"Each surfaced asset must expose why it appeared, which technical and narrative data support it, what contradicts it, what to monitor, and which risks limit confidence."},{title:"Backtesting",body:"Historical validation reports hit rate, forward returns, max adverse excursion, max favorable excursion, false positives and methodology limits. It does not promise future performance."},{title:"Provider architecture",body:"The first provider is yfinance. The backend isolates providers so future integrations can add licensed market data, estimates, filings, transcripts, ownership and portfolio systems."}]},1378:(e,s,t)=>{"use strict";t.r(s),t.d(s,{default:()=>n});let n=(0,t(6691).createProxy)(String.raw`/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/methodology/page.tsx#default`)}};var s=require("../../webpack-runtime.js");s.C(e);var t=e=>s(s.s=e),n=s.X(0,[273,394],()=>t(8353));module.exports=n})();
\ No newline at end of file
diff --git a/frontend/.next/server/app/methodology/page.js.nft.json b/frontend/.next/server/app/methodology/page.js.nft.json
new file mode 100644
index 0000000000000000000000000000000000000000..877e4e935689e2063c7f370e14175cea6de0d164
--- /dev/null
+++ b/frontend/.next/server/app/methodology/page.js.nft.json
@@ -0,0 +1 @@
+{"version":1,"files":["../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/package.json","../../../../node_modules/next","../../../../package.json","../../../package.json","../../chunks/273.js","../../chunks/394.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}
\ No newline at end of file
diff --git a/frontend/.next/server/app/methodology/page_client-reference-manifest.js b/frontend/.next/server/app/methodology/page_client-reference-manifest.js
new file mode 100644
index 0000000000000000000000000000000000000000..36b03c5557d870ecd4e1c79263ba7bb6566964cd
--- /dev/null
+++ b/frontend/.next/server/app/methodology/page_client-reference-manifest.js
@@ -0,0 +1 @@
+globalThis.__RSC_MANIFEST=(globalThis.__RSC_MANIFEST||{});globalThis.__RSC_MANIFEST["/methodology/page"]={"moduleLoading":{"prefix":"/_next/","crossOrigin":null},"ssrModuleMapping":{"176":{"*":{"id":"6676","name":"*","chunks":[],"async":false}},"841":{"*":{"id":"9737","name":"*","chunks":[],"async":false}},"892":{"*":{"id":"5213","name":"*","chunks":[],"async":false}},"2010":{"*":{"id":"7619","name":"*","chunks":[],"async":false}},"2433":{"*":{"id":"6544","name":"*","chunks":[],"async":false}},"2651":{"*":{"id":"9645","name":"*","chunks":[],"async":false}},"2987":{"*":{"id":"1358","name":"*","chunks":[],"async":false}},"3713":{"*":{"id":"5210","name":"*","chunks":[],"async":false}},"4374":{"*":{"id":"9927","name":"*","chunks":[],"async":false}},"6056":{"*":{"id":"1309","name":"*","chunks":[],"async":false}},"6543":{"*":{"id":"9722","name":"*","chunks":[],"async":false}},"6813":{"*":{"id":"5877","name":"*","chunks":[],"async":false}},"7096":{"*":{"id":"1952","name":"*","chunks":[],"async":false}},"7413":{"*":{"id":"8052","name":"*","chunks":[],"async":false}},"7523":{"*":{"id":"3477","name":"*","chunks":[],"async":false}},"7768":{"*":{"id":"7663","name":"*","chunks":[],"async":false}},"8145":{"*":{"id":"8377","name":"*","chunks":[],"async":false}},"8528":{"*":{"id":"5116","name":"*","chunks":[],"async":false}},"8547":{"*":{"id":"5441","name":"*","chunks":[],"async":false}},"9135":{"*":{"id":"432","name":"*","chunks":[],"async":false}},"9239":{"*":{"id":"8132","name":"*","chunks":[],"async":false}},"9414":{"*":{"id":"8850","name":"*","chunks":[],"async":false}},"9570":{"*":{"id":"291","name":"*","chunks":[],"async":false}}},"edgeSSRModuleMapping":{},"clientModules":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/globals.css":{"id":4443,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/components/AppShell.tsx":{"id":6813,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/backtest/page.tsx":{"id":4374,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chart-analyst/page.tsx":{"id":6543,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chat/page.tsx":{"id":841,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chatbot/page.tsx":{"id":8145,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/learning/page.tsx":{"id":6056,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/methodology/page.tsx":{"id":7413,"name":"*","chunks":["651","static/chunks/651-5689242ae9b0ffc6.js","949","static/chunks/app/methodology/page-f0ef96f8ef7d3450.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/ipo-radar/page.tsx":{"id":9135,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/market-brain/page.tsx":{"id":2987,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page.tsx":{"id":892,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/dashboard/page.tsx":{"id":7096,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","96","static/chunks/96-ce8c57cd15d50941.js","931","static/chunks/app/page-d0db9a93fb4af9a5.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/etf-radar/page.tsx":{"id":9239,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/performance/page.tsx":{"id":8547,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/signal-lab/page.tsx":{"id":2010,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/sniper/page.tsx":{"id":7768,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/stock-radar/page.tsx":{"id":9570,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/assets/[ticker]/view.tsx":{"id":3713,"name":"*","chunks":[],"async":false}},"entryCSSFiles":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout":["static/css/02bd12e03544ea91.css"],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/page":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/methodology/page":[]}}
\ No newline at end of file
diff --git a/frontend/.next/server/app/narratives.html b/frontend/.next/server/app/narratives.html
new file mode 100644
index 0000000000000000000000000000000000000000..6e17585853883b96d5301944ac4d789e815a3661
--- /dev/null
+++ b/frontend/.next/server/app/narratives.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading semantic themes
\ No newline at end of file
diff --git a/frontend/.next/server/app/narratives.meta b/frontend/.next/server/app/narratives.meta
new file mode 100644
index 0000000000000000000000000000000000000000..76548f8dacbffa436176f8040cb825e69ca23562
--- /dev/null
+++ b/frontend/.next/server/app/narratives.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/narratives/layout,_N_T_/narratives/page,_N_T_/narratives/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/narratives.rsc b/frontend/.next/server/app/narratives.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..66076876ea72365d165dea94b27d4f035bb04a7b
--- /dev/null
+++ b/frontend/.next/server/app/narratives.rsc
@@ -0,0 +1,8 @@
+2:I[7523,[],"ClientPageRoot"]
+3:I[892,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","433","static/chunks/433-89ff72e62f774508.js","878","static/chunks/app/narratives/page-f858506c5d5d372d.js"],"default",1]
+4:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["narratives",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["narratives",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","narratives","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/narratives/page.js b/frontend/.next/server/app/narratives/page.js
new file mode 100644
index 0000000000000000000000000000000000000000..74cb2bee44da92e1a3ce1bdfb31c2be579c26000
--- /dev/null
+++ b/frontend/.next/server/app/narratives/page.js
@@ -0,0 +1 @@
+(()=>{var e={};e.id=878,e.ids=[878],e.modules={2934:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external.js")},4580:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external.js")},5869:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},399:e=>{"use strict";e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},6441:(e,t,s)=>{"use strict";s.r(t),s.d(t,{GlobalError:()=>i.a,__next_app__:()=>m,originalPathname:()=>u,pages:()=>d,routeModule:()=>h,tree:()=>o}),s(1385),s(8777),s(311);var r=s(9296),n=s(1650),a=s(7045),i=s.n(a),l=s(8184),c={};for(let e in l)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(c[e]=()=>l[e]);s.d(t,c);let o=["",{children:["narratives",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(s.bind(s,1385)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/narratives/page.tsx"]}]},{}]},{layout:[()=>Promise.resolve().then(s.bind(s,8777)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout.tsx"],"not-found":[()=>Promise.resolve().then(s.t.bind(s,311,23)),"next/dist/client/components/not-found-error"]}],d=["/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/narratives/page.tsx"],u="/narratives/page",m={require:s,loadChunk:()=>Promise.resolve()},h=new r.AppPageRouteModule({definition:{kind:n.x.APP_PAGE,page:"/narratives/page",pathname:"/narratives",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:o}})},9652:(e,t,s)=>{Promise.resolve().then(s.bind(s,5213))},5213:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>o});var r=s(8924),n=s(3911),a=s(3789),i=s(6927),l=s(2522);let c=["AI","Rates","Geopolitics","Earnings","Energy","Crypto/Fintech","Market Structure"];function o(){let[e,t]=(0,n.useState)(null),[s,o]=(0,n.useState)(null),[u,p]=(0,n.useState)("AI infrastructure guidance"),[g,x]=(0,n.useState)([]),[v,j]=(0,n.useState)(""),[y,f]=(0,n.useState)(""),[b,N]=(0,n.useState)(""),[S,w]=(0,n.useState)(!1),[_,k]=(0,n.useState)(""),A=(0,n.useMemo)(()=>{let t=e??[];return{articleCount:t.reduce((e,t)=>e+h(t.article_count),0),averageSentiment:t.length?t.reduce((e,t)=>e+h(t.sentiment_score),0)/t.length:0}},[e]),P=async()=>{w(!0),N("");try{let e=await a.h.semanticSearch(u);x(Array.isArray(e)?e:[])}catch(e){x([]),N(e.message)}finally{w(!1)}},C=async e=>{if(e){k(e),f("");try{o(await a.h.themeDetail(e))}catch(e){o(null),f(e.message)}finally{k("")}}};return null===e?r.jsx(l.G,{label:"Loading semantic themes"}):(0,r.jsxs)(r.Fragment,{children:[r.jsx(i.ft,{eyebrow:"Themes and Narratives",title:"Market narrative intelligence.",subtitle:"Semantic clusters, rising themes, linked tickers and source evidence from public financial news.",statusItems:[{label:"Clusters",value:String(e.length),tone:e.length?"positive":"attention"},{label:"Articles",value:String(A.articleCount),tone:A.articleCount?"info":"attention"},{label:"Avg sentiment",value:A.averageSentiment.toFixed(2),tone:A.averageSentiment>=0?"positive":"negative"},{label:"Mode",value:"Evidence only"}]}),v&&(0,r.jsxs)("div",{className:"terminal-empty",style:{marginBottom:12},children:["Narratives endpoint warning: ",v,". The autonomous engine will keep rebuilding semantic clusters as evidence arrives."]}),r.jsx("section",{className:"professional-grid-3",children:c.map(t=>{let s=t.split("/")[0].toLowerCase(),n=e.find(e=>String(e.label??"").toLowerCase().includes(s));return r.jsx(i.x8,{title:t,sentiment:n?.sentiment_score,volume:n?.article_count??0,explanation:n?`Active semantic cluster: ${m(n.keywords).slice(0,4).join(", ")||"keywords pending"}.`:"Strategic narrative taxonomy monitored for future evidence."},t)})}),(0,r.jsxs)(i.Ez,{title:"Semantic Search",value:"Vector evidence",subtitle:"Search public news embeddings and narrative clusters",className:"radar-core-panel",children:[(0,r.jsxs)("div",{className:"control-row",style:{marginBottom:0},children:[r.jsx("input",{className:"input",value:u,onChange:e=>p(e.target.value),"aria-label":"Semantic search query"}),r.jsx("button",{className:"button primary",onClick:P,disabled:S||u.trim().length<3,children:S?"Searching...":"Semantic search"})]}),b&&(0,r.jsxs)("div",{className:"terminal-empty compact",style:{marginTop:10},children:["Search warning: ",b]})]}),r.jsx("section",{className:"professional-grid-3",style:{marginTop:12},children:e.slice(0,12).map((e,t)=>{let s=String(e.label??`Theme ${t+1}`);return(0,r.jsxs)("article",{className:"narrative-card theme-card",onClick:()=>C(s),children:[(0,r.jsxs)("div",{className:"narrative-card-top",children:[r.jsx("strong",{children:s}),(0,r.jsxs)("span",{className:"score-badge tone-attention",children:[r.jsx("strong",{children:h(e.article_count)}),r.jsx("em",{children:"news"})]})]}),(0,r.jsxs)("p",{children:["Keywords: ",m(e.keywords).join(", ")||"semantic cluster"]}),(0,r.jsxs)("div",{className:"narrative-card-meta",children:[(0,r.jsxs)("span",{children:["sentiment ",h(e.sentiment_score).toFixed(2)]}),r.jsx("span",{children:_===s?"loading detail":e.cluster_method??"theme aggregation"})]})]},`${s}-${t}`)})}),!e.length&&!v&&r.jsx(i.Ez,{title:"Narrative Coverage",value:"Building",className:"radar-core-panel",children:r.jsx("div",{className:"terminal-empty",children:"No semantic clusters are stored yet. The autonomous engine is hydrating news, embeddings and theme memory in the background."})}),y&&(0,r.jsxs)("div",{className:"terminal-empty",style:{marginTop:12},children:["Theme detail warning: ",y]}),s&&r.jsx(d,{detail:s}),r.jsx(i.Ez,{title:"Semantic Search Results",value:`${g.length} matches`,className:"radar-core-panel",children:(0,r.jsxs)("div",{className:"news-list",children:[0===g.length&&r.jsx("div",{className:"terminal-empty compact",children:"Search results will appear here after a query is submitted."}),g.map((e,t)=>{let s=e.article??{};return(0,r.jsxs)("a",{className:"news-item",href:s.url??"#",target:"_blank",rel:"noreferrer",children:[r.jsx("strong",{children:s.title??"Untitled evidence item"}),(0,r.jsxs)("span",{children:["Similarity ",h(e.score).toFixed(3)," | ",s.source??"unknown source"]})]},`${s.id??s.url??"result"}-${t}`)})]})})]})}function d({detail:e}){let t=m(e.source_mix),s=m(e.linked_assets),n=m(e.articles);return(0,r.jsxs)(i.Ez,{title:"Theme Detail",value:e.label??"Narrative",className:"radar-core-panel",children:[(0,r.jsxs)("div",{className:"professional-grid-4",children:[r.jsx(u,{label:"Articles",value:h(e.article_count)}),r.jsx(u,{label:"Avg Sentiment",value:h(e.average_sentiment).toFixed(2)}),r.jsx(u,{label:"Sources",value:t.length}),r.jsx(u,{label:"Assets",value:s.length})]}),(0,r.jsxs)("div",{className:"professional-grid-2",style:{marginTop:12},children:[r.jsx(i.Ez,{title:"Linked Assets",dense:!0,children:(0,r.jsxs)("div",{className:"tag-row",children:[0===s.length&&r.jsx("span",{children:"No linked tickers yet"}),s.slice(0,20).map((e,t)=>(0,r.jsxs)("span",{children:[e.ticker??"Asset"," ",e.mentions??0]},`${e.ticker??"asset"}-${t}`))]})}),r.jsx(i.Ez,{title:"Source Mix",dense:!0,children:(0,r.jsxs)("div",{className:"tag-row",children:[0===t.length&&r.jsx("span",{children:"No source concentration yet"}),t.slice(0,16).map((e,t)=>(0,r.jsxs)("span",{children:[e.source??"Source"," ",e.count??0]},`${e.source??"source"}-${t}`))]})})]}),(0,r.jsxs)("div",{className:"news-list",style:{marginTop:12},children:[0===n.length&&r.jsx("div",{className:"terminal-empty compact",children:"No articles are linked to this theme yet."}),n.slice(0,16).map((e,t)=>(0,r.jsxs)("a",{className:"news-item",href:e.url??"#",target:"_blank",rel:"noreferrer",children:[r.jsx("strong",{children:e.title??"Untitled article"}),(0,r.jsxs)("span",{children:[e.source??"unknown"," | sentiment ",h(e.sentiment?.score).toFixed(2)," | assets ",m(e.linked_assets).map(e=>e.ticker).filter(Boolean).join(" | ")||"n/a"]})]},`${e.id??e.url??"article"}-${t}`))]})]})}function u({label:e,value:t}){return r.jsx(i.i9,{label:e,value:t})}function m(e){return Array.isArray(e)?e:[]}function h(e){let t=Number(e);return Number.isFinite(t)?t:0}},2522:(e,t,s)=>{"use strict";s.d(t,{G:()=>n});var r=s(8924);function n({label:e="Loading intelligence snapshot"}){return(0,r.jsxs)("div",{className:"loading-state",children:[r.jsx("div",{}),r.jsx("span",{children:e})]})}},1385:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>r});let r=s(4379).default},4379:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>r});let r=(0,s(6691).createProxy)(String.raw`/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page.tsx#default`)}};var t=require("../../webpack-runtime.js");t.C(e);var s=e=>t(t.s=e),r=t.X(0,[273,394,927],()=>s(6441));module.exports=r})();
\ No newline at end of file
diff --git a/frontend/.next/server/app/narratives/page.js.nft.json b/frontend/.next/server/app/narratives/page.js.nft.json
new file mode 100644
index 0000000000000000000000000000000000000000..77578a3c1517e5a73d13826b0254aea2983bdd03
--- /dev/null
+++ b/frontend/.next/server/app/narratives/page.js.nft.json
@@ -0,0 +1 @@
+{"version":1,"files":["../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/package.json","../../../../node_modules/next","../../../../package.json","../../../package.json","../../chunks/273.js","../../chunks/394.js","../../chunks/927.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}
\ No newline at end of file
diff --git a/frontend/.next/server/app/narratives/page_client-reference-manifest.js b/frontend/.next/server/app/narratives/page_client-reference-manifest.js
new file mode 100644
index 0000000000000000000000000000000000000000..efc460e10f64ad5a9933179b254a80977c1f6887
--- /dev/null
+++ b/frontend/.next/server/app/narratives/page_client-reference-manifest.js
@@ -0,0 +1 @@
+globalThis.__RSC_MANIFEST=(globalThis.__RSC_MANIFEST||{});globalThis.__RSC_MANIFEST["/narratives/page"]={"moduleLoading":{"prefix":"/_next/","crossOrigin":null},"ssrModuleMapping":{"176":{"*":{"id":"6676","name":"*","chunks":[],"async":false}},"841":{"*":{"id":"9737","name":"*","chunks":[],"async":false}},"892":{"*":{"id":"5213","name":"*","chunks":[],"async":false}},"2010":{"*":{"id":"7619","name":"*","chunks":[],"async":false}},"2433":{"*":{"id":"6544","name":"*","chunks":[],"async":false}},"2651":{"*":{"id":"9645","name":"*","chunks":[],"async":false}},"2987":{"*":{"id":"1358","name":"*","chunks":[],"async":false}},"3713":{"*":{"id":"5210","name":"*","chunks":[],"async":false}},"4374":{"*":{"id":"9927","name":"*","chunks":[],"async":false}},"6056":{"*":{"id":"1309","name":"*","chunks":[],"async":false}},"6543":{"*":{"id":"9722","name":"*","chunks":[],"async":false}},"6813":{"*":{"id":"5877","name":"*","chunks":[],"async":false}},"7096":{"*":{"id":"1952","name":"*","chunks":[],"async":false}},"7413":{"*":{"id":"8052","name":"*","chunks":[],"async":false}},"7523":{"*":{"id":"3477","name":"*","chunks":[],"async":false}},"7768":{"*":{"id":"7663","name":"*","chunks":[],"async":false}},"8145":{"*":{"id":"8377","name":"*","chunks":[],"async":false}},"8528":{"*":{"id":"5116","name":"*","chunks":[],"async":false}},"8547":{"*":{"id":"5441","name":"*","chunks":[],"async":false}},"9135":{"*":{"id":"432","name":"*","chunks":[],"async":false}},"9239":{"*":{"id":"8132","name":"*","chunks":[],"async":false}},"9414":{"*":{"id":"8850","name":"*","chunks":[],"async":false}},"9570":{"*":{"id":"291","name":"*","chunks":[],"async":false}}},"edgeSSRModuleMapping":{},"clientModules":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/globals.css":{"id":4443,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/components/AppShell.tsx":{"id":6813,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/backtest/page.tsx":{"id":4374,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chart-analyst/page.tsx":{"id":6543,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chat/page.tsx":{"id":841,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chatbot/page.tsx":{"id":8145,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/learning/page.tsx":{"id":6056,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/methodology/page.tsx":{"id":7413,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/ipo-radar/page.tsx":{"id":9135,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/market-brain/page.tsx":{"id":2987,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page.tsx":{"id":892,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","433","static/chunks/433-89ff72e62f774508.js","878","static/chunks/app/narratives/page-f858506c5d5d372d.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/dashboard/page.tsx":{"id":7096,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","96","static/chunks/96-ce8c57cd15d50941.js","931","static/chunks/app/page-d0db9a93fb4af9a5.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/etf-radar/page.tsx":{"id":9239,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/performance/page.tsx":{"id":8547,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/signal-lab/page.tsx":{"id":2010,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/sniper/page.tsx":{"id":7768,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/stock-radar/page.tsx":{"id":9570,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/assets/[ticker]/view.tsx":{"id":3713,"name":"*","chunks":[],"async":false}},"entryCSSFiles":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout":["static/css/02bd12e03544ea91.css"],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/page":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/narratives/page":[]}}
\ No newline at end of file
diff --git a/frontend/.next/server/app/page.js b/frontend/.next/server/app/page.js
new file mode 100644
index 0000000000000000000000000000000000000000..37c443811dccb82765b4db3102c7c416d88f43a6
--- /dev/null
+++ b/frontend/.next/server/app/page.js
@@ -0,0 +1 @@
+(()=>{var e={};e.id=931,e.ids=[931],e.modules={2934:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external.js")},4580:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external.js")},5869:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},399:e=>{"use strict";e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},2080:(e,t,r)=>{"use strict";r.r(t),r.d(t,{GlobalError:()=>a.a,__next_app__:()=>c,originalPathname:()=>d,pages:()=>u,routeModule:()=>m,tree:()=>l}),r(1363),r(8777),r(311);var n=r(9296),s=r(1650),o=r(7045),a=r.n(o),i=r(8184),p={};for(let e in i)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(p[e]=()=>i[e]);r.d(t,p);let l=["",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(r.bind(r,1363)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/page.tsx"]}]},{layout:[()=>Promise.resolve().then(r.bind(r,8777)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout.tsx"],"not-found":[()=>Promise.resolve().then(r.t.bind(r,311,23)),"next/dist/client/components/not-found-error"]}],u=["/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/page.tsx"],d="/page",c={require:r,loadChunk:()=>Promise.resolve()},m=new n.AppPageRouteModule({definition:{kind:s.x.APP_PAGE,page:"/page",pathname:"/",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:l}})},817:(e,t,r)=>{Promise.resolve().then(r.bind(r,1952))},1363:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>n.default});var n=r(8666)}};var t=require("../webpack-runtime.js");t.C(e);var r=e=>t(t.s=e),n=t.X(0,[273,394,927,965],()=>r(2080));module.exports=n})();
\ No newline at end of file
diff --git a/frontend/.next/server/app/page.js.nft.json b/frontend/.next/server/app/page.js.nft.json
new file mode 100644
index 0000000000000000000000000000000000000000..07eb6d91685068274222803c01181081d2be0362
--- /dev/null
+++ b/frontend/.next/server/app/page.js.nft.json
@@ -0,0 +1 @@
+{"version":1,"files":["../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage-instance.js","../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage.external.js","../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/async-local-storage.js","../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage-instance.js","../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage.external.js","../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/constants.js","../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/tracer.js","../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/package.json","../../../node_modules/next","../../../package.json","../../package.json","../chunks/273.js","../chunks/394.js","../chunks/927.js","../chunks/965.js","../webpack-runtime.js","page_client-reference-manifest.js"]}
\ No newline at end of file
diff --git a/frontend/.next/server/app/page_client-reference-manifest.js b/frontend/.next/server/app/page_client-reference-manifest.js
new file mode 100644
index 0000000000000000000000000000000000000000..85ff3ea6aed48be5c06bafab4c5545f2471db205
--- /dev/null
+++ b/frontend/.next/server/app/page_client-reference-manifest.js
@@ -0,0 +1 @@
+globalThis.__RSC_MANIFEST=(globalThis.__RSC_MANIFEST||{});globalThis.__RSC_MANIFEST["/page"]={"moduleLoading":{"prefix":"/_next/","crossOrigin":null},"ssrModuleMapping":{"176":{"*":{"id":"6676","name":"*","chunks":[],"async":false}},"841":{"*":{"id":"9737","name":"*","chunks":[],"async":false}},"892":{"*":{"id":"5213","name":"*","chunks":[],"async":false}},"2010":{"*":{"id":"7619","name":"*","chunks":[],"async":false}},"2433":{"*":{"id":"6544","name":"*","chunks":[],"async":false}},"2651":{"*":{"id":"9645","name":"*","chunks":[],"async":false}},"2987":{"*":{"id":"1358","name":"*","chunks":[],"async":false}},"3713":{"*":{"id":"5210","name":"*","chunks":[],"async":false}},"4374":{"*":{"id":"9927","name":"*","chunks":[],"async":false}},"6056":{"*":{"id":"1309","name":"*","chunks":[],"async":false}},"6543":{"*":{"id":"9722","name":"*","chunks":[],"async":false}},"6813":{"*":{"id":"5877","name":"*","chunks":[],"async":false}},"7096":{"*":{"id":"1952","name":"*","chunks":[],"async":false}},"7413":{"*":{"id":"8052","name":"*","chunks":[],"async":false}},"7523":{"*":{"id":"3477","name":"*","chunks":[],"async":false}},"7768":{"*":{"id":"7663","name":"*","chunks":[],"async":false}},"8145":{"*":{"id":"8377","name":"*","chunks":[],"async":false}},"8528":{"*":{"id":"5116","name":"*","chunks":[],"async":false}},"8547":{"*":{"id":"5441","name":"*","chunks":[],"async":false}},"9135":{"*":{"id":"432","name":"*","chunks":[],"async":false}},"9239":{"*":{"id":"8132","name":"*","chunks":[],"async":false}},"9414":{"*":{"id":"8850","name":"*","chunks":[],"async":false}},"9570":{"*":{"id":"291","name":"*","chunks":[],"async":false}}},"edgeSSRModuleMapping":{},"clientModules":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/globals.css":{"id":4443,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/components/AppShell.tsx":{"id":6813,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/backtest/page.tsx":{"id":4374,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chart-analyst/page.tsx":{"id":6543,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chat/page.tsx":{"id":841,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chatbot/page.tsx":{"id":8145,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/learning/page.tsx":{"id":6056,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/methodology/page.tsx":{"id":7413,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/ipo-radar/page.tsx":{"id":9135,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/market-brain/page.tsx":{"id":2987,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page.tsx":{"id":892,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/dashboard/page.tsx":{"id":7096,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","96","static/chunks/96-ce8c57cd15d50941.js","931","static/chunks/app/page-d0db9a93fb4af9a5.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/etf-radar/page.tsx":{"id":9239,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/performance/page.tsx":{"id":8547,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/signal-lab/page.tsx":{"id":2010,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/sniper/page.tsx":{"id":7768,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/stock-radar/page.tsx":{"id":9570,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/assets/[ticker]/view.tsx":{"id":3713,"name":"*","chunks":[],"async":false}},"entryCSSFiles":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout":["static/css/02bd12e03544ea91.css"],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/page":[]}}
\ No newline at end of file
diff --git a/frontend/.next/server/app/performance.html b/frontend/.next/server/app/performance.html
new file mode 100644
index 0000000000000000000000000000000000000000..cfe09a51241076436b08eb40437f48ec4907607b
--- /dev/null
+++ b/frontend/.next/server/app/performance.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading performance diagnostics
\ No newline at end of file
diff --git a/frontend/.next/server/app/performance.meta b/frontend/.next/server/app/performance.meta
new file mode 100644
index 0000000000000000000000000000000000000000..50a54f9b2b81f0efd74b06a0cf1db3525dcbd21e
--- /dev/null
+++ b/frontend/.next/server/app/performance.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/performance/layout,_N_T_/performance/page,_N_T_/performance/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/performance.rsc b/frontend/.next/server/app/performance.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..ee475df869ef234720207aa20e26f34bbb8f3e25
--- /dev/null
+++ b/frontend/.next/server/app/performance.rsc
@@ -0,0 +1,8 @@
+2:I[7523,[],"ClientPageRoot"]
+3:I[8547,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","367","static/chunks/app/performance/page-72d89cf8fa4bd0b1.js"],"default",1]
+4:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["performance",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["performance",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","performance","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/performance/page.js b/frontend/.next/server/app/performance/page.js
new file mode 100644
index 0000000000000000000000000000000000000000..c705c4f47d17e71f03214d6fce7559a90a341141
--- /dev/null
+++ b/frontend/.next/server/app/performance/page.js
@@ -0,0 +1 @@
+(()=>{var e={};e.id=367,e.ids=[367],e.modules={2934:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external.js")},4580:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external.js")},5869:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},399:e=>{"use strict";e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},2356:(e,t,s)=>{"use strict";s.r(t),s.d(t,{GlobalError:()=>i.a,__next_app__:()=>p,originalPathname:()=>c,pages:()=>u,routeModule:()=>m,tree:()=>d}),s(1079),s(8777),s(311);var a=s(9296),n=s(1650),r=s(7045),i=s.n(r),o=s(8184),l={};for(let e in o)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(l[e]=()=>o[e]);s.d(t,l);let d=["",{children:["performance",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(s.bind(s,1079)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/performance/page.tsx"]}]},{}]},{layout:[()=>Promise.resolve().then(s.bind(s,8777)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout.tsx"],"not-found":[()=>Promise.resolve().then(s.t.bind(s,311,23)),"next/dist/client/components/not-found-error"]}],u=["/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/performance/page.tsx"],c="/performance/page",p={require:s,loadChunk:()=>Promise.resolve()},m=new a.AppPageRouteModule({definition:{kind:n.x.APP_PAGE,page:"/performance/page",pathname:"/performance",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:d}})},8157:(e,t,s)=>{Promise.resolve().then(s.bind(s,5441))},5441:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>m});var a=s(8924),n=s(3911),r=s(6839),i=s(3041),o=s(6635),l=s(9773),d=s(7617),u=s(3789),c=s(6927),p=s(2522);function m(){let[e,t]=(0,n.useState)(null),[s,m]=(0,n.useState)(null),[v,x]=(0,n.useState)("idle"),[f,w]=(0,n.useState)(""),j=async()=>{try{w(""),t(await u.h.performanceDiagnostics()),m(u.h.clientRequestStats())}catch(e){w(e.message)}},y=async()=>{x("probing"),await Promise.all([["frontend.dashboard.overview",()=>u.h.overview()],["frontend.dashboard.live_news",()=>u.h.liveNews(60)],["frontend.dashboard.market_sentiment",()=>u.h.marketSentiment(48)],["frontend.dashboard.pipeline_status",()=>u.h.pipelineStatus()],["frontend.dashboard.system_status",()=>u.h.systemStatus()],["frontend.dashboard.executive",()=>u.h.executiveDashboard()],["frontend.dashboard.brain_status",()=>u.h.brainStatus()]].map(async([e,t])=>{let s=performance.now();try{await t(),await u.h.recordPerformanceWidget({name:e,duration_ms:performance.now()-s,status:"ok",source:"browser_probe"})}catch(t){await u.h.recordPerformanceWidget({name:e,duration_ms:performance.now()-s,status:"error",source:"browser_probe",detail:t.message.slice(0,180)}).catch(()=>void 0)}})),x("complete"),await j()},k=e?.top_10_bottlenecks??[],N=e?.startup?.phases??[],S=e?.api?.slowest_endpoints??[],P=e?.database?.slowest_queries??[],$=e?.dashboard_widgets?.slowest_widget_events??[],q=e?.background_tasks?.slowest_tasks??[],D=e?.cache??{},z=e?.initial_learning_page_load??{},E=Object.values(e?.dashboard_snapshots?.latest_by_type??{}),L=(0,n.useMemo)(()=>(function(e){if(!e)return"low evidence";let t=Number(e.api?.request_count??0)+Number(e.database?.query_count??0)+Number(e.dashboard_widgets?.event_count??0);return t>500?"strong evidence":t>100?"medium evidence":"low evidence"})(e),[e]);return f&&!e?(0,a.jsxs)("div",{className:"terminal-empty",children:["API error: ",f]}):e?(0,a.jsxs)(a.Fragment,{children:[a.jsx(c.ft,{eyebrow:"Performance Diagnostics",title:"Measure first. Optimize later.",subtitle:"Runtime timing for startup, API endpoints, SQLAlchemy queries, background workers and dashboard widgets. This page exposes bottlenecks without changing financial logic.",statusItems:[{label:"Probe",value:v,tone:"complete"===v?"positive":"attention"},{label:"Evidence",value:L,tone:L.includes("low")?"attention":"positive"},{label:"Generated",value:b(e.generated_at),tone:"info"},{label:"Policy",value:"measurement only",tone:"neutral"}],actions:a.jsx("button",{className:"terminal-button",onClick:y,children:"Run dashboard probe"})}),f&&(0,a.jsxs)("div",{className:"terminal-empty",style:{marginBottom:12},children:["Refresh warning: ",f]}),(0,a.jsxs)("section",{className:"terminal-command-grid",children:[a.jsx(c.i9,{label:"Startup Duration",value:g(e.startup?.total_duration_ms),subvalue:`${N.length} measured phases`,icon:a.jsx(r.Z,{size:18}),tone:"attention"}),a.jsx(c.i9,{label:"API Avg",value:g(e.api?.average_response_ms),subvalue:`p95 ${g(e.api?.p95_response_ms)} | ${e.api?.request_count??0} requests`,icon:a.jsx(i.Z,{size:18}),tone:"info"}),a.jsx(c.i9,{label:"DB Avg",value:g(e.database?.average_query_ms),subvalue:`p95 ${g(e.database?.p95_query_ms)} | ${e.database?.query_count??0} queries`,icon:a.jsx(o.Z,{size:18}),tone:"info"}),a.jsx(c.i9,{label:"Widget Avg",value:g(e.dashboard_widgets?.average_widget_ms),subvalue:`p95 ${g(e.dashboard_widgets?.p95_widget_ms)}`,icon:a.jsx(l.Z,{size:18}),tone:"neutral"}),a.jsx(c.i9,{label:"Cache Hit Rate",value:function(e){let t=Number(e);return Number.isFinite(t)?`${(100*t).toFixed(1)}%`:"n/a"}(D.hit_rate),subvalue:`${D.hits??0} hits / ${D.misses??0} misses`,icon:a.jsx(d.Z,{size:18}),tone:null===D.hit_rate||void 0===D.hit_rate?"attention":"positive"}),a.jsx(c.i9,{label:"Background Avg",value:g(e.background_tasks?.average_duration_ms),subvalue:`p95 ${g(e.background_tasks?.p95_duration_ms)} | ${e.background_tasks?.event_count??0} runs`,icon:a.jsx(i.Z,{size:18}),tone:"attention"})]}),(0,a.jsxs)("section",{className:"professional-grid-2",children:[a.jsx(c.Ez,{title:"Top 10 Bottlenecks",value:`${k.length} events`,subtitle:"Slowest measured operations across API, DB, widgets and background tasks",children:a.jsx(h,{columns:["Kind","Name","Duration","Rows"],rows:k.map(e=>[e.kind,_(e.name,92),g(e.duration_ms),e.rows_scanned_estimate??"-"]),empty:"No bottleneck data has been recorded yet."})}),a.jsx(c.Ez,{title:"Startup Breakdown",value:g(e.startup?.total_duration_ms),subtitle:"Measured application startup phases",children:a.jsx(h,{columns:["Phase","Duration","Started"],rows:N.map(e=>[e.name,g(e.duration_ms),b(e.started_at)]),empty:"Startup phases will appear after the backend process starts."})})]}),(0,a.jsxs)("section",{className:"professional-grid-2",style:{marginTop:12},children:[(0,a.jsxs)(c.Ez,{title:"Initial Learning Page Load",value:`${s?.initialLearningPage?.length??0} requests`,subtitle:"Browser-side request storm and dedupe visibility for the current route session",children:[(0,a.jsxs)("div",{className:"professional-grid-3",style:{marginBottom:10},children:[a.jsx(c.i9,{label:"Total Requests",value:s?.total??0}),a.jsx(c.i9,{label:"Duplicate Requests",value:s?.duplicate??0}),a.jsx(c.i9,{label:"Cache Hits",value:s?.cacheHits??0}),a.jsx(c.i9,{label:"Heavy POST During Load",value:z?.heavy_post_calls_during_page_load?.length??0}),a.jsx(c.i9,{label:"Server Frontend Events",value:z?.frontend_request_count??0}),a.jsx(c.i9,{label:"Server Cache Hits",value:z?.cache_hit_count??0})]}),a.jsx(h,{columns:["Method","Endpoint","Duration","Status","Dedupe"],rows:(s?.initialLearningPage??[]).slice(-18).reverse().map(e=>[e.method,_(e.path,86),g(e.duration_ms),e.status,e.duplicate?"yes":e.cache_hit?"cache":"no"]),empty:"Open the Learning page in this session to collect initial-load request data."})]}),a.jsx(c.Ez,{title:"Recommended Next Optimization",value:"from evidence",subtitle:"Generated from currently visible bottleneck classes",children:a.jsx("ul",{className:"diagnostic-list",children:(function(e,t){let s=[],a=e?.api?.slowest_endpoints?.[0],n=e?.database?.slowest_queries?.[0],r=Number(t?.duplicate??0),i=e?.initial_learning_page_load?.heavy_post_calls_during_page_load??[],o=Number(e?.dashboard_snapshots?.stale_count??0);return r>0&&s.push(`Request dedupe is catching ${r} duplicate frontend calls in this session.`),i.length>0&&s.push(`Remove or gate ${i.length} heavy POST call(s) observed during Learning page load.`),o>0&&s.push(`${o} dashboard snapshot(s) are stale; verify background refresh cadence before adding live recomputation.`),a&&s.push(`Inspect ${a.method} ${a.path}: p95 ${g(a.p95_ms)} and max ${g(a.max_ms)}.`),n&&s.push(`Inspect the slowest SQL operation ${n.operation}: ${g(n.duration_ms)}.`),(e?.background_tasks?.slowest_tasks??[]).length&&s.push("Background worker timing is now available; compare startup pipeline versus scheduled refresh jobs before optimizing."),s.length||s.push("Collect more requests first. Open Learning, Dashboard and Performance pages, then review the top bottlenecks."),s})(e,s).map(e=>a.jsx("li",{children:e},e))})})]}),(0,a.jsxs)("section",{className:"professional-grid-2",style:{marginTop:12},children:[a.jsx(c.Ez,{title:"Snapshot Freshness",value:`${e.dashboard_snapshots?.fresh_count??0} fresh`,subtitle:"Stale-but-usable dashboard payloads available to avoid blank loading states",children:a.jsx(h,{columns:["Snapshot","Age","Stale","Compute","Warnings"],rows:E.slice(0,12).map(e=>[e.snapshot_type,function(e){let t=Number(e);return Number.isFinite(t)?t<60?`${t.toFixed(0)}s`:t<3600?`${(t/60).toFixed(1)}m`:`${(t/3600).toFixed(1)}h`:"n/a"}(e.age_seconds),e.is_stale?"yes":"no",g(e.computation_duration_ms),(e.warnings??[]).length]),empty:"No dashboard snapshots have been written yet."})}),a.jsx(c.Ez,{title:"Heavy POST Calls During Learning Load",value:`${z?.heavy_post_calls_during_page_load?.length??0} events`,subtitle:"These should stay at zero unless the user explicitly requests recalculation",children:a.jsx(h,{columns:["Method","Path","Duration","Referer"],rows:(z?.heavy_post_calls_during_page_load??[]).slice(0,10).map(e=>[e.method,_(e.path,72),g(e.duration_ms),_(e.referer,72)]),empty:"No heavy recalculation POST was triggered during Learning page load."})})]}),(0,a.jsxs)("section",{className:"professional-grid-2",style:{marginTop:12},children:[a.jsx(c.Ez,{title:"Slowest API Endpoints",value:`p95 ${g(e.api?.p95_response_ms)}`,subtitle:"Grouped by method and normalized path",children:a.jsx(h,{columns:["Endpoint","Count","Avg","P95","Max"],rows:S.slice(0,14).map(e=>[`${e.method} ${e.path}`,e.count,g(e.avg_ms),g(e.p95_ms),g(e.max_ms)]),empty:"No API requests recorded yet."})}),a.jsx(c.Ez,{title:"Slowest Database Queries",value:`${e.database?.query_count??0} queries`,subtitle:"Exact query timing; scanned rows are rowcount when exposed by the driver",children:a.jsx(h,{columns:["Operation","Duration","Rows","SQL"],rows:P.slice(0,12).map(e=>[e.operation,g(e.duration_ms),e.rows_scanned_estimate??"unknown",_(e.sql,110)]),empty:"No SQL queries recorded yet."})})]}),(0,a.jsxs)("section",{className:"professional-grid-2",style:{marginTop:12},children:[a.jsx(c.Ez,{title:"Slowest Dashboard Widgets",value:`${e.dashboard_widgets?.event_count??0} events`,subtitle:"Backend widget timings plus browser-side probe timings",children:a.jsx(h,{columns:["Widget","Duration","Source","Status"],rows:$.slice(0,16).map(e=>[e.name,g(e.duration_ms),"frontend_widget"===e.event_type?"browser":"backend",e.metadata?.status??"ok"]),empty:"Run the dashboard probe to collect widget timings."})}),a.jsx(c.Ez,{title:"Background Task Durations",value:`${e.background_tasks?.event_count??0} runs`,subtitle:"Scheduler and startup worker timing",children:a.jsx(h,{columns:["Task","Count","Avg","P95","Max"],rows:q.slice(0,12).map(e=>[e.name,e.count,g(e.avg_ms),g(e.p95_ms),g(e.max_ms)]),empty:"No background jobs have completed in this process yet."})})]}),(0,a.jsxs)("section",{className:"professional-grid-2",style:{marginTop:12},children:[a.jsx(c.Ez,{title:"Query Fingerprints",value:"Grouped SQL",subtitle:"Repeated query shapes ranked by p95 latency",children:a.jsx(h,{columns:["Count","P95","Max","Rows","Fingerprint"],rows:(e.database?.slowest_query_fingerprints??[]).slice(0,12).map(e=>[e.count,g(e.p95_ms),g(e.max_ms),e.last_rows_scanned_estimate??"unknown",_(e.fingerprint,120)]),empty:"No SQL fingerprints recorded yet."})}),a.jsx(c.Ez,{title:"Observability Limits",value:"Honest measurement",subtitle:"Important boundaries before optimization decisions",children:(0,a.jsxs)("ul",{className:"diagnostic-list",children:[(e.observability_limits??[]).map(e=>a.jsx("li",{children:e},e)),a.jsx("li",{children:e.database?.rows_scanned_policy}),a.jsx("li",{children:D.note})]})})]})]}):a.jsx(p.G,{label:"Loading performance diagnostics"})}function h({columns:e,rows:t,empty:s}){return t.length?a.jsx("div",{className:"performance-table-wrap",children:(0,a.jsxs)("table",{className:"asset-terminal-table performance-table",children:[a.jsx("thead",{children:a.jsx("tr",{children:e.map(e=>a.jsx("th",{children:e},e))})}),a.jsx("tbody",{children:t.map((e,t)=>a.jsx("tr",{children:e.map((e,t)=>a.jsx("td",{children:e},`${t}-${String(e).slice(0,20)}`))},`${t}-${e.join("-")}`))})]})}):a.jsx("div",{className:"terminal-empty",children:s})}function g(e){let t=Number(e);return Number.isFinite(t)?t>=1e3?`${(t/1e3).toFixed(2)}s`:`${t.toFixed(1)}ms`:"n/a"}function b(e){if(!e)return"n/a";try{return new Date(e).toLocaleTimeString()}catch{return e}}function _(e,t){let s=String(e??"");return s.length>t?`${s.slice(0,t)}...`:s}},2522:(e,t,s)=>{"use strict";s.d(t,{G:()=>n});var a=s(8924);function n({label:e="Loading intelligence snapshot"}){return(0,a.jsxs)("div",{className:"loading-state",children:[a.jsx("div",{}),a.jsx("span",{children:e})]})}},1079:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>a});let a=(0,s(6691).createProxy)(String.raw`/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/performance/page.tsx#default`)}};var t=require("../../webpack-runtime.js");t.C(e);var s=e=>t(t.s=e),a=t.X(0,[273,394,927],()=>s(2356));module.exports=a})();
\ No newline at end of file
diff --git a/frontend/.next/server/app/performance/page.js.nft.json b/frontend/.next/server/app/performance/page.js.nft.json
new file mode 100644
index 0000000000000000000000000000000000000000..77578a3c1517e5a73d13826b0254aea2983bdd03
--- /dev/null
+++ b/frontend/.next/server/app/performance/page.js.nft.json
@@ -0,0 +1 @@
+{"version":1,"files":["../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/package.json","../../../../node_modules/next","../../../../package.json","../../../package.json","../../chunks/273.js","../../chunks/394.js","../../chunks/927.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}
\ No newline at end of file
diff --git a/frontend/.next/server/app/performance/page_client-reference-manifest.js b/frontend/.next/server/app/performance/page_client-reference-manifest.js
new file mode 100644
index 0000000000000000000000000000000000000000..d7d09424e81e83e6157705d84e8cb8267809017d
--- /dev/null
+++ b/frontend/.next/server/app/performance/page_client-reference-manifest.js
@@ -0,0 +1 @@
+globalThis.__RSC_MANIFEST=(globalThis.__RSC_MANIFEST||{});globalThis.__RSC_MANIFEST["/performance/page"]={"moduleLoading":{"prefix":"/_next/","crossOrigin":null},"ssrModuleMapping":{"176":{"*":{"id":"6676","name":"*","chunks":[],"async":false}},"841":{"*":{"id":"9737","name":"*","chunks":[],"async":false}},"892":{"*":{"id":"5213","name":"*","chunks":[],"async":false}},"2010":{"*":{"id":"7619","name":"*","chunks":[],"async":false}},"2433":{"*":{"id":"6544","name":"*","chunks":[],"async":false}},"2651":{"*":{"id":"9645","name":"*","chunks":[],"async":false}},"2987":{"*":{"id":"1358","name":"*","chunks":[],"async":false}},"3713":{"*":{"id":"5210","name":"*","chunks":[],"async":false}},"4374":{"*":{"id":"9927","name":"*","chunks":[],"async":false}},"6056":{"*":{"id":"1309","name":"*","chunks":[],"async":false}},"6543":{"*":{"id":"9722","name":"*","chunks":[],"async":false}},"6813":{"*":{"id":"5877","name":"*","chunks":[],"async":false}},"7096":{"*":{"id":"1952","name":"*","chunks":[],"async":false}},"7413":{"*":{"id":"8052","name":"*","chunks":[],"async":false}},"7523":{"*":{"id":"3477","name":"*","chunks":[],"async":false}},"7768":{"*":{"id":"7663","name":"*","chunks":[],"async":false}},"8145":{"*":{"id":"8377","name":"*","chunks":[],"async":false}},"8528":{"*":{"id":"5116","name":"*","chunks":[],"async":false}},"8547":{"*":{"id":"5441","name":"*","chunks":[],"async":false}},"9135":{"*":{"id":"432","name":"*","chunks":[],"async":false}},"9239":{"*":{"id":"8132","name":"*","chunks":[],"async":false}},"9414":{"*":{"id":"8850","name":"*","chunks":[],"async":false}},"9570":{"*":{"id":"291","name":"*","chunks":[],"async":false}}},"edgeSSRModuleMapping":{},"clientModules":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/globals.css":{"id":4443,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/components/AppShell.tsx":{"id":6813,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/backtest/page.tsx":{"id":4374,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chart-analyst/page.tsx":{"id":6543,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chat/page.tsx":{"id":841,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chatbot/page.tsx":{"id":8145,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/learning/page.tsx":{"id":6056,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/methodology/page.tsx":{"id":7413,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/ipo-radar/page.tsx":{"id":9135,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/market-brain/page.tsx":{"id":2987,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page.tsx":{"id":892,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/dashboard/page.tsx":{"id":7096,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","96","static/chunks/96-ce8c57cd15d50941.js","931","static/chunks/app/page-d0db9a93fb4af9a5.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/etf-radar/page.tsx":{"id":9239,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/performance/page.tsx":{"id":8547,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","367","static/chunks/app/performance/page-72d89cf8fa4bd0b1.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/signal-lab/page.tsx":{"id":2010,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/sniper/page.tsx":{"id":7768,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/stock-radar/page.tsx":{"id":9570,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/assets/[ticker]/view.tsx":{"id":3713,"name":"*","chunks":[],"async":false}},"entryCSSFiles":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout":["static/css/02bd12e03544ea91.css"],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/page":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/performance/page":[]}}
\ No newline at end of file
diff --git a/frontend/.next/server/app/signal-lab.html b/frontend/.next/server/app/signal-lab.html
new file mode 100644
index 0000000000000000000000000000000000000000..64067c5995fcdf048b5c9bac89f9881c2e181825
--- /dev/null
+++ b/frontend/.next/server/app/signal-lab.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading signal lab
\ No newline at end of file
diff --git a/frontend/.next/server/app/signal-lab.meta b/frontend/.next/server/app/signal-lab.meta
new file mode 100644
index 0000000000000000000000000000000000000000..adb41998e63212d12fc6d9a9570261a11b290c6b
--- /dev/null
+++ b/frontend/.next/server/app/signal-lab.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/signal-lab/layout,_N_T_/signal-lab/page,_N_T_/signal-lab/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/signal-lab.rsc b/frontend/.next/server/app/signal-lab.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..974c6a0ca54d7aa616b65ec23267e28b8d872394
--- /dev/null
+++ b/frontend/.next/server/app/signal-lab.rsc
@@ -0,0 +1,8 @@
+2:I[7523,[],"ClientPageRoot"]
+3:I[2010,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","826","static/chunks/app/signal-lab/page-a2f85a5c0d0847cd.js"],"default",1]
+4:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["signal-lab",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["signal-lab",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","signal-lab","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/signal-lab/page.js b/frontend/.next/server/app/signal-lab/page.js
new file mode 100644
index 0000000000000000000000000000000000000000..f4019f0ffaabca5e8534bbd24f5703195a24c3b7
--- /dev/null
+++ b/frontend/.next/server/app/signal-lab/page.js
@@ -0,0 +1 @@
+(()=>{var e={};e.id=826,e.ids=[826],e.modules={2934:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external.js")},4580:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external.js")},5869:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},399:e=>{"use strict";e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},9379:(e,s,n)=>{"use strict";n.r(s),n.d(s,{GlobalError:()=>t.a,__next_app__:()=>h,originalPathname:()=>u,pages:()=>d,routeModule:()=>p,tree:()=>o}),n(1183),n(8777),n(311);var i=n(9296),a=n(1650),r=n(7045),t=n.n(r),l=n(8184),c={};for(let e in l)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(c[e]=()=>l[e]);n.d(s,c);let o=["",{children:["signal-lab",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(n.bind(n,1183)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/signal-lab/page.tsx"]}]},{}]},{layout:[()=>Promise.resolve().then(n.bind(n,8777)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout.tsx"],"not-found":[()=>Promise.resolve().then(n.t.bind(n,311,23)),"next/dist/client/components/not-found-error"]}],d=["/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/signal-lab/page.tsx"],u="/signal-lab/page",h={require:n,loadChunk:()=>Promise.resolve()},p=new i.AppPageRouteModule({definition:{kind:a.x.APP_PAGE,page:"/signal-lab/page",pathname:"/signal-lab",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:o}})},8073:(e,s,n)=>{Promise.resolve().then(n.bind(n,7619))},7619:(e,s,n)=>{"use strict";n.r(s),n.d(s,{default:()=>p});var i=n(8924),a=n(3911);n(3789);var r=n(6927),t=n(2522),l=n(2828),c=n(398),o=n(8117),d=n(3081);function u({signals:e}){return e.length?i.jsx("div",{className:"table-shell",children:(0,i.jsxs)("table",{className:"intel-table",children:[i.jsx("thead",{children:(0,i.jsxs)("tr",{children:[i.jsx("th",{children:"Asset"}),i.jsx("th",{children:"Market"}),i.jsx("th",{children:"Score"}),i.jsx("th",{children:"Confidence"}),i.jsx("th",{children:"Classification"}),i.jsx("th",{children:"Risk"}),i.jsx("th",{children:"Momentum"}),i.jsx("th",{children:"Trend"}),i.jsx("th",{children:"Sentiment"}),i.jsx("th",{children:"Why it surfaced"})]})}),i.jsx("tbody",{children:e.map(e=>(0,i.jsxs)("tr",{children:[(0,i.jsxs)("td",{children:[i.jsx(l.default,{href:(0,c.up)(e.ticker),className:"asset-link",children:e.ticker}),i.jsx("span",{children:e.asset?.name??"Name pending"}),(0,i.jsxs)("span",{children:[e.asset?.asset_type??"Asset"," | ",e.asset?.sector??"Sector pending"," | ",e.asset?.exchange??"Exchange n/a"]})]}),(0,i.jsxs)("td",{children:[i.jsx("strong",{children:(0,o.T4)(e.market_snapshot?.price,e.market_snapshot?.currency)}),(0,i.jsxs)("span",{children:[(0,o.T3)(e.market_snapshot?.perf_1d)," 1D | ",(0,o.T3)(e.market_snapshot?.perf_5d)," 5D"]}),(0,i.jsxs)("span",{children:[e.market_snapshot?.provider??"provider n/a"," | vol ",(0,o.fP)(e.market_snapshot?.volume)]})]}),i.jsx("td",{children:i.jsx("strong",{className:"score-number",children:e.blum_score.toFixed(1)})}),(0,i.jsxs)("td",{children:[i.jsx("span",{className:"metric-pill",children:Number(e.confidence_score??0).toFixed(0)}),i.jsx("span",{children:e.lifecycle_state??"active"}),e.accuracy&&(0,i.jsxs)("span",{children:["evidence ",e.accuracy.blum_confidence_score.toFixed(0)," / ",e.accuracy.confidence_label]})]}),i.jsx("td",{children:i.jsx(d.O,{label:e.classification})}),(0,i.jsxs)("td",{children:[e.risk_level,i.jsx("span",{children:e.score_version??"blum-score"})]}),i.jsx("td",{children:h(e,"momentum_score")}),i.jsx("td",{children:h(e,"trend_score")}),i.jsx("td",{children:h(e,"sentiment_score")}),i.jsx("td",{className:"why",children:e.explanation})]},`${e.ticker}-${e.created_at}`))})]})}):i.jsx("div",{className:"empty-state",children:"No signal snapshots are available yet. The autonomous intelligence engine is hydrating price, news, sentiment and provider diagnostics."})}function h(e,s){let n=e.score_breakdown?.[s]??0;return i.jsx("span",{className:"metric-pill",children:Number(n).toFixed(0)})}function p(){let[e,s]=(0,a.useState)(null),[n,l]=(0,a.useState)([]),[c,o]=(0,a.useState)(null),[d,h]=(0,a.useState)(""),[p,j]=(0,a.useState)(""),[v,f]=(0,a.useState)(""),b=(0,a.useMemo)(()=>(e??[]).filter(e=>(!d||e.asset?.asset_type===d)&&(!p||e.risk_level===p)&&(!v||e.classification===v)),[e,d,p,v]);return e?(0,i.jsxs)(i.Fragment,{children:[i.jsx(r.ft,{eyebrow:"Signal Lab",title:"Analyst-grade signal feed and evidence audit.",subtitle:"Every signal is treated as a research note with confidence, evidence stack, trigger, invalidation logic and historical learning impact.",statusItems:[{label:"Signal feed",value:String(e.length),tone:e.length?"positive":"attention"},{label:"Filtered",value:String(b.length)},{label:"Evaluations",value:String(n.length),tone:n.length?"info":"attention"},{label:"Accuracy",value:g(c?.historical_accuracy),tone:"attention"}]}),i.jsx(m,{accuracy:c}),i.jsx(r.Ez,{title:"Signal Filters",value:`${b.length} visible`,subtitle:"Filter by asset type, risk and classification",children:(0,i.jsxs)("div",{className:"control-row",style:{marginBottom:0},children:[(0,i.jsxs)("select",{className:"input",value:d,onChange:e=>h(e.target.value),children:[i.jsx("option",{value:"",children:"All asset types"}),i.jsx("option",{value:"Stock",children:"Stock"}),i.jsx("option",{value:"ETF",children:"ETF"})]}),(0,i.jsxs)("select",{className:"input",value:p,onChange:e=>j(e.target.value),children:[i.jsx("option",{value:"",children:"All risks"}),i.jsx("option",{children:"Low"}),i.jsx("option",{children:"Medium"}),i.jsx("option",{children:"High"})]}),(0,i.jsxs)("select",{className:"input",value:v,onChange:e=>f(e.target.value),children:[i.jsx("option",{value:"",children:"All classifications"}),Array.from(new Set(e.map(e=>e.classification))).map(e=>i.jsx("option",{children:e},e))]})]})}),i.jsx("section",{className:"professional-grid-3",style:{marginTop:12},children:b.slice(0,6).map(e=>i.jsx(r.il,{signal:e},`${e.ticker}-${e.created_at}-card`))}),i.jsx(r.Ez,{title:"Signal Feed",value:`${b.length} signals`,subtitle:"Sortable table with price, classification, risk, momentum, trend and sentiment",className:"radar-core-panel",children:i.jsx(u,{signals:b})}),i.jsx(x,{evaluations:n})]}):i.jsx(t.G,{label:"Loading signal lab"})}function m({accuracy:e}){let s=e?.confidence_calibration??{};return(0,i.jsxs)(r.Ez,{title:"Financial Brain Learning Audit",value:s.status??"pending",className:"financial-brain-panel",children:[(0,i.jsxs)("div",{className:"professional-grid-4",children:[i.jsx(r.i9,{label:"Historical Accuracy",value:g(e?.historical_accuracy)}),i.jsx(r.i9,{label:"7D Success",value:g(e?.success_rate_7d)}),i.jsx(r.i9,{label:"30D Success",value:g(e?.success_rate_30d)}),i.jsx(r.i9,{label:"Calibration",value:void 0===s.score||null===s.score?"Pending":`${Number(s.score).toFixed(1)}/100`})]}),i.jsx("div",{style:{marginTop:12},children:i.jsx(r.IL,{value:s.score,label:"Confidence calibration"})}),(0,i.jsxs)("div",{className:"brain-two-col",children:[(0,i.jsxs)("div",{children:[i.jsx("h3",{children:"Best signal types"}),i.jsx(j,{rows:e?.by_signal_type?.slice(0,5)??[]})]}),(0,i.jsxs)("div",{children:[i.jsx("h3",{children:"Source reliability"}),(0,i.jsxs)("div",{className:"brain-performance-list",children:[(e?.source_reliability??[]).slice(0,5).map(e=>(0,i.jsxs)("div",{children:[i.jsx("strong",{children:e.source}),(0,i.jsxs)("span",{children:[Number(e.reliability_score??0).toFixed(1)," reliability | ",e.article_count??0," articles"]})]},e.source)),!e?.source_reliability?.length&&i.jsx("div",{className:"empty-state compact",children:"Waiting for linked source outcomes."})]})]})]}),i.jsx("p",{children:"Signal outcomes are evaluated by the autonomous learning loop. This view shows stored evidence, calibration and source reliability without requiring manual intervention."})]})}function x({evaluations:e}){return(0,i.jsxs)("section",{className:"panel",style:{marginTop:12},children:[(0,i.jsxs)("div",{className:"panel-head",children:[i.jsx("span",{children:"Signal Outcome Memory"}),(0,i.jsxs)("strong",{children:[e.length," horizons"]})]}),(0,i.jsxs)("div",{className:"evaluation-table",children:[(0,i.jsxs)("div",{className:"evaluation-row header",children:[i.jsx("span",{children:"Ticker"}),i.jsx("span",{children:"Signal"}),i.jsx("span",{children:"Horizon"}),i.jsx("span",{children:"Pre-signal confidence"}),i.jsx("span",{children:"Post result"}),i.jsx("span",{children:"Learning impact"}),i.jsx("span",{children:"Invalidating conditions"})]}),e.map(e=>(0,i.jsxs)("div",{className:"evaluation-row",children:[i.jsx("strong",{children:e.ticker}),i.jsx("span",{children:e.signal_type}),(0,i.jsxs)("span",{children:[e.horizon_days,"D"]}),i.jsx("span",{children:e.initial_confidence.toFixed(1)}),i.jsx("span",{className:`outcome ${e.outcome}`,children:e.outcome}),i.jsx("span",{children:"correct"===e.outcome?"Supports future confidence in similar setups":"wrong"===e.outcome?"Reduces future confidence for similar evidence":"neutral"===e.outcome?"Keeps confidence stable; follow-through was inconclusive":"Pending future price observations"}),i.jsx("span",{children:function(e){let s=e.evaluation_payload??{};return"wrong"===e.outcome?s.reason??"Price action contradicted the initial thesis.":"inconclusive"===e.outcome?"Horizon has not matured or future OHLCV is missing.":"Monitor sentiment reversal, volume decay and support/resistance failure."}(e)})]},e.id)),!e.length&&i.jsx("div",{className:"empty-state",children:"No learning evaluations are stored yet. Run the learning cycle after signal snapshots exist."})]})]})}function j({rows:e}){return e.length?i.jsx("div",{className:"brain-performance-list",children:e.map(e=>(0,i.jsxs)("div",{children:[i.jsx("strong",{children:e.key}),(0,i.jsxs)("span",{children:[g(e.success_rate)," success | ",e.mature_count," matured | score ",e.accuracy_score.toFixed(1)]})]},e.key))}):i.jsx("div",{className:"empty-state compact",children:"Waiting for matured signal families."})}function g(e){return null==e?"Pending":`${Math.round(100*Number(e))}%`}},2522:(e,s,n)=>{"use strict";n.d(s,{G:()=>a});var i=n(8924);function a({label:e="Loading intelligence snapshot"}){return(0,i.jsxs)("div",{className:"loading-state",children:[i.jsx("div",{}),i.jsx("span",{children:e})]})}},8117:(e,s,n)=>{"use strict";n.d(s,{Ku:()=>a,T3:()=>t,T4:()=>r,fP:()=>l});var i=n(8924);function a({snapshot:e,compact:s=!1}){return e&&"ready"===e.data_status&&null!=e.price?(0,i.jsxs)("div",{className:s?"market-strip compact":"market-strip",children:[(0,i.jsxs)("div",{children:[i.jsx("span",{children:"Last Price"}),i.jsx("strong",{children:r(e.price,e.currency)})]}),(0,i.jsxs)("div",{children:[i.jsx("span",{children:"1D"}),i.jsx("strong",{className:c(e.perf_1d),children:t(e.perf_1d)})]}),!s&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)("div",{children:[i.jsx("span",{children:"5D"}),i.jsx("strong",{className:c(e.perf_5d),children:t(e.perf_5d)})]}),(0,i.jsxs)("div",{children:[i.jsx("span",{children:"1M"}),i.jsx("strong",{className:c(e.perf_1m),children:t(e.perf_1m)})]})]}),(0,i.jsxs)("div",{children:[i.jsx("span",{children:e.provider??"Provider"}),i.jsx("strong",{children:e.date??"n/a"})]})]}):(0,i.jsxs)("div",{className:s?"market-strip compact":"market-strip",children:[(0,i.jsxs)("div",{children:[i.jsx("span",{children:"Price"}),i.jsx("strong",{children:"Real price pending"})]}),(0,i.jsxs)("div",{children:[i.jsx("span",{children:"Provider"}),i.jsx("strong",{children:"n/a"})]})]})}function r(e,s="USD"){return null==e||Number.isNaN(Number(e))?"n/a":new Intl.NumberFormat("en",{style:"currency",currency:s||"USD",maximumFractionDigits:e>=100?2:4}).format(Number(e))}function t(e){return null==e||Number.isNaN(Number(e))?"n/a":`${e>0?"+":""}${Number(e).toFixed(2)}%`}function l(e){return null==e||Number.isNaN(Number(e))?"n/a":new Intl.NumberFormat("en",{notation:"compact",maximumFractionDigits:2}).format(Number(e))}function c(e){return null==e?"":e>0?"positive-text":e<0?"negative-text":""}},3081:(e,s,n)=>{"use strict";n.d(s,{O:()=>r});var i=n(8924),a=n(9779);function r({label:e}){let s=e.includes("Breakout")||e.includes("Strong")?"positive":e.includes("Risk")||e.includes("Avoid")?"negative":e.includes("Divergence")||e.includes("Contrarian")?"warning":"neutral";return i.jsx("span",{className:(0,a.Z)("status-badge",s),children:e})}},1183:(e,s,n)=>{"use strict";n.r(s),n.d(s,{default:()=>i});let i=(0,n(6691).createProxy)(String.raw`/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/signal-lab/page.tsx#default`)}};var s=require("../../webpack-runtime.js");s.C(e);var n=e=>s(s.s=e),i=s.X(0,[273,394,927],()=>n(9379));module.exports=i})();
\ No newline at end of file
diff --git a/frontend/.next/server/app/signal-lab/page.js.nft.json b/frontend/.next/server/app/signal-lab/page.js.nft.json
new file mode 100644
index 0000000000000000000000000000000000000000..77578a3c1517e5a73d13826b0254aea2983bdd03
--- /dev/null
+++ b/frontend/.next/server/app/signal-lab/page.js.nft.json
@@ -0,0 +1 @@
+{"version":1,"files":["../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/package.json","../../../../node_modules/next","../../../../package.json","../../../package.json","../../chunks/273.js","../../chunks/394.js","../../chunks/927.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}
\ No newline at end of file
diff --git a/frontend/.next/server/app/signal-lab/page_client-reference-manifest.js b/frontend/.next/server/app/signal-lab/page_client-reference-manifest.js
new file mode 100644
index 0000000000000000000000000000000000000000..9d18da7a2bc690248e06b17478df572c8d8aa9ef
--- /dev/null
+++ b/frontend/.next/server/app/signal-lab/page_client-reference-manifest.js
@@ -0,0 +1 @@
+globalThis.__RSC_MANIFEST=(globalThis.__RSC_MANIFEST||{});globalThis.__RSC_MANIFEST["/signal-lab/page"]={"moduleLoading":{"prefix":"/_next/","crossOrigin":null},"ssrModuleMapping":{"176":{"*":{"id":"6676","name":"*","chunks":[],"async":false}},"841":{"*":{"id":"9737","name":"*","chunks":[],"async":false}},"892":{"*":{"id":"5213","name":"*","chunks":[],"async":false}},"2010":{"*":{"id":"7619","name":"*","chunks":[],"async":false}},"2433":{"*":{"id":"6544","name":"*","chunks":[],"async":false}},"2651":{"*":{"id":"9645","name":"*","chunks":[],"async":false}},"2987":{"*":{"id":"1358","name":"*","chunks":[],"async":false}},"3713":{"*":{"id":"5210","name":"*","chunks":[],"async":false}},"4374":{"*":{"id":"9927","name":"*","chunks":[],"async":false}},"6056":{"*":{"id":"1309","name":"*","chunks":[],"async":false}},"6543":{"*":{"id":"9722","name":"*","chunks":[],"async":false}},"6813":{"*":{"id":"5877","name":"*","chunks":[],"async":false}},"7096":{"*":{"id":"1952","name":"*","chunks":[],"async":false}},"7413":{"*":{"id":"8052","name":"*","chunks":[],"async":false}},"7523":{"*":{"id":"3477","name":"*","chunks":[],"async":false}},"7768":{"*":{"id":"7663","name":"*","chunks":[],"async":false}},"8145":{"*":{"id":"8377","name":"*","chunks":[],"async":false}},"8528":{"*":{"id":"5116","name":"*","chunks":[],"async":false}},"8547":{"*":{"id":"5441","name":"*","chunks":[],"async":false}},"9135":{"*":{"id":"432","name":"*","chunks":[],"async":false}},"9239":{"*":{"id":"8132","name":"*","chunks":[],"async":false}},"9414":{"*":{"id":"8850","name":"*","chunks":[],"async":false}},"9570":{"*":{"id":"291","name":"*","chunks":[],"async":false}}},"edgeSSRModuleMapping":{},"clientModules":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/globals.css":{"id":4443,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/components/AppShell.tsx":{"id":6813,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/backtest/page.tsx":{"id":4374,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chart-analyst/page.tsx":{"id":6543,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chat/page.tsx":{"id":841,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chatbot/page.tsx":{"id":8145,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/learning/page.tsx":{"id":6056,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/methodology/page.tsx":{"id":7413,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/ipo-radar/page.tsx":{"id":9135,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/market-brain/page.tsx":{"id":2987,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page.tsx":{"id":892,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/dashboard/page.tsx":{"id":7096,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","96","static/chunks/96-ce8c57cd15d50941.js","931","static/chunks/app/page-d0db9a93fb4af9a5.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/etf-radar/page.tsx":{"id":9239,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/performance/page.tsx":{"id":8547,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/signal-lab/page.tsx":{"id":2010,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","826","static/chunks/app/signal-lab/page-a2f85a5c0d0847cd.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/sniper/page.tsx":{"id":7768,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/stock-radar/page.tsx":{"id":9570,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/assets/[ticker]/view.tsx":{"id":3713,"name":"*","chunks":[],"async":false}},"entryCSSFiles":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout":["static/css/02bd12e03544ea91.css"],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/page":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/signal-lab/page":[]}}
\ No newline at end of file
diff --git a/frontend/.next/server/app/sniper.html b/frontend/.next/server/app/sniper.html
new file mode 100644
index 0000000000000000000000000000000000000000..670c500a9e6fc8d7ed5b64e98d5b9b4bb3171c49
--- /dev/null
+++ b/frontend/.next/server/app/sniper.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading BLUM Market Sniper Engine
\ No newline at end of file
diff --git a/frontend/.next/server/app/sniper.meta b/frontend/.next/server/app/sniper.meta
new file mode 100644
index 0000000000000000000000000000000000000000..b58a7e6877e9600228bc8e88c2cc821849ae52e5
--- /dev/null
+++ b/frontend/.next/server/app/sniper.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/sniper/layout,_N_T_/sniper/page,_N_T_/sniper/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/sniper.rsc b/frontend/.next/server/app/sniper.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..06e868ff83c19754d1884699270d1cbb36eb343b
--- /dev/null
+++ b/frontend/.next/server/app/sniper.rsc
@@ -0,0 +1,8 @@
+2:I[7523,[],"ClientPageRoot"]
+3:I[7768,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","74","static/chunks/app/sniper/page-66e545665c88da6b.js"],"default",1]
+4:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["sniper",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["sniper",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","sniper","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/sniper/page.js b/frontend/.next/server/app/sniper/page.js
new file mode 100644
index 0000000000000000000000000000000000000000..6d51d327e2f3887486320b1e38370aa004c4b5fa
--- /dev/null
+++ b/frontend/.next/server/app/sniper/page.js
@@ -0,0 +1 @@
+(()=>{var e={};e.id=74,e.ids=[74],e.modules={2934:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external.js")},4580:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external.js")},5869:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},399:e=>{"use strict";e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},5409:(e,t,s)=>{"use strict";s.r(t),s.d(t,{GlobalError:()=>a.a,__next_app__:()=>p,originalPathname:()=>u,pages:()=>d,routeModule:()=>x,tree:()=>c}),s(4109),s(8777),s(311);var i=s(9296),n=s(1650),r=s(7045),a=s.n(r),l=s(8184),o={};for(let e in l)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(o[e]=()=>l[e]);s.d(t,o);let c=["",{children:["sniper",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(s.bind(s,4109)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/sniper/page.tsx"]}]},{}]},{layout:[()=>Promise.resolve().then(s.bind(s,8777)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout.tsx"],"not-found":[()=>Promise.resolve().then(s.t.bind(s,311,23)),"next/dist/client/components/not-found-error"]}],d=["/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/sniper/page.tsx"],u="/sniper/page",p={require:s,loadChunk:()=>Promise.resolve()},x=new i.AppPageRouteModule({definition:{kind:n.x.APP_PAGE,page:"/sniper/page",pathname:"/sniper",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:c}})},5043:(e,t,s)=>{Promise.resolve().then(s.bind(s,7663))},7663:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>h});var i=s(8924),n=s(3911),r=s(2828),a=s(9534);let l=(0,s(6745).Z)("Target",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["circle",{cx:"12",cy:"12",r:"6",key:"1vlfrh"}],["circle",{cx:"12",cy:"12",r:"2",key:"1c9p78"}]]);var o=s(741);s(3789);var c=s(398),d=s(6927),u=s(2522),p=s(7749),x=s(3081);function h(){let[e,t]=(0,n.useState)(null),[s,h]=(0,n.useState)(null),[v,y]=(0,n.useState)([]),[_,f]=(0,n.useState)(""),b=e?.candidates??[],k=e?.summary??{},N=e?.market_regime??{},w=e?.sections??{},P=(0,n.useMemo)(()=>[{x:b.slice(0,18).map(e=>e.ticker),y:b.slice(0,18).map(e=>e.sniper_score??0),type:"bar",marker:{color:b.slice(0,18).map(e=>{var t;return"active_setup"===(t=e.actionability)?"#20e070":"actionable_if_confirmed"===t||"wait_for_trigger"===t?"#ffb000":"avoid"===t?"#ff4d5e":"#55aaff"})}}],[b]),R=s?.r_multiple??[],S=(0,n.useMemo)(()=>[{x:R.slice(0,14).map(e=>e.setup_type),y:R.slice(0,14).map(e=>e.expectancy_r??0),type:"bar",marker:{color:R.slice(0,14).map(e=>Number(e.expectancy_r??0)>=0?"#20e070":"#ff4d5e")}}],[R]);return!e&&_?(0,i.jsxs)("div",{className:"empty-state",children:["API error: ",_]}):e?(0,i.jsxs)(i.Fragment,{children:[i.jsx(d.ft,{eyebrow:"Market Sniper Engine",title:"Actionability, not generic attractiveness.",subtitle:"Conditional entry logic, invalidation, target zones, R-multiple learning, no-trade intelligence and exit discipline. Research only.",statusItems:[{label:"Regime",value:N.regime_primary??"n/a",tone:"risk_off"===N.regime_primary?"negative":"attention"},{label:"Candidates",value:String(k.candidate_count??b.length)},{label:"Avg Sniper",value:g(k.average_sniper_score),tone:"info"},{label:"Top Sniper",value:g(k.top_sniper_score),tone:"positive"}],actions:i.jsx(x.O,{label:"Informational scenarios only"})}),_&&(0,i.jsxs)("div",{className:"empty-state",style:{marginBottom:12},children:["API warning: ",_]}),(0,i.jsxs)("section",{className:"terminal-command-grid",children:[i.jsx(d.i9,{label:"Risk Appetite",value:g(N.risk_appetite_score),subvalue:N.breadth_state??"breadth n/a",tone:"attention"}),i.jsx(d.i9,{label:"Rotation Score",value:g(N.sector_rotation_score),subvalue:N.regime_secondary??"secondary regime"}),i.jsx(d.i9,{label:"Active Setups",value:w.active_setups?.length??0,subvalue:"confirmed conditional",tone:"positive"}),i.jsx(d.i9,{label:"Wait For Trigger",value:w.wait_for_trigger?.length??0,subvalue:"interesting, not active",tone:"attention"}),i.jsx(d.i9,{label:"Avoid",value:w.avoid_list?.length??0,subvalue:"no-trade filter",tone:"negative"}),i.jsx(d.i9,{label:"R-Metric Rows",value:R.length,subvalue:"R-multiple memory"}),i.jsx(d.i9,{label:"Lessons",value:v.length,subvalue:"recent reliability notes"}),i.jsx(d.i9,{label:"Policy",value:"Wait > weak entry",subvalue:"selective by design"})]}),(0,i.jsxs)("section",{className:"grid-2",style:{marginTop:12},children:[i.jsx(p.G,{title:"Sniper Score Distribution",data:P,layout:{yaxis:{range:[0,100],title:"Sniper Score"},xaxis:{title:"Candidate"}},emptyMessage:"No Sniper candidates available yet."}),i.jsx(p.G,{title:"Expectancy by Setup Type",data:S,layout:{yaxis:{title:"Expectancy in R"},xaxis:{title:"Setup"}},emptyMessage:"R-multiple metrics appear after historical execution simulations."})]}),i.jsx("section",{className:"grid-3",style:{marginTop:12},children:b.slice(0,9).map(e=>i.jsx(m,{item:e},e.ticker))}),(0,i.jsxs)("section",{className:"grid-2",style:{marginTop:12},children:[i.jsx(j,{title:"Active Setups",icon:i.jsx(a.Z,{size:17}),rows:w.active_setups??[],empty:"No active conditional setup. BLUM prefers patience."}),i.jsx(j,{title:"Wait For Trigger",icon:i.jsx(l,{size:17}),rows:w.wait_for_trigger??[],empty:"No wait-for-trigger setups."})]}),(0,i.jsxs)("section",{className:"grid-2",style:{marginTop:12},children:[i.jsx(j,{title:"Avoid List",icon:i.jsx(o.Z,{size:17}),rows:w.avoid_list??[],empty:"No hard no-trade decisions in the current candidate set."}),i.jsx(d.Ez,{title:"Recent Learning Lessons",value:`${v.length} notes`,children:(0,i.jsxs)("div",{className:"brain-list dense",children:[v.map((e,t)=>(0,i.jsxs)("div",{children:[i.jsx(x.O,{label:e.severity??"Info"}),i.jsx("strong",{children:e.lesson}),(0,i.jsxs)("p",{children:["Sample count: ",e.sample_count??0,". Reliability remains conditional and non-predictive."]})]},`${e.lesson}-${t}`)),!v.length&&i.jsx("div",{className:"empty-state",children:"No Sniper lessons yet. Execution simulations will populate this panel."})]})})]}),i.jsx("section",{style:{marginTop:12},children:i.jsx(d.Ez,{title:"Execution Plan Matrix",value:`${b.length} candidates`,subtitle:"Entry, trigger, invalidation, targets, risk/reward and no-trade reasons",className:"radar-core-panel",children:i.jsx("div",{className:"table-shell",children:(0,i.jsxs)("table",{className:"intel-table",children:[i.jsx("thead",{children:(0,i.jsxs)("tr",{children:[i.jsx("th",{children:"Ticker"}),i.jsx("th",{children:"Actionability"}),i.jsx("th",{children:"Setup"}),i.jsx("th",{children:"Entry / Trigger"}),i.jsx("th",{children:"Risk"}),i.jsx("th",{children:"Targets"}),i.jsx("th",{children:"No-Trade"})]})}),i.jsx("tbody",{children:b.map(e=>{let t=e.trade_plan??{},s=e.setup??{},n=e.risk??{},a=t.entry_zone??{};return(0,i.jsxs)("tr",{children:[(0,i.jsxs)("td",{children:[i.jsx(r.default,{className:"asset-link",href:(0,c.up)(e.ticker),children:e.ticker}),i.jsx("span",{children:e.asset?.name})]}),(0,i.jsxs)("td",{children:[i.jsx(x.O,{label:e.actionability}),(0,i.jsxs)("span",{children:["Sniper ",g(e.sniper_score),"/100"]})]}),(0,i.jsxs)("td",{children:[i.jsx("strong",{children:s.setup_type}),(0,i.jsxs)("span",{children:["Quality ",g(s.setup_quality_score)," | Reliability ",g(s.historical_reliability)]})]}),(0,i.jsxs)("td",{children:[(0,i.jsxs)("strong",{children:[a.low??"n/a"," - ",a.high??"n/a"]}),i.jsx("span",{children:t.entry_trigger})]}),(0,i.jsxs)("td",{children:[(0,i.jsxs)("strong",{children:["Invalidation ",t.invalidation_level??"n/a"]}),(0,i.jsxs)("span",{children:[n.position_risk_class," | RR ",t.risk_reward_estimate?.reward_to_risk??"n/a","R"]})]}),(0,i.jsxs)("td",{children:[(0,i.jsxs)("strong",{children:[t.target_1??"n/a"," / ",t.target_2??"n/a"]}),i.jsx("span",{children:t.trailing_exit_logic})]}),i.jsx("td",{children:i.jsx("span",{children:e.no_trade_reasons?.[0]?.reason??"No hard block; trigger still required."})})]},`plan-${e.ticker}`)})})]})})})})]}):i.jsx(u.G,{label:"Loading BLUM Market Sniper Engine"})}function m({item:e}){let t=e.trade_plan??{},s=e.setup??{},n=e.risk??{};return(0,i.jsxs)("article",{className:"score-card stock-radar-card",children:[(0,i.jsxs)("div",{className:"score-card-top",children:[(0,i.jsxs)("div",{children:[(0,i.jsxs)("span",{children:[e.asset?.sector??"Unknown"," | ",s.setup_type]}),i.jsx("h3",{children:e.ticker}),i.jsx("p",{className:"asset-subtitle",children:e.asset?.name})]}),i.jsx("div",{className:"score-ring",style:{"--score":e.sniper_score??0},children:i.jsx("strong",{children:Math.round(e.sniper_score??0)})})]}),i.jsx(x.O,{label:e.actionability}),i.jsx("p",{children:e.explanation}),(0,i.jsxs)("div",{className:"mini-metrics",children:[(0,i.jsxs)("div",{children:[i.jsx("span",{children:"Entry"}),(0,i.jsxs)("strong",{children:[t.entry_zone?.low??"n/a","-",t.entry_zone?.high??"n/a"]})]}),(0,i.jsxs)("div",{children:[i.jsx("span",{children:"Invalidation"}),i.jsx("strong",{children:t.invalidation_level??"n/a"})]}),(0,i.jsxs)("div",{children:[i.jsx("span",{children:"RR"}),(0,i.jsxs)("strong",{children:[t.risk_reward_estimate?.reward_to_risk??"n/a","R"]})]}),(0,i.jsxs)("div",{children:[i.jsx("span",{children:"Risk"}),i.jsx("strong",{children:n.position_risk_class??"n/a"})]})]})]})}function j({title:e,icon:t,rows:s,empty:n}){return i.jsx(d.Ez,{title:e,value:`${s.length} names`,children:(0,i.jsxs)("div",{className:"brain-list dense",children:[s.slice(0,12).map(s=>(0,i.jsxs)("div",{children:[(0,i.jsxs)("div",{className:"opportunity-line",children:[(0,i.jsxs)("strong",{children:[t,s.ticker]}),i.jsx(x.O,{label:s.actionability})]}),i.jsx("p",{children:s.explanation}),(0,i.jsxs)("div",{className:"mini-metrics",children:[(0,i.jsxs)("div",{children:[i.jsx("span",{children:"Score"}),i.jsx("strong",{children:g(s.sniper_score)})]}),(0,i.jsxs)("div",{children:[i.jsx("span",{children:"Setup"}),i.jsx("strong",{children:s.setup?.setup_type})]}),(0,i.jsxs)("div",{children:[i.jsx("span",{children:"RR"}),(0,i.jsxs)("strong",{children:[s.trade_plan?.risk_reward_estimate?.reward_to_risk??"n/a","R"]})]}),(0,i.jsxs)("div",{children:[i.jsx("span",{children:"Invalidation"}),i.jsx("strong",{children:s.trade_plan?.invalidation_level??"n/a"})]})]})]},`${e}-${s.ticker}`)),!s.length&&i.jsx("div",{className:"empty-state",children:n})]})})}function g(e){return null==e||Number.isNaN(Number(e))?"n/a":Number(e).toFixed(1)}},2522:(e,t,s)=>{"use strict";s.d(t,{G:()=>n});var i=s(8924);function n({label:e="Loading intelligence snapshot"}){return(0,i.jsxs)("div",{className:"loading-state",children:[i.jsx("div",{}),i.jsx("span",{children:e})]})}},7749:(e,t,s)=>{"use strict";s.d(t,{G:()=>o});var i=s(8924),n=s(1328),r=s.n(n),a=s(3911);let l=r()(async()=>{},{loadableGenerated:{modules:["components/PlotPanel.tsx -> react-plotly.js"]},ssr:!1});function o({title:e,data:t,layout:s={},height:n=360,emptyMessage:r="Waiting for real data series."}){let o=t.some(e=>[e?.x,e?.y,e?.z,e?.values,e?.labels].filter(Array.isArray).some(e=>!!e.length&&(!Array.isArray(e[0])||e.some(e=>Array.isArray(e)&&e.length>0)))),c={data:t,layout:{autosize:!0,height:n,paper_bgcolor:"#07090d",plot_bgcolor:"#090d13",font:{color:"#e7edf6",family:"Inter, system-ui, sans-serif"},margin:{l:42,r:18,t:18,b:36},xaxis:{gridcolor:"rgba(255,255,255,.06)",zeroline:!1},yaxis:{gridcolor:"rgba(255,255,255,.06)",zeroline:!1},...s},config:{displayModeBar:!1,responsive:!0},useResizeHandler:!0,style:{width:"100%"}};return(0,i.jsxs)("section",{className:"panel",children:[i.jsx("div",{className:"panel-head",children:i.jsx("span",{children:e})}),o?(0,a.createElement)(l,c):i.jsx("div",{className:"plot-empty",children:r})]})}},3081:(e,t,s)=>{"use strict";s.d(t,{O:()=>r});var i=s(8924),n=s(9779);function r({label:e}){let t=e.includes("Breakout")||e.includes("Strong")?"positive":e.includes("Risk")||e.includes("Avoid")?"negative":e.includes("Divergence")||e.includes("Contrarian")?"warning":"neutral";return i.jsx("span",{className:(0,n.Z)("status-badge",t),children:e})}},741:(e,t,s)=>{"use strict";s.d(t,{Z:()=>i});let i=(0,s(6745).Z)("TriangleAlert",[["path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",key:"wmoenq"}],["path",{d:"M12 9v4",key:"juzpu7"}],["path",{d:"M12 17h.01",key:"p32p05"}]])},1328:(e,t,s)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return r}});let i=s(1607);s(8924),s(3911);let n=i._(s(4737));function r(e,t){var s;let i={loading:e=>{let{error:t,isLoading:s,pastDelay:i}=e;return null}};"function"==typeof e&&(i.loader=e);let r={...i,...t};return(0,n.default)({...r,modules:null==(s=r.loadableGenerated)?void 0:s.modules})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},3880:(e,t,s)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"BailoutToCSR",{enumerable:!0,get:function(){return n}});let i=s(6483);function n(e){let{reason:t,children:s}=e;throw new i.BailoutToCSRError(t)}},4737:(e,t,s)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return c}});let i=s(8924),n=s(3911),r=s(3880),a=s(7083);function l(e){return{default:e&&"default"in e?e.default:e}}let o={loader:()=>Promise.resolve(l(()=>null)),loading:null,ssr:!0},c=function(e){let t={...o,...e},s=(0,n.lazy)(()=>t.loader().then(l)),c=t.loading;function d(e){let l=c?(0,i.jsx)(c,{isLoading:!0,pastDelay:!0,error:null}):null,o=t.ssr?(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(a.PreloadCss,{moduleIds:t.modules}),(0,i.jsx)(s,{...e})]}):(0,i.jsx)(r.BailoutToCSR,{reason:"next/dynamic",children:(0,i.jsx)(s,{...e})});return(0,i.jsx)(n.Suspense,{fallback:l,children:o})}return d.displayName="LoadableComponent",d}},7083:(e,t,s)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"PreloadCss",{enumerable:!0,get:function(){return r}});let i=s(8924),n=s(4580);function r(e){let{moduleIds:t}=e,s=(0,n.getExpectedRequestStore)("next/dynamic css"),r=[];if(s.reactLoadableManifest&&t){let e=s.reactLoadableManifest;for(let s of t){if(!e[s])continue;let t=e[s].files.filter(e=>e.endsWith(".css"));r.push(...t)}}return 0===r.length?null:(0,i.jsx)(i.Fragment,{children:r.map(e=>(0,i.jsx)("link",{precedence:"dynamic",rel:"stylesheet",href:s.assetPrefix+"/_next/"+encodeURI(e),as:"style"},e))})}},4109:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>i});let i=(0,s(6691).createProxy)(String.raw`/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/sniper/page.tsx#default`)}};var t=require("../../webpack-runtime.js");t.C(e);var s=e=>t(t.s=e),i=t.X(0,[273,394,927],()=>s(5409));module.exports=i})();
\ No newline at end of file
diff --git a/frontend/.next/server/app/sniper/page.js.nft.json b/frontend/.next/server/app/sniper/page.js.nft.json
new file mode 100644
index 0000000000000000000000000000000000000000..77578a3c1517e5a73d13826b0254aea2983bdd03
--- /dev/null
+++ b/frontend/.next/server/app/sniper/page.js.nft.json
@@ -0,0 +1 @@
+{"version":1,"files":["../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/package.json","../../../../node_modules/next","../../../../package.json","../../../package.json","../../chunks/273.js","../../chunks/394.js","../../chunks/927.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}
\ No newline at end of file
diff --git a/frontend/.next/server/app/sniper/page_client-reference-manifest.js b/frontend/.next/server/app/sniper/page_client-reference-manifest.js
new file mode 100644
index 0000000000000000000000000000000000000000..556d0e9e2ccb2f32326fee9884736ed7be62dc3f
--- /dev/null
+++ b/frontend/.next/server/app/sniper/page_client-reference-manifest.js
@@ -0,0 +1 @@
+globalThis.__RSC_MANIFEST=(globalThis.__RSC_MANIFEST||{});globalThis.__RSC_MANIFEST["/sniper/page"]={"moduleLoading":{"prefix":"/_next/","crossOrigin":null},"ssrModuleMapping":{"176":{"*":{"id":"6676","name":"*","chunks":[],"async":false}},"841":{"*":{"id":"9737","name":"*","chunks":[],"async":false}},"892":{"*":{"id":"5213","name":"*","chunks":[],"async":false}},"2010":{"*":{"id":"7619","name":"*","chunks":[],"async":false}},"2433":{"*":{"id":"6544","name":"*","chunks":[],"async":false}},"2651":{"*":{"id":"9645","name":"*","chunks":[],"async":false}},"2987":{"*":{"id":"1358","name":"*","chunks":[],"async":false}},"3713":{"*":{"id":"5210","name":"*","chunks":[],"async":false}},"4374":{"*":{"id":"9927","name":"*","chunks":[],"async":false}},"6056":{"*":{"id":"1309","name":"*","chunks":[],"async":false}},"6543":{"*":{"id":"9722","name":"*","chunks":[],"async":false}},"6813":{"*":{"id":"5877","name":"*","chunks":[],"async":false}},"7096":{"*":{"id":"1952","name":"*","chunks":[],"async":false}},"7413":{"*":{"id":"8052","name":"*","chunks":[],"async":false}},"7523":{"*":{"id":"3477","name":"*","chunks":[],"async":false}},"7768":{"*":{"id":"7663","name":"*","chunks":[],"async":false}},"8145":{"*":{"id":"8377","name":"*","chunks":[],"async":false}},"8528":{"*":{"id":"5116","name":"*","chunks":[],"async":false}},"8547":{"*":{"id":"5441","name":"*","chunks":[],"async":false}},"9135":{"*":{"id":"432","name":"*","chunks":[],"async":false}},"9239":{"*":{"id":"8132","name":"*","chunks":[],"async":false}},"9414":{"*":{"id":"8850","name":"*","chunks":[],"async":false}},"9570":{"*":{"id":"291","name":"*","chunks":[],"async":false}}},"edgeSSRModuleMapping":{},"clientModules":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/globals.css":{"id":4443,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/components/AppShell.tsx":{"id":6813,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/backtest/page.tsx":{"id":4374,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chart-analyst/page.tsx":{"id":6543,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chat/page.tsx":{"id":841,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chatbot/page.tsx":{"id":8145,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/learning/page.tsx":{"id":6056,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/methodology/page.tsx":{"id":7413,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/ipo-radar/page.tsx":{"id":9135,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/market-brain/page.tsx":{"id":2987,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page.tsx":{"id":892,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/dashboard/page.tsx":{"id":7096,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","96","static/chunks/96-ce8c57cd15d50941.js","931","static/chunks/app/page-d0db9a93fb4af9a5.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/etf-radar/page.tsx":{"id":9239,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/performance/page.tsx":{"id":8547,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/signal-lab/page.tsx":{"id":2010,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/sniper/page.tsx":{"id":7768,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","74","static/chunks/app/sniper/page-66e545665c88da6b.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/stock-radar/page.tsx":{"id":9570,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/assets/[ticker]/view.tsx":{"id":3713,"name":"*","chunks":[],"async":false}},"entryCSSFiles":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout":["static/css/02bd12e03544ea91.css"],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/page":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/sniper/page":[]}}
\ No newline at end of file
diff --git a/frontend/.next/server/app/stock-radar.html b/frontend/.next/server/app/stock-radar.html
new file mode 100644
index 0000000000000000000000000000000000000000..bd981222822671db6c462d216df7c0d029e8451c
--- /dev/null
+++ b/frontend/.next/server/app/stock-radar.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading Stock Radar
\ No newline at end of file
diff --git a/frontend/.next/server/app/stock-radar.meta b/frontend/.next/server/app/stock-radar.meta
new file mode 100644
index 0000000000000000000000000000000000000000..4f563a0d77559c64c3676af29f2cdf4d37b8473d
--- /dev/null
+++ b/frontend/.next/server/app/stock-radar.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/stock-radar/layout,_N_T_/stock-radar/page,_N_T_/stock-radar/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/stock-radar.rsc b/frontend/.next/server/app/stock-radar.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..a53d0913e64fc0152b3b3a9f8a50b0a9996a3f36
--- /dev/null
+++ b/frontend/.next/server/app/stock-radar.rsc
@@ -0,0 +1,8 @@
+2:I[7523,[],"ClientPageRoot"]
+3:I[9570,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","511","static/chunks/app/stock-radar/page-6e7f483858d9a39e.js"],"default",1]
+4:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["stock-radar",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["stock-radar",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","stock-radar","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/stock-radar/page.js b/frontend/.next/server/app/stock-radar/page.js
new file mode 100644
index 0000000000000000000000000000000000000000..9be7f408622e57f1f1cee4af91d8bdde6aecba01
--- /dev/null
+++ b/frontend/.next/server/app/stock-radar/page.js
@@ -0,0 +1 @@
+(()=>{var e={};e.id=511,e.ids=[511],e.modules={2934:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external.js")},4580:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external.js")},5869:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},399:e=>{"use strict";e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},865:(e,s,t)=>{"use strict";t.r(s),t.d(s,{GlobalError:()=>i.a,__next_app__:()=>m,originalPathname:()=>u,pages:()=>d,routeModule:()=>p,tree:()=>c}),t(107),t(8777),t(311);var r=t(9296),a=t(1650),n=t(7045),i=t.n(n),l=t(8184),o={};for(let e in l)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(o[e]=()=>l[e]);t.d(s,o);let c=["",{children:["stock-radar",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(t.bind(t,107)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/stock-radar/page.tsx"]}]},{}]},{layout:[()=>Promise.resolve().then(t.bind(t,8777)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout.tsx"],"not-found":[()=>Promise.resolve().then(t.t.bind(t,311,23)),"next/dist/client/components/not-found-error"]}],d=["/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/stock-radar/page.tsx"],u="/stock-radar/page",m={require:t,loadChunk:()=>Promise.resolve()},p=new r.AppPageRouteModule({definition:{kind:a.x.APP_PAGE,page:"/stock-radar/page",pathname:"/stock-radar",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:c}})},6064:(e,s,t)=>{Promise.resolve().then(t.bind(t,291))},291:(e,s,t)=>{"use strict";t.r(s),t.d(s,{default:()=>m});var r=t(8924),a=t(2828),n=t(3911);t(3789);var i=t(6927),l=t(2522),o=t(8117),c=t(7749),d=t(3081);let u=[["strongest_signals","Strongest"],["narrative_breakouts","Narrative"],["technical_breakouts","Technical"],["quality_momentum","Quality Momentum"],["quiet_accumulation","Quiet Accumulation"],["sentiment_divergence","Divergence"],["high_risk_momentum","High Risk"],["contrarian_setups","Contrarian"]];function m(){let[e,s]=(0,n.useState)(null),[t,o]=(0,n.useState)("strongest_signals"),[d,m]=(0,n.useState)(""),[h,g]=(0,n.useState)(""),[j,v]=(0,n.useState)(""),[f,y]=(0,n.useState)(""),_=e?.sections?.[t]??[],b=_.length?_:e?.summary.signal_count?[]:e?.data_gaps??e?.rows??[],N=(0,n.useMemo)(()=>{let e=j.trim().toLowerCase();return b.filter(s=>(!d||s.asset.sector===d)&&(!h||s.research_priority===h)&&(!e||`${s.ticker} ${s.asset.name} ${s.asset.sector} ${s.asset.industry}`.toLowerCase().includes(e)))},[b,d,h,j]);if(!e)return f?(0,r.jsxs)("div",{className:"empty-state",children:["API error: ",f]}):r.jsx(l.G,{label:"Loading Stock Radar"});let k=e.rows.length?e.rows:e.data_gaps,S=Array.from(new Set(k.map(e=>e.asset.sector))).sort(),P=Array.from(new Set(k.map(e=>e.research_priority))).sort(),w=e.rows.filter(e=>e.signal);return(0,r.jsxs)(r.Fragment,{children:[r.jsx(i.ft,{eyebrow:"Stock Radar",title:"Equity opportunity radar and signal triage.",subtitle:"A research desk view for equities, price status, score factors, narrative evidence and risk state.",statusItems:[{label:"Stocks",value:String(e.summary.stock_count)},{label:"Signals",value:String(e.summary.signal_count),tone:e.summary.signal_count?"positive":"attention"},{label:"Priced",value:String(e.summary.priced_count),tone:e.summary.priced_count?"positive":"attention"},{label:"Avg score",value:e.summary.average_score.toFixed(1),tone:"attention"}],actions:(0,r.jsxs)("div",{className:"header-actions",children:[r.jsx(a.default,{className:"button",href:"/etf-radar",children:"ETF Radar"}),r.jsx(a.default,{className:"button",href:"/ipo-radar",children:"IPO Radar"})]})}),f&&(0,r.jsxs)("div",{className:"empty-state",style:{marginBottom:12},children:["API error: ",f]}),(0,r.jsxs)("section",{className:"terminal-command-grid",children:[r.jsx(i.i9,{label:"Stocks",value:e.summary.stock_count,subvalue:"Equity universe"}),r.jsx(i.i9,{label:"Signals",value:e.summary.signal_count,subvalue:`${e.summary.missing_signal_count} missing`,tone:e.summary.signal_count?"positive":"attention"}),r.jsx(i.i9,{label:"Priced",value:e.summary.priced_count,subvalue:"Latest stored price"}),r.jsx(i.i9,{label:"Avg Score",value:e.summary.average_score.toFixed(1),subvalue:`Top ${e.summary.top_score.toFixed(1)}`,tone:"attention"}),r.jsx(i.i9,{label:"High Risk",value:e.summary.high_risk_count,subvalue:"Risk-heavy momentum",tone:e.summary.high_risk_count?"negative":"neutral"}),r.jsx(i.i9,{label:"Positive 1D",value:e.summary.positive_1d_count,subvalue:"Short-term breadth",tone:"info"}),r.jsx(i.i9,{label:"Sectors",value:e.sector_leaders.length,subvalue:"Leadership groups"}),r.jsx(i.i9,{label:"Status",value:e.status.replaceAll("_"," "),subvalue:"Radar readiness"})]}),r.jsx("section",{className:"radar-tabs",style:{marginTop:12},children:u.map(([s,a])=>(0,r.jsxs)("button",{className:t===s?"active":"",onClick:()=>o(s),children:[a,r.jsx("span",{children:e.sections[s]?.length??0})]},s))}),"ready"!==e.status&&(0,r.jsxs)("section",{className:"panel readiness-panel",style:{marginTop:12},children:[(0,r.jsxs)("div",{className:"panel-head",children:[r.jsx("span",{children:"Evidence readiness"}),r.jsx("strong",{children:e.status.replaceAll("_"," ")})]}),r.jsx("p",{children:"The autonomous research engine is hydrating prices, news, sentiment, embeddings and signal snapshots in the background. The cards below show the real asset universe and latest stored market status. No synthetic prices, headlines or scores are displayed."}),(0,r.jsxs)("div",{className:"mini-metrics",children:[(0,r.jsxs)("div",{children:[r.jsx("span",{children:"Missing signals"}),r.jsx("strong",{children:e.summary.missing_signal_count})]}),(0,r.jsxs)("div",{children:[r.jsx("span",{children:"Priced names"}),r.jsx("strong",{children:e.summary.priced_count})]}),(0,r.jsxs)("div",{children:[r.jsx("span",{children:"Positive 1D"}),r.jsx("strong",{children:e.summary.positive_1d_count})]}),(0,r.jsxs)("div",{children:[r.jsx("span",{children:"Top score"}),r.jsx("strong",{children:e.summary.top_score.toFixed(1)})]})]})]}),r.jsx("section",{className:"grid-3",style:{marginTop:12},children:N.slice(0,6).map(e=>r.jsx(p,{row:e},`card-${e.ticker}`))}),(0,r.jsxs)("section",{className:"grid-2",style:{marginTop:12},children:[r.jsx(c.G,{title:"Sector Leadership",data:[{x:e.sector_leaders.map(e=>e.average_score),y:e.sector_leaders.map(e=>e.sector),type:"bar",orientation:"h",marker:{color:"#ffb000"}}],layout:{xaxis:{range:[0,100]}},emptyMessage:"Sector leadership appears after real signal snapshots are created."}),r.jsx(c.G,{title:"Momentum vs Sentiment",data:[{x:w.map(e=>e.factor_scores?.momentum??0),y:w.map(e=>e.factor_scores?.sentiment??0),text:w.map(e=>e.ticker),type:"scatter",mode:"markers+text",marker:{size:w.map(e=>Math.max(9,(e.signal?.blum_score??0)/5)),color:"#4dd8ff"}}],layout:{xaxis:{range:[0,100],title:"Momentum"},yaxis:{range:[0,100],title:"Sentiment"}},emptyMessage:"Momentum and sentiment scatter requires priced assets, linked news and signal snapshots."})]}),(0,r.jsxs)(i.Ez,{title:"Stock Radar Table",value:`${N.length} names`,subtitle:"Sortable terminal table for price, sentiment, momentum, confidence, signal and risk",className:"radar-core-panel",children:[(0,r.jsxs)("div",{className:"control-row",children:[r.jsx("input",{className:"input",placeholder:"Search ticker, company, sector",value:j,onChange:e=>v(e.target.value)}),(0,r.jsxs)("select",{className:"input",value:d,onChange:e=>m(e.target.value),children:[r.jsx("option",{value:"",children:"All sectors"}),S.map(e=>r.jsx("option",{children:e},e))]}),(0,r.jsxs)("select",{className:"input",value:h,onChange:e=>g(e.target.value),children:[r.jsx("option",{value:"",children:"All research priorities"}),P.map(e=>r.jsx("option",{children:e},e))]})]}),r.jsx(i.Xz,{rows:N.map(e=>{let s=e.signal?.blum_score??0,t=e.signal?.risk_level??"Not rated";return{ticker:e.ticker,name:e.asset.name,sector:e.asset.sector,assetType:e.asset.asset_type,price:e.market_snapshot.price,currency:e.market_snapshot.currency,changePercent:e.market_snapshot.perf_1d,volumeRelative:null,sentimentScore:x(e,"sentiment"),momentumScore:x(e,"momentum"),trendScore:x(e,"trend"),newsCount:Number(e.narrative_flags?.news_count_7d??0),newsScore:Number(e.narrative_flags?.narrative_intensity??e.narrative_flags?.news_count_7d??0),confidence:e.signal?.confidence_score??0,signalType:e.signal?.classification??"Insufficient Evidence",riskScore:x(e,"volatility"),riskLevel:t,action:s>=84?"Strong Attention":s>=68?"Watch":t.toLowerCase().includes("high")?"Avoid":"Monitor",why:e.why_watch}})})]})]})}function p({row:e}){let s=e.signal?.blum_score??0;return(0,r.jsxs)("article",{className:"score-card stock-radar-card",children:[(0,r.jsxs)("div",{className:"score-card-top",children:[(0,r.jsxs)("div",{children:[(0,r.jsxs)("span",{children:[e.asset.sector," | ",e.research_priority]}),r.jsx("h3",{children:e.ticker}),r.jsx("p",{className:"asset-subtitle",children:e.asset.name})]}),r.jsx("div",{className:"score-ring",style:{"--score":s},children:r.jsx("strong",{children:Math.round(s)})})]}),e.signal?r.jsx(d.O,{label:e.signal.classification}):r.jsx(d.O,{label:"Insufficient Evidence"}),r.jsx(o.Ku,{snapshot:e.market_snapshot,compact:!0}),r.jsx("div",{className:"tag-row",children:e.radar_tags.slice(0,5).map(e=>r.jsx("span",{children:e},e))}),r.jsx("p",{children:e.why_watch}),(0,r.jsxs)("div",{className:"mini-metrics",children:[(0,r.jsxs)("div",{children:[r.jsx("span",{children:"Trend"}),r.jsx("strong",{children:h(e,"trend")})]}),(0,r.jsxs)("div",{children:[r.jsx("span",{children:"Momentum"}),r.jsx("strong",{children:h(e,"momentum")})]}),(0,r.jsxs)("div",{children:[r.jsx("span",{children:"Sentiment"}),r.jsx("strong",{children:h(e,"sentiment")})]}),(0,r.jsxs)("div",{children:[r.jsx("span",{children:"Confidence"}),r.jsx("strong",{children:e.signal?.confidence_score?.toFixed(0)??"n/a"})]})]})]})}function h(e,s){return Number(e.factor_scores?.[s]??0).toFixed(0)}function x(e,s){return Number(e.factor_scores?.[s]??0)}},2522:(e,s,t)=>{"use strict";t.d(s,{G:()=>a});var r=t(8924);function a({label:e="Loading intelligence snapshot"}){return(0,r.jsxs)("div",{className:"loading-state",children:[r.jsx("div",{}),r.jsx("span",{children:e})]})}},8117:(e,s,t)=>{"use strict";t.d(s,{Ku:()=>a,T3:()=>i,T4:()=>n,fP:()=>l});var r=t(8924);function a({snapshot:e,compact:s=!1}){return e&&"ready"===e.data_status&&null!=e.price?(0,r.jsxs)("div",{className:s?"market-strip compact":"market-strip",children:[(0,r.jsxs)("div",{children:[r.jsx("span",{children:"Last Price"}),r.jsx("strong",{children:n(e.price,e.currency)})]}),(0,r.jsxs)("div",{children:[r.jsx("span",{children:"1D"}),r.jsx("strong",{className:o(e.perf_1d),children:i(e.perf_1d)})]}),!s&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("div",{children:[r.jsx("span",{children:"5D"}),r.jsx("strong",{className:o(e.perf_5d),children:i(e.perf_5d)})]}),(0,r.jsxs)("div",{children:[r.jsx("span",{children:"1M"}),r.jsx("strong",{className:o(e.perf_1m),children:i(e.perf_1m)})]})]}),(0,r.jsxs)("div",{children:[r.jsx("span",{children:e.provider??"Provider"}),r.jsx("strong",{children:e.date??"n/a"})]})]}):(0,r.jsxs)("div",{className:s?"market-strip compact":"market-strip",children:[(0,r.jsxs)("div",{children:[r.jsx("span",{children:"Price"}),r.jsx("strong",{children:"Real price pending"})]}),(0,r.jsxs)("div",{children:[r.jsx("span",{children:"Provider"}),r.jsx("strong",{children:"n/a"})]})]})}function n(e,s="USD"){return null==e||Number.isNaN(Number(e))?"n/a":new Intl.NumberFormat("en",{style:"currency",currency:s||"USD",maximumFractionDigits:e>=100?2:4}).format(Number(e))}function i(e){return null==e||Number.isNaN(Number(e))?"n/a":`${e>0?"+":""}${Number(e).toFixed(2)}%`}function l(e){return null==e||Number.isNaN(Number(e))?"n/a":new Intl.NumberFormat("en",{notation:"compact",maximumFractionDigits:2}).format(Number(e))}function o(e){return null==e?"":e>0?"positive-text":e<0?"negative-text":""}},7749:(e,s,t)=>{"use strict";t.d(s,{G:()=>o});var r=t(8924),a=t(1328),n=t.n(a),i=t(3911);let l=n()(async()=>{},{loadableGenerated:{modules:["components/PlotPanel.tsx -> react-plotly.js"]},ssr:!1});function o({title:e,data:s,layout:t={},height:a=360,emptyMessage:n="Waiting for real data series."}){let o=s.some(e=>[e?.x,e?.y,e?.z,e?.values,e?.labels].filter(Array.isArray).some(e=>!!e.length&&(!Array.isArray(e[0])||e.some(e=>Array.isArray(e)&&e.length>0)))),c={data:s,layout:{autosize:!0,height:a,paper_bgcolor:"#07090d",plot_bgcolor:"#090d13",font:{color:"#e7edf6",family:"Inter, system-ui, sans-serif"},margin:{l:42,r:18,t:18,b:36},xaxis:{gridcolor:"rgba(255,255,255,.06)",zeroline:!1},yaxis:{gridcolor:"rgba(255,255,255,.06)",zeroline:!1},...t},config:{displayModeBar:!1,responsive:!0},useResizeHandler:!0,style:{width:"100%"}};return(0,r.jsxs)("section",{className:"panel",children:[r.jsx("div",{className:"panel-head",children:r.jsx("span",{children:e})}),o?(0,i.createElement)(l,c):r.jsx("div",{className:"plot-empty",children:n})]})}},3081:(e,s,t)=>{"use strict";t.d(s,{O:()=>n});var r=t(8924),a=t(9779);function n({label:e}){let s=e.includes("Breakout")||e.includes("Strong")?"positive":e.includes("Risk")||e.includes("Avoid")?"negative":e.includes("Divergence")||e.includes("Contrarian")?"warning":"neutral";return r.jsx("span",{className:(0,a.Z)("status-badge",s),children:e})}},1328:(e,s,t)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0}),Object.defineProperty(s,"default",{enumerable:!0,get:function(){return n}});let r=t(1607);t(8924),t(3911);let a=r._(t(4737));function n(e,s){var t;let r={loading:e=>{let{error:s,isLoading:t,pastDelay:r}=e;return null}};"function"==typeof e&&(r.loader=e);let n={...r,...s};return(0,a.default)({...n,modules:null==(t=n.loadableGenerated)?void 0:t.modules})}("function"==typeof s.default||"object"==typeof s.default&&null!==s.default)&&void 0===s.default.__esModule&&(Object.defineProperty(s.default,"__esModule",{value:!0}),Object.assign(s.default,s),e.exports=s.default)},3880:(e,s,t)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0}),Object.defineProperty(s,"BailoutToCSR",{enumerable:!0,get:function(){return a}});let r=t(6483);function a(e){let{reason:s,children:t}=e;throw new r.BailoutToCSRError(s)}},4737:(e,s,t)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0}),Object.defineProperty(s,"default",{enumerable:!0,get:function(){return c}});let r=t(8924),a=t(3911),n=t(3880),i=t(7083);function l(e){return{default:e&&"default"in e?e.default:e}}let o={loader:()=>Promise.resolve(l(()=>null)),loading:null,ssr:!0},c=function(e){let s={...o,...e},t=(0,a.lazy)(()=>s.loader().then(l)),c=s.loading;function d(e){let l=c?(0,r.jsx)(c,{isLoading:!0,pastDelay:!0,error:null}):null,o=s.ssr?(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(i.PreloadCss,{moduleIds:s.modules}),(0,r.jsx)(t,{...e})]}):(0,r.jsx)(n.BailoutToCSR,{reason:"next/dynamic",children:(0,r.jsx)(t,{...e})});return(0,r.jsx)(a.Suspense,{fallback:l,children:o})}return d.displayName="LoadableComponent",d}},7083:(e,s,t)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0}),Object.defineProperty(s,"PreloadCss",{enumerable:!0,get:function(){return n}});let r=t(8924),a=t(4580);function n(e){let{moduleIds:s}=e,t=(0,a.getExpectedRequestStore)("next/dynamic css"),n=[];if(t.reactLoadableManifest&&s){let e=t.reactLoadableManifest;for(let t of s){if(!e[t])continue;let s=e[t].files.filter(e=>e.endsWith(".css"));n.push(...s)}}return 0===n.length?null:(0,r.jsx)(r.Fragment,{children:n.map(e=>(0,r.jsx)("link",{precedence:"dynamic",rel:"stylesheet",href:t.assetPrefix+"/_next/"+encodeURI(e),as:"style"},e))})}},107:(e,s,t)=>{"use strict";t.r(s),t.d(s,{default:()=>r});let r=(0,t(6691).createProxy)(String.raw`/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/stock-radar/page.tsx#default`)}};var s=require("../../webpack-runtime.js");s.C(e);var t=e=>s(s.s=e),r=s.X(0,[273,394,927],()=>t(865));module.exports=r})();
\ No newline at end of file
diff --git a/frontend/.next/server/app/stock-radar/page.js.nft.json b/frontend/.next/server/app/stock-radar/page.js.nft.json
new file mode 100644
index 0000000000000000000000000000000000000000..77578a3c1517e5a73d13826b0254aea2983bdd03
--- /dev/null
+++ b/frontend/.next/server/app/stock-radar/page.js.nft.json
@@ -0,0 +1 @@
+{"version":1,"files":["../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/package.json","../../../../node_modules/next","../../../../package.json","../../../package.json","../../chunks/273.js","../../chunks/394.js","../../chunks/927.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}
\ No newline at end of file
diff --git a/frontend/.next/server/app/stock-radar/page_client-reference-manifest.js b/frontend/.next/server/app/stock-radar/page_client-reference-manifest.js
new file mode 100644
index 0000000000000000000000000000000000000000..4e544cc81f29fb58a657631ff576bcffcaa483ab
--- /dev/null
+++ b/frontend/.next/server/app/stock-radar/page_client-reference-manifest.js
@@ -0,0 +1 @@
+globalThis.__RSC_MANIFEST=(globalThis.__RSC_MANIFEST||{});globalThis.__RSC_MANIFEST["/stock-radar/page"]={"moduleLoading":{"prefix":"/_next/","crossOrigin":null},"ssrModuleMapping":{"176":{"*":{"id":"6676","name":"*","chunks":[],"async":false}},"841":{"*":{"id":"9737","name":"*","chunks":[],"async":false}},"892":{"*":{"id":"5213","name":"*","chunks":[],"async":false}},"2010":{"*":{"id":"7619","name":"*","chunks":[],"async":false}},"2433":{"*":{"id":"6544","name":"*","chunks":[],"async":false}},"2651":{"*":{"id":"9645","name":"*","chunks":[],"async":false}},"2987":{"*":{"id":"1358","name":"*","chunks":[],"async":false}},"3713":{"*":{"id":"5210","name":"*","chunks":[],"async":false}},"4374":{"*":{"id":"9927","name":"*","chunks":[],"async":false}},"6056":{"*":{"id":"1309","name":"*","chunks":[],"async":false}},"6543":{"*":{"id":"9722","name":"*","chunks":[],"async":false}},"6813":{"*":{"id":"5877","name":"*","chunks":[],"async":false}},"7096":{"*":{"id":"1952","name":"*","chunks":[],"async":false}},"7413":{"*":{"id":"8052","name":"*","chunks":[],"async":false}},"7523":{"*":{"id":"3477","name":"*","chunks":[],"async":false}},"7768":{"*":{"id":"7663","name":"*","chunks":[],"async":false}},"8145":{"*":{"id":"8377","name":"*","chunks":[],"async":false}},"8528":{"*":{"id":"5116","name":"*","chunks":[],"async":false}},"8547":{"*":{"id":"5441","name":"*","chunks":[],"async":false}},"9135":{"*":{"id":"432","name":"*","chunks":[],"async":false}},"9239":{"*":{"id":"8132","name":"*","chunks":[],"async":false}},"9414":{"*":{"id":"8850","name":"*","chunks":[],"async":false}},"9570":{"*":{"id":"291","name":"*","chunks":[],"async":false}}},"edgeSSRModuleMapping":{},"clientModules":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/globals.css":{"id":4443,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/components/AppShell.tsx":{"id":6813,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/backtest/page.tsx":{"id":4374,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chart-analyst/page.tsx":{"id":6543,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chat/page.tsx":{"id":841,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chatbot/page.tsx":{"id":8145,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/learning/page.tsx":{"id":6056,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/methodology/page.tsx":{"id":7413,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/ipo-radar/page.tsx":{"id":9135,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/market-brain/page.tsx":{"id":2987,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page.tsx":{"id":892,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/dashboard/page.tsx":{"id":7096,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","96","static/chunks/96-ce8c57cd15d50941.js","931","static/chunks/app/page-d0db9a93fb4af9a5.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/etf-radar/page.tsx":{"id":9239,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/performance/page.tsx":{"id":8547,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/signal-lab/page.tsx":{"id":2010,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/sniper/page.tsx":{"id":7768,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/stock-radar/page.tsx":{"id":9570,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","511","static/chunks/app/stock-radar/page-6e7f483858d9a39e.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/assets/[ticker]/view.tsx":{"id":3713,"name":"*","chunks":[],"async":false}},"entryCSSFiles":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout":["static/css/02bd12e03544ea91.css"],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/page":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/stock-radar/page":[]}}
\ No newline at end of file
diff --git a/frontend/.next/server/app/themes.html b/frontend/.next/server/app/themes.html
new file mode 100644
index 0000000000000000000000000000000000000000..22b84a8a7f7bc3253da304bfc13f8d12a638be47
--- /dev/null
+++ b/frontend/.next/server/app/themes.html
@@ -0,0 +1 @@
+Blum AI Financial Intelligence Loading semantic themes
\ No newline at end of file
diff --git a/frontend/.next/server/app/themes.meta b/frontend/.next/server/app/themes.meta
new file mode 100644
index 0000000000000000000000000000000000000000..b04fe0046084515338411adb6f38a0b7c4cacccd
--- /dev/null
+++ b/frontend/.next/server/app/themes.meta
@@ -0,0 +1,5 @@
+{
+ "headers": {
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/themes/layout,_N_T_/themes/page,_N_T_/themes/"
+ }
+}
\ No newline at end of file
diff --git a/frontend/.next/server/app/themes.rsc b/frontend/.next/server/app/themes.rsc
new file mode 100644
index 0000000000000000000000000000000000000000..3fdecd48b8d5f331cfc80d3c61917080f1e6c5ea
--- /dev/null
+++ b/frontend/.next/server/app/themes.rsc
@@ -0,0 +1,8 @@
+2:I[7523,[],"ClientPageRoot"]
+3:I[892,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","433","static/chunks/433-89ff72e62f774508.js","277","static/chunks/app/themes/page-9af78316fbb208f8.js"],"default",1]
+4:I[176,[],""]
+5:I[9414,[],""]
+6:I[6813,["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"AppShell"]
+0:["wZUVLKXl_CiOxUlt_FdXC",[[["",{"children":["themes",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["themes",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","themes","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/02bd12e03544ea91.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
+7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Blum AI Financial Intelligence"}],["$","meta","3",{"name":"description","content":"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."}]]
+1:null
diff --git a/frontend/.next/server/app/themes/page.js b/frontend/.next/server/app/themes/page.js
new file mode 100644
index 0000000000000000000000000000000000000000..60bc941d15ff20b82ffba56f40716335a4f70544
--- /dev/null
+++ b/frontend/.next/server/app/themes/page.js
@@ -0,0 +1 @@
+(()=>{var e={};e.id=277,e.ids=[277],e.modules={2934:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external.js")},4580:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external.js")},5869:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},399:e=>{"use strict";e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},3972:(e,t,s)=>{"use strict";s.r(t),s.d(t,{GlobalError:()=>i.a,__next_app__:()=>u,originalPathname:()=>m,pages:()=>d,routeModule:()=>h,tree:()=>o}),s(4379),s(8777),s(311);var n=s(9296),r=s(1650),a=s(7045),i=s.n(a),l=s(8184),c={};for(let e in l)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(c[e]=()=>l[e]);s.d(t,c);let o=["",{children:["themes",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(s.bind(s,4379)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page.tsx"]}]},{}]},{layout:[()=>Promise.resolve().then(s.bind(s,8777)),"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout.tsx"],"not-found":[()=>Promise.resolve().then(s.t.bind(s,311,23)),"next/dist/client/components/not-found-error"]}],d=["/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page.tsx"],m="/themes/page",u={require:s,loadChunk:()=>Promise.resolve()},h=new n.AppPageRouteModule({definition:{kind:r.x.APP_PAGE,page:"/themes/page",pathname:"/themes",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:o}})},8483:(e,t,s)=>{Promise.resolve().then(s.bind(s,5213))},5213:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>o});var n=s(8924),r=s(3911),a=s(3789),i=s(6927),l=s(2522);let c=["AI","Rates","Geopolitics","Earnings","Energy","Crypto/Fintech","Market Structure"];function o(){let[e,t]=(0,r.useState)(null),[s,o]=(0,r.useState)(null),[m,p]=(0,r.useState)("AI infrastructure guidance"),[g,x]=(0,r.useState)([]),[v,j]=(0,r.useState)(""),[y,f]=(0,r.useState)(""),[b,N]=(0,r.useState)(""),[S,w]=(0,r.useState)(!1),[_,k]=(0,r.useState)(""),A=(0,r.useMemo)(()=>{let t=e??[];return{articleCount:t.reduce((e,t)=>e+h(t.article_count),0),averageSentiment:t.length?t.reduce((e,t)=>e+h(t.sentiment_score),0)/t.length:0}},[e]),P=async()=>{w(!0),N("");try{let e=await a.h.semanticSearch(m);x(Array.isArray(e)?e:[])}catch(e){x([]),N(e.message)}finally{w(!1)}},C=async e=>{if(e){k(e),f("");try{o(await a.h.themeDetail(e))}catch(e){o(null),f(e.message)}finally{k("")}}};return null===e?n.jsx(l.G,{label:"Loading semantic themes"}):(0,n.jsxs)(n.Fragment,{children:[n.jsx(i.ft,{eyebrow:"Themes and Narratives",title:"Market narrative intelligence.",subtitle:"Semantic clusters, rising themes, linked tickers and source evidence from public financial news.",statusItems:[{label:"Clusters",value:String(e.length),tone:e.length?"positive":"attention"},{label:"Articles",value:String(A.articleCount),tone:A.articleCount?"info":"attention"},{label:"Avg sentiment",value:A.averageSentiment.toFixed(2),tone:A.averageSentiment>=0?"positive":"negative"},{label:"Mode",value:"Evidence only"}]}),v&&(0,n.jsxs)("div",{className:"terminal-empty",style:{marginBottom:12},children:["Narratives endpoint warning: ",v,". The autonomous engine will keep rebuilding semantic clusters as evidence arrives."]}),n.jsx("section",{className:"professional-grid-3",children:c.map(t=>{let s=t.split("/")[0].toLowerCase(),r=e.find(e=>String(e.label??"").toLowerCase().includes(s));return n.jsx(i.x8,{title:t,sentiment:r?.sentiment_score,volume:r?.article_count??0,explanation:r?`Active semantic cluster: ${u(r.keywords).slice(0,4).join(", ")||"keywords pending"}.`:"Strategic narrative taxonomy monitored for future evidence."},t)})}),(0,n.jsxs)(i.Ez,{title:"Semantic Search",value:"Vector evidence",subtitle:"Search public news embeddings and narrative clusters",className:"radar-core-panel",children:[(0,n.jsxs)("div",{className:"control-row",style:{marginBottom:0},children:[n.jsx("input",{className:"input",value:m,onChange:e=>p(e.target.value),"aria-label":"Semantic search query"}),n.jsx("button",{className:"button primary",onClick:P,disabled:S||m.trim().length<3,children:S?"Searching...":"Semantic search"})]}),b&&(0,n.jsxs)("div",{className:"terminal-empty compact",style:{marginTop:10},children:["Search warning: ",b]})]}),n.jsx("section",{className:"professional-grid-3",style:{marginTop:12},children:e.slice(0,12).map((e,t)=>{let s=String(e.label??`Theme ${t+1}`);return(0,n.jsxs)("article",{className:"narrative-card theme-card",onClick:()=>C(s),children:[(0,n.jsxs)("div",{className:"narrative-card-top",children:[n.jsx("strong",{children:s}),(0,n.jsxs)("span",{className:"score-badge tone-attention",children:[n.jsx("strong",{children:h(e.article_count)}),n.jsx("em",{children:"news"})]})]}),(0,n.jsxs)("p",{children:["Keywords: ",u(e.keywords).join(", ")||"semantic cluster"]}),(0,n.jsxs)("div",{className:"narrative-card-meta",children:[(0,n.jsxs)("span",{children:["sentiment ",h(e.sentiment_score).toFixed(2)]}),n.jsx("span",{children:_===s?"loading detail":e.cluster_method??"theme aggregation"})]})]},`${s}-${t}`)})}),!e.length&&!v&&n.jsx(i.Ez,{title:"Narrative Coverage",value:"Building",className:"radar-core-panel",children:n.jsx("div",{className:"terminal-empty",children:"No semantic clusters are stored yet. The autonomous engine is hydrating news, embeddings and theme memory in the background."})}),y&&(0,n.jsxs)("div",{className:"terminal-empty",style:{marginTop:12},children:["Theme detail warning: ",y]}),s&&n.jsx(d,{detail:s}),n.jsx(i.Ez,{title:"Semantic Search Results",value:`${g.length} matches`,className:"radar-core-panel",children:(0,n.jsxs)("div",{className:"news-list",children:[0===g.length&&n.jsx("div",{className:"terminal-empty compact",children:"Search results will appear here after a query is submitted."}),g.map((e,t)=>{let s=e.article??{};return(0,n.jsxs)("a",{className:"news-item",href:s.url??"#",target:"_blank",rel:"noreferrer",children:[n.jsx("strong",{children:s.title??"Untitled evidence item"}),(0,n.jsxs)("span",{children:["Similarity ",h(e.score).toFixed(3)," | ",s.source??"unknown source"]})]},`${s.id??s.url??"result"}-${t}`)})]})})]})}function d({detail:e}){let t=u(e.source_mix),s=u(e.linked_assets),r=u(e.articles);return(0,n.jsxs)(i.Ez,{title:"Theme Detail",value:e.label??"Narrative",className:"radar-core-panel",children:[(0,n.jsxs)("div",{className:"professional-grid-4",children:[n.jsx(m,{label:"Articles",value:h(e.article_count)}),n.jsx(m,{label:"Avg Sentiment",value:h(e.average_sentiment).toFixed(2)}),n.jsx(m,{label:"Sources",value:t.length}),n.jsx(m,{label:"Assets",value:s.length})]}),(0,n.jsxs)("div",{className:"professional-grid-2",style:{marginTop:12},children:[n.jsx(i.Ez,{title:"Linked Assets",dense:!0,children:(0,n.jsxs)("div",{className:"tag-row",children:[0===s.length&&n.jsx("span",{children:"No linked tickers yet"}),s.slice(0,20).map((e,t)=>(0,n.jsxs)("span",{children:[e.ticker??"Asset"," ",e.mentions??0]},`${e.ticker??"asset"}-${t}`))]})}),n.jsx(i.Ez,{title:"Source Mix",dense:!0,children:(0,n.jsxs)("div",{className:"tag-row",children:[0===t.length&&n.jsx("span",{children:"No source concentration yet"}),t.slice(0,16).map((e,t)=>(0,n.jsxs)("span",{children:[e.source??"Source"," ",e.count??0]},`${e.source??"source"}-${t}`))]})})]}),(0,n.jsxs)("div",{className:"news-list",style:{marginTop:12},children:[0===r.length&&n.jsx("div",{className:"terminal-empty compact",children:"No articles are linked to this theme yet."}),r.slice(0,16).map((e,t)=>(0,n.jsxs)("a",{className:"news-item",href:e.url??"#",target:"_blank",rel:"noreferrer",children:[n.jsx("strong",{children:e.title??"Untitled article"}),(0,n.jsxs)("span",{children:[e.source??"unknown"," | sentiment ",h(e.sentiment?.score).toFixed(2)," | assets ",u(e.linked_assets).map(e=>e.ticker).filter(Boolean).join(" | ")||"n/a"]})]},`${e.id??e.url??"article"}-${t}`))]})]})}function m({label:e,value:t}){return n.jsx(i.i9,{label:e,value:t})}function u(e){return Array.isArray(e)?e:[]}function h(e){let t=Number(e);return Number.isFinite(t)?t:0}},2522:(e,t,s)=>{"use strict";s.d(t,{G:()=>r});var n=s(8924);function r({label:e="Loading intelligence snapshot"}){return(0,n.jsxs)("div",{className:"loading-state",children:[n.jsx("div",{}),n.jsx("span",{children:e})]})}},4379:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>n});let n=(0,s(6691).createProxy)(String.raw`/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page.tsx#default`)}};var t=require("../../webpack-runtime.js");t.C(e);var s=e=>t(t.s=e),n=t.X(0,[273,394,927],()=>s(3972));module.exports=n})();
\ No newline at end of file
diff --git a/frontend/.next/server/app/themes/page.js.nft.json b/frontend/.next/server/app/themes/page.js.nft.json
new file mode 100644
index 0000000000000000000000000000000000000000..77578a3c1517e5a73d13826b0254aea2983bdd03
--- /dev/null
+++ b/frontend/.next/server/app/themes/page.js.nft.json
@@ -0,0 +1 @@
+{"version":1,"files":["../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/package.json","../../../../node_modules/next","../../../../package.json","../../../package.json","../../chunks/273.js","../../chunks/394.js","../../chunks/927.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}
\ No newline at end of file
diff --git a/frontend/.next/server/app/themes/page_client-reference-manifest.js b/frontend/.next/server/app/themes/page_client-reference-manifest.js
new file mode 100644
index 0000000000000000000000000000000000000000..8ed5585e338c0bea965afe3d9c6e44d6bc05722a
--- /dev/null
+++ b/frontend/.next/server/app/themes/page_client-reference-manifest.js
@@ -0,0 +1 @@
+globalThis.__RSC_MANIFEST=(globalThis.__RSC_MANIFEST||{});globalThis.__RSC_MANIFEST["/themes/page"]={"moduleLoading":{"prefix":"/_next/","crossOrigin":null},"ssrModuleMapping":{"176":{"*":{"id":"6676","name":"*","chunks":[],"async":false}},"841":{"*":{"id":"9737","name":"*","chunks":[],"async":false}},"892":{"*":{"id":"5213","name":"*","chunks":[],"async":false}},"2010":{"*":{"id":"7619","name":"*","chunks":[],"async":false}},"2433":{"*":{"id":"6544","name":"*","chunks":[],"async":false}},"2651":{"*":{"id":"9645","name":"*","chunks":[],"async":false}},"2987":{"*":{"id":"1358","name":"*","chunks":[],"async":false}},"3713":{"*":{"id":"5210","name":"*","chunks":[],"async":false}},"4374":{"*":{"id":"9927","name":"*","chunks":[],"async":false}},"6056":{"*":{"id":"1309","name":"*","chunks":[],"async":false}},"6543":{"*":{"id":"9722","name":"*","chunks":[],"async":false}},"6813":{"*":{"id":"5877","name":"*","chunks":[],"async":false}},"7096":{"*":{"id":"1952","name":"*","chunks":[],"async":false}},"7413":{"*":{"id":"8052","name":"*","chunks":[],"async":false}},"7523":{"*":{"id":"3477","name":"*","chunks":[],"async":false}},"7768":{"*":{"id":"7663","name":"*","chunks":[],"async":false}},"8145":{"*":{"id":"8377","name":"*","chunks":[],"async":false}},"8528":{"*":{"id":"5116","name":"*","chunks":[],"async":false}},"8547":{"*":{"id":"5441","name":"*","chunks":[],"async":false}},"9135":{"*":{"id":"432","name":"*","chunks":[],"async":false}},"9239":{"*":{"id":"8132","name":"*","chunks":[],"async":false}},"9414":{"*":{"id":"8850","name":"*","chunks":[],"async":false}},"9570":{"*":{"id":"291","name":"*","chunks":[],"async":false}}},"edgeSSRModuleMapping":{},"clientModules":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/app-router.js":{"id":2433,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/client-page.js":{"id":7523,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/error-boundary.js":{"id":8528,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/layout-router.js":{"id":176,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/not-found-boundary.js":{"id":2651,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/esm/client/components/render-from-template-context.js":{"id":9414,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/globals.css":{"id":4443,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/components/AppShell.tsx":{"id":6813,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","185","static/chunks/app/layout-c302ea2b37a37766.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/backtest/page.tsx":{"id":4374,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chart-analyst/page.tsx":{"id":6543,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chat/page.tsx":{"id":841,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/chatbot/page.tsx":{"id":8145,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/learning/page.tsx":{"id":6056,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/methodology/page.tsx":{"id":7413,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/ipo-radar/page.tsx":{"id":9135,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/market-brain/page.tsx":{"id":2987,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page.tsx":{"id":892,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","433","static/chunks/433-89ff72e62f774508.js","277","static/chunks/app/themes/page-9af78316fbb208f8.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/dashboard/page.tsx":{"id":7096,"name":"*","chunks":["183","static/chunks/183-66f1efcf12b29a02.js","651","static/chunks/651-5689242ae9b0ffc6.js","908","static/chunks/908-fe3c8e03f00ace4e.js","96","static/chunks/96-ce8c57cd15d50941.js","931","static/chunks/app/page-d0db9a93fb4af9a5.js"],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/etf-radar/page.tsx":{"id":9239,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/performance/page.tsx":{"id":8547,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/signal-lab/page.tsx":{"id":2010,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/sniper/page.tsx":{"id":7768,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/stock-radar/page.tsx":{"id":9570,"name":"*","chunks":[],"async":false},"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/assets/[ticker]/view.tsx":{"id":3713,"name":"*","chunks":[],"async":false}},"entryCSSFiles":{"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/layout":["static/css/02bd12e03544ea91.css"],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/page":[],"/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/app/themes/page":[]}}
\ No newline at end of file
diff --git a/frontend/.next/server/chunks/273.js b/frontend/.next/server/chunks/273.js
new file mode 100644
index 0000000000000000000000000000000000000000..85df5134b036c2d47eef5cbcaa23f85527bb8b8d
--- /dev/null
+++ b/frontend/.next/server/chunks/273.js
@@ -0,0 +1,3 @@
+exports.id=273,exports.ids=[273],exports.modules={6745:(e,t,r)=>{"use strict";r.d(t,{Z:()=>u});var n=r(3911);let o=e=>e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),a=(...e)=>e.filter((e,t,r)=>!!e&&""!==e.trim()&&r.indexOf(e)===t).join(" ").trim();var i={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};let l=(0,n.forwardRef)(({color:e="currentColor",size:t=24,strokeWidth:r=2,absoluteStrokeWidth:o,className:l="",children:u,iconNode:s,...c},d)=>(0,n.createElement)("svg",{ref:d,...i,width:t,height:t,stroke:e,strokeWidth:o?24*Number(r)/Number(t):r,className:a("lucide",l),...c},[...s.map(([e,t])=>(0,n.createElement)(e,t)),...Array.isArray(u)?u:[u]])),u=(e,t)=>{let r=(0,n.forwardRef)(({className:r,...i},u)=>(0,n.createElement)(l,{ref:u,iconNode:t,className:a(`lucide-${o(e)}`,r),...i}));return r.displayName=`${e}`,r}},3041:(e,t,r)=>{"use strict";r.d(t,{Z:()=>n});let n=(0,r(6745).Z)("Activity",[["path",{d:"M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2",key:"169zse"}]])},7993:(e,t,r)=>{"use strict";r.d(t,{Z:()=>n});let n=(0,r(6745).Z)("Brain",[["path",{d:"M12 5a3 3 0 1 0-5.997.125 4 4 0 0 0-2.526 5.77 4 4 0 0 0 .556 6.588A4 4 0 1 0 12 18Z",key:"l5xja"}],["path",{d:"M12 5a3 3 0 1 1 5.997.125 4 4 0 0 1 2.526 5.77 4 4 0 0 1-.556 6.588A4 4 0 1 1 12 18Z",key:"ep3f8r"}],["path",{d:"M15 13a4.5 4.5 0 0 1-3-4 4.5 4.5 0 0 1-3 4",key:"1p4c4q"}],["path",{d:"M17.599 6.5a3 3 0 0 0 .399-1.375",key:"tmeiqw"}],["path",{d:"M6.003 5.125A3 3 0 0 0 6.401 6.5",key:"105sqy"}],["path",{d:"M3.477 10.896a4 4 0 0 1 .585-.396",key:"ql3yin"}],["path",{d:"M19.938 10.5a4 4 0 0 1 .585.396",key:"1qfode"}],["path",{d:"M6 18a4 4 0 0 1-1.967-.516",key:"2e4loj"}],["path",{d:"M19.967 17.484A4 4 0 0 1 18 18",key:"159ez6"}]])},2567:(e,t,r)=>{"use strict";r.d(t,{Z:()=>n});let n=(0,r(6745).Z)("ChartLine",[["path",{d:"M3 3v16a2 2 0 0 0 2 2h16",key:"c24i48"}],["path",{d:"m19 9-5 5-4-4-3 3",key:"2osh9i"}]])},3600:(e,t,r)=>{"use strict";r.d(t,{Z:()=>n});let n=(0,r(6745).Z)("Cpu",[["rect",{width:"16",height:"16",x:"4",y:"4",rx:"2",key:"14l7u7"}],["rect",{width:"6",height:"6",x:"9",y:"9",rx:"1",key:"5aljv4"}],["path",{d:"M15 2v2",key:"13l42r"}],["path",{d:"M15 20v2",key:"15mkzm"}],["path",{d:"M2 15h2",key:"1gxd5l"}],["path",{d:"M2 9h2",key:"1bbxkp"}],["path",{d:"M20 15h2",key:"19e6y8"}],["path",{d:"M20 9h2",key:"19tzq7"}],["path",{d:"M9 2v2",key:"165o2o"}],["path",{d:"M9 20v2",key:"i2bqo8"}]])},9534:(e,t,r)=>{"use strict";r.d(t,{Z:()=>n});let n=(0,r(6745).Z)("Crosshair",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"22",x2:"18",y1:"12",y2:"12",key:"l9bcsi"}],["line",{x1:"6",x2:"2",y1:"12",y2:"12",key:"13hhkx"}],["line",{x1:"12",x2:"12",y1:"6",y2:"2",key:"10w3f3"}],["line",{x1:"12",x2:"12",y1:"22",y2:"18",key:"15g9kq"}]])},6635:(e,t,r)=>{"use strict";r.d(t,{Z:()=>n});let n=(0,r(6745).Z)("Database",[["ellipse",{cx:"12",cy:"5",rx:"9",ry:"3",key:"msslwz"}],["path",{d:"M3 5V19A9 3 0 0 0 21 19V5",key:"1wlel7"}],["path",{d:"M3 12A9 3 0 0 0 21 12",key:"mv7ke4"}]])},9773:(e,t,r)=>{"use strict";r.d(t,{Z:()=>n});let n=(0,r(6745).Z)("Gauge",[["path",{d:"m12 14 4-4",key:"9kzdfg"}],["path",{d:"M3.34 19a10 10 0 1 1 17.32 0",key:"19p75a"}]])},3187:(e,t,r)=>{"use strict";r.d(t,{Z:()=>n});let n=(0,r(6745).Z)("MessageSquare",[["path",{d:"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z",key:"1lielz"}]])},5107:(e,t,r)=>{"use strict";r.d(t,{Z:()=>n});let n=(0,r(6745).Z)("Network",[["rect",{x:"16",y:"16",width:"6",height:"6",rx:"1",key:"4q2zg0"}],["rect",{x:"2",y:"16",width:"6",height:"6",rx:"1",key:"8cvhb9"}],["rect",{x:"9",y:"2",width:"6",height:"6",rx:"1",key:"1egb70"}],["path",{d:"M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3",key:"1jsf9p"}],["path",{d:"M12 12V8",key:"2874zd"}]])},7540:(e,t,r)=>{"use strict";r.d(t,{Z:()=>n});let n=(0,r(6745).Z)("Radar",[["path",{d:"M19.07 4.93A10 10 0 0 0 6.99 3.34",key:"z3du51"}],["path",{d:"M4 6h.01",key:"oypzma"}],["path",{d:"M2.29 9.62A10 10 0 1 0 21.31 8.35",key:"qzzz0"}],["path",{d:"M16.24 7.76A6 6 0 1 0 8.23 16.67",key:"1yjesh"}],["path",{d:"M12 18h.01",key:"mhygvu"}],["path",{d:"M17.99 11.66A6 6 0 0 1 15.77 16.67",key:"1u2y91"}],["circle",{cx:"12",cy:"12",r:"2",key:"1c9p78"}],["path",{d:"m13.41 10.59 5.66-5.66",key:"mhq4k0"}]])},470:(e,t,r)=>{"use strict";r.d(t,{Z:()=>n});let n=(0,r(6745).Z)("Search",[["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}],["path",{d:"m21 21-4.3-4.3",key:"1qie3q"}]])},5089:(e,t,r)=>{"use strict";r.d(t,{Z:()=>n});let n=(0,r(6745).Z)("ShieldAlert",[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}],["path",{d:"M12 8v4",key:"1got3b"}],["path",{d:"M12 16h.01",key:"1drbdi"}]])},6839:(e,t,r)=>{"use strict";r.d(t,{Z:()=>n});let n=(0,r(6745).Z)("Timer",[["line",{x1:"10",x2:"14",y1:"2",y2:"2",key:"14vaq8"}],["line",{x1:"12",x2:"15",y1:"14",y2:"11",key:"17fdiu"}],["circle",{cx:"12",cy:"14",r:"8",key:"1e1u0o"}]])},2828:(e,t,r)=>{"use strict";r.d(t,{default:()=>o.a});var n=r(4942),o=r.n(n)},8975:(e,t,r)=>{"use strict";var n=r(3728);r.o(n,"usePathname")&&r.d(t,{usePathname:function(){return n.usePathname}})},5801:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"addBasePath",{enumerable:!0,get:function(){return a}});let n=r(4096),o=r(1858);function a(e,t){return(0,o.normalizePathTrailingSlash)((0,n.addPathPrefix)(e,""))}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},1737:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"addLocale",{enumerable:!0,get:function(){return n}}),r(1858);let n=function(e){for(var t=arguments.length,r=Array(t>1?t-1:0),n=1;n{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"callServer",{enumerable:!0,get:function(){return o}});let n=r(6544);async function o(e,t){let r=(0,n.getServerActionDispatcher)();if(!r)throw Error("Invariant: missing action dispatcher.");return new Promise((n,o)=>{r({actionId:e,actionArgs:t,resolve:n,reject:o})})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},1077:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"AppRouterAnnouncer",{enumerable:!0,get:function(){return i}});let n=r(3911),o=r(6348),a="next-route-announcer";function i(e){let{tree:t}=e,[r,i]=(0,n.useState)(null);(0,n.useEffect)(()=>(i(function(){var e;let t=document.getElementsByName(a)[0];if(null==t?void 0:null==(e=t.shadowRoot)?void 0:e.childNodes[0])return t.shadowRoot.childNodes[0];{let e=document.createElement(a);e.style.cssText="position:absolute";let t=document.createElement("div");return t.ariaLive="assertive",t.id="__next-route-announcer__",t.role="alert",t.style.cssText="position:absolute;border:0;height:1px;margin:-1px;padding:0;width:1px;clip:rect(0 0 0 0);overflow:hidden;white-space:nowrap;word-wrap:normal",e.attachShadow({mode:"open"}).appendChild(t),document.body.appendChild(e),t}}()),()=>{let e=document.getElementsByTagName(a)[0];(null==e?void 0:e.isConnected)&&document.body.removeChild(e)}),[]);let[l,u]=(0,n.useState)(""),s=(0,n.useRef)();return(0,n.useEffect)(()=>{let e="";if(document.title)e=document.title;else{let t=document.querySelector("h1");t&&(e=t.innerText||t.textContent||"")}void 0!==s.current&&s.current!==e&&u(e),s.current=e},[t]),r?(0,o.createPortal)(l,r):null}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},4768:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{ACTION:function(){return n},FLIGHT_PARAMETERS:function(){return u},NEXT_DID_POSTPONE_HEADER:function(){return c},NEXT_ROUTER_PREFETCH_HEADER:function(){return a},NEXT_ROUTER_STATE_TREE:function(){return o},NEXT_RSC_UNION_QUERY:function(){return s},NEXT_URL:function(){return i},RSC_CONTENT_TYPE_HEADER:function(){return l},RSC_HEADER:function(){return r}});let r="RSC",n="Next-Action",o="Next-Router-State-Tree",a="Next-Router-Prefetch",i="Next-Url",l="text/x-component",u=[[r],[o],[a]],s="_rsc",c="x-nextjs-postponed";("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},6544:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{createEmptyCacheNode:function(){return N},default:function(){return I},getServerActionDispatcher:function(){return O},urlToUrlWithoutFlightMarker:function(){return x}});let n=r(5453),o=r(8924),a=n._(r(3911)),i=r(6115),l=r(5343),u=r(7027),s=r(3090),c=r(6743),d=r(5116),f=r(786),p=r(9647),h=r(5801),g=r(1077),_=r(1455),y=r(5873),v=r(8128),b=r(4768),m=r(8183),R=r(9628),P=r(3537),S=null,E=null;function O(){return E}let T={};function x(e){let t=new URL(e,location.origin);if(t.searchParams.delete(b.NEXT_RSC_UNION_QUERY),t.pathname.endsWith(".txt")){let{pathname:e}=t,r=e.endsWith("/index.txt")?10:4;t.pathname=e.slice(0,-r)}return t}function j(e){return e.origin!==window.location.origin}function M(e){let{appRouterState:t,sync:r}=e;return(0,a.useInsertionEffect)(()=>{let{tree:e,pushRef:n,canonicalUrl:o}=t,a={...n.preserveCustomHistoryState?window.history.state:{},__NA:!0,__PRIVATE_NEXTJS_INTERNALS_TREE:e};n.pendingPush&&(0,u.createHrefFromUrl)(new URL(window.location.href))!==o?(n.pendingPush=!1,window.history.pushState(a,"",o)):window.history.replaceState(a,"",o),r(t)},[t,r]),null}function N(){return{lazyData:null,rsc:null,prefetchRsc:null,head:null,prefetchHead:null,parallelRoutes:new Map,lazyDataResolved:!1,loading:null}}function A(e){null==e&&(e={});let t=window.history.state,r=null==t?void 0:t.__NA;r&&(e.__NA=r);let n=null==t?void 0:t.__PRIVATE_NEXTJS_INTERNALS_TREE;return n&&(e.__PRIVATE_NEXTJS_INTERNALS_TREE=n),e}function C(e){let{headCacheNode:t}=e,r=null!==t?t.head:null,n=null!==t?t.prefetchHead:null,o=null!==n?n:r;return(0,a.useDeferredValue)(r,o)}function w(e){let t,{buildId:r,initialHead:n,initialTree:u,urlParts:d,initialSeedData:b,couldBeIntercepted:O,assetPrefix:x,missingSlots:N}=e,w=(0,a.useMemo)(()=>(0,f.createInitialRouterState)({buildId:r,initialSeedData:b,urlParts:d,initialTree:u,initialParallelRoutes:S,location:null,initialHead:n,couldBeIntercepted:O}),[r,b,d,u,n,O]),[I,D,L]=(0,c.useReducerWithReduxDevtools)(w);(0,a.useEffect)(()=>{S=null},[]);let{canonicalUrl:U}=(0,c.useUnwrapState)(I),{searchParams:k,pathname:F}=(0,a.useMemo)(()=>{let e=new URL(U,"http://n");return{searchParams:e.searchParams,pathname:(0,R.hasBasePath)(e.pathname)?(0,m.removeBasePath)(e.pathname):e.pathname}},[U]),H=(0,a.useCallback)(e=>{let{previousTree:t,serverResponse:r}=e;(0,a.startTransition)(()=>{D({type:l.ACTION_SERVER_PATCH,previousTree:t,serverResponse:r})})},[D]),G=(0,a.useCallback)((e,t,r)=>{let n=new URL((0,h.addBasePath)(e),location.href);return D({type:l.ACTION_NAVIGATE,url:n,isExternalUrl:j(n),locationSearch:location.search,shouldScroll:null==r||r,navigateType:t})},[D]);E=(0,a.useCallback)(e=>{(0,a.startTransition)(()=>{D({...e,type:l.ACTION_SERVER_ACTION})})},[D]);let B=(0,a.useMemo)(()=>({back:()=>window.history.back(),forward:()=>window.history.forward(),prefetch:(e,t)=>{let r;if(!(0,p.isBot)(window.navigator.userAgent)){try{r=new URL((0,h.addBasePath)(e),window.location.href)}catch(t){throw Error("Cannot prefetch '"+e+"' because it cannot be converted to a URL.")}j(r)||(0,a.startTransition)(()=>{var e;D({type:l.ACTION_PREFETCH,url:r,kind:null!=(e=null==t?void 0:t.kind)?e:l.PrefetchKind.FULL})})}},replace:(e,t)=>{void 0===t&&(t={}),(0,a.startTransition)(()=>{var r;G(e,"replace",null==(r=t.scroll)||r)})},push:(e,t)=>{void 0===t&&(t={}),(0,a.startTransition)(()=>{var r;G(e,"push",null==(r=t.scroll)||r)})},refresh:()=>{(0,a.startTransition)(()=>{D({type:l.ACTION_REFRESH,origin:window.location.origin})})},fastRefresh:()=>{throw Error("fastRefresh can only be used in development mode. Please use refresh instead.")}}),[D,G]);(0,a.useEffect)(()=>{window.next&&(window.next.router=B)},[B]),(0,a.useEffect)(()=>{function e(e){var t;e.persisted&&(null==(t=window.history.state)?void 0:t.__PRIVATE_NEXTJS_INTERNALS_TREE)&&(T.pendingMpaPath=void 0,D({type:l.ACTION_RESTORE,url:new URL(window.location.href),tree:window.history.state.__PRIVATE_NEXTJS_INTERNALS_TREE}))}return window.addEventListener("pageshow",e),()=>{window.removeEventListener("pageshow",e)}},[D]);let{pushRef:V}=(0,c.useUnwrapState)(I);if(V.mpaNavigation){if(T.pendingMpaPath!==U){let e=window.location;V.pendingPush?e.assign(U):e.replace(U),T.pendingMpaPath=U}(0,a.use)(v.unresolvedThenable)}(0,a.useEffect)(()=>{let e=window.history.pushState.bind(window.history),t=window.history.replaceState.bind(window.history),r=e=>{var t;let r=window.location.href,n=null==(t=window.history.state)?void 0:t.__PRIVATE_NEXTJS_INTERNALS_TREE;(0,a.startTransition)(()=>{D({type:l.ACTION_RESTORE,url:new URL(null!=e?e:r,r),tree:n})})};window.history.pushState=function(t,n,o){return(null==t?void 0:t.__NA)||(null==t?void 0:t._N)||(t=A(t),o&&r(o)),e(t,n,o)},window.history.replaceState=function(e,n,o){return(null==e?void 0:e.__NA)||(null==e?void 0:e._N)||(e=A(e),o&&r(o)),t(e,n,o)};let n=e=>{let{state:t}=e;if(t){if(!t.__NA){window.location.reload();return}(0,a.startTransition)(()=>{D({type:l.ACTION_RESTORE,url:new URL(window.location.href),tree:t.__PRIVATE_NEXTJS_INTERNALS_TREE})})}};return window.addEventListener("popstate",n),()=>{window.history.pushState=e,window.history.replaceState=t,window.removeEventListener("popstate",n)}},[D]);let{cache:X,tree:$,nextUrl:W,focusAndScrollRef:z}=(0,c.useUnwrapState)(I),K=(0,a.useMemo)(()=>(0,y.findHeadInCache)(X,$[1]),[X,$]),Y=(0,a.useMemo)(()=>(function e(t,r){for(let n of(void 0===r&&(r={}),Object.values(t[1]))){let t=n[0],o=Array.isArray(t),a=o?t[1]:t;!a||a.startsWith(P.PAGE_SEGMENT_KEY)||(o&&("c"===t[2]||"oc"===t[2])?r[t[0]]=t[1].split("/"):o&&(r[t[0]]=t[1]),r=e(n,r))}return r})($),[$]);if(null!==K){let[e,r]=K;t=(0,o.jsx)(C,{headCacheNode:e},r)}else t=null;let q=(0,o.jsxs)(_.RedirectBoundary,{children:[t,X.rsc,(0,o.jsx)(g.AppRouterAnnouncer,{tree:$})]});return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(M,{appRouterState:(0,c.useUnwrapState)(I),sync:L}),(0,o.jsx)(s.PathParamsContext.Provider,{value:Y,children:(0,o.jsx)(s.PathnameContext.Provider,{value:F,children:(0,o.jsx)(s.SearchParamsContext.Provider,{value:k,children:(0,o.jsx)(i.GlobalLayoutRouterContext.Provider,{value:{buildId:r,changeByServerResponse:H,tree:$,focusAndScrollRef:z,nextUrl:W},children:(0,o.jsx)(i.AppRouterContext.Provider,{value:B,children:(0,o.jsx)(i.LayoutRouterContext.Provider,{value:{childNodes:X.parallelRoutes,tree:$,url:U,loading:X.loading},children:q})})})})})})]})}function I(e){let{globalErrorComponent:t,...r}=e;return(0,o.jsx)(d.ErrorBoundary,{errorComponent:t,children:(0,o.jsx)(w,{...r})})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},1721:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"bailoutToClientRendering",{enumerable:!0,get:function(){return a}});let n=r(6483),o=r(5869);function a(e){let t=o.staticGenerationAsyncStorage.getStore();if((null==t||!t.forceStatic)&&(null==t?void 0:t.isStaticGeneration))throw new n.BailoutToCSRError(e)}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},3477:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"ClientPageRoot",{enumerable:!0,get:function(){return a}});let n=r(8924),o=r(7248);function a(e){let{Component:t,props:r}=e;return r.searchParams=(0,o.createDynamicallyTrackedSearchParams)(r.searchParams||{}),(0,n.jsx)(t,{...r})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},5116:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{ErrorBoundary:function(){return h},ErrorBoundaryHandler:function(){return d},GlobalError:function(){return f},default:function(){return p}});let n=r(1607),o=r(8924),a=n._(r(3911)),i=r(3728),l=r(1643),u=r(5869),s={error:{fontFamily:'system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"',height:"100vh",textAlign:"center",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},text:{fontSize:"14px",fontWeight:400,lineHeight:"28px",margin:"0 8px"}};function c(e){let{error:t}=e,r=u.staticGenerationAsyncStorage.getStore();if((null==r?void 0:r.isRevalidate)||(null==r?void 0:r.isStaticGeneration))throw console.error(t),t;return null}class d extends a.default.Component{static getDerivedStateFromError(e){if((0,l.isNextRouterError)(e))throw e;return{error:e}}static getDerivedStateFromProps(e,t){return e.pathname!==t.previousPathname&&t.error?{error:null,previousPathname:e.pathname}:{error:t.error,previousPathname:e.pathname}}render(){return this.state.error?(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(c,{error:this.state.error}),this.props.errorStyles,this.props.errorScripts,(0,o.jsx)(this.props.errorComponent,{error:this.state.error,reset:this.reset})]}):this.props.children}constructor(e){super(e),this.reset=()=>{this.setState({error:null})},this.state={error:null,previousPathname:this.props.pathname}}}function f(e){let{error:t}=e,r=null==t?void 0:t.digest;return(0,o.jsxs)("html",{id:"__next_error__",children:[(0,o.jsx)("head",{}),(0,o.jsxs)("body",{children:[(0,o.jsx)(c,{error:t}),(0,o.jsx)("div",{style:s.error,children:(0,o.jsxs)("div",{children:[(0,o.jsx)("h2",{style:s.text,children:"Application error: a "+(r?"server":"client")+"-side exception has occurred (see the "+(r?"server logs":"browser console")+" for more information)."}),r?(0,o.jsx)("p",{style:s.text,children:"Digest: "+r}):null]})})]})]})}let p=f;function h(e){let{errorComponent:t,errorStyles:r,errorScripts:n,children:a}=e,l=(0,i.usePathname)();return t?(0,o.jsx)(d,{pathname:l,errorComponent:t,errorStyles:r,errorScripts:n,children:a}):(0,o.jsx)(o.Fragment,{children:a})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},5667:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{DynamicServerError:function(){return n},isDynamicServerError:function(){return o}});let r="DYNAMIC_SERVER_USAGE";class n extends Error{constructor(e){super("Dynamic server usage: "+e),this.description=e,this.digest=r}}function o(e){return"object"==typeof e&&null!==e&&"digest"in e&&"string"==typeof e.digest&&e.digest===r}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},1643:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"isNextRouterError",{enumerable:!0,get:function(){return a}});let n=r(3872),o=r(1901);function a(e){return e&&e.digest&&((0,o.isRedirectError)(e)||(0,n.isNotFoundError)(e))}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},6676:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return S}}),r(1607);let n=r(5453),o=r(8924),a=n._(r(3911));r(6348);let i=r(6115),l=r(5437),u=r(8128),s=r(5116),c=r(5057),d=r(7546),f=r(1455),p=r(9645),h=r(8821),g=r(5929),_=r(9041),y=["bottom","height","left","right","top","width","x","y"];function v(e,t){let r=e.getBoundingClientRect();return r.top>=0&&r.top<=t}class b extends a.default.Component{componentDidMount(){this.handlePotentialScroll()}componentDidUpdate(){this.props.focusAndScrollRef.apply&&this.handlePotentialScroll()}render(){return this.props.children}constructor(...e){super(...e),this.handlePotentialScroll=()=>{let{focusAndScrollRef:e,segmentPath:t}=this.props;if(e.apply){if(0!==e.segmentPaths.length&&!e.segmentPaths.some(e=>t.every((t,r)=>(0,c.matchSegment)(t,e[r]))))return;let r=null,n=e.hashFragment;if(n&&(r=function(e){var t;return"top"===e?document.body:null!=(t=document.getElementById(e))?t:document.getElementsByName(e)[0]}(n)),!r&&(r=null),!(r instanceof Element))return;for(;!(r instanceof HTMLElement)||function(e){if(["sticky","fixed"].includes(getComputedStyle(e).position))return!0;let t=e.getBoundingClientRect();return y.every(e=>0===t[e])}(r);){if(null===r.nextElementSibling)return;r=r.nextElementSibling}e.apply=!1,e.hashFragment=null,e.segmentPaths=[],(0,d.handleSmoothScroll)(()=>{if(n){r.scrollIntoView();return}let e=document.documentElement,t=e.clientHeight;!v(r,t)&&(e.scrollTop=0,v(r,t)||r.scrollIntoView())},{dontForceLayout:!0,onlyHashChange:e.onlyHashChange}),e.onlyHashChange=!1,r.focus()}}}}function m(e){let{segmentPath:t,children:r}=e,n=(0,a.useContext)(i.GlobalLayoutRouterContext);if(!n)throw Error("invariant global layout router not mounted");return(0,o.jsx)(b,{segmentPath:t,focusAndScrollRef:n.focusAndScrollRef,children:r})}function R(e){let{parallelRouterKey:t,url:r,childNodes:n,segmentPath:s,tree:d,cacheKey:f}=e,p=(0,a.useContext)(i.GlobalLayoutRouterContext);if(!p)throw Error("invariant global layout router not mounted");let{buildId:h,changeByServerResponse:g,tree:y}=p,v=n.get(f);if(void 0===v){let e={lazyData:null,rsc:null,prefetchRsc:null,head:null,prefetchHead:null,parallelRoutes:new Map,lazyDataResolved:!1,loading:null};v=e,n.set(f,e)}let b=null!==v.prefetchRsc?v.prefetchRsc:v.rsc,m=(0,a.useDeferredValue)(v.rsc,b),R="object"==typeof m&&null!==m&&"function"==typeof m.then?(0,a.use)(m):m;if(!R){let e=v.lazyData;if(null===e){let t=function e(t,r){if(t){let[n,o]=t,a=2===t.length;if((0,c.matchSegment)(r[0],n)&&r[1].hasOwnProperty(o)){if(a){let t=e(void 0,r[1][o]);return[r[0],{...r[1],[o]:[t[0],t[1],t[2],"refetch"]}]}return[r[0],{...r[1],[o]:e(t.slice(2),r[1][o])}]}}return r}(["",...s],y),n=(0,_.hasInterceptionRouteInCurrentTree)(y);v.lazyData=e=(0,l.fetchServerResponse)(new URL(r,location.origin),t,n?p.nextUrl:null,h),v.lazyDataResolved=!1}let t=(0,a.use)(e);v.lazyDataResolved||(setTimeout(()=>{(0,a.startTransition)(()=>{g({previousTree:y,serverResponse:t})})}),v.lazyDataResolved=!0),(0,a.use)(u.unresolvedThenable)}return(0,o.jsx)(i.LayoutRouterContext.Provider,{value:{tree:d[1][t],childNodes:v.parallelRoutes,url:r,loading:v.loading},children:R})}function P(e){let{children:t,hasLoading:r,loading:n,loadingStyles:i,loadingScripts:l}=e;return r?(0,o.jsx)(a.Suspense,{fallback:(0,o.jsxs)(o.Fragment,{children:[i,l,n]}),children:t}):(0,o.jsx)(o.Fragment,{children:t})}function S(e){let{parallelRouterKey:t,segmentPath:r,error:n,errorStyles:l,errorScripts:u,templateStyles:c,templateScripts:d,template:_,notFound:y,notFoundStyles:v}=e,b=(0,a.useContext)(i.LayoutRouterContext);if(!b)throw Error("invariant expected layout router to be mounted");let{childNodes:S,tree:E,url:O,loading:T}=b,x=S.get(t);x||(x=new Map,S.set(t,x));let j=E[1][t][0],M=(0,h.getSegmentValue)(j),N=[j];return(0,o.jsx)(o.Fragment,{children:N.map(e=>{let a=(0,h.getSegmentValue)(e),b=(0,g.createRouterCacheKey)(e);return(0,o.jsxs)(i.TemplateContext.Provider,{value:(0,o.jsx)(m,{segmentPath:r,children:(0,o.jsx)(s.ErrorBoundary,{errorComponent:n,errorStyles:l,errorScripts:u,children:(0,o.jsx)(P,{hasLoading:!!T,loading:null==T?void 0:T[0],loadingStyles:null==T?void 0:T[1],loadingScripts:null==T?void 0:T[2],children:(0,o.jsx)(p.NotFoundBoundary,{notFound:y,notFoundStyles:v,children:(0,o.jsx)(f.RedirectBoundary,{children:(0,o.jsx)(R,{parallelRouterKey:t,url:O,tree:E,childNodes:x,segmentPath:r,cacheKey:b,isActive:M===a})})})})})}),children:[c,d,_]},(0,g.createRouterCacheKey)(e,!0))})})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},5057:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{canSegmentBeOverridden:function(){return a},matchSegment:function(){return o}});let n=r(2414),o=(e,t)=>"string"==typeof e?"string"==typeof t&&e===t:"string"!=typeof t&&e[0]===t[0]&&e[1]===t[1],a=(e,t)=>{var r;return!Array.isArray(e)&&!!Array.isArray(t)&&(null==(r=(0,n.getSegmentParam)(e))?void 0:r.param)===t[0]};("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},3728:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{ReadonlyURLSearchParams:function(){return u.ReadonlyURLSearchParams},RedirectType:function(){return u.RedirectType},ServerInsertedHTMLContext:function(){return s.ServerInsertedHTMLContext},notFound:function(){return u.notFound},permanentRedirect:function(){return u.permanentRedirect},redirect:function(){return u.redirect},useParams:function(){return p},usePathname:function(){return d},useRouter:function(){return f},useSearchParams:function(){return c},useSelectedLayoutSegment:function(){return g},useSelectedLayoutSegments:function(){return h},useServerInsertedHTML:function(){return s.useServerInsertedHTML}});let n=r(3911),o=r(6115),a=r(3090),i=r(8821),l=r(3537),u=r(7495),s=r(8376);function c(){let e=(0,n.useContext)(a.SearchParamsContext),t=(0,n.useMemo)(()=>e?new u.ReadonlyURLSearchParams(e):null,[e]);{let{bailoutToClientRendering:e}=r(1721);e("useSearchParams()")}return t}function d(){return(0,n.useContext)(a.PathnameContext)}function f(){let e=(0,n.useContext)(o.AppRouterContext);if(null===e)throw Error("invariant expected app router to be mounted");return e}function p(){return(0,n.useContext)(a.PathParamsContext)}function h(e){void 0===e&&(e="children");let t=(0,n.useContext)(o.LayoutRouterContext);return t?function e(t,r,n,o){let a;if(void 0===n&&(n=!0),void 0===o&&(o=[]),n)a=t[1][r];else{var u;let e=t[1];a=null!=(u=e.children)?u:Object.values(e)[0]}if(!a)return o;let s=a[0],c=(0,i.getSegmentValue)(s);return!c||c.startsWith(l.PAGE_SEGMENT_KEY)?o:(o.push(c),e(a,r,!1,o))}(t.tree,e):null}function g(e){void 0===e&&(e="children");let t=h(e);if(!t||0===t.length)return null;let r="children"===e?t[0]:t[t.length-1];return r===l.DEFAULT_SEGMENT_KEY?null:r}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},7495:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{ReadonlyURLSearchParams:function(){return i},RedirectType:function(){return n.RedirectType},notFound:function(){return o.notFound},permanentRedirect:function(){return n.permanentRedirect},redirect:function(){return n.redirect}});let n=r(1901),o=r(3872);class a extends Error{constructor(){super("Method unavailable on `ReadonlyURLSearchParams`. Read more: https://nextjs.org/docs/app/api-reference/functions/use-search-params#updating-searchparams")}}class i extends URLSearchParams{append(){throw new a}delete(){throw new a}set(){throw new a}sort(){throw new a}}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},9645:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"NotFoundBoundary",{enumerable:!0,get:function(){return c}});let n=r(5453),o=r(8924),a=n._(r(3911)),i=r(3728),l=r(3872);r(7500);let u=r(6115);class s extends a.default.Component{componentDidCatch(){}static getDerivedStateFromError(e){if((0,l.isNotFoundError)(e))return{notFoundTriggered:!0};throw e}static getDerivedStateFromProps(e,t){return e.pathname!==t.previousPathname&&t.notFoundTriggered?{notFoundTriggered:!1,previousPathname:e.pathname}:{notFoundTriggered:t.notFoundTriggered,previousPathname:e.pathname}}render(){return this.state.notFoundTriggered?(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)("meta",{name:"robots",content:"noindex"}),!1,this.props.notFoundStyles,this.props.notFound]}):this.props.children}constructor(e){super(e),this.state={notFoundTriggered:!!e.asNotFound,previousPathname:e.pathname}}}function c(e){let{notFound:t,notFoundStyles:r,asNotFound:n,children:l}=e,c=(0,i.usePathname)(),d=(0,a.useContext)(u.MissingSlotContext);return t?(0,o.jsx)(s,{pathname:c,notFound:t,notFoundStyles:r,asNotFound:n,missingSlots:d,children:l}):(0,o.jsx)(o.Fragment,{children:l})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},3872:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{isNotFoundError:function(){return o},notFound:function(){return n}});let r="NEXT_NOT_FOUND";function n(){let e=Error(r);throw e.digest=r,e}function o(e){return"object"==typeof e&&null!==e&&"digest"in e&&e.digest===r}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},163:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"PromiseQueue",{enumerable:!0,get:function(){return s}});let n=r(7919),o=r(2278);var a=o._("_maxConcurrency"),i=o._("_runningCount"),l=o._("_queue"),u=o._("_processNext");class s{enqueue(e){let t,r;let o=new Promise((e,n)=>{t=e,r=n}),a=async()=>{try{n._(this,i)[i]++;let r=await e();t(r)}catch(e){r(e)}finally{n._(this,i)[i]--,n._(this,u)[u]()}};return n._(this,l)[l].push({promiseFn:o,task:a}),n._(this,u)[u](),o}bump(e){let t=n._(this,l)[l].findIndex(t=>t.promiseFn===e);if(t>-1){let e=n._(this,l)[l].splice(t,1)[0];n._(this,l)[l].unshift(e),n._(this,u)[u](!0)}}constructor(e=5){Object.defineProperty(this,u,{value:c}),Object.defineProperty(this,a,{writable:!0,value:void 0}),Object.defineProperty(this,i,{writable:!0,value:void 0}),Object.defineProperty(this,l,{writable:!0,value:void 0}),n._(this,a)[a]=e,n._(this,i)[i]=0,n._(this,l)[l]=[]}}function c(e){if(void 0===e&&(e=!1),(n._(this,i)[i]0){var t;null==(t=n._(this,l)[l].shift())||t.task()}}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},1455:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{RedirectBoundary:function(){return c},RedirectErrorBoundary:function(){return s}});let n=r(5453),o=r(8924),a=n._(r(3911)),i=r(3728),l=r(1901);function u(e){let{redirect:t,reset:r,redirectType:n}=e,o=(0,i.useRouter)();return(0,a.useEffect)(()=>{a.default.startTransition(()=>{n===l.RedirectType.push?o.push(t,{}):o.replace(t,{}),r()})},[t,n,r,o]),null}class s extends a.default.Component{static getDerivedStateFromError(e){if((0,l.isRedirectError)(e))return{redirect:(0,l.getURLFromRedirectError)(e),redirectType:(0,l.getRedirectTypeFromError)(e)};throw e}render(){let{redirect:e,redirectType:t}=this.state;return null!==e&&null!==t?(0,o.jsx)(u,{redirect:e,redirectType:t,reset:()=>this.setState({redirect:null})}):this.props.children}constructor(e){super(e),this.state={redirect:null,redirectType:null}}}function c(e){let{children:t}=e,r=(0,i.useRouter)();return(0,o.jsx)(s,{router:r,children:t})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},5360:(e,t)=>{"use strict";var r;Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"RedirectStatusCode",{enumerable:!0,get:function(){return r}}),function(e){e[e.SeeOther=303]="SeeOther",e[e.TemporaryRedirect=307]="TemporaryRedirect",e[e.PermanentRedirect=308]="PermanentRedirect"}(r||(r={})),("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},1901:(e,t,r)=>{"use strict";var n;Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{RedirectType:function(){return n},getRedirectError:function(){return u},getRedirectStatusCodeFromError:function(){return h},getRedirectTypeFromError:function(){return p},getURLFromRedirectError:function(){return f},isRedirectError:function(){return d},permanentRedirect:function(){return c},redirect:function(){return s}});let o=r(4580),a=r(2934),i=r(5360),l="NEXT_REDIRECT";function u(e,t,r){void 0===r&&(r=i.RedirectStatusCode.TemporaryRedirect);let n=Error(l);n.digest=l+";"+t+";"+e+";"+r+";";let a=o.requestAsyncStorage.getStore();return a&&(n.mutableCookies=a.mutableCookies),n}function s(e,t){void 0===t&&(t="replace");let r=a.actionAsyncStorage.getStore();throw u(e,t,(null==r?void 0:r.isAction)?i.RedirectStatusCode.SeeOther:i.RedirectStatusCode.TemporaryRedirect)}function c(e,t){void 0===t&&(t="replace");let r=a.actionAsyncStorage.getStore();throw u(e,t,(null==r?void 0:r.isAction)?i.RedirectStatusCode.SeeOther:i.RedirectStatusCode.PermanentRedirect)}function d(e){if("object"!=typeof e||null===e||!("digest"in e)||"string"!=typeof e.digest)return!1;let[t,r,n,o]=e.digest.split(";",4),a=Number(o);return t===l&&("replace"===r||"push"===r)&&"string"==typeof n&&!isNaN(a)&&a in i.RedirectStatusCode}function f(e){return d(e)?e.digest.split(";",3)[2]:null}function p(e){if(!d(e))throw Error("Not a redirect error");return e.digest.split(";",2)[1]}function h(e){if(!d(e))throw Error("Not a redirect error");return Number(e.digest.split(";",4)[3])}(function(e){e.push="push",e.replace="replace"})(n||(n={})),("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},8850:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return l}});let n=r(5453),o=r(8924),a=n._(r(3911)),i=r(6115);function l(){let e=(0,a.useContext)(i.TemplateContext);return(0,o.jsx)(o.Fragment,{children:e})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},8517:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"applyFlightData",{enumerable:!0,get:function(){return a}});let n=r(1742),o=r(503);function a(e,t,r,a){let[i,l,u]=r.slice(-3);if(null===l)return!1;if(3===r.length){let r=l[2],o=l[3];t.loading=o,t.rsc=r,t.prefetchRsc=null,(0,n.fillLazyItemsTillLeafWithHead)(t,e,i,l,u,a)}else t.rsc=e.rsc,t.prefetchRsc=e.prefetchRsc,t.parallelRoutes=new Map(e.parallelRoutes),t.loading=e.loading,(0,o.fillCacheWithNewSubTreeData)(t,e,r,a);return!0}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},7542:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"applyRouterStatePatchToTree",{enumerable:!0,get:function(){return function e(t,r,n,l){let u;let[s,c,d,f,p]=r;if(1===t.length){let e=i(r,n,t);return(0,a.addRefreshMarkerToActiveParallelSegments)(e,l),e}let[h,g]=t;if(!(0,o.matchSegment)(h,s))return null;if(2===t.length)u=i(c[g],n,t);else if(null===(u=e(t.slice(2),c[g],n,l)))return null;let _=[t[0],{...c,[g]:u},d,f];return p&&(_[4]=!0),(0,a.addRefreshMarkerToActiveParallelSegments)(_,l),_}}});let n=r(3537),o=r(5057),a=r(8156);function i(e,t,r){let[a,l]=e,[u,s]=t;if(u===n.DEFAULT_SEGMENT_KEY&&a!==n.DEFAULT_SEGMENT_KEY)return e;if((0,o.matchSegment)(a,u)){let t={};for(let e in l)void 0!==s[e]?t[e]=i(l[e],s[e],r):t[e]=l[e];for(let e in s)t[e]||(t[e]=s[e]);let n=[a,t];return e[2]&&(n[2]=e[2]),e[3]&&(n[3]=e[3]),e[4]&&(n[4]=e[4]),n}return t}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},724:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"clearCacheNodeDataForSegmentPath",{enumerable:!0,get:function(){return function e(t,r,o){let a=o.length<=2,[i,l]=o,u=(0,n.createRouterCacheKey)(l),s=r.parallelRoutes.get(i),c=t.parallelRoutes.get(i);c&&c!==s||(c=new Map(s),t.parallelRoutes.set(i,c));let d=null==s?void 0:s.get(u),f=c.get(u);if(a){f&&f.lazyData&&f!==d||c.set(u,{lazyData:null,rsc:null,prefetchRsc:null,head:null,prefetchHead:null,parallelRoutes:new Map,lazyDataResolved:!1,loading:null});return}if(!f||!d){f||c.set(u,{lazyData:null,rsc:null,prefetchRsc:null,head:null,prefetchHead:null,parallelRoutes:new Map,lazyDataResolved:!1,loading:null});return}return f===d&&(f={lazyData:f.lazyData,rsc:f.rsc,prefetchRsc:f.prefetchRsc,head:f.head,prefetchHead:f.prefetchHead,parallelRoutes:new Map(f.parallelRoutes),lazyDataResolved:f.lazyDataResolved,loading:f.loading},c.set(u,f)),e(f,d,o.slice(2))}}});let n=r(5929);("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},1670:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{computeChangedPath:function(){return c},extractPathFromFlightRouterState:function(){return s}});let n=r(8561),o=r(3537),a=r(5057),i=e=>"/"===e[0]?e.slice(1):e,l=e=>"string"==typeof e?"children"===e?"":e:e[1];function u(e){return e.reduce((e,t)=>""===(t=i(t))||(0,o.isGroupSegment)(t)?e:e+"/"+t,"")||"/"}function s(e){var t;let r=Array.isArray(e[0])?e[0][1]:e[0];if(r===o.DEFAULT_SEGMENT_KEY||n.INTERCEPTION_ROUTE_MARKERS.some(e=>r.startsWith(e)))return;if(r.startsWith(o.PAGE_SEGMENT_KEY))return"";let a=[l(r)],i=null!=(t=e[1])?t:{},c=i.children?s(i.children):void 0;if(void 0!==c)a.push(c);else for(let[e,t]of Object.entries(i)){if("children"===e)continue;let r=s(t);void 0!==r&&a.push(r)}return u(a)}function c(e,t){let r=function e(t,r){let[o,i]=t,[u,c]=r,d=l(o),f=l(u);if(n.INTERCEPTION_ROUTE_MARKERS.some(e=>d.startsWith(e)||f.startsWith(e)))return"";if(!(0,a.matchSegment)(o,u)){var p;return null!=(p=s(r))?p:""}for(let t in i)if(c[t]){let r=e(i[t],c[t]);if(null!==r)return l(u)+"/"+r}return null}(e,t);return null==r||"/"===r?r:u(r.split("/"))}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},7027:(e,t)=>{"use strict";function r(e,t){return void 0===t&&(t=!0),e.pathname+e.search+(t?e.hash:"")}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"createHrefFromUrl",{enumerable:!0,get:function(){return r}}),("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},786:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"createInitialRouterState",{enumerable:!0,get:function(){return s}});let n=r(7027),o=r(1742),a=r(1670),i=r(5296),l=r(5343),u=r(8156);function s(e){var t;let{buildId:r,initialTree:s,initialSeedData:c,urlParts:d,initialParallelRoutes:f,location:p,initialHead:h,couldBeIntercepted:g}=e,_=d.join("/"),y=!p,v={lazyData:null,rsc:c[2],prefetchRsc:null,head:null,prefetchHead:null,parallelRoutes:y?new Map:f,lazyDataResolved:!1,loading:c[3]},b=p?(0,n.createHrefFromUrl)(p):_;(0,u.addRefreshMarkerToActiveParallelSegments)(s,b);let m=new Map;(null===f||0===f.size)&&(0,o.fillLazyItemsTillLeafWithHead)(v,void 0,s,c,h);let R={buildId:r,tree:s,cache:v,prefetchCache:m,pushRef:{pendingPush:!1,mpaNavigation:!1,preserveCustomHistoryState:!0},focusAndScrollRef:{apply:!1,onlyHashChange:!1,hashFragment:null,segmentPaths:[]},canonicalUrl:b,nextUrl:null!=(t=(0,a.extractPathFromFlightRouterState)(s)||(null==p?void 0:p.pathname))?t:null};if(p){let e=new URL(""+p.pathname+p.search,p.origin),t=[["",s,null,null]];(0,i.createPrefetchCacheEntryForInitialLoad)({url:e,kind:l.PrefetchKind.AUTO,data:[t,void 0,!1,g],tree:R.tree,prefetchCache:R.prefetchCache,nextUrl:R.nextUrl})}return R}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},5929:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"createRouterCacheKey",{enumerable:!0,get:function(){return o}});let n=r(3537);function o(e,t){return(void 0===t&&(t=!1),Array.isArray(e))?e[0]+"|"+e[1]+"|"+e[2]:t&&e.startsWith(n.PAGE_SEGMENT_KEY)?n.PAGE_SEGMENT_KEY:e}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},5437:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"fetchServerResponse",{enumerable:!0,get:function(){return d}});let n=r(4768),o=r(6544),a=r(8038),i=r(5343),l=r(5860),u=r(7544),{createFromFetch:s}=r(7447);function c(e){return[(0,o.urlToUrlWithoutFlightMarker)(e).toString(),void 0,!1,!1]}async function d(e,t,r,d,f){let p={[n.RSC_HEADER]:"1",[n.NEXT_ROUTER_STATE_TREE]:(0,u.prepareFlightRouterStateForRequest)(t)};f===i.PrefetchKind.AUTO&&(p[n.NEXT_ROUTER_PREFETCH_HEADER]="1"),r&&(p[n.NEXT_URL]=r);let h=(0,l.hexHash)([p[n.NEXT_ROUTER_PREFETCH_HEADER]||"0",p[n.NEXT_ROUTER_STATE_TREE],p[n.NEXT_URL]].join(","));try{var g;let t=new URL(e);t.pathname.endsWith("/")?t.pathname+="index.txt":t.pathname+=".txt",t.searchParams.set(n.NEXT_RSC_UNION_QUERY,h);let r=await fetch(t,{credentials:"same-origin",headers:p}),i=(0,o.urlToUrlWithoutFlightMarker)(r.url),l=r.redirected?i:void 0,u=r.headers.get("content-type")||"",f=!!r.headers.get(n.NEXT_DID_POSTPONE_HEADER),_=!!(null==(g=r.headers.get("vary"))?void 0:g.includes(n.NEXT_URL)),y=u===n.RSC_CONTENT_TYPE_HEADER;if(y||(y=u.startsWith("text/plain")),!y||!r.ok)return e.hash&&(i.hash=e.hash),c(i.toString());let[v,b]=await s(Promise.resolve(r),{callServer:a.callServer});if(d!==v)return c(r.url);return[b,l,f,_]}catch(t){return console.error("Failed to fetch RSC payload for "+e+". Falling back to browser navigation.",t),[e.toString(),void 0,!1,!1]}}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},503:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"fillCacheWithNewSubTreeData",{enumerable:!0,get:function(){return function e(t,r,i,l){let u=i.length<=5,[s,c]=i,d=(0,a.createRouterCacheKey)(c),f=r.parallelRoutes.get(s);if(!f)return;let p=t.parallelRoutes.get(s);p&&p!==f||(p=new Map(f),t.parallelRoutes.set(s,p));let h=f.get(d),g=p.get(d);if(u){if(!g||!g.lazyData||g===h){let e=i[3];g={lazyData:null,rsc:e[2],prefetchRsc:null,head:null,prefetchHead:null,loading:e[3],parallelRoutes:h?new Map(h.parallelRoutes):new Map,lazyDataResolved:!1},h&&(0,n.invalidateCacheByRouterState)(g,h,i[2]),(0,o.fillLazyItemsTillLeafWithHead)(g,h,i[2],e,i[4],l),p.set(d,g)}return}g&&h&&(g===h&&(g={lazyData:g.lazyData,rsc:g.rsc,prefetchRsc:g.prefetchRsc,head:g.head,prefetchHead:g.prefetchHead,parallelRoutes:new Map(g.parallelRoutes),lazyDataResolved:!1,loading:g.loading},p.set(d,g)),e(g,h,i.slice(2),l))}}});let n=r(875),o=r(1742),a=r(5929);("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},1742:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"fillLazyItemsTillLeafWithHead",{enumerable:!0,get:function(){return function e(t,r,a,i,l,u){if(0===Object.keys(a[1]).length){t.head=l;return}for(let s in a[1]){let c;let d=a[1][s],f=d[0],p=(0,n.createRouterCacheKey)(f),h=null!==i&&void 0!==i[1][s]?i[1][s]:null;if(r){let n=r.parallelRoutes.get(s);if(n){let r;let a=(null==u?void 0:u.kind)==="auto"&&u.status===o.PrefetchCacheEntryStatus.reusable,i=new Map(n),c=i.get(p);r=null!==h?{lazyData:null,rsc:h[2],prefetchRsc:null,head:null,prefetchHead:null,loading:h[3],parallelRoutes:new Map(null==c?void 0:c.parallelRoutes),lazyDataResolved:!1}:a&&c?{lazyData:c.lazyData,rsc:c.rsc,prefetchRsc:c.prefetchRsc,head:c.head,prefetchHead:c.prefetchHead,parallelRoutes:new Map(c.parallelRoutes),lazyDataResolved:c.lazyDataResolved,loading:c.loading}:{lazyData:null,rsc:null,prefetchRsc:null,head:null,prefetchHead:null,parallelRoutes:new Map(null==c?void 0:c.parallelRoutes),lazyDataResolved:!1,loading:null},i.set(p,r),e(r,c,d,h||null,l,u),t.parallelRoutes.set(s,i);continue}}if(null!==h){let e=h[2],t=h[3];c={lazyData:null,rsc:e,prefetchRsc:null,head:null,prefetchHead:null,parallelRoutes:new Map,lazyDataResolved:!1,loading:t}}else c={lazyData:null,rsc:null,prefetchRsc:null,head:null,prefetchHead:null,parallelRoutes:new Map,lazyDataResolved:!1,loading:null};let g=t.parallelRoutes.get(s);g?g.set(p,c):t.parallelRoutes.set(s,new Map([[p,c]])),e(c,void 0,d,h,l,u)}}}});let n=r(5929),o=r(5343);("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},4607:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"handleMutable",{enumerable:!0,get:function(){return a}});let n=r(1670);function o(e){return void 0!==e}function a(e,t){var r,a,i;let l=null==(a=t.shouldScroll)||a,u=e.nextUrl;if(o(t.patchedTree)){let r=(0,n.computeChangedPath)(e.tree,t.patchedTree);r?u=r:u||(u=e.canonicalUrl)}return{buildId:e.buildId,canonicalUrl:o(t.canonicalUrl)?t.canonicalUrl===e.canonicalUrl?e.canonicalUrl:t.canonicalUrl:e.canonicalUrl,pushRef:{pendingPush:o(t.pendingPush)?t.pendingPush:e.pushRef.pendingPush,mpaNavigation:o(t.mpaNavigation)?t.mpaNavigation:e.pushRef.mpaNavigation,preserveCustomHistoryState:o(t.preserveCustomHistoryState)?t.preserveCustomHistoryState:e.pushRef.preserveCustomHistoryState},focusAndScrollRef:{apply:!!l&&(!!o(null==t?void 0:t.scrollableSegments)||e.focusAndScrollRef.apply),onlyHashChange:!!t.hashFragment&&e.canonicalUrl.split("#",1)[0]===(null==(r=t.canonicalUrl)?void 0:r.split("#",1)[0]),hashFragment:l?t.hashFragment&&""!==t.hashFragment?decodeURIComponent(t.hashFragment.slice(1)):e.focusAndScrollRef.hashFragment:null,segmentPaths:l?null!=(i=null==t?void 0:t.scrollableSegments)?i:e.focusAndScrollRef.segmentPaths:[]},cache:t.cache?t.cache:e.cache,prefetchCache:t.prefetchCache?t.prefetchCache:e.prefetchCache,tree:o(t.patchedTree)?t.patchedTree:e.tree,nextUrl:u}}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},5015:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"handleSegmentMismatch",{enumerable:!0,get:function(){return o}});let n=r(2798);function o(e,t,r){return(0,n.handleExternalUrl)(e,{},e.canonicalUrl,!0)}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},487:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"invalidateCacheBelowFlightSegmentPath",{enumerable:!0,get:function(){return function e(t,r,o){let a=o.length<=2,[i,l]=o,u=(0,n.createRouterCacheKey)(l),s=r.parallelRoutes.get(i);if(!s)return;let c=t.parallelRoutes.get(i);if(c&&c!==s||(c=new Map(s),t.parallelRoutes.set(i,c)),a){c.delete(u);return}let d=s.get(u),f=c.get(u);f&&d&&(f===d&&(f={lazyData:f.lazyData,rsc:f.rsc,prefetchRsc:f.prefetchRsc,head:f.head,prefetchHead:f.prefetchHead,parallelRoutes:new Map(f.parallelRoutes),lazyDataResolved:f.lazyDataResolved},c.set(u,f)),e(f,d,o.slice(2)))}}});let n=r(5929);("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},875:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"invalidateCacheByRouterState",{enumerable:!0,get:function(){return o}});let n=r(5929);function o(e,t,r){for(let o in r[1]){let a=r[1][o][0],i=(0,n.createRouterCacheKey)(a),l=t.parallelRoutes.get(o);if(l){let t=new Map(l);t.delete(i),e.parallelRoutes.set(o,t)}}}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},5370:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"isNavigatingToNewRootLayout",{enumerable:!0,get:function(){return function e(t,r){let n=t[0],o=r[0];if(Array.isArray(n)&&Array.isArray(o)){if(n[0]!==o[0]||n[2]!==o[2])return!0}else if(n!==o)return!0;if(t[4])return!r[4];if(r[4])return!0;let a=Object.values(t[1])[0],i=Object.values(r[1])[0];return!a||!i||e(a,i)}}}),("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},8675:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{abortTask:function(){return s},listenForDynamicRequest:function(){return l},updateCacheNodeOnNavigation:function(){return function e(t,r,l,s,c){let d=r[1],f=l[1],p=s[1],h=t.parallelRoutes,g=new Map(h),_={},y=null;for(let t in f){let r;let l=f[t],s=d[t],v=h.get(t),b=p[t],m=l[0],R=(0,a.createRouterCacheKey)(m),P=void 0!==s?s[0]:void 0,S=void 0!==v?v.get(R):void 0;if(null!==(r=m===n.PAGE_SEGMENT_KEY?i(l,void 0!==b?b:null,c):m===n.DEFAULT_SEGMENT_KEY?void 0!==s?{route:s,node:null,children:null}:i(l,void 0!==b?b:null,c):void 0!==P&&(0,o.matchSegment)(m,P)&&void 0!==S&&void 0!==s?null!=b?e(S,s,l,b,c):function(e){let t=u(e,null,null);return{route:e,node:t,children:null}}(l):i(l,void 0!==b?b:null,c))){null===y&&(y=new Map),y.set(t,r);let e=r.node;if(null!==e){let r=new Map(v);r.set(R,e),g.set(t,r)}_[t]=r.route}else _[t]=l}if(null===y)return null;let v={lazyData:null,rsc:t.rsc,prefetchRsc:t.prefetchRsc,head:t.head,prefetchHead:t.prefetchHead,loading:t.loading,parallelRoutes:g,lazyDataResolved:!1};return{route:function(e,t){let r=[e[0],t];return 2 in e&&(r[2]=e[2]),3 in e&&(r[3]=e[3]),4 in e&&(r[4]=e[4]),r}(l,_),node:v,children:y}}},updateCacheNodeOnPopstateRestoration:function(){return function e(t,r){let n=r[1],o=t.parallelRoutes,i=new Map(o);for(let t in n){let r=n[t],l=r[0],u=(0,a.createRouterCacheKey)(l),s=o.get(t);if(void 0!==s){let n=s.get(u);if(void 0!==n){let o=e(n,r),a=new Map(s);a.set(u,o),i.set(t,a)}}}let l=t.rsc,u=f(l)&&"pending"===l.status;return{lazyData:null,rsc:l,head:t.head,prefetchHead:u?t.prefetchHead:null,prefetchRsc:u?t.prefetchRsc:null,loading:u?t.loading:null,parallelRoutes:i,lazyDataResolved:!1}}}});let n=r(3537),o=r(5057),a=r(5929);function i(e,t,r){let n=u(e,t,r);return{route:e,node:n,children:null}}function l(e,t){t.then(t=>{for(let r of t[0]){let t=r.slice(0,-3),n=r[r.length-3],i=r[r.length-2],l=r[r.length-1];"string"!=typeof t&&function(e,t,r,n,i){let l=e;for(let e=0;e{s(e,t)})}function u(e,t,r){let n=e[1],o=null!==t?t[1]:null,i=new Map;for(let e in n){let t=n[e],l=null!==o?o[e]:null,s=t[0],c=(0,a.createRouterCacheKey)(s),d=u(t,void 0===l?null:l,r),f=new Map;f.set(c,d),i.set(e,f)}let l=0===i.size,s=null!==t?t[2]:null,c=null!==t?t[3]:null;return{lazyData:null,parallelRoutes:i,prefetchRsc:void 0!==s?s:null,prefetchHead:l?r:null,loading:void 0!==c?c:null,rsc:p(),head:l?p():null,lazyDataResolved:!1}}function s(e,t){let r=e.node;if(null===r)return;let n=e.children;if(null===n)c(e.route,r,t);else for(let e of n.values())s(e,t);e.node=null}function c(e,t,r){let n=e[1],o=t.parallelRoutes;for(let e in n){let t=n[e],i=o.get(e);if(void 0===i)continue;let l=t[0],u=(0,a.createRouterCacheKey)(l),s=i.get(u);void 0!==s&&c(t,s,r)}let i=t.rsc;f(i)&&(null===r?i.resolve(null):i.reject(r));let l=t.head;f(l)&&l.resolve(null)}let d=Symbol();function f(e){return e&&e.tag===d}function p(){let e,t;let r=new Promise((r,n)=>{e=r,t=n});return r.status="pending",r.resolve=t=>{"pending"===r.status&&(r.status="fulfilled",r.value=t,e(t))},r.reject=e=>{"pending"===r.status&&(r.status="rejected",r.reason=e,t(e))},r.tag=d,r}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},5296:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{createPrefetchCacheEntryForInitialLoad:function(){return s},getOrCreatePrefetchCacheEntry:function(){return u},prunePrefetchCache:function(){return d}});let n=r(7027),o=r(5437),a=r(5343),i=r(8602);function l(e,t){let r=(0,n.createHrefFromUrl)(e,!1);return t?t+"%"+r:r}function u(e){let t,{url:r,nextUrl:n,tree:o,buildId:i,prefetchCache:u,kind:s}=e,d=l(r,n),f=u.get(d);if(f)t=f;else{let e=l(r),n=u.get(e);n&&(t=n)}return t?(t.status=h(t),t.kind!==a.PrefetchKind.FULL&&s===a.PrefetchKind.FULL)?c({tree:o,url:r,buildId:i,nextUrl:n,prefetchCache:u,kind:null!=s?s:a.PrefetchKind.TEMPORARY}):(s&&t.kind===a.PrefetchKind.TEMPORARY&&(t.kind=s),t):c({tree:o,url:r,buildId:i,nextUrl:n,prefetchCache:u,kind:s||a.PrefetchKind.TEMPORARY})}function s(e){let{nextUrl:t,tree:r,prefetchCache:n,url:o,kind:i,data:u}=e,[,,,s]=u,c=s?l(o,t):l(o),d={treeAtTimeOfPrefetch:r,data:Promise.resolve(u),kind:i,prefetchTime:Date.now(),lastUsedTime:Date.now(),key:c,status:a.PrefetchCacheEntryStatus.fresh};return n.set(c,d),d}function c(e){let{url:t,kind:r,tree:n,nextUrl:u,buildId:s,prefetchCache:c}=e,d=l(t),f=i.prefetchQueue.enqueue(()=>(0,o.fetchServerResponse)(t,n,u,s,r).then(e=>{let[,,,r]=e;return r&&function(e){let{url:t,nextUrl:r,prefetchCache:n}=e,o=l(t),a=n.get(o);if(!a)return;let i=l(t,r);n.set(i,a),n.delete(o)}({url:t,nextUrl:u,prefetchCache:c}),e})),p={treeAtTimeOfPrefetch:n,data:f,kind:r,prefetchTime:Date.now(),lastUsedTime:null,key:d,status:a.PrefetchCacheEntryStatus.fresh};return c.set(d,p),p}function d(e){for(let[t,r]of e)h(r)===a.PrefetchCacheEntryStatus.expired&&e.delete(t)}let f=1e3*Number("30"),p=1e3*Number("300");function h(e){let{kind:t,prefetchTime:r,lastUsedTime:n}=e;return Date.now()<(null!=n?n:r)+f?n?a.PrefetchCacheEntryStatus.reusable:a.PrefetchCacheEntryStatus.fresh:"auto"===t&&Date.now(){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"fastRefreshReducer",{enumerable:!0,get:function(){return n}}),r(5437),r(7027),r(7542),r(5370),r(2798),r(4607),r(8517),r(6544),r(5015),r(9041);let n=function(e,t){return e};("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},5873:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"findHeadInCache",{enumerable:!0,get:function(){return o}});let n=r(5929);function o(e,t){return function e(t,r,o){if(0===Object.keys(r).length)return[t,o];for(let a in r){let[i,l]=r[a],u=t.parallelRoutes.get(a);if(!u)continue;let s=(0,n.createRouterCacheKey)(i),c=u.get(s);if(!c)continue;let d=e(c,l,o+"/"+s);if(d)return d}return null}(e,t,"")}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},8821:(e,t)=>{"use strict";function r(e){return Array.isArray(e)?e[1]:e}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"getSegmentValue",{enumerable:!0,get:function(){return r}}),("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},9041:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"hasInterceptionRouteInCurrentTree",{enumerable:!0,get:function(){return function e(t){let[r,o]=t;if(Array.isArray(r)&&("di"===r[2]||"ci"===r[2])||"string"==typeof r&&(0,n.isInterceptionRouteAppPath)(r))return!0;if(o){for(let t in o)if(e(o[t]))return!0}return!1}}});let n=r(8561);("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},2798:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{handleExternalUrl:function(){return _},navigateReducer:function(){return v}}),r(5437);let n=r(7027),o=r(487),a=r(7542),i=r(5521),l=r(5370),u=r(5343),s=r(4607),c=r(8517),d=r(8602),f=r(6544),p=r(3537),h=(r(8675),r(5296)),g=r(724);function _(e,t,r,n){return t.mpaNavigation=!0,t.canonicalUrl=r,t.pendingPush=n,t.scrollableSegments=void 0,(0,s.handleMutable)(e,t)}function y(e){let t=[],[r,n]=e;if(0===Object.keys(n).length)return[[r]];for(let[e,o]of Object.entries(n))for(let n of y(o))""===r?t.push([e,...n]):t.push([r,e,...n]);return t}let v=function(e,t){let{url:r,isExternalUrl:v,navigateType:b,shouldScroll:m}=t,R={},{hash:P}=r,S=(0,n.createHrefFromUrl)(r),E="push"===b;if((0,h.prunePrefetchCache)(e.prefetchCache),R.preserveCustomHistoryState=!1,v)return _(e,R,r.toString(),E);let O=(0,h.getOrCreatePrefetchCacheEntry)({url:r,nextUrl:e.nextUrl,tree:e.tree,buildId:e.buildId,prefetchCache:e.prefetchCache}),{treeAtTimeOfPrefetch:T,data:x}=O;return d.prefetchQueue.bump(x),x.then(t=>{let[r,d]=t,h=!1;if(O.lastUsedTime||(O.lastUsedTime=Date.now(),h=!0),"string"==typeof r)return _(e,R,r,E);if(document.getElementById("__next-page-redirect"))return _(e,R,S,E);let v=e.tree,b=e.cache,x=[];for(let t of r){let r=t.slice(0,-4),n=t.slice(-3)[0],s=["",...r],d=(0,a.applyRouterStatePatchToTree)(s,v,n,S);if(null===d&&(d=(0,a.applyRouterStatePatchToTree)(s,T,n,S)),null!==d){if((0,l.isNavigatingToNewRootLayout)(v,d))return _(e,R,S,E);let a=(0,f.createEmptyCacheNode)(),m=!1;for(let e of(O.status!==u.PrefetchCacheEntryStatus.stale||h?m=(0,c.applyFlightData)(b,a,t,O):(m=function(e,t,r,n){let o=!1;for(let a of(e.rsc=t.rsc,e.prefetchRsc=t.prefetchRsc,e.loading=t.loading,e.parallelRoutes=new Map(t.parallelRoutes),y(n).map(e=>[...r,...e])))(0,g.clearCacheNodeDataForSegmentPath)(e,t,a),o=!0;return o}(a,b,r,n),O.lastUsedTime=Date.now()),(0,i.shouldHardNavigate)(s,v)?(a.rsc=b.rsc,a.prefetchRsc=b.prefetchRsc,(0,o.invalidateCacheBelowFlightSegmentPath)(a,b,r),R.cache=a):m&&(R.cache=a,b=a),v=d,y(n))){let t=[...r,...e];t[t.length-1]!==p.DEFAULT_SEGMENT_KEY&&x.push(t)}}}return R.patchedTree=v,R.canonicalUrl=d?(0,n.createHrefFromUrl)(d):S,R.pendingPush=E,R.scrollableSegments=x,R.hashFragment=P,R.shouldScroll=m,(0,s.handleMutable)(e,R)},()=>e)};("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},8602:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{prefetchQueue:function(){return i},prefetchReducer:function(){return l}});let n=r(4768),o=r(163),a=r(5296),i=new o.PromiseQueue(5);function l(e,t){(0,a.prunePrefetchCache)(e.prefetchCache);let{url:r}=t;return r.searchParams.delete(n.NEXT_RSC_UNION_QUERY),(0,a.getOrCreatePrefetchCacheEntry)({url:r,nextUrl:e.nextUrl,prefetchCache:e.prefetchCache,kind:t.kind,tree:e.tree,buildId:e.buildId}),e}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},7433:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"refreshReducer",{enumerable:!0,get:function(){return h}});let n=r(5437),o=r(7027),a=r(7542),i=r(5370),l=r(2798),u=r(4607),s=r(1742),c=r(6544),d=r(5015),f=r(9041),p=r(8156);function h(e,t){let{origin:r}=t,h={},g=e.canonicalUrl,_=e.tree;h.preserveCustomHistoryState=!1;let y=(0,c.createEmptyCacheNode)(),v=(0,f.hasInterceptionRouteInCurrentTree)(e.tree);return y.lazyData=(0,n.fetchServerResponse)(new URL(g,r),[_[0],_[1],_[2],"refetch"],v?e.nextUrl:null,e.buildId),y.lazyData.then(async r=>{let[n,c]=r;if("string"==typeof n)return(0,l.handleExternalUrl)(e,h,n,e.pushRef.pendingPush);for(let r of(y.lazyData=null,n)){if(3!==r.length)return console.log("REFRESH FAILED"),e;let[n]=r,u=(0,a.applyRouterStatePatchToTree)([""],_,n,e.canonicalUrl);if(null===u)return(0,d.handleSegmentMismatch)(e,t,n);if((0,i.isNavigatingToNewRootLayout)(_,u))return(0,l.handleExternalUrl)(e,h,g,e.pushRef.pendingPush);let f=c?(0,o.createHrefFromUrl)(c):void 0;c&&(h.canonicalUrl=f);let[b,m]=r.slice(-2);if(null!==b){let e=b[2];y.rsc=e,y.prefetchRsc=null,(0,s.fillLazyItemsTillLeafWithHead)(y,void 0,n,b,m),h.prefetchCache=new Map}await (0,p.refreshInactiveParallelSegments)({state:e,updatedTree:u,updatedCache:y,includeNextUrl:v,canonicalUrl:h.canonicalUrl||e.canonicalUrl}),h.cache=y,h.patchedTree=u,h.canonicalUrl=g,_=u}return(0,u.handleMutable)(e,h)},()=>e)}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},5948:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"restoreReducer",{enumerable:!0,get:function(){return a}});let n=r(7027),o=r(1670);function a(e,t){var r;let{url:a,tree:i}=t,l=(0,n.createHrefFromUrl)(a),u=i||e.tree,s=e.cache;return{buildId:e.buildId,canonicalUrl:l,pushRef:{pendingPush:!1,mpaNavigation:!1,preserveCustomHistoryState:!0},focusAndScrollRef:e.focusAndScrollRef,cache:s,prefetchCache:e.prefetchCache,tree:u,nextUrl:null!=(r=(0,o.extractPathFromFlightRouterState)(u))?r:a.pathname}}r(8675),("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},3282:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"serverActionReducer",{enumerable:!0,get:function(){return m}});let n=r(8038),o=r(4768),a=r(5801),i=r(7027),l=r(2798),u=r(7542),s=r(5370),c=r(4607),d=r(1742),f=r(6544),p=r(9041),h=r(5015),g=r(8156),_=r(7544),{createFromFetch:y,encodeReply:v}=r(7447);async function b(e,t,r){let i,{actionId:l,actionArgs:u}=r,s=await v(u),c=await fetch("",{method:"POST",headers:{Accept:o.RSC_CONTENT_TYPE_HEADER,[o.ACTION]:l,[o.NEXT_ROUTER_STATE_TREE]:(0,_.prepareFlightRouterStateForRequest)(e.tree),...t?{[o.NEXT_URL]:t}:{}},body:s}),d=c.headers.get("x-action-redirect");try{let e=JSON.parse(c.headers.get("x-action-revalidated")||"[[],0,0]");i={paths:e[0]||[],tag:!!e[1],cookie:e[2]}}catch(e){i={paths:[],tag:!1,cookie:!1}}let f=d?new URL((0,a.addBasePath)(d),new URL(e.canonicalUrl,window.location.href)):void 0;if(c.headers.get("content-type")===o.RSC_CONTENT_TYPE_HEADER){let e=await y(Promise.resolve(c),{callServer:n.callServer});if(d){let[,t]=null!=e?e:[];return{actionFlightData:t,redirectLocation:f,revalidatedParts:i}}let[t,[,r]]=null!=e?e:[];return{actionResult:t,actionFlightData:r,redirectLocation:f,revalidatedParts:i}}return{redirectLocation:f,revalidatedParts:i}}function m(e,t){let{resolve:r,reject:n}=t,o={},a=e.canonicalUrl,_=e.tree;o.preserveCustomHistoryState=!1;let y=e.nextUrl&&(0,p.hasInterceptionRouteInCurrentTree)(e.tree)?e.nextUrl:null;return o.inFlightServerAction=b(e,y,t),o.inFlightServerAction.then(async n=>{let{actionResult:p,actionFlightData:v,redirectLocation:b}=n;if(b&&(e.pushRef.pendingPush=!0,o.pendingPush=!0),!v)return(r(p),b)?(0,l.handleExternalUrl)(e,o,b.href,e.pushRef.pendingPush):e;if("string"==typeof v)return(0,l.handleExternalUrl)(e,o,v,e.pushRef.pendingPush);if(o.inFlightServerAction=null,b){let e=(0,i.createHrefFromUrl)(b,!1);o.canonicalUrl=e}for(let r of v){if(3!==r.length)return console.log("SERVER ACTION APPLY FAILED"),e;let[n]=r,c=(0,u.applyRouterStatePatchToTree)([""],_,n,b?(0,i.createHrefFromUrl)(b):e.canonicalUrl);if(null===c)return(0,h.handleSegmentMismatch)(e,t,n);if((0,s.isNavigatingToNewRootLayout)(_,c))return(0,l.handleExternalUrl)(e,o,a,e.pushRef.pendingPush);let[p,v]=r.slice(-2),m=null!==p?p[2]:null;if(null!==m){let t=(0,f.createEmptyCacheNode)();t.rsc=m,t.prefetchRsc=null,(0,d.fillLazyItemsTillLeafWithHead)(t,void 0,n,p,v),await (0,g.refreshInactiveParallelSegments)({state:e,updatedTree:c,updatedCache:t,includeNextUrl:!!y,canonicalUrl:o.canonicalUrl||e.canonicalUrl}),o.cache=t,o.prefetchCache=new Map}o.patchedTree=c,_=c}return r(p),(0,c.handleMutable)(e,o)},t=>(n(t),e))}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},7112:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"serverPatchReducer",{enumerable:!0,get:function(){return d}});let n=r(7027),o=r(7542),a=r(5370),i=r(2798),l=r(8517),u=r(4607),s=r(6544),c=r(5015);function d(e,t){let{serverResponse:r}=t,[d,f]=r,p={};if(p.preserveCustomHistoryState=!1,"string"==typeof d)return(0,i.handleExternalUrl)(e,p,d,e.pushRef.pendingPush);let h=e.tree,g=e.cache;for(let r of d){let u=r.slice(0,-4),[d]=r.slice(-3,-2),_=(0,o.applyRouterStatePatchToTree)(["",...u],h,d,e.canonicalUrl);if(null===_)return(0,c.handleSegmentMismatch)(e,t,d);if((0,a.isNavigatingToNewRootLayout)(h,_))return(0,i.handleExternalUrl)(e,p,e.canonicalUrl,e.pushRef.pendingPush);let y=f?(0,n.createHrefFromUrl)(f):void 0;y&&(p.canonicalUrl=y);let v=(0,s.createEmptyCacheNode)();(0,l.applyFlightData)(g,v,r),p.patchedTree=_,p.cache=v,g=v,h=_}return(0,u.handleMutable)(e,p)}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},8156:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{addRefreshMarkerToActiveParallelSegments:function(){return function e(t,r){let[n,o,,i]=t;for(let l in n.includes(a.PAGE_SEGMENT_KEY)&&"refresh"!==i&&(t[2]=r,t[3]="refresh"),o)e(o[l],r)}},refreshInactiveParallelSegments:function(){return i}});let n=r(8517),o=r(5437),a=r(3537);async function i(e){let t=new Set;await l({...e,rootTree:e.updatedTree,fetchedSegments:t})}async function l(e){let{state:t,updatedTree:r,updatedCache:a,includeNextUrl:i,fetchedSegments:u,rootTree:s=r,canonicalUrl:c}=e,[,d,f,p]=r,h=[];if(f&&f!==c&&"refresh"===p&&!u.has(f)){u.add(f);let e=(0,o.fetchServerResponse)(new URL(f,location.origin),[s[0],s[1],s[2],"refetch"],i?t.nextUrl:null,t.buildId).then(e=>{let t=e[0];if("string"!=typeof t)for(let e of t)(0,n.applyFlightData)(a,a,e)});h.push(e)}for(let e in d){let r=l({state:t,updatedTree:d[e],updatedCache:a,includeNextUrl:i,fetchedSegments:u,rootTree:s,canonicalUrl:c});h.push(r)}await Promise.all(h)}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},5343:(e,t)=>{"use strict";var r,n;Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{ACTION_FAST_REFRESH:function(){return s},ACTION_NAVIGATE:function(){return a},ACTION_PREFETCH:function(){return u},ACTION_REFRESH:function(){return o},ACTION_RESTORE:function(){return i},ACTION_SERVER_ACTION:function(){return c},ACTION_SERVER_PATCH:function(){return l},PrefetchCacheEntryStatus:function(){return n},PrefetchKind:function(){return r},isThenable:function(){return d}});let o="refresh",a="navigate",i="restore",l="server-patch",u="prefetch",s="fast-refresh",c="server-action";function d(e){return e&&("object"==typeof e||"function"==typeof e)&&"function"==typeof e.then}(function(e){e.AUTO="auto",e.FULL="full",e.TEMPORARY="temporary"})(r||(r={})),function(e){e.fresh="fresh",e.reusable="reusable",e.expired="expired",e.stale="stale"}(n||(n={})),("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},9337:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"reducer",{enumerable:!0,get:function(){return n}}),r(5343),r(2798),r(7112),r(5948),r(7433),r(8602),r(1119),r(3282);let n=function(e,t){return e};("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},5521:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"shouldHardNavigate",{enumerable:!0,get:function(){return function e(t,r){let[o,a]=r,[i,l]=t;return(0,n.matchSegment)(i,o)?!(t.length<=2)&&e(t.slice(2),a[l]):!!Array.isArray(i)}}});let n=r(5057);("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},7248:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{createDynamicallyTrackedSearchParams:function(){return l},createUntrackedSearchParams:function(){return i}});let n=r(5869),o=r(1967),a=r(1740);function i(e){let t=n.staticGenerationAsyncStorage.getStore();return t&&t.forceStatic?{}:e}function l(e){let t=n.staticGenerationAsyncStorage.getStore();return t?t.forceStatic?{}:t.isStaticGeneration||t.dynamicShouldError?new Proxy({},{get:(e,r,n)=>("string"==typeof r&&(0,o.trackDynamicDataAccessed)(t,"searchParams."+r),a.ReflectAdapter.get(e,r,n)),has:(e,r)=>("string"==typeof r&&(0,o.trackDynamicDataAccessed)(t,"searchParams."+r),Reflect.has(e,r)),ownKeys:e=>((0,o.trackDynamicDataAccessed)(t,"searchParams"),Reflect.ownKeys(e))}):e:e}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},4839:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{StaticGenBailoutError:function(){return n},isStaticGenBailoutError:function(){return o}});let r="NEXT_STATIC_GEN_BAILOUT";class n extends Error{constructor(...e){super(...e),this.code=r}}function o(e){return"object"==typeof e&&null!==e&&"code"in e&&e.code===r}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},8128:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"unresolvedThenable",{enumerable:!0,get:function(){return r}});let r={then:()=>{}};("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},6743:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{useReducerWithReduxDevtools:function(){return l},useUnwrapState:function(){return i}});let n=r(5453)._(r(3911)),o=r(5343);function a(e){if(e instanceof Map){let t={};for(let[r,n]of e.entries()){if("function"==typeof n){t[r]="fn()";continue}if("object"==typeof n&&null!==n){if(n.$$typeof){t[r]=n.$$typeof.toString();continue}if(n._bundlerConfig){t[r]="FlightData";continue}}t[r]=a(n)}return t}if("object"==typeof e&&null!==e){let t={};for(let r in e){let n=e[r];if("function"==typeof n){t[r]="fn()";continue}if("object"==typeof n&&null!==n){if(n.$$typeof){t[r]=n.$$typeof.toString();continue}if(n.hasOwnProperty("_bundlerConfig")){t[r]="FlightData";continue}}t[r]=a(n)}return t}return Array.isArray(e)?e.map(a):e}function i(e){return(0,o.isThenable)(e)?(0,n.use)(e):e}r(8573);let l=function(e){return[e,()=>{},()=>{}]};("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},7544:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"prepareFlightRouterStateForRequest",{enumerable:!0,get:function(){return o}});let n=r(3537);function o(e,t){return t?encodeURIComponent(JSON.stringify(e)):encodeURIComponent(JSON.stringify(function e(t){let[r,o,,a,i]=t,l="string"==typeof r&&r.startsWith(n.PAGE_SEGMENT_KEY+"?")?n.PAGE_SEGMENT_KEY:r,u={};for(let[t,r]of Object.entries(o))u[t]=e(r);let s=[l,u,null,a&&"refresh"!==a?a:null];return void 0!==i&&(s[4]=i),s}(e)))}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},3950:(e,t,r)=>{"use strict";function n(e,t,r,n){return!1}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"getDomainLocale",{enumerable:!0,get:function(){return n}}),r(1858),("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},9628:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"hasBasePath",{enumerable:!0,get:function(){return o}});let n=r(7171);function o(e){return(0,n.pathHasPrefix)(e,"")}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},4942:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return v}});let n=r(1607),o=r(8924),a=n._(r(3911)),i=r(7119),l=r(5133),u=r(4359),s=r(5955),c=r(1737),d=r(7897),f=r(6115),p=r(5546),h=r(3950),g=r(5801),_=r(5343);function y(e){return"string"==typeof e?e:(0,u.formatUrl)(e)}let v=a.default.forwardRef(function(e,t){let r,n;let{href:u,as:v,children:b,prefetch:m=null,passHref:R,replace:P,shallow:S,scroll:E,locale:O,onClick:T,onMouseEnter:x,onTouchStart:j,legacyBehavior:M=!1,...N}=e;r=b,M&&("string"==typeof r||"number"==typeof r)&&(r=(0,o.jsx)("a",{children:r}));let A=a.default.useContext(d.RouterContext),C=a.default.useContext(f.AppRouterContext),w=null!=A?A:C,I=!A,D=!1!==m,L=null===m?_.PrefetchKind.AUTO:_.PrefetchKind.FULL,{href:U,as:k}=a.default.useMemo(()=>{if(!A){let e=y(u);return{href:e,as:v?y(v):e}}let[e,t]=(0,i.resolveHref)(A,u,!0);return{href:e,as:v?(0,i.resolveHref)(A,v):t||e}},[A,u,v]),F=a.default.useRef(U),H=a.default.useRef(k);M&&(n=a.default.Children.only(r));let G=M?n&&"object"==typeof n&&n.ref:t,[B,V,X]=(0,p.useIntersection)({rootMargin:"200px"}),$=a.default.useCallback(e=>{(H.current!==k||F.current!==U)&&(X(),H.current=k,F.current=U),B(e),G&&("function"==typeof G?G(e):"object"==typeof G&&(G.current=e))},[k,G,U,X,B]);a.default.useEffect(()=>{},[k,U,V,O,D,null==A?void 0:A.locale,w,I,L]);let W={ref:$,onClick(e){M||"function"!=typeof T||T(e),M&&n.props&&"function"==typeof n.props.onClick&&n.props.onClick(e),w&&!e.defaultPrevented&&function(e,t,r,n,o,i,u,s,c){let{nodeName:d}=e.currentTarget;if("A"===d.toUpperCase()&&(function(e){let t=e.currentTarget.getAttribute("target");return t&&"_self"!==t||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey||e.nativeEvent&&2===e.nativeEvent.which}(e)||!c&&!(0,l.isLocalURL)(r)))return;e.preventDefault();let f=()=>{let e=null==u||u;"beforePopState"in t?t[o?"replace":"push"](r,n,{shallow:i,locale:s,scroll:e}):t[o?"replace":"push"](n||r,{scroll:e})};c?a.default.startTransition(f):f()}(e,w,U,k,P,S,E,O,I)},onMouseEnter(e){M||"function"!=typeof x||x(e),M&&n.props&&"function"==typeof n.props.onMouseEnter&&n.props.onMouseEnter(e)},onTouchStart:function(e){M||"function"!=typeof j||j(e),M&&n.props&&"function"==typeof n.props.onTouchStart&&n.props.onTouchStart(e)}};if((0,s.isAbsoluteUrl)(k))W.href=k;else if(!M||R||"a"===n.type&&!("href"in n.props)){let e=void 0!==O?O:null==A?void 0:A.locale,t=(null==A?void 0:A.isLocaleDomain)&&(0,h.getDomainLocale)(k,e,null==A?void 0:A.locales,null==A?void 0:A.domainLocales);W.href=t||(0,g.addBasePath)((0,c.addLocale)(k,e,null==A?void 0:A.defaultLocale))}return M?a.default.cloneElement(n,W):(0,o.jsx)("a",{...N,...W,children:r})});("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},1858:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"normalizePathTrailingSlash",{enumerable:!0,get:function(){return a}});let n=r(2188),o=r(6751),a=e=>{if(!e.startsWith("/"))return e;let{pathname:t,query:r,hash:a}=(0,o.parsePath)(e);return/\.[^/]+\/?$/.test(t)?""+(0,n.removeTrailingSlash)(t)+r+a:t.endsWith("/")?""+t+r+a:t+"/"+r+a};("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},8183:(e,t,r)=>{"use strict";function n(e){return e}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"removeBasePath",{enumerable:!0,get:function(){return n}}),r(9628),("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},8605:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{cancelIdleCallback:function(){return n},requestIdleCallback:function(){return r}});let r="undefined"!=typeof self&&self.requestIdleCallback&&self.requestIdleCallback.bind(window)||function(e){let t=Date.now();return self.setTimeout(function(){e({didTimeout:!1,timeRemaining:function(){return Math.max(0,50-(Date.now()-t))}})},1)},n="undefined"!=typeof self&&self.cancelIdleCallback&&self.cancelIdleCallback.bind(window)||function(e){return clearTimeout(e)};("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},7119:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"resolveHref",{enumerable:!0,get:function(){return d}});let n=r(9059),o=r(4359),a=r(7829),i=r(5955),l=r(1858),u=r(5133),s=r(4182),c=r(3388);function d(e,t,r){let d;let f="string"==typeof t?t:(0,o.formatWithValidation)(t),p=f.match(/^[a-zA-Z]{1,}:\/\//),h=p?f.slice(p[0].length):f;if((h.split("?",1)[0]||"").match(/(\/\/|\\)/)){console.error("Invalid href '"+f+"' passed to next/router in page: '"+e.pathname+"'. Repeated forward-slashes (//) or backslashes \\ are not valid in the href.");let t=(0,i.normalizeRepeatedSlashes)(h);f=(p?p[0]:"")+t}if(!(0,u.isLocalURL)(f))return r?[f]:f;try{d=new URL(f.startsWith("#")?e.asPath:e.pathname,"http://n")}catch(e){d=new URL("/","http://n")}try{let e=new URL(f,d);e.pathname=(0,l.normalizePathTrailingSlash)(e.pathname);let t="";if((0,s.isDynamicRoute)(e.pathname)&&e.searchParams&&r){let r=(0,n.searchParamsToUrlQuery)(e.searchParams),{result:i,params:l}=(0,c.interpolateAs)(e.pathname,e.pathname,r);i&&(t=(0,o.formatWithValidation)({pathname:i,hash:e.hash,query:(0,a.omit)(r,l)}))}let i=e.origin===d.origin?e.href.slice(e.origin.length):e.href;return r?[i,t||i]:i}catch(e){return r?[f]:f}}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},5546:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"useIntersection",{enumerable:!0,get:function(){return u}});let n=r(3911),o=r(8605),a="function"==typeof IntersectionObserver,i=new Map,l=[];function u(e){let{rootRef:t,rootMargin:r,disabled:u}=e,s=u||!a,[c,d]=(0,n.useState)(!1),f=(0,n.useRef)(null),p=(0,n.useCallback)(e=>{f.current=e},[]);return(0,n.useEffect)(()=>{if(a){if(s||c)return;let e=f.current;if(e&&e.tagName)return function(e,t,r){let{id:n,observer:o,elements:a}=function(e){let t;let r={root:e.root||null,margin:e.rootMargin||""},n=l.find(e=>e.root===r.root&&e.margin===r.margin);if(n&&(t=i.get(n)))return t;let o=new Map;return t={id:r,observer:new IntersectionObserver(e=>{e.forEach(e=>{let t=o.get(e.target),r=e.isIntersecting||e.intersectionRatio>0;t&&r&&t(r)})},e),elements:o},l.push(r),i.set(r,t),t}(r);return a.set(e,t),o.observe(e),function(){if(a.delete(e),o.unobserve(e),0===a.size){o.disconnect(),i.delete(n);let e=l.findIndex(e=>e.root===n.root&&e.margin===n.margin);e>-1&&l.splice(e,1)}}}(e,e=>e&&d(e),{root:null==t?void 0:t.current,rootMargin:r})}else if(!c){let e=(0,o.requestIdleCallback)(()=>d(!0));return()=>(0,o.cancelIdleCallback)(e)}},[s,r,t,c,f.current]),[p,c,(0,n.useCallback)(()=>{d(!1)},[])]}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},4217:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{ACTION_SUFFIX:function(){return u},APP_DIR_ALIAS:function(){return x},CACHE_ONE_YEAR:function(){return m},DOT_NEXT_ALIAS:function(){return O},ESLINT_DEFAULT_DIRS:function(){return $},GSP_NO_RETURNED_VALUE:function(){return F},GSSP_COMPONENT_MEMBER_ERROR:function(){return B},GSSP_NO_RETURNED_VALUE:function(){return H},INSTRUMENTATION_HOOK_FILENAME:function(){return S},MIDDLEWARE_FILENAME:function(){return R},MIDDLEWARE_LOCATION_REGEXP:function(){return P},NEXT_BODY_SUFFIX:function(){return d},NEXT_CACHE_IMPLICIT_TAG_ID:function(){return b},NEXT_CACHE_REVALIDATED_TAGS_HEADER:function(){return h},NEXT_CACHE_REVALIDATE_TAG_TOKEN_HEADER:function(){return g},NEXT_CACHE_SOFT_TAGS_HEADER:function(){return p},NEXT_CACHE_SOFT_TAG_MAX_LENGTH:function(){return v},NEXT_CACHE_TAGS_HEADER:function(){return f},NEXT_CACHE_TAG_MAX_ITEMS:function(){return _},NEXT_CACHE_TAG_MAX_LENGTH:function(){return y},NEXT_DATA_SUFFIX:function(){return s},NEXT_INTERCEPTION_MARKER_PREFIX:function(){return n},NEXT_META_SUFFIX:function(){return c},NEXT_QUERY_PARAM_PREFIX:function(){return r},NON_STANDARD_NODE_ENV:function(){return V},PAGES_DIR_ALIAS:function(){return E},PRERENDER_REVALIDATE_HEADER:function(){return o},PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER:function(){return a},PUBLIC_DIR_MIDDLEWARE_CONFLICT:function(){return w},ROOT_DIR_ALIAS:function(){return T},RSC_ACTION_CLIENT_WRAPPER_ALIAS:function(){return C},RSC_ACTION_ENCRYPTION_ALIAS:function(){return A},RSC_ACTION_PROXY_ALIAS:function(){return N},RSC_ACTION_VALIDATE_ALIAS:function(){return M},RSC_MOD_REF_PROXY_ALIAS:function(){return j},RSC_PREFETCH_SUFFIX:function(){return i},RSC_SUFFIX:function(){return l},SERVER_PROPS_EXPORT_ERROR:function(){return k},SERVER_PROPS_GET_INIT_PROPS_CONFLICT:function(){return D},SERVER_PROPS_SSG_CONFLICT:function(){return L},SERVER_RUNTIME:function(){return W},SSG_FALLBACK_EXPORT_ERROR:function(){return X},SSG_GET_INITIAL_PROPS_CONFLICT:function(){return I},STATIC_STATUS_PAGE_GET_INITIAL_PROPS_ERROR:function(){return U},UNSTABLE_REVALIDATE_RENAME_ERROR:function(){return G},WEBPACK_LAYERS:function(){return K},WEBPACK_RESOURCE_QUERIES:function(){return Y}});let r="nxtP",n="nxtI",o="x-prerender-revalidate",a="x-prerender-revalidate-if-generated",i=".prefetch.rsc",l=".rsc",u=".action",s=".json",c=".meta",d=".body",f="x-next-cache-tags",p="x-next-cache-soft-tags",h="x-next-revalidated-tags",g="x-next-revalidate-tag-token",_=128,y=256,v=1024,b="_N_T_",m=31536e3,R="middleware",P=`(?:src/)?${R}`,S="instrumentation",E="private-next-pages",O="private-dot-next",T="private-next-root-dir",x="private-next-app-dir",j="private-next-rsc-mod-ref-proxy",M="private-next-rsc-action-validate",N="private-next-rsc-server-reference",A="private-next-rsc-action-encryption",C="private-next-rsc-action-client-wrapper",w="You can not have a '_next' folder inside of your public folder. This conflicts with the internal '/_next' route. https://nextjs.org/docs/messages/public-next-folder-conflict",I="You can not use getInitialProps with getStaticProps. To use SSG, please remove your getInitialProps",D="You can not use getInitialProps with getServerSideProps. Please remove getInitialProps.",L="You can not use getStaticProps or getStaticPaths with getServerSideProps. To use SSG, please remove getServerSideProps",U="can not have getInitialProps/getServerSideProps, https://nextjs.org/docs/messages/404-get-initial-props",k="pages with `getServerSideProps` can not be exported. See more info here: https://nextjs.org/docs/messages/gssp-export",F="Your `getStaticProps` function did not return an object. Did you forget to add a `return`?",H="Your `getServerSideProps` function did not return an object. Did you forget to add a `return`?",G="The `unstable_revalidate` property is available for general use.\nPlease use `revalidate` instead.",B="can not be attached to a page's component and must be exported from the page. See more info here: https://nextjs.org/docs/messages/gssp-component-member",V='You are using a non-standard "NODE_ENV" value in your environment. This creates inconsistencies in the project and is strongly advised against. Read more: https://nextjs.org/docs/messages/non-standard-node-env',X="Pages with `fallback` enabled in `getStaticPaths` can not be exported. See more info here: https://nextjs.org/docs/messages/ssg-fallback-true-export",$=["app","pages","components","lib","src"],W={edge:"edge",experimentalEdge:"experimental-edge",nodejs:"nodejs"},z={shared:"shared",reactServerComponents:"rsc",serverSideRendering:"ssr",actionBrowser:"action-browser",api:"api",middleware:"middleware",instrument:"instrument",edgeAsset:"edge-asset",appPagesBrowser:"app-pages-browser",appMetadataRoute:"app-metadata-route",appRouteHandler:"app-route-handler"},K={...z,GROUP:{serverOnly:[z.reactServerComponents,z.actionBrowser,z.appMetadataRoute,z.appRouteHandler,z.instrument],clientOnly:[z.serverSideRendering,z.appPagesBrowser],nonClientServerTarget:[z.middleware,z.api],app:[z.reactServerComponents,z.actionBrowser,z.appMetadataRoute,z.appRouteHandler,z.serverSideRendering,z.appPagesBrowser,z.shared,z.instrument]}},Y={edgeSSREntry:"__next_edge_ssr_entry__",metadata:"__next_metadata__",metadataRoute:"__next_metadata_route__",metadataImageMeta:"__next_metadata_image_meta__"}},6639:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{getPathname:function(){return n},isFullStringUrl:function(){return o},parseUrl:function(){return a}});let r="http://n";function n(e){return new URL(e,r).pathname}function o(e){return/https?:\/\//.test(e)}function a(e){let t;try{t=new URL(e,r)}catch{}return t}},1967:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{Postpone:function(){return d},createPostponedAbortSignal:function(){return y},createPrerenderState:function(){return u},formatDynamicAPIAccesses:function(){return g},markCurrentScopeAsDynamic:function(){return s},trackDynamicDataAccessed:function(){return c},trackDynamicFetch:function(){return f},usedDynamicAPIs:function(){return h}});let n=function(e){return e&&e.__esModule?e:{default:e}}(r(3911)),o=r(5667),a=r(4839),i=r(6639),l="function"==typeof n.default.unstable_postpone;function u(e){return{isDebugSkeleton:e,dynamicAccesses:[]}}function s(e,t){let r=(0,i.getPathname)(e.urlPathname);if(!e.isUnstableCacheCallback){if(e.dynamicShouldError)throw new a.StaticGenBailoutError(`Route ${r} with \`dynamic = "error"\` couldn't be rendered statically because it used \`${t}\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering`);if(e.prerenderState)p(e.prerenderState,t,r);else if(e.revalidate=0,e.isStaticGeneration){let n=new o.DynamicServerError(`Route ${r} couldn't be rendered statically because it used ${t}. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`);throw e.dynamicUsageDescription=t,e.dynamicUsageStack=n.stack,n}}}function c(e,t){let r=(0,i.getPathname)(e.urlPathname);if(e.isUnstableCacheCallback)throw Error(`Route ${r} used "${t}" inside a function cached with "unstable_cache(...)". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use "${t}" outside of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/app/api-reference/functions/unstable_cache`);if(e.dynamicShouldError)throw new a.StaticGenBailoutError(`Route ${r} with \`dynamic = "error"\` couldn't be rendered statically because it used \`${t}\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering`);if(e.prerenderState)p(e.prerenderState,t,r);else if(e.revalidate=0,e.isStaticGeneration){let n=new o.DynamicServerError(`Route ${r} couldn't be rendered statically because it used \`${t}\`. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`);throw e.dynamicUsageDescription=t,e.dynamicUsageStack=n.stack,n}}function d({reason:e,prerenderState:t,pathname:r}){p(t,e,r)}function f(e,t){e.prerenderState&&p(e.prerenderState,t,e.urlPathname)}function p(e,t,r){_();let o=`Route ${r} needs to bail out of prerendering at this point because it used ${t}. React throws this special object to indicate where. It should not be caught by your own try/catch. Learn more: https://nextjs.org/docs/messages/ppr-caught-error`;e.dynamicAccesses.push({stack:e.isDebugSkeleton?Error().stack:void 0,expression:t}),n.default.unstable_postpone(o)}function h(e){return e.dynamicAccesses.length>0}function g(e){return e.dynamicAccesses.filter(e=>"string"==typeof e.stack&&e.stack.length>0).map(({expression:e,stack:t})=>(t=t.split("\n").slice(4).filter(e=>!(e.includes("node_modules/next/")||e.includes(" ()")||e.includes(" (node:"))).join("\n"),`Dynamic API Usage Debug - ${e}:
+${t}`))}function _(){if(!l)throw Error("Invariant: React.unstable_postpone is not defined. This suggests the wrong version of React was loaded. This is a bug in Next.js")}function y(e){_();let t=new AbortController;try{n.default.unstable_postpone(e)}catch(e){t.abort(e)}return t.signal}},2414:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"getSegmentParam",{enumerable:!0,get:function(){return o}});let n=r(8561);function o(e){let t=n.INTERCEPTION_ROUTE_MARKERS.find(t=>e.startsWith(t));return(t&&(e=e.slice(t.length)),e.startsWith("[[...")&&e.endsWith("]]"))?{type:"optional-catchall",param:e.slice(5,-2)}:e.startsWith("[...")&&e.endsWith("]")?{type:t?"catchall-intercepted":"catchall",param:e.slice(4,-1)}:e.startsWith("[")&&e.endsWith("]")?{type:t?"dynamic-intercepted":"dynamic",param:e.slice(1,-1)}:null}},8561:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{INTERCEPTION_ROUTE_MARKERS:function(){return o},extractInterceptionRouteInformation:function(){return i},isInterceptionRouteAppPath:function(){return a}});let n=r(1609),o=["(..)(..)","(.)","(..)","(...)"];function a(e){return void 0!==e.split("/").find(e=>o.find(t=>e.startsWith(t)))}function i(e){let t,r,a;for(let n of e.split("/"))if(r=o.find(e=>n.startsWith(e))){[t,a]=e.split(r,2);break}if(!t||!r||!a)throw Error(`Invalid interception route: ${e}. Must be in the format //(..|...|..)(..)/`);switch(t=(0,n.normalizeAppPath)(t),r){case"(.)":a="/"===t?`/${a}`:t+"/"+a;break;case"(..)":if("/"===t)throw Error(`Invalid interception route: ${e}. Cannot use (..) marker at the root level, use (.) instead.`);a=t.split("/").slice(0,-1).concat(a).join("/");break;case"(...)":a="/"+a;break;case"(..)(..)":let i=t.split("/");if(i.length<=2)throw Error(`Invalid interception route: ${e}. Cannot use (..)(..) marker at the root level or one level up.`);a=i.slice(0,-2).concat(a).join("/");break;default:throw Error("Invariant: unexpected marker")}return{interceptingRoute:t,interceptedRoute:a}}},6765:(e,t,r)=>{"use strict";e.exports=r(399)},6115:(e,t,r)=>{"use strict";e.exports=r(6765).vendored.contexts.AppRouterContext},3090:(e,t,r)=>{"use strict";e.exports=r(6765).vendored.contexts.HooksClientContext},7897:(e,t,r)=>{"use strict";e.exports=r(6765).vendored.contexts.RouterContext},8376:(e,t,r)=>{"use strict";e.exports=r(6765).vendored.contexts.ServerInsertedHtml},6348:(e,t,r)=>{"use strict";e.exports=r(6765).vendored["react-ssr"].ReactDOM},8924:(e,t,r)=>{"use strict";e.exports=r(6765).vendored["react-ssr"].ReactJsxRuntime},7447:(e,t,r)=>{"use strict";e.exports=r(6765).vendored["react-ssr"].ReactServerDOMWebpackClientEdge},3911:(e,t,r)=>{"use strict";e.exports=r(6765).vendored["react-ssr"].React},1740:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"ReflectAdapter",{enumerable:!0,get:function(){return r}});class r{static get(e,t,r){let n=Reflect.get(e,t,r);return"function"==typeof n?n.bind(e):n}static set(e,t,r,n){return Reflect.set(e,t,r,n)}static has(e,t){return Reflect.has(e,t)}static deleteProperty(e,t){return Reflect.deleteProperty(e,t)}}},5737:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"escapeStringRegexp",{enumerable:!0,get:function(){return o}});let r=/[|\\{}()[\]^$+*?.-]/,n=/[|\\{}()[\]^$+*?.-]/g;function o(e){return r.test(e)?e.replace(n,"\\$&"):e}},5860:(e,t)=>{"use strict";function r(e){let t=5381;for(let r=0;r>>0}function n(e){return r(e).toString(36).slice(0,5)}Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{djb2Hash:function(){return r},hexHash:function(){return n}})},6483:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{BailoutToCSRError:function(){return n},isBailoutToCSRError:function(){return o}});let r="BAILOUT_TO_CLIENT_SIDE_RENDERING";class n extends Error{constructor(e){super("Bail out to client-side rendering: "+e),this.reason=e,this.digest=r}}function o(e){return"object"==typeof e&&null!==e&&"digest"in e&&e.digest===r}},8142:(e,t)=>{"use strict";function r(e){return e.startsWith("/")?e:"/"+e}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"ensureLeadingSlash",{enumerable:!0,get:function(){return r}})},8573:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{ActionQueueContext:function(){return l},createMutableActionQueue:function(){return c}});let n=r(5453),o=r(5343),a=r(9337),i=n._(r(3911)),l=i.default.createContext(null);function u(e,t){null!==e.pending&&(e.pending=e.pending.next,null!==e.pending?s({actionQueue:e,action:e.pending,setState:t}):e.needsRefresh&&(e.needsRefresh=!1,e.dispatch({type:o.ACTION_REFRESH,origin:window.location.origin},t)))}async function s(e){let{actionQueue:t,action:r,setState:n}=e,a=t.state;if(!a)throw Error("Invariant: Router state not initialized");t.pending=r;let i=r.payload,l=t.action(a,i);function s(e){r.discarded||(t.state=e,t.devToolsInstance&&t.devToolsInstance.send(i,e),u(t,n),r.resolve(e))}(0,o.isThenable)(l)?l.then(s,e=>{u(t,n),r.reject(e)}):s(l)}function c(){let e={state:null,dispatch:(t,r)=>(function(e,t,r){let n={resolve:r,reject:()=>{}};if(t.type!==o.ACTION_RESTORE){let e=new Promise((e,t)=>{n={resolve:e,reject:t}});(0,i.startTransition)(()=>{r(e)})}let a={payload:t,next:null,resolve:n.resolve,reject:n.reject};null===e.pending?(e.last=a,s({actionQueue:e,action:a,setState:r})):t.type===o.ACTION_NAVIGATE||t.type===o.ACTION_RESTORE?(e.pending.discarded=!0,e.last=a,e.pending.payload.type===o.ACTION_SERVER_ACTION&&(e.needsRefresh=!0),s({actionQueue:e,action:a,setState:r})):(null!==e.last&&(e.last.next=a),e.last=a)})(e,t,r),action:async(e,t)=>{if(null===e)throw Error("Invariant: Router state not initialized");return(0,a.reducer)(e,t)},pending:null,last:null};return e}},4096:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"addPathPrefix",{enumerable:!0,get:function(){return o}});let n=r(6751);function o(e,t){if(!e.startsWith("/")||!t)return e;let{pathname:r,query:o,hash:a}=(0,n.parsePath)(e);return""+t+r+o+a}},1609:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{normalizeAppPath:function(){return a},normalizeRscURL:function(){return i}});let n=r(8142),o=r(3537);function a(e){return(0,n.ensureLeadingSlash)(e.split("/").reduce((e,t,r,n)=>!t||(0,o.isGroupSegment)(t)||"@"===t[0]||("page"===t||"route"===t)&&r===n.length-1?e:e+"/"+t,""))}function i(e){return e.replace(/\.rsc($|\?)/,"$1")}},4359:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{formatUrl:function(){return a},formatWithValidation:function(){return l},urlObjectKeys:function(){return i}});let n=r(5453)._(r(9059)),o=/https?|ftp|gopher|file/;function a(e){let{auth:t,hostname:r}=e,a=e.protocol||"",i=e.pathname||"",l=e.hash||"",u=e.query||"",s=!1;t=t?encodeURIComponent(t).replace(/%3A/i,":")+"@":"",e.host?s=t+e.host:r&&(s=t+(~r.indexOf(":")?"["+r+"]":r),e.port&&(s+=":"+e.port)),u&&"object"==typeof u&&(u=String(n.urlQueryToSearchParams(u)));let c=e.search||u&&"?"+u||"";return a&&!a.endsWith(":")&&(a+=":"),e.slashes||(!a||o.test(a))&&!1!==s?(s="//"+(s||""),i&&"/"!==i[0]&&(i="/"+i)):s||(s=""),l&&"#"!==l[0]&&(l="#"+l),c&&"?"!==c[0]&&(c="?"+c),""+a+s+(i=i.replace(/[?#]/g,encodeURIComponent))+(c=c.replace("#","%23"))+l}let i=["auth","hash","host","hostname","href","path","pathname","port","protocol","query","search","slashes"];function l(e){return a(e)}},7546:(e,t)=>{"use strict";function r(e,t){if(void 0===t&&(t={}),t.onlyHashChange){e();return}let r=document.documentElement,n=r.style.scrollBehavior;r.style.scrollBehavior="auto",t.dontForceLayout||r.getClientRects(),e(),r.style.scrollBehavior=n}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"handleSmoothScroll",{enumerable:!0,get:function(){return r}})},4182:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{getSortedRoutes:function(){return n.getSortedRoutes},isDynamicRoute:function(){return o.isDynamicRoute}});let n=r(3319),o=r(6952)},3388:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"interpolateAs",{enumerable:!0,get:function(){return a}});let n=r(9620),o=r(6820);function a(e,t,r){let a="",i=(0,o.getRouteRegex)(e),l=i.groups,u=(t!==e?(0,n.getRouteMatcher)(i)(t):"")||r;a=e;let s=Object.keys(l);return s.every(e=>{let t=u[e]||"",{repeat:r,optional:n}=l[e],o="["+(r?"...":"")+e+"]";return n&&(o=(t?"":"/")+"["+o+"]"),r&&!Array.isArray(t)&&(t=[t]),(n||e in u)&&(a=a.replace(o,r?t.map(e=>encodeURIComponent(e)).join("/"):encodeURIComponent(t))||"/")})||(a=""),{params:s,result:a}}},9647:(e,t)=>{"use strict";function r(e){return/Googlebot|Mediapartners-Google|AdsBot-Google|googleweblight|Storebot-Google|Google-PageRenderer|Bingbot|BingPreview|Slurp|DuckDuckBot|baiduspider|yandex|sogou|LinkedInBot|bitlybot|tumblr|vkShare|quora link preview|facebookexternalhit|facebookcatalog|Twitterbot|applebot|redditbot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|ia_archiver/i.test(e)}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"isBot",{enumerable:!0,get:function(){return r}})},6952:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"isDynamicRoute",{enumerable:!0,get:function(){return a}});let n=r(8561),o=/\/\[[^/]+?\](?=\/|$)/;function a(e){return(0,n.isInterceptionRouteAppPath)(e)&&(e=(0,n.extractInterceptionRouteInformation)(e).interceptedRoute),o.test(e)}},5133:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"isLocalURL",{enumerable:!0,get:function(){return a}});let n=r(5955),o=r(9628);function a(e){if(!(0,n.isAbsoluteUrl)(e))return!0;try{let t=(0,n.getLocationOrigin)(),r=new URL(e,t);return r.origin===t&&(0,o.hasBasePath)(r.pathname)}catch(e){return!1}}},7829:(e,t)=>{"use strict";function r(e,t){let r={};return Object.keys(e).forEach(n=>{t.includes(n)||(r[n]=e[n])}),r}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"omit",{enumerable:!0,get:function(){return r}})},6751:(e,t)=>{"use strict";function r(e){let t=e.indexOf("#"),r=e.indexOf("?"),n=r>-1&&(t<0||r-1?{pathname:e.substring(0,n?r:t),query:n?e.substring(r,t>-1?t:void 0):"",hash:t>-1?e.slice(t):""}:{pathname:e,query:"",hash:""}}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"parsePath",{enumerable:!0,get:function(){return r}})},7171:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"pathHasPrefix",{enumerable:!0,get:function(){return o}});let n=r(6751);function o(e,t){if("string"!=typeof e)return!1;let{pathname:r}=(0,n.parsePath)(e);return r===t||r.startsWith(t+"/")}},9059:(e,t)=>{"use strict";function r(e){let t={};return e.forEach((e,r)=>{void 0===t[r]?t[r]=e:Array.isArray(t[r])?t[r].push(e):t[r]=[t[r],e]}),t}function n(e){return"string"!=typeof e&&("number"!=typeof e||isNaN(e))&&"boolean"!=typeof e?"":String(e)}function o(e){let t=new URLSearchParams;return Object.entries(e).forEach(e=>{let[r,o]=e;Array.isArray(o)?o.forEach(e=>t.append(r,n(e))):t.set(r,n(o))}),t}function a(e){for(var t=arguments.length,r=Array(t>1?t-1:0),n=1;n{Array.from(t.keys()).forEach(t=>e.delete(t)),t.forEach((t,r)=>e.append(r,t))}),e}Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{assign:function(){return a},searchParamsToUrlQuery:function(){return r},urlQueryToSearchParams:function(){return o}})},2188:(e,t)=>{"use strict";function r(e){return e.replace(/\/$/,"")||"/"}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"removeTrailingSlash",{enumerable:!0,get:function(){return r}})},9620:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"getRouteMatcher",{enumerable:!0,get:function(){return o}});let n=r(5955);function o(e){let{re:t,groups:r}=e;return e=>{let o=t.exec(e);if(!o)return!1;let a=e=>{try{return decodeURIComponent(e)}catch(e){throw new n.DecodeError("failed to decode param")}},i={};return Object.keys(r).forEach(e=>{let t=r[e],n=o[t.pos];void 0!==n&&(i[e]=~n.indexOf("/")?n.split("/").map(e=>a(e)):t.repeat?[a(n)]:a(n))}),i}}},6820:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{getNamedMiddlewareRegex:function(){return p},getNamedRouteRegex:function(){return f},getRouteRegex:function(){return s},parseParameter:function(){return l}});let n=r(4217),o=r(8561),a=r(5737),i=r(2188);function l(e){let t=e.startsWith("[")&&e.endsWith("]");t&&(e=e.slice(1,-1));let r=e.startsWith("...");return r&&(e=e.slice(3)),{key:e,repeat:r,optional:t}}function u(e){let t=(0,i.removeTrailingSlash)(e).slice(1).split("/"),r={},n=1;return{parameterizedRoute:t.map(e=>{let t=o.INTERCEPTION_ROUTE_MARKERS.find(t=>e.startsWith(t)),i=e.match(/\[((?:\[.*\])|.+)\]/);if(t&&i){let{key:e,optional:o,repeat:u}=l(i[1]);return r[e]={pos:n++,repeat:u,optional:o},"/"+(0,a.escapeStringRegexp)(t)+"([^/]+?)"}if(!i)return"/"+(0,a.escapeStringRegexp)(e);{let{key:e,repeat:t,optional:o}=l(i[1]);return r[e]={pos:n++,repeat:t,optional:o},t?o?"(?:/(.+?))?":"/(.+?)":"/([^/]+?)"}}).join(""),groups:r}}function s(e){let{parameterizedRoute:t,groups:r}=u(e);return{re:RegExp("^"+t+"(?:/)?$"),groups:r}}function c(e){let{interceptionMarker:t,getSafeRouteKey:r,segment:n,routeKeys:o,keyPrefix:i}=e,{key:u,optional:s,repeat:c}=l(n),d=u.replace(/\W/g,"");i&&(d=""+i+d);let f=!1;(0===d.length||d.length>30)&&(f=!0),isNaN(parseInt(d.slice(0,1)))||(f=!0),f&&(d=r()),i?o[d]=""+i+u:o[d]=u;let p=t?(0,a.escapeStringRegexp)(t):"";return c?s?"(?:/"+p+"(?<"+d+">.+?))?":"/"+p+"(?<"+d+">.+?)":"/"+p+"(?<"+d+">[^/]+?)"}function d(e,t){let r;let l=(0,i.removeTrailingSlash)(e).slice(1).split("/"),u=(r=0,()=>{let e="",t=++r;for(;t>0;)e+=String.fromCharCode(97+(t-1)%26),t=Math.floor((t-1)/26);return e}),s={};return{namedParameterizedRoute:l.map(e=>{let r=o.INTERCEPTION_ROUTE_MARKERS.some(t=>e.startsWith(t)),i=e.match(/\[((?:\[.*\])|.+)\]/);if(r&&i){let[r]=e.split(i[0]);return c({getSafeRouteKey:u,interceptionMarker:r,segment:i[1],routeKeys:s,keyPrefix:t?n.NEXT_INTERCEPTION_MARKER_PREFIX:void 0})}return i?c({getSafeRouteKey:u,segment:i[1],routeKeys:s,keyPrefix:t?n.NEXT_QUERY_PARAM_PREFIX:void 0}):"/"+(0,a.escapeStringRegexp)(e)}).join(""),routeKeys:s}}function f(e,t){let r=d(e,t);return{...s(e),namedRegex:"^"+r.namedParameterizedRoute+"(?:/)?$",routeKeys:r.routeKeys}}function p(e,t){let{parameterizedRoute:r}=u(e),{catchAll:n=!0}=t;if("/"===r)return{namedRegex:"^/"+(n?".*":"")+"$"};let{namedParameterizedRoute:o}=d(e,!1);return{namedRegex:"^"+o+(n?"(?:(/.*)?)":"")+"$"}}},3319:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"getSortedRoutes",{enumerable:!0,get:function(){return n}});class r{insert(e){this._insert(e.split("/").filter(Boolean),[],!1)}smoosh(){return this._smoosh()}_smoosh(e){void 0===e&&(e="/");let t=[...this.children.keys()].sort();null!==this.slugName&&t.splice(t.indexOf("[]"),1),null!==this.restSlugName&&t.splice(t.indexOf("[...]"),1),null!==this.optionalRestSlugName&&t.splice(t.indexOf("[[...]]"),1);let r=t.map(t=>this.children.get(t)._smoosh(""+e+t+"/")).reduce((e,t)=>[...e,...t],[]);if(null!==this.slugName&&r.push(...this.children.get("[]")._smoosh(e+"["+this.slugName+"]/")),!this.placeholder){let t="/"===e?"/":e.slice(0,-1);if(null!=this.optionalRestSlugName)throw Error('You cannot define a route with the same specificity as a optional catch-all route ("'+t+'" and "'+t+"[[..."+this.optionalRestSlugName+']]").');r.unshift(t)}return null!==this.restSlugName&&r.push(...this.children.get("[...]")._smoosh(e+"[..."+this.restSlugName+"]/")),null!==this.optionalRestSlugName&&r.push(...this.children.get("[[...]]")._smoosh(e+"[[..."+this.optionalRestSlugName+"]]/")),r}_insert(e,t,n){if(0===e.length){this.placeholder=!1;return}if(n)throw Error("Catch-all must be the last part of the URL.");let o=e[0];if(o.startsWith("[")&&o.endsWith("]")){let r=o.slice(1,-1),i=!1;if(r.startsWith("[")&&r.endsWith("]")&&(r=r.slice(1,-1),i=!0),r.startsWith("...")&&(r=r.substring(3),n=!0),r.startsWith("[")||r.endsWith("]"))throw Error("Segment names may not start or end with extra brackets ('"+r+"').");if(r.startsWith("."))throw Error("Segment names may not start with erroneous periods ('"+r+"').");function a(e,r){if(null!==e&&e!==r)throw Error("You cannot use different slug names for the same dynamic path ('"+e+"' !== '"+r+"').");t.forEach(e=>{if(e===r)throw Error('You cannot have the same slug name "'+r+'" repeat within a single dynamic path');if(e.replace(/\W/g,"")===o.replace(/\W/g,""))throw Error('You cannot have the slug names "'+e+'" and "'+r+'" differ only by non-word symbols within a single dynamic path')}),t.push(r)}if(n){if(i){if(null!=this.restSlugName)throw Error('You cannot use both an required and optional catch-all route at the same level ("[...'+this.restSlugName+']" and "'+e[0]+'" ).');a(this.optionalRestSlugName,r),this.optionalRestSlugName=r,o="[[...]]"}else{if(null!=this.optionalRestSlugName)throw Error('You cannot use both an optional and required catch-all route at the same level ("[[...'+this.optionalRestSlugName+']]" and "'+e[0]+'").');a(this.restSlugName,r),this.restSlugName=r,o="[...]"}}else{if(i)throw Error('Optional route parameters are not yet supported ("'+e[0]+'").');a(this.slugName,r),this.slugName=r,o="[]"}}this.children.has(o)||this.children.set(o,new r),this.children.get(o)._insert(e.slice(1),t,n)}constructor(){this.placeholder=!0,this.children=new Map,this.slugName=null,this.restSlugName=null,this.optionalRestSlugName=null}}function n(e){let t=new r;return e.forEach(e=>t.insert(e)),t.smoosh()}},3537:(e,t)=>{"use strict";function r(e){return"("===e[0]&&e.endsWith(")")}Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{DEFAULT_SEGMENT_KEY:function(){return o},PAGE_SEGMENT_KEY:function(){return n},isGroupSegment:function(){return r}});let n="__PAGE__",o="__DEFAULT__"},5955:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{DecodeError:function(){return h},MiddlewareNotFoundError:function(){return v},MissingStaticPage:function(){return y},NormalizeError:function(){return g},PageNotFoundError:function(){return _},SP:function(){return f},ST:function(){return p},WEB_VITALS:function(){return r},execOnce:function(){return n},getDisplayName:function(){return u},getLocationOrigin:function(){return i},getURL:function(){return l},isAbsoluteUrl:function(){return a},isResSent:function(){return s},loadGetInitialProps:function(){return d},normalizeRepeatedSlashes:function(){return c},stringifyError:function(){return b}});let r=["CLS","FCP","FID","INP","LCP","TTFB"];function n(e){let t,r=!1;return function(){for(var n=arguments.length,o=Array(n),a=0;ao.test(e);function i(){let{protocol:e,hostname:t,port:r}=window.location;return e+"//"+t+(r?":"+r:"")}function l(){let{href:e}=window.location,t=i();return e.substring(t.length)}function u(e){return"string"==typeof e?e:e.displayName||e.name||"Unknown"}function s(e){return e.finished||e.headersSent}function c(e){let t=e.split("?");return t[0].replace(/\\/g,"/").replace(/\/\/+/g,"/")+(t[1]?"?"+t.slice(1).join("?"):"")}async function d(e,t){let r=t.res||t.ctx&&t.ctx.res;if(!e.getInitialProps)return t.ctx&&t.Component?{pageProps:await d(t.Component,t.ctx)}:{};let n=await e.getInitialProps(t);if(r&&s(r))return n;if(!n)throw Error('"'+u(e)+'.getInitialProps()" should resolve to an object. But found "'+n+'" instead.');return n}let f="undefined"!=typeof performance,p=f&&["mark","measure","getEntriesByName"].every(e=>"function"==typeof performance[e]);class h extends Error{}class g extends Error{}class _ extends Error{constructor(e){super(),this.code="ENOENT",this.name="PageNotFoundError",this.message="Cannot find module for page: "+e}}class y extends Error{constructor(e,t){super(),this.message="Failed to load static file for page: "+e+" "+t}}class v extends Error{constructor(){super(),this.code="ENOENT",this.message="Cannot find the middleware module"}}function b(e){return JSON.stringify({message:e.message,stack:e.stack})}},7500:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"warnOnce",{enumerable:!0,get:function(){return r}});let r=e=>{}},8765:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{bootstrap:function(){return l},error:function(){return s},event:function(){return p},info:function(){return f},prefixes:function(){return o},ready:function(){return d},trace:function(){return h},wait:function(){return u},warn:function(){return c},warnOnce:function(){return _}});let n=r(6164),o={wait:(0,n.white)((0,n.bold)("○")),error:(0,n.red)((0,n.bold)("⨯")),warn:(0,n.yellow)((0,n.bold)("⚠")),ready:"▲",info:(0,n.white)((0,n.bold)(" ")),event:(0,n.green)((0,n.bold)("✓")),trace:(0,n.magenta)((0,n.bold)("\xbb"))},a={log:"log",warn:"warn",error:"error"};function i(e,...t){(""===t[0]||void 0===t[0])&&1===t.length&&t.shift();let r=e in a?a[e]:"log",n=o[e];0===t.length?console[r](""):console[r](" "+n,...t)}function l(...e){console.log(" ",...e)}function u(...e){i("wait",...e)}function s(...e){i("error",...e)}function c(...e){i("warn",...e)}function d(...e){i("ready",...e)}function f(...e){i("info",...e)}function p(...e){i("event",...e)}function h(...e){i("trace",...e)}let g=new Set;function _(...e){g.has(e[0])||(g.add(e.join(" ")),c(...e))}},6691:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"createProxy",{enumerable:!0,get:function(){return n}});let n=r(8048).createClientModuleProxy},3750:(e,t,r)=>{"use strict";let{createProxy:n}=r(6691);e.exports=n("/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/app-router.js")},433:(e,t,r)=>{"use strict";let{createProxy:n}=r(6691);e.exports=n("/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/client-page.js")},7045:(e,t,r)=>{"use strict";let{createProxy:n}=r(6691);e.exports=n("/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/error-boundary.js")},3910:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{DynamicServerError:function(){return n},isDynamicServerError:function(){return o}});let r="DYNAMIC_SERVER_USAGE";class n extends Error{constructor(e){super("Dynamic server usage: "+e),this.description=e,this.digest=r}}function o(e){return"object"==typeof e&&null!==e&&"digest"in e&&"string"==typeof e.digest&&e.digest===r}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},5222:(e,t,r)=>{"use strict";let{createProxy:n}=r(6691);e.exports=n("/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/layout-router.js")},8731:(e,t,r)=>{"use strict";let{createProxy:n}=r(6691);e.exports=n("/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/not-found-boundary.js")},311:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return a}}),r(4400);let n=r(5886);r(7354);let o={error:{fontFamily:'system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"',height:"100vh",textAlign:"center",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},desc:{display:"inline-block"},h1:{display:"inline-block",margin:"0 20px 0 0",padding:"0 23px 0 0",fontSize:24,fontWeight:500,verticalAlign:"top",lineHeight:"49px"},h2:{fontSize:14,fontWeight:400,lineHeight:"49px",margin:0}};function a(){return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)("title",{children:"404: This page could not be found."}),(0,n.jsx)("div",{style:o.error,children:(0,n.jsxs)("div",{children:[(0,n.jsx)("style",{dangerouslySetInnerHTML:{__html:"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}),(0,n.jsx)("h1",{className:"next-error-h1",style:o.h1,children:"404"}),(0,n.jsx)("div",{style:o.desc,children:(0,n.jsx)("h2",{style:o.h2,children:"This page could not be found."})})]})})]})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},9357:(e,t,r)=>{"use strict";let{createProxy:n}=r(6691);e.exports=n("/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/node_modules/.pnpm/next@14.2.35_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/client/components/render-from-template-context.js")},6127:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{createDynamicallyTrackedSearchParams:function(){return l},createUntrackedSearchParams:function(){return i}});let n=r(5869),o=r(9293),a=r(3583);function i(e){let t=n.staticGenerationAsyncStorage.getStore();return t&&t.forceStatic?{}:e}function l(e){let t=n.staticGenerationAsyncStorage.getStore();return t?t.forceStatic?{}:t.isStaticGeneration||t.dynamicShouldError?new Proxy({},{get:(e,r,n)=>("string"==typeof r&&(0,o.trackDynamicDataAccessed)(t,"searchParams."+r),a.ReflectAdapter.get(e,r,n)),has:(e,r)=>("string"==typeof r&&(0,o.trackDynamicDataAccessed)(t,"searchParams."+r),Reflect.has(e,r)),ownKeys:e=>((0,o.trackDynamicDataAccessed)(t,"searchParams"),Reflect.ownKeys(e))}):e:e}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},5728:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{StaticGenBailoutError:function(){return n},isStaticGenBailoutError:function(){return o}});let r="NEXT_STATIC_GEN_BAILOUT";class n extends Error{constructor(...e){super(...e),this.code=r}}function o(e){return"object"==typeof e&&null!==e&&"code"in e&&e.code===r}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},1011:e=>{(()=>{"use strict";var t={491:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.ContextAPI=void 0;let n=r(223),o=r(172),a=r(930),i="context",l=new n.NoopContextManager;class u{constructor(){}static getInstance(){return this._instance||(this._instance=new u),this._instance}setGlobalContextManager(e){return(0,o.registerGlobal)(i,e,a.DiagAPI.instance())}active(){return this._getContextManager().active()}with(e,t,r,...n){return this._getContextManager().with(e,t,r,...n)}bind(e,t){return this._getContextManager().bind(e,t)}_getContextManager(){return(0,o.getGlobal)(i)||l}disable(){this._getContextManager().disable(),(0,o.unregisterGlobal)(i,a.DiagAPI.instance())}}t.ContextAPI=u},930:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.DiagAPI=void 0;let n=r(56),o=r(912),a=r(957),i=r(172);class l{constructor(){function e(e){return function(...t){let r=(0,i.getGlobal)("diag");if(r)return r[e](...t)}}let t=this;t.setLogger=(e,r={logLevel:a.DiagLogLevel.INFO})=>{var n,l,u;if(e===t){let e=Error("Cannot use diag as the logger for itself. Please use a DiagLogger implementation like ConsoleDiagLogger or a custom implementation");return t.error(null!==(n=e.stack)&&void 0!==n?n:e.message),!1}"number"==typeof r&&(r={logLevel:r});let s=(0,i.getGlobal)("diag"),c=(0,o.createLogLevelDiagLogger)(null!==(l=r.logLevel)&&void 0!==l?l:a.DiagLogLevel.INFO,e);if(s&&!r.suppressOverrideMessage){let e=null!==(u=Error().stack)&&void 0!==u?u:"";s.warn(`Current logger will be overwritten from ${e}`),c.warn(`Current logger will overwrite one already registered from ${e}`)}return(0,i.registerGlobal)("diag",c,t,!0)},t.disable=()=>{(0,i.unregisterGlobal)("diag",t)},t.createComponentLogger=e=>new n.DiagComponentLogger(e),t.verbose=e("verbose"),t.debug=e("debug"),t.info=e("info"),t.warn=e("warn"),t.error=e("error")}static instance(){return this._instance||(this._instance=new l),this._instance}}t.DiagAPI=l},653:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.MetricsAPI=void 0;let n=r(660),o=r(172),a=r(930),i="metrics";class l{constructor(){}static getInstance(){return this._instance||(this._instance=new l),this._instance}setGlobalMeterProvider(e){return(0,o.registerGlobal)(i,e,a.DiagAPI.instance())}getMeterProvider(){return(0,o.getGlobal)(i)||n.NOOP_METER_PROVIDER}getMeter(e,t,r){return this.getMeterProvider().getMeter(e,t,r)}disable(){(0,o.unregisterGlobal)(i,a.DiagAPI.instance())}}t.MetricsAPI=l},181:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.PropagationAPI=void 0;let n=r(172),o=r(874),a=r(194),i=r(277),l=r(369),u=r(930),s="propagation",c=new o.NoopTextMapPropagator;class d{constructor(){this.createBaggage=l.createBaggage,this.getBaggage=i.getBaggage,this.getActiveBaggage=i.getActiveBaggage,this.setBaggage=i.setBaggage,this.deleteBaggage=i.deleteBaggage}static getInstance(){return this._instance||(this._instance=new d),this._instance}setGlobalPropagator(e){return(0,n.registerGlobal)(s,e,u.DiagAPI.instance())}inject(e,t,r=a.defaultTextMapSetter){return this._getGlobalPropagator().inject(e,t,r)}extract(e,t,r=a.defaultTextMapGetter){return this._getGlobalPropagator().extract(e,t,r)}fields(){return this._getGlobalPropagator().fields()}disable(){(0,n.unregisterGlobal)(s,u.DiagAPI.instance())}_getGlobalPropagator(){return(0,n.getGlobal)(s)||c}}t.PropagationAPI=d},997:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.TraceAPI=void 0;let n=r(172),o=r(846),a=r(139),i=r(607),l=r(930),u="trace";class s{constructor(){this._proxyTracerProvider=new o.ProxyTracerProvider,this.wrapSpanContext=a.wrapSpanContext,this.isSpanContextValid=a.isSpanContextValid,this.deleteSpan=i.deleteSpan,this.getSpan=i.getSpan,this.getActiveSpan=i.getActiveSpan,this.getSpanContext=i.getSpanContext,this.setSpan=i.setSpan,this.setSpanContext=i.setSpanContext}static getInstance(){return this._instance||(this._instance=new s),this._instance}setGlobalTracerProvider(e){let t=(0,n.registerGlobal)(u,this._proxyTracerProvider,l.DiagAPI.instance());return t&&this._proxyTracerProvider.setDelegate(e),t}getTracerProvider(){return(0,n.getGlobal)(u)||this._proxyTracerProvider}getTracer(e,t){return this.getTracerProvider().getTracer(e,t)}disable(){(0,n.unregisterGlobal)(u,l.DiagAPI.instance()),this._proxyTracerProvider=new o.ProxyTracerProvider}}t.TraceAPI=s},277:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.deleteBaggage=t.setBaggage=t.getActiveBaggage=t.getBaggage=void 0;let n=r(491),o=(0,r(780).createContextKey)("OpenTelemetry Baggage Key");function a(e){return e.getValue(o)||void 0}t.getBaggage=a,t.getActiveBaggage=function(){return a(n.ContextAPI.getInstance().active())},t.setBaggage=function(e,t){return e.setValue(o,t)},t.deleteBaggage=function(e){return e.deleteValue(o)}},993:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.BaggageImpl=void 0;class r{constructor(e){this._entries=e?new Map(e):new Map}getEntry(e){let t=this._entries.get(e);if(t)return Object.assign({},t)}getAllEntries(){return Array.from(this._entries.entries()).map(([e,t])=>[e,t])}setEntry(e,t){let n=new r(this._entries);return n._entries.set(e,t),n}removeEntry(e){let t=new r(this._entries);return t._entries.delete(e),t}removeEntries(...e){let t=new r(this._entries);for(let r of e)t._entries.delete(r);return t}clear(){return new r}}t.BaggageImpl=r},830:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.baggageEntryMetadataSymbol=void 0,t.baggageEntryMetadataSymbol=Symbol("BaggageEntryMetadata")},369:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.baggageEntryMetadataFromString=t.createBaggage=void 0;let n=r(930),o=r(993),a=r(830),i=n.DiagAPI.instance();t.createBaggage=function(e={}){return new o.BaggageImpl(new Map(Object.entries(e)))},t.baggageEntryMetadataFromString=function(e){return"string"!=typeof e&&(i.error(`Cannot create baggage metadata from unknown type: ${typeof e}`),e=""),{__TYPE__:a.baggageEntryMetadataSymbol,toString:()=>e}}},67:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.context=void 0;let n=r(491);t.context=n.ContextAPI.getInstance()},223:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.NoopContextManager=void 0;let n=r(780);class o{active(){return n.ROOT_CONTEXT}with(e,t,r,...n){return t.call(r,...n)}bind(e,t){return t}enable(){return this}disable(){return this}}t.NoopContextManager=o},780:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.ROOT_CONTEXT=t.createContextKey=void 0,t.createContextKey=function(e){return Symbol.for(e)};class r{constructor(e){let t=this;t._currentContext=e?new Map(e):new Map,t.getValue=e=>t._currentContext.get(e),t.setValue=(e,n)=>{let o=new r(t._currentContext);return o._currentContext.set(e,n),o},t.deleteValue=e=>{let n=new r(t._currentContext);return n._currentContext.delete(e),n}}}t.ROOT_CONTEXT=new r},506:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.diag=void 0;let n=r(930);t.diag=n.DiagAPI.instance()},56:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.DiagComponentLogger=void 0;let n=r(172);class o{constructor(e){this._namespace=e.namespace||"DiagComponentLogger"}debug(...e){return a("debug",this._namespace,e)}error(...e){return a("error",this._namespace,e)}info(...e){return a("info",this._namespace,e)}warn(...e){return a("warn",this._namespace,e)}verbose(...e){return a("verbose",this._namespace,e)}}function a(e,t,r){let o=(0,n.getGlobal)("diag");if(o)return r.unshift(t),o[e](...r)}t.DiagComponentLogger=o},972:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.DiagConsoleLogger=void 0;let r=[{n:"error",c:"error"},{n:"warn",c:"warn"},{n:"info",c:"info"},{n:"debug",c:"debug"},{n:"verbose",c:"trace"}];class n{constructor(){for(let e=0;e{Object.defineProperty(t,"__esModule",{value:!0}),t.createLogLevelDiagLogger=void 0;let n=r(957);t.createLogLevelDiagLogger=function(e,t){function r(r,n){let o=t[r];return"function"==typeof o&&e>=n?o.bind(t):function(){}}return en.DiagLogLevel.ALL&&(e=n.DiagLogLevel.ALL),t=t||{},{error:r("error",n.DiagLogLevel.ERROR),warn:r("warn",n.DiagLogLevel.WARN),info:r("info",n.DiagLogLevel.INFO),debug:r("debug",n.DiagLogLevel.DEBUG),verbose:r("verbose",n.DiagLogLevel.VERBOSE)}}},957:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.DiagLogLevel=void 0,function(e){e[e.NONE=0]="NONE",e[e.ERROR=30]="ERROR",e[e.WARN=50]="WARN",e[e.INFO=60]="INFO",e[e.DEBUG=70]="DEBUG",e[e.VERBOSE=80]="VERBOSE",e[e.ALL=9999]="ALL"}(t.DiagLogLevel||(t.DiagLogLevel={}))},172:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.unregisterGlobal=t.getGlobal=t.registerGlobal=void 0;let n=r(200),o=r(521),a=r(130),i=o.VERSION.split(".")[0],l=Symbol.for(`opentelemetry.js.api.${i}`),u=n._globalThis;t.registerGlobal=function(e,t,r,n=!1){var a;let i=u[l]=null!==(a=u[l])&&void 0!==a?a:{version:o.VERSION};if(!n&&i[e]){let t=Error(`@opentelemetry/api: Attempted duplicate registration of API: ${e}`);return r.error(t.stack||t.message),!1}if(i.version!==o.VERSION){let t=Error(`@opentelemetry/api: Registration of version v${i.version} for ${e} does not match previously registered API v${o.VERSION}`);return r.error(t.stack||t.message),!1}return i[e]=t,r.debug(`@opentelemetry/api: Registered a global for ${e} v${o.VERSION}.`),!0},t.getGlobal=function(e){var t,r;let n=null===(t=u[l])||void 0===t?void 0:t.version;if(n&&(0,a.isCompatible)(n))return null===(r=u[l])||void 0===r?void 0:r[e]},t.unregisterGlobal=function(e,t){t.debug(`@opentelemetry/api: Unregistering a global for ${e} v${o.VERSION}.`);let r=u[l];r&&delete r[e]}},130:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.isCompatible=t._makeCompatibilityCheck=void 0;let n=r(521),o=/^(\d+)\.(\d+)\.(\d+)(-(.+))?$/;function a(e){let t=new Set([e]),r=new Set,n=e.match(o);if(!n)return()=>!1;let a={major:+n[1],minor:+n[2],patch:+n[3],prerelease:n[4]};if(null!=a.prerelease)return function(t){return t===e};function i(e){return r.add(e),!1}return function(e){if(t.has(e))return!0;if(r.has(e))return!1;let n=e.match(o);if(!n)return i(e);let l={major:+n[1],minor:+n[2],patch:+n[3],prerelease:n[4]};return null!=l.prerelease||a.major!==l.major?i(e):0===a.major?a.minor===l.minor&&a.patch<=l.patch?(t.add(e),!0):i(e):a.minor<=l.minor?(t.add(e),!0):i(e)}}t._makeCompatibilityCheck=a,t.isCompatible=a(n.VERSION)},886:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.metrics=void 0;let n=r(653);t.metrics=n.MetricsAPI.getInstance()},901:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.ValueType=void 0,function(e){e[e.INT=0]="INT",e[e.DOUBLE=1]="DOUBLE"}(t.ValueType||(t.ValueType={}))},102:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.createNoopMeter=t.NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC=t.NOOP_OBSERVABLE_GAUGE_METRIC=t.NOOP_OBSERVABLE_COUNTER_METRIC=t.NOOP_UP_DOWN_COUNTER_METRIC=t.NOOP_HISTOGRAM_METRIC=t.NOOP_COUNTER_METRIC=t.NOOP_METER=t.NoopObservableUpDownCounterMetric=t.NoopObservableGaugeMetric=t.NoopObservableCounterMetric=t.NoopObservableMetric=t.NoopHistogramMetric=t.NoopUpDownCounterMetric=t.NoopCounterMetric=t.NoopMetric=t.NoopMeter=void 0;class r{constructor(){}createHistogram(e,r){return t.NOOP_HISTOGRAM_METRIC}createCounter(e,r){return t.NOOP_COUNTER_METRIC}createUpDownCounter(e,r){return t.NOOP_UP_DOWN_COUNTER_METRIC}createObservableGauge(e,r){return t.NOOP_OBSERVABLE_GAUGE_METRIC}createObservableCounter(e,r){return t.NOOP_OBSERVABLE_COUNTER_METRIC}createObservableUpDownCounter(e,r){return t.NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC}addBatchObservableCallback(e,t){}removeBatchObservableCallback(e){}}t.NoopMeter=r;class n{}t.NoopMetric=n;class o extends n{add(e,t){}}t.NoopCounterMetric=o;class a extends n{add(e,t){}}t.NoopUpDownCounterMetric=a;class i extends n{record(e,t){}}t.NoopHistogramMetric=i;class l{addCallback(e){}removeCallback(e){}}t.NoopObservableMetric=l;class u extends l{}t.NoopObservableCounterMetric=u;class s extends l{}t.NoopObservableGaugeMetric=s;class c extends l{}t.NoopObservableUpDownCounterMetric=c,t.NOOP_METER=new r,t.NOOP_COUNTER_METRIC=new o,t.NOOP_HISTOGRAM_METRIC=new i,t.NOOP_UP_DOWN_COUNTER_METRIC=new a,t.NOOP_OBSERVABLE_COUNTER_METRIC=new u,t.NOOP_OBSERVABLE_GAUGE_METRIC=new s,t.NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC=new c,t.createNoopMeter=function(){return t.NOOP_METER}},660:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.NOOP_METER_PROVIDER=t.NoopMeterProvider=void 0;let n=r(102);class o{getMeter(e,t,r){return n.NOOP_METER}}t.NoopMeterProvider=o,t.NOOP_METER_PROVIDER=new o},200:function(e,t,r){var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r),Object.defineProperty(e,n,{enumerable:!0,get:function(){return t[r]}})}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),o=this&&this.__exportStar||function(e,t){for(var r in e)"default"===r||Object.prototype.hasOwnProperty.call(t,r)||n(t,e,r)};Object.defineProperty(t,"__esModule",{value:!0}),o(r(46),t)},651:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t._globalThis=void 0,t._globalThis="object"==typeof globalThis?globalThis:global},46:function(e,t,r){var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r),Object.defineProperty(e,n,{enumerable:!0,get:function(){return t[r]}})}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),o=this&&this.__exportStar||function(e,t){for(var r in e)"default"===r||Object.prototype.hasOwnProperty.call(t,r)||n(t,e,r)};Object.defineProperty(t,"__esModule",{value:!0}),o(r(651),t)},939:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.propagation=void 0;let n=r(181);t.propagation=n.PropagationAPI.getInstance()},874:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.NoopTextMapPropagator=void 0;class r{inject(e,t){}extract(e,t){return e}fields(){return[]}}t.NoopTextMapPropagator=r},194:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.defaultTextMapSetter=t.defaultTextMapGetter=void 0,t.defaultTextMapGetter={get(e,t){if(null!=e)return e[t]},keys:e=>null==e?[]:Object.keys(e)},t.defaultTextMapSetter={set(e,t,r){null!=e&&(e[t]=r)}}},845:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.trace=void 0;let n=r(997);t.trace=n.TraceAPI.getInstance()},403:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.NonRecordingSpan=void 0;let n=r(476);class o{constructor(e=n.INVALID_SPAN_CONTEXT){this._spanContext=e}spanContext(){return this._spanContext}setAttribute(e,t){return this}setAttributes(e){return this}addEvent(e,t){return this}setStatus(e){return this}updateName(e){return this}end(e){}isRecording(){return!1}recordException(e,t){}}t.NonRecordingSpan=o},614:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.NoopTracer=void 0;let n=r(491),o=r(607),a=r(403),i=r(139),l=n.ContextAPI.getInstance();class u{startSpan(e,t,r=l.active()){if(null==t?void 0:t.root)return new a.NonRecordingSpan;let n=r&&(0,o.getSpanContext)(r);return"object"==typeof n&&"string"==typeof n.spanId&&"string"==typeof n.traceId&&"number"==typeof n.traceFlags&&(0,i.isSpanContextValid)(n)?new a.NonRecordingSpan(n):new a.NonRecordingSpan}startActiveSpan(e,t,r,n){let a,i,u;if(arguments.length<2)return;2==arguments.length?u=t:3==arguments.length?(a=t,u=r):(a=t,i=r,u=n);let s=null!=i?i:l.active(),c=this.startSpan(e,a,s),d=(0,o.setSpan)(s,c);return l.with(d,u,void 0,c)}}t.NoopTracer=u},124:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.NoopTracerProvider=void 0;let n=r(614);class o{getTracer(e,t,r){return new n.NoopTracer}}t.NoopTracerProvider=o},125:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.ProxyTracer=void 0;let n=new(r(614)).NoopTracer;class o{constructor(e,t,r,n){this._provider=e,this.name=t,this.version=r,this.options=n}startSpan(e,t,r){return this._getTracer().startSpan(e,t,r)}startActiveSpan(e,t,r,n){let o=this._getTracer();return Reflect.apply(o.startActiveSpan,o,arguments)}_getTracer(){if(this._delegate)return this._delegate;let e=this._provider.getDelegateTracer(this.name,this.version,this.options);return e?(this._delegate=e,this._delegate):n}}t.ProxyTracer=o},846:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.ProxyTracerProvider=void 0;let n=r(125),o=new(r(124)).NoopTracerProvider;class a{getTracer(e,t,r){var o;return null!==(o=this.getDelegateTracer(e,t,r))&&void 0!==o?o:new n.ProxyTracer(this,e,t,r)}getDelegate(){var e;return null!==(e=this._delegate)&&void 0!==e?e:o}setDelegate(e){this._delegate=e}getDelegateTracer(e,t,r){var n;return null===(n=this._delegate)||void 0===n?void 0:n.getTracer(e,t,r)}}t.ProxyTracerProvider=a},996:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.SamplingDecision=void 0,function(e){e[e.NOT_RECORD=0]="NOT_RECORD",e[e.RECORD=1]="RECORD",e[e.RECORD_AND_SAMPLED=2]="RECORD_AND_SAMPLED"}(t.SamplingDecision||(t.SamplingDecision={}))},607:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.getSpanContext=t.setSpanContext=t.deleteSpan=t.setSpan=t.getActiveSpan=t.getSpan=void 0;let n=r(780),o=r(403),a=r(491),i=(0,n.createContextKey)("OpenTelemetry Context Key SPAN");function l(e){return e.getValue(i)||void 0}function u(e,t){return e.setValue(i,t)}t.getSpan=l,t.getActiveSpan=function(){return l(a.ContextAPI.getInstance().active())},t.setSpan=u,t.deleteSpan=function(e){return e.deleteValue(i)},t.setSpanContext=function(e,t){return u(e,new o.NonRecordingSpan(t))},t.getSpanContext=function(e){var t;return null===(t=l(e))||void 0===t?void 0:t.spanContext()}},325:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.TraceStateImpl=void 0;let n=r(564);class o{constructor(e){this._internalState=new Map,e&&this._parse(e)}set(e,t){let r=this._clone();return r._internalState.has(e)&&r._internalState.delete(e),r._internalState.set(e,t),r}unset(e){let t=this._clone();return t._internalState.delete(e),t}get(e){return this._internalState.get(e)}serialize(){return this._keys().reduce((e,t)=>(e.push(t+"="+this.get(t)),e),[]).join(",")}_parse(e){!(e.length>512)&&(this._internalState=e.split(",").reverse().reduce((e,t)=>{let r=t.trim(),o=r.indexOf("=");if(-1!==o){let a=r.slice(0,o),i=r.slice(o+1,t.length);(0,n.validateKey)(a)&&(0,n.validateValue)(i)&&e.set(a,i)}return e},new Map),this._internalState.size>32&&(this._internalState=new Map(Array.from(this._internalState.entries()).reverse().slice(0,32))))}_keys(){return Array.from(this._internalState.keys()).reverse()}_clone(){let e=new o;return e._internalState=new Map(this._internalState),e}}t.TraceStateImpl=o},564:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.validateValue=t.validateKey=void 0;let r="[_0-9a-z-*/]",n=`[a-z]${r}{0,255}`,o=`[a-z0-9]${r}{0,240}@[a-z]${r}{0,13}`,a=RegExp(`^(?:${n}|${o})$`),i=/^[ -~]{0,255}[!-~]$/,l=/,|=/;t.validateKey=function(e){return a.test(e)},t.validateValue=function(e){return i.test(e)&&!l.test(e)}},98:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.createTraceState=void 0;let n=r(325);t.createTraceState=function(e){return new n.TraceStateImpl(e)}},476:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.INVALID_SPAN_CONTEXT=t.INVALID_TRACEID=t.INVALID_SPANID=void 0;let n=r(475);t.INVALID_SPANID="0000000000000000",t.INVALID_TRACEID="00000000000000000000000000000000",t.INVALID_SPAN_CONTEXT={traceId:t.INVALID_TRACEID,spanId:t.INVALID_SPANID,traceFlags:n.TraceFlags.NONE}},357:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.SpanKind=void 0,function(e){e[e.INTERNAL=0]="INTERNAL",e[e.SERVER=1]="SERVER",e[e.CLIENT=2]="CLIENT",e[e.PRODUCER=3]="PRODUCER",e[e.CONSUMER=4]="CONSUMER"}(t.SpanKind||(t.SpanKind={}))},139:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.wrapSpanContext=t.isSpanContextValid=t.isValidSpanId=t.isValidTraceId=void 0;let n=r(476),o=r(403),a=/^([0-9a-f]{32})$/i,i=/^[0-9a-f]{16}$/i;function l(e){return a.test(e)&&e!==n.INVALID_TRACEID}function u(e){return i.test(e)&&e!==n.INVALID_SPANID}t.isValidTraceId=l,t.isValidSpanId=u,t.isSpanContextValid=function(e){return l(e.traceId)&&u(e.spanId)},t.wrapSpanContext=function(e){return new o.NonRecordingSpan(e)}},847:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.SpanStatusCode=void 0,function(e){e[e.UNSET=0]="UNSET",e[e.OK=1]="OK",e[e.ERROR=2]="ERROR"}(t.SpanStatusCode||(t.SpanStatusCode={}))},475:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.TraceFlags=void 0,function(e){e[e.NONE=0]="NONE",e[e.SAMPLED=1]="SAMPLED"}(t.TraceFlags||(t.TraceFlags={}))},521:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.VERSION=void 0,t.VERSION="1.6.0"}},r={};function n(e){var o=r[e];if(void 0!==o)return o.exports;var a=r[e]={exports:{}},i=!0;try{t[e].call(a.exports,a,a.exports,n),i=!1}finally{i&&delete r[e]}return a.exports}n.ab=__dirname+"/";var o={};(()=>{Object.defineProperty(o,"__esModule",{value:!0}),o.trace=o.propagation=o.metrics=o.diag=o.context=o.INVALID_SPAN_CONTEXT=o.INVALID_TRACEID=o.INVALID_SPANID=o.isValidSpanId=o.isValidTraceId=o.isSpanContextValid=o.createTraceState=o.TraceFlags=o.SpanStatusCode=o.SpanKind=o.SamplingDecision=o.ProxyTracerProvider=o.ProxyTracer=o.defaultTextMapSetter=o.defaultTextMapGetter=o.ValueType=o.createNoopMeter=o.DiagLogLevel=o.DiagConsoleLogger=o.ROOT_CONTEXT=o.createContextKey=o.baggageEntryMetadataFromString=void 0;var e=n(369);Object.defineProperty(o,"baggageEntryMetadataFromString",{enumerable:!0,get:function(){return e.baggageEntryMetadataFromString}});var t=n(780);Object.defineProperty(o,"createContextKey",{enumerable:!0,get:function(){return t.createContextKey}}),Object.defineProperty(o,"ROOT_CONTEXT",{enumerable:!0,get:function(){return t.ROOT_CONTEXT}});var r=n(972);Object.defineProperty(o,"DiagConsoleLogger",{enumerable:!0,get:function(){return r.DiagConsoleLogger}});var a=n(957);Object.defineProperty(o,"DiagLogLevel",{enumerable:!0,get:function(){return a.DiagLogLevel}});var i=n(102);Object.defineProperty(o,"createNoopMeter",{enumerable:!0,get:function(){return i.createNoopMeter}});var l=n(901);Object.defineProperty(o,"ValueType",{enumerable:!0,get:function(){return l.ValueType}});var u=n(194);Object.defineProperty(o,"defaultTextMapGetter",{enumerable:!0,get:function(){return u.defaultTextMapGetter}}),Object.defineProperty(o,"defaultTextMapSetter",{enumerable:!0,get:function(){return u.defaultTextMapSetter}});var s=n(125);Object.defineProperty(o,"ProxyTracer",{enumerable:!0,get:function(){return s.ProxyTracer}});var c=n(846);Object.defineProperty(o,"ProxyTracerProvider",{enumerable:!0,get:function(){return c.ProxyTracerProvider}});var d=n(996);Object.defineProperty(o,"SamplingDecision",{enumerable:!0,get:function(){return d.SamplingDecision}});var f=n(357);Object.defineProperty(o,"SpanKind",{enumerable:!0,get:function(){return f.SpanKind}});var p=n(847);Object.defineProperty(o,"SpanStatusCode",{enumerable:!0,get:function(){return p.SpanStatusCode}});var h=n(475);Object.defineProperty(o,"TraceFlags",{enumerable:!0,get:function(){return h.TraceFlags}});var g=n(98);Object.defineProperty(o,"createTraceState",{enumerable:!0,get:function(){return g.createTraceState}});var _=n(139);Object.defineProperty(o,"isSpanContextValid",{enumerable:!0,get:function(){return _.isSpanContextValid}}),Object.defineProperty(o,"isValidTraceId",{enumerable:!0,get:function(){return _.isValidTraceId}}),Object.defineProperty(o,"isValidSpanId",{enumerable:!0,get:function(){return _.isValidSpanId}});var y=n(476);Object.defineProperty(o,"INVALID_SPANID",{enumerable:!0,get:function(){return y.INVALID_SPANID}}),Object.defineProperty(o,"INVALID_TRACEID",{enumerable:!0,get:function(){return y.INVALID_TRACEID}}),Object.defineProperty(o,"INVALID_SPAN_CONTEXT",{enumerable:!0,get:function(){return y.INVALID_SPAN_CONTEXT}});let v=n(67);Object.defineProperty(o,"context",{enumerable:!0,get:function(){return v.context}});let b=n(506);Object.defineProperty(o,"diag",{enumerable:!0,get:function(){return b.diag}});let m=n(886);Object.defineProperty(o,"metrics",{enumerable:!0,get:function(){return m.metrics}});let R=n(939);Object.defineProperty(o,"propagation",{enumerable:!0,get:function(){return R.propagation}});let P=n(845);Object.defineProperty(o,"trace",{enumerable:!0,get:function(){return P.trace}}),o.default={context:v.context,diag:b.diag,metrics:m.metrics,propagation:R.propagation,trace:P.trace}})(),e.exports=o})()},775:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{ACTION_SUFFIX:function(){return u},APP_DIR_ALIAS:function(){return x},CACHE_ONE_YEAR:function(){return m},DOT_NEXT_ALIAS:function(){return O},ESLINT_DEFAULT_DIRS:function(){return $},GSP_NO_RETURNED_VALUE:function(){return F},GSSP_COMPONENT_MEMBER_ERROR:function(){return B},GSSP_NO_RETURNED_VALUE:function(){return H},INSTRUMENTATION_HOOK_FILENAME:function(){return S},MIDDLEWARE_FILENAME:function(){return R},MIDDLEWARE_LOCATION_REGEXP:function(){return P},NEXT_BODY_SUFFIX:function(){return d},NEXT_CACHE_IMPLICIT_TAG_ID:function(){return b},NEXT_CACHE_REVALIDATED_TAGS_HEADER:function(){return h},NEXT_CACHE_REVALIDATE_TAG_TOKEN_HEADER:function(){return g},NEXT_CACHE_SOFT_TAGS_HEADER:function(){return p},NEXT_CACHE_SOFT_TAG_MAX_LENGTH:function(){return v},NEXT_CACHE_TAGS_HEADER:function(){return f},NEXT_CACHE_TAG_MAX_ITEMS:function(){return _},NEXT_CACHE_TAG_MAX_LENGTH:function(){return y},NEXT_DATA_SUFFIX:function(){return s},NEXT_INTERCEPTION_MARKER_PREFIX:function(){return n},NEXT_META_SUFFIX:function(){return c},NEXT_QUERY_PARAM_PREFIX:function(){return r},NON_STANDARD_NODE_ENV:function(){return V},PAGES_DIR_ALIAS:function(){return E},PRERENDER_REVALIDATE_HEADER:function(){return o},PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER:function(){return a},PUBLIC_DIR_MIDDLEWARE_CONFLICT:function(){return w},ROOT_DIR_ALIAS:function(){return T},RSC_ACTION_CLIENT_WRAPPER_ALIAS:function(){return C},RSC_ACTION_ENCRYPTION_ALIAS:function(){return A},RSC_ACTION_PROXY_ALIAS:function(){return N},RSC_ACTION_VALIDATE_ALIAS:function(){return M},RSC_MOD_REF_PROXY_ALIAS:function(){return j},RSC_PREFETCH_SUFFIX:function(){return i},RSC_SUFFIX:function(){return l},SERVER_PROPS_EXPORT_ERROR:function(){return k},SERVER_PROPS_GET_INIT_PROPS_CONFLICT:function(){return D},SERVER_PROPS_SSG_CONFLICT:function(){return L},SERVER_RUNTIME:function(){return W},SSG_FALLBACK_EXPORT_ERROR:function(){return X},SSG_GET_INITIAL_PROPS_CONFLICT:function(){return I},STATIC_STATUS_PAGE_GET_INITIAL_PROPS_ERROR:function(){return U},UNSTABLE_REVALIDATE_RENAME_ERROR:function(){return G},WEBPACK_LAYERS:function(){return K},WEBPACK_RESOURCE_QUERIES:function(){return Y}});let r="nxtP",n="nxtI",o="x-prerender-revalidate",a="x-prerender-revalidate-if-generated",i=".prefetch.rsc",l=".rsc",u=".action",s=".json",c=".meta",d=".body",f="x-next-cache-tags",p="x-next-cache-soft-tags",h="x-next-revalidated-tags",g="x-next-revalidate-tag-token",_=128,y=256,v=1024,b="_N_T_",m=31536e3,R="middleware",P=`(?:src/)?${R}`,S="instrumentation",E="private-next-pages",O="private-dot-next",T="private-next-root-dir",x="private-next-app-dir",j="next/dist/build/webpack/loaders/next-flight-loader/module-proxy",M="private-next-rsc-action-validate",N="private-next-rsc-server-reference",A="private-next-rsc-action-encryption",C="private-next-rsc-action-client-wrapper",w="You can not have a '_next' folder inside of your public folder. This conflicts with the internal '/_next' route. https://nextjs.org/docs/messages/public-next-folder-conflict",I="You can not use getInitialProps with getStaticProps. To use SSG, please remove your getInitialProps",D="You can not use getInitialProps with getServerSideProps. Please remove getInitialProps.",L="You can not use getStaticProps or getStaticPaths with getServerSideProps. To use SSG, please remove getServerSideProps",U="can not have getInitialProps/getServerSideProps, https://nextjs.org/docs/messages/404-get-initial-props",k="pages with `getServerSideProps` can not be exported. See more info here: https://nextjs.org/docs/messages/gssp-export",F="Your `getStaticProps` function did not return an object. Did you forget to add a `return`?",H="Your `getServerSideProps` function did not return an object. Did you forget to add a `return`?",G="The `unstable_revalidate` property is available for general use.\nPlease use `revalidate` instead.",B="can not be attached to a page's component and must be exported from the page. See more info here: https://nextjs.org/docs/messages/gssp-component-member",V='You are using a non-standard "NODE_ENV" value in your environment. This creates inconsistencies in the project and is strongly advised against. Read more: https://nextjs.org/docs/messages/non-standard-node-env',X="Pages with `fallback` enabled in `getStaticPaths` can not be exported. See more info here: https://nextjs.org/docs/messages/ssg-fallback-true-export",$=["app","pages","components","lib","src"],W={edge:"edge",experimentalEdge:"experimental-edge",nodejs:"nodejs"},z={shared:"shared",reactServerComponents:"rsc",serverSideRendering:"ssr",actionBrowser:"action-browser",api:"api",middleware:"middleware",instrument:"instrument",edgeAsset:"edge-asset",appPagesBrowser:"app-pages-browser",appMetadataRoute:"app-metadata-route",appRouteHandler:"app-route-handler"},K={...z,GROUP:{serverOnly:[z.reactServerComponents,z.actionBrowser,z.appMetadataRoute,z.appRouteHandler,z.instrument],clientOnly:[z.serverSideRendering,z.appPagesBrowser],nonClientServerTarget:[z.middleware,z.api],app:[z.reactServerComponents,z.actionBrowser,z.appMetadataRoute,z.appRouteHandler,z.serverSideRendering,z.appPagesBrowser,z.shared,z.instrument]}},Y={edgeSSREntry:"__next_edge_ssr_entry__",metadata:"__next_metadata__",metadataRoute:"__next_metadata_route__",metadataImageMeta:"__next_metadata_image_meta__"}},6164:(e,t)=>{"use strict";var r;Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{bgBlack:function(){return T},bgBlue:function(){return N},bgCyan:function(){return C},bgGreen:function(){return j},bgMagenta:function(){return A},bgRed:function(){return x},bgWhite:function(){return w},bgYellow:function(){return M},black:function(){return _},blue:function(){return m},bold:function(){return s},cyan:function(){return S},dim:function(){return c},gray:function(){return O},green:function(){return v},hidden:function(){return h},inverse:function(){return p},italic:function(){return d},magenta:function(){return R},purple:function(){return P},red:function(){return y},reset:function(){return u},strikethrough:function(){return g},underline:function(){return f},white:function(){return E},yellow:function(){return b}});let{env:n,stdout:o}=(null==(r=globalThis)?void 0:r.process)??{},a=n&&!n.NO_COLOR&&(n.FORCE_COLOR||(null==o?void 0:o.isTTY)&&!n.CI&&"dumb"!==n.TERM),i=(e,t,r,n)=>{let o=e.substring(0,n)+r,a=e.substring(n+t.length),l=a.indexOf(t);return~l?o+i(a,t,r,l):o+a},l=(e,t,r=e)=>a?n=>{let o=""+n,a=o.indexOf(t,e.length);return~a?e+i(o,t,r,a)+t:e+o+t}:String,u=a?e=>`\x1b[0m${e}\x1b[0m`:String,s=l("\x1b[1m","\x1b[22m","\x1b[22m\x1b[1m"),c=l("\x1b[2m","\x1b[22m","\x1b[22m\x1b[2m"),d=l("\x1b[3m","\x1b[23m"),f=l("\x1b[4m","\x1b[24m"),p=l("\x1b[7m","\x1b[27m"),h=l("\x1b[8m","\x1b[28m"),g=l("\x1b[9m","\x1b[29m"),_=l("\x1b[30m","\x1b[39m"),y=l("\x1b[31m","\x1b[39m"),v=l("\x1b[32m","\x1b[39m"),b=l("\x1b[33m","\x1b[39m"),m=l("\x1b[34m","\x1b[39m"),R=l("\x1b[35m","\x1b[39m"),P=l("\x1b[38;2;173;127;168m","\x1b[39m"),S=l("\x1b[36m","\x1b[39m"),E=l("\x1b[37m","\x1b[39m"),O=l("\x1b[90m","\x1b[39m"),T=l("\x1b[40m","\x1b[49m"),x=l("\x1b[41m","\x1b[49m"),j=l("\x1b[42m","\x1b[49m"),M=l("\x1b[43m","\x1b[49m"),N=l("\x1b[44m","\x1b[49m"),A=l("\x1b[45m","\x1b[49m"),C=l("\x1b[46m","\x1b[49m"),w=l("\x1b[47m","\x1b[49m")},3588:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{getPathname:function(){return n},isFullStringUrl:function(){return o},parseUrl:function(){return a}});let r="http://n";function n(e){return new URL(e,r).pathname}function o(e){return/https?:\/\//.test(e)}function a(e){let t;try{t=new URL(e,r)}catch{}return t}},9293:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{Postpone:function(){return d},createPostponedAbortSignal:function(){return y},createPrerenderState:function(){return u},formatDynamicAPIAccesses:function(){return g},markCurrentScopeAsDynamic:function(){return s},trackDynamicDataAccessed:function(){return c},trackDynamicFetch:function(){return f},usedDynamicAPIs:function(){return h}});let n=function(e){return e&&e.__esModule?e:{default:e}}(r(7354)),o=r(3910),a=r(5728),i=r(3588),l="function"==typeof n.default.unstable_postpone;function u(e){return{isDebugSkeleton:e,dynamicAccesses:[]}}function s(e,t){let r=(0,i.getPathname)(e.urlPathname);if(!e.isUnstableCacheCallback){if(e.dynamicShouldError)throw new a.StaticGenBailoutError(`Route ${r} with \`dynamic = "error"\` couldn't be rendered statically because it used \`${t}\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering`);if(e.prerenderState)p(e.prerenderState,t,r);else if(e.revalidate=0,e.isStaticGeneration){let n=new o.DynamicServerError(`Route ${r} couldn't be rendered statically because it used ${t}. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`);throw e.dynamicUsageDescription=t,e.dynamicUsageStack=n.stack,n}}}function c(e,t){let r=(0,i.getPathname)(e.urlPathname);if(e.isUnstableCacheCallback)throw Error(`Route ${r} used "${t}" inside a function cached with "unstable_cache(...)". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use "${t}" outside of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/app/api-reference/functions/unstable_cache`);if(e.dynamicShouldError)throw new a.StaticGenBailoutError(`Route ${r} with \`dynamic = "error"\` couldn't be rendered statically because it used \`${t}\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering`);if(e.prerenderState)p(e.prerenderState,t,r);else if(e.revalidate=0,e.isStaticGeneration){let n=new o.DynamicServerError(`Route ${r} couldn't be rendered statically because it used \`${t}\`. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`);throw e.dynamicUsageDescription=t,e.dynamicUsageStack=n.stack,n}}function d({reason:e,prerenderState:t,pathname:r}){p(t,e,r)}function f(e,t){e.prerenderState&&p(e.prerenderState,t,e.urlPathname)}function p(e,t,r){_();let o=`Route ${r} needs to bail out of prerendering at this point because it used ${t}. React throws this special object to indicate where. It should not be caught by your own try/catch. Learn more: https://nextjs.org/docs/messages/ppr-caught-error`;e.dynamicAccesses.push({stack:e.isDebugSkeleton?Error().stack:void 0,expression:t}),n.default.unstable_postpone(o)}function h(e){return e.dynamicAccesses.length>0}function g(e){return e.dynamicAccesses.filter(e=>"string"==typeof e.stack&&e.stack.length>0).map(({expression:e,stack:t})=>(t=t.split("\n").slice(4).filter(e=>!(e.includes("node_modules/next/")||e.includes(" ()")||e.includes(" (node:"))).join("\n"),`Dynamic API Usage Debug - ${e}:
+${t}`))}function _(){if(!l)throw Error("Invariant: React.unstable_postpone is not defined. This suggests the wrong version of React was loaded. This is a bug in Next.js")}function y(e){_();let t=new AbortController;try{n.default.unstable_postpone(e)}catch(e){t.abort(e)}return t.signal}},8184:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{AppRouter:function(){return o.default},ClientPageRoot:function(){return c.ClientPageRoot},LayoutRouter:function(){return a.default},NotFoundBoundary:function(){return p.NotFoundBoundary},Postpone:function(){return _.Postpone},RenderFromTemplateContext:function(){return i.default},actionAsyncStorage:function(){return s.actionAsyncStorage},createDynamicallyTrackedSearchParams:function(){return d.createDynamicallyTrackedSearchParams},createUntrackedSearchParams:function(){return d.createUntrackedSearchParams},decodeAction:function(){return n.decodeAction},decodeFormState:function(){return n.decodeFormState},decodeReply:function(){return n.decodeReply},patchFetch:function(){return m},preconnect:function(){return g.preconnect},preloadFont:function(){return g.preloadFont},preloadStyle:function(){return g.preloadStyle},renderToReadableStream:function(){return n.renderToReadableStream},requestAsyncStorage:function(){return u.requestAsyncStorage},serverHooks:function(){return f},staticGenerationAsyncStorage:function(){return l.staticGenerationAsyncStorage},taintObjectReference:function(){return y.taintObjectReference}});let n=r(8048),o=v(r(3750)),a=v(r(5222)),i=v(r(9357)),l=r(5869),u=r(4580),s=r(2934),c=r(433),d=r(6127),f=function(e,t){if(e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var r=b(void 0);if(r&&r.has(e))return r.get(e);var n={__proto__:null},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&Object.prototype.hasOwnProperty.call(e,a)){var i=o?Object.getOwnPropertyDescriptor(e,a):null;i&&(i.get||i.set)?Object.defineProperty(n,a,i):n[a]=e[a]}return n.default=e,r&&r.set(e,n),n}(r(3910)),p=r(8731),h=r(5980);r(7045);let g=r(7256),_=r(663),y=r(973);function v(e){return e&&e.__esModule?e:{default:e}}function b(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,r=new WeakMap;return(b=function(e){return e?r:t})(e)}function m(){return(0,h.patchFetch)({serverHooks:f,staticGenerationAsyncStorage:l.staticGenerationAsyncStorage})}},663:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"Postpone",{enumerable:!0,get:function(){return n.Postpone}});let n=r(9293)},7256:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{preconnect:function(){return i},preloadFont:function(){return a},preloadStyle:function(){return o}});let n=function(e){return e&&e.__esModule?e:{default:e}}(r(8927));function o(e,t){let r={as:"style"};"string"==typeof t&&(r.crossOrigin=t),n.default.preload(e,r)}function a(e,t,r){let o={as:"font",type:t};"string"==typeof r&&(o.crossOrigin=r),n.default.preload(e,o)}function i(e,t){n.default.preconnect(e,"string"==typeof t?{crossOrigin:t}:void 0)}},973:(e,t,r)=>{"use strict";function n(){throw Error("Taint can only be used with the taint flag.")}Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{taintObjectReference:function(){return o},taintUniqueValue:function(){return a}}),r(7354);let o=n,a=n},1650:(e,t)=>{"use strict";var r;Object.defineProperty(t,"x",{enumerable:!0,get:function(){return r}}),function(e){e.PAGES="PAGES",e.PAGES_API="PAGES_API",e.APP_PAGE="APP_PAGE",e.APP_ROUTE="APP_ROUTE"}(r||(r={}))},9296:(e,t,r)=>{"use strict";e.exports=r(399)},8927:(e,t,r)=>{"use strict";e.exports=r(9296).vendored["react-rsc"].ReactDOM},5886:(e,t,r)=>{"use strict";e.exports=r(9296).vendored["react-rsc"].ReactJsxRuntime},8048:(e,t,r)=>{"use strict";e.exports=r(9296).vendored["react-rsc"].ReactServerDOMWebpackServerEdge},7354:(e,t,r)=>{"use strict";e.exports=r(9296).vendored["react-rsc"].React},859:(e,t)=>{"use strict";function r(e){if(!e.body)return[e,e];let[t,r]=e.body.tee(),n=new Response(t,{status:e.status,statusText:e.statusText,headers:e.headers});Object.defineProperty(n,"url",{value:e.url});let o=new Response(r,{status:e.status,statusText:e.statusText,headers:e.headers});return Object.defineProperty(o,"url",{value:e.url}),[n,o]}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"cloneResponse",{enumerable:!0,get:function(){return r}})},5496:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"createDedupeFetch",{enumerable:!0,get:function(){return i}});let n=function(e,t){if(e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var r=a(void 0);if(r&&r.has(e))return r.get(e);var n={__proto__:null},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if("default"!==i&&Object.prototype.hasOwnProperty.call(e,i)){var l=o?Object.getOwnPropertyDescriptor(e,i):null;l&&(l.get||l.set)?Object.defineProperty(n,i,l):n[i]=e[i]}return n.default=e,r&&r.set(e,n),n}(r(7354)),o=r(859);function a(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,r=new WeakMap;return(a=function(e){return e?r:t})(e)}function i(e){let t=n.cache(e=>[]);return function(r,n){let a,i;if(n&&n.signal)return e(r,n);if("string"!=typeof r||n){let t="string"==typeof r||r instanceof URL?new Request(r,n):r;if("GET"!==t.method&&"HEAD"!==t.method||t.keepalive)return e(r,n);i=JSON.stringify([t.method,Array.from(t.headers.entries()),t.mode,t.redirect,t.credentials,t.referrer,t.referrerPolicy,t.integrity]),a=t.url}else i='["GET",[],null,"follow",null,null,null,null]',a=r;let l=t(a);for(let e=0,t=l.length;e{let t=l[e][2];if(!t)throw Error("No cached response");let[r,n]=(0,o.cloneResponse)(t);return l[e][2]=n,r})}let u=new AbortController,s=e(r,{...n,signal:u.signal}),c=[i,s,null];return l.push(c),s.then(e=>{let[t,r]=(0,o.cloneResponse)(e);return c[2]=r,t})}}},5980:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{addImplicitTags:function(){return h},patchFetch:function(){return _},validateRevalidate:function(){return d},validateTags:function(){return f}});let n=r(1223),o=r(7980),a=r(775),i=function(e,t){if(e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var r=c(void 0);if(r&&r.has(e))return r.get(e);var n={__proto__:null},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&Object.prototype.hasOwnProperty.call(e,a)){var i=o?Object.getOwnPropertyDescriptor(e,a):null;i&&(i.get||i.set)?Object.defineProperty(n,a,i):n[a]=e[a]}return n.default=e,r&&r.set(e,n),n}(r(8765)),l=r(9293),u=r(5496),s=r(859);function c(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,r=new WeakMap;return(c=function(e){return e?r:t})(e)}function d(e,t){try{let r;if(!1===e)r=e;else if("number"==typeof e&&!isNaN(e)&&e>-1)r=e;else if(void 0!==e)throw Error(`Invalid revalidate value "${e}" on "${t}", must be a non-negative number or "false"`);return r}catch(e){if(e instanceof Error&&e.message.includes("Invalid revalidate"))throw e;return}}function f(e,t){let r=[],n=[];for(let o=0;oa.NEXT_CACHE_TAG_MAX_LENGTH?n.push({tag:i,reason:`exceeded max length of ${a.NEXT_CACHE_TAG_MAX_LENGTH}`}):r.push(i),r.length>a.NEXT_CACHE_TAG_MAX_ITEMS){console.warn(`Warning: exceeded max tag count for ${t}, dropped tags:`,e.slice(o).join(", "));break}}if(n.length>0)for(let{tag:e,reason:r}of(console.warn(`Warning: invalid tags passed to ${t}: `),n))console.log(`tag: "${e}" ${r}`);return r}let p=e=>{let t=["/layout"];if(e.startsWith("/")){let r=e.split("/");for(let e=1;e{var p,_;let y;try{(y=new URL(u instanceof Request?u.url:u)).username="",y.password=""}catch{y=void 0}let v=(null==y?void 0:y.href)??"",b=Date.now(),m=(null==c?void 0:null==(p=c.method)?void 0:p.toUpperCase())||"GET",R=(null==c?void 0:null==(_=c.next)?void 0:_.internal)===!0,P="1"===process.env.NEXT_OTEL_FETCH_DISABLED;return(0,o.getTracer)().trace(R?n.NextNodeServerSpan.internalFetch:n.AppRenderSpan.fetch,{hideSpan:P,kind:o.SpanKind.CLIENT,spanName:["fetch",m,v].filter(Boolean).join(" "),attributes:{"http.url":v,"http.method":m,"net.peer.name":null==y?void 0:y.hostname,"net.peer.port":(null==y?void 0:y.port)||void 0}},async()=>{var n;let o,p,_;if(R)return e(u,c);let y=r.getStore();if(!y||y.isDraftMode)return e(u,c);let m=u&&"object"==typeof u&&"string"==typeof u.method,P=e=>(null==c?void 0:c[e])||(m?u[e]:null),S=e=>{var t,r,n;return void 0!==(null==c?void 0:null==(t=c.next)?void 0:t[e])?null==c?void 0:null==(r=c.next)?void 0:r[e]:m?null==(n=u.next)?void 0:n[e]:void 0},E=S("revalidate"),O=f(S("tags")||[],`fetch ${u.toString()}`);if(Array.isArray(O))for(let e of(y.tags||(y.tags=[]),O))y.tags.includes(e)||y.tags.push(e);let T=h(y),x=y.fetchCache,j=!!y.isUnstableNoStore,M=P("cache"),N="";"string"==typeof M&&void 0!==E&&(m&&"default"===M||i.warn(`fetch for ${v} on ${y.urlPathname} specified "cache: ${M}" and "revalidate: ${E}", only one should be specified.`),M=void 0),"force-cache"===M?E=!1:("no-cache"===M||"no-store"===M||"force-no-store"===x||"only-no-store"===x)&&(E=0),("no-cache"===M||"no-store"===M)&&(N=`cache: ${M}`),_=d(E,y.urlPathname);let A=P("headers"),C="function"==typeof(null==A?void 0:A.get)?A:new Headers(A||{}),w=C.get("authorization")||C.get("cookie"),I=!["get","head"].includes((null==(n=P("method"))?void 0:n.toLowerCase())||"get"),D=(w||I)&&0===y.revalidate;switch(x){case"force-no-store":N="fetchCache = force-no-store";break;case"only-no-store":if("force-cache"===M||void 0!==_&&(!1===_||_>0))throw Error(`cache: 'force-cache' used on fetch for ${v} with 'export const fetchCache = 'only-no-store'`);N="fetchCache = only-no-store";break;case"only-cache":if("no-store"===M)throw Error(`cache: 'no-store' used on fetch for ${v} with 'export const fetchCache = 'only-cache'`);break;case"force-cache":(void 0===E||0===E)&&(N="fetchCache = force-cache",_=!1)}void 0===_?"default-cache"===x?(_=!1,N="fetchCache = default-cache"):D?(_=0,N="auto no cache"):"default-no-store"===x?(_=0,N="fetchCache = default-no-store"):j?(_=0,N="noStore call"):(N="auto cache",_="boolean"!=typeof y.revalidate&&void 0!==y.revalidate&&y.revalidate):N||(N=`revalidate: ${_}`),y.forceStatic&&0===_||D||void 0!==y.revalidate&&("number"!=typeof _||!1!==y.revalidate&&("number"!=typeof y.revalidate||!(_0||!1===_;if(y.incrementalCache&&L)try{o=await y.incrementalCache.fetchCacheKey(v,m?u:c)}catch(e){console.error("Failed to generate cache key for",u)}let U=y.nextFetchId??1;y.nextFetchId=U+1;let k="number"!=typeof _?a.CACHE_ONE_YEAR:_,F=async(t,r)=>{let n=["cache","credentials","headers","integrity","keepalive","method","mode","redirect","referrer","referrerPolicy","window","duplex",...t?[]:["signal"]];if(m){let e=u,t={body:e._ogBody||e.body};for(let r of n)t[r]=e[r];u=new Request(e.url,t)}else if(c){let{_ogBody:e,body:r,signal:n,...o}=c;c={...o,body:e||r,signal:t?void 0:n}}let a={...c,next:{...null==c?void 0:c.next,fetchType:"origin",fetchIdx:U}};return e(u,a).then(async e=>{if(t||g(y,{start:b,url:v,cacheReason:r||N,cacheStatus:0===_||r?"skip":"miss",status:e.status,method:a.method||"GET"}),200===e.status&&y.incrementalCache&&o&&L){let t=Buffer.from(await e.arrayBuffer());try{await y.incrementalCache.set(o,{kind:"FETCH",data:{headers:Object.fromEntries(e.headers.entries()),body:t.toString("base64"),status:e.status,url:e.url},revalidate:k},{fetchCache:!0,revalidate:_,fetchUrl:v,fetchIdx:U,tags:O})}catch(e){console.warn("Failed to set fetch cache",u,e)}let r=new Response(t,{headers:new Headers(e.headers),status:e.status});return Object.defineProperty(r,"url",{value:e.url}),r}return e})},H=()=>Promise.resolve(),G=!1;if(o&&y.incrementalCache){H=await y.incrementalCache.lock(o);let e=y.isOnDemandRevalidate?null:await y.incrementalCache.get(o,{kindHint:"fetch",revalidate:_,fetchUrl:v,fetchIdx:U,tags:O,softTags:T});if(e?await H():p="cache-control: no-cache (hard refresh)",(null==e?void 0:e.value)&&"FETCH"===e.value.kind){if(y.isRevalidate&&e.isStale)G=!0;else{if(e.isStale&&(y.pendingRevalidates??={},!y.pendingRevalidates[o])){let e=F(!0).then(async e=>({body:await e.arrayBuffer(),headers:e.headers,status:e.status,statusText:e.statusText})).finally(()=>{y.pendingRevalidates??={},delete y.pendingRevalidates[o||""]});e.catch(console.error),y.pendingRevalidates[o]=e}let t=e.value.data;g(y,{start:b,url:v,cacheReason:N,cacheStatus:"hit",status:t.status||200,method:(null==c?void 0:c.method)||"GET"});let r=new Response(Buffer.from(t.body,"base64"),{headers:t.headers,status:t.status});return Object.defineProperty(r,"url",{value:e.value.data.url}),r}}}if(y.isStaticGeneration&&c&&"object"==typeof c){let{cache:e}=c;if(!y.forceStatic&&"no-store"===e){let e=`no-store fetch ${u}${y.urlPathname?` ${y.urlPathname}`:""}`;(0,l.trackDynamicFetch)(y,e),y.revalidate=0;let r=new t(e);throw y.dynamicUsageErr=r,y.dynamicUsageDescription=e,r}let r="next"in c,{next:n={}}=c;if("number"==typeof n.revalidate&&(void 0===y.revalidate||"number"==typeof y.revalidate&&n.revalidate{let t=e[0];return{body:await t.arrayBuffer(),headers:t.headers,status:t.status,statusText:t.statusText}}).finally(()=>{if(o){var e;(null==(e=y.pendingRevalidates)?void 0:e[o])&&delete y.pendingRevalidates[o]}})).catch(()=>{}),y.pendingRevalidates[o]=e,t.then(e=>e[1])}})};return u.__nextPatched=!0,u.__nextGetStaticStore=()=>r,u._nextOriginalFetch=e,u}(r,e)}},1223:(e,t)=>{"use strict";var r,n,o,a,i,l,u,s,c,d,f,p;Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{AppRenderSpan:function(){return u},AppRouteRouteHandlersSpan:function(){return d},BaseServerSpan:function(){return r},LoadComponentsSpan:function(){return n},LogSpanAllowList:function(){return g},MiddlewareSpan:function(){return p},NextNodeServerSpan:function(){return a},NextServerSpan:function(){return o},NextVanillaSpanAllowlist:function(){return h},NodeSpan:function(){return c},RenderSpan:function(){return l},ResolveMetadataSpan:function(){return f},RouterSpan:function(){return s},StartServerSpan:function(){return i}}),function(e){e.handleRequest="BaseServer.handleRequest",e.run="BaseServer.run",e.pipe="BaseServer.pipe",e.getStaticHTML="BaseServer.getStaticHTML",e.render="BaseServer.render",e.renderToResponseWithComponents="BaseServer.renderToResponseWithComponents",e.renderToResponse="BaseServer.renderToResponse",e.renderToHTML="BaseServer.renderToHTML",e.renderError="BaseServer.renderError",e.renderErrorToResponse="BaseServer.renderErrorToResponse",e.renderErrorToHTML="BaseServer.renderErrorToHTML",e.render404="BaseServer.render404"}(r||(r={})),function(e){e.loadDefaultErrorComponents="LoadComponents.loadDefaultErrorComponents",e.loadComponents="LoadComponents.loadComponents"}(n||(n={})),function(e){e.getRequestHandler="NextServer.getRequestHandler",e.getServer="NextServer.getServer",e.getServerRequestHandler="NextServer.getServerRequestHandler",e.createServer="createServer.createServer"}(o||(o={})),function(e){e.compression="NextNodeServer.compression",e.getBuildId="NextNodeServer.getBuildId",e.createComponentTree="NextNodeServer.createComponentTree",e.clientComponentLoading="NextNodeServer.clientComponentLoading",e.getLayoutOrPageModule="NextNodeServer.getLayoutOrPageModule",e.generateStaticRoutes="NextNodeServer.generateStaticRoutes",e.generateFsStaticRoutes="NextNodeServer.generateFsStaticRoutes",e.generatePublicRoutes="NextNodeServer.generatePublicRoutes",e.generateImageRoutes="NextNodeServer.generateImageRoutes.route",e.sendRenderResult="NextNodeServer.sendRenderResult",e.proxyRequest="NextNodeServer.proxyRequest",e.runApi="NextNodeServer.runApi",e.render="NextNodeServer.render",e.renderHTML="NextNodeServer.renderHTML",e.imageOptimizer="NextNodeServer.imageOptimizer",e.getPagePath="NextNodeServer.getPagePath",e.getRoutesManifest="NextNodeServer.getRoutesManifest",e.findPageComponents="NextNodeServer.findPageComponents",e.getFontManifest="NextNodeServer.getFontManifest",e.getServerComponentManifest="NextNodeServer.getServerComponentManifest",e.getRequestHandler="NextNodeServer.getRequestHandler",e.renderToHTML="NextNodeServer.renderToHTML",e.renderError="NextNodeServer.renderError",e.renderErrorToHTML="NextNodeServer.renderErrorToHTML",e.render404="NextNodeServer.render404",e.startResponse="NextNodeServer.startResponse",e.route="route",e.onProxyReq="onProxyReq",e.apiResolver="apiResolver",e.internalFetch="internalFetch"}(a||(a={})),(i||(i={})).startServer="startServer.startServer",function(e){e.getServerSideProps="Render.getServerSideProps",e.getStaticProps="Render.getStaticProps",e.renderToString="Render.renderToString",e.renderDocument="Render.renderDocument",e.createBodyResult="Render.createBodyResult"}(l||(l={})),function(e){e.renderToString="AppRender.renderToString",e.renderToReadableStream="AppRender.renderToReadableStream",e.getBodyResult="AppRender.getBodyResult",e.fetch="AppRender.fetch"}(u||(u={})),(s||(s={})).executeRoute="Router.executeRoute",(c||(c={})).runHandler="Node.runHandler",(d||(d={})).runHandler="AppRouteRouteHandlers.runHandler",function(e){e.generateMetadata="ResolveMetadata.generateMetadata",e.generateViewport="ResolveMetadata.generateViewport"}(f||(f={})),(p||(p={})).execute="Middleware.execute";let h=["Middleware.execute","BaseServer.handleRequest","Render.getServerSideProps","Render.getStaticProps","AppRender.fetch","AppRender.getBodyResult","Render.renderDocument","Node.runHandler","AppRouteRouteHandlers.runHandler","ResolveMetadata.generateMetadata","ResolveMetadata.generateViewport","NextNodeServer.createComponentTree","NextNodeServer.findPageComponents","NextNodeServer.getLayoutOrPageModule","NextNodeServer.startResponse","NextNodeServer.clientComponentLoading"],g=["NextNodeServer.findPageComponents","NextNodeServer.createComponentTree","NextNodeServer.clientComponentLoading"]},7980:(e,t,r)=>{"use strict";let n;Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{SpanKind:function(){return s},SpanStatusCode:function(){return u},getTracer:function(){return v}});let o=r(1223);try{n=r(1011)}catch(e){n=r(1011)}let{context:a,propagation:i,trace:l,SpanStatusCode:u,SpanKind:s,ROOT_CONTEXT:c}=n,d=e=>null!==e&&"object"==typeof e&&"function"==typeof e.then,f=(e,t)=>{(null==t?void 0:t.bubble)===!0?e.setAttribute("next.bubble",!0):(t&&e.recordException(t),e.setStatus({code:u.ERROR,message:null==t?void 0:t.message})),e.end()},p=new Map,h=n.createContextKey("next.rootSpanId"),g=0,_=()=>g++;class y{getTracerInstance(){return l.getTracer("next.js","0.0.1")}getContext(){return a}getActiveScopeSpan(){return l.getSpan(null==a?void 0:a.active())}withPropagatedContext(e,t,r){let n=a.active();if(l.getSpanContext(n))return t();let o=i.extract(n,e,r);return a.with(o,t)}trace(...e){var t;let[r,n,i]=e,{fn:u,options:s}="function"==typeof n?{fn:n,options:{}}:{fn:i,options:{...n}},g=s.spanName??r;if(!o.NextVanillaSpanAllowlist.includes(r)&&"1"!==process.env.NEXT_OTEL_VERBOSE||s.hideSpan)return u();let y=this.getSpanContext((null==s?void 0:s.parentSpan)??this.getActiveScopeSpan()),v=!1;y?(null==(t=l.getSpanContext(y))?void 0:t.isRemote)&&(v=!0):(y=(null==a?void 0:a.active())??c,v=!0);let b=_();return s.attributes={"next.span_name":g,"next.span_type":r,...s.attributes},a.with(y.setValue(h,b),()=>this.getTracerInstance().startActiveSpan(g,s,e=>{let t="performance"in globalThis?globalThis.performance.now():void 0,n=()=>{p.delete(b),t&&process.env.NEXT_OTEL_PERFORMANCE_PREFIX&&o.LogSpanAllowList.includes(r||"")&&performance.measure(`${process.env.NEXT_OTEL_PERFORMANCE_PREFIX}:next-${(r.split(".").pop()||"").replace(/[A-Z]/g,e=>"-"+e.toLowerCase())}`,{start:t,end:performance.now()})};v&&p.set(b,new Map(Object.entries(s.attributes??{})));try{if(u.length>1)return u(e,t=>f(e,t));let t=u(e);if(d(t))return t.then(t=>(e.end(),t)).catch(t=>{throw f(e,t),t}).finally(n);return e.end(),n(),t}catch(t){throw f(e,t),n(),t}}))}wrap(...e){let t=this,[r,n,i]=3===e.length?e:[e[0],{},e[1]];return o.NextVanillaSpanAllowlist.includes(r)||"1"===process.env.NEXT_OTEL_VERBOSE?function(){let e=n;"function"==typeof e&&"function"==typeof i&&(e=e.apply(this,arguments));let o=arguments.length-1,l=arguments[o];if("function"!=typeof l)return t.trace(r,e,()=>i.apply(this,arguments));{let n=t.getContext().bind(a.active(),l);return t.trace(r,e,(e,t)=>(arguments[o]=function(e){return null==t||t(e),n.apply(this,arguments)},i.apply(this,arguments)))}}:i}startSpan(...e){let[t,r]=e,n=this.getSpanContext((null==r?void 0:r.parentSpan)??this.getActiveScopeSpan());return this.getTracerInstance().startSpan(t,r,n)}getSpanContext(e){return e?l.setSpan(a.active(),e):void 0}getRootSpanAttributes(){let e=a.active().getValue(h);return p.get(e)}}let v=(()=>{let e=new y;return()=>e})()},3583:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"ReflectAdapter",{enumerable:!0,get:function(){return r}});class r{static get(e,t,r){let n=Reflect.get(e,t,r);return"function"==typeof n?n.bind(e):n}static set(e,t,r,n){return Reflect.set(e,t,r,n)}static has(e,t){return Reflect.has(e,t)}static deleteProperty(e,t){return Reflect.deleteProperty(e,t)}}},7919:(e,t,r)=>{"use strict";function n(e,t){if(!Object.prototype.hasOwnProperty.call(e,t))throw TypeError("attempted to use private field on non-instance");return e}r.r(t),r.d(t,{_:()=>n,_class_private_field_loose_base:()=>n})},2278:(e,t,r)=>{"use strict";r.r(t),r.d(t,{_:()=>o,_class_private_field_loose_key:()=>o});var n=0;function o(e){return"__private_"+n+++"_"+e}},1607:(e,t,r)=>{"use strict";function n(e){return e&&e.__esModule?e:{default:e}}r.r(t),r.d(t,{_:()=>n,_interop_require_default:()=>n})},5453:(e,t,r)=>{"use strict";function n(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,r=new WeakMap;return(n=function(e){return e?r:t})(e)}function o(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var r=n(t);if(r&&r.has(e))return r.get(e);var o={__proto__:null},a=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if("default"!==i&&Object.prototype.hasOwnProperty.call(e,i)){var l=a?Object.getOwnPropertyDescriptor(e,i):null;l&&(l.get||l.set)?Object.defineProperty(o,i,l):o[i]=e[i]}return o.default=e,r&&r.set(e,o),o}r.r(t),r.d(t,{_:()=>o,_interop_require_wildcard:()=>o})},9779:(e,t,r)=>{"use strict";r.d(t,{Z:()=>n});let n=function(){for(var e,t,r=0,n="",o=arguments.length;r{"use strict";function n(e){return e&&e.__esModule?e:{default:e}}r.r(t),r.d(t,{_:()=>n,_interop_require_default:()=>n})}};
\ No newline at end of file
diff --git a/frontend/.next/server/chunks/377.js b/frontend/.next/server/chunks/377.js
new file mode 100644
index 0000000000000000000000000000000000000000..3073fde7237f2135c37eb94570137d6ecc8d7ead
--- /dev/null
+++ b/frontend/.next/server/chunks/377.js
@@ -0,0 +1 @@
+"use strict";exports.id=377,exports.ids=[377],exports.modules={8377:(e,s,a)=>{a.r(s),a.d(s,{default:()=>u});var t=a(8924),n=a(3911),i=a(2828),r=a(6745);let l=(0,r.Z)("Send",[["path",{d:"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z",key:"1ffxy3"}],["path",{d:"m21.854 2.147-10.94 10.939",key:"12cjpa"}]]),c=(0,r.Z)("Sparkles",[["path",{d:"M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z",key:"4pj2yx"}],["path",{d:"M20 3v4",key:"1olli1"}],["path",{d:"M22 5h-4",key:"1gvqau"}],["path",{d:"M4 17v2",key:"vumght"}],["path",{d:"M5 18H3",key:"zchphs"}]]);var o=a(3789),d=a(398),h=a(6927);let m=["Analizza NVIDIA con approccio tecnico e fondamentale.","Trova ETF AI interessanti con rischio definibile.","Confronta S&P 500 vs Nasdaq.","Dove potrebbe entrare un trader momentum?","Quali titoli stanno mostrando forza relativa?","Quali narrative stanno accelerando?","What could the market be missing today?","Compare Nvidia, AMD and Broadcom."];function u(){let[e,s]=(0,n.useState)(""),[a,i]=(0,n.useState)("short and medium term"),[r,c]=(0,n.useState)("balanced"),[d,u]=(0,n.useState)("auto"),[x,j]=(0,n.useState)(),[v,g]=(0,n.useState)([{id:"welcome",role:"assistant",content:"Sono BLUM Chat. Fai una domanda come faresti a un analista buy-side: io recupero contesto BLUM, segnali, news, narrativa, tecnica, fondamentali, memoria storica e restituisco una risposta strutturata. Analisi informativa, non consulenza finanziaria."}]),[_,f]=(0,n.useState)(!1),[k,w]=(0,n.useState)(""),[M,S]=(0,n.useState)(null),z=(0,n.useRef)(null),$=[...v].reverse().find(e=>e.response)?.response,C=$?.candidate_opportunities??[],U=$?.asset_context??[],A=$?.sources_used??[],B=$?.context_coverage??{},L=$?.answer.market_sniper_mode??{},D=(0,n.useMemo)(()=>{let e=$?.market_context??{},s=e.narrative,a=e.market_sentiment;return{dominantTheme:s?.dominant_theme?.theme??M?.dominant_narrative?.theme??"Waiting",marketMood:s?.market_mood??M?.market_mood??"Waiting",articleCount:a?.article_count??M?.market_sentiment?.article_count??0,semanticHits:$?.semantic_evidence?.length??0,memoryHits:$?.training_memory?.length??0,dataQuality:$?.answer.data_quality?.label??"Pending"}},[M,$]),E=async(t,n)=>{t?.preventDefault();let i=(n??e).trim();if(i.length<3||_)return;let l={id:crypto.randomUUID(),role:"user",content:i};g(e=>[...e,l]),s(""),w(""),f(!0);try{let e=await o.h.financialChat({message:i,horizon:a,risk_profile:r,language:d,session_id:x,include_semantic_search:!0});j(e.session_id),g(s=>[...s,{id:crypto.randomUUID(),role:"assistant",content:e.answer.composed_response??e.answer.answer_to_user,response:e}])}catch(s){let e=s.message;w(e),g(s=>[...s,{id:crypto.randomUUID(),role:"assistant",content:`I could not complete the analysis because the backend returned: ${e}`}])}finally{f(!1),window.setTimeout(()=>z.current?.focus(),0)}},T=e=>{s(e),window.setTimeout(()=>z.current?.focus(),0)};return(0,t.jsxs)(t.Fragment,{children:[t.jsx(h.ft,{eyebrow:"BLUM Chat",title:"Financial intelligence conversation.",subtitle:"Multilingual market assistant connected to Blum signals, narratives, technical analysis, fundamentals, memory, backtests and evidence controls.",statusItems:[{label:"Mode",value:$?.intent??"RAG analyst",tone:"info"},{label:"Language",value:$?.language??d},{label:"Risk",value:r},{label:"Evidence",value:`${D.articleCount} news`,tone:$?"positive":"attention"}]}),(0,t.jsxs)("section",{className:"chatgpt-shell blum-chat-shell",children:[(0,t.jsxs)("div",{className:"chatgpt-main",children:[(0,t.jsxs)("div",{className:"chat-thread",children:[v.map(e=>t.jsx(p,{message:e},e.id)),_&&(0,t.jsxs)("div",{className:"chat-bubble assistant",children:[t.jsx("div",{className:"chat-avatar",children:"B"}),(0,t.jsxs)("div",{className:"chat-message-card",children:[t.jsx("span",{className:"chat-role",children:"BLUM is composing"}),t.jsx("p",{children:"Retrieving assets, technicals, fundamentals, sentiment, narrative, memory, contradictions and risk controls..."})]})]})]}),t.jsx("div",{className:"prompt-chip-row chat-starters",children:m.map(e=>t.jsx("button",{className:"prompt-chip",onClick:()=>T(e),children:e},e))}),(0,t.jsxs)("form",{className:"chat-composer",onSubmit:E,children:[(0,t.jsxs)("div",{className:"chat-composer-controls",children:[(0,t.jsxs)("select",{className:"input",value:d,onChange:e=>u(e.target.value),"aria-label":"Language",children:[t.jsx("option",{value:"auto",children:"Auto language"}),t.jsx("option",{value:"it",children:"Italiano"}),t.jsx("option",{value:"en",children:"English"}),t.jsx("option",{value:"de",children:"Deutsch"}),t.jsx("option",{value:"fr",children:"Francais"}),t.jsx("option",{value:"es",children:"Espanol"})]}),(0,t.jsxs)("select",{className:"input",value:a,onChange:e=>i(e.target.value),"aria-label":"Analysis horizon",children:[t.jsx("option",{children:"intraday and short term"}),t.jsx("option",{children:"short and medium term"}),t.jsx("option",{children:"medium and long term"}),t.jsx("option",{children:"multi-horizon"})]}),(0,t.jsxs)("select",{className:"input",value:r,onChange:e=>c(e.target.value),"aria-label":"Risk profile",children:[t.jsx("option",{children:"balanced"}),t.jsx("option",{children:"conservative"}),t.jsx("option",{children:"opportunistic"}),t.jsx("option",{children:"high volatility tolerant"})]})]}),(0,t.jsxs)("div",{className:"chat-input-row",children:[t.jsx("textarea",{ref:z,className:"input chat-input",value:e,onChange:e=>s(e.target.value),placeholder:"Ask BLUM to analyze an asset, compare setups, find selective opportunities, or plan a monitored technical scenario...",rows:2,onKeyDown:e=>{"Enter"!==e.key||e.shiftKey||(e.preventDefault(),E())}}),t.jsx("button",{className:"button primary chat-send-button",disabled:_||e.trim().length<3,type:"submit","aria-label":"Send",children:t.jsx(l,{size:17})})]}),k&&(0,t.jsxs)("div",{className:"terminal-empty compact",children:["Chat endpoint warning: ",k]})]})]}),(0,t.jsxs)("aside",{className:"chat-context-rail",children:[t.jsx(h.Ez,{title:"Conversation Context",value:D.marketMood,children:(0,t.jsxs)("div",{className:"professional-grid-2",children:[t.jsx(h.i9,{label:"Dominant Theme",value:D.dominantTheme}),t.jsx(h.i9,{label:"Data Quality",value:D.dataQuality}),t.jsx(h.i9,{label:"Semantic Hits",value:D.semanticHits}),t.jsx(h.i9,{label:"Memory Hits",value:D.memoryHits})]})}),t.jsx(h.Ez,{title:"Assets Mentioned",value:`${U.length} names`,children:(0,t.jsxs)("div",{className:"chat-candidate-stack",children:[0===U.length&&t.jsx("div",{className:"terminal-empty compact",children:"Ask about an asset, ETF, sector or market to build context."}),U.slice(0,8).map(e=>t.jsx(b,{asset:e},e.ticker))]})}),t.jsx(h.Ez,{title:"Candidate Queue",value:`${C.length} names`,children:(0,t.jsxs)("div",{className:"chat-candidate-stack",children:[0===C.length&&t.jsx("div",{className:"terminal-empty compact",children:"The assistant will populate a ranked queue from real BLUM evidence."}),C.slice(0,8).map((e,s)=>t.jsx(y,{candidate:e,rank:s+1},`${e.ticker??"candidate"}-${s}`))]})}),L?.asset&&t.jsx(h.Ez,{title:"Market Sniper Mode",value:L.confidence??"Selective",children:(0,t.jsxs)("div",{className:"sniper-box",children:[(0,t.jsxs)("strong",{children:[L.asset," | ",L.setup_type]}),(0,t.jsxs)("span",{children:["Zone: ",L.entry_zone_informational]}),(0,t.jsxs)("span",{children:["Invalidation: ",String(L.invalidation??"n/a")]}),(0,t.jsxs)("span",{children:["Target zone: ",String(L.target_zone_informational??"n/a")]}),t.jsx("span",{children:L.what_could_go_wrong})]})}),(0,t.jsxs)(h.Ez,{title:"Sources Used",value:`${A.length} layers`,children:[t.jsx("div",{className:"source-badge-grid",children:A.map(e=>t.jsx(N,{source:e},`${e.name}-${e.type}`))}),(0,t.jsxs)("div",{className:"context-coverage",children:[(0,t.jsxs)("span",{children:["Price ",B.assets_with_price??0,"/",B.assets_detected??0]}),(0,t.jsxs)("span",{children:["Technicals ",B.assets_with_technical_analysis??0]}),(0,t.jsxs)("span",{children:["Fundamentals ",B.assets_with_fundamentals??0]}),(0,t.jsxs)("span",{children:["News ",B.assets_with_news??0]})]})]}),t.jsx(h.Ez,{title:"Guardrails",value:"Research only",children:(0,t.jsxs)("div",{className:"chat-guardrail-list",children:[t.jsx("span",{children:"No direct buy/sell instruction."}),t.jsx("span",{children:"No guaranteed outcome or market-beating claim."}),t.jsx("span",{children:"Missing data is declared."}),t.jsx("span",{children:"Levels are informational and probabilistic."})]})})]})]})]})}function p({message:e}){let s=e.response;return(0,t.jsxs)("div",{className:`chat-bubble ${e.role}`,children:[t.jsx("div",{className:"chat-avatar",children:"assistant"===e.role?"B":"U"}),(0,t.jsxs)("div",{className:"chat-message-card",children:[t.jsx("span",{className:"chat-role",children:"assistant"===e.role?"BLUM Financial Brain":"You"}),s?.answer.standard_sections?t.jsx(x,{response:s}):t.jsx(j,{text:e.content}),s&&t.jsx(v,{response:s})]})]})}function x({response:e}){return t.jsx("div",{className:"structured-answer",children:e.answer.standard_sections?.map(e=>t.jsxs("section",{className:"structured-section",children:[t.jsx("h3",{children:e.title}),t.jsx("ul",{children:e.bullets.slice(0,8).map((s,a)=>t.jsx("li",{children:s},`${e.key}-${a}`))})]},e.key))})}function j({text:e}){return t.jsx("div",{className:"rich-answer",children:e.split("\n").map((e,s)=>e.trim()?e.startsWith("- ")?t.jsx("li",{children:e.slice(2)},e+s):e.endsWith(":")?t.jsx("h3",{children:e},e+s):t.jsx("p",{children:e},e+s):t.jsx("br",{},`br-${s}`))})}function v({response:e}){return["concise_safe","clarification","error","technical","fundamental"].includes(e.answer.response_style??"structured")?t.jsx("p",{className:"chat-disclaimer",children:e.disclaimer}):(0,t.jsxs)("div",{className:"chat-response-evidence",children:[(0,t.jsxs)("div",{className:"chat-evidence-columns",children:[t.jsx(g,{title:"Supporting Evidence",rows:e.answer.supporting_evidence}),t.jsx(g,{title:"Contradictions",rows:e.answer.contradicting_evidence})]}),(0,t.jsxs)("div",{className:"chat-evidence-columns",children:[t.jsx(g,{title:"Research Plan",rows:e.answer.research_plan??e.answer.what_to_monitor}),t.jsx(g,{title:"What Market May Miss",rows:e.answer.market_may_be_missing??[]})]}),(0,t.jsxs)("div",{className:"scenario-mini-grid",children:[t.jsx(_,{title:"Bull",text:e.answer.bull_case}),t.jsx(_,{title:"Base",text:e.answer.base_case}),t.jsx(_,{title:"Bear",text:e.answer.bear_case})]}),t.jsx("div",{className:"news-list",children:e.semantic_evidence.slice(0,4).map((e,s)=>{let a=e.article??{};return(0,t.jsxs)("a",{className:"news-item",href:a.url??"#",target:"_blank",rel:"noreferrer",children:[t.jsx("strong",{children:a.title??"Untitled evidence"}),(0,t.jsxs)("span",{children:["Similarity ",Number(e.score??0).toFixed(3)," | ",a.source??"unknown source"]})]},`${a.id??a.url??"hit"}-${s}`)})}),t.jsx("p",{className:"chat-disclaimer",children:e.disclaimer})]})}function g({title:e,rows:s}){return(0,t.jsxs)("div",{className:"chat-evidence-list compact-list",children:[t.jsx("strong",{children:e}),0===s.length&&t.jsx("span",{children:"No material evidence retrieved."}),s.slice(0,6).map((s,a)=>t.jsx("span",{children:s},`${e}-${a}`))]})}function _({title:e,text:s}){return(0,t.jsxs)("div",{className:"chat-scenario-card",children:[t.jsx("span",{children:e}),t.jsx("p",{children:s})]})}function b({asset:e}){let s=e.market_snapshot??{};return(0,t.jsxs)("div",{className:"asset-context-pill",children:[(0,t.jsxs)("div",{children:[t.jsx(i.default,{href:(0,d.up)(String(e.ticker)),children:e.ticker}),(0,t.jsxs)("p",{children:[e.name," | ",e.sector]})]}),t.jsx("strong",{children:s.price?`${Number(s.price).toFixed(2)} ${s.currency??""}`:"No price"}),t.jsx("span",{children:s.data_status??"unknown"})]})}function y({candidate:e,rank:s}){let a=String(e.ticker??"");return(0,t.jsxs)("div",{className:"compact-candidate",children:[(0,t.jsxs)("strong",{children:["#",s]}),(0,t.jsxs)("div",{children:[a?t.jsx(i.default,{href:(0,d.up)(a),children:a}):t.jsx("span",{children:"n/a"}),(0,t.jsxs)("p",{children:[e.name??"Asset"," | ",e.sector??"sector pending"]})]}),t.jsx(h.Dk,{value:e.opportunity_score,label:"opp"}),t.jsx(h.en,{risk:e.risk_level??"Not rated",score:e.risk_score}),t.jsx(h.IL,{value:e.technical_score,label:"Tech"})]})}function N({source:e}){return(0,t.jsxs)("div",{className:"source-badge",children:[t.jsx(c,{size:13}),(0,t.jsxs)("div",{children:[t.jsx("strong",{children:e.name}),(0,t.jsxs)("span",{children:[e.type," | coverage ",String(e.coverage??0)]})]})]})}}};
\ No newline at end of file
diff --git a/frontend/.next/server/chunks/394.js b/frontend/.next/server/chunks/394.js
new file mode 100644
index 0000000000000000000000000000000000000000..158b5537fdce3460bca30e1f506337ad7f31ca76
--- /dev/null
+++ b/frontend/.next/server/chunks/394.js
@@ -0,0 +1 @@
+exports.id=394,exports.ids=[394],exports.modules={9257:(e,i,a)=>{Promise.resolve().then(a.bind(a,5877))},9699:(e,i,a)=>{Promise.resolve().then(a.t.bind(a,6544,23)),Promise.resolve().then(a.t.bind(a,3477,23)),Promise.resolve().then(a.t.bind(a,5116,23)),Promise.resolve().then(a.t.bind(a,6676,23)),Promise.resolve().then(a.t.bind(a,9645,23)),Promise.resolve().then(a.t.bind(a,8850,23))},5877:(e,i,a)=>{"use strict";a.d(i,{AppShell:()=>C});var n=a(8924),t=a(2828),r=a(8975),s=a(3911),l=a(9773),o=a(7540),c=a(470),d=a(9534),m=a(3600),g=a(7993),p=a(5107),u=a(2567),h=a(6839),$=a(3187),y=a(3041),f=a(6635),b=a(5089),v=a(9779);a(3789);let k=[{href:"/",label:"Command",icon:l.Z,aliases:["/dashboard"]},{href:"/stock-radar",label:"Radar",icon:o.Z,aliases:["/etf-radar","/ipo-radar","/assets"]},{href:"/signal-lab",label:"Signals",icon:c.Z},{href:"/sniper",label:"Sniper",icon:d.Z},{href:"/market-brain",label:"Brain",icon:m.Z},{href:"/learning",label:"Learning",icon:g.Z},{href:"/narratives",label:"Narratives",icon:p.Z,aliases:["/themes"]},{href:"/chart-analyst",label:"Charts",icon:u.Z},{href:"/performance",label:"Performance",icon:h.Z},{href:"/chat",label:"Chat",icon:$.Z,aliases:["/chatbot"]}];function C({children:e}){let i=(0,r.usePathname)(),[a,l]=(0,s.useState)(null);return(0,n.jsxs)("div",{className:"app-shell",children:[(0,n.jsxs)("aside",{className:"sidebar",children:[(0,n.jsxs)("div",{className:"brand",children:[n.jsx("div",{className:"brand-mark",children:"B"}),(0,n.jsxs)("div",{children:[n.jsx("strong",{children:"Blum"}),n.jsx("span",{children:"Market Intelligence Officer"})]})]}),(0,n.jsxs)("div",{className:"sidebar-market-state",children:[n.jsx(y.Z,{size:15}),(0,n.jsxs)("div",{children:[(0,n.jsxs)("strong",{children:[a?.database_counts?.signals??0," signals"]}),(0,n.jsxs)("span",{children:[a?.database_counts?.news_articles??0," news articles indexed"]})]})]}),n.jsx("nav",{children:k.map(e=>{let a=e.icon,r=i===e.href||e.aliases?.some(e=>i.startsWith(e))||"/"!==e.href&&i.startsWith(e.href);return(0,n.jsxs)(t.default,{href:e.href,className:(0,v.Z)("nav-item",r&&"active"),children:[n.jsx(a,{size:17}),n.jsx("span",{children:e.label})]},e.href)})}),(0,n.jsxs)("div",{className:"system-card",children:[(0,n.jsxs)("div",{children:[n.jsx(f.Z,{size:15})," v",a?.app_version??"loading"," | ",a?.feature_set??"loading"]}),(0,n.jsxs)("div",{children:[n.jsx(m.Z,{size:15})," ",a?.runtime_flags.financial_brain_model_enabled?"Finance LLM active":"Evidence fallback"]}),(0,n.jsxs)("div",{children:[n.jsx(g.Z,{size:15})," ",a?.active_models?.financial_brain_configured??"model pending"]}),(0,n.jsxs)("div",{children:[n.jsx(b.Z,{size:15})," Research only"]}),n.jsx(t.default,{href:"/methodology",children:"Methodology and governance"})]})]}),n.jsx("main",{className:"workspace",children:e})]})}},3789:(e,i,a)=>{"use strict";a.d(i,{h:()=>u});let n=process.env.NEXT_PUBLIC_API_BASE??"",t=new Map,r=new Map,s={total:0,duplicate:0,cacheHits:0,initialLearningPage:[]};async function l(e){let i=await c(e,{method:"GET",cacheTtlMs:2500,timeoutMs:12e3});if(!i.ok)throw Error(await p(i));return i.json()}async function o(e,i){let a=await c(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i),timeoutMs:2e4});if(!a.ok)throw Error(await p(a));return a.json()}async function c(e,i={}){let a=String(i.method??"GET").toUpperCase(),l=`${a}:${e}:${"string"==typeof i.body?i.body:""}`,o=g();if(s.total+=1,"GET"===a){let i=r.get(l);if(i&&i.expiresAt>Date.now())return s.cacheHits+=1,m(e,a,g()-o,"cache",!1,!0),d(e,a,g()-o,"cache_hit",!0),new Response(JSON.stringify(i.value),{status:200,headers:{"Content-Type":"application/json","X-BLUM-FRONTEND-CACHE":"true"}});let n=t.get(l);if(n)return s.duplicate+=1,m(e,a,g()-o,"deduped",!0,!1),d(e,a,g()-o,"deduped",!0),n.then(e=>new Response(JSON.stringify(e),{status:200,headers:{"Content-Type":"application/json","X-BLUM-FRONTEND-DEDUPE":"true"}}))}let c=new AbortController,p=setTimeout(()=>c.abort(),i.timeoutMs??12e3),u=fetch(`${n}${e}`,{...i,method:a,cache:"no-store",signal:c.signal}).then(async n=>{let t=g()-o;if(m(e,a,t,n.ok?"ok":`http_${n.status}`,!1,!1),d(e,a,t,n.ok?"ok":`http_${n.status}`),"GET"===a&&n.ok&&i.cacheTtlMs&&!e.includes("/performance/")){let e=n.clone();try{r.set(l,{expiresAt:Date.now()+i.cacheTtlMs,value:await e.json()})}catch{}}return n}).catch(async t=>{let r=g()-o;if(m(e,a,r,"error",!1,!1),d(e,a,r,"error"),"GET"===a&&!String(t?.name).includes("Abort")&&!e.includes("/performance/"))return fetch(`${n}${e}`,{...i,method:a,cache:"no-store"});throw t}).finally(()=>{clearTimeout(p),t.delete(l)});return"GET"===a&&t.set(l,u.then(e=>e.clone().json()).catch(()=>void 0)),u}function d(e,i,a,t,r=!1){if(e.includes("/performance/frontend-widget")||e.includes("/api/performance/frontend-widget"))return;let s="undefined"!=typeof location&&location.pathname.startsWith("/learning");(r||s||!(a<400)||e.includes("/learning"))&&fetch(`${n}/api/performance/frontend-widget`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:`frontend.api.${i}.${e}`,duration_ms:a,status:t,source:"fetchBlum"}),keepalive:!0}).catch(()=>void 0)}function m(e,i,a,n,t,r){"undefined"!=typeof location&&location.pathname.startsWith("/learning")&&(s.initialLearningPage.push({path:e,method:i,duration_ms:Number(a.toFixed(2)),status:n,duplicate:t,cache_hit:r}),s.initialLearningPage.length>160&&s.initialLearningPage.shift())}function g(){return"undefined"==typeof performance?Date.now():performance.now()}async function p(e){try{let i=await e.json(),a="string"==typeof i?.detail?i.detail:JSON.stringify(i?.detail??i);return`${e.status} ${e.statusText}: ${a}`}catch{return`${e.status} ${e.statusText}`}}let u={clientRequestStats:()=>({...s,initialLearningPage:[...s.initialLearningPage]}),performanceDiagnostics:()=>l("/performance/diagnostics"),recordPerformanceWidget:e=>o("/performance/frontend-widget",e),systemStatus:()=>l("/system/status"),brainStatus:()=>l("/brain/status"),brainAccuracy:()=>l("/brain/accuracy"),brainLearningEvents:(e=50)=>l(`/brain/learning-events?limit=${e}`),brainSignalEvaluations:(e=120,i)=>l(`/brain/signal-evaluations?limit=${e}${i?`&ticker=${encodeURIComponent(i)}`:""}`),brainAssetMemory:e=>l(`/brain/asset-memory/${encodeURIComponent(e)}`),brainConfidenceHistory:e=>l(`/brain/confidence-history/${encodeURIComponent(e)}`),evaluateBrainSignals:(e=240)=>o(`/brain/evaluate-signals?limit=${e}`,{}),recalculateBrainWeights:()=>o("/brain/recalculate-weights",{}),runLearningCycle:(e=240)=>o(`/brain/run-learning-cycle?limit=${e}`,{}),learningDashboard:()=>l("/learning/dashboard"),learningSummary:()=>l("/api/learning-intelligence/summary"),dashboardSnapshot:e=>l(`/api/dashboard-snapshots/${encodeURIComponent(e)}`),startupStatus:()=>l("/startup/status"),learningRuns:(e=50)=>l(`/learning/runs?limit=${e}`),learningPredictions:(e=80,i)=>l(`/learning/predictions?limit=${e}${i?`&ticker=${encodeURIComponent(i)}`:""}`),learningMemory:(e=40)=>l(`/learning/memory?limit=${e}`),runBlumLearningLoop:(e=25)=>o(`/learning/run-cycle?batch_size=${e}`,{}),reasoningCoreStatus:()=>l("/model/reasoning-core/status"),reasoningCoreDiagnostics:()=>l("/model/reasoning-core/diagnostics"),thesisSurvival:(e=40)=>l(`/model/thesis-survival?limit=${e}`),convictionDecay:(e=40)=>l(`/model/conviction-decay?limit=${e}`),reliabilityByRegime:(e=40)=>l(`/model/reliability-by-regime?limit=${e}`),thesisCompetitions:(e=30)=>l(`/model/thesis-competitions?limit=${e}`),ensembleStatus:()=>l("/model/ensemble/status"),benchmarkRelative:(e=40)=>l(`/model/benchmark-relative?limit=${e}`),trainingQuality:(e=40)=>l(`/model/training/quality?limit=${e}`),sniperStatus:()=>l("/api/sniper/status"),sniperCandidates:(e=40,i=!1)=>l(`/api/sniper/candidates?limit=${e}&persist=${i?"true":"false"}`),sniperCandidate:(e,i=!1)=>l(`/api/sniper/candidates/${encodeURIComponent(e)}?persist=${i?"true":"false"}`),sniperEvaluate:(e=40,i)=>o(`/api/sniper/evaluate?limit=${e}${i?`&tickers=${encodeURIComponent(i)}`:""}`,{}),sniperSimulate:(e=120,i)=>o(`/api/sniper/simulate?limit=${e}${i?`&ticker=${encodeURIComponent(i)}`:""}`,{}),sniperSetups:()=>l("/api/sniper/setups"),sniperRegimes:(e=80)=>l(`/api/sniper/regimes?limit=${e}`),sniperMetrics:()=>l("/api/sniper/metrics"),sniperLessons:(e=40)=>l(`/api/sniper/lessons?limit=${e}`),tradingGameStatus:()=>l("/api/trading-game/status"),tradingGameRun:(e=60)=>o(`/api/trading-game/run?batch_size=${e}`,{}),tradingGameReset:()=>o("/api/trading-game/reset",{}),tradingGameEquity:(e=500,i)=>l(`/api/trading-game/equity?limit=${e}${i?`&game_id=${i}`:""}`),tradingGameAnnotatedEquity:(e=800,i)=>l(`/api/trading-game/equity/annotated?limit=${e}${i?`&game_id=${i}`:""}`),tradingGameTrades:(e=200,i)=>l(`/api/trading-game/trades?limit=${e}${i?`&game_id=${i}`:""}`),tradingGameLedger:(e=200,i)=>l(`/api/trading-game/ledger?limit=${e}${i?`&game_id=${i}`:""}`),tradingGameLedgerSummary:e=>l(`/api/trading-game/ledger/summary${e?`?game_id=${e}`:""}`),tradingGameLedgerByTicker:(e,i=200)=>l(`/api/trading-game/ledger/by-ticker/${encodeURIComponent(e)}?limit=${i}`),tradingGameLedgerBySetup:(e,i=200)=>l(`/api/trading-game/ledger/by-setup/${encodeURIComponent(e)}?limit=${i}`),tradingGameLedgerByOutcome:(e,i=200)=>l(`/api/trading-game/ledger/by-outcome/${encodeURIComponent(e)}?limit=${i}`),tradingGameLedgerByCycle:(e,i=500)=>l(`/api/trading-game/ledger/by-cycle/${e}?limit=${i}`),tradingGameTradeDetail:e=>l(`/api/trading-game/trades/${e}`),tradingGameTradeAttribution:e=>l(`/api/trading-game/trades/${e}/attribution`),tradingGameTradeQuality:e=>l(`/api/trading-game/trades/${e}/quality`),tradingGameTradePnlBreakdown:e=>l(`/api/trading-game/trades/${e}/pnl-breakdown`),tradingGameFailures:(e=80)=>l(`/api/trading-game/failures?limit=${e}`),tradingGameLessons:(e=50)=>l(`/api/trading-game/lessons?limit=${e}`),tradingGameBenchmark:e=>l(`/api/trading-game/benchmark${e?`?game_id=${e}`:""}`),tradingGameReproducibility:(e=120)=>l(`/api/trading-game/reproducibility?limit=${e}`),tradingGameLearningEvidence:(e=120)=>l(`/api/trading-game/learning-evidence?limit=${e}`),tradingGameRealityCheck:e=>l(`/api/trading-game/reality-check${e?`?game_id=${e}`:""}`),tradingGamePnlBreakdown:e=>l(`/api/trading-game/pnl-breakdown${e?`?game_id=${e}`:""}`),tradingGameCycles:(e=100,i)=>l(`/api/trading-game/cycles?limit=${e}${i?`&game_id=${i}`:""}`),tradingGameCurrentCycle:e=>l(`/api/trading-game/cycles/current${e?`?game_id=${e}`:""}`),tradingGameCycleStats:e=>l(`/api/trading-game/cycles/stats${e?`?game_id=${e}`:""}`),tradingGameCycleDetail:e=>l(`/api/trading-game/cycles/${e}`),tradingGameCycleReset:e=>o(`/api/trading-game/cycles/reset${e?`?game_id=${e}`:""}`,{}),tradingGameIntelligenceMetrics:e=>l(`/api/trading-game/intelligence-metrics${e?`?game_id=${e}`:""}`),tradingGameIntelligenceRolling:e=>l(`/api/trading-game/intelligence-metrics/rolling${e?`?game_id=${e}`:""}`),tradingGameIntelligenceBySetup:e=>l(`/api/trading-game/intelligence-metrics/by-setup${e?`?game_id=${e}`:""}`),tradingGameIntelligenceByRegime:e=>l(`/api/trading-game/intelligence-metrics/by-regime${e?`?game_id=${e}`:""}`),tradingGameIntelligenceBySector:e=>l(`/api/trading-game/intelligence-metrics/by-sector${e?`?game_id=${e}`:""}`),tradingGameIntelligenceByCycle:e=>l(`/api/trading-game/intelligence-metrics/by-cycle${e?`?game_id=${e}`:""}`),tradingGameHistoricalVsLive:()=>l("/api/trading-game/historical-vs-live"),liveTradingGameStatus:()=>l("/api/live-trading-game/status"),liveTradingGameRunCycle:()=>o("/api/live-trading-game/run-cycle",{}),liveTradingGamePositions:()=>l("/api/live-trading-game/positions"),liveTradingGameTrades:()=>l("/api/live-trading-game/trades"),liveTradingGameLedger:(e=200)=>l(`/api/live-trading-game/ledger?limit=${e}`),liveTradingGameEquity:()=>l("/api/live-trading-game/equity"),liveTradingGameMetrics:()=>l("/api/live-trading-game/metrics"),liveTradingGameCompareHistorical:()=>l("/api/live-trading-game/compare-historical"),learningIntelligenceDashboard:()=>l("/api/learning-intelligence/dashboard"),learningTradingPower:()=>l("/api/learning-intelligence/trading-power"),recalculateLearningTradingPower:()=>o("/api/learning-intelligence/trading-power/recalculate",{}),learningBenchmarks:()=>l("/api/learning-intelligence/benchmarks"),learningBenchmark:e=>l(`/api/learning-intelligence/benchmarks/${encodeURIComponent(e)}`),recalculateLearningBenchmarks:()=>o("/api/learning-intelligence/benchmarks/recalculate",{}),learningProgress:()=>l("/api/learning-intelligence/progress"),learningProgressRolling:()=>l("/api/learning-intelligence/progress/rolling"),learningProgressBySetup:()=>l("/api/learning-intelligence/progress/by-setup"),learningProgressByRegime:()=>l("/api/learning-intelligence/progress/by-regime"),learningWeaknessMap:()=>l("/api/learning-intelligence/weakness-map"),learningWeaknessBySetup:()=>l("/api/learning-intelligence/weakness-map/by-setup"),learningWeaknessByRegime:()=>l("/api/learning-intelligence/weakness-map/by-regime"),learningWeaknessBySector:()=>l("/api/learning-intelligence/weakness-map/by-sector"),learningWeaknessByEngine:()=>l("/api/learning-intelligence/weakness-map/by-engine"),learningSelfImprovementActions:(e=80)=>l(`/api/learning-intelligence/self-improvement/actions?limit=${e}`),generateLearningSelfImprovement:()=>o("/api/learning-intelligence/self-improvement/generate",{}),applyLearningSelfImprovement:e=>o(`/api/learning-intelligence/self-improvement/apply/${e}`,{}),evaluateLearningSelfImprovement:e=>o(`/api/learning-intelligence/self-improvement/evaluate/${e}`,{}),decisionIntelligenceDashboard:()=>l("/api/decision-intelligence/dashboard"),decisionSuperiority:()=>l("/api/decision-intelligence/superiority"),recalculateDecisionSuperiority:()=>o("/api/decision-intelligence/superiority/recalculate",{}),decisionUniverseSnapshots:()=>l("/api/decision-intelligence/universe-snapshots"),recalculateDecisionUniverseSnapshots:()=>o("/api/decision-intelligence/universe-snapshots/recalculate",{}),missedOpportunities:()=>l("/api/decision-intelligence/missed-opportunities"),businessQualityDashboard:()=>l("/api/business-quality/dashboard"),businessQualityScores:(e=80)=>l(`/api/business-quality/scores?limit=${e}`),recalculateBusinessQuality:(e=80)=>o(`/api/business-quality/recalculate?limit=${e}`,{}),portfolioIntelligenceDashboard:()=>l("/api/portfolio-intelligence/dashboard"),portfolioQuality:()=>l("/api/portfolio-intelligence/quality"),recalculatePortfolioIntelligence:()=>o("/api/portfolio-intelligence/recalculate",{}),chartAnalyzeTicker:(e,i="6M",a="1y",n=!1)=>o(`/chart/analyze-ticker?ticker=${encodeURIComponent(e)}&timeframe=${encodeURIComponent(i)}&period=${encodeURIComponent(a)}&include_visual=${n?"true":"false"}`,{}),chartTechnicalReport:(e,i="6M")=>l(`/chart/technical-report/${encodeURIComponent(e)}?timeframe=${encodeURIComponent(i)}`),chartLevels:(e,i="6M")=>l(`/chart/levels/${encodeURIComponent(e)}?timeframe=${encodeURIComponent(i)}`),chartSignals:(e,i="6M")=>l(`/chart/signals/${encodeURIComponent(e)}?timeframe=${encodeURIComponent(i)}`),chartHistory:(e,i=30)=>l(`/chart/history/${encodeURIComponent(e)}?limit=${i}`),assets:()=>l("/assets"),asset:e=>l(`/assets/${encodeURIComponent(e)}`),overview:()=>l("/dashboard/overview"),liveNews:(e=60)=>l(`/news/live?limit=${e}`),marketSentiment:(e=48)=>l(`/sentiment/market?hours=${e}`),dataCoverage:()=>l("/data/coverage"),repairData:(e=36)=>o(`/data/repair?limit=${e}`,{}),accuracyOverview:()=>l("/accuracy/overview"),runAccuracy:(e=80)=>o(`/accuracy/run?limit=${e}`,{}),assetAccuracy:e=>l(`/accuracy/${encodeURIComponent(e)}`),signalValidation:(e=240)=>l(`/validation/signals?limit=${e}`),macroOverview:()=>l("/macro/overview"),updateMacro:()=>o("/macro/update",{}),updateFundamentals:(e=24)=>o(`/fundamentals/update?limit=${e}`,{}),fundamentals:e=>l(`/fundamentals/${encodeURIComponent(e)}`),executiveDashboard:()=>l("/intelligence/executive"),opportunityRadar:(e=30)=>l(`/intelligence/opportunities?limit=${e}`),marketNarrative:()=>l("/intelligence/narrative"),communitySentiment:()=>l("/intelligence/community"),watchlist:()=>l("/intelligence/watchlist"),addWatchlist:(e,i="")=>o(`/intelligence/watchlist/${encodeURIComponent(e)}?thesis=${encodeURIComponent(i)}`,{}),portfolioScenario:(e="balanced")=>l(`/intelligence/portfolio-scenario?risk_profile=${encodeURIComponent(e)}`),intelligenceReport:e=>l(`/intelligence/reports/${encodeURIComponent(e)}`),similarBacktest:e=>l(`/intelligence/backtest/${encodeURIComponent(e)}`),pipelineStatus:()=>l("/pipeline/status"),topSignals:(e="")=>l(`/signals/top${e}`),signal:e=>l(`/signals/${e}`),sentiment:e=>l(`/sentiment/${e}`),explain:e=>l(`/ai/explain/${e}`),relatedNews:e=>l(`/related-news?ticker=${e}`),themes:()=>l("/themes"),themeDetail:e=>l(`/themes/${encodeURIComponent(e)}`),etfTrends:()=>l("/etf-trends"),stockRadar:(e=80)=>l(`/stock-radar?limit=${e}`),updateStockRadar:(e=36)=>o(`/stock-radar/update?limit=${e}`,{}),ipoRadar:(e=80)=>l(`/ipo-radar?limit=${e}`),updateIpoRadar:(e=50)=>o(`/ipo-radar/update?limit_per_form=${e}`,{}),secSubmissions:(e,i=!1)=>l(`/ipo-radar/sec-submissions/${e}?persist=${i?"true":"false"}`),marketBrain:()=>l("/market-brain"),marketBrainHistory:(e=20)=>l(`/market-brain/history?limit=${e}`),runMarketBrain:(e=!1)=>o(`/market-brain/run?refresh_pipeline=${e?"true":"false"}&refresh_sec=true`,{}),modelStatus:()=>l("/ai/models/status"),semanticSearch:e=>o("/semantic-search",{query:e,limit:12}),financialChat:e=>o("/api/chat",e),financialChatContext:()=>l("/api/chat/context"),financialChatHistory:(e=80)=>l(`/api/chat/history?limit=${e}`),marketUpdate:()=>o("/market/update",{period:"max",limit:36}),newsUpdate:()=>o("/news/update",{lookback_hours:72,limit_per_feed:35}),runSignals:()=>o("/signals/run",{refresh_prices:!1,limit:36}),runPipeline:()=>o("/pipeline/run",{refresh_prices:!1,limit:36}),backtest:e=>o(`/backtest/${e}`,{})}},8777:(e,i,a)=>{"use strict";a.r(i),a.d(i,{default:()=>s,metadata:()=>r});var n=a(5886);a(9944);let t=(0,a(6691).createProxy)(String.raw`/Users/renatovinai/Documents/New project/hf-blum-mvp/frontend/components/AppShell.tsx#AppShell`),r={title:"Blum AI Financial Intelligence",description:"Open-source AI financial intelligence case study for equities, ETFs, signals and explainability."};function s({children:e}){return n.jsx("html",{lang:"en",children:n.jsx("body",{children:n.jsx(t,{children:e})})})}},9944:()=>{}};
\ No newline at end of file
diff --git a/frontend/.next/server/chunks/590.js b/frontend/.next/server/chunks/590.js
new file mode 100644
index 0000000000000000000000000000000000000000..249c37c3b36405c8e1ed909c27820ac93d2ff1aa
--- /dev/null
+++ b/frontend/.next/server/chunks/590.js
@@ -0,0 +1,6 @@
+"use strict";exports.id=590,exports.ids=[590],exports.modules={1590:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var n in t)Object.defineProperty(e,n,{enumerable:!0,get:t[n]})}(t,{Head:function(){return y},Html:function(){return I},Main:function(){return T},NextScript:function(){return S},default:function(){return P}});let r=n(997),i=function(e,t){if(e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=p(void 0);if(n&&n.has(e))return n.get(e);var r={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if("default"!==o&&Object.prototype.hasOwnProperty.call(e,o)){var s=i?Object.getOwnPropertyDescriptor(e,o):null;s&&(s.get||s.set)?Object.defineProperty(r,o,s):r[o]=e[o]}return r.default=e,n&&n.set(e,r),r}(n(6689)),o=n(659),s=n(2560),a=n(1004),l=function(e){return e&&e.__esModule?e:{default:e}}(n(3061)),u=n(8083),c=n(8536);function p(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(p=function(e){return e?n:t})(e)}let f=new Set;function d(e,t,n){let r=(0,s.getPageFiles)(e,"/_app"),i=n?[]:(0,s.getPageFiles)(e,t);return{sharedFiles:r,pageFiles:i,allFiles:[...new Set([...r,...i])]}}function h(e,t){let{assetPrefix:n,buildManifest:i,assetQueryString:o,disableOptimizedLoading:s,crossOrigin:a}=e;return i.polyfillFiles.filter(e=>e.endsWith(".js")&&!e.endsWith(".module.js")).map(e=>(0,r.jsx)("script",{defer:!s,nonce:t.nonce,crossOrigin:t.crossOrigin||a,noModule:!0,src:`${n}/_next/${(0,c.encodeURIPath)(e)}${o}`},e))}function m({styles:e}){if(!e)return null;let t=Array.isArray(e)?e:[];if(e.props&&Array.isArray(e.props.children)){let n=e=>{var t,n;return null==e?void 0:null==(n=e.props)?void 0:null==(t=n.dangerouslySetInnerHTML)?void 0:t.__html};e.props.children.forEach(e=>{Array.isArray(e)?e.forEach(e=>n(e)&&t.push(e)):n(e)&&t.push(e)})}return(0,r.jsx)("style",{"amp-custom":"",dangerouslySetInnerHTML:{__html:t.map(e=>e.props.dangerouslySetInnerHTML.__html).join("").replace(/\/\*# sourceMappingURL=.*\*\//g,"").replace(/\/\*@ sourceURL=.*?\*\//g,"")}})}function _(e,t,n){let{dynamicImports:i,assetPrefix:o,isDevelopment:s,assetQueryString:a,disableOptimizedLoading:l,crossOrigin:u}=e;return i.map(e=>!e.endsWith(".js")||n.allFiles.includes(e)?null:(0,r.jsx)("script",{async:!s&&l,defer:!l,src:`${o}/_next/${(0,c.encodeURIPath)(e)}${a}`,nonce:t.nonce,crossOrigin:t.crossOrigin||u},e))}function g(e,t,n){var i;let{assetPrefix:o,buildManifest:s,isDevelopment:a,assetQueryString:l,disableOptimizedLoading:u,crossOrigin:p}=e;return[...n.allFiles.filter(e=>e.endsWith(".js")),...null==(i=s.lowPriorityFiles)?void 0:i.filter(e=>e.endsWith(".js"))].map(e=>(0,r.jsx)("script",{src:`${o}/_next/${(0,c.encodeURIPath)(e)}${l}`,nonce:t.nonce,async:!a&&u,defer:!u,crossOrigin:t.crossOrigin||p},e))}function E(e,t){let{scriptLoader:n,disableOptimizedLoading:o,crossOrigin:s}=e,a=function(e,t){let{assetPrefix:n,scriptLoader:o,crossOrigin:s,nextScriptWorkers:a}=e;if(!a)return null;try{let{partytownSnippet:e}=require("@builder.io/partytown/integration"),a=(Array.isArray(t.children)?t.children:[t.children]).find(e=>{var t,n;return!!e&&!!e.props&&(null==e?void 0:null==(n=e.props)?void 0:null==(t=n.dangerouslySetInnerHTML)?void 0:t.__html.length)&&"data-partytown-config"in e.props});return(0,r.jsxs)(r.Fragment,{children:[!a&&(0,r.jsx)("script",{"data-partytown-config":"",dangerouslySetInnerHTML:{__html:`
+ partytown = {
+ lib: "${n}/_next/static/~partytown/"
+ };
+ `}}),(0,r.jsx)("script",{"data-partytown":"",dangerouslySetInnerHTML:{__html:e()}}),(o.worker||[]).map((e,n)=>{let{strategy:r,src:o,children:a,dangerouslySetInnerHTML:l,...u}=e,c={};if(o)c.src=o;else if(l&&l.__html)c.dangerouslySetInnerHTML={__html:l.__html};else if(a)c.dangerouslySetInnerHTML={__html:"string"==typeof a?a:Array.isArray(a)?a.join(""):""};else throw Error("Invalid usage of next/script. Did you forget to include a src attribute or an inline script? https://nextjs.org/docs/messages/invalid-script");return(0,i.createElement)("script",{...c,...u,type:"text/partytown",key:o||n,nonce:t.nonce,"data-nscript":"worker",crossOrigin:t.crossOrigin||s})})]})}catch(e){return(0,l.default)(e)&&"MODULE_NOT_FOUND"!==e.code&&console.warn(`Warning: ${e.message}`),null}}(e,t),u=(n.beforeInteractive||[]).filter(e=>e.src).map((e,n)=>{let{strategy:r,...a}=e;return(0,i.createElement)("script",{...a,key:a.src||n,defer:a.defer??!o,nonce:t.nonce,"data-nscript":"beforeInteractive",crossOrigin:t.crossOrigin||s})});return(0,r.jsxs)(r.Fragment,{children:[a,u]})}class y extends i.default.Component{static #e=this.contextType=u.HtmlContext;getCssLinks(e){let{assetPrefix:t,assetQueryString:n,dynamicImports:i,crossOrigin:o,optimizeCss:s,optimizeFonts:a}=this.context,l=e.allFiles.filter(e=>e.endsWith(".css")),u=new Set(e.sharedFiles),p=new Set([]),f=Array.from(new Set(i.filter(e=>e.endsWith(".css"))));if(f.length){let e=new Set(l);p=new Set(f=f.filter(t=>!(e.has(t)||u.has(t)))),l.push(...f)}let d=[];return l.forEach(e=>{let i=u.has(e);s||d.push((0,r.jsx)("link",{nonce:this.props.nonce,rel:"preload",href:`${t}/_next/${(0,c.encodeURIPath)(e)}${n}`,as:"style",crossOrigin:this.props.crossOrigin||o},`${e}-preload`));let a=p.has(e);d.push((0,r.jsx)("link",{nonce:this.props.nonce,rel:"stylesheet",href:`${t}/_next/${(0,c.encodeURIPath)(e)}${n}`,crossOrigin:this.props.crossOrigin||o,"data-n-g":a?void 0:i?"":void 0,"data-n-p":a?void 0:i?void 0:""},e))}),a&&(d=this.makeStylesheetInert(d)),0===d.length?null:d}getPreloadDynamicChunks(){let{dynamicImports:e,assetPrefix:t,assetQueryString:n,crossOrigin:i}=this.context;return e.map(e=>e.endsWith(".js")?(0,r.jsx)("link",{rel:"preload",href:`${t}/_next/${(0,c.encodeURIPath)(e)}${n}`,as:"script",nonce:this.props.nonce,crossOrigin:this.props.crossOrigin||i},e):null).filter(Boolean)}getPreloadMainLinks(e){let{assetPrefix:t,assetQueryString:n,scriptLoader:i,crossOrigin:o}=this.context,s=e.allFiles.filter(e=>e.endsWith(".js"));return[...(i.beforeInteractive||[]).map(e=>(0,r.jsx)("link",{nonce:this.props.nonce,rel:"preload",href:e.src,as:"script",crossOrigin:this.props.crossOrigin||o},e.src)),...s.map(e=>(0,r.jsx)("link",{nonce:this.props.nonce,rel:"preload",href:`${t}/_next/${(0,c.encodeURIPath)(e)}${n}`,as:"script",crossOrigin:this.props.crossOrigin||o},e))]}getBeforeInteractiveInlineScripts(){let{scriptLoader:e}=this.context,{nonce:t,crossOrigin:n}=this.props;return(e.beforeInteractive||[]).filter(e=>!e.src&&(e.dangerouslySetInnerHTML||e.children)).map((e,r)=>{let{strategy:o,children:s,dangerouslySetInnerHTML:a,src:l,...u}=e,c="";return a&&a.__html?c=a.__html:s&&(c="string"==typeof s?s:Array.isArray(s)?s.join(""):""),(0,i.createElement)("script",{...u,dangerouslySetInnerHTML:{__html:c},key:u.id||r,nonce:t,"data-nscript":"beforeInteractive",crossOrigin:n||void 0})})}getDynamicChunks(e){return _(this.context,this.props,e)}getPreNextScripts(){return E(this.context,this.props)}getScripts(e){return g(this.context,this.props,e)}getPolyfillScripts(){return h(this.context,this.props)}makeStylesheetInert(e){return i.default.Children.map(e,e=>{var t,n;if((null==e?void 0:e.type)==="link"&&(null==e?void 0:null==(t=e.props)?void 0:t.href)&&o.OPTIMIZED_FONT_PROVIDERS.some(({url:t})=>{var n,r;return null==e?void 0:null==(r=e.props)?void 0:null==(n=r.href)?void 0:n.startsWith(t)})){let t={...e.props||{},"data-href":e.props.href,href:void 0};return i.default.cloneElement(e,t)}if(null==e?void 0:null==(n=e.props)?void 0:n.children){let t={...e.props||{},children:this.makeStylesheetInert(e.props.children)};return i.default.cloneElement(e,t)}return e}).filter(Boolean)}render(){let{styles:e,ampPath:t,inAmpMode:o,hybridAmp:s,canonicalBase:a,__NEXT_DATA__:l,dangerousAsPath:u,headTags:p,unstable_runtimeJS:f,unstable_JsPreload:h,disableOptimizedLoading:_,optimizeCss:g,optimizeFonts:E,assetPrefix:y,nextFontManifest:S}=this.context,I=!1===f,T=!1===h||!_;this.context.docComponentsRendered.Head=!0;let{head:P}=this.context,O=[],x=[];P&&(P.forEach(e=>{let t;this.context.strictNextHead&&(t=i.default.createElement("meta",{name:"next-head",content:"1"})),e&&"link"===e.type&&"preload"===e.props.rel&&"style"===e.props.as?(t&&O.push(t),O.push(e)):e&&(t&&("meta"!==e.type||!e.props.charSet)&&x.push(t),x.push(e))}),P=O.concat(x));let b=i.default.Children.toArray(this.props.children).filter(Boolean);E&&!o&&(b=this.makeStylesheetInert(b));let N=!1,j=!1;P=i.default.Children.map(P||[],e=>{if(!e)return e;let{type:t,props:n}=e;if(o){let r="";if("meta"===t&&"viewport"===n.name?r='name="viewport"':"link"===t&&"canonical"===n.rel?j=!0:"script"===t&&(n.src&&-1>n.src.indexOf("ampproject")||n.dangerouslySetInnerHTML&&(!n.type||"text/javascript"===n.type))&&(r="404: This page could not be found. Blum AI Financial Intelligence 404
This page could not be found.