‏הצגת רשומות עם תוויות אינטרנט. הצג את כל הרשומות
‏הצגת רשומות עם תוויות אינטרנט. הצג את כל הרשומות

יום חמישי, 10 ביולי 2025

צביעת שיחות ב-ChatGpt

הוספת אפשרות לצבוע שיחות (צאטים) ב-ChatGpt
  1. לחץ כאן כדי להעתיק את הקוד
  2. לחץ ctrl+d כדי ליצור סימניה
  3. שנה את שם הסימניה ל-צביעת שיחות, ובמקום הכתובת, הדבק את הטקסט שהעתקת בסעיף 1
  4. בזמן שימוש באתר ChatGPT, לחץ על הסימניה ששמרת כדי להציג את התפריט
javascript:(function(){
  let s = JSON.parse(localStorage.getItem('navMarkerSettings')) || {
    markers: [{symbol:'📌',bgColor:'#fff8b3',color:''}],
    minimized: false
  };
  function save() {
    localStorage.setItem('navMarkerSettings', JSON.stringify(s));
  }
  function h() {
    document.querySelectorAll('nav a').forEach(c=>{
      let t=c.textContent.trim();
      c.style.backgroundColor='';
      c.style.color='';
      s.markers.forEach(m=>{
        if(t.startsWith(m.symbol)||t.endsWith(m.symbol)){
          c.style.backgroundColor=m.bgColor||'';
          c.style.color=m.color||'';
        }
      });
      c.style.fontWeight='';
      if(c.hasAttribute('data-active')){
        c.style.fontWeight='bold';
      }
    });
  }
  h();
  const n=document.querySelector('nav');
  if(n){
    new MutationObserver(h).observe(n,{childList:true,subtree:true,attributes:true,attributeFilter:['data-active']});
  }
  if(!document.getElementById('markerConfigMenu')){
    const m=document.createElement('div');
    m.id='markerConfigMenu';
    m.style.position='fixed';
    m.style.top='55px';
    m.style.right='10px';
    m.style.width='270px';
    m.style.background='#fefefe';
    m.style.border='1px solid #333';
    m.style.borderRadius='8px';
    m.style.boxShadow='0 4px 12px rgba(0,0,0,0.2)';
    m.style.fontFamily='sans-serif';
    m.style.zIndex='9999';
    m.style.overflow='hidden';
    m.style.opacity='0.9';
    m.style.cursor='move';
    m.innerHTML='';
    document.body.appendChild(m);
    const hd=document.getElementById('menuHeader'),
          tb=document.getElementById('toggleMenu'),
          ct=document.getElementById('menuContent'),
          cl=document.getElementById('closeMenu');
    // מצב פתיחה/סגירה לפי saved
    ct.style.display = s.minimized ? 'none' : 'block';
    tb.textContent = s.minimized ? '+' : '−';
    tb.onclick=()=>{
      if(ct.style.display==='none'){
        ct.style.display='block';
        tb.textContent='−';
        s.minimized = false;
      }else{
        ct.style.display='none';
        tb.textContent='+';
        s.minimized = true;
      }
      save();
    };
    cl.onclick=()=>{
      m.style.transition='opacity 0.2s ease';
      m.style.opacity='0';
      setTimeout(()=>{m.remove();},500);
    };
    function r(){
      const l=document.getElementById('markerList');
      l.innerHTML='';
      if(s.markers.length===0){
        l.innerHTML='אין סימנים מוגדרים.';
      }
      s.markers.forEach((m,i)=>{
        const d=document.createElement('div');
        d.style.marginBottom='4px';
        d.style.background='#f0f0f0';
        d.style.padding='4px 30px 4px 4px';
        d.style.borderRadius='4px';
        d.style.position='relative';
        d.innerHTML=`${m.symbol} BG:       Text:     `;
        const b=document.createElement('button');
        b.textContent='🗑️';
        b.style.position='absolute';
        b.style.right='-25px';
        b.style.top='50%';
        b.style.transform='translateY(-50%)';
        b.style.background='none';
        b.style.border='none';
        b.style.cursor='pointer';
        b.onclick=()=>{
          s.markers.splice(i,1);
          save();
          r();
          h();
        };
        d.appendChild(b);
        l.appendChild(d);
      });
    }
    r();
    document.getElementById('addMarker').onclick=()=>{
      const sy=document.getElementById('newSymbol').value.trim(),
            bg=document.getElementById('newBg').value,
            co=document.getElementById('newColor').value;
      if(sy){
        s.markers.push({symbol:sy,bgColor:bg,color:co});
        save();
        r();
        h();
      }
    };
    document.getElementById('resetMarkers').onclick=()=>{
      if(confirm('לאפס הכל?')){
        localStorage.removeItem('navMarkerSettings');
        s={markers:[], minimized: false};
        r();
        h();
      }
    };
    let x=0,y=0,mx=0,my=0;hd.onmousedown=d;
    function d(e){
      e=e||window.event;e.preventDefault();
      mx=e.clientX;my=e.clientY;
      document.onmouseup=c;document.onmousemove=f;
    }
    function f(e){
      e=e||window.event;e.preventDefault();
      x=mx-e.clientX;y=my-e.clientY;
      mx=e.clientX;my=e.clientY;
      m.style.top=(m.offsetTop-y)+'px';
      m.style.left=(m.offsetLeft-x)+'px';
      m.style.right='auto';
    }
    function c(){document.onmouseup=null;document.onmousemove=null;}
  }
})();


שימוש בתוסף:
בתיבת התוסף יש להגדיר תו רצוי וצבעים - למשל
תוצבע רקעצבע טקסט
>      
יש לשנות את שם השיחה הרצויה שתתחיל או תסתיים בתו שנבחר.
כך, כל שיחה תיצבע בצבע ע"י התחלת או סיום השיחה בתו שהוגדר

יום ראשון, 6 ביולי 2025

תפריט שאלות של השיחה הנוכחית לגוגל ג'מיני

תפריט פרומפטים לגוגל ג'מיני:
  1. העתק את הקוד
  2. עבור אל האתר של Google Gemini
  3. לחץ F12
  4. הדבק את הקוד ע"י לחיצת ctrl+v,
  5. ולחץ Enter
