isaikr 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +35 -0
  2. package/cdn/api.js +19 -0
  3. package/cdn/character.js +254 -0
  4. package/cdn/chat.js +33 -0
  5. package/cdn/code-editor.js +1131 -0
  6. package/cdn/community-compose.js +270 -0
  7. package/cdn/games/2048/index.html +12 -0
  8. package/cdn/games/breakout/index.html +13 -0
  9. package/cdn/games/clicker/index.html +26 -0
  10. package/cdn/games/flappy/index.html +11 -0
  11. package/cdn/games/memory/index.html +34 -0
  12. package/cdn/games/pong/index.html +13 -0
  13. package/cdn/games/reaction/index.html +38 -0
  14. package/cdn/games/runner/index.html +11 -0
  15. package/cdn/games/snake/index.html +11 -0
  16. package/cdn/games/tetris/index.html +14 -0
  17. package/cdn/games/whack/index.html +8 -0
  18. package/cdn/go.js +126 -0
  19. package/cdn/go2.js +127 -0
  20. package/cdn/header3_behavior.js +1167 -0
  21. package/cdn/header3_layout.js +1004 -0
  22. package/cdn/header3_layout.js.bak +1004 -0
  23. package/cdn/header3_style.css +3524 -0
  24. package/cdn/header3_style.css.bak +3514 -0
  25. package/cdn/lang.js +198 -0
  26. package/cdn/loading.js +143 -0
  27. package/cdn/loading2.js +144 -0
  28. package/cdn/local-model.js +2941 -0
  29. package/cdn/main.js +4 -0
  30. package/cdn/main_asset.js +1849 -0
  31. package/cdn/main_asset.js.bak +6999 -0
  32. package/cdn/main_index.css +287 -0
  33. package/cdn/re_board3.css +733 -0
  34. package/cdn/re_board3.js +734 -0
  35. package/cdn/re_chat_tts.js +652 -0
  36. package/cdn/re_local_runtime.js +2246 -0
  37. package/cdn/re_local_runtime.js.bak +2246 -0
  38. package/cdn/re_share.js +577 -0
  39. package/cdn/re_voice.js +542 -0
  40. package/cdn/utils.js +36 -0
  41. package/cdn/view.js +321 -0
  42. package/header3_behavior.js +804 -0
  43. package/header3_layout.js +998 -0
  44. package/header3_style.css +2740 -0
  45. package/index.js +0 -0
  46. package/lang.js +179 -0
  47. package/main_asset.js +2416 -0
  48. package/main_index.css +274 -0
  49. package/package.json +14 -0
  50. package/re_chat_tts.js +1419 -0
  51. package/re_voice.js +430 -0
