Tolaspace
0 / 20 הודעות
EN
המרחבים הם כלי תמיכה ועיבוד עצמי ואינם מחליפים טיפול נפשי מקצועי. במצב חירום נפשי פנו לער"ן 1201 (24/7, חינם).
שיחה ראשונה חינם · תקנון

מדיניות פרטיות →
💬
מוכנים להתחיל?
- או המשיכו עם אימייל -
הכניסו אימייל - נשלח קוד אימות חד-פעמי.
- כבר רכשתם חבילה? -
20 הודעות ראשונות חינם לחלוטין · ללא הרשמה · ללא התחייבות
קרדיטים בתוקף ל-90 יום מיום הרכישה · חבילות נוספות
שיחה שנסגרת ללא שמירה לא תישמר - קרדיט שנוצל לא יוחזר.
`); win.document.close(); win.focus(); setTimeout(() => win.print(), 600); } function toggleUserMenu() { const panel = document.getElementById('userMenuPanel'); const btn = document.getElementById('userMenuBtn'); const isOpen = panel.style.display === 'block'; panel.style.display = isOpen ? 'none' : 'block'; btn.classList.toggle('active', !isOpen); if (!isOpen) { const cb = document.getElementById('historyConsentPanel'); if (cb) cb.checked = userConsentHistory; } } document.addEventListener('click', function(e) { const panel = document.getElementById('userMenuPanel'); const btn = document.getElementById('userMenuBtn'); if (panel && btn && !panel.contains(e.target) && !btn.contains(e.target)) { panel.style.display = 'none'; btn.classList.remove('active'); } }); function toggleDiscCheck() { const cb = document.getElementById('discCheck'); cb.checked = !cb.checked; updateDiscBtn(); } function toggleDiscCheck2() { const cb = document.getElementById('discCheck2'); cb.checked = !cb.checked; updateDiscBtn(); } function updateDiscBtn() { const c1 = document.getElementById('discCheck').checked; const c2 = document.getElementById('discCheck2').checked; document.getElementById('discBtn').disabled = !(c1 && c2); } function acceptDisclaimer() { localStorage.setItem('tolaspace_disc', '1'); document.getElementById('discOverlay').style.display = 'none'; // Continue with normal gate flow const savedUUID = localStorage.getItem('merkhavim_uuid'); const savedEmail = localStorage.getItem('merkhavim_email_' + agentSlug); const freeUsed = localStorage.getItem('merkhavim_free_' + agentSlug); if (savedUUID) { userUUID = savedUUID; userEmail = savedEmail || 'uuid_user'; closeGate(); showWelcomeUI(); loadHistory(); } else if (savedEmail && !freeUsed) { userEmail = savedEmail; closeGate(); showWelcomeUI(); } else if (savedEmail && freeUsed) { userEmail = savedEmail; closeGate(); showWelcomeUI(); showLimitBanner(); } else { document.getElementById('gateOverlay').style.display = 'flex'; } } function loadSavedProfile() { try { const p = JSON.parse(localStorage.getItem('merkhavim_profile') || 'null'); if (p && p.email) { document.getElementById('emailInput').value = p.email; document.getElementById('rememberCheck').checked = true; const sub = document.querySelector('.gate-sub'); sub.innerHTML = 'ברוכים חזרה האימייל שלכם מולא אוטומטית.'; } } catch {} } function init() { const params = new URLSearchParams(window.location.search); agentSlug = params.get('agent') || 'horut'; agentCfg = AGENTS[agentSlug] || AGENTS.horut; // UUID מה-URL - מגיע מדף thank-you const urlUUID = params.get('uuid'); if (urlUUID) { localStorage.setItem('merkhavim_uuid', urlUUID.toUpperCase()); } document.title = 'tolaspace'; document.getElementById('gateAgentTag').textContent = agentCfg.name; populateBanner(); // עדכן FAQ גישות לפי הסוכן הנוכחי const faqApproaches = document.getElementById('faqApproachesAnswer'); if (faqApproaches && agentCfg.approaches) { faqApproaches.textContent = 'טולה מבוססת על: ' + agentCfg.approaches + '.'; } document.documentElement.style.setProperty('--agent-color', agentCfg.color); document.documentElement.style.setProperty('--agent-btn', agentCfg.btn); // Admin test bypass (URL param or localStorage) if (params.get('bypass') === 'tolaspace2026' || localStorage.getItem('tolaspace_bypass') === 'tolaspace2026') { localStorage.setItem('tolaspace_bypass', 'tolaspace2026'); localStorage.setItem('tolaspace_disc', '1'); userUUID = 'TEST_ADMIN'; userEmail = 'admin@tolaspace'; closeGate(); showWelcomeUI(); return; } // Show disclaimer on first visit if (!localStorage.getItem('tolaspace_disc')) { document.getElementById('discOverlay').style.display = 'flex'; document.getElementById('gateOverlay').style.display = 'none'; return; } // Enter on email field document.getElementById('emailInput').addEventListener('keydown', e => { if (e.key === 'Enter') startFreeChat(); }); document.getElementById('codeInput').addEventListener('keydown', e => { if (e.key === 'Enter') startWithCode(); }); loadSavedProfile(); loadConsentSetting(); // Check if already passed gate const savedUUID = localStorage.getItem('merkhavim_uuid'); const savedEmail = localStorage.getItem('merkhavim_email_' + agentSlug); const freeUsed = localStorage.getItem('merkhavim_free_' + agentSlug); if (savedUUID) { userUUID = savedUUID; userEmail = savedEmail || 'uuid_user'; closeGate(); showWelcomeUI(); loadHistory(); // בדיקת יתרה בשקט fetch(WORKER + '/validate-customer', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ uuid: savedUUID }), }).then(r => r.json()).then(d => { if (d.ok) { userBalance = d.remaining; showBalanceIndicator(d.remaining); } else if (d.reason === 'no_balance') showLimitBanner(); }).catch(() => {}); } else if (savedEmail && !freeUsed) { userEmail = savedEmail; closeGate(); showWelcomeUI(); } else if (savedEmail && freeUsed) { userEmail = savedEmail; closeGate(); showWelcomeUI(); showLimitBanner(); } } function populateBanner() { const banner = document.getElementById('agentBanner'); banner.style.background = 'linear-gradient(135deg,' + agentCfg.bgFrom + ' 0%,' + agentCfg.bgTo + ' 100%)'; const iconEl = document.getElementById('bannerIcon'); iconEl.innerHTML = agentCfg.icon; const svg = iconEl.querySelector('svg'); if (svg) svg.style.stroke = agentCfg.color; const nameEl = document.getElementById('bannerName'); nameEl.textContent = 'טולה'; nameEl.style.color = agentCfg.textDark; const subEl = document.getElementById('bannerSubtitle'); subEl.textContent = agentCfg.name + ' · ' + agentCfg.approaches; subEl.style.color = agentCfg.subText; const ldot = document.getElementById('bannerLdot'); ldot.style.background = agentCfg.color; const live = banner.querySelector('.banner-live'); if (live) live.style.color = agentCfg.textDark; } function showWelcomeUI() { // Welcome card const welcomeCard = document.getElementById('welcomeCard'); welcomeCard.style.display = 'block'; // Icon + name in welcome header const wIcon = document.getElementById('welcomeAgentIcon'); wIcon.innerHTML = agentCfg.icon; wIcon.style.background = 'linear-gradient(135deg,' + agentCfg.bgFrom + ' 0%,' + agentCfg.bgTo + ' 100%)'; const wSvg = wIcon.querySelector('svg'); if (wSvg) wSvg.style.stroke = agentCfg.color; document.getElementById('welcomeTitle').textContent = 'שלום, אני טולה'; document.getElementById('welcomeText').textContent = agentCfg.desc; // Example questions if (agentCfg.examples && agentCfg.examples.length) { const box = document.getElementById('exampleBox'); box.style.display = 'block'; document.getElementById('exampleList').innerHTML = agentCfg.examples.join('
'); } // Chips const chipsRow = document.getElementById('chipsRow'); chipsRow.innerHTML = ''; (agentCfg.chips || []).forEach(chip => { const el = document.createElement('div'); el.className = 'chip'; el.textContent = chip; el.onclick = () => startWithTopic(chip); chipsRow.appendChild(el); }); // Show history consent modal if user hasn't decided yet setTimeout(showHistoryModal, 600); } function startWithTopic(topic) { hideWelcome(); const ta = document.getElementById('userInput'); ta.value = 'אני רוצה לשאול על: ' + topic; autoResize(ta); document.getElementById('sendBtn').disabled = false; sendMessage(); } function hideWelcome() { const w = document.getElementById('welcomeCard'); if (w) w.style.display = 'none'; } async function sendOtp() { const email = document.getElementById('emailInput').value.trim(); if (!email || !email.includes('@') || !email.includes('.')) { document.getElementById('emailInput').style.borderColor = '#C47A7A'; return; } const btn = document.getElementById('sendOtpBtn'); btn.disabled = true; btn.textContent = 'שולח קוד...'; try { const checkRes = await fetch(WORKER + '/check-email', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email }), }); const checkData = await checkRes.json(); if (checkData.used) { btn.disabled = false; btn.textContent = 'שלחו לי קוד אימות'; const sub = document.getElementById('gateSub1'); sub.innerHTML = 'המייל הזה כבר השתמש בשיחה החינמית.
להמשך - הכניסו קוד גישה למטה.'; sub.style.color = '#C47A7A'; return; } const res = await fetch(WORKER + '/send-otp', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email }), }); const data = await res.json(); if (!data.ok) { btn.disabled = false; btn.textContent = 'שלחו לי קוד אימות'; document.getElementById('gateSub1').innerHTML = 'שגיאה בשליחה. נסו שוב.'; return; } document.getElementById('gateStep1').style.display = 'none'; document.getElementById('gateStep2').style.display = 'block'; document.getElementById('otpInput').focus(); btn.disabled = false; btn.textContent = 'שלחו לי קוד אימות'; } catch { btn.disabled = false; btn.textContent = 'שלחו לי קוד אימות'; document.getElementById('gateSub1').innerHTML = 'שגיאת חיבור. נסו שוב.'; } } async function verifyOtp() { const email = document.getElementById('emailInput').value.trim(); const code = document.getElementById('otpInput').value.trim(); if (code.length !== 6) { document.getElementById('otpInput').style.borderColor = '#C47A7A'; document.getElementById('gateSub2').innerHTML = 'יש להזין קוד בן 6 ספרות מהמייל.'; return; } const btn = document.getElementById('verifyOtpBtn'); btn.disabled = true; btn.textContent = 'מאמת...'; try { const res = await fetch(WORKER + '/verify-otp', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, code }), }); const data = await res.json(); if (!data.ok) { btn.disabled = false; btn.textContent = 'אמתו והתחילו'; const msgs = { expired: 'הקוד פג תוקף - חזרו ובקשו קוד חדש.', wrong_code: `קוד שגוי. נותרו ${data.attempts_left} ניסיונות.`, too_many_attempts: 'יותר מדי ניסיונות. בקשו קוד חדש.' }; document.getElementById('gateSub2').innerHTML = `${msgs[data.error] || 'שגיאה. נסו שוב.'}`; return; } userEmail = email; localStorage.setItem('merkhavim_email_' + agentSlug, email); if (document.getElementById('rememberCheck').checked) { localStorage.setItem('merkhavim_profile', JSON.stringify({ email, date: new Date().toISOString() })); } else { localStorage.removeItem('merkhavim_profile'); } fetch(WORKER + '/save-lead', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, agent: agentSlug, type: 'חינם' }), }).catch(() => {}); closeGate(); showWelcomeUI(); } catch { btn.disabled = false; btn.textContent = 'אמתו והתחילו'; document.getElementById('gateSub2').innerHTML = 'שגיאת חיבור. נסו שוב.'; } } function backToEmail() { document.getElementById('gateStep2').style.display = 'none'; document.getElementById('gateStep1').style.display = 'block'; document.getElementById('otpInput').value = ''; } async function startWithCode() { const input = document.getElementById('codeInput').value.trim().toUpperCase(); const btn = document.querySelector('.gate-code-btn'); if (!input) { document.getElementById('codeInput').style.borderColor = '#C47A7A'; return; } btn.disabled = true; btn.textContent = 'בודק...'; try { const res = await fetch(WORKER + '/validate-customer', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ uuid: input }), }); const data = await res.json(); if (!data.ok) { btn.disabled = false; btn.textContent = 'כניסה'; const inp = document.getElementById('codeInput'); inp.style.borderColor = '#C47A7A'; const note = document.querySelector('.gate-note'); if (data.reason === 'not_found') note.innerHTML = 'הקוד לא נמצא. בדקו שהעתקתם נכון.'; if (data.reason === 'expired') note.innerHTML = 'הקוד פג תוקף. לרכישה מחדש ←'; if (data.reason === 'no_balance') note.innerHTML = 'השיחות נגמרו. לרכישת חבילה נוספת ←'; return; } // הצלחה userUUID = input; userBalance = data.remaining; userEmail = data.email || 'uuid_user'; localStorage.setItem('merkhavim_uuid', input); localStorage.setItem('merkhavim_email_' + agentSlug, userEmail); btn.disabled = false; btn.textContent = 'כניסה'; closeGate(); showWelcomeUI(); showBalanceIndicator(data.remaining); loadHistory(); } catch { btn.disabled = false; btn.textContent = 'כניסה'; document.querySelector('.gate-note').innerHTML = 'שגיאת חיבור. נסו שוב.'; } } function closeGate() { document.getElementById('gateOverlay').style.display = 'none'; document.getElementById('sendBtn').disabled = false; document.getElementById('userInput').focus(); } function showBalanceIndicator(remaining) { const label = document.getElementById('userMenuLabel'); const btn = document.getElementById('userMenuBtn'); const balSection = document.getElementById('userMenuBalanceSection'); const balText = document.getElementById('userMenuBalanceText'); const emailEl = document.getElementById('userMenuEmail'); const divider = document.getElementById('userMenuDivider'); if (label) label.textContent = remaining === 1 ? 'שיחה אחת' : `${remaining} שיחות`; if (btn) btn.style.color = remaining <= 2 ? '#C47A7A' : ''; if (balSection) balSection.style.display = 'block'; if (divider) divider.style.display = 'block'; if (balText) balText.textContent = remaining === 1 ? 'נותרה שיחה אחת' : `נותרו ${remaining} שיחות`; if (emailEl && userEmail) emailEl.textContent = userEmail; } function showLimitBanner() { isLimited = true; document.getElementById('sendBtn').disabled = true; document.getElementById('userInput').disabled = true; document.getElementById('userInput').placeholder = userUUID ? 'השיחות הסתיימו' : 'השיחה החינמית הסתיימה'; const banner = document.createElement('div'); banner.className = 'limit-banner'; banner.innerHTML = userUUID ? 'השיחות בחבילה הסתיימו. לרכישת חבילה נוספת ←' : 'השיחה החינמית הסתיימה. לרכישת חבילה ←'; document.getElementById('chatArea').appendChild(banner); scrollDown(); } function autoResize(el) { el.style.height = 'auto'; el.style.height = Math.min(el.scrollHeight, 130) + 'px'; document.getElementById('sendBtn').disabled = !el.value.trim(); } function handleKey(e) { if (e.key === 'Enter' && e.shiftKey) { e.preventDefault(); if (!document.getElementById('sendBtn').disabled) sendMessage(); } } function startNewChat() { if (messages.length > 0 && !confirm('להתחיל שיחה חדשה? השיחה הנוכחית תאבד.')) return; messages = []; msgCount = 0; updateCounter(); document.getElementById('chatArea').innerHTML = ''; document.getElementById('downloadBtn').style.display = 'none'; showWelcomeUI(); } async function handleGoogleSignIn(response) { const msgEl = document.getElementById('googleMsg'); msgEl.style.color = 'var(--text-muted)'; msgEl.textContent = 'מתחבר...'; try { // פענוח JWT לקבלת מייל const payload = JSON.parse(atob(response.credential.split('.')[1].replace(/-/g,'+').replace(/_/g,'/'))); const email = payload.email; const res = await fetch(WORKER + '/validate-by-email', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email }) }); const data = await res.json(); if (data.ok) { userUUID = data.uuid; userBalance = data.remaining; userEmail = email; localStorage.setItem('merkhavim_uuid', data.uuid); localStorage.setItem('merkhavim_email_' + agentSlug, email); msgEl.textContent = ''; // הצג שלב הסכמה לפני כניסה לצ'אט document.getElementById('gateStep1').style.display = 'none'; document.getElementById('gateStep3').style.display = 'block'; } else { const msgs = { not_found: 'לא נמצא חשבון עם המייל הזה. רכשו חבילה או הכניסו קוד גישה.', expired: 'החבילה פגה תוקף. לרכישה מחדש ←', no_balance: 'השיחות הסתיימו. לרכישת חבילה ←', deactivated: 'החשבון מושבת. פנו לליאת.', }; msgEl.style.color = '#C47A7A'; msgEl.innerHTML = msgs[data.reason] || 'שגיאה. נסו שנית.'; } } catch { msgEl.style.color = '#C47A7A'; msgEl.textContent = 'שגיאת חיבור. נסו שנית.'; } } function finishGoogleLogin() { const checked = document.getElementById('historyConsentGoogle').checked; setHistoryConsent(checked); closeGate(); showWelcomeUI(); showBalanceIndicator(userBalance); loadHistory(); } function loadConsentSetting() { userConsentHistory = localStorage.getItem('merkhavim_history_consent') === '1'; const cb = document.getElementById('historyConsentGate'); if (cb) cb.checked = userConsentHistory; } function setHistoryConsent(on) { userConsentHistory = on; localStorage.setItem('merkhavim_history_consent', on ? '1' : '0'); const cb = document.getElementById('historyConsentPanel'); if (cb) cb.checked = on; if (!on && userUUID) { fetch(WORKER + '/save-history', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ uuid: userUUID, agent: agentSlug, messages: [] }) }).catch(() => {}); } } function showHistoryModal() { // show only if user hasn't answered yet if (localStorage.getItem('merkhavim_history_consent') !== null) return; document.getElementById('histModal').style.display = 'flex'; } function answerConsent(yes) { document.getElementById('histModal').style.display = 'none'; setHistoryConsent(yes); if (yes) loadHistory(); } async function loadHistory() { if (!userConsentHistory || !userUUID) return; try { const res = await fetch(WORKER + '/get-history', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ uuid: userUUID, agent: agentSlug }) }); const data = await res.json(); if (!data.ok || !data.history || !data.history.length) return; // הוסף מחיצה ויזואלית const divider = document.createElement('div'); divider.style.cssText = 'text-align:center;font-size:.72rem;color:var(--text-light);padding:12px 0;opacity:.7'; divider.textContent = '- שיחה קודמת -'; document.getElementById('chatArea').appendChild(divider); // רנדר הודעות קודמות for (const m of data.history) { if (m.role === 'user') addUserMessage(m.content); else addAgentMessage(m.content); } // שמור ב-messages כדי שהמודל יקבל הקשר messages = data.history.map(m => ({ role: m.role, content: m.content })); msgCount = messages.length; updateCounter(); // הצג כפתור הורדה document.getElementById('downloadBtn').style.display = 'inline-flex'; const divider2 = document.createElement('div'); divider2.style.cssText = 'text-align:center;font-size:.72rem;color:var(--text-light);padding:12px 0;opacity:.7'; divider2.textContent = '- המשך שיחה -'; document.getElementById('chatArea').appendChild(divider2); hideWelcome(); } catch {} } function saveHistory() { if (!userConsentHistory || !userUUID || !messages.length) return; fetch(WORKER + '/save-history', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ uuid: userUUID, agent: agentSlug, messages }) }).catch(() => {}); } async function sendMessage() { const ta = document.getElementById('userInput'); const text = ta.value.trim(); if (!text || isLimited) return; hideWelcome(); ta.value = ''; ta.style.height = 'auto'; document.getElementById('sendBtn').disabled = true; addUserMessage(text); messages.push({ role: 'user', content: text }); msgCount++; updateCounter(); const typing = addTyping(); try { const res = await fetch(WORKER + '/merkhavim-chat', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ agent: agentSlug, messages, email: userEmail, uuid: userUUID || undefined, bgContext: bgFileContent || undefined }), }); const data = await res.json(); typing.remove(); if (data.error) { addAgentMessage('אירעה שגיאה: ' + data.error); } else { const reply = data.reply; addAgentMessage(reply); messages.push({ role: 'assistant', content: reply }); msgCount++; updateCounter(); document.getElementById('downloadBtn').style.display = 'inline-flex'; // consume שיחה אם יש UUID (רק בהודעה ה-2 כדי לא לחייב על פתיחה) if (userUUID && msgCount === 2) { fetch(WORKER + '/consume-unit', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ uuid: userUUID, agent: agentSlug }), }).then(r => r.json()).then(d => { if (d.ok) { userBalance = d.remaining; showBalanceIndicator(d.remaining); } else if (d.reason === 'no_balance') showLimitBanner(); }).catch(() => {}); } saveHistory(); if (!userUUID && msgCount >= FREE_LIMIT) { localStorage.setItem('merkhavim_free_' + agentSlug, '1'); showLimitBanner(); return; } if (msgCount >= MAX_MESSAGES) showLimitBanner(); } } catch (err) { typing.remove(); addAgentMessage('לא הצלחתי להתחבר. בדקו חיבור אינטרנט ונסו שוב.'); } document.getElementById('sendBtn').disabled = false; document.getElementById('userInput').focus(); } function addUserMessage(text) { const div = document.createElement('div'); div.className = 'msg user'; div.innerHTML = `
${USER_ICON}
${escHtml(text)}
`; document.getElementById('chatArea').appendChild(div); scrollDown(); } const TOLA_AVATAR = `ט`; function addAgentMessage(text) { const div = document.createElement('div'); div.className = 'msg assistant'; div.innerHTML = `
${TOLA_AVATAR}
${renderMd(text)}
`; document.getElementById('chatArea').appendChild(div); scrollDown(); return div; } function addTyping() { const div = document.createElement('div'); div.className = 'msg assistant'; div.innerHTML = `
${TOLA_AVATAR}
`; document.getElementById('chatArea').appendChild(div); scrollDown(); return div; } function getInitials(name) { const parts = name.trim().split(' '); if (parts.length >= 2) return parts[0][0] + parts[1][0]; return parts[0].slice(0, 2); } function updateCounter() { const limit = userUUID ? MAX_MESSAGES : FREE_LIMIT; document.getElementById('msgCounter').textContent = msgCount + ' / ' + limit + ' הודעות'; } function scrollDown() { const wrap = document.getElementById('chatWrap'); wrap.scrollTop = wrap.scrollHeight; } function escHtml(str) { return str .replace(/&/g,'&').replace(//g,'>') .replace(/\n/g,'
'); } function renderMd(text) { let s = text .replace(/&/g,'&').replace(//g,'>'); s = s.replace(/^#{1,6}\s+/gm, ''); // strip # headings s = s.replace(/\*\*(.+?)\*\*/gs, '$1'); // **bold** s = s.replace(/\*(.+?)\*/g, '$1'); // *italic* → plain s = s.replace(/\s*—\s*/g, ', '); // em-dash → comma s = s.replace(/\n/g,'
'); return s; } init();