(() => {
  // יצירת מדיניות TrustedTypes אם קיימת
  const policy = window.trustedTypes?.createPolicy('default', {
    createHTML: (input) => input
  });

  const style = document.createElement('style');
  // שימוש ב-TrustedHTML ל-style.innerHTML
  style.innerHTML = policy ? policy.createHTML(`
    #floatingMenu {
      position: fixed;
      top: 100px;
      left: 10px;
      width: 270px;
      max-height: 400px;
      background: rgba(0,0,0,0.6);
      color: white;
      font-family: Arial, sans-serif;
      font-size: 14px;
      border-radius: 6px;
      box-shadow: 0 0 10px black;
      display: flex;
      flex-direction: column;
      user-select: none;
      z-index: 999999;
      overflow: hidden;
      transition: max-height 0.4s ease;
    }
    #floatingMenu.collapsed {
      max-height: 40px;
    }
    #floatingMenuHeader {
      padding: 8px 10px;
      background: rgba(0,0,0,0.8);
      cursor: move;
      display: flex;
      justify-content: space-between;
      align-items: center;
      font-weight: bold;
    }
    #floatingMenuTitle {
      flex-grow: 1;
      text-align: center;
    }
    #floatingMenuControls {
      display: flex;
      align-items: center;
    }
    #floatingMenuControls > button {
      cursor: pointer;
      margin-left: 10px;
      font-weight: bold;
      background: none;
      border: none;
      color: white;
      font-size: 16px;
      line-height: 1;
      padding: 0;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    #floatingMenuControls > button:focus {
      outline: 2px solid #fff;
      outline-offset: 2px;
    }
    #searchInput {
      margin: 0 10px;
      padding: 5px 8px;
      border-radius: 4px;
      border: none;
      font-size: 14px;
      width: calc(100% - 20px);
      box-sizing: border-box;
      max-height: 0;
      opacity: 0;
      pointer-events: none;
      transition: max-height 0.4s ease, opacity 0.4s ease, margin 0.4s ease;
      direction: rtl;
    }
    #searchInput.visible {
      max-height: 40px;
      opacity: 1;
      pointer-events: auto;
      margin: 5px 10px;
    }
    #floatingMenuList {
      padding: 5px 10px;
      transition: opacity 0.3s ease;
      flex-grow: 1;
      display: flex;
      flex-direction: column;
      overflow: hidden;
    }
    #floatingMenuList.scrollable {
      overflow-y: auto;
      max-height: 340px;
    }
    #floatingMenuList div {
      padding: 5px 8px;
      border-radius: 4px;
      margin-bottom: 4px;
      background: rgba(255,255,255,0.1);
      cursor: pointer;
      white-space: nowrap;
      text-overflow: ellipsis;
    }
    #floatingMenuList div:hover,
    #floatingMenuList div:focus {
      background: rgba(255,255,255,0.25);
      outline: none;
    }
    #floatingMenu.collapsed #searchInput,
    #floatingMenu.collapsed #floatingMenuList {
      opacity: 0;
      pointer-events: none;
      height: 0;
      padding: 0 10px;
      overflow: hidden !important;
      transition: opacity 0.4s ease, height 0.4s ease, padding 0.4s ease, margin 0.4s ease;
    }
  `) : `
    #floatingMenu {
      position: fixed;
      top: 100px;
      right: 10px;
      width: 270px;
      max-height: 400px;
      background: rgba(0,0,0,0.6);
      color: white;
      font-family: Arial, sans-serif;
      font-size: 14px;
      border-radius: 6px;
      box-shadow: 0 0 10px black;
      display: flex;
      flex-direction: column;
      user-select: none;
      z-index: 999999;
      overflow: hidden;
      transition: max-height 0.4s ease;
    }
    #floatingMenu.collapsed {
      max-height: 40px;
    }
    #floatingMenuHeader {
      padding: 8px 10px;
      background: rgba(0,0,0,0.8);
      cursor: move;
      display: flex;
      justify-content: space-between;
      align-items: center;
      font-weight: bold;
    }
    #floatingMenuTitle {
      flex-grow: 1;
      text-align: center;
    }
    #floatingMenuControls {
      display: flex;
      align-items: center;
    }
    #floatingMenuControls > button {
      cursor: pointer;
      margin-left: 10px;
      font-weight: bold;
      background: none;
      border: none;
      color: white;
      font-size: 16px;
      line-height: 1;
      padding: 0;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    #floatingMenuControls > button:focus {
      outline: 2px solid #fff;
      outline-offset: 2px;
    }
    #searchInput {
      margin: 0 10px;
      padding: 5px 8px;
      border-radius: 4px;
      border: none;
      font-size: 14px;
      width: calc(100% - 20px);
      box-sizing: border-box;
      max-height: 0;
      opacity: 0;
      pointer-events: none;
      transition: max-height 0.4s ease, opacity 0.4s ease, margin 0.4s ease;
      direction: rtl;
    }
    #searchInput.visible {
      max-height: 40px;
      opacity: 1;
      pointer-events: auto;
      margin: 5px 10px;
    }
    #floatingMenuList {
      padding: 5px 10px;
      transition: opacity 0.3s ease;
      flex-grow: 1;
      display: flex;
      flex-direction: column;
      overflow: hidden;
    }
    #floatingMenuList.scrollable {
      overflow-y: auto;
      max-height: 340px;
    }
    #floatingMenuList div {
      padding: 5px 8px;
      border-radius: 4px;
      margin-bottom: 4px;
      background: rgba(255,255,255,0.1);
      cursor: pointer;
      white-space: nowrap;
      text-overflow: ellipsis;
      overflow-x: clip;
    }
    #floatingMenuList div:hover,
    #floatingMenuList div:focus {
      background: rgba(255,255,255,0.25);
      outline: none;
    }
    #floatingMenu.collapsed #searchInput,
    #floatingMenu.collapsed #floatingMenuList {
      opacity: 0;
      pointer-events: none;
      height: 0;
      padding: 0 10px;
      overflow: hidden !important;
      transition: opacity 0.4s ease, height 0.4s ease, padding 0.4s ease, margin 0.4s ease;
    }
  `;

  document.head.appendChild(style);

  const menu = document.createElement('div');
  menu.id = 'floatingMenu';
  menu.setAttribute('role', 'region');
  menu.setAttribute('aria-label', 'תפריט שאלות');

  const header = document.createElement('div');
  header.id = 'floatingMenuHeader';
  header.setAttribute('role', 'banner');

  const title = document.createElement('div');
  title.id = 'floatingMenuTitle';
  // החלפה ל-textContent במקום innerHTML כשמדובר בטקסט
  title.textContent = 'ריק'; // ברירת מחדל

  const controls = document.createElement('div');
  controls.id = 'floatingMenuControls';

  const toggleSearchBtn = document.createElement('button');
  toggleSearchBtn.id = 'toggleSearchBtn';
  toggleSearchBtn.textContent = '?'; // טקסט בלבד

  const collapseBtn = document.createElement('button');
  collapseBtn.id = 'collapseBtn';
  collapseBtn.textContent = '-'; // טקסט בלבד

  const closeBtn = document.createElement('button');
  closeBtn.id = 'closeBtn';
  closeBtn.textContent = '×'; // טקסט בלבד

  //controls.appendChild(toggleSearchBtn);
  controls.appendChild(collapseBtn);
  controls.appendChild(closeBtn);
  header.appendChild(title);
  header.appendChild(controls);

  const searchInput = document.createElement('input');
  searchInput.id = 'searchInput';
  searchInput.type = 'search';
  searchInput.placeholder = 'חפש שאלות...';

  const listContainer = document.createElement('div');
  listContainer.id = 'floatingMenuList';

  menu.appendChild(header);
  menu.appendChild(searchInput);
  menu.appendChild(listContainer);
  document.body.appendChild(menu);

  function isHebrewChar(char) {
    return /[\u0590-\u05FF]/.test(char);
  }

  function hasClassOrParentHasClass(el, className) {
    while (el) {
      if (el.classList && el.classList.contains(className)) {
        return true;
      }
      el = el.parentElement;
    }
    return false;
  }

  function getQuestions() {
    const qs = document.querySelectorAll('.query-text p');

    const questions = [];
    qs.forEach((q, i) => {
      let len = 27;
      if (hasClassOrParentHasClass(q, 'text-page-header')) return;
      let text = q.textContent.trim().replace(/\s+/g, ' ');      
      if (text.length > len) text = text.slice(0, len) + '…';
      questions.push({ el: q, text, index: i, fullText: q.innerHTML.trim() });
    });
    return questions;
  }

  let previousQuestionsJSON = null;

  function updateList() {
    const questions = getQuestions();
    const currentQuestionsJSON = JSON.stringify(questions.map(q => q.fullText));
    if (currentQuestionsJSON === previousQuestionsJSON) return;
    previousQuestionsJSON = currentQuestionsJSON;

    if (questions.length === 0) {
      title.textContent = 'ריק';
    } else {
      // כאן כן innerHTML כי זה יכול לכלול תווים מיוחדים מהכותרת, אבל מומלץ להחליף ל-textContent אם אפשר
      // פה נניח שהכותרת היא טקסט בלבד, לכן:
      title.textContent = document.title || 'צ׳אט';
    }

    // 👇 בדיקת כיוון הכותרת
    const firstChar = title.textContent.trim().charAt(0);
    if (isHebrewChar(firstChar)) {
      title.style.direction = 'rtl';
    } else {
      title.style.direction = 'ltr';
    }

    const searchTerm = searchInput.value.trim().toLowerCase();
    listContainer.innerHTML = ''; // כאן צריך לרוקן תוכן - אין דרך אחרת

    const filtered = questions.filter(q => q.fullText.toLowerCase().includes(searchTerm));
    listContainer.classList.toggle('scrollable', filtered.length > 10);

    if (filtered.length === 0) {
      const noResultDiv = document.createElement('div');
      noResultDiv.textContent = 'לא נמצאו שאלות';
      noResultDiv.style.textAlign = 'center';
      noResultDiv.style.opacity = '0.7';
      listContainer.appendChild(noResultDiv);
      return;
    }

    filtered.forEach(({ el, text, index, fullText }) => {
      const item = document.createElement('div');
      // כאן אפשר להשתמש ב-textContent כי זה טקסט בלבד
      item.textContent = text || `שאלה ${index + 1}`;
      item.title = fullText;

      if (isHebrewChar(text[0])) {
        item.style.direction = 'rtl';
        item.style.textAlign = 'right';
      } else {
        item.style.direction = 'ltr';
        item.style.textAlign = 'left';
      }

      item.addEventListener('click', e => {
        e.preventDefault();
        el.scrollIntoView({ behavior: 'smooth', block: 'center' });
        el.style.transition = 'background-color 0.5s';
        const origBG = el.style.backgroundColor;
        el.style.backgroundColor = 'yellow';
        setTimeout(() => {
          el.style.backgroundColor = origBG || '';
        }, 1000);
      });

      listContainer.appendChild(item);
    });
  }

  closeBtn.addEventListener('click', () => {
    menu.style.display = 'none';
  });

  collapseBtn.addEventListener('click', () => {
    const isCollapsed = menu.classList.toggle('collapsed');
    collapseBtn.textContent = isCollapsed ? '+' : '-';
  });

  toggleSearchBtn.addEventListener('click', () => {
    const visible = searchInput.classList.toggle('visible');
    if (visible) {
      searchInput.focus();
    } else {
      searchInput.value = '';
      updateList();
    }
  });

  searchInput.addEventListener('input', () => {
    updateList();
  });

  let isDragging = false, dragStartX, dragStartY, menuStartX, menuStartY;

  header.addEventListener('mousedown', e => {
    isDragging = true;
    dragStartX = e.clientX;
    dragStartY = e.clientY;
    const rect = menu.getBoundingClientRect();
    menuStartX = rect.left;
    menuStartY = rect.top;
    e.preventDefault();
  });

  window.addEventListener('mousemove', e => {
    if (!isDragging) return;
    let newX = menuStartX + (e.clientX - dragStartX);
    let newY = menuStartY + (e.clientY - dragStartY);
    const maxX = window.innerWidth - menu.offsetWidth - 10;
    const maxY = window.innerHeight - menu.offsetHeight - 10;
    newX = Math.max(0, Math.min(maxX, newX));
    newY = Math.max(0, Math.min(maxY, newY));
    menu.style.right = 'auto';
    menu.style.left = `${newX}px`;
    menu.style.top = `${newY}px`;
  });

  window.addEventListener('mouseup', () => {
    isDragging = false;
  });

  const observer = new MutationObserver(() => {
    updateList();
  });

  observer.observe(document.body, { childList: true, subtree: true, characterData: true });

  updateList();
})();

	

