דילוג לתוכן
  • חוקי הפורום
  • פופולרי
  • לא נפתר
  • משתמשים
  • חיפוש גוגל בפורום
  • צור קשר
עיצובים
  • בהיר
  • 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

  • ברירת מחדל (ללא עיצוב (ברירת מחדל))
  • ללא עיצוב (ברירת מחדל)
כיווץ
מתמחים טופ
מ

מוטל 2

@מוטל 2
הפסקת מעקב מעקב
אודות
פוסטים
264
נושאים
14
שיתופים
0
קבוצות
0
עוקבים
2
עוקב אחרי
2

פוסטים

פוסטים אחרונים הגבוה ביותר שנוי במחלוקת

  • המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!
    מ מוטל 2

    @fhryurygfgdf
    לא ראיתי, זה כנראה היה ביחד
    תבדוק בפוסטים הקודמים מהפוסט בקישור והלאה...

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!
    מ מוטל 2

    @fhryurygfgdf
    לא !!!!
    בקשתי ממנו שיעדכן את הקוד בפוסט הראשון..
    ומה איתך, הצלחת?

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!
    מ מוטל 2

    @יודע-ומייבין
    אולי תעדכן כבר את הקוד בסקריפט שלך...

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!
    מ מוטל 2

    @fhryurygfgdf
    תעדכן את הקוד שאני כתבתי
    בפוסט זה
    https://mitmachim.top/post/1236183

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!
    מ מוטל 2

    @fhryurygfgdf
    איזה קוד מעודכן אצלך?

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!
    מ מוטל 2

    @יודע-ומייבין
    בהצלחה!!!!!
    ותודה רבה.
    אני לא מתמצא באנדרואיד כלל...

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!
    מ מוטל 2

    @fhryurygfgdf בהגדרות התוספים

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!
    מ מוטל 2

    @fhryurygfgdf
    https://mitmachim.top/post/1236480

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!
    מ מוטל 2

    @7090866
    מעניין, כנראה תקלה טכנית אצלך עכשיו בפורום..
    קרה לעוד מישהו?

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!
    מ מוטל 2

    @ברווז-הסגול
    איזה קוד התקנת?

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!
    מ מוטל 2

    @משה-הצדיק
    אשרת את זה?
    b2abdd32-e693-40d3-bdf0-f07b9913477e-image.jpeg

    עזרה הדדית - מחשבים וטכנולוגיה

  • שיתוף | תוסף דפדפן לקבלת SMS ממערכת ימות המשיח
    מ מוטל 2

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

    תודה רבה...

    מערכות IVR - ימות המשיח

  • המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!
    מ מוטל 2

    @רפאל-0 הסתדרת?

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!
    מ מוטל 2

    @YOLEVI
    גם אני מנוטפר
    תמחק את הקוד שם ותעתיק את זה או שתפתח סקריפט חדש
    9dcffd68-857f-450f-8add-5e449cf41bd4-image.jpeg
    תעשה שמור, ולאח"מ תרענן את הדף של מתמחים...

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!
    מ מוטל 2

    @YOLEVI
    https://mitmachim.top/post/1236183

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!
    מ מוטל 2

    @יאיר-דניאל
    להיפך מטרתו לנתח את השאלה שלך ולענות
    ולא להטיף לך מוסר....

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!
    מ מוטל 2

    @יודע-ומייבין
    אני מחזיר את הפוסט

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!
    מ מוטל 2

    @מה-זה-משנה-אה
    מה הבעיה שזה עשה לך?

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!
    מ מוטל 2

    @יודע-ומייבין

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

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🤖 עוזר AI חדש לפורום - עונה תוך שניות, מכיר את מתמחים טופ מבפנים!
    מ מוטל 2

    שלום וברכה,

    כיון שזה היה חשוב לי, ישבתי על הקוד שלו שעות, וב"ה הצלחתי לעשות לו שטיפת מוח, כולל כמה וכמה שיפורים {כגון הסטוריית בקשות, וקישורים לחיצים וכן אפשרות לגרור את החלון ממקום למקום, וכן הוספתי אפשרות להוספת קבצים או תמונות לדיוק השאלה או הבקשה}.

    הקוד המתוקן בספויילר:

    // ==UserScript==
    // @name         מתמחים טופ + בינה טופ - עוזר AI מושלם עם תמיכה בקבצים, תמונות והדבקה ישירה
    // @namespace    https://mitmachim.top/
    // @version      23.0.0
    // @description  עוזר AI צף עם תמיכה בצירוף והדבקת קבצים ותמונות, חיפוש משתמשים ואשכולות, היסטוריית שיחות וגרירת חלון
    // @author       you
    // @match        https://mitmachim.top/*
    // @match        https://bina.top/*
    // @icon         https://mitmachim.top/favicon.ico
    // @grant        GM_setValue
    // @grant        GM_getValue
    // @grant        GM_registerMenuCommand
    // @grant        GM_xmlhttpRequest
    // @connect      generativelanguage.googleapis.com
    // @connect      mitmachim.top
    // @connect      bina.top
    // @run-at       document-end
    // ==/UserScript==
    
    (function () {
      'use strict';
    
      function getSiteOrigin() {
        const host = location.hostname.toLowerCase();
        if (host === 'bina.top' || host.endsWith('.bina.top')) {
          return 'https://bina.top';
        }
        return 'https://mitmachim.top';
      }
    
      const SITE_ORIGIN = getSiteOrigin();
      const SITE_HOST = new URL(SITE_ORIGIN).hostname;
    
      const K = {
        apiKey: 'mt_ai_gemini_key',
        context: 'mt_ai_context',
        persona: 'mt_ai_persona',
        sessions: 'mt_ai_sessions_list',
        currentSessionId: 'mt_ai_current_session_id'
      };
    
      const get = (k, d = '') => GM_getValue(k, d);
      const set = (k, v) => GM_setValue(k, v);
    
      function request(details) {
        return new Promise((resolve, reject) => {
          GM_xmlhttpRequest({
            ...details,
            onload: resolve,
            onerror: () => reject(new Error('שגיאת רשת')),
            ontimeout: () => reject(new Error('זמן קצוב עבר'))
          });
        });
      }
    
      async function fetchText(url) {
        const res = await request({ method: 'GET', url, timeout: 25000 });
        if (res.status < 200 || res.status >= 300) throw new Error('שגיאה בטעינת נתונים');
        return res.responseText;
      }
    
      function htmlToText(root) {
        if (!root) return '';
        const clone = root.cloneNode(true);
        clone.querySelectorAll('script,style').forEach(x => x.remove());
        clone.querySelectorAll('a[href]').forEach(a => {
          try {
            const href = new URL(a.getAttribute('href'), SITE_ORIGIN).href;
            const label = (a.textContent || '').trim();
            const replacement = label && label !== href ? `${label} (${href})` : href;
            a.replaceWith(document.createTextNode(' ' + replacement + ' '));
          } catch {}
        });
        clone.querySelectorAll('br').forEach(br => br.replaceWith(document.createTextNode('\n')));
        clone.querySelectorAll('p,div,li,blockquote,tr,h1,h2,h3,h4,h5,h6').forEach(b => {
          b.appendChild(document.createTextNode('\n'));
        });
        return (clone.textContent || '')
          .replace(/[ \t]+/g, ' ')
          .replace(/ *\n */g, '\n')
          .replace(/\n{3,}/g, '\n\n')
          .trim();
      }
    
      function extractSearchHits(data) {
        const arr = data?.posts || data?.matches || data?.results || [];
        if (!Array.isArray(arr)) return [];
        return arr.map(p => {
          const topic = p.topic || p;
          const title = topic?.title || p.title || '(ללא כותרת)';
          const slug = topic?.slug || p.slug;
          const tid = topic?.tid || p.tid;
          let url = '';
          if (slug) url = `${SITE_ORIGIN}/topic/${slug}`;
          else if (tid) url = `${SITE_ORIGIN}/topic/${tid}`;
          return { title, url };
        }).filter(h => h.url);
      }
    
      async function legacySearchScrape(query) {
        try {
          const url = `${SITE_ORIGIN}/search?term=${encodeURIComponent(query)}`;
          const html = await fetchText(url);
          const doc = new DOMParser().parseFromString(html, 'text/html');
          doc.querySelectorAll('script,style,nav,header,footer').forEach(x => x.remove());
          const results = [];
          doc.querySelectorAll('a[href*="/topic/"]').forEach(a => {
            if (results.length >= 6) return;
            const href = a.getAttribute('href');
            const text = (a.textContent || '').trim();
            if (href && text && text.length > 3) {
              try {
                const absolute = new URL(href, url).href;
                if (!results.some(r => r.url === absolute)) {
                  results.push({ title: text, url: absolute });
                }
              } catch {}
            }
          });
          return results;
        } catch {
          return [];
        }
      }
    
      async function searchUserProfile(query) {
        query = String(query || '').trim();
        if (!query) return '';
        try {
          const apiUrl = `${SITE_ORIGIN}/api/users?query=${encodeURIComponent(query)}&page=1`;
          const raw = await fetchText(apiUrl);
          const data = JSON.parse(raw);
          const users = data?.users || [];
          if (!users.length) return '';
    
          let block = `משתמשים שנמצאו בפורום עבור "${query}":\n\n`;
          users.slice(0, 5).forEach(u => {
            const username = u.username || 'לא ידוע';
            const fullname = u.fullname ? ` (${u.fullname})` : '';
            const reputation = u.reputation !== undefined ? u.reputation : 'לא ידוע';
            const postCount = u.postcount !== undefined ? u.postcount : 'לא ידוע';
            const profileUrl = `${SITE_ORIGIN}/user/${u.userslug || username}`;
            block += `- משתמש: ${username}${fullname}\n  קישור לפרופיל: ${profileUrl}\n  מוניטין: ${reputation} | הודעות: ${postCount}\n\n`;
          });
          return block;
        } catch {
          return '';
        }
      }
    
      async function quickForumSearch(query) {
        query = String(query || '').trim();
        if (!query) return '';
    
        let userBlock = '';
        if (query.includes('משתמש') || query.includes('פרופיל') || query.includes('מוניטין')) {
          const cleanName = query.replace(/משתמש|פרופיל|מוניטין|של/g, '').trim();
          if (cleanName) {
            userBlock = await searchUserProfile(cleanName);
          }
        }
    
        let hits = [];
        try {
          const apiUrl = `${SITE_ORIGIN}/api/search?term=${encodeURIComponent(query)}`;
          const raw = await fetchText(apiUrl);
          const data = JSON.parse(raw);
          hits = extractSearchHits(data);
        } catch {
          hits = [];
        }
    
        if (!hits.length) {
          hits = await legacySearchScrape(query);
        }
    
        let block = userBlock ? userBlock + '\n' : '';
    
        if (hits.length > 0) {
          const seen = new Set();
          const uniqueHits = hits.filter(h => {
            if (seen.has(h.url)) return false;
            seen.add(h.url);
            return true;
          });
    
          const topResults = uniqueHits.slice(0, 3);
          const enriched = await Promise.all(topResults.map(async r => {
            const snippet = await fetchTopicSnippet(r.url);
            return { ...r, snippet };
          }));
    
          block += `תוצאות חיפוש אשכולות בפורום ${SITE_HOST} עבור "${query}":\n\n`;
          enriched.forEach((r, i) => {
            block += `--- נושא ${i + 1}: ${r.title} ---\nקישור מלא: ${r.url}\n`;
            block += r.snippet ? `תוכן הנושא:\n${r.snippet}\n\n` : '(לא ניתן היה לשלוף את תוכן הנושא)\n\n';
          });
        }
    
        return block;
      }
    
      async function fetchTopicSnippet(url, maxChars = 1400) {
        try {
          const html = await fetchText(url);
          const doc = new DOMParser().parseFromString(html, 'text/html');
          doc.querySelectorAll('script,style,nav,header,footer,aside,form').forEach(x => x.remove());
    
          const postEls = Array.from(doc.querySelectorAll('[component="post"]'));
          let text = '';
    
          if (postEls.length) {
            const parts = postEls.slice(0, 8).map((post, i) => {
              const contentEl = post.querySelector('[component="post/content"]') || post;
              const authorEl = post.querySelector('[component="user/username"]') || post.querySelector('a[href*="/user/"]');
              const author = authorEl ? authorEl.textContent.trim() : '';
              const postText = htmlToText(contentEl);
              return postText ? `[פוסט ${i + 1}${author ? ' מאת ' + author : ''}]\n${postText}` : '';
            }).filter(Boolean);
            text = parts.join('\n\n');
          }
    
          if (!text) {
            const container = doc.querySelector('[component="topic"]') || doc.querySelector('main') || doc.body;
            text = htmlToText(container);
          }
    
          if (text.length > maxChars) text = text.slice(0, maxChars) + '\n...[הטקסט קוצץ]';
          return text;
        } catch {
          return '';
        }
      }
    
      function getPageContext() {
        try {
          const main = document.querySelector('[component="topic"]') || document.querySelector('main') || document.body;
          let text = htmlToText(main);
          if (text.length > 1500) {
            text = text.slice(0, 1500) + '\n...[הטקסט קוצץ]';
          }
          return `אתר: ${SITE_HOST}\nכותרת: ${document.title}\nתוכן העמוד:\n${text}`;
        } catch {
          return '';
        }
      }
    
      const MODEL_CANDIDATES = ['gemini-3.6-flash', 'gemini-3.5-flash-lite', 'gemini-2.5-flash-lite'];
    
      function sleep(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
      }
    
      async function callGeminiWithModel(model, key, body) {
        const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${encodeURIComponent(key)}`;
    
        const res = await request({
          method: 'POST',
          url,
          headers: { 'Content-Type': 'application/json' },
          data: JSON.stringify(body),
          timeout: 30000
        });
    
        let data;
        try {
          data = JSON.parse(res.responseText);
        } catch {
          throw new Error('תשובת השרת אינה תקינה.');
        }
    
        if (res.status < 200 || res.status >= 300) {
          const err = new Error(data?.error?.message || `שגיאה (${res.status})`);
          err.status = res.status;
          throw err;
        }
    
        const parts = data?.candidates?.[0]?.content?.parts || [];
        const answer = parts.filter(p => !p.thought).map(p => p.text || '').join('');
    
        const finishReason = data?.candidates?.[0]?.finishReason;
        if (finishReason === 'MAX_TOKENS' && answer.trim()) {
          return answer + '\n\n⚠️ (התשובה נקטעה עקב מגבלת אורך)';
        }
    
        return answer || '(לא התקבלה תשובה)';
      }
    
      async function callGemini(history, searchResults) {
        const key = get(K.apiKey, '').trim();
        if (!key) throw new Error('לא הוגדר מפתח API בהגדרות.');
    
        let systemText = `אתה עוזר AI לפורום ${SITE_HOST}. ענה בעברית ברורה, מדויקת ולעניין. באפשרותך לחפש ולהציג גם פרופילים, מוניטין ונתוני משתמשים בפורום במידת הצורך.`;
        const persona = get(K.persona, '');
        if (persona) systemText += '\n\n' + persona;
    
        if (get(K.context, true)) {
          const context = getPageContext();
          if (context) systemText += '\n\n' + context;
        }
    
        if (searchResults) {
          systemText += '\n\nמידע שנמצא בחיפוש בפורום ובמשתמשים:\n' + searchResults;
        }
    
        const contents = history.map(m => {
          const parts = [];
          if (m.fileData) {
            parts.push({
              inlineData: {
                mimeType: m.fileData.mimeType,
                data: m.fileData.data
              }
            });
          }
          parts.push({ text: m.text });
          return { role: m.role === 'model' ? 'model' : 'user', parts };
        });
    
        const body = {
          contents,
          generationConfig: { maxOutputTokens: 2500 }
        };
    
        if (systemText) {
          body.systemInstruction = { parts: [{ text: systemText }] };
        }
    
        let lastError;
        for (const model of MODEL_CANDIDATES) {
          for (let attempt = 0; attempt < 2; attempt++) {
            try {
              return await callGeminiWithModel(model, key, body);
            } catch (e) {
              lastError = e;
              const retryable = e.status === 503 || e.status === 429;
              if (retryable && attempt === 0) {
                await sleep(1200);
                continue;
              }
              break;
            }
          }
        }
    
        throw lastError || new Error('כל המודלים נכשלו.');
      }
    
      // --- UI Elements & Styling ---
      const style = document.createElement('style');
      style.textContent = `
        #bina-ai-button { position:fixed; bottom:22px; left:22px; width:58px; height:58px; border-radius:50%; border:0; background:linear-gradient(135deg,#4f8cff,#7c5cff); color:white; font-size:27px; cursor:pointer; z-index:999999; box-shadow:0 5px 20px rgba(0,0,0,.3); }
        #bina-ai-panel { position:fixed; left:22px; bottom:92px; width:400px; max-width:92vw; height:560px; max-height:80vh; background:white; border-radius:15px; overflow:hidden; display:none; flex-direction:column; z-index:999999; box-shadow:0 10px 40px rgba(0,0,0,.3); direction:rtl; font-family:Arial,sans-serif; border:1px solid #ddd; }
        #bina-ai-panel.open { display:flex; }
        #bina-ai-panel.fullscreen { inset:0; width:100vw; height:100vh; max-width:none; max-height:none; border-radius:0; }
        #bina-ai-header { padding:11px; background:linear-gradient(135deg,#4f8cff,#7c5cff); color:white; font-weight:bold; display:flex; justify-content:space-between; align-items:center; cursor:move; user-select:none; }
        #bina-ai-header button { border:0; background:transparent; color:white; font-size:15px; cursor:pointer; margin-right:4px; }
        #bina-ai-new-btn { background: #ffffff !important; color: #4f8cff !important; padding: 4px 10px; border-radius: 8px; font-size: 12px !important; font-weight: bold; margin-left: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.15); transition: all 0.2s; cursor: pointer; }
        #bina-ai-new-btn:hover { background: #f0f4ff !important; transform: translateY(-1px); }
        #bina-ai-info { padding:6px 10px; font-size:11px; background:#fafafa; border-bottom:1px solid #eee; color:#666; display:flex; justify-content:space-between; align-items:center; }
        #bina-ai-messages { flex:1; overflow-y:auto; padding:10px; background:#f5f6fa; display:flex; flex-direction:column; gap:8px; }
        .bina-ai-msg { padding:9px 11px; border-radius:10px; max-width:88%; font-size:13px; line-height:1.5; white-space:pre-wrap; word-break:break-word; }
        .bina-ai-user { align-self:flex-end; background:#4f8cff; color:white; }
        .bina-ai-model { align-self:flex-start; background:white; border:1px solid #ddd; color:#222; }
        .bina-ai-error { align-self:center; color:#a00000; background:#ffe3e3; border:1px solid #f0b0b0; }
        .bina-ai-step { align-self:center; color:#444; background:#eef2ff; font-size:11px; }
        .bina-ai-msg a { color:#2a5fd6; text-decoration:underline; word-break:break-all; }
        .bina-ai-user a { color:#eaf1ff; }
        #bina-ai-inputbar { display:flex; gap:6px; padding:8px; border-top:1px solid #ddd; background: #fff; align-items: center; }
        #bina-ai-input { flex:1; resize:none; height:40px; border:1px solid #ddd; border-radius:8px; padding:8px; font-family:inherit; }
        #bina-ai-send { border:0; border-radius:8px; padding:0 14px; background:#4f8cff; color:white; font-weight:bold; cursor:pointer; height:40px; }
        #bina-ai-file-btn { border:0; border-radius:8px; width:40px; height:40px; background:#f0f2f5; color:#555; font-size:18px; cursor:pointer; display:flex; align-items:center; justify-content:center; }
        #bina-ai-file-btn:hover { background:#e4e6eb; }
        #bina-file-indicator { font-size: 11px; color: #4f8cff; padding: 2px 10px; background: #eef2ff; display: none; align-items: center; justify-content: space-between; border-bottom: 1px solid #ddd; }
        #bina-ai-settings { position:fixed; inset:0; display:none; align-items:center; justify-content:center; background:rgba(0,0,0,.45); z-index:1000000; }
        #bina-ai-settings.open { display:flex; }
        #bina-ai-settings-box { width:460px; max-width:92vw; max-height:88vh; overflow:auto; background:white; border-radius:15px; padding:18px; direction:rtl; font-family:Arial,sans-serif; }
        .bina-provider { border:1px solid #ddd; border-radius:10px; padding:10px; margin-bottom:9px; }
        .bina-provider-title { font-weight:bold; margin-bottom:8px; }
        .bina-provider input[type=password] { width:100%; box-sizing:border-box; padding:6px; margin-top:5px; border:1px solid #ddd; border-radius:6px; }
        .bina-field { margin-top:10px; }
        .bina-field label { display:block; font-weight:bold; font-size:12px; margin-bottom:5px; }
        .bina-field textarea { width:100%; box-sizing:border-box; padding:8px; border:1px solid #ddd; border-radius:8px; }
        .bina-buttons { display:flex; justify-content:flex-end; gap:8px; margin-top:15px; }
        .bina-buttons button { padding:8px 16px; border:0; border-radius:8px; cursor:pointer; }
        #bina-ai-save { background:#4f8cff; color:white; }
        .session-item { display: flex; justify-content: space-between; align-items: center; padding: 8px 10px; border-bottom: 1px solid #eee; font-size: 13px; }
        .session-item:hover { background: #f8f9fa; }
        .session-title { cursor: pointer; color: #2a5fd6; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-left: 10px; font-weight: 500; }
        .session-title:hover { text-decoration: underline; }
        .session-actions button { background: #ff4d4d; color: white; border: none; border-radius: 4px; padding: 4px 8px; cursor: pointer; font-size: 11px; margin-right: 4px; }
        .session-actions button.load-btn { background: #4f8cff; }
      `;
      document.head.appendChild(style);
    
      const button = document.createElement('button');
      button.id = 'bina-ai-button';
      button.textContent = '🤖';
      button.title = `עוזר AI — ${SITE_HOST}`;
      document.body.appendChild(button);
    
      const panel = document.createElement('div');
      panel.id = 'bina-ai-panel';
      panel.innerHTML = `
        <div id="bina-ai-header">
          <div style="display:flex; align-items:center;">
            <span>🤖 עוזר AI</span>
            <button id="bina-ai-new-btn" title="התחל שיחה חדשה">💬 שיחה חדשה</button>
          </div>
          <div>
            <button id="bina-ai-settings-btn" title="הגדרות והיסטוריית שיחות">⚙️</button>
            <button id="bina-ai-fullscreen" title="מסך מלא">⛶</button>
            <button id="bina-ai-close" title="סגור">✕</button>
          </div>
        </div>
        <div id="bina-ai-info">
          <div>🌐 מחובר ל-${SITE_HOST}</div>
          <div>
            <label><input type="checkbox" id="bina-ai-context"> הקשר עמוד</label>
          </div>
        </div>
        <div id="bina-file-indicator">
          <span id="bina-file-name">📎 קובץ צורף</span>
          <button id="bina-remove-file" style="background:none; border:none; color:#a00000; cursor:pointer; font-weight:bold;">הסר ✕</button>
        </div>
        <div id="bina-ai-messages"></div>
        <div id="bina-ai-inputbar">
          <input type="file" id="bina-ai-file-input" style="display:none;" />
          <button id="bina-ai-file-btn" type="button" title="צירוף קובץ או תמונה">📎</button>
          <textarea id="bina-ai-input" placeholder="שאל שאלה, חפש אשכול, בדוק משתמש או הדבק תמונה/קובץ (Ctrl+V)..."></textarea>
          <button id="bina-ai-send" type="button">שלח</button>
        </div>
      `;
      document.body.appendChild(panel);
    
      // --- Dragging Logic ---
      const header = document.querySelector('#bina-ai-header');
      let isDragging = false, startX, startY, initialX, initialY;
    
      header.addEventListener('mousedown', e => {
        if (e.target.tagName === 'BUTTON') return;
        isDragging = true;
        startX = e.clientX;
        startY = e.clientY;
        const rect = panel.getBoundingClientRect();
        initialX = rect.left;
        initialY = rect.top;
        panel.style.bottom = 'auto';
        panel.style.left = initialX + 'px';
        panel.style.top = initialY + 'px';
        document.addEventListener('mousemove', onMouseMove);
        document.addEventListener('mouseup', onMouseUp);
      });
    
      function onMouseMove(e) {
        if (!isDragging) return;
        const dx = e.clientX - startX;
        const dy = e.clientY - startY;
        panel.style.left = (initialX + dx) + 'px';
        panel.style.top = (initialY + dy) + 'px';
      }
    
      function onMouseUp() {
        isDragging = false;
        document.removeEventListener('mousemove', onMouseMove);
        document.removeEventListener('mouseup', onMouseUp);
      }
    
      // --- File Attachment & Paste Logic ---
      let attachedFile = null;
      const fileInput = document.querySelector('#bina-ai-file-input');
      const fileBtn = document.querySelector('#bina-ai-file-btn');
      const fileIndicator = document.querySelector('#bina-file-indicator');
      const fileNameSpan = document.querySelector('#bina-file-name');
      const removeFileBtn = document.querySelector('#bina-remove-file');
      const input = document.querySelector('#bina-ai-input');
    
      fileBtn.onclick = () => fileInput.click();
    
      function processFile(file) {
        if (!file) return;
        const reader = new FileReader();
        reader.onload = function (uploadEvent) {
          const base64Data = uploadEvent.target.result.split(',')[1];
          attachedFile = {
            mimeType: file.type || 'application/octet-stream',
            data: base64Data,
            name: file.name || 'קובץ מודבק'
          };
          fileNameSpan.textContent = `📎 ${attachedFile.name} צורף בהצלחה`;
          fileIndicator.style.display = 'flex';
        };
        reader.readAsDataURL(file);
      }
    
      fileInput.onchange = (e) => {
        processFile(e.target.files[0]);
      };
    
      // תמיכה בהדבקת קובץ/תמונה ישירות לתיבת הטקסט (Ctrl + V)
      input.addEventListener('paste', (e) => {
        const items = (e.clipboardData || e.originalEvent.clipboardData).items;
        for (let index in items) {
          const item = items[index];
          if (item.kind === 'file') {
            const blob = item.getAsFile();
            if (blob) {
              e.preventDefault();
              processFile(blob);
              break;
            }
          }
        }
      });
    
      removeFileBtn.onclick = () => {
        attachedFile = null;
        fileInput.value = '';
        fileIndicator.style.display = 'none';
      };
    
      // --- Sessions Management Logic ---
      let sessions = [];
      try {
        sessions = JSON.parse(get(K.sessions, '[]'));
        if (!Array.isArray(sessions)) sessions = [];
      } catch (e) {
        sessions = [];
      }
      let currentSessionId = get(K.currentSessionId, '');
      let history = [];
    
      function saveSessionsToStorage() {
        set(K.sessions, JSON.stringify(sessions));
        set(K.currentSessionId, currentSessionId);
      }
    
      function startNewSession() {
        const newId = 'session_' + Date.now();
        const newSession = { id: newId, title: 'שיחה חדשה', history: [] };
        sessions.unshift(newSession);
        if (sessions.length > 20) sessions.pop();
        currentSessionId = newId;
        history = [];
        saveSessionsToStorage();
        renderMessages();
        welcome();
        renderSessionsList();
      }
    
      function loadSession(id) {
        const found = sessions.find(s => s.id === id);
        if (found) {
          currentSessionId = found.id;
          history = [...found.history];
          saveSessionsToStorage();
          renderMessages();
          if (history.length === 0) welcome();
          renderSessionsList();
        }
      }
    
      function deleteSession(id) {
        sessions = sessions.filter(s => s.id !== id);
        if (currentSessionId === id) {
          if (sessions.length > 0) {
            loadSession(sessions[0].id);
          } else {
            startNewSession();
          }
        } else {
          saveSessionsToStorage();
          renderSessionsList();
        }
      }
    
      // --- Settings & History Modal ---
      const settings = document.createElement('div');
      settings.id = 'bina-ai-settings';
      settings.innerHTML = `
        <div id="bina-ai-settings-box">
          <h3>⚙️ הגדרות והיסטוריית שיחות</h3>
          <div style="font-size:11px;color:#777;margin-bottom:12px">האתר הנוכחי: <b>${SITE_HOST}</b></div>
    
          <div class="bina-provider">
            <div class="bina-provider-title">🔵 Gemini API Key</div>
            <div style="font-size:11px;margin-bottom:3px;color:#555;">מפתח API:</div>
            <input type="password" id="gemini-key" placeholder="הכנס כאן את המפתח">
          </div>
    
          <div class="bina-field"><label>הנחיות אישיות</label><textarea id="bina-persona" placeholder="לדוגמה: ענה בקצרה..."></textarea></div>
    
          <div class="bina-field" style="margin-top:15px;">
            <label>📜 היסטוריית שיחות שמורות</label>
            <div id="bina-sessions-container" style="max-height:180px; overflow-y:auto; border:1px solid #ddd; border-radius:6px; margin-top:5px; background:#fafafa;"></div>
          </div>
    
          <div class="bina-buttons"><button id="bina-cancel">סגור</button><button id="bina-ai-save">שמור הגדרות</button></div>
        </div>
      `;
      document.body.appendChild(settings);
    
      function renderSessionsList() {
        const container = document.querySelector('#bina-sessions-container');
        if (!container) return;
        if (sessions.length === 0) {
          container.innerHTML = '<div style="padding:10px; font-size:12px; color:#777; text-align:center;">אין שיחות שמורות</div>';
          return;
        }
        container.innerHTML = '';
        sessions.forEach(s => {
          const item = document.createElement('div');
          item.className = 'session-item';
          if (s.id === currentSessionId) {
            item.style.background = '#eef2ff';
            item.style.fontWeight = 'bold';
          }
    
          const titleSpan = document.createElement('span');
          titleSpan.className = 'session-title';
          titleSpan.textContent = s.title || 'שיחה ללא כותרת';
          titleSpan.title = s.title;
          titleSpan.onclick = () => {
            loadSession(s.id);
            settings.classList.remove('open');
          };
    
          const actionsDiv = document.createElement('div');
          actionsDiv.className = 'session-actions';
    
          const loadBtn = document.createElement('button');
          loadBtn.className = 'load-btn';
          loadBtn.textContent = 'המשך';
          loadBtn.onclick = () => {
            loadSession(s.id);
            settings.classList.remove('open');
          };
    
          const delBtn = document.createElement('button');
          delBtn.textContent = 'מחק';
          delBtn.onclick = () => {
            deleteSession(s.id);
          };
    
          actionsDiv.appendChild(loadBtn);
          actionsDiv.appendChild(delBtn);
    
          item.appendChild(titleSpan);
          item.appendChild(actionsDiv);
          container.appendChild(item);
        });
      }
    
      function loadSettings() {
        document.querySelector('#gemini-key').value = get(K.apiKey, '');
        document.querySelector('#bina-persona').value = get(K.persona, '');
        document.querySelector('#bina-ai-context').checked = get(K.context, true);
        renderSessionsList();
      }
    
      function saveSettings() {
        set(K.apiKey, document.querySelector('#gemini-key').value.trim());
        set(K.persona, document.querySelector('#bina-persona').value.trim());
        set(K.context, document.querySelector('#bina-ai-context').checked);
        settings.classList.remove('open');
      }
    
      document.querySelector('#bina-ai-settings-btn').onclick = () => { loadSettings(); settings.classList.add('open'); };
      document.querySelector('#bina-cancel').onclick = () => settings.classList.remove('open');
      document.querySelector('#bina-ai-save').onclick = saveSettings;
    
      document.querySelector('#bina-ai-new-btn').onclick = () => {
        startNewSession();
      };
    
      const messagesContainer = document.querySelector('#bina-ai-messages');
      const sendButton = document.querySelector('#bina-ai-send');
    
      function escapeHtml(str) {
        return String(str)
          .replace(/&/g, '&amp;')
          .replace(/</g, '&lt;')
          .replace(/>/g, '&gt;');
      }
    
      function linkify(escapedText) {
        const urlRegex = /(https?:\/\/[^\s<>"')]+)/g;
        return escapedText.replace(urlRegex, raw => {
          const trimmed = raw.replace(/[).,;:!?]+$/, '');
          const trailing = raw.slice(trimmed.length);
          return `<a href="${trimmed}" target="_blank" rel="noopener noreferrer">${trimmed}</a>${trailing}`;
        });
      }
    
      function renderMessages() {
        messagesContainer.innerHTML = '';
        history.forEach(m => {
          const type = m.role === 'user' ? 'bina-ai-user' : 'bina-ai-model';
          const div = document.createElement('div');
          div.className = 'bina-ai-msg ' + type;
          let contentHtml = linkify(escapeHtml(m.text)).replace(/\n/g, '<br>');
          if (m.fileData && m.fileData.name) {
            contentHtml = `📎 <b>[קובץ: ${m.fileData.name}]</b><br>` + contentHtml;
          }
          div.innerHTML = contentHtml;
          messagesContainer.appendChild(div);
        });
        messagesContainer.scrollTop = messagesContainer.scrollHeight;
      }
    
      function addMessage(text, type, fileInfo = null) {
        const div = document.createElement('div');
        div.className = 'bina-ai-msg ' + type;
        let contentHtml = linkify(escapeHtml(text)).replace(/\n/g, '<br>');
        if (fileInfo && fileInfo.name) {
          contentHtml = `📎 <b>[קובץ: ${fileInfo.name}]</b><br>` + contentHtml;
        }
        div.innerHTML = contentHtml;
        messagesContainer.appendChild(div);
        messagesContainer.scrollTop = messagesContainer.scrollHeight;
        return div;
      }
    
      function welcome() {
        addMessage(`שלום! 🤖\nאני עוזר ה-AI של ${SITE_HOST}.\n\nשאל אותי כל שאלה, חפש אשכולות, בדוק פרופילים או צרף/הדבק קובץ ותמונה!`, 'bina-ai-model');
        if (!get(K.apiKey)) {
          addMessage('⚠️ עדיין לא הוגדר מפתח API. פתח ⚙️ והוסף.', 'bina-ai-error');
        }
      }
    
      button.onclick = () => panel.classList.toggle('open');
      document.querySelector('#bina-ai-close').onclick = () => panel.classList.remove('open');
      document.querySelector('#bina-ai-fullscreen').onclick = () => panel.classList.toggle('fullscreen');
    
      async function send() {
        const text = input.value.trim();
        const currentFile = attachedFile;
    
        if (!text && !currentFile) return;
        if (!get(K.apiKey)) {
          addMessage('⚠️ אין מפתח API פעיל. פתח ⚙️ והגדר.', 'bina-ai-error');
          return;
        }
    
        if (!currentSessionId || sessions.length === 0) {
          startNewSession();
        }
    
        const messageText = text || 'צורף קובץ לעיון';
        addMessage(messageText, 'bina-ai-user', currentFile);
    
        history.push({
          role: 'user',
          text: messageText,
          fileData: currentFile ? { mimeType: currentFile.mimeType, data: currentFile.data, name: currentFile.name } : null
        });
    
        input.value = '';
        attachedFile = null;
        fileInput.value = '';
        fileIndicator.style.display = 'none';
        sendButton.disabled = true;
    
        const currentSession = sessions.find(s => s.id === currentSessionId);
        if (currentSession && currentSession.title === 'שיחה חדשה') {
          currentSession.title = messageText.slice(0, 25) + (messageText.length > 25 ? '...' : '');
        }
    
        const stepMsg = addMessage('🔎 מחפש בנתוני הפורום והמשתמשים...', 'bina-ai-step');
    
        try {
          const searchResults = await quickForumSearch(messageText);
          stepMsg.remove();
    
          const pending = addMessage('🤖 מנתח תשובה...', 'bina-ai-model');
          const answer = await callGemini(history, searchResults);
          pending.remove();
    
          addMessage(answer, 'bina-ai-model');
          history.push({ role: 'model', text: answer, fileData: null });
    
          if (currentSession) {
            currentSession.history = [...history];
            saveSessionsToStorage();
          }
        } catch (e) {
          stepMsg.remove();
          addMessage('⚠️ ' + (e?.message || String(e)), 'bina-ai-error');
        } finally {
          sendButton.disabled = false;
          input.focus();
        }
      }
    
      sendButton.onclick = send;
      input.addEventListener('keydown', e => {
        if (e.key === 'Enter' && !e.shiftKey) {
          e.preventDefault();
          send();
        }
      });
    
      GM_registerMenuCommand('⚙️ הגדרות עוזר AI', () => { loadSettings(); settings.classList.add('open'); });
    
      if (sessions.length > 0) {
        if (!currentSessionId || !sessions.some(s => s.id === currentSessionId)) {
          currentSessionId = sessions[0].id;
        }
        loadSession(currentSessionId);
      } else {
        startNewSession();
      }
    })();
    

    כמה תמונות מהעוזר גרסת "חפרן" שעשיתי:

    bbf4fc34-c7cd-4443-985d-3025c914a766-image.jpeg
    2c0532ee-5f87-4bf7-bd9d-ce1bf8f559b8-image.jpeg
    6ca78945-c7f0-4da5-93ff-17bb9ac20bae-image.jpeg

    עזרה הדדית - מחשבים וטכנולוגיה
  • התחברות

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

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