1 2 3 4 5 6(function () { 7 "use strict"; 8 9 var MIN_BODY = 10; 10 var MAX_BODY = 4000; 11 var MIN_DWELL_MS = 3000; 12 var TIMEOUT_MS = 20000; 13 var SLOW_MS = 5000; 14 var KINDS = ["çªçµã¸ã®ææ³ã»ãªã¯ã¨ã¹ã", "ç¹å®ã®åã«ã¤ãã¦", "ãã®ä»"]; 15 16 function epFromSearch(search) { 17 var raw = new URLSearchParams(search || "").get("ep") || ""; 18 return /^\d+$/.test(raw) ? raw : ""; 19 } 20 21 function shareValue(checked) { 22 return checked ? "ã¯ã" : "ããã"; 23 } 24 25 function problems(v) { 26 var out = []; 27 var body = (v.body || "").trim(); 28 if (body.length < MIN_BODY || body.length > MAX_BODY) out.push("body"); 29 30 31 if (KINDS.indexOf(v.kind) < 0) out.push("kind"); 32 if (v.kind === "ç¹å®ã®åã«ã¤ãã¦" && !(v.episode || "")) out.push("episode"); 33 var mail = (v.email || "").trim(); 34 if (mail && mail.indexOf("@") < 0) out.push("email"); 35 return out; 36 } 37 38 function passedTrap(v) { 39 if ((v.website || "") !== "") return false; 40 return (v.elapsedMs || 0) >= MIN_DWELL_MS; 41 } 42 43 44 function receiptFor(state, prev) { 45 if (prev && prev.state === state) return prev; 46 var id = ""; 47 for (var i = 0; i < 12; i++) { 48 id += Math.floor(Math.random() * 16).toString(16); 49 } 50 return {state: state, id: id}; 51 } 52 53 var api = { epFromSearch: epFromSearch, shareValue: shareValue, problems: problems, 54 passedTrap: passedTrap, receiptFor: receiptFor, KINDS: KINDS }; 55 if (typeof module !== "undefined" && module.exports) module.exports = api; 56 if (typeof document === "undefined") return; 57 58 59 var openedAt = Date.now(); 60 var receipt = null; 61 62 function boot() { 63 var form = document.getElementById("contact-form"); 64 if (!form) return; 65 var endpoint = form.getAttribute("data-endpoint") || ""; 66 var group = document.getElementById("contact-episode-group"); 67 var select = document.getElementById("contact-episode"); 68 var body = document.getElementById("contact-body"); 69 var share = document.getElementById("contact-share"); 70 var name = document.getElementById("contact-name"); 71 var email = document.getElementById("contact-email"); 72 var trap = document.getElementById("contact-website"); 73 var submit = document.getElementById("contact-submit"); 74 var status = document.getElementById("contact-status"); 75 76 77 78 var label = submit.textContent; 79 80 function kindNow() { 81 var on = form.querySelector('input[name="kind"]:checked'); 82 return on ? on.value : ""; 83 } 84 85 function alarm(which, on) { 86 var el = document.getElementById("contact-" + which + "-alarm"); 87 if (el) el.hidden = !on; 88 } 89 90 91 92 function syncEpisode() { 93 var wanted = kindNow() === "ç¹å®ã®åã«ã¤ãã¦"; 94 group.hidden = !wanted; 95 select.required = wanted; 96 if (!wanted) alarm("episode", false); 97 } 98 99 function clearAlarms() { 100 ["episode", "body", "email"].forEach(function (w) { alarm(w, false); }); 101 } 102 103 form.addEventListener("change", function (e) { 104 if (e.target.name === "kind") syncEpisode(); 105 }); 106 107 var ep = epFromSearch(location.search); 108 if (ep && select.querySelector('option[value="' + ep + '"]')) { 109 Array.prototype.forEach.call(form.querySelectorAll('input[name="kind"]'), function (r) { 110 r.checked = r.value === "ç¹å®ã®åã«ã¤ãã¦"; 111 }); 112 select.value = ep; 113 } 114 syncEpisode(); 115 116 form.addEventListener("submit", function (e) { 117 e.preventDefault(); 118 if (!endpoint) return; 119 clearAlarms(); 120 121 var values = {kind: kindNow(), episode: select.value, body: body.value, 122 email: email.value}; 123 var bad = problems(values); 124 if (bad.length) { 125 bad.forEach(function (which) { alarm(which, true); }); 126 var first = document.getElementById("contact-" + bad[0]); 127 if (first) first.focus(); 128 return; 129 } 130 131 if (!passedTrap({website: trap.value, elapsedMs: Date.now() - openedAt})) { 132 133 134 showDone(form, body.value, true); 135 return; 136 } 137 138 139 140 141 142 receipt = receiptFor(JSON.stringify([values.kind, values.episode, values.body, 143 name.value, values.email, share.checked]), 144 receipt); 145 146 147 148 149 150 submit.disabled = true; 151 submit.textContent = "éã£ã¦ãã¾ã"; 152 status.hidden = false;
153 status.classList.add("contact-form__status--sending"); 154 status.textContent = "éã£ã¦ãã¾ããå±ãããã©ããã確ããã¦ãã¾ãã"; 155 156 157 158 var slow = setTimeout(function () { 159 status.textContent = "ã¾ã 確ããã¦ãã¾ãããã¼ã¸ãéããã«ãå¾ ã¡ãã ããã"; 160 }, SLOW_MS); 161 162 163 164 165 166 167 168 var settled = false; 169 var stop = typeof AbortController === "function" ? new AbortController() : null; 170 var timer = setTimeout(function () { 171 if (stop) stop.abort(); 172 finish(false); 173 }, TIMEOUT_MS); 174 175 176 function finish(ok) { 177 if (settled) return; 178 settled = true; 179 clearTimeout(timer); 180 clearTimeout(slow); 181 submit.disabled = false; 182 submit.textContent = label; 183 status.hidden = true; 184 status.classList.remove("contact-form__status--sending"); 185 showDone(form, body.value, ok); 186 } 187 188 fetch(endpoint, { 189 method: "POST", 190 signal: stop ? stop.signal : undefined, 191 headers: {"Content-Type": "text/plain;charset=utf-8"}, 192 body: JSON.stringify({ 193 kind: values.kind, episode: values.episode, body: body.value, 194 name: name.value, email: email.value, share: shareValue(share.checked), 195 website: trap.value, receipt: receipt.id 196 }) 197 }) 198 .then(function (res) { 199 200 201 if (!res.ok) throw new Error("http " + res.status); 202 return res.json(); 203 }) 204 .then(function (data) { finish(!!(data && data.ok)); }) 205 .catch(function () { 206 207 208 209 finish(false); 210 }); 211 }); 212 } 213 214 function showDone(form, copy, ok) { 215 var box = document.getElementById("contact-done"); 216 box.textContent = ""; 217 218 var h = document.createElement("h2"); 219 h.textContent = ok ? "ã便ããããã¨ããããã¾ãã" : "éãã¾ããã§ãã"; 220 221 var p = document.createElement("p"); 222 p.textContent = ok 223 ? "3人ã§èªã¾ãã¦ããã ãã¾ãããæ¸ãã«ãªã£ãå 容ããæ§ãã¨ãã¦ä¸ã«æ®ãã¦ãã¾ãã" 224 : "ãã¾ãéãã¾ããã§ããããæ¸ãã«ãªã£ãå 容ã¯ä¸ã«æ®ãã¦ããã¾ãã" 225 + "ããä¸åº¦ã試ãããã ãããX ã® DM ã¸ãéããã ããã"; 226 227 var pre = document.createElement("pre"); 228 pre.className = "contact-done__copy"; 229 pre.textContent = copy; 230 231 var note = document.createElement("p"); 232 note.appendChild(document.createTextNode("çªçµã¸ã®ãé£çµ¡ã¯ ")); 233 var a = document.createElement("a"); 234 a.href = "https://x.com/x_crossing_"; 235 a.target = "_blank"; 236 a.rel = "noopener"; 237 a.textContent = "X ã® DMï¼@x_crossing_ï¼"; 238 note.appendChild(a); 239 note.appendChild(document.createTextNode(" ãããã©ããã")); 240 241 box.appendChild(h); 242 box.appendChild(p); 243 box.appendChild(pre); 244 box.appendChild(note); 245 box.hidden = false; 246 247 248 249 250 if (typeof box.focus === "function") box.focus(); 251 252 253 254 255 256 257 258 259 260 if (ok) { 261 form.hidden = true; 262 var intro = document.getElementById("contact-intro"); 263 if (intro) intro.hidden = true; 264 } 265 box.scrollIntoView({block: "start"}); 266 } 267 268 if (document.readyState === "loading") { 269 document.addEventListener("DOMContentLoaded", boot); 270 } else { 271 boot(); 272 } 273})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.