יום שני, 30 ביוני 2025

תפריט שאלות של השיחה הנוכחית ChatGPT

תפריט פרומפטים ל-chatGPT


כתבתי תוסף לכרום שמוסיף את התפריט באופן אוטומטי (עם אפשרות למזעור או סגירה)
ניתן להוריד את התוסף מחנות גוגל כרום

אם לא ניתן להתקין תוספים אצלך בדפדן, אז אפשר להפעיל את זה בדרך הבאה:

  1. לחץ כאן כדי להעתיק את הקוד
  2. לחץ ctrl+d כדי ליצור סימניה
  3. שנה את שם הסימניה ל-תפריט, ובמקום כתובת, הדבק את הטקסט שהעתקת בסעיף 1
  4. בזמן שימוש באתר ChatGPT, לחץ על הסימניה ששמרת כדי להציג את התפריט

javascript:(()=>{const e=document.createElement("style");e.textContent="#floatingMenu{position:fixed;top:100px;right:10px;width:270px;max-height:400px;background:rgba(0,0,0,.6);color:#fff;font-family:Arial,sans-serif;font-size:14px;border-radius:6px;box-shadow:0 0 10px black;display:flex;flex-direction:column;user-select:none;z-index:999999;overflow:hidden;transition:max-height .4s ease}#floatingMenu.collapsed{max-height:40px}#floatingMenuHeader{padding:8px 10px;background:rgba(0,0,0,.8);cursor:move;display:flex;justify-content:space-between;align-items:center;font-weight:700}#floatingMenuTitle{flex-grow:1;text-align:center}#floatingMenuControls{display:flex;align-items:center}#floatingMenuControls>button{cursor:pointer;margin-left:10px;font-weight:700;background:none;border:none;color:#fff;font-size:16px;line-height:1;padding:0;display:flex;align-items:center;justify-content:center}#floatingMenuControls>button:focus{outline:2px solid #fff;outline-offset:2px}#searchInput{margin:0 10px;padding:5px 8px;border-radius:4px;border:none;font-size:14px;width:calc(100% - 20px);box-sizing:border-box;max-height:0;opacity:0;pointer-events:none;transition:max-height .4s ease,opacity .4s ease,margin .4s ease;direction:rtl}#searchInput.visible{max-height:40px;opacity:1;pointer-events:auto;margin:5px 10px}#floatingMenuList{padding:5px 10px;transition:opacity .3s ease;flex-grow:1;display:flex;flex-direction:column;overflow:hidden}#floatingMenuList.scrollable{overflow-y:auto;max-height:340px}#floatingMenuList div{padding:5px 8px;border-radius:4px;margin-bottom:4px;background:rgba(255,255,255,.1);cursor:pointer;white-space:nowrap;text-overflow:ellipsis}#floatingMenuList div:hover,#floatingMenuList div:focus{background:rgba(255,255,255,.25);outline:none}#floatingMenu.collapsed #searchInput,#floatingMenu.collapsed #floatingMenuList{opacity:0;pointer-events:none;height:0;padding:0 10px;overflow:hidden!important;transition:opacity .4s ease,height .4s ease,padding .4s ease,margin .4s ease}",document.head.appendChild(e);const t=document.createElement("div");t.id="floatingMenu",t.setAttribute("role","region"),t.setAttribute("aria-label","תפריט שאלות");const n=document.createElement("div");n.id="floatingMenuHeader",n.setAttribute("role","banner");const o=document.createElement("div");o.id="floatingMenuTitle",o.textContent="ריק";const i=document.createElement("div");i.id="floatingMenuControls";const l=document.createElement("button");l.id="toggleSearchBtn",l.textContent="?";const a=document.createElement("button");a.id="collapseBtn",a.textContent="-";const c=document.createElement("button");c.id="closeBtn",c.textContent="×",i.appendChild(l),i.appendChild(a),i.appendChild(c),n.appendChild(o),n.appendChild(i);const s=document.createElement("input");s.id="searchInput",s.type="search",s.placeholder="חפש שאלות...";const d=document.createElement("div");d.id="floatingMenuList",t.appendChild(n),t.appendChild(s),t.appendChild(d),document.body.appendChild(t);function p(e){return/[\u0590-\u05FF]/.test(e)}function u(e,t){for(;e;){if(e.classList&&e.classList.contains(t))return!0;e=e.parentElement}return!1}function f(){const e=document.querySelectorAll(".whitespace-pre-wrap"),t=[];return e.forEach(((e,n)=>{let o=27;if(u(e,"text-page-header"))return;let i=e.textContent.trim().replace(/\s+/g," ");i.length>o&&(i=i.slice(0,o)+"…"),t.push({el:e,text:i,index:n,fullText:e.textContent.trim()})})),t}let r=null;function m(){const e=f(),n=JSON.stringify(e.map((e=>e.fullText)));if(n===r)return;r=n,0===e.length?o.textContent="ריק":o.textContent=document.title||"צ׳אט";const i=o.textContent.trim().charAt(0);p(i)?o.style.direction="rtl":o.style.direction="ltr";const l=s.value.trim().toLowerCase();d.innerHTML="";const a=e.filter((e=>e.fullText.toLowerCase().includes(l)));if(d.classList.toggle("scrollable",a.length>10),0===a.length){const e=document.createElement("div");return e.textContent="לא נמצאו שאלות",e.style.textAlign="center",e.style.opacity="0.7",void d.appendChild(e)}a.forEach((({el:e,text:n,index:o,fullText:i})=>{const l=document.createElement("div");l.textContent=n||`שאלה ${o+1}`,l.title=i;const a=n[0];p(a)?(l.style.direction="rtl",l.style.textAlign="right"):(l.style.direction="ltr",l.style.textAlign="left"),l.addEventListener("click",(t=>{t.preventDefault(),e.scrollIntoView({behavior:"smooth",block:"center"}),e.style.transition="background-color .5s";const n=e.style.backgroundColor;e.style.backgroundColor="yellow",setTimeout((()=>{e.style.backgroundColor=n||""}),1e3)})),d.appendChild(l)}))}c.addEventListener("click",(()=>{t.style.display="none"})),a.addEventListener("click",(()=>{const e=t.classList.toggle("collapsed");a.textContent=e?"+":"-"})),l.addEventListener("click",(()=>{const e=s.classList.toggle("visible");e?s.focus():(s.value="",m())})),s.addEventListener("input",(()=>{m()}));let h=!1,v,g,b;function y(e){if(!h)return;let n=g+(e.clientX-v),o=b+(e.clientY-b);n=Math.max(0,Math.min(window.innerWidth-t.offsetWidth-10,n)),o=Math.max(0,Math.min(window.innerHeight-t.offsetHeight-10,o)),t.style.right="auto",t.style.left=`${n}px`,t.style.top=`${o}px`}n.addEventListener("mousedown",(e=>{h=!0,v=e.clientX,b=e.clientY;const n=t.getBoundingClientRect();g=n.left,b=n.top,e.preventDefault()})),window.addEventListener("mousemove",y),window.addEventListener("mouseup",(()=>{h=!1}));new MutationObserver((()=>{m()})).observe(document.body,{childList:!0,subtree:!0,characterData:!0}),m()})();


  



