Files
.sune/ev/landing.sune

1 line
6.1 KiB
Plaintext

[{"id":"fsr2nfx","name":"4ev Landing","pinned":false,"avatar":"","url":"gh://multipleof4/.sune/ev/landing.sune","updatedAt":1758950913132,"settings":{"model":"google/gemini-2.5-pro","temperature":"","top_p":"","top_k":"","frequency_penalty":"","repetition_penalty":"","min_p":"","top_a":"","verbosity":"","reasoning_effort":"default","system_prompt":"","html":"<!--\n Sune: URL Shortener\n Version: 1.0.1\n-->\n<div x-data x-init=\"\n const root = $el;\n const $ = q => root.querySelector(q);\n const cacheKey = `sune_input_${window.SUNE?.id || 'shortener'}`;\n\n const loadScript = (src, check) => new Promise((res, rej) => {\n if (window[check]) return res();\n const s = document.createElement('script');\n s.src = src;\n s.async = true;\n s.defer = true;\n s.onload = res;\n s.onerror = () => rej(`Failed to load ${src}`);\n document.head.appendChild(s);\n });\n\n const form = $('#shorten-form');\n const urlInput = $('#url-input');\n const submitBtn = $('#submit-button');\n const msgArea = $('#message-area');\n const resultBox = $('#result-container');\n const resultOut = $('#result-output');\n const copyBtn = $('#copy-button');\n const openBtn = $('#open-link-button');\n\n const normalizeUrl = s => {\n s = s.trim();\n if (!s) return '';\n if (!s.includes('://')) s = 'https://' + s;\n try { return new URL(s).href; } catch (e) { return ''; }\n };\n \n urlInput.value = localStorage.getItem(cacheKey) || '';\n\n form.onsubmit = async e => {\n e.preventDefault();\n msgArea.textContent = '';\n const u = normalizeUrl(urlInput.value);\n if (!u) return msgArea.textContent = 'Please enter a valid URL.';\n \n try {\n await loadScript('https://www.google.com/recaptcha/api.js', 'grecaptcha');\n } catch(err) {\n return msgArea.textContent = 'Could not load CAPTCHA.';\n }\n\n const k = grecaptcha.getResponse();\n if (!k) return msgArea.textContent = 'Please complete the CAPTCHA.';\n \n submitBtn.disabled = true;\n submitBtn.innerHTML = '…';\n \n try {\n const r = await fetch('/api/create', {\n method: 'POST',\n headers: {'Content-Type': 'application/json'},\n body: JSON.stringify({url: u, token: k})\n });\n if (!r.ok) throw new Error(await r.text() || r.statusText);\n const d = await r.json();\n resultBox.hidden = false;\n resultOut.value = d.shortUrl;\n openBtn.href = d.shortUrl;\n } catch (err) {\n resultBox.hidden = true;\n msgArea.textContent = err.message || 'An unknown error occurred.';\n } finally {\n grecaptcha.reset();\n submitBtn.disabled = false;\n submitBtn.innerHTML = 'Shorten';\n }\n };\n\n copyBtn.onclick = async () => {\n resultOut.select();\n try {\n await navigator.clipboard.writeText(resultOut.value);\n copyBtn.innerHTML = '<i data-lucide=\\'check\\' class=\\'w-5 h-5 text-green-500\\'></i>';\n lucide.createIcons();\n setTimeout(() => {\n copyBtn.innerHTML = '<i data-lucide=\\'copy\\' class=\\'w-5 h-5\\'></i>';\n lucide.createIcons();\n }, 1200);\n } catch (err) {}\n };\n\n resultOut.onclick = () => resultOut.select();\n urlInput.oninput = () => {\n resultBox.hidden = true;\n msgArea.textContent = '';\n localStorage.setItem(cacheKey, urlInput.value);\n };\n\" class=\"relative bg-gray-50 dark:bg-neutral-950 text-gray-800 dark:text-gray-300 antialiased w-full rounded-2xl border border-gray-200 dark:border-neutral-800 overflow-hidden\">\n <span class=\"absolute top-2 right-3 text-xs text-gray-400 dark:text-neutral-600\">v1.0.1</span>\n <section class=\"p-4 sm:p-6 text-center\">\n <h1 class=\"text-2xl sm:text-3xl font-bold tracking-tight text-black dark:text-white\">\n Links that last <span class=\"text-gray-400 dark:text-neutral-500\">forever</span>.\n </h1>\n <p class=\"mt-2 max-w-2xl mx-auto text-sm text-gray-600 dark:text-neutral-400\">\n A simple, fast, and reliable URL shortener.\n </p>\n\n <form id=\"shorten-form\" class=\"mt-6 max-w-xl mx-auto flex flex-col gap-4\">\n <div class=\"flex flex-col sm:flex-row gap-3\">\n <label class=\"relative flex-1\">\n <i data-lucide=\"link\" class=\"absolute top-1/2 left-4 -translate-y-1/2 w-5 h-5 text-gray-400 dark:text-neutral-500\"></i>\n <input id=\"url-input\" type=\"text\" placeholder=\"your-long-link.com\" autocapitalize=\"off\" spellcheck=\"false\" class=\"w-full pl-11 pr-4 py-3 bg-white dark:bg-neutral-900 border border-gray-200 dark:border-neutral-800 rounded-lg focus:ring-2 focus:ring-black dark:focus:ring-white focus:outline-none transition\">\n </label>\n <button id=\"submit-button\" type=\"submit\" class=\"px-6 py-3 font-semibold bg-black dark:bg-white text-white dark:text-black rounded-lg hover:opacity-90 transition-opacity disabled:opacity-50 disabled:cursor-wait\">\n Shorten\n </button>\n </div>\n <div class=\"g-recaptcha self-center\" data-sitekey=\"6LeXhdYrAAAAALW6DdgxNeHU0kwBncdicLnVYvXT\"></div>\n </form>\n\n <div id=\"result-container\" hidden class=\"mt-4 max-w-xl mx-auto flex gap-2\">\n <input id=\"result-output\" type=\"text\" readonly class=\"flex-1 p-3 bg-gray-100 dark:bg-neutral-900 border border-gray-200 dark:border-neutral-800 rounded-lg text-sm text-center truncate\">\n <button id=\"copy-button\" type=\"button\" title=\"Copy to clipboard\" class=\"p-3 bg-gray-200 dark:bg-neutral-800 rounded-lg hover:opacity-80 transition-opacity\">\n <i data-lucide=\"copy\" class=\"w-5 h-5\"></i>\n </button>\n <a id=\"open-link-button\" target=\"_blank\" rel=\"noopener\" title=\"Open link in new tab\" class=\"p-3 bg-gray-200 dark:bg-neutral-800 rounded-lg hover:opacity-80 transition-opacity\">\n <i data-lucide=\"arrow-up-right\" class=\"w-5 h-5\"></i>\n </a>\n </div>\n\n <p id=\"message-area\" class=\"mt-3 text-red-500 text-sm h-5\"></p>\n </section>\n</div>\n","extension_html":"<sune src='https://raw.githubusercontent.com/sune-org/store/refs/heads/main/sync.sune' private></sune>","hide_composer":false,"include_thoughts":false,"json_output":false,"ignore_master_prompt":false,"json_schema":""},"storage":{}}]