commit 293522436aa31955d5a40441b7f15958889dc0df Author: Alvaro Romero Date: Fri Jul 3 12:23:34 2026 -0400 feat: Agente-Marketing initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a20c1d6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,61 @@ +# Python +__pycache__/ +*.py[cod] +*.pyo +*.pyd +.Python +.venv/ +venv/ +env/ +ENV/ +*.egg-info/ +dist/ +build/ + +# Environment / Secrets +.env +.env.* +*.pem +*.key +*.p12 + +# Database +*.db +*.db-wal +*.db-shm +*.sqlite +*.sqlite3 + +# Scan output (may contain scraped PII) +app/scan_results.json +app/scan_results.json.imported +app/scan_status.json + +# Node +node_modules/ +package-lock.json + +# Logs +*.log +*.log.* + +# OS +.DS_Store +Thumbs.db +Desktop.ini + +# IDE +.vscode/ +.idea/ +*.swp +*.swo + +# Cache +.mypy_cache/ +.pytest_cache/ +.ruff_cache/ + +# Nextcloud sync metadata +.nextcloudsync.log +.sync_*.db +.sync_*.db-wal diff --git a/casa-hunter/Dockerfile b/casa-hunter/Dockerfile new file mode 100644 index 0000000..0a9e9ea --- /dev/null +++ b/casa-hunter/Dockerfile @@ -0,0 +1,7 @@ +FROM python:3.11-slim +WORKDIR /app +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt +COPY app/ . +EXPOSE 5000 +CMD ["python", "main.py"] diff --git a/casa-hunter/app/ai_analyzer.py b/casa-hunter/app/ai_analyzer.py new file mode 100644 index 0000000..aca39b4 --- /dev/null +++ b/casa-hunter/app/ai_analyzer.py @@ -0,0 +1,104 @@ +import requests +import json + +# Supports Ollama (local) or Anthropic API +# Set OLLAMA_URL to use local AI, or ANTHROPIC_KEY for Claude API + +OLLAMA_URL = "http://localhost:11434" +OLLAMA_MODEL = "qwen2.5:14b" + +USER_PROFILE = """ +Perfil del comprador: +- Residente permanente en EE.UU., menos de 2 años en el país +- Soltero +- Trabajo independiente: electricista naval/marino ($120/hora) +- Dinero disponible para down payment: $50,000 dólares +- Presupuesto máximo: $200,000 +- Busca: costas de Florida (Stuart hacia el norte hasta Jacksonville) +- Objetivo: casa para vivir, oportunidad de remate o precio bajo de mercado +- Situación crediticia: construyendo historial en USA, no califica para préstamo convencional aún +- Tipo de préstamo ideal: Non-QM, Bank Statement, o ITIN loan +""" + +ANALYSIS_PROMPT = """Eres un asesor experto en bienes raíces y finanzas para compradores en Florida. + +{profile} + +Analiza esta propiedad y responde en español en máximo 4 oraciones: +1. ¿Es una buena oportunidad para este comprador? +2. ¿Qué tipo de préstamo le conviene para esta propiedad específica? +3. ¿Hay algo que deba investigar o que sea una señal de alerta? + +Propiedad: +- Dirección: {address} +- Ciudad/Condado: {city} +- Precio: ${price:,} +- Tipo: {prop_type} +- Estado: {status} +- Habitaciones: {beds} | Baños: {baths} +- Metros cuadrados: {sqft} +- Fuente: {source} + +Responde de forma directa y práctica, como si le hablaras a un amigo.""" + + +def analyze_with_ollama(prop: dict) -> str: + prompt = ANALYSIS_PROMPT.format( + profile=USER_PROFILE, + address=prop.get("address", "N/A"), + city=f"{prop.get('city', '')} {prop.get('county', '')}".strip(), + price=prop.get("price", 0), + prop_type=prop.get("property_type", "Residencial"), + status=prop.get("status", "Foreclosure"), + beds=prop.get("beds", "N/A"), + baths=prop.get("baths", "N/A"), + sqft=prop.get("sqft", "N/A"), + source=prop.get("source", "N/A") + ) + try: + r = requests.post( + f"{OLLAMA_URL}/api/generate", + json={"model": OLLAMA_MODEL, "prompt": prompt, "stream": False}, + timeout=60 + ) + if r.status_code == 200: + return r.json().get("response", "").strip() + except Exception as e: + return f"IA local no disponible: {e}" + return "Análisis no disponible." + + +def analyze_with_anthropic(prop: dict, api_key: str) -> str: + prompt = ANALYSIS_PROMPT.format( + profile=USER_PROFILE, + address=prop.get("address", "N/A"), + city=f"{prop.get('city', '')} {prop.get('county', '')}".strip(), + price=prop.get("price", 0), + prop_type=prop.get("property_type", "Residencial"), + status=prop.get("status", "Foreclosure"), + beds=prop.get("beds", "N/A"), + baths=prop.get("baths", "N/A"), + sqft=prop.get("sqft", "N/A"), + source=prop.get("source", "N/A") + ) + try: + r = requests.post( + "https://api.anthropic.com/v1/messages", + headers={"x-api-key": api_key, "anthropic-version": "2023-06-01", "content-type": "application/json"}, + json={"model": "claude-haiku-4-5-20251001", "max_tokens": 300, "messages": [{"role": "user", "content": prompt}]}, + timeout=30 + ) + if r.status_code == 200: + return r.json()["content"][0]["text"].strip() + except Exception as e: + return f"Error API: {e}" + return "Análisis no disponible." + + +def analyze_property(prop: dict, ollama_model: str = None, anthropic_key: str = None) -> str: + global OLLAMA_MODEL + if ollama_model: + OLLAMA_MODEL = ollama_model + if anthropic_key: + return analyze_with_anthropic(prop, anthropic_key) + return analyze_with_ollama(prop) diff --git a/casa-hunter/app/florida_cities.py b/casa-hunter/app/florida_cities.py new file mode 100644 index 0000000..abd8539 --- /dev/null +++ b/casa-hunter/app/florida_cities.py @@ -0,0 +1,58 @@ +FLORIDA_CITIES = [ + # Treasure Coast + "Stuart", "Palm City", "Hobe Sound", "Jensen Beach", "Port Salerno", + "Indiantown", "Port St. Lucie", "Fort Pierce", "Tradition", "St. Lucie West", + "Vero Beach", "Sebastian", "Fellsmere", "Roseland", "Indian River Shores", + "Orchid", "Gifford", "Wabasso", + # Space Coast / Brevard + "Melbourne", "Palm Bay", "Titusville", "Cocoa", "Cocoa Beach", + "Rockledge", "Merritt Island", "Cape Canaveral", "Satellite Beach", + "Indian Harbour Beach", "Indialantic", "Melbourne Beach", "Grant", + "Valkaria", "Malabar", "Palm Shores", "Micco", "West Melbourne", + # Volusia + "Daytona Beach", "Daytona Beach Shores", "Ormond Beach", "Holly Hill", + "South Daytona", "Port Orange", "Ponce Inlet", "New Smyrna Beach", + "Edgewater", "Oak Hill", "Deltona", "DeLand", "Orange City", + "DeBary", "Lake Helen", "Pierson", "Flagler Beach", + # Flagler + "Palm Coast", "Bunnell", "Flagler Beach", "Beverly Beach", "Marineland", + # St. Johns + "St. Augustine", "St. Augustine Beach", "Ponte Vedra Beach", + "Ponte Vedra", "Palm Valley", "Nocatee", "World Golf Village", + "Hastings", "Crescent Beach", "Vilano Beach", + # Duval / Jacksonville + "Jacksonville", "Jacksonville Beach", "Atlantic Beach", "Neptune Beach", + "Fernandina Beach", "Yulee", "Callahan", "Baldwin", "Mandarin", + "Southside", "Westside", "Arlington", "Baymeadows", "Ponte Vedra", + "Orange Park", "Fleming Island", + # Nassau + "Fernandina Beach", "Yulee", "Hilliard", "Callahan", + # Palm Beach / South (just in case they expand) + "West Palm Beach", "Boca Raton", "Delray Beach", "Lake Worth", + "Boynton Beach", "Riviera Beach", "Palm Beach Gardens", + "Jupiter", "Tequesta", "North Palm Beach", + # Broward + "Fort Lauderdale", "Hollywood", "Pompano Beach", "Deerfield Beach", + "Hallandale Beach", "Coral Springs", "Margate", "Coconut Creek", + "Tamarac", "Plantation", "Davie", "Miramar", "Pembroke Pines", + "Lauderdale-by-the-Sea", "Dania Beach", + # Miami-Dade + "Miami", "Miami Beach", "Coral Gables", "Hialeah", "Homestead", + "Aventura", "Sunny Isles Beach", "North Miami", "North Miami Beach", + "Doral", "Kendall", "Cutler Bay", "Palmetto Bay", + # Gulf Coast + "Naples", "Marco Island", "Bonita Springs", "Estero", "Fort Myers", + "Fort Myers Beach", "Cape Coral", "Punta Gorda", "Port Charlotte", + "Englewood", "Venice", "Sarasota", "Bradenton", "Anna Maria", + "Holmes Beach", "Palmetto", "St. Petersburg", "Clearwater", + "Dunedin", "Tarpon Springs", "New Port Richey", "Port Richey", + "Hudson", "Spring Hill", "Brooksville", + # Central + "Orlando", "Kissimmee", "Sanford", "Altamonte Springs", "Casselberry", + "Winter Park", "Maitland", "Apopka", "Ocoee", "Winter Garden", + "Clermont", "Leesburg", "The Villages", "Ocala", "Gainesville", + "Tallahassee", "Pensacola", "Panama City", "Destin", "Fort Walton Beach", +] + +# Remove duplicates and sort +FLORIDA_CITIES = sorted(list(set(FLORIDA_CITIES))) diff --git a/casa-hunter/app/lenders_data.py b/casa-hunter/app/lenders_data.py new file mode 100644 index 0000000..75295e0 --- /dev/null +++ b/casa-hunter/app/lenders_data.py @@ -0,0 +1,122 @@ +LENDERS = [ + { + "name": "Heart Mortgage", + "loan_type": "ITIN / Non-QM / Bank Statement", + "specialties": "Residentes nuevos, ITIN, sin historial crediticio USA, self-employed", + "min_down_pct": 15.0, + "accepts_new_resident": True, + "accepts_self_employed": True, + "requires_2yr_history": False, + "phone": "", + "email": "", + "website": "https://blog.heartmortgage.com", + "match_score": 98, + "contact_script": "Hola, me llamo [TU NOMBRE]. Soy residente permanente, llevo menos de 2 años en EE.UU. Trabajo como contratista independiente en eléctrica marina y tengo $50,000 para down payment. Estoy buscando propiedades hasta $200,000 en la costa de Florida. ¿Tienen programas Bank Statement o Non-QM para mi situación?", + "notes": "Top lender FL 2026 para residentes nuevos e ITIN. No requieren 2 años de historial." + }, + { + "name": "Jhenesis Mortgage", + "loan_type": "ITIN / Sin score crediticio", + "specialties": "Sin score requerido, hasta 85% LTV, 1 año empleo suficiente", + "min_down_pct": 15.0, + "accepts_new_resident": True, + "accepts_self_employed": True, + "requires_2yr_history": False, + "phone": "", + "email": "", + "website": "https://jhenesismortgage.com", + "match_score": 97, + "contact_script": "Hola, me llamo [TU NOMBRE]. Soy residente permanente con menos de 2 años en EE.UU. Trabajo independiente en instalaciones eléctricas marinas, ingresos de $120/hora. Tengo $50,000 de down payment y busco hasta $200,000. ¿Manejan préstamos ITIN o sin score crediticio americano?", + "notes": "Aceptan sin score crediticio USA. Solo necesitan 1 año de historial laboral." + }, + { + "name": "1st Florida Lending", + "loan_type": "ITIN / DACA / Residentes", + "specialties": "ITIN, DACA, residentes nuevos, toda Florida", + "min_down_pct": 10.0, + "accepts_new_resident": True, + "accepts_self_employed": True, + "requires_2yr_history": False, + "phone": "", + "email": "", + "website": "https://www.1floridalending.com", + "match_score": 95, + "contact_script": "Hola, llamo porque necesito un préstamo hipotecario. Soy residente permanente, menos de 2 años en EE.UU., trabajo contratista independiente en eléctrica marina. Down payment disponible: $50,000. Propiedad buscada: hasta $200,000 en costa de Florida. ¿Trabajan con residentes nuevos y self-employed?", + "notes": "Especializados en ITIN y residentes nuevos en toda Florida. Down payment desde 10%." + }, + { + "name": "Bennett Capital Partners", + "loan_type": "Non-QM / Bank Statement", + "specialties": "Bank Statement loans, residentes nuevos, self-employed, Miami y Florida", + "min_down_pct": 20.0, + "accepts_new_resident": True, + "accepts_self_employed": True, + "requires_2yr_history": False, + "phone": "", + "email": "", + "website": "https://www.bcpmortgage.com", + "match_score": 92, + "contact_script": "Hola, mi nombre es [TU NOMBRE]. Soy residente permanente trabajando como contratista independiente en eléctrica naval, ganando $120 por hora. Tengo $50,000 líquidos para down payment y busco propiedad hasta $200,000 en costa de Florida. ¿Tienen Bank Statement loans para alguien con menos de 2 años de historial en EE.UU.?", + "notes": "Fuertes en Non-QM y Bank Statement. Acceso a múltiples lenders portfolio." + }, + { + "name": "The Doce Group", + "loan_type": "Non-QM / Foreign National / Residente", + "specialties": "Residentes nuevos, extranjeros, sur de Florida", + "min_down_pct": 25.0, + "accepts_new_resident": True, + "accepts_self_employed": True, + "requires_2yr_history": False, + "phone": "", + "email": "", + "website": "https://thedocegroup.com", + "match_score": 88, + "contact_script": "Hola, soy residente permanente, menos de 2 años en EE.UU., work as independent marine electrical contractor. $50,000 down payment disponible, busco hasta $200,000. ¿Tienen programas para mi perfil?", + "notes": "Especializados en perfiles internacionales y residentes nuevos en Florida." + }, + { + "name": "Griffin Funding", + "loan_type": "Bank Statement / Non-QM", + "specialties": "Self-employed, Bank Statement loans, toda Florida", + "min_down_pct": 10.0, + "accepts_new_resident": True, + "accepts_self_employed": True, + "requires_2yr_history": False, + "phone": "", + "email": "", + "website": "https://griffinfunding.com", + "match_score": 90, + "contact_script": "Hola, busco un Bank Statement loan. Soy contratista independiente en eléctrica marina, residente permanente, menos de 2 años en EE.UU. Tengo $50,000 de down payment y busco propiedad hasta $200,000 en costas de Florida. ¿Califico con bank statements de 12 meses?", + "notes": "Líderes en Bank Statement loans para self-employed. Desde 10% down." + }, + { + "name": "DAK Mortgage", + "loan_type": "Non-QM / Internacional", + "specialties": "Compradores internacionales, residentes nuevos, Miami y Florida", + "min_down_pct": 20.0, + "accepts_new_resident": True, + "accepts_self_employed": True, + "requires_2yr_history": False, + "phone": "", + "email": "", + "website": "https://davidakrebs.com", + "match_score": 85, + "contact_script": "Hola, soy residente permanente con menos de 2 años aquí. Trabajo independiente en instalaciones eléctricas marinas. $50,000 down payment, busco hasta $200,000 en costas de Florida. ¿Tienen opciones para mi perfil?", + "notes": "Especialistas en Miami para perfiles internacionales y residentes nuevos." + }, + { + "name": "Angel Oak Mortgage", + "loan_type": "Non-QM / Foreign National", + "specialties": "Non-QM, residentes, bank statement, toda USA", + "min_down_pct": 20.0, + "accepts_new_resident": True, + "accepts_self_employed": True, + "requires_2yr_history": False, + "phone": "", + "email": "", + "website": "https://angeloakms.com", + "match_score": 87, + "contact_script": "Hola, necesito información sobre Non-QM loans. Soy residente permanente, self-employed en eléctrica marina, menos de 2 años en EE.UU., $50,000 down payment, busco hasta $200,000 en Florida. ¿Tienen programas para este perfil?", + "notes": "Pioneros en Non-QM. Tienen programa específico Foreign National y residentes nuevos." + } +] diff --git a/casa-hunter/app/main.py b/casa-hunter/app/main.py new file mode 100644 index 0000000..d0dc998 --- /dev/null +++ b/casa-hunter/app/main.py @@ -0,0 +1,337 @@ +# -*- coding: utf-8 -*- +import sys, io +if sys.stdout.encoding != 'utf-8': + sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace') +from flask import Flask, render_template, request, redirect, url_for, jsonify, flash +from models import db, Property, Lender, ScrapeLog, SearchCity, SearchConfig +from lenders_data import LENDERS +from scrapers import run_all_scrapers +from ai_analyzer import analyze_property +from florida_cities import FLORIDA_CITIES +import os, subprocess, json, sys +from datetime import datetime + +app = Flask(__name__) +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +STATUS_FILE = os.path.join(BASE_DIR, "scan_status.json") +RESULTS_FILE = os.path.join(BASE_DIR, "scan_results.json") +app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get( + "DATABASE_URL", + f"sqlite:///{os.path.join(BASE_DIR, 'casahunter.db')}" +) +app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False +_secret = os.environ.get("SECRET_KEY") +if not _secret: + import secrets as _secrets + _secret = _secrets.token_hex(32) +app.secret_key = _secret + +OLLAMA_MODEL = os.environ.get("OLLAMA_MODEL", "qwen2.5:14b") +OLLAMA_URL = os.environ.get("OLLAMA_URL", "http://localhost:11434") +ANTHROPIC_KEY = os.environ.get("ANTHROPIC_KEY", "") + +db.init_app(app) + +DEFAULT_CITIES = [ + "Vero Beach", "Sebastian", "Stuart", "Jensen Beach", + "Melbourne", "Cocoa Beach", "Titusville", + "Daytona Beach", "Ormond Beach", "New Smyrna Beach", + "St. Augustine", "Jacksonville", "Jacksonville Beach", "Fernandina Beach" +] +DEFAULT_MAX_PRICE = 200000 +DEFAULT_DOWN_PAYMENT = 50000 + + +def get_config(key, default): + row = SearchConfig.query.filter_by(key=key).first() + return row.value if row else default + + +def set_config(key, value): + row = SearchConfig.query.filter_by(key=key).first() + if row: + row.value = str(value) + else: + db.session.add(SearchConfig(key=key, value=str(value))) + db.session.commit() + + +def seed_defaults(): + if Lender.query.count() == 0: + for l in LENDERS: + db.session.add(Lender(**l)) + if SearchCity.query.count() == 0: + for c in DEFAULT_CITIES: + db.session.add(SearchCity(city=c, active=True)) + if not SearchConfig.query.filter_by(key="max_price").first(): + db.session.add(SearchConfig(key="max_price", value=str(DEFAULT_MAX_PRICE))) + if not SearchConfig.query.filter_by(key="down_payment").first(): + db.session.add(SearchConfig(key="down_payment", value=str(DEFAULT_DOWN_PAYMENT))) + db.session.commit() + + +@app.before_request +def init_db(): + if not hasattr(app, "_db_ready"): + db.create_all() + seed_defaults() + app._db_ready = True + + +# ── API: cities autocomplete ────────────────────────────────────────────────── +@app.route("/api/cities") +def api_cities(): + q = request.args.get("q", "").lower() + matches = [c for c in FLORIDA_CITIES if q in c.lower()] if q else FLORIDA_CITIES[:20] + return jsonify(matches[:15]) + + +# ── Dashboard ───────────────────────────────────────────────────────────────── +@app.route("/") +def index(): + max_price = int(get_config("max_price", DEFAULT_MAX_PRICE)) + top_props = Property.query.order_by(Property.score.desc()).limit(6).all() + total = Property.query.count() + favorites = Property.query.filter_by(is_favorite=True).count() + last_scan = ScrapeLog.query.order_by(ScrapeLog.ran_at.desc()).first() + top_lenders = Lender.query.order_by(Lender.match_score.desc()).limit(3).all() + active_cities = SearchCity.query.filter_by(active=True).order_by(SearchCity.city).all() + return render_template("index.html", + properties=top_props, total=total, favorites=favorites, + last_scan=last_scan, top_lenders=top_lenders, + active_cities=active_cities, max_price=max_price + ) + + +# ── Properties list ─────────────────────────────────────────────────────────── +@app.route("/properties") +def properties(): + sort = request.args.get("sort", "score") + source = request.args.get("source", "") + min_score = int(request.args.get("min_score", 0)) + favorites_only = request.args.get("favorites") == "1" + city_filter = request.args.get("city", "") + max_price = int(request.args.get("max_price", get_config("max_price", DEFAULT_MAX_PRICE))) + + q = Property.query + if source: + q = q.filter(Property.source == source) + if min_score > 0: + q = q.filter(Property.score >= min_score) + if favorites_only: + q = q.filter(Property.is_favorite == True) + if city_filter: + q = q.filter(Property.city.ilike(f"%{city_filter}%")) + if max_price: + q = q.filter(Property.price <= max_price) + + order_map = { + "price_asc": Property.price.asc(), + "price_desc": Property.price.desc(), + "newest": Property.created_at.desc(), + } + q = q.order_by(order_map.get(sort, Property.score.desc())) + + props = q.all() + sources = db.session.query(Property.source).distinct().all() + return render_template("properties.html", + properties=props, sources=[s[0] for s in sources], + current_sort=sort, current_source=source, + city_filter=city_filter, max_price=max_price, + config_max_price=int(get_config("max_price", DEFAULT_MAX_PRICE)) + ) + + +# ── Property detail ─────────────────────────────────────────────────────────── +@app.route("/property/") +def property_detail(pid): + prop = Property.query.get_or_404(pid) + lenders = Lender.query.order_by(Lender.match_score.desc()).all() + return render_template("property_detail.html", prop=prop, lenders=lenders) + + +@app.route("/property//analyze", methods=["POST"]) +def analyze(pid): + prop = Property.query.get_or_404(pid) + import ai_analyzer + ai_analyzer.OLLAMA_URL = OLLAMA_URL + analysis = analyze_property( + {"address": prop.address, "city": prop.city, "county": prop.county, + "price": prop.price, "beds": prop.beds, "baths": prop.baths, + "sqft": prop.sqft, "property_type": prop.property_type, + "status": prop.status, "source": prop.source}, + OLLAMA_MODEL, ANTHROPIC_KEY or None + ) + prop.ai_analysis = analysis + db.session.commit() + return jsonify({"analysis": analysis}) + + +@app.route("/property//favorite", methods=["POST"]) +def toggle_favorite(pid): + prop = Property.query.get_or_404(pid) + prop.is_favorite = not prop.is_favorite + db.session.commit() + return jsonify({"is_favorite": prop.is_favorite}) + + +@app.route("/property//notes", methods=["POST"]) +def save_notes(pid): + prop = Property.query.get_or_404(pid) + prop.notes = request.json.get("notes", "") + db.session.commit() + return jsonify({"ok": True}) + + +# ── Lenders ─────────────────────────────────────────────────────────────────── +@app.route("/lenders") +def lenders(): + return render_template("lenders.html", + lenders=Lender.query.order_by(Lender.match_score.desc()).all() + ) + + +# ── Settings ────────────────────────────────────────────────────────────────── +@app.route("/settings", methods=["GET", "POST"]) +def settings(): + if request.method == "POST": + action = request.form.get("action") + + if action == "add_city": + city = request.form.get("city", "").strip() + if city and not SearchCity.query.filter_by(city=city).first(): + db.session.add(SearchCity(city=city, active=True)) + db.session.commit() + flash(f"Ciudad agregada: {city}", "success") + elif city: + existing = SearchCity.query.filter_by(city=city).first() + existing.active = True + db.session.commit() + flash(f"{city} reactivada", "info") + + elif action == "remove_city": + city_id = int(request.form.get("city_id")) + c = SearchCity.query.get(city_id) + if c: + db.session.delete(c) + db.session.commit() + flash(f"Ciudad eliminada: {c.city}", "warning") + + elif action == "toggle_city": + city_id = int(request.form.get("city_id")) + c = SearchCity.query.get(city_id) + if c: + c.active = not c.active + db.session.commit() + + elif action == "save_config": + max_price = request.form.get("max_price", "").strip() + down_payment = request.form.get("down_payment", "").strip() + if max_price and max_price.isdigit(): + set_config("max_price", max_price) + if down_payment and down_payment.isdigit(): + set_config("down_payment", down_payment) + if max_price or down_payment: + flash("Preferencias guardadas", "success") + + return redirect(url_for("settings")) + + cities = SearchCity.query.order_by(SearchCity.city).all() + max_price = int(get_config("max_price", DEFAULT_MAX_PRICE)) + down_payment = int(get_config("down_payment", DEFAULT_DOWN_PAYMENT)) + return render_template("settings.html", + cities=cities, max_price=max_price, + down_payment=down_payment, florida_cities=FLORIDA_CITIES + ) + + +# ── Scan helpers ────────────────────────────────────────────────────────────── +def _read_status(): + try: + with open(STATUS_FILE, encoding="utf-8") as f: + return json.load(f) + except Exception: + return {"running": False, "progress": ""} + +def _save_results_to_db(): + """Lee scan_results.json y guarda en la base de datos.""" + try: + with open(RESULTS_FILE, encoding="utf-8") as f: + data = json.load(f) + except Exception: + return 0, {} + new_count = 0 + for prop_data in data.get("properties", []): + existing = Property.query.filter_by( + address=prop_data.get("address", ""), + source=prop_data.get("source", "") + ).first() + if not existing and prop_data.get("address"): + db.session.add(Property( + source=prop_data.get("source"), + address=prop_data.get("address", ""), + city=prop_data.get("city", ""), + county=prop_data.get("county", ""), + zipcode=prop_data.get("zipcode", ""), + price=prop_data.get("price", 0), + beds=prop_data.get("beds"), + baths=prop_data.get("baths"), + sqft=prop_data.get("sqft"), + property_type=prop_data.get("property_type", "Residential"), + status=prop_data.get("status", ""), + url=prop_data.get("url", ""), + image_url=prop_data.get("image_url", ""), + score=prop_data.get("score", 50) + )) + new_count += 1 + for source, info in data.get("log", {}).items(): + db.session.add(ScrapeLog( + source=source, found=info.get("found", 0), + new=new_count, status=info.get("status", "ok"), message=str(info) + )) + db.session.commit() + return new_count, data.get("log", {}) + + +# ── Scan routes ──────────────────────────────────────────────────────────────── +@app.route("/scan", methods=["POST"]) +def scan(): + st = _read_status() + if st.get("running"): + return jsonify({"status": "already_running", "progress": st["progress"]}) + + active_cities = [c.city for c in SearchCity.query.filter_by(active=True).all()] + max_price = int(get_config("max_price", DEFAULT_MAX_PRICE)) + cities_arg = ",".join(active_cities) + + # Write initial status + with open(STATUS_FILE, "w", encoding="utf-8") as f: + json.dump({"running": True, "progress": "Iniciando..."}, f) + + # Launch scan_runner.py as independent subprocess + runner = os.path.join(BASE_DIR, "scan_runner.py") + subprocess.Popen( + [sys.executable, runner, "--cities", cities_arg, "--max_price", str(max_price)], + creationflags=subprocess.CREATE_NO_WINDOW if os.name == "nt" else 0 + ) + return jsonify({"status": "started", "cities": active_cities, "max_price": max_price}) + + +@app.route("/scan/status") +def scan_status(): + st = _read_status() + # If scan finished, import results to DB + if not st.get("running") and st.get("progress", "").startswith("Completado") and os.path.exists(RESULTS_FILE): + new_count, log = _save_results_to_db() + # Mark results as imported + try: + os.rename(RESULTS_FILE, RESULTS_FILE + ".imported") + except Exception: + pass + st["new"] = new_count + st["log"] = log + return jsonify(st) + + +if __name__ == "__main__": + app.run(host="0.0.0.0", port=5105, debug=False, threaded=True) diff --git a/casa-hunter/app/models.py b/casa-hunter/app/models.py new file mode 100644 index 0000000..df2eb53 --- /dev/null +++ b/casa-hunter/app/models.py @@ -0,0 +1,69 @@ +from flask_sqlalchemy import SQLAlchemy +from datetime import datetime + +db = SQLAlchemy() + +class Property(db.Model): + __tablename__ = 'properties' + id = db.Column(db.Integer, primary_key=True) + source = db.Column(db.String(50)) + address = db.Column(db.String(200)) + city = db.Column(db.String(100)) + county = db.Column(db.String(100)) + state = db.Column(db.String(10), default='FL') + zipcode = db.Column(db.String(10)) + price = db.Column(db.Float) + beds = db.Column(db.Integer) + baths = db.Column(db.Float) + sqft = db.Column(db.Integer) + property_type = db.Column(db.String(50)) + status = db.Column(db.String(50)) + url = db.Column(db.Text) + image_url = db.Column(db.Text) + score = db.Column(db.Integer, default=0) + ai_analysis = db.Column(db.Text) + is_favorite = db.Column(db.Boolean, default=False) + notes = db.Column(db.Text) + created_at = db.Column(db.DateTime, default=datetime.utcnow) + updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) + +class Lender(db.Model): + __tablename__ = 'lenders' + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String(100)) + loan_type = db.Column(db.String(100)) + specialties = db.Column(db.Text) + min_down_pct = db.Column(db.Float) + accepts_new_resident = db.Column(db.Boolean, default=True) + accepts_self_employed = db.Column(db.Boolean, default=True) + requires_2yr_history = db.Column(db.Boolean, default=False) + phone = db.Column(db.String(30)) + email = db.Column(db.String(100)) + website = db.Column(db.String(200)) + contact_script = db.Column(db.Text) + match_score = db.Column(db.Integer, default=0) + notes = db.Column(db.Text) + +class SearchCity(db.Model): + __tablename__ = 'search_cities' + id = db.Column(db.Integer, primary_key=True) + city = db.Column(db.String(100), unique=True) + search_type = db.Column(db.String(20), default='city') # city, county, zip + active = db.Column(db.Boolean, default=True) + added_at = db.Column(db.DateTime, default=datetime.utcnow) + +class SearchConfig(db.Model): + __tablename__ = 'search_config' + id = db.Column(db.Integer, primary_key=True) + key = db.Column(db.String(50), unique=True) + value = db.Column(db.String(200)) + +class ScrapeLog(db.Model): + __tablename__ = 'scrape_logs' + id = db.Column(db.Integer, primary_key=True) + ran_at = db.Column(db.DateTime, default=datetime.utcnow) + source = db.Column(db.String(50)) + found = db.Column(db.Integer, default=0) + new = db.Column(db.Integer, default=0) + status = db.Column(db.String(20)) + message = db.Column(db.Text) diff --git a/casa-hunter/app/scan_results.json b/casa-hunter/app/scan_results.json new file mode 100644 index 0000000..ba5b757 --- /dev/null +++ b/casa-hunter/app/scan_results.json @@ -0,0 +1 @@ +{"properties": [{"source": "Zillow", "address": "1724 SW Diana Ter #37, Stuart, FL 34997", "price": 99900, "beds": 3, "baths": 2, "sqft": 1120, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34997", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1724-SW-Diana-Ter-37-Stuart-FL-34997/2077043090_zpid/", "image_url": "https://photos.zillowstatic.com/fp/e1d15373cf56ccfb4f14d285da677675-p_e.jpg", "property_type": "MANUFACTURED", "score": 95}, {"source": "Zillow", "address": "4284 SE Sweetwood Way #B12023, Stuart, FL 34997", "price": 124900, "beds": 3, "baths": 2, "sqft": 1344, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34997", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4284-SE-Sweetwood-Way-B12023-Stuart-FL-34997/462045687_zpid/", "image_url": "https://photos.zillowstatic.com/fp/5a1b2837ed0bb224430415a45bd76606-p_e.jpg", "property_type": "MANUFACTURED", "score": 95}, {"source": "Zillow", "address": "5000 SE Federal Hwy #2202, Stuart, FL 34997", "price": 85000, "beds": 3, "baths": 2, "sqft": 0, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34997", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/5000-SE-Federal-Hwy-2202-Stuart-FL-34997/2060675346_zpid/", "image_url": "https://photos.zillowstatic.com/fp/81a4fd831238787e9fb38c7f41dc6e2f-p_e.jpg", "property_type": "MANUFACTURED", "score": 95}, {"source": "Zillow", "address": "3510 Applin Way, Melbourne, FL 32901", "price": 115000, "beds": 4, "baths": 2, "sqft": 1166, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32901", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3510-Applin-Way-Melbourne-FL-32901/43491718_zpid/", "image_url": "https://photos.zillowstatic.com/fp/bb61b62de82cfeb75b091dd43ff69681-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 95}, {"source": "Zillow", "address": "4663 Bluejay Ln, Melbourne, FL 32935", "price": 84000, "beds": 3, "baths": 2, "sqft": 0, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32935", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4663-Bluejay-Ln-Melbourne-FL-32935/2091971623_zpid/", "image_url": "https://photos.zillowstatic.com/fp/685060e6d47173451a77268abd0b48fe-p_e.jpg", "property_type": "MANUFACTURED", "score": 95}, {"source": "Zillow", "address": "2033 Mobiland Dr, Melbourne, FL 32935", "price": 60000, "beds": 4, "baths": 2, "sqft": 1600, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32935", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2033-Mobiland-Dr-Melbourne-FL-32935/455178485_zpid/", "image_url": "https://photos.zillowstatic.com/fp/f6d9cc73e912c783069b77b5f7b8bcd3-p_e.jpg", "property_type": "MANUFACTURED", "score": 95}, {"source": "Zillow", "address": "3511 Blue Heron Cir, Titusville, FL 32796", "price": 107000, "beds": 3, "baths": 2, "sqft": 0, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32796", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3511-Blue-Heron-Cir-Titusville-FL-32796/458689602_zpid/", "image_url": "https://photos.zillowstatic.com/fp/0d783f661ab27a41eef4b3236eee979e-p_e.jpg", "property_type": "MANUFACTURED", "score": 95}, {"source": "Zillow", "address": "4300 SE Saint Lucie Boulevard #87, Stuart, FL 34997", "price": 135000, "beds": 2, "baths": 2, "sqft": 912, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34997", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4300-SE-Saint-Lucie-Blvd-LOT-87-Stuart-FL-34997/45691986_zpid/", "image_url": "https://photos.zillowstatic.com/fp/eb9d020951b6b32a4eda6c2d7f7fd82c-p_e.jpg", "property_type": "CONDO", "score": 91}, {"source": "Zillow", "address": "1811 SW Palm City Road #A601, Stuart, FL 34994", "price": 115000, "beds": 2, "baths": 2, "sqft": 1188, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34994", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1811-SW-Palm-City-Rd-APT-A601-Stuart-FL-34994/54567146_zpid/", "image_url": "https://photos.zillowstatic.com/fp/36e3492f677b1670a7367189e1751dcb-p_e.jpg", "property_type": "CONDO", "score": 91}, {"source": "Zillow", "address": "3500 S Kanner Highway #135, Stuart, FL 34994", "price": 82000, "beds": 2, "baths": 2, "sqft": 960, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34994", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3500-S-Kanner-Hwy-LOT-135-Stuart-FL-34994/45687062_zpid/", "image_url": "https://photos.zillowstatic.com/fp/13f308f2c60a62b1da45f919d0bd10ff-p_e.jpg", "property_type": "CONDO", "score": 91}, {"source": "Zillow", "address": "2950 SE Ocean Blvd APT 4, Stuart, FL 34996", "price": 129000, "beds": 2, "baths": 2, "sqft": 1134, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34996", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2950-SE-Ocean-Blvd-APT-4-Stuart-FL-34996/54559241_zpid/", "image_url": "https://photos.zillowstatic.com/fp/05b2566f06a1b7b81ce1d6a93c2c2c09-p_e.jpg", "property_type": "CONDO", "score": 91}, {"source": "Zillow", "address": "1900 S Kanner Hwy APT 5-204, Stuart, FL 34994", "price": 115000, "beds": 2, "baths": 2, "sqft": 1032, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34994", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1900-S-Kanner-Hwy-APT-5-204-Stuart-FL-34994/54566397_zpid/", "image_url": "https://photos.zillowstatic.com/fp/bbdfaae107e58bccea88263a916d0af1-p_e.jpg", "property_type": "CONDO", "score": 91}, {"source": "Zillow", "address": "3500 S Kanner Highway #101, Stuart, FL 34994", "price": 129900, "beds": 2, "baths": 2, "sqft": 888, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34994", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3500-S-Kanner-Hwy-LOT-101-Stuart-FL-34994/45687028_zpid/", "image_url": "https://photos.zillowstatic.com/fp/20eb635f52eb798f7f22ddd0449ef939-p_e.jpg", "property_type": "CONDO", "score": 91}, {"source": "Zillow", "address": "4678 SE Balsawood Ter #B05004, Stuart, FL 34997", "price": 60000, "beds": 2, "baths": 2, "sqft": 1080, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34997", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4678-SE-Balsawood-Ter-B05004-Stuart-FL-34997/457283248_zpid/", "image_url": "https://photos.zillowstatic.com/fp/2d5da689b2fe014a48aab42476ea7790-p_e.jpg", "property_type": "MANUFACTURED", "score": 91}, {"source": "Zillow", "address": "7080 SE Carrotwood Ln #B11008, Stuart, FL 34997", "price": 69000, "beds": 2, "baths": 2, "sqft": 884, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34997", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7080-SE-Carrotwood-Ln-B11008-Stuart-FL-34997/455328377_zpid/", "image_url": "https://photos.zillowstatic.com/fp/bbc8c749f4c2e094ae1cd4cf316e72f9-p_e.jpg", "property_type": "MANUFACTURED", "score": 91}, {"source": "Zillow", "address": "2600 SE Ocean Blvd APT Jj-18, Stuart, FL 34996", "price": 135000, "beds": 2, "baths": 2, "sqft": 1089, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34996", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2600-SE-Ocean-Blvd-APT-JJ-18-Stuart-FL-34996/2064781634_zpid/", "image_url": "https://photos.zillowstatic.com/fp/68f7942eca0398c6ecadc29e30764eff-p_e.jpg", "property_type": "CONDO", "score": 91}, {"source": "Zillow", "address": "4736 NE Blue Heron Ln, Jensen Beach, FL 34957", "price": 135000, "beds": 2, "baths": 2, "sqft": 696, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4736-NE-Blue-Heron-Ln-Jensen-Beach-FL-34957/67181202_zpid/", "image_url": "https://maps.googleapis.com/maps/api/staticmap?mobile=false&sensor=true&maptype=satellite&size=575x242&zoom=17¢er=27.262929916381836,-80.23582458496094&key=AIzaSyBWYJWCA8FNMQvSe_k3LKfDGJaEgdKwsco&signature=EwBrzptfc-n2M-DRR057Zd1djNU=", "property_type": "MANUFACTURED", "score": 91}, {"source": "Zillow", "address": "395 NE Jade Circle, Jensen Beach, FL 34957", "price": 105000, "beds": 2, "baths": 2, "sqft": 1152, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/395-NE-Jade-Cir-Jensen-Beach-FL-34957/459747673_zpid/", "image_url": "https://photos.zillowstatic.com/fp/bb138db62218ddb2b1a0b1a0deb8956c-p_e.jpg", "property_type": "MANUFACTURED", "score": 91}, {"source": "Zillow", "address": "485 Onyx Way, Jensen Beach, FL 34957", "price": 54900, "beds": 2, "baths": 2, "sqft": 1160, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/485-NE-Onyx-Way-Jensen-Beach-FL-34957/460101761_zpid/", "image_url": "https://photos.zillowstatic.com/fp/a6d9982904546036f0620f712f3facac-p_e.jpg", "property_type": "MANUFACTURED", "score": 91}, {"source": "Zillow", "address": "1551 NE 13th Terrace Terrace NE #A13, Jensen Beach, FL 34957", "price": 135000, "beds": 2, "baths": 2, "sqft": 1272, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1551-NE-13th-Ter-APT-A13-Jensen-Beach-FL-34957/441568862_zpid/", "image_url": "https://photos.zillowstatic.com/fp/15dfc2f0916d0513b66f85f285f514e1-p_e.jpg", "property_type": "CONDO", "score": 91}, {"source": "Zillow", "address": "293 NE Moonstone Drive, Jensen Beach, FL 34957", "price": 64900, "beds": 2, "baths": 2, "sqft": 1328, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/293-NE-Moonstone-Dr-Jensen-Beach-FL-34957/2141044750_zpid/", "image_url": "https://photos.zillowstatic.com/fp/c0de5b65c4eefeddc43974804cf43a1c-p_e.jpg", "property_type": "MANUFACTURED", "score": 91}, {"source": "Zillow", "address": "463 Onyx Way, Jensen Beach, FL 34957", "price": 62000, "beds": 2, "baths": 2, "sqft": 1106, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/463-Onyx-Way-Jensen-Beach-FL-34957/352458628_zpid/", "image_url": "https://photos.zillowstatic.com/fp/a03b92ba1236277059998848642c044d-p_e.jpg", "property_type": "MANUFACTURED", "score": 91}, {"source": "Zillow", "address": "4 N North Warner Drive, Jensen Beach, FL 34957", "price": 74900, "beds": 2, "baths": 2, "sqft": 1152, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4-N-North-Warner-Dr-Jensen-Beach-FL-34957/456909601_zpid/", "image_url": "https://photos.zillowstatic.com/fp/54212b17b98e55c9efc51ab2eeaf55ea-p_e.jpg", "property_type": "MANUFACTURED", "score": 91}, {"source": "Zillow", "address": "608 NE Garden View Way, Jensen Beach, FL 34957", "price": 69900, "beds": 2, "baths": 1, "sqft": 648, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/608-NE-Garden-View-Way-Jensen-Beach-FL-34957/52616966_zpid/", "image_url": "https://photos.zillowstatic.com/fp/92406a539b48c8d06e4ac603bbc5763e-p_e.jpg", "property_type": "MANUFACTURED", "score": 91}, {"source": "Zillow", "address": "95 N North Warner Drive, Jensen Beach, FL 34957", "price": 120000, "beds": 2, "baths": 2, "sqft": 1250, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/95-NE-North-Warner-Dr-Jensen-Beach-FL-34957/2095277859_zpid/", "image_url": "https://photos.zillowstatic.com/fp/64eba3afc97f8735447e73a1f31df22e-p_e.jpg", "property_type": "MANUFACTURED", "score": 91}, {"source": "Zillow", "address": "179 NE Emerald Drive, Jensen Beach, FL 34957", "price": 135000, "beds": 2, "baths": 2, "sqft": 1680, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/179-NE-Emerald-Dr-Jensen-Beach-FL-34957/2126886800_zpid/", "image_url": "https://photos.zillowstatic.com/fp/e825ee3a99bfc1436879bfb8615eee6c-p_e.jpg", "property_type": "MANUFACTURED", "score": 91}, {"source": "Zillow", "address": "335 NE Tropicalia Lane, Jensen Beach, FL 34957", "price": 92000, "beds": 2, "baths": 2, "sqft": 768, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/335-NE-Tropicalia-Ln-Jensen-Beach-FL-34957/45667911_zpid/", "image_url": "https://photos.zillowstatic.com/fp/f308293d97706adc9f53b7fcb65b17e7-p_e.jpg", "property_type": "CONDO", "score": 91}, {"source": "Zillow", "address": "3210 N Harbor City Blvd APT 209, Melbourne, FL 32935", "price": 129900, "beds": 2, "baths": 2, "sqft": 1058, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32935", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3210-N-Harbor-City-Blvd-APT-209-Melbourne-FL-32935/43460133_zpid/", "image_url": "https://photos.zillowstatic.com/fp/61f8967f541206af292d16d067e3730c-p_e.jpg", "property_type": "CONDO", "score": 91}, {"source": "Zillow", "address": "608 Williams St, Melbourne, FL 32901", "price": 125000, "beds": 2, "baths": 1, "sqft": 602, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32901", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/608-Williams-St-Melbourne-FL-32901/43491354_zpid/", "image_url": "https://photos.zillowstatic.com/fp/cd3b2dad3037672bc09c1b016e96969d-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 91}, {"source": "Zillow", "address": "25 Elton St #25, Melbourne, FL 32935", "price": 135000, "beds": 2, "baths": 1, "sqft": 740, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32935", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/25-Elton-St-25-Melbourne-FL-32935/60341081_zpid/", "image_url": "https://photos.zillowstatic.com/fp/665a96878a7eee937b41210e8e4135fe-p_e.jpg", "property_type": "TOWNHOUSE", "score": 91}, {"source": "Zillow", "address": "3150 N Harbor City Blvd APT 233, Melbourne, FL 32935", "price": 119500, "beds": 2, "baths": 2, "sqft": 1058, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32935", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3150-N-Harbor-City-Blvd-APT-233-Melbourne-FL-32935/43460204_zpid/", "image_url": "https://photos.zillowstatic.com/fp/5f11751fa5aaa94681448686f46ef09d-p_e.jpg", "property_type": "CONDO", "score": 91}, {"source": "Zillow", "address": "2483 Country Club Dr #C105, Titusville, FL 32780", "price": 75000, "beds": 2, "baths": 2, "sqft": 1075, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2483-Country-Club-Dr-C105-Titusville-FL-32780/43381992_zpid/", "image_url": "https://photos.zillowstatic.com/fp/ca938b5235777a94af9ad50bafc608b3-p_e.jpg", "property_type": "CONDO", "score": 91}, {"source": "Zillow", "address": "1880 Knox McRae Dr Unit 111D, Titusville, FL 32780", "price": 130000, "beds": 2, "baths": 2, "sqft": 880, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1880-Knox-McRae-Dr-UNIT-111D-Titusville-FL-32780/342930339_zpid/", "image_url": "https://photos.zillowstatic.com/fp/ac85441fd590e7bc837536a3de77579f-p_e.jpg", "property_type": "CONDO", "score": 91}, {"source": "Zillow", "address": "2505 Country Club Dr #D115, Titusville, FL 32780", "price": 74500, "beds": 2, "baths": 2, "sqft": 1075, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2505-Country-Club-Dr-D115-Titusville-FL-32780/43382001_zpid/", "image_url": "https://photos.zillowstatic.com/fp/7a4426dff2a11baac667c62f703fbd30-p_e.jpg", "property_type": "CONDO", "score": 91}, {"source": "Zillow", "address": "1765 Harrison St APT 204, Titusville, FL 32780", "price": 121000, "beds": 2, "baths": 2, "sqft": 915, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1765-Harrison-St-APT-204-Titusville-FL-32780/43380588_zpid/", "image_url": "https://photos.zillowstatic.com/fp/18642aa474cf9ec5bd2d0a4452dd2478-p_e.jpg", "property_type": "CONDO", "score": 91}, {"source": "Zillow", "address": "3464 Dove Ct, Titusville, FL 32796", "price": 88500, "beds": 2, "baths": 2, "sqft": 0, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32796", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3464-Dove-Ct-Titusville-FL-32796/456917828_zpid/", "image_url": "https://photos.zillowstatic.com/fp/13334ae59e2a95d22965fdb4133c613f-p_e.jpg", "property_type": "MANUFACTURED", "score": 91}, {"source": "Zillow", "address": "3535 Sable Palm Ln Unit B, Titusville, FL 32780", "price": 115000, "beds": 2, "baths": 2, "sqft": 864, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3535-Sable-Palm-Ln-UNIT-B-Titusville-FL-32780/71029704_zpid/", "image_url": "https://photos.zillowstatic.com/fp/79a21169c682bc049c44b08c211813ce-p_e.jpg", "property_type": "CONDO", "score": 91}, {"source": "Zillow", "address": "190 E Olmstead Dr Unit A11, Titusville, FL 32780", "price": 125000, "beds": 2, "baths": 1, "sqft": 1023, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/190-E-Olmstead-Dr-UNIT-A11-Titusville-FL-32780/54602768_zpid/", "image_url": "https://photos.zillowstatic.com/fp/ab9f6003d475603f3bdfcadf8b5bd090-p_e.jpg", "property_type": "CONDO", "score": 91}, {"source": "Zillow", "address": "170 Astronaut Ln, Titusville, FL 32780", "price": 42300, "beds": 2, "baths": 1, "sqft": 720, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/170-Astronaut-Ln-Titusville-FL-32780/2060511755_zpid/", "image_url": "https://photos.zillowstatic.com/fp/f6c44bd03279423e729d7ee3d146168e-p_e.jpg", "property_type": "MANUFACTURED", "score": 91}, {"source": "Zillow", "address": "2600 SE Ocean Blvd APT F12, Stuart, FL 34996", "price": 109900, "beds": 1, "baths": 2, "sqft": 814, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34996", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2600-SE-Ocean-Blvd-APT-F12-Stuart-FL-34996/54559778_zpid/", "image_url": "https://photos.zillowstatic.com/fp/cfc8c63bf475ab5130f61d572e07e53c-p_e.jpg", "property_type": "CONDO", "score": 87}, {"source": "Zillow", "address": "6470 Borasco Dr APT 2102, Melbourne, FL 32940", "price": 134900, "beds": 1, "baths": 1, "sqft": 598, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32940", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6470-Borasco-Dr-APT-2102-Melbourne-FL-32940/71030951_zpid/", "image_url": "https://photos.zillowstatic.com/fp/45bcc301b24931fef107a83ff0af870d-p_e.jpg", "property_type": "CONDO", "score": 87}, {"source": "Zillow", "address": "3008 Hanson Ave #40, Melbourne, FL 32901", "price": 65000, "beds": 1, "baths": 1, "sqft": 840, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32901", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3008-Hanson-Ave-40-Melbourne-FL-32901/439173036_zpid/", "image_url": "https://photos.zillowstatic.com/fp/cca231bf2f5739df1d71f9148a428fca-p_e.jpg", "property_type": "MANUFACTURED", "score": 87}, {"source": "Zillow", "address": "4476 SE Basswood Ter, Stuart, FL 34997", "price": 169000, "beds": 3, "baths": 2, "sqft": 1568, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34997", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4476-SE-Basswood-Ter-Stuart-FL-34997/2126722996_zpid/", "image_url": "https://photos.zillowstatic.com/fp/9bb1d9e0553c0a77c15aa5a05faea971-p_e.jpg", "property_type": "MANUFACTURED", "score": 85}, {"source": "Zillow", "address": "4432 SE Sweetwood Way #B16012, Stuart, FL 34997", "price": 160000, "beds": 3, "baths": 2, "sqft": 1482, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34997", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4432-SE-Sweetwood-Way-B16012-Stuart-FL-34997/455620137_zpid/", "image_url": "https://photos.zillowstatic.com/fp/df8550284101e926d5d25bd10d920c4f-p_e.jpg", "property_type": "MANUFACTURED", "score": 85}, {"source": "Zillow", "address": "2417 Dakota Dr, Melbourne, FL 32935", "price": 149900, "beds": 3, "baths": 2, "sqft": 1002, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32935", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2417-Dakota-Dr-Melbourne-FL-32935/43470470_zpid/", "image_url": "https://photos.zillowstatic.com/fp/6a0ea9de442329752bededa82804e6d9-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 85}, {"source": "Zillow", "address": "3919 Southwind Dr #423, Melbourne, FL 32904", "price": 144500, "beds": 3, "baths": 2, "sqft": 0, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32904", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3919-Southwind-Dr-423-Melbourne-FL-32904/2065558148_zpid/", "image_url": "https://photos.zillowstatic.com/fp/e5a4f86832c587691aa38ba05347199b-p_e.jpg", "property_type": "MANUFACTURED", "score": 85}, {"source": "Zillow", "address": "3512 Davinci Way #2063, Melbourne, FL 32901", "price": 170000, "beds": 3, "baths": 2, "sqft": 1140, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32901", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3512-Davinci-Way-2063-Melbourne-FL-32901/80774073_zpid/", "image_url": "https://photos.zillowstatic.com/fp/e0268cd5d19d68b11d44e72395d71925-p_e.jpg", "property_type": "CONDO", "score": 85}, {"source": "Zillow", "address": "1717 Tropic St, Titusville, FL 32796", "price": 172500, "beds": 3, "baths": 2, "sqft": 952, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32796", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1717-Tropic-St-Titusville-FL-32796/43376758_zpid/", "image_url": "https://photos.zillowstatic.com/fp/02d10d94bbf127e9498be9260e095bd9-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 85}, {"source": "Zillow", "address": "950 S Kanner Highway #C-10, Stuart, FL 34994", "price": 159900, "beds": 2, "baths": 2, "sqft": 875, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34994", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/950-S-Kanner-Hwy-APT-C10-Stuart-FL-34994/54566515_zpid/", "image_url": "https://photos.zillowstatic.com/fp/c838401f6711846fc3cd39b5cc325b7a-p_e.jpg", "property_type": "CONDO", "score": 81}, {"source": "Zillow", "address": "1225 NW 21st Street #7-708, Stuart, FL 34994", "price": 154900, "beds": 2, "baths": 2, "sqft": 1014, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34994", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1225-NW-21st-St-7-708-Stuart-FL-34994/440224485_zpid/", "image_url": "https://photos.zillowstatic.com/fp/24491bccc820d8d1cfb5b5752ae2708e-p_e.jpg", "property_type": "CONDO", "score": 81}, {"source": "Zillow", "address": "2950 SE Ocean Blvd APT 12-2, Stuart, FL 34996", "price": 159000, "beds": 2, "baths": 2, "sqft": 1044, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34996", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2950-SE-Ocean-Blvd-APT-12-2-Stuart-FL-34996/54559287_zpid/", "image_url": "https://photos.zillowstatic.com/fp/2c1ab42b508d8cca5e9d2ee250dbe143-p_e.jpg", "property_type": "CONDO", "score": 81}, {"source": "Zillow", "address": "4453 Heartwood Trail, Stuart, FL 34997", "price": 150000, "beds": 2, "baths": 2, "sqft": 1512, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34997", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4453-SE-Heartwood-Trl-Stuart-FL-34997/462090942_zpid/", "image_url": "https://photos.zillowstatic.com/fp/7dec01008ebba4939e0100f44f2af630-p_e.jpg", "property_type": "MANUFACTURED", "score": 81}, {"source": "Zillow", "address": "4743 NE Blue Heron Lane #7, Jensen Beach, FL 34957", "price": 159000, "beds": 2, "baths": 2, "sqft": 1100, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4743-NE-Blue-Heron-Ln-7-Jensen-Beach-FL-34957/448099380_zpid/", "image_url": "https://photos.zillowstatic.com/fp/42bbe7bb618e6810c2b20aacf15b70e1-p_e.jpg", "property_type": "CONDO", "score": 81}, {"source": "Zillow", "address": "315 NE Cardinal Ln, Jensen Beach, FL 34957", "price": 148889, "beds": 2, "baths": 2, "sqft": 849, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/315-NE-Cardinal-Ln-Jensen-Beach-FL-34957/52616988_zpid/", "image_url": "https://photos.zillowstatic.com/fp/a7478d2fe2a4eb30d9d1c3fac159746d-p_e.jpg", "property_type": "MANUFACTURED", "score": 81}, {"source": "Zillow", "address": "1310 NE 14th Court Apt K19, Jensen Beach, FL 34957", "price": 149900, "beds": 2, "baths": 2, "sqft": 1272, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1310-NE-14th-Ct-APT-K19-Jensen-Beach-FL-34957/45666720_zpid/", "image_url": "https://photos.zillowstatic.com/fp/ac36deab433d3470ef5afb750ee55a74-p_e.jpg", "property_type": "CONDO", "score": 81}, {"source": "Zillow", "address": "1561 NE 12th Terrace #C-14, Jensen Beach, FL 34957", "price": 170000, "beds": 2, "baths": 2, "sqft": 1272, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1561-NE-12th-Ter-APT-C14-Jensen-Beach-FL-34957/448669764_zpid/", "image_url": "https://photos.zillowstatic.com/fp/cc7749939b8e47d0b9299a21923a516b-p_e.jpg", "property_type": "CONDO", "score": 81}, {"source": "Zillow", "address": "315 NE Cardinal NE #L15, Jensen Beach, FL 34957", "price": 148888, "beds": 2, "baths": 2, "sqft": 869, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/315-NE-Cardinal-NE-L15-Jensen-Beach-FL-34957/460734753_zpid/", "image_url": "https://photos.zillowstatic.com/fp/871fd207396c71076b30dce31e719bdb-p_e.jpg", "property_type": "MANUFACTURED", "score": 81}, {"source": "Zillow", "address": "2727 N Wickham Rd APT 103-5, Melbourne, FL 32935", "price": 149900, "beds": 2, "baths": 2, "sqft": 938, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32935", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2727-N-Wickham-Rd-APT-103-5-Melbourne-FL-32935/43460929_zpid/", "image_url": "https://photos.zillowstatic.com/fp/a206e58d6ad134e0843e070b02a6e74c-p_e.jpg", "property_type": "CONDO", "score": 81}, {"source": "Zillow", "address": "4610 Lake Waterford Way APT 8-101, Melbourne, FL 32901", "price": 149900, "beds": 2, "baths": 2, "sqft": 965, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32901", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4610-Lake-Waterford-Way-APT-8-101-Melbourne-FL-32901/54618094_zpid/", "image_url": "https://photos.zillowstatic.com/fp/75b16289d7ac78eae0be2aed50aebe2a-p_e.jpg", "property_type": "CONDO", "score": 81}, {"source": "Zillow", "address": "519 Williams St, Melbourne, FL 32901", "price": 157975, "beds": 2, "baths": 1, "sqft": 629, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32901", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/519-Williams-St-Melbourne-FL-32901/43491242_zpid/", "image_url": "https://photos.zillowstatic.com/fp/405938e6ecf1c78823435ba6c233860f-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 81}, {"source": "Zillow", "address": "1001 W Eau Gallie Blvd APT 228, Melbourne, FL 32935", "price": 149900, "beds": 2, "baths": 2, "sqft": 1058, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32935", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1001-W-Eau-Gallie-Blvd-APT-228-Melbourne-FL-32935/54615898_zpid/", "image_url": "https://photos.zillowstatic.com/fp/1b86a28e7858e652842af85edb7544c9-p_e.jpg", "property_type": "CONDO", "score": 81}, {"source": "Zillow", "address": "5600 N Banana River Blvd APT 14, Cocoa Beach, FL 32931", "price": 159900, "beds": 2, "baths": 1, "sqft": 759, "city": "Cocoa Beach", "state": "FL", "county": "Brevard", "zipcode": "32931", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/5600-N-Banana-River-Blvd-APT-14-Cocoa-Beach-FL-32931/54607218_zpid/", "image_url": "https://photos.zillowstatic.com/fp/a10a2c2fc45ebd32899b1e780ca4e1ee-p_e.jpg", "property_type": "CONDO", "score": 81}, {"source": "Zillow", "address": "215 N Grannis Ave, Titusville, FL 32796", "price": 144900, "beds": 2, "baths": 1, "sqft": 714, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32796", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/215-N-Grannis-Ave-Titusville-FL-32796/43376273_zpid/", "image_url": "https://photos.zillowstatic.com/fp/2dd775a52584a6396a085b53194f46d1-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 81}, {"source": "Zillow", "address": "1860 Knox McRae Dr Unit 102A, Titusville, FL 32780", "price": 140000, "beds": 2, "baths": 2, "sqft": 880, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1860-Knox-McRae-Dr-UNIT-102A-Titusville-FL-32780/462148031_zpid/", "image_url": "https://photos.zillowstatic.com/fp/04790c70d5f3dc50834a8018f6ea7f0c-p_e.jpg", "property_type": "CONDO", "score": 81}, {"source": "Zillow", "address": "2592 Demaret Dr #326B, Titusville, FL 32780", "price": 159900, "beds": 2, "baths": 2, "sqft": 1200, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2592-Demaret-Dr-326B-Titusville-FL-32780/43380536_zpid/", "image_url": "https://photos.zillowstatic.com/fp/5f94b2a60fa52d4593570b33f8f503e1-p_e.jpg", "property_type": "CONDO", "score": 81}, {"source": "Zillow", "address": "1281 Cheney Hwy APT H, Titusville, FL 32780", "price": 139000, "beds": 2, "baths": 2, "sqft": 962, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1281-Cheney-Hwy-APT-H-Titusville-FL-32780/66677652_zpid/", "image_url": "https://photos.zillowstatic.com/fp/795837b77ac00ab37bbc48aec33f1ac1-p_e.jpg", "property_type": "TOWNHOUSE", "score": 81}, {"source": "Zillow", "address": "3680 Barna Ave Unit 216, Titusville, FL 32780", "price": 159000, "beds": 2, "baths": 2, "sqft": 1157, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3680-Barna-Ave-UNIT-216-Titusville-FL-32780/43380684_zpid/", "image_url": "https://photos.zillowstatic.com/fp/49d922e6ee6b9f25a3031a2271a7d1c2-p_e.jpg", "property_type": "CONDO", "score": 81}, {"source": "Zillow", "address": "10725 S Ocean Dr Lot 468, Jensen Beach, FL 34957", "price": 160000, "beds": 1, "baths": 1, "sqft": 284, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/10725-S-Ocean-Dr-LOT-468-Jensen-Beach-FL-34957/47863055_zpid/", "image_url": "https://photos.zillowstatic.com/fp/ff547ef91ce544d0ce5547c9e51a281b-p_e.jpg", "property_type": "MANUFACTURED", "score": 77}, {"source": "Zillow", "address": "1001 W Eau Gallie Blvd APT 330, Melbourne, FL 32935", "price": 152500, "beds": 1, "baths": 2, "sqft": 828, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32935", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1001-W-Eau-Gallie-Blvd-APT-330-Melbourne-FL-32935/54615906_zpid/", "image_url": "https://photos.zillowstatic.com/fp/e8f8d5ddea28f90d571f2bf70e3b7199-p_e.jpg", "property_type": "CONDO", "score": 77}, {"source": "Zillow", "address": "390 W Cocoa Beach Cswy APT 10-2, Cocoa Beach, FL 32931", "price": 138800, "beds": 1, "baths": 1, "sqft": 512, "city": "Cocoa Beach", "state": "FL", "county": "Brevard", "zipcode": "32931", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/390-W-Cocoa-Beach-Cswy-APT-10-2-Cocoa-Beach-FL-32931/54607755_zpid/", "image_url": "https://photos.zillowstatic.com/fp/8f7c3b7a7aa8745485457f2994115ec3-p_e.jpg", "property_type": "CONDO", "score": 77}, {"source": "Zillow", "address": "518 Wisteria Dr, Melbourne, FL 32901", "price": 189000, "beds": 3, "baths": 1, "sqft": 936, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32901", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/518-Wisteria-Dr-Melbourne-FL-32901/43475952_zpid/", "image_url": "https://photos.zillowstatic.com/fp/75c2413fdca57325c5923b6824ed3c93-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 75}, {"source": "Zillow", "address": "738 Lund Cir, Melbourne, FL 32901", "price": 199900, "beds": 4, "baths": 2, "sqft": 1859, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32901", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/738-Lund-Cir-Melbourne-FL-32901/43487280_zpid/", "image_url": "https://photos.zillowstatic.com/fp/08353a33f679de22323cd6a7f34331e7-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 75}, {"source": "Zillow", "address": "2455 Pepper Ave, Melbourne, FL 32935", "price": 179900, "beds": 3, "baths": 1, "sqft": 1286, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32935", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2455-Pepper-Ave-Melbourne-FL-32935/43469512_zpid/", "image_url": "https://photos.zillowstatic.com/fp/d36b78ce6ec6fe42c5cb494b5d1a91ba-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 75}, {"source": "Zillow", "address": "941 Croton Rd, Melbourne, FL 32935", "price": 199900, "beds": 3, "baths": 1, "sqft": 912, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32935", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/941-Croton-Rd-Melbourne-FL-32935/43471218_zpid/", "image_url": "https://photos.zillowstatic.com/fp/b46a558522b6cb2a8b83e8c9b78ea281-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 75}, {"source": "Zillow", "address": "110 Turpial Way APT 102, Melbourne, FL 32901", "price": 175000, "beds": 3, "baths": 2, "sqft": 1175, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32901", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/110-Turpial-Way-APT-102-Melbourne-FL-32901/80776798_zpid/", "image_url": "https://photos.zillowstatic.com/fp/96e3d6d71f65649f9825885a32859bd0-p_e.jpg", "property_type": "CONDO", "score": 75}, {"source": "Zillow", "address": "7667 N Wickham Rd APT 1416, Melbourne, FL 32940", "price": 189900, "beds": 3, "baths": 2, "sqft": 1256, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32940", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7667-N-Wickham-Rd-APT-1416-Melbourne-FL-32940/80767182_zpid/", "image_url": "https://photos.zillowstatic.com/fp/afd79801dc881eae2a52a7dd15dbe387-p_e.jpg", "property_type": "CONDO", "score": 75}, {"source": "Zillow", "address": "1411 Gibbs St, Melbourne, FL 32901", "price": 175000, "beds": 3, "baths": 1, "sqft": 912, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32901", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1411-Gibbs-St-Melbourne-FL-32901/43491999_zpid/", "image_url": "https://photos.zillowstatic.com/fp/6c047e8902a79c1f30ee24c6034464c9-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 75}, {"source": "Zillow", "address": "37 Sapphire St, Melbourne, FL 32904", "price": 199990, "beds": 3, "baths": 2, "sqft": 1242, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32904", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/37-Sapphire-St-Melbourne-FL-32904/54616803_zpid/", "image_url": "https://photos.zillowstatic.com/fp/c2c14d0f958b91b79df674f2971eb848-p_e.jpg", "property_type": "MANUFACTURED", "score": 75}, {"source": "Zillow", "address": "1765 Thomas St, Titusville, FL 32780", "price": 199007, "beds": 3, "baths": 2, "sqft": 1302, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1765-Thomas-St-Titusville-FL-32780/43383669_zpid/", "image_url": "https://photos.zillowstatic.com/fp/c4409cb153933fcf4d83c720b4602792-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 75}, {"source": "Zillow", "address": "1006 1st Ave, Titusville, FL 32780", "price": 184999, "beds": 3, "baths": 2, "sqft": 1085, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1006-1st-Ave-Titusville-FL-32780/43376659_zpid/", "image_url": "https://photos.zillowstatic.com/fp/93b64d570941b699e40145ddac0500d2-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 75}, {"source": "Zillow", "address": "2960 Beale St, Titusville, FL 32796", "price": 202500, "beds": 3, "baths": 2, "sqft": 1355, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32796", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2960-Beale-St-Titusville-FL-32796/43373444_zpid/", "image_url": "https://photos.zillowstatic.com/fp/4551b81b5e85d3cc96586ad2c2ebc54b-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 75}, {"source": "Zillow", "address": "1660 Barna Ave, Titusville, FL 32780", "price": 175000, "beds": 3, "baths": 2, "sqft": 1127, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1660-Barna-Ave-Titusville-FL-32780/43378610_zpid/", "image_url": "https://photos.zillowstatic.com/fp/e1c2189c632781217355e21a83e4ef01-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 75}, {"source": "Zillow", "address": "3890 Barcelona St, Titusville, FL 32796", "price": 189000, "beds": 3, "baths": 1, "sqft": 960, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32796", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3890-Barcelona-St-Titusville-FL-32796/43374935_zpid/", "image_url": "https://photos.zillowstatic.com/fp/2ca687a0136cd34a686eeb05a927486d-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 75}, {"source": "Zillow", "address": "1400 Milton St, Titusville, FL 32780", "price": 199900, "beds": 3, "baths": 2, "sqft": 1400, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1400-Milton-St-Titusville-FL-32780/43383574_zpid/", "image_url": "https://photos.zillowstatic.com/fp/899d0639ae21983561704d078dac609f-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 75}, {"source": "Zillow", "address": "1980 Old Dixie Hwy, Titusville, FL 32796", "price": 189999, "beds": 3, "baths": 2, "sqft": 1020, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32796", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1980-Old-Dixie-Hwy-Titusville-FL-32796/43372229_zpid/", "image_url": "https://photos.zillowstatic.com/fp/b06fdc0be79eb4b427c56ac8218e9aef-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 75}, {"source": "Zillow", "address": "2235 Anna Dr, Titusville, FL 32796", "price": 189990, "beds": 3, "baths": 2, "sqft": 1140, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32796", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2235-Anna-Dr-Titusville-FL-32796/43375965_zpid/", "image_url": "https://photos.zillowstatic.com/fp/d052391605704c64a25929d4f42ec175-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 75}, {"source": "Zillow", "address": "1225 NW 21st St #14-140, Stuart, FL 34994", "price": 187900, "beds": 2, "baths": 2, "sqft": 1040, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34994", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1225-NW-21st-St-14-140-Stuart-FL-34994/352259433_zpid/", "image_url": "https://maps.googleapis.com/maps/api/staticmap?mobile=false&sensor=true&maptype=satellite&size=575x242&zoom=17¢er=27.230775833129883,-80.27058410644531&key=AIzaSyBWYJWCA8FNMQvSe_k3LKfDGJaEgdKwsco&signature=KZvd-6l81Itrw_1m4bupuVd7VKk=", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "3832 SE Jefferson Street, Stuart, FL 34997", "price": 200000, "beds": 2, "baths": 3, "sqft": 1400, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34997", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3832-SE-Jefferson-St-Stuart-FL-34997/45685704_zpid/", "image_url": "https://photos.zillowstatic.com/fp/2fe4de2d53462b1412aa51f4449c1058-p_e.jpg", "property_type": "TOWNHOUSE", "score": 71}, {"source": "Zillow", "address": "5373 SE Miles Grant Road #C-105, Stuart, FL 34997", "price": 187900, "beds": 2, "baths": 2, "sqft": 1186, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34997", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/5373-SE-Miles-Grant-Rd-APT-C105-Stuart-FL-34997/2059907544_zpid/", "image_url": "https://photos.zillowstatic.com/fp/c25480580c70cd862783a7d37e80beee-p_e.jpg", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "1238 SW Buckskin Trail, Stuart, FL 34997", "price": 179000, "beds": 2, "baths": 1, "sqft": 396, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34997", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1238-SW-Buckskin-Trl-Stuart-FL-34997/54562918_zpid/", "image_url": "https://photos.zillowstatic.com/fp/662691ff8c9c4672f3dc92baadcac581-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 71}, {"source": "Zillow", "address": "361 SW South River Drive #103, Stuart, FL 34997", "price": 190000, "beds": 2, "baths": 2, "sqft": 1035, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34997", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/361-SW-South-River-Dr-APT-103-Stuart-FL-34997/45687309_zpid/", "image_url": "https://photos.zillowstatic.com/fp/aaaf465b6f1047b54446fae928f8d34c-p_e.jpg", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "6537 SE Federal Highway #202, Stuart, FL 34997", "price": 184900, "beds": 2, "baths": 2, "sqft": 969, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34997", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6537-SE-Federal-Hwy-APT-202-Stuart-FL-34997/71743577_zpid/", "image_url": "https://photos.zillowstatic.com/fp/7036ae73150d92021f747a79efa90949-p_e.jpg", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "6531 SE Federal Highway #E202, Stuart, FL 34997", "price": 180000, "beds": 2, "baths": 2, "sqft": 992, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34997", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6531-SE-Federal-Hwy-APT-E202-Stuart-FL-34997/45683669_zpid/", "image_url": "https://photos.zillowstatic.com/fp/d63d55a4199de63761d76d0803df2434-p_e.jpg", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "6403 SE Brandywine Court #223, Stuart, FL 34997", "price": 198000, "beds": 2, "baths": 2, "sqft": 1400, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34997", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6403-SE-Brandywine-Ct-APT-223-Stuart-FL-34997/45669967_zpid/", "image_url": "https://photos.zillowstatic.com/fp/b91188440cf3a8949bc6ecadfb850d91-p_e.jpg", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "2150 SE Letha Ct APT A, Stuart, FL 34994", "price": 175000, "beds": 2, "baths": 1, "sqft": 876, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34994", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2150-SE-Letha-Ct-APT-A-Stuart-FL-34994/45656793_zpid/", "image_url": "https://photos.zillowstatic.com/fp/e4ab7ab00490fa0f6c3b63e2d6a5d863-p_e.jpg", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "800 NW Fork Rd APT 3-12, Stuart, FL 34994", "price": 175000, "beds": 2, "baths": 2, "sqft": 1068, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34994", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/800-NW-Fork-Rd-APT-3-12-Stuart-FL-34994/455223393_zpid/", "image_url": "https://photos.zillowstatic.com/fp/92596d464d2c04700ae2408943ef313b-p_e.jpg", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "950 S Kanner Highway #905, Stuart, FL 34994", "price": 175000, "beds": 2, "baths": 2, "sqft": 1164, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34994", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/950-S-Kanner-Hwy-APT-905-Stuart-FL-34994/54567103_zpid/", "image_url": "https://photos.zillowstatic.com/fp/111e4b1813d4bcd4ee1751fa42e03017-p_e.jpg", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "250 SE Four Winds Dr APT 105, Stuart, FL 34996", "price": 203500, "beds": 2, "baths": 2, "sqft": 1310, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34996", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/250-SE-Four-Winds-Dr-APT-105-Stuart-FL-34996/54561594_zpid/", "image_url": "https://photos.zillowstatic.com/fp/e5d81770bf5af4945d4550e4b78aa084-p_e.jpg", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "2950 SE Ocean Blvd. #135-8, Stuart, FL 34996", "price": 180000, "beds": 2, "baths": 2, "sqft": 1134, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34996", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2950-SE-Ocean-Blvd-APT-135-8-Stuart-FL-34996/54559646_zpid/", "image_url": "https://photos.zillowstatic.com/fp/f52dee23cf85de78885aee7dedef1682-p_e.jpg", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "1225 NW 21st Street #36-3609, Stuart, FL 34994", "price": 175000, "beds": 2, "baths": 2, "sqft": 1014, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34994", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1225-NW-21st-St-36-3609-Stuart-FL-34994/45671033_zpid/", "image_url": "https://photos.zillowstatic.com/fp/24b028ee436d2e15514b757aaa23f5bd-p_e.jpg", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "6531 SE Federal Highway #M112, Stuart, FL 34997", "price": 199900, "beds": 2, "baths": 2, "sqft": 1084, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34997", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6531-SE-Federal-Hwy-APT-M112-Stuart-FL-34997/45683730_zpid/", "image_url": "https://photos.zillowstatic.com/fp/d91093e746defbc104fc2192a0075d59-p_e.jpg", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "6537 SE Federal Hwy #3202, Stuart, FL 34997", "price": 189000, "beds": 2, "baths": 2, "sqft": 967, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34997", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6537-SE-Federal-Hwy-3202-Stuart-FL-34997/2111646408_zpid/", "image_url": "https://photos.zillowstatic.com/fp/51d08a02df952f84dd86a627dee0e422-p_e.jpg", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "1811 SW Palm City Road #A202, Stuart, FL 34994", "price": 199500, "beds": 2, "baths": 2, "sqft": 1188, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34994", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1811-SW-Palm-City-Rd-APT-A202-Stuart-FL-34994/447470920_zpid/", "image_url": "https://photos.zillowstatic.com/fp/eb6730864fdaf07574754a3adef2fa24-p_e.jpg", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "1421 NE 14th Court #Q-19, Jensen Beach, FL 34957", "price": 185000, "beds": 2, "baths": 2, "sqft": 826, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1421-NE-14th-Ct-APT-Q19-Jensen-Beach-FL-34957/45667742_zpid/", "image_url": "https://photos.zillowstatic.com/fp/86761ef94a15710036cd2091db0136fb-p_e.jpg", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "3914 NW Cinnamon Tree Circle, Jensen Beach, FL 34957", "price": 192000, "beds": 2, "baths": 2, "sqft": 1037, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3914-NW-Cinnamon-Tree-Cir-Jensen-Beach-FL-34957/45658315_zpid/", "image_url": "https://photos.zillowstatic.com/fp/c7bd8b32a12155f03ff01682fbbbd3b7-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 71}, {"source": "Zillow", "address": "1637 NE Nautical Pl APT 807, Jensen Beach, FL 34957", "price": 185000, "beds": 2, "baths": 2, "sqft": 961, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1637-NE-Nautical-Pl-APT-807-Jensen-Beach-FL-34957/45667793_zpid/", "image_url": "https://photos.zillowstatic.com/fp/60e1d0c5c23105e4bc31ccfb656c6766-p_e.jpg", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "3662 NW Adriatic Lane, Jensen Beach, FL 34957", "price": 205000, "beds": 2, "baths": 2, "sqft": 1067, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3662-NW-Adriatic-Ln-Jensen-Beach-FL-34957/71743994_zpid/", "image_url": "https://photos.zillowstatic.com/fp/5ae911f7f4a6690d3e0cbeb5df7a941e-p_e.jpg", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "3907 NW Cinnamon Tree Cir, Jensen Beach, FL 34957", "price": 199000, "beds": 2, "baths": 2, "sqft": 1037, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3907-NW-Cinnamon-Tree-Cir-Jensen-Beach-FL-34957/2132903091_zpid/", "image_url": "https://photos.zillowstatic.com/fp/1c8108fde87dbcd77b9dfbb6363b095f-p_e.jpg", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "13827 S Indian River Drive, Jensen Beach, FL 34957", "price": 179000, "beds": 2, "baths": 2, "sqft": 850, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/13827-S-Indian-River-Dr-Jensen-Beach-FL-34957/47862568_zpid/", "image_url": "https://photos.zillowstatic.com/fp/3bcaf4a547baa8e76f8e42bebf6fb742-p_e.jpg", "property_type": "MANUFACTURED", "score": 71}, {"source": "Zillow", "address": "1555 NE Beacon Drive Apt 1006, Jensen Beach, FL 34957", "price": 199900, "beds": 2, "baths": 2, "sqft": 961, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1555-NE-Beacon-Dr-APT-1006-Jensen-Beach-FL-34957/45667807_zpid/", "image_url": "https://photos.zillowstatic.com/fp/1a033e8fed2022e349011117a70ffb53-p_e.jpg", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "2013 NE Collins Cir APT 4-60, Jensen Beach, FL 34957", "price": 200000, "beds": 2, "baths": 2, "sqft": 903, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2013-NE-Collins-Cir-APT-4-60-Jensen-Beach-FL-34957/45669108_zpid/", "image_url": "https://photos.zillowstatic.com/fp/04a89308c7d1451a57d2a1dbb68fada1-p_e.jpg", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "735 Players Ct, Melbourne, FL 32940", "price": 199000, "beds": 2, "baths": 2, "sqft": 994, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32940", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/735-Players-Ct-Melbourne-FL-32940/66679651_zpid/", "image_url": "https://photos.zillowstatic.com/fp/2ef486e18185315b7936c4d6b528a41a-p_e.jpg", "property_type": "TOWNHOUSE", "score": 71}, {"source": "Zillow", "address": "1927 Westwood Blvd, Melbourne, FL 32901", "price": 199999, "beds": 2, "baths": 2, "sqft": 625, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32901", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1927-Westwood-Blvd-Melbourne-FL-32901/43487648_zpid/", "image_url": "https://photos.zillowstatic.com/fp/68e9d4468f1dc5c9312ac89d3372f1b5-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 71}, {"source": "Zillow", "address": "3799 S Banana River Blvd APT 505, Cocoa Beach, FL 32931", "price": 200000, "beds": 2, "baths": 2, "sqft": 1058, "city": "Cocoa Beach", "state": "FL", "county": "Brevard", "zipcode": "32931", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3799-S-Banana-River-Blvd-APT-505-Cocoa-Beach-FL-32931/43423863_zpid/", "image_url": "https://photos.zillowstatic.com/fp/de58479dae52ea5d57d20605298a4e94-p_e.jpg", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "1575 Bunker Hill Ct, Titusville, FL 32796", "price": 179999, "beds": 2, "baths": 2, "sqft": 1074, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32796", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1575-Bunker-Hill-Ct-Titusville-FL-32796/43373988_zpid/", "image_url": "https://photos.zillowstatic.com/fp/6ae3f1b2ea92dbd57bb4021a500daffc-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 71}, {"source": "Zillow", "address": "4500 Coleridge Ave, Titusville, FL 32780", "price": 189900, "beds": 2, "baths": 1, "sqft": 704, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4500-Coleridge-Ave-Titusville-FL-32780/43383284_zpid/", "image_url": "https://photos.zillowstatic.com/fp/1ce12fe78aa92b1d0bb69e9ee1a37a6b-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 71}, {"source": "Zillow", "address": "1670 S Park Ave, Titusville, FL 32780", "price": 200000, "beds": 2, "baths": 3, "sqft": 1345, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1670-S-Park-Ave-Titusville-FL-32780/66676771_zpid/", "image_url": "https://photos.zillowstatic.com/fp/77926da041d4ba15464ba30ef6c7381b-p_e.jpg", "property_type": "TOWNHOUSE", "score": 71}, {"source": "Zillow", "address": "3429 Joe Murell Dr, Titusville, FL 32780", "price": 185000, "beds": 2, "baths": 2, "sqft": 1088, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3429-Joe-Murell-Dr-Titusville-FL-32780/66676599_zpid/", "image_url": "https://photos.zillowstatic.com/fp/126f71ec4179a2f57206cc1334ceb6c2-p_e.jpg", "property_type": "TOWNHOUSE", "score": 71}, {"source": "Zillow", "address": "2465 S Washington Ave APT A-402, Titusville, FL 32780", "price": 199900, "beds": 2, "baths": 2, "sqft": 830, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2465-S-Washington-Ave-APT-A-402-Titusville-FL-32780/54602330_zpid/", "image_url": "https://photos.zillowstatic.com/fp/a0b876f3816ae9a8819d0883d86fbc2e-p_e.jpg", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "3003 Finsterwald Dr, Titusville, FL 32780", "price": 179900, "beds": 2, "baths": 3, "sqft": 1469, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3003-Finsterwald-Dr-Titusville-FL-32780/43381083_zpid/", "image_url": "https://photos.zillowstatic.com/fp/838853467cf218d64fc3f3c6f745df22-p_e.jpg", "property_type": "CONDO", "score": 71}, {"source": "Zillow", "address": "3687 Royal Oak Dr #6, Titusville, FL 32780", "price": 185000, "beds": 2, "baths": 2, "sqft": 1320, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3687-Royal-Oak-Dr-6-Titusville-FL-32780/43380631_zpid/", "image_url": "https://photos.zillowstatic.com/fp/e599f30134771e480868e3c8f520b22b-p_e.jpg", "property_type": "TOWNHOUSE", "score": 71}, {"source": "Zillow", "address": "147 E Towne Pl, Titusville, FL 32796", "price": 185000, "beds": 2, "baths": 2, "sqft": 1024, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32796", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/147-E-Towne-Pl-Titusville-FL-32796/43375788_zpid/", "image_url": "https://photos.zillowstatic.com/fp/5d2a3dbcb537b9d3b7b5e7876d2d4796-p_e.jpg", "property_type": "TOWNHOUSE", "score": 71}, {"source": "Zillow", "address": "905 Cedar Dr, Melbourne, FL 32901", "price": 216000, "beds": 4, "baths": 2, "sqft": 1170, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32901", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/905-Cedar-Dr-Melbourne-FL-32901/43491673_zpid/", "image_url": "https://photos.zillowstatic.com/fp/e4c12d6dacacb6a5fed8cc161a9840ec-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 68}, {"source": "Zillow", "address": "2521 Pond St, Melbourne, FL 32901", "price": 226900, "beds": 6, "baths": 4, "sqft": 2132, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32901", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2521-Pond-St-Melbourne-FL-32901/43492223_zpid/", "image_url": "https://photos.zillowstatic.com/fp/be69434f82ac5d578718984ffd003e42-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 68}, {"source": "Zillow", "address": "397 Oak Haven Dr, Melbourne, FL 32940", "price": 225000, "beds": 3, "baths": 2, "sqft": 1259, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32940", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/397-Oak-Haven-Dr-Melbourne-FL-32940/66679849_zpid/", "image_url": "https://photos.zillowstatic.com/fp/751af44b24de5727b9a3feace1926bec-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 68}, {"source": "Zillow", "address": "801 Espanola Way, Melbourne, FL 32901", "price": 225000, "beds": 3, "baths": 2, "sqft": 1122, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32901", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/801-Espanola-Way-Melbourne-FL-32901/43487374_zpid/", "image_url": "https://photos.zillowstatic.com/fp/8f68314e01b9c16af90f4f1011c87cbb-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 68}, {"source": "Zillow", "address": "514 Hickory St, Melbourne, FL 32901", "price": 224995, "beds": 3, "baths": 2, "sqft": 1035, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32901", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/514-Hickory-St-Melbourne-FL-32901/54616371_zpid/", "image_url": "https://photos.zillowstatic.com/fp/d2cd34976771e9e73e719411754b59f6-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 68}, {"source": "Zillow", "address": "1817 Palm Boulevard, Melbourne, FL 32901", "price": 225000, "beds": 4, "baths": 2, "sqft": 2434, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32901", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1817-Palm-Blvd-Melbourne-FL-32901/43487585_zpid/", "image_url": "https://photos.zillowstatic.com/fp/5ca77e45f9c7a1e32548e4d0f0985b21-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 68}, {"source": "Zillow", "address": "163 Ash St, Melbourne, FL 32904", "price": 229000, "beds": 3, "baths": 1, "sqft": 1032, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32904", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/163-Ash-St-Melbourne-FL-32904/54616772_zpid/", "image_url": "https://photos.zillowstatic.com/fp/d32daec0a331eeda56852e18e2fa6057-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 68}, {"source": "Zillow", "address": "2655 Lorna Dr, Melbourne, FL 32935", "price": 229900, "beds": 3, "baths": 2, "sqft": 1675, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32935", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2655-Lorna-Dr-Melbourne-FL-32935/43468572_zpid/", "image_url": "https://photos.zillowstatic.com/fp/c3da62e4abb6b0b98fad0a8e6b7280d5-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 68}, {"source": "Zillow", "address": "2365 Cottonwood Avenue, West Melbourne, FL 32904", "price": 224900, "beds": 3, "baths": 1, "sqft": 960, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32904", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2365-Cottonwood-Ave-Melbourne-FL-32904/43478830_zpid/", "image_url": "https://photos.zillowstatic.com/fp/b87d6cb87b58a2ceb244f5e98f0286af-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 68}, {"source": "Zillow", "address": "2785 Reston St Unit 103, Melbourne, FL 32935", "price": 210000, "beds": 3, "baths": 3, "sqft": 1548, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32935", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2785-Reston-St-UNIT-103-Melbourne-FL-32935/104081263_zpid/", "image_url": "https://photos.zillowstatic.com/fp/eb2626251eb68e3eeb2e16c9ffdcc552-p_e.jpg", "property_type": "TOWNHOUSE", "score": 68}, {"source": "Zillow", "address": "4405 Keats Ave, Titusville, FL 32780", "price": 224900, "beds": 3, "baths": 2, "sqft": 1165, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4405-Keats-Ave-Titusville-FL-32780/43383453_zpid/", "image_url": "https://photos.zillowstatic.com/fp/7c7bbb6c5bccb4882f5da2f47d920381-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 68}, {"source": "Zillow", "address": "3711 Prescott St, Titusville, FL 32796", "price": 209900, "beds": 3, "baths": 2, "sqft": 1284, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32796", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3711-Prescott-St-Titusville-FL-32796/43372159_zpid/", "image_url": "https://photos.zillowstatic.com/fp/2893076558b09e5e85109ac9c445edfb-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 68}, {"source": "Zillow", "address": "4490 Stuart Ave, Titusville, FL 32780", "price": 229000, "beds": 3, "baths": 2, "sqft": 1228, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4490-Stuart-Ave-Titusville-FL-32780/43383325_zpid/", "image_url": "https://photos.zillowstatic.com/fp/9d864a27aa09cbf6a02f29c8838be3d7-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 68}, {"source": "Zillow", "address": "1675 Ashwood Ave, Titusville, FL 32796", "price": 209900, "beds": 3, "baths": 2, "sqft": 1386, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32796", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1675-Ashwood-Ave-Titusville-FL-32796/43373210_zpid/", "image_url": "https://photos.zillowstatic.com/fp/0c4ac9d8314864c9aadd324af9c87c95-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 68}, {"source": "Zillow", "address": "1995 S Smith Dr, Titusville, FL 32780", "price": 219900, "beds": 3, "baths": 1, "sqft": 1340, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1995-S-Smith-Dr-Titusville-FL-32780/43377102_zpid/", "image_url": "https://photos.zillowstatic.com/fp/3009dc160f1ca4aa69b9db9778f0f394-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 68}, {"source": "Zillow", "address": "1987 Di Pol Courtway, Titusville, FL 32780", "price": 219000, "beds": 3, "baths": 3, "sqft": 1858, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1987-Di-Pol-Courtway-Titusville-FL-32780/66676675_zpid/", "image_url": "https://photos.zillowstatic.com/fp/3f8e7b88e7bd013d664bd007b56bf0ba-p_e.jpg", "property_type": "TOWNHOUSE", "score": 68}, {"source": "Zillow", "address": "1654 Rice Ave, Titusville, FL 32796", "price": 220000, "beds": 3, "baths": 2, "sqft": 1267, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32796", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1654-Rice-Ave-Titusville-FL-32796/43373191_zpid/", "image_url": "https://photos.zillowstatic.com/fp/35a951c09755b1aac4756c91ad180221-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 68}, {"source": "Zillow", "address": "2511 Grove St, Titusville, FL 32796", "price": 209000, "beds": 3, "baths": 2, "sqft": 1634, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32796", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2511-Grove-St-Titusville-FL-32796/43377328_zpid/", "image_url": "https://photos.zillowstatic.com/fp/ca8521b63b5daae947789f3086f155df-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 68}, {"source": "Zillow", "address": "2600 S Kanner Hwy APT A9, Stuart, FL 34994", "price": 205000, "beds": 1, "baths": 1, "sqft": 685, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34994", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2600-S-Kanner-Hwy-APT-A9-Stuart-FL-34994/45657056_zpid/", "image_url": "https://photos.zillowstatic.com/fp/0f632b6d74c83e3785937a4ba4bf52a1-p_e.jpg", "property_type": "CONDO", "score": 67}, {"source": "Zillow", "address": "11000 S Ocean Drive #2-2, Jensen Beach, FL 34957", "price": 175000, "beds": 1, "baths": 1, "sqft": 540, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/11000-S-Ocean-Dr-APT-2-2-Jensen-Beach-FL-34957/47864350_zpid/", "image_url": "https://photos.zillowstatic.com/fp/23064007018930c30088fba69fb1e9b6-p_e.jpg", "property_type": "CONDO", "score": 67}, {"source": "Zillow", "address": "516 Nettles Blvd, Jensen Beach, FL 34957", "price": 186000, "beds": 1, "baths": 1, "sqft": 741, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/516-Nettles-Blvd-Jensen-Beach-FL-34957/47859556_zpid/", "image_url": "https://photos.zillowstatic.com/fp/532ab5708352fccb3176511e8ae608cf-p_e.jpg", "property_type": "MANUFACTURED", "score": 67}, {"source": "Zillow", "address": "3643 NW Mediterranean Lane #103, Jensen Beach, FL 34957", "price": 189000, "beds": 1, "baths": 1, "sqft": 781, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3643-NW-Mediterranean-Ln-103-Jensen-Beach-FL-34957/2059718701_zpid/", "image_url": "https://photos.zillowstatic.com/fp/3f70fa23e262033e87753947ab7b5884-p_e.jpg", "property_type": "CONDO", "score": 67}, {"source": "Zillow", "address": "943 Nettles Blvd, Jensen Beach, FL 34957", "price": 180000, "beds": 1, "baths": 1, "sqft": 461, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/943-Nettles-Blvd-Jensen-Beach-FL-34957/47859945_zpid/", "image_url": "https://photos.zillowstatic.com/fp/0a175985a4ea1ce4b02ac559a0bc2497-p_e.jpg", "property_type": "MANUFACTURED", "score": 67}, {"source": "Zillow", "address": "737 Nettles Blvd, Jensen Beach, FL 34957", "price": 195000, "beds": 1, "baths": 1, "sqft": 420, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/737-Nettles-Blvd-Jensen-Beach-FL-34957/47859759_zpid/", "image_url": "https://photos.zillowstatic.com/fp/dd227001e0724915ba7b8f689ace9f8e-p_e.jpg", "property_type": "CONDO", "score": 67}, {"source": "Zillow", "address": "3820 Ocean Beach Blvd #8, Cocoa Beach, FL 32931", "price": 199000, "beds": 1, "baths": 2, "sqft": 682, "city": "Cocoa Beach", "state": "FL", "county": "Brevard", "zipcode": "32931", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3820-Ocean-Beach-Blvd-8-Cocoa-Beach-FL-32931/2074120898_zpid/", "image_url": "https://photos.zillowstatic.com/fp/ccb068ed1a40e60685dc431586e16d3c-p_e.jpg", "property_type": "CONDO", "score": 67}, {"source": "Zillow", "address": "714 Catalina Rd APT 2, Cocoa Beach, FL 32931", "price": 179000, "beds": 1, "baths": 1, "sqft": 583, "city": "Cocoa Beach", "state": "FL", "county": "Brevard", "zipcode": "32931", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/714-Catalina-Rd-APT-2-Cocoa-Beach-FL-32931/54610628_zpid/", "image_url": "https://photos.zillowstatic.com/fp/93bee9e3c488a5af4dc4f7088ac7bffd-p_e.jpg", "property_type": "CONDO", "score": 67}, {"source": "Zillow", "address": "22 Tulip Ave #312, Cocoa Beach, FL 32931", "price": 199900, "beds": 1, "baths": 1, "sqft": 716, "city": "Cocoa Beach", "state": "FL", "county": "Brevard", "zipcode": "32931", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/22-Tulip-Ave-312-Cocoa-Beach-FL-32931/43434847_zpid/", "image_url": "https://photos.zillowstatic.com/fp/b11cc395bef81267ff4a37aae05baed3-p_e.jpg", "property_type": "CONDO", "score": 67}, {"source": "Zillow", "address": "200 Saint Lucie Ln APT 604, Cocoa Beach, FL 32931", "price": 190000, "beds": 1, "baths": 2, "sqft": 665, "city": "Cocoa Beach", "state": "FL", "county": "Brevard", "zipcode": "32931", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/200-Saint-Lucie-Ln-APT-604-Cocoa-Beach-FL-32931/455112190_zpid/", "image_url": "https://photos.zillowstatic.com/fp/419adafe1b046df4549b5e77df08aa7c-p_e.jpg", "property_type": "CONDO", "score": 67}, {"source": "Zillow", "address": "201 Saint Lucie Ln APT 304, Cocoa Beach, FL 32931", "price": 193000, "beds": 1, "baths": 1, "sqft": 700, "city": "Cocoa Beach", "state": "FL", "county": "Brevard", "zipcode": "32931", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/201-Saint-Lucie-Ln-APT-304-Cocoa-Beach-FL-32931/43423591_zpid/", "image_url": "https://photos.zillowstatic.com/fp/34469d01536f29b04cd250fd648c0eac-p_e.jpg", "property_type": "CONDO", "score": 67}, {"source": "Zillow", "address": "2020 N Atlantic Ave #308, Cocoa Beach, FL 32931", "price": 189900, "beds": 1, "baths": 1, "sqft": 672, "city": "Cocoa Beach", "state": "FL", "county": "Brevard", "zipcode": "32931", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2020-N-Atlantic-Ave-308-Cocoa-Beach-FL-32931/2077421191_zpid/", "image_url": "https://photos.zillowstatic.com/fp/e5ef8c2e7601e38f572629b256893cb2-p_e.jpg", "property_type": "CONDO", "score": 67}, {"source": "Zillow", "address": "6166 SE Riverboat Drive #926, Stuart, FL 34997", "price": 215000, "beds": 2, "baths": 3, "sqft": 1288, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34997", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6166-SE-Riverboat-Dr-926-Stuart-FL-34997/449995604_zpid/", "image_url": "https://photos.zillowstatic.com/fp/efc31ab2cc99f703655233f8c05e8d54-p_e.jpg", "property_type": "TOWNHOUSE", "score": 64}, {"source": "Zillow", "address": "2856 SW Toronado Trl, Stuart, FL 34997", "price": 217000, "beds": 2, "baths": 2, "sqft": 1523, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34997", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2856-SW-Toronado-Trl-Stuart-FL-34997/45652618_zpid/", "image_url": "https://photos.zillowstatic.com/fp/2b10ffc2d3ae1003796c1c11984e517b-p_e.jpg", "property_type": "MANUFACTURED", "score": 64}, {"source": "Zillow", "address": "5403 SE Miles Grant Road #H108, Stuart, FL 34997", "price": 209900, "beds": 2, "baths": 2, "sqft": 1186, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34997", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/5403-SE-Miles-Grant-Rd-APT-H108-Stuart-FL-34997/462077511_zpid/", "image_url": "https://photos.zillowstatic.com/fp/15e8e80ba9a65b2ee3b0a67a1eeaecd2-p_e.jpg", "property_type": "CONDO", "score": 64}, {"source": "Zillow", "address": "5818 SE Windsong Ln, Stuart, FL 34997", "price": 220000, "beds": 2, "baths": 3, "sqft": 1288, "city": "Stuart", "state": "FL", "county": "Martin", "zipcode": "34997", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/5818-SE-Windsong-Ln-Stuart-FL-34997/45665438_zpid/", "image_url": "https://photos.zillowstatic.com/fp/3c6416ad5a7a0b3849df8f87a9988b31-p_e.jpg", "property_type": "TOWNHOUSE", "score": 64}, {"source": "Zillow", "address": "770 Nettles Blvd, Jensen Beach, FL 34957", "price": 215000, "beds": 2, "baths": 2, "sqft": 620, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/770-Nettles-Blvd-Jensen-Beach-FL-34957/47859788_zpid/", "image_url": "https://photos.zillowstatic.com/fp/3b5e2c405780543218a949428ef1d0ad-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 64}, {"source": "Zillow", "address": "3986 NW Cinnamon Tree Cir, Jensen Beach, FL 34957", "price": 210000, "beds": 2, "baths": 2, "sqft": 1037, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3986-NW-Cinnamon-Tree-Cir-Jensen-Beach-FL-34957/2059685002_zpid/", "image_url": "https://photos.zillowstatic.com/fp/98dd11029f561ec2f9d3a5da4f883033-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 64}, {"source": "Zillow", "address": "4047 NW Cinnamon Tree Cir, Jensen Beach, FL 34957", "price": 210000, "beds": 2, "baths": 2, "sqft": 1037, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4047-NW-Cinnamon-Tree-Cir-Jensen-Beach-FL-34957/2136795453_zpid/", "image_url": "https://photos.zillowstatic.com/fp/fab642351d1e22d7dd2202840b4a0ffe-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 64}, {"source": "Zillow", "address": "91 S Warner Drive, Jensen Beach, FL 34957", "price": 219000, "beds": 2, "baths": 2, "sqft": 1203, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/91-S-Warner-Dr-Jensen-Beach-FL-34957/461463722_zpid/", "image_url": "https://photos.zillowstatic.com/fp/cead1873e4aadfd787d614d2a32fb0ad-p_e.jpg", "property_type": "MANUFACTURED", "score": 64}, {"source": "Zillow", "address": "10725 S Ocean Dr Lot 349, Jensen Beach, FL 34957", "price": 219000, "beds": 2, "baths": 1, "sqft": 800, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/10725-S-Ocean-Dr-LOT-349-Jensen-Beach-FL-34957/47863150_zpid/", "image_url": "https://photos.zillowstatic.com/fp/e9b52a439fe6c7c120a49245085e6cb8-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 64}, {"source": "Zillow", "address": "10725 S Ocean Dr Lot 534, Jensen Beach, FL 34957", "price": 219900, "beds": 2, "baths": 2, "sqft": 408, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/10725-S-Ocean-Dr-LOT-534-Jensen-Beach-FL-34957/47863038_zpid/", "image_url": "https://photos.zillowstatic.com/fp/0ac8d58ad3f372b35006d642e9d34106-p_e.jpg", "property_type": "MANUFACTURED", "score": 64}, {"source": "Zillow", "address": "13 NE Nautical Dr Unit 13, Jensen Beach, FL 34957", "price": 229000, "beds": 2, "baths": 2, "sqft": 1008, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/13-NE-Nautical-Dr-UNIT-13-Jensen-Beach-FL-34957/461648251_zpid/", "image_url": "https://photos.zillowstatic.com/fp/abfa0e428688ff5a6eb747411fb7b51b-p_e.jpg", "property_type": "MANUFACTURED", "score": 64}, {"source": "Zillow", "address": "3790 NW Mediterranean Lane #303, Jensen Beach, FL 34957", "price": 229000, "beds": 2, "baths": 2, "sqft": 1067, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3790-NW-Mediterranean-Ln-303-Jensen-Beach-FL-34957/461649178_zpid/", "image_url": "https://photos.zillowstatic.com/fp/cb8b874378aef8ef076869d39170d5f3-p_e.jpg", "property_type": "CONDO", "score": 64}, {"source": "Zillow", "address": "1411 NE 14th Court #P-14, Jensen Beach, FL 34957", "price": 219000, "beds": 2, "baths": 2, "sqft": 1089, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1411-NE-14th-Ct-P-14-Jensen-Beach-FL-34957/45667737_zpid/", "image_url": "https://photos.zillowstatic.com/fp/1a7c91aca381ee7f8829e4ed15d93d22-p_e.jpg", "property_type": "CONDO", "score": 64}, {"source": "Zillow", "address": "1943 NE Collins Cir APT 50, Jensen Beach, FL 34957", "price": 215000, "beds": 2, "baths": 2, "sqft": 903, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1943-NE-Collins-Cir-APT-50-Jensen-Beach-FL-34957/455490871_zpid/", "image_url": "https://photos.zillowstatic.com/fp/62bca391ad4043816172eb928105cb4b-p_e.jpg", "property_type": "CONDO", "score": 64}, {"source": "Zillow", "address": "36 NE Village Ln, Jensen Beach, FL 34957", "price": 225000, "beds": 2, "baths": 2, "sqft": 1286, "city": "Jensen Beach", "state": "FL", "county": "Martin", "zipcode": "34957", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/36-NE-Village-Ln-Jensen-Beach-FL-34957/439341082_zpid/", "image_url": "https://photos.zillowstatic.com/fp/260c8307e2f4683a4e2f5343cdc61c96-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 64}, {"source": "Zillow", "address": "2607 Pepper Ave, Melbourne, FL 32935", "price": 230000, "beds": 2, "baths": 1, "sqft": 874, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32935", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2607-Pepper-Ave-Melbourne-FL-32935/43469740_zpid/", "image_url": "https://photos.zillowstatic.com/fp/6bfd598668b0ff809072dc9818cd976d-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 64}, {"source": "Zillow", "address": "1972 Post Rd, Melbourne, FL 32935", "price": 225000, "beds": 2, "baths": 1, "sqft": 864, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32935", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1972-Post-Rd-Melbourne-FL-32935/43451560_zpid/", "image_url": "https://photos.zillowstatic.com/fp/45ac1605b1b1e149168fd65dc89cb636-p_e.jpg", "property_type": "SINGLE_FAMILY", "score": 64}, {"source": "Zillow", "address": "2780 Reston St Unit 105, Melbourne, FL 32935", "price": 230000, "beds": 2, "baths": 3, "sqft": 1467, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32935", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2780-Reston-St-UNIT-105-Melbourne-FL-32935/104135638_zpid/", "image_url": "https://photos.zillowstatic.com/fp/e7a381f6746036425a72d47e37b34ead-p_e.jpg", "property_type": "TOWNHOUSE", "score": 64}, {"source": "Zillow", "address": "2012 Grant Pl APT 102, Melbourne, FL 32901", "price": 225000, "beds": 2, "baths": 1, "sqft": 1050, "city": "Melbourne", "state": "FL", "county": "Brevard", "zipcode": "32901", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2012-Grant-Pl-APT-102-Melbourne-FL-32901/43486981_zpid/", "image_url": "https://photos.zillowstatic.com/fp/85dc76ac4e64124b9ad7a7f325c5451a-p_e.jpg", "property_type": "CONDO", "score": 64}, {"source": "Zillow", "address": "201 Saint Lucie Ln APT 706, Cocoa Beach, FL 32931", "price": 225000, "beds": 2, "baths": 2, "sqft": 1030, "city": "Cocoa Beach", "state": "FL", "county": "Brevard", "zipcode": "32931", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/201-Saint-Lucie-Ln-APT-706-Cocoa-Beach-FL-32931/43423628_zpid/", "image_url": "https://photos.zillowstatic.com/fp/6502b6a8e481d89078a9d8a0f91de4aa-p_e.jpg", "property_type": "CONDO", "score": 64}, {"source": "Zillow", "address": "2020 N Atlantic Ave #112, Cocoa Beach, FL 32931", "price": 210000, "beds": 2, "baths": 2, "sqft": 816, "city": "Cocoa Beach", "state": "FL", "county": "Brevard", "zipcode": "32931", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2020-N-Atlantic-Ave-112-Cocoa-Beach-FL-32931/2064401345_zpid/", "image_url": "https://photos.zillowstatic.com/fp/d2f23c421ed87c9ef49b6c42dc4506f1-p_e.jpg", "property_type": "CONDO", "score": 64}, {"source": "Zillow", "address": "3799 S Banana River Blvd APT 104, Cocoa Beach, FL 32931", "price": 210900, "beds": 2, "baths": 2, "sqft": 1058, "city": "Cocoa Beach", "state": "FL", "county": "Brevard", "zipcode": "32931", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3799-S-Banana-River-Blvd-APT-104-Cocoa-Beach-FL-32931/54607780_zpid/", "image_url": "https://photos.zillowstatic.com/fp/37646a1aa0c8c84c4a5c05a03a4634f6-p_e.jpg", "property_type": "CONDO", "score": 64}, {"source": "Zillow", "address": "236 Woodland Ave APT 3, Cocoa Beach, FL 32931", "price": 229900, "beds": 2, "baths": 1, "sqft": 660, "city": "Cocoa Beach", "state": "FL", "county": "Brevard", "zipcode": "32931", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/236-Woodland-Ave-APT-3-Cocoa-Beach-FL-32931/84638335_zpid/", "image_url": "https://photos.zillowstatic.com/fp/71118cbcee4e8059cb62456eaa59b1a2-p_e.jpg", "property_type": "CONDO", "score": 64}, {"source": "Zillow", "address": "201 Saint Lucie Ln APT 810, Cocoa Beach, FL 32931", "price": 225000, "beds": 2, "baths": 2, "sqft": 1030, "city": "Cocoa Beach", "state": "FL", "county": "Brevard", "zipcode": "32931", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/201-Saint-Lucie-Ln-APT-810-Cocoa-Beach-FL-32931/54607765_zpid/", "image_url": "https://photos.zillowstatic.com/fp/678d9e77af0dba942371234597dc03dc-p_e.jpg", "property_type": "CONDO", "score": 64}, {"source": "Zillow", "address": "2469 S Washington Ave APT C-206, Titusville, FL 32780", "price": 225000, "beds": 2, "baths": 2, "sqft": 830, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2469-S-Washington-Ave-APT-C-206-Titusville-FL-32780/54602396_zpid/", "image_url": "https://photos.zillowstatic.com/fp/4d9c59f4a723a35a8e69683b86be87ff-p_e.jpg", "property_type": "CONDO", "score": 64}, {"source": "Zillow", "address": "1540 Riverside Dr #5, Titusville, FL 32780", "price": 215000, "beds": 2, "baths": 2, "sqft": 1120, "city": "Titusville", "state": "FL", "county": "Brevard", "zipcode": "32780", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1540-Riverside-Dr-5-Titusville-FL-32780/43379339_zpid/", "image_url": "https://photos.zillowstatic.com/fp/26c678619b5c4e2bb76c8076bb05f0a9-p_e.jpg", "property_type": "CONDO", "score": 64}, {"source": "Zillow", "address": "2020 N Atlantic Ave APT 108-N, Cocoa Beach, FL 32931", "price": 210000, "beds": 1, "baths": 1, "sqft": 822, "city": "Cocoa Beach", "state": "FL", "county": "Brevard", "zipcode": "32931", "status": "FOR_SALE", "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2020-N-Atlantic-Ave-APT-108-N-Cocoa-Beach-FL-32931/54610101_zpid/", "image_url": "https://photos.zillowstatic.com/fp/88719e1b55377bde44dad70f2709972f-p_e.jpg", "property_type": "CONDO", "score": 60}], "log": {"Zillow": {"found": 179, "status": "ok"}, "Realtor.com": {"found": 0, "status": "ok"}, "HUD": {"found": 0, "status": "ok"}, "HomePath": {"found": 0, "status": "ok"}}, "total": 179} \ No newline at end of file diff --git a/casa-hunter/app/scan_runner.py b/casa-hunter/app/scan_runner.py new file mode 100644 index 0000000..def1a5d --- /dev/null +++ b/casa-hunter/app/scan_runner.py @@ -0,0 +1,91 @@ +""" +Proceso independiente que ejecuta el scan y escribe resultados a JSON. +Llamado por Flask via subprocess. +""" +# -*- coding: utf-8 -*- +import sys, io, json, os, argparse + +sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace') +sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace') + +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +STATUS_FILE = os.path.join(BASE_DIR, "scan_status.json") +RESULTS_FILE = os.path.join(BASE_DIR, "scan_results.json") + +def write_status(msg, running=True): + with open(STATUS_FILE, "w", encoding="utf-8") as f: + json.dump({"running": running, "progress": msg}, f) + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--cities", default="Vero Beach,Jacksonville,Melbourne,Stuart,Daytona Beach,St. Augustine,Palm Coast,New Smyrna Beach") + parser.add_argument("--max_price", type=int, default=230000) + args = parser.parse_args() + + cities = [c.strip() for c in args.cities.split(",") if c.strip()] + max_price = args.max_price + + write_status(f"Iniciando scan en {len(cities)} ciudades...") + sys.path.insert(0, BASE_DIR) + from scrapers import scrape_zillow, scrape_realtor, scrape_hud, scrape_homepath, score_property + + all_results = [] + log = {} + + # Zillow + write_status(f"Zillow: buscando en {len(cities)} ciudades... (Chrome se abrira)") + try: + z_results = scrape_zillow(cities, max_price) + log["Zillow"] = {"found": len(z_results), "status": "ok"} + all_results.extend(z_results) + write_status(f"Zillow: {len(z_results)} encontradas. Buscando en Realtor...") + except Exception as e: + log["Zillow"] = {"found": 0, "status": f"error: {e}"} + write_status(f"Zillow error: {e}. Continuando con Realtor...") + + # Realtor.com + try: + r_results = scrape_realtor(cities, max_price) + log["Realtor.com"] = {"found": len(r_results), "status": "ok"} + all_results.extend(r_results) + write_status(f"Realtor: {len(r_results)} encontradas. Procesando...") + except Exception as e: + log["Realtor.com"] = {"found": 0, "status": f"error: {e}"} + + # HUD + HomePath (rapidos, sin browser) + try: + h_results = scrape_hud(cities, max_price) + log["HUD"] = {"found": len(h_results), "status": "ok"} + all_results.extend(h_results) + except Exception as e: + log["HUD"] = {"found": 0, "status": f"error: {e}"} + + try: + hp_results = scrape_homepath(cities, max_price) + log["HomePath"] = {"found": len(hp_results), "status": "ok"} + all_results.extend(hp_results) + except Exception as e: + log["HomePath"] = {"found": 0, "status": f"error: {e}"} + + # Deduplicar + seen, unique = set(), [] + for r in all_results: + key = (r.get("address","").lower().strip(), r.get("price",0)) + if key[0] and key not in seen: + seen.add(key) + r["score"] = score_property(r, cities, max_price) + unique.append(r) + + unique.sort(key=lambda x: x.get("score", 0), reverse=True) + + with open(RESULTS_FILE, "w", encoding="utf-8") as f: + json.dump({"properties": unique, "log": log, "total": len(unique)}, f, ensure_ascii=False) + + write_status( + f"Completado: {len(unique)} propiedades unicas encontradas", + running=False + ) + print(f"SCAN DONE: {len(unique)} propiedades") + +if __name__ == "__main__": + main() diff --git a/casa-hunter/app/scan_status.json b/casa-hunter/app/scan_status.json new file mode 100644 index 0000000..9ce11ed --- /dev/null +++ b/casa-hunter/app/scan_status.json @@ -0,0 +1 @@ +{"running": false, "progress": "Completado: 179 propiedades unicas encontradas"} \ No newline at end of file diff --git a/casa-hunter/app/scrapers.py b/casa-hunter/app/scrapers.py new file mode 100644 index 0000000..80ad036 --- /dev/null +++ b/casa-hunter/app/scrapers.py @@ -0,0 +1,461 @@ +import re, json, time, random, shutil, os +import requests +from bs4 import BeautifulSoup +from datetime import datetime + +# ── Config ──────────────────────────────────────────────────────────────────── +CHROME_PATH = r"C:\Program Files\Google\Chrome\Application\chrome.exe" +CHROME_PROFILE = r"C:\Users\aerom\AppData\Local\Google\Chrome\User Data" +TEMP_PROFILE = r"C:\Temp\chrome_casa_hunter" + +HEADERS = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124 Safari/537.36", + "Accept": "text/html,application/xhtml+xml,*/*;q=0.8", + "Accept-Language": "en-US,en;q=0.9", +} + +CITY_COUNTY_MAP = { + "vero beach": "Indian River", "sebastian": "Indian River", + "fellsmere": "Indian River", "indian river shores": "Indian River", + "stuart": "Martin", "jensen beach": "Martin", "hobe sound": "Martin", + "palm city": "Martin", "port salerno": "Martin", + "fort pierce": "St. Lucie", "port st. lucie": "St. Lucie", + "melbourne": "Brevard", "palm bay": "Brevard", "titusville": "Brevard", + "cocoa": "Brevard", "cocoa beach": "Brevard", "rockledge": "Brevard", + "merritt island": "Brevard", "cape canaveral": "Brevard", + "satellite beach": "Brevard", "west melbourne": "Brevard", + "daytona beach": "Volusia", "ormond beach": "Volusia", + "new smyrna beach": "Volusia", "edgewater": "Volusia", + "port orange": "Volusia", "deltona": "Volusia", + "palm coast": "Flagler", "flagler beach": "Flagler", "bunnell": "Flagler", + "st. augustine": "St. Johns", "ponte vedra beach": "St. Johns", + "nocatee": "St. Johns", "st. augustine beach": "St. Johns", + "jacksonville": "Duval", "jacksonville beach": "Duval", + "atlantic beach": "Duval", "neptune beach": "Duval", + "fernandina beach": "Nassau", "yulee": "Nassau", +} + +COUNTY_CODES = { + "Brevard": "9", "Duval": "31", "Flagler": "35", "Indian River": "61", + "Martin": "86", "Nassau": "89", "St. Johns": "109", "St. Lucie": "111", + "Volusia": "127", +} + + +def get_county_for_city(city: str) -> str: + return CITY_COUNTY_MAP.get(city.lower().strip(), "") + + +def score_property(prop: dict, search_cities: list, max_price: int) -> int: + score = 40 + price = prop.get("price", 0) + if not price or price <= 0: + return 0 + + ratio = price / max_price + if ratio <= 0.60: + score += 35 + elif ratio <= 0.75: + score += 25 + elif ratio <= 0.90: + score += 15 + elif ratio <= 1.0: + score += 8 + + city = (prop.get("city") or "").lower() + county = (prop.get("county") or "").lower() + for s in [c.lower() for c in search_cities]: + if s in city or s in county or city in s or county in s: + score += 12 + break + + beds = prop.get("beds") or 0 + if beds >= 3: + score += 8 + elif beds >= 2: + score += 4 + + status = (prop.get("status") or "").lower() + if any(w in status for w in ["foreclosure", "reo", "bank owned", "hud", "price reduced"]): + score += 10 + elif any(w in status for w in ["new construction", "newly built"]): + score += 5 + + return min(score, 100) + + +# ── Chrome profile setup ─────────────────────────────────────────────────────── +def ensure_chrome_profile(): + """Copia el perfil de Chrome si no existe el temporal.""" + if os.path.exists(os.path.join(TEMP_PROFILE, "Default")): + return True + if not os.path.exists(CHROME_PROFILE): + return False + try: + os.makedirs(os.path.join(TEMP_PROFILE, "Default"), exist_ok=True) + src = os.path.join(CHROME_PROFILE, "Default") + dst = os.path.join(TEMP_PROFILE, "Default") + for item in ["Cookies", "Login Data", "Web Data", "Preferences"]: + s = os.path.join(src, item) + if os.path.exists(s): + shutil.copy2(s, dst) + return True + except Exception as e: + print(f" Profile copy warning: {e}") + return False + + +# ── Playwright helpers ───────────────────────────────────────────────────────── +def _hd(a=1.2, b=3.0): + time.sleep(random.uniform(a, b)) + +def _scroll(page, steps=4): + for _ in range(steps): + page.mouse.wheel(0, random.randint(250, 600)) + time.sleep(random.uniform(0.4, 0.9)) + +def _type_human(page, text): + for ch in text: + page.keyboard.type(ch) + time.sleep(random.uniform(0.07, 0.16)) + +def _parse_zillow_html(html, min_p=40000, max_p=230000): + results = [] + m = re.search(r']*id="__NEXT_DATA__"[^>]*>(.*?)', html, re.DOTALL) + if not m: + return results + try: + data = json.loads(m.group(1)) + list_results = (data.get("props", {}).get("pageProps", {}) + .get("searchPageState", {}).get("cat1", {}) + .get("searchResults", {}).get("listResults", [])) + for p in list_results: + price = p.get("unformattedPrice", 0) + if min_p <= price <= max_p: + city_val = p.get("addressCity", "") + results.append({ + "source": "Zillow", + "address": p.get("address", ""), + "price": price, + "beds": p.get("beds", 0), + "baths": p.get("baths", 0), + "sqft": p.get("area", 0), + "city": city_val, + "state": p.get("addressState", "FL"), + "county": get_county_for_city(city_val), + "zipcode": str(p.get("addressZipcode", "")), + "status": p.get("statusType", "For Sale"), + "url": "https://www.zillow.com" + p.get("detailUrl", ""), + "image_url": p.get("imgSrc", ""), + "property_type": p.get("hdpData", {}).get("homeInfo", {}).get("homeType", ""), + }) + except Exception as e: + print(f" JSON parse error: {e}") + return results + + +# ── Zillow via Playwright + Chrome profile ──────────────────────────────────── +def scrape_zillow(cities: list, max_price: int) -> list: + try: + from playwright.sync_api import sync_playwright + except ImportError: + print(" Playwright no instalado — saltando Zillow") + return [] + + ensure_chrome_profile() + all_results = [] + MIN_PRICE = 40000 + + with sync_playwright() as p: + ctx = p.chromium.launch_persistent_context( + user_data_dir=TEMP_PROFILE, + executable_path=CHROME_PATH, + headless=False, + args=[ + "--profile-directory=Default", + "--disable-blink-features=AutomationControlled", + "--start-maximized", + "--no-first-run", + "--no-default-browser-check", + ], + viewport={"width": 1366, "height": 768}, + ) + page = ctx.new_page() + + for city in cities: + city_q = f"{city}, FL" + print(f" Zillow: buscando {city_q}...") + try: + page.goto("https://www.zillow.com", wait_until="load", timeout=30000) + _hd(1.5, 2.5) + + search = page.query_selector( + "#search-box-input, input[id*='search'], " + "input[placeholder*='address'], input[placeholder*='city']" + ) + if search: + search.click() + _hd(0.3, 0.6) + page.keyboard.down("Control") + page.keyboard.press("a") + page.keyboard.up("Control") + page.keyboard.press("Delete") + _hd(0.2, 0.4) + _type_human(page, city_q) + _hd(0.8, 1.5) + page.keyboard.press("Enter") + page.wait_for_load_state("load", timeout=30000) + _hd(2, 3) + _scroll(page, 4) + _hd(1, 2) + else: + # fallback: URL directa + slug = re.sub(r"[^a-z0-9\s-]", "", city.lower()).strip().replace(" ", "-") + url = (f"https://www.zillow.com/homes/for_sale/{slug}-fl/" + f"?searchQueryState=%7B%22filterState%22%3A%7B" + f"%22price%22%3A%7B%22max%22%3A{max_price}%2C%22min%22%3A{MIN_PRICE}%7D%7D%7D") + page.goto(url, wait_until="load", timeout=45000) + _hd(2, 3) + _scroll(page, 4) + + html = page.content() + title = page.title() + # Si Cloudflare bloqueó, esperar hasta que el usuario lo resuelva (max 90s) + if "denied" in title.lower() or "px-captcha" in html or "cf-browser-verification" in html: + print(f" >> Cloudflare en {city}: resuelve el challenge en el browser (90s max)...") + deadline = time.time() + 90 + while time.time() < deadline: + time.sleep(4) + html = page.content() + t2 = page.title() + if "denied" not in t2.lower() and "px-captcha" not in html: + print(f" Challenge resuelto!") + break + else: + print(f" Timeout esperando challenge - saltando {city}") + continue + + listings = _parse_zillow_html(html, MIN_PRICE, max_price) + print(f" -> {len(listings)} encontradas") + all_results.extend(listings) + + except Exception as e: + print(f" ERROR {city}: {e}") + + _hd(4, 7) # pausa entre ciudades para evitar bloqueo + + ctx.close() + + # Deduplicar + seen, unique = set(), [] + for r in all_results: + key = r["address"].lower().strip() + if key and key not in seen: + seen.add(key) + unique.append(r) + return unique + + +# ── Realtor.com via Playwright + Chrome profile ─────────────────────────────── +def scrape_realtor(cities: list, max_price: int) -> list: + try: + from playwright.sync_api import sync_playwright + except ImportError: + return [] + + ensure_chrome_profile() + all_results = [] + + with sync_playwright() as p: + ctx = p.chromium.launch_persistent_context( + user_data_dir=TEMP_PROFILE, + executable_path=CHROME_PATH, + headless=False, + args=[ + "--profile-directory=Default", + "--disable-blink-features=AutomationControlled", + "--start-maximized", + "--no-first-run", + ], + viewport={"width": 1366, "height": 768}, + ) + page = ctx.new_page() + + for city in cities: + city_slug = re.sub(r"[^a-z0-9\s]", "", city.lower()).strip().replace(" ", "_") + url = f"https://www.realtor.com/realestateandhomes-search/{city_slug}_FL/price-na-{max_price}" + print(f" Realtor.com: buscando {city}...") + try: + page.goto(url, wait_until="load", timeout=45000) + _hd(2, 3) + _scroll(page, 4) + _hd(1, 2) + + html = page.content() + m = re.search(r']*id="__NEXT_DATA__"[^>]*>(.*?)', html, re.DOTALL) + if not m: + continue + data = json.loads(m.group(1)) + properties = (data.get("props", {}).get("pageProps", {}) + .get("properties", [])) + for item in properties: + price = item.get("list_price", 0) + if not isinstance(price, (int, float)): + continue + price = int(price) + if 40000 <= price <= max_price: + loc = item.get("location", {}).get("address", {}) + city_val = loc.get("city", city) + desc = item.get("description", {}) + all_results.append({ + "source": "Realtor.com", + "address": loc.get("line", ""), + "city": city_val, + "county": get_county_for_city(city_val), + "zipcode": str(loc.get("postal_code", "")), + "price": price, + "beds": desc.get("beds", 0), + "baths": desc.get("baths_consolidated", 0), + "sqft": desc.get("sqft", 0), + "status": item.get("status", "For Sale"), + "url": "https://www.realtor.com" + item.get("permalink", ""), + "image_url": item.get("primary_photo", {}).get("href", ""), + "property_type": desc.get("type", ""), + }) + print(f" -> {len(properties)} revisadas") + + except Exception as e: + print(f" ERROR {city}: {e}") + + _hd(3, 5) + + ctx.close() + + seen, unique = set(), [] + for r in all_results: + key = r["address"].lower().strip() + if key and key not in seen: + seen.add(key) + unique.append(r) + return unique + + +# ── HUD Homes (requests - gobierno, sin anti-bot) ───────────────────────────── +def scrape_hud(cities: list, max_price: int) -> list: + results = [] + counties = set() + for city in cities: + c = get_county_for_city(city) + if c: + counties.add(c) + if not counties: + counties = {"Brevard", "Indian River", "Duval", "St. Johns", "Volusia"} + + for county in list(counties)[:6]: + code = COUNTY_CODES.get(county, "") + if not code: + continue + url = (f"https://www.hudhomestore.gov/HudHomes/Index.aspx" + f"?sState=FL&sCounty={code}&sPriceMax={max_price}&sPriceMin=30000") + try: + r = requests.get(url, headers=HEADERS, timeout=15) + soup = BeautifulSoup(r.text, "html.parser") + rows = soup.select("tr.propRow, .property-row, tr[id^='prop']") + for row in rows[:8]: + text = row.get_text(" ", strip=True) + price_m = re.search(r'\$[\d,]+', text) + if not price_m: + continue + price = int(re.sub(r'[^\d]', '', price_m.group())) + if 0 < price <= max_price: + addr_el = row.select_one("a") + prop = { + "source": "HUD Homes", + "address": addr_el.get_text(strip=True) if addr_el else text[:80], + "city": county, "county": county, + "price": price, "url": url, + "status": "HUD Foreclosure", + } + prop["score"] = score_property(prop, cities, max_price) + results.append(prop) + except Exception as e: + print(f" HUD {county}: {e}") + return results + + +# ── Fannie Mae HomePath (REO) ────────────────────────────────────────────────── +def scrape_homepath(cities: list, max_price: int) -> list: + results = [] + for term in cities[:8]: + url = (f"https://www.homepath.fanniemae.com/listings" + f"?searchTerm={requests.utils.quote(term + ' FL')}" + f"&maxPrice={max_price}&state=FL") + try: + r = requests.get(url, headers=HEADERS, timeout=15) + data = r.json() if "json" in r.headers.get("content-type", "") else {} + listings = data.get("listings", data.get("results", [])) + for item in listings[:6]: + price = item.get("listPrice", item.get("price", 0)) + if 0 < price <= max_price: + city_val = item.get("city", term) + prop = { + "source": "Fannie Mae HomePath", + "address": item.get("address", item.get("streetAddress", "")), + "city": city_val, + "county": get_county_for_city(city_val), + "zipcode": str(item.get("postalCode", "")), + "price": price, + "beds": item.get("bedrooms", 0), + "baths": item.get("bathrooms", 0), + "sqft": item.get("squareFeet", 0), + "url": f"https://www.homepath.fanniemae.com/listings/{item.get('id','')}", + "status": "Fannie Mae REO", + } + prop["score"] = score_property(prop, cities, max_price) + results.append(prop) + except Exception as e: + print(f" HomePath {term}: {e}") + return results + + +# ── Main runner ─────────────────────────────────────────────────────────────── +def run_all_scrapers(cities: list = None, max_price: int = 230000) -> dict: + if not cities: + cities = ["Vero Beach", "Jacksonville", "Melbourne", "St. Augustine"] + + all_props = [] + log = {} + + sources = { + "Zillow (Browser)": lambda: scrape_zillow(cities, max_price), + "Realtor.com (Browser)": lambda: scrape_realtor(cities, max_price), + "HUD Homes": lambda: scrape_hud(cities, max_price), + "Fannie Mae HomePath": lambda: scrape_homepath(cities, max_price), + } + + for name, fn in sources.items(): + try: + print(f"\n[{name}]") + props = fn() + seen, unique = set(), [] + for p in props: + key = ((p.get("address") or "").lower().strip(), p.get("price", 0)) + if key[0] and key not in seen: + seen.add(key) + p["score"] = score_property(p, cities, max_price) + unique.append(p) + all_props.extend(unique) + log[name] = {"found": len(unique), "status": "ok"} + print(f" -> {len(unique)} propiedades validas") + except Exception as e: + log[name] = {"found": 0, "status": f"error: {e}"} + print(f" ERROR {name}: {e}") + + all_props.sort(key=lambda x: x.get("score", 0), reverse=True) + return { + "properties": all_props, + "log": log, + "cities_searched": cities, + "max_price": max_price, + "ran_at": datetime.utcnow().isoformat() + } diff --git a/casa-hunter/app/templates/base.html b/casa-hunter/app/templates/base.html new file mode 100644 index 0000000..49e63a8 --- /dev/null +++ b/casa-hunter/app/templates/base.html @@ -0,0 +1,135 @@ + + + + + + {% block title %}Casa Hunter FL{% endblock %} + + + + + + + +
+ {% with messages = get_flashed_messages(with_categories=true) %} + {% for cat, msg in messages %} +
{{ msg }}
+ {% endfor %} + {% endwith %} + {% block content %}{% endblock %} +
+ +
Casa Hunter FL — Tu buscador personal de oportunidades inmobiliarias • Prisa Yachts LLC
+ + + + + +{% block scripts %}{% endblock %} + + diff --git a/casa-hunter/app/templates/index.html b/casa-hunter/app/templates/index.html new file mode 100644 index 0000000..0c95042 --- /dev/null +++ b/casa-hunter/app/templates/index.html @@ -0,0 +1,186 @@ +{% extends "base.html" %} +{% block title %}Dashboard — Casa Hunter FL{% endblock %} +{% block content %} + + +
+
+

Oportunidades en Costa de Florida

+

Stuart → Vero Beach → Melbourne → Daytona → St. Augustine → Jacksonville • Hasta $200,000

+
+ +
+ + +
+
+
+
{{ total }}
+
Propiedades
+
+
+
+
+
{{ favorites }}
+
Favoritas
+
+
+
+
+
$50K
+
Down Payment
+
+
+
+
+
8
+
Lenders Listos
+
+
+
+ + +
Mejores Oportunidades
+{% if properties %} +
+ {% for p in properties %} +
+
+ {% if p.image_url %} + + {% else %} +
+ +
+ {% endif %} +
+
+ {{ p.source }} + + Score: {{ p.score }}/100 + +
+

${{ "{:,.0f}".format(p.price) }}

+

{{ p.address }}

+

{{ p.city }}{% if p.county %}, {{ p.county }} Co.{% endif %}

+
+ {% if p.beds %}{{ p.beds }} hab.{% endif %} + {% if p.baths %}{{ p.baths }} baños{% endif %} + {% if p.sqft %}{{ p.sqft }} sf{% endif %} +
+
+ Ver Detalle + {% if p.url %} + + {% endif %} +
+
+
+
+ {% endfor %} +
+ +{% else %} +
+
+ +
No hay propiedades aún
+

Haz clic en Buscar Ahora para encontrar oportunidades en Florida

+ +
+
+{% endif %} + + +
Lenders Recomendados para Tu Perfil
+
+ {% for l in top_lenders %} +
+
+
+
+
{{ l.name }}
+ {{ l.match_score }}% +
+ {{ l.loan_type }} +

{{ l.specialties[:100] }}{% if l.specialties|length > 100 %}...{% endif %}

+ Ver Script de Contacto +
+
+
+ {% endfor %} +
+ +{% if last_scan %} +

Última búsqueda: {{ last_scan.ran_at.strftime('%d/%m/%Y %H:%M') }}

+{% endif %} + + + + +{% endblock %} + +{% block scripts %} + +{% endblock %} diff --git a/casa-hunter/app/templates/lenders.html b/casa-hunter/app/templates/lenders.html new file mode 100644 index 0000000..93ff821 --- /dev/null +++ b/casa-hunter/app/templates/lenders.html @@ -0,0 +1,104 @@ +{% extends "base.html" %} +{% block title %}Lenders — Casa Hunter FL{% endblock %} +{% block content %} + +

Lenders Recomendados

+

Ordenados por compatibilidad con tu perfil: residente nuevo, self-employed, $50K down, hasta $200K

+ +
+{% for l in lenders %} +
+
+
+
+
+
{{ l.name }}
+ {{ l.loan_type }} +
+
+
{{ l.match_score }}%
+ compatibilidad +
+
+ +

{{ l.specialties }}

+ +
+
+
+ Down mín. + {{ l.min_down_pct|int }}% +
+
+
+
+ Residente nuevo + {% if l.accepts_new_resident %}{% else %}{% endif %} +
+
+
+
+ Self-employed + {% if l.accepts_self_employed %}{% else %}{% endif %} +
+
+
+ + {% if l.notes %} +

{{ l.notes }}

+ {% endif %} + + +
+ Guión de contacto:
+ {{ l.contact_script }} +
+ + + {{ l.contact_script }} +
+
+
+{% endfor %} +
+ + +
+
+
Tu Perfil — Lo que presentas a cada lender
+
+
+
    +
  • Estatus: Residente permanente
  • +
  • Tiempo en USA: Menos de 2 años
  • +
  • Trabajo: Contratista independiente — Eléctrica marina/naval
  • +
  • Tarifa: $120/hora
  • +
+
+
+
    +
  • Down payment disponible: $50,000
  • +
  • Presupuesto máximo: $200,000
  • +
  • Zona: Costa de FL — Stuart hasta Jacksonville
  • +
  • Préstamo ideal: Non-QM, Bank Statement, o ITIN
  • +
+
+
+
+
+{% endblock %} +{% block scripts %} + +{% endblock %} diff --git a/casa-hunter/app/templates/properties.html b/casa-hunter/app/templates/properties.html new file mode 100644 index 0000000..2e26685 --- /dev/null +++ b/casa-hunter/app/templates/properties.html @@ -0,0 +1,99 @@ +{% extends "base.html" %} +{% block title %}Propiedades — Casa Hunter FL{% endblock %} +{% block content %} + +
+

Propiedades en Oportunidad

+ +
+ + +
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ +
+
+
+
+ +{% if properties %} +

{{ properties|length }} propiedades encontradas

+
+ {% for p in properties %} +
+
+ {% if p.image_url %} + + {% else %} +
+ +
+ {% endif %} +
+
+ {{ p.source }} + {{ p.score }}/100 +
+
${{ "{:,.0f}".format(p.price) }}
+

{{ p.address }}

+

{{ p.city }}{% if p.county %}, {{ p.county }}{% endif %}

+
+ {% if p.beds %}{{ p.beds }}{% endif %} + {% if p.baths %}{{ p.baths }}{% endif %} + {% if p.sqft %}{{ p.sqft }}sf{% endif %} +
+
+ Ver Detalle + {% if p.url %}{% endif %} + {% if p.is_favorite %}{% endif %} +
+
+
+
+ {% endfor %} +
+{% else %} +
+
+ +
No hay propiedades
+

Haz clic en Buscar Ahora para encontrar oportunidades

+ +
+
+{% endif %} +{% endblock %} diff --git a/casa-hunter/app/templates/property_detail.html b/casa-hunter/app/templates/property_detail.html new file mode 100644 index 0000000..775a7c8 --- /dev/null +++ b/casa-hunter/app/templates/property_detail.html @@ -0,0 +1,224 @@ +{% extends "base.html" %} +{% block title %}{{ prop.address }} — Casa Hunter FL{% endblock %} +{% block content %} + + + +
+ +
+
+ {% if prop.image_url %} + + {% else %} +
+ +
+ {% endif %} +
+
+
+ {{ prop.source }} + {{ prop.status }} +
+ + Score: {{ prop.score }}/100 + +
+ +

${{ "{:,.0f}".format(prop.price) }}

+

{{ prop.address }}

+

{{ prop.city }}{% if prop.county %}, {{ prop.county }} County{% endif %}, FL {{ prop.zipcode }}

+ +
+ {% if prop.beds %} +
+
+ + {{ prop.beds }}
Habitaciones +
+
+ {% endif %} + {% if prop.baths %} +
+
+ + {{ prop.baths }}
Baños +
+
+ {% endif %} + {% if prop.sqft %} +
+
+ + {{ prop.sqft }}
Sq Ft +
+
+ {% endif %} +
+ +
+ {% if prop.url %} + Ver en {{ prop.source }} + {% endif %} + +
+
+
+ + +
+
+
Análisis con IA (qwen2.5)
+
+ {% if prop.ai_analysis %} +
{{ prop.ai_analysis }}
+ {% else %} +

Aún no se ha analizado esta propiedad.

+ {% endif %} +
+ +
+
+ + +
+
+
Mis Notas
+ + +
+
+
+ + +
+ +
+
+
Kit de Acción
+ +

DOCUMENTOS A PREPARAR

+
    +
  • Green card o visa + pasaporte
  • +
  • 12-24 meses de estados de cuenta bancarios
  • +
  • Comprobante de ingresos (facturas de trabajo)
  • +
  • Carta del landlord confirmando pagos de renta
  • +
  • Carta explicando tu situación laboral (self-employed)
  • +
  • Evidencia de los $50,000 disponibles (bank statement)
  • +
+ +

PASOS A SEGUIR

+
    +
  1. Llama a 2-3 lenders de la lista (empieza con Heart Mortgage y Jhenesis)
  2. +
  3. Pide una pre-qualification letter
  4. +
  5. Contrata un inspector de propiedades ($300-500)
  6. +
  7. Si es HUD/Fannie Mae, necesitas un agente de bienes raíces aprobado
  8. +
  9. Presenta oferta con pre-qual letter y prueba de fondos
  10. +
+ +
+ Estimado para esta propiedad:
+ Down payment (25%): ${{ "{:,.0f}".format(prop.price * 0.25) }}
+ Préstamo estimado: ${{ "{:,.0f}".format(prop.price * 0.75) }}
+ Cuota aprox (7.5%, 30 años): ${{ "{:,.0f}".format(prop.price * 0.75 * 0.007) }}/mes +
+
+
+ + +
+
+
Lenders para Esta Compra
+ {% for l in lenders[:4] %} +
+
+ {{ l.name }} + {{ l.match_score }}% +
+ {{ l.loan_type }}
+ + Visitar + + +
+ {% endfor %} + Ver todos los lenders +
+
+
+
+ + + + +{% endblock %} +{% block scripts %} + +{% endblock %} diff --git a/casa-hunter/app/templates/settings.html b/casa-hunter/app/templates/settings.html new file mode 100644 index 0000000..7dcfe5d --- /dev/null +++ b/casa-hunter/app/templates/settings.html @@ -0,0 +1,181 @@ +{% extends "base.html" %} +{% block title %}Preferencias — Casa Hunter FL{% endblock %} +{% block content %} + +

Preferencias de Búsqueda

+

Configura dónde y hasta cuánto buscar. La próxima búsqueda usará estos ajustes.

+ +
+ + +
+
+
+
Mi Presupuesto
+
+ + + +
+ $ + +
+ +
+ $50K$250K$500K +
+
${{ "{:,}".format(max_price) }}
+ +
+ + +
+ $ + +
+ +
${{ "{:,}".format(down_payment) }}
+ +
+ + Down del {{ ((down_payment / max_price) * 100)|round(1) }}% sobre precio máximo +
+ + +
+
+
+
+ + +
+
+
+
Agregar Ciudad
+
+ +
+ + +
+ +
+

Puedes agregar cualquier ciudad de Florida — Vero Beach, Palm Coast, Ponte Vedra, etc.

+
+
+ + +
+
+
+ + Ciudades en tu búsqueda + {{ cities|selectattr('active')|list|length }} activas +
+ {% if cities %} +
+ {% for c in cities %} +
+
+
+ + {{ c.city }} +
+
+
+ + + +
+
+ + + +
+
+
+
+ {% endfor %} +
+ {% else %} +

No hay ciudades configuradas.

+ {% endif %} +
+
+
+
+ + +
+
+
Agregar rápido — Ciudades costeras populares
+
+ {% set quick_cities = ["Vero Beach","Sebastian","Melbourne","Cocoa Beach","Titusville","Stuart","Jensen Beach", + "Daytona Beach","Ormond Beach","New Smyrna Beach","Flagler Beach","Palm Coast", + "St. Augustine","St. Augustine Beach","Ponte Vedra Beach", + "Jacksonville Beach","Atlantic Beach","Neptune Beach","Fernandina Beach", + "Port St. Lucie","Fort Pierce","Palm City","Hobe Sound"] %} + {% for qc in quick_cities %} + {% set already = cities|selectattr('city','equalto',qc)|list %} + {% if not already %} +
+ + + +
+ {% else %} + + {{ qc }} + + {% endif %} + {% endfor %} +
+
+
+ +{% endblock %} +{% block scripts %} + +{% endblock %} diff --git a/casa-hunter/docker-compose.yml b/casa-hunter/docker-compose.yml new file mode 100644 index 0000000..1e9e752 --- /dev/null +++ b/casa-hunter/docker-compose.yml @@ -0,0 +1,29 @@ +services: + casahunter: + build: . + container_name: casahunter + restart: unless-stopped + ports: + - "127.0.0.1:5050:5000" + environment: + - DATABASE_URL=${DATABASE_URL:-mysql+pymysql://casahunter:CHANGE_ME@mariadb:3306/casahunter} + - SECRET_KEY=${SECRET_KEY:?SECRET_KEY must be set in .env} + - OLLAMA_URL=http://host.docker.internal:11434 + - OLLAMA_MODEL=qwen2.5:14b + - ANTHROPIC_KEY= + extra_hosts: + - "host.docker.internal:host-gateway" + logging: + driver: local + options: + max-size: "10m" + max-file: "3" + networks: + - web + - mariadb_default + +networks: + web: + external: true + mariadb_default: + external: true diff --git a/casa-hunter/find_ids.py b/casa-hunter/find_ids.py new file mode 100644 index 0000000..e73ca71 --- /dev/null +++ b/casa-hunter/find_ids.py @@ -0,0 +1,58 @@ +import requests, re, json + +headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124 Safari/537.36", + "Accept-Language": "en-US,en;q=0.9", +} + +# Fetch Redfin search for FL cities and extract real region IDs +test_urls = [ + ("Vero Beach", "https://www.redfin.com/FL/Vero-Beach"), + ("Jacksonville", "https://www.redfin.com/FL/Jacksonville"), + ("Melbourne", "https://www.redfin.com/FL/Melbourne"), + ("Stuart", "https://www.redfin.com/FL/Stuart"), + ("Daytona Beach", "https://www.redfin.com/FL/Daytona-Beach"), +] + +print("=== Extracting real Redfin region IDs ===") +for city, url in test_urls: + try: + r = requests.get(url, headers=headers, timeout=15, allow_redirects=True) + # Extract region_id from JS or URL + final_url = r.url + match = re.search(r'/city/(\d+)/FL/', final_url) + if not match: + match = re.search(r'"region_id"[:\s]+(\d+)', r.text) + if not match: + match = re.search(r'"regionId"[:\s]+(\d+)', r.text) + if match: + rid = match.group(1) + print(f" {city}: region_id={rid} (url={final_url})") + else: + print(f" {city}: redirected to {final_url}, id not found, status={r.status_code}") + except Exception as e: + print(f" {city}: ERROR {e}") + +# Try direct Redfin search API (county-based = more reliable) +print("\n=== Redfin by ZIP code (more reliable) ===") +fl_zips = { + "Vero Beach": "32960", + "Melbourne": "32901", + "Jacksonville": "32202", + "St. Augustine": "32080", + "Daytona Beach": "32114", +} +for city, zipcode in fl_zips.items(): + try: + url = (f"https://www.redfin.com/stingray/api/gis?" + f"al=1&market=florida®ion_id={zipcode}®ion_type=2" + f"&status=9&uipt=1,2,3,4&max_price=230000&num_homes=5&start=0&v=8") + r = requests.get(url, headers=headers, timeout=15) + data = json.loads(r.text.replace("{}&&", "")) + homes = data.get("payload", {}).get("homes", []) + fl_homes = [h for h in homes if h.get("state") == "FL"] + print(f" {city} (zip={zipcode}): {len(homes)} total, {len(fl_homes)} in FL") + for h in fl_homes[:2]: + print(f" ${h.get('price',{}).get('value',0):,} | {h.get('streetLine',{}).get('value','?')}, {h.get('city','?')}, FL") + except Exception as e: + print(f" {city}: ERROR {e}") diff --git a/casa-hunter/iniciar.bat b/casa-hunter/iniciar.bat new file mode 100644 index 0000000..a428bba --- /dev/null +++ b/casa-hunter/iniciar.bat @@ -0,0 +1,25 @@ +@echo off +echo ======================================== +echo Casa Hunter FL - Iniciando... +echo ======================================== + +cd /d "%~dp0" + +REM Crear entorno virtual si no existe +if not exist "venv" ( + echo Creando entorno virtual... + python -m venv venv +) + +REM Activar entorno e instalar dependencias +call venv\Scripts\activate.bat +pip install -q -r requirements.txt + +REM Iniciar la app +echo. +echo Abriendo en tu navegador: http://localhost:5105 +echo Presiona Ctrl+C para detener. +echo. +start "" "http://localhost:5105" +cd app +python main.py diff --git a/casa-hunter/package.json b/casa-hunter/package.json new file mode 100644 index 0000000..e5a398d --- /dev/null +++ b/casa-hunter/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "agent-browser": "^0.26.0" + } +} diff --git a/casa-hunter/prisayachts_motors_filtration_content.md b/casa-hunter/prisayachts_motors_filtration_content.md new file mode 100644 index 0000000..39ebd37 --- /dev/null +++ b/casa-hunter/prisayachts_motors_filtration_content.md @@ -0,0 +1,417 @@ +# Prisa Yachts LLC — Marketing Content +## Category: Marine Engines & Filtration Systems +## Generated: 2026-05-04 + +--- + +# TIP 1: THE IMPELLER + +## Titulo del Tip +**The $30 Part That Can Kill a $15,000 Engine** + +--- + +### Explicacion Tecnica + +The impeller is a small rubber wheel inside your raw-water pump that moves cooling water from the ocean or river into your engine's heat exchanger. It typically costs between $20 and $50 depending on your engine brand. When it fails — and it will fail — your engine loses cooling water circulation in seconds. Without coolant flow, temperatures spike fast. On a hot Florida day, running even 5 minutes without a functioning impeller can warp cylinder heads, seize bearings, or crack heat exchangers. The repair bill starts at $2,000 and can reach $15,000 or more on larger inboard diesels. + +The failure mode is deceptive. The impeller does not snap suddenly like a belt — it degrades. The rubber vanes harden and crack from heat, age, or running dry even briefly. Florida's warm saltwater accelerates this degradation compared to northern climates. Fragments of a failed impeller can also travel downstream into the heat exchanger and block cooling passages, which means replacing the impeller alone is not enough — you must inspect and flush the entire raw-water circuit. + +The correct replacement interval for most marine engines in Florida saltwater is every 200 hours of operation or once per season — whichever comes first. If your boat sits for months between uses, replace the impeller regardless of hours because rubber hardens when static. Always have a spare impeller onboard. Carry the correct size for your engine model, the right gasket, and the proper grease. A 15-minute dock-side replacement is infinitely better than a tow and a ruined engine. + +--- + +### Caption EN (Instagram) + +That small rubber wheel inside your raw-water pump? It costs $30. When it fails while you're underway in Florida heat, your engine can overheat in under 5 minutes — we're talking warped heads, seized bearings, cracked heat exchangers. The repair? Easily $5,000 to $15,000. + +The impeller is the single most overlooked part in marine engine maintenance. Florida's warm saltwater makes rubber degrade faster than you'd expect. Best practice: replace every 200 hours OR once per season — whichever comes first. And always carry a spare onboard. + +Signs it's failing: rising engine temperature, reduced raw-water flow from the exhaust, or rubber fragments in your strainer basket. Don't wait for an alarm. By then, the damage is done. + +At Prisa Yachts LLC, impeller replacement is part of every seasonal service we perform — from Stuart to Jacksonville. We check the full raw-water circuit, not just the pump. + +DM us for preventive maintenance — Stuart to Jacksonville. + +#PrisaYachts #MarineMaintenance #ImpellerService #BoatMaintenance #FloridaBoating + +--- + +### Caption ES (Instagram) + +Esa pequeña rueda de goma dentro de tu bomba de agua bruta cuesta $30. Cuando falla mientras navegas en el calor de Florida, tu motor puede sobrecalentarse en menos de 5 minutos — estamos hablando de culatas dobladas, cojinetes agarrotados, intercambiadores fisurados. La reparacion? Facil $5,000 a $15,000. + +El impeller es la pieza mas ignorada en el mantenimiento de motores marinos. El agua salada caliente de Florida degrada el caucho mucho mas rapido de lo que imaginas. Lo correcto: cambiarlo cada 200 horas O una vez por temporada — lo que ocurra primero. Y siempre lleva uno de repuesto a bordo. + +Señales de fallo: temperatura del motor subiendo, poco flujo de agua en el escape, o fragmentos de goma en la canastilla del filtro. No esperes la alarma. Para entonces, el daño ya esta hecho. + +En Prisa Yachts LLC, el cambio de impeller es parte de todo servicio de temporada — de Stuart a Jacksonville. Revisamos todo el circuito de agua bruta, no solo la bomba. + +Escríbenos para mantenimiento preventivo — de Stuart a Jacksonville. + +#PrisaYachts #MantenimientoMarino #Impeller #BarcosEnFlorida #MotorMarino + +--- + +### 10 Hashtags +``` +#ImpellerReplacement #MarineEngine #RawWaterPump #BoatMaintenance #FloridaBoating #MarineMechanic #PreventiveMaintenance #SaltwaterBoating #YachtMaintenance #PrisaYachtsLLC +``` + +--- +--- + +# TIP 2: ZINCS / ANODES + +## Titulo del Tip +**Zincs: The Sacrificial Guards Your Engine Needs** + +--- + +### Explicacion Tecnica + +Galvanic corrosion is one of the most destructive forces in the marine environment, and most boat owners do not understand it until something expensive has already been eaten away. When two dissimilar metals are submerged in saltwater — an electrolyte — an electrochemical reaction occurs. One metal becomes the anode and corrodes rapidly; the other becomes the cathode and is protected. Your aluminum lower unit, stainless shaft, bronze through-hulls, and bronze impeller housing are all at risk. + +Zinc anodes work by being the most reactive metal in that circuit. Zinc corrodes first, sacrificially, protecting your more expensive components. Aluminum anodes are used in saltwater and are actually slightly more protective than zinc in full saltwater environments — many professionals now recommend aluminum anodes in Florida. Magnesium anodes are for freshwater only. Using the wrong anode material or allowing anodes to become fully depleted leaves your underwater gear completely exposed to accelerated galvanic attack. + +The rule of thumb is to inspect anodes every 3 to 6 months in Florida saltwater and replace them when they are 50% consumed. Do not wait until they are gone — by then, your outdrive, shaft, or lower unit has already been attacked. On outboard motors, check the anode on the lower unit, the trim tab anode, and any bracket anodes. On inboard diesels, check shaft zincs, rudder zincs, keel bolt zincs, and any sacrificial plates on the hull. After extended haul-outs or dock periods, always check for stray current corrosion, which can eat through an anode in days rather than months. + +--- + +### Caption EN (Instagram) + +Saltwater is relentless. The moment your boat touches it, electrochemical reactions start attacking your underwater metals — aluminum lower units, stainless shafts, bronze fittings. The only thing standing between your engine and accelerated corrosion is a small piece of zinc or aluminum worth a few dollars. + +Anodes work by corroding first, sacrificing themselves so your expensive components don't. But here's what most people miss: a depleted anode is worse than no anode — because it gives you false confidence. In Florida's warm, conductive saltwater, anodes can go from full to 50% consumed in a single season. + +Inspection schedule: every 3–6 months. Replace at 50% consumed — not 100%. On outboards, check your lower unit anode AND your trim tab. On inboard diesels, inspect shaft zincs, rudder zincs, and hull plates. + +Saltwater doesn't take days off. Neither do we. + +DM us for preventive maintenance — Stuart to Jacksonville. + +#PrisaYachts #ZincAnodes #GalvanicCorrosion #MarineMaintenance #FloridaBoating + +--- + +### Caption ES (Instagram) + +El agua salada no para. Desde el momento en que tu barca toca el agua, reacciones electroquimicas atacan tus metales sumergidos — unidades inferiores de aluminio, ejes de acero inoxidable, accesorios de bronce. Lo unico que esta entre tu motor y la corrosion acelerada es un pequeño trozo de zinc o aluminio que cuesta unos pocos dolares. + +Los anodos funcionan corroiendose primero, sacrificandose para que tus piezas caras no lo hagan. Pero esto es lo que la mayoria ignora: un anodo agotado es peor que no tenerlo — porque te da una falsa sensacion de seguridad. En el agua salada calida y conductora de Florida, un anodo puede pasar de nuevo a 50% consumido en una sola temporada. + +Frecuencia de inspeccion: cada 3 a 6 meses. Reemplaza cuando este al 50% — no al 100%. En fuera de borda, revisa el anodo de la unidad inferior Y el trim tab. En diesel inboard, inspecciona los zincs del eje, del timon y las placas del casco. + +El agua salada no descansa. Nosotros tampoco. + +Escríbenos para mantenimiento preventivo — de Stuart a Jacksonville. + +#PrisaYachts #AnodesMarinos #CorrosionGalvanica #MantenimientoMarino #BarcosEnFlorida + +--- + +### 10 Hashtags +``` +#ZincAnodes #GalvanicCorrosion #MarineCorrosionProtection #AnodeReplacement #SaltwaterBoating #OutboardMaintenance #InboardDiesel #FloridaBoating #MarineMechanic #PrisaYachtsLLC +``` + +--- +--- + +# TIP 3: FUEL FILTER — PRIMARY vs. SECONDARY + +## Titulo del Tip +**Two Filters, One Mission: Keeping Bad Fuel Out of Your Engine** + +--- + +### Explicacion Tecnica + +Marine fuel filtration is a two-stage system, and confusing or neglecting either stage can result in injector failure, fuel pump damage, or a dead engine offshore. The primary fuel filter — most commonly a Racor or equivalent bowl-type separator — sits between the fuel tank and the lift pump. Its job is the heavy work: separating water from diesel (or gasoline), catching large sediment, and providing a visual inspection point through its clear or translucent bowl. This is the filter that saves you when you pick up a tank of contaminated fuel from a questionable marina. It handles particles down to 10 or 30 microns depending on the element installed. + +The secondary fuel filter is mounted directly on the engine, between the lift pump and the high-pressure injection pump or injectors. It is the final defense — it catches particles down to 2 or 10 microns, protecting precision-machined injector components that can be damaged by particles invisible to the naked eye. Modern common-rail diesel engines are especially sensitive here: injector tolerances are measured in thousandths of a millimeter. A single episode of contaminated fuel reaching the injectors without proper secondary filtration can result in injector replacement costs of $300 to $800 per injector. + +In Florida's saltwater environment, condensation inside fuel tanks is a year-round problem due to temperature swings and humidity. Water accumulation in diesel tanks also promotes microbial growth — the dark, slimy contamination known as diesel algae or diesel bug. This biological contamination clogs both filter stages rapidly. Best practice: inspect the Racor bowl every 50 hours or monthly, drain any water accumulation immediately, and replace the primary element every 100 to 200 hours. Replace the secondary filter at every engine oil change. If you find dark, coffee-ground-like sediment in your bowl, address the tank contamination before it overruns both filters. + +--- + +### Caption EN (Instagram) + +Your diesel engine has two lines of defense against bad fuel — and most boat owners only know about one of them. + +The PRIMARY filter (Racor bowl-type) does the heavy lifting: it pulls water out of your diesel and catches large sediment before it reaches the lift pump. That clear bowl? Inspect it every 50 hours. If you see water or dark sludge — stop. Deal with it before you go offshore. + +The SECONDARY filter is mounted on the engine itself. It catches particles down to 2 microns — protecting your injection pump and injectors. Modern common-rail diesels can have injector tolerances tighter than a human hair. Contaminated fuel reaching those injectors means a $300–$800 repair per injector. Replace this filter at every oil change. + +Florida's humidity and temperature swings cause constant condensation inside fuel tanks. That means water, and water means diesel algae. Two-stage filtration is not optional here — it's survival. + +DM us for preventive maintenance — Stuart to Jacksonville. + +#PrisaYachts #FuelFilter #RacorFilter #MarineDiesel #FloridaBoating + +--- + +### Caption ES (Instagram) + +Tu motor diesel tiene dos lineas de defensa contra el combustible contaminado — y la mayoria de los dueños de embarcaciones solo conoce una. + +El filtro PRIMARIO (tipo bowl Racor) hace el trabajo pesado: separa el agua del diesel y captura sedimentos grandes antes de que lleguen a la bomba de cebado. Ese bowl transparente? Inspeccionalo cada 50 horas. Si ves agua o lodo oscuro — para. Resuelve eso antes de salir a mar abierto. + +El filtro SECUNDARIO esta montado en el motor mismo. Captura particulas de hasta 2 micrones, protegiendo tu bomba de inyeccion y los inyectores. Los dieseles modern common-rail tienen tolerancias en los inyectores mas finas que un cabello humano. Combustible contaminado llegando a esos inyectores significa $300 a $800 de reparacion por inyector. Cambia este filtro en cada cambio de aceite. + +La humedad y los cambios de temperatura en Florida causan condensacion constante dentro de los depositos. Eso significa agua, y el agua significa algas en el diesel. La filtracion en dos etapas no es opcional aqui — es supervivencia. + +Escríbenos para mantenimiento preventivo — de Stuart a Jacksonville. + +#PrisaYachts #FiltroCombustible #FiltroRacor #DieselMarino #BarcosEnFlorida + +--- + +### 10 Hashtags +``` +#FuelFilter #RacorFilter #MarineDiesel #FuelFiltration #DieselMaintenance #MarineEngine #FloridaBoating #BoatMaintenance #PreventiveMaintenance #PrisaYachtsLLC +``` + +--- +--- + +# TIP 4: MARINE OIL CHANGE vs. CAR OIL CHANGE + +## Titulo del Tip +**Your Boat Engine Is Not Your Car — Oil Changes Are Not the Same** + +--- + +### Explicacion Tecnica + +One of the most dangerous assumptions a boat owner can make is treating their marine engine like an automobile engine for maintenance purposes. The oil change interval on your car — 5,000 to 7,500 miles or 6 months — has no direct equivalent in a marine context. Marine engines operate under fundamentally different conditions: they run at sustained high loads for hours at a time, they rarely have the benefit of air cooling from vehicle movement, they operate in high-humidity environments, and many are cooled by raw water systems that can introduce moisture into the engine compartment. All of these factors accelerate oil degradation. + +For most gasoline inboard and sterndrive engines, the manufacturer recommendation is an oil change every 100 hours of operation or once per season — whichever comes first. For diesel inboard engines, the interval is typically 100 to 150 hours depending on the engine model and whether a bypass filtration system is installed. Critically, hour-based intervals are far more relevant than calendar-based ones in marine applications. A boat that runs 20 hours per month needs oil changes far more frequently than its owner might assume. Conversely, a boat that sits 8 months in a slip still needs an oil change before the next season even if the oil shows no visible contamination, because moisture and acidic combustion byproducts accumulate in stored oil. + +The oil specification also matters. Marine diesel engines require oils meeting specific marine diesel engine ratings — look for API CJ-4 or the manufacturer's specified rating. Many automotive diesel oils lack the additives required for the high sulfur content and load conditions of marine diesels. For gasoline marine engines, use oil meeting the manufacturer's specification, and never use automotive oil with "Energy Conserving" designations in marine applications — the friction modifiers added to these oils to improve car fuel economy can cause clutch slippage in marine transmissions. Always change the oil filter at every oil change, drain the raw-water side of the cooling system if applicable, and inspect the oil for any milky appearance that would indicate water intrusion. + +--- + +### Caption EN (Instagram) + +Your car tells you when to change the oil. Your boat doesn't. And the consequences of getting this wrong are far more expensive on the water. + +Marine engines run at sustained high loads for hours. They sit in humid environments. Raw-water cooling systems can push moisture into the bilge and engine compartment. All of that destroys oil faster than a highway commute ever could. + +The rules are different here: +- Gasoline inboard: every 100 hours OR once per season +- Diesel inboard: every 100–150 hours (check your manual) +- Stored for the season? Change the oil before AND after storage — not just one. + +Also critical: do NOT use automotive "Energy Conserving" oil in a marine gasoline engine. Those friction modifiers can cause your marine transmission clutch to slip. Use oil rated and specified for your exact engine. + +And always — always — change the filter at the same time. + +We perform complete engine oil service from Stuart to Jacksonville. We bring the right oil, the right filter, and the technical knowledge to do it correctly. + +DM us for preventive maintenance — Stuart to Jacksonville. + +#PrisaYachts #MarineOilChange #BoatMaintenance #MarineEngine #FloridaBoating + +--- + +### Caption ES (Instagram) + +Tu carro te avisa cuando cambiar el aceite. Tu barca no. Y las consecuencias de equivocarse son mucho mas caras en el agua. + +Los motores marinos trabajan a cargas altas sostenidas durante horas. Estan en ambientes humidos. Los sistemas de refrigeracion de agua bruta pueden empujar humedad al compartimento del motor. Todo eso destruye el aceite mucho mas rapido que un viaje en autopista. + +Las reglas son distintas aqui: +- Gasolina inboard: cada 100 horas O una vez por temporada +- Diesel inboard: cada 100 a 150 horas (revisa tu manual) +- Guardo la barca por la temporada? Cambia el aceite ANTES y DESPUES — no solo una vez. + +Tambien critico: NO uses aceite automotriz "Energy Conserving" en un motor marino de gasolina. Los modificadores de friccion de esos aceites pueden hacer que el embrague de la transmision marina patine. Usa aceite especificado para tu motor exacto. + +Y siempre — siempre — cambia el filtro al mismo tiempo. + +Hacemos servicio completo de aceite de motor de Stuart a Jacksonville. Llevamos el aceite correcto, el filtro correcto y el conocimiento tecnico para hacerlo bien. + +Escríbenos para mantenimiento preventivo — de Stuart a Jacksonville. + +#PrisaYachts #CambioAceiteMarino #MantenimientoMarino #MotorMarino #BarcosEnFlorida + +--- + +### 10 Hashtags +``` +#MarineOilChange #OilChange #MarineEngine #InboardDiesel #BoatMaintenance #MarineMechanic #PreventiveMaintenance #FloridaBoating #SaltwaterBoating #PrisaYachtsLLC +``` + +--- +--- + +# TIP 5: EXHAUST SMOKE COLORS + +## Titulo del Tip +**Read the Smoke Before the Engine Can't Talk Anymore** + +--- + +### Explicacion Tecnica + +Your engine communicates constantly through its exhaust. A puff of smoke at startup in humid Florida air is normal — that is condensation burning off. But persistent exhaust smoke during normal operation is your engine telling you something is wrong, and each color carries a specific diagnostic message. Learning to read exhaust smoke color is one of the highest-value skills a boat owner or captain can develop, because it often provides early warning before an alarm triggers or damage occurs. + +White smoke during normal operation indicates water or coolant entering the combustion chamber. This is a serious finding. The most common causes are a leaking head gasket, a cracked cylinder head, or a failing heat exchanger allowing raw water into the combustion circuit. In Florida's saltwater environment, a heat exchanger that introduces saltwater into the engine will cause internal corrosion and deposit buildup rapidly. White smoke accompanied by a sweet smell and milky residue in the oil confirms coolant contamination of the oil circuit — shut down immediately and do not restart the engine until it is inspected. On raw-water-cooled engines, white smoke can also result from a faulty thermostat allowing overcooling, which prevents complete combustion. + +Black smoke indicates an overly rich fuel mixture — too much fuel relative to available air. Common causes include clogged air filters, dirty or failing injectors delivering excessive fuel, a malfunctioning turbocharger on turbocharged diesels, or a restricted air intake. Black smoke is most visible at hard acceleration or under heavy load. While it does not always indicate imminent catastrophic failure, it does signal poor combustion efficiency, increased carbon buildup, and fuel waste. Persistent black smoke on a diesel should trigger an injector inspection and service. Blue smoke is the most unambiguous signal: it means engine oil is burning in the combustion chamber. Causes include worn piston rings, worn valve stem seals, or in turbocharged engines, a failing turbo seal allowing oil into the intake charge. Blue smoke that appears only at startup and clears quickly often points to valve stem seals — oil pools on top of closed valves overnight. Blue smoke that is persistent under load indicates piston ring wear and is a more serious mechanical finding requiring immediate evaluation. + +--- + +### Caption EN (Instagram) + +Your engine can't text you. But it can talk through its exhaust — if you know how to listen. + +WHITE SMOKE (persistent, not startup condensation): Water or coolant in the combustion chamber. Head gasket, cracked head, or heat exchanger failure. If your oil looks milky, shut down NOW. Do not restart. + +BLACK SMOKE: Too much fuel, not enough air. Clogged air filter, dirty injectors, failing turbo, restricted intake. Less urgent than white, but fix it — carbon buildup adds up fast and fuel efficiency drops. + +BLUE SMOKE: Oil burning in the combustion chamber. Worn piston rings, valve seals, or a turbo seal failure. Startup blue that clears? Likely valve seals. Persistent blue under load? That's a mechanical inspection — now. + +Florida heat, saltwater exposure, and high humidity accelerate every one of these failure modes compared to northern boating environments. Read your exhaust at startup, during acceleration, and under load. Make it a habit every single time you leave the dock. + +DM us for preventive maintenance — Stuart to Jacksonville. + +#PrisaYachts #ExhaustSmoke #MarineEngine #DiagnosticTips #FloridaBoating + +--- + +### Caption ES (Instagram) + +Tu motor no puede mandarte un mensaje. Pero puede hablar a traves de su escape — si sabes escuchar. + +HUMO BLANCO (persistente, no condensacion al arranque): Agua o refrigerante en la camara de combustion. Junta de culata, culata fisurada, o fallo del intercambiador de calor. Si el aceite se ve lechoso, APAGA el motor YA. No lo vuelvas a encender. + +HUMO NEGRO: Demasiado combustible, poco aire. Filtro de aire obstruido, inyectores sucios, turbo fallando, toma de aire restringida. Menos urgente que el blanco, pero solucionalo — la acumulacion de carbon es costosa y el rendimiento cae. + +HUMO AZUL: Aceite quemandose en la camara de combustion. Anillos de piston desgastados, retenes de valvulas, o fallo del sello del turbo. Azul al arranque que desaparece? Probablemente retenes de valvulas. Azul persistente bajo carga? Inspeccion mecanica — ahora. + +El calor de Florida, la exposicion al agua salada y la humedad aceleran todos estos modos de fallo comparado con la navegacion en climas del norte. Lee tu escape al arrancar, durante la aceleracion y bajo carga. Haz un habito de esto cada vez que salgas del muelle. + +Escríbenos para mantenimiento preventivo — de Stuart a Jacksonville. + +#PrisaYachts #HumoEscape #MotorMarino #DiagnosticoMarino #BarcosEnFlorida + +--- + +### 10 Hashtags +``` +#ExhaustSmoke #MarineEngineDiagnostics #WhiteSmoke #BlackSmoke #BlueSmoke #MarineEngine #BoatMaintenance #FloridaBoating #MarineMechanic #PrisaYachtsLLC +``` + +--- +--- + +# CARRUSEL: ANNUAL ENGINE SERVICE CHECKLIST — FLORIDA SALTWATER + +## Format: 5 Slides para Instagram Carousel + +--- + +### SLIDE 1 — Cover / Hook + +**VISUAL DIRECTION:** Dark navy background, bold white type, Prisa Yachts LLC logo. Engine close-up photo or graphic of checklist icon. + +**HEADLINE:** +Annual Engine Service Checklist +Florida Saltwater Edition + +**SUBTEXT:** +10 things your engine needs every year to survive Florida's saltwater environment. +(Most boat owners skip at least 3 of these.) + +**Bottom tag:** +@prisayachtsllc | Stuart to Jacksonville + +--- + +### SLIDE 2 — Fluid & Filter Service + +**HEADLINE:** +Step 1: Fluids & Filters + +**BODY TEXT:** +- Change engine oil and oil filter (per manufacturer hours) +- Replace primary fuel filter element (Racor) +- Replace secondary engine fuel filter +- Check and replace gear oil in transmission/outdrive +- Inspect coolant concentration and condition (50/50 mix minimum) +- Drain and inspect raw-water strainer basket + +**CALLOUT BOX:** +Florida tip: Diesel tanks collect condensation year-round. Inspect Racor bowl every 50 hours — never skip it. + +--- + +### SLIDE 3 — Raw Water Cooling System + +**HEADLINE:** +Step 2: Raw Water Cooling Circuit + +**BODY TEXT:** +- Replace raw-water impeller (every 200 hours or annually) +- Inspect and flush heat exchanger +- Check all raw-water hoses for cracking, softness, or swelling +- Inspect thermostat — replace every 2 seasons in saltwater +- Clean seacock strainer and test seacock operation +- Check exhaust water flow at startup (look for steady stream) + +**CALLOUT BOX:** +Florida tip: A failed impeller in summer heat can destroy a motor in under 5 minutes. Replace it — do not test it. + +--- + +### SLIDE 4 — Belts, Hoses & Corrosion Protection + +**HEADLINE:** +Step 3: Belts, Hoses & Anodes + +**BODY TEXT:** +- Inspect and replace serpentine/V-belts (look for cracking, glazing, fraying) +- Replace all zincs/anodes: lower unit, trim tab, shaft, rudder, hull plates +- Inspect all coolant hoses — squeeze test for hardness or sponginess +- Check all fuel hose connections for seepage or cracking +- Inspect motor mounts for deterioration +- Check engine alignment (inboard) + +**CALLOUT BOX:** +Florida tip: Replace anodes when 50% consumed — not 100%. Aluminum anodes outperform zinc in full saltwater. + +--- + +### SLIDE 5 — Ignition, Electrical & Final Checks + +**HEADLINE:** +Step 4: Ignition, Electrical & Final Inspection + +**BODY TEXT:** +- Inspect and clean battery terminals — check electrolyte levels (AGM/flooded) +- Test alternator output voltage (13.8–14.4V at charge) +- Inspect spark plugs or glow plugs depending on engine type +- Test all engine alarms: overheat, low oil pressure, no raw-water flow +- Run engine to full operating temperature — observe exhaust color +- Log engine hours and record all service performed with dates + +**CALLOUT BOX:** +Florida tip: Test your alarms with every service. An alarm that doesn't sound gives you zero warning when it matters most. + +**BOTTOM CTA (all slides footer):** +Need this done right? DM us for your annual engine service. +Prisa Yachts LLC — Stuart to Jacksonville +@prisayachtsllc + +--- + +### Hashtags for Carousel Post +``` +#AnnualBoatService #MarineEngineService #BoatMaintenance #FloridaBoating #SaltwaterBoating #MarineMechanic #EngineChecklist #PreventiveMaintenance #YachtMaintenance #PrisaYachtsLLC +``` + +--- + +*End of content block — Prisa Yachts LLC / Marine Engines & Filtration / 2026-05-04* diff --git a/casa-hunter/prisayachts_teca_detailing_content.md b/casa-hunter/prisayachts_teca_detailing_content.md new file mode 100644 index 0000000..f070412 --- /dev/null +++ b/casa-hunter/prisayachts_teca_detailing_content.md @@ -0,0 +1,397 @@ +# Prisa Yachts LLC — Teca Marina & Detailing +## Instagram Content Pack — 5 Technical Tips + 3 Before/After Captions +Generated: 2026-05-04 + +--- + +## TIP 1 — CAN YOUR TEAK BE SAVED? (Visual Evaluation) + +### Technical Explanation + +Teak on a boat deck faces a punishment that few wood species can survive without help: UV radiation, salt spray, standing water, foot traffic, and constant thermal expansion. Before spending money on any product or labor, the first question is always the same — can this wood be recovered, or does it need to go? + +The answer lives in the wood itself. Healthy teak that has simply been neglected shows a consistent gray or silver patina across the surface, with wood fibers that are intact, tight-grained, and firm to pressure. Run your thumbnail across the grain — if the wood feels dense and you get a clean scrape without fiber lift, you are looking at a candidate for recovery. The gray color is oxidized surface oil and UV-bleached lignin, not damage. That layer sands off cleanly and the honey-brown color underneath is waiting. + +Teak that cannot be saved tells a different story. Look for soft spots that compress under thumb pressure, caulking seams that have pulled away from the wood by more than 3mm, planks with longitudinal cracking along the grain (not just surface checking), or areas where the wood has gone thin from previous aggressive sandings. In Florida's climate, two-season neglect is often the threshold — after that, recovery becomes a gamble. When more than 30% of plank thickness is compromised, replacement is the more honest conversation. + +--- + +### Caption EN (Instagram) + +Your teak is gray and looks rough — but is it actually dead? + +Here's the honest evaluation we do before touching a single plank. Run your thumbnail across the grain: if the wood is dense, firm, and fibers don't lift, that gray surface is just oxidation. The honey-brown color is still underneath, waiting. That's a recovery job. + +What tells us replacement is the real answer: soft spots that compress under pressure, caulking seams that have pulled away from the wood by more than an inch, planks cracking along the grain from the inside out, or wood that's gone thin from years of aggressive sanding. + +In Florida, two seasons of zero maintenance is often the turning point. We've recovered teak that looked destroyed — and we've also had the honest conversation when replacement was the smarter investment. + +If you're not sure which side of that line you're on, send us a few photos. We'll give you a straight answer before you spend a dollar. + +DM us for a quote — Stuart to Jacksonville. + +#PrisaYachts #TeakRecovery #MarineTeak #BoatMaintenance #FloridaBoating #YachtDetailing #TeakDeck #MarineServices #BoatCare #SouthFloridaYachts + +--- + +### Caption ES (Instagram) + +Tu teca está gris y se ve mal — pero, ¿realmente está muerta? + +Esta es la evaluación honesta que hacemos antes de tocar una sola tabla. Pasa la uña a contrapelo: si la madera está densa, firme y las fibras no se levantan, esa superficie gris es solo oxidación. El color miel todavía está adentro, esperando. Eso es trabajo de recuperación. + +Lo que nos dice que el reemplazo es la respuesta real: zonas blandas que ceden bajo presión, costuras de sellado separadas más de 2 cm, tablas con grietas a lo largo de la veta desde adentro, o madera que se ha adelgazado demasiado por lijados agresivos previos. + +En Florida, dos temporadas sin mantenimiento suelen ser el punto de quiebre. Hemos recuperado teca que parecía destruida — y también hemos tenido la conversación honesta cuando el reemplazo era la inversión más inteligente. + +Si no sabes de qué lado estás, mándanos unas fotos. Te damos una respuesta directa antes de que gastes un dólar. + +Escríbenos para un presupuesto — Stuart to Jacksonville. + +#PrisaYachts #RecuperacionDeTeca #TecaMarina #MantenimientoNautico #YachtsFlorida #DetallingMarino #TecaNautica #ServiciosMarinos #CuidadoDeBarco #YachtsSurFlorida + +--- +--- + +## TIP 2 — THE TEAK RECOVERY PROCESS: CLEAN → SAND → OIL → SEAL + +### Technical Explanation + +Teak recovery is a sequence, not a product. The biggest mistake boat owners make is applying a new coat of oil or sealer over a neglected surface and expecting results. What actually happens is that the new product sits on top of old oxidized oil, salt residue, and mildew — and fails within weeks. The process only works when it follows the correct order. + +Step one is a dedicated teak cleaner, typically a two-part system: an oxalic acid-based Part A that breaks down oxidation and gray surface cells, followed by a neutralizing Part B that restores the wood's natural pH before sanding. Allow the wood to dry completely — in Florida's humidity, 24 to 48 hours is the minimum. Step two is mechanical: 80-grit to open the grain, followed by 120-grit to smooth without closing the pores. Always sand with the grain. Never use a random orbit sander across teak — you will create circular scratch patterns that telegraphed through any finish and collect water. + +Step three is penetrating oil — tung-based or a dedicated marine teak oil — applied in thin coats with a rag or brush, wiping off the excess before it skins on the surface. This feeds the wood from inside. Step four, the sealer, is optional but critical for high-traffic areas in Florida: a quality teak sealer adds UV protection and slows the reoxidation cycle. The honest timeline for this full process on a mid-size deck? One solid day of labor. The result lasts 12 to 18 months before the next maintenance cycle. + +--- + +### Caption EN (Instagram) + +Teak recovery isn't magic — it's a sequence. And most DIY jobs fail because they skip a step. + +Here's the actual process we follow: + +CLEAN — Two-part teak cleaner. Part A breaks down oxidation and gray surface cells. Part B neutralizes the wood's pH. You're starting with a clean canvas, not covering problems. + +SAND — 80-grit to open the grain, 120-grit to smooth. Always with the grain. Never cross-grain with a random orbit sander — you'll create water traps invisible to the eye. + +OIL — Penetrating marine teak oil, thin coats, wiped before it skins. This feeds the wood from the inside. You're not painting it, you're conditioning it. + +SEAL — UV-blocking teak sealer for high-traffic areas. Florida sun will reoxidize bare teak in one season. The sealer buys you 12 to 18 months before the next maintenance cycle. + +Skip any of these steps and you're spending money to fail faster. + +DM us for a quote — Stuart to Jacksonville. + +#PrisaYachts #TeakRestoration #MarineTeak #BoatDetailingFlorida #TeakDeckCare #MarineWoodcare #FloridaYacht #BoatMaintenance #YachtCare #MarineDetailing + +--- + +### Caption ES (Instagram) + +La recuperación de teca no es magia — es una secuencia. Y la mayoría de los trabajos fallan porque se salta un paso. + +Este es el proceso real que seguimos: + +LIMPIAR — Limpiador de teca en dos partes. La parte A rompe la oxidación y las células grises de la superficie. La parte B neutraliza el pH de la madera. Empiezas con una superficie limpia, no cubriendo problemas. + +LIJAR — Lija 80 para abrir el grano, 120 para alisar. Siempre a favor de la veta. Nunca transversal con lijadora orbital — creas trampas de agua invisibles al ojo. + +ACEITAR — Aceite marino de teca penetrante, capas finas, limpiando el exceso antes de que forme película. Nutres la madera desde adentro. No la estás pintando, la estás acondicionando. + +SELLAR — Sellador UV para zonas de alto tráfico. El sol de Florida reoxida la teca sin protección en una sola temporada. El sellador te da 12 a 18 meses hasta el próximo ciclo de mantenimiento. + +Sáltate cualquiera de estos pasos y estás gastando dinero para fallar más rápido. + +Escríbenos para un presupuesto — Stuart to Jacksonville. + +#PrisaYachts #RestauracionTeca #TecaMarina #DetallingFlorida #CuidadoTeca #MaderaMaritima #YachtFlorida #MantenimientoNautico #CuidadoYacht #DetallingNautico + +--- +--- + +## TIP 3 — TEAK OIL VS. TEAK SEALER: WHICH ONE AND WHEN + +### Technical Explanation + +This is the most common technical confusion in teak maintenance, and it matters because using the wrong product in the wrong situation wastes both the product and your labor. Teak oil and teak sealer are not interchangeable — they solve different problems at different stages of the wood's condition. + +Teak oil is a penetrating product. It goes into the wood, not onto it. Chemically, quality marine teak oils are tung oil or linseed oil derivatives, sometimes blended with UV inhibitors. Their job is to feed dry, depleted wood — replenishing the natural oils that Florida sun and salt air strip out over months. Oil is the right choice after a full sand-and-clean recovery job, when the wood is porous and thirsty. Applied correctly, it disappears into the grain. If it sits on the surface and doesn't absorb within 20 minutes, the wood is still too wet or the pores are too tight from over-sanding. + +Teak sealer is a surface-forming barrier product. It does not feed the wood — it seals the surface to slow moisture movement, UV penetration, and the oxidation cycle. Sealer is the right follow-up product after oiling, particularly on horizontal surfaces like cockpit soles and side decks that take direct Florida sun and standing water. The key distinction for application: oil goes on depleted wood first; sealer goes on conditioned wood after. Applying sealer to bone-dry, un-oiled teak in Florida will produce a surface that looks great for 90 days and then begins to peel as the wood moves beneath it without any internal moisture buffer. + +--- + +### Caption EN (Instagram) + +Teak oil and teak sealer are not the same product. Using the wrong one at the wrong time is one of the most expensive mistakes in boat maintenance. + +Here's the difference: + +TEAK OIL is a penetrating product. It goes INTO the wood, not onto it. It feeds depleted wood — replacing the natural oils that Florida sun and salt air pull out month after month. Use it after a full clean and sand, when the wood is porous and dry. If it doesn't absorb within 20 minutes, something is wrong with the prep. + +TEAK SEALER is a surface barrier. It doesn't feed the wood — it seals the surface against UV, moisture movement, and reoxidation. Use it AFTER oiling, as the final layer on horizontal surfaces that take direct sun and standing water. + +The order matters: oil first, sealer second. Putting sealer on dry, un-oiled teak in Florida gives you 90 days of results before it starts peeling — because the wood is moving underneath and there's nothing holding it stable. + +Two products. Two jobs. Both necessary. Neither optional in this climate. + +DM us for a quote — Stuart to Jacksonville. + +#PrisaYachts #TeakOil #TeakSealer #MarineTeak #BoatWoodcare #FloridaBoating #TeakMaintenance #YachtCare #MarineDetailing #BoatMaintenance + +--- + +### Caption ES (Instagram) + +El aceite de teca y el sellador de teca no son el mismo producto. Usar el equivocado en el momento equivocado es uno de los errores más caros en el mantenimiento de embarcaciones. + +La diferencia: + +ACEITE DE TECA es un producto penetrante. Va DENTRO de la madera, no sobre ella. Nutre la madera agotada — reemplazando los aceites naturales que el sol de Florida y el aire salado extraen mes a mes. Úsalo después de una limpieza y lijado completo, cuando la madera está porosa y seca. Si no absorbe en 20 minutos, algo está mal con la preparación. + +SELLADOR DE TECA es una barrera superficial. No nutre la madera — sella la superficie contra los rayos UV, el movimiento de humedad y la reoxidación. Úsalo DESPUÉS del aceite, como capa final en superficies horizontales que reciben sol directo y agua estancada. + +El orden importa: aceite primero, sellador después. Poner sellador en teca seca sin aceite en Florida te da 90 días de resultados antes de que empiece a despegarse — porque la madera se está moviendo por debajo y no hay nada que la estabilice. + +Dos productos. Dos funciones. Ambos necesarios. Ninguno es opcional en este clima. + +Escríbenos para un presupuesto — Stuart to Jacksonville. + +#PrisaYachts #AceiteDeTeca #SelladorTeca #TecaMarina #MaderaMaritima #NavegacionFlorida #MantenimientoTeca #CuidadoYacht #DetallingMarino #MantenimientoNautico + +--- +--- + +## TIP 4 — WHY FLORIDA SUN DESTROYS TEAK IN 2 SEASONS WITHOUT MAINTENANCE + +### Technical Explanation + +Florida is not a normal marine environment for teak. The combination of UV index, ambient temperature, salt air humidity, and daily thermal cycling creates a degradation rate that boat owners from northern climates consistently underestimate. A well-maintained teak deck in Maine might hold its finish for two years with minimal intervention. The same deck in Stuart or Jacksonville without maintenance will be visibly compromised in 18 months and structurally thin in three seasons. + +The mechanism works in three simultaneous channels. UV radiation at Florida latitudes hits a UV index of 10 to 11 from March through October — among the highest in the continental US. This bleaches the lignin (the natural binder holding teak fibers together) and oxidizes the surface oils that give teak its density and water resistance. Salt air adds hygroscopic stress: salt crystals deposit in the wood grain, absorb moisture, and expand and contract with temperature, physically opening the grain from the inside. Thermal cycling — the 35-40°F daily temperature swings on a dark deck surface from 7 AM to 2 PM — causes wood movement that accelerates both UV and salt damage simultaneously. + +The result of all three combined is a deck that doesn't just look gray — it actually loses structural mass. Teak planks start at roughly 5/8 inch from the factory. Each aggressive sanding to address neglect removes material that doesn't come back. Most recoverable decks have 3/8 to 7/16 inch remaining. Below 1/4 inch, the structural argument for replacement becomes unanswerable. One properly executed maintenance cycle per year in Florida — clean, oil, seal — interrupts all three degradation channels and extends plank life by years. The math on prevention versus replacement is not close. + +--- + +### Caption EN (Instagram) + +Florida is not a forgiving environment for teak. And a lot of boat owners don't understand why until they're looking at a replacement quote. + +Here's what's actually happening to your deck every season you skip maintenance: + +UV INDEX 10-11 from March through October. That's among the highest in the continental US. It bleaches the lignin — the natural binder that holds teak fibers together — and oxidizes the surface oils that give the wood its density. Once the lignin is gone, the fibers start separating. + +SALT AIR deposits salt crystals in the open grain. Those crystals absorb moisture and expand and contract with the daily heat cycle, physically prying the wood open from the inside. + +THERMAL CYCLING on a dark deck surface means 35-40°F swings between 7 AM and 2 PM. That's constant wood movement — and it accelerates everything above. + +Teak planks start at 5/8 inch from the factory. Every aggressive sanding to fix neglect removes material that doesn't come back. Two seasons of zero maintenance in Florida can take a recoverable deck and make it a replacement conversation. + +One maintenance cycle per year stops all three damage channels. The math on prevention versus replacement is not close. + +DM us for a quote — Stuart to Jacksonville. + +#PrisaYachts #FloridaBoating #TeakDeck #UVDamage #MarineTeak #BoatMaintenance #TeakProtection #FloridaYacht #MarineDetailing #YachtCare + +--- + +### Caption ES (Instagram) + +Florida no es un ambiente generoso con la teca. Y muchos dueños de embarcaciones no lo entienden hasta que están viendo un presupuesto de reemplazo. + +Esto es lo que le pasa a tu cubierta cada temporada que saltas el mantenimiento: + +ÍNDICE UV 10-11 de marzo a octubre. Es uno de los más altos de los Estados Unidos continentales. Blanquea la lignina — el aglutinante natural que mantiene las fibras de teca unidas — y oxida los aceites superficiales que le dan densidad a la madera. Una vez que la lignina se va, las fibras comienzan a separarse. + +AIRE SALADO deposita cristales de sal en el grano abierto. Esos cristales absorben humedad y se expanden y contraen con el ciclo de calor diario, abriendo físicamente la madera desde adentro. + +CICLOS TÉRMICOS en una cubierta oscura significan cambios de 18-22°C entre las 7 AM y las 2 PM. Eso es movimiento constante de la madera — y acelera todo lo anterior. + +Las tablas de teca salen de fábrica a 16 mm de espesor. Cada lijado agresivo para corregir el abandono elimina material que no vuelve. Dos temporadas sin mantenimiento en Florida pueden convertir una cubierta recuperable en una conversación de reemplazo. + +Un ciclo de mantenimiento al año detiene los tres canales de daño. La diferencia entre prevención y reemplazo no admite discusión. + +Escríbenos para un presupuesto — Stuart to Jacksonville. + +#PrisaYachts #NavegacionFlorida #TecaMarina #DañoUV #CubertaDeTeca #MantenimientoNautico #ProteccionTeca #YachtFlorida #DetallingMarino #CuidadoYacht + +--- +--- + +## TIP 5 — GELCOAT DETAILING: LIGHT OXIDATION VS. SEVERE — WHEN TO POLISH, WHEN TO WAX + +### Technical Explanation + +Gelcoat is a polyester resin surface — not paint — and it degrades through oxidation, not peeling. Florida's UV load, heat, and salt environment accelerate this process more aggressively than any other environment in the continental US. Understanding the difference between light oxidation and severe oxidation determines whether you reach for a polishing compound, a machine polisher, or a conversation about professional refinishing. + +Light oxidation presents as a slight haze or loss of depth in the gel coat's gloss. The color looks flat rather than vibrant. Run a white rag across the surface — if you get a faint chalky residue, you are in the light oxidation category. At this stage, a fine-cut polish on a dual-action polisher or even by hand will restore the surface without removing significant gelcoat. After polishing, a quality marine wax or paint sealant applied in thin coats provides 3 to 6 months of UV protection in Florida conditions. This is the maintenance cycle — polish when needed, protect always. + +Severe oxidation is visually distinct. The surface chalks heavily when touched, the color has shifted toward white or gray regardless of the original pigment, and you may see micro-cracking or a matte texture that does not respond to light polishing. At this stage, a cutting compound with a wool or foam cutting pad on a rotary or forced-rotation polisher is the entry point. This removes more material from the surface to get below the oxidized layer. The risk here is cutting through the gelcoat entirely — gelcoat is typically 0.5 to 0.8mm thick — which is why severe oxidation requires experienced hands. After a heavy cut, a finishing polish removes the cut marks, then wax or sealant seals the restored surface. In the most severe cases, if the gel coat has checked or crazing cracks across the surface, professional barrier coat application or refinishing may be the only path to a durable result. + +--- + +### Caption EN (Instagram) + +Not all oxidation is the same — and treating them the same way is how you either under-correct or burn through your gelcoat. + +Here's how to read what you're dealing with: + +LIGHT OXIDATION: Surface looks hazy, colors seem flat instead of vibrant. Drag a white rag across it — faint chalk residue. At this stage, a fine-cut polish on a DA polisher (or by hand) restores the gloss without removing significant gelcoat. Follow with a quality marine wax or sealant. In Florida, that protection lasts 3 to 6 months. + +SEVERE OXIDATION: Heavy chalking when touched, original color has shifted toward white or gray, surface feels matte and doesn't respond to light polishing. Now you're in cutting compound territory — wool or foam cutting pad, rotary or forced-rotation polisher. This removes more material. The risk: gelcoat is only 0.5 to 0.8mm thick. Heavy cutting requires experienced hands or you break through. + +The rule we follow: start with the least aggressive correction that solves the problem. You can always cut more. You can't put gelcoat back. + +After any cut: finishing polish to remove cut marks, then wax or sealant to protect what you've restored. + +DM us for a quote — Stuart to Jacksonville. + +#PrisaYachts #GelcoatRestoration #BoatDetailing #MarineDetailing #FloridaBoating #GelcoatPolishing #BoatWax #YachtDetailing #OxidationRemoval #BoatCare + +--- + +### Caption ES (Instagram) + +No toda oxidación es igual — y tratarlas igual es como se corrige de menos o se quema la capa de gelcoat. + +Así se lee lo que tienes frente a ti: + +OXIDACIÓN LEVE: La superficie se ve opaca, los colores parecen apagados en vez de vibrantes. Pasa un trapo blanco — residuo de tiza leve. En este punto, una pulida fina con pulidora DA (o a mano) restaura el brillo sin remover gelcoat significativo. Termina con cera marina o sellador. En Florida, esa protección dura 3 a 6 meses. + +OXIDACIÓN SEVERA: Tizamiento fuerte al tacto, el color original se ha ido hacia el blanco o gris, la superficie se siente mate y no responde al pulido leve. Ahora estás en territorio de compuesto de corte — pad de lana o espuma de corte, pulidora rotativa o de rotación forzada. Esto remueve más material. El riesgo: el gelcoat tiene solo 0.5 a 0.8mm de espesor. El corte agresivo requiere manos con experiencia o lo atraviesas. + +La regla que seguimos: empezar siempre con la corrección menos agresiva que resuelve el problema. Siempre puedes cortar más. No puedes devolver el gelcoat. + +Después de cualquier corte: pulido de acabado para eliminar las marcas, luego cera o sellador para proteger lo que restauraste. + +Escríbenos para un presupuesto — Stuart to Jacksonville. + +#PrisaYachts #RestauracionGelcoat #DetallingNautico #DetallingMarino #NavegacionFlorida #PulidoGelcoat #CeraParaBarcos #DetallingYacht #EliminacionOxidacion #CuidadoBarco + +--- +--- + +## BEFORE/AFTER CAPTIONS — 3 SPECIAL CAPTIONS FOR REAL TEAK PHOTOS + +--- + +### CAPTION 1 — DRAMATIC RESTORATION (Very Deteriorated → Perfect) + +**Caption EN** + +This is what two seasons of Florida sun and zero maintenance does to teak. And this is what the same deck looks like after a full recovery. + +No replacement. No new planks. The same wood — cleaned, sanded, oiled, and sealed by hand. + +What you're seeing on the left: gray, fiber-lifting, salt-embedded teak that most people would write off. What you're seeing on the right: the same deck, same wood, after a full two-part clean, progressive sanding, penetrating marine oil, and UV-blocking sealer. + +The honey-brown color was there the entire time. We just had to take the time to find it. + +This is why we evaluate before we quote. A lot of teak that looks dead in Florida isn't. It's just asking for the right process. + +DM us for a quote — Stuart to Jacksonville. + +#PrisaYachts #TeakBeforeAfter #TeakRestoration #MarineTeak #FloridaBoating #BoatDetailingFlorida #TeakDeck #BeforeAndAfter #YachtCare #MarineDetailing + +--- + +**Caption ES** + +Esto es lo que dos temporadas de sol de Florida y cero mantenimiento le hacen a la teca. Y esto es lo que luce el mismo deck después de una recuperación completa. + +Sin reemplazo. Sin tablas nuevas. La misma madera — limpiada, lijada, aceitada y sellada a mano. + +Lo que ves a la izquierda: teca gris, fibras levantadas, sal incrustada, que la mayoría descartaría. Lo que ves a la derecha: el mismo deck, la misma madera, después de una limpieza en dos partes, lijado progresivo, aceite marino penetrante y sellador con bloqueo UV. + +El color miel estaba ahí todo el tiempo. Solo había que tomarse el tiempo de encontrarlo. + +Por eso evaluamos antes de cotizar. Mucha teca que parece muerta en Florida no lo está. Solo necesita el proceso correcto. + +Escríbenos para un presupuesto — Stuart to Jacksonville. + +#PrisaYachts #TecaAntesYDespues #RestauracionTeca #TecaMarina #NavegacionFlorida #DetallingFlorida #CubertaTeca #AntesYDespues #CuidadoYacht #DetallingMarino + +--- +--- + +### CAPTION 2 — PREVENTIVE MAINTENANCE (Cared-For Teak → Even Better) + +**Caption EN** + +Preventive maintenance doesn't make the news. But this is what it actually looks like. + +This deck wasn't neglected. The owner was already doing the right things — keeping it clean, protecting it seasonally. We came in for a maintenance detail: light clean, light sand to refresh the grain, one coat of oil, sealer applied on horizontal surfaces. + +The difference between left and right isn't dramatic. It's deliberate. + +This is what protects a deck from ever needing the dramatic before/after. This is what adds years to the life of a teak investment. This is what the deck looks like when the owner treats it like the asset it is. + +One maintenance cycle per year in Florida. That's the whole strategy. + +DM us for a quote — Stuart to Jacksonville. + +#PrisaYachts #TeakMaintenance #PreventiveMaintenance #MarineTeak #BoatCare #FloridaYacht #TeakDeck #YachtMaintenance #MarineDetailing #BoatDetailing + +--- + +**Caption ES** + +El mantenimiento preventivo no sale en los titulares. Pero así es como se ve en la realidad. + +Esta cubierta no estaba abandonada. El propietario ya estaba haciendo las cosas bien — manteniéndola limpia, protegiéndola cada temporada. Llegamos para un detailing de mantenimiento: limpieza leve, lijado suave para refrescar el grano, una capa de aceite, sellador en las superficies horizontales. + +La diferencia entre la izquierda y la derecha no es dramática. Es intencional. + +Esto es lo que protege una cubierta de necesitar el antes/después dramático. Esto es lo que le agrega años de vida a una inversión en teca. Así luce una cubierta cuando el propietario la trata como el activo que es. + +Un ciclo de mantenimiento al año en Florida. Esa es toda la estrategia. + +Escríbenos para un presupuesto — Stuart to Jacksonville. + +#PrisaYachts #MantenimientoTeca #MantenimientoPreventivo #TecaMarina #CuidadoBarco #YachtFlorida #CubertaTeca #MantenimientoYacht #DetallingMarino #DetallingNautico + +--- +--- + +### CAPTION 3 — IN PROGRESS (Showing the Work) + +**Caption EN** + +Somewhere between gray and honey-brown, there's a lot of work. + +This is what teak recovery looks like mid-process. Two-part cleaner done. First sand done. The color is already starting to come back — you can see the honey starting to show through in the sections we've finished, still gray in the ones we haven't reached yet. + +This is the part that doesn't get skipped. No shortcuts between the before and after. + +Every plank by hand. Every seam inspected. Sanding with the grain, not against it. Wiping off the oil before it skins. Letting each coat dry before the next one goes on. + +The finished result is in the next post. But we wanted you to see this part too — because this is where the job actually gets done. + +DM us for a quote — Stuart to Jacksonville. + +#PrisaYachts #TeakRecovery #BehindTheScenes #MarineTeak #BoatDetailingFlorida #TeakRestoration #WorkInProgress #YachtCare #MarineDetailing #FloridaBoating + +--- + +**Caption ES** + +Entre el gris y el color miel, hay mucho trabajo. + +Así luce una recuperación de teca a la mitad del proceso. Limpiador en dos partes listo. Primer lijado listo. El color ya está empezando a volver — puedes ver el miel asomando en las secciones que terminamos, todavía gris en las que no hemos llegado. + +Esta es la parte que no se salta. No hay atajos entre el antes y el después. + +Cada tabla a mano. Cada costura inspeccionada. Lijando a favor de la veta, nunca en contra. Limpiando el aceite antes de que forme película. Dejando que cada capa seque antes de aplicar la siguiente. + +El resultado final está en el próximo post. Pero queríamos que vieras esta parte también — porque aquí es donde realmente se hace el trabajo. + +Escríbenos para un presupuesto — Stuart to Jacksonville. + +#PrisaYachts #RecuperacionTeca #DetrásDeEscena #TecaMarina #DetallingFlorida #RestauracionTeca #EnProceso #CuidadoYacht #DetallingMarino #NavegacionFlorida + +--- + +*END OF CONTENT PACK — Prisa Yachts LLC — Teca Marina & Detailing* +*5 Technical Tips + 3 Before/After Captions | Generated 2026-05-04* diff --git a/casa-hunter/requirements.txt b/casa-hunter/requirements.txt new file mode 100644 index 0000000..32c6539 --- /dev/null +++ b/casa-hunter/requirements.txt @@ -0,0 +1,4 @@ +flask==3.0.3 +flask-sqlalchemy==3.1.1 +requests==2.32.3 +beautifulsoup4==4.12.3 diff --git a/casa-hunter/test_apis.py b/casa-hunter/test_apis.py new file mode 100644 index 0000000..b32a15c --- /dev/null +++ b/casa-hunter/test_apis.py @@ -0,0 +1,59 @@ +import requests, json, sys + +headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124 Safari/537.36", + "Accept-Language": "en-US,en;q=0.9", +} + +# 1. Redfin city lookup +print("=== Redfin City IDs ===") +for city in ["Vero Beach, FL", "Jacksonville, FL", "Melbourne, FL", "Stuart, FL", "St. Augustine, FL"]: + try: + r = requests.get( + f"https://www.redfin.com/stingray/do/location-autocomplete?location={requests.utils.quote(city)}&count=3&v=2", + headers=headers, timeout=10 + ) + data = json.loads(r.text.replace("{}&&", "")) + rows = data.get("payload", {}).get("sections", [{}])[0].get("rows", []) + if rows: + row = rows[0] + print(f" {city}: id={row.get('id')}, type={row.get('type')}, url={row.get('url','')}") + else: + print(f" {city}: no result") + except Exception as e: + print(f" {city}: ERROR {e}") + +# 2. Test Redfin search with a known city +print("\n=== Redfin Search Sample (Vero Beach, FL) ===") +try: + # region_id for Vero Beach found via autocomplete + r = requests.get( + "https://www.redfin.com/stingray/api/gis?al=1&market=florida" + "®ion_type=6&status=9&uipt=1,2,3,4&max_price=230000&num_homes=5&start=0&v=8" + "&location=Vero+Beach%2C+FL", + headers=headers, timeout=15 + ) + data = json.loads(r.text.replace("{}&&", "")) + homes = data.get("payload", {}).get("homes", []) + print(f" Found: {len(homes)} homes") + for h in homes[:3]: + print(f" - ${h.get('price',{}).get('value','?'):,} | {h.get('streetLine',{}).get('value','?')}, {h.get('city','?')}") +except Exception as e: + print(f" ERROR: {e}") + +# 3. Test Redfin with city URL slug +print("\n=== Redfin via city page ===") +try: + r = requests.get( + "https://www.redfin.com/city/19073/FL/Vero-Beach/filter/max-price=230000,property-type=house+condo+townhouse", + headers=headers, timeout=15 + ) + import re + match = re.search(r'"payload":\s*\{.*?"homes":\s*(\[.*?\])\s*,\s*"(?:totalRowCount|url)"', r.text, re.DOTALL) + if match: + homes = json.loads(match.group(1)) + print(f" Found {len(homes)} homes via page") + else: + print(f" Status {r.status_code}, size {len(r.text)} - no match") +except Exception as e: + print(f" ERROR: {e}") diff --git a/casa-hunter/test_apis2.py b/casa-hunter/test_apis2.py new file mode 100644 index 0000000..8b2fbc5 --- /dev/null +++ b/casa-hunter/test_apis2.py @@ -0,0 +1,60 @@ +import requests, json, re + +headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124 Safari/537.36", + "Accept": "application/json, text/plain, */*", + "Accept-Language": "en-US,en;q=0.9", + "Referer": "https://www.redfin.com/", +} + +# Test the correct Redfin GIS endpoint that was working before +print("=== Redfin GIS with region_id ===") +try: + r = requests.get( + "https://www.redfin.com/stingray/api/gis?al=1&market=florida" + "®ion_id=14146®ion_type=6&status=9&uipt=1,2,3,4" + "&max_price=230000&num_homes=5&start=0&v=8", + headers=headers, timeout=15 + ) + print(f"Status: {r.status_code}") + raw = r.text.replace("{}&&", "") + data = json.loads(raw) + homes = data.get("payload", {}).get("homes", []) + print(f"Homes: {len(homes)}") + for h in homes[:3]: + print(f" ${h.get('price',{}).get('value',0):,} | {h.get('streetLine',{}).get('value','?')}, {h.get('city','?')} {h.get('zip','')}") +except Exception as e: + print(f"ERROR: {e}") + +# Try finding region IDs for our cities +print("\n=== Finding region IDs ===") +cities = ["Vero Beach", "Melbourne", "Jacksonville", "Stuart", "Daytona Beach"] +for city in cities: + try: + r = requests.get( + f"https://www.redfin.com/stingray/do/location-autocomplete?location={requests.utils.quote(city + ' FL')}&count=3&v=2", + headers=headers, timeout=10 + ) + print(f" {city}: status={r.status_code}, len={len(r.text)}") + raw = r.text.replace("{}&&", "") + if raw.strip(): + data = json.loads(raw) + rows = data.get("payload", {}).get("sections", [{}])[0].get("rows", []) + for row in rows[:2]: + print(f" -> id={row.get('id')}, type={row.get('type')}, name={row.get('name')}") + except Exception as e: + print(f" {city}: ERROR {e}") + +# Try Redfin search API directly +print("\n=== Redfin /stingray/api/gis-search ===") +try: + r = requests.get( + "https://www.redfin.com/stingray/api/gis-search?" + "al=1&market=florida®ion_id=19073®ion_type=6" + "&status=9&uipt=1,2,3,4&max_price=230000&num_homes=10&start=0&v=8", + headers=headers, timeout=15 + ) + print(f"Status: {r.status_code}, size: {len(r.text)}") + print(r.text[:400]) +except Exception as e: + print(f"ERROR: {e}") diff --git a/casa-hunter/test_apis3.py b/casa-hunter/test_apis3.py new file mode 100644 index 0000000..34f7625 --- /dev/null +++ b/casa-hunter/test_apis3.py @@ -0,0 +1,59 @@ +import requests, json, re + +headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124 Safari/537.36", + "Accept": "application/json, text/plain, */*", + "Accept-Language": "en-US,en;q=0.9", + "Referer": "https://www.redfin.com/", +} + +# Redfin city region IDs for Florida coastal cities +FL_CITY_IDS = { + "Vero Beach": 19073, + "Sebastian": 16461, + "Stuart": 16992, + "Jensen Beach": 9058, + "Fort Pierce": 7528, + "Port St. Lucie": 15348, + "Melbourne": 12007, + "Cocoa Beach": 5401, + "Cocoa": 5400, + "Titusville": 18427, + "Daytona Beach": 5866, + "Ormond Beach": 14428, + "New Smyrna Beach": 13473, + "Palm Coast": 14706, + "St. Augustine": 16629, + "Jacksonville": 9009, + "Jacksonville Beach": 9004, + "Atlantic Beach": 2075, + "Neptune Beach": 13437, + "Fernandina Beach": 7082, +} + +print("=== Testing Redfin with Florida region IDs ===\n") +total_found = 0 + +for city, region_id in list(FL_CITY_IDS.items())[:5]: + try: + url = (f"https://www.redfin.com/stingray/api/gis?" + f"al=1&market=florida®ion_id={region_id}®ion_type=6" + f"&status=9&uipt=1,2,3,4&max_price=230000&num_homes=10&start=0&v=8") + r = requests.get(url, headers=headers, timeout=15) + data = json.loads(r.text.replace("{}&&", "")) + homes = data.get("payload", {}).get("homes", []) + print(f"{city} (id={region_id}): {len(homes)} homes found") + for h in homes[:2]: + price = h.get("price", {}).get("value", 0) + addr = h.get("streetLine", {}).get("value", "?") + hcity = h.get("city", "?") + state = h.get("state", "?") + beds = h.get("beds", "?") + sqft = h.get("sqFt", {}).get("value", "?") + status = h.get("mlsStatus", "?") + print(f" ${price:,} | {addr}, {hcity}, {state} | {beds}bd | {sqft}sqft | {status}") + total_found += len(homes) + except Exception as e: + print(f"{city}: ERROR {e}") + +print(f"\nTotal found in 5 cities: {total_found}") diff --git a/casa-hunter/test_chrome.py b/casa-hunter/test_chrome.py new file mode 100644 index 0000000..34b8f35 --- /dev/null +++ b/casa-hunter/test_chrome.py @@ -0,0 +1,82 @@ +import re, time, random +from playwright.sync_api import sync_playwright +from playwright_stealth import Stealth + +CHROME_PATH = r"C:\Program Files\Google\Chrome\Application\chrome.exe" + +def human_delay(a=1.5, b=4.0): + time.sleep(random.uniform(a, b)) + +def slow_scroll(page, steps=5): + for _ in range(steps): + page.mouse.wheel(0, random.randint(250, 600)) + time.sleep(random.uniform(0.4, 1.0)) + +print("=== Zillow con Chrome real + Stealth ===") +with sync_playwright() as p: + browser = p.chromium.launch( + executable_path=CHROME_PATH, + headless=False, + args=[ + "--disable-blink-features=AutomationControlled", + "--start-maximized", + "--no-first-run", + "--no-default-browser-check", + ] + ) + ctx = browser.new_context( + user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", + locale="en-US", + timezone_id="America/New_York", + viewport={"width": 1366, "height": 768}, + ) + page = ctx.new_page() + Stealth().apply_stealth_sync(page) + + page.goto("https://www.zillow.com/homes/for_sale/vero-beach-fl/", wait_until="load", timeout=45000) + human_delay(2, 4) + slow_scroll(page, 5) + human_delay(1, 2) + + print("Title:", page.title()[:80]) + cards = page.query_selector_all("[data-test='property-card']") + print(f"Cards: {len(cards)}") + for card in cards[:5]: + print(" ", card.inner_text()[:130].replace('\n', ' | ')) + + if not cards: + content = page.content() + prices = re.findall(r'"unformattedPrice":\s*(\d+)', content) + zpids = re.findall(r'"zpid":\s*(\d+)', content) + print("Prices:", prices[:5]) + print("ZPIDs:", zpids[:5]) + print("Blocked?", "Access to this page has been denied" in content) + + browser.close() + +print("\n=== Realtor.com con Chrome real ===") +with sync_playwright() as p: + browser = p.chromium.launch( + executable_path=CHROME_PATH, + headless=False, + args=["--disable-blink-features=AutomationControlled", "--start-maximized"] + ) + ctx = browser.new_context( + user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", + locale="en-US", + timezone_id="America/New_York", + ) + page = ctx.new_page() + Stealth().apply_stealth_sync(page) + + page.goto("https://www.realtor.com/realestateandhomes-search/Vero-Beach_FL/price-na-230000", wait_until="load", timeout=45000) + human_delay(2, 4) + slow_scroll(page, 5) + + print("Title:", page.title()[:80]) + cards = page.query_selector_all("[data-testid='property-card-content']") + print(f"Cards: {len(cards)}") + for card in cards[:3]: + print(" ", card.inner_text()[:130].replace('\n', ' | ')) + + browser.close() diff --git a/casa-hunter/test_craigslist.py b/casa-hunter/test_craigslist.py new file mode 100644 index 0000000..ebe667d --- /dev/null +++ b/casa-hunter/test_craigslist.py @@ -0,0 +1,64 @@ +import requests, re +from bs4 import BeautifulSoup + +headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"} + +# Craigslist Florida markets for our target zones +MARKETS = { + "Treasure Coast": "https://treasure.craigslist.org", # Stuart, Vero Beach, Fort Pierce + "Space Coast": "https://spacecoast.craigslist.org", # Melbourne, Titusville, Cocoa + "Daytona": "https://daytona.craigslist.org", # Daytona, Ormond, NSB + "Jacksonville": "https://jacksonville.craigslist.org", # Jacksonville, St. Augustine + "Flagler/Volusia": "https://volusia.craigslist.org", # Palm Coast, Flagler Beach +} + +print("=== Craigslist Florida RSS Test ===\n") +total = 0 +for name, base in MARKETS.items(): + url = f"{base}/search/rfs?format=rss&max_price=230000&min_price=40000" + try: + r = requests.get(url, headers=headers, timeout=15) + soup = BeautifulSoup(r.text, "xml") if "xml" in r.headers.get("content-type","") else BeautifulSoup(r.text, "html.parser") + items = soup.find_all("item") + print(f"{name}: {len(items)} listings") + for item in items[:2]: + title = item.find("title") + price_el = item.find("price") or item.find("ask") + link = item.find("link") + title_text = title.get_text() if title else "?" + price_text = price_el.get_text() if price_el else re.search(r'\$[\d,]+', title_text or "") + if hasattr(price_text, 'group'): + price_text = price_text.group() + print(f" {title_text[:70]} | {price_text}") + total += len(items) + except Exception as e: + print(f"{name}: ERROR {e}") + +print(f"\nTotal listings available: {total}") + +# Test Zillow with session/cookie +print("\n=== Zillow with session ===") +try: + session = requests.Session() + session.headers.update({ + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124 Safari/537.36", + "Accept-Language": "en-US,en;q=0.9", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", + }) + # First get homepage to get cookies + session.get("https://www.zillow.com", timeout=15) + # Now search + r = session.get( + "https://www.zillow.com/homes/for_sale/Vero-Beach-FL/?searchQueryState=%7B%22filterState%22%3A%7B%22price%22%3A%7B%22max%22%3A230000%7D%7D%7D", + timeout=20 + ) + print(f"Status: {r.status_code}, size: {len(r.text)}") + has_data = "__NEXT_DATA__" in r.text + has_listings = "listResults" in r.text or "zpid" in r.text + print(f"Has __NEXT_DATA__: {has_data}, Has listing data: {has_listings}") + if has_listings: + prices = re.findall(r'"unformattedPrice":\s*(\d+)', r.text) + fl_prices = [int(p) for p in prices if 40000 < int(p) <= 230000] + print(f"Prices in range: {fl_prices[:5]}") +except Exception as e: + print(f"ERROR: {e}") diff --git a/casa-hunter/test_human.py b/casa-hunter/test_human.py new file mode 100644 index 0000000..36c69d7 --- /dev/null +++ b/casa-hunter/test_human.py @@ -0,0 +1,100 @@ +import re, json, time, random +from playwright.sync_api import sync_playwright + +def human_delay(min_s=1.5, max_s=4.0): + time.sleep(random.uniform(min_s, max_s)) + +def slow_scroll(page, steps=5): + for i in range(steps): + page.mouse.wheel(0, random.randint(300, 600)) + time.sleep(random.uniform(0.4, 0.9)) + +def test_zillow_human(): + print("=== Zillow - comportamiento humano ===") + with sync_playwright() as p: + browser = p.chromium.launch( + headless=False, # Ventana visible - menos detectable + args=[ + "--disable-blink-features=AutomationControlled", + "--no-sandbox", + "--start-maximized", + ] + ) + ctx = browser.new_context( + user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", + locale="en-US", + timezone_id="America/New_York", + viewport={"width": 1366, "height": 768}, + ) + ctx.add_init_script(""" + Object.defineProperty(navigator, 'webdriver', {get: () => undefined}); + window.chrome = {runtime: {}}; + Object.defineProperty(navigator, 'plugins', {get: () => [1,2,3,4,5]}); + """) + page = ctx.new_page() + + # Primero ir a Google como un humano + print("Abriendo Google...") + page.goto("https://www.google.com", wait_until="load", timeout=30000) + human_delay(1, 2) + + # Buscar Zillow en Google + page.fill("textarea[name=q], input[name=q]", "zillow vero beach florida homes for sale under 230000") + human_delay(0.5, 1) + page.keyboard.press("Enter") + page.wait_for_load_state("load", timeout=20000) + human_delay(1, 2) + + # Ir directo a Zillow + print("Abriendo Zillow...") + page.goto("https://www.zillow.com/homes/for_sale/vero-beach-fl/", wait_until="load", timeout=45000) + human_delay(2, 4) + + print("Title:", page.title()[:80]) + slow_scroll(page, 4) + human_delay(1, 2) + + content = page.content() + cards = page.query_selector_all("[data-test='property-card']") + print(f"Cards: {len(cards)}") + for card in cards[:5]: + print(" ", card.inner_text()[:120].replace('\n', ' | ')) + + if not cards: + prices = re.findall(r'"unformattedPrice":\s*(\d+)', content) + print("Prices en HTML:", prices[:5]) + + browser.close() + +def test_realtor_human(): + print("\n=== Realtor.com - comportamiento humano ===") + with sync_playwright() as p: + browser = p.chromium.launch( + headless=False, + args=["--disable-blink-features=AutomationControlled", "--start-maximized"] + ) + ctx = browser.new_context( + user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", + locale="en-US", + timezone_id="America/New_York", + ) + ctx.add_init_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined});") + page = ctx.new_page() + + page.goto("https://www.realtor.com", wait_until="load", timeout=30000) + human_delay(1.5, 3) + + page.goto("https://www.realtor.com/realestateandhomes-search/Vero-Beach_FL/price-na-230000", wait_until="load", timeout=45000) + human_delay(2, 4) + slow_scroll(page, 5) + + print("Title:", page.title()[:80]) + cards = page.query_selector_all("[data-testid='property-card-content']") + print(f"Cards: {len(cards)}") + for card in cards[:3]: + print(" ", card.inner_text()[:120].replace('\n', ' | ')) + + browser.close() + +test_zillow_human() +test_realtor_human() diff --git a/casa-hunter/test_manual.py b/casa-hunter/test_manual.py new file mode 100644 index 0000000..3f35367 --- /dev/null +++ b/casa-hunter/test_manual.py @@ -0,0 +1,63 @@ +""" +Abre el browser visible y espera a que el usuario resuelva cualquier CAPTCHA. +El script continua solo cuando detecta listings en la página. +""" +import re, time, random +from playwright.sync_api import sync_playwright +from playwright_stealth import Stealth + +CHROME_PATH = r"C:\Program Files\Google\Chrome\Application\chrome.exe" + +def slow_scroll(page, steps=4): + for _ in range(steps): + page.mouse.wheel(0, random.randint(300, 600)) + time.sleep(random.uniform(0.5, 1.2)) + +def wait_for_listings(page, selectors, timeout=90): + """Espera hasta que aparezcan listings o se agote el tiempo.""" + print(f"Esperando listings (max {timeout}s)... resuelve cualquier captcha si aparece") + start = time.time() + while time.time() - start < timeout: + for sel in selectors: + cards = page.query_selector_all(sel) + if cards: + return cards + time.sleep(2) + return [] + +print("=== Zillow - espera manual ===") +with sync_playwright() as p: + browser = p.chromium.launch( + executable_path=CHROME_PATH, + headless=False, + args=["--disable-blink-features=AutomationControlled", "--start-maximized"] + ) + ctx = browser.new_context( + user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", + locale="en-US", + timezone_id="America/New_York", + viewport={"width": 1366, "height": 768}, + ) + page = ctx.new_page() + Stealth().apply_stealth_sync(page) + + print("Navegando a Zillow...") + page.goto("https://www.zillow.com/homes/for_sale/vero-beach-fl/", wait_until="load", timeout=45000) + + # Esperar hasta 90 segundos para que el usuario resuelva captcha + cards = wait_for_listings(page, ["[data-test='property-card']"], timeout=90) + + print(f"\nListings encontrados: {len(cards)}") + for card in cards[:5]: + print(" ", card.inner_text()[:130].replace('\n', ' | ')) + + if not cards: + content = page.content() + prices = re.findall(r'"unformattedPrice":\s*(\d+)', content) + print("Prices in JSON:", prices[:5]) + blocked = "Access to this page has been denied" in content or "cf-browser-verification" in content + print("Bloqueado:", blocked) + print("Título:", page.title()) + + input("\nPresiona Enter para cerrar el browser...") + browser.close() diff --git a/casa-hunter/test_playwright.py b/casa-hunter/test_playwright.py new file mode 100644 index 0000000..dd6f728 --- /dev/null +++ b/casa-hunter/test_playwright.py @@ -0,0 +1,93 @@ +import re, json, time +from playwright.sync_api import sync_playwright + +def test_zillow(): + print("=== Zillow con Playwright ===") + with sync_playwright() as p: + browser = p.chromium.launch( + headless=True, + args=["--disable-blink-features=AutomationControlled"] + ) + ctx = browser.new_context( + user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", + locale="en-US", + viewport={"width": 1280, "height": 800}, + ) + ctx.add_init_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})") + page = ctx.new_page() + try: + page.goto( + "https://www.zillow.com/homes/for_sale/vero-beach-fl/", + wait_until="load", timeout=45000 + ) + time.sleep(3) + print("Title:", page.title()[:80]) + content = page.content() + print("Page size:", len(content)) + cards = page.query_selector_all("[data-test='property-card']") + print(f"Property cards: {len(cards)}") + for card in cards[:3]: + txt = card.inner_text() + print(" ", txt[:150].replace('\n', ' | ')) + if not cards: + prices = re.findall(r'"unformattedPrice":\s*(\d+)', content) + print("Prices in HTML:", prices[:5]) + except Exception as e: + print(f"ERROR: {e}") + browser.close() + +def test_realtor(): + print("\n=== Realtor.com con Playwright ===") + with sync_playwright() as p: + browser = p.chromium.launch( + headless=True, + args=["--disable-blink-features=AutomationControlled"] + ) + ctx = browser.new_context( + user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", + locale="en-US", + ) + ctx.add_init_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})") + page = ctx.new_page() + try: + page.goto( + "https://www.realtor.com/realestateandhomes-search/Vero-Beach_FL/price-na-230000", + wait_until="load", timeout=45000 + ) + time.sleep(3) + print("Title:", page.title()[:80]) + cards = page.query_selector_all("[data-testid='property-card-content']") + print(f"Cards (testid): {len(cards)}") + if not cards: + cards = page.query_selector_all(".jsx-1403264941, [class*='PropertyCard']") + print(f"Cards (class): {len(cards)}") + for card in cards[:3]: + txt = card.inner_text() + print(" ", txt[:150].replace('\n', ' | ')) + except Exception as e: + print(f"ERROR: {e}") + browser.close() + +def test_new_construction(): + print("\n=== NewHomeSource (casas nuevas) ===") + with sync_playwright() as p: + browser = p.chromium.launch(headless=True) + page = browser.new_page() + try: + page.goto( + "https://www.newhomesource.com/homes-for-sale/fl/vero-beach?priceMax=230000", + wait_until="load", timeout=30000 + ) + time.sleep(2) + content = page.content() + print("Title:", page.title()[:80]) + print("Size:", len(content)) + prices = re.findall(r'\$[\d,]+', content) + print("Prices:", prices[:8]) + except Exception as e: + print(f"ERROR: {e}") + browser.close() + +test_zillow() +test_realtor() +test_new_construction() diff --git a/casa-hunter/test_profile.py b/casa-hunter/test_profile.py new file mode 100644 index 0000000..ba7cfe3 --- /dev/null +++ b/casa-hunter/test_profile.py @@ -0,0 +1,137 @@ +""" +Usa el perfil real de Chrome (con sesión de Google) para scrapear Zillow y Realtor.com. +Primero copia el perfil a un directorio temporal para no corromper el original. +""" +import re, time, random, shutil, os, json +from playwright.sync_api import sync_playwright + +CHROME_PATH = r"C:\Program Files\Google\Chrome\Application\chrome.exe" +CHROME_PROFILE = r"C:\Users\aerom\AppData\Local\Google\Chrome\User Data" +TEMP_PROFILE = r"C:\Temp\chrome_casa_hunter" + +def human_delay(a=1.5, b=3.5): + time.sleep(random.uniform(a, b)) + +def slow_scroll(page, steps=4): + for _ in range(steps): + page.mouse.wheel(0, random.randint(300, 600)) + time.sleep(random.uniform(0.4, 0.9)) + +def wait_for_content(page, selector, timeout=60): + print(f" Esperando '{selector}' (max {timeout}s)...") + start = time.time() + while time.time() - start < timeout: + try: + items = page.query_selector_all(selector) + if items: + return items + except Exception: + pass + time.sleep(2) + return [] + +# Copiar perfil si no existe el temporal +if not os.path.exists(TEMP_PROFILE): + print("Copiando perfil de Chrome (solo Default)...") + os.makedirs(TEMP_PROFILE, exist_ok=True) + src_default = os.path.join(CHROME_PROFILE, "Default") + dst_default = os.path.join(TEMP_PROFILE, "Default") + # Solo copiar archivos de sesión, no caché (para ir más rápido) + for item in ["Cookies", "Login Data", "Web Data", "Preferences"]: + src = os.path.join(src_default, item) + if os.path.exists(src): + os.makedirs(dst_default, exist_ok=True) + shutil.copy2(src, dst_default) + print("Perfil copiado.") +else: + print("Usando perfil temporal existente.") + +print("\n=== Zillow con sesión de Google ===") +with sync_playwright() as p: + ctx = p.chromium.launch_persistent_context( + user_data_dir=TEMP_PROFILE, + executable_path=CHROME_PATH, + headless=False, + args=[ + "--profile-directory=Default", + "--disable-blink-features=AutomationControlled", + "--start-maximized", + "--no-first-run", + "--no-default-browser-check", + ], + viewport={"width": 1366, "height": 768}, + ) + page = ctx.new_page() + + # Ir a Zillow directamente + print("Navegando a Zillow...") + try: + page.goto( + "https://www.zillow.com/homes/for_sale/vero-beach-fl/?searchQueryState=%7B%22filterState%22%3A%7B%22price%22%3A%7B%22max%22%3A230000%7D%7D%7D", + wait_until="load", timeout=45000 + ) + except Exception as e: + print(f"Timeout en load (continuando): {e}") + + human_delay(2, 3) + + # Si hay captcha Cloudflare, esperar que el usuario lo resuelva + print("Título actual:", page.title()[:60]) + if "denied" in page.title().lower() or "verification" in page.title().lower(): + print(">> Cloudflare challenge detectado. Resuélvelo en el browser (90s)...") + time.sleep(90) + + slow_scroll(page, 5) + human_delay(1, 2) + + # Buscar listings + cards = wait_for_content(page, "[data-test='property-card']", timeout=30) + print(f"\nListings Zillow: {len(cards)}") + results = [] + for card in cards[:10]: + txt = card.inner_text() + price_m = re.search(r'\$[\d,]+', txt) + addr_lines = txt.strip().split('\n') + price = price_m.group() if price_m else "?" + addr = addr_lines[0] if addr_lines else "?" + print(f" {price} | {addr[:60]}") + results.append({"price": price, "address": addr}) + + if results: + with open("zillow_results.json", "w") as f: + json.dump(results, f, indent=2) + print(f"\nGuardado en zillow_results.json ({len(results)} propiedades)") + else: + content = page.content() + prices = re.findall(r'"unformattedPrice":\s*(\d+)', content) + print("Precios en HTML:", prices[:5]) + + input("\n[Enter para ir a Realtor.com]") + + print("\n=== Realtor.com con sesión de Google ===") + page.goto( + "https://www.realtor.com/realestateandhomes-search/Vero-Beach_FL/price-na-230000", + wait_until="load", timeout=45000 + ) + human_delay(2, 3) + slow_scroll(page, 5) + + cards2 = wait_for_content(page, "[data-testid='property-card-content']", timeout=30) + print(f"\nListings Realtor: {len(cards2)}") + results2 = [] + for card in cards2[:10]: + txt = card.inner_text() + price_m = re.search(r'\$[\d,]+', txt) + lines = txt.strip().split('\n') + price = price_m.group() if price_m else "?" + addr = lines[0] if lines else "?" + print(f" {price} | {addr[:60]}") + results2.append({"price": price, "address": addr}) + + if results2: + with open("realtor_results.json", "w") as f: + json.dump(results2, f, indent=2) + print(f"Guardado en realtor_results.json ({len(results2)} propiedades)") + + input("\n[Enter para cerrar el browser]") + ctx.close() diff --git a/casa-hunter/test_stealth.py b/casa-hunter/test_stealth.py new file mode 100644 index 0000000..431519f --- /dev/null +++ b/casa-hunter/test_stealth.py @@ -0,0 +1,70 @@ +import re, time, random +from playwright.sync_api import sync_playwright +from playwright_stealth import Stealth + +def human_delay(a=1.5, b=3.5): + time.sleep(random.uniform(a, b)) + +def slow_scroll(page, steps=4): + for _ in range(steps): + page.mouse.wheel(0, random.randint(300, 700)) + time.sleep(random.uniform(0.5, 1.0)) + +print("=== Test Stealth Playwright - Zillow ===") +with sync_playwright() as p: + browser = p.chromium.launch( + headless=False, + args=["--disable-blink-features=AutomationControlled", "--start-maximized"] + ) + ctx = browser.new_context( + user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", + locale="en-US", + timezone_id="America/New_York", + viewport={"width": 1366, "height": 768}, + ) + page = ctx.new_page() + Stealth().apply_stealth_sync(page) + + page.goto("https://www.zillow.com/homes/for_sale/vero-beach-fl/", wait_until="load", timeout=45000) + human_delay(2, 4) + slow_scroll(page, 5) + human_delay(1, 2) + + print("Title:", page.title()[:80]) + cards = page.query_selector_all("[data-test='property-card']") + print(f"Property cards: {len(cards)}") + for card in cards[:5]: + print(" ", card.inner_text()[:120].replace('\n', ' | ')) + + if not cards: + content = page.content() + prices = re.findall(r'"unformattedPrice":\s*(\d+)', content) + print("Prices in HTML:", prices[:5]) + + browser.close() + +print("\n=== Test Stealth - Realtor.com ===") +with sync_playwright() as p: + browser = p.chromium.launch( + headless=False, + args=["--disable-blink-features=AutomationControlled", "--start-maximized"] + ) + ctx = browser.new_context( + user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", + locale="en-US", + timezone_id="America/New_York", + ) + page = ctx.new_page() + Stealth().apply_stealth_sync(page) + + page.goto("https://www.realtor.com/realestateandhomes-search/Vero-Beach_FL/price-na-230000", wait_until="load", timeout=45000) + human_delay(2, 4) + slow_scroll(page, 5) + + print("Title:", page.title()[:80]) + cards = page.query_selector_all("[data-testid='property-card-content']") + print(f"Cards: {len(cards)}") + for card in cards[:3]: + print(" ", card.inner_text()[:120].replace('\n', ' | ')) + + browser.close() diff --git a/casa-hunter/test_working.py b/casa-hunter/test_working.py new file mode 100644 index 0000000..d193a50 --- /dev/null +++ b/casa-hunter/test_working.py @@ -0,0 +1,87 @@ +import requests, json, re +from bs4 import BeautifulSoup + +headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124 Safari/537.36", + "Accept": "text/html,application/xhtml+xml,*/*;q=0.8", + "Accept-Language": "en-US,en;q=0.9", + "Accept-Encoding": "gzip, deflate, br", + "Connection": "keep-alive", +} + +# 1. Test Brevard County Property Appraiser (government API - no anti-bot) +print("=== Brevard County Property API ===") +try: + r = requests.get( + "https://www.bcpao.us/api/search?activeOnly=true&saleAmountMax=230000" + "&saleAmountMin=50000&town=MELBOURNE&count=10&page=1", + headers=headers, timeout=15 + ) + print(f"Status: {r.status_code}, size: {len(r.text)}") + print(r.text[:500]) +except Exception as e: + print(f"ERROR: {e}") + +# 2. Test Indian River County (Vero Beach) Property Appraiser +print("\n=== Indian River County Property API ===") +try: + r = requests.get( + "https://www.ircpa.net/propertysearch.aspx", + headers=headers, timeout=15 + ) + print(f"Status: {r.status_code}, size: {len(r.text)}") +except Exception as e: + print(f"ERROR: {e}") + +# 3. Test Point2Homes (no JS required usually) +print("\n=== Point2Homes ===") +try: + r = requests.get( + "https://www.point2homes.com/US/Real-Estate-Listings/FL/Indian-River-County.html" + "?PriceMin=50000&PriceMax=230000", + headers=headers, timeout=15 + ) + print(f"Status: {r.status_code}, size: {len(r.text)}") + soup = BeautifulSoup(r.text, "html.parser") + listings = soup.select(".item-listing, .listing, [class*='listing-card']") + print(f"Listings found: {len(listings)}") + for l in listings[:2]: + print(f" {l.get_text()[:100].strip()}") +except Exception as e: + print(f"ERROR: {e}") + +# 4. Test Homes.com +print("\n=== Homes.com ===") +try: + r = requests.get( + "https://www.homes.com/homes-for-sale/fl/vero-beach/?min_price=50000&max_price=230000", + headers=headers, timeout=15 + ) + print(f"Status: {r.status_code}, size: {len(r.text)}") + soup = BeautifulSoup(r.text, "html.parser") + # Try to find embedded JSON data + scripts = soup.find_all("script", type="application/json") + print(f" JSON scripts found: {len(scripts)}") + scripts2 = [s for s in soup.find_all("script") if s.string and "listPrice" in (s.string or "")] + print(f" Scripts with listPrice: {len(scripts2)}") +except Exception as e: + print(f"ERROR: {e}") + +# 5. Test HUD proper endpoint +print("\n=== HUD Homes (correct endpoint) ===") +try: + # Try different HUD endpoints + urls = [ + "https://www.hudhomestore.gov/HudHomes/SearchProperties.aspx?state=FL&county=Indian+River&maxprice=230000", + "https://www.hudhomestore.gov/HudHomes/SearchProperties.aspx?state=FL&county=Brevard&maxprice=230000", + ] + for url in urls: + r = requests.get(url, headers=headers, timeout=15) + soup = BeautifulSoup(r.text, "html.parser") + listings = soup.select("tr.datarow, .propRow, [class*='prop-row']") + prices = re.findall(r'\$[\d,]+', r.text) + print(f" {url.split('county=')[1].split('&')[0]}: status={r.status_code}, listings={len(listings)}, prices found={len(prices)}") + if prices: + print(f" First prices: {prices[:5]}") +except Exception as e: + print(f"ERROR: {e}") diff --git a/casa-hunter/test_zillow2.py b/casa-hunter/test_zillow2.py new file mode 100644 index 0000000..c651a54 --- /dev/null +++ b/casa-hunter/test_zillow2.py @@ -0,0 +1,155 @@ +""" +Scraper Zillow: usa el search box como humano + extrae JSON de la página. +""" +import re, time, random, json +from playwright.sync_api import sync_playwright + +CHROME_PATH = r"C:\Program Files\Google\Chrome\Application\chrome.exe" +TEMP_PROFILE = r"C:\Temp\chrome_casa_hunter" + +def hd(a=1.0, b=2.5): + time.sleep(random.uniform(a, b)) + +def scroll(page, steps=4): + for _ in range(steps): + page.mouse.wheel(0, random.randint(250, 550)) + time.sleep(random.uniform(0.4, 0.9)) + +def parse_listings(html, min_p=40000, max_p=230000): + results = [] + m = re.search(r']*id="__NEXT_DATA__"[^>]*>(.*?)', html, re.DOTALL) + if m: + try: + data = json.loads(m.group(1)) + list_results = (data.get("props",{}).get("pageProps",{}) + .get("searchPageState",{}).get("cat1",{}) + .get("searchResults",{}).get("listResults",[])) + for p in list_results: + price = p.get("unformattedPrice", 0) + if min_p <= price <= max_p: + city = p.get("addressCity", "") + state = p.get("addressState", "") + results.append({ + "source": "zillow", + "address": p.get("address","?"), + "price": price, + "beds": p.get("beds", 0), + "baths": p.get("baths", 0), + "sqft": p.get("area", 0), + "city": city, + "state": state, + "zip": p.get("addressZipcode",""), + "status": p.get("statusType",""), + "url": "https://www.zillow.com" + p.get("detailUrl",""), + "img": p.get("imgSrc",""), + "type": p.get("hdpData",{}).get("homeInfo",{}).get("homeType",""), + }) + except Exception as e: + print(f" Parse error: {e}") + return results + +def search_city(page, city_query, max_price=230000): + """Busca una ciudad en Zillow usando el search box.""" + print(f"\n--- Buscando: {city_query} ---") + try: + # Ir a zillow.com + page.goto("https://www.zillow.com", wait_until="load", timeout=30000) + hd(1.5, 2.5) + + # Encontrar el search box y escribir la ciudad + search_box = page.query_selector("input[id*='search'], input[placeholder*='address'], input[placeholder*='city']") + if not search_box: + # Probar selectores alternativos + search_box = page.query_selector("#search-box-input, [data-testid='search-input'], input[name='searchQueryState']") + + if search_box: + search_box.click() + hd(0.3, 0.6) + page.keyboard.down("Control") + page.keyboard.press("a") + page.keyboard.up("Control") + hd(0.2, 0.4) + page.keyboard.press("Delete") + hd(0.3, 0.5) + # Escribir como humano, caracter por caracter + for char in city_query: + page.keyboard.type(char) + time.sleep(random.uniform(0.07, 0.18)) + hd(1.0, 1.8) + page.keyboard.press("Enter") + page.wait_for_load_state("load", timeout=30000) + hd(2, 3) + scroll(page, 4) + hd(1, 2) + else: + # Si no encuentra search box, usar URL directamente + city_slug = city_query.lower().replace(" ", "-").replace(",", "") + url = f"https://www.zillow.com/homes/for_sale/{city_slug}/?searchQueryState=%7B%22filterState%22%3A%7B%22price%22%3A%7B%22max%22%3A{max_price}%2C%22min%22%3A40000%7D%7D%7D" + page.goto(url, wait_until="load", timeout=45000) + hd(2, 3) + scroll(page, 4) + + title = page.title() + html = page.content() + print(f" Título: {title[:60]}") + + listings = parse_listings(html) + print(f" Encontrados: {len(listings)} en rango $40K-$230K") + for l in listings[:3]: + print(f" ${l['price']:,} | {l.get('beds','?')}bd | {l['address'][:50]}, {l['city']}") + return listings + + except Exception as e: + print(f" ERROR: {e}") + return [] + +# Ciudades objetivo +CITIES = [ + "Vero Beach, FL", + "Melbourne, FL", + "Jacksonville, FL", + "Stuart, FL", + "Daytona Beach, FL", + "St. Augustine, FL", + "Palm Coast, FL", + "New Smyrna Beach, FL", +] + +all_results = [] + +with sync_playwright() as p: + ctx = p.chromium.launch_persistent_context( + user_data_dir=TEMP_PROFILE, + executable_path=CHROME_PATH, + headless=False, + args=[ + "--profile-directory=Default", + "--disable-blink-features=AutomationControlled", + "--start-maximized", + "--no-first-run", + "--no-default-browser-check", + ], + viewport={"width": 1366, "height": 768}, + ) + page = ctx.new_page() + + for city in CITIES: + listings = search_city(page, city) + all_results.extend(listings) + hd(2, 4) # pausa entre ciudades + + ctx.close() + +# Deduplicar por dirección +seen = set() +unique = [] +for r in all_results: + key = r["address"].lower().strip() + if key not in seen: + seen.add(key) + unique.append(r) + +print(f"\n=== TOTAL: {len(unique)} listings únicos en $40K-$230K ===") +with open("zillow_final.json", "w", encoding="utf-8") as f: + json.dump(unique, f, indent=2, ensure_ascii=False) +print("Guardado en zillow_final.json") diff --git a/casa-hunter/test_zillow_profile.py b/casa-hunter/test_zillow_profile.py new file mode 100644 index 0000000..0f822b9 --- /dev/null +++ b/casa-hunter/test_zillow_profile.py @@ -0,0 +1,120 @@ +""" +Scraper de Zillow usando el perfil real de Chrome. +Extrae datos completos del JSON embebido en la página. +""" +import re, time, random, json, os +from playwright.sync_api import sync_playwright + +CHROME_PATH = r"C:\Program Files\Google\Chrome\Application\chrome.exe" +TEMP_PROFILE = r"C:\Temp\chrome_casa_hunter" + +def human_delay(a=1.5, b=3.5): + time.sleep(random.uniform(a, b)) + +def slow_scroll(page, steps=4): + for _ in range(steps): + page.mouse.wheel(0, random.randint(300, 600)) + time.sleep(random.uniform(0.5, 1.0)) + +def parse_zillow_listings(html, max_price=230000, min_price=40000): + """Extrae listings del JSON embebido en Zillow.""" + results = [] + + # Buscar el JSON principal de Zillow (__NEXT_DATA__ o searchResults) + match = re.search(r']*id="__NEXT_DATA__"[^>]*>(.*?)', html, re.DOTALL) + if match: + try: + data = json.loads(match.group(1)) + # Navegar en la estructura JSON de Zillow + props = data.get("props", {}) + page_props = props.get("pageProps", {}) + search = page_props.get("searchPageState", {}) + cat1 = search.get("cat1", {}) + search_results = cat1.get("searchResults", {}) + list_results = search_results.get("listResults", []) + + for prop in list_results: + price = prop.get("unformattedPrice", 0) + if not (min_price <= price <= max_price): + continue + results.append({ + "source": "zillow", + "address": prop.get("address", "?"), + "price": price, + "beds": prop.get("beds", 0), + "baths": prop.get("baths", 0), + "sqft": prop.get("area", 0), + "city": prop.get("addressCity", ""), + "state": prop.get("addressState", ""), + "zip": prop.get("addressZipcode", ""), + "status": prop.get("statusType", ""), + "url": "https://www.zillow.com" + prop.get("detailUrl", ""), + "img": prop.get("imgSrc", ""), + "property_type": prop.get("hdpData", {}).get("homeInfo", {}).get("homeType", ""), + }) + except Exception as e: + print(f"Error parsing __NEXT_DATA__: {e}") + + if not results: + # Fallback: buscar unformattedPrice directamente + raw_prices = re.findall(r'"unformattedPrice":\s*(\d+)', html) + raw_addrs = re.findall(r'"address":\s*"([^"]+)"', html) + for i, (p, a) in enumerate(zip(raw_prices, raw_addrs)): + price = int(p) + if min_price <= price <= max_price: + results.append({"source": "zillow", "price": price, "address": a}) + + return results + +cities_fl = [ + ("Vero Beach FL", "https://www.zillow.com/homes/for_sale/vero-beach-fl/?searchQueryState=%7B%22filterState%22%3A%7B%22price%22%3A%7B%22max%22%3A230000%2C%22min%22%3A40000%7D%7D%7D"), + ("Jacksonville FL", "https://www.zillow.com/homes/for_sale/jacksonville-fl/?searchQueryState=%7B%22filterState%22%3A%7B%22price%22%3A%7B%22max%22%3A230000%2C%22min%22%3A40000%7D%7D%7D"), + ("Melbourne FL", "https://www.zillow.com/homes/for_sale/melbourne-fl/?searchQueryState=%7B%22filterState%22%3A%7B%22price%22%3A%7B%22max%22%3A230000%2C%22min%22%3A40000%7D%7D%7D"), + ("Stuart FL", "https://www.zillow.com/homes/for_sale/stuart-fl/?searchQueryState=%7B%22filterState%22%3A%7B%22price%22%3A%7B%22max%22%3A230000%2C%22min%22%3A40000%7D%7D%7D"), +] + +all_results = [] + +with sync_playwright() as p: + ctx = p.chromium.launch_persistent_context( + user_data_dir=TEMP_PROFILE, + executable_path=CHROME_PATH, + headless=False, + args=[ + "--profile-directory=Default", + "--disable-blink-features=AutomationControlled", + "--start-maximized", + "--no-first-run", + "--no-default-browser-check", + ], + viewport={"width": 1366, "height": 768}, + ) + page = ctx.new_page() + + for city, url in cities_fl: + print(f"\n--- {city} ---") + try: + page.goto(url, wait_until="load", timeout=45000) + human_delay(2, 3) + slow_scroll(page, 4) + human_delay(1, 2) + + html = page.content() + title = page.title() + print(f"Título: {title[:60]}") + + listings = parse_zillow_listings(html) + print(f"Listings encontrados: {len(listings)}") + for l in listings[:5]: + print(f" ${l['price']:,} | {l.get('beds','?')}bd | {l.get('address','?')[:50]}, {l.get('city','?')}, {l.get('state','?')}") + all_results.extend(listings) + + except Exception as e: + print(f"ERROR en {city}: {e}") + + ctx.close() + +print(f"\n=== TOTAL: {len(all_results)} listings en rango $40K-$230K ===") +with open("zillow_all.json", "w", encoding="utf-8") as f: + json.dump(all_results, f, indent=2, ensure_ascii=False) +print("Guardado en zillow_all.json") diff --git a/casa-hunter/zillow_all.json b/casa-hunter/zillow_all.json new file mode 100644 index 0000000..6038fa5 --- /dev/null +++ b/casa-hunter/zillow_all.json @@ -0,0 +1,2462 @@ +[ + { + "source": "zillow", + "address": "3205 W 16th Avenue, Hialeah, FL 33012", + "price": 230000, + "beds": 3, + "baths": 2, + "sqft": 918, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3205-W-16th-Ave-Hialeah-FL-33012/2070167889_zpid/", + "img": "https://photos.zillowstatic.com/fp/4e89e9a4b4203d6d30ae9df91727b13e-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17530 NW 68th Ave APT C4008, Hialeah, FL 33015", + "price": 167000, + "beds": 1, + "baths": 1, + "sqft": 660, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17530-NW-68th-Ave-APT-C4008-Hialeah-FL-33015/58453444_zpid/", + "img": "https://photos.zillowstatic.com/fp/1db83c8dcd8b99f6f624aa8b57b9b5cb-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "18101 NW 68th Ave APT B105, Hialeah, FL 33015", + "price": 170000, + "beds": 2, + "baths": 2, + "sqft": 1458, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/18101-NW-68th-Ave-APT-B105-Hialeah-FL-33015/82417235_zpid/", + "img": "https://photos.zillowstatic.com/fp/6c1a51416e6a7ed28a1de71b4bc86b58-p_e.jpg", + "property_type": "TOWNHOUSE" + }, + { + "source": "zillow", + "address": "14601 NW 185th St Lot 12, Hialeah Gardens, FL 33018", + "price": 59000, + "beds": 2, + "baths": 2, + "sqft": 0, + "city": "Hialeah Gardens", + "state": "FL", + "zip": "33018", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/14601-NW-185th-St-LOT-12-Hialeah-Gardens-FL-33018/461768626_zpid/", + "img": "https://photos.zillowstatic.com/fp/e6f363fe54a328bb2b48fe671274fcff-p_e.jpg", + "property_type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "305 E 4th Ave APT 1, Hialeah, FL 33010", + "price": 165000, + "beds": 1, + "baths": 1, + "sqft": 800, + "city": "Hialeah", + "state": "FL", + "zip": "33010", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/305-E-4th-Ave-APT-1-Hialeah-FL-33010/43963860_zpid/", + "img": "https://photos.zillowstatic.com/fp/5a73efa293dd4ed2f9d316beac479605-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "18101 NW 68th Ave APT D101, Hialeah, FL 33015", + "price": 169000, + "beds": 2, + "baths": 2, + "sqft": 1458, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/18101-NW-68th-Ave-APT-D101-Hialeah-FL-33015/82420768_zpid/", + "img": "https://photos.zillowstatic.com/fp/1dd65f15e0af8d211e4121242d54304a-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17901 NW 68th Ave APT R206, Hialeah, FL 33015", + "price": 170000, + "beds": 2, + "baths": 3, + "sqft": 1376, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17901-NW-68th-Ave-APT-R206-Hialeah-FL-33015/82421513_zpid/", + "img": "https://photos.zillowstatic.com/fp/9accbe8f1e931f6b43b6fe3c501a686a-p_e.jpg", + "property_type": "TOWNHOUSE" + }, + { + "source": "zillow", + "address": "6980 NW 186th St APT 3-227A, Hialeah, FL 33015", + "price": 158000, + "beds": 1, + "baths": 1, + "sqft": 382, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6980-NW-186th-St-APT-3-227A-Hialeah-FL-33015/70784899_zpid/", + "img": "https://photos.zillowstatic.com/fp/9dc23973a0600dce6c9f53837d2e856e-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "6675 W 4th Ave APT 203, Hialeah, FL 33012", + "price": 225000, + "beds": 2, + "baths": 2, + "sqft": 760, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6675-W-4th-Ave-APT-203-Hialeah-FL-33012/43943885_zpid/", + "img": "https://photos.zillowstatic.com/fp/dd6d0b40d1715b76c0dc589f1914e92f-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17901 NW 68th Ave APT T206, Hialeah, FL 33015", + "price": 210000, + "beds": 2, + "baths": 3, + "sqft": 1376, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17901-NW-68th-Ave-APT-T206-Hialeah-FL-33015/82410347_zpid/", + "img": "https://photos.zillowstatic.com/fp/ee1d58ce40932d6c02502c12ed07ed41-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "4655 Palm Ave APT 124, Hialeah, FL 33012", + "price": 175000, + "beds": 1, + "baths": 1, + "sqft": 596, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4655-Palm-Ave-APT-124-Hialeah-FL-33012/72579665_zpid/", + "img": "https://photos.zillowstatic.com/fp/2f38a50e960da749601b83cbf0d44de9-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17901 NW 68th Ave APT T205, Hialeah, FL 33015", + "price": 188000, + "beds": 2, + "baths": 2, + "sqft": 1119, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17901-NW-68th-Ave-APT-T205-Hialeah-FL-33015/82411503_zpid/", + "img": "https://photos.zillowstatic.com/fp/e29fb5bf261e28aaa95f40922aba2e1c-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "425 E 33rd St, Hialeah, FL 33013", + "price": 70000, + "beds": 2, + "baths": 1, + "sqft": 0, + "city": "Hialeah", + "state": "FL", + "zip": "33013", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/425-E-33rd-St-Hialeah-FL-33013/43956090_zpid/", + "img": "https://photos.zillowstatic.com/fp/8b67838c7091db1fb31067dde421664a-p_e.jpg", + "property_type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "17901 NW 68th Ave APT R209, Hialeah, FL 33015", + "price": 200000, + "beds": 2, + "baths": 2, + "sqft": 1417, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17901-NW-68th-Ave-APT-R209-Hialeah-FL-33015/82413012_zpid/", + "img": "https://photos.zillowstatic.com/fp/74aadbc105343c25c89cd66d1d530ed4-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "3494 E 4th Ave #1207, Hialeah, FL 33013", + "price": 199900, + "beds": 2, + "baths": 1, + "sqft": 896, + "city": "Hialeah", + "state": "FL", + "zip": "33013", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3494-E-4th-Ave-1207-Hialeah-FL-33013/43959304_zpid/", + "img": "https://photos.zillowstatic.com/fp/64166536c1f23936a75d49a305ff35de-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "575 W 69th St APT 205, Hialeah, FL 33014", + "price": 224900, + "beds": 2, + "baths": 2, + "sqft": 890, + "city": "Hialeah", + "state": "FL", + "zip": "33014", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/575-W-69th-St-APT-205-Hialeah-FL-33014/72580305_zpid/", + "img": "https://photos.zillowstatic.com/fp/eb54ea5a6ce485f42ab5bccac1a0d0c8-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17911 NW 68th Ave APT N206, Hialeah, FL 33015", + "price": 155000, + "beds": 1, + "baths": 2, + "sqft": 943, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17911-NW-68th-Ave-APT-N206-Hialeah-FL-33015/82412339_zpid/", + "img": "https://photos.zillowstatic.com/fp/5003d49f94c7136c7057c21fcb1a15a8-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "6960 Miami Gardens Dr #2525, Hialeah, FL 33015", + "price": 164900, + "beds": 1, + "baths": 2, + "sqft": 989, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6960-Miami-Gardens-Dr-2525-Hialeah-FL-33015/70770032_zpid/", + "img": "https://photos.zillowstatic.com/fp/1eeaf6f8fde7f4c30dee09e6cae48abb-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1265 W 24th St APT 201, Hialeah, FL 33010", + "price": 229000, + "beds": 2, + "baths": 1, + "sqft": 794, + "city": "Hialeah", + "state": "FL", + "zip": "33010", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1265-W-24th-St-APT-201-Hialeah-FL-33010/79859202_zpid/", + "img": "https://photos.zillowstatic.com/fp/75ed3cdb2e7ce49b3a50ff961fb89d69-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17530 NW 68th Ave APT C4012, Hialeah, FL 33015", + "price": 180000, + "beds": 1, + "baths": 1, + "sqft": 660, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17530-NW-68th-Ave-APT-C4012-Hialeah-FL-33015/58453459_zpid/", + "img": "https://photos.zillowstatic.com/fp/c08b612d02360d5024ede921df1b1670-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "18111 NW 68th Ave APT G206, Hialeah, FL 33015", + "price": 200000, + "beds": 2, + "baths": 3, + "sqft": 1376, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/18111-NW-68th-Ave-APT-G206-Hialeah-FL-33015/82411311_zpid/", + "img": "https://photos.zillowstatic.com/fp/caa175fd6ff2fb60d41b63d4b631c8d9-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "18304 NW 68th Ave APT C, Hialeah, FL 33015", + "price": 218000, + "beds": 1, + "baths": 1, + "sqft": 782, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/18304-NW-68th-Ave-APT-C-Hialeah-FL-33015/70783989_zpid/", + "img": "https://photos.zillowstatic.com/fp/83c4e5c34646d0fec94a3bd9af6974e1-p_e.jpg", + "property_type": "TOWNHOUSE" + }, + { + "source": "zillow", + "address": "17000 NW 67th Ave APT 115, Hialeah, FL 33015", + "price": 220000, + "beds": 2, + "baths": 2, + "sqft": 1038, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17000-NW-67th-Ave-APT-115-Hialeah-FL-33015/44081299_zpid/", + "img": "https://photos.zillowstatic.com/fp/3744a77e4e39438ac330d294b837c20f-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "4655 Palm Ave APT 205, Hialeah, FL 33012", + "price": 219000, + "beds": 2, + "baths": 1, + "sqft": 798, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4655-Palm-Ave-APT-205-Hialeah-FL-33012/72579035_zpid/", + "img": "https://photos.zillowstatic.com/fp/65b7f9349779dd00da55c36d0ba6680b-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17505 NW 67th Pl #I-11, Hialeah, FL 33015", + "price": 210000, + "beds": 1, + "baths": 1, + "sqft": 750, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17505-NW-67th-Pl-I-11-Hialeah-FL-33015/72565400_zpid/", + "img": "https://photos.zillowstatic.com/fp/afd6eba25abb0b57dec4286feb934518-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "5748 W 26th Ave #5748, Hialeah, FL 33016", + "price": 220000, + "beds": 2, + "baths": 1, + "sqft": 696, + "city": "Hialeah", + "state": "FL", + "zip": "33016", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/5748-W-26th-Ave-5748-Hialeah-FL-33016/62927284_zpid/", + "img": "https://photos.zillowstatic.com/fp/69f9e3de330afb38e01bf54b1f4ffebf-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1750 W 46th St APT 503, Hialeah, FL 33012", + "price": 225000, + "beds": 2, + "baths": 2, + "sqft": 1096, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1750-W-46th-St-APT-503-Hialeah-FL-33012/43950782_zpid/", + "img": "https://photos.zillowstatic.com/fp/7de43c091ec4e6471b8f22ee9392f709-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "7220 NW 179th St APT 111, Hialeah, FL 33015", + "price": 200000, + "beds": 1, + "baths": 1, + "sqft": 679, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7220-NW-179th-St-APT-111-Hialeah-FL-33015/70785539_zpid/", + "img": "https://photos.zillowstatic.com/fp/0476612990a8f5fe76fe3a6fc6d8d26f-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1035 W 77th St APT 312, Hialeah, FL 33014", + "price": 215000, + "beds": 1, + "baths": 2, + "sqft": 753, + "city": "Hialeah", + "state": "FL", + "zip": "33014", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1035-W-77th-St-APT-312-Hialeah-FL-33014/43924045_zpid/", + "img": "https://photos.zillowstatic.com/fp/77c52cff50c7fe722a0e9ef379803c4e-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "383 E 4th Ave APT 8, Hialeah, FL 33010", + "price": 165000, + "beds": 1, + "baths": 1, + "sqft": 800, + "city": "Hialeah", + "state": "FL", + "zip": "33010", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/383-E-4th-Ave-APT-8-Hialeah-FL-33010/43963909_zpid/", + "img": "https://photos.zillowstatic.com/fp/88967065ee62f39969c0f98045469751-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "7160 NW 179th St APT 309, Hialeah, FL 33015", + "price": 195000, + "beds": 1, + "baths": 1, + "sqft": 679, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7160-NW-179th-St-APT-309-Hialeah-FL-33015/70785736_zpid/", + "img": "https://photos.zillowstatic.com/fp/9bf4fd8378217a175d9838a7a582a80a-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1725 W 60th St APT F330, Hialeah, FL 33012", + "price": 195000, + "beds": 1, + "baths": 1, + "sqft": 790, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1725-W-60th-St-APT-F330-Hialeah-FL-33012/62927619_zpid/", + "img": "https://photos.zillowstatic.com/fp/008f4b9afc164500aee34f6304db8da2-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "5755 W 20th Ave APT 308, Hialeah, FL 33012", + "price": 229900, + "beds": 2, + "baths": 2, + "sqft": 996, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/5755-W-20th-Ave-APT-308-Hialeah-FL-33012/63616485_zpid/", + "img": "https://photos.zillowstatic.com/fp/1a3d0f913cb836c0190f2d647f3d93aa-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "6055 W 19th Ave APT 209, Hialeah, FL 33012", + "price": 230000, + "beds": 2, + "baths": 2, + "sqft": 890, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6055-W-19th-Ave-APT-209-Hialeah-FL-33012/43940528_zpid/", + "img": "https://photos.zillowstatic.com/fp/536d5efa22b9c68ed97b5d4e140b7e7a-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1825 W 44th Pl APT 309, Hialeah, FL 33012", + "price": 199999, + "beds": 1, + "baths": 1, + "sqft": 712, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1825-W-44th-Pl-APT-309-Hialeah-FL-33012/43950840_zpid/", + "img": "https://photos.zillowstatic.com/fp/c9a676b37908d2c13e58c00ec9aa44e2-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "7030 NW 179th St APT 205, Hialeah, FL 33015", + "price": 224900, + "beds": 2, + "baths": 1, + "sqft": 844, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7030-NW-179th-St-APT-205-Hialeah-FL-33015/70770172_zpid/", + "img": "https://photos.zillowstatic.com/fp/0f0bed76b2fdd0e1cb1f611b8fbc95c5-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "6940 Miami Gardens Dr APT 1-126, Hialeah, FL 33015", + "price": 210000, + "beds": 1, + "baths": 1, + "sqft": 870, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6940-Miami-Gardens-Dr-APT-1-126-Hialeah-FL-33015/70784289_zpid/", + "img": "https://photos.zillowstatic.com/fp/730506d6551365bd2f3fe360069e95d3-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "606 W 81st St APT 120, Hialeah, FL 33014", + "price": 220000, + "beds": 2, + "baths": 1, + "sqft": 770, + "city": "Hialeah", + "state": "FL", + "zip": "33014", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/606-W-81st-St-APT-120-Hialeah-FL-33014/60333009_zpid/", + "img": "https://photos.zillowstatic.com/fp/0a4e8123fb4acf4cf75259c6cd31d306-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1850 W 56th St APT 2410, Hialeah, FL 33012", + "price": 195000, + "beds": 2, + "baths": 1, + "sqft": 998, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1850-W-56th-St-APT-2410-Hialeah-FL-33012/43939291_zpid/", + "img": "https://photos.zillowstatic.com/fp/10ccfacc9cf60067842fde6312ada280-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1330 W 54th St APT 302C, Hialeah, FL 33012", + "price": 195000, + "beds": 1, + "baths": 1, + "sqft": 583, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1330-W-54th-St-APT-302C-Hialeah-FL-33012/72562328_zpid/", + "img": "https://photos.zillowstatic.com/fp/9c9d47579e467f678deaa469a811108f-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1401 W 29th St Lot C54, Hialeah, FL 33012", + "price": 180000, + "beds": 2, + "baths": 1, + "sqft": 396, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1401-W-29th-St-LOT-C54-Hialeah-FL-33012/460950816_zpid/", + "img": "https://photos.zillowstatic.com/fp/1f441f86348fec76c289b1f2e2a1ae70-p_e.jpg", + "property_type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "3205 W 16th Avenue, Hialeah, FL 33012", + "price": 230000, + "beds": 3, + "baths": 2, + "sqft": 918, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3205-W-16th-Ave-Hialeah-FL-33012/2070167889_zpid/", + "img": "https://photos.zillowstatic.com/fp/4e89e9a4b4203d6d30ae9df91727b13e-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17530 NW 68th Ave APT C4008, Hialeah, FL 33015", + "price": 167000, + "beds": 1, + "baths": 1, + "sqft": 660, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17530-NW-68th-Ave-APT-C4008-Hialeah-FL-33015/58453444_zpid/", + "img": "https://photos.zillowstatic.com/fp/1db83c8dcd8b99f6f624aa8b57b9b5cb-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "18101 NW 68th Ave APT B105, Hialeah, FL 33015", + "price": 170000, + "beds": 2, + "baths": 2, + "sqft": 1458, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/18101-NW-68th-Ave-APT-B105-Hialeah-FL-33015/82417235_zpid/", + "img": "https://photos.zillowstatic.com/fp/6c1a51416e6a7ed28a1de71b4bc86b58-p_e.jpg", + "property_type": "TOWNHOUSE" + }, + { + "source": "zillow", + "address": "14601 NW 185th St Lot 12, Hialeah Gardens, FL 33018", + "price": 59000, + "beds": 2, + "baths": 2, + "sqft": 0, + "city": "Hialeah Gardens", + "state": "FL", + "zip": "33018", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/14601-NW-185th-St-LOT-12-Hialeah-Gardens-FL-33018/461768626_zpid/", + "img": "https://photos.zillowstatic.com/fp/e6f363fe54a328bb2b48fe671274fcff-p_e.jpg", + "property_type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "305 E 4th Ave APT 1, Hialeah, FL 33010", + "price": 165000, + "beds": 1, + "baths": 1, + "sqft": 800, + "city": "Hialeah", + "state": "FL", + "zip": "33010", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/305-E-4th-Ave-APT-1-Hialeah-FL-33010/43963860_zpid/", + "img": "https://photos.zillowstatic.com/fp/5a73efa293dd4ed2f9d316beac479605-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "18101 NW 68th Ave APT D101, Hialeah, FL 33015", + "price": 169000, + "beds": 2, + "baths": 2, + "sqft": 1458, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/18101-NW-68th-Ave-APT-D101-Hialeah-FL-33015/82420768_zpid/", + "img": "https://photos.zillowstatic.com/fp/1dd65f15e0af8d211e4121242d54304a-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17901 NW 68th Ave APT R206, Hialeah, FL 33015", + "price": 170000, + "beds": 2, + "baths": 3, + "sqft": 1376, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17901-NW-68th-Ave-APT-R206-Hialeah-FL-33015/82421513_zpid/", + "img": "https://photos.zillowstatic.com/fp/9accbe8f1e931f6b43b6fe3c501a686a-p_e.jpg", + "property_type": "TOWNHOUSE" + }, + { + "source": "zillow", + "address": "6980 NW 186th St APT 3-227A, Hialeah, FL 33015", + "price": 158000, + "beds": 1, + "baths": 1, + "sqft": 382, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6980-NW-186th-St-APT-3-227A-Hialeah-FL-33015/70784899_zpid/", + "img": "https://photos.zillowstatic.com/fp/9dc23973a0600dce6c9f53837d2e856e-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "6675 W 4th Ave APT 203, Hialeah, FL 33012", + "price": 225000, + "beds": 2, + "baths": 2, + "sqft": 760, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6675-W-4th-Ave-APT-203-Hialeah-FL-33012/43943885_zpid/", + "img": "https://photos.zillowstatic.com/fp/dd6d0b40d1715b76c0dc589f1914e92f-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17901 NW 68th Ave APT T206, Hialeah, FL 33015", + "price": 210000, + "beds": 2, + "baths": 3, + "sqft": 1376, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17901-NW-68th-Ave-APT-T206-Hialeah-FL-33015/82410347_zpid/", + "img": "https://photos.zillowstatic.com/fp/ee1d58ce40932d6c02502c12ed07ed41-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "4655 Palm Ave APT 124, Hialeah, FL 33012", + "price": 175000, + "beds": 1, + "baths": 1, + "sqft": 596, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4655-Palm-Ave-APT-124-Hialeah-FL-33012/72579665_zpid/", + "img": "https://photos.zillowstatic.com/fp/2f38a50e960da749601b83cbf0d44de9-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17901 NW 68th Ave APT T205, Hialeah, FL 33015", + "price": 188000, + "beds": 2, + "baths": 2, + "sqft": 1119, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17901-NW-68th-Ave-APT-T205-Hialeah-FL-33015/82411503_zpid/", + "img": "https://photos.zillowstatic.com/fp/e29fb5bf261e28aaa95f40922aba2e1c-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "425 E 33rd St, Hialeah, FL 33013", + "price": 70000, + "beds": 2, + "baths": 1, + "sqft": 0, + "city": "Hialeah", + "state": "FL", + "zip": "33013", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/425-E-33rd-St-Hialeah-FL-33013/43956090_zpid/", + "img": "https://photos.zillowstatic.com/fp/8b67838c7091db1fb31067dde421664a-p_e.jpg", + "property_type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "17901 NW 68th Ave APT R209, Hialeah, FL 33015", + "price": 200000, + "beds": 2, + "baths": 2, + "sqft": 1417, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17901-NW-68th-Ave-APT-R209-Hialeah-FL-33015/82413012_zpid/", + "img": "https://photos.zillowstatic.com/fp/74aadbc105343c25c89cd66d1d530ed4-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "3494 E 4th Ave #1207, Hialeah, FL 33013", + "price": 199900, + "beds": 2, + "baths": 1, + "sqft": 896, + "city": "Hialeah", + "state": "FL", + "zip": "33013", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3494-E-4th-Ave-1207-Hialeah-FL-33013/43959304_zpid/", + "img": "https://photos.zillowstatic.com/fp/64166536c1f23936a75d49a305ff35de-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "575 W 69th St APT 205, Hialeah, FL 33014", + "price": 224900, + "beds": 2, + "baths": 2, + "sqft": 890, + "city": "Hialeah", + "state": "FL", + "zip": "33014", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/575-W-69th-St-APT-205-Hialeah-FL-33014/72580305_zpid/", + "img": "https://photos.zillowstatic.com/fp/eb54ea5a6ce485f42ab5bccac1a0d0c8-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17911 NW 68th Ave APT N206, Hialeah, FL 33015", + "price": 155000, + "beds": 1, + "baths": 2, + "sqft": 943, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17911-NW-68th-Ave-APT-N206-Hialeah-FL-33015/82412339_zpid/", + "img": "https://photos.zillowstatic.com/fp/5003d49f94c7136c7057c21fcb1a15a8-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "6960 Miami Gardens Dr #2525, Hialeah, FL 33015", + "price": 164900, + "beds": 1, + "baths": 2, + "sqft": 989, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6960-Miami-Gardens-Dr-2525-Hialeah-FL-33015/70770032_zpid/", + "img": "https://photos.zillowstatic.com/fp/1eeaf6f8fde7f4c30dee09e6cae48abb-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1265 W 24th St APT 201, Hialeah, FL 33010", + "price": 229000, + "beds": 2, + "baths": 1, + "sqft": 794, + "city": "Hialeah", + "state": "FL", + "zip": "33010", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1265-W-24th-St-APT-201-Hialeah-FL-33010/79859202_zpid/", + "img": "https://photos.zillowstatic.com/fp/75ed3cdb2e7ce49b3a50ff961fb89d69-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17530 NW 68th Ave APT C4012, Hialeah, FL 33015", + "price": 180000, + "beds": 1, + "baths": 1, + "sqft": 660, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17530-NW-68th-Ave-APT-C4012-Hialeah-FL-33015/58453459_zpid/", + "img": "https://photos.zillowstatic.com/fp/c08b612d02360d5024ede921df1b1670-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "18111 NW 68th Ave APT G206, Hialeah, FL 33015", + "price": 200000, + "beds": 2, + "baths": 3, + "sqft": 1376, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/18111-NW-68th-Ave-APT-G206-Hialeah-FL-33015/82411311_zpid/", + "img": "https://photos.zillowstatic.com/fp/caa175fd6ff2fb60d41b63d4b631c8d9-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "18304 NW 68th Ave APT C, Hialeah, FL 33015", + "price": 218000, + "beds": 1, + "baths": 1, + "sqft": 782, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/18304-NW-68th-Ave-APT-C-Hialeah-FL-33015/70783989_zpid/", + "img": "https://photos.zillowstatic.com/fp/83c4e5c34646d0fec94a3bd9af6974e1-p_e.jpg", + "property_type": "TOWNHOUSE" + }, + { + "source": "zillow", + "address": "17000 NW 67th Ave APT 115, Hialeah, FL 33015", + "price": 220000, + "beds": 2, + "baths": 2, + "sqft": 1038, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17000-NW-67th-Ave-APT-115-Hialeah-FL-33015/44081299_zpid/", + "img": "https://photos.zillowstatic.com/fp/3744a77e4e39438ac330d294b837c20f-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "4655 Palm Ave APT 205, Hialeah, FL 33012", + "price": 219000, + "beds": 2, + "baths": 1, + "sqft": 798, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4655-Palm-Ave-APT-205-Hialeah-FL-33012/72579035_zpid/", + "img": "https://photos.zillowstatic.com/fp/65b7f9349779dd00da55c36d0ba6680b-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17505 NW 67th Pl #I-11, Hialeah, FL 33015", + "price": 210000, + "beds": 1, + "baths": 1, + "sqft": 750, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17505-NW-67th-Pl-I-11-Hialeah-FL-33015/72565400_zpid/", + "img": "https://photos.zillowstatic.com/fp/afd6eba25abb0b57dec4286feb934518-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "5748 W 26th Ave #5748, Hialeah, FL 33016", + "price": 220000, + "beds": 2, + "baths": 1, + "sqft": 696, + "city": "Hialeah", + "state": "FL", + "zip": "33016", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/5748-W-26th-Ave-5748-Hialeah-FL-33016/62927284_zpid/", + "img": "https://photos.zillowstatic.com/fp/69f9e3de330afb38e01bf54b1f4ffebf-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1750 W 46th St APT 503, Hialeah, FL 33012", + "price": 225000, + "beds": 2, + "baths": 2, + "sqft": 1096, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1750-W-46th-St-APT-503-Hialeah-FL-33012/43950782_zpid/", + "img": "https://photos.zillowstatic.com/fp/7de43c091ec4e6471b8f22ee9392f709-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "7220 NW 179th St APT 111, Hialeah, FL 33015", + "price": 200000, + "beds": 1, + "baths": 1, + "sqft": 679, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7220-NW-179th-St-APT-111-Hialeah-FL-33015/70785539_zpid/", + "img": "https://photos.zillowstatic.com/fp/0476612990a8f5fe76fe3a6fc6d8d26f-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1035 W 77th St APT 312, Hialeah, FL 33014", + "price": 215000, + "beds": 1, + "baths": 2, + "sqft": 753, + "city": "Hialeah", + "state": "FL", + "zip": "33014", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1035-W-77th-St-APT-312-Hialeah-FL-33014/43924045_zpid/", + "img": "https://photos.zillowstatic.com/fp/77c52cff50c7fe722a0e9ef379803c4e-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "383 E 4th Ave APT 8, Hialeah, FL 33010", + "price": 165000, + "beds": 1, + "baths": 1, + "sqft": 800, + "city": "Hialeah", + "state": "FL", + "zip": "33010", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/383-E-4th-Ave-APT-8-Hialeah-FL-33010/43963909_zpid/", + "img": "https://photos.zillowstatic.com/fp/88967065ee62f39969c0f98045469751-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "7160 NW 179th St APT 309, Hialeah, FL 33015", + "price": 195000, + "beds": 1, + "baths": 1, + "sqft": 679, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7160-NW-179th-St-APT-309-Hialeah-FL-33015/70785736_zpid/", + "img": "https://photos.zillowstatic.com/fp/9bf4fd8378217a175d9838a7a582a80a-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1725 W 60th St APT F330, Hialeah, FL 33012", + "price": 195000, + "beds": 1, + "baths": 1, + "sqft": 790, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1725-W-60th-St-APT-F330-Hialeah-FL-33012/62927619_zpid/", + "img": "https://photos.zillowstatic.com/fp/008f4b9afc164500aee34f6304db8da2-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "5755 W 20th Ave APT 308, Hialeah, FL 33012", + "price": 229900, + "beds": 2, + "baths": 2, + "sqft": 996, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/5755-W-20th-Ave-APT-308-Hialeah-FL-33012/63616485_zpid/", + "img": "https://photos.zillowstatic.com/fp/1a3d0f913cb836c0190f2d647f3d93aa-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "6055 W 19th Ave APT 209, Hialeah, FL 33012", + "price": 230000, + "beds": 2, + "baths": 2, + "sqft": 890, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6055-W-19th-Ave-APT-209-Hialeah-FL-33012/43940528_zpid/", + "img": "https://photos.zillowstatic.com/fp/536d5efa22b9c68ed97b5d4e140b7e7a-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1825 W 44th Pl APT 309, Hialeah, FL 33012", + "price": 199999, + "beds": 1, + "baths": 1, + "sqft": 712, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1825-W-44th-Pl-APT-309-Hialeah-FL-33012/43950840_zpid/", + "img": "https://photos.zillowstatic.com/fp/c9a676b37908d2c13e58c00ec9aa44e2-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "7030 NW 179th St APT 205, Hialeah, FL 33015", + "price": 224900, + "beds": 2, + "baths": 1, + "sqft": 844, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7030-NW-179th-St-APT-205-Hialeah-FL-33015/70770172_zpid/", + "img": "https://photos.zillowstatic.com/fp/0f0bed76b2fdd0e1cb1f611b8fbc95c5-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "6940 Miami Gardens Dr APT 1-126, Hialeah, FL 33015", + "price": 210000, + "beds": 1, + "baths": 1, + "sqft": 870, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6940-Miami-Gardens-Dr-APT-1-126-Hialeah-FL-33015/70784289_zpid/", + "img": "https://photos.zillowstatic.com/fp/730506d6551365bd2f3fe360069e95d3-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "606 W 81st St APT 120, Hialeah, FL 33014", + "price": 220000, + "beds": 2, + "baths": 1, + "sqft": 770, + "city": "Hialeah", + "state": "FL", + "zip": "33014", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/606-W-81st-St-APT-120-Hialeah-FL-33014/60333009_zpid/", + "img": "https://photos.zillowstatic.com/fp/0a4e8123fb4acf4cf75259c6cd31d306-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1850 W 56th St APT 2410, Hialeah, FL 33012", + "price": 195000, + "beds": 2, + "baths": 1, + "sqft": 998, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1850-W-56th-St-APT-2410-Hialeah-FL-33012/43939291_zpid/", + "img": "https://photos.zillowstatic.com/fp/10ccfacc9cf60067842fde6312ada280-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1330 W 54th St APT 302C, Hialeah, FL 33012", + "price": 195000, + "beds": 1, + "baths": 1, + "sqft": 583, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1330-W-54th-St-APT-302C-Hialeah-FL-33012/72562328_zpid/", + "img": "https://photos.zillowstatic.com/fp/9c9d47579e467f678deaa469a811108f-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1401 W 29th St Lot C54, Hialeah, FL 33012", + "price": 180000, + "beds": 2, + "baths": 1, + "sqft": 396, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1401-W-29th-St-LOT-C54-Hialeah-FL-33012/460950816_zpid/", + "img": "https://photos.zillowstatic.com/fp/1f441f86348fec76c289b1f2e2a1ae70-p_e.jpg", + "property_type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "3205 W 16th Avenue, Hialeah, FL 33012", + "price": 230000, + "beds": 3, + "baths": 2, + "sqft": 918, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3205-W-16th-Ave-Hialeah-FL-33012/2070167889_zpid/", + "img": "https://photos.zillowstatic.com/fp/4e89e9a4b4203d6d30ae9df91727b13e-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17530 NW 68th Ave APT C4008, Hialeah, FL 33015", + "price": 167000, + "beds": 1, + "baths": 1, + "sqft": 660, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17530-NW-68th-Ave-APT-C4008-Hialeah-FL-33015/58453444_zpid/", + "img": "https://photos.zillowstatic.com/fp/1db83c8dcd8b99f6f624aa8b57b9b5cb-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "18101 NW 68th Ave APT B105, Hialeah, FL 33015", + "price": 170000, + "beds": 2, + "baths": 2, + "sqft": 1458, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/18101-NW-68th-Ave-APT-B105-Hialeah-FL-33015/82417235_zpid/", + "img": "https://photos.zillowstatic.com/fp/6c1a51416e6a7ed28a1de71b4bc86b58-p_e.jpg", + "property_type": "TOWNHOUSE" + }, + { + "source": "zillow", + "address": "14601 NW 185th St Lot 12, Hialeah Gardens, FL 33018", + "price": 59000, + "beds": 2, + "baths": 2, + "sqft": 0, + "city": "Hialeah Gardens", + "state": "FL", + "zip": "33018", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/14601-NW-185th-St-LOT-12-Hialeah-Gardens-FL-33018/461768626_zpid/", + "img": "https://photos.zillowstatic.com/fp/e6f363fe54a328bb2b48fe671274fcff-p_e.jpg", + "property_type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "305 E 4th Ave APT 1, Hialeah, FL 33010", + "price": 165000, + "beds": 1, + "baths": 1, + "sqft": 800, + "city": "Hialeah", + "state": "FL", + "zip": "33010", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/305-E-4th-Ave-APT-1-Hialeah-FL-33010/43963860_zpid/", + "img": "https://photos.zillowstatic.com/fp/5a73efa293dd4ed2f9d316beac479605-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "18101 NW 68th Ave APT D101, Hialeah, FL 33015", + "price": 169000, + "beds": 2, + "baths": 2, + "sqft": 1458, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/18101-NW-68th-Ave-APT-D101-Hialeah-FL-33015/82420768_zpid/", + "img": "https://photos.zillowstatic.com/fp/1dd65f15e0af8d211e4121242d54304a-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17901 NW 68th Ave APT R206, Hialeah, FL 33015", + "price": 170000, + "beds": 2, + "baths": 3, + "sqft": 1376, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17901-NW-68th-Ave-APT-R206-Hialeah-FL-33015/82421513_zpid/", + "img": "https://photos.zillowstatic.com/fp/9accbe8f1e931f6b43b6fe3c501a686a-p_e.jpg", + "property_type": "TOWNHOUSE" + }, + { + "source": "zillow", + "address": "6980 NW 186th St APT 3-227A, Hialeah, FL 33015", + "price": 158000, + "beds": 1, + "baths": 1, + "sqft": 382, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6980-NW-186th-St-APT-3-227A-Hialeah-FL-33015/70784899_zpid/", + "img": "https://photos.zillowstatic.com/fp/9dc23973a0600dce6c9f53837d2e856e-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "6675 W 4th Ave APT 203, Hialeah, FL 33012", + "price": 225000, + "beds": 2, + "baths": 2, + "sqft": 760, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6675-W-4th-Ave-APT-203-Hialeah-FL-33012/43943885_zpid/", + "img": "https://photos.zillowstatic.com/fp/dd6d0b40d1715b76c0dc589f1914e92f-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17901 NW 68th Ave APT T206, Hialeah, FL 33015", + "price": 210000, + "beds": 2, + "baths": 3, + "sqft": 1376, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17901-NW-68th-Ave-APT-T206-Hialeah-FL-33015/82410347_zpid/", + "img": "https://photos.zillowstatic.com/fp/ee1d58ce40932d6c02502c12ed07ed41-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "4655 Palm Ave APT 124, Hialeah, FL 33012", + "price": 175000, + "beds": 1, + "baths": 1, + "sqft": 596, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4655-Palm-Ave-APT-124-Hialeah-FL-33012/72579665_zpid/", + "img": "https://photos.zillowstatic.com/fp/2f38a50e960da749601b83cbf0d44de9-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17901 NW 68th Ave APT T205, Hialeah, FL 33015", + "price": 188000, + "beds": 2, + "baths": 2, + "sqft": 1119, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17901-NW-68th-Ave-APT-T205-Hialeah-FL-33015/82411503_zpid/", + "img": "https://photos.zillowstatic.com/fp/e29fb5bf261e28aaa95f40922aba2e1c-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "425 E 33rd St, Hialeah, FL 33013", + "price": 70000, + "beds": 2, + "baths": 1, + "sqft": 0, + "city": "Hialeah", + "state": "FL", + "zip": "33013", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/425-E-33rd-St-Hialeah-FL-33013/43956090_zpid/", + "img": "https://photos.zillowstatic.com/fp/8b67838c7091db1fb31067dde421664a-p_e.jpg", + "property_type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "17901 NW 68th Ave APT R209, Hialeah, FL 33015", + "price": 200000, + "beds": 2, + "baths": 2, + "sqft": 1417, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17901-NW-68th-Ave-APT-R209-Hialeah-FL-33015/82413012_zpid/", + "img": "https://photos.zillowstatic.com/fp/74aadbc105343c25c89cd66d1d530ed4-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "3494 E 4th Ave #1207, Hialeah, FL 33013", + "price": 199900, + "beds": 2, + "baths": 1, + "sqft": 896, + "city": "Hialeah", + "state": "FL", + "zip": "33013", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3494-E-4th-Ave-1207-Hialeah-FL-33013/43959304_zpid/", + "img": "https://photos.zillowstatic.com/fp/64166536c1f23936a75d49a305ff35de-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "575 W 69th St APT 205, Hialeah, FL 33014", + "price": 224900, + "beds": 2, + "baths": 2, + "sqft": 890, + "city": "Hialeah", + "state": "FL", + "zip": "33014", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/575-W-69th-St-APT-205-Hialeah-FL-33014/72580305_zpid/", + "img": "https://photos.zillowstatic.com/fp/eb54ea5a6ce485f42ab5bccac1a0d0c8-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17911 NW 68th Ave APT N206, Hialeah, FL 33015", + "price": 155000, + "beds": 1, + "baths": 2, + "sqft": 943, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17911-NW-68th-Ave-APT-N206-Hialeah-FL-33015/82412339_zpid/", + "img": "https://photos.zillowstatic.com/fp/5003d49f94c7136c7057c21fcb1a15a8-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "6960 Miami Gardens Dr #2525, Hialeah, FL 33015", + "price": 164900, + "beds": 1, + "baths": 2, + "sqft": 989, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6960-Miami-Gardens-Dr-2525-Hialeah-FL-33015/70770032_zpid/", + "img": "https://photos.zillowstatic.com/fp/1eeaf6f8fde7f4c30dee09e6cae48abb-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1265 W 24th St APT 201, Hialeah, FL 33010", + "price": 229000, + "beds": 2, + "baths": 1, + "sqft": 794, + "city": "Hialeah", + "state": "FL", + "zip": "33010", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1265-W-24th-St-APT-201-Hialeah-FL-33010/79859202_zpid/", + "img": "https://photos.zillowstatic.com/fp/75ed3cdb2e7ce49b3a50ff961fb89d69-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17530 NW 68th Ave APT C4012, Hialeah, FL 33015", + "price": 180000, + "beds": 1, + "baths": 1, + "sqft": 660, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17530-NW-68th-Ave-APT-C4012-Hialeah-FL-33015/58453459_zpid/", + "img": "https://photos.zillowstatic.com/fp/c08b612d02360d5024ede921df1b1670-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "18111 NW 68th Ave APT G206, Hialeah, FL 33015", + "price": 200000, + "beds": 2, + "baths": 3, + "sqft": 1376, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/18111-NW-68th-Ave-APT-G206-Hialeah-FL-33015/82411311_zpid/", + "img": "https://photos.zillowstatic.com/fp/caa175fd6ff2fb60d41b63d4b631c8d9-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "18304 NW 68th Ave APT C, Hialeah, FL 33015", + "price": 218000, + "beds": 1, + "baths": 1, + "sqft": 782, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/18304-NW-68th-Ave-APT-C-Hialeah-FL-33015/70783989_zpid/", + "img": "https://photos.zillowstatic.com/fp/83c4e5c34646d0fec94a3bd9af6974e1-p_e.jpg", + "property_type": "TOWNHOUSE" + }, + { + "source": "zillow", + "address": "17000 NW 67th Ave APT 115, Hialeah, FL 33015", + "price": 220000, + "beds": 2, + "baths": 2, + "sqft": 1038, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17000-NW-67th-Ave-APT-115-Hialeah-FL-33015/44081299_zpid/", + "img": "https://photos.zillowstatic.com/fp/3744a77e4e39438ac330d294b837c20f-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "4655 Palm Ave APT 205, Hialeah, FL 33012", + "price": 219000, + "beds": 2, + "baths": 1, + "sqft": 798, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4655-Palm-Ave-APT-205-Hialeah-FL-33012/72579035_zpid/", + "img": "https://photos.zillowstatic.com/fp/65b7f9349779dd00da55c36d0ba6680b-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17505 NW 67th Pl #I-11, Hialeah, FL 33015", + "price": 210000, + "beds": 1, + "baths": 1, + "sqft": 750, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17505-NW-67th-Pl-I-11-Hialeah-FL-33015/72565400_zpid/", + "img": "https://photos.zillowstatic.com/fp/afd6eba25abb0b57dec4286feb934518-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "5748 W 26th Ave #5748, Hialeah, FL 33016", + "price": 220000, + "beds": 2, + "baths": 1, + "sqft": 696, + "city": "Hialeah", + "state": "FL", + "zip": "33016", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/5748-W-26th-Ave-5748-Hialeah-FL-33016/62927284_zpid/", + "img": "https://photos.zillowstatic.com/fp/69f9e3de330afb38e01bf54b1f4ffebf-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1750 W 46th St APT 503, Hialeah, FL 33012", + "price": 225000, + "beds": 2, + "baths": 2, + "sqft": 1096, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1750-W-46th-St-APT-503-Hialeah-FL-33012/43950782_zpid/", + "img": "https://photos.zillowstatic.com/fp/7de43c091ec4e6471b8f22ee9392f709-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "7220 NW 179th St APT 111, Hialeah, FL 33015", + "price": 200000, + "beds": 1, + "baths": 1, + "sqft": 679, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7220-NW-179th-St-APT-111-Hialeah-FL-33015/70785539_zpid/", + "img": "https://photos.zillowstatic.com/fp/0476612990a8f5fe76fe3a6fc6d8d26f-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1035 W 77th St APT 312, Hialeah, FL 33014", + "price": 215000, + "beds": 1, + "baths": 2, + "sqft": 753, + "city": "Hialeah", + "state": "FL", + "zip": "33014", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1035-W-77th-St-APT-312-Hialeah-FL-33014/43924045_zpid/", + "img": "https://photos.zillowstatic.com/fp/77c52cff50c7fe722a0e9ef379803c4e-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "383 E 4th Ave APT 8, Hialeah, FL 33010", + "price": 165000, + "beds": 1, + "baths": 1, + "sqft": 800, + "city": "Hialeah", + "state": "FL", + "zip": "33010", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/383-E-4th-Ave-APT-8-Hialeah-FL-33010/43963909_zpid/", + "img": "https://photos.zillowstatic.com/fp/88967065ee62f39969c0f98045469751-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "7160 NW 179th St APT 309, Hialeah, FL 33015", + "price": 195000, + "beds": 1, + "baths": 1, + "sqft": 679, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7160-NW-179th-St-APT-309-Hialeah-FL-33015/70785736_zpid/", + "img": "https://photos.zillowstatic.com/fp/9bf4fd8378217a175d9838a7a582a80a-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1725 W 60th St APT F330, Hialeah, FL 33012", + "price": 195000, + "beds": 1, + "baths": 1, + "sqft": 790, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1725-W-60th-St-APT-F330-Hialeah-FL-33012/62927619_zpid/", + "img": "https://photos.zillowstatic.com/fp/008f4b9afc164500aee34f6304db8da2-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "5755 W 20th Ave APT 308, Hialeah, FL 33012", + "price": 229900, + "beds": 2, + "baths": 2, + "sqft": 996, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/5755-W-20th-Ave-APT-308-Hialeah-FL-33012/63616485_zpid/", + "img": "https://photos.zillowstatic.com/fp/1a3d0f913cb836c0190f2d647f3d93aa-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "6055 W 19th Ave APT 209, Hialeah, FL 33012", + "price": 230000, + "beds": 2, + "baths": 2, + "sqft": 890, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6055-W-19th-Ave-APT-209-Hialeah-FL-33012/43940528_zpid/", + "img": "https://photos.zillowstatic.com/fp/536d5efa22b9c68ed97b5d4e140b7e7a-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1825 W 44th Pl APT 309, Hialeah, FL 33012", + "price": 199999, + "beds": 1, + "baths": 1, + "sqft": 712, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1825-W-44th-Pl-APT-309-Hialeah-FL-33012/43950840_zpid/", + "img": "https://photos.zillowstatic.com/fp/c9a676b37908d2c13e58c00ec9aa44e2-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "7030 NW 179th St APT 205, Hialeah, FL 33015", + "price": 224900, + "beds": 2, + "baths": 1, + "sqft": 844, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7030-NW-179th-St-APT-205-Hialeah-FL-33015/70770172_zpid/", + "img": "https://photos.zillowstatic.com/fp/0f0bed76b2fdd0e1cb1f611b8fbc95c5-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "6940 Miami Gardens Dr APT 1-126, Hialeah, FL 33015", + "price": 210000, + "beds": 1, + "baths": 1, + "sqft": 870, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6940-Miami-Gardens-Dr-APT-1-126-Hialeah-FL-33015/70784289_zpid/", + "img": "https://photos.zillowstatic.com/fp/730506d6551365bd2f3fe360069e95d3-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "606 W 81st St APT 120, Hialeah, FL 33014", + "price": 220000, + "beds": 2, + "baths": 1, + "sqft": 770, + "city": "Hialeah", + "state": "FL", + "zip": "33014", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/606-W-81st-St-APT-120-Hialeah-FL-33014/60333009_zpid/", + "img": "https://photos.zillowstatic.com/fp/0a4e8123fb4acf4cf75259c6cd31d306-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1850 W 56th St APT 2410, Hialeah, FL 33012", + "price": 195000, + "beds": 2, + "baths": 1, + "sqft": 998, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1850-W-56th-St-APT-2410-Hialeah-FL-33012/43939291_zpid/", + "img": "https://photos.zillowstatic.com/fp/10ccfacc9cf60067842fde6312ada280-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1330 W 54th St APT 302C, Hialeah, FL 33012", + "price": 195000, + "beds": 1, + "baths": 1, + "sqft": 583, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1330-W-54th-St-APT-302C-Hialeah-FL-33012/72562328_zpid/", + "img": "https://photos.zillowstatic.com/fp/9c9d47579e467f678deaa469a811108f-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1401 W 29th St Lot C54, Hialeah, FL 33012", + "price": 180000, + "beds": 2, + "baths": 1, + "sqft": 396, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1401-W-29th-St-LOT-C54-Hialeah-FL-33012/460950816_zpid/", + "img": "https://photos.zillowstatic.com/fp/1f441f86348fec76c289b1f2e2a1ae70-p_e.jpg", + "property_type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "3205 W 16th Avenue, Hialeah, FL 33012", + "price": 230000, + "beds": 3, + "baths": 2, + "sqft": 918, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3205-W-16th-Ave-Hialeah-FL-33012/2070167889_zpid/", + "img": "https://photos.zillowstatic.com/fp/4e89e9a4b4203d6d30ae9df91727b13e-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17530 NW 68th Ave APT C4008, Hialeah, FL 33015", + "price": 167000, + "beds": 1, + "baths": 1, + "sqft": 660, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17530-NW-68th-Ave-APT-C4008-Hialeah-FL-33015/58453444_zpid/", + "img": "https://photos.zillowstatic.com/fp/1db83c8dcd8b99f6f624aa8b57b9b5cb-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "18101 NW 68th Ave APT B105, Hialeah, FL 33015", + "price": 170000, + "beds": 2, + "baths": 2, + "sqft": 1458, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/18101-NW-68th-Ave-APT-B105-Hialeah-FL-33015/82417235_zpid/", + "img": "https://photos.zillowstatic.com/fp/6c1a51416e6a7ed28a1de71b4bc86b58-p_e.jpg", + "property_type": "TOWNHOUSE" + }, + { + "source": "zillow", + "address": "14601 NW 185th St Lot 12, Hialeah Gardens, FL 33018", + "price": 59000, + "beds": 2, + "baths": 2, + "sqft": 0, + "city": "Hialeah Gardens", + "state": "FL", + "zip": "33018", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/14601-NW-185th-St-LOT-12-Hialeah-Gardens-FL-33018/461768626_zpid/", + "img": "https://photos.zillowstatic.com/fp/e6f363fe54a328bb2b48fe671274fcff-p_e.jpg", + "property_type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "305 E 4th Ave APT 1, Hialeah, FL 33010", + "price": 165000, + "beds": 1, + "baths": 1, + "sqft": 800, + "city": "Hialeah", + "state": "FL", + "zip": "33010", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/305-E-4th-Ave-APT-1-Hialeah-FL-33010/43963860_zpid/", + "img": "https://photos.zillowstatic.com/fp/5a73efa293dd4ed2f9d316beac479605-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "18101 NW 68th Ave APT D101, Hialeah, FL 33015", + "price": 169000, + "beds": 2, + "baths": 2, + "sqft": 1458, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/18101-NW-68th-Ave-APT-D101-Hialeah-FL-33015/82420768_zpid/", + "img": "https://photos.zillowstatic.com/fp/1dd65f15e0af8d211e4121242d54304a-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17901 NW 68th Ave APT R206, Hialeah, FL 33015", + "price": 170000, + "beds": 2, + "baths": 3, + "sqft": 1376, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17901-NW-68th-Ave-APT-R206-Hialeah-FL-33015/82421513_zpid/", + "img": "https://photos.zillowstatic.com/fp/9accbe8f1e931f6b43b6fe3c501a686a-p_e.jpg", + "property_type": "TOWNHOUSE" + }, + { + "source": "zillow", + "address": "6980 NW 186th St APT 3-227A, Hialeah, FL 33015", + "price": 158000, + "beds": 1, + "baths": 1, + "sqft": 382, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6980-NW-186th-St-APT-3-227A-Hialeah-FL-33015/70784899_zpid/", + "img": "https://photos.zillowstatic.com/fp/9dc23973a0600dce6c9f53837d2e856e-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "6675 W 4th Ave APT 203, Hialeah, FL 33012", + "price": 225000, + "beds": 2, + "baths": 2, + "sqft": 760, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6675-W-4th-Ave-APT-203-Hialeah-FL-33012/43943885_zpid/", + "img": "https://photos.zillowstatic.com/fp/dd6d0b40d1715b76c0dc589f1914e92f-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17901 NW 68th Ave APT T206, Hialeah, FL 33015", + "price": 210000, + "beds": 2, + "baths": 3, + "sqft": 1376, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17901-NW-68th-Ave-APT-T206-Hialeah-FL-33015/82410347_zpid/", + "img": "https://photos.zillowstatic.com/fp/ee1d58ce40932d6c02502c12ed07ed41-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "4655 Palm Ave APT 124, Hialeah, FL 33012", + "price": 175000, + "beds": 1, + "baths": 1, + "sqft": 596, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4655-Palm-Ave-APT-124-Hialeah-FL-33012/72579665_zpid/", + "img": "https://photos.zillowstatic.com/fp/2f38a50e960da749601b83cbf0d44de9-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17901 NW 68th Ave APT T205, Hialeah, FL 33015", + "price": 188000, + "beds": 2, + "baths": 2, + "sqft": 1119, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17901-NW-68th-Ave-APT-T205-Hialeah-FL-33015/82411503_zpid/", + "img": "https://photos.zillowstatic.com/fp/e29fb5bf261e28aaa95f40922aba2e1c-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "425 E 33rd St, Hialeah, FL 33013", + "price": 70000, + "beds": 2, + "baths": 1, + "sqft": 0, + "city": "Hialeah", + "state": "FL", + "zip": "33013", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/425-E-33rd-St-Hialeah-FL-33013/43956090_zpid/", + "img": "https://photos.zillowstatic.com/fp/8b67838c7091db1fb31067dde421664a-p_e.jpg", + "property_type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "17901 NW 68th Ave APT R209, Hialeah, FL 33015", + "price": 200000, + "beds": 2, + "baths": 2, + "sqft": 1417, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17901-NW-68th-Ave-APT-R209-Hialeah-FL-33015/82413012_zpid/", + "img": "https://photos.zillowstatic.com/fp/74aadbc105343c25c89cd66d1d530ed4-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "3494 E 4th Ave #1207, Hialeah, FL 33013", + "price": 199900, + "beds": 2, + "baths": 1, + "sqft": 896, + "city": "Hialeah", + "state": "FL", + "zip": "33013", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3494-E-4th-Ave-1207-Hialeah-FL-33013/43959304_zpid/", + "img": "https://photos.zillowstatic.com/fp/64166536c1f23936a75d49a305ff35de-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "575 W 69th St APT 205, Hialeah, FL 33014", + "price": 224900, + "beds": 2, + "baths": 2, + "sqft": 890, + "city": "Hialeah", + "state": "FL", + "zip": "33014", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/575-W-69th-St-APT-205-Hialeah-FL-33014/72580305_zpid/", + "img": "https://photos.zillowstatic.com/fp/eb54ea5a6ce485f42ab5bccac1a0d0c8-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17911 NW 68th Ave APT N206, Hialeah, FL 33015", + "price": 155000, + "beds": 1, + "baths": 2, + "sqft": 943, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17911-NW-68th-Ave-APT-N206-Hialeah-FL-33015/82412339_zpid/", + "img": "https://photos.zillowstatic.com/fp/5003d49f94c7136c7057c21fcb1a15a8-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "6960 Miami Gardens Dr #2525, Hialeah, FL 33015", + "price": 164900, + "beds": 1, + "baths": 2, + "sqft": 989, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6960-Miami-Gardens-Dr-2525-Hialeah-FL-33015/70770032_zpid/", + "img": "https://photos.zillowstatic.com/fp/1eeaf6f8fde7f4c30dee09e6cae48abb-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1265 W 24th St APT 201, Hialeah, FL 33010", + "price": 229000, + "beds": 2, + "baths": 1, + "sqft": 794, + "city": "Hialeah", + "state": "FL", + "zip": "33010", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1265-W-24th-St-APT-201-Hialeah-FL-33010/79859202_zpid/", + "img": "https://photos.zillowstatic.com/fp/75ed3cdb2e7ce49b3a50ff961fb89d69-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17530 NW 68th Ave APT C4012, Hialeah, FL 33015", + "price": 180000, + "beds": 1, + "baths": 1, + "sqft": 660, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17530-NW-68th-Ave-APT-C4012-Hialeah-FL-33015/58453459_zpid/", + "img": "https://photos.zillowstatic.com/fp/c08b612d02360d5024ede921df1b1670-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "18111 NW 68th Ave APT G206, Hialeah, FL 33015", + "price": 200000, + "beds": 2, + "baths": 3, + "sqft": 1376, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/18111-NW-68th-Ave-APT-G206-Hialeah-FL-33015/82411311_zpid/", + "img": "https://photos.zillowstatic.com/fp/caa175fd6ff2fb60d41b63d4b631c8d9-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "18304 NW 68th Ave APT C, Hialeah, FL 33015", + "price": 218000, + "beds": 1, + "baths": 1, + "sqft": 782, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/18304-NW-68th-Ave-APT-C-Hialeah-FL-33015/70783989_zpid/", + "img": "https://photos.zillowstatic.com/fp/83c4e5c34646d0fec94a3bd9af6974e1-p_e.jpg", + "property_type": "TOWNHOUSE" + }, + { + "source": "zillow", + "address": "17000 NW 67th Ave APT 115, Hialeah, FL 33015", + "price": 220000, + "beds": 2, + "baths": 2, + "sqft": 1038, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17000-NW-67th-Ave-APT-115-Hialeah-FL-33015/44081299_zpid/", + "img": "https://photos.zillowstatic.com/fp/3744a77e4e39438ac330d294b837c20f-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "4655 Palm Ave APT 205, Hialeah, FL 33012", + "price": 219000, + "beds": 2, + "baths": 1, + "sqft": 798, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4655-Palm-Ave-APT-205-Hialeah-FL-33012/72579035_zpid/", + "img": "https://photos.zillowstatic.com/fp/65b7f9349779dd00da55c36d0ba6680b-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "17505 NW 67th Pl #I-11, Hialeah, FL 33015", + "price": 210000, + "beds": 1, + "baths": 1, + "sqft": 750, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/17505-NW-67th-Pl-I-11-Hialeah-FL-33015/72565400_zpid/", + "img": "https://photos.zillowstatic.com/fp/afd6eba25abb0b57dec4286feb934518-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "5748 W 26th Ave #5748, Hialeah, FL 33016", + "price": 220000, + "beds": 2, + "baths": 1, + "sqft": 696, + "city": "Hialeah", + "state": "FL", + "zip": "33016", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/5748-W-26th-Ave-5748-Hialeah-FL-33016/62927284_zpid/", + "img": "https://photos.zillowstatic.com/fp/69f9e3de330afb38e01bf54b1f4ffebf-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1750 W 46th St APT 503, Hialeah, FL 33012", + "price": 225000, + "beds": 2, + "baths": 2, + "sqft": 1096, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1750-W-46th-St-APT-503-Hialeah-FL-33012/43950782_zpid/", + "img": "https://photos.zillowstatic.com/fp/7de43c091ec4e6471b8f22ee9392f709-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "7220 NW 179th St APT 111, Hialeah, FL 33015", + "price": 200000, + "beds": 1, + "baths": 1, + "sqft": 679, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7220-NW-179th-St-APT-111-Hialeah-FL-33015/70785539_zpid/", + "img": "https://photos.zillowstatic.com/fp/0476612990a8f5fe76fe3a6fc6d8d26f-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1035 W 77th St APT 312, Hialeah, FL 33014", + "price": 215000, + "beds": 1, + "baths": 2, + "sqft": 753, + "city": "Hialeah", + "state": "FL", + "zip": "33014", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1035-W-77th-St-APT-312-Hialeah-FL-33014/43924045_zpid/", + "img": "https://photos.zillowstatic.com/fp/77c52cff50c7fe722a0e9ef379803c4e-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "383 E 4th Ave APT 8, Hialeah, FL 33010", + "price": 165000, + "beds": 1, + "baths": 1, + "sqft": 800, + "city": "Hialeah", + "state": "FL", + "zip": "33010", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/383-E-4th-Ave-APT-8-Hialeah-FL-33010/43963909_zpid/", + "img": "https://photos.zillowstatic.com/fp/88967065ee62f39969c0f98045469751-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "7160 NW 179th St APT 309, Hialeah, FL 33015", + "price": 195000, + "beds": 1, + "baths": 1, + "sqft": 679, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7160-NW-179th-St-APT-309-Hialeah-FL-33015/70785736_zpid/", + "img": "https://photos.zillowstatic.com/fp/9bf4fd8378217a175d9838a7a582a80a-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1725 W 60th St APT F330, Hialeah, FL 33012", + "price": 195000, + "beds": 1, + "baths": 1, + "sqft": 790, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1725-W-60th-St-APT-F330-Hialeah-FL-33012/62927619_zpid/", + "img": "https://photos.zillowstatic.com/fp/008f4b9afc164500aee34f6304db8da2-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "5755 W 20th Ave APT 308, Hialeah, FL 33012", + "price": 229900, + "beds": 2, + "baths": 2, + "sqft": 996, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/5755-W-20th-Ave-APT-308-Hialeah-FL-33012/63616485_zpid/", + "img": "https://photos.zillowstatic.com/fp/1a3d0f913cb836c0190f2d647f3d93aa-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "6055 W 19th Ave APT 209, Hialeah, FL 33012", + "price": 230000, + "beds": 2, + "baths": 2, + "sqft": 890, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6055-W-19th-Ave-APT-209-Hialeah-FL-33012/43940528_zpid/", + "img": "https://photos.zillowstatic.com/fp/536d5efa22b9c68ed97b5d4e140b7e7a-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1825 W 44th Pl APT 309, Hialeah, FL 33012", + "price": 199999, + "beds": 1, + "baths": 1, + "sqft": 712, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1825-W-44th-Pl-APT-309-Hialeah-FL-33012/43950840_zpid/", + "img": "https://photos.zillowstatic.com/fp/c9a676b37908d2c13e58c00ec9aa44e2-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "7030 NW 179th St APT 205, Hialeah, FL 33015", + "price": 224900, + "beds": 2, + "baths": 1, + "sqft": 844, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7030-NW-179th-St-APT-205-Hialeah-FL-33015/70770172_zpid/", + "img": "https://photos.zillowstatic.com/fp/0f0bed76b2fdd0e1cb1f611b8fbc95c5-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "6940 Miami Gardens Dr APT 1-126, Hialeah, FL 33015", + "price": 210000, + "beds": 1, + "baths": 1, + "sqft": 870, + "city": "Hialeah", + "state": "FL", + "zip": "33015", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6940-Miami-Gardens-Dr-APT-1-126-Hialeah-FL-33015/70784289_zpid/", + "img": "https://photos.zillowstatic.com/fp/730506d6551365bd2f3fe360069e95d3-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "606 W 81st St APT 120, Hialeah, FL 33014", + "price": 220000, + "beds": 2, + "baths": 1, + "sqft": 770, + "city": "Hialeah", + "state": "FL", + "zip": "33014", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/606-W-81st-St-APT-120-Hialeah-FL-33014/60333009_zpid/", + "img": "https://photos.zillowstatic.com/fp/0a4e8123fb4acf4cf75259c6cd31d306-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1850 W 56th St APT 2410, Hialeah, FL 33012", + "price": 195000, + "beds": 2, + "baths": 1, + "sqft": 998, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1850-W-56th-St-APT-2410-Hialeah-FL-33012/43939291_zpid/", + "img": "https://photos.zillowstatic.com/fp/10ccfacc9cf60067842fde6312ada280-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1330 W 54th St APT 302C, Hialeah, FL 33012", + "price": 195000, + "beds": 1, + "baths": 1, + "sqft": 583, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1330-W-54th-St-APT-302C-Hialeah-FL-33012/72562328_zpid/", + "img": "https://photos.zillowstatic.com/fp/9c9d47579e467f678deaa469a811108f-p_e.jpg", + "property_type": "CONDO" + }, + { + "source": "zillow", + "address": "1401 W 29th St Lot C54, Hialeah, FL 33012", + "price": 180000, + "beds": 2, + "baths": 1, + "sqft": 396, + "city": "Hialeah", + "state": "FL", + "zip": "33012", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1401-W-29th-St-LOT-C54-Hialeah-FL-33012/460950816_zpid/", + "img": "https://photos.zillowstatic.com/fp/1f441f86348fec76c289b1f2e2a1ae70-p_e.jpg", + "property_type": "MANUFACTURED" + } +] \ No newline at end of file diff --git a/casa-hunter/zillow_final.json b/casa-hunter/zillow_final.json new file mode 100644 index 0000000..06e962f --- /dev/null +++ b/casa-hunter/zillow_final.json @@ -0,0 +1,3077 @@ +[ + { + "source": "zillow", + "address": "400 18th St APT O6, Vero Beach, FL 32960", + "price": 159000, + "beds": 2, + "baths": 2, + "sqft": 1242, + "city": "Vero Beach", + "state": "FL", + "zip": "32960", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/400-18th-St-APT-O6-Vero-Beach-FL-32960/462036626_zpid/", + "img": "https://photos.zillowstatic.com/fp/464b9854c421a21244f97ccba5f6faeb-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "8415 59th Ave, Vero Beach, FL 32967", + "price": 199900, + "beds": 2, + "baths": 2, + "sqft": 960, + "city": "Vero Beach", + "state": "FL", + "zip": "32967", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/8415-59th-Ave-Vero-Beach-FL-32967/45272578_zpid/", + "img": "https://photos.zillowstatic.com/fp/5b489b65401b2ea63fe3972edddc7cbf-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "512 7th Sq APT 101, Vero Beach, FL 32962", + "price": 220000, + "beds": 2, + "baths": 2, + "sqft": 1323, + "city": "Vero Beach", + "state": "FL", + "zip": "32962", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/512-7th-Sq-APT-101-Vero-Beach-FL-32962/66749219_zpid/", + "img": "https://photos.zillowstatic.com/fp/406c949478de32cc62cb740d6aa5e02c-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "11 Vista Palm Ln APT 201, Vero Beach, FL 32962", + "price": 105000, + "beds": 2, + "baths": 2, + "sqft": 1000, + "city": "Vero Beach", + "state": "FL", + "zip": "32962", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/11-Vista-Palm-Ln-APT-201-Vero-Beach-FL-32962/2065576551_zpid/", + "img": "https://photos.zillowstatic.com/fp/d57d0e6d1fd6f75dd676a4c0521be36d-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "16 45th Avenue, Vero Beach, FL 32968", + "price": 219000, + "beds": 2, + "baths": 2, + "sqft": 1108, + "city": "Vero Beach", + "state": "FL", + "zip": "32968", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/16-45th-Ave-Vero-Beach-FL-32968/45250383_zpid/", + "img": "https://photos.zillowstatic.com/fp/fabf53cea8a8a91a8f3ba0f80cf23a15-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "7300 20th St #554, Vero Beach, FL 32966", + "price": 89900, + "beds": 2, + "baths": 2, + "sqft": 0, + "city": "Vero Beach", + "state": "FL", + "zip": "32966", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7300-20th-St-554-Vero-Beach-FL-32966/456249862_zpid/", + "img": "https://photos.zillowstatic.com/fp/72583adb1fc1f404581728ec0326693f-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "523 7th Ln SW, Vero Beach, FL 32962", + "price": 209000, + "beds": 2, + "baths": 1, + "sqft": 1148, + "city": "Vero Beach", + "state": "FL", + "zip": "32962", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/523-7th-Ln-SW-Vero-Beach-FL-32962/45262889_zpid/", + "img": "https://photos.zillowstatic.com/fp/0b49cb997493416e1e89fbd2685541f1-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "2800 Indian River Blvd #4Q, Vero Beach, FL 32960", + "price": 185000, + "beds": 2, + "baths": 2, + "sqft": 1000, + "city": "Vero Beach", + "state": "FL", + "zip": "32960", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2800-Indian-River-Blvd-4Q-Vero-Beach-FL-32960/453169981_zpid/", + "img": "https://photos.zillowstatic.com/fp/85fcc9a18b2b6f7bd42204963fefada8-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "1846 22nd Ave, Vero Beach, FL 32960", + "price": 210000, + "beds": 1, + "baths": 1, + "sqft": 668, + "city": "Vero Beach", + "state": "FL", + "zip": "32960", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1846-22nd-Ave-Vero-Beach-FL-32960/45234786_zpid/", + "img": "https://photos.zillowstatic.com/fp/6e87bba2fc0c829be8550ead4ab149c0-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "5045 Fairways Cir APT D105, Vero Beach, FL 32967", + "price": 184000, + "beds": 2, + "baths": 2, + "sqft": 1219, + "city": "Vero Beach", + "state": "FL", + "zip": "32967", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/5045-Fairways-Cir-APT-D105-Vero-Beach-FL-32967/2069024372_zpid/", + "img": "https://photos.zillowstatic.com/fp/59fb96bed95f41ef7e10a7420ea93f6a-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "219 Bimini Cay Cir, Vero Beach, FL 32966", + "price": 52000, + "beds": 2, + "baths": 2, + "sqft": 1248, + "city": "Vero Beach", + "state": "FL", + "zip": "32966", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/219-Bimini-Cay-Cir-Vero-Beach-FL-32966/2103249845_zpid/", + "img": "https://photos.zillowstatic.com/fp/4ea207e9880c376e11c72a10a0a08cbf-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "4204 36th Ct, Vero Beach, FL 32967", + "price": 177500, + "beds": 4, + "baths": 2, + "sqft": 1206, + "city": "Vero Beach", + "state": "FL", + "zip": "32967", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4204-36th-Ct-Vero-Beach-FL-32967/66743493_zpid/", + "img": "https://photos.zillowstatic.com/fp/fefd3721deb2cb3c6af7b0a271ba04e3-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "400 18th Street #G5, Vero Beach, FL 32960", + "price": 154900, + "beds": 2, + "baths": 2, + "sqft": 1130, + "city": "Vero Beach", + "state": "FL", + "zip": "32960", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/400-18th-Street-G-5-G5-Vero-Beach-FL-32960/2128422333_zpid/", + "img": "https://photos.zillowstatic.com/fp/025ef663448f6e476afba811e4547682-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "2436 42nd Place, Vero Beach, FL 32967", + "price": 229000, + "beds": 4, + "baths": 2, + "sqft": 1278, + "city": "Vero Beach", + "state": "FL", + "zip": "32967", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2436-42nd-Pl-Vero-Beach-FL-32967/45265981_zpid/", + "img": "https://photos.zillowstatic.com/fp/56016f01242a5293e7de8b6239de7b24-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "350 E Waverly Pl APT 5C, Vero Beach, FL 32960", + "price": 189000, + "beds": 2, + "baths": 3, + "sqft": 1170, + "city": "Vero Beach", + "state": "FL", + "zip": "32960", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/350-E-Waverly-Pl-APT-5C-Vero-Beach-FL-32960/449965474_zpid/", + "img": "https://photos.zillowstatic.com/fp/63bd9ce87fa828c5dea81af64bb387b8-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "1901 Westminster Cir APT 2, Vero Beach, FL 32966", + "price": 210000, + "beds": 2, + "baths": 2, + "sqft": 1395, + "city": "Vero Beach", + "state": "FL", + "zip": "32966", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1901-Westminster-Cir-APT-2-Vero-Beach-FL-32966/45238669_zpid/", + "img": "https://photos.zillowstatic.com/fp/ff22ef459bfbf4d90d929fca6fedf32e-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "115 E Harbor Dr, Vero Beach, FL 32960", + "price": 149999, + "beds": 2, + "baths": 2, + "sqft": 1056, + "city": "Vero Beach", + "state": "FL", + "zip": "32960", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/115-E-Harbor-Dr-Vero-Beach-FL-32960/461814465_zpid/", + "img": "https://photos.zillowstatic.com/fp/c5b49773c929e41386387c0c18b3230f-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "38 Plantation Dr APT 203, Vero Beach, FL 32966", + "price": 158900, + "beds": 2, + "baths": 2, + "sqft": 1188, + "city": "Vero Beach", + "state": "FL", + "zip": "32966", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/38-Plantation-Dr-APT-203-Vero-Beach-FL-32966/45238474_zpid/", + "img": "https://photos.zillowstatic.com/fp/6d590da37b081642db2d98aac0a229cf-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "121 Debra Ln, Vero Beach, FL 32962", + "price": 49900, + "beds": 2, + "baths": 2, + "sqft": 1403, + "city": "Vero Beach", + "state": "FL", + "zip": "32962", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/121-Debra-Ln-Vero-Beach-FL-32962/462074662_zpid/", + "img": "https://photos.zillowstatic.com/fp/b45fab07d03350347b14a5f112bc1d47-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "6 Vista Gardens Trail #201, Vero Beach, FL 32962", + "price": 110000, + "beds": 2, + "baths": 2, + "sqft": 1000, + "city": "Vero Beach", + "state": "FL", + "zip": "32962", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6-Vista-Gardens-Trl-APT-201-Vero-Beach-FL-32962/2069026717_zpid/", + "img": "https://photos.zillowstatic.com/fp/2f8bb415967d1890dbde4219a23d5e0f-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "18 Plantation Dr APT 204, Vero Beach, FL 32966", + "price": 155000, + "beds": 2, + "baths": 2, + "sqft": 1184, + "city": "Vero Beach", + "state": "FL", + "zip": "32966", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/18-Plantation-Dr-APT-204-Vero-Beach-FL-32966/45238235_zpid/", + "img": "https://photos.zillowstatic.com/fp/577552c7b428ec28d08e6f2befb41fd1-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "375 S Waverly Pl APT 1D, Vero Beach, FL 32960", + "price": 205000, + "beds": 2, + "baths": 3, + "sqft": 1170, + "city": "Vero Beach", + "state": "FL", + "zip": "32960", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/375-S-Waverly-Pl-APT-1D-Vero-Beach-FL-32960/2059621897_zpid/", + "img": "https://photos.zillowstatic.com/fp/599e1d42eda6898e17fd83ccef22be2c-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "117 E Harbor Dr, Vero Beach, FL 32960", + "price": 200000, + "beds": 2, + "baths": 2, + "sqft": 0, + "city": "Vero Beach", + "state": "FL", + "zip": "32960", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/117-E-Harbor-Dr-Vero-Beach-FL-32960/2085144652_zpid/", + "img": "https://photos.zillowstatic.com/fp/745bf8ae5b61814bcd30f1103c52bd08-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "360 S Waverly Pl APT D, Vero Beach, FL 32960", + "price": 230000, + "beds": 2, + "baths": 3, + "sqft": 1170, + "city": "Vero Beach", + "state": "FL", + "zip": "32960", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/360-S-Waverly-Pl-APT-D-Vero-Beach-FL-32960/2099707440_zpid/", + "img": "https://photos.zillowstatic.com/fp/822caa2d38369e4fd9f904fa4898f0bd-p_e.jpg", + "type": "TOWNHOUSE" + }, + { + "source": "zillow", + "address": "1005 20th Avenue, Vero Beach, FL 32960", + "price": 219000, + "beds": 2, + "baths": 1, + "sqft": 936, + "city": "Vero Beach", + "state": "FL", + "zip": "32960", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1005-20th-Ave-Vero-Beach-FL-32960/66733287_zpid/", + "img": "https://photos.zillowstatic.com/fp/d5f044d8650e1c654ae99e33a18e4bd1-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "675 W Lake Jasmine Circle #206, Vero Beach, FL 32962", + "price": 229000, + "beds": 2, + "baths": 2, + "sqft": 1213, + "city": "Vero Beach", + "state": "FL", + "zip": "32962", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/675-W-Lake-Jasmine-Cir-APT-206-Vero-Beach-FL-32962/2069019106_zpid/", + "img": "https://photos.zillowstatic.com/fp/7e3c38aeeea586ede9232aac5fc4c120-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "400 18th St APT C6, Vero Beach, FL 32960", + "price": 119900, + "beds": 2, + "baths": 2, + "sqft": 1130, + "city": "Vero Beach", + "state": "FL", + "zip": "32960", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/400-18th-St-APT-C6-Vero-Beach-FL-32960/2069027437_zpid/", + "img": "https://photos.zillowstatic.com/fp/c884fab551409385444b83491166a223-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "1416 SW 22nd Ave Avenue SW, Vero Beach, FL 32962", + "price": 190000, + "beds": 1, + "baths": 1, + "sqft": 794, + "city": "Vero Beach", + "state": "FL", + "zip": "32962", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1416-22nd-Ave-SW-Vero-Beach-FL-32962/45266409_zpid/", + "img": "https://photos.zillowstatic.com/fp/303a175d0ab356b7854d84f804b388fc-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "5095 Fairways Circle #102, Vero Beach, FL 32967", + "price": 229000, + "beds": 3, + "baths": 2, + "sqft": 1190, + "city": "Vero Beach", + "state": "FL", + "zip": "32967", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/5095-Fairways-Cir-APT-102-Vero-Beach-FL-32967/63519963_zpid/", + "img": "https://photos.zillowstatic.com/fp/0bc18d2b968a852a9a8c3623414e387a-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "1555 14th Avenue #201, Vero Beach, FL 32960", + "price": 125000, + "beds": 2, + "baths": 2, + "sqft": 1250, + "city": "Vero Beach", + "state": "FL", + "zip": "32960", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1555-14th-Ave-APT-201-Vero-Beach-FL-32960/2069021102_zpid/", + "img": "https://photos.zillowstatic.com/fp/4ee5c7e702d203a08fa9ea63255e05d9-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "2326 SW 15th St Street SW, Vero Beach, FL 32962", + "price": 230000, + "beds": 2, + "baths": 2, + "sqft": 900, + "city": "Vero Beach", + "state": "FL", + "zip": "32962", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2326-15th-St-SW-Vero-Beach-FL-32962/45266371_zpid/", + "img": "https://photos.zillowstatic.com/fp/89f10949b6e26d2511732f552c96b2cc-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "1170 6th Avenue #11, Vero Beach, FL 32960", + "price": 179000, + "beds": 2, + "baths": 3, + "sqft": 1170, + "city": "Vero Beach", + "state": "FL", + "zip": "32960", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1170-6th-Ave-FLOOR-11-Vero-Beach-FL-32960/461646633_zpid/", + "img": "https://photos.zillowstatic.com/fp/06bc1a0e9f30cd1248a8706a00564fe0-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "4280 29th Avenue, Vero Beach, FL 32967", + "price": 165000, + "beds": 2, + "baths": 1, + "sqft": 800, + "city": "Vero Beach", + "state": "FL", + "zip": "32967", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4280-29th-Ave-Vero-Beach-FL-32967/45267064_zpid/", + "img": "https://photos.zillowstatic.com/fp/2a243eda349feaf4c5333be4c621309c-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "1166 6th Avenue #B7, Vero Beach, FL 32960", + "price": 159000, + "beds": 2, + "baths": 2, + "sqft": 1115, + "city": "Vero Beach", + "state": "FL", + "zip": "32960", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1166-6th-Ave-APT-B7-Vero-Beach-FL-32960/2069020274_zpid/", + "img": "https://photos.zillowstatic.com/fp/218fc8c93117ff81cdf8c1d8c635c724-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "700 Lake Orchid Cir APT 205, Vero Beach, FL 32962", + "price": 185000, + "beds": 2, + "baths": 2, + "sqft": 1396, + "city": "Vero Beach", + "state": "FL", + "zip": "32962", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/700-Lake-Orchid-Cir-APT-205-Vero-Beach-FL-32962/45271072_zpid/", + "img": "https://photos.zillowstatic.com/fp/4394a4384804a68a659c15bd7e6430c5-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "2050 Pine Creek Blvd APT 201, Vero Beach, FL 32966", + "price": 225000, + "beds": 2, + "baths": 2, + "sqft": 1433, + "city": "Vero Beach", + "state": "FL", + "zip": "32966", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2050-Pine-Creek-Blvd-APT-201-Vero-Beach-FL-32966/45232572_zpid/", + "img": "https://photos.zillowstatic.com/fp/4aaa3a94d958b450c8af233ed2f96ae1-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "1170 6th Ave APT 24B, Vero Beach, FL 32960", + "price": 199000, + "beds": 2, + "baths": 3, + "sqft": 1170, + "city": "Vero Beach", + "state": "FL", + "zip": "32960", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1170-6th-Ave-APT-24B-Vero-Beach-FL-32960/2069028010_zpid/", + "img": "https://photos.zillowstatic.com/fp/73d59ebe6cb04edb92363cb1050361e0-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "1901 Indian River Blvd #210-D, Vero Beach, FL 32960", + "price": 115000, + "beds": 2, + "baths": 3, + "sqft": 1152, + "city": "Vero Beach", + "state": "FL", + "zip": "32960", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1901-Indian-River-Blvd-210-D-Vero-Beach-FL-32960/2070115389_zpid/", + "img": "https://photos.zillowstatic.com/fp/e3b1d5514ff1340b5bbc80d447bca184-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "412 7th Road SW, Vero Beach, FL 32962", + "price": 210000, + "beds": 2, + "baths": 1, + "sqft": 780, + "city": "Vero Beach", + "state": "FL", + "zip": "32962", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/412-7th-Rd-SW-Vero-Beach-FL-32962/45262700_zpid/", + "img": "https://photos.zillowstatic.com/fp/ec4bc238082bbd5f36e1adeea132224a-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "2800 Indian River Boulevard #8, Vero Beach, FL 32960", + "price": 224500, + "beds": 2, + "baths": 2, + "sqft": 1000, + "city": "Vero Beach", + "state": "FL", + "zip": "32960", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2800-Indian-River-Blvd-8-Vero-Beach-FL-32960/446273508_zpid/", + "img": "https://photos.zillowstatic.com/fp/1734ce1d033a58eb3ccce8cec9bb16bd-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "1455 90th Ave Lot 23, Vero Beach, FL 32966", + "price": 89999, + "beds": 3, + "baths": 2, + "sqft": 0, + "city": "Vero Beach", + "state": "FL", + "zip": "32966", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1455-90th-Ave-LOT-23-Vero-Beach-FL-32966/45241675_zpid/", + "img": "https://photos.zillowstatic.com/fp/07c4919f57080bf55b5ed142bf71fafb-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "518 Wisteria Dr, Melbourne, FL 32901", + "price": 189000, + "beds": 3, + "baths": 1, + "sqft": 936, + "city": "Melbourne", + "state": "FL", + "zip": "32901", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/518-Wisteria-Dr-Melbourne-FL-32901/43475952_zpid/", + "img": "https://photos.zillowstatic.com/fp/75c2413fdca57325c5923b6824ed3c93-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "3510 Applin Way, Melbourne, FL 32901", + "price": 115000, + "beds": 4, + "baths": 2, + "sqft": 1166, + "city": "Melbourne", + "state": "FL", + "zip": "32901", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3510-Applin-Way-Melbourne-FL-32901/43491718_zpid/", + "img": "https://photos.zillowstatic.com/fp/bb61b62de82cfeb75b091dd43ff69681-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "738 Lund Cir, Melbourne, FL 32901", + "price": 199900, + "beds": 4, + "baths": 2, + "sqft": 1859, + "city": "Melbourne", + "state": "FL", + "zip": "32901", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/738-Lund-Cir-Melbourne-FL-32901/43487280_zpid/", + "img": "https://photos.zillowstatic.com/fp/08353a33f679de22323cd6a7f34331e7-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "905 Cedar Dr, Melbourne, FL 32901", + "price": 216000, + "beds": 4, + "baths": 2, + "sqft": 1170, + "city": "Melbourne", + "state": "FL", + "zip": "32901", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/905-Cedar-Dr-Melbourne-FL-32901/43491673_zpid/", + "img": "https://photos.zillowstatic.com/fp/e4c12d6dacacb6a5fed8cc161a9840ec-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "2727 N Wickham Rd APT 103-5, Melbourne, FL 32935", + "price": 149900, + "beds": 2, + "baths": 2, + "sqft": 938, + "city": "Melbourne", + "state": "FL", + "zip": "32935", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2727-N-Wickham-Rd-APT-103-5-Melbourne-FL-32935/43460929_zpid/", + "img": "https://photos.zillowstatic.com/fp/a206e58d6ad134e0843e070b02a6e74c-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "2521 Pond St, Melbourne, FL 32901", + "price": 226900, + "beds": 6, + "baths": 4, + "sqft": 2132, + "city": "Melbourne", + "state": "FL", + "zip": "32901", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2521-Pond-St-Melbourne-FL-32901/43492223_zpid/", + "img": "https://photos.zillowstatic.com/fp/be69434f82ac5d578718984ffd003e42-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "2455 Pepper Ave, Melbourne, FL 32935", + "price": 179900, + "beds": 3, + "baths": 1, + "sqft": 1286, + "city": "Melbourne", + "state": "FL", + "zip": "32935", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2455-Pepper-Ave-Melbourne-FL-32935/43469512_zpid/", + "img": "https://photos.zillowstatic.com/fp/d36b78ce6ec6fe42c5cb494b5d1a91ba-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "397 Oak Haven Dr, Melbourne, FL 32940", + "price": 225000, + "beds": 3, + "baths": 2, + "sqft": 1259, + "city": "Melbourne", + "state": "FL", + "zip": "32940", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/397-Oak-Haven-Dr-Melbourne-FL-32940/66679849_zpid/", + "img": "https://photos.zillowstatic.com/fp/751af44b24de5727b9a3feace1926bec-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "801 Espanola Way, Melbourne, FL 32901", + "price": 225000, + "beds": 3, + "baths": 2, + "sqft": 1122, + "city": "Melbourne", + "state": "FL", + "zip": "32901", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/801-Espanola-Way-Melbourne-FL-32901/43487374_zpid/", + "img": "https://photos.zillowstatic.com/fp/8f68314e01b9c16af90f4f1011c87cbb-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "2417 Dakota Dr, Melbourne, FL 32935", + "price": 149900, + "beds": 3, + "baths": 2, + "sqft": 1002, + "city": "Melbourne", + "state": "FL", + "zip": "32935", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2417-Dakota-Dr-Melbourne-FL-32935/43470470_zpid/", + "img": "https://photos.zillowstatic.com/fp/6a0ea9de442329752bededa82804e6d9-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "4663 Bluejay Ln, Melbourne, FL 32935", + "price": 84000, + "beds": 3, + "baths": 2, + "sqft": 0, + "city": "Melbourne", + "state": "FL", + "zip": "32935", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4663-Bluejay-Ln-Melbourne-FL-32935/2091971623_zpid/", + "img": "https://photos.zillowstatic.com/fp/685060e6d47173451a77268abd0b48fe-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "514 Hickory St, Melbourne, FL 32901", + "price": 224995, + "beds": 3, + "baths": 2, + "sqft": 1035, + "city": "Melbourne", + "state": "FL", + "zip": "32901", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/514-Hickory-St-Melbourne-FL-32901/54616371_zpid/", + "img": "https://photos.zillowstatic.com/fp/d2cd34976771e9e73e719411754b59f6-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "4610 Lake Waterford Way APT 8-101, Melbourne, FL 32901", + "price": 149900, + "beds": 2, + "baths": 2, + "sqft": 965, + "city": "Melbourne", + "state": "FL", + "zip": "32901", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4610-Lake-Waterford-Way-APT-8-101-Melbourne-FL-32901/54618094_zpid/", + "img": "https://photos.zillowstatic.com/fp/75b16289d7ac78eae0be2aed50aebe2a-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "2607 Pepper Ave, Melbourne, FL 32935", + "price": 230000, + "beds": 2, + "baths": 1, + "sqft": 874, + "city": "Melbourne", + "state": "FL", + "zip": "32935", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2607-Pepper-Ave-Melbourne-FL-32935/43469740_zpid/", + "img": "https://photos.zillowstatic.com/fp/6bfd598668b0ff809072dc9818cd976d-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "608 Williams St, Melbourne, FL 32901", + "price": 125000, + "beds": 2, + "baths": 1, + "sqft": 602, + "city": "Melbourne", + "state": "FL", + "zip": "32901", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/608-Williams-St-Melbourne-FL-32901/43491354_zpid/", + "img": "https://photos.zillowstatic.com/fp/cd3b2dad3037672bc09c1b016e96969d-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "519 Williams St, Melbourne, FL 32901", + "price": 157975, + "beds": 2, + "baths": 1, + "sqft": 629, + "city": "Melbourne", + "state": "FL", + "zip": "32901", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/519-Williams-St-Melbourne-FL-32901/43491242_zpid/", + "img": "https://photos.zillowstatic.com/fp/405938e6ecf1c78823435ba6c233860f-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "1817 Palm Boulevard, Melbourne, FL 32901", + "price": 225000, + "beds": 4, + "baths": 2, + "sqft": 2434, + "city": "Melbourne", + "state": "FL", + "zip": "32901", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1817-Palm-Blvd-Melbourne-FL-32901/43487585_zpid/", + "img": "https://photos.zillowstatic.com/fp/5ca77e45f9c7a1e32548e4d0f0985b21-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "1001 W Eau Gallie Blvd APT 228, Melbourne, FL 32935", + "price": 149900, + "beds": 2, + "baths": 2, + "sqft": 1058, + "city": "Melbourne", + "state": "FL", + "zip": "32935", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1001-W-Eau-Gallie-Blvd-APT-228-Melbourne-FL-32935/54615898_zpid/", + "img": "https://photos.zillowstatic.com/fp/1b86a28e7858e652842af85edb7544c9-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "1780 Pinewood Rd, Melbourne, FL 32934", + "price": 199999, + "beds": 3, + "baths": 2, + "sqft": 1248, + "city": "Melbourne", + "state": "FL", + "zip": "32934", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1780-Pinewood-Rd-Melbourne-FL-32934/43456166_zpid/", + "img": "https://photos.zillowstatic.com/fp/cb71ba38dff2775cb33bf81a5e3a3baf-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "941 Croton Rd, Melbourne, FL 32935", + "price": 199900, + "beds": 3, + "baths": 1, + "sqft": 912, + "city": "Melbourne", + "state": "FL", + "zip": "32935", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/941-Croton-Rd-Melbourne-FL-32935/43471218_zpid/", + "img": "https://photos.zillowstatic.com/fp/b46a558522b6cb2a8b83e8c9b78ea281-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "163 Ash St, Melbourne, FL 32904", + "price": 229000, + "beds": 3, + "baths": 1, + "sqft": 1032, + "city": "Melbourne", + "state": "FL", + "zip": "32904", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/163-Ash-St-Melbourne-FL-32904/54616772_zpid/", + "img": "https://photos.zillowstatic.com/fp/d32daec0a331eeda56852e18e2fa6057-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "1972 Post Rd, Melbourne, FL 32935", + "price": 225000, + "beds": 2, + "baths": 1, + "sqft": 864, + "city": "Melbourne", + "state": "FL", + "zip": "32935", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1972-Post-Rd-Melbourne-FL-32935/43451560_zpid/", + "img": "https://photos.zillowstatic.com/fp/45ac1605b1b1e149168fd65dc89cb636-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "735 Players Ct, Melbourne, FL 32940", + "price": 199000, + "beds": 2, + "baths": 2, + "sqft": 994, + "city": "Melbourne", + "state": "FL", + "zip": "32940", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/735-Players-Ct-Melbourne-FL-32940/66679651_zpid/", + "img": "https://photos.zillowstatic.com/fp/2ef486e18185315b7936c4d6b528a41a-p_e.jpg", + "type": "TOWNHOUSE" + }, + { + "source": "zillow", + "address": "2655 Lorna Dr, Melbourne, FL 32935", + "price": 229900, + "beds": 3, + "baths": 2, + "sqft": 1675, + "city": "Melbourne", + "state": "FL", + "zip": "32935", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2655-Lorna-Dr-Melbourne-FL-32935/43468572_zpid/", + "img": "https://photos.zillowstatic.com/fp/c3da62e4abb6b0b98fad0a8e6b7280d5-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "1927 Westwood Blvd, Melbourne, FL 32901", + "price": 199999, + "beds": 2, + "baths": 2, + "sqft": 625, + "city": "Melbourne", + "state": "FL", + "zip": "32901", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1927-Westwood-Blvd-Melbourne-FL-32901/43487648_zpid/", + "img": "https://photos.zillowstatic.com/fp/68e9d4468f1dc5c9312ac89d3372f1b5-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "2033 Mobiland Dr, Melbourne, FL 32935", + "price": 60000, + "beds": 4, + "baths": 2, + "sqft": 1600, + "city": "Melbourne", + "state": "FL", + "zip": "32935", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2033-Mobiland-Dr-Melbourne-FL-32935/455178485_zpid/", + "img": "https://photos.zillowstatic.com/fp/f6d9cc73e912c783069b77b5f7b8bcd3-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "2365 Cottonwood Avenue, West Melbourne, FL 32904", + "price": 224900, + "beds": 3, + "baths": 1, + "sqft": 960, + "city": "Melbourne", + "state": "FL", + "zip": "32904", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2365-Cottonwood-Ave-Melbourne-FL-32904/43478830_zpid/", + "img": "https://photos.zillowstatic.com/fp/b87d6cb87b58a2ceb244f5e98f0286af-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "3919 Southwind Dr #423, Melbourne, FL 32904", + "price": 144500, + "beds": 3, + "baths": 2, + "sqft": 0, + "city": "Melbourne", + "state": "FL", + "zip": "32904", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3919-Southwind-Dr-423-Melbourne-FL-32904/2065558148_zpid/", + "img": "https://photos.zillowstatic.com/fp/e5a4f86832c587691aa38ba05347199b-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "2785 Reston St Unit 103, Melbourne, FL 32935", + "price": 210000, + "beds": 3, + "baths": 3, + "sqft": 1548, + "city": "Melbourne", + "state": "FL", + "zip": "32935", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2785-Reston-St-UNIT-103-Melbourne-FL-32935/104081263_zpid/", + "img": "https://photos.zillowstatic.com/fp/eb2626251eb68e3eeb2e16c9ffdcc552-p_e.jpg", + "type": "TOWNHOUSE" + }, + { + "source": "zillow", + "address": "110 Turpial Way APT 102, Melbourne, FL 32901", + "price": 175000, + "beds": 3, + "baths": 2, + "sqft": 1175, + "city": "Melbourne", + "state": "FL", + "zip": "32901", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/110-Turpial-Way-APT-102-Melbourne-FL-32901/80776798_zpid/", + "img": "https://photos.zillowstatic.com/fp/96e3d6d71f65649f9825885a32859bd0-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "6470 Borasco Dr APT 2102, Melbourne, FL 32940", + "price": 134900, + "beds": 1, + "baths": 1, + "sqft": 598, + "city": "Melbourne", + "state": "FL", + "zip": "32940", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6470-Borasco-Dr-APT-2102-Melbourne-FL-32940/71030951_zpid/", + "img": "https://photos.zillowstatic.com/fp/45bcc301b24931fef107a83ff0af870d-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "7667 N Wickham Rd APT 1416, Melbourne, FL 32940", + "price": 189900, + "beds": 3, + "baths": 2, + "sqft": 1256, + "city": "Melbourne", + "state": "FL", + "zip": "32940", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7667-N-Wickham-Rd-APT-1416-Melbourne-FL-32940/80767182_zpid/", + "img": "https://photos.zillowstatic.com/fp/afd79801dc881eae2a52a7dd15dbe387-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "1411 Gibbs St, Melbourne, FL 32901", + "price": 175000, + "beds": 3, + "baths": 1, + "sqft": 912, + "city": "Melbourne", + "state": "FL", + "zip": "32901", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1411-Gibbs-St-Melbourne-FL-32901/43491999_zpid/", + "img": "https://photos.zillowstatic.com/fp/6c047e8902a79c1f30ee24c6034464c9-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "2780 Reston St Unit 105, Melbourne, FL 32935", + "price": 230000, + "beds": 2, + "baths": 3, + "sqft": 1467, + "city": "Melbourne", + "state": "FL", + "zip": "32935", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2780-Reston-St-UNIT-105-Melbourne-FL-32935/104135638_zpid/", + "img": "https://photos.zillowstatic.com/fp/e7a381f6746036425a72d47e37b34ead-p_e.jpg", + "type": "TOWNHOUSE" + }, + { + "source": "zillow", + "address": "2012 Grant Pl APT 102, Melbourne, FL 32901", + "price": 225000, + "beds": 2, + "baths": 1, + "sqft": 1050, + "city": "Melbourne", + "state": "FL", + "zip": "32901", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2012-Grant-Pl-APT-102-Melbourne-FL-32901/43486981_zpid/", + "img": "https://photos.zillowstatic.com/fp/85dc76ac4e64124b9ad7a7f325c5451a-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "25 Elton St #25, Melbourne, FL 32935", + "price": 135000, + "beds": 2, + "baths": 1, + "sqft": 740, + "city": "Melbourne", + "state": "FL", + "zip": "32935", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/25-Elton-St-25-Melbourne-FL-32935/60341081_zpid/", + "img": "https://photos.zillowstatic.com/fp/665a96878a7eee937b41210e8e4135fe-p_e.jpg", + "type": "TOWNHOUSE" + }, + { + "source": "zillow", + "address": "3150 N Harbor City Blvd APT 233, Melbourne, FL 32935", + "price": 119500, + "beds": 2, + "baths": 2, + "sqft": 1058, + "city": "Melbourne", + "state": "FL", + "zip": "32935", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3150-N-Harbor-City-Blvd-APT-233-Melbourne-FL-32935/43460204_zpid/", + "img": "https://photos.zillowstatic.com/fp/5f11751fa5aaa94681448686f46ef09d-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "3512 Davinci Way #2063, Melbourne, FL 32901", + "price": 170000, + "beds": 3, + "baths": 2, + "sqft": 1140, + "city": "Melbourne", + "state": "FL", + "zip": "32901", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3512-Davinci-Way-2063-Melbourne-FL-32901/80774073_zpid/", + "img": "https://photos.zillowstatic.com/fp/e0268cd5d19d68b11d44e72395d71925-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "3008 Hanson Ave #40, Melbourne, FL 32901", + "price": 65000, + "beds": 1, + "baths": 1, + "sqft": 840, + "city": "Melbourne", + "state": "FL", + "zip": "32901", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3008-Hanson-Ave-40-Melbourne-FL-32901/439173036_zpid/", + "img": "https://photos.zillowstatic.com/fp/cca231bf2f5739df1d71f9148a428fca-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "37 Sapphire St, Melbourne, FL 32904", + "price": 199990, + "beds": 3, + "baths": 2, + "sqft": 1242, + "city": "Melbourne", + "state": "FL", + "zip": "32904", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/37-Sapphire-St-Melbourne-FL-32904/54616803_zpid/", + "img": "https://photos.zillowstatic.com/fp/c2c14d0f958b91b79df674f2971eb848-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "1001 W Eau Gallie Blvd APT 330, Melbourne, FL 32935", + "price": 152500, + "beds": 1, + "baths": 2, + "sqft": 828, + "city": "Melbourne", + "state": "FL", + "zip": "32935", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1001-W-Eau-Gallie-Blvd-APT-330-Melbourne-FL-32935/54615906_zpid/", + "img": "https://photos.zillowstatic.com/fp/e8f8d5ddea28f90d571f2bf70e3b7199-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "7079 ALAN Avenue, Jacksonville, FL 32208", + "price": 144900, + "beds": 3, + "baths": 2, + "sqft": 1182, + "city": "Jacksonville", + "state": "FL", + "zip": "32208", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7079-Alan-Ave-Jacksonville-FL-32208/44436353_zpid/", + "img": "https://photos.zillowstatic.com/fp/ee69f7dbdd27e1d968c125701f9c4101-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "7800 POINT MEADOWS Drive #1134, Jacksonville, FL 32256", + "price": 175000, + "beds": 2, + "baths": 2, + "sqft": 1281, + "city": "Jacksonville", + "state": "FL", + "zip": "32256", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7800-Point-Meadows-Dr-APT-1134-Jacksonville-FL-32256/65796505_zpid/", + "img": "https://photos.zillowstatic.com/fp/cba8a2c4c2410acc43034019f9986a09-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "13703 RICHMOND PARK Drive N #3302, Jacksonville, FL 32224", + "price": 190000, + "beds": 2, + "baths": 2, + "sqft": 1015, + "city": "Jacksonville", + "state": "FL", + "zip": "32224", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/13703-Richmond-Park-Dr-N-APT-3302-Jacksonville-FL-32224/448392019_zpid/", + "img": "https://photos.zillowstatic.com/fp/c8b316e91053e9b9e442f834f0dac7a1-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "5289 MAGNOLIA Circle N, Jacksonville, FL 32211", + "price": 225000, + "beds": 3, + "baths": 2, + "sqft": 1478, + "city": "Jacksonville", + "state": "FL", + "zip": "32211", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/5289-Magnolia-Cir-N-Jacksonville-FL-32211/44540612_zpid/", + "img": "https://photos.zillowstatic.com/fp/ed52aaf64a807b582e859ca15ea0902b-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "9604 WOODLAND Avenue, Jacksonville, FL 32208", + "price": 70000, + "beds": 3, + "baths": 1, + "sqft": 1020, + "city": "Jacksonville", + "state": "FL", + "zip": "32208", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/9604-Woodland-Ave-Jacksonville-FL-32208/168107011_zpid/", + "img": "https://photos.zillowstatic.com/fp/faf500aa5a2071c03310676e8404425f-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "8003 LOURDES Drive S, Jacksonville, FL 32210", + "price": 229900, + "beds": 3, + "baths": 1, + "sqft": 1368, + "city": "Jacksonville", + "state": "FL", + "zip": "32210", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/8003-Lourdes-Dr-S-Jacksonville-FL-32210/44414367_zpid/", + "img": "https://photos.zillowstatic.com/fp/68151f86ee6de41cda7d3b37d832d4f6-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "11287 ESTANCIA VILLA Circle #1205, Jacksonville, FL 32246", + "price": 229500, + "beds": 2, + "baths": 3, + "sqft": 1287, + "city": "Jacksonville", + "state": "FL", + "zip": "32246", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/11287-Estancia-Villa-Cir-1205-Jacksonville-FL-32246/109754073_zpid/", + "img": "https://photos.zillowstatic.com/fp/fd94a92167fd6595543a72dc33d128bf-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "4629 BLOUNT Avenue, Jacksonville, FL 32210", + "price": 175000, + "beds": 2, + "baths": 1, + "sqft": 1035, + "city": "Jacksonville", + "state": "FL", + "zip": "32210", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4629-Blount-Ave-Jacksonville-FL-32210/44500432_zpid/", + "img": "https://photos.zillowstatic.com/fp/afefaefda47c35f294856efe47a02e59-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "1860 LAKE SHORE Boulevard, Jacksonville, FL 32210", + "price": 159000, + "beds": 2, + "baths": 2, + "sqft": 2218, + "city": "Jacksonville", + "state": "FL", + "zip": "32210", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1860-Lake-Shore-Blvd-Jacksonville-FL-32210/44475044_zpid/", + "img": "https://photos.zillowstatic.com/fp/b19406dd52dbb041643e381680ee11f2-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "7615 Mayapple Road, Jacksonville, FL 32211", + "price": 220000, + "beds": 3, + "baths": 2, + "sqft": 1100, + "city": "Jacksonville", + "state": "FL", + "zip": "32211", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7615-Mayapple-Rd-Jacksonville-FL-32211/44522653_zpid/", + "img": "https://photos.zillowstatic.com/fp/2f5ec1e813a20cf53a2c2e9b974a26a8-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "639 E 27TH Street, Jacksonville, FL 32206", + "price": 114900, + "beds": 5, + "baths": 3, + "sqft": 1752, + "city": "Jacksonville", + "state": "FL", + "zip": "32206", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/639-E-27th-St-Jacksonville-FL-32206/154703059_zpid/", + "img": "https://photos.zillowstatic.com/fp/6e486e31732b78abe942a85cf97b0b5d-p_e.jpg", + "type": "MULTI_FAMILY" + }, + { + "source": "zillow", + "address": "4609 CAMBRIDGE Road, Jacksonville, FL 32210", + "price": 125000, + "beds": 4, + "baths": 2, + "sqft": 1270, + "city": "Jacksonville", + "state": "FL", + "zip": "32210", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4609-Cambridge-Rd-Jacksonville-FL-32210/44492322_zpid/", + "img": "https://photos.zillowstatic.com/fp/08bc58dbdbbdcc6abc147152d9b172e2-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "1163 W 5TH Street, Jacksonville, FL 32209", + "price": 199000, + "beds": 6, + "baths": 2, + "sqft": 1824, + "city": "Jacksonville", + "state": "FL", + "zip": "32209", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1163-W-5th-St-Jacksonville-FL-32209/154610730_zpid/", + "img": "https://photos.zillowstatic.com/fp/909c07993e0745dc76b0a4d8e8162e6f-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "1123 OVINGTON Road S, Jacksonville, FL 32216", + "price": 210000, + "beds": 4, + "baths": 2, + "sqft": 1450, + "city": "Jacksonville", + "state": "FL", + "zip": "32216", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1123-Ovington-Rd-S-Jacksonville-FL-32216/44538954_zpid/", + "img": "https://photos.zillowstatic.com/fp/1d4c285233b17f051ed534f7c3cb1bed-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "1121 MELSON Avenue, Jacksonville, FL 32254", + "price": 195000, + "beds": 3, + "baths": 2, + "sqft": 1064, + "city": "Jacksonville", + "state": "FL", + "zip": "32254", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1121-Melson-Ave-Jacksonville-FL-32254/44461506_zpid/", + "img": "https://photos.zillowstatic.com/fp/f3057b3874e75f5aa6c7b74f2959967b-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "11547 EMUNESS Road, Jacksonville, FL 32218", + "price": 200000, + "beds": 4, + "baths": 2, + "sqft": 1928, + "city": "Jacksonville", + "state": "FL", + "zip": "32218", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/11547-Emuness-Rd-Jacksonville-FL-32218/44513249_zpid/", + "img": "https://photos.zillowstatic.com/fp/d9a7f8061be0f598290bb784eae5487f-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "7216 WONDER Lane, Jacksonville, FL 32244", + "price": 190000, + "beds": 3, + "baths": 2, + "sqft": 1125, + "city": "Jacksonville", + "state": "FL", + "zip": "32244", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7216-Wonder-Ln-Jacksonville-FL-32244/44495509_zpid/", + "img": "https://photos.zillowstatic.com/fp/3eb6612e346b42c80381f70e79250017-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "8942 5TH Avenue, Jacksonville, FL 32208", + "price": 214999, + "beds": 3, + "baths": 2, + "sqft": 1027, + "city": "Jacksonville", + "state": "FL", + "zip": "32208", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/8942-5th-Ave-Jacksonville-FL-32208/459663433_zpid/", + "img": "https://photos.zillowstatic.com/fp/a4deec2d64395be3213b5bde34cd1af8-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "1930 Riverview St, Jacksonville, FL 32208", + "price": 129900, + "beds": 3, + "baths": 1, + "sqft": 0, + "city": "Jacksonville", + "state": "FL", + "zip": "32208", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1930-Riverview-St-Jacksonville-FL-32208/44448215_zpid/", + "img": "https://photos.zillowstatic.com/fp/f79569bfc0d76f3f197dde9eccd52461-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "11350 Island Shore Dr W, Jacksonville, FL 32218", + "price": 185000, + "beds": 3, + "baths": 2, + "sqft": 1316, + "city": "Jacksonville", + "state": "FL", + "zip": "32218", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/11350-Island-Shore-Dr-W-Jacksonville-FL-32218/44455385_zpid/", + "img": "https://photos.zillowstatic.com/fp/965062c1677fac4488850a7d2510f3f0-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "11333 AMERICANA Lane, Jacksonville, FL 32218", + "price": 229000, + "beds": 3, + "baths": 2, + "sqft": 1489, + "city": "Jacksonville", + "state": "FL", + "zip": "32218", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/11333-Americana-Ln-Jacksonville-FL-32218/44513381_zpid/", + "img": "https://photos.zillowstatic.com/fp/c7b09f7e5acf140ce3714ae35690a920-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "11530 HOLTON Lane, Jacksonville, FL 32219", + "price": 92000, + "beds": 3, + "baths": 2, + "sqft": 1404, + "city": "Jacksonville", + "state": "FL", + "zip": "32219", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/11530-Holton-Ln-Jacksonville-FL-32219/44404521_zpid/", + "img": "https://photos.zillowstatic.com/fp/d70c7010112eebf115ba83df04a21df9-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "1926 SPRING DRIVE Road, Jacksonville, FL 32209", + "price": 79000, + "beds": 4, + "baths": 2, + "sqft": 2181, + "city": "Jacksonville", + "state": "FL", + "zip": "32209", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1926-Spring-Drive-Rd-Jacksonville-FL-32209/44443456_zpid/", + "img": "https://photos.zillowstatic.com/fp/af43970ffc28e4326dcb5bc4f6925236-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "4958 KEY LIME Drive #205, Jacksonville, FL 32256", + "price": 137000, + "beds": 2, + "baths": 2, + "sqft": 927, + "city": "Jacksonville", + "state": "FL", + "zip": "32256", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4958-Key-Lime-Dr-UNIT-205-Jacksonville-FL-32256/316819576_zpid/", + "img": "https://photos.zillowstatic.com/fp/d1a42bd5dfe9d92562484351522ff193-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "1544 W 26TH Street, Jacksonville, FL 32209", + "price": 119900, + "beds": 4, + "baths": 2, + "sqft": 1214, + "city": "Jacksonville", + "state": "FL", + "zip": "32209", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1544-W-26th-St-Jacksonville-FL-32209/44486184_zpid/", + "img": "https://photos.zillowstatic.com/fp/bd8a45aebc90377c20263278b2d26fa0-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "5112 110TH Street, Jacksonville, FL 32244", + "price": 164900, + "beds": 4, + "baths": 1, + "sqft": 1494, + "city": "Jacksonville", + "state": "FL", + "zip": "32244", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/5112-110th-St-Jacksonville-FL-32244/44502941_zpid/", + "img": "https://photos.zillowstatic.com/fp/d204d309c9b46af84d4c75388f624009-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "311 W ASHLEY Street #608, Jacksonville, FL 32202", + "price": 105000, + "beds": 1, + "baths": 1, + "sqft": 573, + "city": "Jacksonville", + "state": "FL", + "zip": "32202", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/311-W-Ashley-St-APT-608-Jacksonville-FL-32202/82996564_zpid/", + "img": "https://photos.zillowstatic.com/fp/c5ef78e5d0f299dffbf8100742029d86-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "3037 RIBAULT SCENIC Drive, Jacksonville, FL 32208", + "price": 205000, + "beds": 4, + "baths": 2, + "sqft": 1636, + "city": "Jacksonville", + "state": "FL", + "zip": "32208", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3037-Ribault-Scenic-Dr-Jacksonville-FL-32208/44438788_zpid/", + "img": "https://photos.zillowstatic.com/fp/29d3991184bfcbd368b224f27cc2e8e6-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "7709 PASCHAL Street, Jacksonville, FL 32220", + "price": 192000, + "beds": 3, + "baths": 2, + "sqft": 992, + "city": "Jacksonville", + "state": "FL", + "zip": "32220", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7709-Paschal-St-Jacksonville-FL-32220/44407661_zpid/", + "img": "https://photos.zillowstatic.com/fp/d86e853128773fdfb0d3a5981d838948-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "13810 SUTTON PARK Drive N #535, Jacksonville, FL 32224", + "price": 169000, + "beds": 1, + "baths": 1, + "sqft": 885, + "city": "Jacksonville", + "state": "FL", + "zip": "32224", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/13810-Sutton-Park-Dr-N-APT-535-Jacksonville-FL-32224/62775532_zpid/", + "img": "https://photos.zillowstatic.com/fp/c766a85025fea4d27afb026e790dc93d-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "554 Glynlea Rd, Jacksonville, FL 32216", + "price": 220000, + "beds": 3, + "baths": 2, + "sqft": 1561, + "city": "Jacksonville", + "state": "FL", + "zip": "32216", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/554-Glynlea-Rd-Jacksonville-FL-32216/44538173_zpid/", + "img": "https://photos.zillowstatic.com/fp/f4b48cd766776e1955d9d981cac5da4a-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "7351 PROXIMA Road, Jacksonville, FL 32210", + "price": 140000, + "beds": 3, + "baths": 1, + "sqft": 912, + "city": "Jacksonville", + "state": "FL", + "zip": "32210", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7351-Proxima-Rd-Jacksonville-FL-32210/44493325_zpid/", + "img": "https://photos.zillowstatic.com/fp/a41bc54987f0e6fc9ff3972896bfe8b2-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "8135 FIRETOWER Road, Jacksonville, FL 32210", + "price": 212000, + "beds": 3, + "baths": 2, + "sqft": 1220, + "city": "Jacksonville", + "state": "FL", + "zip": "32210", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/8135-Firetower-Rd-Jacksonville-FL-32210/2083458402_zpid/", + "img": "https://photos.zillowstatic.com/fp/bd3681dae16501170a06b68b297dc1e0-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "1735 EL CAMINO Road #2, Jacksonville, FL 32216", + "price": 150000, + "beds": 3, + "baths": 2, + "sqft": 1180, + "city": "Jacksonville", + "state": "FL", + "zip": "32216", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1735-El-Camino-Rd-APT-2-Jacksonville-FL-32216/44536525_zpid/", + "img": "https://photos.zillowstatic.com/fp/65eb48dabdaa19ab24f27dcc4fc2787e-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "6453 BURGUNDY Road S, Jacksonville, FL 32210", + "price": 199900, + "beds": 4, + "baths": 2, + "sqft": 1394, + "city": "Jacksonville", + "state": "FL", + "zip": "32210", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6453-Burgundy-Rd-S-Jacksonville-FL-32210/44492881_zpid/", + "img": "https://photos.zillowstatic.com/fp/54bd30c13ef5958409a0a5bc743cdcde-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "2910 Vern Dr, Atlantic Beach, FL 32233", + "price": 75000, + "beds": 4, + "baths": 2, + "sqft": 56, + "city": "Atlantic Beach", + "state": "FL", + "zip": "32233", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2910-Vern-Dr-Atlantic-Beach-FL-32233/461940572_zpid/", + "img": "https://photos.zillowstatic.com/fp/9d68d7f1a0e3853b639dee3be9e4f9d4-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "10960 Beach Blvd #L-255, Jacksonville, FL 32246", + "price": 63000, + "beds": 3, + "baths": 2, + "sqft": 1456, + "city": "Jacksonville", + "state": "FL", + "zip": "32246", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/10960-Beach-Blvd-L-255-Jacksonville-FL-32246/217080967_zpid/", + "img": "https://photos.zillowstatic.com/fp/f499019cf60546ab54d9f6c733c4a934-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "6608 GRANVILLE Place, Jacksonville, FL 32205", + "price": 219000, + "beds": 3, + "baths": 1, + "sqft": 1117, + "city": "Jacksonville", + "state": "FL", + "zip": "32205", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6608-Granville-Pl-Jacksonville-FL-32205/44414698_zpid/", + "img": "https://photos.zillowstatic.com/fp/a70e5fde151e0b494cbbc44d517cadb4-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "7028 W Lincoln Cir, Jacksonville, FL 32209", + "price": 110000, + "beds": 3, + "baths": 2, + "sqft": 1167, + "city": "Jacksonville", + "state": "FL", + "zip": "32209", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7028-W-Lincoln-Cir-Jacksonville-FL-32209/44451815_zpid/", + "img": "https://photos.zillowstatic.com/fp/c00bdbbb42ed5ab76d0c671a18dea3b8-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "1704 PAINE Avenue, Jacksonville, FL 32211", + "price": 200000, + "beds": 3, + "baths": 1, + "sqft": 1533, + "city": "Jacksonville", + "state": "FL", + "zip": "32211", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1704-Paine-Ave-Jacksonville-FL-32211/44521043_zpid/", + "img": "https://photos.zillowstatic.com/fp/4e88f17ef872530f2ccb533ccaeb0174-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "7341 EL OCHO Road #1, Jacksonville, FL 32216", + "price": 69000, + "beds": 1, + "baths": 1, + "sqft": 725, + "city": "Jacksonville", + "state": "FL", + "zip": "32216", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/7341-El-Ocho-Rd-APT-1-Jacksonville-FL-32216/44536571_zpid/", + "img": "https://photos.zillowstatic.com/fp/6d268a907a3d0a2d3a55f4891c175807-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "1 Lake Forest Pl, Palm Coast, FL 32137", + "price": 219500, + "beds": 3, + "baths": 2, + "sqft": 1172, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1-Lake-Forest-Pl-Palm-Coast-FL-32137/44730071_zpid/", + "img": "https://photos.zillowstatic.com/fp/791367c3d59436638f935c6ba3f4cd8f-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "8 Mid Oaks Cir, Palm Coast, FL 32137", + "price": 189900, + "beds": 2, + "baths": 2, + "sqft": 950, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/8-Mid-Oaks-Cir-Palm-Coast-FL-32137/44744480_zpid/", + "img": "https://photos.zillowstatic.com/fp/7b022ff3b0494525436c63fd6ed9f07d-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "Misty Plan BUILD ON YOUR LOT Plan, Palm Coast BUILD ON YOUR LOT", + "price": 225900, + "beds": 3, + "baths": 2, + "sqft": 1333, + "city": "Palm Coast", + "state": "FL", + "zip": "32164", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/community/palm-coast-build-on-your-lot/348955987_zpid/", + "img": "https://photos.zillowstatic.com/fp/0598f435d0f650c194a4f7ed121b1047-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "20 SHERBURY Court, Palm Coast, FL 32137", + "price": 179000, + "beds": 2, + "baths": 2, + "sqft": 1098, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/20-Sherbury-Ct-Palm-Coast-FL-32137/44744691_zpid/", + "img": "https://photos.zillowstatic.com/fp/aec34e7cf0b6e672a1733e0215c72a6e-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "44 Club House Dr APT 105, Palm Coast, FL 32137", + "price": 219900, + "beds": 2, + "baths": 2, + "sqft": 1127, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/44-Club-House-Dr-APT-105-Palm-Coast-FL-32137/44744201_zpid/", + "img": "https://photos.zillowstatic.com/fp/fa70b91bbc03a53a8904018794aff870-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "Madison Plan, Seminole Trace", + "price": 228990, + "beds": 3, + "baths": 2, + "sqft": 1454, + "city": "Palm Coast", + "state": "FL", + "zip": "32164", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/community/seminole-trace/460993620_zpid/", + "img": "https://photos.zillowstatic.com/fp/805b957f5d4ffc3c903e025bbb5a3201-p_e.jpg", + "type": "MULTI_FAMILY" + }, + { + "source": "zillow", + "address": "101 Palm Harbor Pkwy #C-425, Palm Coast, FL 32137", + "price": 179900, + "beds": 2, + "baths": 2, + "sqft": 1250, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/101-Palm-Harbor-Pkwy-C-425-Palm-Coast-FL-32137/440208899_zpid/", + "img": "https://photos.zillowstatic.com/fp/f8a770b5f66201d888036e63a1465cfb-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "8 Fairways Cir #8, Palm Coast, FL 32137", + "price": 175000, + "beds": 2, + "baths": 2, + "sqft": 1056, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/8-Fairways-Cir-8-Palm-Coast-FL-32137/2070350811_zpid/", + "img": "https://photos.zillowstatic.com/fp/033865978c26192c5faa5c2105ad03e3-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "95 Rivers Edge Ln #95, Palm Coast, FL 32137", + "price": 227500, + "beds": 2, + "baths": 2, + "sqft": 1020, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/95-Rivers-Edge-Ln-95-Palm-Coast-FL-32137/2081570109_zpid/", + "img": "https://photos.zillowstatic.com/fp/d30bd9329a26bcfba1c07512d7fcc20a-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "24 Kings Colony Ct, Palm Coast, FL 32137", + "price": 224000, + "beds": 2, + "baths": 2, + "sqft": 1023, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/24-Kings-Colony-Ct-Palm-Coast-FL-32137/44726791_zpid/", + "img": "https://photos.zillowstatic.com/fp/aac966a3b3d32ff25260dac22886a4cb-p_e.jpg", + "type": "TOWNHOUSE" + }, + { + "source": "zillow", + "address": "6 Salisbury Ct #6, Palm Coast, FL 32137", + "price": 185000, + "beds": 2, + "baths": 2, + "sqft": 1098, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6-Salisbury-Ct-6-Palm-Coast-FL-32137/2075109526_zpid/", + "img": "https://photos.zillowstatic.com/fp/78f3170d7d160eec7efe5f30f7b3ba93-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "24 Bannerwood Ln Lot 62, Palm Coast, FL 32137", + "price": 64900, + "beds": 0, + "baths": 0, + "sqft": 0, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/24-Bannerwood-Ln-LOT-62-Palm-Coast-FL-32137/462138548_zpid/", + "img": "https://photos.zillowstatic.com/fp/ccab5d0aa788ef84423f4312597412e2-p_e.jpg", + "type": "LOT" + }, + { + "source": "zillow", + "address": "29 HEMBURY Lane, Palm Coast, FL 32137", + "price": 198000, + "beds": 2, + "baths": 2, + "sqft": 1098, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/29-Hembury-Ln-Palm-Coast-FL-32137/44744718_zpid/", + "img": "https://photos.zillowstatic.com/fp/804bb76c8f04f0dcd98a1019caa35d7a-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "3 Southbury Ct, Palm Coast, FL 32137", + "price": 189000, + "beds": 3, + "baths": 2, + "sqft": 1338, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3-Southbury-Ct-Palm-Coast-FL-32137/44744769_zpid/", + "img": "https://photos.zillowstatic.com/fp/7373f4e9e8d6defd7350638b064c048a-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "8 Oakmont Ct #8, Palm Coast, FL 32137", + "price": 179900, + "beds": 2, + "baths": 2, + "sqft": 950, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/8-Oakmont-Ct-8-Palm-Coast-FL-32137/441505451_zpid/", + "img": "https://photos.zillowstatic.com/fp/1aaa6e57d9632d4f5b2cdad068628b55-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "20 LAKE FOREST Court, Palm Coast, FL 32137", + "price": 225000, + "beds": 3, + "baths": 2, + "sqft": 1172, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/20-Lake-Forest-Ct-Palm-Coast-FL-32137/44730090_zpid/", + "img": "https://photos.zillowstatic.com/fp/ba7eb0907fa18b87642b1768e77c49f9-p_e.jpg", + "type": "TOWNHOUSE" + }, + { + "source": "zillow", + "address": "310 Palm Coast Pkwy NE APT 203, Palm Coast, FL 32137", + "price": 175000, + "beds": 2, + "baths": 2, + "sqft": 1006, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/310-Palm-Coast-Pkwy-NE-APT-203-Palm-Coast-FL-32137/44744355_zpid/", + "img": "https://photos.zillowstatic.com/fp/073729e66c8fe6aa95ac88f11be80879-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "22 Pine Hurst Pl, Palm Coast, FL 32137", + "price": 185000, + "beds": 2, + "baths": 2, + "sqft": 1177, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/22-Pine-Hurst-Pl-Palm-Coast-FL-32137/44744543_zpid/", + "img": "https://photos.zillowstatic.com/fp/fe589ebdfe9679dc129e0776c4fbd126-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "5 Mid Oaks Cir, Palm Coast, FL 32137", + "price": 215000, + "beds": 2, + "baths": 2, + "sqft": 1150, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/5-Mid-Oaks-Cir-Palm-Coast-FL-32137/44744477_zpid/", + "img": "https://photos.zillowstatic.com/fp/0c3663eae687b1a33e89f5c29f6e3d6c-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "4600 E Moody Blvd Building 3M, Bunnell, FL 32110", + "price": 155000, + "beds": 2, + "baths": 2, + "sqft": 1035, + "city": "Bunnell", + "state": "FL", + "zip": "32110", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4600-E-Moody-Blvd-BUILDING-3M-Bunnell-FL-32110/70760366_zpid/", + "img": "https://photos.zillowstatic.com/fp/092fef3596345f92cdd83b951978da88-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "101 Palm Harbor Pkwy #B-315, Palm Coast, FL 32137", + "price": 199900, + "beds": 2, + "baths": 2, + "sqft": 0, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/101-Palm-Harbor-Pkwy-B-315-Palm-Coast-FL-32137/444482966_zpid/", + "img": "https://photos.zillowstatic.com/fp/e7ed4dc8c4d19ea43e91f845fc71eb3a-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "58 Club House Dr APT 104, Palm Coast, FL 32137", + "price": 219900, + "beds": 2, + "baths": 2, + "sqft": 1127, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/58-Club-House-Dr-APT-104-Palm-Coast-FL-32137/44744296_zpid/", + "img": "https://photos.zillowstatic.com/fp/45c147a980326fabbebf77c435622935-p_e.jpg", + "type": "TOWNHOUSE" + }, + { + "source": "zillow", + "address": "42 Club House Dr APT 205, Palm Coast, FL 32137", + "price": 179500, + "beds": 2, + "baths": 2, + "sqft": 986, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/42-Club-House-Dr-APT-205-Palm-Coast-FL-32137/44744193_zpid/", + "img": "https://photos.zillowstatic.com/fp/468dd9b725714a49fed4ac44eab67a5c-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "4600 E Moody Blvd Building 12F, Bunnell, FL 32110", + "price": 165000, + "beds": 2, + "baths": 2, + "sqft": 1035, + "city": "Bunnell", + "state": "FL", + "zip": "32110", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4600-E-Moody-Blvd-BUILDING-12F-Bunnell-FL-32110/80401504_zpid/", + "img": "https://photos.zillowstatic.com/fp/3bfaf5c2056764434bff6388e4fbadae-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "46 Club House Dr APT 108, Palm Coast, FL 32137", + "price": 196900, + "beds": 2, + "baths": 2, + "sqft": 986, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/46-Club-House-Dr-APT-108-Palm-Coast-FL-32137/44744212_zpid/", + "img": "https://photos.zillowstatic.com/fp/b1b26014aa70dd7e16a2d096ee9776e5-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "21 Mid Pines Cir, Palm Coast, FL 32137", + "price": 225000, + "beds": 2, + "baths": 2, + "sqft": 1150, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/21-Mid-Pines-Cir-Palm-Coast-FL-32137/44744517_zpid/", + "img": "https://photos.zillowstatic.com/fp/9c3df31541fe6dde7ca403ed564d43f7-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "4600 E Moody Blvd Building 9N, Bunnell, FL 32110", + "price": 160000, + "beds": 2, + "baths": 2, + "sqft": 1035, + "city": "Bunnell", + "state": "FL", + "zip": "32110", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4600-E-Moody-Blvd-BUILDING-9N-Bunnell-FL-32110/80408149_zpid/", + "img": "https://photos.zillowstatic.com/fp/0989c58f8f782a5ef7051eec4a2aafdb-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "42 Club House Dr APT 101, Palm Coast, FL 32137", + "price": 199900, + "beds": 2, + "baths": 2, + "sqft": 986, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/42-Club-House-Dr-APT-101-Palm-Coast-FL-32137/44744181_zpid/", + "img": "https://photos.zillowstatic.com/fp/e3db67f36361cb34a379d8ef70d5e3f9-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "4600 E Moody Blvd Bldg 4K, Bunnell, FL 32110", + "price": 174900, + "beds": 2, + "baths": 2, + "sqft": 0, + "city": "Bunnell", + "state": "FL", + "zip": "32110", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4600-E-Moody-Blvd-BLDG-4K-Bunnell-FL-32110/70760380_zpid/", + "img": "https://photos.zillowstatic.com/fp/2dbb2f7ed2994df83dee0caffb39f000-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "306 Palm Coast Pkwy NE, Palm Coast, FL 32137", + "price": 159900, + "beds": 2, + "baths": 2, + "sqft": 1006, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/306-Palm-Coast-Pkwy-NE-Palm-Coast-FL-32137/351850641_zpid/", + "img": "https://photos.zillowstatic.com/fp/cb855eba4acbdcf66332126b946b7055-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "101 Palm Harbor Pkwy #C-226, Palm Coast, FL 32137", + "price": 150000, + "beds": 1, + "baths": 2, + "sqft": 670, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/101-Palm-Harbor-Pkwy-C-226-Palm-Coast-FL-32137/441494436_zpid/", + "img": "https://photos.zillowstatic.com/fp/d000c7aac3296900497cfa4a7f105538-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "24 Fairways Cir #24, Palm Coast, FL 32137", + "price": 210000, + "beds": 2, + "baths": 2, + "sqft": 950, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/24-Fairways-Cir-24-Palm-Coast-FL-32137/2103411198_zpid/", + "img": "https://photos.zillowstatic.com/fp/5df4a86f9f1aba28c13415567c650c21-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "46 Club House Dr APT 208, Palm Coast, FL 32137", + "price": 189900, + "beds": 2, + "baths": 2, + "sqft": 986, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/46-Club-House-Dr-APT-208-Palm-Coast-FL-32137/44744220_zpid/", + "img": "https://photos.zillowstatic.com/fp/3a948f9f0ea2f42904906f0856a35887-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "38 Oxford Ln #38, Palm Coast, FL 32137", + "price": 184000, + "beds": 2, + "baths": 2, + "sqft": 1098, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/38-Oxford-Ln-38-Palm-Coast-FL-32137/2075109912_zpid/", + "img": "https://photos.zillowstatic.com/fp/ade932cbd8df8e9096ace259f320ae86-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "6 Masters Ct #6, Palm Coast, FL 32137", + "price": 190000, + "beds": 2, + "baths": 2, + "sqft": 950, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/6-Masters-Ct-6-Palm-Coast-FL-32137/2075109849_zpid/", + "img": "https://photos.zillowstatic.com/fp/f0d8558e6dcafa539f31ae4fc99b477d-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "4600 E Moody Blvd Building 1N, Bunnell, FL 32110", + "price": 158500, + "beds": 2, + "baths": 2, + "sqft": 1050, + "city": "Bunnell", + "state": "FL", + "zip": "32110", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4600-E-Moody-Blvd-BUILDING-1N-Bunnell-FL-32110/70760346_zpid/", + "img": "https://photos.zillowstatic.com/fp/a69918c512dfd7c92c64c99630f3a933-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "306 PALM COAST Parkway NE #203, Palm Coast, FL 32137", + "price": 159900, + "beds": 2, + "baths": 2, + "sqft": 1006, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/306-Palm-Coast-Pkwy-NE-APT-203-Palm-Coast-FL-32137/44744339_zpid/", + "img": "https://photos.zillowstatic.com/fp/e727cad2ae633af61e47e98c8faf90e5-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "14 Mid Pines Cir #14, Palm Coast, FL 32137", + "price": 215000, + "beds": 2, + "baths": 2, + "sqft": 950, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/14-Mid-Pines-Cir-14-Palm-Coast-FL-32137/2075109929_zpid/", + "img": "https://photos.zillowstatic.com/fp/314288e85ae4276e878e192f64d610fa-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "48 Club House Dr APT 106, Palm Coast, FL 32137", + "price": 195000, + "beds": 2, + "baths": 2, + "sqft": 986, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/48-Club-House-Dr-APT-106-Palm-Coast-FL-32137/44744226_zpid/", + "img": "https://photos.zillowstatic.com/fp/e07b319e1e6e825e177cc3a10917c54d-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "101 Palm Harbor Pkwy #A212, Palm Coast, FL 32164", + "price": 205000, + "beds": 1, + "baths": 2, + "sqft": 0, + "city": "Palm Coast", + "state": "FL", + "zip": "32164", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/101-Palm-Harbor-Pkwy-A212-Palm-Coast-FL-32164/351858621_zpid/", + "img": "https://photos.zillowstatic.com/fp/49139dbc0d43fce4f1ef43f8784c8a6a-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "10 Pinehurst Pl, Palm Coast, FL 32137", + "price": 190000, + "beds": 1, + "baths": 2, + "sqft": 1056, + "city": "Palm Coast", + "state": "FL", + "zip": "32137", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/10-Pinehurst-Pl-Palm-Coast-FL-32137/44744531_zpid/", + "img": "https://photos.zillowstatic.com/fp/70430b11e1506ef036c7a4362f649a3b-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "1103 Washington St, New Smyrna Beach, FL 32168", + "price": 227500, + "beds": 3, + "baths": 2, + "sqft": 1353, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1103-Washington-St-New-Smyrna-Beach-FL-32168/48078403_zpid/", + "img": "https://photos.zillowstatic.com/fp/401add18890157c0ef894aec9cc8ef0c-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "2801 Nordman Ave, New Smyrna Beach, FL 32168", + "price": 197999, + "beds": 2, + "baths": 1, + "sqft": 816, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2801-Nordman-Ave-New-Smyrna-Beach-FL-32168/170946350_zpid/", + "img": "https://photos.zillowstatic.com/fp/dcbd2f71e9193601b4e4ff770e046ff1-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "26 Birdie Dr, New Smyrna Beach, FL 32168", + "price": 199900, + "beds": 2, + "baths": 2, + "sqft": 1270, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/26-Birdie-Dr-New-Smyrna-Beach-FL-32168/170979668_zpid/", + "img": "https://photos.zillowstatic.com/fp/f0b5d16f13c4a4702f53f5ca1beed9e9-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "614 Washington St, New Smyrna Beach, FL 32168", + "price": 199000, + "beds": 2, + "baths": 1, + "sqft": 1120, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/614-Washington-St-New-Smyrna-Beach-FL-32168/48078457_zpid/", + "img": "https://photos.zillowstatic.com/fp/961f219625198b0afaf1301e325c8a64-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "4 Bogey Cir, New Smyrna Beach, FL 32168", + "price": 150000, + "beds": 2, + "baths": 2, + "sqft": 1038, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4-Bogey-Cir-New-Smyrna-Beach-FL-32168/170979919_zpid/", + "img": "https://photos.zillowstatic.com/fp/2806cbb41a53e0622d2c1114d51e04b7-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "3509 S Atlantic Ave #210, New Smyrna Beach, FL 32169", + "price": 187000, + "beds": 1, + "baths": 1, + "sqft": 507, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32169", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3509-S-Atlantic-Ave-210-New-Smyrna-Beach-FL-32169/48079935_zpid/", + "img": "https://photos.zillowstatic.com/fp/db23a3820b756919b8871c284537cc3c-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "2701 Brookline Ave, New Smyrna Beach, FL 32168", + "price": 219000, + "beds": 3, + "baths": 1, + "sqft": 855, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2701-Brookline-Ave-New-Smyrna-Beach-FL-32168/48065558_zpid/", + "img": "https://photos.zillowstatic.com/fp/4474c039dcd78530b1ff268525749923-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "3509 S Atlantic Ave #109, New Smyrna Beach, FL 32169", + "price": 185000, + "beds": 1, + "baths": 1, + "sqft": 507, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32169", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3509-S-Atlantic-Ave-109-New-Smyrna-Beach-FL-32169/453354582_zpid/", + "img": "https://photos.zillowstatic.com/fp/e9a692913d54db8b545510b8d40bf0a6-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "3800 Saxon Dr #C-52, New Smyrna Beach, FL 32169", + "price": 230000, + "beds": 2, + "baths": 2, + "sqft": 838, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32169", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3800-Saxon-Dr-C-52-New-Smyrna-Beach-FL-32169/2068861312_zpid/", + "img": "https://photos.zillowstatic.com/fp/5182c86d1372539572e4ae071cd8e315-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "1804 Enterprise Ave #A, New Smyrna Beach, FL 32168", + "price": 219000, + "beds": 2, + "baths": 2, + "sqft": 1186, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1804-Enterprise-Ave-A-New-Smyrna-Beach-FL-32168/2098044975_zpid/", + "img": "https://photos.zillowstatic.com/fp/7c9d18a8c608d32d332d6f2f9f281a38-p_e.jpg", + "type": "TOWNHOUSE" + }, + { + "source": "zillow", + "address": "415 N Duss St, New Smyrna Beach, FL 32168", + "price": 134900, + "beds": 2, + "baths": 1, + "sqft": 984, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/415-N-Duss-St-New-Smyrna-Beach-FL-32168/48078326_zpid/", + "img": "https://photos.zillowstatic.com/fp/2ef76e63ae7d4d7455034e32c8094e95-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "33 Sandra Cir, New Smyrna Beach, FL 32168", + "price": 219900, + "beds": 2, + "baths": 2, + "sqft": 1326, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/33-Sandra-Cir-New-Smyrna-Beach-FL-32168/170979679_zpid/", + "img": "https://photos.zillowstatic.com/fp/8a30e4fc3a913f1720853dab75005778-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "2051 Pioneer Trl #211, New Smyrna Beach, FL 32168", + "price": 69000, + "beds": 3, + "baths": 2, + "sqft": 1409, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2051-Pioneer-Trl-211-New-Smyrna-Beach-FL-32168/2080016561_zpid/", + "img": "https://photos.zillowstatic.com/fp/ea97cb367c62eff68db1090caa45fe0e-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "2328 Eslinger Rd #116, New Smyrna Beach, FL 32168", + "price": 40000, + "beds": 3, + "baths": 2, + "sqft": 0, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2328-Eslinger-Rd-116-New-Smyrna-Beach-FL-32168/458994342_zpid/", + "img": "https://photos.zillowstatic.com/fp/a9f2f9126d54a40453cf26f380807e34-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "2031 Porto Blvd, New Smyrna Beach, FL 32168", + "price": 199900, + "beds": 3, + "baths": 2, + "sqft": 1323, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2031-Porto-Blvd-New-Smyrna-Beach-FL-32168/48072628_zpid/", + "img": "https://photos.zillowstatic.com/fp/d19a1644d6b22521536aad67bdbf5530-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "903 Conrad Dr, New Smyrna Beach, FL 32168", + "price": 230000, + "beds": 3, + "baths": 1, + "sqft": 1240, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/903-Conrad-Dr-New-Smyrna-Beach-FL-32168/48071099_zpid/", + "img": "https://photos.zillowstatic.com/fp/aa058fd2599aadaecb8f2b6580222f59-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "2133 Turnbull Bay Rd #4, New Smyrna Beach, FL 32168", + "price": 54900, + "beds": 2, + "baths": 1, + "sqft": 0, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2133-Turnbull-Bay-Rd-4-New-Smyrna-Beach-FL-32168/447131062_zpid/", + "img": "https://photos.zillowstatic.com/fp/d19587b2246cca4943d48fbf7e07dbde-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "3700 S Atlantic Ave APT 103, New Smyrna Beach, FL 32169", + "price": 198000, + "beds": 1, + "baths": 1, + "sqft": 459, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32169", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3700-S-Atlantic-Ave-APT-103-New-Smyrna-Beach-FL-32169/48076620_zpid/", + "img": "https://photos.zillowstatic.com/fp/b63868a85503cec9e70b4c88b3c11714-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "335 Causeway D22, New Smyrna Beach, FL 32169", + "price": 230000, + "beds": 1, + "baths": 1, + "sqft": 650, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32169", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/335-Causeway-D22-New-Smyrna-Beach-FL-32169/2067401954_zpid/", + "img": "https://photos.zillowstatic.com/fp/16816c8b33f50f456fedadae48f29333-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "56 Pelican Dr, New Smyrna Beach, FL 32168", + "price": 124995, + "beds": 2, + "baths": 2, + "sqft": 938, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/56-Pelican-Dr-New-Smyrna-Beach-FL-32168/454870488_zpid/", + "img": "https://photos.zillowstatic.com/fp/003806b0018ea76d62753cbc39a4d84e-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "1165 S State Route 415 #7, New Smyrna Beach, FL 32168", + "price": 109000, + "beds": 2, + "baths": 2, + "sqft": 0, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1165-S-State-Route-415-7-New-Smyrna-Beach-FL-32168/461157303_zpid/", + "img": "https://photos.zillowstatic.com/fp/2bfef7ddb6ccc304921701f3deadae98-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "14 New York Dr, New Smyrna Beach, FL 32168", + "price": 59000, + "beds": 2, + "baths": 2, + "sqft": 1176, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/14-New-York-Dr-New-Smyrna-Beach-FL-32168/351547841_zpid/", + "img": "https://photos.zillowstatic.com/fp/53c1e5e8024e46780d022350139f8574-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "181 Fox Fire Cir, New Smyrna Beach, FL 32168", + "price": 142512, + "beds": 2, + "baths": 2, + "sqft": 1056, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/181-Fox-Fire-Cir-New-Smyrna-Beach-FL-32168/443911165_zpid/", + "img": "https://photos.zillowstatic.com/fp/412f3f810839351d1ee8ff75ec85307e-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "4125 Quail Nest Ln Lot 34, New Smyrna Beach, FL 32168", + "price": 54900, + "beds": 0, + "baths": 0, + "sqft": 0, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4125-Quail-Nest-Ln-LOT-34-New-Smyrna-Beach-FL-32168/460977573_zpid/", + "img": "https://photos.zillowstatic.com/fp/69a2db7bdefb27f7e5373c7944416c71-p_e.jpg", + "type": "LOT" + }, + { + "source": "zillow", + "address": "100 Ingham Rd Lot 12, New Smyrna Beach, FL 32168", + "price": 43000, + "beds": 2, + "baths": 1, + "sqft": 0, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/100-Ingham-Rd-LOT-12-New-Smyrna-Beach-FL-32168/461328712_zpid/", + "img": "https://photos.zillowstatic.com/fp/58a82b6387d97d101c1fb4432fa81bcc-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "152 Fox Fire Cir, New Smyrna Beach, FL 32168", + "price": 58900, + "beds": 2, + "baths": 2, + "sqft": 960, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/152-Fox-Fire-Cir-New-Smyrna-Beach-FL-32168/461969676_zpid/", + "img": "https://photos.zillowstatic.com/fp/9615cafd42d10202b8954a11dc0eb972-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "1835 S Glencoe Rd, New Smyrna Beach, FL 32168", + "price": 224000, + "beds": 0, + "baths": 0, + "sqft": 0, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1835-S-Glencoe-Rd-New-Smyrna-Beach-FL-32168/104250419_zpid/", + "img": "https://photos.zillowstatic.com/fp/13a782672a7ccd5f02b12e201e3f44ab-p_e.jpg", + "type": "LOT" + }, + { + "source": "zillow", + "address": "0 S Peninsula Ave #C35, New Smyrna Beach, FL 32169", + "price": 210000, + "beds": 0, + "baths": 0, + "sqft": 0, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32169", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/0-S-Peninsula-Ave-C35-New-Smyrna-Beach-FL-32169/460397372_zpid/", + "img": "https://photos.zillowstatic.com/fp/c00ebd03cb37229d460de77a1f4eac3e-p_e.jpg", + "type": "SINGLE_FAMILY" + }, + { + "source": "zillow", + "address": "3700 S Atlantic Ave APT 101, New Smyrna Beach, FL 32169", + "price": 198000, + "beds": 1, + "baths": 1, + "sqft": 459, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32169", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/3700-S-Atlantic-Ave-APT-101-New-Smyrna-Beach-FL-32169/48076618_zpid/", + "img": "https://photos.zillowstatic.com/fp/09dd8c8354ed5a04e5cce918bdcb0668-p_e.jpg", + "type": "CONDO" + }, + { + "source": "zillow", + "address": "2051 Pioneer Trl Lot 221, New Smyrna Beach, FL 32168", + "price": 57900, + "beds": 2, + "baths": 2, + "sqft": 0, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/2051-Pioneer-Trl-LOT-221-New-Smyrna-Beach-FL-32168/2097917513_zpid/", + "img": "https://photos.zillowstatic.com/fp/a6a3f2345aa5e3d7436e41f7c12ae72b-p_e.jpg", + "type": "MANUFACTURED" + }, + { + "source": "zillow", + "address": "(undisclosed Address), New Smyrna Beach, FL 32168", + "price": 219000, + "beds": 2, + "baths": 2, + "sqft": 1186, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/New-Smyrna-Beach-FL-32168/48069818_zpid/", + "img": "https://photos.zillowstatic.com/fp/b7b5c6c810cb4ddf152ee430b171dede-p_e.jpg", + "type": "MULTI_FAMILY" + }, + { + "source": "zillow", + "address": "Quail Nest Ln #16, New Smyrna Beach, FL 32168", + "price": 70000, + "beds": 0, + "baths": 0, + "sqft": 0, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/Quail-Nest-Ln-16-New-Smyrna-Beach-FL-32168/441284851_zpid/", + "img": "https://photos.zillowstatic.com/fp/dfd74f15605ef059af64ba91d0cf77d9-p_e.jpg", + "type": "LOT" + }, + { + "source": "zillow", + "address": "0 PAIGE Avenue, New Smyrna Beach, FL 32168", + "price": 109000, + "beds": 0, + "baths": 0, + "sqft": 0, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/0-Paige-Ave-New-Smyrna-Beach-FL-32168/2105505662_zpid/", + "img": "https://photos.zillowstatic.com/fp/53ebdfa4e546ef171278c6036a66b512-p_e.jpg", + "type": "LOT" + }, + { + "source": "zillow", + "address": "4678 Gum Rd, New Smyrna Beach, FL 32168", + "price": 229900, + "beds": 0, + "baths": 0, + "sqft": 0, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/4678-Gum-Rd-New-Smyrna-Beach-FL-32168/453903529_zpid/", + "img": "https://photos.zillowstatic.com/fp/ba802f9404eb4e73ca9fbaf37a11442f-p_e.jpg", + "type": "LOT" + }, + { + "source": "zillow", + "address": "S Glencoe Rd, New Smyrna Beach, FL 32168", + "price": 229000, + "beds": 0, + "baths": 0, + "sqft": 0, + "city": "New smyrna beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/S-Glencoe-Rd-New-Smyrna-Beach-FL-32168/104263165_zpid/", + "img": "https://photos.zillowstatic.com/fp/964a2a22d0da4f955e795f05e15a5697-p_e.jpg", + "type": "LOT" + }, + { + "source": "zillow", + "address": "No Address State Rd #44-34, New Smyrna Beach, FL 32168", + "price": 99000, + "beds": 0, + "baths": 0, + "sqft": 0, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/No-Address-State-Rd-44-34-New-Smyrna-Beach-FL-32168/2054325813_zpid/", + "img": "https://photos.zillowstatic.com/fp/a95c063badfd1cb13a2b28069303af47-p_e.jpg", + "type": "LOT" + }, + { + "source": "zillow", + "address": "Brookline Ave Lot 43, New Smyrna Beach, FL 32168", + "price": 99000, + "beds": 0, + "baths": 0, + "sqft": 0, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/Brookline-Ave-LOT-43-New-Smyrna-Beach-FL-32168/461556045_zpid/", + "img": "https://photos.zillowstatic.com/fp/bbe3a91a40c1f1879a100ae2497c4da6-p_e.jpg", + "type": "LOT" + }, + { + "source": "zillow", + "address": "No Address State Rd #44, New Smyrna Beach, FL 32168", + "price": 99000, + "beds": 0, + "baths": 0, + "sqft": 0, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/No-Address-State-Rd-44-New-Smyrna-Beach-FL-32168/2055279831_zpid/", + "img": "https://photos.zillowstatic.com/fp/37dadcdce48f73cd6f0c30e634ddfde9-p_e.jpg", + "type": "LOT" + }, + { + "source": "zillow", + "address": "1521 Ocuan Trl Lot 31, New Smyrna Beach, FL 32168", + "price": 189000, + "beds": 0, + "baths": 0, + "sqft": 0, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/1521-Ocuan-Trl-LOT-31-New-Smyrna-Beach-FL-32168/457619146_zpid/", + "img": "https://photos.zillowstatic.com/fp/381070b634e2bba647e0ecc20d52149d-p_e.jpg", + "type": "LOT" + }, + { + "source": "zillow", + "address": "0 Cherry St, New Smyrna Beach, FL 32168", + "price": 79000, + "beds": 0, + "baths": 0, + "sqft": 0, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/0-Cherry-St-New-Smyrna-Beach-FL-32168/2112364674_zpid/", + "img": "https://photos.zillowstatic.com/fp/f6715430f52e8b9f66c3b1e34c500d6a-p_e.jpg", + "type": "LOT" + }, + { + "source": "zillow", + "address": "508 Terrier Way #25, New Smyrna Beach, FL 32168", + "price": 58000, + "beds": 0, + "baths": 0, + "sqft": 0, + "city": "New Smyrna Beach", + "state": "FL", + "zip": "32168", + "status": "FOR_SALE", + "url": "https://www.zillow.comhttps://www.zillow.com/homedetails/508-Terrier-Way-25-New-Smyrna-Beach-FL-32168/433706853_zpid/", + "img": "https://photos.zillowstatic.com/fp/8531e26df6c197c2b3804e812dfb1340-p_e.jpg", + "type": "LOT" + } +] \ No newline at end of file diff --git a/prisa-yachts/brochures/PrisaYachts_Electrical.pdf b/prisa-yachts/brochures/PrisaYachts_Electrical.pdf new file mode 100644 index 0000000..5d9fa04 --- /dev/null +++ b/prisa-yachts/brochures/PrisaYachts_Electrical.pdf @@ -0,0 +1,91 @@ +%PDF-1.4 +% ReportLab Generated PDF document (opensource) +1 0 obj +<< +/F1 2 0 R /F2 4 0 R /F3 5 0 R +>> +endobj +2 0 obj +<< +/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font +>> +endobj +3 0 obj +<< +/BitsPerComponent 8 /ColorSpace /DeviceRGB /Filter [ /ASCII85Decode /DCTDecode ] /Height 454 /Length 45172 /Subtype /Image + /Type /XObject /Width 476 +>> +stream +s4IA0!"_al8O`[\!<<*#!!*'"s5F(38OGjP:f:(Y8PDPQ!GM6!#0'J=]te*!@RpJ!#/mE=]te*!B^>^!#0X!E-)'[!Diar!#0HQ;F:Ea!Fu01!%;JZ;F:Ea!Fu01!%;;U;F:Ea!Fu01!%;>rEc_9]!K7!Y!'G+7F^kCOz!!*'"!":6[,=5:jTb\Ij1IGVlJs)k5dhbq`PEis11h3ht_U!WrH(zz!!!!$"Tef2!=/YC!(.=u!h&@P]s+;-c'\\E9_]>%X9Jr:t;f)eCgC:@#e=#c_ur/Q.p52k6*7M1Gc.j>N("^q''j`D5D_ee9rgRSE&U;(H>kZTC1YQ$s3>gqhQTh+EBPSOL(H?pF=]+07_Qu4Yd@%2j`Nc`33*^K*g.Z>>>2!pSSr]dNF#7qlJ#m-FfKIDN>$%[`5*"n[K2XK#T-E`af!;FgD>@]EE;6"dQ9BrGE:n"&>pUII[?-`\0plq3IND)t(GtQhhnr2l`@b//^<=I_Qt*X;>s-IA7!`$j3PWT'IFWT&N,U4%$'SXLcfRGSO8K=mMmu=*#@Hra'9\BRr^PYerBOmZKjsPCDYSc0ZWiZ&"B$DIAC]Y;/e1cR!Z-SrP(NTLG8Y\\EH82r(=A_eYN*pA1;55B7712lH\'KoZ;l_?B&jG7\YF0MEYcdh#-V7sFOl>ELhgRfK/@]Aqb.c\#?/&`J&uLohDr,ihe+"1-h-`ddN0KTHaJ^=[BO51EuB>=4j;V^bM0ZDc98t#1')<$pI]j7:8N'[3T`;'!!ds#nj\8B6pt2d,Yc*#!]M.LH`rmqLN)j]f8WYPBDr9UO-5rsY6%nm[fb_j8&+4LNrK*Jd,uI0.nodE`5\J4I!=QG]pRk<%B@Q+RT^'N@@>?;Ng?BqbfBlFgWGM]J-"QqmWUaX]h:WeVE.#9*tub*k6@D-m33b%=X#%6+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+tQ@V51FE#9__t`o7:I3/:Q\bIA43^ZJA@@-P3ts\a=3mg!/E9F_M*CZ1#T&`&:fp/_iSVh>Pc$]XF:JaK&n.dZ`(cF](3lG@;JH^IC3Ob"S_n%oMEWZY#8Jj7>kKrrDmfa+*2SRFXMAca4cX\7s6_g)WJ%THW]DG;.Q6mJ/,`q[Rl+!SI,L&3t1WFBErJ2)Lk.pE\LbQ;G)Ql`Wm9[CtP@iX@TpmCYZ!Sa6aM""A6%oi.R^T[D/OPn-+&Ne*6U`cPqhp+gH<;H2+/Q9uVk!1K,`iGaU/TO+?:+sPHbM=1gZkXS]LV;c[U.h9m;P,5:;Rn#heqpWC1UK[Woede83BH'FM@&%T`Zp,Pi-V/1P=-'`:l/!2CQ*P1";G2uMp3Y42eN9q&2TV[F"Ka3dAn?1+fB6q,:uO`8oR;-N1`/lsO4Bk]"?I.\/snAsUKTXiBiO%-JV8LL/3F"@RV@odX\+LO8f^i"^)rr\[(C"LpqJ,l6bl\5kd4D>1+E>giF,K5jnBS:JV:fq0!^@aE(Z$AJ+3\)6\m'BqFG;.]VfXNp/Eikfe.VV4VR1)bfuorJ9`FnJg;oh2m@MB"Cl@\2!m*?9*JCj>7*VRpBP^YatLA8DYEFg842KKNqmPHr96(81k"+iNMN2?<^GN=FMKoO(Qc/:@`4:^BOla65QthG8ib>*aL%Q/nZ7)G]Hf"K$[B0OO8Nd%UeR6'tBX$f+HrG9'd]3/%(-,H9c`XYC/9nEWT#A[16WG9=E;@Et$4Dd3`dlYF9uDZPB_U0#go[`GDiZ9O!Vg_b.s75%<.cu0nfK`GHU?E./7%63`+OiWI^rBe1maZD:F3&\NXK.kN/-+t5FW)KF/!q-TP8IRmJ8\O'%W?d+a-ulMY%I'6psnU;%XBP&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te(*i>S`g089e5pVL_R:0&rr?"hF)0lWrrAgq?ieL9hn*(T\!V4'Un]e%QrNiLDF^8f".DI:sIPh9rB];48*_b(cl.c!>of^UTBl)/\>T++(^&8#Q2^KX3pDp]ck85)7$i.K5L<@XWcX=aCfdho]W/\F4%)p7pq)@.a!$:B;]].c@##fP6Tj$8!;q6(^sHPM^BLoV;,"8lRlK]jHfC[^Xnm2o,ae5_M.!7%LV/iZP@poW$.A(RCp]-Ohmo%7ktO*N/9,HDoq=2OM.HTja5B)kssppa=&7=])H4_4*#:Aj5lAWfOfZ&EKP%WdKj!"M)UFm<=k%Z=IBT=Fh5a)VVob%>XNSrU]],AEbmo^dtKht;je!Vi]r11L_fJ/a+/U;GpPlVQFAQ!NIo,pW.*W?`mN3@>^uXl"/CqIU\Ws-Z?8Zl%Q:iiYG'.IEtuNu[bYVoQs&Z$Lq;U>]PcB`F$.QiH%=[@kehTs&JB7Jim)LZj%&^@r%g(8el]4>"]/a730q9-)FKobKS9!3$ot$2b)hmNr('jV[EW6#7XcsNg267TbiQp_]jL8B+E,0C=Y]_D'['U:t5eNN9VKn1fWgF``KLA69oaqraCUeQ4/'RddbPbi$)CB)_kMf%lhq!8#GEk-XTI@=#>Rk;a;o1m]_Dq$koXm-8i^oeHfcq4/l]GF-ehICIt6b;d!fip0NfERCe7--3Sme;O(SosHYVQ+$R,6TLm/r8k+liTNXe\q5,/F;o+DCe?'L9\)!t#i[im=DW+a=%-cd#,"u]St"ChqWpE3MbeSSo"NLoN3]UQQ:J/;7Z[m$1cTUDi3E:^Mk2m`NYq6UfkpXMA@Y,0[Du>i66@dBZ'?t`_1hFc*n/3]Z,^KpH1oq'DL&2=P#q[P$\bOg/#tU)[1RRrQW/C]=AJ(J&,3AQ5o@"D?C=i5$omI(9%D`>#U8g[7TpdLt_\:@KeP-9[XJiP"7&lZM4C:cY8NTW2Qk1(T:L_HMEjXJZ\>N,3>Ml:nDlG.a+BcdcG#FfWIP7^m!)nF;QSNNSduebIYQPuDPWAjTbkrfhoSCIkt2%mrO:2UMr^lkk/YR`Wm1S'8an=8JGAtOlH"s^&*6BiL4Fb56`kbf![94QG.CpJ.ahKjg+FDd:SGmelhmEi=^afA`e.jI^rYUhlB-$g7eNHns3i=B6Yqc-aOi$9#kc3V5S1BaVoM]1'UG7OkIRO67U._UMK<[`nPpm&j"_M,%r$Ok8Zp*A[>'L3``ht[$bZDV$G)8V.gu^7&5!AG9&cU`N:.c!o;05]F&WP_tB=Y.pa)ZOQ9)oHWEFXV.E(pZ>K%I_ng1OILV5GRr2JT-IhPHiI27XoKn`:J%)hRVJd/M9=*L"UnrUNH?qf3jD2;r5Lr!XW,#F9/UU2&FRLs(CshcZZ'H1U(Y;t)FY>Kb,>O*U$QZ:J4,--g&'#Bqo@k/u.+MO#nmPOYJ``j$Eeaa@1@6['f%4*m[jc/lcVm1_0Qb]s]687HbgP+J_eu,,EsA4n7o@;:\hRjVrr>NnN@D40EZ6kT7;YBrhUPg$cVZXAB1V1s%qbBn73eo@Eb@OAg_N7o;%XLXe3l\m6psF26psF26psF26psF26psF26psF26psF2>W%e2G5>o'C[0lUVhf7:ZUbqQ%uG;i&Jm3[\>e".m2"[<4OhPQK5NSo9DsG&![Fb6c%ZIbH4\b@@3aB@PcCI<.l=QH>'P29FOJUaqi0U`o0C/X&llg2cN=J:!-GJ#]D?HWQ5mSJF7!ss"l\3)Nd_U#9ob!abFYWA[^.=)Dq/a:=3BrVb9:h?,'/fP]O[A4;J%3Cdqn&J(Z@01%8c!NY4%<8O$S68CT1S$p$s`>&,W;&G;/4&Xjd)Uha"l<^a\T!@,Ngsli,o9*+*9Rbeqk=6$\`)-u=LjYT:5"h4Ed/@M*(gg:@3a%_YPgR+.obP_Eo>8Oq*@"`i&'1"uGV!ZJkC9@]ik.#[ZLfZDHJ>7lh.MoLV)dY<,c$*E32DdqWQFKQKtp7l3urt-2q_O'c@2BtqTZlHYYer<[bJeRP?DF7[G(%jdaK,7G7\*anN6m:U]]TFF%@DckTCEK4dG1gTfm8T':A$Q_T]>j_9\G250GmUdKQ>#fEf#I4p'S$_OgA$[^>nQWFujF?AH&\5sEdGAqQ92QckD`ghdUN#!"7nF!A*VukXdnLb/XW+YGMl$1XQQ)bQ%?Srb[Be&d@k=O',sO>uQ*1]9%8*P+jSDT/=DgiEqSN*aL-WT`WO\W'Bq@i>d*-h8LWs*cET4O"C3?\;*Plu$^L_]*QQ%F5[8sif9m:5E\;AOkK^O+l5TPd.gSp/ho$U%YmB-&j*S6VY`p7+B>M^t)]JNsaGR[tPCQhjOeI^3aBs#fA>-gh3*cs8jS,%%]V=/&bZ\-%&kkFPNg0'tD9bg%[jFPb!f9iAgSh`e5Y1SlHlujX&[Y'9O+"/ujnZ/;GY/sb2?L%KtVW1keWcKNK!59dP>f^/qG:mB/8TT_OnJDP.UtGVAe=Rroue&6g]+^Lp-Cf^B)k"`:;o4r&3a7e/#"rFFn\-e'+&AZXVADQ'S(COJ$Nm!e>E6_*n\)#??#rq!T(Fd)$t.e,N6L0FXB>ZZnmC*Fk(=e[)a+sJ3TG=4hr?@Ch>@O/h1tNsVS]iKDrTfAt<6UQVdOq^3pN;$c7FNLa65b_@aHm+;PclErLi*'A+Rp-WT:2<-qOXAIr!E`'Y!K%2_I$U`aopV*>a:=;]9Dor*eH4K$(m2"4uDmGHl!Bg.\*8J_-4rHE[L1hpJf/ljuES7E24doSSQ*Z&cVQ+I;aU@2Tm^Lu6SB%9X!_=8m]:1,;bEH*Y0DOYcMX,)^LegZJ78V+aSho'dObC-e57i!=G+iRZM/'Y0rfORg(r+<5Q2H'nGC?(N9[okWXZUEe_@>=\3LdCT9YiHF7'Z-k\-l\!bYO[gC.h==K!O,g'3j:>e5+@%"1IHER=fcu;lgWZ4bL"s;A`C2=V3[!e%7D+t?>nIZ:]ib*K*uFWG)g*qE`cVXq]0V0_9U7/e`M>PXJubASic?'NSZi:DhirkW=s(oVg%L03MW[E(EjjN9>;GitYD^#1HMBa-=+*a?<$Ar8hJaIX$KHBOu$%OQue]HHeUQQcl)*Gqr$$OiP!">tdiGbT0eWF+63Q\,M>5l%H/SG:mBtO)g:@%^Om,/d_s^)m'Q4cIl>(>od0DSt;Y_"HgqJJ1Z*f3]WuI5og4]SQ%$M&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&TQ=Mdns%:=]nTA&4"9//@%5mOg1[*3Q1Oi!(eIKE8<.4gE!T&o6IiEd*PV+qO4FaM$.fc'*30GpH,-R!$mcT!4@HNnH2GD/]=KTL0SXPQPe.#H)7OARBQ0rnn1l2EZ,tN*ad%/iQqg%k*Is,D^Q3EWPf$t"PF9RE1Mp<

&]rN4Vm?1Pnk/A9,=ps1[S9>"kE?t9(Q/#Ir^^l5i]3T+71m;"Al0*7"RP>ftCUT6Bo,9]AfsMq3gqhD:>g_B0c?2]U"I/Hm82X9H#e3u"`SZCc)m?e8?DZnp7g9otg`0n96S1$Yhf5"6[JX[cF\d3UmEVcc;3QZ-H.n(CMVQ?u"Cb[m1]8oj<)E/r6!0s<1ZHhq+#pj*^)_odq.'TS`cg*\D_QE\A+rZ4K.Sjf?5k,%RY%EMJc,k/VQtN(G53!:@36\uY;j5VIOH,u)p3,T]H63o`ke\8ce?`Y4nlQdHHE.r+olXcfiI;M_D:D9UohT(3qK?8&F4X6D#2J9cA5Kj`lV'=TiWI6RZDP6D-`HYUT@MXptTCC=/(8t]fDpQnVNIWdigNmB-L<)D;bGf9&*7012bBNPXB2a1L\5^rSA)ChBL2D3tEm`T\fH4$<7#.OAk3O:"-X_.=Q^QnQX10fj&:V#;bUSW5.mNe$?lIMO#,FcVQ`'3iIHPE)@q%(s3pn(5`U?j>49hEZMkp5_m1S;?=qL]6E)H6H69X3\UYbT'^NTF"Cjeg2f?;`f/A"1Br^b%e>s_^fJ7*a=kZ$+qT2b.A0ma?tok*HMe20(D).`Z94CA\BUNV1-mTfKGJ2r6Mc#:*g?)T3TQE&Rf.'"P&o^rph#pPfc!*](V]8&4p#U?#H7sml-!26Ug/!QTR'LrECDYlrXHggm)PIJ6goCD^)^@siEh,^U:#Oqng6*B_A/uR=Pisti\oIeW>]\L9l/=Z(jbn9)rtfVln]^-QiXN>5:4/$j`<4@'[Y/O&p9-oY6Y85Y;/$eDG,UmZeFi3Q1d<4Ni^8P;?oKd7oL)9#;PUbn(\J_kMc6r+\Aa(ctLG-h'/`A@q^JEGEdhPHip`oll/m4i?tP:d,3W%E#4RT2eA=7_IB=Jl;bD)TW*+YL@5dG8pZ-Ri&WW"mHE/>h77X$OQ5"X"d@MIR3f/IbC-\H(i!c_Bo74NfR806#@[u7&:5/@2:,hEf]_;Z5:$fEQ0GP_miT1f;XluJ&#dOJ,&V[a1.o.mh&:$t[dqg/a7EgAEg+nV#+`O^h@]8SnJJ.Q-tkG9?S@O?jY=0I=gAC4L.?E#)`A%Y*f[/kCX5S!++Nb?e`2TO1Ss(T_8CFR96&+[)l$tecD&P6e5P$\>Kku=E'6@0[ekTaS*p?UHA[S?rR%Zgm^LkBE8\,s^a=VFg>Aj^d+Abd+IQ@+29g>%I"B1P`N3b5=+Zr0MX3jeWD,7B4gVr_B"XFGfc/H&e;ST0oi;$[%r*p`d_0]>Qm'1G;eZX>2L?RNejKX]WeD2OahmIq-6&4QHD&8goUm^"sWaeSJ0pPP7K[$:c92)BbU"O__]L2>]G!(ktlGEbrE7R!tPUNUk1^Z`@NaDMa]`bua*QPK=fkLqL)4ecS;M.GfGO(kQFm.oF#Tn)^Co:5g\h@;LocFC1%Apb=+fPnH$q/2P^_<)7aD8eUH,RGb>JpQe'SnE7_?1l$X"rW12fq1C$VUL.N-?%X_T[']'&$j[QdF1'lnI0-oG5J\NhM.ZerZ@u(IBs!jXAnnO*MO,L/M%"!7rmc+e^&4]c?"h`S4Ouh[qfb^5gO)@hrX[8>12GOZ%I]](ZJYR9glSVS`]00QtXBNhf5pYC*sSBgS],m!:$Y@G<:!i@ci.U55SU5k=4gR6sSg$R@Tnd?_;Y/$YY?PU0aQ<+sJ3T+sJ3T+sJ3T+sOL=$W+(p.`8E7p3h@eZrjF!RHgfL-YACTX_@"o\<,:LTU-8k"I3sYC$VlbC#VFsKhdBemR$eWOm.8n!;,sL2YiJ8>R>HkkhEU`YNYbU"RH5&PB%WDfqs9nmsNf`;L?.D_JGuqBCUc-9?$aR9b,,/)"iV"QGZdJV_rVi/KLGFLBsUZoDj.YVQYFaHs87L#%;Gd\;moL.B)Zu17"OW[RTP*d`UPO9iOl/S)ofV1,G8\\S3"FI-2O[g*9s`\slJQ""^e9iJVBLY&_?]9f)MB<[LBEM73.99pm5EI`;eYT`?qVK%4.`%HS]((p$hbS1]48+u&4("2^k$t<=FFZf;2p#g.O&3T9(\("aO&)!]l&\kok$JR*H[nh[*)W`-^`CEOs;=Np"u.%H`gep.3VBC'Y*/\>8H4^*e$bB2O;Udp:(KD/g\08g_eGKV5bYU>Nja$Q4rQ>g98T-\^S,r,O>,A2cMMWD@P5*\aG*N]JILsfmLhgehT#4(He9c)G^/]jm[9+mMWlr#Uh-LMl(!-NK1b[r4S&l*CLJ-eW;KY*=Iq@m^i\r\2W@C+5r7tW4QANfmhLfOEpX:r_;844jN554>(ij+qEmCIH_d@4)]8DaORnYi[1Jo9^Ih$jKW2HWC0-S.RZZm6psF26psF26psF26psF26psF26psF26psF26psF26psF26psF38iWCpEe0^MHJSIl'OPI1VmA25KeGYTPNM8Waj'9pn$`0q1>.%DFGe\=kElah>Ab?bGf-R.'\)lC3`fSMg-*PfnsW(9iU7'+>TDA"Z-OB[ja+r'1jCUi\?6+ZJLL#3-@F0;m>*I\F8%K@3s1UG;\,3jqg*1pT`c#G]1E5PDrIYsE'.g*%$V;a`hd4mkI>pDr&P*Qs9bQ%*"?ap@?lVWR1m%]BI@K9$HO.pT@o^@l48+"]kP",&J8cZOV&0;&J5Te&J5UQZHT&^KOYg7a!\'%'r&f=28ZqurBsIM_Y:ZNeFX!=l?`]u"IfNr\`,oo8+1`N\M:0hj5f@u]-X,Y(uM]b<4d!E=4=3@%Lce0H/9N"j=1H)YMtm6Yq7nm6F&*+Hri#$\l;]Kb4gWh?DNk%8'X4*#c5X9`nIqnD\?*$FeNmoLW02oMZ([cGcPm$TYi_cd>5PlKNQp,?L#`"]md+6Kj[Y@!'_5\NdjTDkch4"B`agioNp_q(-o8E!0cM4KlM)"@d.&sfrCHa+E,]uhd:dtOrP"KqB4M7b*SDCYahtQ$rl:4DC2FBU@_qDi4Hrm)/K>punICOoVNHU'\,ZOkL@d9Aif1r),?!2Fo?2;Q:>N[:hQ7>LL[+XR'YiO0HdiN?G]D7@(XV_-t'[GVn>[H"FML`hqOrkoS2)I2#HcARq)s)R0lb_6_6!/]W-QX.,'fKkpL?5;`I!5MiMd-^62*76UQ1&H#Oo.c^H[pA%R;Vn=jCt%I-q0-O)o^Atq^iIqlg12-4hZ!R2^eP[C-YYE@:p&H4XP'GZ-'lM3C@/HfD*,]eW`XJ*=lbYL4>;[E>qQZkf/YOH/#)4$]gr2&CO:-ld^!RZX*?qd>f2_Ir&kc@8B6QZ'Wkli7_t#DVgL@%l#$qkBAEWmbkMK`93&dip5uVQOL:C(>:Wb;O#?8c+F&Q"!G/c]VQ^QSM\AC1.k/fB+P;L#(A=7$&iHi,falZRRf2OqZk't@rE?tGseKt_#4mDSY\Gf)Z8-[6_GhD&FrPbneeSLquTuSlmEi*$0CbCprXdW=Ah_o0Q_5EM,R)-#^mcX3eBV$]eLQop!j);9p6O:<(BiZ+)fT@trse,G>5O5mrfrC1K_#6psF26psFM1.N>3\g^b5Z/E%7E83Doi/^^KOV)^f2N(RigJ):bgF4`*qDcDmoTYHG(h$h=ehNgTTR6`:m^hoFU`;m7J%=B6`?;?=28YC6%ae?S\GgS+!R0E4'%=H5Yi]_cRYrN+b][Tf'XcMRGcL8]eboRC]X%l[q:62q1p3mSJGXHlIK';#e$j@$#C0h8])l4^kS>Z,fqquO\J6/kKB.4a*ThqNo_#RI\g^a07cV!'TkW9o\0-LiTjc7^4rQIJYC>/j@*F6,c)0WcePpJu@'>[brY&&_J8ma6O(W?%E0HqroU*E=X/R.iEVf0%3^+]S*%Q9BgFgL,$K?5l4*=]fMCbo^'C>;%YVf66D\51=7LOE'=MP5AI^*mt;0:@E3RIa=Y'@[%OlU^%<8QpY2n%J>D.06Q5$20rIkNX3[D]:;!Q#7MU\2)M[s<7"F\K\?*3@ic2M+;k+"'`LAO"EO%YQih>>7ZkIANCi@DJMW)Wr+VFs8-n<2bV/LkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLojBPdp-Nf[-Jj`/Adn%[,a&>URtpSUF3)gB)S=AL:sM4bmNc*lUbg#h%l]cS9jLN"IPbKKe0,&TYBL>4_2"e/ag3U7`,rQ4Re\&)pL3eXq$EdN7p4qUjKdo^K5QqjoeYG4&e$gCsDr&l-i.7Go]6RmqE=3lUdT<3$n*eDFtoI2/6Z[ZGPBaY3sGM&KU)Rc5/(*7EGU]'8.QV2?@0/bb;!kOdo1/TEdO&+JVqDRsgF>9)9r3,SHSPEqsf\d(Sg*lhmt4(@I24*&=]Z.kYQF^&J:PJb.%pi@.["[rF8ZRC!HgNR>HC7V5NV"HM2>2OELKD4bc)^p]S\/2eJ?\<6WS"S9'r8W3)U7mu,"6Z?nNj)g`k5qT*nlu@/97GSp5]VXY4\!V1m\:WAjKeEo6/'o_ZF'Ru"B3Fh2-i669,&&H:4\;N)g[=Q\QBQO\!GIO7&r#jRrr@;*h!bDq'?M8=BGG=#HJtssE6i.%lRjQ)Zq4kTUp/?R4j!#,>bJr>&NoF@grA2Y3LJI?hmpm/7AD]1Ck_Sjej*>?&J7LG6psF26pt#@O!:i<2B.BJPMKrTQCCl9lK`48?5XFgY\rX6T"k?6TrhWVPr)RrMcPDn`P/q>9d+"!q&,Z:TFTc$VMWN<)LI)#3J]h%e'VH-.[fF=SRboR_=j2DcWte=jDEW278Db]:sgFt/8fY.#fEF/=7^55PfFeph*kBE!!V1TR_^"Ea'#[9>K`cOFVK#pjelV^*q,`5>^^qoC?CPJQ70\ZB3/n2\`ff.EAhREoK1&Y[nHZOP@*tUK%34fp;[!d53Ya_Un,&lV3&CYB;mGD\,k![>;*EimFSCU-0!8e6$=Pg#9[!VtQQ,aEoebB"fI4kTjY^laH[*Z`a[P7(['D/NU^mWKMJa\*BGG,G*oS.30C.&[uiFf2!VVoP7V85Q]+@UOfZWMLE"hA7LVc1'Qf*Io2^I3OtKSKh=UZUUR:2;f6<6r>U7&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&Jn@8BXVFeRbJ;:L)Sfpb+;3t\nRYY*72dTf1dZLnaiCie*$2)\TJSokthW9I3[4bb:/VMEe]HuOJEFT9*:b(qOnbhQ-mS^41Uh%blmI1ALu7B11'ij!RB=.qYo[Ar@q/[mc5ZQ@p$7*Up^Iu_J6]1YjZET(KK/Ie#,;/A7(K+#bg)es'M:$/=AjU'[\f1Q68O[%sRd.D+)UiR!$i':(2>$;Y?@SD+sJ4l\:iAA[!P1sI8#$JA@;jt9hd9"B2o]_e$Jo"3]?sf-FCJ&UN28+GZ0pcY2"Ej^:R?)PuQBqK+kM-6^o#dHk)T0LGNW*48^R6n`cW\c#0+g%]O/*npHKmZg6a8EN7dIAtc;RIaS6B$(J[\UN0,U"E%7Gl$&'K&K$@^QVjhdrcL]d\`JtrZ`@=9_FR1]58[#,Xhn[sZU@(Z!!e$O2;iA\Qc.`6@a)?,e9lTgN]0d1N8,_+Sd*S+-ljjZNVuuQ1#Vt5(,^>&@Pr<=(Fud0\=Cs1AJLK;`/]k0.&!QoJ+"PJIL6tP"3!K!22?pFb6>lTN/o"'Z5P&o";OXk>$iIV)VUccf^7#GI+J2=B'$j@k6Mg6=[A^J:'mf.ju\\a*jO/0>&?28WXER""0*@7Z,ElXB1VE[!V_nEO\8D>=Wk-.nfPta#VOM!BSmMQhBqWYNPo_.BEb"AWq,fYQ3jRpmAasdk+4j[o_r2GEul=s)r-),^UHJ/g;c;gdC,laHRZ'/('o_PLkpkCLkpkCLkpkC8-u+AGlP-IGrIo>f::i%X=j53L>21JqMT2hWT,ph?Fd0L%2?ur,%jT_#T7<,uET_2-9%o%-4=Fq<$MY#hp,PbTDFIbC*IY[d4f>KRFW_@JOL4En)!D3']8N1eI&8"bE-"/Hbc.8oP_M(-!45AKVH"F^UE">Gm78YH;]q7TZLEd1/1A\(,PY9QfW"8jo5]e-iD0hk2[Wc_W-(LYD<=P4iTrXtUdsO-Li5JbBCZ0sTW9/HKq0;i^L[+27#ZE3sBcqKQ]qJKhVd;A[pe6&8@?]+hDX@jI5S:+2lZX1"MnpdIK.EJTTnan]E;Aj/iq,G>X$2bj>qd%e;A?L[OB":o<:0f07/rRN;J92Jf9i\/:5S5T+).dZJk1JdpCm%4q`#;"<=D!u$]0YWLh4[r=;$4(Ih^MV46`_,CK$oeArf1,Q:+8C6M0Uice]KIqLbD)OUITAQVf;]2u3>9djpVfOO$qM(VCLMd@<"n=dFF?Ub*L/1StAj"emm0t_Ygj'9A^"62:i_HX&O)9^42HI[=/d5K(0>Aa7:d*p69El,]Rg^3d-*;6^?)_6@dAV*Cp%$-D8413T7r:Vs9;bQ3lYgJ>S[Q-DC?B6AJiK62\iSsB[dH%rlE*>Y`a<,NJ6bs#O9M\4tG.A2#:o.)+=ed_=po\Yb#I.ljGI/n39A0)&XQl`!Af&O6:HXAE^k\:?f:sY34IdeEpP!3Y"A)S)#?9RV/4Wj$UT(*2n]5=!_Nm'dkd2AS`K2:DQ0Y8nB&(J_bYI4T4O@fURa6NCJI(E>'0nXa*XOofp/dA9C5T;k6FBXKB>^KIE>ABqSa1HXFs40gr%+6(*i$j6!X&eohNX84lHtbD5bho&J5Te&J5Te&J5Te&J5Te&J5Te&J5ccEUO?[L24egEMIEFStb&#eXU8"nla3!cqWYC4(8'/lG+dF5En+^Kq!>T7:XMW<#IkUFf)_'DNsLgUTC>;HrIuR]3`oIJdU`)\0``*\8C+(c0Z*Jm!$Tb;HD5fg$CkX,HG(t".J3!Y%Sr0!nG;aE6ZGD#;oNR>VP=Y?;7?J1;7L*/KqNE'VWQr=X[V.D(!=o(dkaenrq3I@V[J2fZSnPh$*KsmM6&`2cI2E%XhflE:%ATVQ>L'S*SrntFl5Abbnj^VXF0e.4DpU)-E"TmN575uqm)q8r;I-X+m5Ur68mU7ID5HA)2"(s7Z.t[\lCf*WoK2r9U4)LpN&Ak.LpZXmRc,")>Yr8U8b&oFY%fIBE[aJW=*bf<)LOsN9,?tVGU`(I]VB`$EbkVe44PiZ-@Y.\Vt4"N'9fRjYXBaTXaC7HOYLjd2%r&A8u\".kQkq(+=upLkpkCLkpk]NGRRg$J15t!6FaNS_b`.jls7c)Cem"'X_ue`pR#r3J>)\OoTO5]*CF3l;pAV(V.=_D?IhIri:p3f?$"3\Hj5Fg^"nI"[m,VcuLA$WS1+4nJ[l=U\H[\3H)l:F^9bl-;_PgUUu>Q4\=-UR9pftScf>.Bu`c8#YQjMEp]Ek/P+3Hf[S\>)fnl][YE7_!IDjOO27W6l_Cjc*QLITmC>8Q*;f&e4:V.MHEZ*Dst3%5W=A2JLD7Y'eeR@f.3I8f9g(Q:1d:>u,?s^#/9#YQt$$8p1[`1lB3ik@:^+9&J`GkB+?7=>jgd<1]#VT]gP*LB5rS[%;10O2g+'!352"lDEr2Nt"9FT4u>cq[5Ne*KK#pB%q@SdkW*FckShYFGu3A2_+k1OBNor)jE`ZRdgt%&J5i>jGkt>,MLQ8-Y1mFTp9AY1PFYaXLU`Ae.>]jGcl'Qr!T-HinY_?*UD3k#?!n#.I&AIi/Xh#Gij`]LW:ZX%VsdF&4]&NC6a6[-%35JB?6mWePT:)Q<7lI@;5Q14UCH]l46^a44QMbT[V#/dk&@jq2=j4.Vr+-XHE/5pG)?rO.1IhjphBVc.Cs_(ds*mJZ&t]oZDKb;[\bsM"lD6&Yk/qrO2Gp#+#997\a%i]))7"',NR#1N:IS`)TQG+B[hPB:bA/56G700A7`]g1U;bj%0mM7[l\GJ_-[s>QeOE%)n2*oqdhU*Q>aMeF$V%#?+4+ie[8:9K%ER\ki%KL^rX&phofpg5hWdBgS[ctBmgnhXQg\T)nNoc2V6rfABUM)fb"fkYXClI6psF2F.1H\iW'($:S:aSTk]T4VO$[faQrj+0-a&dU5*AW3W'Stil$HR:Y?.u==^RHJi7rr?g5L&V-JNVRn':S^-._tlJ(D`Qq;_8#i-i?'++WuXRU*I+=D2R#g?DB-ieL9II%ECu:F[2`ksJ.QW7"-=Nigh%4PgCE+8Ph>2Xm+eGAb\`[?64K49!AdX_5`JGKi_F#&_(FlOD4&14_q5r5r2FRCDjI9>>5KmTP[M(QHDW2SN-Jh:VT"GsAXLhm%ZP6Iqe]%SVG/A#+qrRfPUd`2^J3[ZHF0C13#kZq`>>#:[mu;N\BlS$_..eBgO*rnC\PL!'WGr\@\'5LZ]RrrBXIVe8G<\*Zff!&fu2=I_^BJ(,O>(lDH>Og@D"UQLQHCRTDu,I%L#W@m)HNj.8OTqRAoo2uHH)Z#=nV3$c$4j>U!q3"@^+Q2]bS[Yue=S.*iQ?W?/N'UDci6roohU@qJA,,Un8H/\[+^7cbDl%PDRQ0Agqq8fpnb7XdR_')spT=bDrr>K!rqYqmrr?a^rrD$IJ*98=CJXh6chMW9q.]`g25gDVBDafWr3\WcoK=l-!:qb"rr@t8r2')`dBpC_!6/CG!;O)(!6\^K!*2-rrrBFpq-9NKL&V/5+70C>rUUrVrn"LU*D?B8Ieet;rr?ifrrF]5NL>qlYV\SYks!jn2T`L/l_;n\uJrK1+3G-8Y?+.rrCJ1S(jq"QF@[J\l"%-)QLs>)mC>umS=rbT@$Td9gMbXXsgH&aql/gR+@o']q=fZ?h2f+*tat)E2nYILF..4775"573/\%c[3dd1]\[r8rMp_.]sL_d*U65;,L0[*)T2RkInh#)?B%o.l+IN60WLbQ9:?VL,t9RTq)EY2MHg,@o$S)3]Z)Jl+(u07`S'27oRr,="%JD4$0MKY,(P/74i_g;+I&%[$._ueR&)bDq#+VI?b_5O:-crX(`RV+GMl?#2aA:g,\!Z4\#ATD9^%F]N_Zf>]fBatjkui!8/i9o_b7&n%\`iaJ73>mE.`6;>gZgNL:T:hOcRE^IDPQ$M7O'0=Jk3Hck(2jm\+E`B[e5R>=cJS;4mFQ"AISfMSPTDVKqFM1T9ZM\EoK=a%f6FT_:#439%YS)NQu=nf,M)R",h&,%@,3A"+PP-E(:)Cr&hpGq&8/s,]BN_g:KW/_TMdE7GKAg6psF26psF26psF3A_jT.92h!b<-LCWHKr#YeGd]jp,.Ra"%P.2lh>IEl46[B[r4=1E@C&g09j!eoaHi"NNi5$%-@QedRUrsp%uCPY24;[B"8[`lY\e2IBM1)DM6Wc2sOTmJ2O-F,_pLBJ4G)X?c.!+'uH?kBINhR\./]pbL:gN-+1fdE[+!gqD,jWi-NolQO9CO.l99Xp&'7ce?BX8?>;]\K%jjmdKG+DFj`t?B5J$QRfO$n@^JrQeS;do`e;Xrj6)Z^ED3[5SULA'$6q'/Q&J<<(>$U4j!8N``!/QLFep\k2=?2um`(W*/o64`NT6^i#lco9E+/1e,;q$ubg<6\OMraOJ7Ztel;UN-WQT@*s,Mmb_5["Z8ir8-4H?CpdX$eg[p>BY(9;=Mmr7+Z%@J/JTeahR\FNUU]l3m]RHa\"Ldd)*8^teqiMpn'.TYi!f'35YL!):.Ub1++30)6O5Hd29C2/R2'\YYa-DW6*e+?KQa!RNHVR]S[uC5m\f\4pVE\(",O?LP[!f+6T=92>ag%A/'oT'qV[PX3(AF-$:Mo8%]1dL,^bRWi$%98Ehkjrg_6@WZRIB-(7SQ8#&X)c$eZ:N,>PYha2-GP7KN:k.:*Iu:n@3]3b"64F,*B]a5G:B6s'k[`g*qO@1aMT`*l0n[E.n.tf$2rjPtm"/7=;GgIrarmCRR\Ea6O[`[;p]YkFFCS<(@A\Y[]*>n8\tU9ZC&DQ($U6(RkpU!P;,Y;-&F@K*(t&*^b.8L0fgRuPq)'chj_/SNQ[G*hSKW:F0FnhHZGR&_$/2Rhd-A'mmGALS=BnAnVS%B.F'JDq^.;K%Y&Qg(5DRWjn[2+5m]pc7CbjX-5VSJL).J7IMtc?6]G]Ci_1X/-Q$=>h0)m]"jr"uL`B%]Q#tVj$7C2O><$k]ZYNIbRZ-D^po.D>Jj_[B3q+=O>DV!&ak,U>KKtN*1ZA"UT0ljUi):]L5.U6psF26psF26psF26psF26psF3NgrE*#V@6u"i2^5Y3Qh>i=iukre;iIl1u3FDdi*_g72psV80')$3?9&]R$]ou%p`@a6HB>Saepo=S)t#bCtqPTIt-M'Cg5Q:`:bZ0%B3TUp*_`:E,(rf1ic,&$*BLn7^ULVcB.2?_c8NQI'YUiV'=:bRLP]bgGRpnS/sZ%W@*s*olMgk8r4G7_[^8+^D>J0EbOtX!=cpqRY9*=XD'Q)+pq+nfn/XIE?US78__B5<,+5gFNQTZ6:GR0X\V]L4V<1>Ya[JM?@`KR%'BO?J`GMHC3TUm_R?A>WN%N]RDFisqj]@[rWRkBIQKqqPc"-hSUE8]XQSHn$lu]=E>0^`e&kD%'Ig)h")Q$D@Z:QB9)\;l(/#6=-$+X1iG06`cM]CrTF@EA-(A&aBoa?ru`GjQq>usm^;MlB]8lsHl;Rfh&rBR\[3u`@QH?Un,&JrpH$6gZ<+sJ3T+sJ3T,-\I%%*.a.,a_#B<0c!?d75GC%4j%^CkI1EHB0Z4CcCd`CUPmc1@]:hk5)A3^=&$S\&t9@?L09<8DZ9%grEppDV\:R4Oj#nq:.7@)]D!)H[l*[Yj-Z_mJ*\UIQrZV4P-X!Y1>'Ee^[Z>0uP/0H2WN>&@bthU27cFP+]tXRE[%T8%(+u)@sF-/mX_-EP;-_D+TPN)B"cQ#ej,,3nmTUlJL('Ah5:jElXocb?l8h&6r?hJ-+mn]oVMU:N_GBR_G#!@D,d2W-"l(XEVjA`g0dPb'(1Wo^T/2N=69OGADuk-a0P6'sC&:VY1g)dJt.(gs?.UXn[Dl(CSpN>h`bgf>Idfd.oV>#A\O(*4[7;/sU+Eq3i/#,(('BaWlqEY@H8o>Rtd>mMF:a)@N'#"0!RP^4dBA&4'#-L7/lH)gahlM_YkpMMh6kkGBH=k*B=o8a8hJ/pro"Y/%MbGUDQT"B&_eaLCO(u_d)P5I-,:s>VNq!I_L)F$d]pK`"d"PEVYfB#_bIF,7;B'i2hF+_:Mm"e1\f-T?2`;g<;=>pCE,baO_%G"d*#Kd)>uh2D)Vm(G0uQeX+YpJYS::;MoH]19D4uJEb78ib3F0me94j(IuE078jKt%mX7gEX>KQj!W)("]f9;*r!2/m'p'NUZ`+]\:jB&1Y?1h(G%!bQV"Su&^YR&oF':[uGWr^]aCWl4X*^Jc)TsFB>JItaYrE8n4"-'l;g42s/B(:1nHG-?UF]W+c5lL_7cR\(L=OHogorj0$r`_s!:6M&?i(P&%.Mcbb)1J4/5cK14cU"fLVse[/U+JIRlFPC*$):kBS`m!U*:d*+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T,)c+Ljf%uPP6o\WI$BSRGjZC5P$s(\Sq]4#hKupDQk(iYf5f[sqU%Y:QRQq4er,]:&#hSjWD^VGQ.^(abj6("`#fP_Ac#4/J_'9nGDb?uM;Q6t(o&>Ir9QnDf:31.?AtD1'"#LUNqO4edYf(usm?#P4Lsl+#D>98TS1X\LlW0eSS-gTqGMCI]`n4ndci[YiK-KQN@L'OG\:Hl#8oA$fa3a=PmmF;.\Rc/jg">I-iGk"g"n;L4Vb6si5i)]M-]/-`n+'fdS[jUi)8]L><%iVh])2\gl_[*^k"n^udFn],KNErP:RJSC+.:(CnC%AO#G@9F([_/!p)VI/U$3:s<-4PjVKD48]0L'4O`k16B]=.:F3SRL7d4Hi?5RtRn?=sRc$kUcX\2qElp@1ZV=@O+^crg;5hqCc>>:7C2d

k]I!!BXIhV'R8fh3JCFlhd\%IIqXqm[U>uaTE9Q3'/]X77>+$pIXn5+O^RF4;4O"8=mu);_a;Zh`I7<@ls9BgDtk"DdLU0'q]!TZKj*bWNbJ@_TsN=Pn6g(O3DufHcqOjj]ZoD2PLP;,&`m_jF-Xju8i`G92INc0ROc;W)L=Qk?d]m\uO8C;kIuMR)\fMRDp_UMThA2YB4$AFf>7n$`2+oN#"nBLXk\eDFg!feulIAYH<6>HXiXP#8\c-]lp$-pOI#\YILTF+Ia!!7=\.0Gqm4cn[EcOdb\i!NcL[$P24Gn/A]W-D@*t?*DrTtH)09:Y<%QA13J2RIhN];2(e,`PbgMrUSrQHC5]G(R(n*S1llc"/GU#BpH99.#Y5d^lQG'!2b\CuEK7KW"mKK^eo@=,?l3$DFSG>4(J0Rg>Lb1=+3fmT?>[IIJ?%kiEHTp@:F[*ZK-U)<mY283^m%SYD0\XK\0jH]@U?W3r.%^gkEX[C^H+C&$3N5dR!;j5/SJf1pk+GQh-.Au$Yhe'iYheN>TRPdnbo`GqIXQH+pS7foQ$LOVeUf4jl,,5,`/V/E#pXhY1%c@6K>4918\HXcpqc6@!\6.Jh1$iLIk!;tu?Se:b1/;qMh$qiIeMmaXj=td6XgM33pCfO=Qqg6`#L$&V=/9q^)!#W4$m>YI*(7OI$j\61Wi0D&IY_#)CY*YpR4'8"CNk]/4bXpj'0"iI'dH7"pLN-UtIU"GRLZF\9gNm[n#1mpEAiifg!6eS'Vqs,O,!'R?dF(+%Q'hMnrr??(kPkNB!U91Z:1WYqp.cE$;"5Ub`P_eYUT[G&p!eKjA]%a38&;kX3MY,]C7Vg2OB?B^rjP,tm8gB>9pUYgj'YW43;GYZJjt3*.BWl2FFsqY&DL]71W\:)lXo8T4?j^BVOC[Fa28q^jP"mQ@o.$]c:-Qoe1:Sr./&>I:1a$rk)4RF7E/e:4]Qj/RDM!/aV1q2^rt"c$MZiO"u2%>r&3c^N$hNPMI9Dn(MoKoDni;^HGeErr<8U60>cK#5=,VjZY@;rT@0&n5i&j_=(!jg[0Dnb3FF>btUn:rrCbgeA7M>2fV$r@&#'Vg]6tCk"k"4XVLd#`,sTAZa&>W=DDV^B_`57S%mLOkbCf.M5M0A@ddgQD7522o4Y4ILMrlT3=kL[P^FYLF"mlXlVYTQ]=kq6A,(Bur7+!/_?32s^TqTlE>QO:1lqY:#[4YSVP#2;3cXDn,-9pU3-pcDjohq0fa+G\q=>9K.-*7\n5HlOUR9)134HB)0kpE?`\b\VLS7S_r-YZB4m$o_U'rh%;!Br\YofCN+LNcFC(`\A\Y7BKX;VQf`)`X7%=iUA1-gj`2W:7)QM[]ru+*#aU1f\T7rh1MMtI(&=,%oQ^/8C-63<[MV@Fi@rD?Mc=C_3Mm_U"5^>)"(bp@.0@i;V]s:,uf&P?Wm>paqfk;4c,XDKQ`"Ytl4KjBRg[)BhIJ^YbX5G^LHX`,`lrrg_q=f)G^dbla7iS#2b>o^=$]'_M#r!.IAe%,^_02rQWQr#V/&[^HEi-(S_S,7!`dd_/Ad$RVG.p9/"LjFC[J=D;@-hm%N^=">6fk7@m;AMubm\R"S:pD^MlVTDauH/1bd1f@$Qo3UWcq"_WdYAj<&WAQfBBcs^LP-Rj!\u;>IKh/f,9'GZNlC.NZNK&NK5C!PEhemu2$0l[S!C$Qa,8nQU\$h@+E8&K#FF<'NkJDCgS2)c]NXb!`>^@.OB'Cq6U/'':@Rtc2`[I6*9#A9QoKZP!:PtQWC__0"([j(F/AI)Vqf__m2$qW]S?Nb?r$GueN)\JYN:1Vf1gPXVf>*m=3FGQ&J5Te&J5Te&J5Tk>30b!Zs2fJQO/=Ee?QSf?@<^rkNhbGQ#CCHU2/m5EONauj`B/rL+*&nNF\#qR,=Bc809UonHl%iUR#R4RI+dJ7kt)fH'Kp4CZK8;C^CpI;8ddSWYq@3h19$oAHQ7Bfr&H[gO>@Ai4si22^@<^pPIsV9U.38B/Va:p$sic;pS5.paQAhk%ND==,lt,StgE2UD2r@@9%F3ba@H>^&%g$K8#Yhj$L9lIEltMh>3m@'IB'"3e5b&BjL.Ri2b15_!p9R:*-^$:G3dV"a\ksd@=gQ)X/)`^(gB@p2Mj(EpW4@=C\c8YVgH1+'4*FZlib\L1UP/S0)L,48H'/tL/P7qmn,X7P/rE6bZ0`O"edmUO58CQJLniZHHqF3cYp02JW>nu-k;mrIhL[t!A[+,Z+4i&npo>1hXa8Sn.>HlLhbX/$E5r\(p6(8TLN&X+B/S.H50&5>^9)jsrJ)Lei(--S>>u`(;$U&!Gh.'nr3W)s.!T^tA>3=(4;:cRqWc!'%CDiY?4_`9+=/g^MjE(!Ibf;ah9'nRGbkg9O3piO;Ca:3dddFf'B_!%VoN_me$KGlIcTU@,ur?QR,P3m:HP?oiK3u-8(C_^?\V<,p&X1#o*ak)j!q1DZ"9;E;LXk]q9(\m7fE)\fM].2`(lP.*0E$%D6fl8!6Er`j:V?3]RSd?bB;dA=D`(=Z/\^57c)SAXJ[,J?>,tG2)W763f'?AIG"$TrC\4i"2h0mm/0L)e$%Q_>at`n$-2>'8'CiJIHUq5[<#Ge4BGMu)no72:rh%ScDQ[o#LGla;Lbb^X,Yi=96;-6R8^9]%N?H]32tnUdB*T0XiKY;$niQuWAfhT@N=/*IMn";._:Ksg-+UVhA8CFY&-VsHEWCSWmZ<%Jo:Qn(.1Q$,N6=(*8CJn\I03r'7eph[,'.oj.uE"`?R=qY/4C_@t=LF89^>oqFkY\W\1.gEiM8EB6aDJZ1r]!m-)+9h(:Qi*Gh%reZu@8O0Y?(G`Jb^0l0lm5<$HLr^_UFBY=3QuH6'#T][rUB3mZ!)jhjZ)`?%,&2QKlIP;Nb=W#EGE6Wqo;T]2U_DnRoeC!ncPQ26SNb(r)!,WNUGT%/C1,k?oA`Pi%:AXRSN9nject'ZoAU*pW&oJl4d%RIRX+lB1X6-:PfW&X]>b0A7M;e$:_rVIbpb=@`A]2S#Hf=;NIsp<;O>`Kn5l_!FKa1ZCLr!*BCLWTbli/SXiZM.V[&$Y1*hN+FfU,0b3f7XgmsY4`mNdO?@^pki7qHrmgc]JY<.8XS/%IeU8(j-?`2,6Y1qINO0jZK-V/U8h&o1_NM-].u:23;rqn^BLB]^lJTl\s]ttNQp&GCj^a%K7@9O-FDO,h6uFQe5^UDI(q0F62V$hQLV)oPF>`6gD/@bhPc)'[d(5fNp(Afje\^gdS.gK*SJqc3gj/8A^+W`I*#:k+5tD^`a%`am5/[?RSW&6(E.UK?`[](P^d+T8VBr2g6US@/V_j+4(_j@Xes:]rr;jq@qIUrrBYC=FI+H%s^$#Ojn-3Y1mW")]-rTB\u_NI"]so@D?/$b:3(e_mb?E/?"0]bV!_+k>"C4=cq%tHT60*a8rM`^LC[uD;A::%N?20F,tIXTkq",:YhZpJ]+k+%WdV6ZM\%:eWu]3%B?2%F:pt(7.7_VaVrb27o?c8JdCR,X"VIIOg212d+5Q(eq(%*H3O/FNN])4*U5f4G^7ZL7IqUikoM9rRSEUXB!oK*3qq??Zq*Cd-mpV9\D]e#I$.[7fbQ@+p&>#dY7G\?pjlBrf>_Dn+ut.q(7@GfGL_ur-pB*O4`Ci'nOq##X&crPWp;?SCZWGf92NLdf]7i-_7u@.=2BjmGTQ&/=F([gZ;'mQbCtp=23<1iCPp5l=DcW)F9?3U-n/:p$U:B*!7CQF;++T@P&=7r+sQ=.DH-=VD,&Xo"+b6<+S6eW#4J8\"l?B3JqA:r4S(_CP4C'sV4I+(n\h)c%-.1X>+.Ol$s7ofr$>D+sNFaLkpkCLkpkCLkpkCLkpkg*D4#8A(^e]Eu#*tS=8smiM;aGc#eqY".f>V\_%MOVd7V7ZCk>Wa&?b"(Mnk)CZoN(mg*XhI%e;"mfj;q"=rL_C[H0JG`KmZ,U2$pk6$logrX37opOKQjCh@I@4_2`RbnF=9>[?%85Yq.+ehf\:AhkY(0]uqo3ESD\[G"jRH#b[Q0>1GaZY,Lu-t@-SOVGmfGRge$i&:D+E4tmoG?hDI]7S6!Jf=JVH?`;,&,0OG=;DdC],INQ1p@;@;d[)Ri^D1"$+D@R,-R0Y$0rj)WL"I;aIqDQ>8I&^!AH\W*e$H[2>0/#B8%LkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLkpuZc"l$8p4kNC@L1a#^JPSb,ff7-3'M+("5FCE\s\6?qNkrgNfoKEdSdsg4Z8:N^YlY"HZGE?6s_&]+sJ3T+sJ3T+sJ3T+sJ3T+tG$d]T6`f54)OdKY@V6NXSDI_o3%;Xk3o]`.KF.J8smL8&-J4O.GZ!#S,@IUJdS49)]^dJJ<+]icT-U`B,_LmF11*qFUN)CLsD%%7.th>tEGR[o38fHqTss+/.dGjfi9=*Ce/QQcg=[/@![Ll/+$\Nb"=Rf#R8C)Y/%sF<;7FU"8")Q0-8=\5H!+jV@EMaD'PH9q9fEfRAPArc5\lgj7LZARq+*U15f5-EZ-(@>u4V!!%J>cn:Q/*:YIR"205@tA].PfU_jRD/G?rpUhfD?7$%X=DD%BloHtGo@96dLM%"[YO8c>nIn$'d=hG+sJ3T+sJ3T+sJ3T+sJ3T.kV6a[Fk`'cXt'ugXQFr:K(*@1);V!njm:1^"glt)@$/V,AkupXc28cZF9;AV7b&r"Cp2lqos!&-\'p*o.)RQ`dnheXiAOo(Y*BS\Rc/3;je\dRok[KW5hiP`/pTYEG2'"5L7Rt$<:l>Qa\_bACi5\9\YL>J>^#d'e2\bY]cOT'BK<1g[?!H@;ql"pD">3eb^78'!;,P;FpG&G__+!2p9Dk[<->ETb`&i@.k9VC6O=u_>1\)0UPTFn/I-.EcS-nUQplA@>9*L=8F$@QE=2s;R'aK3Ea7dhibr7@/"4%j;[D[0&\#)d@cDZ>g[G;61a;j-fcqF]D@UH4/Tb(dQC_POIX22?#kT=rm670^+ZRM0F,YspAA/3G"kFS6"C?Kr[,QSI;un2["^E9qc?,If8p/Uh7m3U`=meqpMSNQttq!T<<7]Go?37c+sOS6$?eXs[0uYn6%igO[qoo#ilBM\_U\4)tULn*_l\Sd[pkqRA([Fn],Af=q"6bILpReHVL5;s]mZ*L^-a&=gJ#2G./tp'&kRp*B>7mWLerY-i0+Q:cLP4_Y'#5ISlEgR::G]#2"U)jC3_41_qgcu<*X*?.YHCC/S9DGb3H\o2ptOEMu+'g5KJUc*3V-N5ELMUcL:+sJ3T+sJ3T+sJ3T+sJ3T+sQf\Jf:R5V5T6V75G?m0uItmOg,/P6Mj41!Q)lf#24bIits\Hi"ad@?`0Xq7O_\-1mO8V76,AYgr:G]l,lc?gQ%iAqp]H=^4sHM;jf5GQE1p;+`K$7Y&X-h]J4q\-h!XZga"E$rrA$_DcKimSQ$lb=m?/j4.=N$G4*YiLSs,4;7p#>F+2=RS`Note=4Z,8Rd!.Q.gG@30's0`fTr.1S[Sj^6G;Tc2b-urkis;]a;Ps6\Zdqprs$<^h$I&('/RgfYl$@E(0D\TUD%lH@<$HWu6Vmaq(f]gFEZ>j&"DS8qs`nOj8MN.uuJ7,dT(60M)Co69QZ4U\aaj0`!L;/0[*cH3(7/VXKpSW7K5f"7G,qs7SWk(bo.gl;32c'olbh[MtQOu\dAEYrP*V&ZeXn`]-5%rb"rNl?(nm5,T',cA,e,AbiP;^YkojH7F,EB_'3lI^D2RmtQ#TiXumkai')3o>_)XbHIs`jo8)E3_6dj6GJ,E4*3%oBu-![YTh6C*FiG+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sMtg0*S>fh'h?-6WHE[Xe0s9D1CX,O>l!Z@Whe-X_B/U3us@C8^!-gSdMtQV5f64__VZGA&dnW8D&MW7`qJF_B?k_%4pMui9j(i%>Zo(3,o)k>;W`@V3@unlgl'LC0GC0pB@CR`FZ!G'"ieV;?Kir1\N2?"p3e-#JWualiO%p)Q.P_hX/tW]+LuiFj82%=]IO.+beZlQEus0d/E?m6?_S)eM_52$cNR0j':;12SNp`=gmCW2`-pAb5VHE)u7,=E,T7:>5Cgba2J&J8+n;%XBP&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5UQZ4$:_>$$NTI8,*O4k-j$7en,^RQ_,_L@.;ZgL7\^NU!%0;HGP!6h]rd1Hk_OK9.*3qeo"t#p?$GO8'DS&AOh^=Z-WcN0+B\L1GRK1F'M!U:%IB^dc>>Pg8:cifpup?(UlI;5.<\tQX>?tFWQiac)uDYT.-\%c(!H\gFR7jFtrC:Cqp8!ErbF];@$5`%S'#sa^h*qq_X8E2=,`SiS;DgX8jpUcHYVJS(s4O4/pN*3MiU=.XB5N]oHkS%1Xq/*?DEKG!1!ugkOELS6L"!h<(:VRVll24a@&RmH_*&mBYhhqBa\A7m-sC.XOq&7o_-sBlhsU*mj69D4GK\]nMD)NS%Af3AqX:o6An,Ci-H)I,ar!:VC"S]"1C!>BgQe0t_>dBq!V-LCZnePW4_!K@'(/U+YkgME2$SW;)P8H+Cr_EUP0:n/\$?6&.Aa/b_XPIW14\7Ja/ZCX]H\ne..OtS0Epd9O`:!LE=oo[$3I?!,m\$"Z9Y?5+"Om:!ACmnRV]&,ouEE:u3+ELi4fT2a#g^CkUe#pfkRB1Xe*B"(R;Zh9ECLMrG#3M>Vm!ko"pDa$'O/DgoA:>"=l_hB-Fl)?_Aq!4WN+3cM%P8gYC,Y)6gQm_\$nSa@QX3#>P"G)VlXM2;el(9P@]c?&Nd)maHu^sr[D;Wj\WgN5Z.u^A'9;ZeG*]9X4d')b*:@Lo,]II>5,$4R)u;d/f^6&8*/p1Ab7fMqn/U$i`#cmAGX`u2F?u13oi$UQc=QHPle$j4i/V2s3>57g"(HE5G%P!0Hp=!*8;ODaZ6CJ:+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+tel7qe*t67^HMA>^(RY`F,!t)qE4P1KsAi##\XV3";@Wm^\Z!\IOqZ(\=JIeYH>m,?^CM8sYcd"Ajl5msATUpq.^9C-k\4HpXa>L"L7U3>=(ohTnSEa,XsO?@S>:.YSIhqhepUS7MPna71nB^nbkmAlq<8>S5/2F7_Z'%aOe8Bq>tBr7XS(EI'L(,?2a@$V]<'ENI$!]E,j4C7ORjeQ1RL2*#W@;:m:r()k)]CUDBH$q85R#5e]u)OMHmP1(/j(c\3Tf)s/geAS((-d^Qdctc_nZnIY\&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J9/'F=t)N8P:(@73gWnAFMgKlu5%=n0;r&&4%]&KccUp#@![FDG16N3"*tmJXBGPNS:"#n8RXUh()i6<#U$(Z1%7C^%_1]D<\^d7nXj;*#)6_=\fuGBg)0'fRJM4[ot@ALtrfCf1ABNS_VqD)]0sb)?T<.HkQ[^Tr=RpYEu>^>6A;G[B7/DZk?)eaX$.II]#6,VFniq$Z`MdA/8d@D8binD.CAHY4u8Ak'*^Ff>U_:2[HnB.#<\8LkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLoHa=QH+q]Rd9(T.TlC,TuVAiO%-L!EV]hQo>OEARWetCC.U;c`0HN'ko:VhE`Gh<3EB\gI^Y-i:MHf"9$2s!I8f-HBka%1nqTD'[bp!Ji^Z`1][%nLl>76'4qCk6MU(rcmkN\sO(3q"dW7@4N=J#]3fUTo%JHXLC2QsaUmfu9\p#m(R>*/j.6>E0Og4R25MHR(`VNk7(4(/7nQ5i=0pb?qgRJJ'M%V%U6p4(5@kJ@#BPp;RVlLLR,ZJTQ6Ci!'I^"D6VoHVrbU/73)n1.q-A0A1W+e-*g$g_9C96c51A(=q4q+b@^3c4!^,H-UT;lC",4[*JbZlIBC5`M+q54T$'Iqm8`k)Br[Xb[>o22h#oa&mg#5D^;\h,#5uk:+jeTagM#Q=TnGi;%1H_OT_b7Ur6J9O+G'r&=\VTu,)R_%0oTd]>1(t&3sG>i9J6c1J(rJbXJg(=n$!V;+>a2`a'i`)l8mgBK$5/AhT1M1h.n2Y+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T.k;X(-E5"`m5-_V>ML[F.OqSQ/`h9TiK40]nd.Ha=?Sr"m']`rfkmOn`:EV"5o^>RmR(.r&+!SeBPLRBGfMPmfkhL.lA;,6CfO:hY%/"i@cr8eLFDnJjWf2_+],_RoR;eMFUiKh[T`C=J8>*SYLGB(tKQ.>MgCbY+Sfp8fS,hO)_f0L[?^!\rW=X=u?5]o4tC;Y-)K7UQL>,T'b6:e*F4J+SIl-MP.dsFq95KMrHCsZA6Y-8M+U:L:+Jm5["Vu99,oH[jmgrC0OCE[qYkYa@/H>)'>+9$<3)ApOCV.e)8dZ"lukjWldO\D/,(/#OGbhe]Z"QY_]#g:Jp_I$@@9d6';7#/%0)a`6^l2C(A$qZUmK8;02@'f`6TUEagk0(@3f-SZ&6[_APrUPlRpZ`(4Qq!$(3%Ccf@CTktQ;F2j-Rjt`$/[8T\.UNoQ`NuGK1AZf/q#a:D*U[`&*PqOE$J;?,=g+4T;+5\F[N2Y6Dh>A3Y%@i3I;!E>I);"f+>`7SgRcp#]UX`l)gI,M6fBsm'5O+7\a9b*&cl]9,6%mFb5d^QBY=qj>A83^dd[%7#`A[\Yl3HEskM@@cRCRf2gFa1;eK_T2efjf1Qc[,oj0[k&!`^YS+Iu\*qc3#\b`hl&J7^A6psF26psF26psF26psF26psF26psF26psF26psF26psF26psF26psF26psF2pXW\/?,ke.0H9f*;mA#7@m!W4RogPq$'j%S1^hc79a?Si:/agc3[nJ4=u\LU/@T%U,[r_=hcUp%@7>NAUJ:EY#&Np%PHNid(Uk'$W%+=](>H3Ia6]Y.c??A5u.5fUniU6Bn6b[.%8b[R6,QhG?2u'$G+^J9u#O?'75FqQGFSH/Sh=kkkN%RB//aK-p)aRWp+;h8=hObOEG)bAhg3j81lMT[((#S"iZC[;99C9*208-aZMOb>JHTq<[O8*FjG$)@93cpUpo(=ngb4*eP`lD\Zp\DZs[]?2cJ15#Be_L7SeWdj)uCL^:)otEhCJ7'f&K*0'm@tN^Dmr9=oc,@_"#kmu-JMb.b&$YIE2j%s?;k_"cSCftkYtQS`UZE&U"Rf4<%E[Hl[.:N8Qu1_ddq(\DM""Ki[cO#UhN!r:c11BMAG\>p7_:"C8km:_RcQJTT?/E/7%:!"mN223<%97=tQ8a0]_HXh,2WhZ!0\]rn2*Qcp,qJo@m2]U;t0&P4NXjVWIJ*2<%2&h[W+;J#]h7M3^`7[Tc-ihlF8.1jhqu>!MNn?d`1KWsPZ(X.to1$u>oWi*PReo)e71ZgeF[qs(4q@?.&Oa!4*e:!VGnh5hTQ%ZLV(7B6?T,(`MOh(V%l>([`8/l.]UK9iJnnFEhb^hUe6NSYCEXKC?F:Hd(C,i'4Re]GTK]/NmX//SptPZBmD"pAoOWQJd?Ob"*>Y(-SJe>#r?ab"Heo@L\+O2mLa"r<71AjuC>g)L@=$lCO:kVXm.=M-tT+6LL>VYZjQVgL-Xt??W,5PR0#i#nu^:p*tC8eRGf+uH.A[bf\0\'.>cSb6s3"Xo]hl,3#,PA'S>H)lH*H6bbEItWFRFoQbPgMAGH-Qj%\\J8>:[1fRp*h\CK%[)%EO\:Df!a=QCId6Bg*A3si_2j\WuA`1JZZ,\c'M?lYAQL.mJ,qkAgkE6]&dcLac80t(@Yk05G)I]R/]8L4Ig`^5dhM('VFR97,D9gE,P!JX^p)s9"n)i/LFs/ADL.TY9aJEEEmEHkfHWoQka;a]\h8gZq*G4rS*[d.?Wj\FGoFNjf.ucQfA)/Y?FtRi=]35_1:GMUS:W6XMpsi[aU?t7>"D(aF$b>sXh3ge_BX<-Eilbmc6]t?U;HC$o=1S/(-Wi>9!/X815Pn@%ll/QQ3J1_:V+FC/k(aV!T]??Y10_a6bWNue:FheOgpdS0a7FaPZJ+X,>Glqh:LgMelSTqA\CIh4[?GJ*BJ/R;>gVnhSuqhU8^pVK]+L\E&k=H^SU_-b`!oqIpFQLX:,ZHV0JS6psF26psF26psF26psF26psF26psF26psF26psF26psF26psF26psF26psF26psF26psF26psFBbP!`#am%PQIC;LDaNl\SgP<$2>2cfWp_?^r'_"Ok)2<*b!FlqG$D>K*O>%dH+WLlZ<%dn$SmghP8nc@.3?`:!in-h@`PLprtU:<*q/JeO$:0V(%%_(+e*G!Phf*>U9>jLuYhHu"K[iD]iRTW@pf3>!?C*AaA[=iGccK3i@T&JFRWk@M`l#*jsb=aG@[?7k[Gt'cPO6,[,!-koEDqAFfkS6N%<4FbA;U701E-.u?:dB/RbQ.iOJ1kkgXf=rlkuu*>!ZSV'p@tT47IeTg%A9c.hspQ!*E?!MD*qrenH$]8a-Gc@mQX,6;Hqp[dbrR5#2u=occ`?e7@"=77=e:A%tW#I)5&UimCrW+_0K$YlFBU7!#*IE9X&&Q4f]gJZ4(DNkq9oBJ(/rFMDA.*3=Pt0$f[MZo+Yj7lYlkgq+U+9##>cD>0N9endstream +endobj +4 0 obj +<< +/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font +>> +endobj +5 0 obj +<< +/BaseFont /Helvetica-BoldOblique /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font +>> +endobj +6 0 obj +<< +/Contents 10 0 R /MediaBox [ 0 0 612 792 ] /Parent 9 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /XObject << +/FormXob.3d48064d70f9dd3282a3ec25fafdd35d 3 0 R +>> +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +7 0 obj +<< +/PageMode /UseNone /Pages 9 0 R /Type /Catalog +>> +endobj +8 0 obj +<< +/Author (Prisa Yachts LLC) /CreationDate (D:20260505022642-04'00') /Creator (anonymous) /Keywords () /ModDate (D:20260505022642-04'00') /Producer (ReportLab PDF Library - \(opensource\)) + /Subject (Marine Electrical Brochure EN/ES) /Title (Prisa Yachts LLC \204 Marine Electrical Services) /Trapped /False +>> +endobj +9 0 obj +<< +/Count 1 /Kids [ 6 0 R ] /Type /Pages +>> +endobj +10 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 2765 +>> +stream +GauHMmr',T(B)NcEOASGF][(`h_XVs8'%Lf/V,HLFX-FqbSY^TG$hbhBa(Tp4TA2J_hnL]NiQT3PHpX8Y0S6-Pf1el/Df2O!ihMQpoASjQ9hYaQ/OW(q[@M&_lHp=)61MQ^5+spH-ZO(q4$C\$Ed`Iqo4;9o?9p4phrUB4j/@U7Z3ZhZ;o1Sj4RJm]JrV8RJc41Y.0[9&81cq'MC5^YBMsRLP_N`T6.);!rh@TIK%gB*N!O76Q^`$6Q&qqIC,Otj`Ote,`obJ6:qFY7TLH!'$F2O#)//%'H6D=,d>;]RWLhoc6"q>2crr0VH;IC?EYY-M%.meXV=t`f`NZ!Kp3_JLb*9i$.n4*r&V'tVdE)"LHR#'c2V(]\RC^prA`Fq5\2gg)a(NsgWc0J$Xj3FRuK%eiq@i;2SJhH$il>YDmMOUAp@,:%iB\0phQ)cci[\Lhpaur/O1':q=P/FL4#3rk0qFs3-b./M3>B.5JGG?&9scO93cjJ$;QWJ&^!e6f@=N_EI!,_b,'&dIfu`H+C=M;OpBGO#!XSSg"NZYGKt+2gh_u_UK@4Jlb1I"49`=HNIC#`MREWM0k7j/3n'*e4$JSqWY@64%Y`nIY`SC>s>X-"rC6XU*+*,0_QNZb)(8B*_CJO%#+,b>DXE!VG9?LU,Tp_)Z=8'Kg4EI6JmRWp!%#.mmB9jHo>>bSj0sU:TZbTVc(3ZgM?JE:p@fq#mFjH7A2sQ%LcR,Ne&k#1oQ3Ei'U(dnq-@oRX:VE:(Cnicq1X`Z=jM20YeuP7NX8H,"t<5T5+Lk?q.oh8gl*&U\[6+WjbB*+RCN+?Cqn-(LcAD\\FJO^HmDg>tQo"Ttj<5:-tuk7CTh93`5rT)DAtGa/.u@7GQ(.Vt&M(lj8S9M5;I%K,U$-U1()?TqiF^M@,A:gkD<9'^@)U&F=GeoQ*_`/ql%eD5G$u@4Se]jOrs1`lA#XnDWf52K[`Sl=iHG?]=RTjTGdOl^La8T0-bj]C:0p4scL\>RJhE@qJ?M0^O+'a%O>B!QF2rk"la$rJ0M3(,AU-SttVJ[Y[83[Fli'cop#6DlJFRBCKjS`Gjd4G+uDZkOKOg046TkqBE-9!>k_)?il\*0cKk0&c-KsAhHTkq="VC*!S"A,uql;-@gJ,2RZ"'__GC&L3sCgn+5cSfUbs+[:$Va\n/Yp'k.XjL<\=:G&'-KJkKP/0pW!Zba$P@h^FDXgdPr.g(`jd\pJ5@">'pfWYhn_89V--W&Let;*r"%<0oqCb?\XIg5Bnd#+Eq>9OM8fpX]24WN6FurVeJ735HHtWnMdO9E\=C4uOe"5>(e6B5]Q#dQ2L@VbT%>.qXa=cm3RD^^[Z]ECUC5:JOr-LBp_b4k@3"#nWQ;Z:[)D)GXW"O@B:gn$NO-0X2/0"41[tL50_4MP@?3BJH'[u?%#%:8S<&lfc/nu]q)""dPLfT?e(b99,?;-"N)&aA'-N.c@TJq51UK,LNB`;a4V2NQ3>n07riROXS;HDmmiH&nQ_mBQ5G)Z(O@2t;fS;&8e,nRC!/jpl3*Q4]8K>L*]I^@,C/SlXn]_$i8uh@_/iHn,6<%S\N]Ob8@R!/mJ%2MVTtX8Y2.92o^.gFU:s\`C#]1SWI1QRQrrJZ,86u~>endstream +endobj +xref +0 11 +0000000000 65535 f +0000000061 00000 n +0000000112 00000 n +0000000219 00000 n +0000045581 00000 n +0000045693 00000 n +0000045812 00000 n +0000046069 00000 n +0000046137 00000 n +0000046466 00000 n +0000046525 00000 n +trailer +<< +/ID +[] +% ReportLab generated PDF document -- digest (opensource) + +/Info 8 0 R +/Root 7 0 R +/Size 11 +>> +startxref +49382 +%%EOF diff --git a/prisa-yachts/brochures/PrisaYachts_General_Services.pdf b/prisa-yachts/brochures/PrisaYachts_General_Services.pdf new file mode 100644 index 0000000..eddba84 --- /dev/null +++ b/prisa-yachts/brochures/PrisaYachts_General_Services.pdf @@ -0,0 +1,97 @@ +%PDF-1.4 +% ReportLab Generated PDF document (opensource) +1 0 obj +<< +/F1 2 0 R /F2 4 0 R /F3 5 0 R /F4 6 0 R +>> +endobj +2 0 obj +<< +/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font +>> +endobj +3 0 obj +<< +/BitsPerComponent 8 /ColorSpace /DeviceRGB /Filter [ /ASCII85Decode /DCTDecode ] /Height 454 /Length 45172 /Subtype /Image + /Type /XObject /Width 476 +>> +stream +s4IA0!"_al8O`[\!<<*#!!*'"s5F(38OGjP:f:(Y8PDPQ!GM6!#0'J=]te*!@RpJ!#/mE=]te*!B^>^!#0X!E-)'[!Diar!#0HQ;F:Ea!Fu01!%;JZ;F:Ea!Fu01!%;;U;F:Ea!Fu01!%;>rEc_9]!K7!Y!'G+7F^kCOz!!*'"!":6[,=5:jTb\Ij1IGVlJs)k5dhbq`PEis11h3ht_U!WrH(zz!!!!$"Tef2!=/YC!(.=u!h&@P]s+;-c'\\E9_]>%X9Jr:t;f)eCgC:@#e=#c_ur/Q.p52k6*7M1Gc.j>N("^q''j`D5D_ee9rgRSE&U;(H>kZTC1YQ$s3>gqhQTh+EBPSOL(H?pF=]+07_Qu4Yd@%2j`Nc`33*^K*g.Z>>>2!pSSr]dNF#7qlJ#m-FfKIDN>$%[`5*"n[K2XK#T-E`af!;FgD>@]EE;6"dQ9BrGE:n"&>pUII[?-`\0plq3IND)t(GtQhhnr2l`@b//^<=I_Qt*X;>s-IA7!`$j3PWT'IFWT&N,U4%$'SXLcfRGSO8K=mMmu=*#@Hra'9\BRr^PYerBOmZKjsPCDYSc0ZWiZ&"B$DIAC]Y;/e1cR!Z-SrP(NTLG8Y\\EH82r(=A_eYN*pA1;55B7712lH\'KoZ;l_?B&jG7\YF0MEYcdh#-V7sFOl>ELhgRfK/@]Aqb.c\#?/&`J&uLohDr,ihe+"1-h-`ddN0KTHaJ^=[BO51EuB>=4j;V^bM0ZDc98t#1')<$pI]j7:8N'[3T`;'!!ds#nj\8B6pt2d,Yc*#!]M.LH`rmqLN)j]f8WYPBDr9UO-5rsY6%nm[fb_j8&+4LNrK*Jd,uI0.nodE`5\J4I!=QG]pRk<%B@Q+RT^'N@@>?;Ng?BqbfBlFgWGM]J-"QqmWUaX]h:WeVE.#9*tub*k6@D-m33b%=X#%6+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+tQ@V51FE#9__t`o7:I3/:Q\bIA43^ZJA@@-P3ts\a=3mg!/E9F_M*CZ1#T&`&:fp/_iSVh>Pc$]XF:JaK&n.dZ`(cF](3lG@;JH^IC3Ob"S_n%oMEWZY#8Jj7>kKrrDmfa+*2SRFXMAca4cX\7s6_g)WJ%THW]DG;.Q6mJ/,`q[Rl+!SI,L&3t1WFBErJ2)Lk.pE\LbQ;G)Ql`Wm9[CtP@iX@TpmCYZ!Sa6aM""A6%oi.R^T[D/OPn-+&Ne*6U`cPqhp+gH<;H2+/Q9uVk!1K,`iGaU/TO+?:+sPHbM=1gZkXS]LV;c[U.h9m;P,5:;Rn#heqpWC1UK[Woede83BH'FM@&%T`Zp,Pi-V/1P=-'`:l/!2CQ*P1";G2uMp3Y42eN9q&2TV[F"Ka3dAn?1+fB6q,:uO`8oR;-N1`/lsO4Bk]"?I.\/snAsUKTXiBiO%-JV8LL/3F"@RV@odX\+LO8f^i"^)rr\[(C"LpqJ,l6bl\5kd4D>1+E>giF,K5jnBS:JV:fq0!^@aE(Z$AJ+3\)6\m'BqFG;.]VfXNp/Eikfe.VV4VR1)bfuorJ9`FnJg;oh2m@MB"Cl@\2!m*?9*JCj>7*VRpBP^YatLA8DYEFg842KKNqmPHr96(81k"+iNMN2?<^GN=FMKoO(Qc/:@`4:^BOla65QthG8ib>*aL%Q/nZ7)G]Hf"K$[B0OO8Nd%UeR6'tBX$f+HrG9'd]3/%(-,H9c`XYC/9nEWT#A[16WG9=E;@Et$4Dd3`dlYF9uDZPB_U0#go[`GDiZ9O!Vg_b.s75%<.cu0nfK`GHU?E./7%63`+OiWI^rBe1maZD:F3&\NXK.kN/-+t5FW)KF/!q-TP8IRmJ8\O'%W?d+a-ulMY%I'6psnU;%XBP&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te(*i>S`g089e5pVL_R:0&rr?"hF)0lWrrAgq?ieL9hn*(T\!V4'Un]e%QrNiLDF^8f".DI:sIPh9rB];48*_b(cl.c!>of^UTBl)/\>T++(^&8#Q2^KX3pDp]ck85)7$i.K5L<@XWcX=aCfdho]W/\F4%)p7pq)@.a!$:B;]].c@##fP6Tj$8!;q6(^sHPM^BLoV;,"8lRlK]jHfC[^Xnm2o,ae5_M.!7%LV/iZP@poW$.A(RCp]-Ohmo%7ktO*N/9,HDoq=2OM.HTja5B)kssppa=&7=])H4_4*#:Aj5lAWfOfZ&EKP%WdKj!"M)UFm<=k%Z=IBT=Fh5a)VVob%>XNSrU]],AEbmo^dtKht;je!Vi]r11L_fJ/a+/U;GpPlVQFAQ!NIo,pW.*W?`mN3@>^uXl"/CqIU\Ws-Z?8Zl%Q:iiYG'.IEtuNu[bYVoQs&Z$Lq;U>]PcB`F$.QiH%=[@kehTs&JB7Jim)LZj%&^@r%g(8el]4>"]/a730q9-)FKobKS9!3$ot$2b)hmNr('jV[EW6#7XcsNg267TbiQp_]jL8B+E,0C=Y]_D'['U:t5eNN9VKn1fWgF``KLA69oaqraCUeQ4/'RddbPbi$)CB)_kMf%lhq!8#GEk-XTI@=#>Rk;a;o1m]_Dq$koXm-8i^oeHfcq4/l]GF-ehICIt6b;d!fip0NfERCe7--3Sme;O(SosHYVQ+$R,6TLm/r8k+liTNXe\q5,/F;o+DCe?'L9\)!t#i[im=DW+a=%-cd#,"u]St"ChqWpE3MbeSSo"NLoN3]UQQ:J/;7Z[m$1cTUDi3E:^Mk2m`NYq6UfkpXMA@Y,0[Du>i66@dBZ'?t`_1hFc*n/3]Z,^KpH1oq'DL&2=P#q[P$\bOg/#tU)[1RRrQW/C]=AJ(J&,3AQ5o@"D?C=i5$omI(9%D`>#U8g[7TpdLt_\:@KeP-9[XJiP"7&lZM4C:cY8NTW2Qk1(T:L_HMEjXJZ\>N,3>Ml:nDlG.a+BcdcG#FfWIP7^m!)nF;QSNNSduebIYQPuDPWAjTbkrfhoSCIkt2%mrO:2UMr^lkk/YR`Wm1S'8an=8JGAtOlH"s^&*6BiL4Fb56`kbf![94QG.CpJ.ahKjg+FDd:SGmelhmEi=^afA`e.jI^rYUhlB-$g7eNHns3i=B6Yqc-aOi$9#kc3V5S1BaVoM]1'UG7OkIRO67U._UMK<[`nPpm&j"_M,%r$Ok8Zp*A[>'L3``ht[$bZDV$G)8V.gu^7&5!AG9&cU`N:.c!o;05]F&WP_tB=Y.pa)ZOQ9)oHWEFXV.E(pZ>K%I_ng1OILV5GRr2JT-IhPHiI27XoKn`:J%)hRVJd/M9=*L"UnrUNH?qf3jD2;r5Lr!XW,#F9/UU2&FRLs(CshcZZ'H1U(Y;t)FY>Kb,>O*U$QZ:J4,--g&'#Bqo@k/u.+MO#nmPOYJ``j$Eeaa@1@6['f%4*m[jc/lcVm1_0Qb]s]687HbgP+J_eu,,EsA4n7o@;:\hRjVrr>NnN@D40EZ6kT7;YBrhUPg$cVZXAB1V1s%qbBn73eo@Eb@OAg_N7o;%XLXe3l\m6psF26psF26psF26psF26psF26psF26psF2>W%e2G5>o'C[0lUVhf7:ZUbqQ%uG;i&Jm3[\>e".m2"[<4OhPQK5NSo9DsG&![Fb6c%ZIbH4\b@@3aB@PcCI<.l=QH>'P29FOJUaqi0U`o0C/X&llg2cN=J:!-GJ#]D?HWQ5mSJF7!ss"l\3)Nd_U#9ob!abFYWA[^.=)Dq/a:=3BrVb9:h?,'/fP]O[A4;J%3Cdqn&J(Z@01%8c!NY4%<8O$S68CT1S$p$s`>&,W;&G;/4&Xjd)Uha"l<^a\T!@,Ngsli,o9*+*9Rbeqk=6$\`)-u=LjYT:5"h4Ed/@M*(gg:@3a%_YPgR+.obP_Eo>8Oq*@"`i&'1"uGV!ZJkC9@]ik.#[ZLfZDHJ>7lh.MoLV)dY<,c$*E32DdqWQFKQKtp7l3urt-2q_O'c@2BtqTZlHYYer<[bJeRP?DF7[G(%jdaK,7G7\*anN6m:U]]TFF%@DckTCEK4dG1gTfm8T':A$Q_T]>j_9\G250GmUdKQ>#fEf#I4p'S$_OgA$[^>nQWFujF?AH&\5sEdGAqQ92QckD`ghdUN#!"7nF!A*VukXdnLb/XW+YGMl$1XQQ)bQ%?Srb[Be&d@k=O',sO>uQ*1]9%8*P+jSDT/=DgiEqSN*aL-WT`WO\W'Bq@i>d*-h8LWs*cET4O"C3?\;*Plu$^L_]*QQ%F5[8sif9m:5E\;AOkK^O+l5TPd.gSp/ho$U%YmB-&j*S6VY`p7+B>M^t)]JNsaGR[tPCQhjOeI^3aBs#fA>-gh3*cs8jS,%%]V=/&bZ\-%&kkFPNg0'tD9bg%[jFPb!f9iAgSh`e5Y1SlHlujX&[Y'9O+"/ujnZ/;GY/sb2?L%KtVW1keWcKNK!59dP>f^/qG:mB/8TT_OnJDP.UtGVAe=Rroue&6g]+^Lp-Cf^B)k"`:;o4r&3a7e/#"rFFn\-e'+&AZXVADQ'S(COJ$Nm!e>E6_*n\)#??#rq!T(Fd)$t.e,N6L0FXB>ZZnmC*Fk(=e[)a+sJ3TG=4hr?@Ch>@O/h1tNsVS]iKDrTfAt<6UQVdOq^3pN;$c7FNLa65b_@aHm+;PclErLi*'A+Rp-WT:2<-qOXAIr!E`'Y!K%2_I$U`aopV*>a:=;]9Dor*eH4K$(m2"4uDmGHl!Bg.\*8J_-4rHE[L1hpJf/ljuES7E24doSSQ*Z&cVQ+I;aU@2Tm^Lu6SB%9X!_=8m]:1,;bEH*Y0DOYcMX,)^LegZJ78V+aSho'dObC-e57i!=G+iRZM/'Y0rfORg(r+<5Q2H'nGC?(N9[okWXZUEe_@>=\3LdCT9YiHF7'Z-k\-l\!bYO[gC.h==K!O,g'3j:>e5+@%"1IHER=fcu;lgWZ4bL"s;A`C2=V3[!e%7D+t?>nIZ:]ib*K*uFWG)g*qE`cVXq]0V0_9U7/e`M>PXJubASic?'NSZi:DhirkW=s(oVg%L03MW[E(EjjN9>;GitYD^#1HMBa-=+*a?<$Ar8hJaIX$KHBOu$%OQue]HHeUQQcl)*Gqr$$OiP!">tdiGbT0eWF+63Q\,M>5l%H/SG:mBtO)g:@%^Om,/d_s^)m'Q4cIl>(>od0DSt;Y_"HgqJJ1Z*f3]WuI5og4]SQ%$M&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&TQ=Mdns%:=]nTA&4"9//@%5mOg1[*3Q1Oi!(eIKE8<.4gE!T&o6IiEd*PV+qO4FaM$.fc'*30GpH,-R!$mcT!4@HNnH2GD/]=KTL0SXPQPe.#H)7OARBQ0rnn1l2EZ,tN*ad%/iQqg%k*Is,D^Q3EWPf$t"PF9RE1Mp<

&]rN4Vm?1Pnk/A9,=ps1[S9>"kE?t9(Q/#Ir^^l5i]3T+71m;"Al0*7"RP>ftCUT6Bo,9]AfsMq3gqhD:>g_B0c?2]U"I/Hm82X9H#e3u"`SZCc)m?e8?DZnp7g9otg`0n96S1$Yhf5"6[JX[cF\d3UmEVcc;3QZ-H.n(CMVQ?u"Cb[m1]8oj<)E/r6!0s<1ZHhq+#pj*^)_odq.'TS`cg*\D_QE\A+rZ4K.Sjf?5k,%RY%EMJc,k/VQtN(G53!:@36\uY;j5VIOH,u)p3,T]H63o`ke\8ce?`Y4nlQdHHE.r+olXcfiI;M_D:D9UohT(3qK?8&F4X6D#2J9cA5Kj`lV'=TiWI6RZDP6D-`HYUT@MXptTCC=/(8t]fDpQnVNIWdigNmB-L<)D;bGf9&*7012bBNPXB2a1L\5^rSA)ChBL2D3tEm`T\fH4$<7#.OAk3O:"-X_.=Q^QnQX10fj&:V#;bUSW5.mNe$?lIMO#,FcVQ`'3iIHPE)@q%(s3pn(5`U?j>49hEZMkp5_m1S;?=qL]6E)H6H69X3\UYbT'^NTF"Cjeg2f?;`f/A"1Br^b%e>s_^fJ7*a=kZ$+qT2b.A0ma?tok*HMe20(D).`Z94CA\BUNV1-mTfKGJ2r6Mc#:*g?)T3TQE&Rf.'"P&o^rph#pPfc!*](V]8&4p#U?#H7sml-!26Ug/!QTR'LrECDYlrXHggm)PIJ6goCD^)^@siEh,^U:#Oqng6*B_A/uR=Pisti\oIeW>]\L9l/=Z(jbn9)rtfVln]^-QiXN>5:4/$j`<4@'[Y/O&p9-oY6Y85Y;/$eDG,UmZeFi3Q1d<4Ni^8P;?oKd7oL)9#;PUbn(\J_kMc6r+\Aa(ctLG-h'/`A@q^JEGEdhPHip`oll/m4i?tP:d,3W%E#4RT2eA=7_IB=Jl;bD)TW*+YL@5dG8pZ-Ri&WW"mHE/>h77X$OQ5"X"d@MIR3f/IbC-\H(i!c_Bo74NfR806#@[u7&:5/@2:,hEf]_;Z5:$fEQ0GP_miT1f;XluJ&#dOJ,&V[a1.o.mh&:$t[dqg/a7EgAEg+nV#+`O^h@]8SnJJ.Q-tkG9?S@O?jY=0I=gAC4L.?E#)`A%Y*f[/kCX5S!++Nb?e`2TO1Ss(T_8CFR96&+[)l$tecD&P6e5P$\>Kku=E'6@0[ekTaS*p?UHA[S?rR%Zgm^LkBE8\,s^a=VFg>Aj^d+Abd+IQ@+29g>%I"B1P`N3b5=+Zr0MX3jeWD,7B4gVr_B"XFGfc/H&e;ST0oi;$[%r*p`d_0]>Qm'1G;eZX>2L?RNejKX]WeD2OahmIq-6&4QHD&8goUm^"sWaeSJ0pPP7K[$:c92)BbU"O__]L2>]G!(ktlGEbrE7R!tPUNUk1^Z`@NaDMa]`bua*QPK=fkLqL)4ecS;M.GfGO(kQFm.oF#Tn)^Co:5g\h@;LocFC1%Apb=+fPnH$q/2P^_<)7aD8eUH,RGb>JpQe'SnE7_?1l$X"rW12fq1C$VUL.N-?%X_T[']'&$j[QdF1'lnI0-oG5J\NhM.ZerZ@u(IBs!jXAnnO*MO,L/M%"!7rmc+e^&4]c?"h`S4Ouh[qfb^5gO)@hrX[8>12GOZ%I]](ZJYR9glSVS`]00QtXBNhf5pYC*sSBgS],m!:$Y@G<:!i@ci.U55SU5k=4gR6sSg$R@Tnd?_;Y/$YY?PU0aQ<+sJ3T+sJ3T+sJ3T+sOL=$W+(p.`8E7p3h@eZrjF!RHgfL-YACTX_@"o\<,:LTU-8k"I3sYC$VlbC#VFsKhdBemR$eWOm.8n!;,sL2YiJ8>R>HkkhEU`YNYbU"RH5&PB%WDfqs9nmsNf`;L?.D_JGuqBCUc-9?$aR9b,,/)"iV"QGZdJV_rVi/KLGFLBsUZoDj.YVQYFaHs87L#%;Gd\;moL.B)Zu17"OW[RTP*d`UPO9iOl/S)ofV1,G8\\S3"FI-2O[g*9s`\slJQ""^e9iJVBLY&_?]9f)MB<[LBEM73.99pm5EI`;eYT`?qVK%4.`%HS]((p$hbS1]48+u&4("2^k$t<=FFZf;2p#g.O&3T9(\("aO&)!]l&\kok$JR*H[nh[*)W`-^`CEOs;=Np"u.%H`gep.3VBC'Y*/\>8H4^*e$bB2O;Udp:(KD/g\08g_eGKV5bYU>Nja$Q4rQ>g98T-\^S,r,O>,A2cMMWD@P5*\aG*N]JILsfmLhgehT#4(He9c)G^/]jm[9+mMWlr#Uh-LMl(!-NK1b[r4S&l*CLJ-eW;KY*=Iq@m^i\r\2W@C+5r7tW4QANfmhLfOEpX:r_;844jN554>(ij+qEmCIH_d@4)]8DaORnYi[1Jo9^Ih$jKW2HWC0-S.RZZm6psF26psF26psF26psF26psF26psF26psF26psF26psF26psF38iWCpEe0^MHJSIl'OPI1VmA25KeGYTPNM8Waj'9pn$`0q1>.%DFGe\=kElah>Ab?bGf-R.'\)lC3`fSMg-*PfnsW(9iU7'+>TDA"Z-OB[ja+r'1jCUi\?6+ZJLL#3-@F0;m>*I\F8%K@3s1UG;\,3jqg*1pT`c#G]1E5PDrIYsE'.g*%$V;a`hd4mkI>pDr&P*Qs9bQ%*"?ap@?lVWR1m%]BI@K9$HO.pT@o^@l48+"]kP",&J8cZOV&0;&J5Te&J5UQZHT&^KOYg7a!\'%'r&f=28ZqurBsIM_Y:ZNeFX!=l?`]u"IfNr\`,oo8+1`N\M:0hj5f@u]-X,Y(uM]b<4d!E=4=3@%Lce0H/9N"j=1H)YMtm6Yq7nm6F&*+Hri#$\l;]Kb4gWh?DNk%8'X4*#c5X9`nIqnD\?*$FeNmoLW02oMZ([cGcPm$TYi_cd>5PlKNQp,?L#`"]md+6Kj[Y@!'_5\NdjTDkch4"B`agioNp_q(-o8E!0cM4KlM)"@d.&sfrCHa+E,]uhd:dtOrP"KqB4M7b*SDCYahtQ$rl:4DC2FBU@_qDi4Hrm)/K>punICOoVNHU'\,ZOkL@d9Aif1r),?!2Fo?2;Q:>N[:hQ7>LL[+XR'YiO0HdiN?G]D7@(XV_-t'[GVn>[H"FML`hqOrkoS2)I2#HcARq)s)R0lb_6_6!/]W-QX.,'fKkpL?5;`I!5MiMd-^62*76UQ1&H#Oo.c^H[pA%R;Vn=jCt%I-q0-O)o^Atq^iIqlg12-4hZ!R2^eP[C-YYE@:p&H4XP'GZ-'lM3C@/HfD*,]eW`XJ*=lbYL4>;[E>qQZkf/YOH/#)4$]gr2&CO:-ld^!RZX*?qd>f2_Ir&kc@8B6QZ'Wkli7_t#DVgL@%l#$qkBAEWmbkMK`93&dip5uVQOL:C(>:Wb;O#?8c+F&Q"!G/c]VQ^QSM\AC1.k/fB+P;L#(A=7$&iHi,falZRRf2OqZk't@rE?tGseKt_#4mDSY\Gf)Z8-[6_GhD&FrPbneeSLquTuSlmEi*$0CbCprXdW=Ah_o0Q_5EM,R)-#^mcX3eBV$]eLQop!j);9p6O:<(BiZ+)fT@trse,G>5O5mrfrC1K_#6psF26psFM1.N>3\g^b5Z/E%7E83Doi/^^KOV)^f2N(RigJ):bgF4`*qDcDmoTYHG(h$h=ehNgTTR6`:m^hoFU`;m7J%=B6`?;?=28YC6%ae?S\GgS+!R0E4'%=H5Yi]_cRYrN+b][Tf'XcMRGcL8]eboRC]X%l[q:62q1p3mSJGXHlIK';#e$j@$#C0h8])l4^kS>Z,fqquO\J6/kKB.4a*ThqNo_#RI\g^a07cV!'TkW9o\0-LiTjc7^4rQIJYC>/j@*F6,c)0WcePpJu@'>[brY&&_J8ma6O(W?%E0HqroU*E=X/R.iEVf0%3^+]S*%Q9BgFgL,$K?5l4*=]fMCbo^'C>;%YVf66D\51=7LOE'=MP5AI^*mt;0:@E3RIa=Y'@[%OlU^%<8QpY2n%J>D.06Q5$20rIkNX3[D]:;!Q#7MU\2)M[s<7"F\K\?*3@ic2M+;k+"'`LAO"EO%YQih>>7ZkIANCi@DJMW)Wr+VFs8-n<2bV/LkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLojBPdp-Nf[-Jj`/Adn%[,a&>URtpSUF3)gB)S=AL:sM4bmNc*lUbg#h%l]cS9jLN"IPbKKe0,&TYBL>4_2"e/ag3U7`,rQ4Re\&)pL3eXq$EdN7p4qUjKdo^K5QqjoeYG4&e$gCsDr&l-i.7Go]6RmqE=3lUdT<3$n*eDFtoI2/6Z[ZGPBaY3sGM&KU)Rc5/(*7EGU]'8.QV2?@0/bb;!kOdo1/TEdO&+JVqDRsgF>9)9r3,SHSPEqsf\d(Sg*lhmt4(@I24*&=]Z.kYQF^&J:PJb.%pi@.["[rF8ZRC!HgNR>HC7V5NV"HM2>2OELKD4bc)^p]S\/2eJ?\<6WS"S9'r8W3)U7mu,"6Z?nNj)g`k5qT*nlu@/97GSp5]VXY4\!V1m\:WAjKeEo6/'o_ZF'Ru"B3Fh2-i669,&&H:4\;N)g[=Q\QBQO\!GIO7&r#jRrr@;*h!bDq'?M8=BGG=#HJtssE6i.%lRjQ)Zq4kTUp/?R4j!#,>bJr>&NoF@grA2Y3LJI?hmpm/7AD]1Ck_Sjej*>?&J7LG6psF26pt#@O!:i<2B.BJPMKrTQCCl9lK`48?5XFgY\rX6T"k?6TrhWVPr)RrMcPDn`P/q>9d+"!q&,Z:TFTc$VMWN<)LI)#3J]h%e'VH-.[fF=SRboR_=j2DcWte=jDEW278Db]:sgFt/8fY.#fEF/=7^55PfFeph*kBE!!V1TR_^"Ea'#[9>K`cOFVK#pjelV^*q,`5>^^qoC?CPJQ70\ZB3/n2\`ff.EAhREoK1&Y[nHZOP@*tUK%34fp;[!d53Ya_Un,&lV3&CYB;mGD\,k![>;*EimFSCU-0!8e6$=Pg#9[!VtQQ,aEoebB"fI4kTjY^laH[*Z`a[P7(['D/NU^mWKMJa\*BGG,G*oS.30C.&[uiFf2!VVoP7V85Q]+@UOfZWMLE"hA7LVc1'Qf*Io2^I3OtKSKh=UZUUR:2;f6<6r>U7&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&Jn@8BXVFeRbJ;:L)Sfpb+;3t\nRYY*72dTf1dZLnaiCie*$2)\TJSokthW9I3[4bb:/VMEe]HuOJEFT9*:b(qOnbhQ-mS^41Uh%blmI1ALu7B11'ij!RB=.qYo[Ar@q/[mc5ZQ@p$7*Up^Iu_J6]1YjZET(KK/Ie#,;/A7(K+#bg)es'M:$/=AjU'[\f1Q68O[%sRd.D+)UiR!$i':(2>$;Y?@SD+sJ4l\:iAA[!P1sI8#$JA@;jt9hd9"B2o]_e$Jo"3]?sf-FCJ&UN28+GZ0pcY2"Ej^:R?)PuQBqK+kM-6^o#dHk)T0LGNW*48^R6n`cW\c#0+g%]O/*npHKmZg6a8EN7dIAtc;RIaS6B$(J[\UN0,U"E%7Gl$&'K&K$@^QVjhdrcL]d\`JtrZ`@=9_FR1]58[#,Xhn[sZU@(Z!!e$O2;iA\Qc.`6@a)?,e9lTgN]0d1N8,_+Sd*S+-ljjZNVuuQ1#Vt5(,^>&@Pr<=(Fud0\=Cs1AJLK;`/]k0.&!QoJ+"PJIL6tP"3!K!22?pFb6>lTN/o"'Z5P&o";OXk>$iIV)VUccf^7#GI+J2=B'$j@k6Mg6=[A^J:'mf.ju\\a*jO/0>&?28WXER""0*@7Z,ElXB1VE[!V_nEO\8D>=Wk-.nfPta#VOM!BSmMQhBqWYNPo_.BEb"AWq,fYQ3jRpmAasdk+4j[o_r2GEul=s)r-),^UHJ/g;c;gdC,laHRZ'/('o_PLkpkCLkpkCLkpkC8-u+AGlP-IGrIo>f::i%X=j53L>21JqMT2hWT,ph?Fd0L%2?ur,%jT_#T7<,uET_2-9%o%-4=Fq<$MY#hp,PbTDFIbC*IY[d4f>KRFW_@JOL4En)!D3']8N1eI&8"bE-"/Hbc.8oP_M(-!45AKVH"F^UE">Gm78YH;]q7TZLEd1/1A\(,PY9QfW"8jo5]e-iD0hk2[Wc_W-(LYD<=P4iTrXtUdsO-Li5JbBCZ0sTW9/HKq0;i^L[+27#ZE3sBcqKQ]qJKhVd;A[pe6&8@?]+hDX@jI5S:+2lZX1"MnpdIK.EJTTnan]E;Aj/iq,G>X$2bj>qd%e;A?L[OB":o<:0f07/rRN;J92Jf9i\/:5S5T+).dZJk1JdpCm%4q`#;"<=D!u$]0YWLh4[r=;$4(Ih^MV46`_,CK$oeArf1,Q:+8C6M0Uice]KIqLbD)OUITAQVf;]2u3>9djpVfOO$qM(VCLMd@<"n=dFF?Ub*L/1StAj"emm0t_Ygj'9A^"62:i_HX&O)9^42HI[=/d5K(0>Aa7:d*p69El,]Rg^3d-*;6^?)_6@dAV*Cp%$-D8413T7r:Vs9;bQ3lYgJ>S[Q-DC?B6AJiK62\iSsB[dH%rlE*>Y`a<,NJ6bs#O9M\4tG.A2#:o.)+=ed_=po\Yb#I.ljGI/n39A0)&XQl`!Af&O6:HXAE^k\:?f:sY34IdeEpP!3Y"A)S)#?9RV/4Wj$UT(*2n]5=!_Nm'dkd2AS`K2:DQ0Y8nB&(J_bYI4T4O@fURa6NCJI(E>'0nXa*XOofp/dA9C5T;k6FBXKB>^KIE>ABqSa1HXFs40gr%+6(*i$j6!X&eohNX84lHtbD5bho&J5Te&J5Te&J5Te&J5Te&J5Te&J5ccEUO?[L24egEMIEFStb&#eXU8"nla3!cqWYC4(8'/lG+dF5En+^Kq!>T7:XMW<#IkUFf)_'DNsLgUTC>;HrIuR]3`oIJdU`)\0``*\8C+(c0Z*Jm!$Tb;HD5fg$CkX,HG(t".J3!Y%Sr0!nG;aE6ZGD#;oNR>VP=Y?;7?J1;7L*/KqNE'VWQr=X[V.D(!=o(dkaenrq3I@V[J2fZSnPh$*KsmM6&`2cI2E%XhflE:%ATVQ>L'S*SrntFl5Abbnj^VXF0e.4DpU)-E"TmN575uqm)q8r;I-X+m5Ur68mU7ID5HA)2"(s7Z.t[\lCf*WoK2r9U4)LpN&Ak.LpZXmRc,")>Yr8U8b&oFY%fIBE[aJW=*bf<)LOsN9,?tVGU`(I]VB`$EbkVe44PiZ-@Y.\Vt4"N'9fRjYXBaTXaC7HOYLjd2%r&A8u\".kQkq(+=upLkpkCLkpk]NGRRg$J15t!6FaNS_b`.jls7c)Cem"'X_ue`pR#r3J>)\OoTO5]*CF3l;pAV(V.=_D?IhIri:p3f?$"3\Hj5Fg^"nI"[m,VcuLA$WS1+4nJ[l=U\H[\3H)l:F^9bl-;_PgUUu>Q4\=-UR9pftScf>.Bu`c8#YQjMEp]Ek/P+3Hf[S\>)fnl][YE7_!IDjOO27W6l_Cjc*QLITmC>8Q*;f&e4:V.MHEZ*Dst3%5W=A2JLD7Y'eeR@f.3I8f9g(Q:1d:>u,?s^#/9#YQt$$8p1[`1lB3ik@:^+9&J`GkB+?7=>jgd<1]#VT]gP*LB5rS[%;10O2g+'!352"lDEr2Nt"9FT4u>cq[5Ne*KK#pB%q@SdkW*FckShYFGu3A2_+k1OBNor)jE`ZRdgt%&J5i>jGkt>,MLQ8-Y1mFTp9AY1PFYaXLU`Ae.>]jGcl'Qr!T-HinY_?*UD3k#?!n#.I&AIi/Xh#Gij`]LW:ZX%VsdF&4]&NC6a6[-%35JB?6mWePT:)Q<7lI@;5Q14UCH]l46^a44QMbT[V#/dk&@jq2=j4.Vr+-XHE/5pG)?rO.1IhjphBVc.Cs_(ds*mJZ&t]oZDKb;[\bsM"lD6&Yk/qrO2Gp#+#997\a%i]))7"',NR#1N:IS`)TQG+B[hPB:bA/56G700A7`]g1U;bj%0mM7[l\GJ_-[s>QeOE%)n2*oqdhU*Q>aMeF$V%#?+4+ie[8:9K%ER\ki%KL^rX&phofpg5hWdBgS[ctBmgnhXQg\T)nNoc2V6rfABUM)fb"fkYXClI6psF2F.1H\iW'($:S:aSTk]T4VO$[faQrj+0-a&dU5*AW3W'Stil$HR:Y?.u==^RHJi7rr?g5L&V-JNVRn':S^-._tlJ(D`Qq;_8#i-i?'++WuXRU*I+=D2R#g?DB-ieL9II%ECu:F[2`ksJ.QW7"-=Nigh%4PgCE+8Ph>2Xm+eGAb\`[?64K49!AdX_5`JGKi_F#&_(FlOD4&14_q5r5r2FRCDjI9>>5KmTP[M(QHDW2SN-Jh:VT"GsAXLhm%ZP6Iqe]%SVG/A#+qrRfPUd`2^J3[ZHF0C13#kZq`>>#:[mu;N\BlS$_..eBgO*rnC\PL!'WGr\@\'5LZ]RrrBXIVe8G<\*Zff!&fu2=I_^BJ(,O>(lDH>Og@D"UQLQHCRTDu,I%L#W@m)HNj.8OTqRAoo2uHH)Z#=nV3$c$4j>U!q3"@^+Q2]bS[Yue=S.*iQ?W?/N'UDci6roohU@qJA,,Un8H/\[+^7cbDl%PDRQ0Agqq8fpnb7XdR_')spT=bDrr>K!rqYqmrr?a^rrD$IJ*98=CJXh6chMW9q.]`g25gDVBDafWr3\WcoK=l-!:qb"rr@t8r2')`dBpC_!6/CG!;O)(!6\^K!*2-rrrBFpq-9NKL&V/5+70C>rUUrVrn"LU*D?B8Ieet;rr?ifrrF]5NL>qlYV\SYks!jn2T`L/l_;n\uJrK1+3G-8Y?+.rrCJ1S(jq"QF@[J\l"%-)QLs>)mC>umS=rbT@$Td9gMbXXsgH&aql/gR+@o']q=fZ?h2f+*tat)E2nYILF..4775"573/\%c[3dd1]\[r8rMp_.]sL_d*U65;,L0[*)T2RkInh#)?B%o.l+IN60WLbQ9:?VL,t9RTq)EY2MHg,@o$S)3]Z)Jl+(u07`S'27oRr,="%JD4$0MKY,(P/74i_g;+I&%[$._ueR&)bDq#+VI?b_5O:-crX(`RV+GMl?#2aA:g,\!Z4\#ATD9^%F]N_Zf>]fBatjkui!8/i9o_b7&n%\`iaJ73>mE.`6;>gZgNL:T:hOcRE^IDPQ$M7O'0=Jk3Hck(2jm\+E`B[e5R>=cJS;4mFQ"AISfMSPTDVKqFM1T9ZM\EoK=a%f6FT_:#439%YS)NQu=nf,M)R",h&,%@,3A"+PP-E(:)Cr&hpGq&8/s,]BN_g:KW/_TMdE7GKAg6psF26psF26psF3A_jT.92h!b<-LCWHKr#YeGd]jp,.Ra"%P.2lh>IEl46[B[r4=1E@C&g09j!eoaHi"NNi5$%-@QedRUrsp%uCPY24;[B"8[`lY\e2IBM1)DM6Wc2sOTmJ2O-F,_pLBJ4G)X?c.!+'uH?kBINhR\./]pbL:gN-+1fdE[+!gqD,jWi-NolQO9CO.l99Xp&'7ce?BX8?>;]\K%jjmdKG+DFj`t?B5J$QRfO$n@^JrQeS;do`e;Xrj6)Z^ED3[5SULA'$6q'/Q&J<<(>$U4j!8N``!/QLFep\k2=?2um`(W*/o64`NT6^i#lco9E+/1e,;q$ubg<6\OMraOJ7Ztel;UN-WQT@*s,Mmb_5["Z8ir8-4H?CpdX$eg[p>BY(9;=Mmr7+Z%@J/JTeahR\FNUU]l3m]RHa\"Ldd)*8^teqiMpn'.TYi!f'35YL!):.Ub1++30)6O5Hd29C2/R2'\YYa-DW6*e+?KQa!RNHVR]S[uC5m\f\4pVE\(",O?LP[!f+6T=92>ag%A/'oT'qV[PX3(AF-$:Mo8%]1dL,^bRWi$%98Ehkjrg_6@WZRIB-(7SQ8#&X)c$eZ:N,>PYha2-GP7KN:k.:*Iu:n@3]3b"64F,*B]a5G:B6s'k[`g*qO@1aMT`*l0n[E.n.tf$2rjPtm"/7=;GgIrarmCRR\Ea6O[`[;p]YkFFCS<(@A\Y[]*>n8\tU9ZC&DQ($U6(RkpU!P;,Y;-&F@K*(t&*^b.8L0fgRuPq)'chj_/SNQ[G*hSKW:F0FnhHZGR&_$/2Rhd-A'mmGALS=BnAnVS%B.F'JDq^.;K%Y&Qg(5DRWjn[2+5m]pc7CbjX-5VSJL).J7IMtc?6]G]Ci_1X/-Q$=>h0)m]"jr"uL`B%]Q#tVj$7C2O><$k]ZYNIbRZ-D^po.D>Jj_[B3q+=O>DV!&ak,U>KKtN*1ZA"UT0ljUi):]L5.U6psF26psF26psF26psF26psF3NgrE*#V@6u"i2^5Y3Qh>i=iukre;iIl1u3FDdi*_g72psV80')$3?9&]R$]ou%p`@a6HB>Saepo=S)t#bCtqPTIt-M'Cg5Q:`:bZ0%B3TUp*_`:E,(rf1ic,&$*BLn7^ULVcB.2?_c8NQI'YUiV'=:bRLP]bgGRpnS/sZ%W@*s*olMgk8r4G7_[^8+^D>J0EbOtX!=cpqRY9*=XD'Q)+pq+nfn/XIE?US78__B5<,+5gFNQTZ6:GR0X\V]L4V<1>Ya[JM?@`KR%'BO?J`GMHC3TUm_R?A>WN%N]RDFisqj]@[rWRkBIQKqqPc"-hSUE8]XQSHn$lu]=E>0^`e&kD%'Ig)h")Q$D@Z:QB9)\;l(/#6=-$+X1iG06`cM]CrTF@EA-(A&aBoa?ru`GjQq>usm^;MlB]8lsHl;Rfh&rBR\[3u`@QH?Un,&JrpH$6gZ<+sJ3T+sJ3T,-\I%%*.a.,a_#B<0c!?d75GC%4j%^CkI1EHB0Z4CcCd`CUPmc1@]:hk5)A3^=&$S\&t9@?L09<8DZ9%grEppDV\:R4Oj#nq:.7@)]D!)H[l*[Yj-Z_mJ*\UIQrZV4P-X!Y1>'Ee^[Z>0uP/0H2WN>&@bthU27cFP+]tXRE[%T8%(+u)@sF-/mX_-EP;-_D+TPN)B"cQ#ej,,3nmTUlJL('Ah5:jElXocb?l8h&6r?hJ-+mn]oVMU:N_GBR_G#!@D,d2W-"l(XEVjA`g0dPb'(1Wo^T/2N=69OGADuk-a0P6'sC&:VY1g)dJt.(gs?.UXn[Dl(CSpN>h`bgf>Idfd.oV>#A\O(*4[7;/sU+Eq3i/#,(('BaWlqEY@H8o>Rtd>mMF:a)@N'#"0!RP^4dBA&4'#-L7/lH)gahlM_YkpMMh6kkGBH=k*B=o8a8hJ/pro"Y/%MbGUDQT"B&_eaLCO(u_d)P5I-,:s>VNq!I_L)F$d]pK`"d"PEVYfB#_bIF,7;B'i2hF+_:Mm"e1\f-T?2`;g<;=>pCE,baO_%G"d*#Kd)>uh2D)Vm(G0uQeX+YpJYS::;MoH]19D4uJEb78ib3F0me94j(IuE078jKt%mX7gEX>KQj!W)("]f9;*r!2/m'p'NUZ`+]\:jB&1Y?1h(G%!bQV"Su&^YR&oF':[uGWr^]aCWl4X*^Jc)TsFB>JItaYrE8n4"-'l;g42s/B(:1nHG-?UF]W+c5lL_7cR\(L=OHogorj0$r`_s!:6M&?i(P&%.Mcbb)1J4/5cK14cU"fLVse[/U+JIRlFPC*$):kBS`m!U*:d*+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T,)c+Ljf%uPP6o\WI$BSRGjZC5P$s(\Sq]4#hKupDQk(iYf5f[sqU%Y:QRQq4er,]:&#hSjWD^VGQ.^(abj6("`#fP_Ac#4/J_'9nGDb?uM;Q6t(o&>Ir9QnDf:31.?AtD1'"#LUNqO4edYf(usm?#P4Lsl+#D>98TS1X\LlW0eSS-gTqGMCI]`n4ndci[YiK-KQN@L'OG\:Hl#8oA$fa3a=PmmF;.\Rc/jg">I-iGk"g"n;L4Vb6si5i)]M-]/-`n+'fdS[jUi)8]L><%iVh])2\gl_[*^k"n^udFn],KNErP:RJSC+.:(CnC%AO#G@9F([_/!p)VI/U$3:s<-4PjVKD48]0L'4O`k16B]=.:F3SRL7d4Hi?5RtRn?=sRc$kUcX\2qElp@1ZV=@O+^crg;5hqCc>>:7C2d

k]I!!BXIhV'R8fh3JCFlhd\%IIqXqm[U>uaTE9Q3'/]X77>+$pIXn5+O^RF4;4O"8=mu);_a;Zh`I7<@ls9BgDtk"DdLU0'q]!TZKj*bWNbJ@_TsN=Pn6g(O3DufHcqOjj]ZoD2PLP;,&`m_jF-Xju8i`G92INc0ROc;W)L=Qk?d]m\uO8C;kIuMR)\fMRDp_UMThA2YB4$AFf>7n$`2+oN#"nBLXk\eDFg!feulIAYH<6>HXiXP#8\c-]lp$-pOI#\YILTF+Ia!!7=\.0Gqm4cn[EcOdb\i!NcL[$P24Gn/A]W-D@*t?*DrTtH)09:Y<%QA13J2RIhN];2(e,`PbgMrUSrQHC5]G(R(n*S1llc"/GU#BpH99.#Y5d^lQG'!2b\CuEK7KW"mKK^eo@=,?l3$DFSG>4(J0Rg>Lb1=+3fmT?>[IIJ?%kiEHTp@:F[*ZK-U)<mY283^m%SYD0\XK\0jH]@U?W3r.%^gkEX[C^H+C&$3N5dR!;j5/SJf1pk+GQh-.Au$Yhe'iYheN>TRPdnbo`GqIXQH+pS7foQ$LOVeUf4jl,,5,`/V/E#pXhY1%c@6K>4918\HXcpqc6@!\6.Jh1$iLIk!;tu?Se:b1/;qMh$qiIeMmaXj=td6XgM33pCfO=Qqg6`#L$&V=/9q^)!#W4$m>YI*(7OI$j\61Wi0D&IY_#)CY*YpR4'8"CNk]/4bXpj'0"iI'dH7"pLN-UtIU"GRLZF\9gNm[n#1mpEAiifg!6eS'Vqs,O,!'R?dF(+%Q'hMnrr??(kPkNB!U91Z:1WYqp.cE$;"5Ub`P_eYUT[G&p!eKjA]%a38&;kX3MY,]C7Vg2OB?B^rjP,tm8gB>9pUYgj'YW43;GYZJjt3*.BWl2FFsqY&DL]71W\:)lXo8T4?j^BVOC[Fa28q^jP"mQ@o.$]c:-Qoe1:Sr./&>I:1a$rk)4RF7E/e:4]Qj/RDM!/aV1q2^rt"c$MZiO"u2%>r&3c^N$hNPMI9Dn(MoKoDni;^HGeErr<8U60>cK#5=,VjZY@;rT@0&n5i&j_=(!jg[0Dnb3FF>btUn:rrCbgeA7M>2fV$r@&#'Vg]6tCk"k"4XVLd#`,sTAZa&>W=DDV^B_`57S%mLOkbCf.M5M0A@ddgQD7522o4Y4ILMrlT3=kL[P^FYLF"mlXlVYTQ]=kq6A,(Bur7+!/_?32s^TqTlE>QO:1lqY:#[4YSVP#2;3cXDn,-9pU3-pcDjohq0fa+G\q=>9K.-*7\n5HlOUR9)134HB)0kpE?`\b\VLS7S_r-YZB4m$o_U'rh%;!Br\YofCN+LNcFC(`\A\Y7BKX;VQf`)`X7%=iUA1-gj`2W:7)QM[]ru+*#aU1f\T7rh1MMtI(&=,%oQ^/8C-63<[MV@Fi@rD?Mc=C_3Mm_U"5^>)"(bp@.0@i;V]s:,uf&P?Wm>paqfk;4c,XDKQ`"Ytl4KjBRg[)BhIJ^YbX5G^LHX`,`lrrg_q=f)G^dbla7iS#2b>o^=$]'_M#r!.IAe%,^_02rQWQr#V/&[^HEi-(S_S,7!`dd_/Ad$RVG.p9/"LjFC[J=D;@-hm%N^=">6fk7@m;AMubm\R"S:pD^MlVTDauH/1bd1f@$Qo3UWcq"_WdYAj<&WAQfBBcs^LP-Rj!\u;>IKh/f,9'GZNlC.NZNK&NK5C!PEhemu2$0l[S!C$Qa,8nQU\$h@+E8&K#FF<'NkJDCgS2)c]NXb!`>^@.OB'Cq6U/'':@Rtc2`[I6*9#A9QoKZP!:PtQWC__0"([j(F/AI)Vqf__m2$qW]S?Nb?r$GueN)\JYN:1Vf1gPXVf>*m=3FGQ&J5Te&J5Te&J5Tk>30b!Zs2fJQO/=Ee?QSf?@<^rkNhbGQ#CCHU2/m5EONauj`B/rL+*&nNF\#qR,=Bc809UonHl%iUR#R4RI+dJ7kt)fH'Kp4CZK8;C^CpI;8ddSWYq@3h19$oAHQ7Bfr&H[gO>@Ai4si22^@<^pPIsV9U.38B/Va:p$sic;pS5.paQAhk%ND==,lt,StgE2UD2r@@9%F3ba@H>^&%g$K8#Yhj$L9lIEltMh>3m@'IB'"3e5b&BjL.Ri2b15_!p9R:*-^$:G3dV"a\ksd@=gQ)X/)`^(gB@p2Mj(EpW4@=C\c8YVgH1+'4*FZlib\L1UP/S0)L,48H'/tL/P7qmn,X7P/rE6bZ0`O"edmUO58CQJLniZHHqF3cYp02JW>nu-k;mrIhL[t!A[+,Z+4i&npo>1hXa8Sn.>HlLhbX/$E5r\(p6(8TLN&X+B/S.H50&5>^9)jsrJ)Lei(--S>>u`(;$U&!Gh.'nr3W)s.!T^tA>3=(4;:cRqWc!'%CDiY?4_`9+=/g^MjE(!Ibf;ah9'nRGbkg9O3piO;Ca:3dddFf'B_!%VoN_me$KGlIcTU@,ur?QR,P3m:HP?oiK3u-8(C_^?\V<,p&X1#o*ak)j!q1DZ"9;E;LXk]q9(\m7fE)\fM].2`(lP.*0E$%D6fl8!6Er`j:V?3]RSd?bB;dA=D`(=Z/\^57c)SAXJ[,J?>,tG2)W763f'?AIG"$TrC\4i"2h0mm/0L)e$%Q_>at`n$-2>'8'CiJIHUq5[<#Ge4BGMu)no72:rh%ScDQ[o#LGla;Lbb^X,Yi=96;-6R8^9]%N?H]32tnUdB*T0XiKY;$niQuWAfhT@N=/*IMn";._:Ksg-+UVhA8CFY&-VsHEWCSWmZ<%Jo:Qn(.1Q$,N6=(*8CJn\I03r'7eph[,'.oj.uE"`?R=qY/4C_@t=LF89^>oqFkY\W\1.gEiM8EB6aDJZ1r]!m-)+9h(:Qi*Gh%reZu@8O0Y?(G`Jb^0l0lm5<$HLr^_UFBY=3QuH6'#T][rUB3mZ!)jhjZ)`?%,&2QKlIP;Nb=W#EGE6Wqo;T]2U_DnRoeC!ncPQ26SNb(r)!,WNUGT%/C1,k?oA`Pi%:AXRSN9nject'ZoAU*pW&oJl4d%RIRX+lB1X6-:PfW&X]>b0A7M;e$:_rVIbpb=@`A]2S#Hf=;NIsp<;O>`Kn5l_!FKa1ZCLr!*BCLWTbli/SXiZM.V[&$Y1*hN+FfU,0b3f7XgmsY4`mNdO?@^pki7qHrmgc]JY<.8XS/%IeU8(j-?`2,6Y1qINO0jZK-V/U8h&o1_NM-].u:23;rqn^BLB]^lJTl\s]ttNQp&GCj^a%K7@9O-FDO,h6uFQe5^UDI(q0F62V$hQLV)oPF>`6gD/@bhPc)'[d(5fNp(Afje\^gdS.gK*SJqc3gj/8A^+W`I*#:k+5tD^`a%`am5/[?RSW&6(E.UK?`[](P^d+T8VBr2g6US@/V_j+4(_j@Xes:]rr;jq@qIUrrBYC=FI+H%s^$#Ojn-3Y1mW")]-rTB\u_NI"]so@D?/$b:3(e_mb?E/?"0]bV!_+k>"C4=cq%tHT60*a8rM`^LC[uD;A::%N?20F,tIXTkq",:YhZpJ]+k+%WdV6ZM\%:eWu]3%B?2%F:pt(7.7_VaVrb27o?c8JdCR,X"VIIOg212d+5Q(eq(%*H3O/FNN])4*U5f4G^7ZL7IqUikoM9rRSEUXB!oK*3qq??Zq*Cd-mpV9\D]e#I$.[7fbQ@+p&>#dY7G\?pjlBrf>_Dn+ut.q(7@GfGL_ur-pB*O4`Ci'nOq##X&crPWp;?SCZWGf92NLdf]7i-_7u@.=2BjmGTQ&/=F([gZ;'mQbCtp=23<1iCPp5l=DcW)F9?3U-n/:p$U:B*!7CQF;++T@P&=7r+sQ=.DH-=VD,&Xo"+b6<+S6eW#4J8\"l?B3JqA:r4S(_CP4C'sV4I+(n\h)c%-.1X>+.Ol$s7ofr$>D+sNFaLkpkCLkpkCLkpkCLkpkg*D4#8A(^e]Eu#*tS=8smiM;aGc#eqY".f>V\_%MOVd7V7ZCk>Wa&?b"(Mnk)CZoN(mg*XhI%e;"mfj;q"=rL_C[H0JG`KmZ,U2$pk6$logrX37opOKQjCh@I@4_2`RbnF=9>[?%85Yq.+ehf\:AhkY(0]uqo3ESD\[G"jRH#b[Q0>1GaZY,Lu-t@-SOVGmfGRge$i&:D+E4tmoG?hDI]7S6!Jf=JVH?`;,&,0OG=;DdC],INQ1p@;@;d[)Ri^D1"$+D@R,-R0Y$0rj)WL"I;aIqDQ>8I&^!AH\W*e$H[2>0/#B8%LkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLkpuZc"l$8p4kNC@L1a#^JPSb,ff7-3'M+("5FCE\s\6?qNkrgNfoKEdSdsg4Z8:N^YlY"HZGE?6s_&]+sJ3T+sJ3T+sJ3T+sJ3T+tG$d]T6`f54)OdKY@V6NXSDI_o3%;Xk3o]`.KF.J8smL8&-J4O.GZ!#S,@IUJdS49)]^dJJ<+]icT-U`B,_LmF11*qFUN)CLsD%%7.th>tEGR[o38fHqTss+/.dGjfi9=*Ce/QQcg=[/@![Ll/+$\Nb"=Rf#R8C)Y/%sF<;7FU"8")Q0-8=\5H!+jV@EMaD'PH9q9fEfRAPArc5\lgj7LZARq+*U15f5-EZ-(@>u4V!!%J>cn:Q/*:YIR"205@tA].PfU_jRD/G?rpUhfD?7$%X=DD%BloHtGo@96dLM%"[YO8c>nIn$'d=hG+sJ3T+sJ3T+sJ3T+sJ3T.kV6a[Fk`'cXt'ugXQFr:K(*@1);V!njm:1^"glt)@$/V,AkupXc28cZF9;AV7b&r"Cp2lqos!&-\'p*o.)RQ`dnheXiAOo(Y*BS\Rc/3;je\dRok[KW5hiP`/pTYEG2'"5L7Rt$<:l>Qa\_bACi5\9\YL>J>^#d'e2\bY]cOT'BK<1g[?!H@;ql"pD">3eb^78'!;,P;FpG&G__+!2p9Dk[<->ETb`&i@.k9VC6O=u_>1\)0UPTFn/I-.EcS-nUQplA@>9*L=8F$@QE=2s;R'aK3Ea7dhibr7@/"4%j;[D[0&\#)d@cDZ>g[G;61a;j-fcqF]D@UH4/Tb(dQC_POIX22?#kT=rm670^+ZRM0F,YspAA/3G"kFS6"C?Kr[,QSI;un2["^E9qc?,If8p/Uh7m3U`=meqpMSNQttq!T<<7]Go?37c+sOS6$?eXs[0uYn6%igO[qoo#ilBM\_U\4)tULn*_l\Sd[pkqRA([Fn],Af=q"6bILpReHVL5;s]mZ*L^-a&=gJ#2G./tp'&kRp*B>7mWLerY-i0+Q:cLP4_Y'#5ISlEgR::G]#2"U)jC3_41_qgcu<*X*?.YHCC/S9DGb3H\o2ptOEMu+'g5KJUc*3V-N5ELMUcL:+sJ3T+sJ3T+sJ3T+sJ3T+sQf\Jf:R5V5T6V75G?m0uItmOg,/P6Mj41!Q)lf#24bIits\Hi"ad@?`0Xq7O_\-1mO8V76,AYgr:G]l,lc?gQ%iAqp]H=^4sHM;jf5GQE1p;+`K$7Y&X-h]J4q\-h!XZga"E$rrA$_DcKimSQ$lb=m?/j4.=N$G4*YiLSs,4;7p#>F+2=RS`Note=4Z,8Rd!.Q.gG@30's0`fTr.1S[Sj^6G;Tc2b-urkis;]a;Ps6\Zdqprs$<^h$I&('/RgfYl$@E(0D\TUD%lH@<$HWu6Vmaq(f]gFEZ>j&"DS8qs`nOj8MN.uuJ7,dT(60M)Co69QZ4U\aaj0`!L;/0[*cH3(7/VXKpSW7K5f"7G,qs7SWk(bo.gl;32c'olbh[MtQOu\dAEYrP*V&ZeXn`]-5%rb"rNl?(nm5,T',cA,e,AbiP;^YkojH7F,EB_'3lI^D2RmtQ#TiXumkai')3o>_)XbHIs`jo8)E3_6dj6GJ,E4*3%oBu-![YTh6C*FiG+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sMtg0*S>fh'h?-6WHE[Xe0s9D1CX,O>l!Z@Whe-X_B/U3us@C8^!-gSdMtQV5f64__VZGA&dnW8D&MW7`qJF_B?k_%4pMui9j(i%>Zo(3,o)k>;W`@V3@unlgl'LC0GC0pB@CR`FZ!G'"ieV;?Kir1\N2?"p3e-#JWualiO%p)Q.P_hX/tW]+LuiFj82%=]IO.+beZlQEus0d/E?m6?_S)eM_52$cNR0j':;12SNp`=gmCW2`-pAb5VHE)u7,=E,T7:>5Cgba2J&J8+n;%XBP&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5UQZ4$:_>$$NTI8,*O4k-j$7en,^RQ_,_L@.;ZgL7\^NU!%0;HGP!6h]rd1Hk_OK9.*3qeo"t#p?$GO8'DS&AOh^=Z-WcN0+B\L1GRK1F'M!U:%IB^dc>>Pg8:cifpup?(UlI;5.<\tQX>?tFWQiac)uDYT.-\%c(!H\gFR7jFtrC:Cqp8!ErbF];@$5`%S'#sa^h*qq_X8E2=,`SiS;DgX8jpUcHYVJS(s4O4/pN*3MiU=.XB5N]oHkS%1Xq/*?DEKG!1!ugkOELS6L"!h<(:VRVll24a@&RmH_*&mBYhhqBa\A7m-sC.XOq&7o_-sBlhsU*mj69D4GK\]nMD)NS%Af3AqX:o6An,Ci-H)I,ar!:VC"S]"1C!>BgQe0t_>dBq!V-LCZnePW4_!K@'(/U+YkgME2$SW;)P8H+Cr_EUP0:n/\$?6&.Aa/b_XPIW14\7Ja/ZCX]H\ne..OtS0Epd9O`:!LE=oo[$3I?!,m\$"Z9Y?5+"Om:!ACmnRV]&,ouEE:u3+ELi4fT2a#g^CkUe#pfkRB1Xe*B"(R;Zh9ECLMrG#3M>Vm!ko"pDa$'O/DgoA:>"=l_hB-Fl)?_Aq!4WN+3cM%P8gYC,Y)6gQm_\$nSa@QX3#>P"G)VlXM2;el(9P@]c?&Nd)maHu^sr[D;Wj\WgN5Z.u^A'9;ZeG*]9X4d')b*:@Lo,]II>5,$4R)u;d/f^6&8*/p1Ab7fMqn/U$i`#cmAGX`u2F?u13oi$UQc=QHPle$j4i/V2s3>57g"(HE5G%P!0Hp=!*8;ODaZ6CJ:+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+tel7qe*t67^HMA>^(RY`F,!t)qE4P1KsAi##\XV3";@Wm^\Z!\IOqZ(\=JIeYH>m,?^CM8sYcd"Ajl5msATUpq.^9C-k\4HpXa>L"L7U3>=(ohTnSEa,XsO?@S>:.YSIhqhepUS7MPna71nB^nbkmAlq<8>S5/2F7_Z'%aOe8Bq>tBr7XS(EI'L(,?2a@$V]<'ENI$!]E,j4C7ORjeQ1RL2*#W@;:m:r()k)]CUDBH$q85R#5e]u)OMHmP1(/j(c\3Tf)s/geAS((-d^Qdctc_nZnIY\&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J9/'F=t)N8P:(@73gWnAFMgKlu5%=n0;r&&4%]&KccUp#@![FDG16N3"*tmJXBGPNS:"#n8RXUh()i6<#U$(Z1%7C^%_1]D<\^d7nXj;*#)6_=\fuGBg)0'fRJM4[ot@ALtrfCf1ABNS_VqD)]0sb)?T<.HkQ[^Tr=RpYEu>^>6A;G[B7/DZk?)eaX$.II]#6,VFniq$Z`MdA/8d@D8binD.CAHY4u8Ak'*^Ff>U_:2[HnB.#<\8LkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLoHa=QH+q]Rd9(T.TlC,TuVAiO%-L!EV]hQo>OEARWetCC.U;c`0HN'ko:VhE`Gh<3EB\gI^Y-i:MHf"9$2s!I8f-HBka%1nqTD'[bp!Ji^Z`1][%nLl>76'4qCk6MU(rcmkN\sO(3q"dW7@4N=J#]3fUTo%JHXLC2QsaUmfu9\p#m(R>*/j.6>E0Og4R25MHR(`VNk7(4(/7nQ5i=0pb?qgRJJ'M%V%U6p4(5@kJ@#BPp;RVlLLR,ZJTQ6Ci!'I^"D6VoHVrbU/73)n1.q-A0A1W+e-*g$g_9C96c51A(=q4q+b@^3c4!^,H-UT;lC",4[*JbZlIBC5`M+q54T$'Iqm8`k)Br[Xb[>o22h#oa&mg#5D^;\h,#5uk:+jeTagM#Q=TnGi;%1H_OT_b7Ur6J9O+G'r&=\VTu,)R_%0oTd]>1(t&3sG>i9J6c1J(rJbXJg(=n$!V;+>a2`a'i`)l8mgBK$5/AhT1M1h.n2Y+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T.k;X(-E5"`m5-_V>ML[F.OqSQ/`h9TiK40]nd.Ha=?Sr"m']`rfkmOn`:EV"5o^>RmR(.r&+!SeBPLRBGfMPmfkhL.lA;,6CfO:hY%/"i@cr8eLFDnJjWf2_+],_RoR;eMFUiKh[T`C=J8>*SYLGB(tKQ.>MgCbY+Sfp8fS,hO)_f0L[?^!\rW=X=u?5]o4tC;Y-)K7UQL>,T'b6:e*F4J+SIl-MP.dsFq95KMrHCsZA6Y-8M+U:L:+Jm5["Vu99,oH[jmgrC0OCE[qYkYa@/H>)'>+9$<3)ApOCV.e)8dZ"lukjWldO\D/,(/#OGbhe]Z"QY_]#g:Jp_I$@@9d6';7#/%0)a`6^l2C(A$qZUmK8;02@'f`6TUEagk0(@3f-SZ&6[_APrUPlRpZ`(4Qq!$(3%Ccf@CTktQ;F2j-Rjt`$/[8T\.UNoQ`NuGK1AZf/q#a:D*U[`&*PqOE$J;?,=g+4T;+5\F[N2Y6Dh>A3Y%@i3I;!E>I);"f+>`7SgRcp#]UX`l)gI,M6fBsm'5O+7\a9b*&cl]9,6%mFb5d^QBY=qj>A83^dd[%7#`A[\Yl3HEskM@@cRCRf2gFa1;eK_T2efjf1Qc[,oj0[k&!`^YS+Iu\*qc3#\b`hl&J7^A6psF26psF26psF26psF26psF26psF26psF26psF26psF26psF26psF26psF2pXW\/?,ke.0H9f*;mA#7@m!W4RogPq$'j%S1^hc79a?Si:/agc3[nJ4=u\LU/@T%U,[r_=hcUp%@7>NAUJ:EY#&Np%PHNid(Uk'$W%+=](>H3Ia6]Y.c??A5u.5fUniU6Bn6b[.%8b[R6,QhG?2u'$G+^J9u#O?'75FqQGFSH/Sh=kkkN%RB//aK-p)aRWp+;h8=hObOEG)bAhg3j81lMT[((#S"iZC[;99C9*208-aZMOb>JHTq<[O8*FjG$)@93cpUpo(=ngb4*eP`lD\Zp\DZs[]?2cJ15#Be_L7SeWdj)uCL^:)otEhCJ7'f&K*0'm@tN^Dmr9=oc,@_"#kmu-JMb.b&$YIE2j%s?;k_"cSCftkYtQS`UZE&U"Rf4<%E[Hl[.:N8Qu1_ddq(\DM""Ki[cO#UhN!r:c11BMAG\>p7_:"C8km:_RcQJTT?/E/7%:!"mN223<%97=tQ8a0]_HXh,2WhZ!0\]rn2*Qcp,qJo@m2]U;t0&P4NXjVWIJ*2<%2&h[W+;J#]h7M3^`7[Tc-ihlF8.1jhqu>!MNn?d`1KWsPZ(X.to1$u>oWi*PReo)e71ZgeF[qs(4q@?.&Oa!4*e:!VGnh5hTQ%ZLV(7B6?T,(`MOh(V%l>([`8/l.]UK9iJnnFEhb^hUe6NSYCEXKC?F:Hd(C,i'4Re]GTK]/NmX//SptPZBmD"pAoOWQJd?Ob"*>Y(-SJe>#r?ab"Heo@L\+O2mLa"r<71AjuC>g)L@=$lCO:kVXm.=M-tT+6LL>VYZjQVgL-Xt??W,5PR0#i#nu^:p*tC8eRGf+uH.A[bf\0\'.>cSb6s3"Xo]hl,3#,PA'S>H)lH*H6bbEItWFRFoQbPgMAGH-Qj%\\J8>:[1fRp*h\CK%[)%EO\:Df!a=QCId6Bg*A3si_2j\WuA`1JZZ,\c'M?lYAQL.mJ,qkAgkE6]&dcLac80t(@Yk05G)I]R/]8L4Ig`^5dhM('VFR97,D9gE,P!JX^p)s9"n)i/LFs/ADL.TY9aJEEEmEHkfHWoQka;a]\h8gZq*G4rS*[d.?Wj\FGoFNjf.ucQfA)/Y?FtRi=]35_1:GMUS:W6XMpsi[aU?t7>"D(aF$b>sXh3ge_BX<-Eilbmc6]t?U;HC$o=1S/(-Wi>9!/X815Pn@%ll/QQ3J1_:V+FC/k(aV!T]??Y10_a6bWNue:FheOgpdS0a7FaPZJ+X,>Glqh:LgMelSTqA\CIh4[?GJ*BJ/R;>gVnhSuqhU8^pVK]+L\E&k=H^SU_-b`!oqIpFQLX:,ZHV0JS6psF26psF26psF26psF26psF26psF26psF26psF26psF26psF26psF26psF26psF26psF26psFBbP!`#am%PQIC;LDaNl\SgP<$2>2cfWp_?^r'_"Ok)2<*b!FlqG$D>K*O>%dH+WLlZ<%dn$SmghP8nc@.3?`:!in-h@`PLprtU:<*q/JeO$:0V(%%_(+e*G!Phf*>U9>jLuYhHu"K[iD]iRTW@pf3>!?C*AaA[=iGccK3i@T&JFRWk@M`l#*jsb=aG@[?7k[Gt'cPO6,[,!-koEDqAFfkS6N%<4FbA;U701E-.u?:dB/RbQ.iOJ1kkgXf=rlkuu*>!ZSV'p@tT47IeTg%A9c.hspQ!*E?!MD*qrenH$]8a-Gc@mQX,6;Hqp[dbrR5#2u=occ`?e7@"=77=e:A%tW#I)5&UimCrW+_0K$YlFBU7!#*IE9X&&Q4f]gJZ4(DNkq9oBJ(/rFMDA.*3=Pt0$f[MZo+Yj7lYlkgq+U+9##>cD>0N9endstream +endobj +4 0 obj +<< +/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font +>> +endobj +5 0 obj +<< +/BaseFont /Helvetica-Oblique /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font +>> +endobj +6 0 obj +<< +/BaseFont /ZapfDingbats /Name /F4 /Subtype /Type1 /Type /Font +>> +endobj +7 0 obj +<< +/Contents 11 0 R /MediaBox [ 0 0 792 612 ] /Parent 10 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /XObject << +/FormXob.3d48064d70f9dd3282a3ec25fafdd35d 3 0 R +>> +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +8 0 obj +<< +/PageMode /UseNone /Pages 10 0 R /Type /Catalog +>> +endobj +9 0 obj +<< +/Author (Prisa Yachts LLC) /CreationDate (D:20260505022642-04'00') /Creator (anonymous) /Keywords () /ModDate (D:20260505022642-04'00') /Producer (ReportLab PDF Library - \(opensource\)) + /Subject (General Marine Services Brochure EN/ES) /Title (Prisa Yachts LLC \204 Professional Marine Services) /Trapped /False +>> +endobj +10 0 obj +<< +/Count 1 /Kids [ 7 0 R ] /Type /Pages +>> +endobj +11 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 2034 +>> +stream +Gau`T>uTcC(4G@IgaC6-eLdjU>CN''%TB\;1G!(;B<(MHm$gE!Nl9!K9_R(Vac;o'k\b^4,R"pe/%S76g^i_<64>Tqjtg?ES<)XqJc]L;ScTWp_"\O3itDdYa3RLso@5[-OAH-&@J\FZTs7RS!F[MoOoc4P94HG#SOp]P&"9@@;Z^Jr8[;\!f1@HK:b'ZB\.$f=#a%^d1)>s):E-XHk#NO,ar[BBCWD\[J+A&4UJ?V_d4R8+hUdPEcloC*cKZ+@QMFj*j5du&s0Q`5,[KSnuF*8^uKS]!kp=%+MDRN,UOsP)t5pR<[U'Z=[r-R[0E2APrd;#-q"JDI^\4,Y]<:h+4;FYod?q\)5`,JSMYgA&=i+4Ne#..0u5]dLXJ^oX4Qd3[dFmj@k/u$))4K8X)e$GmB1j+%33Kh^(9>8C9!EWDXdhZpcVUi,#SS,UEjP>0+'n[^Rog?KP.d+84^Q;DI)Z#Q0CYuPT,od`\;&V.Nu?c>RQ"E;2h*rPje[q7&sFX4nO81I52XIdYVDi`K:ebli@]"oe`qIm1=bD(^o&HZLsf(cXs;lhJ/X=iI(HXdY*d6F!)Ys9?8_Q)8a9:IbFZ2W&^08;/:=$8K91i_NWPW'!M:U#(B/jZN6+HErWW$i0',0mGBXCfS<+922d*48$#3UIG@J#+K(o"4Ye6k"V\(_a<5b4eu4ui3V1qGO:gaj7\Y3R#)$I6'X!["[&1CL,MX0$,BQF]!"mX[H07n@t;)Vr]08%<`'kSpZ8k\Kg'_n#IsoPhFBC0X_bi#SjCjLb_WDI'4Dj$?hC\%6`(rc:+[E._0Xr13ZEp#+Qqn.o7M+iul\1pHf2H2(od;-RtCoHB@ba[HPKn6X)?$6J,mIP-Jek3aGhle-XH+#_aJ)C*G+i8S^jtNW(?+P@qS*"Wmq>D^R^@%aif-&d[4QerP"%Y8X.s!1LI>QS^hZCB-a5tV6'DID5rSr=u51gBH9iXE.6$ZoV"?>P9ug4V4m,S%V]T%QTLj;48O);SAbh)jb-:\f$[_j?,7d)R%057_?j#:"'e&*F`&Ngi>)b/Q7$nD5;i9DQVpoDo$Z%-m6Q[u\t35e/_=LL"1"a_-r"qZe#S$8Y*\+,>9hW"qTAW?U%U9J355\I%V^TB.5jZZ$9pVU.qfC>W`>kb7!kVS:b1&Ch6K@+R-V?sFlC4'm/%E2#Ergj>/@-o$Y-ZV2th!7]a#"V3^W[id*:UXkIVe0d!;cWE+\)8H1+%k4=749Be7g@.i@@=d-5o8)eV[^E=Wtih,Ka$?+9M#KR"mTTAU/l.-c0'42/OLNH&t,]Il%Becs;W(^.VH>+bJ^V>)d;eV.-&X>C51iD!RCUl*N2\90E>lj=!*f6@(t"5KE0*I-)1q/:LU<]HTendstream +endobj +xref +0 12 +0000000000 65535 f +0000000061 00000 n +0000000122 00000 n +0000000229 00000 n +0000045591 00000 n +0000045703 00000 n +0000045818 00000 n +0000045901 00000 n +0000046159 00000 n +0000046228 00000 n +0000046565 00000 n +0000046625 00000 n +trailer +<< +/ID +[] +% ReportLab generated PDF document -- digest (opensource) + +/Info 9 0 R +/Root 8 0 R +/Size 12 +>> +startxref +48751 +%%EOF diff --git a/prisa-yachts/brochures/PrisaYachts_Teak_Detailing.pdf b/prisa-yachts/brochures/PrisaYachts_Teak_Detailing.pdf new file mode 100644 index 0000000..361f73c --- /dev/null +++ b/prisa-yachts/brochures/PrisaYachts_Teak_Detailing.pdf @@ -0,0 +1,97 @@ +%PDF-1.4 +% ReportLab Generated PDF document (opensource) +1 0 obj +<< +/F1 2 0 R /F2 4 0 R /F3 5 0 R /F4 6 0 R +>> +endobj +2 0 obj +<< +/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font +>> +endobj +3 0 obj +<< +/BitsPerComponent 8 /ColorSpace /DeviceRGB /Filter [ /ASCII85Decode /DCTDecode ] /Height 454 /Length 45172 /Subtype /Image + /Type /XObject /Width 476 +>> +stream +s4IA0!"_al8O`[\!<<*#!!*'"s5F(38OGjP:f:(Y8PDPQ!GM6!#0'J=]te*!@RpJ!#/mE=]te*!B^>^!#0X!E-)'[!Diar!#0HQ;F:Ea!Fu01!%;JZ;F:Ea!Fu01!%;;U;F:Ea!Fu01!%;>rEc_9]!K7!Y!'G+7F^kCOz!!*'"!":6[,=5:jTb\Ij1IGVlJs)k5dhbq`PEis11h3ht_U!WrH(zz!!!!$"Tef2!=/YC!(.=u!h&@P]s+;-c'\\E9_]>%X9Jr:t;f)eCgC:@#e=#c_ur/Q.p52k6*7M1Gc.j>N("^q''j`D5D_ee9rgRSE&U;(H>kZTC1YQ$s3>gqhQTh+EBPSOL(H?pF=]+07_Qu4Yd@%2j`Nc`33*^K*g.Z>>>2!pSSr]dNF#7qlJ#m-FfKIDN>$%[`5*"n[K2XK#T-E`af!;FgD>@]EE;6"dQ9BrGE:n"&>pUII[?-`\0plq3IND)t(GtQhhnr2l`@b//^<=I_Qt*X;>s-IA7!`$j3PWT'IFWT&N,U4%$'SXLcfRGSO8K=mMmu=*#@Hra'9\BRr^PYerBOmZKjsPCDYSc0ZWiZ&"B$DIAC]Y;/e1cR!Z-SrP(NTLG8Y\\EH82r(=A_eYN*pA1;55B7712lH\'KoZ;l_?B&jG7\YF0MEYcdh#-V7sFOl>ELhgRfK/@]Aqb.c\#?/&`J&uLohDr,ihe+"1-h-`ddN0KTHaJ^=[BO51EuB>=4j;V^bM0ZDc98t#1')<$pI]j7:8N'[3T`;'!!ds#nj\8B6pt2d,Yc*#!]M.LH`rmqLN)j]f8WYPBDr9UO-5rsY6%nm[fb_j8&+4LNrK*Jd,uI0.nodE`5\J4I!=QG]pRk<%B@Q+RT^'N@@>?;Ng?BqbfBlFgWGM]J-"QqmWUaX]h:WeVE.#9*tub*k6@D-m33b%=X#%6+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+tQ@V51FE#9__t`o7:I3/:Q\bIA43^ZJA@@-P3ts\a=3mg!/E9F_M*CZ1#T&`&:fp/_iSVh>Pc$]XF:JaK&n.dZ`(cF](3lG@;JH^IC3Ob"S_n%oMEWZY#8Jj7>kKrrDmfa+*2SRFXMAca4cX\7s6_g)WJ%THW]DG;.Q6mJ/,`q[Rl+!SI,L&3t1WFBErJ2)Lk.pE\LbQ;G)Ql`Wm9[CtP@iX@TpmCYZ!Sa6aM""A6%oi.R^T[D/OPn-+&Ne*6U`cPqhp+gH<;H2+/Q9uVk!1K,`iGaU/TO+?:+sPHbM=1gZkXS]LV;c[U.h9m;P,5:;Rn#heqpWC1UK[Woede83BH'FM@&%T`Zp,Pi-V/1P=-'`:l/!2CQ*P1";G2uMp3Y42eN9q&2TV[F"Ka3dAn?1+fB6q,:uO`8oR;-N1`/lsO4Bk]"?I.\/snAsUKTXiBiO%-JV8LL/3F"@RV@odX\+LO8f^i"^)rr\[(C"LpqJ,l6bl\5kd4D>1+E>giF,K5jnBS:JV:fq0!^@aE(Z$AJ+3\)6\m'BqFG;.]VfXNp/Eikfe.VV4VR1)bfuorJ9`FnJg;oh2m@MB"Cl@\2!m*?9*JCj>7*VRpBP^YatLA8DYEFg842KKNqmPHr96(81k"+iNMN2?<^GN=FMKoO(Qc/:@`4:^BOla65QthG8ib>*aL%Q/nZ7)G]Hf"K$[B0OO8Nd%UeR6'tBX$f+HrG9'd]3/%(-,H9c`XYC/9nEWT#A[16WG9=E;@Et$4Dd3`dlYF9uDZPB_U0#go[`GDiZ9O!Vg_b.s75%<.cu0nfK`GHU?E./7%63`+OiWI^rBe1maZD:F3&\NXK.kN/-+t5FW)KF/!q-TP8IRmJ8\O'%W?d+a-ulMY%I'6psnU;%XBP&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te(*i>S`g089e5pVL_R:0&rr?"hF)0lWrrAgq?ieL9hn*(T\!V4'Un]e%QrNiLDF^8f".DI:sIPh9rB];48*_b(cl.c!>of^UTBl)/\>T++(^&8#Q2^KX3pDp]ck85)7$i.K5L<@XWcX=aCfdho]W/\F4%)p7pq)@.a!$:B;]].c@##fP6Tj$8!;q6(^sHPM^BLoV;,"8lRlK]jHfC[^Xnm2o,ae5_M.!7%LV/iZP@poW$.A(RCp]-Ohmo%7ktO*N/9,HDoq=2OM.HTja5B)kssppa=&7=])H4_4*#:Aj5lAWfOfZ&EKP%WdKj!"M)UFm<=k%Z=IBT=Fh5a)VVob%>XNSrU]],AEbmo^dtKht;je!Vi]r11L_fJ/a+/U;GpPlVQFAQ!NIo,pW.*W?`mN3@>^uXl"/CqIU\Ws-Z?8Zl%Q:iiYG'.IEtuNu[bYVoQs&Z$Lq;U>]PcB`F$.QiH%=[@kehTs&JB7Jim)LZj%&^@r%g(8el]4>"]/a730q9-)FKobKS9!3$ot$2b)hmNr('jV[EW6#7XcsNg267TbiQp_]jL8B+E,0C=Y]_D'['U:t5eNN9VKn1fWgF``KLA69oaqraCUeQ4/'RddbPbi$)CB)_kMf%lhq!8#GEk-XTI@=#>Rk;a;o1m]_Dq$koXm-8i^oeHfcq4/l]GF-ehICIt6b;d!fip0NfERCe7--3Sme;O(SosHYVQ+$R,6TLm/r8k+liTNXe\q5,/F;o+DCe?'L9\)!t#i[im=DW+a=%-cd#,"u]St"ChqWpE3MbeSSo"NLoN3]UQQ:J/;7Z[m$1cTUDi3E:^Mk2m`NYq6UfkpXMA@Y,0[Du>i66@dBZ'?t`_1hFc*n/3]Z,^KpH1oq'DL&2=P#q[P$\bOg/#tU)[1RRrQW/C]=AJ(J&,3AQ5o@"D?C=i5$omI(9%D`>#U8g[7TpdLt_\:@KeP-9[XJiP"7&lZM4C:cY8NTW2Qk1(T:L_HMEjXJZ\>N,3>Ml:nDlG.a+BcdcG#FfWIP7^m!)nF;QSNNSduebIYQPuDPWAjTbkrfhoSCIkt2%mrO:2UMr^lkk/YR`Wm1S'8an=8JGAtOlH"s^&*6BiL4Fb56`kbf![94QG.CpJ.ahKjg+FDd:SGmelhmEi=^afA`e.jI^rYUhlB-$g7eNHns3i=B6Yqc-aOi$9#kc3V5S1BaVoM]1'UG7OkIRO67U._UMK<[`nPpm&j"_M,%r$Ok8Zp*A[>'L3``ht[$bZDV$G)8V.gu^7&5!AG9&cU`N:.c!o;05]F&WP_tB=Y.pa)ZOQ9)oHWEFXV.E(pZ>K%I_ng1OILV5GRr2JT-IhPHiI27XoKn`:J%)hRVJd/M9=*L"UnrUNH?qf3jD2;r5Lr!XW,#F9/UU2&FRLs(CshcZZ'H1U(Y;t)FY>Kb,>O*U$QZ:J4,--g&'#Bqo@k/u.+MO#nmPOYJ``j$Eeaa@1@6['f%4*m[jc/lcVm1_0Qb]s]687HbgP+J_eu,,EsA4n7o@;:\hRjVrr>NnN@D40EZ6kT7;YBrhUPg$cVZXAB1V1s%qbBn73eo@Eb@OAg_N7o;%XLXe3l\m6psF26psF26psF26psF26psF26psF26psF2>W%e2G5>o'C[0lUVhf7:ZUbqQ%uG;i&Jm3[\>e".m2"[<4OhPQK5NSo9DsG&![Fb6c%ZIbH4\b@@3aB@PcCI<.l=QH>'P29FOJUaqi0U`o0C/X&llg2cN=J:!-GJ#]D?HWQ5mSJF7!ss"l\3)Nd_U#9ob!abFYWA[^.=)Dq/a:=3BrVb9:h?,'/fP]O[A4;J%3Cdqn&J(Z@01%8c!NY4%<8O$S68CT1S$p$s`>&,W;&G;/4&Xjd)Uha"l<^a\T!@,Ngsli,o9*+*9Rbeqk=6$\`)-u=LjYT:5"h4Ed/@M*(gg:@3a%_YPgR+.obP_Eo>8Oq*@"`i&'1"uGV!ZJkC9@]ik.#[ZLfZDHJ>7lh.MoLV)dY<,c$*E32DdqWQFKQKtp7l3urt-2q_O'c@2BtqTZlHYYer<[bJeRP?DF7[G(%jdaK,7G7\*anN6m:U]]TFF%@DckTCEK4dG1gTfm8T':A$Q_T]>j_9\G250GmUdKQ>#fEf#I4p'S$_OgA$[^>nQWFujF?AH&\5sEdGAqQ92QckD`ghdUN#!"7nF!A*VukXdnLb/XW+YGMl$1XQQ)bQ%?Srb[Be&d@k=O',sO>uQ*1]9%8*P+jSDT/=DgiEqSN*aL-WT`WO\W'Bq@i>d*-h8LWs*cET4O"C3?\;*Plu$^L_]*QQ%F5[8sif9m:5E\;AOkK^O+l5TPd.gSp/ho$U%YmB-&j*S6VY`p7+B>M^t)]JNsaGR[tPCQhjOeI^3aBs#fA>-gh3*cs8jS,%%]V=/&bZ\-%&kkFPNg0'tD9bg%[jFPb!f9iAgSh`e5Y1SlHlujX&[Y'9O+"/ujnZ/;GY/sb2?L%KtVW1keWcKNK!59dP>f^/qG:mB/8TT_OnJDP.UtGVAe=Rroue&6g]+^Lp-Cf^B)k"`:;o4r&3a7e/#"rFFn\-e'+&AZXVADQ'S(COJ$Nm!e>E6_*n\)#??#rq!T(Fd)$t.e,N6L0FXB>ZZnmC*Fk(=e[)a+sJ3TG=4hr?@Ch>@O/h1tNsVS]iKDrTfAt<6UQVdOq^3pN;$c7FNLa65b_@aHm+;PclErLi*'A+Rp-WT:2<-qOXAIr!E`'Y!K%2_I$U`aopV*>a:=;]9Dor*eH4K$(m2"4uDmGHl!Bg.\*8J_-4rHE[L1hpJf/ljuES7E24doSSQ*Z&cVQ+I;aU@2Tm^Lu6SB%9X!_=8m]:1,;bEH*Y0DOYcMX,)^LegZJ78V+aSho'dObC-e57i!=G+iRZM/'Y0rfORg(r+<5Q2H'nGC?(N9[okWXZUEe_@>=\3LdCT9YiHF7'Z-k\-l\!bYO[gC.h==K!O,g'3j:>e5+@%"1IHER=fcu;lgWZ4bL"s;A`C2=V3[!e%7D+t?>nIZ:]ib*K*uFWG)g*qE`cVXq]0V0_9U7/e`M>PXJubASic?'NSZi:DhirkW=s(oVg%L03MW[E(EjjN9>;GitYD^#1HMBa-=+*a?<$Ar8hJaIX$KHBOu$%OQue]HHeUQQcl)*Gqr$$OiP!">tdiGbT0eWF+63Q\,M>5l%H/SG:mBtO)g:@%^Om,/d_s^)m'Q4cIl>(>od0DSt;Y_"HgqJJ1Z*f3]WuI5og4]SQ%$M&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&TQ=Mdns%:=]nTA&4"9//@%5mOg1[*3Q1Oi!(eIKE8<.4gE!T&o6IiEd*PV+qO4FaM$.fc'*30GpH,-R!$mcT!4@HNnH2GD/]=KTL0SXPQPe.#H)7OARBQ0rnn1l2EZ,tN*ad%/iQqg%k*Is,D^Q3EWPf$t"PF9RE1Mp<

&]rN4Vm?1Pnk/A9,=ps1[S9>"kE?t9(Q/#Ir^^l5i]3T+71m;"Al0*7"RP>ftCUT6Bo,9]AfsMq3gqhD:>g_B0c?2]U"I/Hm82X9H#e3u"`SZCc)m?e8?DZnp7g9otg`0n96S1$Yhf5"6[JX[cF\d3UmEVcc;3QZ-H.n(CMVQ?u"Cb[m1]8oj<)E/r6!0s<1ZHhq+#pj*^)_odq.'TS`cg*\D_QE\A+rZ4K.Sjf?5k,%RY%EMJc,k/VQtN(G53!:@36\uY;j5VIOH,u)p3,T]H63o`ke\8ce?`Y4nlQdHHE.r+olXcfiI;M_D:D9UohT(3qK?8&F4X6D#2J9cA5Kj`lV'=TiWI6RZDP6D-`HYUT@MXptTCC=/(8t]fDpQnVNIWdigNmB-L<)D;bGf9&*7012bBNPXB2a1L\5^rSA)ChBL2D3tEm`T\fH4$<7#.OAk3O:"-X_.=Q^QnQX10fj&:V#;bUSW5.mNe$?lIMO#,FcVQ`'3iIHPE)@q%(s3pn(5`U?j>49hEZMkp5_m1S;?=qL]6E)H6H69X3\UYbT'^NTF"Cjeg2f?;`f/A"1Br^b%e>s_^fJ7*a=kZ$+qT2b.A0ma?tok*HMe20(D).`Z94CA\BUNV1-mTfKGJ2r6Mc#:*g?)T3TQE&Rf.'"P&o^rph#pPfc!*](V]8&4p#U?#H7sml-!26Ug/!QTR'LrECDYlrXHggm)PIJ6goCD^)^@siEh,^U:#Oqng6*B_A/uR=Pisti\oIeW>]\L9l/=Z(jbn9)rtfVln]^-QiXN>5:4/$j`<4@'[Y/O&p9-oY6Y85Y;/$eDG,UmZeFi3Q1d<4Ni^8P;?oKd7oL)9#;PUbn(\J_kMc6r+\Aa(ctLG-h'/`A@q^JEGEdhPHip`oll/m4i?tP:d,3W%E#4RT2eA=7_IB=Jl;bD)TW*+YL@5dG8pZ-Ri&WW"mHE/>h77X$OQ5"X"d@MIR3f/IbC-\H(i!c_Bo74NfR806#@[u7&:5/@2:,hEf]_;Z5:$fEQ0GP_miT1f;XluJ&#dOJ,&V[a1.o.mh&:$t[dqg/a7EgAEg+nV#+`O^h@]8SnJJ.Q-tkG9?S@O?jY=0I=gAC4L.?E#)`A%Y*f[/kCX5S!++Nb?e`2TO1Ss(T_8CFR96&+[)l$tecD&P6e5P$\>Kku=E'6@0[ekTaS*p?UHA[S?rR%Zgm^LkBE8\,s^a=VFg>Aj^d+Abd+IQ@+29g>%I"B1P`N3b5=+Zr0MX3jeWD,7B4gVr_B"XFGfc/H&e;ST0oi;$[%r*p`d_0]>Qm'1G;eZX>2L?RNejKX]WeD2OahmIq-6&4QHD&8goUm^"sWaeSJ0pPP7K[$:c92)BbU"O__]L2>]G!(ktlGEbrE7R!tPUNUk1^Z`@NaDMa]`bua*QPK=fkLqL)4ecS;M.GfGO(kQFm.oF#Tn)^Co:5g\h@;LocFC1%Apb=+fPnH$q/2P^_<)7aD8eUH,RGb>JpQe'SnE7_?1l$X"rW12fq1C$VUL.N-?%X_T[']'&$j[QdF1'lnI0-oG5J\NhM.ZerZ@u(IBs!jXAnnO*MO,L/M%"!7rmc+e^&4]c?"h`S4Ouh[qfb^5gO)@hrX[8>12GOZ%I]](ZJYR9glSVS`]00QtXBNhf5pYC*sSBgS],m!:$Y@G<:!i@ci.U55SU5k=4gR6sSg$R@Tnd?_;Y/$YY?PU0aQ<+sJ3T+sJ3T+sJ3T+sOL=$W+(p.`8E7p3h@eZrjF!RHgfL-YACTX_@"o\<,:LTU-8k"I3sYC$VlbC#VFsKhdBemR$eWOm.8n!;,sL2YiJ8>R>HkkhEU`YNYbU"RH5&PB%WDfqs9nmsNf`;L?.D_JGuqBCUc-9?$aR9b,,/)"iV"QGZdJV_rVi/KLGFLBsUZoDj.YVQYFaHs87L#%;Gd\;moL.B)Zu17"OW[RTP*d`UPO9iOl/S)ofV1,G8\\S3"FI-2O[g*9s`\slJQ""^e9iJVBLY&_?]9f)MB<[LBEM73.99pm5EI`;eYT`?qVK%4.`%HS]((p$hbS1]48+u&4("2^k$t<=FFZf;2p#g.O&3T9(\("aO&)!]l&\kok$JR*H[nh[*)W`-^`CEOs;=Np"u.%H`gep.3VBC'Y*/\>8H4^*e$bB2O;Udp:(KD/g\08g_eGKV5bYU>Nja$Q4rQ>g98T-\^S,r,O>,A2cMMWD@P5*\aG*N]JILsfmLhgehT#4(He9c)G^/]jm[9+mMWlr#Uh-LMl(!-NK1b[r4S&l*CLJ-eW;KY*=Iq@m^i\r\2W@C+5r7tW4QANfmhLfOEpX:r_;844jN554>(ij+qEmCIH_d@4)]8DaORnYi[1Jo9^Ih$jKW2HWC0-S.RZZm6psF26psF26psF26psF26psF26psF26psF26psF26psF26psF38iWCpEe0^MHJSIl'OPI1VmA25KeGYTPNM8Waj'9pn$`0q1>.%DFGe\=kElah>Ab?bGf-R.'\)lC3`fSMg-*PfnsW(9iU7'+>TDA"Z-OB[ja+r'1jCUi\?6+ZJLL#3-@F0;m>*I\F8%K@3s1UG;\,3jqg*1pT`c#G]1E5PDrIYsE'.g*%$V;a`hd4mkI>pDr&P*Qs9bQ%*"?ap@?lVWR1m%]BI@K9$HO.pT@o^@l48+"]kP",&J8cZOV&0;&J5Te&J5UQZHT&^KOYg7a!\'%'r&f=28ZqurBsIM_Y:ZNeFX!=l?`]u"IfNr\`,oo8+1`N\M:0hj5f@u]-X,Y(uM]b<4d!E=4=3@%Lce0H/9N"j=1H)YMtm6Yq7nm6F&*+Hri#$\l;]Kb4gWh?DNk%8'X4*#c5X9`nIqnD\?*$FeNmoLW02oMZ([cGcPm$TYi_cd>5PlKNQp,?L#`"]md+6Kj[Y@!'_5\NdjTDkch4"B`agioNp_q(-o8E!0cM4KlM)"@d.&sfrCHa+E,]uhd:dtOrP"KqB4M7b*SDCYahtQ$rl:4DC2FBU@_qDi4Hrm)/K>punICOoVNHU'\,ZOkL@d9Aif1r),?!2Fo?2;Q:>N[:hQ7>LL[+XR'YiO0HdiN?G]D7@(XV_-t'[GVn>[H"FML`hqOrkoS2)I2#HcARq)s)R0lb_6_6!/]W-QX.,'fKkpL?5;`I!5MiMd-^62*76UQ1&H#Oo.c^H[pA%R;Vn=jCt%I-q0-O)o^Atq^iIqlg12-4hZ!R2^eP[C-YYE@:p&H4XP'GZ-'lM3C@/HfD*,]eW`XJ*=lbYL4>;[E>qQZkf/YOH/#)4$]gr2&CO:-ld^!RZX*?qd>f2_Ir&kc@8B6QZ'Wkli7_t#DVgL@%l#$qkBAEWmbkMK`93&dip5uVQOL:C(>:Wb;O#?8c+F&Q"!G/c]VQ^QSM\AC1.k/fB+P;L#(A=7$&iHi,falZRRf2OqZk't@rE?tGseKt_#4mDSY\Gf)Z8-[6_GhD&FrPbneeSLquTuSlmEi*$0CbCprXdW=Ah_o0Q_5EM,R)-#^mcX3eBV$]eLQop!j);9p6O:<(BiZ+)fT@trse,G>5O5mrfrC1K_#6psF26psFM1.N>3\g^b5Z/E%7E83Doi/^^KOV)^f2N(RigJ):bgF4`*qDcDmoTYHG(h$h=ehNgTTR6`:m^hoFU`;m7J%=B6`?;?=28YC6%ae?S\GgS+!R0E4'%=H5Yi]_cRYrN+b][Tf'XcMRGcL8]eboRC]X%l[q:62q1p3mSJGXHlIK';#e$j@$#C0h8])l4^kS>Z,fqquO\J6/kKB.4a*ThqNo_#RI\g^a07cV!'TkW9o\0-LiTjc7^4rQIJYC>/j@*F6,c)0WcePpJu@'>[brY&&_J8ma6O(W?%E0HqroU*E=X/R.iEVf0%3^+]S*%Q9BgFgL,$K?5l4*=]fMCbo^'C>;%YVf66D\51=7LOE'=MP5AI^*mt;0:@E3RIa=Y'@[%OlU^%<8QpY2n%J>D.06Q5$20rIkNX3[D]:;!Q#7MU\2)M[s<7"F\K\?*3@ic2M+;k+"'`LAO"EO%YQih>>7ZkIANCi@DJMW)Wr+VFs8-n<2bV/LkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLojBPdp-Nf[-Jj`/Adn%[,a&>URtpSUF3)gB)S=AL:sM4bmNc*lUbg#h%l]cS9jLN"IPbKKe0,&TYBL>4_2"e/ag3U7`,rQ4Re\&)pL3eXq$EdN7p4qUjKdo^K5QqjoeYG4&e$gCsDr&l-i.7Go]6RmqE=3lUdT<3$n*eDFtoI2/6Z[ZGPBaY3sGM&KU)Rc5/(*7EGU]'8.QV2?@0/bb;!kOdo1/TEdO&+JVqDRsgF>9)9r3,SHSPEqsf\d(Sg*lhmt4(@I24*&=]Z.kYQF^&J:PJb.%pi@.["[rF8ZRC!HgNR>HC7V5NV"HM2>2OELKD4bc)^p]S\/2eJ?\<6WS"S9'r8W3)U7mu,"6Z?nNj)g`k5qT*nlu@/97GSp5]VXY4\!V1m\:WAjKeEo6/'o_ZF'Ru"B3Fh2-i669,&&H:4\;N)g[=Q\QBQO\!GIO7&r#jRrr@;*h!bDq'?M8=BGG=#HJtssE6i.%lRjQ)Zq4kTUp/?R4j!#,>bJr>&NoF@grA2Y3LJI?hmpm/7AD]1Ck_Sjej*>?&J7LG6psF26pt#@O!:i<2B.BJPMKrTQCCl9lK`48?5XFgY\rX6T"k?6TrhWVPr)RrMcPDn`P/q>9d+"!q&,Z:TFTc$VMWN<)LI)#3J]h%e'VH-.[fF=SRboR_=j2DcWte=jDEW278Db]:sgFt/8fY.#fEF/=7^55PfFeph*kBE!!V1TR_^"Ea'#[9>K`cOFVK#pjelV^*q,`5>^^qoC?CPJQ70\ZB3/n2\`ff.EAhREoK1&Y[nHZOP@*tUK%34fp;[!d53Ya_Un,&lV3&CYB;mGD\,k![>;*EimFSCU-0!8e6$=Pg#9[!VtQQ,aEoebB"fI4kTjY^laH[*Z`a[P7(['D/NU^mWKMJa\*BGG,G*oS.30C.&[uiFf2!VVoP7V85Q]+@UOfZWMLE"hA7LVc1'Qf*Io2^I3OtKSKh=UZUUR:2;f6<6r>U7&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&Jn@8BXVFeRbJ;:L)Sfpb+;3t\nRYY*72dTf1dZLnaiCie*$2)\TJSokthW9I3[4bb:/VMEe]HuOJEFT9*:b(qOnbhQ-mS^41Uh%blmI1ALu7B11'ij!RB=.qYo[Ar@q/[mc5ZQ@p$7*Up^Iu_J6]1YjZET(KK/Ie#,;/A7(K+#bg)es'M:$/=AjU'[\f1Q68O[%sRd.D+)UiR!$i':(2>$;Y?@SD+sJ4l\:iAA[!P1sI8#$JA@;jt9hd9"B2o]_e$Jo"3]?sf-FCJ&UN28+GZ0pcY2"Ej^:R?)PuQBqK+kM-6^o#dHk)T0LGNW*48^R6n`cW\c#0+g%]O/*npHKmZg6a8EN7dIAtc;RIaS6B$(J[\UN0,U"E%7Gl$&'K&K$@^QVjhdrcL]d\`JtrZ`@=9_FR1]58[#,Xhn[sZU@(Z!!e$O2;iA\Qc.`6@a)?,e9lTgN]0d1N8,_+Sd*S+-ljjZNVuuQ1#Vt5(,^>&@Pr<=(Fud0\=Cs1AJLK;`/]k0.&!QoJ+"PJIL6tP"3!K!22?pFb6>lTN/o"'Z5P&o";OXk>$iIV)VUccf^7#GI+J2=B'$j@k6Mg6=[A^J:'mf.ju\\a*jO/0>&?28WXER""0*@7Z,ElXB1VE[!V_nEO\8D>=Wk-.nfPta#VOM!BSmMQhBqWYNPo_.BEb"AWq,fYQ3jRpmAasdk+4j[o_r2GEul=s)r-),^UHJ/g;c;gdC,laHRZ'/('o_PLkpkCLkpkCLkpkC8-u+AGlP-IGrIo>f::i%X=j53L>21JqMT2hWT,ph?Fd0L%2?ur,%jT_#T7<,uET_2-9%o%-4=Fq<$MY#hp,PbTDFIbC*IY[d4f>KRFW_@JOL4En)!D3']8N1eI&8"bE-"/Hbc.8oP_M(-!45AKVH"F^UE">Gm78YH;]q7TZLEd1/1A\(,PY9QfW"8jo5]e-iD0hk2[Wc_W-(LYD<=P4iTrXtUdsO-Li5JbBCZ0sTW9/HKq0;i^L[+27#ZE3sBcqKQ]qJKhVd;A[pe6&8@?]+hDX@jI5S:+2lZX1"MnpdIK.EJTTnan]E;Aj/iq,G>X$2bj>qd%e;A?L[OB":o<:0f07/rRN;J92Jf9i\/:5S5T+).dZJk1JdpCm%4q`#;"<=D!u$]0YWLh4[r=;$4(Ih^MV46`_,CK$oeArf1,Q:+8C6M0Uice]KIqLbD)OUITAQVf;]2u3>9djpVfOO$qM(VCLMd@<"n=dFF?Ub*L/1StAj"emm0t_Ygj'9A^"62:i_HX&O)9^42HI[=/d5K(0>Aa7:d*p69El,]Rg^3d-*;6^?)_6@dAV*Cp%$-D8413T7r:Vs9;bQ3lYgJ>S[Q-DC?B6AJiK62\iSsB[dH%rlE*>Y`a<,NJ6bs#O9M\4tG.A2#:o.)+=ed_=po\Yb#I.ljGI/n39A0)&XQl`!Af&O6:HXAE^k\:?f:sY34IdeEpP!3Y"A)S)#?9RV/4Wj$UT(*2n]5=!_Nm'dkd2AS`K2:DQ0Y8nB&(J_bYI4T4O@fURa6NCJI(E>'0nXa*XOofp/dA9C5T;k6FBXKB>^KIE>ABqSa1HXFs40gr%+6(*i$j6!X&eohNX84lHtbD5bho&J5Te&J5Te&J5Te&J5Te&J5Te&J5ccEUO?[L24egEMIEFStb&#eXU8"nla3!cqWYC4(8'/lG+dF5En+^Kq!>T7:XMW<#IkUFf)_'DNsLgUTC>;HrIuR]3`oIJdU`)\0``*\8C+(c0Z*Jm!$Tb;HD5fg$CkX,HG(t".J3!Y%Sr0!nG;aE6ZGD#;oNR>VP=Y?;7?J1;7L*/KqNE'VWQr=X[V.D(!=o(dkaenrq3I@V[J2fZSnPh$*KsmM6&`2cI2E%XhflE:%ATVQ>L'S*SrntFl5Abbnj^VXF0e.4DpU)-E"TmN575uqm)q8r;I-X+m5Ur68mU7ID5HA)2"(s7Z.t[\lCf*WoK2r9U4)LpN&Ak.LpZXmRc,")>Yr8U8b&oFY%fIBE[aJW=*bf<)LOsN9,?tVGU`(I]VB`$EbkVe44PiZ-@Y.\Vt4"N'9fRjYXBaTXaC7HOYLjd2%r&A8u\".kQkq(+=upLkpkCLkpk]NGRRg$J15t!6FaNS_b`.jls7c)Cem"'X_ue`pR#r3J>)\OoTO5]*CF3l;pAV(V.=_D?IhIri:p3f?$"3\Hj5Fg^"nI"[m,VcuLA$WS1+4nJ[l=U\H[\3H)l:F^9bl-;_PgUUu>Q4\=-UR9pftScf>.Bu`c8#YQjMEp]Ek/P+3Hf[S\>)fnl][YE7_!IDjOO27W6l_Cjc*QLITmC>8Q*;f&e4:V.MHEZ*Dst3%5W=A2JLD7Y'eeR@f.3I8f9g(Q:1d:>u,?s^#/9#YQt$$8p1[`1lB3ik@:^+9&J`GkB+?7=>jgd<1]#VT]gP*LB5rS[%;10O2g+'!352"lDEr2Nt"9FT4u>cq[5Ne*KK#pB%q@SdkW*FckShYFGu3A2_+k1OBNor)jE`ZRdgt%&J5i>jGkt>,MLQ8-Y1mFTp9AY1PFYaXLU`Ae.>]jGcl'Qr!T-HinY_?*UD3k#?!n#.I&AIi/Xh#Gij`]LW:ZX%VsdF&4]&NC6a6[-%35JB?6mWePT:)Q<7lI@;5Q14UCH]l46^a44QMbT[V#/dk&@jq2=j4.Vr+-XHE/5pG)?rO.1IhjphBVc.Cs_(ds*mJZ&t]oZDKb;[\bsM"lD6&Yk/qrO2Gp#+#997\a%i]))7"',NR#1N:IS`)TQG+B[hPB:bA/56G700A7`]g1U;bj%0mM7[l\GJ_-[s>QeOE%)n2*oqdhU*Q>aMeF$V%#?+4+ie[8:9K%ER\ki%KL^rX&phofpg5hWdBgS[ctBmgnhXQg\T)nNoc2V6rfABUM)fb"fkYXClI6psF2F.1H\iW'($:S:aSTk]T4VO$[faQrj+0-a&dU5*AW3W'Stil$HR:Y?.u==^RHJi7rr?g5L&V-JNVRn':S^-._tlJ(D`Qq;_8#i-i?'++WuXRU*I+=D2R#g?DB-ieL9II%ECu:F[2`ksJ.QW7"-=Nigh%4PgCE+8Ph>2Xm+eGAb\`[?64K49!AdX_5`JGKi_F#&_(FlOD4&14_q5r5r2FRCDjI9>>5KmTP[M(QHDW2SN-Jh:VT"GsAXLhm%ZP6Iqe]%SVG/A#+qrRfPUd`2^J3[ZHF0C13#kZq`>>#:[mu;N\BlS$_..eBgO*rnC\PL!'WGr\@\'5LZ]RrrBXIVe8G<\*Zff!&fu2=I_^BJ(,O>(lDH>Og@D"UQLQHCRTDu,I%L#W@m)HNj.8OTqRAoo2uHH)Z#=nV3$c$4j>U!q3"@^+Q2]bS[Yue=S.*iQ?W?/N'UDci6roohU@qJA,,Un8H/\[+^7cbDl%PDRQ0Agqq8fpnb7XdR_')spT=bDrr>K!rqYqmrr?a^rrD$IJ*98=CJXh6chMW9q.]`g25gDVBDafWr3\WcoK=l-!:qb"rr@t8r2')`dBpC_!6/CG!;O)(!6\^K!*2-rrrBFpq-9NKL&V/5+70C>rUUrVrn"LU*D?B8Ieet;rr?ifrrF]5NL>qlYV\SYks!jn2T`L/l_;n\uJrK1+3G-8Y?+.rrCJ1S(jq"QF@[J\l"%-)QLs>)mC>umS=rbT@$Td9gMbXXsgH&aql/gR+@o']q=fZ?h2f+*tat)E2nYILF..4775"573/\%c[3dd1]\[r8rMp_.]sL_d*U65;,L0[*)T2RkInh#)?B%o.l+IN60WLbQ9:?VL,t9RTq)EY2MHg,@o$S)3]Z)Jl+(u07`S'27oRr,="%JD4$0MKY,(P/74i_g;+I&%[$._ueR&)bDq#+VI?b_5O:-crX(`RV+GMl?#2aA:g,\!Z4\#ATD9^%F]N_Zf>]fBatjkui!8/i9o_b7&n%\`iaJ73>mE.`6;>gZgNL:T:hOcRE^IDPQ$M7O'0=Jk3Hck(2jm\+E`B[e5R>=cJS;4mFQ"AISfMSPTDVKqFM1T9ZM\EoK=a%f6FT_:#439%YS)NQu=nf,M)R",h&,%@,3A"+PP-E(:)Cr&hpGq&8/s,]BN_g:KW/_TMdE7GKAg6psF26psF26psF3A_jT.92h!b<-LCWHKr#YeGd]jp,.Ra"%P.2lh>IEl46[B[r4=1E@C&g09j!eoaHi"NNi5$%-@QedRUrsp%uCPY24;[B"8[`lY\e2IBM1)DM6Wc2sOTmJ2O-F,_pLBJ4G)X?c.!+'uH?kBINhR\./]pbL:gN-+1fdE[+!gqD,jWi-NolQO9CO.l99Xp&'7ce?BX8?>;]\K%jjmdKG+DFj`t?B5J$QRfO$n@^JrQeS;do`e;Xrj6)Z^ED3[5SULA'$6q'/Q&J<<(>$U4j!8N``!/QLFep\k2=?2um`(W*/o64`NT6^i#lco9E+/1e,;q$ubg<6\OMraOJ7Ztel;UN-WQT@*s,Mmb_5["Z8ir8-4H?CpdX$eg[p>BY(9;=Mmr7+Z%@J/JTeahR\FNUU]l3m]RHa\"Ldd)*8^teqiMpn'.TYi!f'35YL!):.Ub1++30)6O5Hd29C2/R2'\YYa-DW6*e+?KQa!RNHVR]S[uC5m\f\4pVE\(",O?LP[!f+6T=92>ag%A/'oT'qV[PX3(AF-$:Mo8%]1dL,^bRWi$%98Ehkjrg_6@WZRIB-(7SQ8#&X)c$eZ:N,>PYha2-GP7KN:k.:*Iu:n@3]3b"64F,*B]a5G:B6s'k[`g*qO@1aMT`*l0n[E.n.tf$2rjPtm"/7=;GgIrarmCRR\Ea6O[`[;p]YkFFCS<(@A\Y[]*>n8\tU9ZC&DQ($U6(RkpU!P;,Y;-&F@K*(t&*^b.8L0fgRuPq)'chj_/SNQ[G*hSKW:F0FnhHZGR&_$/2Rhd-A'mmGALS=BnAnVS%B.F'JDq^.;K%Y&Qg(5DRWjn[2+5m]pc7CbjX-5VSJL).J7IMtc?6]G]Ci_1X/-Q$=>h0)m]"jr"uL`B%]Q#tVj$7C2O><$k]ZYNIbRZ-D^po.D>Jj_[B3q+=O>DV!&ak,U>KKtN*1ZA"UT0ljUi):]L5.U6psF26psF26psF26psF26psF3NgrE*#V@6u"i2^5Y3Qh>i=iukre;iIl1u3FDdi*_g72psV80')$3?9&]R$]ou%p`@a6HB>Saepo=S)t#bCtqPTIt-M'Cg5Q:`:bZ0%B3TUp*_`:E,(rf1ic,&$*BLn7^ULVcB.2?_c8NQI'YUiV'=:bRLP]bgGRpnS/sZ%W@*s*olMgk8r4G7_[^8+^D>J0EbOtX!=cpqRY9*=XD'Q)+pq+nfn/XIE?US78__B5<,+5gFNQTZ6:GR0X\V]L4V<1>Ya[JM?@`KR%'BO?J`GMHC3TUm_R?A>WN%N]RDFisqj]@[rWRkBIQKqqPc"-hSUE8]XQSHn$lu]=E>0^`e&kD%'Ig)h")Q$D@Z:QB9)\;l(/#6=-$+X1iG06`cM]CrTF@EA-(A&aBoa?ru`GjQq>usm^;MlB]8lsHl;Rfh&rBR\[3u`@QH?Un,&JrpH$6gZ<+sJ3T+sJ3T,-\I%%*.a.,a_#B<0c!?d75GC%4j%^CkI1EHB0Z4CcCd`CUPmc1@]:hk5)A3^=&$S\&t9@?L09<8DZ9%grEppDV\:R4Oj#nq:.7@)]D!)H[l*[Yj-Z_mJ*\UIQrZV4P-X!Y1>'Ee^[Z>0uP/0H2WN>&@bthU27cFP+]tXRE[%T8%(+u)@sF-/mX_-EP;-_D+TPN)B"cQ#ej,,3nmTUlJL('Ah5:jElXocb?l8h&6r?hJ-+mn]oVMU:N_GBR_G#!@D,d2W-"l(XEVjA`g0dPb'(1Wo^T/2N=69OGADuk-a0P6'sC&:VY1g)dJt.(gs?.UXn[Dl(CSpN>h`bgf>Idfd.oV>#A\O(*4[7;/sU+Eq3i/#,(('BaWlqEY@H8o>Rtd>mMF:a)@N'#"0!RP^4dBA&4'#-L7/lH)gahlM_YkpMMh6kkGBH=k*B=o8a8hJ/pro"Y/%MbGUDQT"B&_eaLCO(u_d)P5I-,:s>VNq!I_L)F$d]pK`"d"PEVYfB#_bIF,7;B'i2hF+_:Mm"e1\f-T?2`;g<;=>pCE,baO_%G"d*#Kd)>uh2D)Vm(G0uQeX+YpJYS::;MoH]19D4uJEb78ib3F0me94j(IuE078jKt%mX7gEX>KQj!W)("]f9;*r!2/m'p'NUZ`+]\:jB&1Y?1h(G%!bQV"Su&^YR&oF':[uGWr^]aCWl4X*^Jc)TsFB>JItaYrE8n4"-'l;g42s/B(:1nHG-?UF]W+c5lL_7cR\(L=OHogorj0$r`_s!:6M&?i(P&%.Mcbb)1J4/5cK14cU"fLVse[/U+JIRlFPC*$):kBS`m!U*:d*+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T,)c+Ljf%uPP6o\WI$BSRGjZC5P$s(\Sq]4#hKupDQk(iYf5f[sqU%Y:QRQq4er,]:&#hSjWD^VGQ.^(abj6("`#fP_Ac#4/J_'9nGDb?uM;Q6t(o&>Ir9QnDf:31.?AtD1'"#LUNqO4edYf(usm?#P4Lsl+#D>98TS1X\LlW0eSS-gTqGMCI]`n4ndci[YiK-KQN@L'OG\:Hl#8oA$fa3a=PmmF;.\Rc/jg">I-iGk"g"n;L4Vb6si5i)]M-]/-`n+'fdS[jUi)8]L><%iVh])2\gl_[*^k"n^udFn],KNErP:RJSC+.:(CnC%AO#G@9F([_/!p)VI/U$3:s<-4PjVKD48]0L'4O`k16B]=.:F3SRL7d4Hi?5RtRn?=sRc$kUcX\2qElp@1ZV=@O+^crg;5hqCc>>:7C2d

k]I!!BXIhV'R8fh3JCFlhd\%IIqXqm[U>uaTE9Q3'/]X77>+$pIXn5+O^RF4;4O"8=mu);_a;Zh`I7<@ls9BgDtk"DdLU0'q]!TZKj*bWNbJ@_TsN=Pn6g(O3DufHcqOjj]ZoD2PLP;,&`m_jF-Xju8i`G92INc0ROc;W)L=Qk?d]m\uO8C;kIuMR)\fMRDp_UMThA2YB4$AFf>7n$`2+oN#"nBLXk\eDFg!feulIAYH<6>HXiXP#8\c-]lp$-pOI#\YILTF+Ia!!7=\.0Gqm4cn[EcOdb\i!NcL[$P24Gn/A]W-D@*t?*DrTtH)09:Y<%QA13J2RIhN];2(e,`PbgMrUSrQHC5]G(R(n*S1llc"/GU#BpH99.#Y5d^lQG'!2b\CuEK7KW"mKK^eo@=,?l3$DFSG>4(J0Rg>Lb1=+3fmT?>[IIJ?%kiEHTp@:F[*ZK-U)<mY283^m%SYD0\XK\0jH]@U?W3r.%^gkEX[C^H+C&$3N5dR!;j5/SJf1pk+GQh-.Au$Yhe'iYheN>TRPdnbo`GqIXQH+pS7foQ$LOVeUf4jl,,5,`/V/E#pXhY1%c@6K>4918\HXcpqc6@!\6.Jh1$iLIk!;tu?Se:b1/;qMh$qiIeMmaXj=td6XgM33pCfO=Qqg6`#L$&V=/9q^)!#W4$m>YI*(7OI$j\61Wi0D&IY_#)CY*YpR4'8"CNk]/4bXpj'0"iI'dH7"pLN-UtIU"GRLZF\9gNm[n#1mpEAiifg!6eS'Vqs,O,!'R?dF(+%Q'hMnrr??(kPkNB!U91Z:1WYqp.cE$;"5Ub`P_eYUT[G&p!eKjA]%a38&;kX3MY,]C7Vg2OB?B^rjP,tm8gB>9pUYgj'YW43;GYZJjt3*.BWl2FFsqY&DL]71W\:)lXo8T4?j^BVOC[Fa28q^jP"mQ@o.$]c:-Qoe1:Sr./&>I:1a$rk)4RF7E/e:4]Qj/RDM!/aV1q2^rt"c$MZiO"u2%>r&3c^N$hNPMI9Dn(MoKoDni;^HGeErr<8U60>cK#5=,VjZY@;rT@0&n5i&j_=(!jg[0Dnb3FF>btUn:rrCbgeA7M>2fV$r@&#'Vg]6tCk"k"4XVLd#`,sTAZa&>W=DDV^B_`57S%mLOkbCf.M5M0A@ddgQD7522o4Y4ILMrlT3=kL[P^FYLF"mlXlVYTQ]=kq6A,(Bur7+!/_?32s^TqTlE>QO:1lqY:#[4YSVP#2;3cXDn,-9pU3-pcDjohq0fa+G\q=>9K.-*7\n5HlOUR9)134HB)0kpE?`\b\VLS7S_r-YZB4m$o_U'rh%;!Br\YofCN+LNcFC(`\A\Y7BKX;VQf`)`X7%=iUA1-gj`2W:7)QM[]ru+*#aU1f\T7rh1MMtI(&=,%oQ^/8C-63<[MV@Fi@rD?Mc=C_3Mm_U"5^>)"(bp@.0@i;V]s:,uf&P?Wm>paqfk;4c,XDKQ`"Ytl4KjBRg[)BhIJ^YbX5G^LHX`,`lrrg_q=f)G^dbla7iS#2b>o^=$]'_M#r!.IAe%,^_02rQWQr#V/&[^HEi-(S_S,7!`dd_/Ad$RVG.p9/"LjFC[J=D;@-hm%N^=">6fk7@m;AMubm\R"S:pD^MlVTDauH/1bd1f@$Qo3UWcq"_WdYAj<&WAQfBBcs^LP-Rj!\u;>IKh/f,9'GZNlC.NZNK&NK5C!PEhemu2$0l[S!C$Qa,8nQU\$h@+E8&K#FF<'NkJDCgS2)c]NXb!`>^@.OB'Cq6U/'':@Rtc2`[I6*9#A9QoKZP!:PtQWC__0"([j(F/AI)Vqf__m2$qW]S?Nb?r$GueN)\JYN:1Vf1gPXVf>*m=3FGQ&J5Te&J5Te&J5Tk>30b!Zs2fJQO/=Ee?QSf?@<^rkNhbGQ#CCHU2/m5EONauj`B/rL+*&nNF\#qR,=Bc809UonHl%iUR#R4RI+dJ7kt)fH'Kp4CZK8;C^CpI;8ddSWYq@3h19$oAHQ7Bfr&H[gO>@Ai4si22^@<^pPIsV9U.38B/Va:p$sic;pS5.paQAhk%ND==,lt,StgE2UD2r@@9%F3ba@H>^&%g$K8#Yhj$L9lIEltMh>3m@'IB'"3e5b&BjL.Ri2b15_!p9R:*-^$:G3dV"a\ksd@=gQ)X/)`^(gB@p2Mj(EpW4@=C\c8YVgH1+'4*FZlib\L1UP/S0)L,48H'/tL/P7qmn,X7P/rE6bZ0`O"edmUO58CQJLniZHHqF3cYp02JW>nu-k;mrIhL[t!A[+,Z+4i&npo>1hXa8Sn.>HlLhbX/$E5r\(p6(8TLN&X+B/S.H50&5>^9)jsrJ)Lei(--S>>u`(;$U&!Gh.'nr3W)s.!T^tA>3=(4;:cRqWc!'%CDiY?4_`9+=/g^MjE(!Ibf;ah9'nRGbkg9O3piO;Ca:3dddFf'B_!%VoN_me$KGlIcTU@,ur?QR,P3m:HP?oiK3u-8(C_^?\V<,p&X1#o*ak)j!q1DZ"9;E;LXk]q9(\m7fE)\fM].2`(lP.*0E$%D6fl8!6Er`j:V?3]RSd?bB;dA=D`(=Z/\^57c)SAXJ[,J?>,tG2)W763f'?AIG"$TrC\4i"2h0mm/0L)e$%Q_>at`n$-2>'8'CiJIHUq5[<#Ge4BGMu)no72:rh%ScDQ[o#LGla;Lbb^X,Yi=96;-6R8^9]%N?H]32tnUdB*T0XiKY;$niQuWAfhT@N=/*IMn";._:Ksg-+UVhA8CFY&-VsHEWCSWmZ<%Jo:Qn(.1Q$,N6=(*8CJn\I03r'7eph[,'.oj.uE"`?R=qY/4C_@t=LF89^>oqFkY\W\1.gEiM8EB6aDJZ1r]!m-)+9h(:Qi*Gh%reZu@8O0Y?(G`Jb^0l0lm5<$HLr^_UFBY=3QuH6'#T][rUB3mZ!)jhjZ)`?%,&2QKlIP;Nb=W#EGE6Wqo;T]2U_DnRoeC!ncPQ26SNb(r)!,WNUGT%/C1,k?oA`Pi%:AXRSN9nject'ZoAU*pW&oJl4d%RIRX+lB1X6-:PfW&X]>b0A7M;e$:_rVIbpb=@`A]2S#Hf=;NIsp<;O>`Kn5l_!FKa1ZCLr!*BCLWTbli/SXiZM.V[&$Y1*hN+FfU,0b3f7XgmsY4`mNdO?@^pki7qHrmgc]JY<.8XS/%IeU8(j-?`2,6Y1qINO0jZK-V/U8h&o1_NM-].u:23;rqn^BLB]^lJTl\s]ttNQp&GCj^a%K7@9O-FDO,h6uFQe5^UDI(q0F62V$hQLV)oPF>`6gD/@bhPc)'[d(5fNp(Afje\^gdS.gK*SJqc3gj/8A^+W`I*#:k+5tD^`a%`am5/[?RSW&6(E.UK?`[](P^d+T8VBr2g6US@/V_j+4(_j@Xes:]rr;jq@qIUrrBYC=FI+H%s^$#Ojn-3Y1mW")]-rTB\u_NI"]so@D?/$b:3(e_mb?E/?"0]bV!_+k>"C4=cq%tHT60*a8rM`^LC[uD;A::%N?20F,tIXTkq",:YhZpJ]+k+%WdV6ZM\%:eWu]3%B?2%F:pt(7.7_VaVrb27o?c8JdCR,X"VIIOg212d+5Q(eq(%*H3O/FNN])4*U5f4G^7ZL7IqUikoM9rRSEUXB!oK*3qq??Zq*Cd-mpV9\D]e#I$.[7fbQ@+p&>#dY7G\?pjlBrf>_Dn+ut.q(7@GfGL_ur-pB*O4`Ci'nOq##X&crPWp;?SCZWGf92NLdf]7i-_7u@.=2BjmGTQ&/=F([gZ;'mQbCtp=23<1iCPp5l=DcW)F9?3U-n/:p$U:B*!7CQF;++T@P&=7r+sQ=.DH-=VD,&Xo"+b6<+S6eW#4J8\"l?B3JqA:r4S(_CP4C'sV4I+(n\h)c%-.1X>+.Ol$s7ofr$>D+sNFaLkpkCLkpkCLkpkCLkpkg*D4#8A(^e]Eu#*tS=8smiM;aGc#eqY".f>V\_%MOVd7V7ZCk>Wa&?b"(Mnk)CZoN(mg*XhI%e;"mfj;q"=rL_C[H0JG`KmZ,U2$pk6$logrX37opOKQjCh@I@4_2`RbnF=9>[?%85Yq.+ehf\:AhkY(0]uqo3ESD\[G"jRH#b[Q0>1GaZY,Lu-t@-SOVGmfGRge$i&:D+E4tmoG?hDI]7S6!Jf=JVH?`;,&,0OG=;DdC],INQ1p@;@;d[)Ri^D1"$+D@R,-R0Y$0rj)WL"I;aIqDQ>8I&^!AH\W*e$H[2>0/#B8%LkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLkpuZc"l$8p4kNC@L1a#^JPSb,ff7-3'M+("5FCE\s\6?qNkrgNfoKEdSdsg4Z8:N^YlY"HZGE?6s_&]+sJ3T+sJ3T+sJ3T+sJ3T+tG$d]T6`f54)OdKY@V6NXSDI_o3%;Xk3o]`.KF.J8smL8&-J4O.GZ!#S,@IUJdS49)]^dJJ<+]icT-U`B,_LmF11*qFUN)CLsD%%7.th>tEGR[o38fHqTss+/.dGjfi9=*Ce/QQcg=[/@![Ll/+$\Nb"=Rf#R8C)Y/%sF<;7FU"8")Q0-8=\5H!+jV@EMaD'PH9q9fEfRAPArc5\lgj7LZARq+*U15f5-EZ-(@>u4V!!%J>cn:Q/*:YIR"205@tA].PfU_jRD/G?rpUhfD?7$%X=DD%BloHtGo@96dLM%"[YO8c>nIn$'d=hG+sJ3T+sJ3T+sJ3T+sJ3T.kV6a[Fk`'cXt'ugXQFr:K(*@1);V!njm:1^"glt)@$/V,AkupXc28cZF9;AV7b&r"Cp2lqos!&-\'p*o.)RQ`dnheXiAOo(Y*BS\Rc/3;je\dRok[KW5hiP`/pTYEG2'"5L7Rt$<:l>Qa\_bACi5\9\YL>J>^#d'e2\bY]cOT'BK<1g[?!H@;ql"pD">3eb^78'!;,P;FpG&G__+!2p9Dk[<->ETb`&i@.k9VC6O=u_>1\)0UPTFn/I-.EcS-nUQplA@>9*L=8F$@QE=2s;R'aK3Ea7dhibr7@/"4%j;[D[0&\#)d@cDZ>g[G;61a;j-fcqF]D@UH4/Tb(dQC_POIX22?#kT=rm670^+ZRM0F,YspAA/3G"kFS6"C?Kr[,QSI;un2["^E9qc?,If8p/Uh7m3U`=meqpMSNQttq!T<<7]Go?37c+sOS6$?eXs[0uYn6%igO[qoo#ilBM\_U\4)tULn*_l\Sd[pkqRA([Fn],Af=q"6bILpReHVL5;s]mZ*L^-a&=gJ#2G./tp'&kRp*B>7mWLerY-i0+Q:cLP4_Y'#5ISlEgR::G]#2"U)jC3_41_qgcu<*X*?.YHCC/S9DGb3H\o2ptOEMu+'g5KJUc*3V-N5ELMUcL:+sJ3T+sJ3T+sJ3T+sJ3T+sQf\Jf:R5V5T6V75G?m0uItmOg,/P6Mj41!Q)lf#24bIits\Hi"ad@?`0Xq7O_\-1mO8V76,AYgr:G]l,lc?gQ%iAqp]H=^4sHM;jf5GQE1p;+`K$7Y&X-h]J4q\-h!XZga"E$rrA$_DcKimSQ$lb=m?/j4.=N$G4*YiLSs,4;7p#>F+2=RS`Note=4Z,8Rd!.Q.gG@30's0`fTr.1S[Sj^6G;Tc2b-urkis;]a;Ps6\Zdqprs$<^h$I&('/RgfYl$@E(0D\TUD%lH@<$HWu6Vmaq(f]gFEZ>j&"DS8qs`nOj8MN.uuJ7,dT(60M)Co69QZ4U\aaj0`!L;/0[*cH3(7/VXKpSW7K5f"7G,qs7SWk(bo.gl;32c'olbh[MtQOu\dAEYrP*V&ZeXn`]-5%rb"rNl?(nm5,T',cA,e,AbiP;^YkojH7F,EB_'3lI^D2RmtQ#TiXumkai')3o>_)XbHIs`jo8)E3_6dj6GJ,E4*3%oBu-![YTh6C*FiG+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sMtg0*S>fh'h?-6WHE[Xe0s9D1CX,O>l!Z@Whe-X_B/U3us@C8^!-gSdMtQV5f64__VZGA&dnW8D&MW7`qJF_B?k_%4pMui9j(i%>Zo(3,o)k>;W`@V3@unlgl'LC0GC0pB@CR`FZ!G'"ieV;?Kir1\N2?"p3e-#JWualiO%p)Q.P_hX/tW]+LuiFj82%=]IO.+beZlQEus0d/E?m6?_S)eM_52$cNR0j':;12SNp`=gmCW2`-pAb5VHE)u7,=E,T7:>5Cgba2J&J8+n;%XBP&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5UQZ4$:_>$$NTI8,*O4k-j$7en,^RQ_,_L@.;ZgL7\^NU!%0;HGP!6h]rd1Hk_OK9.*3qeo"t#p?$GO8'DS&AOh^=Z-WcN0+B\L1GRK1F'M!U:%IB^dc>>Pg8:cifpup?(UlI;5.<\tQX>?tFWQiac)uDYT.-\%c(!H\gFR7jFtrC:Cqp8!ErbF];@$5`%S'#sa^h*qq_X8E2=,`SiS;DgX8jpUcHYVJS(s4O4/pN*3MiU=.XB5N]oHkS%1Xq/*?DEKG!1!ugkOELS6L"!h<(:VRVll24a@&RmH_*&mBYhhqBa\A7m-sC.XOq&7o_-sBlhsU*mj69D4GK\]nMD)NS%Af3AqX:o6An,Ci-H)I,ar!:VC"S]"1C!>BgQe0t_>dBq!V-LCZnePW4_!K@'(/U+YkgME2$SW;)P8H+Cr_EUP0:n/\$?6&.Aa/b_XPIW14\7Ja/ZCX]H\ne..OtS0Epd9O`:!LE=oo[$3I?!,m\$"Z9Y?5+"Om:!ACmnRV]&,ouEE:u3+ELi4fT2a#g^CkUe#pfkRB1Xe*B"(R;Zh9ECLMrG#3M>Vm!ko"pDa$'O/DgoA:>"=l_hB-Fl)?_Aq!4WN+3cM%P8gYC,Y)6gQm_\$nSa@QX3#>P"G)VlXM2;el(9P@]c?&Nd)maHu^sr[D;Wj\WgN5Z.u^A'9;ZeG*]9X4d')b*:@Lo,]II>5,$4R)u;d/f^6&8*/p1Ab7fMqn/U$i`#cmAGX`u2F?u13oi$UQc=QHPle$j4i/V2s3>57g"(HE5G%P!0Hp=!*8;ODaZ6CJ:+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+tel7qe*t67^HMA>^(RY`F,!t)qE4P1KsAi##\XV3";@Wm^\Z!\IOqZ(\=JIeYH>m,?^CM8sYcd"Ajl5msATUpq.^9C-k\4HpXa>L"L7U3>=(ohTnSEa,XsO?@S>:.YSIhqhepUS7MPna71nB^nbkmAlq<8>S5/2F7_Z'%aOe8Bq>tBr7XS(EI'L(,?2a@$V]<'ENI$!]E,j4C7ORjeQ1RL2*#W@;:m:r()k)]CUDBH$q85R#5e]u)OMHmP1(/j(c\3Tf)s/geAS((-d^Qdctc_nZnIY\&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J5Te&J9/'F=t)N8P:(@73gWnAFMgKlu5%=n0;r&&4%]&KccUp#@![FDG16N3"*tmJXBGPNS:"#n8RXUh()i6<#U$(Z1%7C^%_1]D<\^d7nXj;*#)6_=\fuGBg)0'fRJM4[ot@ALtrfCf1ABNS_VqD)]0sb)?T<.HkQ[^Tr=RpYEu>^>6A;G[B7/DZk?)eaX$.II]#6,VFniq$Z`MdA/8d@D8binD.CAHY4u8Ak'*^Ff>U_:2[HnB.#<\8LkpkCLkpkCLkpkCLkpkCLkpkCLkpkCLoHa=QH+q]Rd9(T.TlC,TuVAiO%-L!EV]hQo>OEARWetCC.U;c`0HN'ko:VhE`Gh<3EB\gI^Y-i:MHf"9$2s!I8f-HBka%1nqTD'[bp!Ji^Z`1][%nLl>76'4qCk6MU(rcmkN\sO(3q"dW7@4N=J#]3fUTo%JHXLC2QsaUmfu9\p#m(R>*/j.6>E0Og4R25MHR(`VNk7(4(/7nQ5i=0pb?qgRJJ'M%V%U6p4(5@kJ@#BPp;RVlLLR,ZJTQ6Ci!'I^"D6VoHVrbU/73)n1.q-A0A1W+e-*g$g_9C96c51A(=q4q+b@^3c4!^,H-UT;lC",4[*JbZlIBC5`M+q54T$'Iqm8`k)Br[Xb[>o22h#oa&mg#5D^;\h,#5uk:+jeTagM#Q=TnGi;%1H_OT_b7Ur6J9O+G'r&=\VTu,)R_%0oTd]>1(t&3sG>i9J6c1J(rJbXJg(=n$!V;+>a2`a'i`)l8mgBK$5/AhT1M1h.n2Y+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T+sJ3T.k;X(-E5"`m5-_V>ML[F.OqSQ/`h9TiK40]nd.Ha=?Sr"m']`rfkmOn`:EV"5o^>RmR(.r&+!SeBPLRBGfMPmfkhL.lA;,6CfO:hY%/"i@cr8eLFDnJjWf2_+],_RoR;eMFUiKh[T`C=J8>*SYLGB(tKQ.>MgCbY+Sfp8fS,hO)_f0L[?^!\rW=X=u?5]o4tC;Y-)K7UQL>,T'b6:e*F4J+SIl-MP.dsFq95KMrHCsZA6Y-8M+U:L:+Jm5["Vu99,oH[jmgrC0OCE[qYkYa@/H>)'>+9$<3)ApOCV.e)8dZ"lukjWldO\D/,(/#OGbhe]Z"QY_]#g:Jp_I$@@9d6';7#/%0)a`6^l2C(A$qZUmK8;02@'f`6TUEagk0(@3f-SZ&6[_APrUPlRpZ`(4Qq!$(3%Ccf@CTktQ;F2j-Rjt`$/[8T\.UNoQ`NuGK1AZf/q#a:D*U[`&*PqOE$J;?,=g+4T;+5\F[N2Y6Dh>A3Y%@i3I;!E>I);"f+>`7SgRcp#]UX`l)gI,M6fBsm'5O+7\a9b*&cl]9,6%mFb5d^QBY=qj>A83^dd[%7#`A[\Yl3HEskM@@cRCRf2gFa1;eK_T2efjf1Qc[,oj0[k&!`^YS+Iu\*qc3#\b`hl&J7^A6psF26psF26psF26psF26psF26psF26psF26psF26psF26psF26psF26psF2pXW\/?,ke.0H9f*;mA#7@m!W4RogPq$'j%S1^hc79a?Si:/agc3[nJ4=u\LU/@T%U,[r_=hcUp%@7>NAUJ:EY#&Np%PHNid(Uk'$W%+=](>H3Ia6]Y.c??A5u.5fUniU6Bn6b[.%8b[R6,QhG?2u'$G+^J9u#O?'75FqQGFSH/Sh=kkkN%RB//aK-p)aRWp+;h8=hObOEG)bAhg3j81lMT[((#S"iZC[;99C9*208-aZMOb>JHTq<[O8*FjG$)@93cpUpo(=ngb4*eP`lD\Zp\DZs[]?2cJ15#Be_L7SeWdj)uCL^:)otEhCJ7'f&K*0'm@tN^Dmr9=oc,@_"#kmu-JMb.b&$YIE2j%s?;k_"cSCftkYtQS`UZE&U"Rf4<%E[Hl[.:N8Qu1_ddq(\DM""Ki[cO#UhN!r:c11BMAG\>p7_:"C8km:_RcQJTT?/E/7%:!"mN223<%97=tQ8a0]_HXh,2WhZ!0\]rn2*Qcp,qJo@m2]U;t0&P4NXjVWIJ*2<%2&h[W+;J#]h7M3^`7[Tc-ihlF8.1jhqu>!MNn?d`1KWsPZ(X.to1$u>oWi*PReo)e71ZgeF[qs(4q@?.&Oa!4*e:!VGnh5hTQ%ZLV(7B6?T,(`MOh(V%l>([`8/l.]UK9iJnnFEhb^hUe6NSYCEXKC?F:Hd(C,i'4Re]GTK]/NmX//SptPZBmD"pAoOWQJd?Ob"*>Y(-SJe>#r?ab"Heo@L\+O2mLa"r<71AjuC>g)L@=$lCO:kVXm.=M-tT+6LL>VYZjQVgL-Xt??W,5PR0#i#nu^:p*tC8eRGf+uH.A[bf\0\'.>cSb6s3"Xo]hl,3#,PA'S>H)lH*H6bbEItWFRFoQbPgMAGH-Qj%\\J8>:[1fRp*h\CK%[)%EO\:Df!a=QCId6Bg*A3si_2j\WuA`1JZZ,\c'M?lYAQL.mJ,qkAgkE6]&dcLac80t(@Yk05G)I]R/]8L4Ig`^5dhM('VFR97,D9gE,P!JX^p)s9"n)i/LFs/ADL.TY9aJEEEmEHkfHWoQka;a]\h8gZq*G4rS*[d.?Wj\FGoFNjf.ucQfA)/Y?FtRi=]35_1:GMUS:W6XMpsi[aU?t7>"D(aF$b>sXh3ge_BX<-Eilbmc6]t?U;HC$o=1S/(-Wi>9!/X815Pn@%ll/QQ3J1_:V+FC/k(aV!T]??Y10_a6bWNue:FheOgpdS0a7FaPZJ+X,>Glqh:LgMelSTqA\CIh4[?GJ*BJ/R;>gVnhSuqhU8^pVK]+L\E&k=H^SU_-b`!oqIpFQLX:,ZHV0JS6psF26psF26psF26psF26psF26psF26psF26psF26psF26psF26psF26psF26psF26psF26psFBbP!`#am%PQIC;LDaNl\SgP<$2>2cfWp_?^r'_"Ok)2<*b!FlqG$D>K*O>%dH+WLlZ<%dn$SmghP8nc@.3?`:!in-h@`PLprtU:<*q/JeO$:0V(%%_(+e*G!Phf*>U9>jLuYhHu"K[iD]iRTW@pf3>!?C*AaA[=iGccK3i@T&JFRWk@M`l#*jsb=aG@[?7k[Gt'cPO6,[,!-koEDqAFfkS6N%<4FbA;U701E-.u?:dB/RbQ.iOJ1kkgXf=rlkuu*>!ZSV'p@tT47IeTg%A9c.hspQ!*E?!MD*qrenH$]8a-Gc@mQX,6;Hqp[dbrR5#2u=occ`?e7@"=77=e:A%tW#I)5&UimCrW+_0K$YlFBU7!#*IE9X&&Q4f]gJZ4(DNkq9oBJ(/rFMDA.*3=Pt0$f[MZo+Yj7lYlkgq+U+9##>cD>0N9endstream +endobj +4 0 obj +<< +/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font +>> +endobj +5 0 obj +<< +/BaseFont /ZapfDingbats /Name /F3 /Subtype /Type1 /Type /Font +>> +endobj +6 0 obj +<< +/BaseFont /Helvetica-BoldOblique /Encoding /WinAnsiEncoding /Name /F4 /Subtype /Type1 /Type /Font +>> +endobj +7 0 obj +<< +/Contents 11 0 R /MediaBox [ 0 0 612 792 ] /Parent 10 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /XObject << +/FormXob.3d48064d70f9dd3282a3ec25fafdd35d 3 0 R +>> +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +8 0 obj +<< +/PageMode /UseNone /Pages 10 0 R /Type /Catalog +>> +endobj +9 0 obj +<< +/Author (Prisa Yachts LLC) /CreationDate (D:20260505022642-04'00') /Creator (anonymous) /Keywords () /ModDate (D:20260505022642-04'00') /Producer (ReportLab PDF Library - \(opensource\)) + /Subject (Teak & Detailing Brochure EN/ES) /Title (Prisa Yachts LLC \204 Teak Restoration & Marine Detailing) /Trapped /False +>> +endobj +10 0 obj +<< +/Count 1 /Kids [ 7 0 R ] /Type /Pages +>> +endobj +11 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 3405 +>> +stream +GauHNhfBGk&q8/6dBsLTG:R>i^W0,o-5ah,$+W%"[oI]NB%jMG7P^.H_:8GR="VZV%M3R2pejpBnRVJpJ)0BjJ"?q#0SIOI>;ZC6cJdAV&O\@DcQPn`$Kk?TS0+tKR$D4k/<5WFMh%YO-m+a_Xpu-STnm`T66=*BA1Rt<0`U6b'kJ71)6fVP9nC9YEgVgDm.EZg1:Z"`Z3ekRCC.>":Bu0fU--Ut^Tot20k5PgNhF]o:HZn@+);-bPh)=n!331KMb>piba0D3/r%jIZ2k3Ba/)+0X801RS]]R4_U;%Z*YO4^[i,#@E?"+t[Uf5QJqBu?Lg$D,(dCYB_Bsr^DW:o,-!#Uj@@`+13%gk6iZaEC/Maa?ptC%#QG)r5B<9hj_,*=)$.0NL1)BUK5)d"W,@UA\6k7eSJs@M3a#!M^h>8ufT8\8T5Mhs%^Ob)5_stk7Ir;HYi99WH65?RpW?f4h,V<+1\9Mlc)B@-VX_DCo$b@0eULWeMIg77[^pV1c6o_)fKQe\Zm)K>C0`d&`r"f4]BE`Hgq2>UZa'H,-/[#hfDS9?A^Vi51(M+P;Dfg/*c8+bR8X\j4IKJjfg9G2Yl8mp;?KA@5Vo^QcgtfYPVZ3`(WT!&WQ7V9p#]bI3&7X+ku6XA%7pLH)1m*2Qp]s13%79Xc;@G&jnKpY;5ES5#%#I@-Q'$)_G)N[D*c&(Sf!$X&!0dN3/cE!]AIqU'C?55D74p25i'A(Yjb;]50Zh!!ooWkSbPSF8pA9_O905aIhm1j&!V9>Zk$tgk.KD#f&'kH)2gUXKi6XMkR15>3l@fhJejYj(`X,9<*ZQ8"g-iH33."P#(0>8,[89Jo.gE3RHF&7k[#A-*i,5p)n#usc>1J3_MEQVrA)AU=Fg"cAH/@pucXbb+mUZ5d.^O`G@8"95nGH2LlC+[D**VD9%8[Lq&f02W03UAN'ql7BefQ`a[L*F@d@a4JMp!qi7DQO2ljV-=JQC8j\CHJQWR4?q*hLr'frcnpnO4G\;$i4_DXiAX+H8-WQB1J>BiL69>5ZRcq=o2\I.A1fPHte?8!E=Xcl)cTW3JDlmU?Xs%dV_Jak*BoU"b#$jR8XddejU7i&+,!i2nWiqZ<+'0p'+&5D'.1eJbI=?2V?Jf+Zlp:[7d.inuDl(0!_g=phllB5kaQLVqSTB*:6tK_4+KJE"J]0p'`SPdHa8kl[=,Jk>*,N%H?<%\'ikdU$NDmDY>r$OZ3121Q.kdRN'2].uG[&G%cOe;#;CJQFsfk=*H.c?d?I$F='Srnout:F[&'#SkC.ZC*dl:ZHs&0qSUW;/#87dD(poMi"f:IDA3us2dAB>>_B-e?S\"BWhHi9@Ca`[mhe?R..35/1B:-F2-/5FIsP3Uq1$Z`8OVR^epouiRt7/85R$=QEEI-Rr4X;5RnJ=T@1[B7eFstm]`"rE^['T<2VrXYqY<<*kcD))q7\Y745aJa7IaeKS\T=UVj!A+`V>]JHf8mEWedYe8kKUC6oW!.-VqCG-L,cG"Z#9krTc?[E7;HKhjju'LXLsaq2MXos)M)8+f*GtllCFlkXS5h*KiU0.Xoo%s6_t7^V]U;0$s'\Y@Hf#UKW+BpE\c]7ppAK]hSDjg/%e*;S;iSi09S:Tg"4^b5kD>f4lo`=]#++7mHO09lu.ppZ"IZ)mS?9X'YO/<"t2P_8hBq//g[>/.]B`YOrn@RR.>2&@mDI]Tf?V85Ag*SqUGo?EKTPNuZ:cEQ*KUG>OG.Telk$1Q)(A;HRfRbdu6D@Eqpti0(tb*T-Sj)pi\+oSUVEB?qHuljA`KTn5D%n2\CU-2/.??aUlT4uEVUJ',*+urC0gdC<4a[3[C7!C,V`&4tb(e_M7&]0?,ZlXTikBmG6%hkb:9L@n=($D+ZpIVaEEMn1&=#I,3,Fo7n)F,i\J$L-GPBSWaV/+c)9tSD`?0"KDCZ03=J.DH,?g72V"D'>mnP7pPK/%Q3B6`$b#Zsbj_7F`J4i)h%e\\,Nh[s4oEK>Tb!3:)?+&,*;PKomN>ce$U\>\N&&!/uC@Nui;7mdP]-$bi\chWp.&IeV]^#(-%p^HknCDO(br@&lT,')C4OTNZ#u_d3f4).\Zf#'Ai2Yp3n!jUB1@"D.O3P)e3feLl7[SsG0WKJ^L@bo*GGthG(W5b>i<:6O8T[/oD3OJ&ElQPq<>2I]csQtU"h5B`=aKTo`5C!o,UkMK@D`hpo&$,?CMAI`CL/T_AX2*f)]s#;g=:/K-tcDa]rq7+^36n,Zc'bjY3%_`%AO=Ecc!M8m2X!DmI-Y)i.$b_CW?~>endstream +endobj +xref +0 12 +0000000000 65535 f +0000000061 00000 n +0000000122 00000 n +0000000229 00000 n +0000045591 00000 n +0000045703 00000 n +0000045786 00000 n +0000045905 00000 n +0000046163 00000 n +0000046232 00000 n +0000046569 00000 n +0000046629 00000 n +trailer +<< +/ID +[<9b784fb1c6216be4948891bddebb6409><9b784fb1c6216be4948891bddebb6409>] +% ReportLab generated PDF document -- digest (opensource) + +/Info 9 0 R +/Root 8 0 R +/Size 12 +>> +startxref +50126 +%%EOF diff --git a/prisa-yachts/calendario_mayo_junio_2026.md b/prisa-yachts/calendario_mayo_junio_2026.md new file mode 100644 index 0000000..10f93d4 --- /dev/null +++ b/prisa-yachts/calendario_mayo_junio_2026.md @@ -0,0 +1,145 @@ +# Calendario de Contenido — Prisa Yachts LLC +## Mayo 5 - Junio 1, 2026 + +--- + +## SETS DE HASHTAGS + +**Set A — Trabajo Técnico / Instalaciones** +`#MarineElectrical #BoatWiring #MarineElectrician #LithiumBatteryBank #BoatRewiring #MarineInstallation #BoatElectrical #MarineTech #YachtElectrical #MarineServices #SouthFloridaBoating #FloridaBoating #StuartFL #TreasureCoastBoating #BoaterLife` + +**Set B — Seguridad / Educación** +`#BoatSafety #MarineSafety #ElectricalSafety #BoatMaintenance #PreventiveMaintenance #MarineEducation #BoatTips #SailboatLife #PowerBoat #LiveaboardLife #FloridaYachts #JacksonvilleBoating #MarineElectrics #BoatLife #CostaEsteFL` + +**Set C — B2B / Referidos / Comercial** +`#MarineProfessionals #MarinaMaintenance #YachtCaptain #BoatBroker #MarineIndustry #CommercialMarine #FleetMaintenance #MarineTechnician #YachtServices #MarinaManager #BoatDealers #MarineContractor #FloridaMarina #TreasureCoast #PrisaYachts` + +--- + +## SEMANA 1: Mayo 6-11 + +| Fecha | Hora ET | Plataforma | Caption # | Tema | Visual | Hashtags | +|-------|---------|-----------|-----------|------|--------|---------| +| Lun Mayo 6 | 11:00 AM | Instagram | #1 | Battery Bank Install (EN) | Foto litio instalado, cables etiquetados | Set A | +| Lun Mayo 6 | 12:00 PM | Facebook Page | #1 | Mismo + CTA "DM para cotización" | Misma foto | Set A | +| Mar Mayo 7 | 10:00 AM | LinkedIn | #11 | Marina Managers/Captains (B2B) | Foto profesional del dueño en barco | Set C | +| Mié Mayo 8 | 9:00 AM | Instagram | #4 | Safety Warning Shore Power (EN) | Foto conector dañado - close-up impactante | Set B | +| Jue Mayo 9 | 11:00 AM | Instagram | #3 | Trabajo de Cableado (ES) | Foto cableado ordenado | Set A | +| Vie Mayo 10 | 10:00 AM | Facebook Page | #8 | Hurricane Season Checklist (EN) | Gráfico tipo lista o foto del tablero | Set B | +| Sáb Mayo 11 | 9:00 AM | Instagram | REEL S1 | "Panel Transformation - Watch This" | Slideshow 5 fotos: antes→durante→después | Set A+B | + +**Reel S1:** Texto en pantalla: Foto 1 "Before" / Foto 3 "During" / Foto 5 "After - Clean. Safe. Done." | CTA: "DM for a quote - Stuart to Jacksonville" | Duración: 15-20 seg + +--- + +## SEMANA 2: Mayo 12-18 + +| Fecha | Hora ET | Plataforma | Caption # | Tema | Visual | Hashtags | +|-------|---------|-----------|-----------|------|--------|---------| +| Lun Mayo 12 | 11:00 AM | Instagram | #5 | Lithium vs AGM (EN) | Infografía 2 columnas o foto ambas baterías | Set B | +| Lun Mayo 12 | 5:00 PM | Facebook Groups | FB GROUP #1 | Space/Treasure Coast Power Boat Club | Ver texto abajo | Set B | +| Mar Mayo 13 | 10:00 AM | LinkedIn | #10 | Liveaboard Focus (EN) | Foto sistema completo: panel, baterías, cableado | Set C | +| Mié Mayo 14 | 9:00 AM | Instagram | #6 | Before/After Panel (EN) | Foto antes/después lado a lado | Set A | +| Jue Mayo 15 | 11:00 AM | Instagram | #9 | Seguridad Eléctrica (ES) | Foto materiales correctos vs incorrectos | Set B | +| Vie Mayo 16 | 10:00 AM | Facebook Page | #5 | Lithium vs AGM (republica) | Misma infografía | Set B | +| Sáb Mayo 17 | 9:00 AM | Instagram | REEL S2 | "Lithium vs AGM - The Numbers Don't Lie" | 4 slides comparativos con texto superpuesto | Set B | + +**Reel S2:** CTA: "Comment BATTERY for a free quote" | Duración: 20-25 seg | Bilingüe EN/ES + +--- + +## SEMANA 3: Mayo 19-25 + +| Fecha | Hora ET | Plataforma | Caption # | Tema | Visual | Hashtags | +|-------|---------|-----------|-----------|------|--------|---------| +| Lun Mayo 19 | 11:00 AM | Instagram | #7 | Washdown System (EN) | Foto sistema instalado, bomba + mangueras | Set A | +| Lun Mayo 19 | 6:00 PM | Facebook Groups | FB GROUP #2 | Freedom Boat Club Florida | Ver texto abajo | Set C | +| Mar Mayo 20 | 10:00 AM | LinkedIn | #13 | Call for Referrals (EN) | Foto del equipo o logo Prisa Yachts | Set C | +| Mié Mayo 21 | 9:00 AM | Instagram | #12 | Diagrama Eléctrico (ES) | Foto del diagrama + manos del técnico | Set A | +| Jue Mayo 22 | 11:00 AM | Instagram | #2 | Rewiring Job (EN) | Foto cableado nuevo, alta estética | Set A | +| Vie Mayo 23 | 10:00 AM | Facebook Page | #7 | Washdown System (republica) | Misma foto | Set A | +| Sáb Mayo 24 | 9:00 AM | Instagram | REEL S3 | "Lo que nadie te dice del rewiring" | 5 fotos: cable incorrecto→herramientas→resultado→logo | Set A+C | + +**Reel S3:** Texto #1: "Most boat fires start here" | Texto #5: "Prisa Yachts LLC - Marine Electrical" | CTA: "Save this - share with your marina neighbor" | Duración: 15 seg + +--- + +## SEMANA 4: Mayo 26 - Junio 1 + +| Fecha | Hora ET | Plataforma | Caption # | Tema | Visual | Hashtags | +|-------|---------|-----------|-----------|------|--------|---------| +| Lun Mayo 26 | 11:00 AM | Instagram | #14 | Banco de Baterías Litio (ES) | Foto batería litio instalada | Set A | +| Mar Mayo 27 | 10:00 AM | LinkedIn | #15 | Pre-Temporada (ES) | Foto barco en marina o checklist mantenimiento | Set B | +| Mié Mayo 28 | 9:00 AM | Instagram | #15 | Pre-Temporada (ES) | Foto mantenimiento activo o panel antes de revisión | Set B | +| Jue Mayo 29 | 11:00 AM | Instagram | #13 | Call for Referrals (EN) | Foto trabajo exitoso o testimonio | Set C | +| Vie Mayo 30 | 10:00 AM | Facebook Page | #14 | Banco Baterías Litio (republica) | Misma foto | Set A | +| Vie Mayo 30 | 2:00 PM | LinkedIn | #13 | Call for Referrals (segundo empuje) | Foto cliente/trabajo exitoso | Set C | +| Sáb Mayo 31 | 9:00 AM | Instagram | REEL S4 | "Hurricane Season Prep - 5-Point Checklist" | 6 fotos checklist visual + logo final | Set B+C | + +**Reel S4:** Bilingüe — cada punto en EN, CTA final en ES | Texto final: "Prisa Yachts LLC - (xxx) xxx-xxxx" | CTA: "Save this. Share this. Call us before June 1st." | MAYOR POTENCIAL VIRAL por seasonality + +--- + +## POSTS PARA GRUPOS DE FACEBOOK + +### FB GROUP POST #1 — Space/Treasure Coast Power Boat Club +**Publicar:** Lunes Mayo 12, 5:00 PM + +> Hey everyone - I work as a marine electrical technician out of Stuart and wanted to introduce myself to the group. I specialize in rewiring, lithium battery banks, solar/shore power systems, and washdown installs - all with marine-grade materials from stem to stern. +> +> If you've been putting off an electrical issue or want a pre-season inspection before hurricane season hits, I'm currently booking jobs from Stuart up to Jacksonville. Happy to do a free 20-minute phone consult before committing to anything. +> +> Prisa Yachts LLC - bilingual service (EN/ES). Drop a comment or DM if you want details. + +--- + +### FB GROUP POST #2 — Freedom Boat Club Florida +**Publicar:** Lunes Mayo 19, 6:00 PM + +> Asking because I've been seeing a lot of AGM batteries failing early this season - usually from improper charging profiles or undersized alternators. It's one of those things that shows up quietly until the boat doesn't start. +> +> I'm a marine electrician based out of Stuart (Prisa Yachts LLC) - if anyone's had intermittent power issues, flickering lights, or slow starts, it might be worth having the system load-tested before it becomes an emergency. +> +> Currently working Stuart to Jacksonville. Bilingual (EN/ES). Free phone consult before any commitment. Happy to answer questions here too. + +--- + +## ESTRUCTURA DEL GOOGLE SHEET PARA n8n + +**Nombre del sheet:** `PrisaYachts_ContentCalendar` +**Tab activa:** `Schedule` + +| Col | Header exacto | Tipo | Ejemplo | +|-----|--------------|------|---------| +| A | `post_id` | Texto | `PY-2026-001` | +| B | `publish_date` | Fecha ISO 8601 | `2026-05-06` | +| C | `publish_time_et` | Hora HH:MM | `11:00` | +| D | `platform` | Texto fijo | `instagram` / `facebook_page` / `facebook_group` / `linkedin` | +| E | `caption_number` | Entero | `1` | +| F | `caption_text` | Texto largo | (caption completo) | +| G | `hashtag_set` | Texto | `A` / `B` / `C` / `A+B` | +| H | `visual_type` | Texto | `photo_installation` / `before_after` / `reel_slideshow` | +| I | `visual_filename` | Texto | `battery_install_may06.jpg` | +| J | `status` | Texto fijo | `pending` / `approved` / `published` / `skipped` | +| K | `language` | Texto | `EN` / `ES` / `EN+ES` | +| L | `content_type` | Texto | `educational` / `portfolio` / `safety` / `b2b` / `reel` | +| M | `cta` | Texto | `DM for quote` / `Save this` | +| N | `campaign_week` | Entero | `1` / `2` / `3` / `4` | +| O | `notes` | Texto libre | (notas internas) | + +**Reglas críticas:** +1. n8n filtra filas donde `status = "approved"` Y `publish_date` <= fecha actual +2. `platform` en minúsculas exactas sin tildes +3. Fechas en formato `YYYY-MM-DD` (no MM/DD/YYYY) +4. Después de publicar, n8n actualiza `status` a `"published"` para evitar repost +5. Para `facebook_group`: poner el Group ID numérico en columna O (la API requiere ID, no nombre) + +--- + +## RESUMEN: 28 publicaciones en 4 semanas +- Instagram: 15 posts (11 captions + 4 Reels) +- Facebook Page: 5 republicas +- Facebook Groups: 2 posts de comunidad +- LinkedIn: 5 posts B2B + +**Distribución:** 10 EN / 4 ES / 1 bilingüe | Sábados siempre Reel (máximo algoritmo de fin de semana) diff --git a/prisa-yachts/contenido_electrico_abyc_nmea.md b/prisa-yachts/contenido_electrico_abyc_nmea.md new file mode 100644 index 0000000..a6548f9 --- /dev/null +++ b/prisa-yachts/contenido_electrico_abyc_nmea.md @@ -0,0 +1,12 @@ +# Prisa Yachts LLC — Tips Eléctrico ABYC/NMEA +## 5 Tips + Carrusel "5 Errores Que Pueden Incendiar Tu Barco" + +### TIP 1 — Calibre de cable correcto (ABYC E-11) +### TIP 2 — Cable estañado (tinned wire) +### TIP 3 — NMEA 2000 vs NMEA 0183 +### TIP 4 — Fusibles y breakers correctamente dimensionados +### TIP 5 — Ground vs Bonding: la diferencia crítica + +### CARRUSEL — 7 slides "5 Errores Eléctricos Que Pueden Incendiar Tu Barco" + +[Ver contenido completo en el archivo fuente — todos los captions EN/ES listos para copiar] diff --git a/prisa-yachts/contenido_hardware_marino.md b/prisa-yachts/contenido_hardware_marino.md new file mode 100644 index 0000000..25aec32 --- /dev/null +++ b/prisa-yachts/contenido_hardware_marino.md @@ -0,0 +1,12 @@ +# Prisa Yachts LLC — Tips Hardware Marino +## 5 Tips + Carrusel "Pre-Season Hardware Checklist" + +### TIP 1 — Winches: lubricación correcta +### TIP 2 — Cadena de ancla: inspección, marcado y reemplazo +### TIP 3 — Herrajes inoxidable: por qué se oxidan y cómo prevenirlo +### TIP 4 — Tornillería: 316 SS o bronce marino (nunca galvanizado) +### TIP 5 — Escotillas y sellos: mantenimiento preventivo + +### CARRUSEL — 5 slides "Pre-Season Hardware Checklist" + +[Ver contenido completo en archivo fuente — todos los captions EN/ES listos] diff --git a/prisa-yachts/contenido_motores_filtros.md b/prisa-yachts/contenido_motores_filtros.md new file mode 100644 index 0000000..cb33253 --- /dev/null +++ b/prisa-yachts/contenido_motores_filtros.md @@ -0,0 +1,256 @@ +# Prisa Yachts LLC — Motores y Filtración Marina +## 5 Tips Técnicos + Carrusel "Annual Engine Service Checklist" + +--- + +## TIP 1 — THE IMPELLER +### "The $30 Part That Can Kill a $15,000 Engine" + +**Caption EN** + +That small rubber wheel inside your raw-water pump? It costs $30. When it fails while you're underway in Florida heat, your engine can overheat in under 5 minutes — we're talking warped heads, seized bearings, cracked heat exchangers. The repair? Easily $5,000 to $15,000. + +The impeller is the single most overlooked part in marine engine maintenance. Florida's warm saltwater makes rubber degrade faster than you'd expect. Best practice: replace every 200 hours OR once per season — whichever comes first. And always carry a spare onboard. + +Signs it's failing: rising engine temperature, reduced raw-water flow from the exhaust, or rubber fragments in your strainer basket. Don't wait for an alarm. By then, the damage is done. + +At Prisa Yachts LLC, impeller replacement is part of every seasonal service we perform — from Stuart to Jacksonville. We check the full raw-water circuit, not just the pump. + +DM us for preventive maintenance — Stuart to Jacksonville. + +`#ImpellerReplacement #MarineEngine #RawWaterPump #BoatMaintenance #FloridaBoating #MarineMechanic #PreventiveMaintenance #SaltwaterBoating #YachtMaintenance #PrisaYachtsLLC` + +--- + +**Caption ES** + +Esa pequeña rueda de goma dentro de tu bomba de agua bruta cuesta $30. Cuando falla mientras navegas en el calor de Florida, tu motor puede sobrecalentarse en menos de 5 minutos — estamos hablando de culatas dobladas, cojinetes agarrotados, intercambiadores fisurados. La reparación? Fácil $5,000 a $15,000. + +El impeller es la pieza más ignorada en el mantenimiento de motores marinos. El agua salada caliente de Florida degrada el caucho mucho más rápido de lo que imaginas. Lo correcto: cambiarlo cada 200 horas O una vez por temporada — lo que ocurra primero. Y siempre lleva uno de repuesto a bordo. + +Señales de fallo: temperatura del motor subiendo, poco flujo de agua en el escape, o fragmentos de goma en la canastilla del filtro. No esperes la alarma. Para entonces, el daño ya está hecho. + +En Prisa Yachts LLC, el cambio de impeller es parte de todo servicio de temporada — de Stuart a Jacksonville. Revisamos todo el circuito de agua bruta, no solo la bomba. + +Escríbenos para mantenimiento preventivo — de Stuart a Jacksonville. + +`#ImpellerReplacement #MarineEngine #RawWaterPump #BoatMaintenance #FloridaBoating #MarineMechanic #PreventiveMaintenance #SaltwaterBoating #YachtMaintenance #PrisaYachtsLLC` + +--- + +## TIP 2 — ZINCS / ÁNODOS +### "Zincs: The Sacrificial Guards Your Engine Needs" + +**Caption EN** + +Saltwater is relentless. The moment your boat touches it, electrochemical reactions start attacking your underwater metals — aluminum lower units, stainless shafts, bronze fittings. The only thing standing between your engine and accelerated corrosion is a small piece of zinc or aluminum worth a few dollars. + +Anodes work by corroding first, sacrificing themselves so your expensive components don't. But here's what most people miss: a depleted anode is worse than no anode — because it gives you false confidence. In Florida's warm, conductive saltwater, anodes can go from full to 50% consumed in a single season. + +Inspection schedule: every 3-6 months. Replace at 50% consumed — not 100%. On outboards, check your lower unit anode AND your trim tab. On inboard diesels, inspect shaft zincs, rudder zincs, and hull plates. + +Saltwater doesn't take days off. Neither do we. + +DM us for preventive maintenance — Stuart to Jacksonville. + +`#ZincAnodes #GalvanicCorrosion #MarineCorrosionProtection #AnodeReplacement #SaltwaterBoating #OutboardMaintenance #InboardDiesel #FloridaBoating #MarineMechanic #PrisaYachtsLLC` + +--- + +**Caption ES** + +El agua salada no para. Desde el momento en que tu barca toca el agua, reacciones electroquímicas atacan tus metales sumergidos — unidades inferiores de aluminio, ejes de acero inoxidable, accesorios de bronce. Lo único que está entre tu motor y la corrosión acelerada es un pequeño trozo de zinc o aluminio que cuesta unos pocos dólares. + +Los ánodos funcionan corroiéndose primero, sacrificándose para que tus piezas caras no lo hagan. Pero esto es lo que la mayoría ignora: un ánodo agotado es peor que no tenerlo — porque te da una falsa sensación de seguridad. En el agua salada cálida de Florida, un ánodo puede pasar de nuevo a 50% consumido en una sola temporada. + +Frecuencia de inspección: cada 3 a 6 meses. Reemplaza cuando esté al 50% — no al 100%. En fuera de borda, revisa el ánodo de la unidad inferior Y el trim tab. En diesel inboard, inspecciona los zincs del eje, del timón y las placas del casco. + +El agua salada no descansa. Nosotros tampoco. + +Escríbenos para mantenimiento preventivo — de Stuart a Jacksonville. + +`#ZincAnodes #GalvanicCorrosion #MarineCorrosionProtection #AnodeReplacement #SaltwaterBoating #OutboardMaintenance #InboardDiesel #FloridaBoating #MarineMechanic #PrisaYachtsLLC` + +--- + +## TIP 3 — FILTRO DE COMBUSTIBLE: PRIMARIO vs. SECUNDARIO +### "Two Filters, One Mission: Keeping Bad Fuel Out of Your Engine" + +**Caption EN** + +Your diesel engine has two lines of defense against bad fuel — and most boat owners only know about one of them. + +The PRIMARY filter (Racor bowl-type) does the heavy lifting: it pulls water out of your diesel and catches large sediment before it reaches the lift pump. That clear bowl? Inspect it every 50 hours. If you see water or dark sludge — stop. Deal with it before you go offshore. + +The SECONDARY filter is mounted on the engine itself. It catches particles down to 2 microns — protecting your injection pump and injectors. Modern common-rail diesels can have injector tolerances tighter than a human hair. Contaminated fuel reaching those injectors means $300-$800 per injector in repairs. Replace this filter at every oil change. + +Florida's humidity and temperature swings cause constant condensation inside fuel tanks. That means water, and water means diesel algae. Two-stage filtration is not optional here — it's survival. + +DM us for preventive maintenance — Stuart to Jacksonville. + +`#FuelFilter #RacorFilter #MarineDiesel #FuelFiltration #DieselMaintenance #MarineEngine #FloridaBoating #BoatMaintenance #PreventiveMaintenance #PrisaYachtsLLC` + +--- + +**Caption ES** + +Tu motor diesel tiene dos líneas de defensa contra el combustible contaminado — y la mayoría de los dueños de embarcaciones solo conoce una. + +El filtro PRIMARIO (tipo bowl Racor) hace el trabajo pesado: separa el agua del diesel y captura sedimentos grandes antes de que lleguen a la bomba de cebado. Ese bowl transparente? Inspecciónalo cada 50 horas. Si ves agua o lodo oscuro — para. Resuélve eso antes de salir a mar abierto. + +El filtro SECUNDARIO está montado en el motor mismo. Captura partículas de hasta 2 micrones, protegiendo tu bomba de inyección y los inyectores. Los dieseles common-rail modernos tienen tolerancias en los inyectores más finas que un cabello humano. Combustible contaminado llegando a esos inyectores significa $300 a $800 por inyector en reparaciones. Cambia este filtro en cada cambio de aceite. + +La humedad y los cambios de temperatura en Florida causan condensación constante dentro de los depósitos. Eso significa agua, y el agua significa algas en el diesel. La filtración en dos etapas no es opcional aquí — es supervivencia. + +Escríbenos para mantenimiento preventivo — de Stuart a Jacksonville. + +`#FuelFilter #RacorFilter #MarineDiesel #FuelFiltration #DieselMaintenance #MarineEngine #FloridaBoating #BoatMaintenance #PreventiveMaintenance #PrisaYachtsLLC` + +--- + +## TIP 4 — CAMBIO DE ACEITE MARINO vs. AUTOMOTRIZ +### "Your Boat Engine Is Not Your Car" + +**Caption EN** + +Your car tells you when to change the oil. Your boat doesn't. And the consequences of getting this wrong are far more expensive on the water. + +Marine engines run at sustained high loads for hours. They sit in humid environments. Raw-water cooling systems push moisture into the engine compartment. All of that destroys oil far faster than a highway commute ever could. + +The rules are different here: +- Gasoline inboard: every 100 hours OR once per season +- Diesel inboard: every 100-150 hours (check your manual) +- Stored for the season? Change the oil before AND after storage — not just one. + +Also critical: do NOT use automotive "Energy Conserving" oil in a marine gasoline engine. Those friction modifiers can cause your marine transmission clutch to slip. Use oil rated and specified for your exact engine. + +And always — always — change the filter at the same time. + +DM us for preventive maintenance — Stuart to Jacksonville. + +`#MarineOilChange #OilChange #MarineEngine #InboardDiesel #BoatMaintenance #MarineMechanic #PreventiveMaintenance #FloridaBoating #SaltwaterBoating #PrisaYachtsLLC` + +--- + +**Caption ES** + +Tu carro te avisa cuando cambiar el aceite. Tu barca no. Y las consecuencias de equivocarse son mucho más caras en el agua. + +Los motores marinos trabajan a cargas altas sostenidas durante horas. Están en ambientes húmedos. Los sistemas de refrigeración de agua bruta empujan humedad al compartimento del motor. Todo eso destruye el aceite mucho más rápido que un viaje en autopista. + +Las reglas son distintas aquí: +- Gasolina inboard: cada 100 horas O una vez por temporada +- Diesel inboard: cada 100 a 150 horas (revisa tu manual) +- ¿Guardaste la barca por la temporada? Cambia el aceite ANTES y DESPUÉS — no solo una vez. + +También crítico: NO uses aceite automotriz "Energy Conserving" en un motor marino de gasolina. Los modificadores de fricción de esos aceites pueden hacer que el embrague de la transmisión marina patine. Usa aceite especificado para tu motor exacto. + +Y siempre — siempre — cambia el filtro al mismo tiempo. + +Escríbenos para mantenimiento preventivo — de Stuart a Jacksonville. + +`#MarineOilChange #OilChange #MarineEngine #InboardDiesel #BoatMaintenance #MarineMechanic #PreventiveMaintenance #FloridaBoating #SaltwaterBoating #PrisaYachtsLLC` + +--- + +## TIP 5 — COLORES DEL HUMO DEL ESCAPE +### "Read the Smoke Before the Engine Can't Talk Anymore" + +**Caption EN** + +Your engine can't text you. But it can talk through its exhaust — if you know how to listen. + +WHITE SMOKE (persistent, not startup condensation): Water or coolant in the combustion chamber. Head gasket, cracked head, or heat exchanger failure. If your oil looks milky, shut down NOW. Do not restart. + +BLACK SMOKE: Too much fuel, not enough air. Clogged air filter, dirty injectors, failing turbo, restricted intake. Less urgent than white, but fix it — carbon buildup adds up fast and fuel efficiency drops. + +BLUE SMOKE: Oil burning in the combustion chamber. Worn piston rings, valve seals, or a turbo seal failure. Startup blue that clears? Likely valve seals. Persistent blue under load? That's a mechanical inspection — now. + +Florida heat, saltwater exposure, and high humidity accelerate every one of these failure modes. Read your exhaust at startup, during acceleration, and under load. Make it a habit every single time you leave the dock. + +DM us for preventive maintenance — Stuart to Jacksonville. + +`#ExhaustSmoke #MarineEngineDiagnostics #WhiteSmoke #BlackSmoke #BlueSmoke #MarineEngine #BoatMaintenance #FloridaBoating #MarineMechanic #PrisaYachtsLLC` + +--- + +**Caption ES** + +Tu motor no puede mandarte un mensaje. Pero puede hablar a través de su escape — si sabes escuchar. + +HUMO BLANCO (persistente, no condensación al arranque): Agua o refrigerante en la cámara de combustión. Junta de culata, culata fisurada, o fallo del intercambiador de calor. Si el aceite se ve lechoso, APAGA el motor YA. No lo vuelvas a encender. + +HUMO NEGRO: Demasiado combustible, poco aire. Filtro de aire obstruido, inyectores sucios, turbo fallando, toma de aire restringida. Menos urgente que el blanco, pero soluciónalo — la acumulación de carbón es costosa y el rendimiento cae. + +HUMO AZUL: Aceite quemándose en la cámara de combustión. Anillos de pistón desgastados, retenes de válvulas, o fallo del sello del turbo. ¿Azul al arranque que desaparece? Probablemente retenes de válvulas. ¿Azul persistente bajo carga? Inspección mecánica — ahora. + +El calor de Florida, la exposición al agua salada y la humedad aceleran todos estos modos de fallo. Lee tu escape al arrancar, durante la aceleración y bajo carga. Haz un hábito de esto cada vez que salgas del muelle. + +Escríbenos para mantenimiento preventivo — de Stuart a Jacksonville. + +`#ExhaustSmoke #MarineEngineDiagnostics #WhiteSmoke #BlackSmoke #BlueSmoke #MarineEngine #BoatMaintenance #FloridaBoating #MarineMechanic #PrisaYachtsLLC` + +--- + +## CARRUSEL — "Annual Engine Service Checklist — Florida Saltwater Edition" + +### SLIDE 1 — Cover +**HEADLINE:** Annual Engine Service Checklist — Florida Saltwater Edition +**SUBTEXT:** 10 things your engine needs every year to survive Florida's saltwater environment. (Most boat owners skip at least 3 of these.) +**Bottom tag:** @prisayachts | Stuart to Jacksonville + +--- + +### SLIDE 2 — Fluids and Filters +**HEADLINE:** Step 1 — Fluids and Filters +- Change engine oil and oil filter (per manufacturer hours) +- Replace primary fuel filter element (Racor bowl) +- Replace secondary engine fuel filter +- Check and replace gear oil in transmission/outdrive +- Inspect coolant concentration and condition (50/50 minimum) +- Drain and inspect raw-water strainer basket + +**Florida tip:** Diesel tanks collect condensation year-round. Inspect Racor bowl every 50 hours — never skip it. + +--- + +### SLIDE 3 — Raw Water Cooling System +**HEADLINE:** Step 2 — Raw Water Cooling Circuit +- Replace raw-water impeller (every 200 hours or annually) +- Inspect and flush heat exchanger +- Check all raw-water hoses for cracking, softness, or swelling +- Inspect thermostat — replace every 2 seasons in saltwater +- Clean seacock strainer and test seacock operation +- Verify exhaust water flow at startup (look for a steady stream) + +**Florida tip:** A failed impeller in summer heat can destroy a motor in under 5 minutes. Replace it every season — do not test it. + +--- + +### SLIDE 4 — Belts, Hoses and Anodes +**HEADLINE:** Step 3 — Belts, Hoses and Anodes +- Inspect and replace serpentine/V-belts (check for cracking, glazing, fraying) +- Replace all zincs/anodes: lower unit, trim tab, shaft, rudder, hull plates +- Inspect all coolant hoses — squeeze test for hardness or sponginess +- Check all fuel hose connections for seepage or cracking +- Inspect motor mounts for deterioration +- Check engine alignment (inboard) + +**Florida tip:** Replace anodes when 50% consumed — not 100%. Aluminum anodes outperform zinc in full saltwater. + +--- + +### SLIDE 5 — Ignition, Electrical and Final Checks +**HEADLINE:** Step 4 — Ignition, Electrical and Final Checks +- Inspect and clean battery terminals — check electrolyte levels +- Test alternator output voltage (13.8-14.4V at charge) +- Inspect spark plugs or glow plugs depending on engine type +- Test all engine alarms: overheat, low oil pressure, no raw-water flow +- Run engine to full operating temperature — observe exhaust color +- Log engine hours and record all service performed with dates + +**Florida tip:** Test your alarms with every service. An alarm that doesn't sound gives you zero warning when it matters most. + +**CTA (all slides):** Need this done right? DM us for your annual engine service. Prisa Yachts LLC — Stuart to Jacksonville | @prisayachts + +`#AnnualBoatService #MarineEngineService #BoatMaintenance #FloridaBoating #SaltwaterBoating #MarineMechanic #EngineChecklist #PreventiveMaintenance #YachtMaintenance #PrisaYachtsLLC` diff --git a/prisa-yachts/contenido_teca_detailing.md b/prisa-yachts/contenido_teca_detailing.md new file mode 100644 index 0000000..ca800e1 --- /dev/null +++ b/prisa-yachts/contenido_teca_detailing.md @@ -0,0 +1,333 @@ +# Prisa Yachts LLC — Recuperación de Teca y Detailing +## 5 Tips Técnicos + 3 Captions Before/After para fotos reales + +--- + +## TIP 1 — ¿SE PUEDE SALVAR TU TECA? +### "Can Your Teak Be Saved? (Visual Evaluation)" + +**Caption EN** + +Your teak is gray and looks rough — but is it actually dead? + +Here's the honest evaluation we do before touching a single plank. Run your thumbnail across the grain: if the wood is dense, firm, and fibers don't lift, that gray surface is just oxidation. The honey-brown color is still underneath, waiting. That's a recovery job. + +What tells us replacement is the real answer: soft spots that compress under pressure, caulking seams that have pulled away from the wood by more than an inch, planks cracking along the grain from the inside out, or wood that's gone thin from years of aggressive sanding. + +In Florida, two seasons of zero maintenance is often the turning point. We've recovered teak that looked destroyed — and we've also had the honest conversation when replacement was the smarter investment. + +If you're not sure which side of that line you're on, send us a few photos. We'll give you a straight answer before you spend a dollar. + +DM us for a quote — Stuart to Jacksonville. + +`#PrisaYachts #TeakRecovery #MarineTeak #BoatMaintenance #FloridaBoating #YachtDetailing #TeakDeck #MarineServices #BoatCare #SouthFloridaYachts` + +--- + +**Caption ES** + +Tu teca está gris y se ve mal — pero, ¿realmente está muerta? + +Esta es la evaluación honesta que hacemos antes de tocar una sola tabla. Pasa la uña a contrapelo: si la madera está densa, firme y las fibras no se levantan, esa superficie gris es solo oxidación. El color miel todavía está adentro, esperando. Eso es trabajo de recuperación. + +Lo que nos dice que el reemplazo es la respuesta real: zonas blandas que ceden bajo presión, costuras de sellado separadas más de 2 cm, tablas con grietas a lo largo de la veta desde adentro, o madera que se ha adelgazado por lijados agresivos previos. + +En Florida, dos temporadas sin mantenimiento suelen ser el punto de quiebre. Hemos recuperado teca que parecía destruida — y también hemos tenido la conversación honesta cuando el reemplazo era la inversión más inteligente. + +Si no sabes de qué lado estás, mándanos unas fotos. Te damos una respuesta directa antes de que gastes un dólar. + +Escríbenos para un presupuesto — Stuart to Jacksonville. + +`#PrisaYachts #RecuperacionDeTeca #TecaMarina #MantenimientoNautico #YachtsFlorida #DetallingMarino #TecaNautica #ServiciosMarinos #CuidadoDeBarco #YachtsSurFlorida` + +--- + +## TIP 2 — EL PROCESO: CLEAN → SAND → OIL → SEAL + +**Caption EN** + +Teak recovery isn't magic — it's a sequence. And most DIY jobs fail because they skip a step. + +Here's the actual process we follow: + +CLEAN — Two-part teak cleaner. Part A breaks down oxidation and gray surface cells. Part B neutralizes the wood's pH. You're starting with a clean canvas, not covering problems. + +SAND — 80-grit to open the grain, 120-grit to smooth. Always with the grain. Never cross-grain with a random orbit sander — you'll create water traps invisible to the eye. + +OIL — Penetrating marine teak oil, thin coats, wiped before it skins. This feeds the wood from the inside. You're not painting it, you're conditioning it. + +SEAL — UV-blocking teak sealer for high-traffic areas. Florida sun will reoxidize bare teak in one season. The sealer buys you 12 to 18 months before the next maintenance cycle. + +Skip any of these steps and you're spending money to fail faster. + +DM us for a quote — Stuart to Jacksonville. + +`#PrisaYachts #TeakRestoration #MarineTeak #BoatDetailingFlorida #TeakDeckCare #MarineWoodcare #FloridaYacht #BoatMaintenance #YachtCare #MarineDetailing` + +--- + +**Caption ES** + +La recuperación de teca no es magia — es una secuencia. Y la mayoría de los trabajos fallan porque se salta un paso. + +Este es el proceso real que seguimos: + +LIMPIAR — Limpiador de teca en dos partes. La parte A rompe la oxidación y las células grises de la superficie. La parte B neutraliza el pH de la madera. Empiezas con una superficie limpia, no cubriendo problemas. + +LIJAR — Lija 80 para abrir el grano, 120 para alisar. Siempre a favor de la veta. Nunca transversal con lijadora orbital — creas trampas de agua invisibles al ojo. + +ACEITAR — Aceite marino de teca penetrante, capas finas, limpiando el exceso antes de que forme película. Nutres la madera desde adentro. No la estás pintando, la estás acondicionando. + +SELLAR — Sellador UV para zonas de alto tráfico. El sol de Florida reoxida la teca sin protección en una sola temporada. El sellador te da 12 a 18 meses hasta el próximo ciclo de mantenimiento. + +Sáltate cualquiera de estos pasos y estás gastando dinero para fallar más rápido. + +Escríbenos para un presupuesto — Stuart to Jacksonville. + +`#PrisaYachts #RestauracionTeca #TecaMarina #DetallingFlorida #CuidadoTeca #MaderaMaritima #YachtFlorida #MantenimientoNautico #CuidadoYacht #DetallingNautico` + +--- + +## TIP 3 — TEAK OIL vs. TEAK SEALER: CUÁL Y CUÁNDO + +**Caption EN** + +Teak oil and teak sealer are not the same product. Using the wrong one at the wrong time is one of the most expensive mistakes in boat maintenance. + +Here's the difference: + +TEAK OIL is a penetrating product. It goes INTO the wood, not onto it. It feeds depleted wood — replacing the natural oils that Florida sun and salt air pull out month after month. Use it after a full clean and sand, when the wood is porous and dry. If it doesn't absorb within 20 minutes, something is wrong with the prep. + +TEAK SEALER is a surface barrier. It doesn't feed the wood — it seals the surface against UV, moisture movement, and reoxidation. Use it AFTER oiling, as the final layer on horizontal surfaces that take direct sun and standing water. + +The order matters: oil first, sealer second. Putting sealer on dry, un-oiled teak in Florida gives you 90 days of results before it starts peeling — because the wood is moving underneath and there's nothing holding it stable. + +Two products. Two jobs. Both necessary. Neither optional in this climate. + +DM us for a quote — Stuart to Jacksonville. + +`#PrisaYachts #TeakOil #TeakSealer #MarineTeak #BoatWoodcare #FloridaBoating #TeakMaintenance #YachtCare #MarineDetailing #BoatMaintenance` + +--- + +**Caption ES** + +El aceite de teca y el sellador de teca no son el mismo producto. Usar el equivocado en el momento equivocado es uno de los errores más caros en el mantenimiento de embarcaciones. + +La diferencia: + +ACEITE DE TECA es un producto penetrante. Va DENTRO de la madera, no sobre ella. Nutre la madera agotada — reemplazando los aceites naturales que el sol de Florida y el aire salado extraen mes a mes. Úsalo después de una limpieza y lijado completo, cuando la madera está porosa y seca. Si no absorbe en 20 minutos, algo está mal con la preparación. + +SELLADOR DE TECA es una barrera superficial. No nutre la madera — sella la superficie contra los rayos UV, el movimiento de humedad y la reoxidación. Úsalo DESPUÉS del aceite, como capa final en superficies horizontales que reciben sol directo y agua estancada. + +El orden importa: aceite primero, sellador después. Poner sellador en teca seca sin aceite en Florida te da 90 días de resultados antes de que empiece a despegarse — porque la madera se está moviendo por debajo y no hay nada que la estabilice. + +Dos productos. Dos funciones. Ambos necesarios. Ninguno es opcional en este clima. + +Escríbenos para un presupuesto — Stuart to Jacksonville. + +`#PrisaYachts #AceiteDeTeca #SelladorTeca #TecaMarina #MaderaMaritima #NavegacionFlorida #MantenimientoTeca #CuidadoYacht #DetallingMarino #MantenimientoNautico` + +--- + +## TIP 4 — POR QUÉ EL SOL DE FLORIDA DESTRUYE LA TECA EN 2 TEMPORADAS + +**Caption EN** + +Florida is not a forgiving environment for teak. And a lot of boat owners don't understand why until they're looking at a replacement quote. + +Here's what's actually happening to your deck every season you skip maintenance: + +UV INDEX 10-11 from March through October. That's among the highest in the continental US. It bleaches the lignin — the natural binder that holds teak fibers together — and oxidizes the surface oils that give the wood its density. Once the lignin is gone, the fibers start separating. + +SALT AIR deposits salt crystals in the open grain. Those crystals absorb moisture and expand and contract with the daily heat cycle, physically prying the wood open from the inside. + +THERMAL CYCLING on a dark deck surface means 35-40°F swings between 7 AM and 2 PM. That's constant wood movement — and it accelerates everything above. + +Teak planks start at 5/8 inch from the factory. Every aggressive sanding to fix neglect removes material that doesn't come back. Two seasons of zero maintenance in Florida can take a recoverable deck and make it a replacement conversation. + +One maintenance cycle per year stops all three damage channels. The math on prevention versus replacement is not close. + +DM us for a quote — Stuart to Jacksonville. + +`#PrisaYachts #FloridaBoating #TeakDeck #UVDamage #MarineTeak #BoatMaintenance #TeakProtection #FloridaYacht #MarineDetailing #YachtCare` + +--- + +**Caption ES** + +Florida no es un ambiente generoso con la teca. Y muchos dueños de embarcaciones no lo entienden hasta que están viendo un presupuesto de reemplazo. + +Esto es lo que le pasa a tu cubierta cada temporada que saltas el mantenimiento: + +ÍNDICE UV 10-11 de marzo a octubre. Es uno de los más altos de los Estados Unidos continentales. Blanquea la lignina — el aglutinante natural que mantiene las fibras de teca unidas — y oxida los aceites superficiales que le dan densidad a la madera. Una vez que la lignina se va, las fibras comienzan a separarse. + +AIRE SALADO deposita cristales de sal en el grano abierto. Esos cristales absorben humedad y se expanden y contraen con el ciclo de calor diario, abriendo físicamente la madera desde adentro. + +CICLOS TÉRMICOS en una cubierta oscura significan cambios de 18-22°C entre las 7 AM y las 2 PM. Eso es movimiento constante de la madera — y acelera todo lo anterior. + +Las tablas de teca salen de fábrica a 16 mm de espesor. Cada lijado agresivo para corregir el abandono elimina material que no vuelve. Dos temporadas sin mantenimiento en Florida pueden convertir una cubierta recuperable en una conversación de reemplazo. + +Un ciclo de mantenimiento al año detiene los tres canales de daño. La diferencia entre prevención y reemplazo no admite discusión. + +Escríbenos para un presupuesto — Stuart to Jacksonville. + +`#PrisaYachts #NavegacionFlorida #TecaMarina #DañoUV #CubertaDeTeca #MantenimientoNautico #ProteccionTeca #YachtFlorida #DetallingMarino #CuidadoYacht` + +--- + +## TIP 5 — GELCOAT DETAILING: OXIDACIÓN LEVE vs. SEVERA + +**Caption EN** + +Not all oxidation is the same — and treating them the same way is how you either under-correct or burn through your gelcoat. + +Here's how to read what you're dealing with: + +LIGHT OXIDATION: Surface looks hazy, colors seem flat instead of vibrant. Drag a white rag across it — faint chalk residue. At this stage, a fine-cut polish on a DA polisher restores the gloss without removing significant gelcoat. Follow with a quality marine wax or sealant. In Florida, that protection lasts 3 to 6 months. + +SEVERE OXIDATION: Heavy chalking when touched, original color has shifted toward white or gray, surface feels matte and doesn't respond to light polishing. Now you're in cutting compound territory — wool or foam cutting pad, rotary or forced-rotation polisher. The risk: gelcoat is only 0.5 to 0.8mm thick. Heavy cutting requires experienced hands or you break through. + +The rule we follow: start with the least aggressive correction that solves the problem. You can always cut more. You can't put gelcoat back. + +After any cut: finishing polish to remove cut marks, then wax or sealant to protect what you've restored. + +DM us for a quote — Stuart to Jacksonville. + +`#PrisaYachts #GelcoatRestoration #BoatDetailing #MarineDetailing #FloridaBoating #GelcoatPolishing #BoatWax #YachtDetailing #OxidationRemoval #BoatCare` + +--- + +**Caption ES** + +No toda oxidación es igual — y tratarlas igual es como se corrige de menos o se quema la capa de gelcoat. + +Así se lee lo que tienes frente a ti: + +OXIDACIÓN LEVE: La superficie se ve opaca, los colores parecen apagados en vez de vibrantes. Pasa un trapo blanco — residuo de tiza leve. En este punto, una pulida fina con pulidora DA restaura el brillo sin remover gelcoat significativo. Termina con cera marina o sellador. En Florida, esa protección dura 3 a 6 meses. + +OXIDACIÓN SEVERA: Tizamiento fuerte al tacto, el color original se ha ido hacia el blanco o gris, la superficie se siente mate y no responde al pulido leve. Ahora estás en territorio de compuesto de corte — pad de lana o espuma de corte, pulidora rotativa o de rotación forzada. El riesgo: el gelcoat tiene solo 0.5 a 0.8mm de espesor. El corte agresivo requiere manos con experiencia o lo atraviesas. + +La regla que seguimos: empezar siempre con la corrección menos agresiva que resuelve el problema. Siempre puedes cortar más. No puedes devolver el gelcoat. + +Después de cualquier corte: pulido de acabado para eliminar las marcas, luego cera o sellador para proteger lo que restauraste. + +Escríbenos para un presupuesto — Stuart to Jacksonville. + +`#PrisaYachts #RestauracionGelcoat #DetallingNautico #DetallingMarino #NavegacionFlorida #PulidoGelcoat #CeraParaBarcos #DetallingYacht #EliminacionOxidacion #CuidadoBarco` + +--- + +## CAPTIONS BEFORE/AFTER — PARA TUS 10 FOTOS REALES DE TECA + +### CAPTION A — RESTAURACIÓN DRAMÁTICA (Muy deteriorada → Perfecta) + +**Caption EN** + +This is what two seasons of Florida sun and zero maintenance does to teak. And this is what the same deck looks like after a full recovery. + +No replacement. No new planks. The same wood — cleaned, sanded, oiled, and sealed by hand. + +What you're seeing on the left: gray, fiber-lifting, salt-embedded teak that most people would write off. What you're seeing on the right: the same deck, same wood, after a full two-part clean, progressive sanding, penetrating marine oil, and UV-blocking sealer. + +The honey-brown color was there the entire time. We just had to take the time to find it. + +This is why we evaluate before we quote. A lot of teak that looks dead in Florida isn't. It's just asking for the right process. + +DM us for a quote — Stuart to Jacksonville. + +`#PrisaYachts #TeakBeforeAfter #TeakRestoration #MarineTeak #FloridaBoating #BoatDetailingFlorida #TeakDeck #BeforeAndAfter #YachtCare #MarineDetailing` + +--- + +**Caption ES** + +Esto es lo que dos temporadas de sol de Florida y cero mantenimiento le hacen a la teca. Y esto es lo que luce el mismo deck después de una recuperación completa. + +Sin reemplazo. Sin tablas nuevas. La misma madera — limpiada, lijada, aceitada y sellada a mano. + +Lo que ves a la izquierda: teca gris, fibras levantadas, sal incrustada, que la mayoría descartaría. Lo que ves a la derecha: el mismo deck, la misma madera, después de una limpieza en dos partes, lijado progresivo, aceite marino penetrante y sellador con bloqueo UV. + +El color miel estaba ahí todo el tiempo. Solo había que tomarse el tiempo de encontrarlo. + +Por eso evaluamos antes de cotizar. Mucha teca que parece muerta en Florida no lo está. Solo necesita el proceso correcto. + +Escríbenos para un presupuesto — Stuart to Jacksonville. + +`#PrisaYachts #TecaAntesYDespues #RestauracionTeca #TecaMarina #NavegacionFlorida #DetallingFlorida #CubertaTeca #AntesYDespues #CuidadoYacht #DetallingMarino` + +--- + +### CAPTION B — MANTENIMIENTO PREVENTIVO (Teca ya cuidada → Mejor aún) + +**Caption EN** + +Preventive maintenance doesn't make the news. But this is what it actually looks like. + +This deck wasn't neglected. The owner was already doing the right things — keeping it clean, protecting it seasonally. We came in for a maintenance detail: light clean, light sand to refresh the grain, one coat of oil, sealer applied on horizontal surfaces. + +The difference between left and right isn't dramatic. It's deliberate. + +This is what protects a deck from ever needing the dramatic before/after. This is what adds years to the life of a teak investment. This is what the deck looks like when the owner treats it like the asset it is. + +One maintenance cycle per year in Florida. That's the whole strategy. + +DM us for a quote — Stuart to Jacksonville. + +`#PrisaYachts #TeakMaintenance #PreventiveMaintenance #MarineTeak #BoatCare #FloridaYacht #TeakDeck #YachtMaintenance #MarineDetailing #BoatDetailing` + +--- + +**Caption ES** + +El mantenimiento preventivo no sale en los titulares. Pero así es como se ve en la realidad. + +Esta cubierta no estaba abandonada. El propietario ya estaba haciendo las cosas bien — manteniéndola limpia, protegiéndola cada temporada. Llegamos para un detailing de mantenimiento: limpieza leve, lijado suave para refrescar el grano, una capa de aceite, sellador en las superficies horizontales. + +La diferencia entre la izquierda y la derecha no es dramática. Es intencional. + +Esto es lo que protege una cubierta de necesitar el antes/después dramático. Esto es lo que le agrega años de vida a una inversión en teca. Así luce una cubierta cuando el propietario la trata como el activo que es. + +Un ciclo de mantenimiento al año en Florida. Esa es toda la estrategia. + +Escríbenos para un presupuesto — Stuart to Jacksonville. + +`#PrisaYachts #MantenimientoTeca #MantenimientoPreventivo #TecaMarina #CuidadoBarco #YachtFlorida #CubertaTeca #MantenimientoYacht #DetallingMarino #DetallingNautico` + +--- + +### CAPTION C — EN PROCESO (Mostrando el trabajo) + +**Caption EN** + +Somewhere between gray and honey-brown, there's a lot of work. + +This is what teak recovery looks like mid-process. Two-part cleaner done. First sand done. The color is already starting to come back — you can see the honey showing through in the sections we've finished, still gray in the ones we haven't reached yet. + +This is the part that doesn't get skipped. No shortcuts between the before and after. + +Every plank by hand. Every seam inspected. Sanding with the grain, not against it. Wiping off the oil before it skins. Letting each coat dry before the next one goes on. + +The finished result is in the next post. But we wanted you to see this part too — because this is where the job actually gets done. + +DM us for a quote — Stuart to Jacksonville. + +`#PrisaYachts #TeakRecovery #BehindTheScenes #MarineTeak #BoatDetailingFlorida #TeakRestoration #WorkInProgress #YachtCare #MarineDetailing #FloridaBoating` + +--- + +**Caption ES** + +Entre el gris y el color miel, hay mucho trabajo. + +Así luce una recuperación de teca a la mitad del proceso. Limpiador en dos partes listo. Primer lijado listo. El color ya está empezando a volver — puedes ver el miel asomando en las secciones que terminamos, todavía gris en las que no hemos llegado. + +Esta es la parte que no se salta. No hay atajos entre el antes y el después. + +Cada tabla a mano. Cada costura inspeccionada. Lijando a favor de la veta, nunca en contra. Limpiando el aceite antes de que forme película. Dejando que cada capa seque antes de aplicar la siguiente. + +El resultado final está en el próximo post. Pero queríamos que vieras esta parte también — porque aquí es donde realmente se hace el trabajo. + +Escríbenos para un presupuesto — Stuart to Jacksonville. + +`#PrisaYachts #RecuperacionTeca #DetrásDeEscena #TecaMarina #DetallingFlorida #RestauracionTeca #EnProceso #CuidadoYacht #DetallingMarino #NavegacionFlorida` diff --git a/prisa-yachts/generate_brochures.py b/prisa-yachts/generate_brochures.py new file mode 100644 index 0000000..846d101 --- /dev/null +++ b/prisa-yachts/generate_brochures.py @@ -0,0 +1,757 @@ +""" +Prisa Yachts LLC — Bilingual PDF Brochure Generator +Generates 3 professional PDFs using ReportLab. +""" + +import os +from reportlab.lib.pagesizes import letter, landscape +from reportlab.lib.units import inch +from reportlab.lib.colors import Color, HexColor, white, black +from reportlab.pdfgen import canvas +from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle +from reportlab.platypus import Paragraph +from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_RIGHT, TA_JUSTIFY +from reportlab.pdfbase import pdfmetrics +from reportlab.pdfbase.ttfonts import TTFont +from PIL import Image as PILImage +import textwrap + +# ── Brand constants ──────────────────────────────────────────────────────────── +NAVY = HexColor('#1B3A6B') +GOLD = HexColor('#C9A84C') +WHITE = HexColor('#FFFFFF') +LIGHT_NAVY = HexColor('#2A5298') +LIGHT_GRAY = HexColor('#F5F5F5') +DARK_GRAY = HexColor('#333333') + +LOGO_PATH = r"D:\Prisa Yachts LLC\WhatsApp Image 2026-03-11 at 22.24.00.jpeg" +OUTPUT_DIR = r"D:\Proyectos Software\Agente Marketing\prisa-yachts\brochures" + +TAGLINE = "Safe Command ◇ Luxury Maintenance and Care" +WEBSITE = "prisayachts.com" +AREA = "Stuart to Jacksonville, FL" + +# ── Helper: draw logo or text placeholder ───────────────────────────────────── +def draw_logo(c, x, y, width, height, centered=True): + """Draw the logo image; fall back to a styled text block if unavailable.""" + if os.path.exists(LOGO_PATH): + try: + if centered: + c.drawImage(LOGO_PATH, x - width / 2, y - height, + width=width, height=height, + preserveAspectRatio=True, mask='auto') + else: + c.drawImage(LOGO_PATH, x, y - height, + width=width, height=height, + preserveAspectRatio=True, mask='auto') + return + except Exception: + pass + # Fallback placeholder + bx = x - width / 2 if centered else x + by = y - height + c.setFillColor(NAVY) + c.rect(bx, by, width, height, fill=1, stroke=0) + c.setFillColor(GOLD) + c.setFont("Helvetica-Bold", 10) + c.drawCentredString(bx + width / 2, by + height / 2 - 4, "PRISA YACHTS LLC") + c.setFont("Helvetica", 7) + c.setFillColor(WHITE) + c.drawCentredString(bx + width / 2, by + height / 2 - 16, "prisayachts.com") + + +def draw_gold_line(c, x1, y, x2, thickness=1.0): + c.setStrokeColor(GOLD) + c.setLineWidth(thickness) + c.line(x1, y, x2, y) + + +def draw_gold_divider(c, x, y, width, thickness=1.0): + draw_gold_line(c, x, y, x + width, thickness) + + +# ── Text wrapping helper ─────────────────────────────────────────────────────── +def draw_wrapped_text(c, text, x, y, max_width, font_name, font_size, + line_height, color=None, align='left'): + """Draw text wrapping within max_width, returns final y position.""" + if color: + c.setFillColor(color) + c.setFont(font_name, font_size) + words = text.split() + lines = [] + current = [] + for word in words: + test_line = ' '.join(current + [word]) + if c.stringWidth(test_line, font_name, font_size) <= max_width: + current.append(word) + else: + if current: + lines.append(' '.join(current)) + current = [word] + if current: + lines.append(' '.join(current)) + for line in lines: + if align == 'center': + c.drawCentredString(x + max_width / 2, y, line) + elif align == 'right': + c.drawRightString(x + max_width, y, line) + else: + c.drawString(x, y, line) + y -= line_height + return y + + +def draw_section_header(c, text, x, y, width, bg_color=NAVY, text_color=GOLD, + font_size=11, padding=5): + """Draw a colored section header bar.""" + bar_h = font_size + padding * 2 + c.setFillColor(bg_color) + c.rect(x, y - bar_h, width, bar_h, fill=1, stroke=0) + c.setFillColor(text_color) + c.setFont("Helvetica-Bold", font_size) + c.drawString(x + padding + 2, y - bar_h + padding, text) + return y - bar_h + + +def draw_bullet_item(c, text, x, y, max_width, font_name="Helvetica", + font_size=8.5, line_height=12, bullet_color=GOLD, + text_color=DARK_GRAY): + """Draw a gold diamond bullet followed by wrapped text.""" + bullet = "◇ " + indent = 14 + c.setFont("Helvetica-Bold", font_size) + c.setFillColor(bullet_color) + c.drawString(x, y, "◇") + y = draw_wrapped_text(c, text, x + indent, y, + max_width - indent, font_name, font_size, + line_height, color=text_color) + return y - 2 + + +# ══════════════════════════════════════════════════════════════════════════════ +# BROCHURE 1 — General Services (landscape letter, 3 columns) +# ══════════════════════════════════════════════════════════════════════════════ +def generate_brochure1(): + path = os.path.join(OUTPUT_DIR, "PrisaYachts_General_Services.pdf") + pw, ph = landscape(letter) # 792 x 612 pts + c = canvas.Canvas(path, pagesize=landscape(letter)) + c.setTitle("Prisa Yachts LLC — Professional Marine Services") + c.setAuthor("Prisa Yachts LLC") + c.setSubject("General Marine Services Brochure EN/ES") + + margin = 0.35 * inch + col_gap = 0.18 * inch + usable_w = pw - 2 * margin + left_col_w = usable_w * 0.24 + center_col_w = usable_w * 0.38 + right_col_w = usable_w - left_col_w - center_col_w - 2 * col_gap + + left_x = margin + center_x = left_x + left_col_w + col_gap + right_x = center_x + center_col_w + col_gap + top_y = ph - margin + bottom_y = margin + + # ── Full background white ── + c.setFillColor(WHITE) + c.rect(0, 0, pw, ph, fill=1, stroke=0) + + # ── LEFT COLUMN — navy background ──────────────────────────────────────── + col_h = ph - 2 * margin + c.setFillColor(NAVY) + c.rect(left_x, bottom_y, left_col_w, col_h, fill=1, stroke=0) + + # Logo + logo_y = top_y - 0.15 * inch + logo_w = left_col_w - 0.3 * inch + logo_h = 1.0 * inch + draw_logo(c, left_x + left_col_w / 2, logo_y, logo_w, logo_h, centered=True) + cur_y = logo_y - logo_h - 0.1 * inch + + # Company name + c.setFillColor(WHITE) + c.setFont("Helvetica-Bold", 12) + c.drawCentredString(left_x + left_col_w / 2, cur_y, "Prisa Yachts LLC") + cur_y -= 0.22 * inch + + # Tagline (gold italic, wrapped) + c.setFillColor(GOLD) + c.setFont("Helvetica-Oblique", 7.5) + tagline_parts = ["Safe Command ◇", "Luxury Maintenance and Care"] + for part in tagline_parts: + c.drawCentredString(left_x + left_col_w / 2, cur_y, part) + cur_y -= 0.16 * inch + cur_y -= 0.05 * inch + + # Service area + c.setFillColor(WHITE) + c.setFont("Helvetica", 7.5) + c.drawCentredString(left_x + left_col_w / 2, cur_y, AREA) + cur_y -= 0.18 * inch + + # Gold divider + pad = 0.15 * inch + draw_gold_divider(c, left_x + pad, cur_y, left_col_w - 2 * pad, 1.5) + cur_y -= 0.2 * inch + + # Contact blocks + contacts = [ + ("Alberto", "(954) 655-4084", "technical@prisayachts.com"), + ("Federico", "(754) 209-3375", "management@prisayachts.com"), + ] + for name, phone, email in contacts: + c.setFillColor(GOLD) + c.setFont("Helvetica-Bold", 8.5) + c.drawCentredString(left_x + left_col_w / 2, cur_y, name) + cur_y -= 0.15 * inch + c.setFillColor(WHITE) + c.setFont("Helvetica", 7.5) + c.drawCentredString(left_x + left_col_w / 2, cur_y, phone) + cur_y -= 0.14 * inch + c.setFont("Helvetica", 6.8) + c.drawCentredString(left_x + left_col_w / 2, cur_y, email) + cur_y -= 0.2 * inch + + # Gold divider + draw_gold_divider(c, left_x + pad, cur_y, left_col_w - 2 * pad, 1.0) + cur_y -= 0.18 * inch + + # Website + c.setFillColor(GOLD) + c.setFont("Helvetica-Bold", 8) + c.drawCentredString(left_x + left_col_w / 2, cur_y, WEBSITE) + + # ── CENTER COLUMN — English services ───────────────────────────────────── + # Column background (very light) + c.setFillColor(WHITE) + c.rect(center_x, bottom_y, center_col_w, col_h, fill=1, stroke=0) + + # Thin navy left border + c.setFillColor(NAVY) + c.rect(center_x, bottom_y, 3, col_h, fill=1, stroke=0) + + cur_y = top_y - 0.15 * inch + + # Header + c.setFillColor(NAVY) + c.setFont("Helvetica-Bold", 14) + c.drawString(center_x + 0.15 * inch, cur_y, "Professional Marine Services") + cur_y -= 0.12 * inch + draw_gold_divider(c, center_x + 0.15 * inch, cur_y, + center_col_w - 0.2 * inch, 2.0) + cur_y -= 0.22 * inch + + en_services = [ + "Marine Electrical (ABYC E-11 Certified)", + "Lithium Battery Bank Design & Installation", + "Shore Power & Inverter/Charger Systems", + "Solar & Alternator Upgrades", + "Full Rewiring (Tinned Wire, Labeled Circuits)", + "Teak Deck Recovery & Restoration", + "Gelcoat Polishing & Oxidation Removal", + "Washdown System Installation", + "Anchor Windlass & Bilge Systems", + "NMEA 2000 / 0183 Integration", + "Pre-Season Inspection & Annual Service", + ] + + bx = center_x + 0.15 * inch + bw = center_col_w - 0.25 * inch + for svc in en_services: + cur_y = draw_bullet_item(c, svc, bx, cur_y, bw, + font_size=8.5, line_height=11.5) + cur_y -= 1 + + # Footer band + footer_h = 0.55 * inch + footer_y = bottom_y + c.setFillColor(LIGHT_GRAY) + c.rect(center_x, footer_y, center_col_w, footer_h, fill=1, stroke=0) + draw_gold_divider(c, center_x, footer_y + footer_h, + center_col_w, 1.5) + c.setFillColor(NAVY) + c.setFont("Helvetica-Oblique", 7) + footer_text = ("All electrical work performed to ABYC E-11 standards. " + "Bilingual service EN/ES.") + c.drawString(center_x + 0.1 * inch, footer_y + 0.28 * inch, footer_text) + + # ── RIGHT COLUMN — Spanish services ────────────────────────────────────── + c.setFillColor(WHITE) + c.rect(right_x, bottom_y, right_col_w, col_h, fill=1, stroke=0) + + # Thin gold left border + c.setFillColor(GOLD) + c.rect(right_x, bottom_y, 3, col_h, fill=1, stroke=0) + + cur_y = top_y - 0.15 * inch + + c.setFillColor(NAVY) + c.setFont("Helvetica-Bold", 14) + c.drawString(right_x + 0.15 * inch, cur_y, "Servicios Marinos Profesionales") + cur_y -= 0.12 * inch + draw_gold_divider(c, right_x + 0.15 * inch, cur_y, + right_col_w - 0.2 * inch, 2.0) + cur_y -= 0.22 * inch + + es_services = [ + "Instalaciones Eléctricas Marinas (Estándar ABYC E-11)", + "Diseño e Instalación de Banco de Baterías de Litio", + "Sistemas de Alimentación en Puerto e Inversor/Cargador", + "Mejoras Solar y de Alternador", + "Recableado Completo (Cable Estañado, Circuitos Etiquetados)", + "Recuperación y Restauración de Teca", + "Pulido de Gelcoat y Eliminación de Oxidación", + "Instalación de Sistema Washdown", + "Sistemas de Molinete y Achique", + "Integración NMEA 2000 / 0183", + "Inspección Pre-Temporada y Servicio Anual", + ] + + bx2 = right_x + 0.15 * inch + bw2 = right_col_w - 0.25 * inch + for svc in es_services: + cur_y = draw_bullet_item(c, svc, bx2, cur_y, bw2, + font_size=8.5, line_height=11.5) + cur_y -= 1 + + # Footer band + c.setFillColor(LIGHT_GRAY) + c.rect(right_x, footer_y, right_col_w, footer_h, fill=1, stroke=0) + draw_gold_divider(c, right_x, footer_y + footer_h, right_col_w, 1.5) + c.setFillColor(NAVY) + c.setFont("Helvetica-Oblique", 7) + es_footer = ("Todo trabajo eléctrico realizado según estándar ABYC E-11. " + "Servicio bilingüe EN/ES.") + c.drawString(right_x + 0.1 * inch, footer_y + 0.28 * inch, es_footer) + + c.save() + print(f" [OK] {path}") + return path + + +# ══════════════════════════════════════════════════════════════════════════════ +# BROCHURE 2 — Marine Electrical (portrait letter, 2 columns) +# ══════════════════════════════════════════════════════════════════════════════ +def generate_brochure2(): + path = os.path.join(OUTPUT_DIR, "PrisaYachts_Electrical.pdf") + pw, ph = letter # 612 x 792 pts + c = canvas.Canvas(path, pagesize=letter) + c.setTitle("Prisa Yachts LLC — Marine Electrical Services") + c.setAuthor("Prisa Yachts LLC") + c.setSubject("Marine Electrical Brochure EN/ES") + + margin = 0.4 * inch + col_gap = 0.2 * inch + usable_w = pw - 2 * margin + col_w = (usable_w - col_gap) / 2 + + # ── Header band ─────────────────────────────────────────────────────────── + header_h = 1.05 * inch + header_y = ph - header_h + c.setFillColor(NAVY) + c.rect(0, header_y, pw, header_h, fill=1, stroke=0) + + # Gold bottom border on header + c.setStrokeColor(GOLD) + c.setLineWidth(2.5) + c.line(0, header_y, pw, header_y) + + # Logo in header (left side) + draw_logo(c, margin, ph - 0.08 * inch, 1.5 * inch, 0.85 * inch, centered=False) + + # Title center + c.setFillColor(WHITE) + c.setFont("Helvetica-Bold", 18) + c.drawCentredString(pw / 2, ph - 0.42 * inch, "Marine Electrical Services") + + # ABYC badge right + c.setFillColor(GOLD) + c.setFont("Helvetica-Bold", 9.5) + c.drawRightString(pw - margin, ph - 0.38 * inch, "ABYC E-11 Certified") + c.setFillColor(WHITE) + c.setFont("Helvetica", 8) + c.drawRightString(pw - margin, ph - 0.55 * inch, "Stuart to Jacksonville, FL") + + # ── Body columns ───────────────────────────────────────────────────────── + body_top = header_y - 0.22 * inch + footer_h = 0.55 * inch + body_bottom = margin + footer_h + 0.1 * inch + + left_x = margin + right_x = margin + col_w + col_gap + + # Vertical gold divider between columns + mid_x = margin + col_w + col_gap / 2 + c.setStrokeColor(GOLD) + c.setLineWidth(1.0) + c.line(mid_x, body_bottom, mid_x, body_top) + + def draw_electrical_column(start_x, cur_y, lang='en'): + cw = col_w - 0.05 * inch + line_sm = 10.5 + line_md = 12 + + if lang == 'en': + c.setFillColor(NAVY) + c.setFont("Helvetica-Bold", 10.5) + c.drawString(start_x, cur_y, "Expert Marine Electrical — Stuart to Jacksonville") + cur_y -= 0.18 * inch + draw_gold_divider(c, start_x, cur_y, cw, 1.5) + cur_y -= 0.18 * inch + + sections = [ + ("WHY ABYC CERTIFIED WORK MATTERS", + "Marine electrical failures are the #1 cause of boat fires. Every " + "installation we do meets or exceeds ABYC E-11 standards: correct wire " + "gauge, tinned marine-grade wire, properly sized overcurrent protection, " + "and labeled circuits from stem to stern."), + ("FULL REWIRING", + "Complete vessel rewiring using marine-grade tinned wire. Correct gauge " + "per ABYC E-11. Every circuit labeled and documented."), + ("LITHIUM BATTERY BANKS", + "Custom LiFePO4 battery bank design and installation. BMS integration, " + "proper charge profiles, and full system documentation."), + ("SOLAR & SHORE POWER", + "Solar panel installation with MPPT charge controllers. Shore power " + "systems, isolation transformers, and inverter/charger integration."), + ("SYSTEMS & ELECTRONICS", + "NMEA 2000 backbone design and installation. Bilge pumps, washdown " + "systems, anchor windlass, lighting upgrades."), + ("DIAGNOSTICS & INSPECTION", + "Pre-purchase electrical inspection. Annual safety audit. " + "Load testing and fault finding."), + ] + icons = ["⚡", "⚡", "\U0001f50b", "☀️", "\U0001f50c", "\U0001f50d"] + else: + c.setFillColor(NAVY) + c.setFont("Helvetica-Bold", 10.5) + c.drawString(start_x, cur_y, + "Instalaciones Eléctricas Marinas — Stuart a Jacksonville") + cur_y -= 0.18 * inch + draw_gold_divider(c, start_x, cur_y, cw, 1.5) + cur_y -= 0.18 * inch + + sections = [ + ("POR QUÉ IMPORTA EL ESTÁNDAR ABYC", + "Los fallos eléctricos son la causa número 1 de incendios en embarcaciones. " + "Cada instalación que realizamos cumple o supera el estándar ABYC E-11: " + "calibre de cable correcto, cable marino estañado, protección contra " + "sobrecorriente correctamente dimensionada, y circuitos etiquetados de proa a popa."), + ("RECABLEADO COMPLETO", + "Recableado total de la embarcación con cable estañado de grado marino. " + "Calibre correcto según ABYC E-11. Cada circuito etiquetado y documentado."), + ("BANCO DE BATERÍAS DE LITIO", + "Diseño e instalación personalizada de banco LiFePO4. Integración de BMS, " + "perfiles de carga correctos y documentación completa del sistema."), + ("SOLAR Y ALIMENTACIÓN EN PUERTO", + "Instalación de paneles solares con controladores MPPT. Sistemas de shore power, " + "transformadores de aislamiento e integración inversor/cargador."), + ("SISTEMAS Y ELECTRÓNICA", + "Diseño e instalación de backbone NMEA 2000. Bombas de achique, sistemas " + "washdown, molinete de ancla, mejoras de iluminación."), + ("DIAGNÓSTICO E INSPECCIÓN", + "Inspección eléctrica previa a compra. Auditoría de seguridad anual. " + "Pruebas de carga y localización de fallos."), + ] + icons = ["⚡", "⚡", "\U0001f50b", "☀️", "\U0001f50c", "\U0001f50d"] + + for i, (title, body) in enumerate(sections): + if i == 0: + # First section: intro paragraph, no icon + c.setFillColor(NAVY) + c.setFont("Helvetica-Bold", 8.5) + c.drawString(start_x, cur_y, title) + cur_y -= 0.14 * inch + cur_y = draw_wrapped_text(c, body, start_x, cur_y, cw, + "Helvetica", 8, line_sm, color=DARK_GRAY) + cur_y -= 0.12 * inch + else: + # Service sections with colored mini-header + bar_h = 14 + c.setFillColor(NAVY) + c.rect(start_x, cur_y - bar_h + 3, cw, bar_h, fill=1, stroke=0) + c.setFillColor(GOLD) + c.setFont("Helvetica-Bold", 8.5) + c.drawString(start_x + 4, cur_y - bar_h + 6, title) + cur_y -= bar_h + 2 + + cur_y = draw_wrapped_text(c, body, start_x + 4, cur_y, cw - 4, + "Helvetica", 7.8, line_sm, color=DARK_GRAY) + cur_y -= 0.1 * inch + + # Quote + cur_y -= 0.05 * inch + draw_gold_divider(c, start_x, cur_y, cw, 1.0) + cur_y -= 0.16 * inch + if lang == 'en': + quote = '"Every wire we touch, we own. No shortcuts."' + else: + quote = '"Cada cable que tocamos, lo respaldamos. Sin atajos."' + c.setFillColor(NAVY) + c.setFont("Helvetica-BoldOblique", 8) + cur_y = draw_wrapped_text(c, quote, start_x, cur_y, cw, + "Helvetica-BoldOblique", 8, 11, color=NAVY) + return cur_y + + draw_electrical_column(left_x, body_top, 'en') + draw_electrical_column(right_x, body_top, 'es') + + # ── Footer ──────────────────────────────────────────────────────────────── + c.setFillColor(NAVY) + c.rect(0, 0, pw, margin + footer_h, fill=1, stroke=0) + c.setStrokeColor(GOLD) + c.setLineWidth(1.5) + c.line(0, margin + footer_h, pw, margin + footer_h) + + c.setFillColor(WHITE) + c.setFont("Helvetica", 8) + c.drawString(margin, margin + footer_h - 0.18 * inch, + "Alberto | (954) 655-4084 | technical@prisayachts.com") + c.setFillColor(GOLD) + c.setFont("Helvetica-Bold", 8.5) + c.drawRightString(pw - margin, margin + footer_h - 0.18 * inch, WEBSITE) + c.setFillColor(WHITE) + c.setFont("Helvetica", 7) + c.drawCentredString(pw / 2, margin + 0.15 * inch, AREA) + + c.save() + print(f" [OK] {path}") + return path + + +# ══════════════════════════════════════════════════════════════════════════════ +# BROCHURE 3 — Teak & Detailing (portrait letter, 2 columns) +# ══════════════════════════════════════════════════════════════════════════════ +def generate_brochure3(): + path = os.path.join(OUTPUT_DIR, "PrisaYachts_Teak_Detailing.pdf") + pw, ph = letter + c = canvas.Canvas(path, pagesize=letter) + c.setTitle("Prisa Yachts LLC — Teak Restoration & Marine Detailing") + c.setAuthor("Prisa Yachts LLC") + c.setSubject("Teak & Detailing Brochure EN/ES") + + margin = 0.4 * inch + col_gap = 0.2 * inch + usable_w = pw - 2 * margin + col_w = (usable_w - col_gap) / 2 + + # ── Header band ─────────────────────────────────────────────────────────── + header_h = 1.05 * inch + header_y = ph - header_h + c.setFillColor(NAVY) + c.rect(0, header_y, pw, header_h, fill=1, stroke=0) + + c.setStrokeColor(GOLD) + c.setLineWidth(2.5) + c.line(0, header_y, pw, header_y) + + draw_logo(c, margin, ph - 0.08 * inch, 1.5 * inch, 0.85 * inch, centered=False) + + c.setFillColor(WHITE) + c.setFont("Helvetica-Bold", 16) + c.drawCentredString(pw / 2, ph - 0.4 * inch, "Teak Restoration & Marine Detailing") + + c.setFillColor(GOLD) + c.setFont("Helvetica-Bold", 9) + c.drawRightString(pw - margin, ph - 0.38 * inch, "Stuart to Jacksonville") + c.setFillColor(WHITE) + c.setFont("Helvetica", 8) + c.drawRightString(pw - margin, ph - 0.55 * inch, "Florida's Saltwater Environment") + + # ── Body ───────────────────────────────────────────────────────────────── + body_top = header_y - 0.22 * inch + footer_h = 0.55 * inch + body_bottom = margin + footer_h + 0.1 * inch + + left_x = margin + right_x = margin + col_w + col_gap + + # Vertical gold divider + mid_x = margin + col_w + col_gap / 2 + c.setStrokeColor(GOLD) + c.setLineWidth(1.0) + c.line(mid_x, body_bottom, mid_x, body_top) + + def draw_teak_column(start_x, cur_y, lang='en'): + cw = col_w - 0.05 * inch + line_sm = 10.5 + + if lang == 'en': + subtitle = "Teak & Detailing Specialists — Florida’s Saltwater Environment" + h2 = "IS YOUR TEAK WORTH SAVING?" + p1 = ("Gray teak isn’t always dead teak. Before we quote any job, we do an honest " + "hands-on assessment — and we’ll tell you straight if recovery makes " + "financial sense or if replacement is the smarter move. Most teak we see in " + "Florida is recoverable. It just needs the right process.") + steps_title = "THE RECOVERY PROCESS" + steps = [ + ("Step 1 — CLEAN", + "Two-part oxalic acid cleaner. Part A removes oxidation and gray surface " + "cells. Part B neutralizes pH. Clean canvas only — never cover problems."), + ("Step 2 — SAND", + "80-grit to open the grain. 120-grit to smooth. Always with the grain. " + "Never cross-grain — water traps are invisible until they rot your plank from inside."), + ("Step 3 — OIL", + "Penetrating marine teak oil, thin coats, wiped before skinning. " + "Feeds the wood from inside. Conditions, doesn’t coat."), + ("Step 4 — SEAL", + "UV-blocking teak sealer on all horizontal surfaces. Florida sun reoxidizes " + "bare teak in one season. Proper sealing buys 12–18 months."), + ] + det_title = "DETAILING SERVICES" + det_items = [ + "Gelcoat oxidation removal (light & heavy cut)", + "Machine polish & wax — DA and rotary", + "Hull cleaning & brightwork", + "Caulking inspection & reseam", + "Full exterior detail packages", + ] + quote = '"We’ve restored teak that owners wanted to scrap. Send us a photo before you decide."' + else: + subtitle = "Especialistas en Teca y Detailing — Ambiente Marino de Florida" + h2 = "¿VALE LA PENA SALVAR TU TECA?" + p1 = ("La teca gris no siempre está muerta. Antes de cotizar cualquier trabajo, " + "hacemos una evaluación honesta — y te diremos directamente si la " + "recuperación tiene sentido económico o si el reemplazo es la decisión " + "más inteligente. La mayoría de la teca que vemos en Florida es recuperable. " + "Solo necesita el proceso correcto.") + steps_title = "EL PROCESO DE RECUPERACIÓN" + steps = [ + ("Paso 1 — LIMPIAR", + "Limpiador de ácido oxálico en dos partes. La parte A elimina la oxidación " + "y las células grises. La parte B neutraliza el pH. Solo superficie limpia — " + "nunca cubrir problemas."), + ("Paso 2 — LIJAR", + "Lija 80 para abrir el grano. Lija 120 para alisar. Siempre a favor de la veta. " + "Nunca transversal — las trampas de agua son invisibles hasta que pudren la tabla desde adentro."), + ("Paso 3 — ACEITAR", + "Aceite marino penetrante de teca, capas finas, limpiando antes de que forme película. " + "Nutre la madera desde adentro. Acondiciona, no recubre."), + ("Paso 4 — SELLAR", + "Sellador UV en todas las superficies horizontales. El sol de Florida reoxida la teca " + "sin protección en una temporada. El sellado correcto da 12 a 18 meses."), + ] + det_title = "SERVICIOS DE DETAILING" + det_items = [ + "Eliminación de oxidación de gelcoat (corte suave y profundo)", + "Pulido a máquina y encerado — DA y rotativa", + "Limpieza de casco y herrajes brillantes", + "Inspección de sellado y recalafateo", + "Paquetes completos de detailing exterior", + ] + quote = '"Hemos restaurado teca que los dueños querían desechar. Mándanos una foto antes de decidir."' + + # Subtitle + c.setFillColor(NAVY) + c.setFont("Helvetica-Bold", 9.5) + cur_y = draw_wrapped_text(c, subtitle, start_x, cur_y, cw, + "Helvetica-Bold", 9.5, 12, color=NAVY) + cur_y -= 0.1 * inch + draw_gold_divider(c, start_x, cur_y, cw, 1.5) + cur_y -= 0.16 * inch + + # H2 + c.setFillColor(NAVY) + c.setFont("Helvetica-Bold", 8.5) + c.drawString(start_x, cur_y, h2) + cur_y -= 0.14 * inch + + # Intro paragraph + cur_y = draw_wrapped_text(c, p1, start_x, cur_y, cw, + "Helvetica", 7.8, line_sm, color=DARK_GRAY) + cur_y -= 0.15 * inch + + # Recovery process header + bar_h = 14 + c.setFillColor(NAVY) + c.rect(start_x, cur_y - bar_h + 3, cw, bar_h, fill=1, stroke=0) + c.setFillColor(WHITE) + c.setFont("Helvetica-Bold", 8.5) + c.drawString(start_x + 4, cur_y - bar_h + 6, steps_title) + cur_y -= bar_h + 6 + + # Steps + for step_title, step_body in steps: + c.setFillColor(GOLD) + c.setFont("Helvetica-Bold", 8) + c.drawString(start_x + 4, cur_y, step_title) + cur_y -= 0.13 * inch + cur_y = draw_wrapped_text(c, step_body, start_x + 10, cur_y, cw - 10, + "Helvetica", 7.5, 10.5, color=DARK_GRAY) + cur_y -= 0.08 * inch + + cur_y -= 0.05 * inch + + # Detailing services header + c.setFillColor(NAVY) + c.rect(start_x, cur_y - bar_h + 3, cw, bar_h, fill=1, stroke=0) + c.setFillColor(WHITE) + c.setFont("Helvetica-Bold", 8.5) + c.drawString(start_x + 4, cur_y - bar_h + 6, det_title) + cur_y -= bar_h + 6 + + for item in det_items: + cur_y = draw_bullet_item(c, item, start_x + 4, cur_y, + cw - 4, font_size=7.8, line_height=10.5) + cur_y -= 1 + + # Quote + cur_y -= 0.08 * inch + draw_gold_divider(c, start_x, cur_y, cw, 1.0) + cur_y -= 0.14 * inch + cur_y = draw_wrapped_text(c, quote, start_x, cur_y, cw, + "Helvetica-BoldOblique", 7.8, 11, color=NAVY) + return cur_y + + draw_teak_column(left_x, body_top, 'en') + draw_teak_column(right_x, body_top, 'es') + + # ── Footer ──────────────────────────────────────────────────────────────── + c.setFillColor(NAVY) + c.rect(0, 0, pw, margin + footer_h, fill=1, stroke=0) + c.setStrokeColor(GOLD) + c.setLineWidth(1.5) + c.line(0, margin + footer_h, pw, margin + footer_h) + + c.setFillColor(WHITE) + c.setFont("Helvetica", 8) + c.drawString(margin, margin + footer_h - 0.18 * inch, + "Federico | (754) 209-3375 | management@prisayachts.com") + c.setFillColor(GOLD) + c.setFont("Helvetica-Bold", 8.5) + c.drawRightString(pw - margin, margin + footer_h - 0.18 * inch, WEBSITE) + c.setFillColor(WHITE) + c.setFont("Helvetica", 7) + c.drawCentredString(pw / 2, margin + 0.15 * inch, AREA) + + c.save() + print(f" [OK] {path}") + return path + + +# ── Main ─────────────────────────────────────────────────────────────────────── +if __name__ == "__main__": + import sys + print("Prisa Yachts LLC — Brochure Generator") + print(f"Output: {OUTPUT_DIR}\n") + + files = [] + try: + files.append(generate_brochure1()) + except Exception as e: + print(f" [ERROR] Brochure 1: {e}", file=sys.stderr) + + try: + files.append(generate_brochure2()) + except Exception as e: + print(f" [ERROR] Brochure 2: {e}", file=sys.stderr) + + try: + files.append(generate_brochure3()) + except Exception as e: + print(f" [ERROR] Brochure 3: {e}", file=sys.stderr) + + print("\nFile sizes:") + for f in files: + size = os.path.getsize(f) + print(f" {os.path.basename(f)}: {size:,} bytes ({size/1024:.1f} KB)") diff --git a/prisa-yachts/n8n_tip_publisher_local_ai.md b/prisa-yachts/n8n_tip_publisher_local_ai.md new file mode 100644 index 0000000..82e9acb --- /dev/null +++ b/prisa-yachts/n8n_tip_publisher_local_ai.md @@ -0,0 +1,475 @@ +# n8n Workflow — Tip Auto-Publisher con IA Local +## Prisa Yachts LLC | SearXNG + Ollama + WordPress +## Versión: 1.0 | 2026-05-05 + +--- + +## ARQUITECTURA COMPLETA + +``` +[Schedule Trigger: Lun/Mié/Vie 8AM ET] + ↓ +[Google Sheets: leer próximo tema pendiente] + ↓ +[SearXNG: buscar referencias del tema] + ↓ +[Ollama qwen2.5:14b: generar tip EN+ES en JSON] + ↓ + ¿Hay foto? + / \ + SÍ NO + ↓ ↓ +[Vision: [WP Post + analiza] directo] + ↓ +[WP Media Upload] + ↓ +[WordPress: crear post bilingüe] + ↓ +[Google Sheets: marcar publicado + agregar a ContentCalendar Instagram] +``` + +--- + +## VARIABLES DE ENTORNO (agregar en n8n) + +```env +PRISA_WP_URL=https://prisayachts.com +PRISA_WP_USER=admin # usuario WordPress +PRISA_WP_APP_PASSWORD=xxxx xxxx xxxx xxxx # Application Password (ver Paso 0) +PRISA_OLLAMA_URL=http://localhost:11434 # o host.docker.internal:11434 si n8n es Docker +PRISA_SEARXNG_URL=http://localhost:8080 # o el container name si están en misma red Docker +PRISA_TOPICS_SHEET_ID=1BxiMVs... +PRISA_TOPICS_SHEET_NAME=TipTopics +``` + +--- + +## PASO 0: PREPARACIÓN PREVIA A n8n + +### A) WordPress Application Password +``` +WordPress Admin → Usuarios → Tu perfil +→ Bajar hasta "Contraseñas de aplicación" +→ Nombre: "n8n Publisher" +→ Añadir contraseña +→ GUARDAR el password que aparece (formato: xxxx xxxx xxxx xxxx) +``` + +### B) Google Sheet — Tab "TipTopics" + +| Col | Header | Tipo | Ejemplo | +|-----|--------|------|---------| +| A | `topic_id` | Texto | `TIP-001` | +| B | `topic_EN` | Texto | `How to inspect your anchor chain` | +| C | `topic_ES` | Texto | `Cómo inspeccionar tu cadena de ancla` | +| D | `pillar` | Texto | `hardware` / `electrical` / `teak` / `engine` / `safety` | +| E | `status` | Texto | `pending` / `publishing` / `published` / `skipped` | +| F | `drive_photo_id` | Texto | FILE_ID de Google Drive (vacío si no hay foto) | +| G | `wp_post_id` | Número | Lo escribe el workflow | +| H | `wp_post_url` | URL | Lo escribe el workflow | +| I | `published_at` | Datetime | Lo escribe el workflow | +| J | `ig_added` | Boolean | `true` cuando se agrega al ContentCalendar | + +### C) Verificar acceso Ollama desde n8n + +Desde la terminal del servidor: +```bash +curl http://localhost:11434/api/tags +# Debe devolver lista de modelos instalados +``` + +Si n8n corre como Docker container: +```bash +# Agregar al docker-compose de n8n: +extra_hosts: + - "host.docker.internal:host-gateway" +# Luego usar: http://host.docker.internal:11434 +``` + +--- + +## WORKFLOW COMPLETO — NODO POR NODO + +### NODO 1: Schedule Trigger +``` +Tipo: Schedule Trigger +Cron: 0 8 * * 1,3,5 ← Lun, Mié, Vie a las 8AM +Timezone: America/New_York +``` + +--- + +### NODO 2: Google Sheets — Leer próximo tema +``` +Tipo: Google Sheets +Operación: Get Many Rows +Sheet ID: {{ $env.PRISA_TOPICS_SHEET_ID }} +Sheet Name: TipTopics +Filters: + - Column: status + - Value: pending +Limit: 1 +Sort: topic_id ASC +``` + +→ Si no hay filas: **NoOp** (fin silencioso) + +--- + +### NODO 3: Google Sheets — Marcar "publishing" (lock anti-duplicado) +``` +Tipo: Google Sheets +Operación: Update Row +Row Number: {{ $json.row_number }} +status: publishing +``` + +--- + +### NODO 4: HTTP Request — SearXNG Search +``` +Tipo: HTTP Request +Método: GET +URL: {{ $env.PRISA_SEARXNG_URL }}/search + +Query Parameters: + q: {{ $json.topic_EN }} marine Florida boat + format: json + language: en + categories: general + pageno: 1 + +Headers: + Accept: application/json +``` + +**Code: Extraer snippets relevantes** +```javascript +const results = $input.first().json; +const items = results.results || []; + +// Tomar los primeros 4 resultados, extraer título + snippet +const snippets = items.slice(0, 4).map(r => ({ + title: r.title || '', + snippet: r.content || r.snippet || '' +})); + +const referenceText = snippets + .map((s, i) => `[${i+1}] ${s.title}: ${s.snippet}`) + .join('\n\n'); + +return [{ json: { + ...($input.first().json), + searchReference: referenceText +}}]; +``` + +--- + +### NODO 5: HTTP Request — Ollama qwen2.5:14b Generar Contenido +``` +Tipo: HTTP Request +Método: POST +URL: {{ $env.PRISA_OLLAMA_URL }}/api/chat + +Headers: + Content-Type: application/json + +Body (JSON): +{ + "model": "qwen2.5:14b", + "stream": false, + "format": "json", + "options": { + "temperature": 0.7, + "num_ctx": 4096 + }, + "messages": [ + { + "role": "system", + "content": "You are a professional marine content writer for Prisa Yachts LLC, a marine electrical and maintenance company serving Stuart to Jacksonville, FL. You write authoritative, practical tips for boat owners in both English and Spanish. Your tone is expert but approachable. Always include specific Florida saltwater context. Return ONLY valid JSON, no other text." + }, + { + "role": "user", + "content": "Write a detailed marine tip blog post about: \"{{ $json.topic_EN }}\"\n\nReference material from web search:\n{{ $json.searchReference }}\n\nReturn this exact JSON structure:\n{\n \"title_EN\": \"SEO-optimized title in English (max 60 chars)\",\n \"title_ES\": \"Título optimizado en español (max 60 chars)\",\n \"excerpt_EN\": \"Meta description in English (max 155 chars)\",\n \"excerpt_ES\": \"Meta descripción en español (max 155 chars)\",\n \"content_EN\": \"Full HTML blog post in English (400-600 words). Use

for subheadings,
    for lists, for emphasis. Include Florida-specific context. End with a CTA to contact Prisa Yachts LLC at (954) 655-4084 or management@prisayachts.com\",\n \"content_ES\": \"Artículo completo en HTML en español (400-600 palabras). Misma estructura. CTA al final con los mismos datos de contacto.\",\n \"tags\": [\"tag1\", \"tag2\", \"tag3\", \"tag4\", \"tag5\"],\n \"ig_caption_EN\": \"Instagram caption in English (max 200 words) with CTA to DM\",\n \"ig_caption_ES\": \"Caption de Instagram en español (max 200 palabras) con CTA\"\n}" + } + ] +} +``` + +--- + +### NODO 6: Code — Parsear respuesta de Ollama +```javascript +const response = $input.first().json; +const messageContent = response.message?.content || response.response || ''; + +let parsed; +try { + // Ollama con format:json devuelve JSON limpio + parsed = JSON.parse(messageContent); +} catch(e) { + // Fallback: buscar JSON dentro del texto + const jsonMatch = messageContent.match(/\{[\s\S]*\}/); + if (jsonMatch) { + parsed = JSON.parse(jsonMatch[0]); + } else { + throw new Error('Ollama no devolvió JSON válido: ' + messageContent.substring(0, 200)); + } +} + +// Construir el contenido WordPress: EN arriba, ES abajo con separador +const wpContent = ` +${parsed.content_EN} + +
    + +

    ─── Versión en Español ───

    + +${parsed.content_ES} +`; + +return [{ json: { + ...($input.first().json), // mantener topic_id, drive_photo_id, etc. + title_EN: parsed.title_EN, + title_ES: parsed.title_ES, + excerpt_EN: parsed.excerpt_EN, + excerpt_ES: parsed.excerpt_ES, + wp_content: wpContent, + tags: parsed.tags || [], + ig_caption_EN: parsed.ig_caption_EN || '', + ig_caption_ES: parsed.ig_caption_ES || '' +}}]; +``` + +--- + +### NODO 7: IF — ¿Tiene foto en Drive? +``` +Condición: {{ $json.drive_photo_id }} is not empty +``` + +--- + +### RAMA A: CON FOTO (drive_photo_id existe) + +#### NODO 8A: HTTP Request — Descargar foto de Google Drive +``` +Tipo: HTTP Request +Método: GET +URL: https://drive.google.com/uc?export=download&id={{ $json.drive_photo_id }} +Response Format: File +``` + +#### NODO 9A: HTTP Request — Ollama llama3.2-vision — Analizar foto +``` +Tipo: HTTP Request +Método: POST +URL: {{ $env.PRISA_OLLAMA_URL }}/api/generate + +Body (JSON): +{ + "model": "llama3.2-vision:latest", + "prompt": "Describe this marine work photo in 1-2 sentences for use as an image alt text on a professional marine services website. Be specific about what you see (teak deck, electrical panel, battery installation, etc). Keep it under 125 characters.", + "stream": false, + "images": ["{{ $binary.data.toString('base64') }}"] +} +``` + +#### NODO 10A: HTTP Request — WordPress Media Upload +``` +Tipo: HTTP Request +Método: POST +URL: {{ $env.PRISA_WP_URL }}/wp-json/wp/v2/media + +Authentication: Basic Auth + Username: {{ $env.PRISA_WP_USER }} + Password: {{ $env.PRISA_WP_APP_PASSWORD }} + +Headers: + Content-Type: image/jpeg + Content-Disposition: attachment; filename="prisa-tip-{{ $json.topic_id }}.jpg" + +Body: [binary image data] +``` + +→ Respuesta guarda `media_id` = `$json.id` + +--- + +### RAMA B: SIN FOTO + +#### NODO 8B: Set +``` +Operación: Set Value +media_id: 0 +alt_text: "" +``` + +--- + +### NODO 11: Merge — Reunir ambas ramas + +--- + +### NODO 12: HTTP Request — WordPress Get/Create Tags +```javascript +// Code node: preparar tags +// Obtener o crear cada tag vía WP REST API +// Devolver array de tag IDs + +const tags = $json.tags || []; +const wpUrl = $env.PRISA_WP_URL; +const auth = 'Basic ' + Buffer.from(`${$env.PRISA_WP_USER}:${$env.PRISA_WP_APP_PASSWORD}`).toString('base64'); + +const tagIds = []; +for (const tagName of tags) { + // Buscar si existe + const searchResp = await $helpers.httpRequest({ + method: 'GET', + url: `${wpUrl}/wp-json/wp/v2/tags?search=${encodeURIComponent(tagName)}&per_page=1`, + headers: { Authorization: auth } + }); + + if (searchResp[0]) { + tagIds.push(searchResp[0].id); + } else { + // Crear nuevo tag + const createResp = await $helpers.httpRequest({ + method: 'POST', + url: `${wpUrl}/wp-json/wp/v2/tags`, + headers: { Authorization: auth, 'Content-Type': 'application/json' }, + body: JSON.stringify({ name: tagName }) + }); + tagIds.push(createResp.id); + } +} + +return [{ json: { ...($input.first().json), tag_ids: tagIds }}]; +``` + +--- + +### NODO 13: HTTP Request — WordPress Crear Post +``` +Tipo: HTTP Request +Método: POST +URL: {{ $env.PRISA_WP_URL }}/wp-json/wp/v2/posts + +Authentication: Basic Auth + Username: {{ $env.PRISA_WP_USER }} + Password: {{ $env.PRISA_WP_APP_PASSWORD }} + +Headers: + Content-Type: application/json + +Body (JSON): +{ + "title": "{{ $json.title_EN }} | {{ $json.title_ES }}", + "content": "{{ $json.wp_content }}", + "excerpt": "{{ $json.excerpt_EN }}", + "status": "publish", + "featured_media": {{ $json.media_id }}, + "tags": {{ $json.tag_ids }}, + "meta": { + "tip_topic_id": "{{ $json.topic_id }}", + "tip_pillar": "{{ $json.pillar }}" + } +} +``` + +→ Respuesta: `{ "id": 123, "link": "https://prisayachts.com/..." }` + +--- + +### NODO 14: Google Sheets — Actualizar TipTopics +``` +Tipo: Google Sheets +Operación: Update Row +Row: {{ $json.row_number }} +status: published +wp_post_id: {{ $json.wp_response.id }} +wp_post_url: {{ $json.wp_response.link }} +published_at: {{ new Date().toISOString() }} +``` + +--- + +### NODO 15: Google Sheets — Agregar a ContentCalendar Instagram + +Append nueva fila al tab `ContentCalendar` del sheet principal de n8n: + +``` +post_id: PY-TIP-{{ $json.topic_id }} +scheduled_date: (fecha de mañana) +scheduled_time: 11:00 +platform: instagram +caption_EN: {{ $json.ig_caption_EN }} +caption_ES: {{ $json.ig_caption_ES }} +hashtags: (según pillar → set A/B/C) +image_url: (URL pública Drive si existe) +pillar: {{ $json.pillar }} +status: draft +``` + +--- + +## FLUJO DE IMPLEMENTACIÓN + +### Semana 1: Base +1. [ ] Crear Application Password en WordPress +2. [ ] Crear Google Sheet TipTopics con los temas del plan de contenido +3. [ ] Verificar: `curl http://localhost:11434/api/tags` desde el servidor +4. [ ] Verificar: `curl http://localhost:8080/search?q=marine+electrical&format=json` desde el servidor +5. [ ] Configurar variables de entorno en n8n + +### Semana 2: Workflow +6. [ ] Construir Nodos 1-6 (trigger → Ollama) y probar con 1 tema +7. [ ] Verificar que el JSON de Ollama sale correcto +8. [ ] Agregar Nodo 13 (post a WordPress) y verificar que publica +9. [ ] Agregar Nodo 14-15 (actualizar sheets) + +### Semana 3: Fotos +10. [ ] Agregar rama con foto (Nodos 8A-10A) +11. [ ] Probar con una foto real de teca de Google Drive +12. [ ] Verificar alt text generado por llama3.2-vision + +--- + +## TEMAS INICIALES PARA GOOGLE SHEET TIPTOPICS + +| topic_id | topic_EN | topic_ES | pillar | +|----------|----------|----------|--------| +| TIP-001 | How to inspect your raw water impeller | Cómo inspeccionar el impeller de agua bruta | engine | +| TIP-002 | Why boat batteries fail in Florida heat | Por qué las baterías marinas fallan en el calor de Florida | electrical | +| TIP-003 | Teak deck gray vs. dead: how to tell the difference | Teca gris vs. teca muerta: cómo saberlo | teak | +| TIP-004 | Shore power safety: what every liveaboard needs to know | Seguridad en shore power: lo que todo liveaboard necesita saber | electrical | +| TIP-005 | How to read exhaust smoke color on your diesel | Cómo interpretar el color del humo de escape en tu diesel | engine | +| TIP-006 | 316 stainless vs. galvanized: never again | Inoxidable 316 vs. galvanizado: nunca más | hardware | +| TIP-007 | Pre-hurricane season electrical checklist | Lista de verificación eléctrica pre-temporada de huracanes | safety | +| TIP-008 | Lithium vs AGM: the real numbers for Florida boaters | Litio vs AGM: los números reales para navegantes en Florida | electrical | +| TIP-009 | Zinc anodes in Florida saltwater: replacement schedule | Ánodos de zinc en Florida: calendario de reemplazo | hardware | +| TIP-010 | Gelcoat oxidation: light vs. severe — what to do | Oxidación de gelcoat: leve vs. severa — qué hacer | teak | +| TIP-011 | Marine fuel filtration: primary vs. secondary filter | Filtración de combustible marino: filtro primario vs. secundario | engine | +| TIP-012 | ABYC E-11: why wire gauge matters on your boat | ABYC E-11: por qué el calibre del cable importa en tu barco | electrical | + +--- + +## NOTAS TÉCNICAS + +**Tiempo de respuesta Ollama qwen2.5:14b:** +- En servidor con GPU: ~15-30 segundos por post +- Sin GPU (CPU only): ~3-8 minutos por post +- Ajustar timeout del nodo HTTP Request a 600000ms (10 min) para CPU + +**Si Ollama no devuelve JSON válido:** +- Agregar nodo "Error Handler" que reintenta con temperatura=0.3 +- O cambiar modelo a qwen2.5:32b si hay RAM disponible + +**WordPress SEO:** +- Si tienen Yoast o RankMath instalado, se puede agregar los campos SEO vía meta fields adicionales en el POST body + +**Categorías WordPress:** +- Crear categorías en WP Admin: Electrical / Teak & Detailing / Engine / Hardware / Safety +- Mapear pillar → category_id en un Code node antes del post diff --git a/prisa-yachts/n8n_workflows_spec.md b/prisa-yachts/n8n_workflows_spec.md new file mode 100644 index 0000000..d51f77e --- /dev/null +++ b/prisa-yachts/n8n_workflows_spec.md @@ -0,0 +1,274 @@ +# n8n Workflows — Prisa Yachts LLC +## Instancia: n8n.crewinghunters.com +## Versión: 1.0 | 2026-05-04 + +--- + +## RESUMEN DE WORKFLOWS + +| Workflow | Trigger | Qué hace | +|----------|---------|----------| +| WF1: Content Buffer Publisher | Cron 9AM / 12PM / 5PM ET diario | Lee Google Sheet → publica en Instagram y Facebook automáticamente | +| WF2: LinkedIn Reminder | Cron Lu/Mié/Vie 12PM ET | Envía email con el texto del día listo para copiar en LinkedIn | +| WF3: Weekly Analytics Report | Cron Domingo 7PM ET | Jala métricas de Meta API → guarda en Sheet → envía resumen por email | +| WF4: Content Prep Reminder | Cron Domingo 8AM ET | Detecta posts sin imagen para la semana y alerta por email | + +--- + +## VARIABLES DE ENTORNO (configurar en n8n antes de todo) + +```env +PRISA_META_PAGE_ACCESS_TOKEN=EAA... # Long-lived Page Access Token (60 días) +PRISA_IG_USER_ID=17841400000000000 # Instagram Business Account ID (numérico) +PRISA_FB_PAGE_ID=100000000000000 # Facebook Page ID (numérico) +PRISA_CONTENT_SHEET_ID=1BxiMVs... # ID del Google Sheet (del URL) +PRISA_CONTENT_SHEET_NAME=ContentCalendar +PRISA_NOTIFY_EMAIL=alro65@gmail.com +``` + +--- + +## GOOGLE SHEETS — ESTRUCTURA + +### Tab 1: ContentCalendar + +| Col | Header | Tipo | Valores permitidos | +|-----|--------|------|-------------------| +| A | `post_id` | Texto | `PY-2026-001` | +| B | `scheduled_date` | Fecha ISO | `2026-05-06` | +| C | `scheduled_time` | Hora 24h | `11:00` | +| D | `platform` | Texto fijo | `instagram` / `facebook` / `both` | +| E | `caption_EN` | Texto largo | Caption en inglés (max 2200 chars) | +| F | `caption_ES` | Texto largo | Caption en español | +| G | `hashtags` | Texto | `#tag1 #tag2 #tag3` | +| H | `image_url` | URL | URL directa pública (ver nota crítica abajo) | +| I | `pillar` | Texto | `electrical` / `battery` / `education` / `safety` / `promo` | +| J | `status` | Texto fijo | `draft` / `scheduled` / `publishing` / `published` / `failed` / `skipped` | +| K | `published_at` | Datetime | Lo escribe WF1 automáticamente | +| L | `ig_media_id` | Texto | Lo escribe WF1 automáticamente | +| M | `fb_post_id` | Texto | Lo escribe WF1 automáticamente | +| N | `error_message` | Texto | Lo escribe WF1 si hay error | +| O | `linkedin_copy` | Texto largo | Caption adaptado para LinkedIn (lo usa WF2) | + +### Tab 2: Analytics +Columnas A-R: `report_date`, `post_id`, `platform`, `published_date`, `pillar`, métricas IG (impressions, reach, likes, comments, saved, shares), métricas FB, engagement rates. WF3 appenda filas aquí cada domingo. + +--- + +## WF1: CONTENT BUFFER PUBLISHER + +### Flujo completo + +``` +[Schedule Trigger: 9AM / 12PM / 5PM ET] + → [Google Sheets: Read ALL rows de ContentCalendar] + → [Code: Filter — status=scheduled AND fecha=hoy AND hora±30min] + → ¿Hay filas? NO → [NoOp Exit] FIN + → ¿Hay filas? SÍ → [Split In Batches: 1 por vez] + → [Google Sheets: Update status="publishing"] ← lock anti-duplicado + → [Switch por platform:] + instagram → [Code: Build caption] → [HTTP: Create IG Container] → [Wait 10s] → [HTTP: Publish IG Container] + facebook → [Code: Build caption] → [HTTP: POST /photos a Facebook Page] + both → ambas ramas secuencial (IG primero, luego FB) + → [SUCCESS] → [Google Sheets: Update status="published", published_at, ig_media_id, fb_post_id] + → [FAILURE] → [Google Sheets: Update status="failed", error_message] → [Gmail: Notify alro65@gmail.com] +``` + +### API Calls exactas + +**Instagram — Crear container:** +``` +POST https://graph.facebook.com/v21.0/{PRISA_IG_USER_ID}/media + ?image_url={image_url} + &caption={caption_EN}\n\n{caption_ES}\n\n{hashtags} + &access_token={PRISA_META_PAGE_ACCESS_TOKEN} +``` +Respuesta: `{ "id": "container_id" }` → esperar 10s → publicar + +**Instagram — Publicar container:** +``` +POST https://graph.facebook.com/v21.0/{PRISA_IG_USER_ID}/media_publish + ?creation_id={container_id} + &access_token={PRISA_META_PAGE_ACCESS_TOKEN} +``` +Respuesta: `{ "id": "published_media_id" }` → guardar en columna L + +**Facebook — Post con imagen:** +``` +POST https://graph.facebook.com/v21.0/{PRISA_FB_PAGE_ID}/photos + ?url={image_url} + &message={caption_EN}\n\n{caption_ES}\n\n{hashtags} + &access_token={PRISA_META_PAGE_ACCESS_TOKEN} +``` +Respuesta: `{ "post_id": "...", "id": "..." }` → guardar en columna M + +### Manejo de errores + +| Error | Acción | +|-------|--------| +| Token expirado (code 190) | Halt todo, email crítico a alro65@gmail.com | +| imagen_url inválida (code 100) | Marcar fila `failed`, email, continuar con siguiente | +| Container no listo (code 9007) | Retry 4x con delay 15s, luego `failed` | +| Rate limit (429) | Retry 3x con delay 60s, luego `failed` | +| Sheet no accesible | Halt todo, email crítico | + +### Estados del row (ciclo completo) + +``` +draft → (operador promueve) → scheduled +scheduled → (WF1 bloquea) → publishing +publishing → (éxito) → published +publishing → (error) → failed +failed → (operador resetea) → scheduled +``` + +--- + +## WF2: LINKEDIN REMINDER + +``` +[Schedule Trigger: Lun/Mié/Vie 12PM ET] + → [Google Sheets: Read ContentCalendar] + → [Code: Filter — fecha=hoy AND status=scheduled/published] + → ¿Hay post? NO → [Gmail: "No hay post de LinkedIn hoy"] + → ¿Hay post? SÍ → [Code: Build email — usar linkedin_copy si existe, sino caption_EN+ES] + → [Gmail: Enviar a alro65@gmail.com con texto listo para copiar/pegar] +``` + +**Formato del email:** +``` +Asunto: [Prisa Yachts] LinkedIn post listo — 2026-05-06 + +LinkedIn post de hoy: +--- +[texto del post] +--- + +Instrucciones: +1. Ir a LinkedIn +2. Crear nuevo post +3. Copiar texto arriba +4. Subir imagen desde Google Drive +5. Publicar +``` + +--- + +## WF3: WEEKLY ANALYTICS REPORT + +``` +[Schedule Trigger: Domingo 7PM ET] + → [Google Sheets: Read ContentCalendar] + → [Code: Filter — status=published AND published_at últimos 7 días] + → ¿Posts? NO → [Gmail: "Sin publicaciones esta semana"] + → ¿Posts? SÍ → [Split In Batches: 1 por vez] + → [IF ig_media_id existe] → [HTTP GET /{ig_media_id}/insights?metric=impressions,reach,likes,comments,saved,shares] + → [IF fb_post_id existe] → [HTTP GET /{fb_post_id}/insights?metric=post_impressions,post_impressions_unique,...] + → [Code: Calcular engagement rate = (likes+comments+saves+shares)/reach*100] + → [Google Sheets: Append row a Analytics tab] + → [Merge: Esperar todos los items] + → [Code: Build reporte — ordenar por engagement desc, top post, tabla completa] + → [Gmail: Enviar reporte a alro65@gmail.com] +``` + +**Instagram insights endpoint:** +``` +GET https://graph.facebook.com/v21.0/{ig_media_id}/insights + ?metric=impressions,reach,likes,comments,saved,shares + &access_token={token} +``` + +--- + +## WF4: CONTENT PREP REMINDER + +``` +[Schedule Trigger: Domingo 8AM ET] + → [Google Sheets: Read ContentCalendar] + → [Code: Filter — scheduled_date próximos 7 días AND status=scheduled/draft] + → ¿Hay posts? NO → [Gmail: "Sin posts programados para la semana"] + → ¿Hay posts? SÍ → [Code: Separar los que tienen image_url vs los que no] + → [Code: Build email] + SI hay faltantes → "ACTION REQUIRED: X posts sin imagen" + SI todos tienen → "Todo listo para la semana" + → [Gmail: Enviar a alro65@gmail.com] +``` + +--- + +## GUÍA DE IMPLEMENTACIÓN — ORDEN DE PASOS + +### Paso 1: Credenciales en n8n +1. **Google Sheets OAuth2** — autorizar con la cuenta que tiene el Sheet +2. **Gmail OAuth2** — autorizar con alro65@gmail.com +3. **Meta API** — Header Auth: `Bearer {PRISA_META_PAGE_ACCESS_TOKEN}` + +### Paso 2: Obtener los IDs de Meta + +**Page Access Token (long-lived):** +``` +1. developers.facebook.com → Graph API Explorer +2. Seleccionar App + Facebook Page +3. Pedir permisos: instagram_content_publish, pages_manage_posts, pages_read_engagement, instagram_manage_insights +4. GET /me/accounts → copiar access_token de tu página +5. Convertir a long-lived: + GET https://graph.facebook.com/v21.0/oauth/access_token + ?grant_type=fb_exchange_token + &client_id={APP_ID} + &client_secret={APP_SECRET} + &fb_exchange_token={SHORT_TOKEN} +``` + +**Instagram Business Account ID:** +``` +GET https://graph.facebook.com/v21.0/{PAGE_ID} + ?fields=instagram_business_account + &access_token={LONG_TOKEN} +→ respuesta: { "instagram_business_account": { "id": "ESTE_ES_EL_IG_USER_ID" } } +``` + +### Paso 3: Crear el Google Sheet +1. Crear spreadsheet con 2 tabs: `ContentCalendar` y `Analytics` +2. Agregar headers exactos según tabla arriba +3. Agregar fila de prueba con status=`scheduled` y fecha=mañana + +### Paso 4: Orden de construcción (de menor a mayor riesgo) +1. **WF4 primero** — solo lectura, envía email → probar sin riesgo +2. **WF2 segundo** — solo lectura + email → probar sin riesgo +3. **WF1 tercero** — publicación real → probar con 1 fila de prueba primero +4. **WF3 último** — requiere posts publicados con IDs reales para probar + +--- + +## ⚠️ NOTA CRÍTICA: URLs DE IMÁGENES + +Meta Graph API NO acepta links de Google Drive del tipo: +``` +❌ https://drive.google.com/file/d/{ID}/view +``` + +Formato correcto (compartir como "Cualquiera con el link"): +``` +✅ https://drive.google.com/uc?export=download&id={FILE_ID} +``` + +Para obtener el FILE_ID: en el link de compartir de Drive, el ID es el string alfanumérico largo. + +Alternativa recomendada para producción: subir fotos a **Google Cloud Storage** con acceso público — URLs más estables y sin límites de descarga. + +--- + +## TOKEN REFRESH (importante) + +El Page Access Token expira en **60 días**. Antes de que expire: +- Opción A: Agregar WF5 "Token Expiry Reminder" que envía email cada 30 días +- Opción B (recomendada): Usar **System User Token** en Meta Business Manager — no expira nunca + +--- + +## PREGUNTAS A RESOLVER ANTES DEL PRIMER DEPLOY + +1. ¿Tienes Meta Developer App creada para Prisa Yachts? +2. ¿Instagram está como cuenta Business vinculada a tu Facebook Page? +3. ¿Las fotos irán a Google Drive o a otro storage? +4. ¿Los posts serán bilingües (EN+ES en el mismo post) o separados? diff --git a/prisa-yachts/plan_marketing_maestro.md b/prisa-yachts/plan_marketing_maestro.md new file mode 100644 index 0000000..80ac1e1 --- /dev/null +++ b/prisa-yachts/plan_marketing_maestro.md @@ -0,0 +1,628 @@ +# PLAN MAESTRO DE MARKETING — PRISA YACHTS LLC +## Electricidad Marina | Stuart a Jacksonville, FL +### Generado: Mayo 2026 + +--- + +## RESUMEN EJECUTIVO + +**Negocio:** Prisa Yachts LLC — Técnico eléctrico marino independiente, bilingüe (EN/ES) +**Servicios:** Rewiring, bancos de baterías, paneles, washdown, mantenimiento preventivo, teca, detailing +**Área:** Stuart → Vero Beach → Melbourne → Cocoa Beach → Daytona → Jacksonville +**Diferenciadores:** Bilingüe, independiente (sin overhead de taller), viaja a la marina del cliente, documenta todo con diagramas + +--- + +## MÓDULO 1: SEO LOCAL + +### Top 25 Keywords (prioridad de implementación) + +**Tier 1 — Dinero inmediato:** +- "marine electrician Stuart FL" +- "boat electrician Vero Beach FL" +- "marine electrical contractor Melbourne FL" +- "boat rewiring Florida" +- "lithium battery bank installation boat Florida" + +**Tier 2 — Alto volumen:** +- "boat battery replacement Florida east coast" +- "marine electrical repair near me" +- "yacht electrical contractor Florida" +- "ABYC marine electrician Florida" +- "boat panel upgrade Stuart FL" + +**Tier 3 — Long tail, alta conversión:** +- "boat won't start battery dead Stuart FL" +- "marine electrical inspection before buying boat Florida" +- "boat shore power problems Fort Pierce" +- "liveaboard electrical upgrade Florida" +- "bilingual marine electrician Florida" + +### Google Business Profile +- **Categoría primaria:** Electrician (Marine Electrician no disponible como categoría) +- **Área de servicio:** Stuart, Vero Beach, Fort Pierce, Sebastian, Melbourne, Cocoa Beach, Titusville, Daytona Beach, Ormond Beach, Jacksonville +- **Posts semanales:** 1 foto de trabajo completado + descripción con keyword local +- **Responder todas las reseñas** en 24 horas + +### Arquitectura de Páginas de Servicio (prisayachts.com) +``` +/services/boat-rewiring/ +/services/battery-bank-installation/ +/services/marine-panel-upgrade/ +/services/shore-power-systems/ +/services/washdown-system-installation/ +/services/marine-electrical-inspection/ +/services/liveaboard-electrical/ +``` + +### Páginas de Área de Servicio +``` +/service-area/stuart-fl/ +/service-area/vero-beach-fl/ +/service-area/melbourne-fl/ +/service-area/daytona-beach-fl/ +/service-area/jacksonville-fl/ +``` + +### 3 Blog Posts para autoridad SEO +1. "My Boat Battery Won't Hold a Charge: 5 Causes and Fixes (Stuart FL)" +2. "Lithium vs AGM Marine Batteries: The Complete Guide for Florida Boaters" +3. "Why Every Boat Needs a Proper Electrical Diagram (And How to Get One)" + +### 10 Directorios prioritarios +1. Google Business Profile +2. Yelp for Business +3. Angi (HomeAdvisor) +4. Houzz +5. Thumbtack +6. ABYC Member Directory (si aplica) +7. MarineMax service partner listings +8. BoatUS Cooperating Marina network +9. Facebook Business +10. Nextdoor Business + +--- + +## MÓDULO 2: REDES SOCIALES — ESTRATEGIA DE PLATAFORMAS + +### Prioridad de plataformas + +| Prioridad | Plataforma | Por qué | +|-----------|-----------|---------| +| #1 | **Instagram** | Dueños de yates 35-65 años, Reels = descubrimiento orgánico masivo, geotagging en marinas | +| #2 | **Facebook** | Grupos de boating locales = leads directos, demografía 45-65 compradora | +| #3 | **LinkedIn** | B2B: marina managers, capitanes, brokers, contratos de flota | +| #4 | **Nextdoor** | Alta confianza local, recomendaciones de vecinos de marina | +| #5 | **TikTok** | Activar en Día 60 con contenido reutilizado de Instagram | + +### Calendario Semanal de Publicación + +| Día | Hora ET | Plataforma | Pilar | Formato | +|-----|---------|-----------|-------|---------| +| Lunes | 7:30 AM | Instagram + Facebook | Seguridad | Reel o foto | +| Lunes | 12:00 PM | LinkedIn | Educación | Texto + foto | +| Martes | 8:00 AM | Instagram | Trabajo real | Carousel 3-5 fotos | +| Martes | 6:00 PM | Facebook Groups | Detrás del técnico | Post nativo | +| Miércoles | 7:30 AM | Instagram + Facebook | Prueba social | Testimonio/reseña | +| Miércoles | 11:00 AM | LinkedIn | Seguridad/Autoridad | Texto + foto | +| Jueves | 8:00 AM | Instagram | Trabajo real | Reel instalación | +| Jueves | 7:00 PM | Nextdoor | Cualquier pilar | Update de negocio | +| Viernes | 7:30 AM | Instagram + Facebook | Educación | Carousel | +| Viernes | 12:00 PM | LinkedIn | Prueba social | Foto de proyecto | +| Sábado | 8:30 AM | Instagram | Detrás del técnico | Reel en el muelle | +| **Domingo** | — | — | — | **Día de preparación de contenido** | + +### 5 Pilares de Contenido + +1. **Muestra el Trabajo (Prueba)** — Fotos antes/después de instalaciones reales +2. **Educa para Ganar Confianza (Autoridad)** — Tips técnicos, explicaciones claras +3. **Seguridad y Prevención (Urgencia)** — Alertas sobre riegos reales +4. **Detrás del Técnico (Confianza y Personalidad)** — Bilingüe, independiente, llega a tu marina +5. **Prueba Social y Resultados (Conversión)** — Testimonios, reseñas, proyectos completados + +--- + +## MÓDULO 3: INSTAGRAM — PERFIL Y CONTENIDO + +### Bio Optimizada + +**Inglés:** +``` +Prisa Yachts LLC ⚡ +Marine Electrical Technician | FL Coast +Rewiring · Battery Banks · Panels · Washdown +Stuart to Jacksonville — We Come to Your Marina +📲 DM for a free quote +🔗 prisayachts.com +``` + +**Español:** +``` +Prisa Yachts LLC ⚡ +Electricista Marino | Costa de Florida +Cableado · Baterías · Paneles · Washdown +Stuart hasta Jacksonville — Vamos a tu marina +📲 Escríbenos para cotización gratis +🔗 prisayachts.com +``` + +### Highlights a crear INMEDIATAMENTE +1. **Our Work** — Mejor trabajo terminado (fotos limpias de instalaciones) +2. **Before & After** — Solo transformaciones +3. **Services** — Una diapositiva por servicio con "DM for quote" +4. **Where We Work** — Mapa Stuart a Jacksonville, marinas donde has trabajado +5. **Tips** — Slides educacionales guardados +6. **Reviews** — Screenshots de clientes satisfechos + +### Rotación de Posts (ciclo de 3) +- Post Tipo 1: Foto de trabajo terminado (prueba) +- Post Tipo 2: Antes/Después (transformación) +- Post Tipo 3: Educación/confianza + +### Regla de CTA en cada post +Exactamente **1 CTA al final** — nunca dos, nunca cero. Rotar entre: +- "DM us for a free quote. We come to your marina." +- "Send us a photo of your setup and we will tell you what it needs." +- "Tag a boat owner who needs to see this." +- "Save this — you will want to refer back to it." +- "Escríbenos por DM — cotización gratis, sin compromiso." + +### Hashtags por post (usar 8-12, mezclar tiers) +**Tier A (volumen alto):** #MarineElectrical #BoatLife #YachtLife #FloridaBoating #BoatMaintenance #MarineElectrician +**Tier B (intención alta):** #YachtElectrical #LithiumBattery #MarineBatteries #VictronEnergy #BoatWiring #MarineSafety +**Tier C (geográfico, conversión alta):** #TreasureCoast #SpaceCoast #StuartFL #FortPierce #CocoaBeach #FloridaYacht + +### Reels con solo fotos (NO necesitas video) +**Estructura del Reel de Transformación:** +1. Frame texto: "Here is what we found." (1-2 seg) +2. Frames 2-4: Fotos del ANTES (problema) +3. Frame texto: "Here is what we did." (1 seg) +4. Frames 6-8: Fotos del DESPUÉS (trabajo limpio) +5. Frame final: "Stuart to Jacksonville. DM for a free quote. Prisa Yachts LLC" + +**Audio:** Buscar sonidos trending en home renovation / "satisfying work" — este nicho cruza perfecto. + +--- + +## MÓDULO 4: TIKTOK — SCRIPTS LISTOS PARA FILMAR + +### Top 5 Formatos de Video + +1. **Antes/Después** — El de mayor rendimiento en trades. Muestra problema, trabaja, revela resultado limpio. +2. **"Why Your Boat Did That"** — Lead con síntoma conocido (baterías muriendo, luces parpadeando) → explica causa raíz +3. **POV Día de Trabajo** — Cámara mostrando lo que ves mientras trabajas. Con audio trending. +4. **Transparencia de Costos** — Desglosa qué cuesta un trabajo y por qué. Filtra clientes de precio, atrae serios. +5. **Safety Warning Bilingüe** — Tip de seguridad en inglés, punto clave repetido en español. + +### 10 Hooks de Apertura (primeros 3 segundos) + +1. "This boat almost burned down last week because of this." [muestra cable dañado] +2. "If you own a boat, stop what you are doing and look at your battery terminals right now." +3. "Six hundred thousand dollar yacht. Wire nuts." +4. "I pulled two hundred and thirty feet of wrong wire out of one boat today." +5. "The previous owner of this boat was three bad connections away from losing everything." +6. "Nobody tells boat owners this about shore power." +7. "This is what your battery bank looks like after five years if nobody services it." +8. "Day one versus day three on a full rewire. Watch." +9. "Your bilge pump wiring is probably wrong. Here is why it matters." +10. "I have been doing marine electrical for twelve years and this is still the most common mistake I find." + +### Estructura Universal de Video (Hook → Proof → Value → Anchor) + +- **0-3 seg: Hook** — Una afirmación. Una imagen. Genera miedo, curiosidad o reconocimiento. +- **3-15 seg: Proof** — Muestra que lo que dijiste en el hook es real. En la locación, tocando el problema. +- **15-40 seg: Value** — La información, demostración o transformación real. Aquí ocurren los "saves". +- **40-55 seg: Anchor** — Razón para seguir, comentar o contactar. Elegir UNO: + - Anchor Comunidad: "Drop your question in the comments" + - Anchor Negocio: "If your boat needs this, I work Stuart to Jacksonville — DM me" + +**Regla:** Contenido tutorial → Anchor Comunidad. Contenido de transformación/seguridad → Anchor Negocio. + +### Script #1 — "The Battery That Almost Burned This Boat Down" (55 seg) + +[Abrir en terminales corroídas, zoom lento] + +"Look at this. I got called to a 42-foot Viking today because the owner kept losing power every time he ran the AC. He thought it was the inverter. It was not the inverter." + +[Pan al banco de baterías completo — conexiones flojas, corrosión, cableado incorrecto] + +"Three Group 31 batteries. None of them properly terminated. The positive bus bar is connected with the wrong gauge wire — this thing is a heat source waiting to find something to burn." + +[Corte al trabajo — limpiando terminales, crimpando nuevas terminaciones] + +"We are pulling all of this out, cleaning every contact point, installing proper tinned marine wire and rebuilding this battery bank the right way." + +[Corte a la instalación terminada — limpia, etiquetada, bien organizada] + +"Same boat. Thirty-six hours later. Every connection torqued to spec, labeled, heat-shrink on every terminal. That AC runs all night and the owner sleeps without worrying about waking up to smoke." + +[Mirar a cámara] + +"If your batteries are more than five years old and you have not had them inspected, call someone. Not because I want the work. Because boats burn." + +[Overlay: Stuart to Jacksonville FL | DM for inspection] + +--- + +### Script #2 — "Why Your Shore Power Is Dangerous Right Now" (45 seg, Bilingüe) + +[En el muelle de la marina, pedestal de shore power visible] + +"Real quick — if you are plugged into shore power and you have not replaced your shore power cord in the last three to five years, go check it right now." + +[Mostrar conector deteriorado — pines corroídos, carcasa agrietada] + +"This came off a boat at the marina this morning. The owner had no idea. This connector was pulling 30 amps through connections that were partially melted. That is a fire." + +[Mostrar cable nuevo al lado del dañado] + +"Thirty-amp cords — inspect the male end, inspect the female end. Any discoloration, any heat marks, any corrosion — replace it." + +[Cambiar a español, misma energía] + +"Para mis amigos hispanos — el cable de shore power de su barco, reviselo hoy. Si el conector tiene corrosión o marcas de calor, cámbielo antes de su próximo viaje." + +[Volver a inglés] + +"Stuart to Jacksonville, I do shore power inspections. Link in bio." + +--- + +### Script #3 — "What a Full Rewire Actually Looks Like" (30 seg, POV) + +[Sin intro, abrir directamente en manos sacando cableado viejo de un panel] + +"This is day two of a full rewire on a 38-foot trawler. The previous owner ran extensions. Everywhere. Instead of running proper circuits, they just ran extension cords and stapled them to the bulkhead." + +[Corte a la pila de cable viejo removido] + +"That pile is 230 feet of wrong wire pulled out of one boat." + +[Corte al nuevo cableado siendo instalado, limpio y organizado] + +"New tinned marine wire, color-coded, properly fused at the source. Every circuit labeled." + +[Toma final: panel terminado] + +"This is what a real electrical system looks like." + +[Overlay: Full rewires, Stuart to Jax FL] + +--- + +### Script #9 — Historia Personal Bilingüe (60 seg, Brand Story) + +[Cámara de frente, luz natural] + +"Quick story — people ask me why I specialize in marine electrical. The honest answer is that I did not plan to." + +[Caminar y hablar, moviéndose por la marina] + +"I came to Florida from Colombia. My first years in the trades were general electrical — residential, commercial, everything. Then a friend asked me to help him troubleshoot his boat. I spent four hours on that boat and I was completely hooked." + +[Parar, mirar a cámara] + +"Marine electrical is harder than residential. The environment is hostile. Everything corrodes. Vibration loosens connections. You are working in confined spaces. And if you get it wrong, the consequences are not a tripped breaker — the consequences are someone stranded offshore or worse." + +[Cambiar a español] + +"Para los que me siguen en español — soy colombiano, hablo inglés y español, y atiendo clientes en ambos idiomas desde Stuart hasta Jacksonville. Hay muy pocos técnicos bilingües en este nicho y quiero que la comunidad hispana tenga acceso al mismo nivel de servicio." + +[Volver a inglés] + +"Prisa Yachts LLC. Marine electrical done right. Link in bio." + +--- + +### Frecuencia y Timing TikTok + +**Frecuencia:** 3 videos/semana (meses 1-2) → 4-5/semana (mes 3+) + +**Mejores horarios ET:** +- Martes 7:00-9:00 AM +- Miércoles 12:00-1:00 PM +- Jueves 7:00-9:00 PM +- Sábado 8:00-10:00 AM + +**Por día:** +- Lunes: Contenido de seguridad (urgencia del lunes impulsa shares) +- Miércoles: Tutorial/educación (saves de mitad de semana) +- Viernes/Sábado: Antes/Después (audiencia del fin de semana) + +--- + +## MÓDULO 5: CAPTIONS LISTAS — COPY AND PASTE + +### 15 Captions de Instagram listas para usar + +**[1] Battery Bank Install (EN)** +"This 200Ah lithium bank replaced a pair of AGM batteries that were 6 years past their prime. + +The owner had been losing shore power every night. Now he has full power through sunrise — without plugging in. + +We installed, wired, programmed the BMS, and were gone before noon. + +If your batteries are struggling to hold a charge, DM us. We work at marinas from Stuart to Jacksonville. Quote is free. + +#marineelectrical #yachtlife #lithiumbattery #batterybank #boatlife #marinetech #floridaboating #marinafl" + +--- + +**[2] Rewiring Job (EN)** +"This boat came to us with 40 feet of original wiring from the late 90s. Brittle insulation. Undersized conductors. Three mystery circuits no one could trace. + +We pulled it all. Started clean. + +Every wire labeled. Every run secured. Every circuit documented. + +DM us for a full rewiring quote. We travel to your marina. + +#rewiring #marineelectrical #boatsafety #yachtrepair #marineelectrician #floridamarina #boatmaintenance" + +--- + +**[3] Trabajo de Cableado (ES)** +"Cableado completo de un velero de 42 pies. Todo el sistema original estaba fuera de norma. + +Cada cable marcado. Cada circuito documentado. Cada conexión sellada. + +Cuando terminamos, el dueño sabía exactamente qué hacía cada interruptor en su tablero — por primera vez en años. + +Servicio en marinas desde Stuart hasta Jacksonville. + +Cotización gratis por mensaje directo. + +#electricidadmarina #cableado #velero #marineelectrician #floridamarina #mantenimientonaval" + +--- + +**[4] Safety Warning — Shore Power (EN)** +"This shore power connection failed a GFCI test during a routine inspection. The boat owner had no idea — everything 'worked fine.' + +Shore power is the #1 cause of electrical fires on boats at the dock. + +If your boat lives at a marina and you have not had a shore power inspection in the last 2 years, this post is for you. + +DM me to schedule. I work at your marina — Stuart to Jacksonville. + +#MarineElectricalSafety #ShorePower #BoatFire #MarineSafety #BoatInspection #MarineElectrician #FloridaBoating" + +--- + +**[5] Lithium vs AGM (EN)** +"AGM or Lithium — here is the short version: + +AGM: Lower upfront cost, reliable, best for occasional boaters. +Lithium: 3-4x usable capacity, charges faster, lasts 8-10x longer — best for liveaboards and high-draw systems. + +The honest answer: it depends on how you use your boat. I do a load calculation and tell you what actually makes sense. + +DM me for a no-pressure consultation. + +#LithiumVsAGM #MarineBatteries #BoatBatteries #MarineElectrical #floridaboating" + +--- + +**[6] Before/After Panel (EN)** +"Before: Old panel. Corroded terminals. Half the breakers tripped and never reset. + +After: New panel. Clean runs. Every circuit marked and tested. Full wiring diagram delivered. + +Serving Florida marinas from Stuart to Jacksonville. Free quotes via DM. + +⚡ Tag a boat owner who needs this. + +#electricalpanel #marinepanel #boatelectrical #yachtmaintenance #marineelectrical #floridaboating" + +--- + +**[7] Washdown System (EN)** +"A saltwater washdown system is one of the best upgrades you can add to a working vessel. + +We install complete systems: pump, plumbing, deck fittings, wired and tested. + +Takes about 3-4 hours. Takes care of your boat for years. + +DM us to schedule. We come to your slip. + +#washdownsystem #marineinstallation #yachtupgrade #boatlife #marinework #floridayacht" + +--- + +**[8] Hurricane Season Checklist (EN)** +"5 electrical checks before hurricane season: + +1. Shore power cord — look for discoloration or cracks +2. Battery terminals — white powder = sulfation, needs attention +3. Cycle all breakers manually — replace any that feel spongy +4. Test bilge pump float switch +5. Check running lights — they fail silently + +Florida hurricane season starts June 1. Save this. Share with a boat neighbor. + +#HurricaneSeason #BoatMaintenance #MarineElectrical #FloridaBoating #BoatSafety" + +--- + +**[9] Seguridad Eléctrica (ES)** +"El cableado eléctrico marino no es igual al terrestre. + +El ambiente salado corroe todo. La vibración afloja conexiones. La humedad crea cortos donde menos lo esperas. + +Por eso usamos materiales certificados para uso marino en cada instalación. Sin atajos. + +Si tu barco tiene más de 10 años y nunca ha tenido una revisión eléctrica completa — es momento. + +DM para inspecciones y cotizaciones. + +#seguridadmarina #inspeccionelectrica #electricidadmarina #barcosfl #marineelectrical" + +--- + +**[10] Liveaboard Focus (EN)** +"Liveaboards have different electrical needs than weekend boaters. + +You need consistent power, redundancy, and a system that handles daily household loads. + +We have designed and installed full liveaboard electrical systems including shore power management, 12V banks, inverters, and solar integration. + +DM us if your liveaboard electrical feels like a patchwork of band-aids. + +#liveaboard #liveaboardlife #marineelectrical #batterybank #solarboat #floridamarina #yachtlife" + +--- + +**[11] Marina Managers/Captains (EN)** +"Marina managers and captains — we keep you on the water. + +Electrical issues are the #1 cause of unexpected downtime on working vessels. We prioritize commercial and fleet clients with faster scheduling and documented service records. + +Stuart to Jacksonville. DM or share with your marina manager. + +#marinebusiness #captainslife #yachtcaptain #fleetmaintenance #marineelectrical #floridamarina" + +--- + +**[12] Diagrama Eléctrico (ES)** +"Cada instalación nueva que hago incluye un diagrama eléctrico completo. + +No porque sea obligatorio — porque el próximo técnico que trabaje en tu barco merece saber exactamente qué está viendo. + +Un cálculo de carga correcto también te dice si tu sistema de carga puede mantenerse al ritmo de tu consumo. + +Escríbeme para precios. + +#DiagramaElectrico #ElectricidadMarina #BarcosEnFlorida #TecnicoNautico" + +--- + +**[13] Call for Referrals (EN)** +"Good referrals run this industry. + +If your marina neighbor has been complaining about battery problems, flickering lights, or a panel that looks like it was last touched in 2003 — send them our way. + +Honest work, fair prices, we document everything. + +Florida coast, Stuart to Jacksonville. Tag them below. + +#marineelectrical #referral #yachtlife #boatmaintenance #floridamarina" + +--- + +**[14] Banco de Baterías Litio (ES)** +"Banco de baterías de litio instalado en un crucero en Stuart. + +El cliente llevaba dos años lidiando con baterías AGM que no aguantaban la noche. Hoy tiene energía de sobra, BMS programado y diagrama de cableado en mano. + +Trabajamos en marinas de toda la costa de Florida. + +Escríbenos por DM para una cotización sin costo. + +#electricidadmarina #baterias #litio #yachtlife #floridaboating #barcosfl" + +--- + +**[15] Pre-Temporada (ES)** +"Antes de la próxima temporada de navegación — revisión eléctrica completa. + +Los problemas que ignoraste el año pasado no desaparecen solos. Las conexiones corroídas empeoran. Las baterías débiles se mueren. + +Una inspección ahora te ahorra una avería después. + +Cotización gratis. DM esta semana. + +⚡ Comparte con alguien que esté preparando su barco. + +#temporadanavegacion #electricidadmarina #mantenimientonaval #floridaboating" + +--- + +## MÓDULO 6: KPIs Y MÉTRICAS + +### Días 1-30 (Fundación) +- Instagram: 200 cuentas únicas alcanzadas por post para fin de semana 4 +- Instagram: Tasa de engagement 3.5%+ (likes + comments + saves / reach) +- Facebook: 1 contacto directo (DM o llamada) originado de redes sociales +- LinkedIn: 50 vistas de perfil por post +- Nextdoor: perfil verificado en 5 zip codes costeros + +### Días 31-60 (Tracción) +- Instagram: +75-150 seguidores nuevos +- Instagram: Al menos 1 Reel con 1,000+ vistas de no-seguidores +- Facebook Groups: 3+ conversaciones iniciadas, 1 resultando en DM +- LinkedIn: Primer mensaje entrante de marina manager, capitán o broker +- Lead: 3+ consultas directamente atribuidas a contenido de redes sociales + +### Días 61-90 (Conversión) +- Instagram: 300+ seguidores, engagement 4%+ consistente +- LinkedIn: +25 conexiones en audiencia objetivo +- Revenue: 1 trabajo/mes que el cliente atribuye a haber visto Prisa Yachts en redes +- Método: preguntar a cada cliente nuevo "¿cómo nos encontraste?" + +### 5 Métricas semanales a trackear (para n8n → Google Sheets) +1. Posts publicados (objetivo vs. real) +2. Alcance total de la semana +3. Engagement total (likes + comments + shares + saves) +4. Tasa de engagement (%) +5. Contactos entrantes atribuidos a redes (DMs, llamadas, emails) + +--- + +## MÓDULO 7: AUTOMATIZACIÓN EN n8n + +### Workflows a construir en n8n.crewinghunters.com + +**Workflow 1: Buffer de Contenido (Google Sheets → Instagram/Facebook)** +- Google Sheet con columnas: plataforma, fecha/hora, caption EN, caption ES, hashtag set, image URL (Google Drive) +- Schedule Trigger con cron según calendario semanal +- HTTP Node → Meta Graph API para publicación automática +- Rotación de sets de hashtags por pilar de contenido + +**Workflow 2: Reminder de LinkedIn** +- Schedule Trigger (Lu/Mi/Vi 12 PM) +- Notificación push al teléfono con el texto del post del día +- LinkedIn no permite publicación automática via API para posts personales + +**Workflow 3: Recordatorio de Grupos de Facebook** +- Schedule Trigger (Ma/Ju) +- Notificación al dueño con el post de valor de la semana para copiar/pegar en grupos + +**Workflow 4: Reporte Semanal (Domingo noche)** +- Cron cada domingo 7 PM +- Leer métricas de Meta Graph API y LinkedIn API +- Guardar en Google Sheets +- Enviar resumen por email a alro65@gmail.com + +**Workflow 5: Preparación de Contenido (Domingo)** +- Trigger manual o cron domingo 8 AM +- Lista de qué fotografiar esta semana +- Recordatorio de cargar fotos a Google Drive por folder de pilar + +### Grupos de Facebook donde participar +- Space/Treasure Coast Power Boat Club +- Freedom Boat Club of the Space and Treasure Coasts +- Grupos de marinas locales por ciudad del área de servicio + +--- + +## PLAN DE ACCIÓN — PRIMERAS 2 SEMANAS + +### Semana 1: Establecer Presencia +- [ ] Actualizar bio de Instagram (versión EN o ES) +- [ ] Crear los 6 Highlights inmediatamente (aunque tengan 1 sola story cada uno) +- [ ] Publicar los primeros 3 posts (rotación Tipo 1/2/3 con fotos de trabajos existentes) +- [ ] Agregar geotag a cada post y story desde ahora +- [ ] Registrar perfil de negocio en Nextdoor en 5 zip codes +- [ ] Verificar/crear Google Business Profile + +### Semana 2: Primer Reel y Grupos +- [ ] Publicar primer Reel usando formato "Job Story" con fotos antes/después +- [ ] Unirse a 3 grupos de Facebook de boating de Florida +- [ ] Hacer 1 post de valor en cada grupo (no vender, educar) +- [ ] Crear perfil de LinkedIn y publicar primer post con foto de proyecto +- [ ] Responder todos los comments y DMs en menos de 2 horas + +--- + +*Plan generado por Claude con especialistas: Social Media Strategist, Instagram Curator, TikTok Strategist, SEO Specialist* +*Para implementación de n8n: ir a n8n.crewinghunters.com y crear los 5 workflows del Módulo 7* diff --git a/prisa-yachts/whatsapp_automation_spec.md b/prisa-yachts/whatsapp_automation_spec.md new file mode 100644 index 0000000..0a7d730 --- /dev/null +++ b/prisa-yachts/whatsapp_automation_spec.md @@ -0,0 +1,481 @@ +# WhatsApp Automation — Prisa Yachts LLC +## Evolution API + n8n | Zero Additional Cost +## Versión: 1.0 | 2026-05-04 + +--- + +## ARQUITECTURA GENERAL + +``` +Cliente envía WhatsApp + ↓ + Evolution API + (Docker en tu servidor) + ↓ + Webhook → n8n.crewinghunters.com + ↓ + n8n procesa mensaje + ↓ + Evolution API → responde al cliente +``` + +**Costo adicional:** $0 — todo corre en infraestructura existente. +**Número:** Tu número personal/negocio actual (solo hay que escanearlo con QR una vez). + +--- + +## PASO 1: INSTALAR EVOLUTION API + +### Opción A — Docker Compose (recomendado) + +En tu servidor, crear el archivo `/opt/evolution-api/docker-compose.yml`: + +```yaml +version: "3.7" + +services: + evolution-api: + image: atendai/evolution-api:latest + container_name: evolution-api + restart: always + ports: + - "8080:8080" + environment: + - SERVER_URL=https://wa.crewinghunters.com # subdominio que apuntes a este servidor + - AUTHENTICATION_TYPE=apikey + - AUTHENTICATION_API_KEY=PRISA_WA_SECRET_KEY_AQUI + - AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true + - QRCODE_LIMIT=30 + - WEBHOOK_GLOBAL_ENABLED=true + - WEBHOOK_GLOBAL_URL=https://n8n.crewinghunters.com/webhook/prisa-whatsapp + - WEBHOOK_EVENTS_MESSAGES_UPSERT=true + - WEBHOOK_EVENTS_MESSAGES_UPDATE=true + - WEBHOOK_EVENTS_CONNECTION_UPDATE=true + - DATABASE_ENABLED=false + - CACHE_REDIS_ENABLED=false + volumes: + - evolution_instances:/evolution/instances + +volumes: + evolution_instances: +``` + +```bash +cd /opt/evolution-api +docker-compose up -d +``` + +### Conectar tu número (una sola vez) + +```bash +# 1. Crear instancia +curl -X POST https://wa.crewinghunters.com/instance/create \ + -H "apikey: PRISA_WA_SECRET_KEY_AQUI" \ + -H "Content-Type: application/json" \ + -d '{"instanceName": "prisa-yachts", "qrcode": true}' + +# 2. Obtener QR +curl https://wa.crewinghunters.com/instance/connect/prisa-yachts \ + -H "apikey: PRISA_WA_SECRET_KEY_AQUI" +# → responde con imagen QR en base64 o URL + +# 3. Escanear QR desde WhatsApp en tu teléfono +# WhatsApp → Dispositivos Vinculados → Vincular dispositivo → Escanear QR +``` + +Una vez escaneado, el número queda conectado. Si el servidor se reinicia, Evolution API reconecta solo usando la sesión guardada. + +--- + +## PASO 2: CONFIGURAR NGINX (si usas reverse proxy) + +```nginx +server { + listen 80; + server_name wa.crewinghunters.com; + return 301 https://$host$request_uri; +} + +server { + listen 443 ssl; + server_name wa.crewinghunters.com; + + # SSL (certbot o tu certificado) + ssl_certificate /etc/letsencrypt/live/wa.crewinghunters.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/wa.crewinghunters.com/privkey.pem; + + location / { + proxy_pass http://localhost:8080; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } +} +``` + +--- + +## PASO 3: WORKFLOWS EN n8n + +### Variables de entorno (agregar en n8n) + +```env +PRISA_WA_API_URL=https://wa.crewinghunters.com +PRISA_WA_API_KEY=PRISA_WA_SECRET_KEY_AQUI +PRISA_WA_INSTANCE=prisa-yachts +PRISA_OWNER_PHONE=1XXXXXXXXXX # número del dueño en formato internacional sin + +``` + +--- + +### WA-WF1: AUTO-RESPUESTA INTELIGENTE + +**Trigger:** Webhook POST en `/webhook/prisa-whatsapp` + +**Lógica completa:** + +``` +[Webhook: recibe mensaje de Evolution API] + → [Code: extraer remoteJid, message.conversation, pushName] + → [Code: normalizar mensaje — trim, toLowerCase] + → [Switch — detectar intención:] + + COTIZACIÓN ("quote", "cotiz", "precio", "cost", "how much", "cuánto") + → [HTTP: Evolution API → enviar mensaje texto] + → [Wait 2s] + → [HTTP: Evolution API → enviar brochure PDF] + + TECA ("teak", "teca", "wood", "madera", "deck") + → [HTTP: Evolution API → enviar respuesta teca + brochure teca] + + ELÉCTRICO ("electric", "eléctric", "wiring", "cable", "battery", "batería", "panel") + → [HTTP: Evolution API → enviar respuesta eléctrico + brochure eléctrico] + + UBICACIÓN ("where", "dónde", "location", "area", "stuart", "jacksonville") + → [HTTP: Evolution API → enviar área de servicio] + + EMERGENCIA ("emergency", "urgente", "urgent", "fire", "fuego", "smoke", "humo") + → [HTTP: Evolution API → enviar número directo] + → [Gmail: notificar al dueño inmediatamente] + + HOLA / SALUDO (primeras palabras: "hi", "hello", "hola", "buenos", "good") + → [HTTP: Evolution API → enviar bienvenida] + + DEFAULT (cualquier otro mensaje) + → [HTTP: Evolution API → enviar menú de opciones] + → [Gmail: notificar al dueño — lead sin clasificar] +``` + +--- + +### MENSAJES EXACTOS + +**BIENVENIDA** (trigger: saludo genérico o primer contacto): +``` +Hi! 👋 Thanks for reaching out to *Prisa Yachts LLC*. + +I'm Alberto, marine electrical technician based out of Stuart, FL — serving Stuart to Jacksonville. + +What can I help you with today? + +1️⃣ Request a quote +2️⃣ Teak restoration & detailing +3️⃣ Marine electrical (ABYC certified work) +4️⃣ Our service area +5️⃣ Emergency / urgent issue + +Just reply with the number or describe your situation. +``` + +--- + +**COTIZACIÓN RECIBIDA** (trigger: "quote", "cotización", "precio", etc.): +``` +Great — I'd love to give you a quote! 🛥️ + +To get you an accurate estimate, I need a few quick details: + +• *What service?* (electrical, teak, detailing, batteries, washdown, or full service) +• *Boat type and length?* (e.g., 38ft sailboat, 45ft twinscrew) +• *Your marina/location?* +• *Best time to call?* + +Reply here or call me directly. I'll also send you our services overview right now. +``` + +*(seguido del brochure PDF general)* + +--- + +**SERVICIOS DE TECA** (trigger: "teak", "teca", "deck", "wood"): +``` +Teak restoration is one of our specialties. 🌿 + +We handle everything from quick maintenance cycles to full recoveries — and we do an honest assessment before quoting so you know if recovery or replacement makes more sense. + +*Our teak services:* +• Two-part clean + sand + oil + seal +• Before/after documentation +• Gelcoat polishing & oxidation removal +• Caulking inspection and reseam + +Send me a photo of your deck and I can give you a rough idea before we even schedule a visit. + +Sending you our teak & detailing brochure now 👇 +``` + +*(seguido del brochure PDF teca)* + +--- + +**SERVICIOS ELÉCTRICOS** (trigger: "electric", "wiring", "battery", "panel"): +``` +Marine electrical is our core specialty — all work done to ABYC E-11 standards. ⚡ + +*What we do:* +• Full rewiring (tinned wire, proper gauge, labeled circuits) +• Lithium battery bank design & installation +• Shore power systems & inverter/charger +• Solar & alternator upgrades +• NMEA 2000 / 0183 integration +• Bilge pump, washdown, anchor windlass + +We work Stuart to Jacksonville. No job too small. + +Sending you our electrical services brochure now 👇 +``` + +*(seguido del brochure PDF eléctrico)* + +--- + +**ÁREA DE SERVICIO** (trigger: "where", "location", "area"): +``` +📍 *Service Area — Prisa Yachts LLC* + +We're based out of *Stuart, FL* and cover the full east coast of Florida: + +• Stuart / Treasure Coast ✅ +• Fort Pierce ✅ +• Vero Beach ✅ +• Sebastian / Brevard ✅ +• Titusville / Space Coast ✅ +• Daytona Beach ✅ +• Jacksonville ✅ + +Travel fees may apply for jobs north of Daytona. Free 20-min phone consult for any location before committing. + +Want to schedule a consult? +``` + +--- + +**EMERGENCIA** (trigger: "emergency", "urgent", "fire", "smoke"): +``` +⚠️ *URGENT — Prisa Yachts LLC* + +For an active emergency (fire, flooding, electrical failure), call me directly right now: + +📞 *[PHONE_NUMBER]* + +If it's an electrical emergency: +• Turn off shore power at the dock pedestal +• Turn off your main breaker +• If there's smoke, get everyone off the boat + +I'm responding to your message now. +``` + +*(+ email automático al dueño: "URGENT: WhatsApp emergency message from [nombre] at [número]")* + +--- + +**MENÚ DEFAULT** (cualquier mensaje no clasificado): +``` +Thanks for reaching out to *Prisa Yachts LLC*! 🛥️ + +I want to make sure I get you to the right place. What are you looking for? + +1️⃣ *Quote* — I need a price for a job +2️⃣ *Teak & Detailing* — restoration, polishing, gelcoat +3️⃣ *Marine Electrical* — wiring, batteries, solar, panels +4️⃣ *Service Area* — where do you work? +5️⃣ *Emergency* — I need help now + +Reply with a number or describe your situation and I'll get back to you shortly. + +— Alberto | Prisa Yachts LLC | Stuart to Jacksonville +``` + +--- + +### WA-WF2: NOTIFICACIÓN DE LEAD AL DUEÑO + +**Trigger:** Todos los mensajes entrantes (paralelo a WA-WF1) + +**Flujo:** +``` +[Webhook: recibe mensaje] + → [Code: formatear — nombre, número, texto, hora ET] + → [Code: ¿es número propio? → IF sí → NoOp (ignorar mensajes del dueño)] + → [Gmail: enviar a alro65@gmail.com] +``` + +**Formato del email:** +``` +Asunto: [Prisa Yachts WA] Nuevo mensaje — Juan Pérez + +Nuevo mensaje de WhatsApp recibido: + +Nombre: Juan Pérez +Número: +1 (772) 555-0123 +Hora: 2026-05-04 10:32 AM ET + +Mensaje: +"Hi I need a quote for my 42ft Hatteras rewiring. I'm in Fort Pierce." + +--- +Respuesta automática enviada: COTIZACIÓN +Brochure enviado: prisa_yachts_general.pdf + +Responder: https://wa.me/17725550123 +``` + +--- + +### WA-WF3: FOLLOW-UP AUTOMÁTICO (24 HORAS) + +**Trigger:** Cron — cada hora, revisar leads sin respuesta humana + +**Lógica:** +``` +[Schedule Trigger: cada hora] + → [Google Sheets: leer tab WALeads] + → [Code: filtrar — status="auto_replied" AND created_at > 24h ago AND no_human_reply=true] + → [IF hay leads pendientes] + → [HTTP: Evolution API → enviar follow-up] + → [Google Sheets: update status="followed_up"] + → [Gmail: notificar al dueño] +``` + +**Mensaje follow-up (24h después):** +``` +Hi [nombre]! Just wanted to follow up on your message yesterday about [tema]. + +Have you had a chance to think about it? I'm happy to answer any questions before you decide. + +📞 Or call me directly: [PHONE_NUMBER] + +— Alberto | Prisa Yachts LLC +``` + +--- + +### WA-WF4: LOG DE CONVERSACIONES (Google Sheets) + +Cada mensaje recibido appenda una fila al tab `WALeads`: + +| Col | Header | Ejemplo | +|-----|--------|---------| +| A | `timestamp` | `2026-05-04 10:32:00` | +| B | `phone` | `+17725550123` | +| C | `name` | `Juan Pérez` | +| D | `message` | `Hi I need a quote...` | +| E | `intent` | `quote` / `teak` / `electrical` / `emergency` / `default` | +| F | `auto_response_sent` | `yes` | +| G | `brochure_sent` | `general` / `teak` / `electrical` / `none` | +| H | `status` | `auto_replied` / `followed_up` / `converted` / `closed` | +| I | `notes` | (notas manuales del dueño) | + +--- + +## PASO 4: API CALLS EXACTAS A EVOLUTION API + +### Enviar mensaje de texto: +``` +POST https://wa.crewinghunters.com/message/sendText/prisa-yachts +Headers: apikey: PRISA_WA_SECRET_KEY_AQUI +Body: { + "number": "17725550123", ← sin +, sin espacios + "text": "Hola mensaje aquí" +} +``` + +### Enviar documento/brochure PDF: +``` +POST https://wa.crewinghunters.com/message/sendMedia/prisa-yachts +Headers: apikey: PRISA_WA_SECRET_KEY_AQUI +Body: { + "number": "17725550123", + "mediatype": "document", + "mimetype": "application/pdf", + "media": "https://drive.google.com/uc?export=download&id={FILE_ID}", + "fileName": "PrisaYachts_Services.pdf", + "caption": "Here's our services overview 👆" +} +``` + +### Enviar imagen: +``` +POST https://wa.crewinghunters.com/message/sendMedia/prisa-yachts +Body: { + "number": "17725550123", + "mediatype": "image", + "mimetype": "image/jpeg", + "media": "https://...", + "caption": "Before & After — Teak Restoration" +} +``` + +--- + +## FLUJO DE IMPLEMENTACIÓN (orden) + +### Semana 1: Setup +1. [ ] Instalar Evolution API con Docker en tu servidor +2. [ ] Configurar DNS: `wa.crewinghunters.com` → IP del servidor +3. [ ] Configurar Nginx + SSL (certbot) +4. [ ] Escanear QR y conectar número +5. [ ] Verificar que el webhook llega a n8n (test con mensaje de prueba) + +### Semana 2: Workflows básicos +6. [ ] Construir WA-WF2 (notificación al dueño) — mínimo viable, sin riesgo +7. [ ] Construir WA-WF4 (log en Google Sheets) — solo lectura/escritura +8. [ ] Probar con mensaje real de tu propio teléfono + +### Semana 3: Respuesta automática +9. [ ] Construir WA-WF1 (auto-respuesta) — empezar solo con el menú DEFAULT +10. [ ] Agregar lógica de cotización +11. [ ] Subir brochures a Google Drive, obtener FILE_IDs +12. [ ] Conectar envío de PDFs +13. [ ] Agregar resto de intenciones (teca, eléctrico, emergencia) + +### Semana 4: Follow-up +14. [ ] Construir WA-WF3 (follow-up 24h) +15. [ ] Probar flujo completo end-to-end + +--- + +## PREGUNTAS A RESOLVER ANTES DEL PRIMER DEPLOY + +1. ¿Cuál es la IP o hostname de tu servidor? +2. ¿Ya tienes Docker instalado en el servidor? +3. ¿Usas Nginx o Caddy como reverse proxy? +4. ¿Cuál es tu número de WhatsApp (formato +1XXXXXXXXXX)? +5. ¿Tienes los brochures PDF listos o hay que crearlos primero? + +--- + +## NOTAS IMPORTANTES + +**Riesgo de ban:** WhatsApp tolera la automatización con números conectados via QR siempre que: +- Los mensajes sean respuestas a conversaciones iniciadas por el cliente (no bulk messaging) +- No envíes mensajes masivos no solicitados +- El comportamiento sea similar al humano (con delays entre mensajes) +Esta arquitectura cumple todo eso — solo responde a mensajes entrantes. + +**Sesión persistente:** Evolution API guarda la sesión en el volumen Docker. Si reinicias el servidor, reconecta solo en <30 segundos sin necesidad de escanear el QR de nuevo. + +**Backup del QR:** Después de conectar el número, hacer backup del volumen: `docker run --rm -v evolution_instances:/data alpine tar czf - /data > evolution_backup.tar.gz`