יום חמישי, 12 ביוני 2025

אחסון אתרים בחינם ע"י github

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

  1. ניצור repo בשם שנבחר
  2. ניצור או נוסיף את קובץ עמוד האינטרנט שלנו (עדיף שם קובץ index.html)
  3. בתוך האתר של github נלחץ על הקובץ שיצרנו ונעתיק את הכתובת של העמו המתקבל: https://github.com/snirex/snir-resume/blob/main/index.html
  4. נלך אל הכתובת https://raw.githack.com ונזין בתיבת הטקסט העליונה את הכתובת שהעתקנו
  5. נבחר את הכתובת שנרצה:
    אם בשביל development:
    - שינויים חדשים יתעדכנו בתוך מספר דקות
    - תעבורה מוגזמת תנותב באופן זמני לכתובות CDN מתאימות
    אם בשביל production:
    - אין מגבלות תעבורה. הקבצים מוגשים דרך רשת ה-CDN של CloudFlare.
    - ניתן לבצע אופטימיזציה אוטומטית לקבצים אם מוסיפים את הפרמטר ?min=1 לכתובת.
    - השתמש בתג מסוים (tag) או במזהה commit ספציפי בכתובת ה-URL (ולא בענף - branch). הקבצים מאוחסנים במטמון לצמיתות לפי כתובת ה-URL. מחרוזת השאילתה (Query string) לא נלקחת בחשבון.



raw.githack.com



יום חמישי, 5 בספטמבר 2024

ChatGPT - תיקון ימין-שמאל בכתיבת עברית

יש בעיה בכתיבת שאלות ב-ChatGPT בעברית במחשב - הכתיבה היא רק משמאל לימין.
כתבתי תוסף לכרום שמתקן את זה
ניתן להוריד את התוסף מחנות גוגל כרום

במידה ואין אפשרות להתקנת תוספים בדפדפן שלך, אפשר להשתמש בדרך הבאה:
  1. לחץ כאן כדי להעתיק את הקוד
  2. לחץ ctrl+d
  3. שנה את שם הסימניה, ובמקום כתובת, הדבק את הטקסט שהעתקת בסעיף 1
  4. בזמן שימוש באתר ChatGPT, לחץ על הסימניה ששמרת כדי לשנות כיוון כתיבה

  1. לחץ כאן כדי להעתיק את הקוד
  2. לחץ ctrl+d
  3. שנה את שם הסימניה ל-שניר, ובמקום כתובת, הדבק את הטקסט שהעתקת בסעיף 1