package/cdn/view.js ADDED
@@ -0,0 +1,321 @@
1
+ (function initViewUI() {
2
+ const cfg = window.__VIEW_CONFIG__ || {};
3
+ window.userLang = cfg.userLang || window.userLang || "en";
4
+ window.selectedGifUrl = "";
5
+
6
+ const tMap = {
7
+ ko: { comment: "\ub313\uae00\uc744 \uc785\ub825\ud558\uc138\uc694...", chat: "AI\uc5d0\uac8c \uc9c8\ubb38\ud574\ubcf4\uc138\uc694...", search: "\uac80\uc0c9\uc5b4\ub97c \uc785\ub825\ud558\uc138\uc694...", image: "\uc774\ubbf8\uc9c0\ub97c \uc124\uba85\ud574\ubcf4\uc138\uc694...", video: "\uc601\uc0c1\uc744 \uc124\uba85\ud574\ubcf4\uc138\uc694...", music: "\uc74c\uc545\uc744 \uc124\uba85\ud574\ubcf4\uc138\uc694...", code: "\ucf54\ub4dc\ub97c \uc124\uba85\ud574\ubcf4\uc138\uc694..." },
8
+ en: { comment: "Write a comment...", chat: "Ask AI...", search: "Search...", image: "Describe an image...", video: "Describe a video...", music: "Describe music...", code: "Describe code..." },
9
+ ja: { comment: "\u30b3\u30e1\u30f3\u30c8\u3092\u5165\u529b...", chat: "AI\u306b\u8cea\u554f\u3057\u3066\u307f\u307e\u3057\u3087\u3046...", search: "\u691c\u7d22\u8a9e\u3092\u5165\u529b...", image: "\u753b\u50cf\u3092\u8aac\u660e\u3057\u3066\u307f\u307e\u3057\u3087\u3046...", video: "\u52d5\u753b\u3092\u8aac\u660e\u3057\u3066\u307f\u307e\u3057\u3087\u3046...", music: "\u97f3\u697d\u3092\u8aac\u660e\u3057\u3066\u307f\u307e\u3057\u3087\u3046...", code: "\u30b3\u30fc\u30c9\u3092\u8aac\u660e\u3057\u3066\u307f\u307e\u3057\u3087\u3046..." },
10
+ hi: { comment: "\u091f\u093f\u092a\u094d\u092a\u0923\u0940 \u0932\u093f\u0916\u0947\u0902...", chat: "AI \u0938\u0947 \u092a\u0942\u091b\u0947\u0902...", search: "\u0916\u094b\u091c \u0936\u092c\u094d\u0926 \u0932\u093f\u0916\u0947\u0902...", image: "\u091b\u0935\u093f \u0915\u093e \u0935\u0930\u094d\u0923\u0928 \u0915\u0930\u0947\u0902...", video: "\u0935\u0940\u0921\u093f\u092f\u094b \u0915\u093e \u0935\u0930\u094d\u0923\u0928 \u0915\u0930\u0947\u0902...", music: "\u0938\u0902\u0917\u0940\u0924 \u0915\u093e \u0935\u0930\u094d\u0923\u0928 \u0915\u0930\u0947\u0902...", code: "\u0915\u094b\u0921 \u0915\u093e \u0935\u0930\u094d\u0923\u0928 \u0915\u0930\u0947\u0902..." },
11
+ es: { comment: "Escribe un comentario...", chat: "Pregunta a la IA...", search: "Escribe una busqueda...", image: "Describe una imagen...", video: "Describe un video...", music: "Describe musica...", code: "Describe codigo..." }
12
+ };
13
+ const t = Object.assign({}, tMap.en, tMap[window.userLang] || {});
14
+ const icons = { comment: "ri-discuss-line", chat: "ri-chat-ai-line", search: "ri-search-line", image: "ri-image-circle-ai-line", video: "ri-video-ai-line", music: "ri-music-ai-fill", code: "ri-code-block" };
15
+ const viewReportI18n = cfg.viewReportI18n || {};
16
+ let mode = "comment";
17
+ let isSubmitting = false;
18
+ let inlineEditKey = "";
19
+ let giphyDebounce = null;
20
+
21
+ window.mountViewShareBanner = () => {
22
+ const isDark = document.documentElement.classList.contains("dark") || localStorage.theme === "dark";
23
+ const src = `https://cdn.jsdelivr.net/gh/sllkx/olla@main/sharebanner.js?a=https://ollapp.isai.kr/view/9&p=tc&m=mini${isDark ? "" : "&t=light"}`;
24
+ let old = document.getElementById("view-sharebanner-script");
25
+ if (old && old.dataset.src === src) return;
26
+ if (old) old.remove();
27
+ let script = document.createElement("script");
28
+ script.id = "view-sharebanner-script";
29
+ script.dataset.src = src;
30
+ script.src = src;
31
+ script.async = true;
32
+ document.body.appendChild(script);
33
+ };
34
+
35
+ window.toggleTheme = () => {
36
+ document.documentElement.classList.toggle("dark");
37
+ localStorage.setItem("theme", document.documentElement.classList.contains("dark") ? "dark" : "light");
38
+ window.mountViewShareBanner();
39
+ };
40
+
41
+ window.openGiphyModal = () => {
42
+ const modal = document.getElementById("giphy-modal");
43
+ const surface = document.getElementById("giphy-modal-surface");
44
+ if (!modal || !surface) return;
45
+ modal.classList.remove("hidden");
46
+ void modal.offsetWidth;
47
+ modal.classList.remove("opacity-0", "pointer-events-none");
48
+ surface.classList.remove("translate-y-10");
49
+ const results = document.getElementById("giphy-results");
50
+ if (results && results.innerHTML === "") searchGiphy("");
51
+ const input = document.getElementById("giphy-search-input");
52
+ if (input) input.focus();
53
+ };
54
+
55
+ window.closeGiphyModal = () => {
56
+ const modal = document.getElementById("giphy-modal");
57
+ const surface = document.getElementById("giphy-modal-surface");
58
+ if (!modal || !surface) return;
59
+ modal.classList.add("opacity-0", "pointer-events-none");
60
+ surface.classList.add("translate-y-10");
61
+ setTimeout(() => modal.classList.add("hidden"), 300);
62
+ };
63
+
64
+ window.searchGiphy = async (query) => {
65
+ const container = document.getElementById("giphy-results");
66
+ const loader = document.getElementById("giphy-loading");
67
+ if (!container || !loader) return;
68
+ container.innerHTML = "";
69
+ loader.classList.remove("hidden");
70
+ try {
71
+ const res = await fetch(`/re_store.php?action=giphy_search&q=${encodeURIComponent(query)}&limit=24`);
72
+ const json = await res.json();
73
+ if (json.success && json.data) {
74
+ json.data.forEach(gif => {
75
+ const imgUrl = gif.images.fixed_height.url;
76
+ const actualUrl = gif.images.downsized.url || gif.images.original.url;
77
+ const div = document.createElement("div");
78
+ div.className = "cursor-pointer rounded-xl overflow-hidden bg-gray-100 dark:bg-white/5 relative group h-32";
79
+ div.innerHTML = `<img src="${imgUrl}" class="w-full h-full object-cover" loading="lazy"><div class="absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors"></div>`;
80
+ div.onclick = () => selectGif(actualUrl);
81
+ container.appendChild(div);
82
+ });
83
+ }
84
+ } catch (e) {
85
+ console.error(e);
86
+ } finally {
87
+ loader.classList.add("hidden");
88
+ }
89
+ };
90
+
91
+ window.selectGif = (url) => {
92
+ window.selectedGifUrl = url;
93
+ const preview = document.getElementById("selected-gif-preview");
94
+ const img = document.getElementById("selected-gif-img");
95
+ if (img) img.src = url;
96
+ if (preview) preview.classList.remove("hidden");
97
+ closeGiphyModal();
98
+ const input = document.getElementById("msg-input");
99
+ if (input) input.focus();
100
+ };
101
+
102
+ window.clearSelectedGif = () => {
103
+ window.selectedGifUrl = "";
104
+ const preview = document.getElementById("selected-gif-preview");
105
+ const img = document.getElementById("selected-gif-img");
106
+ if (preview) preview.classList.add("hidden");
107
+ if (img) img.src = "";
108
+ };
109
+
110
+ window.viewToggleModeSelector = () => {
111
+ const sel = document.getElementById("mode-selector-container");
112
+ if (sel) sel.classList.toggle("opacity-0");
113
+ if (sel) sel.classList.toggle("pointer-events-none");
114
+ };
115
+
116
+ window.viewSetMode = (m) => {
117
+ mode = m;
118
+ const icon = document.getElementById("current-mode-icon");
119
+ const input = document.getElementById("msg-input");
120
+ const selector = document.getElementById("mode-selector-container");
121
+ if (icon) icon.className = `${icons[m]} text-lg`;
122
+ if (input) input.placeholder = t[m] || t.comment;
123
+ const metaWrapper = document.getElementById("meta-wrapper");
124
+ if (metaWrapper) {
125
+ Object.assign(metaWrapper.style, mode === "comment"
126
+ ? { height: "auto", marginTop: "0.25rem", opacity: "1", pointerEvents: "auto" }
127
+ : { height: "0", marginTop: "0", opacity: "0", pointerEvents: "none" });
128
+ }
129
+ if (selector) selector.classList.add("opacity-0", "pointer-events-none");
130
+ };
131
+
132
+ window.viewSubmitAction = async () => {
133
+ const input = document.getElementById("msg-input");
134
+ if (!input) return;
135
+ let contentVal = input.value.trim();
136
+ if (window.selectedGifUrl) contentVal += (contentVal ? "\n" : "") + `[gif:${window.selectedGifUrl}]`;
137
+ if (!contentVal || isSubmitting) return;
138
+ if (mode !== "comment") {
139
+ window.location.href = `/?${mode}=${encodeURIComponent(input.value.trim())}`;
140
+ return;
141
+ }
142
+ isSubmitting = true;
143
+ const btn = document.getElementById("view-btn-submit");
144
+ const ogHtml = btn ? btn.innerHTML : "";
145
+ if (btn) {
146
+ btn.disabled = true;
147
+ btn.innerHTML = '<i class="ri-loader-4-line animate-spin text-xl"></i>';
148
+ }
149
+ try {
150
+ const fd = new FormData(document.getElementById("chat-form"));
151
+ fd.set("content", contentVal);
152
+ const res = await fetch("/re_store.php?action=add_comment", { method: "POST", body: fd });
153
+ const text = await res.text();
154
+ const json = JSON.parse(text.replace(/^\uFEFF/, "").substring(text.indexOf("{")));
155
+ if (json.success) window.location.reload();
156
+ else alert("Error: " + (json.error || "Failed"));
157
+ } catch (e) {
158
+ alert("Server Error");
159
+ } finally {
160
+ isSubmitting = false;
161
+ if (btn) {
162
+ btn.disabled = false;
163
+ btn.innerHTML = ogHtml;
164
+ }
165
+ }
166
+ };
167
+
168
+ window.startInlineEdit = (type, id) => {
169
+ const k = `${type}-${id}`;
170
+ if (inlineEditKey && inlineEditKey !== k) cancelInlineEdit(...inlineEditKey.split("-"));
171
+ const prefix = type === "post" ? "post" : "comment";
172
+ const cEl = document.getElementById(`${prefix}-content-display${type === "post" ? "" : `-${id}`}`);
173
+ const eEl = document.getElementById(`${prefix}-inline-editor-${id}`);
174
+ const tEl = document.getElementById(`${prefix}-inline-text-${id}`);
175
+ const pEl = document.getElementById(`${prefix}-inline-password-${id}`);
176
+ if (!cEl || !eEl || !tEl) return;
177
+ if (pEl) pEl.value = "";
178
+ tEl.value = cEl.dataset.raw || cEl.innerText || "";
179
+ cEl.classList.add("hidden");
180
+ eEl.classList.remove("hidden");
181
+ inlineEditKey = k;
182
+ tEl.focus();
183
+ };
184
+
185
+ window.cancelInlineEdit = (type, id) => {
186
+ const prefix = type === "post" ? "post" : "comment";
187
+ const cEl = document.getElementById(`${prefix}-content-display${type === "post" ? "" : `-${id}`}`);
188
+ const eEl = document.getElementById(`${prefix}-inline-editor-${id}`);
189
+ if (eEl) eEl.classList.add("hidden");
190
+ if (cEl) cEl.classList.remove("hidden");
191
+ inlineEditKey = "";
192
+ };
193
+
194
+ window.submitInlineEdit = async (type, id, m) => {
195
+ const prefix = type === "post" ? "post" : "comment";
196
+ const tEl = document.getElementById(`${prefix}-inline-text-${id}`);
197
+ const pEl = document.getElementById(`${prefix}-inline-password-${id}`);
198
+ if (!tEl || !pEl) return;
199
+ if (m === "update" && !tEl.value.trim()) return alert("Empty content.");
200
+ try {
201
+ const fd = new FormData();
202
+ fd.append("id", id);
203
+ fd.append("password", pEl.value.trim());
204
+ fd.append("content", tEl.value.trim());
205
+ fd.append("mode", m);
206
+ const action = type === "post" ? "edit_post" : "edit_comment";
207
+ const res = await fetch(`/re_store.php?action=${action}`, { method: "POST", body: fd });
208
+ const text = await res.text();
209
+ const data = JSON.parse(text.replace(/^\uFEFF/, "").substring(text.indexOf("{")));
210
+ if (!data.success) return alert("Failed: " + (data.error || "Unknown error"));
211
+ if (m === "delete") return type === "post" ? window.location.href = "/" : document.getElementById(`comment-${id}`).remove();
212
+ window.location.reload();
213
+ } catch (e) {
214
+ alert("Network error.");
215
+ }
216
+ };
217
+
218
+ window.translateItem = async (type, id) => {
219
+ if (type === "post") {
220
+ try {
221
+ const res = await fetch("/re_store.php?action=create_post_translation", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ post_id: id, lang: window.userLang }) });
222
+ const json = await res.json();
223
+ if (json.success && json.url) window.location.href = json.url;
224
+ } catch (e) {
225
+ console.error(e);
226
+ }
227
+ return;
228
+ }
229
+ const el = document.getElementById(`comment-content-display-${id}`);
230
+ if (!el) return;
231
+ const ogHtml = el.innerHTML;
232
+ el.innerHTML = '<span class="animate-pulse opacity-50">Translating...</span>';
233
+ try {
234
+ const rawText = (el.dataset.raw || el.innerText).replace(/\[gif:.*?\]/g, "");
235
+ const res = await fetch("/re_store.php?action=ai_translate", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ text: rawText, lang: window.userLang }) });
236
+ const data = JSON.parse((await res.text()).replace(/^\uFEFF/, "").trimStart());
237
+ let translatedHtml = data.response ? data.response.trim() : "";
238
+ const gifMatch = (el.dataset.raw || "").match(/\[gif:(https?:\/\/[^\]]+)\]/);
239
+ if (gifMatch) translatedHtml += `<img src="${gifMatch[1]}" class="mt-2 max-w-[200px] w-full rounded-xl object-cover shadow-sm block border border-black/5 dark:border-white/5" alt="GIF">`;
240
+ if (data.success && data.response) el.innerHTML = `<div class="mb-3 pb-2 border-b border-black/10 dark:border-white/10 text-[11px] opacity-70 flex items-center gap-1 font-bold"><i class="ri-translate-2"></i> Translated</div><div class="leading-relaxed text-[14px]">${translatedHtml}</div>`;
241
+ else el.innerHTML = ogHtml;
242
+ } catch (e) {
243
+ alert("Error: " + e.message);
244
+ el.innerHTML = ogHtml;
245
+ }
246
+ };
247
+
248
+ window.playTTS = (id) => {
249
+ const el = document.getElementById(id);
250
+ if (!el) return;
251
+ if (window.speechSynthesis.speaking) return window.speechSynthesis.cancel();
252
+ const textToSpeak = (el.dataset.raw || el.innerText).replace(/\[gif:.*?\]/g, "");
253
+ const u = new SpeechSynthesisUtterance(textToSpeak);
254
+ u.lang = window.userLang;
255
+ window.speechSynthesis.speak(u);
256
+ };
257
+
258
+ window.chooseViewReportType = (type, btn) => {
259
+ document.getElementById("view-report-type").value = type || "";
260
+ document.querySelectorAll("#view-report-modal .report-type-chip").forEach(c => c.classList.remove("active"));
261
+ if (btn) btn.classList.add("active");
262
+ };
263
+
264
+ window.openViewReportModal = (targetType, targetId) => {
265
+ document.getElementById("view-report-target-type").value = targetType || "";
266
+ document.getElementById("view-report-target-id").value = targetId || "";
267
+ document.getElementById("view-report-reason").value = "";
268
+ document.getElementById("view-report-type").value = "";
269
+ document.querySelectorAll("#view-report-modal .report-type-chip").forEach(c => c.classList.remove("active"));
270
+ document.getElementById("view-report-modal-title").textContent = targetType === "forum_comment" ? (viewReportI18n.modalTitleComment || "Report Comment") : (viewReportI18n.modalTitlePost || "Report Post");
271
+ document.getElementById("view-report-modal").classList.remove("hidden");
272
+ };
273
+
274
+ window.closeViewReportModal = () => document.getElementById("view-report-modal").classList.add("hidden");
275
+
276
+ window.submitViewReport = async () => {
277
+ const tType = document.getElementById("view-report-target-type").value;
278
+ const tId = document.getElementById("view-report-target-id").value;
279
+ const rType = document.getElementById("view-report-type").value;
280
+ const reason = document.getElementById("view-report-reason").value.trim();
281
+ if (!rType) return alert(viewReportI18n.typeRequired || "Please select type");
282
+ if (!reason) return alert(viewReportI18n.reasonRequired || "Please write reason");
283
+ try {
284
+ const res = await fetch("/re_store.php?action=submit_content_report", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ target_type: tType, target_id: tId, report_type: rType, reason }) });
285
+ const data = await res.json();
286
+ if (!data.success) throw new Error(data.error);
287
+ closeViewReportModal();
288
+ if (data.deleted) tType === "forum_comment" ? document.getElementById("comment-" + tId).remove() : window.location.href = "/";
289
+ else alert(data.duplicate ? "\uc774\ubbf8 \uc2e0\uace0\ud55c \ud56d\ubaa9\uc785\ub2c8\ub2e4." : "\uc2e0\uace0\uac00 \uc811\uc218\ub418\uc5c8\uc2b5\ub2c8\ub2e4.");
290
+ } catch (e) {
291
+ alert("Error occurred");
292
+ }
293
+ };
294
+
295
+ document.addEventListener("DOMContentLoaded", () => {
296
+ const gSearchInput = document.getElementById("giphy-search-input");
297
+ if (gSearchInput) {
298
+ gSearchInput.addEventListener("input", (e) => {
299
+ clearTimeout(giphyDebounce);
300
+ giphyDebounce = setTimeout(() => searchGiphy(e.target.value), 500);
301
+ });
302
+ gSearchInput.addEventListener("keydown", (e) => {
303
+ if (e.key === "Enter") {
304
+ e.preventDefault();
305
+ searchGiphy(e.target.value);
306
+ }
307
+ });
308
+ }
309
+ mountViewShareBanner();
310
+ viewSetMode("comment");
311
+ }, { once: true });
312
+
313
+ document.addEventListener("click", (e) => {
314
+ const sel = document.getElementById("mode-selector-container");
315
+ const tBtn = document.getElementById("btn-mode-toggle");
316
+ if (sel && tBtn && !sel.contains(e.target) && !tBtn.contains(e.target)) sel.classList.add("opacity-0", "pointer-events-none");
317
+ const gModal = document.getElementById("giphy-modal-surface");
318
+ const gWrap = document.getElementById("giphy-modal");
319
+ if (gModal && gWrap && !gWrap.classList.contains("hidden") && !gModal.contains(e.target) && e.target === gWrap) closeGiphyModal();
320
+ });
321
+ })();