דילוג לתוכן
  • חוקי הפורום
  • פופולרי
  • לא נפתר
  • משתמשים
  • חיפוש גוגל בפורום
  • צור קשר
עיצובים
  • בהיר
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • כהה
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • ברירת מחדל (ללא עיצוב (ברירת מחדל))
  • ללא עיצוב (ברירת מחדל)
כיווץ
מתמחים טופ
  1. דף הבית
  2. קטגוריות בהרצה
  3. תכנות
  4. בינה מלאכותית - AI
  5. עזרה הדדית - בינה מלאכותית
  6. תחרות מוחות בין הAI השונים

תחרות מוחות בין הAI השונים

מתוזמן נעוץ נעול הועבר עזרה הדדית - בינה מלאכותית
27 פוסטים 13 כותבים 427 צפיות 12 עוקבים
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
תגובה
  • תגובה כנושא
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • Y YAHBDK

    המקום הרבעי גיפיטי

    אני עדיין מחכה☹️

    עריכה:
    שם התוכנה: „נובה” — מרכז השליטה החכם ל-Windows.
    נובה יושבת ברקע ונפתחת ב־Ctrl+Space: חיפוש מיידי של תוכנות וקבצים, היסטוריית לוח־העתקה, פעולות חכמות, פתיחת תיקיות/קישורים וחיפוש טבעי — הכול בממשק עברי מודרני.

    הקוד המלא [לא נבדק]

    $ErrorActionPreference = "Stop"
    
    # ============================================================
    # NOVA — נובה
    # Windows Smart Command Center
    # התקנה + יצירת קבצים + אייקון + Build ל-EXE בלחיצה אחת
    # ============================================================
    
    $Base = Join-Path $env:USERPROFILE "Desktop\NOVA"
    $Src  = Join-Path $Base "src"
    $Out  = Join-Path $Base "NOVA"
    $Py   = Join-Path $Src "nova.py"
    $Icon = Join-Path $Src "nova.ico"
    
    Write-Host ""
    Write-Host "=============================================" -ForegroundColor Cyan
    Write-Host "              NOVA / נובה" -ForegroundColor Cyan
    Write-Host "       מרכז השליטה החכם ל-Windows" -ForegroundColor White
    Write-Host "=============================================" -ForegroundColor Cyan
    Write-Host ""
    
    # ------------------------------------------------------------
    # מציאת Python
    # ------------------------------------------------------------
    $Python = $null
    
    $Candidates = @(
        "py",
        "python",
        "python3"
    )
    
    foreach ($cmd in $Candidates) {
        try {
            $test = & $cmd --version 2>$null
            if ($LASTEXITCODE -eq 0 -and $test -match "Python 3") {
                $Python = $cmd
                break
            }
        } catch {}
    }
    
    if (-not $Python) {
        Write-Host "לא נמצא Python במחשב." -ForegroundColor Red
        Write-Host ""
        Write-Host "הסקריפט מנסה להתקין Python באופן אוטומטי..." -ForegroundColor Yellow
    
        try {
            winget --version | Out-Null
            winget install --id Python.Python.3.12 -e --source winget `
                --accept-package-agreements `
                --accept-source-agreements
    
            $Python = "py"
        }
        catch {
            Write-Host ""
            Write-Host "לא ניתן להתקין Python באופן אוטומטי." -ForegroundColor Red
            Write-Host "יש להתקין Python 3.11 ומעלה ואז להריץ את הבלוק שוב." -ForegroundColor Yellow
            exit 1
        }
    }
    
    Write-Host "Python נמצא: $Python" -ForegroundColor Green
    
    # ------------------------------------------------------------
    # יצירת תיקיות
    # ------------------------------------------------------------
    New-Item -ItemType Directory -Force -Path $Base | Out-Null
    New-Item -ItemType Directory -Force -Path $Src  | Out-Null
    New-Item -ItemType Directory -Force -Path $Out  | Out-Null
    
    # ------------------------------------------------------------
    # יצירת קובץ התוכנה
    # ------------------------------------------------------------
    @'
    import sys
    import os
    import re
    import json
    import time
    import ctypes
    import shutil
    import subprocess
    import threading
    from pathlib import Path
    from urllib.parse import quote
    
    from PySide6.QtCore import (
        Qt, QTimer, Signal, QObject, QThread, QSize, QPoint
    )
    from PySide6.QtGui import (
        QAction, QIcon, QPixmap, QPainter, QColor, QFont,
        QKeySequence, QShortcut
    )
    from PySide6.QtWidgets import (
        QApplication, QWidget, QMainWindow, QVBoxLayout, QHBoxLayout,
        QLabel, QLineEdit, QListWidget, QListWidgetItem, QPushButton,
        QFrame, QSystemTrayIcon, QMenu, QMessageBox, QStackedWidget,
        QGraphicsDropShadowEffect
    )
    
    APP_NAME = "נובה"
    APP_VERSION = "1.0.0"
    
    APPDATA = Path(os.environ.get("APPDATA", Path.home()))
    DATA_DIR = APPDATA / "NOVA"
    DATA_DIR.mkdir(parents=True, exist_ok=True)
    
    CLIP_FILE = DATA_DIR / "clipboard.json"
    
    MAX_CLIPS = 60
    MAX_RESULTS = 40
    
    
    # ============================================================
    # עזרי Windows
    # ============================================================
    
    user32 = ctypes.windll.user32
    kernel32 = ctypes.windll.kernel32
    
    HOTKEY_ID = 7351
    WM_HOTKEY = 0x0312
    MOD_CONTROL = 0x0002
    MOD_SHIFT = 0x0004
    MOD_ALT = 0x0001
    VK_SPACE = 0x20
    
    
    def register_global_hotkey():
        try:
            user32.RegisterHotKey(None, HOTKEY_ID, MOD_CONTROL, VK_SPACE)
            return True
        except Exception:
            return False
    
    
    def unregister_global_hotkey():
        try:
            user32.UnregisterHotKey(None, HOTKEY_ID)
        except Exception:
            pass
    
    
    def open_target(target):
        try:
            os.startfile(str(target))
            return True
        except Exception:
            try:
                subprocess.Popen([str(target)])
                return True
            except Exception:
                return False
    
    
    def open_url(url):
        try:
            os.startfile(url)
            return True
        except Exception:
            return False
    
    
    # ============================================================
    # Clipboard
    # ============================================================
    
    class ClipboardStore:
        def __init__(self):
            self.items = []
            self.load()
    
        def load(self):
            try:
                if CLIP_FILE.exists():
                    data = json.loads(CLIP_FILE.read_text(encoding="utf-8"))
                    if isinstance(data, list):
                        self.items = data[:MAX_CLIPS]
            except Exception:
                self.items = []
    
        def save(self):
            try:
                CLIP_FILE.write_text(
                    json.dumps(self.items, ensure_ascii=False, indent=2),
                    encoding="utf-8"
                )
            except Exception:
                pass
    
        def add(self, text):
            text = text.strip()
    
            if not text:
                return False
    
            if len(text) > 10000:
                text = text[:10000]
    
            if self.items and self.items[0] == text:
                return False
    
            self.items = [x for x in self.items if x != text]
            self.items.insert(0, text)
            self.items = self.items[:MAX_CLIPS]
            self.save()
            return True
    
    
    # ============================================================
    # אינדקס תוכנות
    # ============================================================
    
    class SearchItem:
        def __init__(self, name, path, kind="file", extra=""):
            self.name = name
            self.path = path
            self.kind = kind
            self.extra = extra
    
    
    class SearchIndex(QObject):
        ready = Signal()
    
        def __init__(self):
            super().__init__()
            self.items = []
            self.lock = threading.Lock()
    
        def build(self):
            thread = threading.Thread(
                target=self._build,
                daemon=True
            )
            thread.start()
    
        def _add(self, name, path, kind, extra=""):
            if not name or not path:
                return
    
            self.items.append(
                SearchItem(name, path, kind, extra)
            )
    
        def _build(self):
            result = []
    
            start_locations = []
    
            appdata = os.environ.get("APPDATA")
            programdata = os.environ.get("PROGRAMDATA")
            userprofile = os.environ.get("USERPROFILE")
    
            if appdata:
                start_locations.append(
                    Path(appdata) / "Microsoft/Windows/Start Menu/Programs"
                )
    
            if programdata:
                start_locations.append(
                    Path(programdata) / "Microsoft/Windows/Start Menu/Programs"
                )
    
            desktop = Path(userprofile) / "Desktop"
    
            # תוכנות מתפריט התחל
            for root in start_locations:
                try:
                    if not root.exists():
                        continue
    
                    for p in root.rglob("*.lnk"):
                        try:
                            result.append(
                                SearchItem(
                                    p.stem,
                                    str(p),
                                    "app",
                                    "תוכנה"
                                )
                            )
                        except Exception:
                            pass
    
                    for p in root.rglob("*.exe"):
                        try:
                            result.append(
                                SearchItem(
                                    p.stem,
                                    str(p),
                                    "app",
                                    "תוכנה"
                                )
                            )
                        except Exception:
                            pass
    
                except Exception:
                    pass
    
            # קיצורי דרך בשולחן העבודה
            try:
                if desktop.exists():
                    for p in desktop.iterdir():
                        if p.suffix.lower() in (".lnk", ".exe", ".url"):
                            result.append(
                                SearchItem(
                                    p.stem,
                                    str(p),
                                    "app" if p.suffix.lower() != ".url" else "url",
                                    "שולחן העבודה"
                                )
                            )
            except Exception:
                pass
    
            # תיקיות נפוצות
            folders = [
                ("שולחן העבודה", Path(userprofile) / "Desktop"),
                ("הורדות", Path(userprofile) / "Downloads"),
                ("מסמכים", Path(userprofile) / "Documents"),
                ("תמונות", Path(userprofile) / "Pictures"),
                ("וידאו", Path(userprofile) / "Videos"),
            ]
    
            allowed = {
                ".pdf", ".doc", ".docx", ".xls", ".xlsx",
                ".ppt", ".pptx", ".txt", ".csv",
                ".jpg", ".jpeg", ".png", ".gif", ".webp",
                ".mp4", ".mkv", ".avi", ".mp3", ".wav",
                ".zip", ".rar", ".7z",
                ".py", ".ps1", ".bat", ".json"
            }
    
            for label, folder in folders:
                try:
                    if not folder.exists():
                        continue
    
                    count = 0
    
                    for p in folder.rglob("*"):
                        try:
                            if not p.is_file():
                                continue
    
                            if p.suffix.lower() not in allowed:
                                continue
    
                            result.append(
                                SearchItem(
                                    p.name,
                                    str(p),
                                    "file",
                                    label
                                )
                            )
    
                            count += 1
    
                            # מונע אינדקס עצום במחשבים עמוסים
                            if count >= 3500:
                                break
    
                        except Exception:
                            pass
    
                except Exception:
                    pass
    
            # הסרת כפילויות
            unique = {}
            for item in result:
                key = item.path.lower()
    
                if key not in unique:
                    unique[key] = item
    
            with self.lock:
                self.items = list(unique.values())
    
            self.ready.emit()
    
    
    # ============================================================
    # חיפוש חכם
    # ============================================================
    
    def score_text(query, text):
        q = query.lower().strip()
        t = text.lower()
    
        if not q:
            return 0
    
        if t == q:
            return 1000
    
        if t.startswith(q):
            return 800
    
        if q in t:
            return 600
    
        # התאמה לפי מילים
        words = [x for x in re.split(r"\s+", q) if x]
    
        score = 0
    
        for word in words:
            if word in t:
                score += 150
    
        # התאמת אותיות עוקבות
        pos = 0
        matched = 0
    
        for char in q:
            idx = t.find(char, pos)
    
            if idx >= 0:
                matched += 1
                pos = idx + 1
    
        if matched:
            score += int((matched / len(q)) * 100)
    
        return score
    
    
    # ============================================================
    # כרטיס תוצאה
    # ============================================================
    
    class ResultRow(QFrame):
        clicked = Signal(object)
    
        def __init__(self, item, parent=None):
            super().__init__(parent)
            self.item = item
    
            self.setObjectName("resultRow")
            self.setCursor(Qt.PointingHandCursor)
    
            layout = QHBoxLayout(self)
            layout.setContentsMargins(16, 11, 16, 11)
            layout.setSpacing(12)
    
            icon = QLabel()
    
            icon_text = {
                "app": "▣",
                "file": "▤",
                "url": "↗",
                "action": "✦",
                "clipboard": "⧉"
            }.get(item.kind, "•")
    
            icon.setText(icon_text)
            icon.setObjectName("resultIcon")
            icon.setFixedWidth(30)
    
            text_box = QVBoxLayout()
            text_box.setSpacing(2)
    
            title = QLabel(item.name)
            title.setObjectName("resultTitle")
    
            subtitle = QLabel(item.extra or item.path)
            subtitle.setObjectName("resultSub")
            subtitle.setTextInteractionFlags(Qt.NoTextInteraction)
    
            text_box.addWidget(title)
            text_box.addWidget(subtitle)
    
            layout.addWidget(icon)
            layout.addLayout(text_box, 1)
    
            arrow = QLabel("‹")
            arrow.setObjectName("resultArrow")
            layout.addWidget(arrow)
    
        def mousePressEvent(self, event):
            if event.button() == Qt.LeftButton:
                self.clicked.emit(self.item)
    
            super().mousePressEvent(event)
    
    
    # ============================================================
    # התוכנה
    # ============================================================
    
    class NovaWindow(QMainWindow):
    
        def __init__(self):
            super().__init__()
    
            self.clipboard_store = ClipboardStore()
            self.index = SearchIndex()
    
            self.index.ready.connect(self.index_ready)
    
            self.all_results = []
            self.selected_index = 0
            self.hotkey_registered = False
    
            self.setWindowTitle("נובה — מרכז השליטה")
            self.setWindowIcon(QIcon(str(Path(sys.executable).parent / "nova.ico")))
    
            self.setMinimumSize(760, 560)
            self.resize(860, 650)
    
            self.setAttribute(Qt.WA_DeleteOnClose, False)
    
            self.build_ui()
            self.install_global_hotkey_handler()
    
            self.index.build()
    
            # מעקב לוח
            self.clipboard_timer = QTimer(self)
            self.clipboard_timer.timeout.connect(self.check_clipboard)
            self.clipboard_timer.start(450)
    
            # עדכון סטטוס
            self.status_timer = QTimer(self)
            self.status_timer.timeout.connect(self.update_status)
            self.status_timer.start(1000)
    
            self.search_edit.setFocus()
    
        # --------------------------------------------------------
        # UI
        # --------------------------------------------------------
    
        def build_ui(self):
    
            root = QWidget()
            root.setObjectName("root")
            self.setCentralWidget(root)
    
            main = QVBoxLayout(root)
            main.setContentsMargins(28, 25, 28, 20)
            main.setSpacing(16)
    
            # Header
            header = QHBoxLayout()
    
            brand_box = QVBoxLayout()
            brand_box.setSpacing(0)
    
            brand = QLabel("נובה")
            brand.setObjectName("brand")
    
            subtitle = QLabel("מרכז השליטה החכם שלך")
            subtitle.setObjectName("subtitle")
    
            brand_box.addWidget(brand)
            brand_box.addWidget(subtitle)
    
            header.addLayout(brand_box)
            header.addStretch()
    
            status = QLabel("● פעילה")
            status.setObjectName("onlineStatus")
    
            header.addWidget(status)
    
            main.addLayout(header)
    
            # Search
            search_frame = QFrame()
            search_frame.setObjectName("searchFrame")
    
            search_layout = QHBoxLayout(search_frame)
            search_layout.setContentsMargins(18, 5, 18, 5)
    
            search_icon = QLabel("⌕")
            search_icon.setObjectName("searchIcon")
    
            self.search_edit = QLineEdit()
            self.search_edit.setPlaceholderText(
                "חפש תוכנה, קובץ, פעולה או כתובת..."
            )
            self.search_edit.setClearButtonEnabled(True)
            self.search_edit.setObjectName("searchEdit")
    
            search_layout.addWidget(search_icon)
            search_layout.addWidget(self.search_edit)
    
            main.addWidget(search_frame)
    
            self.search_edit.textChanged.connect(self.perform_search)
            self.search_edit.returnPressed.connect(self.activate_selected)
    
            # Hint
            hint = QLabel(
                "Ctrl+Space לפתיחה מכל מקום  •  Enter לפתיחה  •  Esc להסתרה"
            )
            hint.setObjectName("hint")
            hint.setAlignment(Qt.AlignCenter)
    
            main.addWidget(hint)
    
            # Content
            content = QHBoxLayout()
            content.setSpacing(14)
    
            # Results
            result_panel = QFrame()
            result_panel.setObjectName("panel")
    
            result_layout = QVBoxLayout(result_panel)
            result_layout.setContentsMargins(15, 15, 15, 15)
            result_layout.setSpacing(9)
    
            title_row = QHBoxLayout()
    
            self.results_title = QLabel("גישה מהירה")
            self.results_title.setObjectName("sectionTitle")
    
            self.results_count = QLabel("")
            self.results_count.setObjectName("count")
    
            title_row.addWidget(self.results_title)
            title_row.addStretch()
            title_row.addWidget(self.results_count)
    
            result_layout.addLayout(title_row)
    
            self.results = QVBoxLayout()
            self.results.setSpacing(7)
    
            result_layout.addLayout(self.results)
            result_layout.addStretch()
    
            content.addWidget(result_panel, 3)
    
            # Sidebar
            side = QFrame()
            side.setObjectName("sidePanel")
    
            side_layout = QVBoxLayout(side)
            side_layout.setContentsMargins(14, 14, 14, 14)
            side_layout.setSpacing(9)
    
            side_title = QLabel("פעולות מהירות")
            side_title.setObjectName("sectionTitle")
            side_layout.addWidget(side_title)
    
            actions = [
                ("📋", "לוח ההעתקות", self.show_clipboard),
                ("📁", "פתח הורדות", self.open_downloads),
                ("🖥", "מחשב זה", self.open_computer),
                ("⚙", "הגדרות Windows", self.open_settings),
                ("🌐", "חיפוש באינטרנט", self.web_search),
            ]
    
            for icon, text, callback in actions:
                btn = QPushButton(f"{icon}   {text}")
                btn.setObjectName("actionButton")
                btn.setCursor(Qt.PointingHandCursor)
                btn.clicked.connect(callback)
                side_layout.addWidget(btn)
    
            side_layout.addStretch()
    
            info = QLabel(
                "נובה עובדת ברקע.\n"
                "אין צורך להשאיר את החלון פתוח.\n\n"
                "הנתונים המקומיים נשמרים\n"
                "במחשב שלך."
            )
            info.setObjectName("info")
            info.setWordWrap(True)
    
            side_layout.addWidget(info)
    
            content.addWidget(side, 1)
    
            main.addLayout(content, 1)
    
            # Footer
            footer = QHBoxLayout()
    
            self.status_label = QLabel("מאתחל אינדקס...")
            self.status_label.setObjectName("footer")
    
            footer.addWidget(self.status_label)
            footer.addStretch()
    
            version = QLabel(f"נובה {APP_VERSION}")
            version.setObjectName("footer")
    
            footer.addWidget(version)
    
            main.addLayout(footer)
    
            self.apply_style()
    
        # --------------------------------------------------------
        # Style
        # --------------------------------------------------------
    
        def apply_style(self):
            self.setStyleSheet("""
            * {
                font-family: "Segoe UI";
            }
    
            QMainWindow, QWidget#root {
                background: #0b1020;
                color: #edf2ff;
            }
    
            QLabel {
                color: #edf2ff;
            }
    
            QLabel#brand {
                font-size: 31px;
                font-weight: 800;
                color: #ffffff;
            }
    
            QLabel#subtitle {
                font-size: 13px;
                color: #8792ad;
            }
    
            QLabel#onlineStatus {
                background: #112a25;
                color: #55e6b1;
                border: 1px solid #1c5547;
                border-radius: 15px;
                padding: 6px 12px;
                font-size: 12px;
                font-weight: 600;
            }
    
            QFrame#searchFrame {
                background: #141b31;
                border: 1px solid #273253;
                border-radius: 17px;
            }
    
            QFrame#searchFrame:focus-within {
                border: 1px solid #6077ff;
            }
    
            QLabel#searchIcon {
                font-size: 29px;
                color: #7185ff;
                padding-bottom: 2px;
            }
    
            QLineEdit#searchEdit {
                background: transparent;
                border: none;
                color: #ffffff;
                font-size: 18px;
                padding: 11px 4px;
                selection-background-color: #4f61d8;
            }
    
            QLabel#hint {
                color: #68738e;
                font-size: 11px;
            }
    
            QFrame#panel {
                background: #10172a;
                border: 1px solid #1e2943;
                border-radius: 17px;
            }
    
            QFrame#sidePanel {
                background: #10172a;
                border: 1px solid #1e2943;
                border-radius: 17px;
            }
    
            QLabel#sectionTitle {
                color: #ffffff;
                font-size: 14px;
                font-weight: 700;
            }
    
            QLabel#count {
                color: #68738e;
                font-size: 11px;
            }
    
            QFrame#resultRow {
                background: #151d33;
                border: 1px solid transparent;
                border-radius: 12px;
            }
    
            QFrame#resultRow:hover {
                background: #1b2642;
                border: 1px solid #34436b;
            }
    
            QLabel#resultIcon {
                color: #7185ff;
                font-size: 21px;
                font-weight: bold;
            }
    
            QLabel#resultTitle {
                color: #f4f6ff;
                font-size: 13px;
                font-weight: 600;
            }
    
            QLabel#resultSub {
                color: #687690;
                font-size: 10px;
            }
    
            QLabel#resultArrow {
                color: #52607d;
                font-size: 21px;
            }
    
            QPushButton#actionButton {
                text-align: right;
                background: #151d33;
                border: 1px solid #222e4a;
                border-radius: 11px;
                color: #dbe2f6;
                padding: 12px 11px;
                font-size: 12px;
            }
    
            QPushButton#actionButton:hover {
                background: #1d2948;
                border: 1px solid #394b7a;
            }
    
            QPushButton#actionButton:pressed {
                background: #11182b;
            }
    
            QLabel#info {
                color: #626e89;
                background: #0d1426;
                border-radius: 10px;
                padding: 12px;
                font-size: 10px;
            }
    
            QLabel#footer {
                color: #59657f;
                font-size: 10px;
            }
            """)
    
        # --------------------------------------------------------
        # חיפוש
        # --------------------------------------------------------
    
        def clear_results(self):
            while self.results.count():
                item = self.results.takeAt(0)
                widget = item.widget()
    
                if widget:
                    widget.deleteLater()
    
        def perform_search(self, query):
    
            query = query.strip()
    
            self.clear_results()
    
            if not query:
                self.results_title.setText("גישה מהירה")
    
                quick = [
                    SearchItem(
                        "לוח ההעתקות",
                        "",
                        "clipboard",
                        "העתקות אחרונות"
                    ),
                    SearchItem(
                        "פתח הורדות",
                        "",
                        "action",
                        "תיקיית ההורדות"
                    ),
                    SearchItem(
                        "מחשב זה",
                        "",
                        "action",
                        "סייר הקבצים"
                    ),
                    SearchItem(
                        "הגדרות Windows",
                        "",
                        "action",
                        "הגדרות מערכת"
                    )
                ]
    
                self.all_results = quick
    
                for item in quick:
                    row = ResultRow(item)
                    row.clicked.connect(self.activate_item)
                    self.results.addWidget(row)
    
                self.results_count.setText("גישה מהירה")
                return
    
            self.results_title.setText("תוצאות")
    
            results = []
    
            # פקודות חכמות
            normalized = query.lower()
    
            if normalized.startswith("פתח "):
                target = query[5:].strip()
    
                candidates = [
                    ("הורדות", Path.home() / "Downloads"),
                    ("מסמכים", Path.home() / "Documents"),
                    ("שולחן העבודה", Path.home() / "Desktop"),
                    ("תמונות", Path.home() / "Pictures"),
                    ("וידאו", Path.home() / "Videos"),
                ]
    
                for name, path in candidates:
                    if target in name or name in target:
                        results.append(
                            SearchItem(
                                f"פתח {name}",
                                str(path),
                                "action",
                                str(path)
                            )
                        )
    
            # URL
            if re.match(r"^(https?://|www\.)", query, re.I):
                url = query
    
                if url.startswith("www."):
                    url = "https://" + url
    
                results.append(
                    SearchItem(
                        "פתח כתובת",
                        url,
                        "url",
                        url
                    )
                )
    
            # חיפוש באינטרנט
            if normalized.startswith("חפש "):
                text = query[5:].strip()
    
                if text:
                    url = (
                        "https://www.google.com/search?q="
                        + quote(text)
                    )
    
                    results.append(
                        SearchItem(
                            "חפש באינטרנט",
                            url,
                            "url",
                            text
                        )
                    )
    
            # לוח העתקות
            if normalized in (
                "לוח",
                "העתקות",
                "לוח העתקות",
                "clipboard"
            ):
                for i, text in enumerate(self.clipboard_store.items[:10]):
                    short = text.replace("\n", " ")
    
                    if len(short) > 80:
                        short = short[:80] + "..."
    
                    results.append(
                        SearchItem(
                            short,
                            text,
                            "clipboard",
                            "לחץ כדי להעתיק"
                        )
                    )
    
            # אינדקס
            with self.index.lock:
                indexed = list(self.index.items)
    
            scored = []
    
            for item in indexed:
                s = max(
                    score_text(query, item.name),
                    score_text(query, Path(item.path).name)
                )
    
                if s > 0:
                    scored.append((s, item))
    
            scored.sort(
                key=lambda x: (
                    -x[0],
                    x[1].name.lower()
                )
            )
    
            results.extend(
                [item for _, item in scored[:MAX_RESULTS]]
            )
    
            self.all_results = results[:MAX_RESULTS]
    
            if not self.all_results:
                empty = QLabel(
                    "לא מצאתי תוצאה מתאימה.\n\n"
                    "אפשר לנסות שם תוכנה, שם קובץ,\n"
                    "כתובת אינטרנט או \"חפש ...\"."
                )
    
                empty.setAlignment(Qt.AlignCenter)
                empty.setObjectName("info")
                empty.setMinimumHeight(130)
    
                self.results.addWidget(empty)
    
                self.results_count.setText("0 תוצאות")
                return
    
            for item in self.all_results:
                row = ResultRow(item)
                row.clicked.connect(self.activate_item)
                self.results.addWidget(row)
    
            self.results_count.setText(
                f"{len(self.all_results)} תוצאות"
            )
    
        # --------------------------------------------------------
        # פעולות
        # --------------------------------------------------------
    
        def activate_selected(self):
            if self.all_results:
                self.activate_item(self.all_results[0])
    
        def activate_item(self, item):
    
            if item.kind == "clipboard":
                QApplication.clipboard().setText(item.path)
                self.status_label.setText("הטקסט הועתק ללוח")
                self.hide()
                return
    
            if item.kind == "action":
                if item.name == "פתח הורדות":
                    self.open_downloads()
                elif item.name == "מחשב זה":
                    self.open_computer()
                elif item.name == "הגדרות Windows":
                    self.open_settings()
                elif item.name == "לוח ההעתקות":
                    self.show_clipboard()
                else:
                    open_target(item.path)
    
                return
    
            if item.kind == "url":
                open_url(item.path)
                self.hide()
                return
    
            if item.kind in ("app", "file"):
                open_target(item.path)
                self.hide()
                return
    
            open_target(item.path)
            self.hide()
    
        def show_clipboard(self):
            self.search_edit.setText("לוח")
            self.search_edit.setFocus()
            self.show()
            self.raise_()
            self.activateWindow()
    
        def open_downloads(self):
            open_target(Path.home() / "Downloads")
            self.hide()
    
        def open_computer(self):
            try:
                subprocess.Popen("explorer.exe shell:MyComputerFolder")
            except Exception:
                pass
            self.hide()
    
        def open_settings(self):
            try:
                subprocess.Popen(
                    "start ms-settings:",
                    shell=True
                )
            except Exception:
                pass
            self.hide()
    
        def web_search(self):
            text = self.search_edit.text().strip()
    
            if not text:
                text = "חיפוש"
    
            url = (
                "https://www.google.com/search?q="
                + quote(text)
            )
    
            open_url(url)
            self.hide()
    
        # --------------------------------------------------------
        # Clipboard monitor
        # --------------------------------------------------------
    
        def check_clipboard(self):
            try:
                text = QApplication.clipboard().text()
    
                if text and text.strip():
                    changed = self.clipboard_store.add(text)
    
                    if changed and self.isVisible():
                        if self.search_edit.text().strip() == "לוח":
                            self.perform_search("לוח")
    
            except Exception:
                pass
    
        # --------------------------------------------------------
        # אינדקס
        # --------------------------------------------------------
    
        def index_ready(self):
            count = len(self.index.items)
    
            self.status_label.setText(
                f"האינדקס מוכן • {count:,} פריטים זמינים לחיפוש"
            )
    
            if not self.search_edit.text().strip():
                self.perform_search("")
    
        def update_status(self):
            if not self.index.items:
                self.status_label.setText("בונה אינדקס...")
    
        # --------------------------------------------------------
        # Global Hotkey
        # --------------------------------------------------------
    
        def install_global_hotkey_handler(self):
    
            self.hotkey_registered = register_global_hotkey()
    
            timer = QTimer(self)
            timer.timeout.connect(self.poll_windows_messages)
            timer.start(80)
    
            self.hotkey_timer = timer
    
        def poll_windows_messages(self):
    
            msg = ctypes.wintypes.MSG()
    
            try:
                while user32.PeekMessageW(
                    ctypes.byref(msg),
                    None,
                    WM_HOTKEY,
                    WM_HOTKEY,
                    1
                ):
                    if msg.message == WM_HOTKEY:
                        self.toggle_window()
    
            except Exception:
                pass
    
        def toggle_window(self):
    
            if self.isVisible() and self.isActiveWindow():
                self.hide()
                return
    
            self.show()
            self.raise_()
            self.activateWindow()
            self.search_edit.setFocus()
            self.search_edit.selectAll()
    
        # --------------------------------------------------------
        # Keyboard
        # --------------------------------------------------------
    
        def keyPressEvent(self, event):
    
            if event.key() == Qt.Key_Escape:
                self.hide()
                event.accept()
                return
    
            if event.key() in (
                Qt.Key_Return,
                Qt.Key_Enter
            ):
                self.activate_selected()
                event.accept()
                return
    
            super().keyPressEvent(event)
    
        # --------------------------------------------------------
        # Close = hide to tray
        # --------------------------------------------------------
    
        def closeEvent(self, event):
            event.ignore()
            self.hide()
    
        def cleanup(self):
            unregister_global_hotkey()
    
    
    # ============================================================
    # System Tray
    # ============================================================
    
    def create_tray(app, window):
    
        icon_path = Path(sys.executable).parent / "nova.ico"
    
        tray = QSystemTrayIcon()
    
        if icon_path.exists():
            tray.setIcon(QIcon(str(icon_path)))
        else:
            tray.setIcon(app.style().standardIcon(
                app.style().SP_ComputerIcon
            ))
    
        tray.setToolTip("נובה — מרכז השליטה החכם")
    
        menu = QMenu()
    
        open_action = QAction("פתח את נובה", menu)
        open_action.triggered.connect(window.toggle_window)
    
        menu.addAction(open_action)
    
        menu.addSeparator()
    
        quit_action = QAction("יציאה מנובה", menu)
    
        def quit_app():
            window.cleanup()
            app.quit()
    
        quit_action.triggered.connect(quit_app)
    
        menu.addAction(quit_action)
    
        tray.setContextMenu(menu)
    
        tray.activated.connect(
            lambda reason: (
                window.toggle_window()
                if reason == QSystemTrayIcon.DoubleClick
                else None
            )
        )
    
        tray.show()
    
        return tray
    
    
    # ============================================================
    # Main
    # ============================================================
    
    def main():
    
        QApplication.setHighDpiScaleFactorRoundingPolicy(
            Qt.HighDpiScaleFactorRoundingPolicy.PassThrough
        )
    
        app = QApplication(sys.argv)
    
        app.setApplicationName("נובה")
        app.setApplicationDisplayName("נובה — מרכז השליטה החכם")
        app.setQuitOnLastWindowClosed(False)
    
        window = NovaWindow()
    
        tray = create_tray(app, window)
    
        # מתחילים פתוח בפעם הראשונה
        window.show()
        window.raise_()
        window.activateWindow()
    
        exit_code = app.exec()
    
        window.cleanup()
    
        sys.exit(exit_code)
    
    
    if __name__ == "__main__":
        main()
    '@ | Set-Content -Path $Py -Encoding UTF8
    
    # ------------------------------------------------------------
    # יצירת אייקון מקצועי באמצעות Pillow
    # ------------------------------------------------------------
    @'
    from PIL import Image, ImageDraw
    
    sizes = [16, 24, 32, 48, 64, 128, 256]
    
    images = []
    
    for size in sizes:
        img = Image.new("RGBA", (size, size), (11, 16, 32, 255))
        d = ImageDraw.Draw(img)
    
        # רקע מעוגל
        margin = max(1, size // 16)
    
        d.rounded_rectangle(
            (margin, margin, size-margin, size-margin),
            radius=max(3, size//5),
            fill=(20, 28, 50, 255),
            outline=(91, 112, 255, 255),
            width=max(1, size//32)
        )
    
        # סמל N / כוכב טכנולוגי
        cx = size // 2
        cy = size // 2
    
        pts = [
            (cx, int(size*0.17)),
            (int(size*0.66), int(size*0.39)),
            (int(size*0.84), int(size*0.30)),
            (int(size*0.73), int(size*0.55)),
            (int(size*0.83), int(size*0.80)),
            (int(size*0.62), int(size*0.64)),
            (int(size*0.38), int(size*0.83)),
            (int(size*0.26), int(size*0.59)),
            (int(size*0.16), int(size*0.70)),
            (int(size*0.27), int(size*0.43)),
        ]
    
        d.polygon(
            pts,
            fill=(106, 126, 255, 255)
        )
    
        # מרכז זוהר
        r = max(1, size // 11)
    
        d.ellipse(
            (cx-r, cy-r, cx+r, cy+r),
            fill=(236, 240, 255, 255)
        )
    
        images.append(img)
    
    images[0].save(
        "nova.ico",
        format="ICO",
        sizes=[(s, s) for s in sizes],
        append_images=images[1:]
    )
    '@ | Set-Content -Path (Join-Path $Src "make_icon.py") -Encoding UTF8
    
    # ------------------------------------------------------------
    # התקנת Build dependencies
    # ------------------------------------------------------------
    Write-Host ""
    Write-Host "מתקין את מנוע הממשק ואת כלי הבנייה..." -ForegroundColor Yellow
    
    & $Python -m pip install --upgrade pip --disable-pip-version-check
    
    if ($LASTEXITCODE -ne 0) {
        throw "עדכון pip נכשל."
    }
    
    & $Python -m pip install PySide6 Pillow PyInstaller --disable-pip-version-check
    
    if ($LASTEXITCODE -ne 0) {
        throw "התקנת התלויות נכשלה."
    }
    
    # ------------------------------------------------------------
    # יצירת אייקון
    # ------------------------------------------------------------
    Write-Host "יוצר אייקון..." -ForegroundColor Yellow
    
    Push-Location $Src
    
    & $Python "make_icon.py"
    
    if ($LASTEXITCODE -ne 0) {
        Pop-Location
        throw "יצירת האייקון נכשלה."
    }
    
    Pop-Location
    
    # ------------------------------------------------------------
    # Build
    # ------------------------------------------------------------
    Write-Host ""
    Write-Host "בונה את NOVA.EXE..." -ForegroundColor Yellow
    Write-Host "זה השלב הארוך ביותר." -ForegroundColor DarkGray
    
    # ניקוי Build קודם
    $BuildDir = Join-Path $Src "build"
    $SpecFile = Join-Path $Src "nova.spec"
    
    if (Test-Path $BuildDir) {
        Remove-Item $BuildDir -Recurse -Force
    }
    
    if (Test-Path $SpecFile) {
        Remove-Item $SpecFile -Force
    }
    
    if (Test-Path $Out) {
        Get-ChildItem $Out -Force | Remove-Item -Recurse -Force
    }
    
    Push-Location $Src
    
    & $Python -m PyInstaller `
        --noconfirm `
        --clean `
        --onefile `
        --windowed `
        --name "NOVA" `
        --icon "nova.ico" `
        --add-data "nova.ico;." `
        "nova.py"
    
    $BuildExit = $LASTEXITCODE
    
    Pop-Location
    
    if ($BuildExit -ne 0) {
        throw "בניית ה-EXE נכשלה."
    }
    
    # ------------------------------------------------------------
    # העתקה לתיקיית התוצאה
    # ------------------------------------------------------------
    $BuiltExe = Join-Path $Src "dist\NOVA.exe"
    $FinalExe = Join-Path $Out "NOVA.exe"
    
    if (-not (Test-Path $BuiltExe)) {
        throw "ה-EXE לא נוצר."
    }
    
    Copy-Item $BuiltExe $FinalExe -Force
    
    # ------------------------------------------------------------
    # יצירת README
    # ------------------------------------------------------------
    @'
    נובה — מרכז השליטה החכם
    ========================
    
    קובץ ההפעלה:
    NOVA.exe
    
    הפעלה:
    לחיצה כפולה על NOVA.exe
    
    קיצור דרך גלובלי:
    Ctrl + Space
    
    מה נובה יודעת לעשות:
    • חיפוש תוכנות
    • חיפוש קבצים בתיקיות נפוצות
    • פתיחת קבצים ותוכנות
    • פתיחת תיקיות Windows
    • היסטוריית לוח העתקות
    • חיפוש באינטרנט
    • פתיחת כתובות אינטרנט
    • עבודה ברקע דרך אזור ההתראות
    • קיצור דרך גלובלי לפתיחה מכל מקום
    
    הנתונים נשמרים מקומית במחשב.
    
    אין צורך להתקין Python כדי להריץ את NOVA.exe.
    '@ | Set-Content -Path (Join-Path $Out "README.txt") -Encoding UTF8
    
    # ------------------------------------------------------------
    # יצירת קיצור דרך על שולחן העבודה
    # ------------------------------------------------------------
    try {
    
        $WshShell = New-Object -ComObject WScript.Shell
    
        $ShortcutPath = Join-Path `
            ([Environment]::GetFolderPath("Desktop")) `
            "נובה.lnk"
    
        $Shortcut = $WshShell.CreateShortcut($ShortcutPath)
    
        $Shortcut.TargetPath = $FinalExe
        $Shortcut.WorkingDirectory = $Out
        $Shortcut.IconLocation = "$FinalExe,0"
        $Shortcut.Description = "נובה — מרכז השליטה החכם"
    
        $Shortcut.Save()
    
    }
    catch {
        Write-Host "לא ניתן היה ליצור קיצור דרך אוטומטי." -ForegroundColor DarkYellow
    }
    
    # ------------------------------------------------------------
    # סיום
    # ------------------------------------------------------------
    $SizeMB = [math]::Round(
        (Get-Item $FinalExe).Length / 1MB,
        1
    )
    
    Write-Host ""
    Write-Host "=============================================" -ForegroundColor Green
    Write-Host "              הבנייה הסתיימה!" -ForegroundColor Green
    Write-Host "=============================================" -ForegroundColor Green
    Write-Host ""
    Write-Host "ה-EXE המוכן נמצא כאן:" -ForegroundColor White
    Write-Host $FinalExe -ForegroundColor Cyan
    Write-Host ""
    Write-Host "גודל: $SizeMB MB" -ForegroundColor Gray
    Write-Host ""
    Write-Host "נוצר גם קיצור דרך 'נובה' על שולחן העבודה." -ForegroundColor Green
    Write-Host ""
    Write-Host "הפעל עכשיו את NOVA.exe." -ForegroundColor White
    Write-Host ""
    Write-Host "קיצור הדרך של התוכנה: Ctrl + Space" -ForegroundColor Cyan
    Write-Host ""
    
    # פתיחת תיקיית התוצאה
    Start-Process explorer.exe -ArgumentList "`"$Out`""
    
    # הפעלת התוכנה
    Start-Process -FilePath $FinalExe
    

    אבל מה שהכי מוזר ומעצבן
    זה שהם לא הביאו איזה משהו חדש ומעניין כל כך
    הם לא שברו את הכלים
    אם לי היה את הידע שלהם מזמן הייתי יוצר...
    ולא איזה לוח שנה עם תזכורות וכדו'

    או שזה בכלל היה בעיה בהנחיה שלי
    אז למישהו יש הנחיות יותר מאתגרים?

    A מנותק
    A מנותק
    AVIVI
    כתב נערך לאחרונה על ידי
    #9

    @YAHBDK האם ביקשת או נעזרת בהנחייה באחד מהמודלים?

    בעזרת השם נעשה ונצליח....

    Y תגובה 1 תגובה אחרונה
    0
    • Z ztcebuck

      @yahbdk איזה מודלים השתמשת בכל AI ובאיזה מצב?
      גימני תמיד הכי מהיר גם באנטיגרויטי הוא הכי מהיר

      Y מנותק
      Y מנותק
      YAHBDK
      כתב נערך לאחרונה על ידי
      #10

      @ztcebuck
      קלוד=אופוס 5
      גימיני=3.5 Flash-Lite
      פריבף=DeepSeek V4.1 Flash
      גיפיטי=אני לא יודע איפה בודקים

      Z י ב מ 5 תגובות תגובה אחרונה
      0
      • A AVIVI

        @YAHBDK האם ביקשת או נעזרת בהנחייה באחד מהמודלים?

        Y מנותק
        Y מנותק
        YAHBDK
        כתב נערך לאחרונה על ידי
        #11

        @AVIVI כתב:

        @YAHBDK האם ביקשת או נעזרת בהנחייה באחד מהמודלים?

        לא הבנתי את השאלה אתה שואל אם ביקשתי מאחד מהמודלים לכתוב לי את ההנחיות אז כן אבל לא מודל שזוכר בין שיחות או משהו דומה השתמשתי באיזה מודל סיני

        תגובה 1 תגובה אחרונה
        0
        • Y YAHBDK

          @ztcebuck
          קלוד=אופוס 5
          גימיני=3.5 Flash-Lite
          פריבף=DeepSeek V4.1 Flash
          גיפיטי=אני לא יודע איפה בודקים

          Z מנותק
          Z מנותק
          ztcebuck
          כתב נערך לאחרונה על ידי
          #12

          @YAHBDK אופוס 5 פי כמה טוב מגימיני 3.5 אז זה לא כ"כ כוחות

          תגובה 1 תגובה אחרונה
          0
          • Y YAHBDK

            המקום הרבעי גיפיטי

            אני עדיין מחכה☹️

            עריכה:
            שם התוכנה: „נובה” — מרכז השליטה החכם ל-Windows.
            נובה יושבת ברקע ונפתחת ב־Ctrl+Space: חיפוש מיידי של תוכנות וקבצים, היסטוריית לוח־העתקה, פעולות חכמות, פתיחת תיקיות/קישורים וחיפוש טבעי — הכול בממשק עברי מודרני.

            הקוד המלא [לא נבדק]

            $ErrorActionPreference = "Stop"
            
            # ============================================================
            # NOVA — נובה
            # Windows Smart Command Center
            # התקנה + יצירת קבצים + אייקון + Build ל-EXE בלחיצה אחת
            # ============================================================
            
            $Base = Join-Path $env:USERPROFILE "Desktop\NOVA"
            $Src  = Join-Path $Base "src"
            $Out  = Join-Path $Base "NOVA"
            $Py   = Join-Path $Src "nova.py"
            $Icon = Join-Path $Src "nova.ico"
            
            Write-Host ""
            Write-Host "=============================================" -ForegroundColor Cyan
            Write-Host "              NOVA / נובה" -ForegroundColor Cyan
            Write-Host "       מרכז השליטה החכם ל-Windows" -ForegroundColor White
            Write-Host "=============================================" -ForegroundColor Cyan
            Write-Host ""
            
            # ------------------------------------------------------------
            # מציאת Python
            # ------------------------------------------------------------
            $Python = $null
            
            $Candidates = @(
                "py",
                "python",
                "python3"
            )
            
            foreach ($cmd in $Candidates) {
                try {
                    $test = & $cmd --version 2>$null
                    if ($LASTEXITCODE -eq 0 -and $test -match "Python 3") {
                        $Python = $cmd
                        break
                    }
                } catch {}
            }
            
            if (-not $Python) {
                Write-Host "לא נמצא Python במחשב." -ForegroundColor Red
                Write-Host ""
                Write-Host "הסקריפט מנסה להתקין Python באופן אוטומטי..." -ForegroundColor Yellow
            
                try {
                    winget --version | Out-Null
                    winget install --id Python.Python.3.12 -e --source winget `
                        --accept-package-agreements `
                        --accept-source-agreements
            
                    $Python = "py"
                }
                catch {
                    Write-Host ""
                    Write-Host "לא ניתן להתקין Python באופן אוטומטי." -ForegroundColor Red
                    Write-Host "יש להתקין Python 3.11 ומעלה ואז להריץ את הבלוק שוב." -ForegroundColor Yellow
                    exit 1
                }
            }
            
            Write-Host "Python נמצא: $Python" -ForegroundColor Green
            
            # ------------------------------------------------------------
            # יצירת תיקיות
            # ------------------------------------------------------------
            New-Item -ItemType Directory -Force -Path $Base | Out-Null
            New-Item -ItemType Directory -Force -Path $Src  | Out-Null
            New-Item -ItemType Directory -Force -Path $Out  | Out-Null
            
            # ------------------------------------------------------------
            # יצירת קובץ התוכנה
            # ------------------------------------------------------------
            @'
            import sys
            import os
            import re
            import json
            import time
            import ctypes
            import shutil
            import subprocess
            import threading
            from pathlib import Path
            from urllib.parse import quote
            
            from PySide6.QtCore import (
                Qt, QTimer, Signal, QObject, QThread, QSize, QPoint
            )
            from PySide6.QtGui import (
                QAction, QIcon, QPixmap, QPainter, QColor, QFont,
                QKeySequence, QShortcut
            )
            from PySide6.QtWidgets import (
                QApplication, QWidget, QMainWindow, QVBoxLayout, QHBoxLayout,
                QLabel, QLineEdit, QListWidget, QListWidgetItem, QPushButton,
                QFrame, QSystemTrayIcon, QMenu, QMessageBox, QStackedWidget,
                QGraphicsDropShadowEffect
            )
            
            APP_NAME = "נובה"
            APP_VERSION = "1.0.0"
            
            APPDATA = Path(os.environ.get("APPDATA", Path.home()))
            DATA_DIR = APPDATA / "NOVA"
            DATA_DIR.mkdir(parents=True, exist_ok=True)
            
            CLIP_FILE = DATA_DIR / "clipboard.json"
            
            MAX_CLIPS = 60
            MAX_RESULTS = 40
            
            
            # ============================================================
            # עזרי Windows
            # ============================================================
            
            user32 = ctypes.windll.user32
            kernel32 = ctypes.windll.kernel32
            
            HOTKEY_ID = 7351
            WM_HOTKEY = 0x0312
            MOD_CONTROL = 0x0002
            MOD_SHIFT = 0x0004
            MOD_ALT = 0x0001
            VK_SPACE = 0x20
            
            
            def register_global_hotkey():
                try:
                    user32.RegisterHotKey(None, HOTKEY_ID, MOD_CONTROL, VK_SPACE)
                    return True
                except Exception:
                    return False
            
            
            def unregister_global_hotkey():
                try:
                    user32.UnregisterHotKey(None, HOTKEY_ID)
                except Exception:
                    pass
            
            
            def open_target(target):
                try:
                    os.startfile(str(target))
                    return True
                except Exception:
                    try:
                        subprocess.Popen([str(target)])
                        return True
                    except Exception:
                        return False
            
            
            def open_url(url):
                try:
                    os.startfile(url)
                    return True
                except Exception:
                    return False
            
            
            # ============================================================
            # Clipboard
            # ============================================================
            
            class ClipboardStore:
                def __init__(self):
                    self.items = []
                    self.load()
            
                def load(self):
                    try:
                        if CLIP_FILE.exists():
                            data = json.loads(CLIP_FILE.read_text(encoding="utf-8"))
                            if isinstance(data, list):
                                self.items = data[:MAX_CLIPS]
                    except Exception:
                        self.items = []
            
                def save(self):
                    try:
                        CLIP_FILE.write_text(
                            json.dumps(self.items, ensure_ascii=False, indent=2),
                            encoding="utf-8"
                        )
                    except Exception:
                        pass
            
                def add(self, text):
                    text = text.strip()
            
                    if not text:
                        return False
            
                    if len(text) > 10000:
                        text = text[:10000]
            
                    if self.items and self.items[0] == text:
                        return False
            
                    self.items = [x for x in self.items if x != text]
                    self.items.insert(0, text)
                    self.items = self.items[:MAX_CLIPS]
                    self.save()
                    return True
            
            
            # ============================================================
            # אינדקס תוכנות
            # ============================================================
            
            class SearchItem:
                def __init__(self, name, path, kind="file", extra=""):
                    self.name = name
                    self.path = path
                    self.kind = kind
                    self.extra = extra
            
            
            class SearchIndex(QObject):
                ready = Signal()
            
                def __init__(self):
                    super().__init__()
                    self.items = []
                    self.lock = threading.Lock()
            
                def build(self):
                    thread = threading.Thread(
                        target=self._build,
                        daemon=True
                    )
                    thread.start()
            
                def _add(self, name, path, kind, extra=""):
                    if not name or not path:
                        return
            
                    self.items.append(
                        SearchItem(name, path, kind, extra)
                    )
            
                def _build(self):
                    result = []
            
                    start_locations = []
            
                    appdata = os.environ.get("APPDATA")
                    programdata = os.environ.get("PROGRAMDATA")
                    userprofile = os.environ.get("USERPROFILE")
            
                    if appdata:
                        start_locations.append(
                            Path(appdata) / "Microsoft/Windows/Start Menu/Programs"
                        )
            
                    if programdata:
                        start_locations.append(
                            Path(programdata) / "Microsoft/Windows/Start Menu/Programs"
                        )
            
                    desktop = Path(userprofile) / "Desktop"
            
                    # תוכנות מתפריט התחל
                    for root in start_locations:
                        try:
                            if not root.exists():
                                continue
            
                            for p in root.rglob("*.lnk"):
                                try:
                                    result.append(
                                        SearchItem(
                                            p.stem,
                                            str(p),
                                            "app",
                                            "תוכנה"
                                        )
                                    )
                                except Exception:
                                    pass
            
                            for p in root.rglob("*.exe"):
                                try:
                                    result.append(
                                        SearchItem(
                                            p.stem,
                                            str(p),
                                            "app",
                                            "תוכנה"
                                        )
                                    )
                                except Exception:
                                    pass
            
                        except Exception:
                            pass
            
                    # קיצורי דרך בשולחן העבודה
                    try:
                        if desktop.exists():
                            for p in desktop.iterdir():
                                if p.suffix.lower() in (".lnk", ".exe", ".url"):
                                    result.append(
                                        SearchItem(
                                            p.stem,
                                            str(p),
                                            "app" if p.suffix.lower() != ".url" else "url",
                                            "שולחן העבודה"
                                        )
                                    )
                    except Exception:
                        pass
            
                    # תיקיות נפוצות
                    folders = [
                        ("שולחן העבודה", Path(userprofile) / "Desktop"),
                        ("הורדות", Path(userprofile) / "Downloads"),
                        ("מסמכים", Path(userprofile) / "Documents"),
                        ("תמונות", Path(userprofile) / "Pictures"),
                        ("וידאו", Path(userprofile) / "Videos"),
                    ]
            
                    allowed = {
                        ".pdf", ".doc", ".docx", ".xls", ".xlsx",
                        ".ppt", ".pptx", ".txt", ".csv",
                        ".jpg", ".jpeg", ".png", ".gif", ".webp",
                        ".mp4", ".mkv", ".avi", ".mp3", ".wav",
                        ".zip", ".rar", ".7z",
                        ".py", ".ps1", ".bat", ".json"
                    }
            
                    for label, folder in folders:
                        try:
                            if not folder.exists():
                                continue
            
                            count = 0
            
                            for p in folder.rglob("*"):
                                try:
                                    if not p.is_file():
                                        continue
            
                                    if p.suffix.lower() not in allowed:
                                        continue
            
                                    result.append(
                                        SearchItem(
                                            p.name,
                                            str(p),
                                            "file",
                                            label
                                        )
                                    )
            
                                    count += 1
            
                                    # מונע אינדקס עצום במחשבים עמוסים
                                    if count >= 3500:
                                        break
            
                                except Exception:
                                    pass
            
                        except Exception:
                            pass
            
                    # הסרת כפילויות
                    unique = {}
                    for item in result:
                        key = item.path.lower()
            
                        if key not in unique:
                            unique[key] = item
            
                    with self.lock:
                        self.items = list(unique.values())
            
                    self.ready.emit()
            
            
            # ============================================================
            # חיפוש חכם
            # ============================================================
            
            def score_text(query, text):
                q = query.lower().strip()
                t = text.lower()
            
                if not q:
                    return 0
            
                if t == q:
                    return 1000
            
                if t.startswith(q):
                    return 800
            
                if q in t:
                    return 600
            
                # התאמה לפי מילים
                words = [x for x in re.split(r"\s+", q) if x]
            
                score = 0
            
                for word in words:
                    if word in t:
                        score += 150
            
                # התאמת אותיות עוקבות
                pos = 0
                matched = 0
            
                for char in q:
                    idx = t.find(char, pos)
            
                    if idx >= 0:
                        matched += 1
                        pos = idx + 1
            
                if matched:
                    score += int((matched / len(q)) * 100)
            
                return score
            
            
            # ============================================================
            # כרטיס תוצאה
            # ============================================================
            
            class ResultRow(QFrame):
                clicked = Signal(object)
            
                def __init__(self, item, parent=None):
                    super().__init__(parent)
                    self.item = item
            
                    self.setObjectName("resultRow")
                    self.setCursor(Qt.PointingHandCursor)
            
                    layout = QHBoxLayout(self)
                    layout.setContentsMargins(16, 11, 16, 11)
                    layout.setSpacing(12)
            
                    icon = QLabel()
            
                    icon_text = {
                        "app": "▣",
                        "file": "▤",
                        "url": "↗",
                        "action": "✦",
                        "clipboard": "⧉"
                    }.get(item.kind, "•")
            
                    icon.setText(icon_text)
                    icon.setObjectName("resultIcon")
                    icon.setFixedWidth(30)
            
                    text_box = QVBoxLayout()
                    text_box.setSpacing(2)
            
                    title = QLabel(item.name)
                    title.setObjectName("resultTitle")
            
                    subtitle = QLabel(item.extra or item.path)
                    subtitle.setObjectName("resultSub")
                    subtitle.setTextInteractionFlags(Qt.NoTextInteraction)
            
                    text_box.addWidget(title)
                    text_box.addWidget(subtitle)
            
                    layout.addWidget(icon)
                    layout.addLayout(text_box, 1)
            
                    arrow = QLabel("‹")
                    arrow.setObjectName("resultArrow")
                    layout.addWidget(arrow)
            
                def mousePressEvent(self, event):
                    if event.button() == Qt.LeftButton:
                        self.clicked.emit(self.item)
            
                    super().mousePressEvent(event)
            
            
            # ============================================================
            # התוכנה
            # ============================================================
            
            class NovaWindow(QMainWindow):
            
                def __init__(self):
                    super().__init__()
            
                    self.clipboard_store = ClipboardStore()
                    self.index = SearchIndex()
            
                    self.index.ready.connect(self.index_ready)
            
                    self.all_results = []
                    self.selected_index = 0
                    self.hotkey_registered = False
            
                    self.setWindowTitle("נובה — מרכז השליטה")
                    self.setWindowIcon(QIcon(str(Path(sys.executable).parent / "nova.ico")))
            
                    self.setMinimumSize(760, 560)
                    self.resize(860, 650)
            
                    self.setAttribute(Qt.WA_DeleteOnClose, False)
            
                    self.build_ui()
                    self.install_global_hotkey_handler()
            
                    self.index.build()
            
                    # מעקב לוח
                    self.clipboard_timer = QTimer(self)
                    self.clipboard_timer.timeout.connect(self.check_clipboard)
                    self.clipboard_timer.start(450)
            
                    # עדכון סטטוס
                    self.status_timer = QTimer(self)
                    self.status_timer.timeout.connect(self.update_status)
                    self.status_timer.start(1000)
            
                    self.search_edit.setFocus()
            
                # --------------------------------------------------------
                # UI
                # --------------------------------------------------------
            
                def build_ui(self):
            
                    root = QWidget()
                    root.setObjectName("root")
                    self.setCentralWidget(root)
            
                    main = QVBoxLayout(root)
                    main.setContentsMargins(28, 25, 28, 20)
                    main.setSpacing(16)
            
                    # Header
                    header = QHBoxLayout()
            
                    brand_box = QVBoxLayout()
                    brand_box.setSpacing(0)
            
                    brand = QLabel("נובה")
                    brand.setObjectName("brand")
            
                    subtitle = QLabel("מרכז השליטה החכם שלך")
                    subtitle.setObjectName("subtitle")
            
                    brand_box.addWidget(brand)
                    brand_box.addWidget(subtitle)
            
                    header.addLayout(brand_box)
                    header.addStretch()
            
                    status = QLabel("● פעילה")
                    status.setObjectName("onlineStatus")
            
                    header.addWidget(status)
            
                    main.addLayout(header)
            
                    # Search
                    search_frame = QFrame()
                    search_frame.setObjectName("searchFrame")
            
                    search_layout = QHBoxLayout(search_frame)
                    search_layout.setContentsMargins(18, 5, 18, 5)
            
                    search_icon = QLabel("⌕")
                    search_icon.setObjectName("searchIcon")
            
                    self.search_edit = QLineEdit()
                    self.search_edit.setPlaceholderText(
                        "חפש תוכנה, קובץ, פעולה או כתובת..."
                    )
                    self.search_edit.setClearButtonEnabled(True)
                    self.search_edit.setObjectName("searchEdit")
            
                    search_layout.addWidget(search_icon)
                    search_layout.addWidget(self.search_edit)
            
                    main.addWidget(search_frame)
            
                    self.search_edit.textChanged.connect(self.perform_search)
                    self.search_edit.returnPressed.connect(self.activate_selected)
            
                    # Hint
                    hint = QLabel(
                        "Ctrl+Space לפתיחה מכל מקום  •  Enter לפתיחה  •  Esc להסתרה"
                    )
                    hint.setObjectName("hint")
                    hint.setAlignment(Qt.AlignCenter)
            
                    main.addWidget(hint)
            
                    # Content
                    content = QHBoxLayout()
                    content.setSpacing(14)
            
                    # Results
                    result_panel = QFrame()
                    result_panel.setObjectName("panel")
            
                    result_layout = QVBoxLayout(result_panel)
                    result_layout.setContentsMargins(15, 15, 15, 15)
                    result_layout.setSpacing(9)
            
                    title_row = QHBoxLayout()
            
                    self.results_title = QLabel("גישה מהירה")
                    self.results_title.setObjectName("sectionTitle")
            
                    self.results_count = QLabel("")
                    self.results_count.setObjectName("count")
            
                    title_row.addWidget(self.results_title)
                    title_row.addStretch()
                    title_row.addWidget(self.results_count)
            
                    result_layout.addLayout(title_row)
            
                    self.results = QVBoxLayout()
                    self.results.setSpacing(7)
            
                    result_layout.addLayout(self.results)
                    result_layout.addStretch()
            
                    content.addWidget(result_panel, 3)
            
                    # Sidebar
                    side = QFrame()
                    side.setObjectName("sidePanel")
            
                    side_layout = QVBoxLayout(side)
                    side_layout.setContentsMargins(14, 14, 14, 14)
                    side_layout.setSpacing(9)
            
                    side_title = QLabel("פעולות מהירות")
                    side_title.setObjectName("sectionTitle")
                    side_layout.addWidget(side_title)
            
                    actions = [
                        ("📋", "לוח ההעתקות", self.show_clipboard),
                        ("📁", "פתח הורדות", self.open_downloads),
                        ("🖥", "מחשב זה", self.open_computer),
                        ("⚙", "הגדרות Windows", self.open_settings),
                        ("🌐", "חיפוש באינטרנט", self.web_search),
                    ]
            
                    for icon, text, callback in actions:
                        btn = QPushButton(f"{icon}   {text}")
                        btn.setObjectName("actionButton")
                        btn.setCursor(Qt.PointingHandCursor)
                        btn.clicked.connect(callback)
                        side_layout.addWidget(btn)
            
                    side_layout.addStretch()
            
                    info = QLabel(
                        "נובה עובדת ברקע.\n"
                        "אין צורך להשאיר את החלון פתוח.\n\n"
                        "הנתונים המקומיים נשמרים\n"
                        "במחשב שלך."
                    )
                    info.setObjectName("info")
                    info.setWordWrap(True)
            
                    side_layout.addWidget(info)
            
                    content.addWidget(side, 1)
            
                    main.addLayout(content, 1)
            
                    # Footer
                    footer = QHBoxLayout()
            
                    self.status_label = QLabel("מאתחל אינדקס...")
                    self.status_label.setObjectName("footer")
            
                    footer.addWidget(self.status_label)
                    footer.addStretch()
            
                    version = QLabel(f"נובה {APP_VERSION}")
                    version.setObjectName("footer")
            
                    footer.addWidget(version)
            
                    main.addLayout(footer)
            
                    self.apply_style()
            
                # --------------------------------------------------------
                # Style
                # --------------------------------------------------------
            
                def apply_style(self):
                    self.setStyleSheet("""
                    * {
                        font-family: "Segoe UI";
                    }
            
                    QMainWindow, QWidget#root {
                        background: #0b1020;
                        color: #edf2ff;
                    }
            
                    QLabel {
                        color: #edf2ff;
                    }
            
                    QLabel#brand {
                        font-size: 31px;
                        font-weight: 800;
                        color: #ffffff;
                    }
            
                    QLabel#subtitle {
                        font-size: 13px;
                        color: #8792ad;
                    }
            
                    QLabel#onlineStatus {
                        background: #112a25;
                        color: #55e6b1;
                        border: 1px solid #1c5547;
                        border-radius: 15px;
                        padding: 6px 12px;
                        font-size: 12px;
                        font-weight: 600;
                    }
            
                    QFrame#searchFrame {
                        background: #141b31;
                        border: 1px solid #273253;
                        border-radius: 17px;
                    }
            
                    QFrame#searchFrame:focus-within {
                        border: 1px solid #6077ff;
                    }
            
                    QLabel#searchIcon {
                        font-size: 29px;
                        color: #7185ff;
                        padding-bottom: 2px;
                    }
            
                    QLineEdit#searchEdit {
                        background: transparent;
                        border: none;
                        color: #ffffff;
                        font-size: 18px;
                        padding: 11px 4px;
                        selection-background-color: #4f61d8;
                    }
            
                    QLabel#hint {
                        color: #68738e;
                        font-size: 11px;
                    }
            
                    QFrame#panel {
                        background: #10172a;
                        border: 1px solid #1e2943;
                        border-radius: 17px;
                    }
            
                    QFrame#sidePanel {
                        background: #10172a;
                        border: 1px solid #1e2943;
                        border-radius: 17px;
                    }
            
                    QLabel#sectionTitle {
                        color: #ffffff;
                        font-size: 14px;
                        font-weight: 700;
                    }
            
                    QLabel#count {
                        color: #68738e;
                        font-size: 11px;
                    }
            
                    QFrame#resultRow {
                        background: #151d33;
                        border: 1px solid transparent;
                        border-radius: 12px;
                    }
            
                    QFrame#resultRow:hover {
                        background: #1b2642;
                        border: 1px solid #34436b;
                    }
            
                    QLabel#resultIcon {
                        color: #7185ff;
                        font-size: 21px;
                        font-weight: bold;
                    }
            
                    QLabel#resultTitle {
                        color: #f4f6ff;
                        font-size: 13px;
                        font-weight: 600;
                    }
            
                    QLabel#resultSub {
                        color: #687690;
                        font-size: 10px;
                    }
            
                    QLabel#resultArrow {
                        color: #52607d;
                        font-size: 21px;
                    }
            
                    QPushButton#actionButton {
                        text-align: right;
                        background: #151d33;
                        border: 1px solid #222e4a;
                        border-radius: 11px;
                        color: #dbe2f6;
                        padding: 12px 11px;
                        font-size: 12px;
                    }
            
                    QPushButton#actionButton:hover {
                        background: #1d2948;
                        border: 1px solid #394b7a;
                    }
            
                    QPushButton#actionButton:pressed {
                        background: #11182b;
                    }
            
                    QLabel#info {
                        color: #626e89;
                        background: #0d1426;
                        border-radius: 10px;
                        padding: 12px;
                        font-size: 10px;
                    }
            
                    QLabel#footer {
                        color: #59657f;
                        font-size: 10px;
                    }
                    """)
            
                # --------------------------------------------------------
                # חיפוש
                # --------------------------------------------------------
            
                def clear_results(self):
                    while self.results.count():
                        item = self.results.takeAt(0)
                        widget = item.widget()
            
                        if widget:
                            widget.deleteLater()
            
                def perform_search(self, query):
            
                    query = query.strip()
            
                    self.clear_results()
            
                    if not query:
                        self.results_title.setText("גישה מהירה")
            
                        quick = [
                            SearchItem(
                                "לוח ההעתקות",
                                "",
                                "clipboard",
                                "העתקות אחרונות"
                            ),
                            SearchItem(
                                "פתח הורדות",
                                "",
                                "action",
                                "תיקיית ההורדות"
                            ),
                            SearchItem(
                                "מחשב זה",
                                "",
                                "action",
                                "סייר הקבצים"
                            ),
                            SearchItem(
                                "הגדרות Windows",
                                "",
                                "action",
                                "הגדרות מערכת"
                            )
                        ]
            
                        self.all_results = quick
            
                        for item in quick:
                            row = ResultRow(item)
                            row.clicked.connect(self.activate_item)
                            self.results.addWidget(row)
            
                        self.results_count.setText("גישה מהירה")
                        return
            
                    self.results_title.setText("תוצאות")
            
                    results = []
            
                    # פקודות חכמות
                    normalized = query.lower()
            
                    if normalized.startswith("פתח "):
                        target = query[5:].strip()
            
                        candidates = [
                            ("הורדות", Path.home() / "Downloads"),
                            ("מסמכים", Path.home() / "Documents"),
                            ("שולחן העבודה", Path.home() / "Desktop"),
                            ("תמונות", Path.home() / "Pictures"),
                            ("וידאו", Path.home() / "Videos"),
                        ]
            
                        for name, path in candidates:
                            if target in name or name in target:
                                results.append(
                                    SearchItem(
                                        f"פתח {name}",
                                        str(path),
                                        "action",
                                        str(path)
                                    )
                                )
            
                    # URL
                    if re.match(r"^(https?://|www\.)", query, re.I):
                        url = query
            
                        if url.startswith("www."):
                            url = "https://" + url
            
                        results.append(
                            SearchItem(
                                "פתח כתובת",
                                url,
                                "url",
                                url
                            )
                        )
            
                    # חיפוש באינטרנט
                    if normalized.startswith("חפש "):
                        text = query[5:].strip()
            
                        if text:
                            url = (
                                "https://www.google.com/search?q="
                                + quote(text)
                            )
            
                            results.append(
                                SearchItem(
                                    "חפש באינטרנט",
                                    url,
                                    "url",
                                    text
                                )
                            )
            
                    # לוח העתקות
                    if normalized in (
                        "לוח",
                        "העתקות",
                        "לוח העתקות",
                        "clipboard"
                    ):
                        for i, text in enumerate(self.clipboard_store.items[:10]):
                            short = text.replace("\n", " ")
            
                            if len(short) > 80:
                                short = short[:80] + "..."
            
                            results.append(
                                SearchItem(
                                    short,
                                    text,
                                    "clipboard",
                                    "לחץ כדי להעתיק"
                                )
                            )
            
                    # אינדקס
                    with self.index.lock:
                        indexed = list(self.index.items)
            
                    scored = []
            
                    for item in indexed:
                        s = max(
                            score_text(query, item.name),
                            score_text(query, Path(item.path).name)
                        )
            
                        if s > 0:
                            scored.append((s, item))
            
                    scored.sort(
                        key=lambda x: (
                            -x[0],
                            x[1].name.lower()
                        )
                    )
            
                    results.extend(
                        [item for _, item in scored[:MAX_RESULTS]]
                    )
            
                    self.all_results = results[:MAX_RESULTS]
            
                    if not self.all_results:
                        empty = QLabel(
                            "לא מצאתי תוצאה מתאימה.\n\n"
                            "אפשר לנסות שם תוכנה, שם קובץ,\n"
                            "כתובת אינטרנט או \"חפש ...\"."
                        )
            
                        empty.setAlignment(Qt.AlignCenter)
                        empty.setObjectName("info")
                        empty.setMinimumHeight(130)
            
                        self.results.addWidget(empty)
            
                        self.results_count.setText("0 תוצאות")
                        return
            
                    for item in self.all_results:
                        row = ResultRow(item)
                        row.clicked.connect(self.activate_item)
                        self.results.addWidget(row)
            
                    self.results_count.setText(
                        f"{len(self.all_results)} תוצאות"
                    )
            
                # --------------------------------------------------------
                # פעולות
                # --------------------------------------------------------
            
                def activate_selected(self):
                    if self.all_results:
                        self.activate_item(self.all_results[0])
            
                def activate_item(self, item):
            
                    if item.kind == "clipboard":
                        QApplication.clipboard().setText(item.path)
                        self.status_label.setText("הטקסט הועתק ללוח")
                        self.hide()
                        return
            
                    if item.kind == "action":
                        if item.name == "פתח הורדות":
                            self.open_downloads()
                        elif item.name == "מחשב זה":
                            self.open_computer()
                        elif item.name == "הגדרות Windows":
                            self.open_settings()
                        elif item.name == "לוח ההעתקות":
                            self.show_clipboard()
                        else:
                            open_target(item.path)
            
                        return
            
                    if item.kind == "url":
                        open_url(item.path)
                        self.hide()
                        return
            
                    if item.kind in ("app", "file"):
                        open_target(item.path)
                        self.hide()
                        return
            
                    open_target(item.path)
                    self.hide()
            
                def show_clipboard(self):
                    self.search_edit.setText("לוח")
                    self.search_edit.setFocus()
                    self.show()
                    self.raise_()
                    self.activateWindow()
            
                def open_downloads(self):
                    open_target(Path.home() / "Downloads")
                    self.hide()
            
                def open_computer(self):
                    try:
                        subprocess.Popen("explorer.exe shell:MyComputerFolder")
                    except Exception:
                        pass
                    self.hide()
            
                def open_settings(self):
                    try:
                        subprocess.Popen(
                            "start ms-settings:",
                            shell=True
                        )
                    except Exception:
                        pass
                    self.hide()
            
                def web_search(self):
                    text = self.search_edit.text().strip()
            
                    if not text:
                        text = "חיפוש"
            
                    url = (
                        "https://www.google.com/search?q="
                        + quote(text)
                    )
            
                    open_url(url)
                    self.hide()
            
                # --------------------------------------------------------
                # Clipboard monitor
                # --------------------------------------------------------
            
                def check_clipboard(self):
                    try:
                        text = QApplication.clipboard().text()
            
                        if text and text.strip():
                            changed = self.clipboard_store.add(text)
            
                            if changed and self.isVisible():
                                if self.search_edit.text().strip() == "לוח":
                                    self.perform_search("לוח")
            
                    except Exception:
                        pass
            
                # --------------------------------------------------------
                # אינדקס
                # --------------------------------------------------------
            
                def index_ready(self):
                    count = len(self.index.items)
            
                    self.status_label.setText(
                        f"האינדקס מוכן • {count:,} פריטים זמינים לחיפוש"
                    )
            
                    if not self.search_edit.text().strip():
                        self.perform_search("")
            
                def update_status(self):
                    if not self.index.items:
                        self.status_label.setText("בונה אינדקס...")
            
                # --------------------------------------------------------
                # Global Hotkey
                # --------------------------------------------------------
            
                def install_global_hotkey_handler(self):
            
                    self.hotkey_registered = register_global_hotkey()
            
                    timer = QTimer(self)
                    timer.timeout.connect(self.poll_windows_messages)
                    timer.start(80)
            
                    self.hotkey_timer = timer
            
                def poll_windows_messages(self):
            
                    msg = ctypes.wintypes.MSG()
            
                    try:
                        while user32.PeekMessageW(
                            ctypes.byref(msg),
                            None,
                            WM_HOTKEY,
                            WM_HOTKEY,
                            1
                        ):
                            if msg.message == WM_HOTKEY:
                                self.toggle_window()
            
                    except Exception:
                        pass
            
                def toggle_window(self):
            
                    if self.isVisible() and self.isActiveWindow():
                        self.hide()
                        return
            
                    self.show()
                    self.raise_()
                    self.activateWindow()
                    self.search_edit.setFocus()
                    self.search_edit.selectAll()
            
                # --------------------------------------------------------
                # Keyboard
                # --------------------------------------------------------
            
                def keyPressEvent(self, event):
            
                    if event.key() == Qt.Key_Escape:
                        self.hide()
                        event.accept()
                        return
            
                    if event.key() in (
                        Qt.Key_Return,
                        Qt.Key_Enter
                    ):
                        self.activate_selected()
                        event.accept()
                        return
            
                    super().keyPressEvent(event)
            
                # --------------------------------------------------------
                # Close = hide to tray
                # --------------------------------------------------------
            
                def closeEvent(self, event):
                    event.ignore()
                    self.hide()
            
                def cleanup(self):
                    unregister_global_hotkey()
            
            
            # ============================================================
            # System Tray
            # ============================================================
            
            def create_tray(app, window):
            
                icon_path = Path(sys.executable).parent / "nova.ico"
            
                tray = QSystemTrayIcon()
            
                if icon_path.exists():
                    tray.setIcon(QIcon(str(icon_path)))
                else:
                    tray.setIcon(app.style().standardIcon(
                        app.style().SP_ComputerIcon
                    ))
            
                tray.setToolTip("נובה — מרכז השליטה החכם")
            
                menu = QMenu()
            
                open_action = QAction("פתח את נובה", menu)
                open_action.triggered.connect(window.toggle_window)
            
                menu.addAction(open_action)
            
                menu.addSeparator()
            
                quit_action = QAction("יציאה מנובה", menu)
            
                def quit_app():
                    window.cleanup()
                    app.quit()
            
                quit_action.triggered.connect(quit_app)
            
                menu.addAction(quit_action)
            
                tray.setContextMenu(menu)
            
                tray.activated.connect(
                    lambda reason: (
                        window.toggle_window()
                        if reason == QSystemTrayIcon.DoubleClick
                        else None
                    )
                )
            
                tray.show()
            
                return tray
            
            
            # ============================================================
            # Main
            # ============================================================
            
            def main():
            
                QApplication.setHighDpiScaleFactorRoundingPolicy(
                    Qt.HighDpiScaleFactorRoundingPolicy.PassThrough
                )
            
                app = QApplication(sys.argv)
            
                app.setApplicationName("נובה")
                app.setApplicationDisplayName("נובה — מרכז השליטה החכם")
                app.setQuitOnLastWindowClosed(False)
            
                window = NovaWindow()
            
                tray = create_tray(app, window)
            
                # מתחילים פתוח בפעם הראשונה
                window.show()
                window.raise_()
                window.activateWindow()
            
                exit_code = app.exec()
            
                window.cleanup()
            
                sys.exit(exit_code)
            
            
            if __name__ == "__main__":
                main()
            '@ | Set-Content -Path $Py -Encoding UTF8
            
            # ------------------------------------------------------------
            # יצירת אייקון מקצועי באמצעות Pillow
            # ------------------------------------------------------------
            @'
            from PIL import Image, ImageDraw
            
            sizes = [16, 24, 32, 48, 64, 128, 256]
            
            images = []
            
            for size in sizes:
                img = Image.new("RGBA", (size, size), (11, 16, 32, 255))
                d = ImageDraw.Draw(img)
            
                # רקע מעוגל
                margin = max(1, size // 16)
            
                d.rounded_rectangle(
                    (margin, margin, size-margin, size-margin),
                    radius=max(3, size//5),
                    fill=(20, 28, 50, 255),
                    outline=(91, 112, 255, 255),
                    width=max(1, size//32)
                )
            
                # סמל N / כוכב טכנולוגי
                cx = size // 2
                cy = size // 2
            
                pts = [
                    (cx, int(size*0.17)),
                    (int(size*0.66), int(size*0.39)),
                    (int(size*0.84), int(size*0.30)),
                    (int(size*0.73), int(size*0.55)),
                    (int(size*0.83), int(size*0.80)),
                    (int(size*0.62), int(size*0.64)),
                    (int(size*0.38), int(size*0.83)),
                    (int(size*0.26), int(size*0.59)),
                    (int(size*0.16), int(size*0.70)),
                    (int(size*0.27), int(size*0.43)),
                ]
            
                d.polygon(
                    pts,
                    fill=(106, 126, 255, 255)
                )
            
                # מרכז זוהר
                r = max(1, size // 11)
            
                d.ellipse(
                    (cx-r, cy-r, cx+r, cy+r),
                    fill=(236, 240, 255, 255)
                )
            
                images.append(img)
            
            images[0].save(
                "nova.ico",
                format="ICO",
                sizes=[(s, s) for s in sizes],
                append_images=images[1:]
            )
            '@ | Set-Content -Path (Join-Path $Src "make_icon.py") -Encoding UTF8
            
            # ------------------------------------------------------------
            # התקנת Build dependencies
            # ------------------------------------------------------------
            Write-Host ""
            Write-Host "מתקין את מנוע הממשק ואת כלי הבנייה..." -ForegroundColor Yellow
            
            & $Python -m pip install --upgrade pip --disable-pip-version-check
            
            if ($LASTEXITCODE -ne 0) {
                throw "עדכון pip נכשל."
            }
            
            & $Python -m pip install PySide6 Pillow PyInstaller --disable-pip-version-check
            
            if ($LASTEXITCODE -ne 0) {
                throw "התקנת התלויות נכשלה."
            }
            
            # ------------------------------------------------------------
            # יצירת אייקון
            # ------------------------------------------------------------
            Write-Host "יוצר אייקון..." -ForegroundColor Yellow
            
            Push-Location $Src
            
            & $Python "make_icon.py"
            
            if ($LASTEXITCODE -ne 0) {
                Pop-Location
                throw "יצירת האייקון נכשלה."
            }
            
            Pop-Location
            
            # ------------------------------------------------------------
            # Build
            # ------------------------------------------------------------
            Write-Host ""
            Write-Host "בונה את NOVA.EXE..." -ForegroundColor Yellow
            Write-Host "זה השלב הארוך ביותר." -ForegroundColor DarkGray
            
            # ניקוי Build קודם
            $BuildDir = Join-Path $Src "build"
            $SpecFile = Join-Path $Src "nova.spec"
            
            if (Test-Path $BuildDir) {
                Remove-Item $BuildDir -Recurse -Force
            }
            
            if (Test-Path $SpecFile) {
                Remove-Item $SpecFile -Force
            }
            
            if (Test-Path $Out) {
                Get-ChildItem $Out -Force | Remove-Item -Recurse -Force
            }
            
            Push-Location $Src
            
            & $Python -m PyInstaller `
                --noconfirm `
                --clean `
                --onefile `
                --windowed `
                --name "NOVA" `
                --icon "nova.ico" `
                --add-data "nova.ico;." `
                "nova.py"
            
            $BuildExit = $LASTEXITCODE
            
            Pop-Location
            
            if ($BuildExit -ne 0) {
                throw "בניית ה-EXE נכשלה."
            }
            
            # ------------------------------------------------------------
            # העתקה לתיקיית התוצאה
            # ------------------------------------------------------------
            $BuiltExe = Join-Path $Src "dist\NOVA.exe"
            $FinalExe = Join-Path $Out "NOVA.exe"
            
            if (-not (Test-Path $BuiltExe)) {
                throw "ה-EXE לא נוצר."
            }
            
            Copy-Item $BuiltExe $FinalExe -Force
            
            # ------------------------------------------------------------
            # יצירת README
            # ------------------------------------------------------------
            @'
            נובה — מרכז השליטה החכם
            ========================
            
            קובץ ההפעלה:
            NOVA.exe
            
            הפעלה:
            לחיצה כפולה על NOVA.exe
            
            קיצור דרך גלובלי:
            Ctrl + Space
            
            מה נובה יודעת לעשות:
            • חיפוש תוכנות
            • חיפוש קבצים בתיקיות נפוצות
            • פתיחת קבצים ותוכנות
            • פתיחת תיקיות Windows
            • היסטוריית לוח העתקות
            • חיפוש באינטרנט
            • פתיחת כתובות אינטרנט
            • עבודה ברקע דרך אזור ההתראות
            • קיצור דרך גלובלי לפתיחה מכל מקום
            
            הנתונים נשמרים מקומית במחשב.
            
            אין צורך להתקין Python כדי להריץ את NOVA.exe.
            '@ | Set-Content -Path (Join-Path $Out "README.txt") -Encoding UTF8
            
            # ------------------------------------------------------------
            # יצירת קיצור דרך על שולחן העבודה
            # ------------------------------------------------------------
            try {
            
                $WshShell = New-Object -ComObject WScript.Shell
            
                $ShortcutPath = Join-Path `
                    ([Environment]::GetFolderPath("Desktop")) `
                    "נובה.lnk"
            
                $Shortcut = $WshShell.CreateShortcut($ShortcutPath)
            
                $Shortcut.TargetPath = $FinalExe
                $Shortcut.WorkingDirectory = $Out
                $Shortcut.IconLocation = "$FinalExe,0"
                $Shortcut.Description = "נובה — מרכז השליטה החכם"
            
                $Shortcut.Save()
            
            }
            catch {
                Write-Host "לא ניתן היה ליצור קיצור דרך אוטומטי." -ForegroundColor DarkYellow
            }
            
            # ------------------------------------------------------------
            # סיום
            # ------------------------------------------------------------
            $SizeMB = [math]::Round(
                (Get-Item $FinalExe).Length / 1MB,
                1
            )
            
            Write-Host ""
            Write-Host "=============================================" -ForegroundColor Green
            Write-Host "              הבנייה הסתיימה!" -ForegroundColor Green
            Write-Host "=============================================" -ForegroundColor Green
            Write-Host ""
            Write-Host "ה-EXE המוכן נמצא כאן:" -ForegroundColor White
            Write-Host $FinalExe -ForegroundColor Cyan
            Write-Host ""
            Write-Host "גודל: $SizeMB MB" -ForegroundColor Gray
            Write-Host ""
            Write-Host "נוצר גם קיצור דרך 'נובה' על שולחן העבודה." -ForegroundColor Green
            Write-Host ""
            Write-Host "הפעל עכשיו את NOVA.exe." -ForegroundColor White
            Write-Host ""
            Write-Host "קיצור הדרך של התוכנה: Ctrl + Space" -ForegroundColor Cyan
            Write-Host ""
            
            # פתיחת תיקיית התוצאה
            Start-Process explorer.exe -ArgumentList "`"$Out`""
            
            # הפעלת התוכנה
            Start-Process -FilePath $FinalExe
            

            אבל מה שהכי מוזר ומעצבן
            זה שהם לא הביאו איזה משהו חדש ומעניין כל כך
            הם לא שברו את הכלים
            אם לי היה את הידע שלהם מזמן הייתי יוצר...
            ולא איזה לוח שנה עם תזכורות וכדו'

            או שזה בכלל היה בעיה בהנחיה שלי
            אז למישהו יש הנחיות יותר מאתגרים?

            Y מנותק
            Y מנותק
            YAHBDK
            כתב נערך לאחרונה על ידי
            #13

            גיפיטי נזכר לענות אפשר לעיין כאן

            תגובה 1 תגובה אחרונה
            0
            • Y YAHBDK

              המקום הרבעי גיפיטי

              אני עדיין מחכה☹️

              עריכה:
              שם התוכנה: „נובה” — מרכז השליטה החכם ל-Windows.
              נובה יושבת ברקע ונפתחת ב־Ctrl+Space: חיפוש מיידי של תוכנות וקבצים, היסטוריית לוח־העתקה, פעולות חכמות, פתיחת תיקיות/קישורים וחיפוש טבעי — הכול בממשק עברי מודרני.

              הקוד המלא [לא נבדק]

              $ErrorActionPreference = "Stop"
              
              # ============================================================
              # NOVA — נובה
              # Windows Smart Command Center
              # התקנה + יצירת קבצים + אייקון + Build ל-EXE בלחיצה אחת
              # ============================================================
              
              $Base = Join-Path $env:USERPROFILE "Desktop\NOVA"
              $Src  = Join-Path $Base "src"
              $Out  = Join-Path $Base "NOVA"
              $Py   = Join-Path $Src "nova.py"
              $Icon = Join-Path $Src "nova.ico"
              
              Write-Host ""
              Write-Host "=============================================" -ForegroundColor Cyan
              Write-Host "              NOVA / נובה" -ForegroundColor Cyan
              Write-Host "       מרכז השליטה החכם ל-Windows" -ForegroundColor White
              Write-Host "=============================================" -ForegroundColor Cyan
              Write-Host ""
              
              # ------------------------------------------------------------
              # מציאת Python
              # ------------------------------------------------------------
              $Python = $null
              
              $Candidates = @(
                  "py",
                  "python",
                  "python3"
              )
              
              foreach ($cmd in $Candidates) {
                  try {
                      $test = & $cmd --version 2>$null
                      if ($LASTEXITCODE -eq 0 -and $test -match "Python 3") {
                          $Python = $cmd
                          break
                      }
                  } catch {}
              }
              
              if (-not $Python) {
                  Write-Host "לא נמצא Python במחשב." -ForegroundColor Red
                  Write-Host ""
                  Write-Host "הסקריפט מנסה להתקין Python באופן אוטומטי..." -ForegroundColor Yellow
              
                  try {
                      winget --version | Out-Null
                      winget install --id Python.Python.3.12 -e --source winget `
                          --accept-package-agreements `
                          --accept-source-agreements
              
                      $Python = "py"
                  }
                  catch {
                      Write-Host ""
                      Write-Host "לא ניתן להתקין Python באופן אוטומטי." -ForegroundColor Red
                      Write-Host "יש להתקין Python 3.11 ומעלה ואז להריץ את הבלוק שוב." -ForegroundColor Yellow
                      exit 1
                  }
              }
              
              Write-Host "Python נמצא: $Python" -ForegroundColor Green
              
              # ------------------------------------------------------------
              # יצירת תיקיות
              # ------------------------------------------------------------
              New-Item -ItemType Directory -Force -Path $Base | Out-Null
              New-Item -ItemType Directory -Force -Path $Src  | Out-Null
              New-Item -ItemType Directory -Force -Path $Out  | Out-Null
              
              # ------------------------------------------------------------
              # יצירת קובץ התוכנה
              # ------------------------------------------------------------
              @'
              import sys
              import os
              import re
              import json
              import time
              import ctypes
              import shutil
              import subprocess
              import threading
              from pathlib import Path
              from urllib.parse import quote
              
              from PySide6.QtCore import (
                  Qt, QTimer, Signal, QObject, QThread, QSize, QPoint
              )
              from PySide6.QtGui import (
                  QAction, QIcon, QPixmap, QPainter, QColor, QFont,
                  QKeySequence, QShortcut
              )
              from PySide6.QtWidgets import (
                  QApplication, QWidget, QMainWindow, QVBoxLayout, QHBoxLayout,
                  QLabel, QLineEdit, QListWidget, QListWidgetItem, QPushButton,
                  QFrame, QSystemTrayIcon, QMenu, QMessageBox, QStackedWidget,
                  QGraphicsDropShadowEffect
              )
              
              APP_NAME = "נובה"
              APP_VERSION = "1.0.0"
              
              APPDATA = Path(os.environ.get("APPDATA", Path.home()))
              DATA_DIR = APPDATA / "NOVA"
              DATA_DIR.mkdir(parents=True, exist_ok=True)
              
              CLIP_FILE = DATA_DIR / "clipboard.json"
              
              MAX_CLIPS = 60
              MAX_RESULTS = 40
              
              
              # ============================================================
              # עזרי Windows
              # ============================================================
              
              user32 = ctypes.windll.user32
              kernel32 = ctypes.windll.kernel32
              
              HOTKEY_ID = 7351
              WM_HOTKEY = 0x0312
              MOD_CONTROL = 0x0002
              MOD_SHIFT = 0x0004
              MOD_ALT = 0x0001
              VK_SPACE = 0x20
              
              
              def register_global_hotkey():
                  try:
                      user32.RegisterHotKey(None, HOTKEY_ID, MOD_CONTROL, VK_SPACE)
                      return True
                  except Exception:
                      return False
              
              
              def unregister_global_hotkey():
                  try:
                      user32.UnregisterHotKey(None, HOTKEY_ID)
                  except Exception:
                      pass
              
              
              def open_target(target):
                  try:
                      os.startfile(str(target))
                      return True
                  except Exception:
                      try:
                          subprocess.Popen([str(target)])
                          return True
                      except Exception:
                          return False
              
              
              def open_url(url):
                  try:
                      os.startfile(url)
                      return True
                  except Exception:
                      return False
              
              
              # ============================================================
              # Clipboard
              # ============================================================
              
              class ClipboardStore:
                  def __init__(self):
                      self.items = []
                      self.load()
              
                  def load(self):
                      try:
                          if CLIP_FILE.exists():
                              data = json.loads(CLIP_FILE.read_text(encoding="utf-8"))
                              if isinstance(data, list):
                                  self.items = data[:MAX_CLIPS]
                      except Exception:
                          self.items = []
              
                  def save(self):
                      try:
                          CLIP_FILE.write_text(
                              json.dumps(self.items, ensure_ascii=False, indent=2),
                              encoding="utf-8"
                          )
                      except Exception:
                          pass
              
                  def add(self, text):
                      text = text.strip()
              
                      if not text:
                          return False
              
                      if len(text) > 10000:
                          text = text[:10000]
              
                      if self.items and self.items[0] == text:
                          return False
              
                      self.items = [x for x in self.items if x != text]
                      self.items.insert(0, text)
                      self.items = self.items[:MAX_CLIPS]
                      self.save()
                      return True
              
              
              # ============================================================
              # אינדקס תוכנות
              # ============================================================
              
              class SearchItem:
                  def __init__(self, name, path, kind="file", extra=""):
                      self.name = name
                      self.path = path
                      self.kind = kind
                      self.extra = extra
              
              
              class SearchIndex(QObject):
                  ready = Signal()
              
                  def __init__(self):
                      super().__init__()
                      self.items = []
                      self.lock = threading.Lock()
              
                  def build(self):
                      thread = threading.Thread(
                          target=self._build,
                          daemon=True
                      )
                      thread.start()
              
                  def _add(self, name, path, kind, extra=""):
                      if not name or not path:
                          return
              
                      self.items.append(
                          SearchItem(name, path, kind, extra)
                      )
              
                  def _build(self):
                      result = []
              
                      start_locations = []
              
                      appdata = os.environ.get("APPDATA")
                      programdata = os.environ.get("PROGRAMDATA")
                      userprofile = os.environ.get("USERPROFILE")
              
                      if appdata:
                          start_locations.append(
                              Path(appdata) / "Microsoft/Windows/Start Menu/Programs"
                          )
              
                      if programdata:
                          start_locations.append(
                              Path(programdata) / "Microsoft/Windows/Start Menu/Programs"
                          )
              
                      desktop = Path(userprofile) / "Desktop"
              
                      # תוכנות מתפריט התחל
                      for root in start_locations:
                          try:
                              if not root.exists():
                                  continue
              
                              for p in root.rglob("*.lnk"):
                                  try:
                                      result.append(
                                          SearchItem(
                                              p.stem,
                                              str(p),
                                              "app",
                                              "תוכנה"
                                          )
                                      )
                                  except Exception:
                                      pass
              
                              for p in root.rglob("*.exe"):
                                  try:
                                      result.append(
                                          SearchItem(
                                              p.stem,
                                              str(p),
                                              "app",
                                              "תוכנה"
                                          )
                                      )
                                  except Exception:
                                      pass
              
                          except Exception:
                              pass
              
                      # קיצורי דרך בשולחן העבודה
                      try:
                          if desktop.exists():
                              for p in desktop.iterdir():
                                  if p.suffix.lower() in (".lnk", ".exe", ".url"):
                                      result.append(
                                          SearchItem(
                                              p.stem,
                                              str(p),
                                              "app" if p.suffix.lower() != ".url" else "url",
                                              "שולחן העבודה"
                                          )
                                      )
                      except Exception:
                          pass
              
                      # תיקיות נפוצות
                      folders = [
                          ("שולחן העבודה", Path(userprofile) / "Desktop"),
                          ("הורדות", Path(userprofile) / "Downloads"),
                          ("מסמכים", Path(userprofile) / "Documents"),
                          ("תמונות", Path(userprofile) / "Pictures"),
                          ("וידאו", Path(userprofile) / "Videos"),
                      ]
              
                      allowed = {
                          ".pdf", ".doc", ".docx", ".xls", ".xlsx",
                          ".ppt", ".pptx", ".txt", ".csv",
                          ".jpg", ".jpeg", ".png", ".gif", ".webp",
                          ".mp4", ".mkv", ".avi", ".mp3", ".wav",
                          ".zip", ".rar", ".7z",
                          ".py", ".ps1", ".bat", ".json"
                      }
              
                      for label, folder in folders:
                          try:
                              if not folder.exists():
                                  continue
              
                              count = 0
              
                              for p in folder.rglob("*"):
                                  try:
                                      if not p.is_file():
                                          continue
              
                                      if p.suffix.lower() not in allowed:
                                          continue
              
                                      result.append(
                                          SearchItem(
                                              p.name,
                                              str(p),
                                              "file",
                                              label
                                          )
                                      )
              
                                      count += 1
              
                                      # מונע אינדקס עצום במחשבים עמוסים
                                      if count >= 3500:
                                          break
              
                                  except Exception:
                                      pass
              
                          except Exception:
                              pass
              
                      # הסרת כפילויות
                      unique = {}
                      for item in result:
                          key = item.path.lower()
              
                          if key not in unique:
                              unique[key] = item
              
                      with self.lock:
                          self.items = list(unique.values())
              
                      self.ready.emit()
              
              
              # ============================================================
              # חיפוש חכם
              # ============================================================
              
              def score_text(query, text):
                  q = query.lower().strip()
                  t = text.lower()
              
                  if not q:
                      return 0
              
                  if t == q:
                      return 1000
              
                  if t.startswith(q):
                      return 800
              
                  if q in t:
                      return 600
              
                  # התאמה לפי מילים
                  words = [x for x in re.split(r"\s+", q) if x]
              
                  score = 0
              
                  for word in words:
                      if word in t:
                          score += 150
              
                  # התאמת אותיות עוקבות
                  pos = 0
                  matched = 0
              
                  for char in q:
                      idx = t.find(char, pos)
              
                      if idx >= 0:
                          matched += 1
                          pos = idx + 1
              
                  if matched:
                      score += int((matched / len(q)) * 100)
              
                  return score
              
              
              # ============================================================
              # כרטיס תוצאה
              # ============================================================
              
              class ResultRow(QFrame):
                  clicked = Signal(object)
              
                  def __init__(self, item, parent=None):
                      super().__init__(parent)
                      self.item = item
              
                      self.setObjectName("resultRow")
                      self.setCursor(Qt.PointingHandCursor)
              
                      layout = QHBoxLayout(self)
                      layout.setContentsMargins(16, 11, 16, 11)
                      layout.setSpacing(12)
              
                      icon = QLabel()
              
                      icon_text = {
                          "app": "▣",
                          "file": "▤",
                          "url": "↗",
                          "action": "✦",
                          "clipboard": "⧉"
                      }.get(item.kind, "•")
              
                      icon.setText(icon_text)
                      icon.setObjectName("resultIcon")
                      icon.setFixedWidth(30)
              
                      text_box = QVBoxLayout()
                      text_box.setSpacing(2)
              
                      title = QLabel(item.name)
                      title.setObjectName("resultTitle")
              
                      subtitle = QLabel(item.extra or item.path)
                      subtitle.setObjectName("resultSub")
                      subtitle.setTextInteractionFlags(Qt.NoTextInteraction)
              
                      text_box.addWidget(title)
                      text_box.addWidget(subtitle)
              
                      layout.addWidget(icon)
                      layout.addLayout(text_box, 1)
              
                      arrow = QLabel("‹")
                      arrow.setObjectName("resultArrow")
                      layout.addWidget(arrow)
              
                  def mousePressEvent(self, event):
                      if event.button() == Qt.LeftButton:
                          self.clicked.emit(self.item)
              
                      super().mousePressEvent(event)
              
              
              # ============================================================
              # התוכנה
              # ============================================================
              
              class NovaWindow(QMainWindow):
              
                  def __init__(self):
                      super().__init__()
              
                      self.clipboard_store = ClipboardStore()
                      self.index = SearchIndex()
              
                      self.index.ready.connect(self.index_ready)
              
                      self.all_results = []
                      self.selected_index = 0
                      self.hotkey_registered = False
              
                      self.setWindowTitle("נובה — מרכז השליטה")
                      self.setWindowIcon(QIcon(str(Path(sys.executable).parent / "nova.ico")))
              
                      self.setMinimumSize(760, 560)
                      self.resize(860, 650)
              
                      self.setAttribute(Qt.WA_DeleteOnClose, False)
              
                      self.build_ui()
                      self.install_global_hotkey_handler()
              
                      self.index.build()
              
                      # מעקב לוח
                      self.clipboard_timer = QTimer(self)
                      self.clipboard_timer.timeout.connect(self.check_clipboard)
                      self.clipboard_timer.start(450)
              
                      # עדכון סטטוס
                      self.status_timer = QTimer(self)
                      self.status_timer.timeout.connect(self.update_status)
                      self.status_timer.start(1000)
              
                      self.search_edit.setFocus()
              
                  # --------------------------------------------------------
                  # UI
                  # --------------------------------------------------------
              
                  def build_ui(self):
              
                      root = QWidget()
                      root.setObjectName("root")
                      self.setCentralWidget(root)
              
                      main = QVBoxLayout(root)
                      main.setContentsMargins(28, 25, 28, 20)
                      main.setSpacing(16)
              
                      # Header
                      header = QHBoxLayout()
              
                      brand_box = QVBoxLayout()
                      brand_box.setSpacing(0)
              
                      brand = QLabel("נובה")
                      brand.setObjectName("brand")
              
                      subtitle = QLabel("מרכז השליטה החכם שלך")
                      subtitle.setObjectName("subtitle")
              
                      brand_box.addWidget(brand)
                      brand_box.addWidget(subtitle)
              
                      header.addLayout(brand_box)
                      header.addStretch()
              
                      status = QLabel("● פעילה")
                      status.setObjectName("onlineStatus")
              
                      header.addWidget(status)
              
                      main.addLayout(header)
              
                      # Search
                      search_frame = QFrame()
                      search_frame.setObjectName("searchFrame")
              
                      search_layout = QHBoxLayout(search_frame)
                      search_layout.setContentsMargins(18, 5, 18, 5)
              
                      search_icon = QLabel("⌕")
                      search_icon.setObjectName("searchIcon")
              
                      self.search_edit = QLineEdit()
                      self.search_edit.setPlaceholderText(
                          "חפש תוכנה, קובץ, פעולה או כתובת..."
                      )
                      self.search_edit.setClearButtonEnabled(True)
                      self.search_edit.setObjectName("searchEdit")
              
                      search_layout.addWidget(search_icon)
                      search_layout.addWidget(self.search_edit)
              
                      main.addWidget(search_frame)
              
                      self.search_edit.textChanged.connect(self.perform_search)
                      self.search_edit.returnPressed.connect(self.activate_selected)
              
                      # Hint
                      hint = QLabel(
                          "Ctrl+Space לפתיחה מכל מקום  •  Enter לפתיחה  •  Esc להסתרה"
                      )
                      hint.setObjectName("hint")
                      hint.setAlignment(Qt.AlignCenter)
              
                      main.addWidget(hint)
              
                      # Content
                      content = QHBoxLayout()
                      content.setSpacing(14)
              
                      # Results
                      result_panel = QFrame()
                      result_panel.setObjectName("panel")
              
                      result_layout = QVBoxLayout(result_panel)
                      result_layout.setContentsMargins(15, 15, 15, 15)
                      result_layout.setSpacing(9)
              
                      title_row = QHBoxLayout()
              
                      self.results_title = QLabel("גישה מהירה")
                      self.results_title.setObjectName("sectionTitle")
              
                      self.results_count = QLabel("")
                      self.results_count.setObjectName("count")
              
                      title_row.addWidget(self.results_title)
                      title_row.addStretch()
                      title_row.addWidget(self.results_count)
              
                      result_layout.addLayout(title_row)
              
                      self.results = QVBoxLayout()
                      self.results.setSpacing(7)
              
                      result_layout.addLayout(self.results)
                      result_layout.addStretch()
              
                      content.addWidget(result_panel, 3)
              
                      # Sidebar
                      side = QFrame()
                      side.setObjectName("sidePanel")
              
                      side_layout = QVBoxLayout(side)
                      side_layout.setContentsMargins(14, 14, 14, 14)
                      side_layout.setSpacing(9)
              
                      side_title = QLabel("פעולות מהירות")
                      side_title.setObjectName("sectionTitle")
                      side_layout.addWidget(side_title)
              
                      actions = [
                          ("📋", "לוח ההעתקות", self.show_clipboard),
                          ("📁", "פתח הורדות", self.open_downloads),
                          ("🖥", "מחשב זה", self.open_computer),
                          ("⚙", "הגדרות Windows", self.open_settings),
                          ("🌐", "חיפוש באינטרנט", self.web_search),
                      ]
              
                      for icon, text, callback in actions:
                          btn = QPushButton(f"{icon}   {text}")
                          btn.setObjectName("actionButton")
                          btn.setCursor(Qt.PointingHandCursor)
                          btn.clicked.connect(callback)
                          side_layout.addWidget(btn)
              
                      side_layout.addStretch()
              
                      info = QLabel(
                          "נובה עובדת ברקע.\n"
                          "אין צורך להשאיר את החלון פתוח.\n\n"
                          "הנתונים המקומיים נשמרים\n"
                          "במחשב שלך."
                      )
                      info.setObjectName("info")
                      info.setWordWrap(True)
              
                      side_layout.addWidget(info)
              
                      content.addWidget(side, 1)
              
                      main.addLayout(content, 1)
              
                      # Footer
                      footer = QHBoxLayout()
              
                      self.status_label = QLabel("מאתחל אינדקס...")
                      self.status_label.setObjectName("footer")
              
                      footer.addWidget(self.status_label)
                      footer.addStretch()
              
                      version = QLabel(f"נובה {APP_VERSION}")
                      version.setObjectName("footer")
              
                      footer.addWidget(version)
              
                      main.addLayout(footer)
              
                      self.apply_style()
              
                  # --------------------------------------------------------
                  # Style
                  # --------------------------------------------------------
              
                  def apply_style(self):
                      self.setStyleSheet("""
                      * {
                          font-family: "Segoe UI";
                      }
              
                      QMainWindow, QWidget#root {
                          background: #0b1020;
                          color: #edf2ff;
                      }
              
                      QLabel {
                          color: #edf2ff;
                      }
              
                      QLabel#brand {
                          font-size: 31px;
                          font-weight: 800;
                          color: #ffffff;
                      }
              
                      QLabel#subtitle {
                          font-size: 13px;
                          color: #8792ad;
                      }
              
                      QLabel#onlineStatus {
                          background: #112a25;
                          color: #55e6b1;
                          border: 1px solid #1c5547;
                          border-radius: 15px;
                          padding: 6px 12px;
                          font-size: 12px;
                          font-weight: 600;
                      }
              
                      QFrame#searchFrame {
                          background: #141b31;
                          border: 1px solid #273253;
                          border-radius: 17px;
                      }
              
                      QFrame#searchFrame:focus-within {
                          border: 1px solid #6077ff;
                      }
              
                      QLabel#searchIcon {
                          font-size: 29px;
                          color: #7185ff;
                          padding-bottom: 2px;
                      }
              
                      QLineEdit#searchEdit {
                          background: transparent;
                          border: none;
                          color: #ffffff;
                          font-size: 18px;
                          padding: 11px 4px;
                          selection-background-color: #4f61d8;
                      }
              
                      QLabel#hint {
                          color: #68738e;
                          font-size: 11px;
                      }
              
                      QFrame#panel {
                          background: #10172a;
                          border: 1px solid #1e2943;
                          border-radius: 17px;
                      }
              
                      QFrame#sidePanel {
                          background: #10172a;
                          border: 1px solid #1e2943;
                          border-radius: 17px;
                      }
              
                      QLabel#sectionTitle {
                          color: #ffffff;
                          font-size: 14px;
                          font-weight: 700;
                      }
              
                      QLabel#count {
                          color: #68738e;
                          font-size: 11px;
                      }
              
                      QFrame#resultRow {
                          background: #151d33;
                          border: 1px solid transparent;
                          border-radius: 12px;
                      }
              
                      QFrame#resultRow:hover {
                          background: #1b2642;
                          border: 1px solid #34436b;
                      }
              
                      QLabel#resultIcon {
                          color: #7185ff;
                          font-size: 21px;
                          font-weight: bold;
                      }
              
                      QLabel#resultTitle {
                          color: #f4f6ff;
                          font-size: 13px;
                          font-weight: 600;
                      }
              
                      QLabel#resultSub {
                          color: #687690;
                          font-size: 10px;
                      }
              
                      QLabel#resultArrow {
                          color: #52607d;
                          font-size: 21px;
                      }
              
                      QPushButton#actionButton {
                          text-align: right;
                          background: #151d33;
                          border: 1px solid #222e4a;
                          border-radius: 11px;
                          color: #dbe2f6;
                          padding: 12px 11px;
                          font-size: 12px;
                      }
              
                      QPushButton#actionButton:hover {
                          background: #1d2948;
                          border: 1px solid #394b7a;
                      }
              
                      QPushButton#actionButton:pressed {
                          background: #11182b;
                      }
              
                      QLabel#info {
                          color: #626e89;
                          background: #0d1426;
                          border-radius: 10px;
                          padding: 12px;
                          font-size: 10px;
                      }
              
                      QLabel#footer {
                          color: #59657f;
                          font-size: 10px;
                      }
                      """)
              
                  # --------------------------------------------------------
                  # חיפוש
                  # --------------------------------------------------------
              
                  def clear_results(self):
                      while self.results.count():
                          item = self.results.takeAt(0)
                          widget = item.widget()
              
                          if widget:
                              widget.deleteLater()
              
                  def perform_search(self, query):
              
                      query = query.strip()
              
                      self.clear_results()
              
                      if not query:
                          self.results_title.setText("גישה מהירה")
              
                          quick = [
                              SearchItem(
                                  "לוח ההעתקות",
                                  "",
                                  "clipboard",
                                  "העתקות אחרונות"
                              ),
                              SearchItem(
                                  "פתח הורדות",
                                  "",
                                  "action",
                                  "תיקיית ההורדות"
                              ),
                              SearchItem(
                                  "מחשב זה",
                                  "",
                                  "action",
                                  "סייר הקבצים"
                              ),
                              SearchItem(
                                  "הגדרות Windows",
                                  "",
                                  "action",
                                  "הגדרות מערכת"
                              )
                          ]
              
                          self.all_results = quick
              
                          for item in quick:
                              row = ResultRow(item)
                              row.clicked.connect(self.activate_item)
                              self.results.addWidget(row)
              
                          self.results_count.setText("גישה מהירה")
                          return
              
                      self.results_title.setText("תוצאות")
              
                      results = []
              
                      # פקודות חכמות
                      normalized = query.lower()
              
                      if normalized.startswith("פתח "):
                          target = query[5:].strip()
              
                          candidates = [
                              ("הורדות", Path.home() / "Downloads"),
                              ("מסמכים", Path.home() / "Documents"),
                              ("שולחן העבודה", Path.home() / "Desktop"),
                              ("תמונות", Path.home() / "Pictures"),
                              ("וידאו", Path.home() / "Videos"),
                          ]
              
                          for name, path in candidates:
                              if target in name or name in target:
                                  results.append(
                                      SearchItem(
                                          f"פתח {name}",
                                          str(path),
                                          "action",
                                          str(path)
                                      )
                                  )
              
                      # URL
                      if re.match(r"^(https?://|www\.)", query, re.I):
                          url = query
              
                          if url.startswith("www."):
                              url = "https://" + url
              
                          results.append(
                              SearchItem(
                                  "פתח כתובת",
                                  url,
                                  "url",
                                  url
                              )
                          )
              
                      # חיפוש באינטרנט
                      if normalized.startswith("חפש "):
                          text = query[5:].strip()
              
                          if text:
                              url = (
                                  "https://www.google.com/search?q="
                                  + quote(text)
                              )
              
                              results.append(
                                  SearchItem(
                                      "חפש באינטרנט",
                                      url,
                                      "url",
                                      text
                                  )
                              )
              
                      # לוח העתקות
                      if normalized in (
                          "לוח",
                          "העתקות",
                          "לוח העתקות",
                          "clipboard"
                      ):
                          for i, text in enumerate(self.clipboard_store.items[:10]):
                              short = text.replace("\n", " ")
              
                              if len(short) > 80:
                                  short = short[:80] + "..."
              
                              results.append(
                                  SearchItem(
                                      short,
                                      text,
                                      "clipboard",
                                      "לחץ כדי להעתיק"
                                  )
                              )
              
                      # אינדקס
                      with self.index.lock:
                          indexed = list(self.index.items)
              
                      scored = []
              
                      for item in indexed:
                          s = max(
                              score_text(query, item.name),
                              score_text(query, Path(item.path).name)
                          )
              
                          if s > 0:
                              scored.append((s, item))
              
                      scored.sort(
                          key=lambda x: (
                              -x[0],
                              x[1].name.lower()
                          )
                      )
              
                      results.extend(
                          [item for _, item in scored[:MAX_RESULTS]]
                      )
              
                      self.all_results = results[:MAX_RESULTS]
              
                      if not self.all_results:
                          empty = QLabel(
                              "לא מצאתי תוצאה מתאימה.\n\n"
                              "אפשר לנסות שם תוכנה, שם קובץ,\n"
                              "כתובת אינטרנט או \"חפש ...\"."
                          )
              
                          empty.setAlignment(Qt.AlignCenter)
                          empty.setObjectName("info")
                          empty.setMinimumHeight(130)
              
                          self.results.addWidget(empty)
              
                          self.results_count.setText("0 תוצאות")
                          return
              
                      for item in self.all_results:
                          row = ResultRow(item)
                          row.clicked.connect(self.activate_item)
                          self.results.addWidget(row)
              
                      self.results_count.setText(
                          f"{len(self.all_results)} תוצאות"
                      )
              
                  # --------------------------------------------------------
                  # פעולות
                  # --------------------------------------------------------
              
                  def activate_selected(self):
                      if self.all_results:
                          self.activate_item(self.all_results[0])
              
                  def activate_item(self, item):
              
                      if item.kind == "clipboard":
                          QApplication.clipboard().setText(item.path)
                          self.status_label.setText("הטקסט הועתק ללוח")
                          self.hide()
                          return
              
                      if item.kind == "action":
                          if item.name == "פתח הורדות":
                              self.open_downloads()
                          elif item.name == "מחשב זה":
                              self.open_computer()
                          elif item.name == "הגדרות Windows":
                              self.open_settings()
                          elif item.name == "לוח ההעתקות":
                              self.show_clipboard()
                          else:
                              open_target(item.path)
              
                          return
              
                      if item.kind == "url":
                          open_url(item.path)
                          self.hide()
                          return
              
                      if item.kind in ("app", "file"):
                          open_target(item.path)
                          self.hide()
                          return
              
                      open_target(item.path)
                      self.hide()
              
                  def show_clipboard(self):
                      self.search_edit.setText("לוח")
                      self.search_edit.setFocus()
                      self.show()
                      self.raise_()
                      self.activateWindow()
              
                  def open_downloads(self):
                      open_target(Path.home() / "Downloads")
                      self.hide()
              
                  def open_computer(self):
                      try:
                          subprocess.Popen("explorer.exe shell:MyComputerFolder")
                      except Exception:
                          pass
                      self.hide()
              
                  def open_settings(self):
                      try:
                          subprocess.Popen(
                              "start ms-settings:",
                              shell=True
                          )
                      except Exception:
                          pass
                      self.hide()
              
                  def web_search(self):
                      text = self.search_edit.text().strip()
              
                      if not text:
                          text = "חיפוש"
              
                      url = (
                          "https://www.google.com/search?q="
                          + quote(text)
                      )
              
                      open_url(url)
                      self.hide()
              
                  # --------------------------------------------------------
                  # Clipboard monitor
                  # --------------------------------------------------------
              
                  def check_clipboard(self):
                      try:
                          text = QApplication.clipboard().text()
              
                          if text and text.strip():
                              changed = self.clipboard_store.add(text)
              
                              if changed and self.isVisible():
                                  if self.search_edit.text().strip() == "לוח":
                                      self.perform_search("לוח")
              
                      except Exception:
                          pass
              
                  # --------------------------------------------------------
                  # אינדקס
                  # --------------------------------------------------------
              
                  def index_ready(self):
                      count = len(self.index.items)
              
                      self.status_label.setText(
                          f"האינדקס מוכן • {count:,} פריטים זמינים לחיפוש"
                      )
              
                      if not self.search_edit.text().strip():
                          self.perform_search("")
              
                  def update_status(self):
                      if not self.index.items:
                          self.status_label.setText("בונה אינדקס...")
              
                  # --------------------------------------------------------
                  # Global Hotkey
                  # --------------------------------------------------------
              
                  def install_global_hotkey_handler(self):
              
                      self.hotkey_registered = register_global_hotkey()
              
                      timer = QTimer(self)
                      timer.timeout.connect(self.poll_windows_messages)
                      timer.start(80)
              
                      self.hotkey_timer = timer
              
                  def poll_windows_messages(self):
              
                      msg = ctypes.wintypes.MSG()
              
                      try:
                          while user32.PeekMessageW(
                              ctypes.byref(msg),
                              None,
                              WM_HOTKEY,
                              WM_HOTKEY,
                              1
                          ):
                              if msg.message == WM_HOTKEY:
                                  self.toggle_window()
              
                      except Exception:
                          pass
              
                  def toggle_window(self):
              
                      if self.isVisible() and self.isActiveWindow():
                          self.hide()
                          return
              
                      self.show()
                      self.raise_()
                      self.activateWindow()
                      self.search_edit.setFocus()
                      self.search_edit.selectAll()
              
                  # --------------------------------------------------------
                  # Keyboard
                  # --------------------------------------------------------
              
                  def keyPressEvent(self, event):
              
                      if event.key() == Qt.Key_Escape:
                          self.hide()
                          event.accept()
                          return
              
                      if event.key() in (
                          Qt.Key_Return,
                          Qt.Key_Enter
                      ):
                          self.activate_selected()
                          event.accept()
                          return
              
                      super().keyPressEvent(event)
              
                  # --------------------------------------------------------
                  # Close = hide to tray
                  # --------------------------------------------------------
              
                  def closeEvent(self, event):
                      event.ignore()
                      self.hide()
              
                  def cleanup(self):
                      unregister_global_hotkey()
              
              
              # ============================================================
              # System Tray
              # ============================================================
              
              def create_tray(app, window):
              
                  icon_path = Path(sys.executable).parent / "nova.ico"
              
                  tray = QSystemTrayIcon()
              
                  if icon_path.exists():
                      tray.setIcon(QIcon(str(icon_path)))
                  else:
                      tray.setIcon(app.style().standardIcon(
                          app.style().SP_ComputerIcon
                      ))
              
                  tray.setToolTip("נובה — מרכז השליטה החכם")
              
                  menu = QMenu()
              
                  open_action = QAction("פתח את נובה", menu)
                  open_action.triggered.connect(window.toggle_window)
              
                  menu.addAction(open_action)
              
                  menu.addSeparator()
              
                  quit_action = QAction("יציאה מנובה", menu)
              
                  def quit_app():
                      window.cleanup()
                      app.quit()
              
                  quit_action.triggered.connect(quit_app)
              
                  menu.addAction(quit_action)
              
                  tray.setContextMenu(menu)
              
                  tray.activated.connect(
                      lambda reason: (
                          window.toggle_window()
                          if reason == QSystemTrayIcon.DoubleClick
                          else None
                      )
                  )
              
                  tray.show()
              
                  return tray
              
              
              # ============================================================
              # Main
              # ============================================================
              
              def main():
              
                  QApplication.setHighDpiScaleFactorRoundingPolicy(
                      Qt.HighDpiScaleFactorRoundingPolicy.PassThrough
                  )
              
                  app = QApplication(sys.argv)
              
                  app.setApplicationName("נובה")
                  app.setApplicationDisplayName("נובה — מרכז השליטה החכם")
                  app.setQuitOnLastWindowClosed(False)
              
                  window = NovaWindow()
              
                  tray = create_tray(app, window)
              
                  # מתחילים פתוח בפעם הראשונה
                  window.show()
                  window.raise_()
                  window.activateWindow()
              
                  exit_code = app.exec()
              
                  window.cleanup()
              
                  sys.exit(exit_code)
              
              
              if __name__ == "__main__":
                  main()
              '@ | Set-Content -Path $Py -Encoding UTF8
              
              # ------------------------------------------------------------
              # יצירת אייקון מקצועי באמצעות Pillow
              # ------------------------------------------------------------
              @'
              from PIL import Image, ImageDraw
              
              sizes = [16, 24, 32, 48, 64, 128, 256]
              
              images = []
              
              for size in sizes:
                  img = Image.new("RGBA", (size, size), (11, 16, 32, 255))
                  d = ImageDraw.Draw(img)
              
                  # רקע מעוגל
                  margin = max(1, size // 16)
              
                  d.rounded_rectangle(
                      (margin, margin, size-margin, size-margin),
                      radius=max(3, size//5),
                      fill=(20, 28, 50, 255),
                      outline=(91, 112, 255, 255),
                      width=max(1, size//32)
                  )
              
                  # סמל N / כוכב טכנולוגי
                  cx = size // 2
                  cy = size // 2
              
                  pts = [
                      (cx, int(size*0.17)),
                      (int(size*0.66), int(size*0.39)),
                      (int(size*0.84), int(size*0.30)),
                      (int(size*0.73), int(size*0.55)),
                      (int(size*0.83), int(size*0.80)),
                      (int(size*0.62), int(size*0.64)),
                      (int(size*0.38), int(size*0.83)),
                      (int(size*0.26), int(size*0.59)),
                      (int(size*0.16), int(size*0.70)),
                      (int(size*0.27), int(size*0.43)),
                  ]
              
                  d.polygon(
                      pts,
                      fill=(106, 126, 255, 255)
                  )
              
                  # מרכז זוהר
                  r = max(1, size // 11)
              
                  d.ellipse(
                      (cx-r, cy-r, cx+r, cy+r),
                      fill=(236, 240, 255, 255)
                  )
              
                  images.append(img)
              
              images[0].save(
                  "nova.ico",
                  format="ICO",
                  sizes=[(s, s) for s in sizes],
                  append_images=images[1:]
              )
              '@ | Set-Content -Path (Join-Path $Src "make_icon.py") -Encoding UTF8
              
              # ------------------------------------------------------------
              # התקנת Build dependencies
              # ------------------------------------------------------------
              Write-Host ""
              Write-Host "מתקין את מנוע הממשק ואת כלי הבנייה..." -ForegroundColor Yellow
              
              & $Python -m pip install --upgrade pip --disable-pip-version-check
              
              if ($LASTEXITCODE -ne 0) {
                  throw "עדכון pip נכשל."
              }
              
              & $Python -m pip install PySide6 Pillow PyInstaller --disable-pip-version-check
              
              if ($LASTEXITCODE -ne 0) {
                  throw "התקנת התלויות נכשלה."
              }
              
              # ------------------------------------------------------------
              # יצירת אייקון
              # ------------------------------------------------------------
              Write-Host "יוצר אייקון..." -ForegroundColor Yellow
              
              Push-Location $Src
              
              & $Python "make_icon.py"
              
              if ($LASTEXITCODE -ne 0) {
                  Pop-Location
                  throw "יצירת האייקון נכשלה."
              }
              
              Pop-Location
              
              # ------------------------------------------------------------
              # Build
              # ------------------------------------------------------------
              Write-Host ""
              Write-Host "בונה את NOVA.EXE..." -ForegroundColor Yellow
              Write-Host "זה השלב הארוך ביותר." -ForegroundColor DarkGray
              
              # ניקוי Build קודם
              $BuildDir = Join-Path $Src "build"
              $SpecFile = Join-Path $Src "nova.spec"
              
              if (Test-Path $BuildDir) {
                  Remove-Item $BuildDir -Recurse -Force
              }
              
              if (Test-Path $SpecFile) {
                  Remove-Item $SpecFile -Force
              }
              
              if (Test-Path $Out) {
                  Get-ChildItem $Out -Force | Remove-Item -Recurse -Force
              }
              
              Push-Location $Src
              
              & $Python -m PyInstaller `
                  --noconfirm `
                  --clean `
                  --onefile `
                  --windowed `
                  --name "NOVA" `
                  --icon "nova.ico" `
                  --add-data "nova.ico;." `
                  "nova.py"
              
              $BuildExit = $LASTEXITCODE
              
              Pop-Location
              
              if ($BuildExit -ne 0) {
                  throw "בניית ה-EXE נכשלה."
              }
              
              # ------------------------------------------------------------
              # העתקה לתיקיית התוצאה
              # ------------------------------------------------------------
              $BuiltExe = Join-Path $Src "dist\NOVA.exe"
              $FinalExe = Join-Path $Out "NOVA.exe"
              
              if (-not (Test-Path $BuiltExe)) {
                  throw "ה-EXE לא נוצר."
              }
              
              Copy-Item $BuiltExe $FinalExe -Force
              
              # ------------------------------------------------------------
              # יצירת README
              # ------------------------------------------------------------
              @'
              נובה — מרכז השליטה החכם
              ========================
              
              קובץ ההפעלה:
              NOVA.exe
              
              הפעלה:
              לחיצה כפולה על NOVA.exe
              
              קיצור דרך גלובלי:
              Ctrl + Space
              
              מה נובה יודעת לעשות:
              • חיפוש תוכנות
              • חיפוש קבצים בתיקיות נפוצות
              • פתיחת קבצים ותוכנות
              • פתיחת תיקיות Windows
              • היסטוריית לוח העתקות
              • חיפוש באינטרנט
              • פתיחת כתובות אינטרנט
              • עבודה ברקע דרך אזור ההתראות
              • קיצור דרך גלובלי לפתיחה מכל מקום
              
              הנתונים נשמרים מקומית במחשב.
              
              אין צורך להתקין Python כדי להריץ את NOVA.exe.
              '@ | Set-Content -Path (Join-Path $Out "README.txt") -Encoding UTF8
              
              # ------------------------------------------------------------
              # יצירת קיצור דרך על שולחן העבודה
              # ------------------------------------------------------------
              try {
              
                  $WshShell = New-Object -ComObject WScript.Shell
              
                  $ShortcutPath = Join-Path `
                      ([Environment]::GetFolderPath("Desktop")) `
                      "נובה.lnk"
              
                  $Shortcut = $WshShell.CreateShortcut($ShortcutPath)
              
                  $Shortcut.TargetPath = $FinalExe
                  $Shortcut.WorkingDirectory = $Out
                  $Shortcut.IconLocation = "$FinalExe,0"
                  $Shortcut.Description = "נובה — מרכז השליטה החכם"
              
                  $Shortcut.Save()
              
              }
              catch {
                  Write-Host "לא ניתן היה ליצור קיצור דרך אוטומטי." -ForegroundColor DarkYellow
              }
              
              # ------------------------------------------------------------
              # סיום
              # ------------------------------------------------------------
              $SizeMB = [math]::Round(
                  (Get-Item $FinalExe).Length / 1MB,
                  1
              )
              
              Write-Host ""
              Write-Host "=============================================" -ForegroundColor Green
              Write-Host "              הבנייה הסתיימה!" -ForegroundColor Green
              Write-Host "=============================================" -ForegroundColor Green
              Write-Host ""
              Write-Host "ה-EXE המוכן נמצא כאן:" -ForegroundColor White
              Write-Host $FinalExe -ForegroundColor Cyan
              Write-Host ""
              Write-Host "גודל: $SizeMB MB" -ForegroundColor Gray
              Write-Host ""
              Write-Host "נוצר גם קיצור דרך 'נובה' על שולחן העבודה." -ForegroundColor Green
              Write-Host ""
              Write-Host "הפעל עכשיו את NOVA.exe." -ForegroundColor White
              Write-Host ""
              Write-Host "קיצור הדרך של התוכנה: Ctrl + Space" -ForegroundColor Cyan
              Write-Host ""
              
              # פתיחת תיקיית התוצאה
              Start-Process explorer.exe -ArgumentList "`"$Out`""
              
              # הפעלת התוכנה
              Start-Process -FilePath $FinalExe
              

              אבל מה שהכי מוזר ומעצבן
              זה שהם לא הביאו איזה משהו חדש ומעניין כל כך
              הם לא שברו את הכלים
              אם לי היה את הידע שלהם מזמן הייתי יוצר...
              ולא איזה לוח שנה עם תזכורות וכדו'

              או שזה בכלל היה בעיה בהנחיה שלי
              אז למישהו יש הנחיות יותר מאתגרים?

              דאנציגד מנותק
              דאנציגד מנותק
              דאנציג
              מדריכים
              כתב נערך לאחרונה על ידי
              #14

              @YAHBDK כתב:

              אבל מה שהכי מוזר ומעצבן
              זה שהם לא הביאו איזה משהו חדש ומעניין כל כך
              הם לא שברו את הכלים
              אם לי היה את הידע שלהם מזמן הייתי יוצר...
              ולא איזה לוח שנה עם תזכורות וכדו'

              או שזה בכלל היה בעיה בהנחיה שלי
              אז למישהו יש הנחיות יותר מאתגרים?

              זה בדיוק AI, יש לו הכל ואין לו כלום, AI לא יכול להיות יצירתי, או בלשון שלך, לשבור את הכלים, כי הוא עצמו כלי.

              אתה מנסה לדחוק במשהו מתוכנת שפועל על פי הסתברות, שיעבוד עם יצירתיות, וזה לא הולך ביחד.

              Y תגובה 1 תגובה אחרונה
              2
              • דאנציגד דאנציג

                @YAHBDK כתב:

                אבל מה שהכי מוזר ומעצבן
                זה שהם לא הביאו איזה משהו חדש ומעניין כל כך
                הם לא שברו את הכלים
                אם לי היה את הידע שלהם מזמן הייתי יוצר...
                ולא איזה לוח שנה עם תזכורות וכדו'

                או שזה בכלל היה בעיה בהנחיה שלי
                אז למישהו יש הנחיות יותר מאתגרים?

                זה בדיוק AI, יש לו הכל ואין לו כלום, AI לא יכול להיות יצירתי, או בלשון שלך, לשבור את הכלים, כי הוא עצמו כלי.

                אתה מנסה לדחוק במשהו מתוכנת שפועל על פי הסתברות, שיעבוד עם יצירתיות, וזה לא הולך ביחד.

                Y מנותק
                Y מנותק
                YAHBDK
                כתב נערך לאחרונה על ידי
                #15

                @דאנציג
                אתה די צודק
                אבל שכשאני מתכתב איתו מה לבנות ומה חסר לאנושות וכו' יש לו רעיונות קצת יותר טובים
                אם כי תמיד כולם מישום מה יחזרו על דבר אחד אלף פעם
                שהדבר הכי חשוב שצריך לבנות זה סוג של לוח דפים של תזכורות אוטומטים

                דאנציגד תגובה 1 תגובה אחרונה
                😂
                0
                • Y YAHBDK

                  @דאנציג
                  אתה די צודק
                  אבל שכשאני מתכתב איתו מה לבנות ומה חסר לאנושות וכו' יש לו רעיונות קצת יותר טובים
                  אם כי תמיד כולם מישום מה יחזרו על דבר אחד אלף פעם
                  שהדבר הכי חשוב שצריך לבנות זה סוג של לוח דפים של תזכורות אוטומטים

                  דאנציגד מנותק
                  דאנציגד מנותק
                  דאנציג
                  מדריכים
                  כתב נערך לאחרונה על ידי דאנציג
                  #16

                  @YAHBDK
                  כי כנראה זה הדבר שהכי מבקשים באנגלית.
                  היה לאחרונה פוסט על בקשה מAI שיזרוק מספר בין X לY שרוב המודלים ענו רוב הפעמים את אותו מספר, מכיון שבעצם AI לא זורק מספר, אלא מנסה להבין את הבקשה שלך על פי הסתברות לפי מאגר הידע האדיר שקיים אצלו.
                  האמת היא שיצרן יש רק אחד, שהוא ברא יצר ועשה את העולם מאין ליש פעם אחת, וכל השאר זה משחק עם היצירה הקיימת.
                  אין שום אדם בעולם שיכול ליצור משהו שלא קיים, אלא להשתמש ולהרכיב את הדברים הקיימים בדרכים שעד היום לא הורכבו.
                  לעומת זאת, AI גם את זה הוא עושה רק על פי בקשה / הנחיה.

                  תגובה 1 תגובה אחרונה
                  5
                  • Y YAHBDK

                    @ztcebuck
                    קלוד=אופוס 5
                    גימיני=3.5 Flash-Lite
                    פריבף=DeepSeek V4.1 Flash
                    גיפיטי=אני לא יודע איפה בודקים

                    י מנותק
                    י מנותק
                    יוסף מאיר וייס
                    כתב נערך לאחרונה על ידי
                    #17

                    @YAHBDK כתב:

                    =3.5 Flash-Lite

                    למה???? זה הכי זול ומהיר - תוצאה נמוכה יותר

                    תעשה בפלאש 3.8 (עדיף עם חשיבה גבוהה, אבל שכל האחרים גם הם יהיו עם חשבה גבוהה אם אפשרי )

                    תגובה 1 תגובה אחרונה
                    0
                    • Y YAHBDK

                      שלום לכולם!
                      אני משתמש בAI שונים ומכולם אני מאוד מרוצה
                      כל אחד טוב בדבר אחד וטיפש\גרוע בדבר אחר
                      חשבתי לעשות מבחן ולהבין מי באמת הכי "חכם" מכולם בצורה כללית
                      פתחתי כמה מהAI והכנסתי להם אותם הנחיות בדיוק
                      אמרתי להם שאני לא אומר להם מה ליצור הם צריכים לחשוב לבד מה ואיך וכמה וכו' ולעשות הכל כדי לנצח בתחרות

                      המתמודדים הם
                      קלוד, גיפיטי, גימיני, פריבף
                      ההנחיות שהכנסתי להם

                      אתה
                      משתתף בתחרות בין 4 מודלי AI: Claude, ChatGPT,
                      Gemini, ו-Freebuff.

                      כל אחד
                      מכם מקבל בדיוק את ההנחיה הזו, במקביל, בלי לראות את התשובות של האחרים. בסוף
                      התהליך, המשתמש ישווה בין 4 התוצרים ויקבע מי ניצח. הקריטריונים לניצחון: מי
                      יצר את התוכנה הכי מקצועית, הכי יפה ויזואלית, והכי שימושית בפועל בחיי היום-יום.

                      אתה מתחרה נגד שלושת המודלים האחרים - קח את זה ברצינות ותן את המקסימום שלך.

                      המשימה
                      שלך:

                      עליך
                      להמציא בעצמך, ללא כל הכוונה נוספת מהמשתמש, רעיון לתוכנת Windows ברמה
                      גבוהה - לא אפליקציית פתקים, לא To-Do List, לא תזכורות, לא מחשבון. אתה צריך לחשוב על
                      כלי אמיתי שפותר בעיה יומיומית בצורה חכמה וטכנית מרשימה. לדוגמה (רק כדוגמאות
                      בלבד להמחשת הרמה - אל תעתיק אותן, תמציא רעיון משלך שיהיה מקורי ומרשים
                      יותר):

                      • כלי שיושב ברקע ומאפשר הורדת סרטון/אודיו ישירות מדף יוטיוב פתוח בדפדפן בלחיצה אחת
                      • תוסף שמאפשר לערוך/לבטל מייל אחרי ששלחת אותו בג'ימייל/אאוטלוק
                      • כלי שסורק תמונות מסך ומחלץ מהן טקסט/טבלאות אוטומטית לאקסל
                      • מנהל קבצים חכם שמארגן תיקיות לפי תוכן בעזרת ניתוח אוטומטי

                      תבחר
                      רעיון אחד אחר (משלך, לא מהרשימה!) שלדעתך יביא לך ניצחון
                      בתחרות, כי הוא הכי שימושי, הכי מרשים טכנית, והכי מגניב ויזואלית.

                      חוקי
                      ברזל - קרא בעיון:

                      1. אתה עובד לבד, ברצף, עד הסוף. אסור לך לעצור ולשאול את המשתמש שאלות הבהרה באמצע התהליך. כל החלטת עיצוב, שם לתוכנה, פיצ'רים, צבעים - הכל עליך להחליט בעצמך ולהמשיך הלאה. אם יש התלבטות - תבחר את האפשרות הכי מקצועית ותמשיך.
                      2. שפת הממשק: עברית מלאה. כל כפתור, כל הודעה, כל טקסט בתוכנה חייב להיות בעברית (כולל תמיכה נכונה בכיווניות RTL אם רלוונטי).
                      3. התוצר הסופי חייב לרוץ על כל מחשב Windows בלי שהמשתמש הסופי יצטרך להתקין Python, Node.js, או כל תלות אחרת. התוצר הוא קובץ EXE עצמאי (standalone) שרץ פשוט בלחיצה כפולה.
                      4. לתוכנה חייב להיות אייקון (icon) מעוצב ויפה משלה - לא האייקון הדיפולטיבי. תיצור אייקון רלוונטי לנושא התוכנה (למשל כקובץ .ico מבוסס SVG/ציור שאתה יוצר, או קוד שמייצר אותו).
                      5. מותר לך להשתמש בכל דבר שתרצה - חיבור לאינטרנט, ספריות חיצוניות, API-ים - הכל מותר, כל עוד בסוף התהליך המשתמש מקבל EXE עובד.
                      6. הפלט הסופי שאתה נותן למשתמש חייב להיות בלוק קוד אחד בלבד, שהמשתמש יכול להדביק ישירות במסוף (טרמינל/PowerShell) על מחשב Windows שלו - לא קובץ שצריך לשמור ואז להריץ בנפרד. ההרצה של הבלוק הזה צריכה, מתחילתה ועד סופה, לבד:
                        • ליצור את כל קבצי הפרויקט (קוד, אייקון, קבצי תצורה)
                        • להתקין כל תלות נדרשת (pip install / npm install וכו', אם צריך - כחלק מאותה הרצה)
                        • לקמפל את הכל לקובץ EXE אחד סופי
                        • להשאיר למשתמש בסוף רק את קובץ ה-EXE המוכן, בתיקייה ברורה

                      המשתמש לא
                      יודע לתכנת ולא ידביק שום דבר נוסף חוץ מהבלוק הזה. אם צריך כמה שלבים - תשלב הכל
                      לסקריפט אחד מאסטר (PowerShell/batch)
                      שמריץ את כל שאר השלבים בעצמו.

                      1. תן לתוכנה שם מקורי, מגניב, ולוגו/זהות ברורה. זה חלק מהניקוד על "יופי".
                      2. איכות מעל מהירות. מותר לך לקחת את הזמן, לחשוב לעומק, לתכנן ארכיטקטורה נקייה, ולתת קוד מלא ועובד - לא שלד/דוגמה חלקית. המשתמש מצפה לתוכנה אמיתית שעובדת מהריצה הראשונה.

                      לפני
                      שאתה כותב קוד
                      , כתוב
                      בקצרה (2-3 שורות בלבד): מה שם התוכנה שבחרת, ומה היא עושה - ואז ישר תתחיל לבנות.
                      אל תחכה לאישור, אל תשאל שאלות. תתחיל.

                      בהצלחה -
                      תזכור, אתה מתמודד מול Claude, ChatGPT, Gemini ו-Freebuff, וכולם מקבלים את אותה משימה בדיוק. תראה
                      להם מי הכי טוב.

                      מ מנותק
                      מ מנותק
                      מוצ'
                      כתב נערך לאחרונה על ידי
                      #18

                      @YAHBDK ומי היה המנצח? 🏆

                      תגובה 1 תגובה אחרונה
                      0
                      • א מנותק
                        א מנותק
                        אהרן
                        כתב נערך לאחרונה על ידי
                        #19

                        @yahbdk זה נעשה בצ'אט או בסוכנים?

                        Y תגובה 1 תגובה אחרונה
                        0
                        • א אהרן

                          @yahbdk זה נעשה בצ'אט או בסוכנים?

                          Y מנותק
                          Y מנותק
                          YAHBDK
                          כתב נערך לאחרונה על ידי
                          #20

                          @אהרן
                          צא'ט

                          תגובה 1 תגובה אחרונה
                          1
                          • Y YAHBDK

                            @ztcebuck
                            קלוד=אופוס 5
                            גימיני=3.5 Flash-Lite
                            פריבף=DeepSeek V4.1 Flash
                            גיפיטי=אני לא יודע איפה בודקים

                            ב מנותק
                            ב מנותק
                            בינארי חכם
                            כתב נערך לאחרונה על ידי
                            #21
                            פוסט זה נמחק!
                            תגובה 1 תגובה אחרונה
                            0
                            • מ מנותק
                              מ מנותק
                              מוקד המערכות
                              כתב נערך לאחרונה על ידי
                              #22

                              עשיתי עם ג'ימיני 3.1 פרו מורחב והוא יצר לי את התוכנה הבאה (כניסוחו) :

                              "שם התוכנה: כספת אישית (SecureVault)
                              מה היא עושה: כלי מתקדם להצפנה ופענוח של קבצים מקומיים (AES-256) השומר על פרטיות מוחלטת בלחיצת כפתור, עם ממשק משתמש מודרני ואפל (Dark Mode). היא מאפשרת לנעול כל מסמך, תמונה או קובץ רגיש עם סיסמה, כך שאף אחד לא יוכל לפתוח אותם בלעדיה."

                              הקוד :

                              $ErrorActionPreference = "Stop"
                              
                              # Check if Python is installed
                              if (!(Get-Command python -ErrorAction SilentlyContinue)) {
                                  Write-Host "Error: Python is not installed or not in PATH! Please install Python from python.org, check 'Add Python to PATH', and try again." -ForegroundColor Red
                                  exit
                              }
                              
                              Write-Host "1. Creating project environment..." -ForegroundColor Cyan
                              $BuildDir = Join-Path $env:TEMP "SecureVault_Project"
                              if (Test-Path $BuildDir) { Remove-Item $BuildDir -Recurse -Force }
                              New-Item -ItemType Directory -Path $BuildDir | Out-Null
                              Set-Location $BuildDir
                              
                              Write-Host "2. Writing source code..." -ForegroundColor Cyan
                              
                              # UTF-8 Without BOM encoder to prevent Python compilation errors
                              $Utf8NoBom = New-Object System.Text.UTF8Encoding($false)
                              
                              $pyCode = @"
                              import customtkinter as ctk
                              from tkinter import filedialog, messagebox
                              import os
                              import base64
                              import hashlib
                              from cryptography.fernet import Fernet
                              import threading
                              
                              ctk.set_appearance_mode("Dark")
                              ctk.set_default_color_theme("blue")
                              
                              class SecureVaultApp(ctk.CTk):
                                  def __init__(self):
                                      super().__init__()
                                      self.title("כספת אישית - SecureVault")
                                      self.geometry("650x450")
                                      self.resizable(False, False)
                                      self.filepath = None
                                      
                                      self.lbl_title = ctk.CTkLabel(self, text="כספת אישית", font=("Segoe UI", 32, "bold"), text_color="#3498DB")
                                      self.lbl_title.pack(pady=(30, 5))
                                      
                                      self.lbl_desc = ctk.CTkLabel(self, text="הצפנת קבצים מאובטחת - AES 256", font=("Segoe UI", 16))
                                      self.lbl_desc.pack(pady=(0, 40))
                                      
                                      self.frame_file = ctk.CTkFrame(self, fg_color="transparent")
                                      self.frame_file.pack(pady=10, fill="x", padx=60)
                                      
                                      self.btn_select = ctk.CTkButton(self.frame_file, text="📁 בחירת קובץ", font=("Segoe UI", 16, "bold"), command=self.select_file, width=120)
                                      self.btn_select.pack(side="right", padx=10)
                                      
                                      self.lbl_file = ctk.CTkLabel(self.frame_file, text="...לא נבחר קובץ", font=("Segoe UI", 14), fg_color="#2C3E50", corner_radius=6, padding=[10, 5])
                                      self.lbl_file.pack(side="right", fill="x", expand=True)
                                      
                                      self.frame_pass = ctk.CTkFrame(self, fg_color="transparent")
                                      self.frame_pass.pack(pady=25, fill="x", padx=60)
                                      
                                      self.lbl_pass = ctk.CTkLabel(self.frame_pass, text=":סיסמה", font=("Segoe UI", 18, "bold"))
                                      self.lbl_pass.pack(side="right", padx=10)
                                      
                                      self.entry_pass = ctk.CTkEntry(self.frame_pass, show="●", font=("Segoe UI", 18), justify="right", height=40)
                                      self.entry_pass.pack(side="right", fill="x", expand=True)
                                      
                                      self.frame_actions = ctk.CTkFrame(self, fg_color="transparent")
                                      self.frame_actions.pack(pady=30)
                                      
                                      self.btn_encrypt = ctk.CTkButton(self.frame_actions, text="🔒 הצפן קובץ", font=("Segoe UI", 18, "bold"), fg_color="#E74C3C", hover_color="#C0392B", width=160, height=45, command=lambda: self.process("encrypt"))
                                      self.btn_encrypt.pack(side="right", padx=15)
                                      
                                      self.btn_decrypt = ctk.CTkButton(self.frame_actions, text="🔓 פענח קובץ", font=("Segoe UI", 18, "bold"), fg_color="#2ECC71", hover_color="#27AE60", width=160, height=45, command=lambda: self.process("decrypt"))
                                      self.btn_decrypt.pack(side="left", padx=15)
                                      
                                      self.lbl_status = ctk.CTkLabel(self, text="", font=("Segoe UI", 15, "bold"))
                                      self.lbl_status.pack(pady=5)
                              
                                  def select_file(self):
                                      path = filedialog.askopenfilename(title="בחר קובץ")
                                      if path:
                                          self.filepath = path
                                          display_name = os.path.basename(path)
                                          self.lbl_file.configure(text=display_name)
                                          self.lbl_status.configure(text="")
                              
                                  def get_fernet(self, password):
                                      key = hashlib.sha256(password.encode()).digest()
                                      return Fernet(base64.urlsafe_b64encode(key))
                              
                                  def process(self, action):
                                      if not self.filepath:
                                          messagebox.showerror("שגיאה", "אנא בחר קובץ תחילה.")
                                          return
                                      pwd = self.entry_pass.get()
                                      if not pwd:
                                          messagebox.showerror("שגיאה", "אנא הכנס סיסמה.")
                                          return
                                      
                                      self.lbl_status.configure(text="...מעבד קובץ, אנא המתן", text_color="#F1C40F")
                                      self.btn_encrypt.configure(state="disabled")
                                      self.btn_decrypt.configure(state="disabled")
                                      self.update()
                                      
                                      threading.Thread(target=self._process_file, args=(action, pwd), daemon=True).start()
                              
                                  def _process_file(self, action, pwd):
                                      try:
                                          fernet = self.get_fernet(pwd)
                                          with open(self.filepath, "rb") as f:
                                              data = f.read()
                                          
                                          if action == "encrypt":
                                              processed_data = fernet.encrypt(data)
                                              out_path = self.filepath + ".vault"
                                              success_msg = "הקובץ הוצפן בהצלחה!"
                                          else:
                                              processed_data = fernet.decrypt(data)
                                              if self.filepath.endswith(".vault"):
                                                  out_path = self.filepath[:-6]
                                              else:
                                                  out_path = self.filepath + ".decrypted"
                                              
                                              if os.path.exists(out_path):
                                                  name, ext = os.path.splitext(out_path)
                                                  out_path = f"{name}_decrypted{ext}"
                                                  
                                              success_msg = "הקובץ פוענח בהצלחה!"
                                          
                                          with open(out_path, "wb") as f:
                                              f.write(processed_data)
                                              
                                          self.after(0, lambda: self._on_success(success_msg, out_path))
                                          
                                      except Exception as e:
                                          err_msg = "שגיאת פענוח! סיסמה שגויה או קובץ פגום." if action == "decrypt" else f"שגיאה: {str(e)}"
                                          self.after(0, lambda: self._on_error(err_msg))
                              
                                  def _on_success(self, msg, path):
                                      self.lbl_status.configure(text=msg, text_color="#2ECC71")
                                      self.btn_encrypt.configure(state="normal")
                                      self.btn_decrypt.configure(state="normal")
                                      self.entry_pass.delete(0, 'end')
                                      messagebox.showinfo("פעולה הושלמה", f"{msg}\n\nנשמר במיקום:\n{path}")
                              
                                  def _on_error(self, msg):
                                      self.lbl_status.configure(text="הפעולה נכשלה", text_color="#E74C3C")
                                      self.btn_encrypt.configure(state="normal")
                                      self.btn_decrypt.configure(state="normal")
                                      messagebox.showerror("שגיאה", msg)
                              
                              if __name__ == "__main__":
                                  app = SecureVaultApp()
                                  app.mainloop()
                              "@
                              [IO.File]::WriteAllText("app.py", $pyCode, $Utf8NoBom)
                              
                              $iconCode = @"
                              from PIL import Image, ImageDraw
                              img = Image.new('RGBA', (256, 256), color=(0, 0, 0, 0))
                              d = ImageDraw.Draw(img)
                              # Shield Background
                              d.polygon([(128, 15), (235, 55), (235, 145), (128, 245), (21, 145), (21, 55)], fill="#2980B9", outline="#1A5276", width=8)
                              # Lock Body
                              d.rounded_rectangle([(85, 120), (171, 190)], radius=15, fill="#F1C40F", outline="#B7950B", width=6)
                              # Lock Shackle
                              d.arc([(105, 80), (151, 130)], start=180, end=0, fill="#ECF0F1", width=12)
                              # Keyhole
                              d.ellipse([(121, 140), (135, 154)], fill="#2C3E50")
                              d.polygon([(125, 150), (131, 150), (135, 175), (121, 175)], fill="#2C3E50")
                              img.save('icon.ico', format='ICO', sizes=[(256, 256)])
                              "@
                              [IO.File]::WriteAllText("make_icon.py", $iconCode, $Utf8NoBom)
                              
                              Write-Host "3. Installing dependencies (CustomTkinter, Cryptography, Pillow, PyInstaller)..." -ForegroundColor Cyan
                              python -m pip install --upgrade pip > $null
                              python -m pip install customtkinter cryptography pillow pyinstaller
                              
                              Write-Host "4. Generating beautiful vector icon..." -ForegroundColor Cyan
                              python make_icon.py
                              
                              Write-Host "5. Compiling to a standalone Windows EXE (This usually takes 1-2 minutes, please wait)..." -ForegroundColor Yellow
                              python -m PyInstaller --noconfirm --onefile --windowed --icon "icon.ico" --name "SecureVault" "app.py"
                              
                              Write-Host "6. Moving application to Desktop..." -ForegroundColor Cyan
                              $DesktopPath = [Environment]::GetFolderPath("Desktop")
                              $ExePath = Join-Path $BuildDir "dist\SecureVault.exe"
                              Move-Item -Path $ExePath -Destination $DesktopPath -Force
                              
                              Write-Host ""
                              Write-Host "=======================================================" -ForegroundColor Green
                              Write-Host " SUCCESS! The application is ready!" -ForegroundColor Green
                              Write-Host " Look for 'SecureVault.exe' on your Desktop." -ForegroundColor Green
                              Write-Host "=======================================================" -ForegroundColor Green
                              
                              F תגובה 1 תגובה אחרונה
                              1
                              • Y YAHBDK

                                @ztcebuck
                                קלוד=אופוס 5
                                גימיני=3.5 Flash-Lite
                                פריבף=DeepSeek V4.1 Flash
                                גיפיטי=אני לא יודע איפה בודקים

                                ב מנותק
                                ב מנותק
                                בינארי חכם
                                כתב נערך לאחרונה על ידי
                                #23

                                @YAHBDK כתב:

                                3.5 Flash-Lite

                                אין השוואת כוחות כלל הוא לא עשוי לקוד או לדברים מסובכים
                                ואתה חייב לנסות את 3.8
                                באנטי גרוונטי לא בצ'אט שבצ'אט הוא מוגבל לזמן חשיבה וגם במהירות
                                ותאשר להם לעבוד עם בוטים פנימיים

                                נתתי את זה ל3.8 באנטי גרוונטי וזה התוצאה

                                שם התוכנה: OmniDrop Pro (אומני-דרופ) מה היא עושה: גשר אלחוטי מקומי, מהיר ומאובטח להעברת קבצים ללא הגבלת נפח, סנכרון לוח עתק-הדבק בזמן אמת, תיקון מקלדת הפוכה (ג'יבריש) ומגן פרטיות להסרת נתוני מיקום GPS מתמונות – ישירות בין המחשב לכל סמארטפון (iPhone / Android) ברשת המקומית, באמצעות סריקת קוד QR פשוטה וללא צורך בהתקנת אפליקציה כלשהי בטלפון!

                                # .txt

                                אשמח עם מישהו יכול לבדוק שזה עובד...

                                תגובה 1 תגובה אחרונה
                                3
                                • Y YAHBDK

                                  @ztcebuck
                                  קלוד=אופוס 5
                                  גימיני=3.5 Flash-Lite
                                  פריבף=DeepSeek V4.1 Flash
                                  גיפיטי=אני לא יודע איפה בודקים

                                  מ מנותק
                                  מ מנותק
                                  מוקד המערכות
                                  כתב נערך לאחרונה על ידי
                                  #24

                                  @YAHBDK כתב:

                                  גימיני=3.5 Flash-Lite

                                  אהבל בכתיבת קודים ובכלל !

                                  מטען ניידמ תגובה 1 תגובה אחרונה
                                  😂
                                  0
                                  • מ מוקד המערכות

                                    @YAHBDK כתב:

                                    גימיני=3.5 Flash-Lite

                                    אהבל בכתיבת קודים ובכלל !

                                    מטען ניידמ מנותק
                                    מטען ניידמ מנותק
                                    מטען נייד
                                    כתב נערך לאחרונה על ידי
                                    #25

                                    @מוקד-המערכות בסוף‌​‌‌​‌​​​​​‌ הוא יעלב ובכלל ישבש אותך, זהירות

                                    "לאהוב הכל, לחבק ולמחול-כי החיים חזקים מהכל"

                                    מ תגובה 1 תגובה אחרונה
                                    0
                                    • מטען ניידמ מטען נייד

                                      @מוקד-המערכות בסוף‌​‌‌​‌​​​​​‌ הוא יעלב ובכלל ישבש אותך, זהירות

                                      מ מנותק
                                      מ מנותק
                                      מוקד המערכות
                                      כתב נערך לאחרונה על ידי מוקד המערכות
                                      #26

                                      @מטען-נייד כתב:

                                      ובכלל ישבש אותך,

                                      שינסה...

                                      לא מציע לו...

                                      תגובה 1 תגובה אחרונה
                                      🤖 🤦
                                      1
                                      • מ מוקד המערכות

                                        עשיתי עם ג'ימיני 3.1 פרו מורחב והוא יצר לי את התוכנה הבאה (כניסוחו) :

                                        "שם התוכנה: כספת אישית (SecureVault)
                                        מה היא עושה: כלי מתקדם להצפנה ופענוח של קבצים מקומיים (AES-256) השומר על פרטיות מוחלטת בלחיצת כפתור, עם ממשק משתמש מודרני ואפל (Dark Mode). היא מאפשרת לנעול כל מסמך, תמונה או קובץ רגיש עם סיסמה, כך שאף אחד לא יוכל לפתוח אותם בלעדיה."

                                        הקוד :

                                        $ErrorActionPreference = "Stop"
                                        
                                        # Check if Python is installed
                                        if (!(Get-Command python -ErrorAction SilentlyContinue)) {
                                            Write-Host "Error: Python is not installed or not in PATH! Please install Python from python.org, check 'Add Python to PATH', and try again." -ForegroundColor Red
                                            exit
                                        }
                                        
                                        Write-Host "1. Creating project environment..." -ForegroundColor Cyan
                                        $BuildDir = Join-Path $env:TEMP "SecureVault_Project"
                                        if (Test-Path $BuildDir) { Remove-Item $BuildDir -Recurse -Force }
                                        New-Item -ItemType Directory -Path $BuildDir | Out-Null
                                        Set-Location $BuildDir
                                        
                                        Write-Host "2. Writing source code..." -ForegroundColor Cyan
                                        
                                        # UTF-8 Without BOM encoder to prevent Python compilation errors
                                        $Utf8NoBom = New-Object System.Text.UTF8Encoding($false)
                                        
                                        $pyCode = @"
                                        import customtkinter as ctk
                                        from tkinter import filedialog, messagebox
                                        import os
                                        import base64
                                        import hashlib
                                        from cryptography.fernet import Fernet
                                        import threading
                                        
                                        ctk.set_appearance_mode("Dark")
                                        ctk.set_default_color_theme("blue")
                                        
                                        class SecureVaultApp(ctk.CTk):
                                            def __init__(self):
                                                super().__init__()
                                                self.title("כספת אישית - SecureVault")
                                                self.geometry("650x450")
                                                self.resizable(False, False)
                                                self.filepath = None
                                                
                                                self.lbl_title = ctk.CTkLabel(self, text="כספת אישית", font=("Segoe UI", 32, "bold"), text_color="#3498DB")
                                                self.lbl_title.pack(pady=(30, 5))
                                                
                                                self.lbl_desc = ctk.CTkLabel(self, text="הצפנת קבצים מאובטחת - AES 256", font=("Segoe UI", 16))
                                                self.lbl_desc.pack(pady=(0, 40))
                                                
                                                self.frame_file = ctk.CTkFrame(self, fg_color="transparent")
                                                self.frame_file.pack(pady=10, fill="x", padx=60)
                                                
                                                self.btn_select = ctk.CTkButton(self.frame_file, text="📁 בחירת קובץ", font=("Segoe UI", 16, "bold"), command=self.select_file, width=120)
                                                self.btn_select.pack(side="right", padx=10)
                                                
                                                self.lbl_file = ctk.CTkLabel(self.frame_file, text="...לא נבחר קובץ", font=("Segoe UI", 14), fg_color="#2C3E50", corner_radius=6, padding=[10, 5])
                                                self.lbl_file.pack(side="right", fill="x", expand=True)
                                                
                                                self.frame_pass = ctk.CTkFrame(self, fg_color="transparent")
                                                self.frame_pass.pack(pady=25, fill="x", padx=60)
                                                
                                                self.lbl_pass = ctk.CTkLabel(self.frame_pass, text=":סיסמה", font=("Segoe UI", 18, "bold"))
                                                self.lbl_pass.pack(side="right", padx=10)
                                                
                                                self.entry_pass = ctk.CTkEntry(self.frame_pass, show="●", font=("Segoe UI", 18), justify="right", height=40)
                                                self.entry_pass.pack(side="right", fill="x", expand=True)
                                                
                                                self.frame_actions = ctk.CTkFrame(self, fg_color="transparent")
                                                self.frame_actions.pack(pady=30)
                                                
                                                self.btn_encrypt = ctk.CTkButton(self.frame_actions, text="🔒 הצפן קובץ", font=("Segoe UI", 18, "bold"), fg_color="#E74C3C", hover_color="#C0392B", width=160, height=45, command=lambda: self.process("encrypt"))
                                                self.btn_encrypt.pack(side="right", padx=15)
                                                
                                                self.btn_decrypt = ctk.CTkButton(self.frame_actions, text="🔓 פענח קובץ", font=("Segoe UI", 18, "bold"), fg_color="#2ECC71", hover_color="#27AE60", width=160, height=45, command=lambda: self.process("decrypt"))
                                                self.btn_decrypt.pack(side="left", padx=15)
                                                
                                                self.lbl_status = ctk.CTkLabel(self, text="", font=("Segoe UI", 15, "bold"))
                                                self.lbl_status.pack(pady=5)
                                        
                                            def select_file(self):
                                                path = filedialog.askopenfilename(title="בחר קובץ")
                                                if path:
                                                    self.filepath = path
                                                    display_name = os.path.basename(path)
                                                    self.lbl_file.configure(text=display_name)
                                                    self.lbl_status.configure(text="")
                                        
                                            def get_fernet(self, password):
                                                key = hashlib.sha256(password.encode()).digest()
                                                return Fernet(base64.urlsafe_b64encode(key))
                                        
                                            def process(self, action):
                                                if not self.filepath:
                                                    messagebox.showerror("שגיאה", "אנא בחר קובץ תחילה.")
                                                    return
                                                pwd = self.entry_pass.get()
                                                if not pwd:
                                                    messagebox.showerror("שגיאה", "אנא הכנס סיסמה.")
                                                    return
                                                
                                                self.lbl_status.configure(text="...מעבד קובץ, אנא המתן", text_color="#F1C40F")
                                                self.btn_encrypt.configure(state="disabled")
                                                self.btn_decrypt.configure(state="disabled")
                                                self.update()
                                                
                                                threading.Thread(target=self._process_file, args=(action, pwd), daemon=True).start()
                                        
                                            def _process_file(self, action, pwd):
                                                try:
                                                    fernet = self.get_fernet(pwd)
                                                    with open(self.filepath, "rb") as f:
                                                        data = f.read()
                                                    
                                                    if action == "encrypt":
                                                        processed_data = fernet.encrypt(data)
                                                        out_path = self.filepath + ".vault"
                                                        success_msg = "הקובץ הוצפן בהצלחה!"
                                                    else:
                                                        processed_data = fernet.decrypt(data)
                                                        if self.filepath.endswith(".vault"):
                                                            out_path = self.filepath[:-6]
                                                        else:
                                                            out_path = self.filepath + ".decrypted"
                                                        
                                                        if os.path.exists(out_path):
                                                            name, ext = os.path.splitext(out_path)
                                                            out_path = f"{name}_decrypted{ext}"
                                                            
                                                        success_msg = "הקובץ פוענח בהצלחה!"
                                                    
                                                    with open(out_path, "wb") as f:
                                                        f.write(processed_data)
                                                        
                                                    self.after(0, lambda: self._on_success(success_msg, out_path))
                                                    
                                                except Exception as e:
                                                    err_msg = "שגיאת פענוח! סיסמה שגויה או קובץ פגום." if action == "decrypt" else f"שגיאה: {str(e)}"
                                                    self.after(0, lambda: self._on_error(err_msg))
                                        
                                            def _on_success(self, msg, path):
                                                self.lbl_status.configure(text=msg, text_color="#2ECC71")
                                                self.btn_encrypt.configure(state="normal")
                                                self.btn_decrypt.configure(state="normal")
                                                self.entry_pass.delete(0, 'end')
                                                messagebox.showinfo("פעולה הושלמה", f"{msg}\n\nנשמר במיקום:\n{path}")
                                        
                                            def _on_error(self, msg):
                                                self.lbl_status.configure(text="הפעולה נכשלה", text_color="#E74C3C")
                                                self.btn_encrypt.configure(state="normal")
                                                self.btn_decrypt.configure(state="normal")
                                                messagebox.showerror("שגיאה", msg)
                                        
                                        if __name__ == "__main__":
                                            app = SecureVaultApp()
                                            app.mainloop()
                                        "@
                                        [IO.File]::WriteAllText("app.py", $pyCode, $Utf8NoBom)
                                        
                                        $iconCode = @"
                                        from PIL import Image, ImageDraw
                                        img = Image.new('RGBA', (256, 256), color=(0, 0, 0, 0))
                                        d = ImageDraw.Draw(img)
                                        # Shield Background
                                        d.polygon([(128, 15), (235, 55), (235, 145), (128, 245), (21, 145), (21, 55)], fill="#2980B9", outline="#1A5276", width=8)
                                        # Lock Body
                                        d.rounded_rectangle([(85, 120), (171, 190)], radius=15, fill="#F1C40F", outline="#B7950B", width=6)
                                        # Lock Shackle
                                        d.arc([(105, 80), (151, 130)], start=180, end=0, fill="#ECF0F1", width=12)
                                        # Keyhole
                                        d.ellipse([(121, 140), (135, 154)], fill="#2C3E50")
                                        d.polygon([(125, 150), (131, 150), (135, 175), (121, 175)], fill="#2C3E50")
                                        img.save('icon.ico', format='ICO', sizes=[(256, 256)])
                                        "@
                                        [IO.File]::WriteAllText("make_icon.py", $iconCode, $Utf8NoBom)
                                        
                                        Write-Host "3. Installing dependencies (CustomTkinter, Cryptography, Pillow, PyInstaller)..." -ForegroundColor Cyan
                                        python -m pip install --upgrade pip > $null
                                        python -m pip install customtkinter cryptography pillow pyinstaller
                                        
                                        Write-Host "4. Generating beautiful vector icon..." -ForegroundColor Cyan
                                        python make_icon.py
                                        
                                        Write-Host "5. Compiling to a standalone Windows EXE (This usually takes 1-2 minutes, please wait)..." -ForegroundColor Yellow
                                        python -m PyInstaller --noconfirm --onefile --windowed --icon "icon.ico" --name "SecureVault" "app.py"
                                        
                                        Write-Host "6. Moving application to Desktop..." -ForegroundColor Cyan
                                        $DesktopPath = [Environment]::GetFolderPath("Desktop")
                                        $ExePath = Join-Path $BuildDir "dist\SecureVault.exe"
                                        Move-Item -Path $ExePath -Destination $DesktopPath -Force
                                        
                                        Write-Host ""
                                        Write-Host "=======================================================" -ForegroundColor Green
                                        Write-Host " SUCCESS! The application is ready!" -ForegroundColor Green
                                        Write-Host " Look for 'SecureVault.exe' on your Desktop." -ForegroundColor Green
                                        Write-Host "=======================================================" -ForegroundColor Green
                                        
                                        F מנותק
                                        F מנותק
                                        fhryurygfgdf
                                        כתב נערך לאחרונה על ידי
                                        #27

                                        @מוקד-המערכות כתב:

                                        "שם התוכנה: כספת אישית (SecureVault)
                                        מה היא עושה: כלי מתקדם להצפנה ופענוח של קבצים מקומיים (AES-256) השומר על פרטיות מוחלטת בלחיצת כפתור, עם ממשק משתמש מודרני ואפל (Dark Mode). היא מאפשרת לנעול כל מסמך, תמונה או קובץ רגיש עם סיסמה, כך שאף אחד לא יוכל לפתוח אותם בלעדיה."

                                        לא הבנתי מה עושים עם הקוד הלאה,איזה כלי יוצר את התוכנה עצמה ?

                                        תגובה 1 תגובה אחרונה
                                        2

                                        שלום! נראה שהשיחה הזו מעניינת אותך, אבל עדיין אין לך חשבון.

                                        נמאס לכם לגלול בין אותם הפוסטים בכל ביקור? כשנרשמים לחשבון, תמיד תחזרו בדיוק למקום שבו הייתם קודם, ותוכלו לבחור לקבל התראות על תגובות חדשות (בין אם במייל, ובין אם בהתראת פוש). תוכלו גם לשמור סימניות ולפרגן ב-upvote לפוסטים כדי להביע הערכה לחברי קהילה אחרים.

                                        בעזרת התרומה שלך, הפוסט הזה יכול להיות אפילו טוב יותר 💗

                                        הרשמה התחברות

                                        • התחברות

                                        • אין לך חשבון עדיין? הרשמה

                                        • התחברו או הירשמו כדי לחפש.
                                        • פוסט ראשון
                                          פוסט אחרון
                                        0
                                        • חוקי הפורום
                                        • פופולרי
                                        • לא נפתר
                                        • משתמשים
                                        • חיפוש גוגל בפורום
                                        • צור קשר