javascript:(function(){let e=localStorage.getItem("snir-textarea-direction")||"rtl";function t(){e="rtl"===e?"ltr":"rtl",localStorage.setItem("snir-textarea-direction",e);const t=document.querySelector("#prompt-textarea");t&&(t.style.direction=e);const o=document.querySelector("#direction-toggle-button img");o&&(o.style.transform="ltr"===e?"scaleX(-1)":"scaleX(1)")}function o(){document.querySelectorAll(".markdown").forEach((e=>{e.dir="rtl"===e.dir?"ltr":"rtl"}));const e=document.querySelector("#markdown-toggle-button img");e&&(e.style.transform="scaleX(-1)"===e.style.transform?"scaleX(1)":"scaleX(-1)")}function n(e,t,o,n,r){const l=document.createElement("button");l.id=e,l.title=t,l.style.cssText="width:2.2rem;height:2.2rem;border-radius:50%;background:white;color:black;border:1px solid lightgray;font-size:1.2rem;box-shadow:0 2px 6px rgba(0,0,0,0.2);cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;position:relative;transition:transform 0.3s cubic-bezier(.68,-0.55,.27,1.55);",l.onmouseover=()=>l.style.backgroundColor="#f0f0f0",l.onmouseout=()=>l.style.backgroundColor="white",l.onclick=(e=>{e.preventDefault(),r()});const c=document.createElement("img");return c.src=o,c.alt=n,c.style.cssText="width:1.5rem;height:1.5rem;object-fit:contain;pointer-events:none;",l.appendChild(c),l}const r="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAMAAAAp4XiDAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAD/UExURenp6c7OzrKysnl5eVZWVpOTkwAAAAEBAaGhoW1tbQMDA5ycnI2NjVtbW8bGxsjIyMrKyrGxscXFxd3d3dLS0ubm5ujo6IuLi3d3d+Li4uTk5E1NTezs7CYmJicnJ1BQUI6OjtXV1ZKSknZ2dpqamgICAt/f36ampnJyclxcXDk5OaqqqrCwsK+vr7+/v66urnR0dMPDw29vb+7u7rW1tSwsLIWFhUJCQkRERMTExNTU1AYGBsfHx3FxcWtra8nJybOzswQEBE5OTjMzM6mpqa2trdzc3OXl5UxMTKWlpUtLS52dnUlJSZ6enuPj40hISMvLy0ZGRqSkpOvr6wAAAKVmCqgAAABVdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////wCwoQfPAAAACXBIWXMAAA7BAAAOwQG4kWvtAAAAGHRFWHRTb2Z0d2FyZQBQYWludC5ORVQgNS4xLjgbaeqoAAAAtmVYSWZJSSoACAAAAAUAGgEFAAEAAABKAAAAGwEFAAEAAABSAAAAKAEDAAEAAAACAAAAMQECABAAAABaAAAAaYcEAAEAAABqAAAAAAAAANl2AQDoAwAA2XYBAOgDAABQYWludC5ORVQgNS4xLjgAAwAAkAcABAAAADAyMzABoAMAAQAAAAEAAAAFoAQAAQAAAJQAAAAAAAAAAgABAAIABAAAAFI5OAACAAcABAAAADAxMDAAAAAA5X1phWJRlb4AAAFhSURBVEhL5ZRXV8JAEIUpurEiorGAHdGIxoYo9i5WbPP/f4uzmZFkl6xsXuV7yHLP3C9kYU9SkJh/rqTSmWyfQponRKfSLxBHXtoM8IjoUAa5PxSUHUeGYZ4RujLCXSFGc2P5cVwz+cIEDwlNmaS6JIvRxXWKJiGaMh3uYgbjLK5FmoRoSonqEktlbp7qEltlgeoS2wdbpLrEVllKvv1lqktsFVhp/5XWCpR/D5i9AquBUEmiwNq6t1FN9C0Bm8mVreSK36vKtievO0Ls4mKl7AmxXwM4qFcPMRWPGg2XBiGacoy3FSccDKhKQRp5DiYUxcpQlBwKpwUOZiLKmTzy9bJ3HsfFJbeiCv6gFe31HeWKa1GlVhLXfyg+15QHc2/Qub3L+HHcP3BL3X7zEe/2xMFMVIHmMzovHIwoChRf0XnjYEJVoPWOzgcHA5oCrU/xxR9N6Ap8dzmUMUp3eloB+AGGLqjp2OH2dAAAAABJRU5ErkJggg==",l="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAE4AAABOCAIAAAAByLdKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAALeSURBVHhe7ZsxjuIwFIZTU+0RKLkBJWlX4gLT0SPtDZBAokFcAYFoqaDZFiqQQKKAHi5ARUvB/orfWCSZOF7ivDHM+ypiXvL7ix2HSCG4/xhE9R2xVV0ul61Wq1qtBiyEYXg+nynbEVaqCKYuMILT6tY2XzXtiU6UCsW4ts1R7Xa7FBsE+Ox8UqXBZUJ5EQ5tTarIoMAgwLVKrSWTUAWubE2qk8lEhWE8qal8tCpC9WR2YmtS1bP3W1Qxj4BDW5PqYyo1lU8i1KGt76rAle0LqAIntq+hCorbvowqKGj7SqqgiK2/qrirU1Ocp229U9W/W5BOTSmes/VOFVkqFBgcnrD1ThVoB/NT6//a+qiKTmsHAGH05Esey3JtfVQFjyNmj/m3uqeqAEOUGLdcUE87f4W/qhqkA6zMWegnsJdXzQXdU/0UVUJUI0TVO0Q1iahGiGqMTqdTq9VQ87s0cHBEIIgiU3CojkYjVcAD4ig4Dofq4XBQBTwcj0cKjsOhCi6Xy5oFBFFkCiZVHxDVJKIakat6vV7VnYaBRqOBOAqOw6E6GAxUAQ+Io+A4HKq3263ZbKoazS9H0OE+QRDiKDgOh6oniGoSUY2wUT2dTn9ZQBBFpuBQ3W63qoAHxFFwHA7V6XSqCnhAHAXH4VAFw+GwXq+j5qM0cHBEIIgiUzCp+oCoJhHVCBvV8Xj8x5per0e7RUsaWjabDW0XgEN1NpupAnva7TZ2nM/ntB0EWc8r9nCorlYrVWBPv9/Hjuv1Wm1WKhV1qCJwqILdboepaMlisaDd7vf9fo+W4kMKmFR9QFSTiGqEqHqHqCYR1QhR9Q5RTSKqET9RdZLxGr0nWP6hzaQKQ3UI89n6drSqeUhMqpgY+nVcb+ewnr2AmjLI+VqfMIDPue/HM5PoHrVmkKMKnnixnB90krqbTb4q0OuTn1guJVaqAFd8GIY4ef4Msvqnhv0iYqv6Bojq+3G//wN9rsRvy4i5OAAAAABJRU5ErkJggg==",c=n("direction-toggle-button","החלף כיוון כתיבת טקסט",r,"direction",t),a=n("markdown-toggle-button","החלף כיוון הצגת תשובות",l,"markdown",o);let i;function d(){i||(i=document.createElement("div"),i.id="custom-btn-group",i.style.cssText="position:absolute;display:flex;gap:10px;z-index:99999;",[c,a].forEach((e=>i.appendChild(e))),document.body.appendChild(i));const t=document.querySelector("#prompt-textarea");if(!t)return;t.style.direction=e;const o=t.getBoundingClientRect(),n=o.top+window.scrollY-10,r=o.left+o.width+110;(i.dataset.top!=n||i.dataset.left!=r)&&(i.dataset.top=n,i.dataset.left=r,[c,a].forEach((e=>{e.style.transform="translateY(0)"}))),i.style.top=n+"px",i.style.left=r+"px"}d(),window.addEventListener("scroll",d),window.addEventListener("resize",d);new MutationObserver(d).observe(document.body,{childList:!0,subtree:!0})})();

דרך שניה

תוסף לדפדפן גוגל כרום

