Siteβ―Builder
Editing:
play-json2.php
writable 0666
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Interactive Prompt Playground</title> <meta name="viewport" content="width=device-width,initial-scale=1"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"> <style> body { max-width: 860px; margin: 3rem auto; font-family: sans-serif; } h1 { text-align: center; margin-bottom: 2rem; } article.prompt-card { background: #fff; border: 1px solid #ddd; border-radius: 8px; padding: 1rem; margin-bottom: 1.5rem; } .prompt-text { line-height: 1.6; } .token { color: #5c3bff; font-weight: 600; cursor: pointer; position: relative; } .token .tooltip { position: absolute; bottom: 100%; left: 0; background: #fff; color: #000; padding: .2rem .4rem; border: 1px solid #ccc; border-radius: 4px; font-size: .8rem; white-space: nowrap; opacity: 0; transform: translateY(4px); transition: opacity .2s, transform .2s; pointer-events: none; } .token:hover .tooltip { opacity: 1; transform: translateY(0); } .editor-panel { max-height: 0; overflow: hidden; opacity: 0; transition: max-height .3s ease, opacity .2s ease; margin-top: 1rem; } .editor-panel.open { max-height: 600px; opacity: 1; overflow-y: auto; } .editor-panel .body { background: #f9f9f9; border: 1px solid #ccc; border-radius: 6px; padding: .8rem; } .editor-panel .body input[type="text"], .editor-panel .body textarea, .editor-panel .body select { width: 100%; margin-top: .5rem; padding: .4rem; border: 1px solid #999; border-radius: 4px; font-size: 1rem; } .editor-panel .body label { display: block; margin-top: .5rem; } .ai-btns { margin-top: 1rem; display: flex; gap: .7rem; } .ai-btns a { display: inline-block; padding: .5em 1em; border-radius: 6px; color: #fff; text-decoration: none; font-weight: 600; } .ai-btns a.chatgpt { background: #6c48ff; } .ai-btns a.perplexity { background: #1ca7ec; } .ai-btns a.copilot { background: #00c853; color: #173E22; } .ai-btns a:hover { filter: brightness(1.1); } </style> </head> <body> <h1>Interactive Prompt Playground</h1> <div id="app"></div> <script> (async () => { const SEP = ' β’ '; const RX = /\[(?:([A-DI]?)-)?([^~|\-\]]+)(?:-([^~\]]+))?(?:~([^~]+)~)?\]/g; const resp = await fetch('prompts.json'); const data = await resp.json(); const app = document.getElementById('app'); // Renders one prompt card function renderPrompt(tpl, pi) { const meta = [], state = {}; const tokenized = tpl.replace(RX, (match, cmd, lab, ops, def) => { cmd = cmd || ''; ops = ops || ''; def = def || ''; const opts = ops.split('|').map(s => s.trim()).filter(Boolean); let initial = def; if (cmd === 'C' && def) { initial = def.split(',').map(s => s.trim()).join(SEP); } meta.push({ cmd, lab, opts }); state[lab] = initial; return `<span class="token" data-i="${meta.length-1}">` + `[${initial}]<span class="tooltip">${lab}</span></span>`; }); const card = document.createElement('article'); card.className = 'prompt-card'; card.innerHTML = `<p class="prompt-text">${tokenized.replace(/\n/g, '<br>')}</p>` + `<div class="editor-panel"><div class="body"></div></div>` + `<div class="ai-btns">` + `<a class="chatgpt" data-base="https://chatgpt.com/?prompt=">ChatGPT</a>` + `<a class="perplexity" data-base="https://www.perplexity.ai/search?q=">Perplexity</a>` + `<a class="copilot" data-base="https://copilot.microsoft.com/?q=">Copilot</a>` + `</div>`; app.append(card); // Update AI buttons function rebuild() { let result = tpl; result = result.replace(RX, (_, __, lab) => state[lab] || ''); card.querySelectorAll('.ai-btns a').forEach(a => { a.href = a.dataset.base + encodeURIComponent(result); }); } rebuild(); // Token click handler card.querySelectorAll('.token').forEach(tok => { tok.addEventListener('click', () => { const mi = +tok.dataset.i; const { cmd, lab, opts } = meta[mi]; const cur = state[lab]; const panel = card.querySelector('.editor-panel'); const body = panel.querySelector('.body'); panel.classList.add('open'); body.innerHTML = `<strong>${lab}</strong><br>`; let inputEl; switch (cmd) { case 'A': inputEl = document.createElement('textarea'); inputEl.rows = 3; inputEl.value = cur; inputEl.addEventListener('input', () => { state[lab] = inputEl.value; tok.firstChild.nodeValue = `[${inputEl.value}]`; rebuild(); }); break; case 'B': inputEl = document.createElement('div'); opts.forEach(o => { const lbl = document.createElement('label'); const r = document.createElement('input'); r.type = 'radio'; r.name = `r${pi}${mi}`; r.value = o; if (o === cur) r.checked = true; r.addEventListener('change', () => { state[lab] = o; tok.firstChild.nodeValue = `[${o}]`; rebuild(); panel.classList.remove('open'); }); lbl.append(r, ' ', o); inputEl.append(lbl); }); break; case 'C': inputEl = document.createElement('div'); opts.forEach(o => { const lbl = document.createElement('label'); const c = document.createElement('input'); c.type = 'checkbox'; c.value = o; c.checked = state[lab].split(SEP).includes(o); c.addEventListener('change', () => { const sel = [...inputEl.querySelectorAll('input:checked')].map(i => i.value); state[lab] = sel.join(SEP); tok.firstChild.nodeValue = `[${state[lab]}]`; rebuild(); }); lbl.append(c, ' ', o); inputEl.append(lbl); }); break; case 'D': inputEl = document.createElement('select'); let list = opts; if (opts.every(o => /^\d+$/.test(o))) { const max = Math.max(...opts.map(Number)); list = Array.from({ length: max }, (_, i) => '' + (i + 1)); } list.forEach(o => { const optEl = document.createElement('option'); optEl.textContent = o; if (o === cur) optEl.selected = true; inputEl.append(optEl); }); inputEl.addEventListener('change', () => { state[lab] = inputEl.value; tok.firstChild.nodeValue = `[${inputEl.value}]`; rebuild(); panel.classList.remove('open'); }); break; case 'I': inputEl = document.createElement('select'); const placeholder = document.createElement('option'); placeholder.textContent = cur; placeholder.disabled = true; placeholder.selected = true; inputEl.append(placeholder); opts.forEach(u => { const optEl = document.createElement('option'); optEl.textContent = u; inputEl.append(optEl); }); inputEl.addEventListener('change', () => { state[lab] = inputEl.value; tok.firstChild.nodeValue = `[${inputEl.value}]`; rebuild(); panel.classList.remove('open'); }); break; default: inputEl = document.createElement('input'); inputEl.type = 'text'; inputEl.value = cur; inputEl.addEventListener('input', () => { state[lab] = inputEl.value; tok.firstChild.nodeValue = `[${inputEl.value}]`; rebuild(); }); } if (inputEl) body.append(inputEl); const onDocClick = e => { if (!panel.contains(e.target) && !tok.contains(e.target)) { panel.classList.remove('open'); document.removeEventListener('mousedown', onDocClick); } }; document.addEventListener('mousedown', onDocClick); }); }); } // Render all prompts as cards data.forEach((item, idx) => renderPrompt(item.prompt, idx)); })(); </script> </body> </html>
Save changes
Create folder
writable 0777
Create
Cancel