יש ליצור תיקיה חדשה ולשמור בתוכה את הקבצים הבאים:
  1. manifest.json
    {
      "manifest_version": 3,
      "name": "כיוון כתיבת עברית ב-ChatGPT",
      "version": "1.2",
      "author": "Snir Elgabsi",
      "description": "הוספת תפריט קטן לשינוי כיוון כתיבה ב-ChatGPT",
      "icons": {
        "16": "icon.png",
        "48": "icon.png",
        "128": "icon.png"
      },
      "content_scripts": [
        {
          "matches": [
            "https://chat.openai.com/*",
            "https://chatgpt.com/*"
          ],
          "js": [
            "content.js"
          ]
        }
      ],
      "permissions": [],
      "host_permissions": [
        "https://chat.openai.com/*"
        "https://chatgpt.com/*"
      ]
    }
    לחץ כאן כדי להעתיק את הקוד
  2. content.js
    javascript:(function(){
    let textareaDirection = localStorage.getItem('snir-textarea-direction') || 'rtl';
    
    function toggleDirection(){
      textareaDirection = textareaDirection === 'rtl' ? 'ltr' : 'rtl';
      localStorage.setItem('snir-textarea-direction', textareaDirection);
      const textarea = document.querySelector('#prompt-textarea');
      if(textarea){ textarea.style.direction = textareaDirection; }
      const img = document.querySelector('#direction-toggle-button img');
      if(img){ img.style.transform = textareaDirection === 'ltr' ? 'scaleX(-1)' : 'scaleX(1)'; }
    }
    
    function toggleMarkdownDirection(){
      const markdowns=document.querySelectorAll('.markdown');
      markdowns.forEach(el=>{el.dir=el.dir==='rtl'?'ltr':'rtl';});
      const img=document.querySelector('#markdown-toggle-button img');
      if(img){img.style.transform=img.style.transform==='scaleX(-1)'?'scaleX(1)':'scaleX(-1)';}
    }
    
    function toggleWhitespaceStyle(){
      document.querySelectorAll('.whitespace-pre-wrap').forEach(el=>{
        const isActive=el.classList.contains('styled-q');
        if(isActive){
          el.classList.remove('styled-q');
          el.style.border='';el.style.borderRadius='';el.style.background='';
        }else{
          el.classList.add('styled-q');
          el.style.border='2px solid red';
          el.style.borderRadius='10px';
          el.style.boxShadow='0 0 8px 2px red';
          el.style.padding='5px';
        }
      });
    }
    
    function jumpToNext(){	
      const messages = document.querySelectorAll('[data-message-author-role]');
      let current = [...messages].findIndex(m => m.getBoundingClientRect().top > 100);
      if (current !== -1 && messages[current]) {
        messages[current].scrollIntoView({behavior: 'smooth', block: 'start'});
      }
    }
    
    function jumpToPrevious() {
      const messages = [...document.querySelectorAll('[data-message-author-role]')];
      if (messages.length === 0) return;
      let index = messages.findIndex(m => m.getBoundingClientRect().top >= 10);
      if (index === -1) index = messages.length;
      if (index > 0) {
        messages[index - 1].scrollIntoView({ behavior: 'smooth', block: 'start' });
      }
    }
    
    function toggleQButtonGlow(){
      const qButton=document.querySelector('#q-style-toggle-button');
      if(!qButton)return;
      const glowing=qButton.classList.toggle('glowing-q');
      if(glowing){qButton.style.boxShadow='0 0 10px 4px yellow';}
      else{qButton.style.boxShadow='0 2px 6px rgba(0,0,0,0.2)';}
    }
    
    function createTooltip(btn){
      let tooltip = document.createElement('div');
      tooltip.textContent = 'Snir Elgabsi';
      tooltip.style.cssText = `
        position:absolute;
        bottom:120%;
        left:50%;
        transform:translateX(-50%) scale(0.5);
        padding:5px 10px;
        background:rgba(0,0,0,0.7);
        color:white;
        border-radius:6px;
        font-size:0.9rem;
        opacity:0;
        transition:opacity 0.3s ease, transform 0.3s ease;
        pointer-events:auto;
        cursor:pointer;
        z-index:10000;
        white-space:nowrap;
      `;
      tooltip.onclick = () => {
        window.open('https://snir.blogspot.com', '_blank');
      };
      btn.appendChild(tooltip);
      setTimeout(() => {
        tooltip.style.opacity = '1';
        tooltip.style.transform = 'translateX(-50%) scale(1)';
      }, 500);
      setTimeout(() => {
        tooltip.style.opacity = '0';
        tooltip.style.transform = 'translateX(-50%) scale(0.5)';
        setTimeout(() => {
          if (tooltip.parentElement) {
            tooltip.remove();
          }
        }, 300);
      }, 5030);
      btn._tooltip = tooltip;
    }
    
    function removeTooltip(btn){
      if(btn._tooltip){
        btn._tooltip.style.opacity='0';
        btn._tooltip.style.transform='translateX(-50%) scale(0.5)';
        setTimeout(()=>{if(btn._tooltip){btn._tooltip.remove();btn._tooltip=null;}},300);
      }
    }
    
    function addTooltipEvents(btn){
      let hoverTimeout=null;
      let leaveTimeout=null;
      btn.addEventListener('mouseenter',()=>{
        clearTimeout(leaveTimeout);
        hoverTimeout=setTimeout(()=>createTooltip(btn),1500);
      });
      btn.addEventListener('mouseleave',()=>{
        clearTimeout(hoverTimeout);
        leaveTimeout=setTimeout(()=>removeTooltip(btn),1000);
      });
    }
    
    function makeButtonImage(id,title,imgSrc,imgAlt,clickHandler){
      const btn=document.createElement('button');
      btn.id=id;
      btn.title=title;
      btn.style.cssText='width:2.2rem;height:2.2rem;border-radius:50%;background:white;color:black;border:1px solid lightgray;font-size:1.2rem;box-shadow:0 2px 6px rgba(0,0,0,0.2);cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;position:relative;';
      btn.onmouseover=()=>btn.style.backgroundColor='#f0f0f0';
      btn.onmouseout=()=>btn.style.backgroundColor='white';
      btn.onclick=(e)=>{e.preventDefault();clickHandler();};
      const img=document.createElement('img');
      img.src=imgSrc;
      img.alt=imgAlt;
      img.style.cssText='width:1.5rem;height:1.5rem;object-fit:contain;pointer-events:none;';
      btn.appendChild(img);
      addTooltipEvents(btn);
      return btn;
    }
    
    // BASE64 images:
    const imgPromptDir = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAMAAAAp4XiDAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAD/UExURenp6c7OzrKysnl5eVZWVpOTkwAAAAEBAaGhoW1tbQMDA5ycnI2NjVtbW8bGxsjIyMrKyrGxscXFxd3d3dLS0ubm5ujo6IuLi3d3d+Li4uTk5E1NTezs7CYmJicnJ1BQUI6OjtXV1ZKSknZ2dpqamgICAt/f36ampnJyclxcXDk5OaqqqrCwsK+vr7+/v66urnR0dMPDw29vb+7u7rW1tSwsLIWFhUJCQkRERMTExNTU1AYGBsfHx3FxcWtra8nJybOzswQEBE5OTjMzM6mpqa2trdzc3OXl5UxMTKWlpUtLS52dnUlJSZ6enuPj40hISMvLy0ZGRqSkpOvr6wAAAKVmCqgAAABVdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////wCwoQfPAAAACXBIWXMAAA7BAAAOwQG4kWvtAAAAGHRFWHRTb2Z0d2FyZQBQYWludC5ORVQgNS4xLjgbaeqoAAAAtmVYSWZJSSoACAAAAAUAGgEFAAEAAABKAAAAGwEFAAEAAABSAAAAKAEDAAEAAAACAAAAMQECABAAAABaAAAAaYcEAAEAAABqAAAAAAAAANl2AQDoAwAA2XYBAOgDAABQYWludC5ORVQgNS4xLjgAAwAAkAcABAAAADAyMzABoAMAAQAAAAEAAAAFoAQAAQAAAJQAAAAAAAAAAgABAAIABAAAAFI5OAACAAcABAAAADAxMDAAAAAA5X1phWJRlb4AAAFhSURBVEhL5ZRXV8JAEIUpurEiorGAHdGIxoYo9i5WbPP/f4uzmZFkl6xsXuV7yHLP3C9kYU9SkJh/rqTSmWyfQponRKfSLxBHXtoM8IjoUAa5PxSUHUeGYZ4RujLCXSFGc2P5cVwz+cIEDwlNmaS6JIvRxXWKJiGaMh3uYgbjLK5FmoRoSonqEktlbp7qEltlgeoS2wdbpLrEVllKvv1lqktsFVhp/5XWCpR/D5i9AquBUEmiwNq6t1FN9C0Bm8mVreSK36vKtievO0Ls4mKl7AmxXwM4qFcPMRWPGg2XBiGacoy3FSccDKhKQRp5DiYUxcpQlBwKpwUOZiLKmTzy9bJ3HsfFJbeiCv6gFe31HeWKa1GlVhLXfyg+15QHc2/Qub3L+HHcP3BL3X7zEe/2xMFMVIHmMzovHIwoChRf0XnjYEJVoPWOzgcHA5oCrU/xxR9N6Ap8dzmUMUp3eloB+AGGLqjp2OH2dAAAAABJRU5ErkJggg==';
      const imgMarkdownDir = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAE4AAABOCAIAAAAByLdKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAALeSURBVHhe7ZsxjuIwFIZTU+0RKLkBJWlX4gLT0SPtDZBAokFcAYFoqaDZFiqQQKKAHi5ARUvB/orfWCSZOF7ivDHM+ypiXvL7ix2HSCG4/xhE9R2xVV0ul61Wq1qtBiyEYXg+nynbEVaqCKYuMILT6tY2XzXtiU6UCsW4ts1R7Xa7FBsE+Ox8UqXBZUJ5EQ5tTarIoMAgwLVKrSWTUAWubE2qk8lEhWE8qal8tCpC9WR2YmtS1bP3W1Qxj4BDW5PqYyo1lU8i1KGt76rAle0LqAIntq+hCorbvowqKGj7SqqgiK2/qrirU1Ocp229U9W/W5BOTSmes/VOFVkqFBgcnrD1ThVoB/NT6//a+qiKTmsHAGH05Esey3JtfVQFjyNmj/m3uqeqAEOUGLdcUE87f4W/qhqkA6zMWegnsJdXzQXdU/0UVUJUI0TVO0Q1iahGiGqMTqdTq9VQ87s0cHBEIIgiU3CojkYjVcAD4ig4Dofq4XBQBTwcj0cKjsOhCi6Xy5oFBFFkCiZVHxDVJKIakat6vV7VnYaBRqOBOAqOw6E6GAxUAQ+Io+A4HKq3263ZbKoazS9H0OE+QRDiKDgOh6oniGoSUY2wUT2dTn9ZQBBFpuBQ3W63qoAHxFFwHA7V6XSqCnhAHAXH4VAFw+GwXq+j5qM0cHBEIIgiUzCp+oCoJhHVCBvV8Xj8x5per0e7RUsaWjabDW0XgEN1NpupAnva7TZ2nM/ntB0EWc8r9nCorlYrVWBPv9/Hjuv1Wm1WKhV1qCJwqILdboepaMlisaDd7vf9fo+W4kMKmFR9QFSTiGqEqHqHqCYR1QhR9Q5RTSKqET9RdZLxGr0nWP6hzaQKQ3UI89n6drSqeUhMqpgY+nVcb+ewnr2AmjLI+VqfMIDPue/HM5PoHrVmkKMKnnixnB90krqbTb4q0OuTn1guJVaqAFd8GIY4ef4Msvqnhv0iYqv6Bojq+3G//wN9rsRvy4i5OAAAAABJRU5ErkJggg==';
      const imgPrevBtn='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAFBhaW50Lk5FVCA1LjEuOBtp6qgAAAC2ZVhJZklJKgAIAAAABQAaAQUAAQAAAEoAAAAbAQUAAQAAAFIAAAAoAQMAAQAAAAIAAAAxAQIAEAAAAFoAAABphwQAAQAAAGoAAAAAAAAAYAAAAAEAAABgAAAAAQAAAFBhaW50Lk5FVCA1LjEuOAADAACQBwAEAAAAMDIzMAGgAwABAAAAAQAAAAWgBAABAAAAlAAAAAAAAAACAAEAAgAEAAAAUjk4AAIABwAEAAAAMDEwMAAAAACrgCETU544KAAAAeNJREFUaEPtmbtKxEAUhuMFLdRCsRC0ULQTES+VD2Bhr2AraKGljbYWXrASwdY3UAQbKxFRbFwrURCx9gFEK/U/mUmY7CaTEHLM7Ho++DgzG5Ldk7lkZ+IJgpCbHngM7+E6fVCPUBK38MdwD2ahT8c/pUlHk254Dmf8WhRKZkMVE5mCczDu2kWypWMslMQNNFui2l1oYwLGnVe0iWRJInAHJkEtEndO0UYImt/WnZKgltlUxQiDcBs2w5ovLJBFHUN64R2szjiL+9AJ6K61wg6/pn4c8QKfVDHkCn6qYkhwnjPQlFmBlMgbHIZnuh64BBeM+iF0kgF4Asf8muddQDORVUiswANVrA+SEnESGiMNge3pSy0yq4o+a/BIFa20wX5VZIXGcghHIuPwGrZA6pJcdOqYSt4xMgnN87iMwDFGvuEH/IL03OEyAkfXaoc0lXPzqmMqMv2WgSTiGpKIa3BMv0OQVo/cN2lex1TyTr+lrNmla1mg1eYytF27CKz7WibyZC8DScQ1JBHX4Jh+u+A0pGvXPLgK5FLHVPJOvw2zZi8Fjq41Ck8h93bQiI4+HIlQK9MGBDc1OylJyF+UMrAlQi+ATKjPO4stkWf4CB8gvb16h85iG+x0zDwejBVB+D943i8TrRfXoZttJgAAAABJRU5ErkJggg==';  
      const imgNextBtn='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAFBhaW50Lk5FVCA1LjEuOBtp6qgAAAC2ZVhJZklJKgAIAAAABQAaAQUAAQAAAEoAAAAbAQUAAQAAAFIAAAAoAQMAAQAAAAIAAAAxAQIAEAAAAFoAAABphwQAAQAAAGoAAAAAAAAAYAAAAAEAAABgAAAAAQAAAFBhaW50Lk5FVCA1LjEuOAADAACQBwAEAAAAMDIzMAGgAwABAAAAAQAAAAWgBAABAAAAlAAAAAAAAAACAAEAAgAEAAAAUjk4AAIABwAEAAAAMDEwMAAAAACrgCETU544KAAAAfhJREFUaEPtmc0rBVEYhweFBYWVYkFhI8nHirKRjT1lLQskCytbC9mJIks7SxtZKUl3y4IUJf4JHwvh95tzzu3MnWvmds1rZnKeenrfubeZO+89Z87MOeM5HDLU6FgOfmd//6XNHQfwFl7BOzgLc8kFNK1AV2AltOv4p0R1rTM4qVKfZbiv0khG4DSMOnYSbOgYCwuxW2QJVsIQtPeTMkCtjkkiccxYJLpWF9yELCj0zyXInI6xVNu1UiGVbiCBKyRruEKyhsTwWw87VCrKk44+EoUMwktYByXvI006xlLtfWQY2vtJGUDiGvmEL/AdvgkaQKJrNcBOlYryqGMs7hElDVwhWcMVkjUkht9uuAWl/6QZHWOpdvjlKoq9n5QBXNeKgAt0CzDq2Ekgvq6VCm74zRr/shDpi/dX2IVwDnEMB/yt8ImbsXsRbqs0O5iT5ZB5CrmS/gyn4A7k6wHDPHyFR/6W5+3CVZUGaIajkMcO3bgS5FzHIiziBvJHOU1lfID3OjfyxQ+nmPZne7CU1ObsH5BzbGJaqBf2qbTIBGxUaRG2UCYwJ94CT+C4v1UZfDBcV2mAfshrTXo5qEdHH/uCboUsZszfiuanIghbmQsQ0oRWUmxYTAGW9kdbFpELoorJTRGGcsXkrghDGzyE13CNHzgcjrzied8Om+958SArgwAAAABJRU5ErkJggg==';
    
    // כפתורים:
    const dirBtn = makeButtonImage('direction-toggle-button', textareaDirection==='rtl'?'כיוון כתיבה מימין לשמאל - Ctrl+Shift':'כיוון כתיבה משמאל לימין - Ctrl+Shift', imgPromptDir, 'כיוון כתיבה', toggleDirection);
    dirBtn.querySelector('img').style.transform = textareaDirection === "ltr" ? "scaleX(-1)" : "scaleX(1)";
    
    const mdBtn = makeButtonImage('markdown-toggle-button', 'החלף כיוון כתיבה של התשובות', imgMarkdownDir, 'כיוון תשובות', toggleMarkdownDirection);
    
    const qBtn=document.createElement('button');
    qBtn.id='q-style-toggle-button';
    qBtn.title='הפעל/בטל עיצוב על whitespace-pre-wrap';
    qBtn.textContent='Q';
    qBtn.style.cssText=dirBtn.style.cssText;
    qBtn.onclick=(e)=>{e.preventDefault();toggleWhitespaceStyle();toggleQButtonGlow();};
    addTooltipEvents(qBtn);
    
    const nextBtn=makeButtonImage('next-snir-button','קפוץ לשאלה הבאה - Alt+↓',imgNextBtn,'קפוץ לשאלה הבאה',jumpToNext);
    const prevBtn=makeButtonImage('prev-snir-button','קפוץ לשאלה הקודמת - Alt+↑',imgPrevBtn,'קפוץ לשאלה הקודמת',jumpToPrevious);
    
    // יצירת כפתורים
    function createButtons(){
      if(document.querySelector('#direction-toggle-button')) return;
    
      const textarea=document.querySelector('#prompt-textarea');
      const buttonContainer=textarea?.closest('form')?.querySelector('div.flex > div.flex');
      if(!textarea||!buttonContainer) return;
    
      let btnGroup=document.querySelector('#custom-btn-group');
      if(!btnGroup){
        btnGroup=document.createElement('div');
        btnGroup.id='custom-btn-group';
        btnGroup.style.cssText='position:absolute;bottom:13px;right:95px;display:flex;gap:10px;z-index:9999;';
        buttonContainer.style.position='relative';
        buttonContainer.appendChild(btnGroup);
      }
    
      btnGroup.appendChild(prevBtn);
      btnGroup.appendChild(nextBtn);
      btnGroup.appendChild(mdBtn);
      btnGroup.appendChild(dirBtn);
    
      // החלת כיוון כתיבה מה־localStorage
      if (textarea) {
        textarea.style.direction = textareaDirection;
        const img = dirBtn.querySelector('img');
        if (img) img.style.transform = textareaDirection === 'ltr' ? 'scaleX(-1)' : 'scaleX(1)';
      }
    }
    
    document.addEventListener('keydown', function (e) {
      if (e.key === 'ArrowUp' && e.altKey) {
        e.preventDefault();
        jumpToPrevious();
      }
      if (e.key === 'ArrowDown' && e.altKey) {
        e.preventDefault();
        jumpToNext();
      }
      if(e.ctrlKey && e.shiftKey && !e.altKey) {
        e.preventDefault();
        toggleDirection();
      }
    });
    
    const observer=new MutationObserver(()=>{createButtons();});
    observer.observe(document.body,{childList:true,subtree:true});
    createButtons();
    })();
        
    
    
    לחץ כאן כדי להעתיק את הקוד
  3. שמור את התמונה הבאה בשם icon.png 

    התוסף מוכן, כעת נפעיל אותו ע"י הדפדפן:
  1. פתח את Chrome.
  2. :עבור לכתובת
  3. הפעל את Developer mode (בצד ימין למעלה).
  4. לחץ על Load unpacked ובחר את התיקייה עם הקבצים שלך.

יום שני, 16 במאי 2022

הורדה ישירה מחנות מיקרוסופט

1. צריך למצוא את האפליקציה שרוצים להוריד, ולהעתיק את id שלה. 
למשל עבור WinDbg Preview   הכתובת היא:
https://apps.microsoft.com/store/detail/windbg-preview/9PGJGD53TN86
הקוד הוא 9PGJGD53TN86

2. ללכת לאתר: https://store.rg-adguard.net   לבחור ברשימה הנפתחת את product id להזין שם הקוד שהעתקנו,וללחוץ v. 
כמה שניות והכתובות יופיעו. 

 3. צריך להוריד קובץ appx

4. ע"פ אתר https://github.com/MicrosoftFeedback/WinDbg-Feedback/issues/19       צריך לעשות לקובץ unzip לתוך תיקיה ולהריץ את קובץ DbgX.Shell.exe 

5. ע"פ אתר https://digitalitskills.com   צריך להריץ PowerShell ולהתקין:
PS C:\WINDOWS\System32\Add-AppxPackage -Path C:\windbg.appx

יום שלישי, 11 בינואר 2022

C# - Udp Server & Client

UDP Server:


  Thread trdServerUdp = 
     new Thread(new ThreadStart(serverThread));
  trdServerUdp.Start();
}

void ServerThread() {
  UdpClient server = new UdpClient(port);
  while (true) {
    IPEndPoint remoteIpep = new IPEndPoint(IPAddress.Parse(ip), port);
    byte[] receiveBytes = server.Receive(ref remoteIpep);
    string str = Encoding.ASCII.GetString(receiveBytes);
    Console.WriteLine($"{remoteIpep}: {str}");
  }
}
  
UDP Client:


  string ip = "127.0.0.1";
  int port = 8080;

  string input;
  UdpClient client = new UdpClient();
  client.Connect(ip, port);

  byte[] data;
  while (true) {
    input = Console.ReadLine();
    if (input == "exit") break;
    data = Encoding.ASCII.GetBytes(input);
    client.Send(data, data.Length);
  }
}
  

C# - Tcp Server & Client

קוד סרבר שמחכה עד שקליינט יתחבר, ואז מקבל הודעות ומחזיר אותן אל הקליינט:

TCP Server:

void server_foo(){
  int port = 9050;
  int recv;
  byte[]data = new byte[1024];
  IPEndPoint ipep = new IPEndPoint(IPAdress.Any, port);
  Socket newsock = new Socket(AddressFamily.InterNetwork, 
                        SocketType.Stream,
                        ProtocolType.Tcp);

  newsock.Bind(ipep);
  newsock.Listen(10);

  Console.WriteLine("waiting for client...");
  Socket client = newsoc.Accept();

  IPEndPoint clientep = (IPEndPoint )client.RemoteEndPoint;
  Console.WriteLine($"Connected with {clientep.Address} at port {clientep.Port}");
  data = Encoding.ASCII.GetBytes("[CONNECTED TO SERVER]");
  client.Send(data, data.Length, SocketFlag.None);

  while (true) {
     try {
        data = new byte[1024];
        recv = client.Receive(data);
        Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
        if(recv == 0) break; // 0 == exit
        client.Send(data, recv, SocketFlags.None);
     }
     catch (Exception ex) {
        Console.WriteLine(ex.Message);
        Console.ReadLine();
        break;
     }
     finally {
        client.Close();
        newsock.Close();
     }
  }
  Console.WriteLine($"Disconnected from {clientep.Address}:{clientep.Port}");
}
  
לחץ כאן כדי להעתיק את הקוד

קוד קליינט שמנסה כל 5 שניות להתחבר:

TCP Client:

void client_foo(){
   byte[]data = new byte[1024];
   string input, stringData;
   IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(ip), port);
   Socket server = new Socket(AddressFamily.InterNetwork, 
        SocketType.Stream,
        ProtocolType.Tcp);
  
  //try to connect:
  while (true) {
    try {
      server.Connect(ipep);
      Console.WriteLine("CONNECTED");
      break;
    }
    catch {
      //try to reconnect:
      Console.WriteLine("Unable to connect: " + ex.Message);
      Console.WriteLine("Trying to reconnect in:");
  
      for (int i = 1; i <= 5; i++) {
        Console.Write(i);
        Console.CursorLeft = 0;
        Thread.Sleep(1000);
      }
    }
  }

  // connected
  int recv = server.Receive(data);
  stringData = Encoding.ASCII.GetString(data, 0 ,recv);
  Console.WriteLine(stringData);
                            
  while (true) {
    input = Console.ReadLine();
    if (input == "exit") break;

    // send message
    server.Send(Encoding.ASCII.GetBytes(input));
                            
    // get message back
    data = new byte[1024];
    recv = server.Receive(data);
    stringData = Encoding.ASCII.GetString(data, 0 ,recv);
    Console.WriteLine(stringData);
  }

  //close connection to server
  Console.WriteLine("Disconnected from server");
  server.Shutdown(SocketShutdown.Both);
  server.Close();
}
לחץ כאן כדי להעתיק את הקוד

יום חמישי, 15 ביולי 2021

חלוקת מסך בדפדפן האינטרנט

ניתן לבצע חלוקת מסך אופקית או אנכית בדפדפן האינטרנט לשני אתרים בו זמנית!
לשם כך, לחצו ctrl+d בשביל יצירת סימניה חדשה ריקה, ובחרו ליצור אותה בסרגל הסימניות.

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

חלוקת מסך אנכית

חלוקת מסך אופקית

יום שני, 20 בנובמבר 2017

כיצד לתקשר בין צד c# אל צד js בתוך WebBrowser ולהיפך

פרויקט דוגמה להורדה

יש להוסיף בראש הדף (לפני המחלקה הראשונה) את הקוד הבא:
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
[ComVisible(true)]
//[ComVisibleAttribute(true)]
public partial class Form1 : Form {   ... }

בחלק Load של הדף יש להגדיר את WebBrowser ולצורך הדוגמה נכתוב בתוכו את ה-html:
private void Form1_Load(object sender, EventArgs e)
{
  // 4. Set the ObjectForScripting property in the 
      // form's constructor or a Load event handler.
      // The following code uses the form class 
      // itself for the scripting object.
      // Component Object Model (COM) must be able 
      // to access the scripting object.
      // Use [ComVisible(true)] in order to make your 
      //form visible to COM 
      // (add the ComVisibleAttribute attribute to your form class).
  webBrowser1.ObjectForScripting = this;
webBrowser1.DocumentText =
  @"<html><head>
  <script>
  // the js function to call from the c# side:
  function myFoo(arg) { alert(arg); }   </script>   </head><body>
  send code to c# side: <br/>
  <input type='text' id='snir' value='snir send to c#'></input>
  <button onclick='window.external.Test(document.getElementById('snir').value)'>
  call client C# code from javscript code</button>
  </body>
  </html>";
}


נגדיר מתודה שתקבל את המיד מצד js:
// get message from the webpage's js
[ComVisible(true)]
public void Test(string arg)
{
  MessageBox.Show(argt, "C# side");
}

נגדיר מתודה שתשלח מידע אל צד js:
private void SendToWebpage()
{
  webBrowser1.Document.InvokeScript(
    "myFoo",
    new String[] { textBox1.Text }
  );
}