全局美化 v5
@@ -266,3 +266,35 @@ home-light / home-dark / explore-light 三页差异均 **0.024%**,bbox 只有
|
||||
**踩坑**:暗色主题图标原来写 `display:inline`,span 里放块级 `<svg>` 会让导航栏高度变化 → 整页下移 36px。
|
||||
用行亮度曲线做互相关定位到 dy=36,改成 `inline-flex` 后复测差异回到 0.059%(只剩随机 emoji)。
|
||||
教训:**改图标尺寸/显示模式一定要量整页位移**,不能只看局部截图。
|
||||
|
||||
## P2 线上复测(2026-10-19 12:2x)
|
||||
|
||||
- `GET /static/css/base.css?v=20261019c` → 200 / text/css / **23918 字节,与本地逐字节一致**,页面已引用该版本。
|
||||
- meta:viewport 已带 `initial-scale=1`;`msvalidate.01` 只剩 1 份。
|
||||
- 图标:首页 emoji 🌐🌙☀️ 归零,`<svg ... stroke="currentColor">` ×5(语言 1 + 桌面主题 2 + 移动主题 2);
|
||||
计算样式暗色下 `#theme-toggle .tb-icon-dark` = `display:flex`、亮色图标 `none`;
|
||||
**导航高度亮/暗均 80px** → 上次 36px 位移问题确认修好。
|
||||
- 探索页:`.tb-chip` ×25(全部有底色 `rgb(244,246,248)`、文字 `rgb(92,99,112)`、圆角 6px、字号 11.52px);
|
||||
残留彩色 `uk-label` 4 个,均为置顶/私密等语义状态。
|
||||
- 结果页:`/user/votes/{id}/results` 原生 `<progress class="uk-progress" value max>`,计算高度 **10px**、圆角 6px;
|
||||
遍历 10 个结果页 `uk-progressbar` 全部为 0。
|
||||
- 巡检 `/ /explore /rules /login /register /_/admin6 /_/admin3` 均 200。
|
||||
|
||||
## P2 补漏(已改,待部署)
|
||||
|
||||
复测时发现 **结果页与参与页的题型标签仍是实心彩色** —— 那两处的 class 由 Go 模板函数
|
||||
`fieldTypeLabelClass` 生成,我上一轮只按字面 `class="uk-label uk-label-primary"` 搜索,漏了它们。
|
||||
|
||||
- `templates/user/vote-results.html`(2 处)、`templates/vote/page.html`(2 处):序号 + 题型 → `.tb-chip`;
|
||||
状态标签(未开始/已结束/进行中/已参与)保留彩色,属语义。
|
||||
- 删除 `internal/template/template.go` 的 `fieldTypeLabelClass`(19 行,已无引用)。
|
||||
顺带查明:该函数 `text/textarea` 走 `return ""`,注释说"默认灰",**实际渲染成 UIkit 默认蓝**,
|
||||
所以文本框标签一直是蓝的——注释与实现不符。
|
||||
- `.uk-progress::-webkit-progress-value` 圆角改成两端都圆(`-moz-progress-bar` 同步)。
|
||||
⚠️ 起因是误判:我先前测"右端方角"时像素扫描循环上界写成 `range(110,830)`,恰好等于条宽,
|
||||
于是右端永远"恒定不变"→ 假象。放宽到整幅宽度后两版端点曲线完全一致(830/832/833/834/833/832/830),
|
||||
即**没有视觉 bug**。保留改动只为 Firefox 的 `-moz-progress-bar` 保险。
|
||||
- `base.css?v=` → `20261019d`。`go build` + `./templates ./internal/i18n ./internal/template` 全绿。
|
||||
|
||||
**教训(重要)**:像素测量脚本的扫描范围必须覆盖整幅图,循环上界不能与被测对象边界重合,
|
||||
否则会把"边界截断"读成"图形特征"。之前 3.77→6.89 那组对比不知是否也受此影响,需复查时再确认。
|
||||
|
||||
@@ -93,6 +93,11 @@
|
||||
- 视觉自检:`TEST_PREVIEW=1 go test ./templates -run TestGenPreview` → `outputs/preview-*.html`;
|
||||
截图必须 `chrome --headless=old`(新版 headless 在本机挂住),外部资源先落到 `outputs/preview-assets/`。
|
||||
改 CSS 的正确验证法是**像素比对**(PIL 在 `~/.workbuddy/binaries/python/envs/default`),不是目测。
|
||||
⚠️ 像素扫描的循环上界**不能与物体边界重合**(曾把 `range(110,830)` 当成条宽 →
|
||||
右端恒为 829 被读成"方角",其实是边界截断)。
|
||||
- 分类/题型标签一律 `.tb-chip`(浅底 + 次要色);**彩色 `uk-label` 只留给语义状态**
|
||||
(置顶/私密/被举报/已读、投票未开始/进行中/已结束/已参与)。题型配色曾由 Go 的
|
||||
`fieldTypeLabelClass` 生成(已删),故 grep `uk-label` 搜不到,改前先搜模板函数名。
|
||||
|
||||
## 其它约定
|
||||
|
||||
|
||||
@@ -168,25 +168,6 @@ func FuncMap() []template.FuncMap {
|
||||
}
|
||||
return i18n.T(lang, key)
|
||||
},
|
||||
// fieldTypeLabelClass 返回表单字段类型的标签配色(题型视觉区分)。
|
||||
"fieldTypeLabelClass": func(fieldType string) string {
|
||||
switch fieldType {
|
||||
case "text", "textarea":
|
||||
return "" // 默认灰
|
||||
case "radio", "select":
|
||||
return "uk-label-primary"
|
||||
case "checkbox":
|
||||
return "uk-label-success"
|
||||
case "rating":
|
||||
return "uk-label-warning"
|
||||
case "rank":
|
||||
return "uk-label-danger"
|
||||
case "number":
|
||||
return "uk-label-secondary"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
},
|
||||
// toJSON 将值序列化为 JSON 并标记为安全的 JS 字面量。
|
||||
// 必须用于 <script> 上下文中的 JSON 注入:template.HTML 会在 script 上下文中
|
||||
// 被 html/template 按 JS 规则转义(引号被转义导致 JS 语法错误/值变成字符串),
|
||||
|
||||
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 114 KiB |
|
After Width: | Height: | Size: 114 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 49 KiB |
@@ -0,0 +1 @@
|
||||
{"code":0,"data":{"id":"1ca74ac2fda2ab07","question":"72 + 75 ="}}
|
||||
@@ -0,0 +1,5 @@
|
||||
# Netscape HTTP Cookie File
|
||||
# https://curl.se/docs/http-cookies.html
|
||||
# This file was generated by libcurl! Edit at your own risk.
|
||||
|
||||
#HttpOnly_box-dev-api.337845818.best FALSE / TRUE 0 flamego_session hprz8iav3vfy6tzb
|
||||
@@ -0,0 +1,21 @@
|
||||
HTTP/1.1 200 Connection Established
|
||||
|
||||
HTTP/1.1 302 Found
|
||||
Date: Mon, 19 Oct 2026 04:24:11 GMT
|
||||
Content-Length: 0
|
||||
Connection: keep-alive
|
||||
location: /
|
||||
referrer-policy: strict-origin-when-cross-origin
|
||||
Set-Cookie: flamego_session=hprz8iav3vfy6tzb; Path=/; HttpOnly; Secure; SameSite=Lax
|
||||
strict-transport-security: max-age=31536000; includeSubDomains
|
||||
trace-id: 00000000000000000000000000000000
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: DENY
|
||||
x-xss-protection: 1; mode=block
|
||||
cf-cache-status: DYNAMIC
|
||||
Nel: {"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}
|
||||
Report-To: {"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=xCuQqn2mEttANrv5sLh%2BGTlX5Y72aBFAAsUVPIWcvKvdv3w32AaiR%2FpBwbfkeIwSznnctdkAKyXjUtksAPe64DdTILC%2F1ZkMC8tx5l8BH3AatTgML4IDtsg%2BKz0u8npwzjh0oL6oa0mKWwIEFg%3D%3D"}]}
|
||||
Server: cloudflare
|
||||
CF-RAY: a4cd02ff3c26a11d-AMS
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
|
||||
@@ -0,0 +1,638 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>狼の質問箱 | 匿名質問箱</title>
|
||||
<meta name="msvalidate.01" content="2F185E8E63C93635F50B3574F3B31E42" />
|
||||
<meta name="description" content="狼の質問箱は登録不要で使える匿名質問箱。誰でも匿名で質問でき、安心してやり取りできる場所です。">
|
||||
<meta name="keywords" content="匿名質問箱,質問箱,匿名質問,狼の質問箱,匿名で質問,匿名Q&A">
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
if (m && m[1] === 'dark') document.documentElement.setAttribute('data-theme', 'dark');
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://r2.337845818.best" crossorigin>
|
||||
<link rel="preconnect" href="https://cdnjs.snrat.com" crossorigin>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/css/uikit.min.css"/>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/base.css?v=20261019c"/>
|
||||
|
||||
<link rel="stylesheet" href="https://r2.337845818.best/tamabox/cdn/waline/client/v2/waline-no-commits.css" media="print" onload="this.media='all'"/>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit-icons.min.js"></script>
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/dayjs/1.10.8/dayjs.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/alpinejs/3.9.0/cdn.min.js"></script>
|
||||
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/waline/2.15.8/waline.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.captcha-equation-box {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: #f0f2f5;
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 8px;
|
||||
padding: 8px 8px 8px 16px;
|
||||
gap: 6px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
.captcha-equation-box:focus-within {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 3px rgba(30,135,240,0.12);
|
||||
}
|
||||
.math-captcha-modal-question {
|
||||
font-size: 1.4rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
letter-spacing: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
width: 80px;
|
||||
padding: 6px 10px;
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 600;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
transition: border-color 0.15s, box-shadow 0.15s;
|
||||
background: #fff;
|
||||
}
|
||||
#captcha-modal-answer:focus {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 2px rgba(30,135,240,0.2);
|
||||
}
|
||||
|
||||
#captcha-modal-answer::-webkit-inner-spin-button,
|
||||
#captcha-modal-answer::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta property="og:site_name" content="狼の質問箱 | 匿名質問箱" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content="狼の質問箱 | 匿名質問箱" />
|
||||
<meta property="og:url" content="https://box-dev-api.337845818.best/login" />
|
||||
<meta property="og:description" content="狼の質問箱は登録不要で使える匿名質問箱。誰でも匿名で質問でき、安心してやり取りできる場所です。" />
|
||||
|
||||
|
||||
<meta itemprop="image" content="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<meta name="msapplication-TileImage" content="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<link rel="shortcut icon" href="https://r2.337845818.best/tamabox/tamabox_low.png" />
|
||||
<link rel="apple-touch-icon" href="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<link rel="icon" sizes="192x192" href="https://r2.337845818.best/tamabox/tamabox_low.png">
|
||||
<meta name="twitter:image:src" content="https://r2.337845818.best/tamabox/tamabox_low.png" />
|
||||
|
||||
|
||||
|
||||
<meta name="google-site-verification" content="fEPwRRJfiGsgwc5SINBQwZhPK8F0cwRaOvRx0YRurI4" />
|
||||
|
||||
<script>
|
||||
window.addEventListener("load", function () {
|
||||
var s = document.createElement("script");
|
||||
s.src = "https://mami.shiroko.one/tamami.js";
|
||||
s.setAttribute("data-website-id", "c42ebe8b-9281-4da0-83a4-8f18b3e710fe");
|
||||
document.body.appendChild(s);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window.tbRenderQR = function (el, getOptions) {
|
||||
if (!el || typeof QRCode === 'undefined') return;
|
||||
var opts = getOptions();
|
||||
function remoteOf(o, key) {
|
||||
var v = o[key];
|
||||
return (typeof v === 'string' && v.indexOf('http') === 0) ? v : '';
|
||||
}
|
||||
var good = window._tbQrGood || (window._tbQrGood = {});
|
||||
var bad = window._tbQrBad || (window._tbQrBad = {});
|
||||
|
||||
function layerState(url) { return !url ? '' : (good[url] ? 1 : (bad[url] ? 0 : null)); }
|
||||
var layers = [
|
||||
{ url: remoteOf(opts, 'logo'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.logo = undefined; o.logoWidth = undefined; o.logoHeight = undefined; o.logoBackgroundTransparent = undefined; }
|
||||
} },
|
||||
{ url: remoteOf(opts, 'backgroundImage'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.backgroundImage = undefined; o.backgroundImageAlpha = undefined; }
|
||||
} }
|
||||
];
|
||||
var needProbe = false;
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
layers[i].st = layerState(layers[i].url);
|
||||
if (layers[i].st === null) needProbe = true;
|
||||
}
|
||||
function paint(states) {
|
||||
var o = {};
|
||||
for (var k in opts) o[k] = opts[k];
|
||||
for (var j = 0; j < layers.length; j++) layers[j].present(o, states[j] === 1);
|
||||
el.innerHTML = '';
|
||||
new QRCode(el, o);
|
||||
}
|
||||
|
||||
var initStates = [];
|
||||
for (var n = 0; n < layers.length; n++) initStates.push(layers[n].st === 1 ? 1 : 0);
|
||||
paint(initStates);
|
||||
if (!needProbe) return;
|
||||
|
||||
var pending = 0, cross = opts.crossOrigin || 'anonymous';
|
||||
layers.forEach(function (L) {
|
||||
if (L.st !== null) return;
|
||||
pending++;
|
||||
var im = new Image();
|
||||
im.onload = function () { good[L.url] = true; L.st = 1; onDone(); };
|
||||
im.onerror = function () { bad[L.url] = true; L.st = 0; onDone(); };
|
||||
if (cross) im.crossOrigin = cross;
|
||||
im.src = L.url;
|
||||
});
|
||||
function onDone() {
|
||||
if (--pending > 0) return;
|
||||
var finalStates = [];
|
||||
for (var m = 0; m < layers.length; m++) finalStates.push(layers[m].st === 1 ? 1 : 0);
|
||||
var changed = false;
|
||||
for (var q = 0; q < finalStates.length; q++) if (finalStates[q] !== initStates[q]) changed = true;
|
||||
if (changed) paint(finalStates);
|
||||
}
|
||||
|
||||
setTimeout(function () { if (pending > 0) { pending = 0; onDone(); } }, 3000);
|
||||
};
|
||||
</script>
|
||||
<nav class="uk-navbar-container uk-margin tb-navbar" uk-navbar>
|
||||
<div class="uk-navbar-center">
|
||||
<div class="uk-navbar-center-left">
|
||||
<div>
|
||||
<ul class="uk-navbar-nav">
|
||||
|
||||
<li><a href="/explore">探索</a></li>
|
||||
|
||||
|
||||
<li class="tb-mobile-balancer" aria-hidden="true"><a tabindex="-1" style="visibility:hidden">マイ</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="uk-navbar-item uk-logo" href="/"><span class="emoji-placeholder" aria-label="random animal">🐺</span>の質問箱</a>
|
||||
|
||||
<div class="uk-navbar-center-right">
|
||||
<div>
|
||||
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/register">登録</a></li>
|
||||
</ul>
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/login">ログイン</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" aria-label="言語" title="言語"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="9"/><path d="M3.2 9h17.6M3.2 15h17.6"/><ellipse cx="12" cy="12" rx="4" ry="9"/></svg></a>
|
||||
<div class="uk-navbar-dropdown" uk-drop="mode: click; pos: bottom-right">
|
||||
<ul class="uk-nav uk-navbar-dropdown-nav">
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/zh-CN?to=%2Flogin">简体中文</a>
|
||||
</li>
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/zh-TW?to=%2Flogin">繁體中文</a>
|
||||
</li>
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/en?to=%2Flogin">English</a>
|
||||
</li>
|
||||
|
||||
<li class="uk-active">
|
||||
<a href="/i18n/ja?to=%2Flogin">日本語</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" id="theme-toggle" title="ダーク/ライトモード切替" aria-label="ダーク/ライトモード切替">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const emojis = ["🐺","🐗","🐻","🐨","🐼","🐹","🐭","🐰","🦊","🐮","🐷","🐽","🐸","🐒","🦍","🐔","🐧","🐦","🐤","🐦⬛","🦅","🦉","🦇","🐴","🦄","🐝","🦎","🦖","🦕","🐙","🦑","🦐","🦞","🦀","🐡","🐠","🐟","🐬","🐳","🐋","🦈","🐊","🐅","🐆","🦓","🦍","🦧","🐘","🦛","🦏","🐪","🐫","🦒","🦘","🐃","🐂","🐄","🐎","🐖","🐏","🐑","🦙","🐐","🦌","🐕","🐩","🦮","🐕🦺","🐈","🐋","🐳","🐬","🐉","🐲"];
|
||||
const placeholder = document.querySelector('.emoji-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.textContent = emojis[Math.floor(Math.random() * emojis.length)];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="tb-mobile-utils">
|
||||
|
||||
<select id="mobile-lang-select" class="uk-select uk-form-small" aria-label="言語">
|
||||
|
||||
<option value="zh-CN" >简体中文</option>
|
||||
|
||||
<option value="zh-TW" >繁體中文</option>
|
||||
|
||||
<option value="en" >English</option>
|
||||
|
||||
<option value="ja" selected>日本語</option>
|
||||
|
||||
</select>
|
||||
|
||||
<button type="button" id="theme-toggle-mobile" class="uk-button uk-button-default uk-button-small"
|
||||
title="ダーク/ライトモード切替" aria-label="ダーク/ライトモード切替">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
var THEME_COOKIE = 'theme';
|
||||
function getTheme() {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
return m ? m[1] : '';
|
||||
}
|
||||
function applyTheme(theme) {
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
}
|
||||
}
|
||||
function toggleTheme() {
|
||||
var next = getTheme() === 'dark' ? 'light' : 'dark';
|
||||
applyTheme(next);
|
||||
var expires = new Date(Date.now() + 365 * 24 * 3600 * 1000).toUTCString();
|
||||
document.cookie = THEME_COOKIE + '=' + next + '; path=/; max-age=' + (365 * 24 * 3600) + '; SameSite=Lax';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
var buttons = document.querySelectorAll('#theme-toggle, #theme-toggle-mobile');
|
||||
buttons.forEach(function(btn) {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
toggleTheme();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var langSel = document.getElementById('mobile-lang-select');
|
||||
if (langSel) {
|
||||
langSel.addEventListener('change', function() {
|
||||
if (!this.value) return;
|
||||
var to = window.location.pathname + window.location.search;
|
||||
window.location.href = '/i18n/' + encodeURIComponent(this.value) + '?to=' + encodeURIComponent(to);
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-container uk-container-xsmall">
|
||||
|
||||
|
||||
|
||||
<div id="math-captcha-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body uk-text-center">
|
||||
<h3 class="uk-modal-title">人機認証</h3>
|
||||
<p class="uk-text-meta">以下の計算問題を解いて、ロボットでないことを証明してください</p>
|
||||
<div class="captcha-equation-box">
|
||||
<span id="captcha-modal-question" class="math-captcha-modal-question">読み込み中...</span>
|
||||
<input type="number" id="captcha-modal-answer" placeholder="?" autocomplete="off" inputmode="numeric">
|
||||
</div>
|
||||
<div style="margin-top:6px;">
|
||||
<button type="button" class="uk-button uk-button-text uk-text-small" id="captcha-modal-refresh">別の問題</button>
|
||||
</div>
|
||||
<div id="captcha-modal-error" class="uk-text-danger uk-text-small" style="display:none;min-height:20px;"></div>
|
||||
<div class="uk-margin-small-top">
|
||||
<button type="button" class="uk-button uk-button-primary" id="captcha-modal-submit">送信</button>
|
||||
<button type="button" class="uk-button uk-button-default uk-modal-close">キャンセル</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var CAPTCHA_I18N = {
|
||||
loading: "読み込み中...",
|
||||
loadFailed: "読み込み失敗",
|
||||
loadRetry: "読み込み失敗、再試行してください",
|
||||
inputAnswer: "答えを入力してください",
|
||||
wrongAnswer: "答えが違います。もう一度計算してください",
|
||||
verifyFailed: "認証失敗、再試行してください",
|
||||
needPassword: "この質問箱にはパスワードが必要です",
|
||||
needEmail: "通知を受け取るメールアドレスを入力してください"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var captchaId = '';
|
||||
var pendingForm = null;
|
||||
var pendingNeedPassword = false;
|
||||
var verifying = false;
|
||||
|
||||
function fetchCaptcha() {
|
||||
var qEl = document.getElementById('captcha-modal-question');
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
var ansEl = document.getElementById('captcha-modal-answer');
|
||||
qEl.textContent = CAPTCHA_I18N.loading;
|
||||
fetch('/api/captcha/generate')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.code === 0 && data.data) {
|
||||
captchaId = data.data.id;
|
||||
qEl.textContent = data.data.question;
|
||||
if (errEl) errEl.style.display = 'none';
|
||||
if (ansEl) { ansEl.value = ''; ansEl.focus(); }
|
||||
} else {
|
||||
qEl.textContent = CAPTCHA_I18N.loadFailed;
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
qEl.textContent = CAPTCHA_I18N.loadRetry;
|
||||
});
|
||||
}
|
||||
|
||||
function getCSRFToken() {
|
||||
var input = document.querySelector('input[name="_csrf"]');
|
||||
return input ? input.value : '';
|
||||
}
|
||||
|
||||
function doSubmit(form) {
|
||||
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
var hidden = form.querySelector('[name="g-recaptcha-response"]');
|
||||
if (hidden) hidden.value = captchaId + ':' + (ans || '0');
|
||||
|
||||
UIkit.modal('#math-captcha-modal').hide();
|
||||
|
||||
|
||||
if (pendingNeedPassword) {
|
||||
UIkit.modal.prompt(CAPTCHA_I18N.needPassword, '', 'password')
|
||||
.then(function(password) {
|
||||
if (password) {
|
||||
var pwInput = document.getElementById('ask_password_input');
|
||||
if (pwInput) pwInput.value = password;
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-submit').addEventListener('click', function() {
|
||||
if (verifying) return;
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
if (!ans) {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.inputAnswer;
|
||||
errEl.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
verifying = true;
|
||||
fetch('/api/captcha/verify', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-Token': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify({ id: captchaId, answer: parseInt(ans, 10) })
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
verifying = false;
|
||||
if (data.correct) {
|
||||
if (pendingForm) doSubmit(pendingForm);
|
||||
} else {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.wrongAnswer;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
verifying = false;
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.verifyFailed;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-answer').addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
document.getElementById('captcha-modal-submit').click();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-refresh').addEventListener('click', fetchCaptcha);
|
||||
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target.closest('.math-captcha-trigger');
|
||||
if (!btn) return;
|
||||
e.preventDefault();
|
||||
|
||||
var form = btn.closest('form');
|
||||
if (!form) return;
|
||||
pendingForm = form;
|
||||
|
||||
|
||||
pendingNeedPassword = !!(form.querySelector('#ask_password_input'));
|
||||
|
||||
|
||||
var notifyCb = document.getElementById('notify-checkbox');
|
||||
var emailInput = document.getElementById('email-input');
|
||||
if (notifyCb && notifyCb.checked && emailInput && emailInput.value.trim() === '') {
|
||||
UIkit.modal.alert(CAPTCHA_I18N.needEmail);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchCaptcha();
|
||||
UIkit.modal('#math-captcha-modal').show();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<form method="post" id="form">
|
||||
<fieldset class="uk-fieldset">
|
||||
<input type="hidden" name="_csrf" value="muaJ9C5fXIhN1tRRVzm6_i-3SkA6MTc5MjM4Mzg0NTM5NTIwNDYzMg">
|
||||
<legend class="uk-legend">ログイン</legend>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="uk-margin">
|
||||
<label class="uk-form-label" for="email">メールアドレス</label>
|
||||
<input name="email" id="email" class="uk-input" type="text" value="">
|
||||
</div>
|
||||
<div class="uk-margin">
|
||||
<label class="uk-form-label" for="password">パスワード</label>
|
||||
<input type="password" name="password" id="password" class="uk-input">
|
||||
</div>
|
||||
<div class="uk-margin">
|
||||
|
||||
<input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response" value="">
|
||||
<button type="button" class="uk-button uk-button-primary math-captcha-trigger">ログイン</button>
|
||||
|
||||
<a href="/forgot-password" class="uk-button uk-button-default">パスワードを忘れた
|
||||
</a>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
<p class=" uk-text-right uk-text-muted uk-text-small">
|
||||
<br>
|
||||
<a href="/rules">ルール</a> |
|
||||
|
||||
<a href="https://box.shiroko.one/_/tamakyi" target="_blank">管理者へ</a>
|
||||
<br>
|
||||
<a href="https://share.shiroko.one" target="_blank">ドライブ</a>
|
||||
| <a href="https://blog.shiroko.one" target="_blank">お知らせ</a>
|
||||
| <a href="https://chat.shiroko.one" target="_blank">チャット</a>
|
||||
| <a href="https://status.shiroko.one" target="_blank">ステータス</a>
|
||||
| <a href="https://shiroko.one" target="_blank">リンク</a>
|
||||
<br>Powered by NekoBox | 狼ICP备 20230101
|
||||
<br>質問箱は稼働中:<span id="box_runtime"></span>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
(function () {
|
||||
var create = Math.round(Date.UTC(2023, 6, 1, 18, 15, 43) / 1000);
|
||||
function tick() {
|
||||
var el = document.getElementById("box_runtime");
|
||||
if (!el) return;
|
||||
var s = Math.round((Date.now() + 8 * 3600 * 1000) / 1000) - create;
|
||||
var t = [0, 0, 0, 0, 0];
|
||||
if (s >= 31536000) { t[0] = s / 31536000 | 0; s %= 31536000; }
|
||||
if (s >= 86400) { t[1] = s / 86400 | 0; s %= 86400; }
|
||||
if (s >= 3600) { t[2] = s / 3600 | 0; s %= 3600; }
|
||||
if (s >= 60) { t[3] = s / 60 | 0; s %= 60; }
|
||||
if (s > 0) { t[4] = s; }
|
||||
el.innerHTML = t[0] + '年 ' + t[1] + '天 ' + t[2] + '时 ' + t[3] + '分 ' + t[4] + '秒 ';
|
||||
}
|
||||
tick();
|
||||
setInterval(tick, 1000);
|
||||
})();
|
||||
</script>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
var SUBMIT_I18N = {
|
||||
submitting: '送信中...',
|
||||
uploading: 'アップロード中...'
|
||||
};
|
||||
|
||||
function tbResetSubmitButtons() {
|
||||
document.querySelectorAll('button[data-tb-submitting]').forEach(function(b) {
|
||||
b.disabled = false;
|
||||
b.removeAttribute('data-tb-submitting');
|
||||
var orig = b.getAttribute('data-tb-restore');
|
||||
if (orig !== null) {
|
||||
b.innerHTML = orig;
|
||||
b.removeAttribute('data-tb-restore');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('submit', function(e) {
|
||||
var form = e.target;
|
||||
if (!form || form.tagName !== 'FORM') return;
|
||||
|
||||
|
||||
|
||||
if (e.defaultPrevented || form.getAttribute('data-tb-skip-submit-feedback') === '1') {
|
||||
form.removeAttribute('data-tb-skip-submit-feedback');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (form.getAttribute('target') === '_blank') return;
|
||||
|
||||
|
||||
var trigger = e.submitter || form.querySelector('button[type="submit"]');
|
||||
|
||||
|
||||
var hasFile = false;
|
||||
form.querySelectorAll('input[type="file"]').forEach(function(f) {
|
||||
if (f.files && f.files.length > 0) hasFile = true;
|
||||
});
|
||||
var label = hasFile ? SUBMIT_I18N.uploading : SUBMIT_I18N.submitting;
|
||||
|
||||
if (trigger && trigger.tagName === 'BUTTON') {
|
||||
trigger.setAttribute('data-tb-restore', trigger.innerHTML);
|
||||
trigger.innerHTML = '<span uk-spinner="ratio: 0.6"></span> ' + label;
|
||||
}
|
||||
|
||||
|
||||
form.querySelectorAll('button').forEach(function(b) {
|
||||
b.disabled = true;
|
||||
b.setAttribute('data-tb-submitting', '1');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener('pageshow', tbResetSubmitButtons);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,668 @@
|
||||
/* TamaBox 全站基础样式:设计令牌 / 主题覆盖 / 组件质感 / 响应式。
|
||||
由 base/header.html 内联块抽出,集中一份便于缓存与维护。
|
||||
⚠️ 改完务必把 header 里的 ?v= 版本号 +1,否则老访客仍用缓存。 */
|
||||
|
||||
/* 设计令牌:亮色为默认(:root),深色在 html[data-theme="dark"] 覆盖。
|
||||
页面与组件样式一律引用 var(--tb-*),不再写死色值/圆角/阴影;
|
||||
var() 的第二个参数仅作兜底(旧缓存页、邮件模板等不引入本文件的场景)。
|
||||
改配色只动这一块,亮暗两套自动保持一致。 */
|
||||
:root {
|
||||
--tb-bg: #f7f8fa;
|
||||
--tb-surface: #ffffff;
|
||||
--tb-surface-2: #f4f6f8;
|
||||
--tb-surface-hover: #f3f7ff;
|
||||
--tb-border: #e8eaee;
|
||||
--tb-text: #1f2329;
|
||||
--tb-text-secondary: #5c6370;
|
||||
--tb-text-muted: #8a919c;
|
||||
--tb-primary: #1e87f0;
|
||||
--tb-primary-weak: rgba(30, 135, 240, 0.10);
|
||||
--tb-radius: 12px;
|
||||
--tb-radius-sm: 8px;
|
||||
--tb-radius-xs: 6px;
|
||||
--tb-shadow: 0 1px 2px rgba(16, 24, 40, 0.04), 0 12px 28px -18px rgba(16, 24, 40, 0.20);
|
||||
--tb-shadow-hover: 0 1px 2px rgba(16, 24, 40, 0.05), 0 18px 40px -20px rgba(16, 24, 40, 0.28);
|
||||
--tb-font: system-ui, -apple-system, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC", "Microsoft YaHei", sans-serif;
|
||||
}
|
||||
html[data-theme="dark"] {
|
||||
--tb-bg: #1a1d23;
|
||||
--tb-surface: #242830;
|
||||
--tb-surface-2: #2d323c;
|
||||
--tb-surface-hover: rgba(92, 141, 255, 0.12);
|
||||
--tb-border: #3a404c;
|
||||
--tb-text: #d8dce4;
|
||||
--tb-text-secondary: #a8b0bd;
|
||||
--tb-text-muted: #8b93a1;
|
||||
--tb-primary: #5c8dff;
|
||||
--tb-primary-weak: rgba(92, 141, 255, 0.14);
|
||||
--tb-shadow: 0 1px 2px rgba(0, 0, 0, 0.30), 0 12px 28px -18px rgba(0, 0, 0, 0.55);
|
||||
--tb-shadow-hover: 0 1px 2px rgba(0, 0, 0, 0.35), 0 18px 40px -20px rgba(0, 0, 0, 0.65);
|
||||
}
|
||||
|
||||
/* UIkit 补丁:复刻原自建版 "modify-black-font"(官方版与自建版仅 3 处颜色差异——把有色容器内默认白字/白标题改为黑字)。
|
||||
模板当前只用到 .uk-light 容器(用户背景封面,question/list.html、question-not-found.html;
|
||||
其中 h3/p 已由 #usernamecolor/#introcolor 内联 style 覆盖),故只需补该容器的 3 处投影即可保持渲染一致。
|
||||
若日后新增 .uk-card-primary/.uk-card-secondary/.uk-section-primary/.uk-tile-*/.uk-overlay-primary 等容器且需黑字,须同步扩展。 */
|
||||
.uk-light { color: rgba(0,0,0,.7); }
|
||||
.uk-light .uk-h1, .uk-light .uk-h2, .uk-light .uk-h3, .uk-light .uk-h4, .uk-light .uk-h5, .uk-light .uk-h6,
|
||||
.uk-light .uk-heading-2xlarge, .uk-light .uk-heading-large, .uk-light .uk-heading-medium, .uk-light .uk-heading-small, .uk-light .uk-heading-xlarge,
|
||||
.uk-light h1, .uk-light h2, .uk-light h3, .uk-light h4, .uk-light h5, .uk-light h6 { color: #000; }
|
||||
.uk-light .uk-table th { color: rgba(0,0,0,.7); }
|
||||
|
||||
.grecaptcha-badge {visibility: hidden;}
|
||||
.icon-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
}
|
||||
.icon {
|
||||
margin-left: 10px;
|
||||
width: 20px; /* 设置图标的宽度 */
|
||||
height: auto; /* 保持图标的高度自动调整 */
|
||||
}
|
||||
.emoji-placeholder {
|
||||
display: inline-block;
|
||||
animation: jump 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes jump {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-5px); }
|
||||
}
|
||||
/* 防止 UIkit Dropbar 初始闪烁 */
|
||||
.uk-dropbar {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 0.2s ease, visibility 0.2s ease;
|
||||
}
|
||||
|
||||
.uk-dropbar.uk-open {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
a.uk-button.uk-button-link {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/* 移动端优化:缩小字体和间距,避免右侧空白 */
|
||||
@media (max-width: 640px) {
|
||||
.uk-logo {
|
||||
font-size: 1rem;
|
||||
}
|
||||
.uk-navbar-nav a {
|
||||
font-size: 0.78rem;
|
||||
padding: 0 4px;
|
||||
}
|
||||
.emoji-placeholder {
|
||||
font-size: 1rem;
|
||||
}
|
||||
/* 移动端用户名限宽省略,避免长英文用户名撑爆顶栏 */
|
||||
.tb-nav-username {
|
||||
max-width: 64px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
/* 深色模式:html[data-theme="dark"] 时覆盖 UIkit 3.3.3 编译主题的关键颜色 */
|
||||
/* 变量(--tb-*)已上移到 head 顶部的令牌块,亮暗两套同名常量在那里定义。 */
|
||||
/* 根元素与 body 一起覆盖,确保整个视口(含内容不足一屏时的空白区)都是深色背景 */
|
||||
html[data-theme="dark"],
|
||||
html[data-theme="dark"] body {
|
||||
background-color: var(--tb-bg) !important;
|
||||
color: var(--tb-text) !important;
|
||||
}
|
||||
/* 通用表面容器 */
|
||||
html[data-theme="dark"] .uk-card,
|
||||
html[data-theme="dark"] .uk-card-default,
|
||||
html[data-theme="dark"] .uk-card-secondary,
|
||||
html[data-theme="dark"] .uk-dropbar,
|
||||
html[data-theme="dark"] .uk-navbar-dropdown,
|
||||
html[data-theme="dark"] .uk-modal-dialog,
|
||||
html[data-theme="dark"] .uk-dropdown,
|
||||
html[data-theme="dark"] .uk-offcanvas-bar,
|
||||
html[data-theme="dark"] .uk-section,
|
||||
html[data-theme="dark"] .uk-tile,
|
||||
html[data-theme="dark"] .uk-panel,
|
||||
html[data-theme="dark"] .uk-background-default,
|
||||
html[data-theme="dark"] .uk-search-default .uk-search-input {
|
||||
background-color: var(--tb-surface) !important;
|
||||
color: var(--tb-text) !important;
|
||||
}
|
||||
html[data-theme="dark"] .uk-navbar-container {
|
||||
background-color: var(--tb-surface) !important;
|
||||
color: var(--tb-text) !important;
|
||||
}
|
||||
html[data-theme="dark"] .uk-navbar-nav > li > a,
|
||||
html[data-theme="dark"] .uk-card a,
|
||||
html[data-theme="dark"] .uk-link,
|
||||
html[data-theme="dark"] a.uk-button-link,
|
||||
html[data-theme="dark"] .uk-navbar-dropdown-nav > li > a,
|
||||
html[data-theme="dark"] .uk-dropdown-nav > li > a,
|
||||
html[data-theme="dark"] .uk-list a {
|
||||
color: var(--tb-text) !important;
|
||||
}
|
||||
html[data-theme="dark"] .uk-navbar-nav > li > a:hover,
|
||||
html[data-theme="dark"] .uk-card a:hover,
|
||||
html[data-theme="dark"] .uk-navbar-dropdown-nav > li > a:hover,
|
||||
html[data-theme="dark"] .uk-dropdown-nav > li > a:hover {
|
||||
color: var(--tb-primary) !important;
|
||||
}
|
||||
html[data-theme="dark"] .uk-input,
|
||||
html[data-theme="dark"] .uk-textarea,
|
||||
html[data-theme="dark"] .uk-select {
|
||||
background-color: var(--tb-surface-2) !important;
|
||||
color: var(--tb-text) !important;
|
||||
border-color: var(--tb-border) !important;
|
||||
}
|
||||
html[data-theme="dark"] .uk-input:focus,
|
||||
html[data-theme="dark"] .uk-textarea:focus,
|
||||
html[data-theme="dark"] .uk-select:focus {
|
||||
border-color: var(--tb-primary) !important;
|
||||
}
|
||||
html[data-theme="dark"] .uk-text-muted,
|
||||
html[data-theme="dark"] .uk-text-meta,
|
||||
html[data-theme="dark"] .uk-text-secondary,
|
||||
html[data-theme="dark"] .uk-text-muted a,
|
||||
html[data-theme="dark"] .uk-text-small.uk-text-muted {
|
||||
color: var(--tb-text-muted) !important;
|
||||
}
|
||||
html[data-theme="dark"] .uk-divider-icon::after,
|
||||
html[data-theme="dark"] hr,
|
||||
html[data-theme="dark"] .uk-table th,
|
||||
html[data-theme="dark"] .uk-table td,
|
||||
html[data-theme="dark"] .uk-list-divider > li:nth-child(n+2) {
|
||||
border-color: var(--tb-border) !important;
|
||||
}
|
||||
html[data-theme="dark"] .uk-button-default {
|
||||
background-color: var(--tb-surface-2) !important;
|
||||
color: var(--tb-text) !important;
|
||||
border-color: var(--tb-border) !important;
|
||||
}
|
||||
html[data-theme="dark"] .uk-modal-title,
|
||||
html[data-theme="dark"] h1, html[data-theme="dark"] h2, html[data-theme="dark"] h3,
|
||||
html[data-theme="dark"] h4, html[data-theme="dark"] h5, html[data-theme="dark"] h6,
|
||||
html[data-theme="dark"] .uk-card-title {
|
||||
color: var(--tb-text) !important;
|
||||
}
|
||||
html[data-theme="dark"] .uk-alert-warning,
|
||||
html[data-theme="dark"] .uk-alert-danger,
|
||||
html[data-theme="dark"] .uk-alert-success,
|
||||
html[data-theme="dark"] .uk-alert-primary {
|
||||
background-color: var(--tb-surface-2) !important;
|
||||
color: var(--tb-text) !important;
|
||||
}
|
||||
html[data-theme="dark"] #math-captcha-modal .uk-modal-dialog {
|
||||
background-color: var(--tb-surface) !important;
|
||||
color: var(--tb-text) !important;
|
||||
}
|
||||
html[data-theme="dark"] #math-captcha-modal .captcha-equation-box {
|
||||
background-color: var(--tb-surface-2) !important;
|
||||
border-color: var(--tb-border) !important;
|
||||
}
|
||||
html[data-theme="dark"] #math-captcha-modal .math-captcha-modal-question {
|
||||
color: var(--tb-text) !important;
|
||||
}
|
||||
html[data-theme="dark"] #math-captcha-modal #captcha-modal-answer {
|
||||
background-color: var(--tb-surface) !important;
|
||||
color: var(--tb-text) !important;
|
||||
border-color: var(--tb-border) !important;
|
||||
}
|
||||
html[data-theme="dark"] #math-captcha-modal #captcha-modal-answer::placeholder {
|
||||
color: var(--tb-text-muted) !important;
|
||||
}
|
||||
html[data-theme="dark"] #math-captcha-modal .uk-text-meta,
|
||||
html[data-theme="dark"] #math-captcha-modal #captcha-modal-refresh {
|
||||
color: var(--tb-text-muted) !important;
|
||||
}
|
||||
html[data-theme="dark"] #math-captcha-modal #captcha-modal-refresh:hover {
|
||||
color: var(--tb-primary) !important;
|
||||
}
|
||||
html[data-theme="dark"] .uk-label {
|
||||
color: #fff !important;
|
||||
}
|
||||
/* 自定义组件(探索页推荐卡片等)深色覆盖 */
|
||||
html[data-theme="dark"] .recommend-card,
|
||||
html[data-theme="dark"] .recommend-card:hover {
|
||||
background-color: var(--tb-surface-2) !important;
|
||||
}
|
||||
html[data-theme="dark"] .explore-name a {
|
||||
color: var(--tb-text) !important;
|
||||
}
|
||||
html[data-theme="dark"] .explore-name a:hover {
|
||||
color: var(--tb-primary) !important;
|
||||
}
|
||||
html[data-theme="dark"] .explore-intro {
|
||||
color: var(--tb-text-muted) !important;
|
||||
}
|
||||
/* 切换按钮图标切换(内联 SVG,不依赖 UIkit 图标库) */
|
||||
#theme-toggle .tb-icon-light, #theme-toggle-mobile .tb-icon-light,
|
||||
#theme-toggle .tb-icon-dark, #theme-toggle-mobile .tb-icon-dark {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
#theme-toggle .tb-icon-light svg, #theme-toggle-mobile .tb-icon-light svg,
|
||||
#theme-toggle .tb-icon-dark svg, #theme-toggle-mobile .tb-icon-dark svg { display: block; }
|
||||
#theme-toggle .tb-icon-dark, #theme-toggle-mobile .tb-icon-dark { display: none; }
|
||||
html[data-theme="dark"] #theme-toggle .tb-icon-light,
|
||||
html[data-theme="dark"] #theme-toggle-mobile .tb-icon-light { display: none; }
|
||||
html[data-theme="dark"] #theme-toggle .tb-icon-dark,
|
||||
html[data-theme="dark"] #theme-toggle-mobile .tb-icon-dark { display: inline-flex; }
|
||||
|
||||
/* 基础质感层:只调整外观(圆角/投影/字体/数字对齐),不改任何结构与布局。
|
||||
颜色一律取自头部令牌,亮暗两套自动生效,因此这里不需要再写 html[data-theme="dark"] 分支。 */
|
||||
/* 根元素与 body 同时上色:内容不足一屏时,body 之外的视口区域也要是同一底色 */
|
||||
html,
|
||||
body {
|
||||
font-family: var(--tb-font);
|
||||
background-color: var(--tb-bg);
|
||||
color: var(--tb-text);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
/* 卡片:12px 圆角 + 一层极淡接触影 + 一层大扩散影(UIkit 默认的 0 5px 15px 偏硬) */
|
||||
.uk-card {
|
||||
border-radius: var(--tb-radius);
|
||||
}
|
||||
.uk-card-default {
|
||||
background-color: var(--tb-surface);
|
||||
box-shadow: var(--tb-shadow);
|
||||
}
|
||||
.uk-card-default.uk-card-hover:hover {
|
||||
box-shadow: var(--tb-shadow-hover);
|
||||
}
|
||||
.uk-card-header {
|
||||
border-radius: var(--tb-radius) var(--tb-radius) 0 0;
|
||||
}
|
||||
.uk-card-footer {
|
||||
border-radius: 0 0 var(--tb-radius) var(--tb-radius);
|
||||
}
|
||||
.uk-card,
|
||||
.uk-button,
|
||||
.uk-alert,
|
||||
.uk-label {
|
||||
transition: box-shadow 0.18s ease, background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease;
|
||||
}
|
||||
/* 交互元素:统一 8px 圆角,标签 6px */
|
||||
.uk-button {
|
||||
border-radius: var(--tb-radius-sm);
|
||||
}
|
||||
.uk-input,
|
||||
.uk-select,
|
||||
.uk-textarea,
|
||||
.uk-form-small,
|
||||
.uk-search-input {
|
||||
border-radius: var(--tb-radius-sm);
|
||||
}
|
||||
.uk-label {
|
||||
border-radius: var(--tb-radius-xs);
|
||||
}
|
||||
.uk-alert {
|
||||
border-radius: 10px;
|
||||
}
|
||||
.uk-modal-dialog {
|
||||
border-radius: 14px;
|
||||
}
|
||||
.uk-dropdown,
|
||||
.uk-navbar-dropdown {
|
||||
border-radius: 10px;
|
||||
box-shadow: var(--tb-shadow);
|
||||
}
|
||||
.uk-navbar-container:not(.uk-navbar-transparent) {
|
||||
background-color: var(--tb-surface);
|
||||
}
|
||||
/* 键盘可达性:仅在键盘聚焦时出现描边,鼠标点击不出现 */
|
||||
.uk-button:focus-visible,
|
||||
.uk-navbar-nav > li > a:focus-visible {
|
||||
outline: 2px solid var(--tb-primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
/* 次要文字统一走令牌,避免 #999 / #8a919c 混用 */
|
||||
.uk-text-muted,
|
||||
.uk-text-meta {
|
||||
color: var(--tb-text-muted);
|
||||
}
|
||||
|
||||
/* 轻量胶囊:用于投票类型、热门标签等「只是分类信息」的位置。
|
||||
实心 uk-label 一屏多个会变成一排色块,这里统一降级为浅底 + 次要色文字。 */
|
||||
.tb-chip {
|
||||
display: inline-block;
|
||||
padding: 1px 8px;
|
||||
border-radius: var(--tb-radius-xs);
|
||||
background-color: var(--tb-surface-2);
|
||||
color: var(--tb-text-secondary);
|
||||
font-size: 0.72rem;
|
||||
line-height: 1.7;
|
||||
white-space: nowrap;
|
||||
}
|
||||
a.tb-chip:hover {
|
||||
background-color: var(--tb-primary-weak);
|
||||
color: var(--tb-primary);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* 统计/日期等数字列等宽对齐,避免刷新时左右跳动 */
|
||||
.uk-table,
|
||||
.tb-num {
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
/* 图片上传条:原为 item/new-question 两处各写一份内联 style(写死 #f8f8f8,深色下露白),
|
||||
收敛到一处并走令牌,亮暗自动适配 */
|
||||
.tb-img-uploader {
|
||||
width: 100%;
|
||||
background-color: var(--tb-surface-2);
|
||||
display: flex;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
gap: 5px;
|
||||
}
|
||||
/* 背景图封面(提问箱主页):渐变遮罩,保证用户自选文字色叠加后仍可读。
|
||||
默认浅色遮罩(页面 .uk-light 补丁把文字兜底成深色);若箱主选了浅色文字,
|
||||
question/list.html 会按亮度加上 .tb-cover-dark 换成深色遮罩。 */
|
||||
.tb-cover {
|
||||
position: relative;
|
||||
border-radius: var(--tb-radius) var(--tb-radius) 0 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
/* ⚠️ 必须带 .uk-flex 复合选择器:UIkit 3.3.3 里有
|
||||
.uk-flex::after,.uk-flex::before{display:none}(优先级 0,2,0),
|
||||
会把这个遮罩伪元素整个干掉——不报错、只是什么都不显示(踩过一次)。
|
||||
单写 .tb-cover::after 优先级不够,会被它压回 display:none。 */
|
||||
.tb-cover::after,
|
||||
.tb-cover.uk-flex::after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.58) 55%, rgba(255, 255, 255, 0.84) 100%);
|
||||
pointer-events: none;
|
||||
}
|
||||
.tb-cover.tb-cover-dark::after {
|
||||
background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.16) 45%, rgba(0, 0, 0, 0.46) 100%);
|
||||
}
|
||||
.tb-cover > * {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.tb-cover h3,
|
||||
.tb-cover p {
|
||||
text-shadow: 0 1px 10px rgba(255, 255, 255, 0.65);
|
||||
}
|
||||
.tb-cover.tb-cover-dark h3,
|
||||
.tb-cover.tb-cover-dark p {
|
||||
text-shadow: 0 1px 12px rgba(0, 0, 0, 0.45);
|
||||
}
|
||||
/* 尊重系统的减少动效设置 */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.uk-card,
|
||||
.uk-button,
|
||||
.emoji-placeholder {
|
||||
transition: none;
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* 顶栏自适应:导航全部直接显示,窄屏时分级缩小字号/间距,保证英文/日文等长文字不溢出 */
|
||||
.uk-navbar-nav a {
|
||||
font-size: 0.95rem;
|
||||
padding: 0 10px;
|
||||
}
|
||||
/* 未登录移动端占位:桌面端隐藏,仅 ≤640px 显示(见下方 media 查询)。
|
||||
桌面端布局与改动前完全一致,不受影响。 */
|
||||
.tb-mobile-balancer { display: none; }
|
||||
/* 桌面端保持 UIkit 原生居中三列布局(无需额外 CSS) */
|
||||
.tb-navbar .uk-logo {
|
||||
white-space: nowrap;
|
||||
}
|
||||
@media (max-width: 1200px) {
|
||||
.uk-navbar-nav a {
|
||||
font-size: 0.88rem;
|
||||
padding: 0 8px;
|
||||
}
|
||||
}
|
||||
@media (max-width: 1000px) {
|
||||
.uk-navbar-nav a {
|
||||
font-size: 0.82rem;
|
||||
padding: 0 6px;
|
||||
}
|
||||
.uk-logo {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
/* 登录用户名限宽,过长省略号截断 */
|
||||
.tb-nav-username {
|
||||
max-width: 110px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
@media (max-width: 800px) {
|
||||
.uk-navbar-nav a {
|
||||
font-size: 0.78rem;
|
||||
padding: 0 4px;
|
||||
}
|
||||
.uk-logo {
|
||||
font-size: 1rem;
|
||||
}
|
||||
.tb-nav-username {
|
||||
max-width: 80px;
|
||||
}
|
||||
}
|
||||
/* 手机端(≤640px):沿用 UIkit 桌面端 navbar 的原生三列定位。
|
||||
不再重写 .uk-navbar-center / center-left / center-right 的定位,
|
||||
避免 logo 被挤到下一行;底部语言与深色模式按钮仍由下方独立栏承载。 */
|
||||
@media (max-width: 640px) {
|
||||
.tb-navbar {
|
||||
position: relative;
|
||||
min-height: 56px;
|
||||
overflow: visible;
|
||||
}
|
||||
.tb-navbar > .uk-navbar-center {
|
||||
position: relative !important;
|
||||
top: auto !important;
|
||||
left: auto !important;
|
||||
right: auto !important;
|
||||
bottom: auto !important;
|
||||
transform: none !important;
|
||||
display: flex !important;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
min-height: 56px;
|
||||
white-space: nowrap;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
.tb-navbar .uk-navbar-center-left,
|
||||
.tb-navbar .uk-navbar-center-right {
|
||||
position: static !important;
|
||||
top: auto !important;
|
||||
left: auto !important;
|
||||
right: auto !important;
|
||||
bottom: auto !important;
|
||||
transform: none !important;
|
||||
display: flex !important;
|
||||
align-items: center;
|
||||
flex: 0 0 auto;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.tb-navbar .uk-navbar-center-left > div,
|
||||
.tb-navbar .uk-navbar-center-right > div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.tb-navbar .uk-navbar-nav {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
.tb-navbar .uk-navbar-nav > li > a,
|
||||
.tb-navbar .uk-logo {
|
||||
white-space: nowrap;
|
||||
}
|
||||
/* 未登录:移动端显示与「我的」等宽的隐藏占位,使左栏「探索+占位」与
|
||||
右栏「注册/登录」两项等宽,logo 真正居中,左右视觉平衡 */
|
||||
.tb-mobile-balancer { display: block; }
|
||||
}
|
||||
|
||||
/* 标签样式的按钮(管理页置顶等):
|
||||
尺寸完全继承 .uk-label(font-size/padding/line-height/text-transform 等),
|
||||
仅覆盖 button 元素特有的默认样式(边框/字体族/光标等),保证与相邻 span 标签完全一致。 */
|
||||
.tb-label-btn {
|
||||
border: none !important;
|
||||
cursor: pointer;
|
||||
font-family: inherit;
|
||||
margin: 0;
|
||||
vertical-align: middle;
|
||||
outline: none;
|
||||
background-image: none;
|
||||
box-sizing: border-box;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
.tb-label-btn:hover {
|
||||
opacity: 0.85;
|
||||
}
|
||||
/* 公开页置顶小图标:仅一个图钉,不占行高、不影响原布局 */
|
||||
.tb-pin-flag {
|
||||
font-size: 0.9em;
|
||||
margin-right: 4px;
|
||||
vertical-align: -1px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* Markdown 渲染排版(问题/回答/追问正文,左对齐以保留排版格式) */
|
||||
/* 纯文本列表:保留换行与连续空格(pre-wrap),不渲染 Markdown 大字号/彩色 */
|
||||
.tb-preline {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
/* 纯文本列表:超过 5 行截断并显示省略号(不足 5 行则完整显示) */
|
||||
.tb-clamp-5 {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 5;
|
||||
overflow: hidden;
|
||||
}
|
||||
.md-body {
|
||||
line-height: 1.7;
|
||||
text-align: left;
|
||||
word-break: break-word;
|
||||
}
|
||||
.md-body p { margin: 0.5em 0; }
|
||||
.md-body h1, .md-body h2, .md-body h3,
|
||||
.md-body h4, .md-body h5, .md-body h6 {
|
||||
margin: 0.8em 0 0.4em;
|
||||
font-weight: 600;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.md-body ul, .md-body ol { padding-left: 1.6em; margin: 0.5em 0; }
|
||||
.md-body li { margin: 0.2em 0; }
|
||||
.md-body blockquote {
|
||||
border-left: 3px solid #d3d1c7;
|
||||
margin: 0.6em 0;
|
||||
padding: 0.2em 1em;
|
||||
color: #5f5e5a;
|
||||
}
|
||||
.md-body pre {
|
||||
background: #f5f5f5;
|
||||
padding: 0.8em 1em;
|
||||
border-radius: 6px;
|
||||
overflow-x: auto;
|
||||
margin: 0.6em 0;
|
||||
}
|
||||
.md-body code {
|
||||
background: #f0f0f0;
|
||||
padding: 0.1em 0.35em;
|
||||
border-radius: 4px;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
.md-body pre code { background: none; padding: 0; }
|
||||
.md-body img { max-width: 100%; height: auto; }
|
||||
.md-body table { border-collapse: collapse; margin: 0.6em 0; }
|
||||
.md-body th, .md-body td {
|
||||
border: 1px solid #ddd;
|
||||
padding: 0.4em 0.8em;
|
||||
}
|
||||
.md-body hr { margin: 1em 0; }
|
||||
html[data-theme="dark"] .md-body blockquote {
|
||||
border-color: #3a404c;
|
||||
color: #8b93a1;
|
||||
}
|
||||
html[data-theme="dark"] .md-body pre,
|
||||
html[data-theme="dark"] .md-body code { background: #2d323c; }
|
||||
html[data-theme="dark"] .md-body th,
|
||||
html[data-theme="dark"] .md-body td { border-color: #3a404c; }
|
||||
|
||||
/* 投票结果占比条:模板已改用 UIkit 3 原生 <progress class="uk-progress" value max>,
|
||||
这里只把默认的 15px 高 / 500px 圆角 / 20px 外边距收紧到与页面一致的规格。
|
||||
(原先为 UIkit 2 的 .uk-progressbar 结构打的补丁已删除) */
|
||||
.uk-progress {
|
||||
height: 10px;
|
||||
margin: 0;
|
||||
border-radius: var(--tb-radius-xs);
|
||||
background-color: var(--tb-surface-2);
|
||||
}
|
||||
.uk-progress::-webkit-progress-bar {
|
||||
background-color: var(--tb-surface-2);
|
||||
border-radius: var(--tb-radius-xs);
|
||||
}
|
||||
.uk-progress::-webkit-progress-value {
|
||||
background-color: var(--tb-primary);
|
||||
border-radius: var(--tb-radius-xs) 0 0 var(--tb-radius-xs);
|
||||
}
|
||||
.uk-progress::-moz-progress-bar {
|
||||
background-color: var(--tb-primary);
|
||||
}
|
||||
|
||||
/* 移动端底部操作栏:固定底栏承载语言切换与深色模式,桌面端隐藏 */
|
||||
#tb-mobile-utils {
|
||||
display: none;
|
||||
}
|
||||
@media (max-width: 640px) {
|
||||
/* 顶栏不再容纳语言/深色按钮,恢复原有导航空间 */
|
||||
.tb-nav-utils {
|
||||
display: none !important;
|
||||
}
|
||||
/* 手机端隐藏登录用户名(左边仅保留"探索"),保证 logo 居中、
|
||||
两侧各不超过 2 个短按钮,避免用户名宽度挤压布局 */
|
||||
.tb-nav-username {
|
||||
display: none !important;
|
||||
}
|
||||
/* 固定底部操作栏 */
|
||||
#tb-mobile-utils {
|
||||
display: flex;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 1000;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 8px 12px calc(8px + env(safe-area-inset-bottom));
|
||||
background: rgba(255, 255, 255, 0.92);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
backdrop-filter: blur(8px);
|
||||
box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
#tb-mobile-utils .uk-select {
|
||||
width: 110px;
|
||||
}
|
||||
html[data-theme="dark"] #tb-mobile-utils {
|
||||
background: rgba(36, 40, 48, 0.92);
|
||||
box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
/* 给页面底部预留空间,避免页脚内容被固定底栏遮挡 */
|
||||
body {
|
||||
padding-bottom: 56px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
HTTP/1.1 200 Connection Established
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Date: Mon, 19 Oct 2026 04:22:53 GMT
|
||||
Content-Type: text/html; charset=utf-8
|
||||
Transfer-Encoding: chunked
|
||||
Connection: keep-alive
|
||||
Speculation-Rules: "/cdn-cgi/speculation"
|
||||
referrer-policy: strict-origin-when-cross-origin
|
||||
Set-Cookie: flamego_session=sa1s4htg9ll3f6qw; Path=/; HttpOnly; Secure; SameSite=Lax
|
||||
strict-transport-security: max-age=31536000; includeSubDomains
|
||||
trace-id: 00000000000000000000000000000000
|
||||
vary: Accept-Encoding
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: DENY
|
||||
x-xss-protection: 1; mode=block
|
||||
cf-cache-status: DYNAMIC
|
||||
Nel: {"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}
|
||||
Report-To: {"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=s4%2FRWTCedXYJQnbw46UeaM1OcjLEpBS32BiqnIVkSxWffJBUOeQX52rMEhSWxJQBW%2B7BHcmVxrdiqzpfMfj1EjifJX3tFmiFo%2FZC7xzrK48mAdNhMA2%2BDDrJWMMkG7hEZAk5QZ5%2FDH%2B8INO%2BnA%3D%3D"}]}
|
||||
Server: cloudflare
|
||||
CF-RAY: a4cd01154a414a25-AMS
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
|
||||
@@ -0,0 +1,937 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>狼の質問箱 | 匿名質問箱</title>
|
||||
<meta name="msvalidate.01" content="2F185E8E63C93635F50B3574F3B31E42" />
|
||||
<meta name="description" content="狼の質問箱は登録不要で使える匿名質問箱。誰でも匿名で質問でき、安心してやり取りできる場所です。">
|
||||
<meta name="keywords" content="匿名質問箱,質問箱,匿名質問,狼の質問箱,匿名で質問,匿名Q&A">
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
if (m && m[1] === 'dark') document.documentElement.setAttribute('data-theme', 'dark');
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://r2.337845818.best" crossorigin>
|
||||
<link rel="preconnect" href="https://cdnjs.snrat.com" crossorigin>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/css/uikit.min.css"/>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/base.css?v=20261019c"/>
|
||||
|
||||
<link rel="stylesheet" href="https://r2.337845818.best/tamabox/cdn/waline/client/v2/waline-no-commits.css" media="print" onload="this.media='all'"/>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit-icons.min.js"></script>
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/dayjs/1.10.8/dayjs.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/alpinejs/3.9.0/cdn.min.js"></script>
|
||||
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/waline/2.15.8/waline.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.captcha-equation-box {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: #f0f2f5;
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 8px;
|
||||
padding: 8px 8px 8px 16px;
|
||||
gap: 6px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
.captcha-equation-box:focus-within {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 3px rgba(30,135,240,0.12);
|
||||
}
|
||||
.math-captcha-modal-question {
|
||||
font-size: 1.4rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
letter-spacing: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
width: 80px;
|
||||
padding: 6px 10px;
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 600;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
transition: border-color 0.15s, box-shadow 0.15s;
|
||||
background: #fff;
|
||||
}
|
||||
#captcha-modal-answer:focus {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 2px rgba(30,135,240,0.2);
|
||||
}
|
||||
|
||||
#captcha-modal-answer::-webkit-inner-spin-button,
|
||||
#captcha-modal-answer::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta property="og:site_name" content="狼の質問箱 | 匿名質問箱" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content="狼の質問箱 | 匿名質問箱" />
|
||||
<meta property="og:url" content="https://box-dev-api.337845818.best/" />
|
||||
<meta property="og:description" content="狼の質問箱は登録不要で使える匿名質問箱。誰でも匿名で質問でき、安心してやり取りできる場所です。" />
|
||||
|
||||
|
||||
<meta itemprop="image" content="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<meta name="msapplication-TileImage" content="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<link rel="shortcut icon" href="https://r2.337845818.best/tamabox/tamabox_low.png" />
|
||||
<link rel="apple-touch-icon" href="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<link rel="icon" sizes="192x192" href="https://r2.337845818.best/tamabox/tamabox_low.png">
|
||||
<meta name="twitter:image:src" content="https://r2.337845818.best/tamabox/tamabox_low.png" />
|
||||
|
||||
|
||||
|
||||
<meta name="google-site-verification" content="fEPwRRJfiGsgwc5SINBQwZhPK8F0cwRaOvRx0YRurI4" />
|
||||
|
||||
<script>
|
||||
window.addEventListener("load", function () {
|
||||
var s = document.createElement("script");
|
||||
s.src = "https://mami.shiroko.one/tamami.js";
|
||||
s.setAttribute("data-website-id", "c42ebe8b-9281-4da0-83a4-8f18b3e710fe");
|
||||
document.body.appendChild(s);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window.tbRenderQR = function (el, getOptions) {
|
||||
if (!el || typeof QRCode === 'undefined') return;
|
||||
var opts = getOptions();
|
||||
function remoteOf(o, key) {
|
||||
var v = o[key];
|
||||
return (typeof v === 'string' && v.indexOf('http') === 0) ? v : '';
|
||||
}
|
||||
var good = window._tbQrGood || (window._tbQrGood = {});
|
||||
var bad = window._tbQrBad || (window._tbQrBad = {});
|
||||
|
||||
function layerState(url) { return !url ? '' : (good[url] ? 1 : (bad[url] ? 0 : null)); }
|
||||
var layers = [
|
||||
{ url: remoteOf(opts, 'logo'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.logo = undefined; o.logoWidth = undefined; o.logoHeight = undefined; o.logoBackgroundTransparent = undefined; }
|
||||
} },
|
||||
{ url: remoteOf(opts, 'backgroundImage'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.backgroundImage = undefined; o.backgroundImageAlpha = undefined; }
|
||||
} }
|
||||
];
|
||||
var needProbe = false;
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
layers[i].st = layerState(layers[i].url);
|
||||
if (layers[i].st === null) needProbe = true;
|
||||
}
|
||||
function paint(states) {
|
||||
var o = {};
|
||||
for (var k in opts) o[k] = opts[k];
|
||||
for (var j = 0; j < layers.length; j++) layers[j].present(o, states[j] === 1);
|
||||
el.innerHTML = '';
|
||||
new QRCode(el, o);
|
||||
}
|
||||
|
||||
var initStates = [];
|
||||
for (var n = 0; n < layers.length; n++) initStates.push(layers[n].st === 1 ? 1 : 0);
|
||||
paint(initStates);
|
||||
if (!needProbe) return;
|
||||
|
||||
var pending = 0, cross = opts.crossOrigin || 'anonymous';
|
||||
layers.forEach(function (L) {
|
||||
if (L.st !== null) return;
|
||||
pending++;
|
||||
var im = new Image();
|
||||
im.onload = function () { good[L.url] = true; L.st = 1; onDone(); };
|
||||
im.onerror = function () { bad[L.url] = true; L.st = 0; onDone(); };
|
||||
if (cross) im.crossOrigin = cross;
|
||||
im.src = L.url;
|
||||
});
|
||||
function onDone() {
|
||||
if (--pending > 0) return;
|
||||
var finalStates = [];
|
||||
for (var m = 0; m < layers.length; m++) finalStates.push(layers[m].st === 1 ? 1 : 0);
|
||||
var changed = false;
|
||||
for (var q = 0; q < finalStates.length; q++) if (finalStates[q] !== initStates[q]) changed = true;
|
||||
if (changed) paint(finalStates);
|
||||
}
|
||||
|
||||
setTimeout(function () { if (pending > 0) { pending = 0; onDone(); } }, 3000);
|
||||
};
|
||||
</script>
|
||||
<nav class="uk-navbar-container uk-margin tb-navbar" uk-navbar>
|
||||
<div class="uk-navbar-center">
|
||||
<div class="uk-navbar-center-left">
|
||||
<div>
|
||||
<ul class="uk-navbar-nav">
|
||||
|
||||
<li><a href="/explore">探索</a></li>
|
||||
|
||||
|
||||
<li class="tb-mobile-balancer" aria-hidden="true"><a tabindex="-1" style="visibility:hidden">マイ</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="uk-navbar-item uk-logo" href="/"><span class="emoji-placeholder" aria-label="random animal">🐺</span>の質問箱</a>
|
||||
|
||||
<div class="uk-navbar-center-right">
|
||||
<div>
|
||||
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/register">登録</a></li>
|
||||
</ul>
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/login">ログイン</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" aria-label="言語" title="言語"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="9"/><path d="M3.2 9h17.6M3.2 15h17.6"/><ellipse cx="12" cy="12" rx="4" ry="9"/></svg></a>
|
||||
<div class="uk-navbar-dropdown" uk-drop="mode: click; pos: bottom-right">
|
||||
<ul class="uk-nav uk-navbar-dropdown-nav">
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/zh-CN?to=%2F">简体中文</a>
|
||||
</li>
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/zh-TW?to=%2F">繁體中文</a>
|
||||
</li>
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/en?to=%2F">English</a>
|
||||
</li>
|
||||
|
||||
<li class="uk-active">
|
||||
<a href="/i18n/ja?to=%2F">日本語</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" id="theme-toggle" title="ダーク/ライトモード切替" aria-label="ダーク/ライトモード切替">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const emojis = ["🐺","🐗","🐻","🐨","🐼","🐹","🐭","🐰","🦊","🐮","🐷","🐽","🐸","🐒","🦍","🐔","🐧","🐦","🐤","🐦⬛","🦅","🦉","🦇","🐴","🦄","🐝","🦎","🦖","🦕","🐙","🦑","🦐","🦞","🦀","🐡","🐠","🐟","🐬","🐳","🐋","🦈","🐊","🐅","🐆","🦓","🦍","🦧","🐘","🦛","🦏","🐪","🐫","🦒","🦘","🐃","🐂","🐄","🐎","🐖","🐏","🐑","🦙","🐐","🦌","🐕","🐩","🦮","🐕🦺","🐈","🐋","🐳","🐬","🐉","🐲"];
|
||||
const placeholder = document.querySelector('.emoji-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.textContent = emojis[Math.floor(Math.random() * emojis.length)];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="tb-mobile-utils">
|
||||
|
||||
<select id="mobile-lang-select" class="uk-select uk-form-small" aria-label="言語">
|
||||
|
||||
<option value="zh-CN" >简体中文</option>
|
||||
|
||||
<option value="zh-TW" >繁體中文</option>
|
||||
|
||||
<option value="en" >English</option>
|
||||
|
||||
<option value="ja" selected>日本語</option>
|
||||
|
||||
</select>
|
||||
|
||||
<button type="button" id="theme-toggle-mobile" class="uk-button uk-button-default uk-button-small"
|
||||
title="ダーク/ライトモード切替" aria-label="ダーク/ライトモード切替">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
var THEME_COOKIE = 'theme';
|
||||
function getTheme() {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
return m ? m[1] : '';
|
||||
}
|
||||
function applyTheme(theme) {
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
}
|
||||
}
|
||||
function toggleTheme() {
|
||||
var next = getTheme() === 'dark' ? 'light' : 'dark';
|
||||
applyTheme(next);
|
||||
var expires = new Date(Date.now() + 365 * 24 * 3600 * 1000).toUTCString();
|
||||
document.cookie = THEME_COOKIE + '=' + next + '; path=/; max-age=' + (365 * 24 * 3600) + '; SameSite=Lax';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
var buttons = document.querySelectorAll('#theme-toggle, #theme-toggle-mobile');
|
||||
buttons.forEach(function(btn) {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
toggleTheme();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var langSel = document.getElementById('mobile-lang-select');
|
||||
if (langSel) {
|
||||
langSel.addEventListener('change', function() {
|
||||
if (!this.value) return;
|
||||
var to = window.location.pathname + window.location.search;
|
||||
window.location.href = '/i18n/' + encodeURIComponent(this.value) + '?to=' + encodeURIComponent(to);
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-container uk-container-xsmall">
|
||||
|
||||
|
||||
|
||||
<div id="math-captcha-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body uk-text-center">
|
||||
<h3 class="uk-modal-title">人機認証</h3>
|
||||
<p class="uk-text-meta">以下の計算問題を解いて、ロボットでないことを証明してください</p>
|
||||
<div class="captcha-equation-box">
|
||||
<span id="captcha-modal-question" class="math-captcha-modal-question">読み込み中...</span>
|
||||
<input type="number" id="captcha-modal-answer" placeholder="?" autocomplete="off" inputmode="numeric">
|
||||
</div>
|
||||
<div style="margin-top:6px;">
|
||||
<button type="button" class="uk-button uk-button-text uk-text-small" id="captcha-modal-refresh">別の問題</button>
|
||||
</div>
|
||||
<div id="captcha-modal-error" class="uk-text-danger uk-text-small" style="display:none;min-height:20px;"></div>
|
||||
<div class="uk-margin-small-top">
|
||||
<button type="button" class="uk-button uk-button-primary" id="captcha-modal-submit">送信</button>
|
||||
<button type="button" class="uk-button uk-button-default uk-modal-close">キャンセル</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var CAPTCHA_I18N = {
|
||||
loading: "読み込み中...",
|
||||
loadFailed: "読み込み失敗",
|
||||
loadRetry: "読み込み失敗、再試行してください",
|
||||
inputAnswer: "答えを入力してください",
|
||||
wrongAnswer: "答えが違います。もう一度計算してください",
|
||||
verifyFailed: "認証失敗、再試行してください",
|
||||
needPassword: "この質問箱にはパスワードが必要です",
|
||||
needEmail: "通知を受け取るメールアドレスを入力してください"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var captchaId = '';
|
||||
var pendingForm = null;
|
||||
var pendingNeedPassword = false;
|
||||
var verifying = false;
|
||||
|
||||
function fetchCaptcha() {
|
||||
var qEl = document.getElementById('captcha-modal-question');
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
var ansEl = document.getElementById('captcha-modal-answer');
|
||||
qEl.textContent = CAPTCHA_I18N.loading;
|
||||
fetch('/api/captcha/generate')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.code === 0 && data.data) {
|
||||
captchaId = data.data.id;
|
||||
qEl.textContent = data.data.question;
|
||||
if (errEl) errEl.style.display = 'none';
|
||||
if (ansEl) { ansEl.value = ''; ansEl.focus(); }
|
||||
} else {
|
||||
qEl.textContent = CAPTCHA_I18N.loadFailed;
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
qEl.textContent = CAPTCHA_I18N.loadRetry;
|
||||
});
|
||||
}
|
||||
|
||||
function getCSRFToken() {
|
||||
var input = document.querySelector('input[name="_csrf"]');
|
||||
return input ? input.value : '';
|
||||
}
|
||||
|
||||
function doSubmit(form) {
|
||||
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
var hidden = form.querySelector('[name="g-recaptcha-response"]');
|
||||
if (hidden) hidden.value = captchaId + ':' + (ans || '0');
|
||||
|
||||
UIkit.modal('#math-captcha-modal').hide();
|
||||
|
||||
|
||||
if (pendingNeedPassword) {
|
||||
UIkit.modal.prompt(CAPTCHA_I18N.needPassword, '', 'password')
|
||||
.then(function(password) {
|
||||
if (password) {
|
||||
var pwInput = document.getElementById('ask_password_input');
|
||||
if (pwInput) pwInput.value = password;
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-submit').addEventListener('click', function() {
|
||||
if (verifying) return;
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
if (!ans) {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.inputAnswer;
|
||||
errEl.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
verifying = true;
|
||||
fetch('/api/captcha/verify', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-Token': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify({ id: captchaId, answer: parseInt(ans, 10) })
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
verifying = false;
|
||||
if (data.correct) {
|
||||
if (pendingForm) doSubmit(pendingForm);
|
||||
} else {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.wrongAnswer;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
verifying = false;
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.verifyFailed;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-answer').addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
document.getElementById('captcha-modal-submit').click();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-refresh').addEventListener('click', fetchCaptcha);
|
||||
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target.closest('.math-captcha-trigger');
|
||||
if (!btn) return;
|
||||
e.preventDefault();
|
||||
|
||||
var form = btn.closest('form');
|
||||
if (!form) return;
|
||||
pendingForm = form;
|
||||
|
||||
|
||||
pendingNeedPassword = !!(form.querySelector('#ask_password_input'));
|
||||
|
||||
|
||||
var notifyCb = document.getElementById('notify-checkbox');
|
||||
var emailInput = document.getElementById('email-input');
|
||||
if (notifyCb && notifyCb.checked && emailInput && emailInput.value.trim() === '') {
|
||||
UIkit.modal.alert(CAPTCHA_I18N.needEmail);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchCaptcha();
|
||||
UIkit.modal('#math-captcha-modal').show();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
.tb-hero {
|
||||
padding: 36px 24px 32px;
|
||||
text-align: center;
|
||||
background-image: linear-gradient(180deg, var(--tb-primary-weak), rgba(255, 255, 255, 0));
|
||||
}
|
||||
.tb-hero-title {
|
||||
margin: 0;
|
||||
font-size: 1.75rem;
|
||||
line-height: 1.35;
|
||||
font-weight: 600;
|
||||
color: var(--tb-text);
|
||||
}
|
||||
.tb-hero-lead {
|
||||
margin: 12px auto 0;
|
||||
max-width: 30rem;
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.8;
|
||||
color: var(--tb-text-muted);
|
||||
}
|
||||
.tb-hero-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
margin-top: 22px;
|
||||
}
|
||||
.tb-hero-actions .uk-button {
|
||||
min-width: 112px;
|
||||
}
|
||||
.tb-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
|
||||
gap: 12px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
.tb-grid .uk-card {
|
||||
padding: 18px 18px 20px;
|
||||
text-align: left;
|
||||
}
|
||||
.tb-card-title {
|
||||
margin: 0 0 6px;
|
||||
font-size: 0.98rem;
|
||||
font-weight: 600;
|
||||
color: var(--tb-text);
|
||||
}
|
||||
.tb-card-text {
|
||||
margin: 0;
|
||||
font-size: 0.86rem;
|
||||
line-height: 1.7;
|
||||
color: var(--tb-text-muted);
|
||||
}
|
||||
.tb-card-text + .tb-card-text {
|
||||
margin-top: 8px;
|
||||
}
|
||||
.tb-card-text.tb-lead {
|
||||
margin-top: 12px;
|
||||
}
|
||||
.tb-changelog summary + ul {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.tb-section-title {
|
||||
margin: 0 0 10px;
|
||||
font-size: 0.95rem;
|
||||
font-weight: 600;
|
||||
color: var(--tb-text);
|
||||
}
|
||||
.tb-notice-tag {
|
||||
display: inline-block;
|
||||
margin: 0 0 8px;
|
||||
padding: 2px 8px;
|
||||
border-radius: var(--tb-radius-xs);
|
||||
background: var(--tb-primary-weak);
|
||||
color: var(--tb-primary);
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
.tb-list {
|
||||
margin: 0;
|
||||
padding-left: 1.15em;
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.9;
|
||||
color: var(--tb-text);
|
||||
}
|
||||
.tb-changelog summary {
|
||||
cursor: pointer;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
color: var(--tb-text);
|
||||
list-style: none;
|
||||
}
|
||||
.tb-changelog summary::-webkit-details-marker { display: none; }
|
||||
.tb-changelog summary::before {
|
||||
content: "▸";
|
||||
display: inline-block;
|
||||
margin-right: 8px;
|
||||
color: var(--tb-text-muted);
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
.tb-changelog[open] summary::before { transform: rotate(90deg); }
|
||||
.tb-stats {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
.tb-stat-num {
|
||||
display: block;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
color: var(--tb-text);
|
||||
}
|
||||
.tb-stat-label {
|
||||
display: block;
|
||||
margin-top: 2px;
|
||||
font-size: 0.78rem;
|
||||
color: var(--tb-text-muted);
|
||||
}
|
||||
.tb-stats-meta {
|
||||
margin: 14px 0 0;
|
||||
font-size: 0.78rem;
|
||||
line-height: 1.8;
|
||||
color: var(--tb-text-muted);
|
||||
text-align: center;
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.tb-hero { padding: 28px 16px 24px; }
|
||||
.tb-hero-title { font-size: 1.4rem; }
|
||||
.tb-stat-num { font-size: 1.25rem; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="uk-card uk-card-default tb-hero">
|
||||
<h1 class="tb-hero-title">狼の質問箱 | 匿名質問箱</h1>
|
||||
<p class="tb-hero-lead">
|
||||
一个无需注册即可提问的匿名提问箱。不用下载 App,不用绑定社交账号,连邮箱都不必是真的。
|
||||
</p>
|
||||
<div class="tb-hero-actions">
|
||||
<a href="/explore" class="uk-button uk-button-primary">探索</a>
|
||||
<a href="/rules" class="uk-button uk-button-default">ルール</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tb-grid">
|
||||
<div class="uk-card uk-card-default">
|
||||
<p class="tb-card-title">匿名也能问</p>
|
||||
<p class="tb-card-text">不需要账号、不需要真实邮箱,打开就能写。想收到回复再留邮箱即可。</p>
|
||||
</div>
|
||||
<div class="uk-card uk-card-default">
|
||||
<p class="tb-card-title">不止一问一答</p>
|
||||
<p class="tb-card-text">问题二维码、私聊、投票、追加提问、Markdown 排版,原版没有的这里都有。</p>
|
||||
</div>
|
||||
<div class="uk-card uk-card-default">
|
||||
<p class="tb-card-title">箱子归你</p>
|
||||
<p class="tb-card-text">头像、背景、二维码配色都能自己调,还能设置审核严格度和收集时段。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-body">
|
||||
<p class="tb-notice-tag">域名迁移</p>
|
||||
<p class="tb-card-text">
|
||||
本站已切换到 <a href="https://box.shiroko.one/">box.shiroko.one</a>,原域名将在 2026 年 12 月 24 日到期,
|
||||
期间通过 301 转发指向新域名,到期后旧域名将彻底不再使用。
|
||||
</p>
|
||||
<p class="tb-card-text">
|
||||
审核服务已切换到阿里云,审核速度提升且误伤更少;同时允许用户调整审核严格度,在不碰底线的前提下
|
||||
可以设置不接受辱骂、广告等信息(即「不听坏话模式」)。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-body">
|
||||
<h2 class="tb-section-title">一点提醒</h2>
|
||||
<ul class="tb-list">
|
||||
<li>本站唯一指定认证站长:<a href="https://box.shiroko.one/_/tamakyi">小狼</a>,注意不要被骗。</li>
|
||||
<li>本站提倡友好、友善的发言,请遵守<a href="/rules">社区规则</a>。无论匿名与否,都要为自己的发言负责。</li>
|
||||
<li>不允许垃圾信息、广告、辱骂、涉政、暴恐、色情、违禁、无意义、灌水提问,涉政或不良言论将直接删除。</li>
|
||||
</ul>
|
||||
<p class="tb-card-text tb-lead">
|
||||
想先试试功能,可以到站长的提问箱
|
||||
<a href="//box.shiroko.one/_/tamakyi">小狼的提问箱</a> 提问或提意见。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<details class="uk-card uk-card-default uk-card-body tb-changelog">
|
||||
<summary>近期更新</summary>
|
||||
<ul class="tb-list">
|
||||
<li><strong>2026.9</strong> 新增审核严格度选项,增加提问、投票、私聊的总开关,可设置定时收集、定量收集或关闭功能,前后端显示也更易用了。</li>
|
||||
<li><strong>2026.8</strong> 新增<a href="https://box.shiroko.one/vote/sANyLkiBNUGN">投票功能</a>、追加提问、多语言、<a href="https://box.shiroko.one/_/tamakyi/2894">Markdown 显示</a>、置顶显示等,详情见<a href="https://blog.shiroko.one/record/tamabox_changelog_20260813">这里</a>。</li>
|
||||
<li><strong>2026.8</strong> 放弃使用 recaptcha 等对国内用户不友好的验证方式,更新密码加密方式,修复图片上传等一系列问题。</li>
|
||||
<li><strong>2026.5</strong> 增加私聊功能,可连续对话,详见<a href="https://blog.shiroko.one/record/tamabox-update-20260513">介绍</a>;另有提问箱卡片分享。</li>
|
||||
<li><strong>2026.2</strong> 新增用户展示和标签功能,可给自己贴 5 个标签并选择是否在<a href="https://box.shiroko.one/explore">探索页</a>展示,详情见<a href="https://blog.shiroko.one/record/tamabox-tags">狼的公告板</a>。</li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-body">
|
||||
<h2 class="tb-section-title">質問箱の統計</h2>
|
||||
<div class="tb-stats">
|
||||
<div>
|
||||
<span class="tb-stat-num tb-num" data-stat="registered_users">28</span>
|
||||
<span class="tb-stat-label">注册用户</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="tb-stat-num tb-num" data-stat="total_questions">94</span>
|
||||
<span class="tb-stat-label">累计提问</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="tb-stat-num tb-num" data-stat="answered_questions">21</span>
|
||||
<span class="tb-stat-label">已获回答</span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="tb-stats-meta">
|
||||
最后提问:<span data-stat="last_question_at">2026-10-19 00:58:03</span><br>
|
||||
最后回答:<span data-stat="last_answer_at">2026-10-19 02:44:47</span><br>
|
||||
数据更新于:<span data-stat="updated_at">2026-10-19 12:22:53</span>
|
||||
</p>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
setInterval(function () {
|
||||
fetch("/api/v1/site-stats")
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (resp) {
|
||||
var d = resp.data;
|
||||
if (!d) return;
|
||||
["registered_users", "total_questions", "answered_questions",
|
||||
"last_question_at", "last_answer_at", "updated_at"].forEach(function (k) {
|
||||
var v = d[k];
|
||||
if (v === undefined || v === null || v === "") return;
|
||||
var el = document.querySelector('[data-stat="' + k + '"]');
|
||||
if (el) el.textContent = v;
|
||||
});
|
||||
})
|
||||
.catch(function () {});
|
||||
}, 30 * 60 * 1000);
|
||||
});
|
||||
</script>
|
||||
<div id="waline"></div>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const waline = Waline.init({
|
||||
el: '#waline',
|
||||
|
||||
serverURL: 'https://waline.337845818.best/',
|
||||
path: window.location.href,
|
||||
|
||||
locale: {
|
||||
nick: '昵称',
|
||||
nickError: '昵称不能少于3个字符',
|
||||
mail: '邮箱',
|
||||
mailError: '请填写正确的邮件地址',
|
||||
link: '网址',
|
||||
optional: '可选',
|
||||
placeholder: '欢迎评论(可以无需登录,但需要手工审核,不会立即展现)',
|
||||
sofa: '来发评论吧~',
|
||||
submit: '提交',
|
||||
like: '喜欢',
|
||||
cancelLike: '取消喜欢',
|
||||
reply: '回复',
|
||||
cancelReply: '取消回复',
|
||||
comment: '评论',
|
||||
refresh: '刷新',
|
||||
more: '加载更多...',
|
||||
preview: '预览',
|
||||
emoji: '表情',
|
||||
uploadImage: '上传图片',
|
||||
seconds: '秒前',
|
||||
minutes: '分钟前',
|
||||
hours: '小时前',
|
||||
days: '天前',
|
||||
now: '刚刚',
|
||||
uploading: '正在上传',
|
||||
login: '登录',
|
||||
logout: '退出',
|
||||
admin: '博主',
|
||||
sticky: '置顶',
|
||||
word: '字',
|
||||
wordHint: '评论字数应在 $0 到 $1 字之间!\n当前字数:$2',
|
||||
anonymous: '无名小狼',
|
||||
level0: '潜水',
|
||||
level1: '冒泡',
|
||||
level2: '吐槽',
|
||||
level3: '活跃',
|
||||
level4: '话痨',
|
||||
level5: '传说',
|
||||
gif: '表情包',
|
||||
gifSearchPlaceholder: '搜索表情包',
|
||||
profile: '个人资料',
|
||||
approved: '通过',
|
||||
waiting: '待审核',
|
||||
spam: '垃圾',
|
||||
unsticky: '取消置顶',
|
||||
oldest: '按倒序',
|
||||
latest: '按正序',
|
||||
hottest: '按热度',
|
||||
reactionTitle: '',
|
||||
reaction0: '哇哦',
|
||||
reaction1: 'prpr',
|
||||
reaction2: '流汗',
|
||||
reaction3: '生气',
|
||||
reaction4: '流鼻血',
|
||||
reaction5: 'あべ',
|
||||
},
|
||||
reaction: [
|
||||
'https://ali-imgs.acfun.cn/kimg/bs2/zt-image-host/ChYwOGQ3OTRhYzRjMTBkZmZhZDVmZTA1EIjM1y8.gif',
|
||||
'https://ali-imgs.acfun.cn/kimg/bs2/zt-image-host/ChQwOGEyOTlhYzRjMTBmOWFkZjAwYRCIzNcv.gif',
|
||||
'https://ali-imgs.acfun.cn/kimg/bs2/zt-image-host/ChYwOGRhOTVhYzRjMTBkNmViYTVlNTA2EIjM1y8.gif',
|
||||
'https://ali-imgs.acfun.cn/kimg/bs2/zt-image-host/ChYwOGU1OTJhYzRjMTBmMzk3ZmVmNTAyEIjM1y8.gif',
|
||||
'https://ali-imgs.acfun.cn/kimg/bs2/zt-image-host/ChYwOGNkODdhYzRjMTBjYmEwOTFjNjAxEIjM1y8.gif',
|
||||
'https://ali-imgs.acfun.cn/kimg/bs2/zt-image-host/ChQwODliOGVhYzRjMTBmOGM0ZWY1ZRCIzNcv.gif',
|
||||
],
|
||||
meta: ['nick','mail'],
|
||||
requiredMeta: ['mail'],
|
||||
pageview: true,
|
||||
search: false,
|
||||
login: 'enable',
|
||||
wordLimit: 50,
|
||||
pageSize: 5,
|
||||
avatar: 'identicon',
|
||||
emoji: [
|
||||
'https://gcore.jsdelivr.net/gh/tamakyi/emoji-collection@main/acfun-color/60x60',
|
||||
],
|
||||
|
||||
imageUploader: false,
|
||||
|
||||
copyright: false,
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<p class=" uk-text-right uk-text-muted uk-text-small">
|
||||
<br>
|
||||
<a href="/rules">ルール</a> |
|
||||
|
||||
<a href="https://box.shiroko.one/_/tamakyi" target="_blank">管理者へ</a>
|
||||
<br>
|
||||
<a href="https://share.shiroko.one" target="_blank">ドライブ</a>
|
||||
| <a href="https://blog.shiroko.one" target="_blank">お知らせ</a>
|
||||
| <a href="https://chat.shiroko.one" target="_blank">チャット</a>
|
||||
| <a href="https://status.shiroko.one" target="_blank">ステータス</a>
|
||||
| <a href="https://shiroko.one" target="_blank">リンク</a>
|
||||
<br>Powered by NekoBox | 狼ICP备 20230101
|
||||
<br>質問箱は稼働中:<span id="box_runtime"></span>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
(function () {
|
||||
var create = Math.round(Date.UTC(2023, 6, 1, 18, 15, 43) / 1000);
|
||||
function tick() {
|
||||
var el = document.getElementById("box_runtime");
|
||||
if (!el) return;
|
||||
var s = Math.round((Date.now() + 8 * 3600 * 1000) / 1000) - create;
|
||||
var t = [0, 0, 0, 0, 0];
|
||||
if (s >= 31536000) { t[0] = s / 31536000 | 0; s %= 31536000; }
|
||||
if (s >= 86400) { t[1] = s / 86400 | 0; s %= 86400; }
|
||||
if (s >= 3600) { t[2] = s / 3600 | 0; s %= 3600; }
|
||||
if (s >= 60) { t[3] = s / 60 | 0; s %= 60; }
|
||||
if (s > 0) { t[4] = s; }
|
||||
el.innerHTML = t[0] + '年 ' + t[1] + '天 ' + t[2] + '时 ' + t[3] + '分 ' + t[4] + '秒 ';
|
||||
}
|
||||
tick();
|
||||
setInterval(tick, 1000);
|
||||
})();
|
||||
</script>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
var SUBMIT_I18N = {
|
||||
submitting: '送信中...',
|
||||
uploading: 'アップロード中...'
|
||||
};
|
||||
|
||||
function tbResetSubmitButtons() {
|
||||
document.querySelectorAll('button[data-tb-submitting]').forEach(function(b) {
|
||||
b.disabled = false;
|
||||
b.removeAttribute('data-tb-submitting');
|
||||
var orig = b.getAttribute('data-tb-restore');
|
||||
if (orig !== null) {
|
||||
b.innerHTML = orig;
|
||||
b.removeAttribute('data-tb-restore');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('submit', function(e) {
|
||||
var form = e.target;
|
||||
if (!form || form.tagName !== 'FORM') return;
|
||||
|
||||
|
||||
|
||||
if (e.defaultPrevented || form.getAttribute('data-tb-skip-submit-feedback') === '1') {
|
||||
form.removeAttribute('data-tb-skip-submit-feedback');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (form.getAttribute('target') === '_blank') return;
|
||||
|
||||
|
||||
var trigger = e.submitter || form.querySelector('button[type="submit"]');
|
||||
|
||||
|
||||
var hasFile = false;
|
||||
form.querySelectorAll('input[type="file"]').forEach(function(f) {
|
||||
if (f.files && f.files.length > 0) hasFile = true;
|
||||
});
|
||||
var label = hasFile ? SUBMIT_I18N.uploading : SUBMIT_I18N.submitting;
|
||||
|
||||
if (trigger && trigger.tagName === 'BUTTON') {
|
||||
trigger.setAttribute('data-tb-restore', trigger.innerHTML);
|
||||
trigger.innerHTML = '<span uk-spinner="ratio: 0.6"></span> ' + label;
|
||||
}
|
||||
|
||||
|
||||
form.querySelectorAll('button').forEach(function(b) {
|
||||
b.disabled = true;
|
||||
b.setAttribute('data-tb-submitting', '1');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener('pageshow', tbResetSubmitButtons);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,626 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>投票结果</title>
|
||||
<meta name="msvalidate.01" content="2F185E8E63C93635F50B3574F3B31E42" />
|
||||
<meta name="description" content="狼的提问箱——一个无需注册、可匿名提问的匿名提问箱,安全地倾诉与回应。">
|
||||
<meta name="keywords" content="匿名提问箱,提问箱,匿名提问,狼的提问箱,匿名问答,匿名提问网站">
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
if (m && m[1] === 'dark') document.documentElement.setAttribute('data-theme', 'dark');
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://r2.337845818.best" crossorigin>
|
||||
<link rel="preconnect" href="https://cdnjs.snrat.com" crossorigin>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/css/uikit.min.css"/>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/base.css?v=20261019c"/>
|
||||
|
||||
<link rel="stylesheet" href="https://r2.337845818.best/tamabox/cdn/waline/client/v2/waline-no-commits.css" media="print" onload="this.media='all'"/>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit-icons.min.js"></script>
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/dayjs/1.10.8/dayjs.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/alpinejs/3.9.0/cdn.min.js"></script>
|
||||
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/waline/2.15.8/waline.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.captcha-equation-box {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: #f0f2f5;
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 8px;
|
||||
padding: 8px 8px 8px 16px;
|
||||
gap: 6px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
.captcha-equation-box:focus-within {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 3px rgba(30,135,240,0.12);
|
||||
}
|
||||
.math-captcha-modal-question {
|
||||
font-size: 1.4rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
letter-spacing: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
width: 80px;
|
||||
padding: 6px 10px;
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 600;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
transition: border-color 0.15s, box-shadow 0.15s;
|
||||
background: #fff;
|
||||
}
|
||||
#captcha-modal-answer:focus {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 2px rgba(30,135,240,0.2);
|
||||
}
|
||||
|
||||
#captcha-modal-answer::-webkit-inner-spin-button,
|
||||
#captcha-modal-answer::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta property="og:site_name" content="狼的提问箱 | 匿名提问箱" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content=" - 狼的提问箱 | 匿名提问箱" />
|
||||
<meta property="og:url" content="https://box-dev-api.337845818.best/user/votes/13/results" />
|
||||
<meta property="og:description" content=" - 狼的提问箱——一个无需注册、可匿名提问的匿名提问箱,安全地倾诉与回应。" />
|
||||
<meta name="robots" content="noindex">
|
||||
|
||||
<meta property="og:image" content="?og-image=1" />
|
||||
<meta property="og:image:alt" content="" />
|
||||
<meta itemprop="image" content="?og-image=1"/>
|
||||
<meta name="msapplication-TileImage" content=""/>
|
||||
<link rel="shortcut icon" href="?og-image=1"/>
|
||||
<link rel="apple-touch-icon" href="?og-image=1"/>
|
||||
<link rel="icon" sizes="192x192" href="?og-image=1">
|
||||
<meta name="twitter:image:src" content="?og-image=1" />
|
||||
|
||||
|
||||
|
||||
<meta name="google-site-verification" content="fEPwRRJfiGsgwc5SINBQwZhPK8F0cwRaOvRx0YRurI4" />
|
||||
|
||||
<script>
|
||||
window.addEventListener("load", function () {
|
||||
var s = document.createElement("script");
|
||||
s.src = "https://mami.shiroko.one/tamami.js";
|
||||
s.setAttribute("data-website-id", "c42ebe8b-9281-4da0-83a4-8f18b3e710fe");
|
||||
document.body.appendChild(s);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window.tbRenderQR = function (el, getOptions) {
|
||||
if (!el || typeof QRCode === 'undefined') return;
|
||||
var opts = getOptions();
|
||||
function remoteOf(o, key) {
|
||||
var v = o[key];
|
||||
return (typeof v === 'string' && v.indexOf('http') === 0) ? v : '';
|
||||
}
|
||||
var good = window._tbQrGood || (window._tbQrGood = {});
|
||||
var bad = window._tbQrBad || (window._tbQrBad = {});
|
||||
|
||||
function layerState(url) { return !url ? '' : (good[url] ? 1 : (bad[url] ? 0 : null)); }
|
||||
var layers = [
|
||||
{ url: remoteOf(opts, 'logo'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.logo = undefined; o.logoWidth = undefined; o.logoHeight = undefined; o.logoBackgroundTransparent = undefined; }
|
||||
} },
|
||||
{ url: remoteOf(opts, 'backgroundImage'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.backgroundImage = undefined; o.backgroundImageAlpha = undefined; }
|
||||
} }
|
||||
];
|
||||
var needProbe = false;
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
layers[i].st = layerState(layers[i].url);
|
||||
if (layers[i].st === null) needProbe = true;
|
||||
}
|
||||
function paint(states) {
|
||||
var o = {};
|
||||
for (var k in opts) o[k] = opts[k];
|
||||
for (var j = 0; j < layers.length; j++) layers[j].present(o, states[j] === 1);
|
||||
el.innerHTML = '';
|
||||
new QRCode(el, o);
|
||||
}
|
||||
|
||||
var initStates = [];
|
||||
for (var n = 0; n < layers.length; n++) initStates.push(layers[n].st === 1 ? 1 : 0);
|
||||
paint(initStates);
|
||||
if (!needProbe) return;
|
||||
|
||||
var pending = 0, cross = opts.crossOrigin || 'anonymous';
|
||||
layers.forEach(function (L) {
|
||||
if (L.st !== null) return;
|
||||
pending++;
|
||||
var im = new Image();
|
||||
im.onload = function () { good[L.url] = true; L.st = 1; onDone(); };
|
||||
im.onerror = function () { bad[L.url] = true; L.st = 0; onDone(); };
|
||||
if (cross) im.crossOrigin = cross;
|
||||
im.src = L.url;
|
||||
});
|
||||
function onDone() {
|
||||
if (--pending > 0) return;
|
||||
var finalStates = [];
|
||||
for (var m = 0; m < layers.length; m++) finalStates.push(layers[m].st === 1 ? 1 : 0);
|
||||
var changed = false;
|
||||
for (var q = 0; q < finalStates.length; q++) if (finalStates[q] !== initStates[q]) changed = true;
|
||||
if (changed) paint(finalStates);
|
||||
}
|
||||
|
||||
setTimeout(function () { if (pending > 0) { pending = 0; onDone(); } }, 3000);
|
||||
};
|
||||
</script>
|
||||
<nav class="uk-navbar-container uk-margin tb-navbar" uk-navbar>
|
||||
<div class="uk-navbar-center">
|
||||
<div class="uk-navbar-center-left">
|
||||
<div>
|
||||
<ul class="uk-navbar-nav">
|
||||
|
||||
<li><a href="/explore">探索</a></li>
|
||||
|
||||
|
||||
<li><a href="/_/admin6">我的</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="uk-navbar-item uk-logo" href="/"><span class="emoji-placeholder" aria-label="random animal">🐺</span>的提问箱</a>
|
||||
|
||||
<div class="uk-navbar-center-right">
|
||||
<div>
|
||||
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/user/questions">提问</a></li>
|
||||
</ul>
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/user/profile">设置</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" id="theme-toggle" title="切换深色/浅色模式" aria-label="切换深色/浅色模式">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const emojis = ["🐺","🐗","🐻","🐨","🐼","🐹","🐭","🐰","🦊","🐮","🐷","🐽","🐸","🐒","🦍","🐔","🐧","🐦","🐤","🐦⬛","🦅","🦉","🦇","🐴","🦄","🐝","🦎","🦖","🦕","🐙","🦑","🦐","🦞","🦀","🐡","🐠","🐟","🐬","🐳","🐋","🦈","🐊","🐅","🐆","🦓","🦍","🦧","🐘","🦛","🦏","🐪","🐫","🦒","🦘","🐃","🐂","🐄","🐎","🐖","🐏","🐑","🦙","🐐","🦌","🐕","🐩","🦮","🐕🦺","🐈","🐋","🐳","🐬","🐉","🐲"];
|
||||
const placeholder = document.querySelector('.emoji-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.textContent = emojis[Math.floor(Math.random() * emojis.length)];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="tb-mobile-utils">
|
||||
|
||||
<button type="button" id="theme-toggle-mobile" class="uk-button uk-button-default uk-button-small"
|
||||
title="切换深色/浅色模式" aria-label="切换深色/浅色模式">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
var THEME_COOKIE = 'theme';
|
||||
function getTheme() {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
return m ? m[1] : '';
|
||||
}
|
||||
function applyTheme(theme) {
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
}
|
||||
}
|
||||
function toggleTheme() {
|
||||
var next = getTheme() === 'dark' ? 'light' : 'dark';
|
||||
applyTheme(next);
|
||||
var expires = new Date(Date.now() + 365 * 24 * 3600 * 1000).toUTCString();
|
||||
document.cookie = THEME_COOKIE + '=' + next + '; path=/; max-age=' + (365 * 24 * 3600) + '; SameSite=Lax';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
var buttons = document.querySelectorAll('#theme-toggle, #theme-toggle-mobile');
|
||||
buttons.forEach(function(btn) {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
toggleTheme();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var langSel = document.getElementById('mobile-lang-select');
|
||||
if (langSel) {
|
||||
langSel.addEventListener('change', function() {
|
||||
if (!this.value) return;
|
||||
var to = window.location.pathname + window.location.search;
|
||||
window.location.href = '/i18n/' + encodeURIComponent(this.value) + '?to=' + encodeURIComponent(to);
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-container uk-container-xsmall">
|
||||
|
||||
|
||||
|
||||
<div id="math-captcha-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body uk-text-center">
|
||||
<h3 class="uk-modal-title">人机验证</h3>
|
||||
<p class="uk-text-meta">请计算下方的算术题以验证你不是机器人</p>
|
||||
<div class="captcha-equation-box">
|
||||
<span id="captcha-modal-question" class="math-captcha-modal-question">加载中...</span>
|
||||
<input type="number" id="captcha-modal-answer" placeholder="?" autocomplete="off" inputmode="numeric">
|
||||
</div>
|
||||
<div style="margin-top:6px;">
|
||||
<button type="button" class="uk-button uk-button-text uk-text-small" id="captcha-modal-refresh">换一题</button>
|
||||
</div>
|
||||
<div id="captcha-modal-error" class="uk-text-danger uk-text-small" style="display:none;min-height:20px;"></div>
|
||||
<div class="uk-margin-small-top">
|
||||
<button type="button" class="uk-button uk-button-primary" id="captcha-modal-submit">提交</button>
|
||||
<button type="button" class="uk-button uk-button-default uk-modal-close">取消</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var CAPTCHA_I18N = {
|
||||
loading: "加载中...",
|
||||
loadFailed: "加载失败",
|
||||
loadRetry: "加载失败,请重试",
|
||||
inputAnswer: "请输入答案",
|
||||
wrongAnswer: "答案错误,请重新计算",
|
||||
verifyFailed: "验证失败,请重试",
|
||||
needPassword: "此提问箱需要密码",
|
||||
needEmail: "请填写接收通知的邮箱地址"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var captchaId = '';
|
||||
var pendingForm = null;
|
||||
var pendingNeedPassword = false;
|
||||
var verifying = false;
|
||||
|
||||
function fetchCaptcha() {
|
||||
var qEl = document.getElementById('captcha-modal-question');
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
var ansEl = document.getElementById('captcha-modal-answer');
|
||||
qEl.textContent = CAPTCHA_I18N.loading;
|
||||
fetch('/api/captcha/generate')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.code === 0 && data.data) {
|
||||
captchaId = data.data.id;
|
||||
qEl.textContent = data.data.question;
|
||||
if (errEl) errEl.style.display = 'none';
|
||||
if (ansEl) { ansEl.value = ''; ansEl.focus(); }
|
||||
} else {
|
||||
qEl.textContent = CAPTCHA_I18N.loadFailed;
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
qEl.textContent = CAPTCHA_I18N.loadRetry;
|
||||
});
|
||||
}
|
||||
|
||||
function getCSRFToken() {
|
||||
var input = document.querySelector('input[name="_csrf"]');
|
||||
return input ? input.value : '';
|
||||
}
|
||||
|
||||
function doSubmit(form) {
|
||||
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
var hidden = form.querySelector('[name="g-recaptcha-response"]');
|
||||
if (hidden) hidden.value = captchaId + ':' + (ans || '0');
|
||||
|
||||
UIkit.modal('#math-captcha-modal').hide();
|
||||
|
||||
|
||||
if (pendingNeedPassword) {
|
||||
UIkit.modal.prompt(CAPTCHA_I18N.needPassword, '', 'password')
|
||||
.then(function(password) {
|
||||
if (password) {
|
||||
var pwInput = document.getElementById('ask_password_input');
|
||||
if (pwInput) pwInput.value = password;
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-submit').addEventListener('click', function() {
|
||||
if (verifying) return;
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
if (!ans) {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.inputAnswer;
|
||||
errEl.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
verifying = true;
|
||||
fetch('/api/captcha/verify', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-Token': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify({ id: captchaId, answer: parseInt(ans, 10) })
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
verifying = false;
|
||||
if (data.correct) {
|
||||
if (pendingForm) doSubmit(pendingForm);
|
||||
} else {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.wrongAnswer;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
verifying = false;
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.verifyFailed;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-answer').addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
document.getElementById('captcha-modal-submit').click();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-refresh').addEventListener('click', fetchCaptcha);
|
||||
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target.closest('.math-captcha-trigger');
|
||||
if (!btn) return;
|
||||
e.preventDefault();
|
||||
|
||||
var form = btn.closest('form');
|
||||
if (!form) return;
|
||||
pendingForm = form;
|
||||
|
||||
|
||||
pendingNeedPassword = !!(form.querySelector('#ask_password_input'));
|
||||
|
||||
|
||||
var notifyCb = document.getElementById('notify-checkbox');
|
||||
var emailInput = document.getElementById('email-input');
|
||||
if (notifyCb && notifyCb.checked && emailInput && emailInput.value.trim() === '') {
|
||||
UIkit.modal.alert(CAPTCHA_I18N.needEmail);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchCaptcha();
|
||||
UIkit.modal('#math-captcha-modal').show();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-flex-middle uk-margin-bottom">
|
||||
<h3 class="uk-margin-remove">投票结果:吃什么</h3>
|
||||
<div class="uk-flex uk-flex-middle" style="gap: 8px;">
|
||||
<a class="uk-button uk-button-default uk-button-small" href="/user/votes/13/export">导出 CSV</a>
|
||||
<a class="uk-button uk-button-default uk-button-small" href="/user/questions#votes">返回</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-small uk-card-body uk-margin-bottom">
|
||||
<div class="uk-text-large uk-text-bold">0</div>
|
||||
<div class="uk-text-meta">总参与人数</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<h4>投票结果</h4>
|
||||
<div class="uk-card uk-card-default uk-card-small uk-card-body uk-margin-bottom">
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 8px;">
|
||||
<span class="uk-label">1</span>
|
||||
<span class="uk-label ">单行文本</span>
|
||||
<span class="uk-text-bold">是啊,吃什么?</span>
|
||||
<span class="uk-text-meta uk-text-small">回答数: 0</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="uk-text-meta uk-margin-small-top">已填写: 0</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
function toggleFieldReplies(id) {
|
||||
var box = document.getElementById('replies-' + id);
|
||||
var caret = document.getElementById('caret-' + id);
|
||||
if (!box) { return; }
|
||||
if (box.hasAttribute('hidden')) {
|
||||
box.removeAttribute('hidden');
|
||||
if (caret) { caret.style.transform = 'rotate(0deg)'; }
|
||||
} else {
|
||||
box.setAttribute('hidden', '');
|
||||
if (caret) { caret.style.transform = 'rotate(-90deg)'; }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<p class=" uk-text-right uk-text-muted uk-text-small">
|
||||
<br>
|
||||
<a href="/rules">社区规则</a> |
|
||||
|
||||
<a href="https://box.shiroko.one/_/tamakyi" target="_blank">找站长</a>
|
||||
<br>
|
||||
<a href="https://share.shiroko.one" target="_blank">盘</a>
|
||||
| <a href="https://blog.shiroko.one" target="_blank">公告板</a>
|
||||
| <a href="https://chat.shiroko.one" target="_blank">聊天室</a>
|
||||
| <a href="https://status.shiroko.one" target="_blank">监控板</a>
|
||||
| <a href="https://shiroko.one" target="_blank">导航页</a>
|
||||
<br>Powered by NekoBox | 狼ICP备 20230101
|
||||
<br>提问箱已成功存活:<span id="box_runtime"></span>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
(function () {
|
||||
var create = Math.round(Date.UTC(2023, 6, 1, 18, 15, 43) / 1000);
|
||||
function tick() {
|
||||
var el = document.getElementById("box_runtime");
|
||||
if (!el) return;
|
||||
var s = Math.round((Date.now() + 8 * 3600 * 1000) / 1000) - create;
|
||||
var t = [0, 0, 0, 0, 0];
|
||||
if (s >= 31536000) { t[0] = s / 31536000 | 0; s %= 31536000; }
|
||||
if (s >= 86400) { t[1] = s / 86400 | 0; s %= 86400; }
|
||||
if (s >= 3600) { t[2] = s / 3600 | 0; s %= 3600; }
|
||||
if (s >= 60) { t[3] = s / 60 | 0; s %= 60; }
|
||||
if (s > 0) { t[4] = s; }
|
||||
el.innerHTML = t[0] + '年 ' + t[1] + '天 ' + t[2] + '时 ' + t[3] + '分 ' + t[4] + '秒 ';
|
||||
}
|
||||
tick();
|
||||
setInterval(tick, 1000);
|
||||
})();
|
||||
</script>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
var SUBMIT_I18N = {
|
||||
submitting: '提交中...',
|
||||
uploading: '上传中...'
|
||||
};
|
||||
|
||||
function tbResetSubmitButtons() {
|
||||
document.querySelectorAll('button[data-tb-submitting]').forEach(function(b) {
|
||||
b.disabled = false;
|
||||
b.removeAttribute('data-tb-submitting');
|
||||
var orig = b.getAttribute('data-tb-restore');
|
||||
if (orig !== null) {
|
||||
b.innerHTML = orig;
|
||||
b.removeAttribute('data-tb-restore');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('submit', function(e) {
|
||||
var form = e.target;
|
||||
if (!form || form.tagName !== 'FORM') return;
|
||||
|
||||
|
||||
|
||||
if (e.defaultPrevented || form.getAttribute('data-tb-skip-submit-feedback') === '1') {
|
||||
form.removeAttribute('data-tb-skip-submit-feedback');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (form.getAttribute('target') === '_blank') return;
|
||||
|
||||
|
||||
var trigger = e.submitter || form.querySelector('button[type="submit"]');
|
||||
|
||||
|
||||
var hasFile = false;
|
||||
form.querySelectorAll('input[type="file"]').forEach(function(f) {
|
||||
if (f.files && f.files.length > 0) hasFile = true;
|
||||
});
|
||||
var label = hasFile ? SUBMIT_I18N.uploading : SUBMIT_I18N.submitting;
|
||||
|
||||
if (trigger && trigger.tagName === 'BUTTON') {
|
||||
trigger.setAttribute('data-tb-restore', trigger.innerHTML);
|
||||
trigger.innerHTML = '<span uk-spinner="ratio: 0.6"></span> ' + label;
|
||||
}
|
||||
|
||||
|
||||
form.querySelectorAll('button').forEach(function(b) {
|
||||
b.disabled = true;
|
||||
b.setAttribute('data-tb-submitting', '1');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener('pageshow', tbResetSubmitButtons);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,885 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>测试</title>
|
||||
<meta name="msvalidate.01" content="2F185E8E63C93635F50B3574F3B31E42" />
|
||||
<meta name="description" content="狼の質問箱は登録不要で使える匿名質問箱。誰でも匿名で質問でき、安心してやり取りできる場所です。">
|
||||
<meta name="keywords" content="匿名質問箱,質問箱,匿名質問,狼の質問箱,匿名で質問,匿名Q&A">
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
if (m && m[1] === 'dark') document.documentElement.setAttribute('data-theme', 'dark');
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://r2.337845818.best" crossorigin>
|
||||
<link rel="preconnect" href="https://cdnjs.snrat.com" crossorigin>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/css/uikit.min.css"/>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/base.css?v=20261019c"/>
|
||||
|
||||
<link rel="stylesheet" href="https://r2.337845818.best/tamabox/cdn/waline/client/v2/waline-no-commits.css" media="print" onload="this.media='all'"/>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit-icons.min.js"></script>
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/dayjs/1.10.8/dayjs.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/alpinejs/3.9.0/cdn.min.js"></script>
|
||||
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/waline/2.15.8/waline.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.captcha-equation-box {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: #f0f2f5;
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 8px;
|
||||
padding: 8px 8px 8px 16px;
|
||||
gap: 6px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
.captcha-equation-box:focus-within {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 3px rgba(30,135,240,0.12);
|
||||
}
|
||||
.math-captcha-modal-question {
|
||||
font-size: 1.4rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
letter-spacing: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
width: 80px;
|
||||
padding: 6px 10px;
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 600;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
transition: border-color 0.15s, box-shadow 0.15s;
|
||||
background: #fff;
|
||||
}
|
||||
#captcha-modal-answer:focus {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 2px rgba(30,135,240,0.2);
|
||||
}
|
||||
|
||||
#captcha-modal-answer::-webkit-inner-spin-button,
|
||||
#captcha-modal-answer::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta property="og:site_name" content="狼の質問箱 | 匿名質問箱" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content="狼の質問箱 | 匿名質問箱" />
|
||||
<meta property="og:url" content="https://box-dev-api.337845818.best/vote/7kcP5kR8YnJC" />
|
||||
<meta property="og:description" content="狼の質問箱は登録不要で使える匿名質問箱。誰でも匿名で質問でき、安心してやり取りできる場所です。" />
|
||||
<meta name="robots" content="noindex">
|
||||
|
||||
<meta itemprop="image" content="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<meta name="msapplication-TileImage" content="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<link rel="shortcut icon" href="https://r2.337845818.best/tamabox/tamabox_low.png" />
|
||||
<link rel="apple-touch-icon" href="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<link rel="icon" sizes="192x192" href="https://r2.337845818.best/tamabox/tamabox_low.png">
|
||||
<meta name="twitter:image:src" content="https://r2.337845818.best/tamabox/tamabox_low.png" />
|
||||
|
||||
|
||||
|
||||
<meta name="google-site-verification" content="fEPwRRJfiGsgwc5SINBQwZhPK8F0cwRaOvRx0YRurI4" />
|
||||
|
||||
<script>
|
||||
window.addEventListener("load", function () {
|
||||
var s = document.createElement("script");
|
||||
s.src = "https://mami.shiroko.one/tamami.js";
|
||||
s.setAttribute("data-website-id", "c42ebe8b-9281-4da0-83a4-8f18b3e710fe");
|
||||
document.body.appendChild(s);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window.tbRenderQR = function (el, getOptions) {
|
||||
if (!el || typeof QRCode === 'undefined') return;
|
||||
var opts = getOptions();
|
||||
function remoteOf(o, key) {
|
||||
var v = o[key];
|
||||
return (typeof v === 'string' && v.indexOf('http') === 0) ? v : '';
|
||||
}
|
||||
var good = window._tbQrGood || (window._tbQrGood = {});
|
||||
var bad = window._tbQrBad || (window._tbQrBad = {});
|
||||
|
||||
function layerState(url) { return !url ? '' : (good[url] ? 1 : (bad[url] ? 0 : null)); }
|
||||
var layers = [
|
||||
{ url: remoteOf(opts, 'logo'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.logo = undefined; o.logoWidth = undefined; o.logoHeight = undefined; o.logoBackgroundTransparent = undefined; }
|
||||
} },
|
||||
{ url: remoteOf(opts, 'backgroundImage'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.backgroundImage = undefined; o.backgroundImageAlpha = undefined; }
|
||||
} }
|
||||
];
|
||||
var needProbe = false;
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
layers[i].st = layerState(layers[i].url);
|
||||
if (layers[i].st === null) needProbe = true;
|
||||
}
|
||||
function paint(states) {
|
||||
var o = {};
|
||||
for (var k in opts) o[k] = opts[k];
|
||||
for (var j = 0; j < layers.length; j++) layers[j].present(o, states[j] === 1);
|
||||
el.innerHTML = '';
|
||||
new QRCode(el, o);
|
||||
}
|
||||
|
||||
var initStates = [];
|
||||
for (var n = 0; n < layers.length; n++) initStates.push(layers[n].st === 1 ? 1 : 0);
|
||||
paint(initStates);
|
||||
if (!needProbe) return;
|
||||
|
||||
var pending = 0, cross = opts.crossOrigin || 'anonymous';
|
||||
layers.forEach(function (L) {
|
||||
if (L.st !== null) return;
|
||||
pending++;
|
||||
var im = new Image();
|
||||
im.onload = function () { good[L.url] = true; L.st = 1; onDone(); };
|
||||
im.onerror = function () { bad[L.url] = true; L.st = 0; onDone(); };
|
||||
if (cross) im.crossOrigin = cross;
|
||||
im.src = L.url;
|
||||
});
|
||||
function onDone() {
|
||||
if (--pending > 0) return;
|
||||
var finalStates = [];
|
||||
for (var m = 0; m < layers.length; m++) finalStates.push(layers[m].st === 1 ? 1 : 0);
|
||||
var changed = false;
|
||||
for (var q = 0; q < finalStates.length; q++) if (finalStates[q] !== initStates[q]) changed = true;
|
||||
if (changed) paint(finalStates);
|
||||
}
|
||||
|
||||
setTimeout(function () { if (pending > 0) { pending = 0; onDone(); } }, 3000);
|
||||
};
|
||||
</script>
|
||||
<nav class="uk-navbar-container uk-margin tb-navbar" uk-navbar>
|
||||
<div class="uk-navbar-center">
|
||||
<div class="uk-navbar-center-left">
|
||||
<div>
|
||||
<ul class="uk-navbar-nav">
|
||||
|
||||
<li><a href="/explore">探索</a></li>
|
||||
|
||||
|
||||
<li class="tb-mobile-balancer" aria-hidden="true"><a tabindex="-1" style="visibility:hidden">マイ</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="uk-navbar-item uk-logo" href="/"><span class="emoji-placeholder" aria-label="random animal">🐺</span>の質問箱</a>
|
||||
|
||||
<div class="uk-navbar-center-right">
|
||||
<div>
|
||||
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/register">登録</a></li>
|
||||
</ul>
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/login">ログイン</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" aria-label="言語" title="言語"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="9"/><path d="M3.2 9h17.6M3.2 15h17.6"/><ellipse cx="12" cy="12" rx="4" ry="9"/></svg></a>
|
||||
<div class="uk-navbar-dropdown" uk-drop="mode: click; pos: bottom-right">
|
||||
<ul class="uk-nav uk-navbar-dropdown-nav">
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/zh-CN?to=%2Fvote%2F7kcP5kR8YnJC">简体中文</a>
|
||||
</li>
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/zh-TW?to=%2Fvote%2F7kcP5kR8YnJC">繁體中文</a>
|
||||
</li>
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/en?to=%2Fvote%2F7kcP5kR8YnJC">English</a>
|
||||
</li>
|
||||
|
||||
<li class="uk-active">
|
||||
<a href="/i18n/ja?to=%2Fvote%2F7kcP5kR8YnJC">日本語</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" id="theme-toggle" title="ダーク/ライトモード切替" aria-label="ダーク/ライトモード切替">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const emojis = ["🐺","🐗","🐻","🐨","🐼","🐹","🐭","🐰","🦊","🐮","🐷","🐽","🐸","🐒","🦍","🐔","🐧","🐦","🐤","🐦⬛","🦅","🦉","🦇","🐴","🦄","🐝","🦎","🦖","🦕","🐙","🦑","🦐","🦞","🦀","🐡","🐠","🐟","🐬","🐳","🐋","🦈","🐊","🐅","🐆","🦓","🦍","🦧","🐘","🦛","🦏","🐪","🐫","🦒","🦘","🐃","🐂","🐄","🐎","🐖","🐏","🐑","🦙","🐐","🦌","🐕","🐩","🦮","🐕🦺","🐈","🐋","🐳","🐬","🐉","🐲"];
|
||||
const placeholder = document.querySelector('.emoji-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.textContent = emojis[Math.floor(Math.random() * emojis.length)];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="tb-mobile-utils">
|
||||
|
||||
<select id="mobile-lang-select" class="uk-select uk-form-small" aria-label="言語">
|
||||
|
||||
<option value="zh-CN" >简体中文</option>
|
||||
|
||||
<option value="zh-TW" >繁體中文</option>
|
||||
|
||||
<option value="en" >English</option>
|
||||
|
||||
<option value="ja" selected>日本語</option>
|
||||
|
||||
</select>
|
||||
|
||||
<button type="button" id="theme-toggle-mobile" class="uk-button uk-button-default uk-button-small"
|
||||
title="ダーク/ライトモード切替" aria-label="ダーク/ライトモード切替">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
var THEME_COOKIE = 'theme';
|
||||
function getTheme() {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
return m ? m[1] : '';
|
||||
}
|
||||
function applyTheme(theme) {
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
}
|
||||
}
|
||||
function toggleTheme() {
|
||||
var next = getTheme() === 'dark' ? 'light' : 'dark';
|
||||
applyTheme(next);
|
||||
var expires = new Date(Date.now() + 365 * 24 * 3600 * 1000).toUTCString();
|
||||
document.cookie = THEME_COOKIE + '=' + next + '; path=/; max-age=' + (365 * 24 * 3600) + '; SameSite=Lax';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
var buttons = document.querySelectorAll('#theme-toggle, #theme-toggle-mobile');
|
||||
buttons.forEach(function(btn) {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
toggleTheme();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var langSel = document.getElementById('mobile-lang-select');
|
||||
if (langSel) {
|
||||
langSel.addEventListener('change', function() {
|
||||
if (!this.value) return;
|
||||
var to = window.location.pathname + window.location.search;
|
||||
window.location.href = '/i18n/' + encodeURIComponent(this.value) + '?to=' + encodeURIComponent(to);
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-container uk-container-xsmall">
|
||||
|
||||
|
||||
|
||||
<div id="math-captcha-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body uk-text-center">
|
||||
<h3 class="uk-modal-title">人機認証</h3>
|
||||
<p class="uk-text-meta">以下の計算問題を解いて、ロボットでないことを証明してください</p>
|
||||
<div class="captcha-equation-box">
|
||||
<span id="captcha-modal-question" class="math-captcha-modal-question">読み込み中...</span>
|
||||
<input type="number" id="captcha-modal-answer" placeholder="?" autocomplete="off" inputmode="numeric">
|
||||
</div>
|
||||
<div style="margin-top:6px;">
|
||||
<button type="button" class="uk-button uk-button-text uk-text-small" id="captcha-modal-refresh">別の問題</button>
|
||||
</div>
|
||||
<div id="captcha-modal-error" class="uk-text-danger uk-text-small" style="display:none;min-height:20px;"></div>
|
||||
<div class="uk-margin-small-top">
|
||||
<button type="button" class="uk-button uk-button-primary" id="captcha-modal-submit">送信</button>
|
||||
<button type="button" class="uk-button uk-button-default uk-modal-close">キャンセル</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var CAPTCHA_I18N = {
|
||||
loading: "読み込み中...",
|
||||
loadFailed: "読み込み失敗",
|
||||
loadRetry: "読み込み失敗、再試行してください",
|
||||
inputAnswer: "答えを入力してください",
|
||||
wrongAnswer: "答えが違います。もう一度計算してください",
|
||||
verifyFailed: "認証失敗、再試行してください",
|
||||
needPassword: "この質問箱にはパスワードが必要です",
|
||||
needEmail: "通知を受け取るメールアドレスを入力してください"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var captchaId = '';
|
||||
var pendingForm = null;
|
||||
var pendingNeedPassword = false;
|
||||
var verifying = false;
|
||||
|
||||
function fetchCaptcha() {
|
||||
var qEl = document.getElementById('captcha-modal-question');
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
var ansEl = document.getElementById('captcha-modal-answer');
|
||||
qEl.textContent = CAPTCHA_I18N.loading;
|
||||
fetch('/api/captcha/generate')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.code === 0 && data.data) {
|
||||
captchaId = data.data.id;
|
||||
qEl.textContent = data.data.question;
|
||||
if (errEl) errEl.style.display = 'none';
|
||||
if (ansEl) { ansEl.value = ''; ansEl.focus(); }
|
||||
} else {
|
||||
qEl.textContent = CAPTCHA_I18N.loadFailed;
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
qEl.textContent = CAPTCHA_I18N.loadRetry;
|
||||
});
|
||||
}
|
||||
|
||||
function getCSRFToken() {
|
||||
var input = document.querySelector('input[name="_csrf"]');
|
||||
return input ? input.value : '';
|
||||
}
|
||||
|
||||
function doSubmit(form) {
|
||||
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
var hidden = form.querySelector('[name="g-recaptcha-response"]');
|
||||
if (hidden) hidden.value = captchaId + ':' + (ans || '0');
|
||||
|
||||
UIkit.modal('#math-captcha-modal').hide();
|
||||
|
||||
|
||||
if (pendingNeedPassword) {
|
||||
UIkit.modal.prompt(CAPTCHA_I18N.needPassword, '', 'password')
|
||||
.then(function(password) {
|
||||
if (password) {
|
||||
var pwInput = document.getElementById('ask_password_input');
|
||||
if (pwInput) pwInput.value = password;
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-submit').addEventListener('click', function() {
|
||||
if (verifying) return;
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
if (!ans) {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.inputAnswer;
|
||||
errEl.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
verifying = true;
|
||||
fetch('/api/captcha/verify', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-Token': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify({ id: captchaId, answer: parseInt(ans, 10) })
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
verifying = false;
|
||||
if (data.correct) {
|
||||
if (pendingForm) doSubmit(pendingForm);
|
||||
} else {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.wrongAnswer;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
verifying = false;
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.verifyFailed;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-answer').addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
document.getElementById('captcha-modal-submit').click();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-refresh').addEventListener('click', fetchCaptcha);
|
||||
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target.closest('.math-captcha-trigger');
|
||||
if (!btn) return;
|
||||
e.preventDefault();
|
||||
|
||||
var form = btn.closest('form');
|
||||
if (!form) return;
|
||||
pendingForm = form;
|
||||
|
||||
|
||||
pendingNeedPassword = !!(form.querySelector('#ask_password_input'));
|
||||
|
||||
|
||||
var notifyCb = document.getElementById('notify-checkbox');
|
||||
var emailInput = document.getElementById('email-input');
|
||||
if (notifyCb && notifyCb.checked && emailInput && emailInput.value.trim() === '') {
|
||||
UIkit.modal.alert(CAPTCHA_I18N.needEmail);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchCaptcha();
|
||||
UIkit.modal('#math-captcha-modal').show();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<style>
|
||||
|
||||
.tb-field-head {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 6px 8px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.tb-field-head .tb-field-label {
|
||||
flex-basis: 100%;
|
||||
font-weight: 600;
|
||||
line-height: 1.5;
|
||||
word-break: break-word;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.tb-choice {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
padding: 12px 14px;
|
||||
margin-bottom: 8px;
|
||||
border: 1px solid var(--tb-border);
|
||||
border-radius: 8px;
|
||||
background: var(--tb-surface);
|
||||
cursor: pointer;
|
||||
transition: border-color 0.2s ease, background 0.2s ease;
|
||||
}
|
||||
.tb-choice:last-child { margin-bottom: 0; }
|
||||
.tb-choice input[type="radio"], .tb-choice input[type="checkbox"] {
|
||||
margin-top: 3px;
|
||||
}
|
||||
.tb-choice span {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
line-height: 1.5;
|
||||
word-break: break-word;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.tb-choice:hover {
|
||||
border-color: var(--tb-primary);
|
||||
background: var(--tb-surface-hover);
|
||||
}
|
||||
.tb-choice:has(input:checked) {
|
||||
border-color: var(--tb-primary);
|
||||
background: var(--tb-surface-active);
|
||||
}
|
||||
html[data-theme="dark"] .tb-choice {
|
||||
border-color: var(--tb-border);
|
||||
background: var(--tb-surface);
|
||||
}
|
||||
html[data-theme="dark"] .tb-choice:hover {
|
||||
border-color: var(--tb-primary);
|
||||
background: rgba(78, 168, 245, 0.08);
|
||||
}
|
||||
html[data-theme="dark"] .tb-choice:has(input:checked) {
|
||||
border-color: var(--tb-primary);
|
||||
background: rgba(78, 168, 245, 0.14);
|
||||
}
|
||||
|
||||
.tb-custom-input {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.tb-text-counter {
|
||||
margin-top: 2px;
|
||||
text-align: right;
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.tb-choice { padding: 10px 12px; }
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-body uk-margin-bottom">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 10px;">
|
||||
|
||||
<img class="uk-border-circle" src="https://r2.337845818.best/tamabox/picture/2026/08/19/9af3e38222d972ff9141e9cfdb0475" style="width: 40px; height: 40px;">
|
||||
<div>
|
||||
<a class="uk-text-bold" href="/_admin6">admin6</a>
|
||||
<div class="uk-text-meta uk-text-small">の投票</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-auto-left">
|
||||
|
||||
|
||||
<span class="uk-label uk-label-success">進行中</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="uk-margin-remove-top uk-margin-small-bottom">测试</h3>
|
||||
|
||||
<p class="uk-margin-remove-top">测试</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="uk-alert uk-alert-primary uk-text-small">匿名での参加が可能で、あなたの身元は記録されません(同一端末で最大1回)。</div>
|
||||
|
||||
|
||||
<form method="post" action="/vote/7kcP5kR8YnJC/submit" id="vote-form" onsubmit="return validateVoteForm()">
|
||||
<input type="hidden" name="_csrf" value="WPzW1HpnY6XGRuptOZfgAA-HQgE6MTc5MjM4MzgxODI3Njk5OTE4Ng">
|
||||
<input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response" value="">
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-body uk-margin-bottom">
|
||||
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="tb-field-head">
|
||||
<span class="uk-label">1</span>
|
||||
<span class="uk-label ">一行テキスト</span>
|
||||
<div class="tb-field-label">测试 <span class="uk-text-danger">*</span></div>
|
||||
</div>
|
||||
|
||||
<input class="uk-input" type="text" name="field_21" data-vote-required data-vote-label="测试">
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
|
||||
<button type="button" class="uk-button uk-button-primary math-captcha-trigger" onclick="return voteValidate(event)">投票する</button>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
var MAX_CUSTOM_LEN = 200 ;
|
||||
|
||||
|
||||
|
||||
function countChars(s) { return Array.from(String(s || '')).length; }
|
||||
|
||||
|
||||
function setupTextCounters() {
|
||||
var form = document.getElementById('vote-form');
|
||||
if (!form) { return; }
|
||||
form.querySelectorAll('[data-tb-text-counter]').forEach(function (input) {
|
||||
var max = parseInt(input.getAttribute('data-tb-text-max'), 10);
|
||||
if (!max || max < 1) { max = MAX_CUSTOM_LEN; }
|
||||
var counter = document.createElement('div');
|
||||
counter.className = 'uk-text-meta uk-text-small tb-text-counter';
|
||||
if (input.parentNode) { input.parentNode.insertBefore(counter, input.nextSibling); }
|
||||
var update = function () {
|
||||
var n = countChars(input.value);
|
||||
counter.textContent = n + ' / ' + max;
|
||||
if (n > max) {
|
||||
counter.classList.add('uk-text-danger');
|
||||
input.setAttribute('data-tb-too-long', '1');
|
||||
} else {
|
||||
counter.classList.remove('uk-text-danger');
|
||||
input.removeAttribute('data-tb-too-long');
|
||||
}
|
||||
};
|
||||
input.addEventListener('input', update);
|
||||
update();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
function validateVoteForm() {
|
||||
var form = document.getElementById('vote-form');
|
||||
if (!form) { return true; }
|
||||
|
||||
var tooLong = form.querySelector('[data-tb-text-counter][data-tb-too-long]');
|
||||
if (tooLong) {
|
||||
alert('自由記入オプションは 200 字以内にしてください');
|
||||
tooLong.focus();
|
||||
return false;
|
||||
}
|
||||
|
||||
var groups = {};
|
||||
form.querySelectorAll('input[data-vote-required][type="radio"], input[data-vote-required][type="checkbox"]').forEach(function (el) {
|
||||
(groups[el.name] = groups[el.name] || []).push(el);
|
||||
});
|
||||
for (var name in groups) {
|
||||
var any = groups[name].some(function (el) { return el.checked; });
|
||||
if (!any) {
|
||||
alert('入力してください「' + groups[name][0].getAttribute('data-vote-label') + '」');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var els = form.querySelectorAll('[data-vote-required]:not(input[type="radio"]):not(input[type="checkbox"])');
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
var el = els[i];
|
||||
if (el.disabled) { continue; }
|
||||
if ((el.value || '').trim() === '') {
|
||||
alert('入力してください「' + el.getAttribute('data-vote-label') + '」');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function voteValidate(e) {
|
||||
if (!validateVoteForm()) {
|
||||
if (e) { e.stopPropagation(); e.preventDefault(); }
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
if (validateVoteForm()) {
|
||||
document.getElementById('vote-form').submit();
|
||||
}
|
||||
}
|
||||
|
||||
(function () {
|
||||
var form = document.getElementById('vote-form');
|
||||
if (!form) { return; }
|
||||
setupTextCounters();
|
||||
var maxChoices = 0;
|
||||
if (maxChoices > 0) {
|
||||
var boxes = form.querySelectorAll('input[type="checkbox"][name="option_ids"]');
|
||||
boxes.forEach(function (box) {
|
||||
box.addEventListener('change', function () {
|
||||
var checked = form.querySelectorAll('input[type="checkbox"][name="option_ids"]:checked').length;
|
||||
if (checked > maxChoices) { this.checked = false; }
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var CUSTOM_MARKER = "__tb_custom_option__";
|
||||
form.querySelectorAll('[data-vote-custom-input]').forEach(function (input) {
|
||||
var fid = input.getAttribute('data-vote-custom-input');
|
||||
var group = form.querySelectorAll('input[name="field_' + fid + '"]');
|
||||
var select = form.querySelector('select[name="field_' + fid + '"]');
|
||||
var sync = function () {
|
||||
var on = false;
|
||||
if (select) {
|
||||
on = (select.value === CUSTOM_MARKER);
|
||||
} else {
|
||||
group.forEach(function (r) { if (r.value === CUSTOM_MARKER && r.checked) { on = true; } });
|
||||
}
|
||||
input.disabled = !on;
|
||||
if (!on) { input.value = ''; }
|
||||
};
|
||||
if (select) { select.addEventListener('change', sync); } else { group.forEach(function (r) { r.addEventListener('change', sync); }); }
|
||||
sync();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<p class=" uk-text-right uk-text-muted uk-text-small">
|
||||
<br>
|
||||
<a href="/rules">ルール</a> |
|
||||
|
||||
<a href="https://box.shiroko.one/_/tamakyi" target="_blank">管理者へ</a>
|
||||
<br>
|
||||
<a href="https://share.shiroko.one" target="_blank">ドライブ</a>
|
||||
| <a href="https://blog.shiroko.one" target="_blank">お知らせ</a>
|
||||
| <a href="https://chat.shiroko.one" target="_blank">チャット</a>
|
||||
| <a href="https://status.shiroko.one" target="_blank">ステータス</a>
|
||||
| <a href="https://shiroko.one" target="_blank">リンク</a>
|
||||
<br>Powered by NekoBox | 狼ICP备 20230101
|
||||
<br>質問箱は稼働中:<span id="box_runtime"></span>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
(function () {
|
||||
var create = Math.round(Date.UTC(2023, 6, 1, 18, 15, 43) / 1000);
|
||||
function tick() {
|
||||
var el = document.getElementById("box_runtime");
|
||||
if (!el) return;
|
||||
var s = Math.round((Date.now() + 8 * 3600 * 1000) / 1000) - create;
|
||||
var t = [0, 0, 0, 0, 0];
|
||||
if (s >= 31536000) { t[0] = s / 31536000 | 0; s %= 31536000; }
|
||||
if (s >= 86400) { t[1] = s / 86400 | 0; s %= 86400; }
|
||||
if (s >= 3600) { t[2] = s / 3600 | 0; s %= 3600; }
|
||||
if (s >= 60) { t[3] = s / 60 | 0; s %= 60; }
|
||||
if (s > 0) { t[4] = s; }
|
||||
el.innerHTML = t[0] + '年 ' + t[1] + '天 ' + t[2] + '时 ' + t[3] + '分 ' + t[4] + '秒 ';
|
||||
}
|
||||
tick();
|
||||
setInterval(tick, 1000);
|
||||
})();
|
||||
</script>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
var SUBMIT_I18N = {
|
||||
submitting: '送信中...',
|
||||
uploading: 'アップロード中...'
|
||||
};
|
||||
|
||||
function tbResetSubmitButtons() {
|
||||
document.querySelectorAll('button[data-tb-submitting]').forEach(function(b) {
|
||||
b.disabled = false;
|
||||
b.removeAttribute('data-tb-submitting');
|
||||
var orig = b.getAttribute('data-tb-restore');
|
||||
if (orig !== null) {
|
||||
b.innerHTML = orig;
|
||||
b.removeAttribute('data-tb-restore');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('submit', function(e) {
|
||||
var form = e.target;
|
||||
if (!form || form.tagName !== 'FORM') return;
|
||||
|
||||
|
||||
|
||||
if (e.defaultPrevented || form.getAttribute('data-tb-skip-submit-feedback') === '1') {
|
||||
form.removeAttribute('data-tb-skip-submit-feedback');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (form.getAttribute('target') === '_blank') return;
|
||||
|
||||
|
||||
var trigger = e.submitter || form.querySelector('button[type="submit"]');
|
||||
|
||||
|
||||
var hasFile = false;
|
||||
form.querySelectorAll('input[type="file"]').forEach(function(f) {
|
||||
if (f.files && f.files.length > 0) hasFile = true;
|
||||
});
|
||||
var label = hasFile ? SUBMIT_I18N.uploading : SUBMIT_I18N.submitting;
|
||||
|
||||
if (trigger && trigger.tagName === 'BUTTON') {
|
||||
trigger.setAttribute('data-tb-restore', trigger.innerHTML);
|
||||
trigger.innerHTML = '<span uk-spinner="ratio: 0.6"></span> ' + label;
|
||||
}
|
||||
|
||||
|
||||
form.querySelectorAll('button').forEach(function(b) {
|
||||
b.disabled = true;
|
||||
b.setAttribute('data-tb-submitting', '1');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener('pageshow', tbResetSubmitButtons);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,758 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>投票结果</title>
|
||||
<meta name="msvalidate.01" content="2F185E8E63C93635F50B3574F3B31E42" />
|
||||
<meta name="description" content="狼的提问箱——一个无需注册、可匿名提问的匿名提问箱,安全地倾诉与回应。">
|
||||
<meta name="keywords" content="匿名提问箱,提问箱,匿名提问,狼的提问箱,匿名问答,匿名提问网站">
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
if (m && m[1] === 'dark') document.documentElement.setAttribute('data-theme', 'dark');
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://r2.337845818.best" crossorigin>
|
||||
<link rel="preconnect" href="https://cdnjs.snrat.com" crossorigin>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/css/uikit.min.css"/>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/base.css?v=20261019c"/>
|
||||
|
||||
<link rel="stylesheet" href="https://r2.337845818.best/tamabox/cdn/waline/client/v2/waline-no-commits.css" media="print" onload="this.media='all'"/>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit-icons.min.js"></script>
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/dayjs/1.10.8/dayjs.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/alpinejs/3.9.0/cdn.min.js"></script>
|
||||
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/waline/2.15.8/waline.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.captcha-equation-box {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: #f0f2f5;
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 8px;
|
||||
padding: 8px 8px 8px 16px;
|
||||
gap: 6px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
.captcha-equation-box:focus-within {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 3px rgba(30,135,240,0.12);
|
||||
}
|
||||
.math-captcha-modal-question {
|
||||
font-size: 1.4rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
letter-spacing: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
width: 80px;
|
||||
padding: 6px 10px;
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 600;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
transition: border-color 0.15s, box-shadow 0.15s;
|
||||
background: #fff;
|
||||
}
|
||||
#captcha-modal-answer:focus {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 2px rgba(30,135,240,0.2);
|
||||
}
|
||||
|
||||
#captcha-modal-answer::-webkit-inner-spin-button,
|
||||
#captcha-modal-answer::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta property="og:site_name" content="狼的提问箱 | 匿名提问箱" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content=" - 狼的提问箱 | 匿名提问箱" />
|
||||
<meta property="og:url" content="https://box-dev-api.337845818.best/user/votes/12/results" />
|
||||
<meta property="og:description" content=" - 狼的提问箱——一个无需注册、可匿名提问的匿名提问箱,安全地倾诉与回应。" />
|
||||
<meta name="robots" content="noindex">
|
||||
|
||||
<meta property="og:image" content="?og-image=1" />
|
||||
<meta property="og:image:alt" content="" />
|
||||
<meta itemprop="image" content="?og-image=1"/>
|
||||
<meta name="msapplication-TileImage" content=""/>
|
||||
<link rel="shortcut icon" href="?og-image=1"/>
|
||||
<link rel="apple-touch-icon" href="?og-image=1"/>
|
||||
<link rel="icon" sizes="192x192" href="?og-image=1">
|
||||
<meta name="twitter:image:src" content="?og-image=1" />
|
||||
|
||||
|
||||
|
||||
<meta name="google-site-verification" content="fEPwRRJfiGsgwc5SINBQwZhPK8F0cwRaOvRx0YRurI4" />
|
||||
|
||||
<script>
|
||||
window.addEventListener("load", function () {
|
||||
var s = document.createElement("script");
|
||||
s.src = "https://mami.shiroko.one/tamami.js";
|
||||
s.setAttribute("data-website-id", "c42ebe8b-9281-4da0-83a4-8f18b3e710fe");
|
||||
document.body.appendChild(s);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window.tbRenderQR = function (el, getOptions) {
|
||||
if (!el || typeof QRCode === 'undefined') return;
|
||||
var opts = getOptions();
|
||||
function remoteOf(o, key) {
|
||||
var v = o[key];
|
||||
return (typeof v === 'string' && v.indexOf('http') === 0) ? v : '';
|
||||
}
|
||||
var good = window._tbQrGood || (window._tbQrGood = {});
|
||||
var bad = window._tbQrBad || (window._tbQrBad = {});
|
||||
|
||||
function layerState(url) { return !url ? '' : (good[url] ? 1 : (bad[url] ? 0 : null)); }
|
||||
var layers = [
|
||||
{ url: remoteOf(opts, 'logo'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.logo = undefined; o.logoWidth = undefined; o.logoHeight = undefined; o.logoBackgroundTransparent = undefined; }
|
||||
} },
|
||||
{ url: remoteOf(opts, 'backgroundImage'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.backgroundImage = undefined; o.backgroundImageAlpha = undefined; }
|
||||
} }
|
||||
];
|
||||
var needProbe = false;
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
layers[i].st = layerState(layers[i].url);
|
||||
if (layers[i].st === null) needProbe = true;
|
||||
}
|
||||
function paint(states) {
|
||||
var o = {};
|
||||
for (var k in opts) o[k] = opts[k];
|
||||
for (var j = 0; j < layers.length; j++) layers[j].present(o, states[j] === 1);
|
||||
el.innerHTML = '';
|
||||
new QRCode(el, o);
|
||||
}
|
||||
|
||||
var initStates = [];
|
||||
for (var n = 0; n < layers.length; n++) initStates.push(layers[n].st === 1 ? 1 : 0);
|
||||
paint(initStates);
|
||||
if (!needProbe) return;
|
||||
|
||||
var pending = 0, cross = opts.crossOrigin || 'anonymous';
|
||||
layers.forEach(function (L) {
|
||||
if (L.st !== null) return;
|
||||
pending++;
|
||||
var im = new Image();
|
||||
im.onload = function () { good[L.url] = true; L.st = 1; onDone(); };
|
||||
im.onerror = function () { bad[L.url] = true; L.st = 0; onDone(); };
|
||||
if (cross) im.crossOrigin = cross;
|
||||
im.src = L.url;
|
||||
});
|
||||
function onDone() {
|
||||
if (--pending > 0) return;
|
||||
var finalStates = [];
|
||||
for (var m = 0; m < layers.length; m++) finalStates.push(layers[m].st === 1 ? 1 : 0);
|
||||
var changed = false;
|
||||
for (var q = 0; q < finalStates.length; q++) if (finalStates[q] !== initStates[q]) changed = true;
|
||||
if (changed) paint(finalStates);
|
||||
}
|
||||
|
||||
setTimeout(function () { if (pending > 0) { pending = 0; onDone(); } }, 3000);
|
||||
};
|
||||
</script>
|
||||
<nav class="uk-navbar-container uk-margin tb-navbar" uk-navbar>
|
||||
<div class="uk-navbar-center">
|
||||
<div class="uk-navbar-center-left">
|
||||
<div>
|
||||
<ul class="uk-navbar-nav">
|
||||
|
||||
<li><a href="/explore">探索</a></li>
|
||||
|
||||
|
||||
<li><a href="/_/admin6">我的</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="uk-navbar-item uk-logo" href="/"><span class="emoji-placeholder" aria-label="random animal">🐺</span>的提问箱</a>
|
||||
|
||||
<div class="uk-navbar-center-right">
|
||||
<div>
|
||||
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/user/questions">提问</a></li>
|
||||
</ul>
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/user/profile">设置</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" id="theme-toggle" title="切换深色/浅色模式" aria-label="切换深色/浅色模式">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const emojis = ["🐺","🐗","🐻","🐨","🐼","🐹","🐭","🐰","🦊","🐮","🐷","🐽","🐸","🐒","🦍","🐔","🐧","🐦","🐤","🐦⬛","🦅","🦉","🦇","🐴","🦄","🐝","🦎","🦖","🦕","🐙","🦑","🦐","🦞","🦀","🐡","🐠","🐟","🐬","🐳","🐋","🦈","🐊","🐅","🐆","🦓","🦍","🦧","🐘","🦛","🦏","🐪","🐫","🦒","🦘","🐃","🐂","🐄","🐎","🐖","🐏","🐑","🦙","🐐","🦌","🐕","🐩","🦮","🐕🦺","🐈","🐋","🐳","🐬","🐉","🐲"];
|
||||
const placeholder = document.querySelector('.emoji-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.textContent = emojis[Math.floor(Math.random() * emojis.length)];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="tb-mobile-utils">
|
||||
|
||||
<button type="button" id="theme-toggle-mobile" class="uk-button uk-button-default uk-button-small"
|
||||
title="切换深色/浅色模式" aria-label="切换深色/浅色模式">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
var THEME_COOKIE = 'theme';
|
||||
function getTheme() {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
return m ? m[1] : '';
|
||||
}
|
||||
function applyTheme(theme) {
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
}
|
||||
}
|
||||
function toggleTheme() {
|
||||
var next = getTheme() === 'dark' ? 'light' : 'dark';
|
||||
applyTheme(next);
|
||||
var expires = new Date(Date.now() + 365 * 24 * 3600 * 1000).toUTCString();
|
||||
document.cookie = THEME_COOKIE + '=' + next + '; path=/; max-age=' + (365 * 24 * 3600) + '; SameSite=Lax';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
var buttons = document.querySelectorAll('#theme-toggle, #theme-toggle-mobile');
|
||||
buttons.forEach(function(btn) {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
toggleTheme();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var langSel = document.getElementById('mobile-lang-select');
|
||||
if (langSel) {
|
||||
langSel.addEventListener('change', function() {
|
||||
if (!this.value) return;
|
||||
var to = window.location.pathname + window.location.search;
|
||||
window.location.href = '/i18n/' + encodeURIComponent(this.value) + '?to=' + encodeURIComponent(to);
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-container uk-container-xsmall">
|
||||
|
||||
|
||||
|
||||
<div id="math-captcha-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body uk-text-center">
|
||||
<h3 class="uk-modal-title">人机验证</h3>
|
||||
<p class="uk-text-meta">请计算下方的算术题以验证你不是机器人</p>
|
||||
<div class="captcha-equation-box">
|
||||
<span id="captcha-modal-question" class="math-captcha-modal-question">加载中...</span>
|
||||
<input type="number" id="captcha-modal-answer" placeholder="?" autocomplete="off" inputmode="numeric">
|
||||
</div>
|
||||
<div style="margin-top:6px;">
|
||||
<button type="button" class="uk-button uk-button-text uk-text-small" id="captcha-modal-refresh">换一题</button>
|
||||
</div>
|
||||
<div id="captcha-modal-error" class="uk-text-danger uk-text-small" style="display:none;min-height:20px;"></div>
|
||||
<div class="uk-margin-small-top">
|
||||
<button type="button" class="uk-button uk-button-primary" id="captcha-modal-submit">提交</button>
|
||||
<button type="button" class="uk-button uk-button-default uk-modal-close">取消</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var CAPTCHA_I18N = {
|
||||
loading: "加载中...",
|
||||
loadFailed: "加载失败",
|
||||
loadRetry: "加载失败,请重试",
|
||||
inputAnswer: "请输入答案",
|
||||
wrongAnswer: "答案错误,请重新计算",
|
||||
verifyFailed: "验证失败,请重试",
|
||||
needPassword: "此提问箱需要密码",
|
||||
needEmail: "请填写接收通知的邮箱地址"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var captchaId = '';
|
||||
var pendingForm = null;
|
||||
var pendingNeedPassword = false;
|
||||
var verifying = false;
|
||||
|
||||
function fetchCaptcha() {
|
||||
var qEl = document.getElementById('captcha-modal-question');
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
var ansEl = document.getElementById('captcha-modal-answer');
|
||||
qEl.textContent = CAPTCHA_I18N.loading;
|
||||
fetch('/api/captcha/generate')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.code === 0 && data.data) {
|
||||
captchaId = data.data.id;
|
||||
qEl.textContent = data.data.question;
|
||||
if (errEl) errEl.style.display = 'none';
|
||||
if (ansEl) { ansEl.value = ''; ansEl.focus(); }
|
||||
} else {
|
||||
qEl.textContent = CAPTCHA_I18N.loadFailed;
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
qEl.textContent = CAPTCHA_I18N.loadRetry;
|
||||
});
|
||||
}
|
||||
|
||||
function getCSRFToken() {
|
||||
var input = document.querySelector('input[name="_csrf"]');
|
||||
return input ? input.value : '';
|
||||
}
|
||||
|
||||
function doSubmit(form) {
|
||||
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
var hidden = form.querySelector('[name="g-recaptcha-response"]');
|
||||
if (hidden) hidden.value = captchaId + ':' + (ans || '0');
|
||||
|
||||
UIkit.modal('#math-captcha-modal').hide();
|
||||
|
||||
|
||||
if (pendingNeedPassword) {
|
||||
UIkit.modal.prompt(CAPTCHA_I18N.needPassword, '', 'password')
|
||||
.then(function(password) {
|
||||
if (password) {
|
||||
var pwInput = document.getElementById('ask_password_input');
|
||||
if (pwInput) pwInput.value = password;
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-submit').addEventListener('click', function() {
|
||||
if (verifying) return;
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
if (!ans) {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.inputAnswer;
|
||||
errEl.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
verifying = true;
|
||||
fetch('/api/captcha/verify', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-Token': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify({ id: captchaId, answer: parseInt(ans, 10) })
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
verifying = false;
|
||||
if (data.correct) {
|
||||
if (pendingForm) doSubmit(pendingForm);
|
||||
} else {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.wrongAnswer;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
verifying = false;
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.verifyFailed;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-answer').addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
document.getElementById('captcha-modal-submit').click();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-refresh').addEventListener('click', fetchCaptcha);
|
||||
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target.closest('.math-captcha-trigger');
|
||||
if (!btn) return;
|
||||
e.preventDefault();
|
||||
|
||||
var form = btn.closest('form');
|
||||
if (!form) return;
|
||||
pendingForm = form;
|
||||
|
||||
|
||||
pendingNeedPassword = !!(form.querySelector('#ask_password_input'));
|
||||
|
||||
|
||||
var notifyCb = document.getElementById('notify-checkbox');
|
||||
var emailInput = document.getElementById('email-input');
|
||||
if (notifyCb && notifyCb.checked && emailInput && emailInput.value.trim() === '') {
|
||||
UIkit.modal.alert(CAPTCHA_I18N.needEmail);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchCaptcha();
|
||||
UIkit.modal('#math-captcha-modal').show();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-flex-middle uk-margin-bottom">
|
||||
<h3 class="uk-margin-remove">投票结果:测试功能</h3>
|
||||
<div class="uk-flex uk-flex-middle" style="gap: 8px;">
|
||||
<a class="uk-button uk-button-default uk-button-small" href="/user/votes/12/export">导出 CSV</a>
|
||||
<a class="uk-button uk-button-default uk-button-small" href="/user/questions#votes">返回</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-small uk-card-body uk-margin-bottom">
|
||||
<div class="uk-text-large uk-text-bold">3</div>
|
||||
<div class="uk-text-meta">总参与人数</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<h4>投票结果</h4>
|
||||
<div class="uk-card uk-card-default uk-card-small uk-card-body uk-margin-bottom">
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 8px;">
|
||||
<span class="uk-label">1</span>
|
||||
<span class="uk-label uk-label-primary">单选</span>
|
||||
<span class="uk-text-bold">必填</span>
|
||||
<span class="uk-text-meta uk-text-small">回答数: 3</span>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>A</span>
|
||||
<span class="uk-text-meta">3 票(100%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="100" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>B</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>C</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 8px;">
|
||||
<span class="uk-label">2</span>
|
||||
<span class="uk-label uk-label-success">多选</span>
|
||||
<span class="uk-text-bold">非必填</span>
|
||||
<span class="uk-text-meta uk-text-small">回答数: 1</span>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>A</span>
|
||||
<span class="uk-text-meta">1 票(100%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="100" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>B</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>C</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>D</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 8px;">
|
||||
<span class="uk-label">3</span>
|
||||
<span class="uk-label ">单行文本</span>
|
||||
<span class="uk-text-bold">文本1</span>
|
||||
<span class="uk-text-meta uk-text-small">回答数: 0</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="uk-text-meta uk-margin-small-top">已填写: 0</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 8px;">
|
||||
<span class="uk-label">4</span>
|
||||
<span class="uk-label ">多行文本</span>
|
||||
<span class="uk-text-bold">文本2</span>
|
||||
<span class="uk-text-meta uk-text-small">回答数: 3</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="uk-text-meta uk-margin-small-top">已填写: 3</div>
|
||||
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-text-small" style="cursor:pointer; user-select:none; color:#1e87f0;" onclick="toggleFieldReplies('40')" title="点击展开或收起文本回复明细">
|
||||
<span id="caret-40" style="display:inline-block; transition:transform .15s; transform:rotate(-90deg);">▾</span>
|
||||
查看文本提交(3)
|
||||
</div>
|
||||
<div id="replies-40" hidden>
|
||||
<ul class="uk-list uk-list-divider uk-margin-small-top">
|
||||
|
||||
<li>
|
||||
<div class="uk-text-meta uk-text-small">2026-08-26 01:06</div>
|
||||
<div style="white-space:pre-wrap;">ddd</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div class="uk-text-meta uk-text-small">2026-08-26 00:57</div>
|
||||
<div style="white-space:pre-wrap;">cc</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div class="uk-text-meta uk-text-small">2026-08-25 19:05</div>
|
||||
<div style="white-space:pre-wrap;">1212</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
function toggleFieldReplies(id) {
|
||||
var box = document.getElementById('replies-' + id);
|
||||
var caret = document.getElementById('caret-' + id);
|
||||
if (!box) { return; }
|
||||
if (box.hasAttribute('hidden')) {
|
||||
box.removeAttribute('hidden');
|
||||
if (caret) { caret.style.transform = 'rotate(0deg)'; }
|
||||
} else {
|
||||
box.setAttribute('hidden', '');
|
||||
if (caret) { caret.style.transform = 'rotate(-90deg)'; }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<p class=" uk-text-right uk-text-muted uk-text-small">
|
||||
<br>
|
||||
<a href="/rules">社区规则</a> |
|
||||
|
||||
<a href="https://box.shiroko.one/_/tamakyi" target="_blank">找站长</a>
|
||||
<br>
|
||||
<a href="https://share.shiroko.one" target="_blank">盘</a>
|
||||
| <a href="https://blog.shiroko.one" target="_blank">公告板</a>
|
||||
| <a href="https://chat.shiroko.one" target="_blank">聊天室</a>
|
||||
| <a href="https://status.shiroko.one" target="_blank">监控板</a>
|
||||
| <a href="https://shiroko.one" target="_blank">导航页</a>
|
||||
<br>Powered by NekoBox | 狼ICP备 20230101
|
||||
<br>提问箱已成功存活:<span id="box_runtime"></span>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
(function () {
|
||||
var create = Math.round(Date.UTC(2023, 6, 1, 18, 15, 43) / 1000);
|
||||
function tick() {
|
||||
var el = document.getElementById("box_runtime");
|
||||
if (!el) return;
|
||||
var s = Math.round((Date.now() + 8 * 3600 * 1000) / 1000) - create;
|
||||
var t = [0, 0, 0, 0, 0];
|
||||
if (s >= 31536000) { t[0] = s / 31536000 | 0; s %= 31536000; }
|
||||
if (s >= 86400) { t[1] = s / 86400 | 0; s %= 86400; }
|
||||
if (s >= 3600) { t[2] = s / 3600 | 0; s %= 3600; }
|
||||
if (s >= 60) { t[3] = s / 60 | 0; s %= 60; }
|
||||
if (s > 0) { t[4] = s; }
|
||||
el.innerHTML = t[0] + '年 ' + t[1] + '天 ' + t[2] + '时 ' + t[3] + '分 ' + t[4] + '秒 ';
|
||||
}
|
||||
tick();
|
||||
setInterval(tick, 1000);
|
||||
})();
|
||||
</script>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
var SUBMIT_I18N = {
|
||||
submitting: '提交中...',
|
||||
uploading: '上传中...'
|
||||
};
|
||||
|
||||
function tbResetSubmitButtons() {
|
||||
document.querySelectorAll('button[data-tb-submitting]').forEach(function(b) {
|
||||
b.disabled = false;
|
||||
b.removeAttribute('data-tb-submitting');
|
||||
var orig = b.getAttribute('data-tb-restore');
|
||||
if (orig !== null) {
|
||||
b.innerHTML = orig;
|
||||
b.removeAttribute('data-tb-restore');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('submit', function(e) {
|
||||
var form = e.target;
|
||||
if (!form || form.tagName !== 'FORM') return;
|
||||
|
||||
|
||||
|
||||
if (e.defaultPrevented || form.getAttribute('data-tb-skip-submit-feedback') === '1') {
|
||||
form.removeAttribute('data-tb-skip-submit-feedback');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (form.getAttribute('target') === '_blank') return;
|
||||
|
||||
|
||||
var trigger = e.submitter || form.querySelector('button[type="submit"]');
|
||||
|
||||
|
||||
var hasFile = false;
|
||||
form.querySelectorAll('input[type="file"]').forEach(function(f) {
|
||||
if (f.files && f.files.length > 0) hasFile = true;
|
||||
});
|
||||
var label = hasFile ? SUBMIT_I18N.uploading : SUBMIT_I18N.submitting;
|
||||
|
||||
if (trigger && trigger.tagName === 'BUTTON') {
|
||||
trigger.setAttribute('data-tb-restore', trigger.innerHTML);
|
||||
trigger.innerHTML = '<span uk-spinner="ratio: 0.6"></span> ' + label;
|
||||
}
|
||||
|
||||
|
||||
form.querySelectorAll('button').forEach(function(b) {
|
||||
b.disabled = true;
|
||||
b.setAttribute('data-tb-submitting', '1');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener('pageshow', tbResetSubmitButtons);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,626 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>投票结果</title>
|
||||
<meta name="msvalidate.01" content="2F185E8E63C93635F50B3574F3B31E42" />
|
||||
<meta name="description" content="狼的提问箱——一个无需注册、可匿名提问的匿名提问箱,安全地倾诉与回应。">
|
||||
<meta name="keywords" content="匿名提问箱,提问箱,匿名提问,狼的提问箱,匿名问答,匿名提问网站">
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
if (m && m[1] === 'dark') document.documentElement.setAttribute('data-theme', 'dark');
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://r2.337845818.best" crossorigin>
|
||||
<link rel="preconnect" href="https://cdnjs.snrat.com" crossorigin>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/css/uikit.min.css"/>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/base.css?v=20261019c"/>
|
||||
|
||||
<link rel="stylesheet" href="https://r2.337845818.best/tamabox/cdn/waline/client/v2/waline-no-commits.css" media="print" onload="this.media='all'"/>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit-icons.min.js"></script>
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/dayjs/1.10.8/dayjs.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/alpinejs/3.9.0/cdn.min.js"></script>
|
||||
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/waline/2.15.8/waline.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.captcha-equation-box {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: #f0f2f5;
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 8px;
|
||||
padding: 8px 8px 8px 16px;
|
||||
gap: 6px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
.captcha-equation-box:focus-within {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 3px rgba(30,135,240,0.12);
|
||||
}
|
||||
.math-captcha-modal-question {
|
||||
font-size: 1.4rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
letter-spacing: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
width: 80px;
|
||||
padding: 6px 10px;
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 600;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
transition: border-color 0.15s, box-shadow 0.15s;
|
||||
background: #fff;
|
||||
}
|
||||
#captcha-modal-answer:focus {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 2px rgba(30,135,240,0.2);
|
||||
}
|
||||
|
||||
#captcha-modal-answer::-webkit-inner-spin-button,
|
||||
#captcha-modal-answer::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta property="og:site_name" content="狼的提问箱 | 匿名提问箱" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content=" - 狼的提问箱 | 匿名提问箱" />
|
||||
<meta property="og:url" content="https://box-dev-api.337845818.best/user/votes/13/results" />
|
||||
<meta property="og:description" content=" - 狼的提问箱——一个无需注册、可匿名提问的匿名提问箱,安全地倾诉与回应。" />
|
||||
<meta name="robots" content="noindex">
|
||||
|
||||
<meta property="og:image" content="?og-image=1" />
|
||||
<meta property="og:image:alt" content="" />
|
||||
<meta itemprop="image" content="?og-image=1"/>
|
||||
<meta name="msapplication-TileImage" content=""/>
|
||||
<link rel="shortcut icon" href="?og-image=1"/>
|
||||
<link rel="apple-touch-icon" href="?og-image=1"/>
|
||||
<link rel="icon" sizes="192x192" href="?og-image=1">
|
||||
<meta name="twitter:image:src" content="?og-image=1" />
|
||||
|
||||
|
||||
|
||||
<meta name="google-site-verification" content="fEPwRRJfiGsgwc5SINBQwZhPK8F0cwRaOvRx0YRurI4" />
|
||||
|
||||
<script>
|
||||
window.addEventListener("load", function () {
|
||||
var s = document.createElement("script");
|
||||
s.src = "https://mami.shiroko.one/tamami.js";
|
||||
s.setAttribute("data-website-id", "c42ebe8b-9281-4da0-83a4-8f18b3e710fe");
|
||||
document.body.appendChild(s);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window.tbRenderQR = function (el, getOptions) {
|
||||
if (!el || typeof QRCode === 'undefined') return;
|
||||
var opts = getOptions();
|
||||
function remoteOf(o, key) {
|
||||
var v = o[key];
|
||||
return (typeof v === 'string' && v.indexOf('http') === 0) ? v : '';
|
||||
}
|
||||
var good = window._tbQrGood || (window._tbQrGood = {});
|
||||
var bad = window._tbQrBad || (window._tbQrBad = {});
|
||||
|
||||
function layerState(url) { return !url ? '' : (good[url] ? 1 : (bad[url] ? 0 : null)); }
|
||||
var layers = [
|
||||
{ url: remoteOf(opts, 'logo'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.logo = undefined; o.logoWidth = undefined; o.logoHeight = undefined; o.logoBackgroundTransparent = undefined; }
|
||||
} },
|
||||
{ url: remoteOf(opts, 'backgroundImage'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.backgroundImage = undefined; o.backgroundImageAlpha = undefined; }
|
||||
} }
|
||||
];
|
||||
var needProbe = false;
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
layers[i].st = layerState(layers[i].url);
|
||||
if (layers[i].st === null) needProbe = true;
|
||||
}
|
||||
function paint(states) {
|
||||
var o = {};
|
||||
for (var k in opts) o[k] = opts[k];
|
||||
for (var j = 0; j < layers.length; j++) layers[j].present(o, states[j] === 1);
|
||||
el.innerHTML = '';
|
||||
new QRCode(el, o);
|
||||
}
|
||||
|
||||
var initStates = [];
|
||||
for (var n = 0; n < layers.length; n++) initStates.push(layers[n].st === 1 ? 1 : 0);
|
||||
paint(initStates);
|
||||
if (!needProbe) return;
|
||||
|
||||
var pending = 0, cross = opts.crossOrigin || 'anonymous';
|
||||
layers.forEach(function (L) {
|
||||
if (L.st !== null) return;
|
||||
pending++;
|
||||
var im = new Image();
|
||||
im.onload = function () { good[L.url] = true; L.st = 1; onDone(); };
|
||||
im.onerror = function () { bad[L.url] = true; L.st = 0; onDone(); };
|
||||
if (cross) im.crossOrigin = cross;
|
||||
im.src = L.url;
|
||||
});
|
||||
function onDone() {
|
||||
if (--pending > 0) return;
|
||||
var finalStates = [];
|
||||
for (var m = 0; m < layers.length; m++) finalStates.push(layers[m].st === 1 ? 1 : 0);
|
||||
var changed = false;
|
||||
for (var q = 0; q < finalStates.length; q++) if (finalStates[q] !== initStates[q]) changed = true;
|
||||
if (changed) paint(finalStates);
|
||||
}
|
||||
|
||||
setTimeout(function () { if (pending > 0) { pending = 0; onDone(); } }, 3000);
|
||||
};
|
||||
</script>
|
||||
<nav class="uk-navbar-container uk-margin tb-navbar" uk-navbar>
|
||||
<div class="uk-navbar-center">
|
||||
<div class="uk-navbar-center-left">
|
||||
<div>
|
||||
<ul class="uk-navbar-nav">
|
||||
|
||||
<li><a href="/explore">探索</a></li>
|
||||
|
||||
|
||||
<li><a href="/_/admin6">我的</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="uk-navbar-item uk-logo" href="/"><span class="emoji-placeholder" aria-label="random animal">🐺</span>的提问箱</a>
|
||||
|
||||
<div class="uk-navbar-center-right">
|
||||
<div>
|
||||
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/user/questions">提问</a></li>
|
||||
</ul>
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/user/profile">设置</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" id="theme-toggle" title="切换深色/浅色模式" aria-label="切换深色/浅色模式">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const emojis = ["🐺","🐗","🐻","🐨","🐼","🐹","🐭","🐰","🦊","🐮","🐷","🐽","🐸","🐒","🦍","🐔","🐧","🐦","🐤","🐦⬛","🦅","🦉","🦇","🐴","🦄","🐝","🦎","🦖","🦕","🐙","🦑","🦐","🦞","🦀","🐡","🐠","🐟","🐬","🐳","🐋","🦈","🐊","🐅","🐆","🦓","🦍","🦧","🐘","🦛","🦏","🐪","🐫","🦒","🦘","🐃","🐂","🐄","🐎","🐖","🐏","🐑","🦙","🐐","🦌","🐕","🐩","🦮","🐕🦺","🐈","🐋","🐳","🐬","🐉","🐲"];
|
||||
const placeholder = document.querySelector('.emoji-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.textContent = emojis[Math.floor(Math.random() * emojis.length)];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="tb-mobile-utils">
|
||||
|
||||
<button type="button" id="theme-toggle-mobile" class="uk-button uk-button-default uk-button-small"
|
||||
title="切换深色/浅色模式" aria-label="切换深色/浅色模式">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
var THEME_COOKIE = 'theme';
|
||||
function getTheme() {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
return m ? m[1] : '';
|
||||
}
|
||||
function applyTheme(theme) {
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
}
|
||||
}
|
||||
function toggleTheme() {
|
||||
var next = getTheme() === 'dark' ? 'light' : 'dark';
|
||||
applyTheme(next);
|
||||
var expires = new Date(Date.now() + 365 * 24 * 3600 * 1000).toUTCString();
|
||||
document.cookie = THEME_COOKIE + '=' + next + '; path=/; max-age=' + (365 * 24 * 3600) + '; SameSite=Lax';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
var buttons = document.querySelectorAll('#theme-toggle, #theme-toggle-mobile');
|
||||
buttons.forEach(function(btn) {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
toggleTheme();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var langSel = document.getElementById('mobile-lang-select');
|
||||
if (langSel) {
|
||||
langSel.addEventListener('change', function() {
|
||||
if (!this.value) return;
|
||||
var to = window.location.pathname + window.location.search;
|
||||
window.location.href = '/i18n/' + encodeURIComponent(this.value) + '?to=' + encodeURIComponent(to);
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-container uk-container-xsmall">
|
||||
|
||||
|
||||
|
||||
<div id="math-captcha-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body uk-text-center">
|
||||
<h3 class="uk-modal-title">人机验证</h3>
|
||||
<p class="uk-text-meta">请计算下方的算术题以验证你不是机器人</p>
|
||||
<div class="captcha-equation-box">
|
||||
<span id="captcha-modal-question" class="math-captcha-modal-question">加载中...</span>
|
||||
<input type="number" id="captcha-modal-answer" placeholder="?" autocomplete="off" inputmode="numeric">
|
||||
</div>
|
||||
<div style="margin-top:6px;">
|
||||
<button type="button" class="uk-button uk-button-text uk-text-small" id="captcha-modal-refresh">换一题</button>
|
||||
</div>
|
||||
<div id="captcha-modal-error" class="uk-text-danger uk-text-small" style="display:none;min-height:20px;"></div>
|
||||
<div class="uk-margin-small-top">
|
||||
<button type="button" class="uk-button uk-button-primary" id="captcha-modal-submit">提交</button>
|
||||
<button type="button" class="uk-button uk-button-default uk-modal-close">取消</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var CAPTCHA_I18N = {
|
||||
loading: "加载中...",
|
||||
loadFailed: "加载失败",
|
||||
loadRetry: "加载失败,请重试",
|
||||
inputAnswer: "请输入答案",
|
||||
wrongAnswer: "答案错误,请重新计算",
|
||||
verifyFailed: "验证失败,请重试",
|
||||
needPassword: "此提问箱需要密码",
|
||||
needEmail: "请填写接收通知的邮箱地址"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var captchaId = '';
|
||||
var pendingForm = null;
|
||||
var pendingNeedPassword = false;
|
||||
var verifying = false;
|
||||
|
||||
function fetchCaptcha() {
|
||||
var qEl = document.getElementById('captcha-modal-question');
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
var ansEl = document.getElementById('captcha-modal-answer');
|
||||
qEl.textContent = CAPTCHA_I18N.loading;
|
||||
fetch('/api/captcha/generate')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.code === 0 && data.data) {
|
||||
captchaId = data.data.id;
|
||||
qEl.textContent = data.data.question;
|
||||
if (errEl) errEl.style.display = 'none';
|
||||
if (ansEl) { ansEl.value = ''; ansEl.focus(); }
|
||||
} else {
|
||||
qEl.textContent = CAPTCHA_I18N.loadFailed;
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
qEl.textContent = CAPTCHA_I18N.loadRetry;
|
||||
});
|
||||
}
|
||||
|
||||
function getCSRFToken() {
|
||||
var input = document.querySelector('input[name="_csrf"]');
|
||||
return input ? input.value : '';
|
||||
}
|
||||
|
||||
function doSubmit(form) {
|
||||
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
var hidden = form.querySelector('[name="g-recaptcha-response"]');
|
||||
if (hidden) hidden.value = captchaId + ':' + (ans || '0');
|
||||
|
||||
UIkit.modal('#math-captcha-modal').hide();
|
||||
|
||||
|
||||
if (pendingNeedPassword) {
|
||||
UIkit.modal.prompt(CAPTCHA_I18N.needPassword, '', 'password')
|
||||
.then(function(password) {
|
||||
if (password) {
|
||||
var pwInput = document.getElementById('ask_password_input');
|
||||
if (pwInput) pwInput.value = password;
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-submit').addEventListener('click', function() {
|
||||
if (verifying) return;
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
if (!ans) {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.inputAnswer;
|
||||
errEl.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
verifying = true;
|
||||
fetch('/api/captcha/verify', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-Token': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify({ id: captchaId, answer: parseInt(ans, 10) })
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
verifying = false;
|
||||
if (data.correct) {
|
||||
if (pendingForm) doSubmit(pendingForm);
|
||||
} else {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.wrongAnswer;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
verifying = false;
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.verifyFailed;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-answer').addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
document.getElementById('captcha-modal-submit').click();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-refresh').addEventListener('click', fetchCaptcha);
|
||||
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target.closest('.math-captcha-trigger');
|
||||
if (!btn) return;
|
||||
e.preventDefault();
|
||||
|
||||
var form = btn.closest('form');
|
||||
if (!form) return;
|
||||
pendingForm = form;
|
||||
|
||||
|
||||
pendingNeedPassword = !!(form.querySelector('#ask_password_input'));
|
||||
|
||||
|
||||
var notifyCb = document.getElementById('notify-checkbox');
|
||||
var emailInput = document.getElementById('email-input');
|
||||
if (notifyCb && notifyCb.checked && emailInput && emailInput.value.trim() === '') {
|
||||
UIkit.modal.alert(CAPTCHA_I18N.needEmail);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchCaptcha();
|
||||
UIkit.modal('#math-captcha-modal').show();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-flex-middle uk-margin-bottom">
|
||||
<h3 class="uk-margin-remove">投票结果:吃什么</h3>
|
||||
<div class="uk-flex uk-flex-middle" style="gap: 8px;">
|
||||
<a class="uk-button uk-button-default uk-button-small" href="/user/votes/13/export">导出 CSV</a>
|
||||
<a class="uk-button uk-button-default uk-button-small" href="/user/questions#votes">返回</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-small uk-card-body uk-margin-bottom">
|
||||
<div class="uk-text-large uk-text-bold">0</div>
|
||||
<div class="uk-text-meta">总参与人数</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<h4>投票结果</h4>
|
||||
<div class="uk-card uk-card-default uk-card-small uk-card-body uk-margin-bottom">
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 8px;">
|
||||
<span class="uk-label">1</span>
|
||||
<span class="uk-label ">单行文本</span>
|
||||
<span class="uk-text-bold">是啊,吃什么?</span>
|
||||
<span class="uk-text-meta uk-text-small">回答数: 0</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="uk-text-meta uk-margin-small-top">已填写: 0</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
function toggleFieldReplies(id) {
|
||||
var box = document.getElementById('replies-' + id);
|
||||
var caret = document.getElementById('caret-' + id);
|
||||
if (!box) { return; }
|
||||
if (box.hasAttribute('hidden')) {
|
||||
box.removeAttribute('hidden');
|
||||
if (caret) { caret.style.transform = 'rotate(0deg)'; }
|
||||
} else {
|
||||
box.setAttribute('hidden', '');
|
||||
if (caret) { caret.style.transform = 'rotate(-90deg)'; }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<p class=" uk-text-right uk-text-muted uk-text-small">
|
||||
<br>
|
||||
<a href="/rules">社区规则</a> |
|
||||
|
||||
<a href="https://box.shiroko.one/_/tamakyi" target="_blank">找站长</a>
|
||||
<br>
|
||||
<a href="https://share.shiroko.one" target="_blank">盘</a>
|
||||
| <a href="https://blog.shiroko.one" target="_blank">公告板</a>
|
||||
| <a href="https://chat.shiroko.one" target="_blank">聊天室</a>
|
||||
| <a href="https://status.shiroko.one" target="_blank">监控板</a>
|
||||
| <a href="https://shiroko.one" target="_blank">导航页</a>
|
||||
<br>Powered by NekoBox | 狼ICP备 20230101
|
||||
<br>提问箱已成功存活:<span id="box_runtime"></span>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
(function () {
|
||||
var create = Math.round(Date.UTC(2023, 6, 1, 18, 15, 43) / 1000);
|
||||
function tick() {
|
||||
var el = document.getElementById("box_runtime");
|
||||
if (!el) return;
|
||||
var s = Math.round((Date.now() + 8 * 3600 * 1000) / 1000) - create;
|
||||
var t = [0, 0, 0, 0, 0];
|
||||
if (s >= 31536000) { t[0] = s / 31536000 | 0; s %= 31536000; }
|
||||
if (s >= 86400) { t[1] = s / 86400 | 0; s %= 86400; }
|
||||
if (s >= 3600) { t[2] = s / 3600 | 0; s %= 3600; }
|
||||
if (s >= 60) { t[3] = s / 60 | 0; s %= 60; }
|
||||
if (s > 0) { t[4] = s; }
|
||||
el.innerHTML = t[0] + '年 ' + t[1] + '天 ' + t[2] + '时 ' + t[3] + '分 ' + t[4] + '秒 ';
|
||||
}
|
||||
tick();
|
||||
setInterval(tick, 1000);
|
||||
})();
|
||||
</script>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
var SUBMIT_I18N = {
|
||||
submitting: '提交中...',
|
||||
uploading: '上传中...'
|
||||
};
|
||||
|
||||
function tbResetSubmitButtons() {
|
||||
document.querySelectorAll('button[data-tb-submitting]').forEach(function(b) {
|
||||
b.disabled = false;
|
||||
b.removeAttribute('data-tb-submitting');
|
||||
var orig = b.getAttribute('data-tb-restore');
|
||||
if (orig !== null) {
|
||||
b.innerHTML = orig;
|
||||
b.removeAttribute('data-tb-restore');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('submit', function(e) {
|
||||
var form = e.target;
|
||||
if (!form || form.tagName !== 'FORM') return;
|
||||
|
||||
|
||||
|
||||
if (e.defaultPrevented || form.getAttribute('data-tb-skip-submit-feedback') === '1') {
|
||||
form.removeAttribute('data-tb-skip-submit-feedback');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (form.getAttribute('target') === '_blank') return;
|
||||
|
||||
|
||||
var trigger = e.submitter || form.querySelector('button[type="submit"]');
|
||||
|
||||
|
||||
var hasFile = false;
|
||||
form.querySelectorAll('input[type="file"]').forEach(function(f) {
|
||||
if (f.files && f.files.length > 0) hasFile = true;
|
||||
});
|
||||
var label = hasFile ? SUBMIT_I18N.uploading : SUBMIT_I18N.submitting;
|
||||
|
||||
if (trigger && trigger.tagName === 'BUTTON') {
|
||||
trigger.setAttribute('data-tb-restore', trigger.innerHTML);
|
||||
trigger.innerHTML = '<span uk-spinner="ratio: 0.6"></span> ' + label;
|
||||
}
|
||||
|
||||
|
||||
form.querySelectorAll('button').forEach(function(b) {
|
||||
b.disabled = true;
|
||||
b.setAttribute('data-tb-submitting', '1');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener('pageshow', tbResetSubmitButtons);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,609 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>投票结果</title>
|
||||
<meta name="msvalidate.01" content="2F185E8E63C93635F50B3574F3B31E42" />
|
||||
<meta name="description" content="狼的提问箱——一个无需注册、可匿名提问的匿名提问箱,安全地倾诉与回应。">
|
||||
<meta name="keywords" content="匿名提问箱,提问箱,匿名提问,狼的提问箱,匿名问答,匿名提问网站">
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
if (m && m[1] === 'dark') document.documentElement.setAttribute('data-theme', 'dark');
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://r2.337845818.best" crossorigin>
|
||||
<link rel="preconnect" href="https://cdnjs.snrat.com" crossorigin>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/css/uikit.min.css"/>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/base.css?v=20261019c"/>
|
||||
|
||||
<link rel="stylesheet" href="https://r2.337845818.best/tamabox/cdn/waline/client/v2/waline-no-commits.css" media="print" onload="this.media='all'"/>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit-icons.min.js"></script>
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/dayjs/1.10.8/dayjs.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/alpinejs/3.9.0/cdn.min.js"></script>
|
||||
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/waline/2.15.8/waline.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.captcha-equation-box {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: #f0f2f5;
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 8px;
|
||||
padding: 8px 8px 8px 16px;
|
||||
gap: 6px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
.captcha-equation-box:focus-within {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 3px rgba(30,135,240,0.12);
|
||||
}
|
||||
.math-captcha-modal-question {
|
||||
font-size: 1.4rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
letter-spacing: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
width: 80px;
|
||||
padding: 6px 10px;
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 600;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
transition: border-color 0.15s, box-shadow 0.15s;
|
||||
background: #fff;
|
||||
}
|
||||
#captcha-modal-answer:focus {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 2px rgba(30,135,240,0.2);
|
||||
}
|
||||
|
||||
#captcha-modal-answer::-webkit-inner-spin-button,
|
||||
#captcha-modal-answer::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta property="og:site_name" content="狼的提问箱 | 匿名提问箱" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content=" - 狼的提问箱 | 匿名提问箱" />
|
||||
<meta property="og:url" content="https://box-dev-api.337845818.best/user/votes/2/results" />
|
||||
<meta property="og:description" content=" - 狼的提问箱——一个无需注册、可匿名提问的匿名提问箱,安全地倾诉与回应。" />
|
||||
<meta name="robots" content="noindex">
|
||||
|
||||
<meta property="og:image" content="?og-image=1" />
|
||||
<meta property="og:image:alt" content="" />
|
||||
<meta itemprop="image" content="?og-image=1"/>
|
||||
<meta name="msapplication-TileImage" content=""/>
|
||||
<link rel="shortcut icon" href="?og-image=1"/>
|
||||
<link rel="apple-touch-icon" href="?og-image=1"/>
|
||||
<link rel="icon" sizes="192x192" href="?og-image=1">
|
||||
<meta name="twitter:image:src" content="?og-image=1" />
|
||||
|
||||
|
||||
|
||||
<meta name="google-site-verification" content="fEPwRRJfiGsgwc5SINBQwZhPK8F0cwRaOvRx0YRurI4" />
|
||||
|
||||
<script>
|
||||
window.addEventListener("load", function () {
|
||||
var s = document.createElement("script");
|
||||
s.src = "https://mami.shiroko.one/tamami.js";
|
||||
s.setAttribute("data-website-id", "c42ebe8b-9281-4da0-83a4-8f18b3e710fe");
|
||||
document.body.appendChild(s);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window.tbRenderQR = function (el, getOptions) {
|
||||
if (!el || typeof QRCode === 'undefined') return;
|
||||
var opts = getOptions();
|
||||
function remoteOf(o, key) {
|
||||
var v = o[key];
|
||||
return (typeof v === 'string' && v.indexOf('http') === 0) ? v : '';
|
||||
}
|
||||
var good = window._tbQrGood || (window._tbQrGood = {});
|
||||
var bad = window._tbQrBad || (window._tbQrBad = {});
|
||||
|
||||
function layerState(url) { return !url ? '' : (good[url] ? 1 : (bad[url] ? 0 : null)); }
|
||||
var layers = [
|
||||
{ url: remoteOf(opts, 'logo'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.logo = undefined; o.logoWidth = undefined; o.logoHeight = undefined; o.logoBackgroundTransparent = undefined; }
|
||||
} },
|
||||
{ url: remoteOf(opts, 'backgroundImage'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.backgroundImage = undefined; o.backgroundImageAlpha = undefined; }
|
||||
} }
|
||||
];
|
||||
var needProbe = false;
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
layers[i].st = layerState(layers[i].url);
|
||||
if (layers[i].st === null) needProbe = true;
|
||||
}
|
||||
function paint(states) {
|
||||
var o = {};
|
||||
for (var k in opts) o[k] = opts[k];
|
||||
for (var j = 0; j < layers.length; j++) layers[j].present(o, states[j] === 1);
|
||||
el.innerHTML = '';
|
||||
new QRCode(el, o);
|
||||
}
|
||||
|
||||
var initStates = [];
|
||||
for (var n = 0; n < layers.length; n++) initStates.push(layers[n].st === 1 ? 1 : 0);
|
||||
paint(initStates);
|
||||
if (!needProbe) return;
|
||||
|
||||
var pending = 0, cross = opts.crossOrigin || 'anonymous';
|
||||
layers.forEach(function (L) {
|
||||
if (L.st !== null) return;
|
||||
pending++;
|
||||
var im = new Image();
|
||||
im.onload = function () { good[L.url] = true; L.st = 1; onDone(); };
|
||||
im.onerror = function () { bad[L.url] = true; L.st = 0; onDone(); };
|
||||
if (cross) im.crossOrigin = cross;
|
||||
im.src = L.url;
|
||||
});
|
||||
function onDone() {
|
||||
if (--pending > 0) return;
|
||||
var finalStates = [];
|
||||
for (var m = 0; m < layers.length; m++) finalStates.push(layers[m].st === 1 ? 1 : 0);
|
||||
var changed = false;
|
||||
for (var q = 0; q < finalStates.length; q++) if (finalStates[q] !== initStates[q]) changed = true;
|
||||
if (changed) paint(finalStates);
|
||||
}
|
||||
|
||||
setTimeout(function () { if (pending > 0) { pending = 0; onDone(); } }, 3000);
|
||||
};
|
||||
</script>
|
||||
<nav class="uk-navbar-container uk-margin tb-navbar" uk-navbar>
|
||||
<div class="uk-navbar-center">
|
||||
<div class="uk-navbar-center-left">
|
||||
<div>
|
||||
<ul class="uk-navbar-nav">
|
||||
|
||||
<li><a href="/explore">探索</a></li>
|
||||
|
||||
|
||||
<li><a href="/_/admin6">我的</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="uk-navbar-item uk-logo" href="/"><span class="emoji-placeholder" aria-label="random animal">🐺</span>的提问箱</a>
|
||||
|
||||
<div class="uk-navbar-center-right">
|
||||
<div>
|
||||
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/user/questions">提问</a></li>
|
||||
</ul>
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/user/profile">设置</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" id="theme-toggle" title="切换深色/浅色模式" aria-label="切换深色/浅色模式">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const emojis = ["🐺","🐗","🐻","🐨","🐼","🐹","🐭","🐰","🦊","🐮","🐷","🐽","🐸","🐒","🦍","🐔","🐧","🐦","🐤","🐦⬛","🦅","🦉","🦇","🐴","🦄","🐝","🦎","🦖","🦕","🐙","🦑","🦐","🦞","🦀","🐡","🐠","🐟","🐬","🐳","🐋","🦈","🐊","🐅","🐆","🦓","🦍","🦧","🐘","🦛","🦏","🐪","🐫","🦒","🦘","🐃","🐂","🐄","🐎","🐖","🐏","🐑","🦙","🐐","🦌","🐕","🐩","🦮","🐕🦺","🐈","🐋","🐳","🐬","🐉","🐲"];
|
||||
const placeholder = document.querySelector('.emoji-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.textContent = emojis[Math.floor(Math.random() * emojis.length)];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="tb-mobile-utils">
|
||||
|
||||
<button type="button" id="theme-toggle-mobile" class="uk-button uk-button-default uk-button-small"
|
||||
title="切换深色/浅色模式" aria-label="切换深色/浅色模式">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
var THEME_COOKIE = 'theme';
|
||||
function getTheme() {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
return m ? m[1] : '';
|
||||
}
|
||||
function applyTheme(theme) {
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
}
|
||||
}
|
||||
function toggleTheme() {
|
||||
var next = getTheme() === 'dark' ? 'light' : 'dark';
|
||||
applyTheme(next);
|
||||
var expires = new Date(Date.now() + 365 * 24 * 3600 * 1000).toUTCString();
|
||||
document.cookie = THEME_COOKIE + '=' + next + '; path=/; max-age=' + (365 * 24 * 3600) + '; SameSite=Lax';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
var buttons = document.querySelectorAll('#theme-toggle, #theme-toggle-mobile');
|
||||
buttons.forEach(function(btn) {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
toggleTheme();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var langSel = document.getElementById('mobile-lang-select');
|
||||
if (langSel) {
|
||||
langSel.addEventListener('change', function() {
|
||||
if (!this.value) return;
|
||||
var to = window.location.pathname + window.location.search;
|
||||
window.location.href = '/i18n/' + encodeURIComponent(this.value) + '?to=' + encodeURIComponent(to);
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-container uk-container-xsmall">
|
||||
|
||||
|
||||
|
||||
<div id="math-captcha-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body uk-text-center">
|
||||
<h3 class="uk-modal-title">人机验证</h3>
|
||||
<p class="uk-text-meta">请计算下方的算术题以验证你不是机器人</p>
|
||||
<div class="captcha-equation-box">
|
||||
<span id="captcha-modal-question" class="math-captcha-modal-question">加载中...</span>
|
||||
<input type="number" id="captcha-modal-answer" placeholder="?" autocomplete="off" inputmode="numeric">
|
||||
</div>
|
||||
<div style="margin-top:6px;">
|
||||
<button type="button" class="uk-button uk-button-text uk-text-small" id="captcha-modal-refresh">换一题</button>
|
||||
</div>
|
||||
<div id="captcha-modal-error" class="uk-text-danger uk-text-small" style="display:none;min-height:20px;"></div>
|
||||
<div class="uk-margin-small-top">
|
||||
<button type="button" class="uk-button uk-button-primary" id="captcha-modal-submit">提交</button>
|
||||
<button type="button" class="uk-button uk-button-default uk-modal-close">取消</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var CAPTCHA_I18N = {
|
||||
loading: "加载中...",
|
||||
loadFailed: "加载失败",
|
||||
loadRetry: "加载失败,请重试",
|
||||
inputAnswer: "请输入答案",
|
||||
wrongAnswer: "答案错误,请重新计算",
|
||||
verifyFailed: "验证失败,请重试",
|
||||
needPassword: "此提问箱需要密码",
|
||||
needEmail: "请填写接收通知的邮箱地址"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var captchaId = '';
|
||||
var pendingForm = null;
|
||||
var pendingNeedPassword = false;
|
||||
var verifying = false;
|
||||
|
||||
function fetchCaptcha() {
|
||||
var qEl = document.getElementById('captcha-modal-question');
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
var ansEl = document.getElementById('captcha-modal-answer');
|
||||
qEl.textContent = CAPTCHA_I18N.loading;
|
||||
fetch('/api/captcha/generate')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.code === 0 && data.data) {
|
||||
captchaId = data.data.id;
|
||||
qEl.textContent = data.data.question;
|
||||
if (errEl) errEl.style.display = 'none';
|
||||
if (ansEl) { ansEl.value = ''; ansEl.focus(); }
|
||||
} else {
|
||||
qEl.textContent = CAPTCHA_I18N.loadFailed;
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
qEl.textContent = CAPTCHA_I18N.loadRetry;
|
||||
});
|
||||
}
|
||||
|
||||
function getCSRFToken() {
|
||||
var input = document.querySelector('input[name="_csrf"]');
|
||||
return input ? input.value : '';
|
||||
}
|
||||
|
||||
function doSubmit(form) {
|
||||
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
var hidden = form.querySelector('[name="g-recaptcha-response"]');
|
||||
if (hidden) hidden.value = captchaId + ':' + (ans || '0');
|
||||
|
||||
UIkit.modal('#math-captcha-modal').hide();
|
||||
|
||||
|
||||
if (pendingNeedPassword) {
|
||||
UIkit.modal.prompt(CAPTCHA_I18N.needPassword, '', 'password')
|
||||
.then(function(password) {
|
||||
if (password) {
|
||||
var pwInput = document.getElementById('ask_password_input');
|
||||
if (pwInput) pwInput.value = password;
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-submit').addEventListener('click', function() {
|
||||
if (verifying) return;
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
if (!ans) {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.inputAnswer;
|
||||
errEl.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
verifying = true;
|
||||
fetch('/api/captcha/verify', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-Token': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify({ id: captchaId, answer: parseInt(ans, 10) })
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
verifying = false;
|
||||
if (data.correct) {
|
||||
if (pendingForm) doSubmit(pendingForm);
|
||||
} else {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.wrongAnswer;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
verifying = false;
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.verifyFailed;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-answer').addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
document.getElementById('captcha-modal-submit').click();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-refresh').addEventListener('click', fetchCaptcha);
|
||||
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target.closest('.math-captcha-trigger');
|
||||
if (!btn) return;
|
||||
e.preventDefault();
|
||||
|
||||
var form = btn.closest('form');
|
||||
if (!form) return;
|
||||
pendingForm = form;
|
||||
|
||||
|
||||
pendingNeedPassword = !!(form.querySelector('#ask_password_input'));
|
||||
|
||||
|
||||
var notifyCb = document.getElementById('notify-checkbox');
|
||||
var emailInput = document.getElementById('email-input');
|
||||
if (notifyCb && notifyCb.checked && emailInput && emailInput.value.trim() === '') {
|
||||
UIkit.modal.alert(CAPTCHA_I18N.needEmail);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchCaptcha();
|
||||
UIkit.modal('#math-captcha-modal').show();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-flex-middle uk-margin-bottom">
|
||||
<h3 class="uk-margin-remove">投票结果:今天吃什么</h3>
|
||||
<div class="uk-flex uk-flex-middle" style="gap: 8px;">
|
||||
<a class="uk-button uk-button-default uk-button-small" href="/user/votes/2/export">导出 CSV</a>
|
||||
<a class="uk-button uk-button-default uk-button-small" href="/user/questions#votes">返回</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-small uk-card-body uk-margin-bottom">
|
||||
<div class="uk-text-large uk-text-bold">2</div>
|
||||
<div class="uk-text-meta">总参与人数</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<h4>投票结果</h4>
|
||||
<div class="uk-card uk-card-default uk-card-small uk-card-body">
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
function toggleFieldReplies(id) {
|
||||
var box = document.getElementById('replies-' + id);
|
||||
var caret = document.getElementById('caret-' + id);
|
||||
if (!box) { return; }
|
||||
if (box.hasAttribute('hidden')) {
|
||||
box.removeAttribute('hidden');
|
||||
if (caret) { caret.style.transform = 'rotate(0deg)'; }
|
||||
} else {
|
||||
box.setAttribute('hidden', '');
|
||||
if (caret) { caret.style.transform = 'rotate(-90deg)'; }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<p class=" uk-text-right uk-text-muted uk-text-small">
|
||||
<br>
|
||||
<a href="/rules">社区规则</a> |
|
||||
|
||||
<a href="https://box.shiroko.one/_/tamakyi" target="_blank">找站长</a>
|
||||
<br>
|
||||
<a href="https://share.shiroko.one" target="_blank">盘</a>
|
||||
| <a href="https://blog.shiroko.one" target="_blank">公告板</a>
|
||||
| <a href="https://chat.shiroko.one" target="_blank">聊天室</a>
|
||||
| <a href="https://status.shiroko.one" target="_blank">监控板</a>
|
||||
| <a href="https://shiroko.one" target="_blank">导航页</a>
|
||||
<br>Powered by NekoBox | 狼ICP备 20230101
|
||||
<br>提问箱已成功存活:<span id="box_runtime"></span>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
(function () {
|
||||
var create = Math.round(Date.UTC(2023, 6, 1, 18, 15, 43) / 1000);
|
||||
function tick() {
|
||||
var el = document.getElementById("box_runtime");
|
||||
if (!el) return;
|
||||
var s = Math.round((Date.now() + 8 * 3600 * 1000) / 1000) - create;
|
||||
var t = [0, 0, 0, 0, 0];
|
||||
if (s >= 31536000) { t[0] = s / 31536000 | 0; s %= 31536000; }
|
||||
if (s >= 86400) { t[1] = s / 86400 | 0; s %= 86400; }
|
||||
if (s >= 3600) { t[2] = s / 3600 | 0; s %= 3600; }
|
||||
if (s >= 60) { t[3] = s / 60 | 0; s %= 60; }
|
||||
if (s > 0) { t[4] = s; }
|
||||
el.innerHTML = t[0] + '年 ' + t[1] + '天 ' + t[2] + '时 ' + t[3] + '分 ' + t[4] + '秒 ';
|
||||
}
|
||||
tick();
|
||||
setInterval(tick, 1000);
|
||||
})();
|
||||
</script>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
var SUBMIT_I18N = {
|
||||
submitting: '提交中...',
|
||||
uploading: '上传中...'
|
||||
};
|
||||
|
||||
function tbResetSubmitButtons() {
|
||||
document.querySelectorAll('button[data-tb-submitting]').forEach(function(b) {
|
||||
b.disabled = false;
|
||||
b.removeAttribute('data-tb-submitting');
|
||||
var orig = b.getAttribute('data-tb-restore');
|
||||
if (orig !== null) {
|
||||
b.innerHTML = orig;
|
||||
b.removeAttribute('data-tb-restore');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('submit', function(e) {
|
||||
var form = e.target;
|
||||
if (!form || form.tagName !== 'FORM') return;
|
||||
|
||||
|
||||
|
||||
if (e.defaultPrevented || form.getAttribute('data-tb-skip-submit-feedback') === '1') {
|
||||
form.removeAttribute('data-tb-skip-submit-feedback');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (form.getAttribute('target') === '_blank') return;
|
||||
|
||||
|
||||
var trigger = e.submitter || form.querySelector('button[type="submit"]');
|
||||
|
||||
|
||||
var hasFile = false;
|
||||
form.querySelectorAll('input[type="file"]').forEach(function(f) {
|
||||
if (f.files && f.files.length > 0) hasFile = true;
|
||||
});
|
||||
var label = hasFile ? SUBMIT_I18N.uploading : SUBMIT_I18N.submitting;
|
||||
|
||||
if (trigger && trigger.tagName === 'BUTTON') {
|
||||
trigger.setAttribute('data-tb-restore', trigger.innerHTML);
|
||||
trigger.innerHTML = '<span uk-spinner="ratio: 0.6"></span> ' + label;
|
||||
}
|
||||
|
||||
|
||||
form.querySelectorAll('button').forEach(function(b) {
|
||||
b.disabled = true;
|
||||
b.setAttribute('data-tb-submitting', '1');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener('pageshow', tbResetSubmitButtons);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,693 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>投票结果</title>
|
||||
<meta name="msvalidate.01" content="2F185E8E63C93635F50B3574F3B31E42" />
|
||||
<meta name="description" content="狼的提问箱——一个无需注册、可匿名提问的匿名提问箱,安全地倾诉与回应。">
|
||||
<meta name="keywords" content="匿名提问箱,提问箱,匿名提问,狼的提问箱,匿名问答,匿名提问网站">
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
if (m && m[1] === 'dark') document.documentElement.setAttribute('data-theme', 'dark');
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://r2.337845818.best" crossorigin>
|
||||
<link rel="preconnect" href="https://cdnjs.snrat.com" crossorigin>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/css/uikit.min.css"/>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/base.css?v=20261019c"/>
|
||||
|
||||
<link rel="stylesheet" href="https://r2.337845818.best/tamabox/cdn/waline/client/v2/waline-no-commits.css" media="print" onload="this.media='all'"/>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit-icons.min.js"></script>
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/dayjs/1.10.8/dayjs.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/alpinejs/3.9.0/cdn.min.js"></script>
|
||||
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/waline/2.15.8/waline.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.captcha-equation-box {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: #f0f2f5;
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 8px;
|
||||
padding: 8px 8px 8px 16px;
|
||||
gap: 6px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
.captcha-equation-box:focus-within {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 3px rgba(30,135,240,0.12);
|
||||
}
|
||||
.math-captcha-modal-question {
|
||||
font-size: 1.4rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
letter-spacing: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
width: 80px;
|
||||
padding: 6px 10px;
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 600;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
transition: border-color 0.15s, box-shadow 0.15s;
|
||||
background: #fff;
|
||||
}
|
||||
#captcha-modal-answer:focus {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 2px rgba(30,135,240,0.2);
|
||||
}
|
||||
|
||||
#captcha-modal-answer::-webkit-inner-spin-button,
|
||||
#captcha-modal-answer::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta property="og:site_name" content="狼的提问箱 | 匿名提问箱" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content=" - 狼的提问箱 | 匿名提问箱" />
|
||||
<meta property="og:url" content="https://box-dev-api.337845818.best/user/votes/3/results" />
|
||||
<meta property="og:description" content=" - 狼的提问箱——一个无需注册、可匿名提问的匿名提问箱,安全地倾诉与回应。" />
|
||||
<meta name="robots" content="noindex">
|
||||
|
||||
<meta property="og:image" content="?og-image=1" />
|
||||
<meta property="og:image:alt" content="" />
|
||||
<meta itemprop="image" content="?og-image=1"/>
|
||||
<meta name="msapplication-TileImage" content=""/>
|
||||
<link rel="shortcut icon" href="?og-image=1"/>
|
||||
<link rel="apple-touch-icon" href="?og-image=1"/>
|
||||
<link rel="icon" sizes="192x192" href="?og-image=1">
|
||||
<meta name="twitter:image:src" content="?og-image=1" />
|
||||
|
||||
|
||||
|
||||
<meta name="google-site-verification" content="fEPwRRJfiGsgwc5SINBQwZhPK8F0cwRaOvRx0YRurI4" />
|
||||
|
||||
<script>
|
||||
window.addEventListener("load", function () {
|
||||
var s = document.createElement("script");
|
||||
s.src = "https://mami.shiroko.one/tamami.js";
|
||||
s.setAttribute("data-website-id", "c42ebe8b-9281-4da0-83a4-8f18b3e710fe");
|
||||
document.body.appendChild(s);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window.tbRenderQR = function (el, getOptions) {
|
||||
if (!el || typeof QRCode === 'undefined') return;
|
||||
var opts = getOptions();
|
||||
function remoteOf(o, key) {
|
||||
var v = o[key];
|
||||
return (typeof v === 'string' && v.indexOf('http') === 0) ? v : '';
|
||||
}
|
||||
var good = window._tbQrGood || (window._tbQrGood = {});
|
||||
var bad = window._tbQrBad || (window._tbQrBad = {});
|
||||
|
||||
function layerState(url) { return !url ? '' : (good[url] ? 1 : (bad[url] ? 0 : null)); }
|
||||
var layers = [
|
||||
{ url: remoteOf(opts, 'logo'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.logo = undefined; o.logoWidth = undefined; o.logoHeight = undefined; o.logoBackgroundTransparent = undefined; }
|
||||
} },
|
||||
{ url: remoteOf(opts, 'backgroundImage'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.backgroundImage = undefined; o.backgroundImageAlpha = undefined; }
|
||||
} }
|
||||
];
|
||||
var needProbe = false;
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
layers[i].st = layerState(layers[i].url);
|
||||
if (layers[i].st === null) needProbe = true;
|
||||
}
|
||||
function paint(states) {
|
||||
var o = {};
|
||||
for (var k in opts) o[k] = opts[k];
|
||||
for (var j = 0; j < layers.length; j++) layers[j].present(o, states[j] === 1);
|
||||
el.innerHTML = '';
|
||||
new QRCode(el, o);
|
||||
}
|
||||
|
||||
var initStates = [];
|
||||
for (var n = 0; n < layers.length; n++) initStates.push(layers[n].st === 1 ? 1 : 0);
|
||||
paint(initStates);
|
||||
if (!needProbe) return;
|
||||
|
||||
var pending = 0, cross = opts.crossOrigin || 'anonymous';
|
||||
layers.forEach(function (L) {
|
||||
if (L.st !== null) return;
|
||||
pending++;
|
||||
var im = new Image();
|
||||
im.onload = function () { good[L.url] = true; L.st = 1; onDone(); };
|
||||
im.onerror = function () { bad[L.url] = true; L.st = 0; onDone(); };
|
||||
if (cross) im.crossOrigin = cross;
|
||||
im.src = L.url;
|
||||
});
|
||||
function onDone() {
|
||||
if (--pending > 0) return;
|
||||
var finalStates = [];
|
||||
for (var m = 0; m < layers.length; m++) finalStates.push(layers[m].st === 1 ? 1 : 0);
|
||||
var changed = false;
|
||||
for (var q = 0; q < finalStates.length; q++) if (finalStates[q] !== initStates[q]) changed = true;
|
||||
if (changed) paint(finalStates);
|
||||
}
|
||||
|
||||
setTimeout(function () { if (pending > 0) { pending = 0; onDone(); } }, 3000);
|
||||
};
|
||||
</script>
|
||||
<nav class="uk-navbar-container uk-margin tb-navbar" uk-navbar>
|
||||
<div class="uk-navbar-center">
|
||||
<div class="uk-navbar-center-left">
|
||||
<div>
|
||||
<ul class="uk-navbar-nav">
|
||||
|
||||
<li><a href="/explore">探索</a></li>
|
||||
|
||||
|
||||
<li><a href="/_/admin6">我的</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="uk-navbar-item uk-logo" href="/"><span class="emoji-placeholder" aria-label="random animal">🐺</span>的提问箱</a>
|
||||
|
||||
<div class="uk-navbar-center-right">
|
||||
<div>
|
||||
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/user/questions">提问</a></li>
|
||||
</ul>
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/user/profile">设置</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" id="theme-toggle" title="切换深色/浅色模式" aria-label="切换深色/浅色模式">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const emojis = ["🐺","🐗","🐻","🐨","🐼","🐹","🐭","🐰","🦊","🐮","🐷","🐽","🐸","🐒","🦍","🐔","🐧","🐦","🐤","🐦⬛","🦅","🦉","🦇","🐴","🦄","🐝","🦎","🦖","🦕","🐙","🦑","🦐","🦞","🦀","🐡","🐠","🐟","🐬","🐳","🐋","🦈","🐊","🐅","🐆","🦓","🦍","🦧","🐘","🦛","🦏","🐪","🐫","🦒","🦘","🐃","🐂","🐄","🐎","🐖","🐏","🐑","🦙","🐐","🦌","🐕","🐩","🦮","🐕🦺","🐈","🐋","🐳","🐬","🐉","🐲"];
|
||||
const placeholder = document.querySelector('.emoji-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.textContent = emojis[Math.floor(Math.random() * emojis.length)];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="tb-mobile-utils">
|
||||
|
||||
<button type="button" id="theme-toggle-mobile" class="uk-button uk-button-default uk-button-small"
|
||||
title="切换深色/浅色模式" aria-label="切换深色/浅色模式">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
var THEME_COOKIE = 'theme';
|
||||
function getTheme() {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
return m ? m[1] : '';
|
||||
}
|
||||
function applyTheme(theme) {
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
}
|
||||
}
|
||||
function toggleTheme() {
|
||||
var next = getTheme() === 'dark' ? 'light' : 'dark';
|
||||
applyTheme(next);
|
||||
var expires = new Date(Date.now() + 365 * 24 * 3600 * 1000).toUTCString();
|
||||
document.cookie = THEME_COOKIE + '=' + next + '; path=/; max-age=' + (365 * 24 * 3600) + '; SameSite=Lax';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
var buttons = document.querySelectorAll('#theme-toggle, #theme-toggle-mobile');
|
||||
buttons.forEach(function(btn) {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
toggleTheme();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var langSel = document.getElementById('mobile-lang-select');
|
||||
if (langSel) {
|
||||
langSel.addEventListener('change', function() {
|
||||
if (!this.value) return;
|
||||
var to = window.location.pathname + window.location.search;
|
||||
window.location.href = '/i18n/' + encodeURIComponent(this.value) + '?to=' + encodeURIComponent(to);
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-container uk-container-xsmall">
|
||||
|
||||
|
||||
|
||||
<div id="math-captcha-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body uk-text-center">
|
||||
<h3 class="uk-modal-title">人机验证</h3>
|
||||
<p class="uk-text-meta">请计算下方的算术题以验证你不是机器人</p>
|
||||
<div class="captcha-equation-box">
|
||||
<span id="captcha-modal-question" class="math-captcha-modal-question">加载中...</span>
|
||||
<input type="number" id="captcha-modal-answer" placeholder="?" autocomplete="off" inputmode="numeric">
|
||||
</div>
|
||||
<div style="margin-top:6px;">
|
||||
<button type="button" class="uk-button uk-button-text uk-text-small" id="captcha-modal-refresh">换一题</button>
|
||||
</div>
|
||||
<div id="captcha-modal-error" class="uk-text-danger uk-text-small" style="display:none;min-height:20px;"></div>
|
||||
<div class="uk-margin-small-top">
|
||||
<button type="button" class="uk-button uk-button-primary" id="captcha-modal-submit">提交</button>
|
||||
<button type="button" class="uk-button uk-button-default uk-modal-close">取消</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var CAPTCHA_I18N = {
|
||||
loading: "加载中...",
|
||||
loadFailed: "加载失败",
|
||||
loadRetry: "加载失败,请重试",
|
||||
inputAnswer: "请输入答案",
|
||||
wrongAnswer: "答案错误,请重新计算",
|
||||
verifyFailed: "验证失败,请重试",
|
||||
needPassword: "此提问箱需要密码",
|
||||
needEmail: "请填写接收通知的邮箱地址"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var captchaId = '';
|
||||
var pendingForm = null;
|
||||
var pendingNeedPassword = false;
|
||||
var verifying = false;
|
||||
|
||||
function fetchCaptcha() {
|
||||
var qEl = document.getElementById('captcha-modal-question');
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
var ansEl = document.getElementById('captcha-modal-answer');
|
||||
qEl.textContent = CAPTCHA_I18N.loading;
|
||||
fetch('/api/captcha/generate')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.code === 0 && data.data) {
|
||||
captchaId = data.data.id;
|
||||
qEl.textContent = data.data.question;
|
||||
if (errEl) errEl.style.display = 'none';
|
||||
if (ansEl) { ansEl.value = ''; ansEl.focus(); }
|
||||
} else {
|
||||
qEl.textContent = CAPTCHA_I18N.loadFailed;
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
qEl.textContent = CAPTCHA_I18N.loadRetry;
|
||||
});
|
||||
}
|
||||
|
||||
function getCSRFToken() {
|
||||
var input = document.querySelector('input[name="_csrf"]');
|
||||
return input ? input.value : '';
|
||||
}
|
||||
|
||||
function doSubmit(form) {
|
||||
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
var hidden = form.querySelector('[name="g-recaptcha-response"]');
|
||||
if (hidden) hidden.value = captchaId + ':' + (ans || '0');
|
||||
|
||||
UIkit.modal('#math-captcha-modal').hide();
|
||||
|
||||
|
||||
if (pendingNeedPassword) {
|
||||
UIkit.modal.prompt(CAPTCHA_I18N.needPassword, '', 'password')
|
||||
.then(function(password) {
|
||||
if (password) {
|
||||
var pwInput = document.getElementById('ask_password_input');
|
||||
if (pwInput) pwInput.value = password;
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-submit').addEventListener('click', function() {
|
||||
if (verifying) return;
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
if (!ans) {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.inputAnswer;
|
||||
errEl.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
verifying = true;
|
||||
fetch('/api/captcha/verify', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-Token': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify({ id: captchaId, answer: parseInt(ans, 10) })
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
verifying = false;
|
||||
if (data.correct) {
|
||||
if (pendingForm) doSubmit(pendingForm);
|
||||
} else {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.wrongAnswer;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
verifying = false;
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.verifyFailed;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-answer').addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
document.getElementById('captcha-modal-submit').click();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-refresh').addEventListener('click', fetchCaptcha);
|
||||
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target.closest('.math-captcha-trigger');
|
||||
if (!btn) return;
|
||||
e.preventDefault();
|
||||
|
||||
var form = btn.closest('form');
|
||||
if (!form) return;
|
||||
pendingForm = form;
|
||||
|
||||
|
||||
pendingNeedPassword = !!(form.querySelector('#ask_password_input'));
|
||||
|
||||
|
||||
var notifyCb = document.getElementById('notify-checkbox');
|
||||
var emailInput = document.getElementById('email-input');
|
||||
if (notifyCb && notifyCb.checked && emailInput && emailInput.value.trim() === '') {
|
||||
UIkit.modal.alert(CAPTCHA_I18N.needEmail);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchCaptcha();
|
||||
UIkit.modal('#math-captcha-modal').show();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-flex-middle uk-margin-bottom">
|
||||
<h3 class="uk-margin-remove">投票结果:明天吃什么</h3>
|
||||
<div class="uk-flex uk-flex-middle" style="gap: 8px;">
|
||||
<a class="uk-button uk-button-default uk-button-small" href="/user/votes/3/export">导出 CSV</a>
|
||||
<a class="uk-button uk-button-default uk-button-small" href="/user/questions#votes">返回</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-small uk-card-body uk-margin-bottom">
|
||||
<div class="uk-text-large uk-text-bold">1</div>
|
||||
<div class="uk-text-meta">总参与人数</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<h4>投票结果</h4>
|
||||
<div class="uk-card uk-card-default uk-card-small uk-card-body">
|
||||
|
||||
<div class="uk-text-meta uk-margin-small-bottom">平均分: 8.0</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>1 分</span>
|
||||
<span class="uk-text-meta">0 票</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>2 分</span>
|
||||
<span class="uk-text-meta">0 票</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>3 分</span>
|
||||
<span class="uk-text-meta">0 票</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>4 分</span>
|
||||
<span class="uk-text-meta">0 票</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>5 分</span>
|
||||
<span class="uk-text-meta">0 票</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>6 分</span>
|
||||
<span class="uk-text-meta">0 票</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>7 分</span>
|
||||
<span class="uk-text-meta">0 票</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>8 分</span>
|
||||
<span class="uk-text-meta">1 票</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="100" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>9 分</span>
|
||||
<span class="uk-text-meta">0 票</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>10 分</span>
|
||||
<span class="uk-text-meta">0 票</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
function toggleFieldReplies(id) {
|
||||
var box = document.getElementById('replies-' + id);
|
||||
var caret = document.getElementById('caret-' + id);
|
||||
if (!box) { return; }
|
||||
if (box.hasAttribute('hidden')) {
|
||||
box.removeAttribute('hidden');
|
||||
if (caret) { caret.style.transform = 'rotate(0deg)'; }
|
||||
} else {
|
||||
box.setAttribute('hidden', '');
|
||||
if (caret) { caret.style.transform = 'rotate(-90deg)'; }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<p class=" uk-text-right uk-text-muted uk-text-small">
|
||||
<br>
|
||||
<a href="/rules">社区规则</a> |
|
||||
|
||||
<a href="https://box.shiroko.one/_/tamakyi" target="_blank">找站长</a>
|
||||
<br>
|
||||
<a href="https://share.shiroko.one" target="_blank">盘</a>
|
||||
| <a href="https://blog.shiroko.one" target="_blank">公告板</a>
|
||||
| <a href="https://chat.shiroko.one" target="_blank">聊天室</a>
|
||||
| <a href="https://status.shiroko.one" target="_blank">监控板</a>
|
||||
| <a href="https://shiroko.one" target="_blank">导航页</a>
|
||||
<br>Powered by NekoBox | 狼ICP备 20230101
|
||||
<br>提问箱已成功存活:<span id="box_runtime"></span>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
(function () {
|
||||
var create = Math.round(Date.UTC(2023, 6, 1, 18, 15, 43) / 1000);
|
||||
function tick() {
|
||||
var el = document.getElementById("box_runtime");
|
||||
if (!el) return;
|
||||
var s = Math.round((Date.now() + 8 * 3600 * 1000) / 1000) - create;
|
||||
var t = [0, 0, 0, 0, 0];
|
||||
if (s >= 31536000) { t[0] = s / 31536000 | 0; s %= 31536000; }
|
||||
if (s >= 86400) { t[1] = s / 86400 | 0; s %= 86400; }
|
||||
if (s >= 3600) { t[2] = s / 3600 | 0; s %= 3600; }
|
||||
if (s >= 60) { t[3] = s / 60 | 0; s %= 60; }
|
||||
if (s > 0) { t[4] = s; }
|
||||
el.innerHTML = t[0] + '年 ' + t[1] + '天 ' + t[2] + '时 ' + t[3] + '分 ' + t[4] + '秒 ';
|
||||
}
|
||||
tick();
|
||||
setInterval(tick, 1000);
|
||||
})();
|
||||
</script>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
var SUBMIT_I18N = {
|
||||
submitting: '提交中...',
|
||||
uploading: '上传中...'
|
||||
};
|
||||
|
||||
function tbResetSubmitButtons() {
|
||||
document.querySelectorAll('button[data-tb-submitting]').forEach(function(b) {
|
||||
b.disabled = false;
|
||||
b.removeAttribute('data-tb-submitting');
|
||||
var orig = b.getAttribute('data-tb-restore');
|
||||
if (orig !== null) {
|
||||
b.innerHTML = orig;
|
||||
b.removeAttribute('data-tb-restore');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('submit', function(e) {
|
||||
var form = e.target;
|
||||
if (!form || form.tagName !== 'FORM') return;
|
||||
|
||||
|
||||
|
||||
if (e.defaultPrevented || form.getAttribute('data-tb-skip-submit-feedback') === '1') {
|
||||
form.removeAttribute('data-tb-skip-submit-feedback');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (form.getAttribute('target') === '_blank') return;
|
||||
|
||||
|
||||
var trigger = e.submitter || form.querySelector('button[type="submit"]');
|
||||
|
||||
|
||||
var hasFile = false;
|
||||
form.querySelectorAll('input[type="file"]').forEach(function(f) {
|
||||
if (f.files && f.files.length > 0) hasFile = true;
|
||||
});
|
||||
var label = hasFile ? SUBMIT_I18N.uploading : SUBMIT_I18N.submitting;
|
||||
|
||||
if (trigger && trigger.tagName === 'BUTTON') {
|
||||
trigger.setAttribute('data-tb-restore', trigger.innerHTML);
|
||||
trigger.innerHTML = '<span uk-spinner="ratio: 0.6"></span> ' + label;
|
||||
}
|
||||
|
||||
|
||||
form.querySelectorAll('button').forEach(function(b) {
|
||||
b.disabled = true;
|
||||
b.setAttribute('data-tb-submitting', '1');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener('pageshow', tbResetSubmitButtons);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,636 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>投票结果</title>
|
||||
<meta name="msvalidate.01" content="2F185E8E63C93635F50B3574F3B31E42" />
|
||||
<meta name="description" content="狼的提问箱——一个无需注册、可匿名提问的匿名提问箱,安全地倾诉与回应。">
|
||||
<meta name="keywords" content="匿名提问箱,提问箱,匿名提问,狼的提问箱,匿名问答,匿名提问网站">
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
if (m && m[1] === 'dark') document.documentElement.setAttribute('data-theme', 'dark');
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://r2.337845818.best" crossorigin>
|
||||
<link rel="preconnect" href="https://cdnjs.snrat.com" crossorigin>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/css/uikit.min.css"/>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/base.css?v=20261019c"/>
|
||||
|
||||
<link rel="stylesheet" href="https://r2.337845818.best/tamabox/cdn/waline/client/v2/waline-no-commits.css" media="print" onload="this.media='all'"/>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit-icons.min.js"></script>
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/dayjs/1.10.8/dayjs.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/alpinejs/3.9.0/cdn.min.js"></script>
|
||||
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/waline/2.15.8/waline.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.captcha-equation-box {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: #f0f2f5;
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 8px;
|
||||
padding: 8px 8px 8px 16px;
|
||||
gap: 6px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
.captcha-equation-box:focus-within {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 3px rgba(30,135,240,0.12);
|
||||
}
|
||||
.math-captcha-modal-question {
|
||||
font-size: 1.4rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
letter-spacing: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
width: 80px;
|
||||
padding: 6px 10px;
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 600;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
transition: border-color 0.15s, box-shadow 0.15s;
|
||||
background: #fff;
|
||||
}
|
||||
#captcha-modal-answer:focus {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 2px rgba(30,135,240,0.2);
|
||||
}
|
||||
|
||||
#captcha-modal-answer::-webkit-inner-spin-button,
|
||||
#captcha-modal-answer::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta property="og:site_name" content="狼的提问箱 | 匿名提问箱" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content=" - 狼的提问箱 | 匿名提问箱" />
|
||||
<meta property="og:url" content="https://box-dev-api.337845818.best/user/votes/4/results" />
|
||||
<meta property="og:description" content=" - 狼的提问箱——一个无需注册、可匿名提问的匿名提问箱,安全地倾诉与回应。" />
|
||||
<meta name="robots" content="noindex">
|
||||
|
||||
<meta property="og:image" content="?og-image=1" />
|
||||
<meta property="og:image:alt" content="" />
|
||||
<meta itemprop="image" content="?og-image=1"/>
|
||||
<meta name="msapplication-TileImage" content=""/>
|
||||
<link rel="shortcut icon" href="?og-image=1"/>
|
||||
<link rel="apple-touch-icon" href="?og-image=1"/>
|
||||
<link rel="icon" sizes="192x192" href="?og-image=1">
|
||||
<meta name="twitter:image:src" content="?og-image=1" />
|
||||
|
||||
|
||||
|
||||
<meta name="google-site-verification" content="fEPwRRJfiGsgwc5SINBQwZhPK8F0cwRaOvRx0YRurI4" />
|
||||
|
||||
<script>
|
||||
window.addEventListener("load", function () {
|
||||
var s = document.createElement("script");
|
||||
s.src = "https://mami.shiroko.one/tamami.js";
|
||||
s.setAttribute("data-website-id", "c42ebe8b-9281-4da0-83a4-8f18b3e710fe");
|
||||
document.body.appendChild(s);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window.tbRenderQR = function (el, getOptions) {
|
||||
if (!el || typeof QRCode === 'undefined') return;
|
||||
var opts = getOptions();
|
||||
function remoteOf(o, key) {
|
||||
var v = o[key];
|
||||
return (typeof v === 'string' && v.indexOf('http') === 0) ? v : '';
|
||||
}
|
||||
var good = window._tbQrGood || (window._tbQrGood = {});
|
||||
var bad = window._tbQrBad || (window._tbQrBad = {});
|
||||
|
||||
function layerState(url) { return !url ? '' : (good[url] ? 1 : (bad[url] ? 0 : null)); }
|
||||
var layers = [
|
||||
{ url: remoteOf(opts, 'logo'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.logo = undefined; o.logoWidth = undefined; o.logoHeight = undefined; o.logoBackgroundTransparent = undefined; }
|
||||
} },
|
||||
{ url: remoteOf(opts, 'backgroundImage'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.backgroundImage = undefined; o.backgroundImageAlpha = undefined; }
|
||||
} }
|
||||
];
|
||||
var needProbe = false;
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
layers[i].st = layerState(layers[i].url);
|
||||
if (layers[i].st === null) needProbe = true;
|
||||
}
|
||||
function paint(states) {
|
||||
var o = {};
|
||||
for (var k in opts) o[k] = opts[k];
|
||||
for (var j = 0; j < layers.length; j++) layers[j].present(o, states[j] === 1);
|
||||
el.innerHTML = '';
|
||||
new QRCode(el, o);
|
||||
}
|
||||
|
||||
var initStates = [];
|
||||
for (var n = 0; n < layers.length; n++) initStates.push(layers[n].st === 1 ? 1 : 0);
|
||||
paint(initStates);
|
||||
if (!needProbe) return;
|
||||
|
||||
var pending = 0, cross = opts.crossOrigin || 'anonymous';
|
||||
layers.forEach(function (L) {
|
||||
if (L.st !== null) return;
|
||||
pending++;
|
||||
var im = new Image();
|
||||
im.onload = function () { good[L.url] = true; L.st = 1; onDone(); };
|
||||
im.onerror = function () { bad[L.url] = true; L.st = 0; onDone(); };
|
||||
if (cross) im.crossOrigin = cross;
|
||||
im.src = L.url;
|
||||
});
|
||||
function onDone() {
|
||||
if (--pending > 0) return;
|
||||
var finalStates = [];
|
||||
for (var m = 0; m < layers.length; m++) finalStates.push(layers[m].st === 1 ? 1 : 0);
|
||||
var changed = false;
|
||||
for (var q = 0; q < finalStates.length; q++) if (finalStates[q] !== initStates[q]) changed = true;
|
||||
if (changed) paint(finalStates);
|
||||
}
|
||||
|
||||
setTimeout(function () { if (pending > 0) { pending = 0; onDone(); } }, 3000);
|
||||
};
|
||||
</script>
|
||||
<nav class="uk-navbar-container uk-margin tb-navbar" uk-navbar>
|
||||
<div class="uk-navbar-center">
|
||||
<div class="uk-navbar-center-left">
|
||||
<div>
|
||||
<ul class="uk-navbar-nav">
|
||||
|
||||
<li><a href="/explore">探索</a></li>
|
||||
|
||||
|
||||
<li><a href="/_/admin6">我的</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="uk-navbar-item uk-logo" href="/"><span class="emoji-placeholder" aria-label="random animal">🐺</span>的提问箱</a>
|
||||
|
||||
<div class="uk-navbar-center-right">
|
||||
<div>
|
||||
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/user/questions">提问</a></li>
|
||||
</ul>
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/user/profile">设置</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" id="theme-toggle" title="切换深色/浅色模式" aria-label="切换深色/浅色模式">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const emojis = ["🐺","🐗","🐻","🐨","🐼","🐹","🐭","🐰","🦊","🐮","🐷","🐽","🐸","🐒","🦍","🐔","🐧","🐦","🐤","🐦⬛","🦅","🦉","🦇","🐴","🦄","🐝","🦎","🦖","🦕","🐙","🦑","🦐","🦞","🦀","🐡","🐠","🐟","🐬","🐳","🐋","🦈","🐊","🐅","🐆","🦓","🦍","🦧","🐘","🦛","🦏","🐪","🐫","🦒","🦘","🐃","🐂","🐄","🐎","🐖","🐏","🐑","🦙","🐐","🦌","🐕","🐩","🦮","🐕🦺","🐈","🐋","🐳","🐬","🐉","🐲"];
|
||||
const placeholder = document.querySelector('.emoji-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.textContent = emojis[Math.floor(Math.random() * emojis.length)];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="tb-mobile-utils">
|
||||
|
||||
<button type="button" id="theme-toggle-mobile" class="uk-button uk-button-default uk-button-small"
|
||||
title="切换深色/浅色模式" aria-label="切换深色/浅色模式">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
var THEME_COOKIE = 'theme';
|
||||
function getTheme() {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
return m ? m[1] : '';
|
||||
}
|
||||
function applyTheme(theme) {
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
}
|
||||
}
|
||||
function toggleTheme() {
|
||||
var next = getTheme() === 'dark' ? 'light' : 'dark';
|
||||
applyTheme(next);
|
||||
var expires = new Date(Date.now() + 365 * 24 * 3600 * 1000).toUTCString();
|
||||
document.cookie = THEME_COOKIE + '=' + next + '; path=/; max-age=' + (365 * 24 * 3600) + '; SameSite=Lax';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
var buttons = document.querySelectorAll('#theme-toggle, #theme-toggle-mobile');
|
||||
buttons.forEach(function(btn) {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
toggleTheme();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var langSel = document.getElementById('mobile-lang-select');
|
||||
if (langSel) {
|
||||
langSel.addEventListener('change', function() {
|
||||
if (!this.value) return;
|
||||
var to = window.location.pathname + window.location.search;
|
||||
window.location.href = '/i18n/' + encodeURIComponent(this.value) + '?to=' + encodeURIComponent(to);
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-container uk-container-xsmall">
|
||||
|
||||
|
||||
|
||||
<div id="math-captcha-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body uk-text-center">
|
||||
<h3 class="uk-modal-title">人机验证</h3>
|
||||
<p class="uk-text-meta">请计算下方的算术题以验证你不是机器人</p>
|
||||
<div class="captcha-equation-box">
|
||||
<span id="captcha-modal-question" class="math-captcha-modal-question">加载中...</span>
|
||||
<input type="number" id="captcha-modal-answer" placeholder="?" autocomplete="off" inputmode="numeric">
|
||||
</div>
|
||||
<div style="margin-top:6px;">
|
||||
<button type="button" class="uk-button uk-button-text uk-text-small" id="captcha-modal-refresh">换一题</button>
|
||||
</div>
|
||||
<div id="captcha-modal-error" class="uk-text-danger uk-text-small" style="display:none;min-height:20px;"></div>
|
||||
<div class="uk-margin-small-top">
|
||||
<button type="button" class="uk-button uk-button-primary" id="captcha-modal-submit">提交</button>
|
||||
<button type="button" class="uk-button uk-button-default uk-modal-close">取消</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var CAPTCHA_I18N = {
|
||||
loading: "加载中...",
|
||||
loadFailed: "加载失败",
|
||||
loadRetry: "加载失败,请重试",
|
||||
inputAnswer: "请输入答案",
|
||||
wrongAnswer: "答案错误,请重新计算",
|
||||
verifyFailed: "验证失败,请重试",
|
||||
needPassword: "此提问箱需要密码",
|
||||
needEmail: "请填写接收通知的邮箱地址"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var captchaId = '';
|
||||
var pendingForm = null;
|
||||
var pendingNeedPassword = false;
|
||||
var verifying = false;
|
||||
|
||||
function fetchCaptcha() {
|
||||
var qEl = document.getElementById('captcha-modal-question');
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
var ansEl = document.getElementById('captcha-modal-answer');
|
||||
qEl.textContent = CAPTCHA_I18N.loading;
|
||||
fetch('/api/captcha/generate')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.code === 0 && data.data) {
|
||||
captchaId = data.data.id;
|
||||
qEl.textContent = data.data.question;
|
||||
if (errEl) errEl.style.display = 'none';
|
||||
if (ansEl) { ansEl.value = ''; ansEl.focus(); }
|
||||
} else {
|
||||
qEl.textContent = CAPTCHA_I18N.loadFailed;
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
qEl.textContent = CAPTCHA_I18N.loadRetry;
|
||||
});
|
||||
}
|
||||
|
||||
function getCSRFToken() {
|
||||
var input = document.querySelector('input[name="_csrf"]');
|
||||
return input ? input.value : '';
|
||||
}
|
||||
|
||||
function doSubmit(form) {
|
||||
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
var hidden = form.querySelector('[name="g-recaptcha-response"]');
|
||||
if (hidden) hidden.value = captchaId + ':' + (ans || '0');
|
||||
|
||||
UIkit.modal('#math-captcha-modal').hide();
|
||||
|
||||
|
||||
if (pendingNeedPassword) {
|
||||
UIkit.modal.prompt(CAPTCHA_I18N.needPassword, '', 'password')
|
||||
.then(function(password) {
|
||||
if (password) {
|
||||
var pwInput = document.getElementById('ask_password_input');
|
||||
if (pwInput) pwInput.value = password;
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-submit').addEventListener('click', function() {
|
||||
if (verifying) return;
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
if (!ans) {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.inputAnswer;
|
||||
errEl.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
verifying = true;
|
||||
fetch('/api/captcha/verify', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-Token': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify({ id: captchaId, answer: parseInt(ans, 10) })
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
verifying = false;
|
||||
if (data.correct) {
|
||||
if (pendingForm) doSubmit(pendingForm);
|
||||
} else {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.wrongAnswer;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
verifying = false;
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.verifyFailed;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-answer').addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
document.getElementById('captcha-modal-submit').click();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-refresh').addEventListener('click', fetchCaptcha);
|
||||
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target.closest('.math-captcha-trigger');
|
||||
if (!btn) return;
|
||||
e.preventDefault();
|
||||
|
||||
var form = btn.closest('form');
|
||||
if (!form) return;
|
||||
pendingForm = form;
|
||||
|
||||
|
||||
pendingNeedPassword = !!(form.querySelector('#ask_password_input'));
|
||||
|
||||
|
||||
var notifyCb = document.getElementById('notify-checkbox');
|
||||
var emailInput = document.getElementById('email-input');
|
||||
if (notifyCb && notifyCb.checked && emailInput && emailInput.value.trim() === '') {
|
||||
UIkit.modal.alert(CAPTCHA_I18N.needEmail);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchCaptcha();
|
||||
UIkit.modal('#math-captcha-modal').show();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-flex-middle uk-margin-bottom">
|
||||
<h3 class="uk-margin-remove">投票结果:测试</h3>
|
||||
<div class="uk-flex uk-flex-middle" style="gap: 8px;">
|
||||
<a class="uk-button uk-button-default uk-button-small" href="/user/votes/4/export">导出 CSV</a>
|
||||
<a class="uk-button uk-button-default uk-button-small" href="/user/questions#votes">返回</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-small uk-card-body uk-margin-bottom">
|
||||
<div class="uk-text-large uk-text-bold">1</div>
|
||||
<div class="uk-text-meta">总参与人数</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<h4>投票结果</h4>
|
||||
<div class="uk-card uk-card-default uk-card-small uk-card-body">
|
||||
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>测试</span>
|
||||
<span class="uk-text-meta">1 票(100%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="100" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>测试2</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>测试3</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
function toggleFieldReplies(id) {
|
||||
var box = document.getElementById('replies-' + id);
|
||||
var caret = document.getElementById('caret-' + id);
|
||||
if (!box) { return; }
|
||||
if (box.hasAttribute('hidden')) {
|
||||
box.removeAttribute('hidden');
|
||||
if (caret) { caret.style.transform = 'rotate(0deg)'; }
|
||||
} else {
|
||||
box.setAttribute('hidden', '');
|
||||
if (caret) { caret.style.transform = 'rotate(-90deg)'; }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<p class=" uk-text-right uk-text-muted uk-text-small">
|
||||
<br>
|
||||
<a href="/rules">社区规则</a> |
|
||||
|
||||
<a href="https://box.shiroko.one/_/tamakyi" target="_blank">找站长</a>
|
||||
<br>
|
||||
<a href="https://share.shiroko.one" target="_blank">盘</a>
|
||||
| <a href="https://blog.shiroko.one" target="_blank">公告板</a>
|
||||
| <a href="https://chat.shiroko.one" target="_blank">聊天室</a>
|
||||
| <a href="https://status.shiroko.one" target="_blank">监控板</a>
|
||||
| <a href="https://shiroko.one" target="_blank">导航页</a>
|
||||
<br>Powered by NekoBox | 狼ICP备 20230101
|
||||
<br>提问箱已成功存活:<span id="box_runtime"></span>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
(function () {
|
||||
var create = Math.round(Date.UTC(2023, 6, 1, 18, 15, 43) / 1000);
|
||||
function tick() {
|
||||
var el = document.getElementById("box_runtime");
|
||||
if (!el) return;
|
||||
var s = Math.round((Date.now() + 8 * 3600 * 1000) / 1000) - create;
|
||||
var t = [0, 0, 0, 0, 0];
|
||||
if (s >= 31536000) { t[0] = s / 31536000 | 0; s %= 31536000; }
|
||||
if (s >= 86400) { t[1] = s / 86400 | 0; s %= 86400; }
|
||||
if (s >= 3600) { t[2] = s / 3600 | 0; s %= 3600; }
|
||||
if (s >= 60) { t[3] = s / 60 | 0; s %= 60; }
|
||||
if (s > 0) { t[4] = s; }
|
||||
el.innerHTML = t[0] + '年 ' + t[1] + '天 ' + t[2] + '时 ' + t[3] + '分 ' + t[4] + '秒 ';
|
||||
}
|
||||
tick();
|
||||
setInterval(tick, 1000);
|
||||
})();
|
||||
</script>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
var SUBMIT_I18N = {
|
||||
submitting: '提交中...',
|
||||
uploading: '上传中...'
|
||||
};
|
||||
|
||||
function tbResetSubmitButtons() {
|
||||
document.querySelectorAll('button[data-tb-submitting]').forEach(function(b) {
|
||||
b.disabled = false;
|
||||
b.removeAttribute('data-tb-submitting');
|
||||
var orig = b.getAttribute('data-tb-restore');
|
||||
if (orig !== null) {
|
||||
b.innerHTML = orig;
|
||||
b.removeAttribute('data-tb-restore');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('submit', function(e) {
|
||||
var form = e.target;
|
||||
if (!form || form.tagName !== 'FORM') return;
|
||||
|
||||
|
||||
|
||||
if (e.defaultPrevented || form.getAttribute('data-tb-skip-submit-feedback') === '1') {
|
||||
form.removeAttribute('data-tb-skip-submit-feedback');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (form.getAttribute('target') === '_blank') return;
|
||||
|
||||
|
||||
var trigger = e.submitter || form.querySelector('button[type="submit"]');
|
||||
|
||||
|
||||
var hasFile = false;
|
||||
form.querySelectorAll('input[type="file"]').forEach(function(f) {
|
||||
if (f.files && f.files.length > 0) hasFile = true;
|
||||
});
|
||||
var label = hasFile ? SUBMIT_I18N.uploading : SUBMIT_I18N.submitting;
|
||||
|
||||
if (trigger && trigger.tagName === 'BUTTON') {
|
||||
trigger.setAttribute('data-tb-restore', trigger.innerHTML);
|
||||
trigger.innerHTML = '<span uk-spinner="ratio: 0.6"></span> ' + label;
|
||||
}
|
||||
|
||||
|
||||
form.querySelectorAll('button').forEach(function(b) {
|
||||
b.disabled = true;
|
||||
b.setAttribute('data-tb-submitting', '1');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener('pageshow', tbResetSubmitButtons);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,929 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>投票结果</title>
|
||||
<meta name="msvalidate.01" content="2F185E8E63C93635F50B3574F3B31E42" />
|
||||
<meta name="description" content="狼的提问箱——一个无需注册、可匿名提问的匿名提问箱,安全地倾诉与回应。">
|
||||
<meta name="keywords" content="匿名提问箱,提问箱,匿名提问,狼的提问箱,匿名问答,匿名提问网站">
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
if (m && m[1] === 'dark') document.documentElement.setAttribute('data-theme', 'dark');
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://r2.337845818.best" crossorigin>
|
||||
<link rel="preconnect" href="https://cdnjs.snrat.com" crossorigin>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/css/uikit.min.css"/>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/base.css?v=20261019c"/>
|
||||
|
||||
<link rel="stylesheet" href="https://r2.337845818.best/tamabox/cdn/waline/client/v2/waline-no-commits.css" media="print" onload="this.media='all'"/>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit-icons.min.js"></script>
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/dayjs/1.10.8/dayjs.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/alpinejs/3.9.0/cdn.min.js"></script>
|
||||
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/waline/2.15.8/waline.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.captcha-equation-box {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: #f0f2f5;
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 8px;
|
||||
padding: 8px 8px 8px 16px;
|
||||
gap: 6px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
.captcha-equation-box:focus-within {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 3px rgba(30,135,240,0.12);
|
||||
}
|
||||
.math-captcha-modal-question {
|
||||
font-size: 1.4rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
letter-spacing: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
width: 80px;
|
||||
padding: 6px 10px;
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 600;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
transition: border-color 0.15s, box-shadow 0.15s;
|
||||
background: #fff;
|
||||
}
|
||||
#captcha-modal-answer:focus {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 2px rgba(30,135,240,0.2);
|
||||
}
|
||||
|
||||
#captcha-modal-answer::-webkit-inner-spin-button,
|
||||
#captcha-modal-answer::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta property="og:site_name" content="狼的提问箱 | 匿名提问箱" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content=" - 狼的提问箱 | 匿名提问箱" />
|
||||
<meta property="og:url" content="https://box-dev-api.337845818.best/user/votes/5/results" />
|
||||
<meta property="og:description" content=" - 狼的提问箱——一个无需注册、可匿名提问的匿名提问箱,安全地倾诉与回应。" />
|
||||
<meta name="robots" content="noindex">
|
||||
|
||||
<meta property="og:image" content="?og-image=1" />
|
||||
<meta property="og:image:alt" content="" />
|
||||
<meta itemprop="image" content="?og-image=1"/>
|
||||
<meta name="msapplication-TileImage" content=""/>
|
||||
<link rel="shortcut icon" href="?og-image=1"/>
|
||||
<link rel="apple-touch-icon" href="?og-image=1"/>
|
||||
<link rel="icon" sizes="192x192" href="?og-image=1">
|
||||
<meta name="twitter:image:src" content="?og-image=1" />
|
||||
|
||||
|
||||
|
||||
<meta name="google-site-verification" content="fEPwRRJfiGsgwc5SINBQwZhPK8F0cwRaOvRx0YRurI4" />
|
||||
|
||||
<script>
|
||||
window.addEventListener("load", function () {
|
||||
var s = document.createElement("script");
|
||||
s.src = "https://mami.shiroko.one/tamami.js";
|
||||
s.setAttribute("data-website-id", "c42ebe8b-9281-4da0-83a4-8f18b3e710fe");
|
||||
document.body.appendChild(s);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window.tbRenderQR = function (el, getOptions) {
|
||||
if (!el || typeof QRCode === 'undefined') return;
|
||||
var opts = getOptions();
|
||||
function remoteOf(o, key) {
|
||||
var v = o[key];
|
||||
return (typeof v === 'string' && v.indexOf('http') === 0) ? v : '';
|
||||
}
|
||||
var good = window._tbQrGood || (window._tbQrGood = {});
|
||||
var bad = window._tbQrBad || (window._tbQrBad = {});
|
||||
|
||||
function layerState(url) { return !url ? '' : (good[url] ? 1 : (bad[url] ? 0 : null)); }
|
||||
var layers = [
|
||||
{ url: remoteOf(opts, 'logo'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.logo = undefined; o.logoWidth = undefined; o.logoHeight = undefined; o.logoBackgroundTransparent = undefined; }
|
||||
} },
|
||||
{ url: remoteOf(opts, 'backgroundImage'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.backgroundImage = undefined; o.backgroundImageAlpha = undefined; }
|
||||
} }
|
||||
];
|
||||
var needProbe = false;
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
layers[i].st = layerState(layers[i].url);
|
||||
if (layers[i].st === null) needProbe = true;
|
||||
}
|
||||
function paint(states) {
|
||||
var o = {};
|
||||
for (var k in opts) o[k] = opts[k];
|
||||
for (var j = 0; j < layers.length; j++) layers[j].present(o, states[j] === 1);
|
||||
el.innerHTML = '';
|
||||
new QRCode(el, o);
|
||||
}
|
||||
|
||||
var initStates = [];
|
||||
for (var n = 0; n < layers.length; n++) initStates.push(layers[n].st === 1 ? 1 : 0);
|
||||
paint(initStates);
|
||||
if (!needProbe) return;
|
||||
|
||||
var pending = 0, cross = opts.crossOrigin || 'anonymous';
|
||||
layers.forEach(function (L) {
|
||||
if (L.st !== null) return;
|
||||
pending++;
|
||||
var im = new Image();
|
||||
im.onload = function () { good[L.url] = true; L.st = 1; onDone(); };
|
||||
im.onerror = function () { bad[L.url] = true; L.st = 0; onDone(); };
|
||||
if (cross) im.crossOrigin = cross;
|
||||
im.src = L.url;
|
||||
});
|
||||
function onDone() {
|
||||
if (--pending > 0) return;
|
||||
var finalStates = [];
|
||||
for (var m = 0; m < layers.length; m++) finalStates.push(layers[m].st === 1 ? 1 : 0);
|
||||
var changed = false;
|
||||
for (var q = 0; q < finalStates.length; q++) if (finalStates[q] !== initStates[q]) changed = true;
|
||||
if (changed) paint(finalStates);
|
||||
}
|
||||
|
||||
setTimeout(function () { if (pending > 0) { pending = 0; onDone(); } }, 3000);
|
||||
};
|
||||
</script>
|
||||
<nav class="uk-navbar-container uk-margin tb-navbar" uk-navbar>
|
||||
<div class="uk-navbar-center">
|
||||
<div class="uk-navbar-center-left">
|
||||
<div>
|
||||
<ul class="uk-navbar-nav">
|
||||
|
||||
<li><a href="/explore">探索</a></li>
|
||||
|
||||
|
||||
<li><a href="/_/admin6">我的</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="uk-navbar-item uk-logo" href="/"><span class="emoji-placeholder" aria-label="random animal">🐺</span>的提问箱</a>
|
||||
|
||||
<div class="uk-navbar-center-right">
|
||||
<div>
|
||||
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/user/questions">提问</a></li>
|
||||
</ul>
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/user/profile">设置</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" id="theme-toggle" title="切换深色/浅色模式" aria-label="切换深色/浅色模式">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const emojis = ["🐺","🐗","🐻","🐨","🐼","🐹","🐭","🐰","🦊","🐮","🐷","🐽","🐸","🐒","🦍","🐔","🐧","🐦","🐤","🐦⬛","🦅","🦉","🦇","🐴","🦄","🐝","🦎","🦖","🦕","🐙","🦑","🦐","🦞","🦀","🐡","🐠","🐟","🐬","🐳","🐋","🦈","🐊","🐅","🐆","🦓","🦍","🦧","🐘","🦛","🦏","🐪","🐫","🦒","🦘","🐃","🐂","🐄","🐎","🐖","🐏","🐑","🦙","🐐","🦌","🐕","🐩","🦮","🐕🦺","🐈","🐋","🐳","🐬","🐉","🐲"];
|
||||
const placeholder = document.querySelector('.emoji-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.textContent = emojis[Math.floor(Math.random() * emojis.length)];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="tb-mobile-utils">
|
||||
|
||||
<button type="button" id="theme-toggle-mobile" class="uk-button uk-button-default uk-button-small"
|
||||
title="切换深色/浅色模式" aria-label="切换深色/浅色模式">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
var THEME_COOKIE = 'theme';
|
||||
function getTheme() {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
return m ? m[1] : '';
|
||||
}
|
||||
function applyTheme(theme) {
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
}
|
||||
}
|
||||
function toggleTheme() {
|
||||
var next = getTheme() === 'dark' ? 'light' : 'dark';
|
||||
applyTheme(next);
|
||||
var expires = new Date(Date.now() + 365 * 24 * 3600 * 1000).toUTCString();
|
||||
document.cookie = THEME_COOKIE + '=' + next + '; path=/; max-age=' + (365 * 24 * 3600) + '; SameSite=Lax';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
var buttons = document.querySelectorAll('#theme-toggle, #theme-toggle-mobile');
|
||||
buttons.forEach(function(btn) {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
toggleTheme();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var langSel = document.getElementById('mobile-lang-select');
|
||||
if (langSel) {
|
||||
langSel.addEventListener('change', function() {
|
||||
if (!this.value) return;
|
||||
var to = window.location.pathname + window.location.search;
|
||||
window.location.href = '/i18n/' + encodeURIComponent(this.value) + '?to=' + encodeURIComponent(to);
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-container uk-container-xsmall">
|
||||
|
||||
|
||||
|
||||
<div id="math-captcha-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body uk-text-center">
|
||||
<h3 class="uk-modal-title">人机验证</h3>
|
||||
<p class="uk-text-meta">请计算下方的算术题以验证你不是机器人</p>
|
||||
<div class="captcha-equation-box">
|
||||
<span id="captcha-modal-question" class="math-captcha-modal-question">加载中...</span>
|
||||
<input type="number" id="captcha-modal-answer" placeholder="?" autocomplete="off" inputmode="numeric">
|
||||
</div>
|
||||
<div style="margin-top:6px;">
|
||||
<button type="button" class="uk-button uk-button-text uk-text-small" id="captcha-modal-refresh">换一题</button>
|
||||
</div>
|
||||
<div id="captcha-modal-error" class="uk-text-danger uk-text-small" style="display:none;min-height:20px;"></div>
|
||||
<div class="uk-margin-small-top">
|
||||
<button type="button" class="uk-button uk-button-primary" id="captcha-modal-submit">提交</button>
|
||||
<button type="button" class="uk-button uk-button-default uk-modal-close">取消</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var CAPTCHA_I18N = {
|
||||
loading: "加载中...",
|
||||
loadFailed: "加载失败",
|
||||
loadRetry: "加载失败,请重试",
|
||||
inputAnswer: "请输入答案",
|
||||
wrongAnswer: "答案错误,请重新计算",
|
||||
verifyFailed: "验证失败,请重试",
|
||||
needPassword: "此提问箱需要密码",
|
||||
needEmail: "请填写接收通知的邮箱地址"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var captchaId = '';
|
||||
var pendingForm = null;
|
||||
var pendingNeedPassword = false;
|
||||
var verifying = false;
|
||||
|
||||
function fetchCaptcha() {
|
||||
var qEl = document.getElementById('captcha-modal-question');
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
var ansEl = document.getElementById('captcha-modal-answer');
|
||||
qEl.textContent = CAPTCHA_I18N.loading;
|
||||
fetch('/api/captcha/generate')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.code === 0 && data.data) {
|
||||
captchaId = data.data.id;
|
||||
qEl.textContent = data.data.question;
|
||||
if (errEl) errEl.style.display = 'none';
|
||||
if (ansEl) { ansEl.value = ''; ansEl.focus(); }
|
||||
} else {
|
||||
qEl.textContent = CAPTCHA_I18N.loadFailed;
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
qEl.textContent = CAPTCHA_I18N.loadRetry;
|
||||
});
|
||||
}
|
||||
|
||||
function getCSRFToken() {
|
||||
var input = document.querySelector('input[name="_csrf"]');
|
||||
return input ? input.value : '';
|
||||
}
|
||||
|
||||
function doSubmit(form) {
|
||||
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
var hidden = form.querySelector('[name="g-recaptcha-response"]');
|
||||
if (hidden) hidden.value = captchaId + ':' + (ans || '0');
|
||||
|
||||
UIkit.modal('#math-captcha-modal').hide();
|
||||
|
||||
|
||||
if (pendingNeedPassword) {
|
||||
UIkit.modal.prompt(CAPTCHA_I18N.needPassword, '', 'password')
|
||||
.then(function(password) {
|
||||
if (password) {
|
||||
var pwInput = document.getElementById('ask_password_input');
|
||||
if (pwInput) pwInput.value = password;
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-submit').addEventListener('click', function() {
|
||||
if (verifying) return;
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
if (!ans) {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.inputAnswer;
|
||||
errEl.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
verifying = true;
|
||||
fetch('/api/captcha/verify', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-Token': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify({ id: captchaId, answer: parseInt(ans, 10) })
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
verifying = false;
|
||||
if (data.correct) {
|
||||
if (pendingForm) doSubmit(pendingForm);
|
||||
} else {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.wrongAnswer;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
verifying = false;
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.verifyFailed;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-answer').addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
document.getElementById('captcha-modal-submit').click();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-refresh').addEventListener('click', fetchCaptcha);
|
||||
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target.closest('.math-captcha-trigger');
|
||||
if (!btn) return;
|
||||
e.preventDefault();
|
||||
|
||||
var form = btn.closest('form');
|
||||
if (!form) return;
|
||||
pendingForm = form;
|
||||
|
||||
|
||||
pendingNeedPassword = !!(form.querySelector('#ask_password_input'));
|
||||
|
||||
|
||||
var notifyCb = document.getElementById('notify-checkbox');
|
||||
var emailInput = document.getElementById('email-input');
|
||||
if (notifyCb && notifyCb.checked && emailInput && emailInput.value.trim() === '') {
|
||||
UIkit.modal.alert(CAPTCHA_I18N.needEmail);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchCaptcha();
|
||||
UIkit.modal('#math-captcha-modal').show();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-flex-middle uk-margin-bottom">
|
||||
<h3 class="uk-margin-remove">投票结果:11</h3>
|
||||
<div class="uk-flex uk-flex-middle" style="gap: 8px;">
|
||||
<a class="uk-button uk-button-default uk-button-small" href="/user/votes/5/export">导出 CSV</a>
|
||||
<a class="uk-button uk-button-default uk-button-small" href="/user/questions#votes">返回</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-small uk-card-body uk-margin-bottom">
|
||||
<div class="uk-text-large uk-text-bold">2</div>
|
||||
<div class="uk-text-meta">总参与人数</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<h4>投票结果</h4>
|
||||
<div class="uk-card uk-card-default uk-card-small uk-card-body uk-margin-bottom">
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 8px;">
|
||||
<span class="uk-label">1</span>
|
||||
<span class="uk-label uk-label-primary">单选</span>
|
||||
<span class="uk-text-bold">11</span>
|
||||
<span class="uk-text-meta uk-text-small">回答数: 2</span>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>11</span>
|
||||
<span class="uk-text-meta">2 票(100%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="100" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>22</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>33</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 8px;">
|
||||
<span class="uk-label">2</span>
|
||||
<span class="uk-label uk-label-success">多选</span>
|
||||
<span class="uk-text-bold">22</span>
|
||||
<span class="uk-text-meta uk-text-small">回答数: 2</span>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>11</span>
|
||||
<span class="uk-text-meta">2 票(66%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="66" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>22</span>
|
||||
<span class="uk-text-meta">1 票(33%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="33" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>33</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 8px;">
|
||||
<span class="uk-label">3</span>
|
||||
<span class="uk-label ">单行文本</span>
|
||||
<span class="uk-text-bold">33</span>
|
||||
<span class="uk-text-meta uk-text-small">回答数: 2</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="uk-text-meta uk-margin-small-top">已填写: 2</div>
|
||||
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-text-small" style="cursor:pointer; user-select:none; color:#1e87f0;" onclick="toggleFieldReplies('4')" title="点击展开或收起文本回复明细">
|
||||
<span id="caret-4" style="display:inline-block; transition:transform .15s; transform:rotate(-90deg);">▾</span>
|
||||
查看文本提交(2)
|
||||
</div>
|
||||
<div id="replies-4" hidden>
|
||||
<ul class="uk-list uk-list-divider uk-margin-small-top">
|
||||
|
||||
<li>
|
||||
<div class="uk-text-meta uk-text-small">2026-08-24 16:05</div>
|
||||
<div style="white-space:pre-wrap;">12</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div class="uk-text-meta uk-text-small">2026-08-24 15:26</div>
|
||||
<div style="white-space:pre-wrap;">12</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 8px;">
|
||||
<span class="uk-label">4</span>
|
||||
<span class="uk-label ">多行文本</span>
|
||||
<span class="uk-text-bold">44</span>
|
||||
<span class="uk-text-meta uk-text-small">回答数: 2</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="uk-text-meta uk-margin-small-top">已填写: 2</div>
|
||||
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-text-small" style="cursor:pointer; user-select:none; color:#1e87f0;" onclick="toggleFieldReplies('5')" title="点击展开或收起文本回复明细">
|
||||
<span id="caret-5" style="display:inline-block; transition:transform .15s; transform:rotate(-90deg);">▾</span>
|
||||
查看文本提交(2)
|
||||
</div>
|
||||
<div id="replies-5" hidden>
|
||||
<ul class="uk-list uk-list-divider uk-margin-small-top">
|
||||
|
||||
<li>
|
||||
<div class="uk-text-meta uk-text-small">2026-08-24 16:05</div>
|
||||
<div style="white-space:pre-wrap;">12</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div class="uk-text-meta uk-text-small">2026-08-24 15:26</div>
|
||||
<div style="white-space:pre-wrap;">12
|
||||
1212
|
||||
121212</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 8px;">
|
||||
<span class="uk-label">5</span>
|
||||
<span class="uk-label uk-label-primary">下拉选择</span>
|
||||
<span class="uk-text-bold">55</span>
|
||||
<span class="uk-text-meta uk-text-small">回答数: 2</span>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>11</span>
|
||||
<span class="uk-text-meta">2 票(100%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="100" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>22</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>33</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 8px;">
|
||||
<span class="uk-label">6</span>
|
||||
<span class="uk-label uk-label-secondary">数字</span>
|
||||
<span class="uk-text-bold">66</span>
|
||||
<span class="uk-text-meta uk-text-small">回答数: 2</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="uk-text-meta uk-margin-small-top">平均: 4.0(2 票)</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 8px;">
|
||||
<span class="uk-label">7</span>
|
||||
<span class="uk-label uk-label-warning">评分</span>
|
||||
<span class="uk-text-bold">77</span>
|
||||
<span class="uk-text-meta uk-text-small">回答数: 2</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="uk-text-meta uk-margin-small-top">平均分: 9.0(2 票)</div>
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-margin-small-top">
|
||||
<span>1 分</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-margin-small-top">
|
||||
<span>2 分</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-margin-small-top">
|
||||
<span>3 分</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-margin-small-top">
|
||||
<span>4 分</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-margin-small-top">
|
||||
<span>5 分</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-margin-small-top">
|
||||
<span>6 分</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-margin-small-top">
|
||||
<span>7 分</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-margin-small-top">
|
||||
<span>8 分</span>
|
||||
<span class="uk-text-meta">1 票(50%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="50" max="100"></progress>
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-margin-small-top">
|
||||
<span>9 分</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-margin-small-top">
|
||||
<span>10 分</span>
|
||||
<span class="uk-text-meta">1 票(50%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="50" max="100"></progress>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 8px;">
|
||||
<span class="uk-label">8</span>
|
||||
<span class="uk-label uk-label-danger">排序</span>
|
||||
<span class="uk-text-bold">88</span>
|
||||
<span class="uk-text-meta uk-text-small">回答数: 2</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="uk-text-meta uk-margin-small-top">平均排名: 1.48(2 票)</div>
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-margin-small-top">
|
||||
<span>11</span>
|
||||
<span class="uk-text-meta">平均排名: 1.10 · 被排次数: 2</span>
|
||||
</div>
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-margin-small-top">
|
||||
<span>22</span>
|
||||
<span class="uk-text-meta">平均排名: 1.25 · 被排次数: 2</span>
|
||||
</div>
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-margin-small-top">
|
||||
<span>33</span>
|
||||
<span class="uk-text-meta">平均排名: 2.10 · 被排次数: 2</span>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
function toggleFieldReplies(id) {
|
||||
var box = document.getElementById('replies-' + id);
|
||||
var caret = document.getElementById('caret-' + id);
|
||||
if (!box) { return; }
|
||||
if (box.hasAttribute('hidden')) {
|
||||
box.removeAttribute('hidden');
|
||||
if (caret) { caret.style.transform = 'rotate(0deg)'; }
|
||||
} else {
|
||||
box.setAttribute('hidden', '');
|
||||
if (caret) { caret.style.transform = 'rotate(-90deg)'; }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<p class=" uk-text-right uk-text-muted uk-text-small">
|
||||
<br>
|
||||
<a href="/rules">社区规则</a> |
|
||||
|
||||
<a href="https://box.shiroko.one/_/tamakyi" target="_blank">找站长</a>
|
||||
<br>
|
||||
<a href="https://share.shiroko.one" target="_blank">盘</a>
|
||||
| <a href="https://blog.shiroko.one" target="_blank">公告板</a>
|
||||
| <a href="https://chat.shiroko.one" target="_blank">聊天室</a>
|
||||
| <a href="https://status.shiroko.one" target="_blank">监控板</a>
|
||||
| <a href="https://shiroko.one" target="_blank">导航页</a>
|
||||
<br>Powered by NekoBox | 狼ICP备 20230101
|
||||
<br>提问箱已成功存活:<span id="box_runtime"></span>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
(function () {
|
||||
var create = Math.round(Date.UTC(2023, 6, 1, 18, 15, 43) / 1000);
|
||||
function tick() {
|
||||
var el = document.getElementById("box_runtime");
|
||||
if (!el) return;
|
||||
var s = Math.round((Date.now() + 8 * 3600 * 1000) / 1000) - create;
|
||||
var t = [0, 0, 0, 0, 0];
|
||||
if (s >= 31536000) { t[0] = s / 31536000 | 0; s %= 31536000; }
|
||||
if (s >= 86400) { t[1] = s / 86400 | 0; s %= 86400; }
|
||||
if (s >= 3600) { t[2] = s / 3600 | 0; s %= 3600; }
|
||||
if (s >= 60) { t[3] = s / 60 | 0; s %= 60; }
|
||||
if (s > 0) { t[4] = s; }
|
||||
el.innerHTML = t[0] + '年 ' + t[1] + '天 ' + t[2] + '时 ' + t[3] + '分 ' + t[4] + '秒 ';
|
||||
}
|
||||
tick();
|
||||
setInterval(tick, 1000);
|
||||
})();
|
||||
</script>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
var SUBMIT_I18N = {
|
||||
submitting: '提交中...',
|
||||
uploading: '上传中...'
|
||||
};
|
||||
|
||||
function tbResetSubmitButtons() {
|
||||
document.querySelectorAll('button[data-tb-submitting]').forEach(function(b) {
|
||||
b.disabled = false;
|
||||
b.removeAttribute('data-tb-submitting');
|
||||
var orig = b.getAttribute('data-tb-restore');
|
||||
if (orig !== null) {
|
||||
b.innerHTML = orig;
|
||||
b.removeAttribute('data-tb-restore');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('submit', function(e) {
|
||||
var form = e.target;
|
||||
if (!form || form.tagName !== 'FORM') return;
|
||||
|
||||
|
||||
|
||||
if (e.defaultPrevented || form.getAttribute('data-tb-skip-submit-feedback') === '1') {
|
||||
form.removeAttribute('data-tb-skip-submit-feedback');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (form.getAttribute('target') === '_blank') return;
|
||||
|
||||
|
||||
var trigger = e.submitter || form.querySelector('button[type="submit"]');
|
||||
|
||||
|
||||
var hasFile = false;
|
||||
form.querySelectorAll('input[type="file"]').forEach(function(f) {
|
||||
if (f.files && f.files.length > 0) hasFile = true;
|
||||
});
|
||||
var label = hasFile ? SUBMIT_I18N.uploading : SUBMIT_I18N.submitting;
|
||||
|
||||
if (trigger && trigger.tagName === 'BUTTON') {
|
||||
trigger.setAttribute('data-tb-restore', trigger.innerHTML);
|
||||
trigger.innerHTML = '<span uk-spinner="ratio: 0.6"></span> ' + label;
|
||||
}
|
||||
|
||||
|
||||
form.querySelectorAll('button').forEach(function(b) {
|
||||
b.disabled = true;
|
||||
b.setAttribute('data-tb-submitting', '1');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener('pageshow', tbResetSubmitButtons);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,701 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>投票结果</title>
|
||||
<meta name="msvalidate.01" content="2F185E8E63C93635F50B3574F3B31E42" />
|
||||
<meta name="description" content="狼的提问箱——一个无需注册、可匿名提问的匿名提问箱,安全地倾诉与回应。">
|
||||
<meta name="keywords" content="匿名提问箱,提问箱,匿名提问,狼的提问箱,匿名问答,匿名提问网站">
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
if (m && m[1] === 'dark') document.documentElement.setAttribute('data-theme', 'dark');
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://r2.337845818.best" crossorigin>
|
||||
<link rel="preconnect" href="https://cdnjs.snrat.com" crossorigin>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/css/uikit.min.css"/>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/base.css?v=20261019c"/>
|
||||
|
||||
<link rel="stylesheet" href="https://r2.337845818.best/tamabox/cdn/waline/client/v2/waline-no-commits.css" media="print" onload="this.media='all'"/>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit-icons.min.js"></script>
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/dayjs/1.10.8/dayjs.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/alpinejs/3.9.0/cdn.min.js"></script>
|
||||
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/waline/2.15.8/waline.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.captcha-equation-box {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: #f0f2f5;
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 8px;
|
||||
padding: 8px 8px 8px 16px;
|
||||
gap: 6px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
.captcha-equation-box:focus-within {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 3px rgba(30,135,240,0.12);
|
||||
}
|
||||
.math-captcha-modal-question {
|
||||
font-size: 1.4rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
letter-spacing: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
width: 80px;
|
||||
padding: 6px 10px;
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 600;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
transition: border-color 0.15s, box-shadow 0.15s;
|
||||
background: #fff;
|
||||
}
|
||||
#captcha-modal-answer:focus {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 2px rgba(30,135,240,0.2);
|
||||
}
|
||||
|
||||
#captcha-modal-answer::-webkit-inner-spin-button,
|
||||
#captcha-modal-answer::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta property="og:site_name" content="狼的提问箱 | 匿名提问箱" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content=" - 狼的提问箱 | 匿名提问箱" />
|
||||
<meta property="og:url" content="https://box-dev-api.337845818.best/user/votes/6/results" />
|
||||
<meta property="og:description" content=" - 狼的提问箱——一个无需注册、可匿名提问的匿名提问箱,安全地倾诉与回应。" />
|
||||
<meta name="robots" content="noindex">
|
||||
|
||||
<meta property="og:image" content="?og-image=1" />
|
||||
<meta property="og:image:alt" content="" />
|
||||
<meta itemprop="image" content="?og-image=1"/>
|
||||
<meta name="msapplication-TileImage" content=""/>
|
||||
<link rel="shortcut icon" href="?og-image=1"/>
|
||||
<link rel="apple-touch-icon" href="?og-image=1"/>
|
||||
<link rel="icon" sizes="192x192" href="?og-image=1">
|
||||
<meta name="twitter:image:src" content="?og-image=1" />
|
||||
|
||||
|
||||
|
||||
<meta name="google-site-verification" content="fEPwRRJfiGsgwc5SINBQwZhPK8F0cwRaOvRx0YRurI4" />
|
||||
|
||||
<script>
|
||||
window.addEventListener("load", function () {
|
||||
var s = document.createElement("script");
|
||||
s.src = "https://mami.shiroko.one/tamami.js";
|
||||
s.setAttribute("data-website-id", "c42ebe8b-9281-4da0-83a4-8f18b3e710fe");
|
||||
document.body.appendChild(s);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window.tbRenderQR = function (el, getOptions) {
|
||||
if (!el || typeof QRCode === 'undefined') return;
|
||||
var opts = getOptions();
|
||||
function remoteOf(o, key) {
|
||||
var v = o[key];
|
||||
return (typeof v === 'string' && v.indexOf('http') === 0) ? v : '';
|
||||
}
|
||||
var good = window._tbQrGood || (window._tbQrGood = {});
|
||||
var bad = window._tbQrBad || (window._tbQrBad = {});
|
||||
|
||||
function layerState(url) { return !url ? '' : (good[url] ? 1 : (bad[url] ? 0 : null)); }
|
||||
var layers = [
|
||||
{ url: remoteOf(opts, 'logo'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.logo = undefined; o.logoWidth = undefined; o.logoHeight = undefined; o.logoBackgroundTransparent = undefined; }
|
||||
} },
|
||||
{ url: remoteOf(opts, 'backgroundImage'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.backgroundImage = undefined; o.backgroundImageAlpha = undefined; }
|
||||
} }
|
||||
];
|
||||
var needProbe = false;
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
layers[i].st = layerState(layers[i].url);
|
||||
if (layers[i].st === null) needProbe = true;
|
||||
}
|
||||
function paint(states) {
|
||||
var o = {};
|
||||
for (var k in opts) o[k] = opts[k];
|
||||
for (var j = 0; j < layers.length; j++) layers[j].present(o, states[j] === 1);
|
||||
el.innerHTML = '';
|
||||
new QRCode(el, o);
|
||||
}
|
||||
|
||||
var initStates = [];
|
||||
for (var n = 0; n < layers.length; n++) initStates.push(layers[n].st === 1 ? 1 : 0);
|
||||
paint(initStates);
|
||||
if (!needProbe) return;
|
||||
|
||||
var pending = 0, cross = opts.crossOrigin || 'anonymous';
|
||||
layers.forEach(function (L) {
|
||||
if (L.st !== null) return;
|
||||
pending++;
|
||||
var im = new Image();
|
||||
im.onload = function () { good[L.url] = true; L.st = 1; onDone(); };
|
||||
im.onerror = function () { bad[L.url] = true; L.st = 0; onDone(); };
|
||||
if (cross) im.crossOrigin = cross;
|
||||
im.src = L.url;
|
||||
});
|
||||
function onDone() {
|
||||
if (--pending > 0) return;
|
||||
var finalStates = [];
|
||||
for (var m = 0; m < layers.length; m++) finalStates.push(layers[m].st === 1 ? 1 : 0);
|
||||
var changed = false;
|
||||
for (var q = 0; q < finalStates.length; q++) if (finalStates[q] !== initStates[q]) changed = true;
|
||||
if (changed) paint(finalStates);
|
||||
}
|
||||
|
||||
setTimeout(function () { if (pending > 0) { pending = 0; onDone(); } }, 3000);
|
||||
};
|
||||
</script>
|
||||
<nav class="uk-navbar-container uk-margin tb-navbar" uk-navbar>
|
||||
<div class="uk-navbar-center">
|
||||
<div class="uk-navbar-center-left">
|
||||
<div>
|
||||
<ul class="uk-navbar-nav">
|
||||
|
||||
<li><a href="/explore">探索</a></li>
|
||||
|
||||
|
||||
<li><a href="/_/admin6">我的</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="uk-navbar-item uk-logo" href="/"><span class="emoji-placeholder" aria-label="random animal">🐺</span>的提问箱</a>
|
||||
|
||||
<div class="uk-navbar-center-right">
|
||||
<div>
|
||||
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/user/questions">提问</a></li>
|
||||
</ul>
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/user/profile">设置</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" id="theme-toggle" title="切换深色/浅色模式" aria-label="切换深色/浅色模式">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const emojis = ["🐺","🐗","🐻","🐨","🐼","🐹","🐭","🐰","🦊","🐮","🐷","🐽","🐸","🐒","🦍","🐔","🐧","🐦","🐤","🐦⬛","🦅","🦉","🦇","🐴","🦄","🐝","🦎","🦖","🦕","🐙","🦑","🦐","🦞","🦀","🐡","🐠","🐟","🐬","🐳","🐋","🦈","🐊","🐅","🐆","🦓","🦍","🦧","🐘","🦛","🦏","🐪","🐫","🦒","🦘","🐃","🐂","🐄","🐎","🐖","🐏","🐑","🦙","🐐","🦌","🐕","🐩","🦮","🐕🦺","🐈","🐋","🐳","🐬","🐉","🐲"];
|
||||
const placeholder = document.querySelector('.emoji-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.textContent = emojis[Math.floor(Math.random() * emojis.length)];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="tb-mobile-utils">
|
||||
|
||||
<button type="button" id="theme-toggle-mobile" class="uk-button uk-button-default uk-button-small"
|
||||
title="切换深色/浅色模式" aria-label="切换深色/浅色模式">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
var THEME_COOKIE = 'theme';
|
||||
function getTheme() {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
return m ? m[1] : '';
|
||||
}
|
||||
function applyTheme(theme) {
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
}
|
||||
}
|
||||
function toggleTheme() {
|
||||
var next = getTheme() === 'dark' ? 'light' : 'dark';
|
||||
applyTheme(next);
|
||||
var expires = new Date(Date.now() + 365 * 24 * 3600 * 1000).toUTCString();
|
||||
document.cookie = THEME_COOKIE + '=' + next + '; path=/; max-age=' + (365 * 24 * 3600) + '; SameSite=Lax';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
var buttons = document.querySelectorAll('#theme-toggle, #theme-toggle-mobile');
|
||||
buttons.forEach(function(btn) {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
toggleTheme();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var langSel = document.getElementById('mobile-lang-select');
|
||||
if (langSel) {
|
||||
langSel.addEventListener('change', function() {
|
||||
if (!this.value) return;
|
||||
var to = window.location.pathname + window.location.search;
|
||||
window.location.href = '/i18n/' + encodeURIComponent(this.value) + '?to=' + encodeURIComponent(to);
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-container uk-container-xsmall">
|
||||
|
||||
|
||||
|
||||
<div id="math-captcha-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body uk-text-center">
|
||||
<h3 class="uk-modal-title">人机验证</h3>
|
||||
<p class="uk-text-meta">请计算下方的算术题以验证你不是机器人</p>
|
||||
<div class="captcha-equation-box">
|
||||
<span id="captcha-modal-question" class="math-captcha-modal-question">加载中...</span>
|
||||
<input type="number" id="captcha-modal-answer" placeholder="?" autocomplete="off" inputmode="numeric">
|
||||
</div>
|
||||
<div style="margin-top:6px;">
|
||||
<button type="button" class="uk-button uk-button-text uk-text-small" id="captcha-modal-refresh">换一题</button>
|
||||
</div>
|
||||
<div id="captcha-modal-error" class="uk-text-danger uk-text-small" style="display:none;min-height:20px;"></div>
|
||||
<div class="uk-margin-small-top">
|
||||
<button type="button" class="uk-button uk-button-primary" id="captcha-modal-submit">提交</button>
|
||||
<button type="button" class="uk-button uk-button-default uk-modal-close">取消</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var CAPTCHA_I18N = {
|
||||
loading: "加载中...",
|
||||
loadFailed: "加载失败",
|
||||
loadRetry: "加载失败,请重试",
|
||||
inputAnswer: "请输入答案",
|
||||
wrongAnswer: "答案错误,请重新计算",
|
||||
verifyFailed: "验证失败,请重试",
|
||||
needPassword: "此提问箱需要密码",
|
||||
needEmail: "请填写接收通知的邮箱地址"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var captchaId = '';
|
||||
var pendingForm = null;
|
||||
var pendingNeedPassword = false;
|
||||
var verifying = false;
|
||||
|
||||
function fetchCaptcha() {
|
||||
var qEl = document.getElementById('captcha-modal-question');
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
var ansEl = document.getElementById('captcha-modal-answer');
|
||||
qEl.textContent = CAPTCHA_I18N.loading;
|
||||
fetch('/api/captcha/generate')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.code === 0 && data.data) {
|
||||
captchaId = data.data.id;
|
||||
qEl.textContent = data.data.question;
|
||||
if (errEl) errEl.style.display = 'none';
|
||||
if (ansEl) { ansEl.value = ''; ansEl.focus(); }
|
||||
} else {
|
||||
qEl.textContent = CAPTCHA_I18N.loadFailed;
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
qEl.textContent = CAPTCHA_I18N.loadRetry;
|
||||
});
|
||||
}
|
||||
|
||||
function getCSRFToken() {
|
||||
var input = document.querySelector('input[name="_csrf"]');
|
||||
return input ? input.value : '';
|
||||
}
|
||||
|
||||
function doSubmit(form) {
|
||||
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
var hidden = form.querySelector('[name="g-recaptcha-response"]');
|
||||
if (hidden) hidden.value = captchaId + ':' + (ans || '0');
|
||||
|
||||
UIkit.modal('#math-captcha-modal').hide();
|
||||
|
||||
|
||||
if (pendingNeedPassword) {
|
||||
UIkit.modal.prompt(CAPTCHA_I18N.needPassword, '', 'password')
|
||||
.then(function(password) {
|
||||
if (password) {
|
||||
var pwInput = document.getElementById('ask_password_input');
|
||||
if (pwInput) pwInput.value = password;
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-submit').addEventListener('click', function() {
|
||||
if (verifying) return;
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
if (!ans) {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.inputAnswer;
|
||||
errEl.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
verifying = true;
|
||||
fetch('/api/captcha/verify', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-Token': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify({ id: captchaId, answer: parseInt(ans, 10) })
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
verifying = false;
|
||||
if (data.correct) {
|
||||
if (pendingForm) doSubmit(pendingForm);
|
||||
} else {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.wrongAnswer;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
verifying = false;
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.verifyFailed;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-answer').addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
document.getElementById('captcha-modal-submit').click();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-refresh').addEventListener('click', fetchCaptcha);
|
||||
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target.closest('.math-captcha-trigger');
|
||||
if (!btn) return;
|
||||
e.preventDefault();
|
||||
|
||||
var form = btn.closest('form');
|
||||
if (!form) return;
|
||||
pendingForm = form;
|
||||
|
||||
|
||||
pendingNeedPassword = !!(form.querySelector('#ask_password_input'));
|
||||
|
||||
|
||||
var notifyCb = document.getElementById('notify-checkbox');
|
||||
var emailInput = document.getElementById('email-input');
|
||||
if (notifyCb && notifyCb.checked && emailInput && emailInput.value.trim() === '') {
|
||||
UIkit.modal.alert(CAPTCHA_I18N.needEmail);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchCaptcha();
|
||||
UIkit.modal('#math-captcha-modal').show();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-flex-middle uk-margin-bottom">
|
||||
<h3 class="uk-margin-remove">投票结果:测试4</h3>
|
||||
<div class="uk-flex uk-flex-middle" style="gap: 8px;">
|
||||
<a class="uk-button uk-button-default uk-button-small" href="/user/votes/6/export">导出 CSV</a>
|
||||
<a class="uk-button uk-button-default uk-button-small" href="/user/questions#votes">返回</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-small uk-card-body uk-margin-bottom">
|
||||
<div class="uk-text-large uk-text-bold">0</div>
|
||||
<div class="uk-text-meta">总参与人数</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<h4>投票结果</h4>
|
||||
<div class="uk-card uk-card-default uk-card-small uk-card-body uk-margin-bottom">
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 8px;">
|
||||
<span class="uk-label">1</span>
|
||||
<span class="uk-label uk-label-primary">单选</span>
|
||||
<span class="uk-text-bold">这里显示第一题</span>
|
||||
<span class="uk-text-meta uk-text-small">回答数: 0</span>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>A</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>B</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>C</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>D</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>E</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 8px;">
|
||||
<span class="uk-label">2</span>
|
||||
<span class="uk-label uk-label-primary">单选</span>
|
||||
<span class="uk-text-bold">11</span>
|
||||
<span class="uk-text-meta uk-text-small">回答数: 0</span>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>1</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-small-top">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>2</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
function toggleFieldReplies(id) {
|
||||
var box = document.getElementById('replies-' + id);
|
||||
var caret = document.getElementById('caret-' + id);
|
||||
if (!box) { return; }
|
||||
if (box.hasAttribute('hidden')) {
|
||||
box.removeAttribute('hidden');
|
||||
if (caret) { caret.style.transform = 'rotate(0deg)'; }
|
||||
} else {
|
||||
box.setAttribute('hidden', '');
|
||||
if (caret) { caret.style.transform = 'rotate(-90deg)'; }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<p class=" uk-text-right uk-text-muted uk-text-small">
|
||||
<br>
|
||||
<a href="/rules">社区规则</a> |
|
||||
|
||||
<a href="https://box.shiroko.one/_/tamakyi" target="_blank">找站长</a>
|
||||
<br>
|
||||
<a href="https://share.shiroko.one" target="_blank">盘</a>
|
||||
| <a href="https://blog.shiroko.one" target="_blank">公告板</a>
|
||||
| <a href="https://chat.shiroko.one" target="_blank">聊天室</a>
|
||||
| <a href="https://status.shiroko.one" target="_blank">监控板</a>
|
||||
| <a href="https://shiroko.one" target="_blank">导航页</a>
|
||||
<br>Powered by NekoBox | 狼ICP备 20230101
|
||||
<br>提问箱已成功存活:<span id="box_runtime"></span>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
(function () {
|
||||
var create = Math.round(Date.UTC(2023, 6, 1, 18, 15, 43) / 1000);
|
||||
function tick() {
|
||||
var el = document.getElementById("box_runtime");
|
||||
if (!el) return;
|
||||
var s = Math.round((Date.now() + 8 * 3600 * 1000) / 1000) - create;
|
||||
var t = [0, 0, 0, 0, 0];
|
||||
if (s >= 31536000) { t[0] = s / 31536000 | 0; s %= 31536000; }
|
||||
if (s >= 86400) { t[1] = s / 86400 | 0; s %= 86400; }
|
||||
if (s >= 3600) { t[2] = s / 3600 | 0; s %= 3600; }
|
||||
if (s >= 60) { t[3] = s / 60 | 0; s %= 60; }
|
||||
if (s > 0) { t[4] = s; }
|
||||
el.innerHTML = t[0] + '年 ' + t[1] + '天 ' + t[2] + '时 ' + t[3] + '分 ' + t[4] + '秒 ';
|
||||
}
|
||||
tick();
|
||||
setInterval(tick, 1000);
|
||||
})();
|
||||
</script>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
var SUBMIT_I18N = {
|
||||
submitting: '提交中...',
|
||||
uploading: '上传中...'
|
||||
};
|
||||
|
||||
function tbResetSubmitButtons() {
|
||||
document.querySelectorAll('button[data-tb-submitting]').forEach(function(b) {
|
||||
b.disabled = false;
|
||||
b.removeAttribute('data-tb-submitting');
|
||||
var orig = b.getAttribute('data-tb-restore');
|
||||
if (orig !== null) {
|
||||
b.innerHTML = orig;
|
||||
b.removeAttribute('data-tb-restore');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('submit', function(e) {
|
||||
var form = e.target;
|
||||
if (!form || form.tagName !== 'FORM') return;
|
||||
|
||||
|
||||
|
||||
if (e.defaultPrevented || form.getAttribute('data-tb-skip-submit-feedback') === '1') {
|
||||
form.removeAttribute('data-tb-skip-submit-feedback');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (form.getAttribute('target') === '_blank') return;
|
||||
|
||||
|
||||
var trigger = e.submitter || form.querySelector('button[type="submit"]');
|
||||
|
||||
|
||||
var hasFile = false;
|
||||
form.querySelectorAll('input[type="file"]').forEach(function(f) {
|
||||
if (f.files && f.files.length > 0) hasFile = true;
|
||||
});
|
||||
var label = hasFile ? SUBMIT_I18N.uploading : SUBMIT_I18N.submitting;
|
||||
|
||||
if (trigger && trigger.tagName === 'BUTTON') {
|
||||
trigger.setAttribute('data-tb-restore', trigger.innerHTML);
|
||||
trigger.innerHTML = '<span uk-spinner="ratio: 0.6"></span> ' + label;
|
||||
}
|
||||
|
||||
|
||||
form.querySelectorAll('button').forEach(function(b) {
|
||||
b.disabled = true;
|
||||
b.setAttribute('data-tb-submitting', '1');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener('pageshow', tbResetSubmitButtons);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,628 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>投票结果</title>
|
||||
<meta name="msvalidate.01" content="2F185E8E63C93635F50B3574F3B31E42" />
|
||||
<meta name="description" content="狼的提问箱——一个无需注册、可匿名提问的匿名提问箱,安全地倾诉与回应。">
|
||||
<meta name="keywords" content="匿名提问箱,提问箱,匿名提问,狼的提问箱,匿名问答,匿名提问网站">
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
if (m && m[1] === 'dark') document.documentElement.setAttribute('data-theme', 'dark');
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://r2.337845818.best" crossorigin>
|
||||
<link rel="preconnect" href="https://cdnjs.snrat.com" crossorigin>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/css/uikit.min.css"/>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/base.css?v=20261019c"/>
|
||||
|
||||
<link rel="stylesheet" href="https://r2.337845818.best/tamabox/cdn/waline/client/v2/waline-no-commits.css" media="print" onload="this.media='all'"/>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit-icons.min.js"></script>
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/dayjs/1.10.8/dayjs.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/alpinejs/3.9.0/cdn.min.js"></script>
|
||||
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/waline/2.15.8/waline.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.captcha-equation-box {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: #f0f2f5;
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 8px;
|
||||
padding: 8px 8px 8px 16px;
|
||||
gap: 6px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
.captcha-equation-box:focus-within {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 3px rgba(30,135,240,0.12);
|
||||
}
|
||||
.math-captcha-modal-question {
|
||||
font-size: 1.4rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
letter-spacing: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
width: 80px;
|
||||
padding: 6px 10px;
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 600;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
transition: border-color 0.15s, box-shadow 0.15s;
|
||||
background: #fff;
|
||||
}
|
||||
#captcha-modal-answer:focus {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 2px rgba(30,135,240,0.2);
|
||||
}
|
||||
|
||||
#captcha-modal-answer::-webkit-inner-spin-button,
|
||||
#captcha-modal-answer::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta property="og:site_name" content="狼的提问箱 | 匿名提问箱" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content=" - 狼的提问箱 | 匿名提问箱" />
|
||||
<meta property="og:url" content="https://box-dev-api.337845818.best/user/votes/7/results" />
|
||||
<meta property="og:description" content=" - 狼的提问箱——一个无需注册、可匿名提问的匿名提问箱,安全地倾诉与回应。" />
|
||||
<meta name="robots" content="noindex">
|
||||
|
||||
<meta property="og:image" content="?og-image=1" />
|
||||
<meta property="og:image:alt" content="" />
|
||||
<meta itemprop="image" content="?og-image=1"/>
|
||||
<meta name="msapplication-TileImage" content=""/>
|
||||
<link rel="shortcut icon" href="?og-image=1"/>
|
||||
<link rel="apple-touch-icon" href="?og-image=1"/>
|
||||
<link rel="icon" sizes="192x192" href="?og-image=1">
|
||||
<meta name="twitter:image:src" content="?og-image=1" />
|
||||
|
||||
|
||||
|
||||
<meta name="google-site-verification" content="fEPwRRJfiGsgwc5SINBQwZhPK8F0cwRaOvRx0YRurI4" />
|
||||
|
||||
<script>
|
||||
window.addEventListener("load", function () {
|
||||
var s = document.createElement("script");
|
||||
s.src = "https://mami.shiroko.one/tamami.js";
|
||||
s.setAttribute("data-website-id", "c42ebe8b-9281-4da0-83a4-8f18b3e710fe");
|
||||
document.body.appendChild(s);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window.tbRenderQR = function (el, getOptions) {
|
||||
if (!el || typeof QRCode === 'undefined') return;
|
||||
var opts = getOptions();
|
||||
function remoteOf(o, key) {
|
||||
var v = o[key];
|
||||
return (typeof v === 'string' && v.indexOf('http') === 0) ? v : '';
|
||||
}
|
||||
var good = window._tbQrGood || (window._tbQrGood = {});
|
||||
var bad = window._tbQrBad || (window._tbQrBad = {});
|
||||
|
||||
function layerState(url) { return !url ? '' : (good[url] ? 1 : (bad[url] ? 0 : null)); }
|
||||
var layers = [
|
||||
{ url: remoteOf(opts, 'logo'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.logo = undefined; o.logoWidth = undefined; o.logoHeight = undefined; o.logoBackgroundTransparent = undefined; }
|
||||
} },
|
||||
{ url: remoteOf(opts, 'backgroundImage'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.backgroundImage = undefined; o.backgroundImageAlpha = undefined; }
|
||||
} }
|
||||
];
|
||||
var needProbe = false;
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
layers[i].st = layerState(layers[i].url);
|
||||
if (layers[i].st === null) needProbe = true;
|
||||
}
|
||||
function paint(states) {
|
||||
var o = {};
|
||||
for (var k in opts) o[k] = opts[k];
|
||||
for (var j = 0; j < layers.length; j++) layers[j].present(o, states[j] === 1);
|
||||
el.innerHTML = '';
|
||||
new QRCode(el, o);
|
||||
}
|
||||
|
||||
var initStates = [];
|
||||
for (var n = 0; n < layers.length; n++) initStates.push(layers[n].st === 1 ? 1 : 0);
|
||||
paint(initStates);
|
||||
if (!needProbe) return;
|
||||
|
||||
var pending = 0, cross = opts.crossOrigin || 'anonymous';
|
||||
layers.forEach(function (L) {
|
||||
if (L.st !== null) return;
|
||||
pending++;
|
||||
var im = new Image();
|
||||
im.onload = function () { good[L.url] = true; L.st = 1; onDone(); };
|
||||
im.onerror = function () { bad[L.url] = true; L.st = 0; onDone(); };
|
||||
if (cross) im.crossOrigin = cross;
|
||||
im.src = L.url;
|
||||
});
|
||||
function onDone() {
|
||||
if (--pending > 0) return;
|
||||
var finalStates = [];
|
||||
for (var m = 0; m < layers.length; m++) finalStates.push(layers[m].st === 1 ? 1 : 0);
|
||||
var changed = false;
|
||||
for (var q = 0; q < finalStates.length; q++) if (finalStates[q] !== initStates[q]) changed = true;
|
||||
if (changed) paint(finalStates);
|
||||
}
|
||||
|
||||
setTimeout(function () { if (pending > 0) { pending = 0; onDone(); } }, 3000);
|
||||
};
|
||||
</script>
|
||||
<nav class="uk-navbar-container uk-margin tb-navbar" uk-navbar>
|
||||
<div class="uk-navbar-center">
|
||||
<div class="uk-navbar-center-left">
|
||||
<div>
|
||||
<ul class="uk-navbar-nav">
|
||||
|
||||
<li><a href="/explore">探索</a></li>
|
||||
|
||||
|
||||
<li><a href="/_/admin6">我的</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="uk-navbar-item uk-logo" href="/"><span class="emoji-placeholder" aria-label="random animal">🐺</span>的提问箱</a>
|
||||
|
||||
<div class="uk-navbar-center-right">
|
||||
<div>
|
||||
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/user/questions">提问</a></li>
|
||||
</ul>
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/user/profile">设置</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" id="theme-toggle" title="切换深色/浅色模式" aria-label="切换深色/浅色模式">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const emojis = ["🐺","🐗","🐻","🐨","🐼","🐹","🐭","🐰","🦊","🐮","🐷","🐽","🐸","🐒","🦍","🐔","🐧","🐦","🐤","🐦⬛","🦅","🦉","🦇","🐴","🦄","🐝","🦎","🦖","🦕","🐙","🦑","🦐","🦞","🦀","🐡","🐠","🐟","🐬","🐳","🐋","🦈","🐊","🐅","🐆","🦓","🦍","🦧","🐘","🦛","🦏","🐪","🐫","🦒","🦘","🐃","🐂","🐄","🐎","🐖","🐏","🐑","🦙","🐐","🦌","🐕","🐩","🦮","🐕🦺","🐈","🐋","🐳","🐬","🐉","🐲"];
|
||||
const placeholder = document.querySelector('.emoji-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.textContent = emojis[Math.floor(Math.random() * emojis.length)];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="tb-mobile-utils">
|
||||
|
||||
<button type="button" id="theme-toggle-mobile" class="uk-button uk-button-default uk-button-small"
|
||||
title="切换深色/浅色模式" aria-label="切换深色/浅色模式">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
var THEME_COOKIE = 'theme';
|
||||
function getTheme() {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
return m ? m[1] : '';
|
||||
}
|
||||
function applyTheme(theme) {
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
}
|
||||
}
|
||||
function toggleTheme() {
|
||||
var next = getTheme() === 'dark' ? 'light' : 'dark';
|
||||
applyTheme(next);
|
||||
var expires = new Date(Date.now() + 365 * 24 * 3600 * 1000).toUTCString();
|
||||
document.cookie = THEME_COOKIE + '=' + next + '; path=/; max-age=' + (365 * 24 * 3600) + '; SameSite=Lax';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
var buttons = document.querySelectorAll('#theme-toggle, #theme-toggle-mobile');
|
||||
buttons.forEach(function(btn) {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
toggleTheme();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var langSel = document.getElementById('mobile-lang-select');
|
||||
if (langSel) {
|
||||
langSel.addEventListener('change', function() {
|
||||
if (!this.value) return;
|
||||
var to = window.location.pathname + window.location.search;
|
||||
window.location.href = '/i18n/' + encodeURIComponent(this.value) + '?to=' + encodeURIComponent(to);
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-container uk-container-xsmall">
|
||||
|
||||
|
||||
|
||||
<div id="math-captcha-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body uk-text-center">
|
||||
<h3 class="uk-modal-title">人机验证</h3>
|
||||
<p class="uk-text-meta">请计算下方的算术题以验证你不是机器人</p>
|
||||
<div class="captcha-equation-box">
|
||||
<span id="captcha-modal-question" class="math-captcha-modal-question">加载中...</span>
|
||||
<input type="number" id="captcha-modal-answer" placeholder="?" autocomplete="off" inputmode="numeric">
|
||||
</div>
|
||||
<div style="margin-top:6px;">
|
||||
<button type="button" class="uk-button uk-button-text uk-text-small" id="captcha-modal-refresh">换一题</button>
|
||||
</div>
|
||||
<div id="captcha-modal-error" class="uk-text-danger uk-text-small" style="display:none;min-height:20px;"></div>
|
||||
<div class="uk-margin-small-top">
|
||||
<button type="button" class="uk-button uk-button-primary" id="captcha-modal-submit">提交</button>
|
||||
<button type="button" class="uk-button uk-button-default uk-modal-close">取消</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var CAPTCHA_I18N = {
|
||||
loading: "加载中...",
|
||||
loadFailed: "加载失败",
|
||||
loadRetry: "加载失败,请重试",
|
||||
inputAnswer: "请输入答案",
|
||||
wrongAnswer: "答案错误,请重新计算",
|
||||
verifyFailed: "验证失败,请重试",
|
||||
needPassword: "此提问箱需要密码",
|
||||
needEmail: "请填写接收通知的邮箱地址"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var captchaId = '';
|
||||
var pendingForm = null;
|
||||
var pendingNeedPassword = false;
|
||||
var verifying = false;
|
||||
|
||||
function fetchCaptcha() {
|
||||
var qEl = document.getElementById('captcha-modal-question');
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
var ansEl = document.getElementById('captcha-modal-answer');
|
||||
qEl.textContent = CAPTCHA_I18N.loading;
|
||||
fetch('/api/captcha/generate')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.code === 0 && data.data) {
|
||||
captchaId = data.data.id;
|
||||
qEl.textContent = data.data.question;
|
||||
if (errEl) errEl.style.display = 'none';
|
||||
if (ansEl) { ansEl.value = ''; ansEl.focus(); }
|
||||
} else {
|
||||
qEl.textContent = CAPTCHA_I18N.loadFailed;
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
qEl.textContent = CAPTCHA_I18N.loadRetry;
|
||||
});
|
||||
}
|
||||
|
||||
function getCSRFToken() {
|
||||
var input = document.querySelector('input[name="_csrf"]');
|
||||
return input ? input.value : '';
|
||||
}
|
||||
|
||||
function doSubmit(form) {
|
||||
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
var hidden = form.querySelector('[name="g-recaptcha-response"]');
|
||||
if (hidden) hidden.value = captchaId + ':' + (ans || '0');
|
||||
|
||||
UIkit.modal('#math-captcha-modal').hide();
|
||||
|
||||
|
||||
if (pendingNeedPassword) {
|
||||
UIkit.modal.prompt(CAPTCHA_I18N.needPassword, '', 'password')
|
||||
.then(function(password) {
|
||||
if (password) {
|
||||
var pwInput = document.getElementById('ask_password_input');
|
||||
if (pwInput) pwInput.value = password;
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-submit').addEventListener('click', function() {
|
||||
if (verifying) return;
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
if (!ans) {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.inputAnswer;
|
||||
errEl.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
verifying = true;
|
||||
fetch('/api/captcha/verify', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-Token': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify({ id: captchaId, answer: parseInt(ans, 10) })
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
verifying = false;
|
||||
if (data.correct) {
|
||||
if (pendingForm) doSubmit(pendingForm);
|
||||
} else {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.wrongAnswer;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
verifying = false;
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.verifyFailed;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-answer').addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
document.getElementById('captcha-modal-submit').click();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-refresh').addEventListener('click', fetchCaptcha);
|
||||
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target.closest('.math-captcha-trigger');
|
||||
if (!btn) return;
|
||||
e.preventDefault();
|
||||
|
||||
var form = btn.closest('form');
|
||||
if (!form) return;
|
||||
pendingForm = form;
|
||||
|
||||
|
||||
pendingNeedPassword = !!(form.querySelector('#ask_password_input'));
|
||||
|
||||
|
||||
var notifyCb = document.getElementById('notify-checkbox');
|
||||
var emailInput = document.getElementById('email-input');
|
||||
if (notifyCb && notifyCb.checked && emailInput && emailInput.value.trim() === '') {
|
||||
UIkit.modal.alert(CAPTCHA_I18N.needEmail);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchCaptcha();
|
||||
UIkit.modal('#math-captcha-modal').show();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-flex-middle uk-margin-bottom">
|
||||
<h3 class="uk-margin-remove">投票结果:测试5</h3>
|
||||
<div class="uk-flex uk-flex-middle" style="gap: 8px;">
|
||||
<a class="uk-button uk-button-default uk-button-small" href="/user/votes/7/export">导出 CSV</a>
|
||||
<a class="uk-button uk-button-default uk-button-small" href="/user/questions#votes">返回</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-small uk-card-body uk-margin-bottom">
|
||||
<div class="uk-text-large uk-text-bold">0</div>
|
||||
<div class="uk-text-meta">总参与人数</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<h4>投票结果</h4>
|
||||
<div class="uk-card uk-card-default uk-card-small uk-card-body">
|
||||
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>1</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>2</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
function toggleFieldReplies(id) {
|
||||
var box = document.getElementById('replies-' + id);
|
||||
var caret = document.getElementById('caret-' + id);
|
||||
if (!box) { return; }
|
||||
if (box.hasAttribute('hidden')) {
|
||||
box.removeAttribute('hidden');
|
||||
if (caret) { caret.style.transform = 'rotate(0deg)'; }
|
||||
} else {
|
||||
box.setAttribute('hidden', '');
|
||||
if (caret) { caret.style.transform = 'rotate(-90deg)'; }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<p class=" uk-text-right uk-text-muted uk-text-small">
|
||||
<br>
|
||||
<a href="/rules">社区规则</a> |
|
||||
|
||||
<a href="https://box.shiroko.one/_/tamakyi" target="_blank">找站长</a>
|
||||
<br>
|
||||
<a href="https://share.shiroko.one" target="_blank">盘</a>
|
||||
| <a href="https://blog.shiroko.one" target="_blank">公告板</a>
|
||||
| <a href="https://chat.shiroko.one" target="_blank">聊天室</a>
|
||||
| <a href="https://status.shiroko.one" target="_blank">监控板</a>
|
||||
| <a href="https://shiroko.one" target="_blank">导航页</a>
|
||||
<br>Powered by NekoBox | 狼ICP备 20230101
|
||||
<br>提问箱已成功存活:<span id="box_runtime"></span>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
(function () {
|
||||
var create = Math.round(Date.UTC(2023, 6, 1, 18, 15, 43) / 1000);
|
||||
function tick() {
|
||||
var el = document.getElementById("box_runtime");
|
||||
if (!el) return;
|
||||
var s = Math.round((Date.now() + 8 * 3600 * 1000) / 1000) - create;
|
||||
var t = [0, 0, 0, 0, 0];
|
||||
if (s >= 31536000) { t[0] = s / 31536000 | 0; s %= 31536000; }
|
||||
if (s >= 86400) { t[1] = s / 86400 | 0; s %= 86400; }
|
||||
if (s >= 3600) { t[2] = s / 3600 | 0; s %= 3600; }
|
||||
if (s >= 60) { t[3] = s / 60 | 0; s %= 60; }
|
||||
if (s > 0) { t[4] = s; }
|
||||
el.innerHTML = t[0] + '年 ' + t[1] + '天 ' + t[2] + '时 ' + t[3] + '分 ' + t[4] + '秒 ';
|
||||
}
|
||||
tick();
|
||||
setInterval(tick, 1000);
|
||||
})();
|
||||
</script>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
var SUBMIT_I18N = {
|
||||
submitting: '提交中...',
|
||||
uploading: '上传中...'
|
||||
};
|
||||
|
||||
function tbResetSubmitButtons() {
|
||||
document.querySelectorAll('button[data-tb-submitting]').forEach(function(b) {
|
||||
b.disabled = false;
|
||||
b.removeAttribute('data-tb-submitting');
|
||||
var orig = b.getAttribute('data-tb-restore');
|
||||
if (orig !== null) {
|
||||
b.innerHTML = orig;
|
||||
b.removeAttribute('data-tb-restore');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('submit', function(e) {
|
||||
var form = e.target;
|
||||
if (!form || form.tagName !== 'FORM') return;
|
||||
|
||||
|
||||
|
||||
if (e.defaultPrevented || form.getAttribute('data-tb-skip-submit-feedback') === '1') {
|
||||
form.removeAttribute('data-tb-skip-submit-feedback');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (form.getAttribute('target') === '_blank') return;
|
||||
|
||||
|
||||
var trigger = e.submitter || form.querySelector('button[type="submit"]');
|
||||
|
||||
|
||||
var hasFile = false;
|
||||
form.querySelectorAll('input[type="file"]').forEach(function(f) {
|
||||
if (f.files && f.files.length > 0) hasFile = true;
|
||||
});
|
||||
var label = hasFile ? SUBMIT_I18N.uploading : SUBMIT_I18N.submitting;
|
||||
|
||||
if (trigger && trigger.tagName === 'BUTTON') {
|
||||
trigger.setAttribute('data-tb-restore', trigger.innerHTML);
|
||||
trigger.innerHTML = '<span uk-spinner="ratio: 0.6"></span> ' + label;
|
||||
}
|
||||
|
||||
|
||||
form.querySelectorAll('button').forEach(function(b) {
|
||||
b.disabled = true;
|
||||
b.setAttribute('data-tb-submitting', '1');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener('pageshow', tbResetSubmitButtons);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,628 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>投票结果</title>
|
||||
<meta name="msvalidate.01" content="2F185E8E63C93635F50B3574F3B31E42" />
|
||||
<meta name="description" content="狼的提问箱——一个无需注册、可匿名提问的匿名提问箱,安全地倾诉与回应。">
|
||||
<meta name="keywords" content="匿名提问箱,提问箱,匿名提问,狼的提问箱,匿名问答,匿名提问网站">
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
if (m && m[1] === 'dark') document.documentElement.setAttribute('data-theme', 'dark');
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://r2.337845818.best" crossorigin>
|
||||
<link rel="preconnect" href="https://cdnjs.snrat.com" crossorigin>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/css/uikit.min.css"/>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/base.css?v=20261019c"/>
|
||||
|
||||
<link rel="stylesheet" href="https://r2.337845818.best/tamabox/cdn/waline/client/v2/waline-no-commits.css" media="print" onload="this.media='all'"/>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit-icons.min.js"></script>
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/dayjs/1.10.8/dayjs.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/alpinejs/3.9.0/cdn.min.js"></script>
|
||||
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/waline/2.15.8/waline.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.captcha-equation-box {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: #f0f2f5;
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 8px;
|
||||
padding: 8px 8px 8px 16px;
|
||||
gap: 6px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
.captcha-equation-box:focus-within {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 3px rgba(30,135,240,0.12);
|
||||
}
|
||||
.math-captcha-modal-question {
|
||||
font-size: 1.4rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
letter-spacing: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
width: 80px;
|
||||
padding: 6px 10px;
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 600;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
transition: border-color 0.15s, box-shadow 0.15s;
|
||||
background: #fff;
|
||||
}
|
||||
#captcha-modal-answer:focus {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 2px rgba(30,135,240,0.2);
|
||||
}
|
||||
|
||||
#captcha-modal-answer::-webkit-inner-spin-button,
|
||||
#captcha-modal-answer::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta property="og:site_name" content="狼的提问箱 | 匿名提问箱" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content=" - 狼的提问箱 | 匿名提问箱" />
|
||||
<meta property="og:url" content="https://box-dev-api.337845818.best/user/votes/8/results" />
|
||||
<meta property="og:description" content=" - 狼的提问箱——一个无需注册、可匿名提问的匿名提问箱,安全地倾诉与回应。" />
|
||||
<meta name="robots" content="noindex">
|
||||
|
||||
<meta property="og:image" content="?og-image=1" />
|
||||
<meta property="og:image:alt" content="" />
|
||||
<meta itemprop="image" content="?og-image=1"/>
|
||||
<meta name="msapplication-TileImage" content=""/>
|
||||
<link rel="shortcut icon" href="?og-image=1"/>
|
||||
<link rel="apple-touch-icon" href="?og-image=1"/>
|
||||
<link rel="icon" sizes="192x192" href="?og-image=1">
|
||||
<meta name="twitter:image:src" content="?og-image=1" />
|
||||
|
||||
|
||||
|
||||
<meta name="google-site-verification" content="fEPwRRJfiGsgwc5SINBQwZhPK8F0cwRaOvRx0YRurI4" />
|
||||
|
||||
<script>
|
||||
window.addEventListener("load", function () {
|
||||
var s = document.createElement("script");
|
||||
s.src = "https://mami.shiroko.one/tamami.js";
|
||||
s.setAttribute("data-website-id", "c42ebe8b-9281-4da0-83a4-8f18b3e710fe");
|
||||
document.body.appendChild(s);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window.tbRenderQR = function (el, getOptions) {
|
||||
if (!el || typeof QRCode === 'undefined') return;
|
||||
var opts = getOptions();
|
||||
function remoteOf(o, key) {
|
||||
var v = o[key];
|
||||
return (typeof v === 'string' && v.indexOf('http') === 0) ? v : '';
|
||||
}
|
||||
var good = window._tbQrGood || (window._tbQrGood = {});
|
||||
var bad = window._tbQrBad || (window._tbQrBad = {});
|
||||
|
||||
function layerState(url) { return !url ? '' : (good[url] ? 1 : (bad[url] ? 0 : null)); }
|
||||
var layers = [
|
||||
{ url: remoteOf(opts, 'logo'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.logo = undefined; o.logoWidth = undefined; o.logoHeight = undefined; o.logoBackgroundTransparent = undefined; }
|
||||
} },
|
||||
{ url: remoteOf(opts, 'backgroundImage'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.backgroundImage = undefined; o.backgroundImageAlpha = undefined; }
|
||||
} }
|
||||
];
|
||||
var needProbe = false;
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
layers[i].st = layerState(layers[i].url);
|
||||
if (layers[i].st === null) needProbe = true;
|
||||
}
|
||||
function paint(states) {
|
||||
var o = {};
|
||||
for (var k in opts) o[k] = opts[k];
|
||||
for (var j = 0; j < layers.length; j++) layers[j].present(o, states[j] === 1);
|
||||
el.innerHTML = '';
|
||||
new QRCode(el, o);
|
||||
}
|
||||
|
||||
var initStates = [];
|
||||
for (var n = 0; n < layers.length; n++) initStates.push(layers[n].st === 1 ? 1 : 0);
|
||||
paint(initStates);
|
||||
if (!needProbe) return;
|
||||
|
||||
var pending = 0, cross = opts.crossOrigin || 'anonymous';
|
||||
layers.forEach(function (L) {
|
||||
if (L.st !== null) return;
|
||||
pending++;
|
||||
var im = new Image();
|
||||
im.onload = function () { good[L.url] = true; L.st = 1; onDone(); };
|
||||
im.onerror = function () { bad[L.url] = true; L.st = 0; onDone(); };
|
||||
if (cross) im.crossOrigin = cross;
|
||||
im.src = L.url;
|
||||
});
|
||||
function onDone() {
|
||||
if (--pending > 0) return;
|
||||
var finalStates = [];
|
||||
for (var m = 0; m < layers.length; m++) finalStates.push(layers[m].st === 1 ? 1 : 0);
|
||||
var changed = false;
|
||||
for (var q = 0; q < finalStates.length; q++) if (finalStates[q] !== initStates[q]) changed = true;
|
||||
if (changed) paint(finalStates);
|
||||
}
|
||||
|
||||
setTimeout(function () { if (pending > 0) { pending = 0; onDone(); } }, 3000);
|
||||
};
|
||||
</script>
|
||||
<nav class="uk-navbar-container uk-margin tb-navbar" uk-navbar>
|
||||
<div class="uk-navbar-center">
|
||||
<div class="uk-navbar-center-left">
|
||||
<div>
|
||||
<ul class="uk-navbar-nav">
|
||||
|
||||
<li><a href="/explore">探索</a></li>
|
||||
|
||||
|
||||
<li><a href="/_/admin6">我的</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="uk-navbar-item uk-logo" href="/"><span class="emoji-placeholder" aria-label="random animal">🐺</span>的提问箱</a>
|
||||
|
||||
<div class="uk-navbar-center-right">
|
||||
<div>
|
||||
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/user/questions">提问</a></li>
|
||||
</ul>
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/user/profile">设置</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" id="theme-toggle" title="切换深色/浅色模式" aria-label="切换深色/浅色模式">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const emojis = ["🐺","🐗","🐻","🐨","🐼","🐹","🐭","🐰","🦊","🐮","🐷","🐽","🐸","🐒","🦍","🐔","🐧","🐦","🐤","🐦⬛","🦅","🦉","🦇","🐴","🦄","🐝","🦎","🦖","🦕","🐙","🦑","🦐","🦞","🦀","🐡","🐠","🐟","🐬","🐳","🐋","🦈","🐊","🐅","🐆","🦓","🦍","🦧","🐘","🦛","🦏","🐪","🐫","🦒","🦘","🐃","🐂","🐄","🐎","🐖","🐏","🐑","🦙","🐐","🦌","🐕","🐩","🦮","🐕🦺","🐈","🐋","🐳","🐬","🐉","🐲"];
|
||||
const placeholder = document.querySelector('.emoji-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.textContent = emojis[Math.floor(Math.random() * emojis.length)];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="tb-mobile-utils">
|
||||
|
||||
<button type="button" id="theme-toggle-mobile" class="uk-button uk-button-default uk-button-small"
|
||||
title="切换深色/浅色模式" aria-label="切换深色/浅色模式">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
var THEME_COOKIE = 'theme';
|
||||
function getTheme() {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
return m ? m[1] : '';
|
||||
}
|
||||
function applyTheme(theme) {
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
}
|
||||
}
|
||||
function toggleTheme() {
|
||||
var next = getTheme() === 'dark' ? 'light' : 'dark';
|
||||
applyTheme(next);
|
||||
var expires = new Date(Date.now() + 365 * 24 * 3600 * 1000).toUTCString();
|
||||
document.cookie = THEME_COOKIE + '=' + next + '; path=/; max-age=' + (365 * 24 * 3600) + '; SameSite=Lax';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
var buttons = document.querySelectorAll('#theme-toggle, #theme-toggle-mobile');
|
||||
buttons.forEach(function(btn) {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
toggleTheme();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var langSel = document.getElementById('mobile-lang-select');
|
||||
if (langSel) {
|
||||
langSel.addEventListener('change', function() {
|
||||
if (!this.value) return;
|
||||
var to = window.location.pathname + window.location.search;
|
||||
window.location.href = '/i18n/' + encodeURIComponent(this.value) + '?to=' + encodeURIComponent(to);
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-container uk-container-xsmall">
|
||||
|
||||
|
||||
|
||||
<div id="math-captcha-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body uk-text-center">
|
||||
<h3 class="uk-modal-title">人机验证</h3>
|
||||
<p class="uk-text-meta">请计算下方的算术题以验证你不是机器人</p>
|
||||
<div class="captcha-equation-box">
|
||||
<span id="captcha-modal-question" class="math-captcha-modal-question">加载中...</span>
|
||||
<input type="number" id="captcha-modal-answer" placeholder="?" autocomplete="off" inputmode="numeric">
|
||||
</div>
|
||||
<div style="margin-top:6px;">
|
||||
<button type="button" class="uk-button uk-button-text uk-text-small" id="captcha-modal-refresh">换一题</button>
|
||||
</div>
|
||||
<div id="captcha-modal-error" class="uk-text-danger uk-text-small" style="display:none;min-height:20px;"></div>
|
||||
<div class="uk-margin-small-top">
|
||||
<button type="button" class="uk-button uk-button-primary" id="captcha-modal-submit">提交</button>
|
||||
<button type="button" class="uk-button uk-button-default uk-modal-close">取消</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var CAPTCHA_I18N = {
|
||||
loading: "加载中...",
|
||||
loadFailed: "加载失败",
|
||||
loadRetry: "加载失败,请重试",
|
||||
inputAnswer: "请输入答案",
|
||||
wrongAnswer: "答案错误,请重新计算",
|
||||
verifyFailed: "验证失败,请重试",
|
||||
needPassword: "此提问箱需要密码",
|
||||
needEmail: "请填写接收通知的邮箱地址"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var captchaId = '';
|
||||
var pendingForm = null;
|
||||
var pendingNeedPassword = false;
|
||||
var verifying = false;
|
||||
|
||||
function fetchCaptcha() {
|
||||
var qEl = document.getElementById('captcha-modal-question');
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
var ansEl = document.getElementById('captcha-modal-answer');
|
||||
qEl.textContent = CAPTCHA_I18N.loading;
|
||||
fetch('/api/captcha/generate')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.code === 0 && data.data) {
|
||||
captchaId = data.data.id;
|
||||
qEl.textContent = data.data.question;
|
||||
if (errEl) errEl.style.display = 'none';
|
||||
if (ansEl) { ansEl.value = ''; ansEl.focus(); }
|
||||
} else {
|
||||
qEl.textContent = CAPTCHA_I18N.loadFailed;
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
qEl.textContent = CAPTCHA_I18N.loadRetry;
|
||||
});
|
||||
}
|
||||
|
||||
function getCSRFToken() {
|
||||
var input = document.querySelector('input[name="_csrf"]');
|
||||
return input ? input.value : '';
|
||||
}
|
||||
|
||||
function doSubmit(form) {
|
||||
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
var hidden = form.querySelector('[name="g-recaptcha-response"]');
|
||||
if (hidden) hidden.value = captchaId + ':' + (ans || '0');
|
||||
|
||||
UIkit.modal('#math-captcha-modal').hide();
|
||||
|
||||
|
||||
if (pendingNeedPassword) {
|
||||
UIkit.modal.prompt(CAPTCHA_I18N.needPassword, '', 'password')
|
||||
.then(function(password) {
|
||||
if (password) {
|
||||
var pwInput = document.getElementById('ask_password_input');
|
||||
if (pwInput) pwInput.value = password;
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-submit').addEventListener('click', function() {
|
||||
if (verifying) return;
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
if (!ans) {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.inputAnswer;
|
||||
errEl.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
verifying = true;
|
||||
fetch('/api/captcha/verify', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-Token': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify({ id: captchaId, answer: parseInt(ans, 10) })
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
verifying = false;
|
||||
if (data.correct) {
|
||||
if (pendingForm) doSubmit(pendingForm);
|
||||
} else {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.wrongAnswer;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
verifying = false;
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.verifyFailed;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-answer').addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
document.getElementById('captcha-modal-submit').click();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-refresh').addEventListener('click', fetchCaptcha);
|
||||
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target.closest('.math-captcha-trigger');
|
||||
if (!btn) return;
|
||||
e.preventDefault();
|
||||
|
||||
var form = btn.closest('form');
|
||||
if (!form) return;
|
||||
pendingForm = form;
|
||||
|
||||
|
||||
pendingNeedPassword = !!(form.querySelector('#ask_password_input'));
|
||||
|
||||
|
||||
var notifyCb = document.getElementById('notify-checkbox');
|
||||
var emailInput = document.getElementById('email-input');
|
||||
if (notifyCb && notifyCb.checked && emailInput && emailInput.value.trim() === '') {
|
||||
UIkit.modal.alert(CAPTCHA_I18N.needEmail);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchCaptcha();
|
||||
UIkit.modal('#math-captcha-modal').show();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-flex-middle uk-margin-bottom">
|
||||
<h3 class="uk-margin-remove">投票结果:测试7</h3>
|
||||
<div class="uk-flex uk-flex-middle" style="gap: 8px;">
|
||||
<a class="uk-button uk-button-default uk-button-small" href="/user/votes/8/export">导出 CSV</a>
|
||||
<a class="uk-button uk-button-default uk-button-small" href="/user/questions#votes">返回</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-small uk-card-body uk-margin-bottom">
|
||||
<div class="uk-text-large uk-text-bold">0</div>
|
||||
<div class="uk-text-meta">总参与人数</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<h4>投票结果</h4>
|
||||
<div class="uk-card uk-card-default uk-card-small uk-card-body">
|
||||
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>11</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-between">
|
||||
<span>22</span>
|
||||
<span class="uk-text-meta">0 票(0%)</span>
|
||||
</div>
|
||||
<progress class="uk-progress uk-margin-small-top" value="0" max="100"></progress>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
function toggleFieldReplies(id) {
|
||||
var box = document.getElementById('replies-' + id);
|
||||
var caret = document.getElementById('caret-' + id);
|
||||
if (!box) { return; }
|
||||
if (box.hasAttribute('hidden')) {
|
||||
box.removeAttribute('hidden');
|
||||
if (caret) { caret.style.transform = 'rotate(0deg)'; }
|
||||
} else {
|
||||
box.setAttribute('hidden', '');
|
||||
if (caret) { caret.style.transform = 'rotate(-90deg)'; }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<p class=" uk-text-right uk-text-muted uk-text-small">
|
||||
<br>
|
||||
<a href="/rules">社区规则</a> |
|
||||
|
||||
<a href="https://box.shiroko.one/_/tamakyi" target="_blank">找站长</a>
|
||||
<br>
|
||||
<a href="https://share.shiroko.one" target="_blank">盘</a>
|
||||
| <a href="https://blog.shiroko.one" target="_blank">公告板</a>
|
||||
| <a href="https://chat.shiroko.one" target="_blank">聊天室</a>
|
||||
| <a href="https://status.shiroko.one" target="_blank">监控板</a>
|
||||
| <a href="https://shiroko.one" target="_blank">导航页</a>
|
||||
<br>Powered by NekoBox | 狼ICP备 20230101
|
||||
<br>提问箱已成功存活:<span id="box_runtime"></span>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
(function () {
|
||||
var create = Math.round(Date.UTC(2023, 6, 1, 18, 15, 43) / 1000);
|
||||
function tick() {
|
||||
var el = document.getElementById("box_runtime");
|
||||
if (!el) return;
|
||||
var s = Math.round((Date.now() + 8 * 3600 * 1000) / 1000) - create;
|
||||
var t = [0, 0, 0, 0, 0];
|
||||
if (s >= 31536000) { t[0] = s / 31536000 | 0; s %= 31536000; }
|
||||
if (s >= 86400) { t[1] = s / 86400 | 0; s %= 86400; }
|
||||
if (s >= 3600) { t[2] = s / 3600 | 0; s %= 3600; }
|
||||
if (s >= 60) { t[3] = s / 60 | 0; s %= 60; }
|
||||
if (s > 0) { t[4] = s; }
|
||||
el.innerHTML = t[0] + '年 ' + t[1] + '天 ' + t[2] + '时 ' + t[3] + '分 ' + t[4] + '秒 ';
|
||||
}
|
||||
tick();
|
||||
setInterval(tick, 1000);
|
||||
})();
|
||||
</script>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
var SUBMIT_I18N = {
|
||||
submitting: '提交中...',
|
||||
uploading: '上传中...'
|
||||
};
|
||||
|
||||
function tbResetSubmitButtons() {
|
||||
document.querySelectorAll('button[data-tb-submitting]').forEach(function(b) {
|
||||
b.disabled = false;
|
||||
b.removeAttribute('data-tb-submitting');
|
||||
var orig = b.getAttribute('data-tb-restore');
|
||||
if (orig !== null) {
|
||||
b.innerHTML = orig;
|
||||
b.removeAttribute('data-tb-restore');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('submit', function(e) {
|
||||
var form = e.target;
|
||||
if (!form || form.tagName !== 'FORM') return;
|
||||
|
||||
|
||||
|
||||
if (e.defaultPrevented || form.getAttribute('data-tb-skip-submit-feedback') === '1') {
|
||||
form.removeAttribute('data-tb-skip-submit-feedback');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (form.getAttribute('target') === '_blank') return;
|
||||
|
||||
|
||||
var trigger = e.submitter || form.querySelector('button[type="submit"]');
|
||||
|
||||
|
||||
var hasFile = false;
|
||||
form.querySelectorAll('input[type="file"]').forEach(function(f) {
|
||||
if (f.files && f.files.length > 0) hasFile = true;
|
||||
});
|
||||
var label = hasFile ? SUBMIT_I18N.uploading : SUBMIT_I18N.submitting;
|
||||
|
||||
if (trigger && trigger.tagName === 'BUTTON') {
|
||||
trigger.setAttribute('data-tb-restore', trigger.innerHTML);
|
||||
trigger.innerHTML = '<span uk-spinner="ratio: 0.6"></span> ' + label;
|
||||
}
|
||||
|
||||
|
||||
form.querySelectorAll('button').forEach(function(b) {
|
||||
b.disabled = true;
|
||||
b.setAttribute('data-tb-submitting', '1');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener('pageshow', tbResetSubmitButtons);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,626 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>投票结果</title>
|
||||
<meta name="msvalidate.01" content="2F185E8E63C93635F50B3574F3B31E42" />
|
||||
<meta name="description" content="狼的提问箱——一个无需注册、可匿名提问的匿名提问箱,安全地倾诉与回应。">
|
||||
<meta name="keywords" content="匿名提问箱,提问箱,匿名提问,狼的提问箱,匿名问答,匿名提问网站">
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
if (m && m[1] === 'dark') document.documentElement.setAttribute('data-theme', 'dark');
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://r2.337845818.best" crossorigin>
|
||||
<link rel="preconnect" href="https://cdnjs.snrat.com" crossorigin>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/css/uikit.min.css"/>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/base.css?v=20261019c"/>
|
||||
|
||||
<link rel="stylesheet" href="https://r2.337845818.best/tamabox/cdn/waline/client/v2/waline-no-commits.css" media="print" onload="this.media='all'"/>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit-icons.min.js"></script>
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/dayjs/1.10.8/dayjs.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/alpinejs/3.9.0/cdn.min.js"></script>
|
||||
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/waline/2.15.8/waline.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.captcha-equation-box {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: #f0f2f5;
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 8px;
|
||||
padding: 8px 8px 8px 16px;
|
||||
gap: 6px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
.captcha-equation-box:focus-within {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 3px rgba(30,135,240,0.12);
|
||||
}
|
||||
.math-captcha-modal-question {
|
||||
font-size: 1.4rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
letter-spacing: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
width: 80px;
|
||||
padding: 6px 10px;
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 600;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
transition: border-color 0.15s, box-shadow 0.15s;
|
||||
background: #fff;
|
||||
}
|
||||
#captcha-modal-answer:focus {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 2px rgba(30,135,240,0.2);
|
||||
}
|
||||
|
||||
#captcha-modal-answer::-webkit-inner-spin-button,
|
||||
#captcha-modal-answer::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta property="og:site_name" content="狼的提问箱 | 匿名提问箱" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content=" - 狼的提问箱 | 匿名提问箱" />
|
||||
<meta property="og:url" content="https://box-dev-api.337845818.best/user/votes/9/results" />
|
||||
<meta property="og:description" content=" - 狼的提问箱——一个无需注册、可匿名提问的匿名提问箱,安全地倾诉与回应。" />
|
||||
<meta name="robots" content="noindex">
|
||||
|
||||
<meta property="og:image" content="?og-image=1" />
|
||||
<meta property="og:image:alt" content="" />
|
||||
<meta itemprop="image" content="?og-image=1"/>
|
||||
<meta name="msapplication-TileImage" content=""/>
|
||||
<link rel="shortcut icon" href="?og-image=1"/>
|
||||
<link rel="apple-touch-icon" href="?og-image=1"/>
|
||||
<link rel="icon" sizes="192x192" href="?og-image=1">
|
||||
<meta name="twitter:image:src" content="?og-image=1" />
|
||||
|
||||
|
||||
|
||||
<meta name="google-site-verification" content="fEPwRRJfiGsgwc5SINBQwZhPK8F0cwRaOvRx0YRurI4" />
|
||||
|
||||
<script>
|
||||
window.addEventListener("load", function () {
|
||||
var s = document.createElement("script");
|
||||
s.src = "https://mami.shiroko.one/tamami.js";
|
||||
s.setAttribute("data-website-id", "c42ebe8b-9281-4da0-83a4-8f18b3e710fe");
|
||||
document.body.appendChild(s);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window.tbRenderQR = function (el, getOptions) {
|
||||
if (!el || typeof QRCode === 'undefined') return;
|
||||
var opts = getOptions();
|
||||
function remoteOf(o, key) {
|
||||
var v = o[key];
|
||||
return (typeof v === 'string' && v.indexOf('http') === 0) ? v : '';
|
||||
}
|
||||
var good = window._tbQrGood || (window._tbQrGood = {});
|
||||
var bad = window._tbQrBad || (window._tbQrBad = {});
|
||||
|
||||
function layerState(url) { return !url ? '' : (good[url] ? 1 : (bad[url] ? 0 : null)); }
|
||||
var layers = [
|
||||
{ url: remoteOf(opts, 'logo'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.logo = undefined; o.logoWidth = undefined; o.logoHeight = undefined; o.logoBackgroundTransparent = undefined; }
|
||||
} },
|
||||
{ url: remoteOf(opts, 'backgroundImage'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.backgroundImage = undefined; o.backgroundImageAlpha = undefined; }
|
||||
} }
|
||||
];
|
||||
var needProbe = false;
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
layers[i].st = layerState(layers[i].url);
|
||||
if (layers[i].st === null) needProbe = true;
|
||||
}
|
||||
function paint(states) {
|
||||
var o = {};
|
||||
for (var k in opts) o[k] = opts[k];
|
||||
for (var j = 0; j < layers.length; j++) layers[j].present(o, states[j] === 1);
|
||||
el.innerHTML = '';
|
||||
new QRCode(el, o);
|
||||
}
|
||||
|
||||
var initStates = [];
|
||||
for (var n = 0; n < layers.length; n++) initStates.push(layers[n].st === 1 ? 1 : 0);
|
||||
paint(initStates);
|
||||
if (!needProbe) return;
|
||||
|
||||
var pending = 0, cross = opts.crossOrigin || 'anonymous';
|
||||
layers.forEach(function (L) {
|
||||
if (L.st !== null) return;
|
||||
pending++;
|
||||
var im = new Image();
|
||||
im.onload = function () { good[L.url] = true; L.st = 1; onDone(); };
|
||||
im.onerror = function () { bad[L.url] = true; L.st = 0; onDone(); };
|
||||
if (cross) im.crossOrigin = cross;
|
||||
im.src = L.url;
|
||||
});
|
||||
function onDone() {
|
||||
if (--pending > 0) return;
|
||||
var finalStates = [];
|
||||
for (var m = 0; m < layers.length; m++) finalStates.push(layers[m].st === 1 ? 1 : 0);
|
||||
var changed = false;
|
||||
for (var q = 0; q < finalStates.length; q++) if (finalStates[q] !== initStates[q]) changed = true;
|
||||
if (changed) paint(finalStates);
|
||||
}
|
||||
|
||||
setTimeout(function () { if (pending > 0) { pending = 0; onDone(); } }, 3000);
|
||||
};
|
||||
</script>
|
||||
<nav class="uk-navbar-container uk-margin tb-navbar" uk-navbar>
|
||||
<div class="uk-navbar-center">
|
||||
<div class="uk-navbar-center-left">
|
||||
<div>
|
||||
<ul class="uk-navbar-nav">
|
||||
|
||||
<li><a href="/explore">探索</a></li>
|
||||
|
||||
|
||||
<li><a href="/_/admin6">我的</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="uk-navbar-item uk-logo" href="/"><span class="emoji-placeholder" aria-label="random animal">🐺</span>的提问箱</a>
|
||||
|
||||
<div class="uk-navbar-center-right">
|
||||
<div>
|
||||
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/user/questions">提问</a></li>
|
||||
</ul>
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/user/profile">设置</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" id="theme-toggle" title="切换深色/浅色模式" aria-label="切换深色/浅色模式">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const emojis = ["🐺","🐗","🐻","🐨","🐼","🐹","🐭","🐰","🦊","🐮","🐷","🐽","🐸","🐒","🦍","🐔","🐧","🐦","🐤","🐦⬛","🦅","🦉","🦇","🐴","🦄","🐝","🦎","🦖","🦕","🐙","🦑","🦐","🦞","🦀","🐡","🐠","🐟","🐬","🐳","🐋","🦈","🐊","🐅","🐆","🦓","🦍","🦧","🐘","🦛","🦏","🐪","🐫","🦒","🦘","🐃","🐂","🐄","🐎","🐖","🐏","🐑","🦙","🐐","🦌","🐕","🐩","🦮","🐕🦺","🐈","🐋","🐳","🐬","🐉","🐲"];
|
||||
const placeholder = document.querySelector('.emoji-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.textContent = emojis[Math.floor(Math.random() * emojis.length)];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="tb-mobile-utils">
|
||||
|
||||
<button type="button" id="theme-toggle-mobile" class="uk-button uk-button-default uk-button-small"
|
||||
title="切换深色/浅色模式" aria-label="切换深色/浅色模式">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
var THEME_COOKIE = 'theme';
|
||||
function getTheme() {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
return m ? m[1] : '';
|
||||
}
|
||||
function applyTheme(theme) {
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
}
|
||||
}
|
||||
function toggleTheme() {
|
||||
var next = getTheme() === 'dark' ? 'light' : 'dark';
|
||||
applyTheme(next);
|
||||
var expires = new Date(Date.now() + 365 * 24 * 3600 * 1000).toUTCString();
|
||||
document.cookie = THEME_COOKIE + '=' + next + '; path=/; max-age=' + (365 * 24 * 3600) + '; SameSite=Lax';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
var buttons = document.querySelectorAll('#theme-toggle, #theme-toggle-mobile');
|
||||
buttons.forEach(function(btn) {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
toggleTheme();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var langSel = document.getElementById('mobile-lang-select');
|
||||
if (langSel) {
|
||||
langSel.addEventListener('change', function() {
|
||||
if (!this.value) return;
|
||||
var to = window.location.pathname + window.location.search;
|
||||
window.location.href = '/i18n/' + encodeURIComponent(this.value) + '?to=' + encodeURIComponent(to);
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-container uk-container-xsmall">
|
||||
|
||||
|
||||
|
||||
<div id="math-captcha-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body uk-text-center">
|
||||
<h3 class="uk-modal-title">人机验证</h3>
|
||||
<p class="uk-text-meta">请计算下方的算术题以验证你不是机器人</p>
|
||||
<div class="captcha-equation-box">
|
||||
<span id="captcha-modal-question" class="math-captcha-modal-question">加载中...</span>
|
||||
<input type="number" id="captcha-modal-answer" placeholder="?" autocomplete="off" inputmode="numeric">
|
||||
</div>
|
||||
<div style="margin-top:6px;">
|
||||
<button type="button" class="uk-button uk-button-text uk-text-small" id="captcha-modal-refresh">换一题</button>
|
||||
</div>
|
||||
<div id="captcha-modal-error" class="uk-text-danger uk-text-small" style="display:none;min-height:20px;"></div>
|
||||
<div class="uk-margin-small-top">
|
||||
<button type="button" class="uk-button uk-button-primary" id="captcha-modal-submit">提交</button>
|
||||
<button type="button" class="uk-button uk-button-default uk-modal-close">取消</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var CAPTCHA_I18N = {
|
||||
loading: "加载中...",
|
||||
loadFailed: "加载失败",
|
||||
loadRetry: "加载失败,请重试",
|
||||
inputAnswer: "请输入答案",
|
||||
wrongAnswer: "答案错误,请重新计算",
|
||||
verifyFailed: "验证失败,请重试",
|
||||
needPassword: "此提问箱需要密码",
|
||||
needEmail: "请填写接收通知的邮箱地址"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var captchaId = '';
|
||||
var pendingForm = null;
|
||||
var pendingNeedPassword = false;
|
||||
var verifying = false;
|
||||
|
||||
function fetchCaptcha() {
|
||||
var qEl = document.getElementById('captcha-modal-question');
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
var ansEl = document.getElementById('captcha-modal-answer');
|
||||
qEl.textContent = CAPTCHA_I18N.loading;
|
||||
fetch('/api/captcha/generate')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.code === 0 && data.data) {
|
||||
captchaId = data.data.id;
|
||||
qEl.textContent = data.data.question;
|
||||
if (errEl) errEl.style.display = 'none';
|
||||
if (ansEl) { ansEl.value = ''; ansEl.focus(); }
|
||||
} else {
|
||||
qEl.textContent = CAPTCHA_I18N.loadFailed;
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
qEl.textContent = CAPTCHA_I18N.loadRetry;
|
||||
});
|
||||
}
|
||||
|
||||
function getCSRFToken() {
|
||||
var input = document.querySelector('input[name="_csrf"]');
|
||||
return input ? input.value : '';
|
||||
}
|
||||
|
||||
function doSubmit(form) {
|
||||
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
var hidden = form.querySelector('[name="g-recaptcha-response"]');
|
||||
if (hidden) hidden.value = captchaId + ':' + (ans || '0');
|
||||
|
||||
UIkit.modal('#math-captcha-modal').hide();
|
||||
|
||||
|
||||
if (pendingNeedPassword) {
|
||||
UIkit.modal.prompt(CAPTCHA_I18N.needPassword, '', 'password')
|
||||
.then(function(password) {
|
||||
if (password) {
|
||||
var pwInput = document.getElementById('ask_password_input');
|
||||
if (pwInput) pwInput.value = password;
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-submit').addEventListener('click', function() {
|
||||
if (verifying) return;
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
if (!ans) {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.inputAnswer;
|
||||
errEl.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
verifying = true;
|
||||
fetch('/api/captcha/verify', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-Token': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify({ id: captchaId, answer: parseInt(ans, 10) })
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
verifying = false;
|
||||
if (data.correct) {
|
||||
if (pendingForm) doSubmit(pendingForm);
|
||||
} else {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.wrongAnswer;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
verifying = false;
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.verifyFailed;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-answer').addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
document.getElementById('captcha-modal-submit').click();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-refresh').addEventListener('click', fetchCaptcha);
|
||||
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target.closest('.math-captcha-trigger');
|
||||
if (!btn) return;
|
||||
e.preventDefault();
|
||||
|
||||
var form = btn.closest('form');
|
||||
if (!form) return;
|
||||
pendingForm = form;
|
||||
|
||||
|
||||
pendingNeedPassword = !!(form.querySelector('#ask_password_input'));
|
||||
|
||||
|
||||
var notifyCb = document.getElementById('notify-checkbox');
|
||||
var emailInput = document.getElementById('email-input');
|
||||
if (notifyCb && notifyCb.checked && emailInput && emailInput.value.trim() === '') {
|
||||
UIkit.modal.alert(CAPTCHA_I18N.needEmail);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchCaptcha();
|
||||
UIkit.modal('#math-captcha-modal').show();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-flex uk-flex-between uk-flex-middle uk-margin-bottom">
|
||||
<h3 class="uk-margin-remove">投票结果:测试</h3>
|
||||
<div class="uk-flex uk-flex-middle" style="gap: 8px;">
|
||||
<a class="uk-button uk-button-default uk-button-small" href="/user/votes/9/export">导出 CSV</a>
|
||||
<a class="uk-button uk-button-default uk-button-small" href="/user/questions#votes">返回</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-small uk-card-body uk-margin-bottom">
|
||||
<div class="uk-text-large uk-text-bold">0</div>
|
||||
<div class="uk-text-meta">总参与人数</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<h4>投票结果</h4>
|
||||
<div class="uk-card uk-card-default uk-card-small uk-card-body uk-margin-bottom">
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 8px;">
|
||||
<span class="uk-label">1</span>
|
||||
<span class="uk-label ">单行文本</span>
|
||||
<span class="uk-text-bold">测试</span>
|
||||
<span class="uk-text-meta uk-text-small">回答数: 0</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="uk-text-meta uk-margin-small-top">已填写: 0</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
function toggleFieldReplies(id) {
|
||||
var box = document.getElementById('replies-' + id);
|
||||
var caret = document.getElementById('caret-' + id);
|
||||
if (!box) { return; }
|
||||
if (box.hasAttribute('hidden')) {
|
||||
box.removeAttribute('hidden');
|
||||
if (caret) { caret.style.transform = 'rotate(0deg)'; }
|
||||
} else {
|
||||
box.setAttribute('hidden', '');
|
||||
if (caret) { caret.style.transform = 'rotate(-90deg)'; }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<p class=" uk-text-right uk-text-muted uk-text-small">
|
||||
<br>
|
||||
<a href="/rules">社区规则</a> |
|
||||
|
||||
<a href="https://box.shiroko.one/_/tamakyi" target="_blank">找站长</a>
|
||||
<br>
|
||||
<a href="https://share.shiroko.one" target="_blank">盘</a>
|
||||
| <a href="https://blog.shiroko.one" target="_blank">公告板</a>
|
||||
| <a href="https://chat.shiroko.one" target="_blank">聊天室</a>
|
||||
| <a href="https://status.shiroko.one" target="_blank">监控板</a>
|
||||
| <a href="https://shiroko.one" target="_blank">导航页</a>
|
||||
<br>Powered by NekoBox | 狼ICP备 20230101
|
||||
<br>提问箱已成功存活:<span id="box_runtime"></span>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
(function () {
|
||||
var create = Math.round(Date.UTC(2023, 6, 1, 18, 15, 43) / 1000);
|
||||
function tick() {
|
||||
var el = document.getElementById("box_runtime");
|
||||
if (!el) return;
|
||||
var s = Math.round((Date.now() + 8 * 3600 * 1000) / 1000) - create;
|
||||
var t = [0, 0, 0, 0, 0];
|
||||
if (s >= 31536000) { t[0] = s / 31536000 | 0; s %= 31536000; }
|
||||
if (s >= 86400) { t[1] = s / 86400 | 0; s %= 86400; }
|
||||
if (s >= 3600) { t[2] = s / 3600 | 0; s %= 3600; }
|
||||
if (s >= 60) { t[3] = s / 60 | 0; s %= 60; }
|
||||
if (s > 0) { t[4] = s; }
|
||||
el.innerHTML = t[0] + '年 ' + t[1] + '天 ' + t[2] + '时 ' + t[3] + '分 ' + t[4] + '秒 ';
|
||||
}
|
||||
tick();
|
||||
setInterval(tick, 1000);
|
||||
})();
|
||||
</script>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
var SUBMIT_I18N = {
|
||||
submitting: '提交中...',
|
||||
uploading: '上传中...'
|
||||
};
|
||||
|
||||
function tbResetSubmitButtons() {
|
||||
document.querySelectorAll('button[data-tb-submitting]').forEach(function(b) {
|
||||
b.disabled = false;
|
||||
b.removeAttribute('data-tb-submitting');
|
||||
var orig = b.getAttribute('data-tb-restore');
|
||||
if (orig !== null) {
|
||||
b.innerHTML = orig;
|
||||
b.removeAttribute('data-tb-restore');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('submit', function(e) {
|
||||
var form = e.target;
|
||||
if (!form || form.tagName !== 'FORM') return;
|
||||
|
||||
|
||||
|
||||
if (e.defaultPrevented || form.getAttribute('data-tb-skip-submit-feedback') === '1') {
|
||||
form.removeAttribute('data-tb-skip-submit-feedback');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (form.getAttribute('target') === '_blank') return;
|
||||
|
||||
|
||||
var trigger = e.submitter || form.querySelector('button[type="submit"]');
|
||||
|
||||
|
||||
var hasFile = false;
|
||||
form.querySelectorAll('input[type="file"]').forEach(function(f) {
|
||||
if (f.files && f.files.length > 0) hasFile = true;
|
||||
});
|
||||
var label = hasFile ? SUBMIT_I18N.uploading : SUBMIT_I18N.submitting;
|
||||
|
||||
if (trigger && trigger.tagName === 'BUTTON') {
|
||||
trigger.setAttribute('data-tb-restore', trigger.innerHTML);
|
||||
trigger.innerHTML = '<span uk-spinner="ratio: 0.6"></span> ' + label;
|
||||
}
|
||||
|
||||
|
||||
form.querySelectorAll('button').forEach(function(b) {
|
||||
b.disabled = true;
|
||||
b.setAttribute('data-tb-submitting', '1');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener('pageshow', tbResetSubmitButtons);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,885 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>测试</title>
|
||||
<meta name="msvalidate.01" content="2F185E8E63C93635F50B3574F3B31E42" />
|
||||
<meta name="description" content="狼の質問箱は登録不要で使える匿名質問箱。誰でも匿名で質問でき、安心してやり取りできる場所です。">
|
||||
<meta name="keywords" content="匿名質問箱,質問箱,匿名質問,狼の質問箱,匿名で質問,匿名Q&A">
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
if (m && m[1] === 'dark') document.documentElement.setAttribute('data-theme', 'dark');
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://r2.337845818.best" crossorigin>
|
||||
<link rel="preconnect" href="https://cdnjs.snrat.com" crossorigin>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/css/uikit.min.css"/>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/base.css?v=20261019c"/>
|
||||
|
||||
<link rel="stylesheet" href="https://r2.337845818.best/tamabox/cdn/waline/client/v2/waline-no-commits.css" media="print" onload="this.media='all'"/>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit-icons.min.js"></script>
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/dayjs/1.10.8/dayjs.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/alpinejs/3.9.0/cdn.min.js"></script>
|
||||
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/waline/2.15.8/waline.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.captcha-equation-box {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: #f0f2f5;
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 8px;
|
||||
padding: 8px 8px 8px 16px;
|
||||
gap: 6px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
.captcha-equation-box:focus-within {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 3px rgba(30,135,240,0.12);
|
||||
}
|
||||
.math-captcha-modal-question {
|
||||
font-size: 1.4rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
letter-spacing: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
width: 80px;
|
||||
padding: 6px 10px;
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 600;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
transition: border-color 0.15s, box-shadow 0.15s;
|
||||
background: #fff;
|
||||
}
|
||||
#captcha-modal-answer:focus {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 2px rgba(30,135,240,0.2);
|
||||
}
|
||||
|
||||
#captcha-modal-answer::-webkit-inner-spin-button,
|
||||
#captcha-modal-answer::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta property="og:site_name" content="狼の質問箱 | 匿名質問箱" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content="狼の質問箱 | 匿名質問箱" />
|
||||
<meta property="og:url" content="https://box-dev-api.337845818.best/vote/7kcP5kR8YnJC" />
|
||||
<meta property="og:description" content="狼の質問箱は登録不要で使える匿名質問箱。誰でも匿名で質問でき、安心してやり取りできる場所です。" />
|
||||
<meta name="robots" content="noindex">
|
||||
|
||||
<meta itemprop="image" content="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<meta name="msapplication-TileImage" content="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<link rel="shortcut icon" href="https://r2.337845818.best/tamabox/tamabox_low.png" />
|
||||
<link rel="apple-touch-icon" href="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<link rel="icon" sizes="192x192" href="https://r2.337845818.best/tamabox/tamabox_low.png">
|
||||
<meta name="twitter:image:src" content="https://r2.337845818.best/tamabox/tamabox_low.png" />
|
||||
|
||||
|
||||
|
||||
<meta name="google-site-verification" content="fEPwRRJfiGsgwc5SINBQwZhPK8F0cwRaOvRx0YRurI4" />
|
||||
|
||||
<script>
|
||||
window.addEventListener("load", function () {
|
||||
var s = document.createElement("script");
|
||||
s.src = "https://mami.shiroko.one/tamami.js";
|
||||
s.setAttribute("data-website-id", "c42ebe8b-9281-4da0-83a4-8f18b3e710fe");
|
||||
document.body.appendChild(s);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window.tbRenderQR = function (el, getOptions) {
|
||||
if (!el || typeof QRCode === 'undefined') return;
|
||||
var opts = getOptions();
|
||||
function remoteOf(o, key) {
|
||||
var v = o[key];
|
||||
return (typeof v === 'string' && v.indexOf('http') === 0) ? v : '';
|
||||
}
|
||||
var good = window._tbQrGood || (window._tbQrGood = {});
|
||||
var bad = window._tbQrBad || (window._tbQrBad = {});
|
||||
|
||||
function layerState(url) { return !url ? '' : (good[url] ? 1 : (bad[url] ? 0 : null)); }
|
||||
var layers = [
|
||||
{ url: remoteOf(opts, 'logo'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.logo = undefined; o.logoWidth = undefined; o.logoHeight = undefined; o.logoBackgroundTransparent = undefined; }
|
||||
} },
|
||||
{ url: remoteOf(opts, 'backgroundImage'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.backgroundImage = undefined; o.backgroundImageAlpha = undefined; }
|
||||
} }
|
||||
];
|
||||
var needProbe = false;
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
layers[i].st = layerState(layers[i].url);
|
||||
if (layers[i].st === null) needProbe = true;
|
||||
}
|
||||
function paint(states) {
|
||||
var o = {};
|
||||
for (var k in opts) o[k] = opts[k];
|
||||
for (var j = 0; j < layers.length; j++) layers[j].present(o, states[j] === 1);
|
||||
el.innerHTML = '';
|
||||
new QRCode(el, o);
|
||||
}
|
||||
|
||||
var initStates = [];
|
||||
for (var n = 0; n < layers.length; n++) initStates.push(layers[n].st === 1 ? 1 : 0);
|
||||
paint(initStates);
|
||||
if (!needProbe) return;
|
||||
|
||||
var pending = 0, cross = opts.crossOrigin || 'anonymous';
|
||||
layers.forEach(function (L) {
|
||||
if (L.st !== null) return;
|
||||
pending++;
|
||||
var im = new Image();
|
||||
im.onload = function () { good[L.url] = true; L.st = 1; onDone(); };
|
||||
im.onerror = function () { bad[L.url] = true; L.st = 0; onDone(); };
|
||||
if (cross) im.crossOrigin = cross;
|
||||
im.src = L.url;
|
||||
});
|
||||
function onDone() {
|
||||
if (--pending > 0) return;
|
||||
var finalStates = [];
|
||||
for (var m = 0; m < layers.length; m++) finalStates.push(layers[m].st === 1 ? 1 : 0);
|
||||
var changed = false;
|
||||
for (var q = 0; q < finalStates.length; q++) if (finalStates[q] !== initStates[q]) changed = true;
|
||||
if (changed) paint(finalStates);
|
||||
}
|
||||
|
||||
setTimeout(function () { if (pending > 0) { pending = 0; onDone(); } }, 3000);
|
||||
};
|
||||
</script>
|
||||
<nav class="uk-navbar-container uk-margin tb-navbar" uk-navbar>
|
||||
<div class="uk-navbar-center">
|
||||
<div class="uk-navbar-center-left">
|
||||
<div>
|
||||
<ul class="uk-navbar-nav">
|
||||
|
||||
<li><a href="/explore">探索</a></li>
|
||||
|
||||
|
||||
<li class="tb-mobile-balancer" aria-hidden="true"><a tabindex="-1" style="visibility:hidden">マイ</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="uk-navbar-item uk-logo" href="/"><span class="emoji-placeholder" aria-label="random animal">🐺</span>の質問箱</a>
|
||||
|
||||
<div class="uk-navbar-center-right">
|
||||
<div>
|
||||
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/register">登録</a></li>
|
||||
</ul>
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/login">ログイン</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" aria-label="言語" title="言語"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="9"/><path d="M3.2 9h17.6M3.2 15h17.6"/><ellipse cx="12" cy="12" rx="4" ry="9"/></svg></a>
|
||||
<div class="uk-navbar-dropdown" uk-drop="mode: click; pos: bottom-right">
|
||||
<ul class="uk-nav uk-navbar-dropdown-nav">
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/zh-CN?to=%2Fvote%2F7kcP5kR8YnJC">简体中文</a>
|
||||
</li>
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/zh-TW?to=%2Fvote%2F7kcP5kR8YnJC">繁體中文</a>
|
||||
</li>
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/en?to=%2Fvote%2F7kcP5kR8YnJC">English</a>
|
||||
</li>
|
||||
|
||||
<li class="uk-active">
|
||||
<a href="/i18n/ja?to=%2Fvote%2F7kcP5kR8YnJC">日本語</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" id="theme-toggle" title="ダーク/ライトモード切替" aria-label="ダーク/ライトモード切替">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const emojis = ["🐺","🐗","🐻","🐨","🐼","🐹","🐭","🐰","🦊","🐮","🐷","🐽","🐸","🐒","🦍","🐔","🐧","🐦","🐤","🐦⬛","🦅","🦉","🦇","🐴","🦄","🐝","🦎","🦖","🦕","🐙","🦑","🦐","🦞","🦀","🐡","🐠","🐟","🐬","🐳","🐋","🦈","🐊","🐅","🐆","🦓","🦍","🦧","🐘","🦛","🦏","🐪","🐫","🦒","🦘","🐃","🐂","🐄","🐎","🐖","🐏","🐑","🦙","🐐","🦌","🐕","🐩","🦮","🐕🦺","🐈","🐋","🐳","🐬","🐉","🐲"];
|
||||
const placeholder = document.querySelector('.emoji-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.textContent = emojis[Math.floor(Math.random() * emojis.length)];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="tb-mobile-utils">
|
||||
|
||||
<select id="mobile-lang-select" class="uk-select uk-form-small" aria-label="言語">
|
||||
|
||||
<option value="zh-CN" >简体中文</option>
|
||||
|
||||
<option value="zh-TW" >繁體中文</option>
|
||||
|
||||
<option value="en" >English</option>
|
||||
|
||||
<option value="ja" selected>日本語</option>
|
||||
|
||||
</select>
|
||||
|
||||
<button type="button" id="theme-toggle-mobile" class="uk-button uk-button-default uk-button-small"
|
||||
title="ダーク/ライトモード切替" aria-label="ダーク/ライトモード切替">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
var THEME_COOKIE = 'theme';
|
||||
function getTheme() {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
return m ? m[1] : '';
|
||||
}
|
||||
function applyTheme(theme) {
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
}
|
||||
}
|
||||
function toggleTheme() {
|
||||
var next = getTheme() === 'dark' ? 'light' : 'dark';
|
||||
applyTheme(next);
|
||||
var expires = new Date(Date.now() + 365 * 24 * 3600 * 1000).toUTCString();
|
||||
document.cookie = THEME_COOKIE + '=' + next + '; path=/; max-age=' + (365 * 24 * 3600) + '; SameSite=Lax';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
var buttons = document.querySelectorAll('#theme-toggle, #theme-toggle-mobile');
|
||||
buttons.forEach(function(btn) {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
toggleTheme();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var langSel = document.getElementById('mobile-lang-select');
|
||||
if (langSel) {
|
||||
langSel.addEventListener('change', function() {
|
||||
if (!this.value) return;
|
||||
var to = window.location.pathname + window.location.search;
|
||||
window.location.href = '/i18n/' + encodeURIComponent(this.value) + '?to=' + encodeURIComponent(to);
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-container uk-container-xsmall">
|
||||
|
||||
|
||||
|
||||
<div id="math-captcha-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body uk-text-center">
|
||||
<h3 class="uk-modal-title">人機認証</h3>
|
||||
<p class="uk-text-meta">以下の計算問題を解いて、ロボットでないことを証明してください</p>
|
||||
<div class="captcha-equation-box">
|
||||
<span id="captcha-modal-question" class="math-captcha-modal-question">読み込み中...</span>
|
||||
<input type="number" id="captcha-modal-answer" placeholder="?" autocomplete="off" inputmode="numeric">
|
||||
</div>
|
||||
<div style="margin-top:6px;">
|
||||
<button type="button" class="uk-button uk-button-text uk-text-small" id="captcha-modal-refresh">別の問題</button>
|
||||
</div>
|
||||
<div id="captcha-modal-error" class="uk-text-danger uk-text-small" style="display:none;min-height:20px;"></div>
|
||||
<div class="uk-margin-small-top">
|
||||
<button type="button" class="uk-button uk-button-primary" id="captcha-modal-submit">送信</button>
|
||||
<button type="button" class="uk-button uk-button-default uk-modal-close">キャンセル</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var CAPTCHA_I18N = {
|
||||
loading: "読み込み中...",
|
||||
loadFailed: "読み込み失敗",
|
||||
loadRetry: "読み込み失敗、再試行してください",
|
||||
inputAnswer: "答えを入力してください",
|
||||
wrongAnswer: "答えが違います。もう一度計算してください",
|
||||
verifyFailed: "認証失敗、再試行してください",
|
||||
needPassword: "この質問箱にはパスワードが必要です",
|
||||
needEmail: "通知を受け取るメールアドレスを入力してください"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var captchaId = '';
|
||||
var pendingForm = null;
|
||||
var pendingNeedPassword = false;
|
||||
var verifying = false;
|
||||
|
||||
function fetchCaptcha() {
|
||||
var qEl = document.getElementById('captcha-modal-question');
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
var ansEl = document.getElementById('captcha-modal-answer');
|
||||
qEl.textContent = CAPTCHA_I18N.loading;
|
||||
fetch('/api/captcha/generate')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.code === 0 && data.data) {
|
||||
captchaId = data.data.id;
|
||||
qEl.textContent = data.data.question;
|
||||
if (errEl) errEl.style.display = 'none';
|
||||
if (ansEl) { ansEl.value = ''; ansEl.focus(); }
|
||||
} else {
|
||||
qEl.textContent = CAPTCHA_I18N.loadFailed;
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
qEl.textContent = CAPTCHA_I18N.loadRetry;
|
||||
});
|
||||
}
|
||||
|
||||
function getCSRFToken() {
|
||||
var input = document.querySelector('input[name="_csrf"]');
|
||||
return input ? input.value : '';
|
||||
}
|
||||
|
||||
function doSubmit(form) {
|
||||
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
var hidden = form.querySelector('[name="g-recaptcha-response"]');
|
||||
if (hidden) hidden.value = captchaId + ':' + (ans || '0');
|
||||
|
||||
UIkit.modal('#math-captcha-modal').hide();
|
||||
|
||||
|
||||
if (pendingNeedPassword) {
|
||||
UIkit.modal.prompt(CAPTCHA_I18N.needPassword, '', 'password')
|
||||
.then(function(password) {
|
||||
if (password) {
|
||||
var pwInput = document.getElementById('ask_password_input');
|
||||
if (pwInput) pwInput.value = password;
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-submit').addEventListener('click', function() {
|
||||
if (verifying) return;
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
if (!ans) {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.inputAnswer;
|
||||
errEl.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
verifying = true;
|
||||
fetch('/api/captcha/verify', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-Token': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify({ id: captchaId, answer: parseInt(ans, 10) })
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
verifying = false;
|
||||
if (data.correct) {
|
||||
if (pendingForm) doSubmit(pendingForm);
|
||||
} else {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.wrongAnswer;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
verifying = false;
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.verifyFailed;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-answer').addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
document.getElementById('captcha-modal-submit').click();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-refresh').addEventListener('click', fetchCaptcha);
|
||||
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target.closest('.math-captcha-trigger');
|
||||
if (!btn) return;
|
||||
e.preventDefault();
|
||||
|
||||
var form = btn.closest('form');
|
||||
if (!form) return;
|
||||
pendingForm = form;
|
||||
|
||||
|
||||
pendingNeedPassword = !!(form.querySelector('#ask_password_input'));
|
||||
|
||||
|
||||
var notifyCb = document.getElementById('notify-checkbox');
|
||||
var emailInput = document.getElementById('email-input');
|
||||
if (notifyCb && notifyCb.checked && emailInput && emailInput.value.trim() === '') {
|
||||
UIkit.modal.alert(CAPTCHA_I18N.needEmail);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchCaptcha();
|
||||
UIkit.modal('#math-captcha-modal').show();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<style>
|
||||
|
||||
.tb-field-head {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 6px 8px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.tb-field-head .tb-field-label {
|
||||
flex-basis: 100%;
|
||||
font-weight: 600;
|
||||
line-height: 1.5;
|
||||
word-break: break-word;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.tb-choice {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
padding: 12px 14px;
|
||||
margin-bottom: 8px;
|
||||
border: 1px solid var(--tb-border);
|
||||
border-radius: 8px;
|
||||
background: var(--tb-surface);
|
||||
cursor: pointer;
|
||||
transition: border-color 0.2s ease, background 0.2s ease;
|
||||
}
|
||||
.tb-choice:last-child { margin-bottom: 0; }
|
||||
.tb-choice input[type="radio"], .tb-choice input[type="checkbox"] {
|
||||
margin-top: 3px;
|
||||
}
|
||||
.tb-choice span {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
line-height: 1.5;
|
||||
word-break: break-word;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.tb-choice:hover {
|
||||
border-color: var(--tb-primary);
|
||||
background: var(--tb-surface-hover);
|
||||
}
|
||||
.tb-choice:has(input:checked) {
|
||||
border-color: var(--tb-primary);
|
||||
background: var(--tb-surface-active);
|
||||
}
|
||||
html[data-theme="dark"] .tb-choice {
|
||||
border-color: var(--tb-border);
|
||||
background: var(--tb-surface);
|
||||
}
|
||||
html[data-theme="dark"] .tb-choice:hover {
|
||||
border-color: var(--tb-primary);
|
||||
background: rgba(78, 168, 245, 0.08);
|
||||
}
|
||||
html[data-theme="dark"] .tb-choice:has(input:checked) {
|
||||
border-color: var(--tb-primary);
|
||||
background: rgba(78, 168, 245, 0.14);
|
||||
}
|
||||
|
||||
.tb-custom-input {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.tb-text-counter {
|
||||
margin-top: 2px;
|
||||
text-align: right;
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.tb-choice { padding: 10px 12px; }
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-body uk-margin-bottom">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 10px;">
|
||||
|
||||
<img class="uk-border-circle" src="https://r2.337845818.best/tamabox/picture/2026/08/19/9af3e38222d972ff9141e9cfdb0475" style="width: 40px; height: 40px;">
|
||||
<div>
|
||||
<a class="uk-text-bold" href="/_admin6">admin6</a>
|
||||
<div class="uk-text-meta uk-text-small">の投票</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-auto-left">
|
||||
|
||||
|
||||
<span class="uk-label uk-label-success">進行中</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="uk-margin-remove-top uk-margin-small-bottom">测试</h3>
|
||||
|
||||
<p class="uk-margin-remove-top">测试</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="uk-alert uk-alert-primary uk-text-small">匿名での参加が可能で、あなたの身元は記録されません(同一端末で最大1回)。</div>
|
||||
|
||||
|
||||
<form method="post" action="/vote/7kcP5kR8YnJC/submit" id="vote-form" onsubmit="return validateVoteForm()">
|
||||
<input type="hidden" name="_csrf" value="-2aYUm8MloWAfN0A1_ReAOd58306MTc5MjM4NDM1NjI2NTE4MTMyMQ">
|
||||
<input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response" value="">
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-body uk-margin-bottom">
|
||||
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="tb-field-head">
|
||||
<span class="uk-label">1</span>
|
||||
<span class="uk-label ">一行テキスト</span>
|
||||
<div class="tb-field-label">测试 <span class="uk-text-danger">*</span></div>
|
||||
</div>
|
||||
|
||||
<input class="uk-input" type="text" name="field_21" data-vote-required data-vote-label="测试">
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
|
||||
<button type="button" class="uk-button uk-button-primary math-captcha-trigger" onclick="return voteValidate(event)">投票する</button>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
var MAX_CUSTOM_LEN = 200 ;
|
||||
|
||||
|
||||
|
||||
function countChars(s) { return Array.from(String(s || '')).length; }
|
||||
|
||||
|
||||
function setupTextCounters() {
|
||||
var form = document.getElementById('vote-form');
|
||||
if (!form) { return; }
|
||||
form.querySelectorAll('[data-tb-text-counter]').forEach(function (input) {
|
||||
var max = parseInt(input.getAttribute('data-tb-text-max'), 10);
|
||||
if (!max || max < 1) { max = MAX_CUSTOM_LEN; }
|
||||
var counter = document.createElement('div');
|
||||
counter.className = 'uk-text-meta uk-text-small tb-text-counter';
|
||||
if (input.parentNode) { input.parentNode.insertBefore(counter, input.nextSibling); }
|
||||
var update = function () {
|
||||
var n = countChars(input.value);
|
||||
counter.textContent = n + ' / ' + max;
|
||||
if (n > max) {
|
||||
counter.classList.add('uk-text-danger');
|
||||
input.setAttribute('data-tb-too-long', '1');
|
||||
} else {
|
||||
counter.classList.remove('uk-text-danger');
|
||||
input.removeAttribute('data-tb-too-long');
|
||||
}
|
||||
};
|
||||
input.addEventListener('input', update);
|
||||
update();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
function validateVoteForm() {
|
||||
var form = document.getElementById('vote-form');
|
||||
if (!form) { return true; }
|
||||
|
||||
var tooLong = form.querySelector('[data-tb-text-counter][data-tb-too-long]');
|
||||
if (tooLong) {
|
||||
alert('自由記入オプションは 200 字以内にしてください');
|
||||
tooLong.focus();
|
||||
return false;
|
||||
}
|
||||
|
||||
var groups = {};
|
||||
form.querySelectorAll('input[data-vote-required][type="radio"], input[data-vote-required][type="checkbox"]').forEach(function (el) {
|
||||
(groups[el.name] = groups[el.name] || []).push(el);
|
||||
});
|
||||
for (var name in groups) {
|
||||
var any = groups[name].some(function (el) { return el.checked; });
|
||||
if (!any) {
|
||||
alert('入力してください「' + groups[name][0].getAttribute('data-vote-label') + '」');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var els = form.querySelectorAll('[data-vote-required]:not(input[type="radio"]):not(input[type="checkbox"])');
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
var el = els[i];
|
||||
if (el.disabled) { continue; }
|
||||
if ((el.value || '').trim() === '') {
|
||||
alert('入力してください「' + el.getAttribute('data-vote-label') + '」');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function voteValidate(e) {
|
||||
if (!validateVoteForm()) {
|
||||
if (e) { e.stopPropagation(); e.preventDefault(); }
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
if (validateVoteForm()) {
|
||||
document.getElementById('vote-form').submit();
|
||||
}
|
||||
}
|
||||
|
||||
(function () {
|
||||
var form = document.getElementById('vote-form');
|
||||
if (!form) { return; }
|
||||
setupTextCounters();
|
||||
var maxChoices = 0;
|
||||
if (maxChoices > 0) {
|
||||
var boxes = form.querySelectorAll('input[type="checkbox"][name="option_ids"]');
|
||||
boxes.forEach(function (box) {
|
||||
box.addEventListener('change', function () {
|
||||
var checked = form.querySelectorAll('input[type="checkbox"][name="option_ids"]:checked').length;
|
||||
if (checked > maxChoices) { this.checked = false; }
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var CUSTOM_MARKER = "__tb_custom_option__";
|
||||
form.querySelectorAll('[data-vote-custom-input]').forEach(function (input) {
|
||||
var fid = input.getAttribute('data-vote-custom-input');
|
||||
var group = form.querySelectorAll('input[name="field_' + fid + '"]');
|
||||
var select = form.querySelector('select[name="field_' + fid + '"]');
|
||||
var sync = function () {
|
||||
var on = false;
|
||||
if (select) {
|
||||
on = (select.value === CUSTOM_MARKER);
|
||||
} else {
|
||||
group.forEach(function (r) { if (r.value === CUSTOM_MARKER && r.checked) { on = true; } });
|
||||
}
|
||||
input.disabled = !on;
|
||||
if (!on) { input.value = ''; }
|
||||
};
|
||||
if (select) { select.addEventListener('change', sync); } else { group.forEach(function (r) { r.addEventListener('change', sync); }); }
|
||||
sync();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<p class=" uk-text-right uk-text-muted uk-text-small">
|
||||
<br>
|
||||
<a href="/rules">ルール</a> |
|
||||
|
||||
<a href="https://box.shiroko.one/_/tamakyi" target="_blank">管理者へ</a>
|
||||
<br>
|
||||
<a href="https://share.shiroko.one" target="_blank">ドライブ</a>
|
||||
| <a href="https://blog.shiroko.one" target="_blank">お知らせ</a>
|
||||
| <a href="https://chat.shiroko.one" target="_blank">チャット</a>
|
||||
| <a href="https://status.shiroko.one" target="_blank">ステータス</a>
|
||||
| <a href="https://shiroko.one" target="_blank">リンク</a>
|
||||
<br>Powered by NekoBox | 狼ICP备 20230101
|
||||
<br>質問箱は稼働中:<span id="box_runtime"></span>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
(function () {
|
||||
var create = Math.round(Date.UTC(2023, 6, 1, 18, 15, 43) / 1000);
|
||||
function tick() {
|
||||
var el = document.getElementById("box_runtime");
|
||||
if (!el) return;
|
||||
var s = Math.round((Date.now() + 8 * 3600 * 1000) / 1000) - create;
|
||||
var t = [0, 0, 0, 0, 0];
|
||||
if (s >= 31536000) { t[0] = s / 31536000 | 0; s %= 31536000; }
|
||||
if (s >= 86400) { t[1] = s / 86400 | 0; s %= 86400; }
|
||||
if (s >= 3600) { t[2] = s / 3600 | 0; s %= 3600; }
|
||||
if (s >= 60) { t[3] = s / 60 | 0; s %= 60; }
|
||||
if (s > 0) { t[4] = s; }
|
||||
el.innerHTML = t[0] + '年 ' + t[1] + '天 ' + t[2] + '时 ' + t[3] + '分 ' + t[4] + '秒 ';
|
||||
}
|
||||
tick();
|
||||
setInterval(tick, 1000);
|
||||
})();
|
||||
</script>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
var SUBMIT_I18N = {
|
||||
submitting: '送信中...',
|
||||
uploading: 'アップロード中...'
|
||||
};
|
||||
|
||||
function tbResetSubmitButtons() {
|
||||
document.querySelectorAll('button[data-tb-submitting]').forEach(function(b) {
|
||||
b.disabled = false;
|
||||
b.removeAttribute('data-tb-submitting');
|
||||
var orig = b.getAttribute('data-tb-restore');
|
||||
if (orig !== null) {
|
||||
b.innerHTML = orig;
|
||||
b.removeAttribute('data-tb-restore');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('submit', function(e) {
|
||||
var form = e.target;
|
||||
if (!form || form.tagName !== 'FORM') return;
|
||||
|
||||
|
||||
|
||||
if (e.defaultPrevented || form.getAttribute('data-tb-skip-submit-feedback') === '1') {
|
||||
form.removeAttribute('data-tb-skip-submit-feedback');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (form.getAttribute('target') === '_blank') return;
|
||||
|
||||
|
||||
var trigger = e.submitter || form.querySelector('button[type="submit"]');
|
||||
|
||||
|
||||
var hasFile = false;
|
||||
form.querySelectorAll('input[type="file"]').forEach(function(f) {
|
||||
if (f.files && f.files.length > 0) hasFile = true;
|
||||
});
|
||||
var label = hasFile ? SUBMIT_I18N.uploading : SUBMIT_I18N.submitting;
|
||||
|
||||
if (trigger && trigger.tagName === 'BUTTON') {
|
||||
trigger.setAttribute('data-tb-restore', trigger.innerHTML);
|
||||
trigger.innerHTML = '<span uk-spinner="ratio: 0.6"></span> ' + label;
|
||||
}
|
||||
|
||||
|
||||
form.querySelectorAll('button').forEach(function(b) {
|
||||
b.disabled = true;
|
||||
b.setAttribute('data-tb-submitting', '1');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener('pageshow', tbResetSubmitButtons);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,946 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>测试功能</title>
|
||||
<meta name="msvalidate.01" content="2F185E8E63C93635F50B3574F3B31E42" />
|
||||
<meta name="description" content="狼の質問箱は登録不要で使える匿名質問箱。誰でも匿名で質問でき、安心してやり取りできる場所です。">
|
||||
<meta name="keywords" content="匿名質問箱,質問箱,匿名質問,狼の質問箱,匿名で質問,匿名Q&A">
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
if (m && m[1] === 'dark') document.documentElement.setAttribute('data-theme', 'dark');
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://r2.337845818.best" crossorigin>
|
||||
<link rel="preconnect" href="https://cdnjs.snrat.com" crossorigin>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/css/uikit.min.css"/>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/base.css?v=20261019c"/>
|
||||
|
||||
<link rel="stylesheet" href="https://r2.337845818.best/tamabox/cdn/waline/client/v2/waline-no-commits.css" media="print" onload="this.media='all'"/>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit-icons.min.js"></script>
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/dayjs/1.10.8/dayjs.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/alpinejs/3.9.0/cdn.min.js"></script>
|
||||
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/waline/2.15.8/waline.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.captcha-equation-box {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: #f0f2f5;
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 8px;
|
||||
padding: 8px 8px 8px 16px;
|
||||
gap: 6px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
.captcha-equation-box:focus-within {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 3px rgba(30,135,240,0.12);
|
||||
}
|
||||
.math-captcha-modal-question {
|
||||
font-size: 1.4rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
letter-spacing: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
width: 80px;
|
||||
padding: 6px 10px;
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 600;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
transition: border-color 0.15s, box-shadow 0.15s;
|
||||
background: #fff;
|
||||
}
|
||||
#captcha-modal-answer:focus {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 2px rgba(30,135,240,0.2);
|
||||
}
|
||||
|
||||
#captcha-modal-answer::-webkit-inner-spin-button,
|
||||
#captcha-modal-answer::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta property="og:site_name" content="狼の質問箱 | 匿名質問箱" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content="狼の質問箱 | 匿名質問箱" />
|
||||
<meta property="og:url" content="https://box-dev-api.337845818.best/vote/9wfpVjXi73mc" />
|
||||
<meta property="og:description" content="狼の質問箱は登録不要で使える匿名質問箱。誰でも匿名で質問でき、安心してやり取りできる場所です。" />
|
||||
<meta name="robots" content="noindex">
|
||||
|
||||
<meta itemprop="image" content="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<meta name="msapplication-TileImage" content="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<link rel="shortcut icon" href="https://r2.337845818.best/tamabox/tamabox_low.png" />
|
||||
<link rel="apple-touch-icon" href="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<link rel="icon" sizes="192x192" href="https://r2.337845818.best/tamabox/tamabox_low.png">
|
||||
<meta name="twitter:image:src" content="https://r2.337845818.best/tamabox/tamabox_low.png" />
|
||||
|
||||
|
||||
|
||||
<meta name="google-site-verification" content="fEPwRRJfiGsgwc5SINBQwZhPK8F0cwRaOvRx0YRurI4" />
|
||||
|
||||
<script>
|
||||
window.addEventListener("load", function () {
|
||||
var s = document.createElement("script");
|
||||
s.src = "https://mami.shiroko.one/tamami.js";
|
||||
s.setAttribute("data-website-id", "c42ebe8b-9281-4da0-83a4-8f18b3e710fe");
|
||||
document.body.appendChild(s);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window.tbRenderQR = function (el, getOptions) {
|
||||
if (!el || typeof QRCode === 'undefined') return;
|
||||
var opts = getOptions();
|
||||
function remoteOf(o, key) {
|
||||
var v = o[key];
|
||||
return (typeof v === 'string' && v.indexOf('http') === 0) ? v : '';
|
||||
}
|
||||
var good = window._tbQrGood || (window._tbQrGood = {});
|
||||
var bad = window._tbQrBad || (window._tbQrBad = {});
|
||||
|
||||
function layerState(url) { return !url ? '' : (good[url] ? 1 : (bad[url] ? 0 : null)); }
|
||||
var layers = [
|
||||
{ url: remoteOf(opts, 'logo'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.logo = undefined; o.logoWidth = undefined; o.logoHeight = undefined; o.logoBackgroundTransparent = undefined; }
|
||||
} },
|
||||
{ url: remoteOf(opts, 'backgroundImage'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.backgroundImage = undefined; o.backgroundImageAlpha = undefined; }
|
||||
} }
|
||||
];
|
||||
var needProbe = false;
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
layers[i].st = layerState(layers[i].url);
|
||||
if (layers[i].st === null) needProbe = true;
|
||||
}
|
||||
function paint(states) {
|
||||
var o = {};
|
||||
for (var k in opts) o[k] = opts[k];
|
||||
for (var j = 0; j < layers.length; j++) layers[j].present(o, states[j] === 1);
|
||||
el.innerHTML = '';
|
||||
new QRCode(el, o);
|
||||
}
|
||||
|
||||
var initStates = [];
|
||||
for (var n = 0; n < layers.length; n++) initStates.push(layers[n].st === 1 ? 1 : 0);
|
||||
paint(initStates);
|
||||
if (!needProbe) return;
|
||||
|
||||
var pending = 0, cross = opts.crossOrigin || 'anonymous';
|
||||
layers.forEach(function (L) {
|
||||
if (L.st !== null) return;
|
||||
pending++;
|
||||
var im = new Image();
|
||||
im.onload = function () { good[L.url] = true; L.st = 1; onDone(); };
|
||||
im.onerror = function () { bad[L.url] = true; L.st = 0; onDone(); };
|
||||
if (cross) im.crossOrigin = cross;
|
||||
im.src = L.url;
|
||||
});
|
||||
function onDone() {
|
||||
if (--pending > 0) return;
|
||||
var finalStates = [];
|
||||
for (var m = 0; m < layers.length; m++) finalStates.push(layers[m].st === 1 ? 1 : 0);
|
||||
var changed = false;
|
||||
for (var q = 0; q < finalStates.length; q++) if (finalStates[q] !== initStates[q]) changed = true;
|
||||
if (changed) paint(finalStates);
|
||||
}
|
||||
|
||||
setTimeout(function () { if (pending > 0) { pending = 0; onDone(); } }, 3000);
|
||||
};
|
||||
</script>
|
||||
<nav class="uk-navbar-container uk-margin tb-navbar" uk-navbar>
|
||||
<div class="uk-navbar-center">
|
||||
<div class="uk-navbar-center-left">
|
||||
<div>
|
||||
<ul class="uk-navbar-nav">
|
||||
|
||||
<li><a href="/explore">探索</a></li>
|
||||
|
||||
|
||||
<li class="tb-mobile-balancer" aria-hidden="true"><a tabindex="-1" style="visibility:hidden">マイ</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="uk-navbar-item uk-logo" href="/"><span class="emoji-placeholder" aria-label="random animal">🐺</span>の質問箱</a>
|
||||
|
||||
<div class="uk-navbar-center-right">
|
||||
<div>
|
||||
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/register">登録</a></li>
|
||||
</ul>
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/login">ログイン</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" aria-label="言語" title="言語"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="9"/><path d="M3.2 9h17.6M3.2 15h17.6"/><ellipse cx="12" cy="12" rx="4" ry="9"/></svg></a>
|
||||
<div class="uk-navbar-dropdown" uk-drop="mode: click; pos: bottom-right">
|
||||
<ul class="uk-nav uk-navbar-dropdown-nav">
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/zh-CN?to=%2Fvote%2F9wfpVjXi73mc">简体中文</a>
|
||||
</li>
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/zh-TW?to=%2Fvote%2F9wfpVjXi73mc">繁體中文</a>
|
||||
</li>
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/en?to=%2Fvote%2F9wfpVjXi73mc">English</a>
|
||||
</li>
|
||||
|
||||
<li class="uk-active">
|
||||
<a href="/i18n/ja?to=%2Fvote%2F9wfpVjXi73mc">日本語</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" id="theme-toggle" title="ダーク/ライトモード切替" aria-label="ダーク/ライトモード切替">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const emojis = ["🐺","🐗","🐻","🐨","🐼","🐹","🐭","🐰","🦊","🐮","🐷","🐽","🐸","🐒","🦍","🐔","🐧","🐦","🐤","🐦⬛","🦅","🦉","🦇","🐴","🦄","🐝","🦎","🦖","🦕","🐙","🦑","🦐","🦞","🦀","🐡","🐠","🐟","🐬","🐳","🐋","🦈","🐊","🐅","🐆","🦓","🦍","🦧","🐘","🦛","🦏","🐪","🐫","🦒","🦘","🐃","🐂","🐄","🐎","🐖","🐏","🐑","🦙","🐐","🦌","🐕","🐩","🦮","🐕🦺","🐈","🐋","🐳","🐬","🐉","🐲"];
|
||||
const placeholder = document.querySelector('.emoji-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.textContent = emojis[Math.floor(Math.random() * emojis.length)];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="tb-mobile-utils">
|
||||
|
||||
<select id="mobile-lang-select" class="uk-select uk-form-small" aria-label="言語">
|
||||
|
||||
<option value="zh-CN" >简体中文</option>
|
||||
|
||||
<option value="zh-TW" >繁體中文</option>
|
||||
|
||||
<option value="en" >English</option>
|
||||
|
||||
<option value="ja" selected>日本語</option>
|
||||
|
||||
</select>
|
||||
|
||||
<button type="button" id="theme-toggle-mobile" class="uk-button uk-button-default uk-button-small"
|
||||
title="ダーク/ライトモード切替" aria-label="ダーク/ライトモード切替">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
var THEME_COOKIE = 'theme';
|
||||
function getTheme() {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
return m ? m[1] : '';
|
||||
}
|
||||
function applyTheme(theme) {
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
}
|
||||
}
|
||||
function toggleTheme() {
|
||||
var next = getTheme() === 'dark' ? 'light' : 'dark';
|
||||
applyTheme(next);
|
||||
var expires = new Date(Date.now() + 365 * 24 * 3600 * 1000).toUTCString();
|
||||
document.cookie = THEME_COOKIE + '=' + next + '; path=/; max-age=' + (365 * 24 * 3600) + '; SameSite=Lax';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
var buttons = document.querySelectorAll('#theme-toggle, #theme-toggle-mobile');
|
||||
buttons.forEach(function(btn) {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
toggleTheme();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var langSel = document.getElementById('mobile-lang-select');
|
||||
if (langSel) {
|
||||
langSel.addEventListener('change', function() {
|
||||
if (!this.value) return;
|
||||
var to = window.location.pathname + window.location.search;
|
||||
window.location.href = '/i18n/' + encodeURIComponent(this.value) + '?to=' + encodeURIComponent(to);
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-container uk-container-xsmall">
|
||||
|
||||
|
||||
|
||||
<div id="math-captcha-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body uk-text-center">
|
||||
<h3 class="uk-modal-title">人機認証</h3>
|
||||
<p class="uk-text-meta">以下の計算問題を解いて、ロボットでないことを証明してください</p>
|
||||
<div class="captcha-equation-box">
|
||||
<span id="captcha-modal-question" class="math-captcha-modal-question">読み込み中...</span>
|
||||
<input type="number" id="captcha-modal-answer" placeholder="?" autocomplete="off" inputmode="numeric">
|
||||
</div>
|
||||
<div style="margin-top:6px;">
|
||||
<button type="button" class="uk-button uk-button-text uk-text-small" id="captcha-modal-refresh">別の問題</button>
|
||||
</div>
|
||||
<div id="captcha-modal-error" class="uk-text-danger uk-text-small" style="display:none;min-height:20px;"></div>
|
||||
<div class="uk-margin-small-top">
|
||||
<button type="button" class="uk-button uk-button-primary" id="captcha-modal-submit">送信</button>
|
||||
<button type="button" class="uk-button uk-button-default uk-modal-close">キャンセル</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var CAPTCHA_I18N = {
|
||||
loading: "読み込み中...",
|
||||
loadFailed: "読み込み失敗",
|
||||
loadRetry: "読み込み失敗、再試行してください",
|
||||
inputAnswer: "答えを入力してください",
|
||||
wrongAnswer: "答えが違います。もう一度計算してください",
|
||||
verifyFailed: "認証失敗、再試行してください",
|
||||
needPassword: "この質問箱にはパスワードが必要です",
|
||||
needEmail: "通知を受け取るメールアドレスを入力してください"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var captchaId = '';
|
||||
var pendingForm = null;
|
||||
var pendingNeedPassword = false;
|
||||
var verifying = false;
|
||||
|
||||
function fetchCaptcha() {
|
||||
var qEl = document.getElementById('captcha-modal-question');
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
var ansEl = document.getElementById('captcha-modal-answer');
|
||||
qEl.textContent = CAPTCHA_I18N.loading;
|
||||
fetch('/api/captcha/generate')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.code === 0 && data.data) {
|
||||
captchaId = data.data.id;
|
||||
qEl.textContent = data.data.question;
|
||||
if (errEl) errEl.style.display = 'none';
|
||||
if (ansEl) { ansEl.value = ''; ansEl.focus(); }
|
||||
} else {
|
||||
qEl.textContent = CAPTCHA_I18N.loadFailed;
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
qEl.textContent = CAPTCHA_I18N.loadRetry;
|
||||
});
|
||||
}
|
||||
|
||||
function getCSRFToken() {
|
||||
var input = document.querySelector('input[name="_csrf"]');
|
||||
return input ? input.value : '';
|
||||
}
|
||||
|
||||
function doSubmit(form) {
|
||||
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
var hidden = form.querySelector('[name="g-recaptcha-response"]');
|
||||
if (hidden) hidden.value = captchaId + ':' + (ans || '0');
|
||||
|
||||
UIkit.modal('#math-captcha-modal').hide();
|
||||
|
||||
|
||||
if (pendingNeedPassword) {
|
||||
UIkit.modal.prompt(CAPTCHA_I18N.needPassword, '', 'password')
|
||||
.then(function(password) {
|
||||
if (password) {
|
||||
var pwInput = document.getElementById('ask_password_input');
|
||||
if (pwInput) pwInput.value = password;
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-submit').addEventListener('click', function() {
|
||||
if (verifying) return;
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
if (!ans) {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.inputAnswer;
|
||||
errEl.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
verifying = true;
|
||||
fetch('/api/captcha/verify', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-Token': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify({ id: captchaId, answer: parseInt(ans, 10) })
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
verifying = false;
|
||||
if (data.correct) {
|
||||
if (pendingForm) doSubmit(pendingForm);
|
||||
} else {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.wrongAnswer;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
verifying = false;
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.verifyFailed;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-answer').addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
document.getElementById('captcha-modal-submit').click();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-refresh').addEventListener('click', fetchCaptcha);
|
||||
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target.closest('.math-captcha-trigger');
|
||||
if (!btn) return;
|
||||
e.preventDefault();
|
||||
|
||||
var form = btn.closest('form');
|
||||
if (!form) return;
|
||||
pendingForm = form;
|
||||
|
||||
|
||||
pendingNeedPassword = !!(form.querySelector('#ask_password_input'));
|
||||
|
||||
|
||||
var notifyCb = document.getElementById('notify-checkbox');
|
||||
var emailInput = document.getElementById('email-input');
|
||||
if (notifyCb && notifyCb.checked && emailInput && emailInput.value.trim() === '') {
|
||||
UIkit.modal.alert(CAPTCHA_I18N.needEmail);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchCaptcha();
|
||||
UIkit.modal('#math-captcha-modal').show();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<style>
|
||||
|
||||
.tb-field-head {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 6px 8px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.tb-field-head .tb-field-label {
|
||||
flex-basis: 100%;
|
||||
font-weight: 600;
|
||||
line-height: 1.5;
|
||||
word-break: break-word;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.tb-choice {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
padding: 12px 14px;
|
||||
margin-bottom: 8px;
|
||||
border: 1px solid var(--tb-border);
|
||||
border-radius: 8px;
|
||||
background: var(--tb-surface);
|
||||
cursor: pointer;
|
||||
transition: border-color 0.2s ease, background 0.2s ease;
|
||||
}
|
||||
.tb-choice:last-child { margin-bottom: 0; }
|
||||
.tb-choice input[type="radio"], .tb-choice input[type="checkbox"] {
|
||||
margin-top: 3px;
|
||||
}
|
||||
.tb-choice span {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
line-height: 1.5;
|
||||
word-break: break-word;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.tb-choice:hover {
|
||||
border-color: var(--tb-primary);
|
||||
background: var(--tb-surface-hover);
|
||||
}
|
||||
.tb-choice:has(input:checked) {
|
||||
border-color: var(--tb-primary);
|
||||
background: var(--tb-surface-active);
|
||||
}
|
||||
html[data-theme="dark"] .tb-choice {
|
||||
border-color: var(--tb-border);
|
||||
background: var(--tb-surface);
|
||||
}
|
||||
html[data-theme="dark"] .tb-choice:hover {
|
||||
border-color: var(--tb-primary);
|
||||
background: rgba(78, 168, 245, 0.08);
|
||||
}
|
||||
html[data-theme="dark"] .tb-choice:has(input:checked) {
|
||||
border-color: var(--tb-primary);
|
||||
background: rgba(78, 168, 245, 0.14);
|
||||
}
|
||||
|
||||
.tb-custom-input {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.tb-text-counter {
|
||||
margin-top: 2px;
|
||||
text-align: right;
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.tb-choice { padding: 10px 12px; }
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-body uk-margin-bottom">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 10px;">
|
||||
|
||||
<img class="uk-border-circle" src="https://r2.337845818.best/tamabox/picture/2026/08/19/9af3e38222d972ff9141e9cfdb0475" style="width: 40px; height: 40px;">
|
||||
<div>
|
||||
<a class="uk-text-bold" href="/_admin6">admin6</a>
|
||||
<div class="uk-text-meta uk-text-small">の投票</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-auto-left">
|
||||
|
||||
|
||||
<span class="uk-label uk-label-success">進行中</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="uk-margin-remove-top uk-margin-small-bottom">测试功能</h3>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="uk-alert uk-alert-primary uk-text-small">匿名での参加が可能で、あなたの身元は記録されません(同一端末で最大1回)。</div>
|
||||
|
||||
|
||||
<form method="post" action="/vote/9wfpVjXi73mc/submit" id="vote-form" onsubmit="return validateVoteForm()">
|
||||
<input type="hidden" name="_csrf" value="023c_cDvZG6m9x0LDkdd-YNSO1A6MTc5MjM4NDM2MDE0NzkwMjY5OA">
|
||||
<input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response" value="">
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-body uk-margin-bottom">
|
||||
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="tb-field-head">
|
||||
<span class="uk-label">1</span>
|
||||
<span class="uk-label uk-label-primary">単一選択</span>
|
||||
<div class="tb-field-label">必填 <span class="uk-text-danger">*</span></div>
|
||||
</div>
|
||||
|
||||
|
||||
<label class="tb-choice">
|
||||
<input class="uk-radio" type="radio" name="field_37" value="A" data-vote-required data-vote-label="必填"><span>A</span>
|
||||
</label>
|
||||
|
||||
<label class="tb-choice">
|
||||
<input class="uk-radio" type="radio" name="field_37" value="B" data-vote-required data-vote-label="必填"><span>B</span>
|
||||
</label>
|
||||
|
||||
<label class="tb-choice">
|
||||
<input class="uk-radio" type="radio" name="field_37" value="C" data-vote-required data-vote-label="必填"><span>C</span>
|
||||
</label>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="tb-field-head">
|
||||
<span class="uk-label">2</span>
|
||||
<span class="uk-label uk-label-success">複数選択</span>
|
||||
<div class="tb-field-label">非必填</div>
|
||||
</div>
|
||||
|
||||
|
||||
<label class="tb-choice">
|
||||
<input class="uk-checkbox" type="checkbox" name="field_38" value="A" ><span>A</span>
|
||||
</label>
|
||||
|
||||
<label class="tb-choice">
|
||||
<input class="uk-checkbox" type="checkbox" name="field_38" value="B" ><span>B</span>
|
||||
</label>
|
||||
|
||||
<label class="tb-choice">
|
||||
<input class="uk-checkbox" type="checkbox" name="field_38" value="C" ><span>C</span>
|
||||
</label>
|
||||
|
||||
<label class="tb-choice">
|
||||
<input class="uk-checkbox" type="checkbox" name="field_38" value="D" ><span>D</span>
|
||||
</label>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="tb-field-head">
|
||||
<span class="uk-label">3</span>
|
||||
<span class="uk-label ">一行テキスト</span>
|
||||
<div class="tb-field-label">文本1</div>
|
||||
</div>
|
||||
|
||||
<input class="uk-input" type="text" name="field_39" >
|
||||
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="tb-field-head">
|
||||
<span class="uk-label">4</span>
|
||||
<span class="uk-label ">複数行テキスト</span>
|
||||
<div class="tb-field-label">文本2 <span class="uk-text-danger">*</span></div>
|
||||
</div>
|
||||
|
||||
<textarea class="uk-textarea" rows="3" name="field_40" data-vote-required data-vote-label="文本2"></textarea>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
|
||||
<button type="button" class="uk-button uk-button-primary math-captcha-trigger" onclick="return voteValidate(event)">投票する</button>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
var MAX_CUSTOM_LEN = 200 ;
|
||||
|
||||
|
||||
|
||||
function countChars(s) { return Array.from(String(s || '')).length; }
|
||||
|
||||
|
||||
function setupTextCounters() {
|
||||
var form = document.getElementById('vote-form');
|
||||
if (!form) { return; }
|
||||
form.querySelectorAll('[data-tb-text-counter]').forEach(function (input) {
|
||||
var max = parseInt(input.getAttribute('data-tb-text-max'), 10);
|
||||
if (!max || max < 1) { max = MAX_CUSTOM_LEN; }
|
||||
var counter = document.createElement('div');
|
||||
counter.className = 'uk-text-meta uk-text-small tb-text-counter';
|
||||
if (input.parentNode) { input.parentNode.insertBefore(counter, input.nextSibling); }
|
||||
var update = function () {
|
||||
var n = countChars(input.value);
|
||||
counter.textContent = n + ' / ' + max;
|
||||
if (n > max) {
|
||||
counter.classList.add('uk-text-danger');
|
||||
input.setAttribute('data-tb-too-long', '1');
|
||||
} else {
|
||||
counter.classList.remove('uk-text-danger');
|
||||
input.removeAttribute('data-tb-too-long');
|
||||
}
|
||||
};
|
||||
input.addEventListener('input', update);
|
||||
update();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
function validateVoteForm() {
|
||||
var form = document.getElementById('vote-form');
|
||||
if (!form) { return true; }
|
||||
|
||||
var tooLong = form.querySelector('[data-tb-text-counter][data-tb-too-long]');
|
||||
if (tooLong) {
|
||||
alert('自由記入オプションは 200 字以内にしてください');
|
||||
tooLong.focus();
|
||||
return false;
|
||||
}
|
||||
|
||||
var groups = {};
|
||||
form.querySelectorAll('input[data-vote-required][type="radio"], input[data-vote-required][type="checkbox"]').forEach(function (el) {
|
||||
(groups[el.name] = groups[el.name] || []).push(el);
|
||||
});
|
||||
for (var name in groups) {
|
||||
var any = groups[name].some(function (el) { return el.checked; });
|
||||
if (!any) {
|
||||
alert('入力してください「' + groups[name][0].getAttribute('data-vote-label') + '」');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var els = form.querySelectorAll('[data-vote-required]:not(input[type="radio"]):not(input[type="checkbox"])');
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
var el = els[i];
|
||||
if (el.disabled) { continue; }
|
||||
if ((el.value || '').trim() === '') {
|
||||
alert('入力してください「' + el.getAttribute('data-vote-label') + '」');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function voteValidate(e) {
|
||||
if (!validateVoteForm()) {
|
||||
if (e) { e.stopPropagation(); e.preventDefault(); }
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
if (validateVoteForm()) {
|
||||
document.getElementById('vote-form').submit();
|
||||
}
|
||||
}
|
||||
|
||||
(function () {
|
||||
var form = document.getElementById('vote-form');
|
||||
if (!form) { return; }
|
||||
setupTextCounters();
|
||||
var maxChoices = 0;
|
||||
if (maxChoices > 0) {
|
||||
var boxes = form.querySelectorAll('input[type="checkbox"][name="option_ids"]');
|
||||
boxes.forEach(function (box) {
|
||||
box.addEventListener('change', function () {
|
||||
var checked = form.querySelectorAll('input[type="checkbox"][name="option_ids"]:checked').length;
|
||||
if (checked > maxChoices) { this.checked = false; }
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var CUSTOM_MARKER = "__tb_custom_option__";
|
||||
form.querySelectorAll('[data-vote-custom-input]').forEach(function (input) {
|
||||
var fid = input.getAttribute('data-vote-custom-input');
|
||||
var group = form.querySelectorAll('input[name="field_' + fid + '"]');
|
||||
var select = form.querySelector('select[name="field_' + fid + '"]');
|
||||
var sync = function () {
|
||||
var on = false;
|
||||
if (select) {
|
||||
on = (select.value === CUSTOM_MARKER);
|
||||
} else {
|
||||
group.forEach(function (r) { if (r.value === CUSTOM_MARKER && r.checked) { on = true; } });
|
||||
}
|
||||
input.disabled = !on;
|
||||
if (!on) { input.value = ''; }
|
||||
};
|
||||
if (select) { select.addEventListener('change', sync); } else { group.forEach(function (r) { r.addEventListener('change', sync); }); }
|
||||
sync();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<p class=" uk-text-right uk-text-muted uk-text-small">
|
||||
<br>
|
||||
<a href="/rules">ルール</a> |
|
||||
|
||||
<a href="https://box.shiroko.one/_/tamakyi" target="_blank">管理者へ</a>
|
||||
<br>
|
||||
<a href="https://share.shiroko.one" target="_blank">ドライブ</a>
|
||||
| <a href="https://blog.shiroko.one" target="_blank">お知らせ</a>
|
||||
| <a href="https://chat.shiroko.one" target="_blank">チャット</a>
|
||||
| <a href="https://status.shiroko.one" target="_blank">ステータス</a>
|
||||
| <a href="https://shiroko.one" target="_blank">リンク</a>
|
||||
<br>Powered by NekoBox | 狼ICP备 20230101
|
||||
<br>質問箱は稼働中:<span id="box_runtime"></span>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
(function () {
|
||||
var create = Math.round(Date.UTC(2023, 6, 1, 18, 15, 43) / 1000);
|
||||
function tick() {
|
||||
var el = document.getElementById("box_runtime");
|
||||
if (!el) return;
|
||||
var s = Math.round((Date.now() + 8 * 3600 * 1000) / 1000) - create;
|
||||
var t = [0, 0, 0, 0, 0];
|
||||
if (s >= 31536000) { t[0] = s / 31536000 | 0; s %= 31536000; }
|
||||
if (s >= 86400) { t[1] = s / 86400 | 0; s %= 86400; }
|
||||
if (s >= 3600) { t[2] = s / 3600 | 0; s %= 3600; }
|
||||
if (s >= 60) { t[3] = s / 60 | 0; s %= 60; }
|
||||
if (s > 0) { t[4] = s; }
|
||||
el.innerHTML = t[0] + '年 ' + t[1] + '天 ' + t[2] + '时 ' + t[3] + '分 ' + t[4] + '秒 ';
|
||||
}
|
||||
tick();
|
||||
setInterval(tick, 1000);
|
||||
})();
|
||||
</script>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
var SUBMIT_I18N = {
|
||||
submitting: '送信中...',
|
||||
uploading: 'アップロード中...'
|
||||
};
|
||||
|
||||
function tbResetSubmitButtons() {
|
||||
document.querySelectorAll('button[data-tb-submitting]').forEach(function(b) {
|
||||
b.disabled = false;
|
||||
b.removeAttribute('data-tb-submitting');
|
||||
var orig = b.getAttribute('data-tb-restore');
|
||||
if (orig !== null) {
|
||||
b.innerHTML = orig;
|
||||
b.removeAttribute('data-tb-restore');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('submit', function(e) {
|
||||
var form = e.target;
|
||||
if (!form || form.tagName !== 'FORM') return;
|
||||
|
||||
|
||||
|
||||
if (e.defaultPrevented || form.getAttribute('data-tb-skip-submit-feedback') === '1') {
|
||||
form.removeAttribute('data-tb-skip-submit-feedback');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (form.getAttribute('target') === '_blank') return;
|
||||
|
||||
|
||||
var trigger = e.submitter || form.querySelector('button[type="submit"]');
|
||||
|
||||
|
||||
var hasFile = false;
|
||||
form.querySelectorAll('input[type="file"]').forEach(function(f) {
|
||||
if (f.files && f.files.length > 0) hasFile = true;
|
||||
});
|
||||
var label = hasFile ? SUBMIT_I18N.uploading : SUBMIT_I18N.submitting;
|
||||
|
||||
if (trigger && trigger.tagName === 'BUTTON') {
|
||||
trigger.setAttribute('data-tb-restore', trigger.innerHTML);
|
||||
trigger.innerHTML = '<span uk-spinner="ratio: 0.6"></span> ' + label;
|
||||
}
|
||||
|
||||
|
||||
form.querySelectorAll('button').forEach(function(b) {
|
||||
b.disabled = true;
|
||||
b.setAttribute('data-tb-submitting', '1');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener('pageshow', tbResetSubmitButtons);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,883 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>测试5</title>
|
||||
<meta name="msvalidate.01" content="2F185E8E63C93635F50B3574F3B31E42" />
|
||||
<meta name="description" content="狼の質問箱は登録不要で使える匿名質問箱。誰でも匿名で質問でき、安心してやり取りできる場所です。">
|
||||
<meta name="keywords" content="匿名質問箱,質問箱,匿名質問,狼の質問箱,匿名で質問,匿名Q&A">
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
if (m && m[1] === 'dark') document.documentElement.setAttribute('data-theme', 'dark');
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://r2.337845818.best" crossorigin>
|
||||
<link rel="preconnect" href="https://cdnjs.snrat.com" crossorigin>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/css/uikit.min.css"/>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/base.css?v=20261019c"/>
|
||||
|
||||
<link rel="stylesheet" href="https://r2.337845818.best/tamabox/cdn/waline/client/v2/waline-no-commits.css" media="print" onload="this.media='all'"/>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit-icons.min.js"></script>
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/dayjs/1.10.8/dayjs.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/alpinejs/3.9.0/cdn.min.js"></script>
|
||||
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/waline/2.15.8/waline.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.captcha-equation-box {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: #f0f2f5;
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 8px;
|
||||
padding: 8px 8px 8px 16px;
|
||||
gap: 6px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
.captcha-equation-box:focus-within {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 3px rgba(30,135,240,0.12);
|
||||
}
|
||||
.math-captcha-modal-question {
|
||||
font-size: 1.4rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
letter-spacing: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
width: 80px;
|
||||
padding: 6px 10px;
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 600;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
transition: border-color 0.15s, box-shadow 0.15s;
|
||||
background: #fff;
|
||||
}
|
||||
#captcha-modal-answer:focus {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 2px rgba(30,135,240,0.2);
|
||||
}
|
||||
|
||||
#captcha-modal-answer::-webkit-inner-spin-button,
|
||||
#captcha-modal-answer::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta property="og:site_name" content="狼の質問箱 | 匿名質問箱" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content="狼の質問箱 | 匿名質問箱" />
|
||||
<meta property="og:url" content="https://box-dev-api.337845818.best/vote/C84m7PoENWsG" />
|
||||
<meta property="og:description" content="狼の質問箱は登録不要で使える匿名質問箱。誰でも匿名で質問でき、安心してやり取りできる場所です。" />
|
||||
<meta name="robots" content="noindex">
|
||||
|
||||
<meta itemprop="image" content="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<meta name="msapplication-TileImage" content="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<link rel="shortcut icon" href="https://r2.337845818.best/tamabox/tamabox_low.png" />
|
||||
<link rel="apple-touch-icon" href="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<link rel="icon" sizes="192x192" href="https://r2.337845818.best/tamabox/tamabox_low.png">
|
||||
<meta name="twitter:image:src" content="https://r2.337845818.best/tamabox/tamabox_low.png" />
|
||||
|
||||
|
||||
|
||||
<meta name="google-site-verification" content="fEPwRRJfiGsgwc5SINBQwZhPK8F0cwRaOvRx0YRurI4" />
|
||||
|
||||
<script>
|
||||
window.addEventListener("load", function () {
|
||||
var s = document.createElement("script");
|
||||
s.src = "https://mami.shiroko.one/tamami.js";
|
||||
s.setAttribute("data-website-id", "c42ebe8b-9281-4da0-83a4-8f18b3e710fe");
|
||||
document.body.appendChild(s);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window.tbRenderQR = function (el, getOptions) {
|
||||
if (!el || typeof QRCode === 'undefined') return;
|
||||
var opts = getOptions();
|
||||
function remoteOf(o, key) {
|
||||
var v = o[key];
|
||||
return (typeof v === 'string' && v.indexOf('http') === 0) ? v : '';
|
||||
}
|
||||
var good = window._tbQrGood || (window._tbQrGood = {});
|
||||
var bad = window._tbQrBad || (window._tbQrBad = {});
|
||||
|
||||
function layerState(url) { return !url ? '' : (good[url] ? 1 : (bad[url] ? 0 : null)); }
|
||||
var layers = [
|
||||
{ url: remoteOf(opts, 'logo'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.logo = undefined; o.logoWidth = undefined; o.logoHeight = undefined; o.logoBackgroundTransparent = undefined; }
|
||||
} },
|
||||
{ url: remoteOf(opts, 'backgroundImage'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.backgroundImage = undefined; o.backgroundImageAlpha = undefined; }
|
||||
} }
|
||||
];
|
||||
var needProbe = false;
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
layers[i].st = layerState(layers[i].url);
|
||||
if (layers[i].st === null) needProbe = true;
|
||||
}
|
||||
function paint(states) {
|
||||
var o = {};
|
||||
for (var k in opts) o[k] = opts[k];
|
||||
for (var j = 0; j < layers.length; j++) layers[j].present(o, states[j] === 1);
|
||||
el.innerHTML = '';
|
||||
new QRCode(el, o);
|
||||
}
|
||||
|
||||
var initStates = [];
|
||||
for (var n = 0; n < layers.length; n++) initStates.push(layers[n].st === 1 ? 1 : 0);
|
||||
paint(initStates);
|
||||
if (!needProbe) return;
|
||||
|
||||
var pending = 0, cross = opts.crossOrigin || 'anonymous';
|
||||
layers.forEach(function (L) {
|
||||
if (L.st !== null) return;
|
||||
pending++;
|
||||
var im = new Image();
|
||||
im.onload = function () { good[L.url] = true; L.st = 1; onDone(); };
|
||||
im.onerror = function () { bad[L.url] = true; L.st = 0; onDone(); };
|
||||
if (cross) im.crossOrigin = cross;
|
||||
im.src = L.url;
|
||||
});
|
||||
function onDone() {
|
||||
if (--pending > 0) return;
|
||||
var finalStates = [];
|
||||
for (var m = 0; m < layers.length; m++) finalStates.push(layers[m].st === 1 ? 1 : 0);
|
||||
var changed = false;
|
||||
for (var q = 0; q < finalStates.length; q++) if (finalStates[q] !== initStates[q]) changed = true;
|
||||
if (changed) paint(finalStates);
|
||||
}
|
||||
|
||||
setTimeout(function () { if (pending > 0) { pending = 0; onDone(); } }, 3000);
|
||||
};
|
||||
</script>
|
||||
<nav class="uk-navbar-container uk-margin tb-navbar" uk-navbar>
|
||||
<div class="uk-navbar-center">
|
||||
<div class="uk-navbar-center-left">
|
||||
<div>
|
||||
<ul class="uk-navbar-nav">
|
||||
|
||||
<li><a href="/explore">探索</a></li>
|
||||
|
||||
|
||||
<li class="tb-mobile-balancer" aria-hidden="true"><a tabindex="-1" style="visibility:hidden">マイ</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="uk-navbar-item uk-logo" href="/"><span class="emoji-placeholder" aria-label="random animal">🐺</span>の質問箱</a>
|
||||
|
||||
<div class="uk-navbar-center-right">
|
||||
<div>
|
||||
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/register">登録</a></li>
|
||||
</ul>
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/login">ログイン</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" aria-label="言語" title="言語"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="9"/><path d="M3.2 9h17.6M3.2 15h17.6"/><ellipse cx="12" cy="12" rx="4" ry="9"/></svg></a>
|
||||
<div class="uk-navbar-dropdown" uk-drop="mode: click; pos: bottom-right">
|
||||
<ul class="uk-nav uk-navbar-dropdown-nav">
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/zh-CN?to=%2Fvote%2FC84m7PoENWsG">简体中文</a>
|
||||
</li>
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/zh-TW?to=%2Fvote%2FC84m7PoENWsG">繁體中文</a>
|
||||
</li>
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/en?to=%2Fvote%2FC84m7PoENWsG">English</a>
|
||||
</li>
|
||||
|
||||
<li class="uk-active">
|
||||
<a href="/i18n/ja?to=%2Fvote%2FC84m7PoENWsG">日本語</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" id="theme-toggle" title="ダーク/ライトモード切替" aria-label="ダーク/ライトモード切替">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const emojis = ["🐺","🐗","🐻","🐨","🐼","🐹","🐭","🐰","🦊","🐮","🐷","🐽","🐸","🐒","🦍","🐔","🐧","🐦","🐤","🐦⬛","🦅","🦉","🦇","🐴","🦄","🐝","🦎","🦖","🦕","🐙","🦑","🦐","🦞","🦀","🐡","🐠","🐟","🐬","🐳","🐋","🦈","🐊","🐅","🐆","🦓","🦍","🦧","🐘","🦛","🦏","🐪","🐫","🦒","🦘","🐃","🐂","🐄","🐎","🐖","🐏","🐑","🦙","🐐","🦌","🐕","🐩","🦮","🐕🦺","🐈","🐋","🐳","🐬","🐉","🐲"];
|
||||
const placeholder = document.querySelector('.emoji-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.textContent = emojis[Math.floor(Math.random() * emojis.length)];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="tb-mobile-utils">
|
||||
|
||||
<select id="mobile-lang-select" class="uk-select uk-form-small" aria-label="言語">
|
||||
|
||||
<option value="zh-CN" >简体中文</option>
|
||||
|
||||
<option value="zh-TW" >繁體中文</option>
|
||||
|
||||
<option value="en" >English</option>
|
||||
|
||||
<option value="ja" selected>日本語</option>
|
||||
|
||||
</select>
|
||||
|
||||
<button type="button" id="theme-toggle-mobile" class="uk-button uk-button-default uk-button-small"
|
||||
title="ダーク/ライトモード切替" aria-label="ダーク/ライトモード切替">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
var THEME_COOKIE = 'theme';
|
||||
function getTheme() {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
return m ? m[1] : '';
|
||||
}
|
||||
function applyTheme(theme) {
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
}
|
||||
}
|
||||
function toggleTheme() {
|
||||
var next = getTheme() === 'dark' ? 'light' : 'dark';
|
||||
applyTheme(next);
|
||||
var expires = new Date(Date.now() + 365 * 24 * 3600 * 1000).toUTCString();
|
||||
document.cookie = THEME_COOKIE + '=' + next + '; path=/; max-age=' + (365 * 24 * 3600) + '; SameSite=Lax';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
var buttons = document.querySelectorAll('#theme-toggle, #theme-toggle-mobile');
|
||||
buttons.forEach(function(btn) {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
toggleTheme();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var langSel = document.getElementById('mobile-lang-select');
|
||||
if (langSel) {
|
||||
langSel.addEventListener('change', function() {
|
||||
if (!this.value) return;
|
||||
var to = window.location.pathname + window.location.search;
|
||||
window.location.href = '/i18n/' + encodeURIComponent(this.value) + '?to=' + encodeURIComponent(to);
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-container uk-container-xsmall">
|
||||
|
||||
|
||||
|
||||
<div id="math-captcha-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body uk-text-center">
|
||||
<h3 class="uk-modal-title">人機認証</h3>
|
||||
<p class="uk-text-meta">以下の計算問題を解いて、ロボットでないことを証明してください</p>
|
||||
<div class="captcha-equation-box">
|
||||
<span id="captcha-modal-question" class="math-captcha-modal-question">読み込み中...</span>
|
||||
<input type="number" id="captcha-modal-answer" placeholder="?" autocomplete="off" inputmode="numeric">
|
||||
</div>
|
||||
<div style="margin-top:6px;">
|
||||
<button type="button" class="uk-button uk-button-text uk-text-small" id="captcha-modal-refresh">別の問題</button>
|
||||
</div>
|
||||
<div id="captcha-modal-error" class="uk-text-danger uk-text-small" style="display:none;min-height:20px;"></div>
|
||||
<div class="uk-margin-small-top">
|
||||
<button type="button" class="uk-button uk-button-primary" id="captcha-modal-submit">送信</button>
|
||||
<button type="button" class="uk-button uk-button-default uk-modal-close">キャンセル</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var CAPTCHA_I18N = {
|
||||
loading: "読み込み中...",
|
||||
loadFailed: "読み込み失敗",
|
||||
loadRetry: "読み込み失敗、再試行してください",
|
||||
inputAnswer: "答えを入力してください",
|
||||
wrongAnswer: "答えが違います。もう一度計算してください",
|
||||
verifyFailed: "認証失敗、再試行してください",
|
||||
needPassword: "この質問箱にはパスワードが必要です",
|
||||
needEmail: "通知を受け取るメールアドレスを入力してください"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var captchaId = '';
|
||||
var pendingForm = null;
|
||||
var pendingNeedPassword = false;
|
||||
var verifying = false;
|
||||
|
||||
function fetchCaptcha() {
|
||||
var qEl = document.getElementById('captcha-modal-question');
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
var ansEl = document.getElementById('captcha-modal-answer');
|
||||
qEl.textContent = CAPTCHA_I18N.loading;
|
||||
fetch('/api/captcha/generate')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.code === 0 && data.data) {
|
||||
captchaId = data.data.id;
|
||||
qEl.textContent = data.data.question;
|
||||
if (errEl) errEl.style.display = 'none';
|
||||
if (ansEl) { ansEl.value = ''; ansEl.focus(); }
|
||||
} else {
|
||||
qEl.textContent = CAPTCHA_I18N.loadFailed;
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
qEl.textContent = CAPTCHA_I18N.loadRetry;
|
||||
});
|
||||
}
|
||||
|
||||
function getCSRFToken() {
|
||||
var input = document.querySelector('input[name="_csrf"]');
|
||||
return input ? input.value : '';
|
||||
}
|
||||
|
||||
function doSubmit(form) {
|
||||
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
var hidden = form.querySelector('[name="g-recaptcha-response"]');
|
||||
if (hidden) hidden.value = captchaId + ':' + (ans || '0');
|
||||
|
||||
UIkit.modal('#math-captcha-modal').hide();
|
||||
|
||||
|
||||
if (pendingNeedPassword) {
|
||||
UIkit.modal.prompt(CAPTCHA_I18N.needPassword, '', 'password')
|
||||
.then(function(password) {
|
||||
if (password) {
|
||||
var pwInput = document.getElementById('ask_password_input');
|
||||
if (pwInput) pwInput.value = password;
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-submit').addEventListener('click', function() {
|
||||
if (verifying) return;
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
if (!ans) {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.inputAnswer;
|
||||
errEl.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
verifying = true;
|
||||
fetch('/api/captcha/verify', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-Token': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify({ id: captchaId, answer: parseInt(ans, 10) })
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
verifying = false;
|
||||
if (data.correct) {
|
||||
if (pendingForm) doSubmit(pendingForm);
|
||||
} else {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.wrongAnswer;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
verifying = false;
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.verifyFailed;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-answer').addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
document.getElementById('captcha-modal-submit').click();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-refresh').addEventListener('click', fetchCaptcha);
|
||||
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target.closest('.math-captcha-trigger');
|
||||
if (!btn) return;
|
||||
e.preventDefault();
|
||||
|
||||
var form = btn.closest('form');
|
||||
if (!form) return;
|
||||
pendingForm = form;
|
||||
|
||||
|
||||
pendingNeedPassword = !!(form.querySelector('#ask_password_input'));
|
||||
|
||||
|
||||
var notifyCb = document.getElementById('notify-checkbox');
|
||||
var emailInput = document.getElementById('email-input');
|
||||
if (notifyCb && notifyCb.checked && emailInput && emailInput.value.trim() === '') {
|
||||
UIkit.modal.alert(CAPTCHA_I18N.needEmail);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchCaptcha();
|
||||
UIkit.modal('#math-captcha-modal').show();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<style>
|
||||
|
||||
.tb-field-head {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 6px 8px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.tb-field-head .tb-field-label {
|
||||
flex-basis: 100%;
|
||||
font-weight: 600;
|
||||
line-height: 1.5;
|
||||
word-break: break-word;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.tb-choice {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
padding: 12px 14px;
|
||||
margin-bottom: 8px;
|
||||
border: 1px solid var(--tb-border);
|
||||
border-radius: 8px;
|
||||
background: var(--tb-surface);
|
||||
cursor: pointer;
|
||||
transition: border-color 0.2s ease, background 0.2s ease;
|
||||
}
|
||||
.tb-choice:last-child { margin-bottom: 0; }
|
||||
.tb-choice input[type="radio"], .tb-choice input[type="checkbox"] {
|
||||
margin-top: 3px;
|
||||
}
|
||||
.tb-choice span {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
line-height: 1.5;
|
||||
word-break: break-word;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.tb-choice:hover {
|
||||
border-color: var(--tb-primary);
|
||||
background: var(--tb-surface-hover);
|
||||
}
|
||||
.tb-choice:has(input:checked) {
|
||||
border-color: var(--tb-primary);
|
||||
background: var(--tb-surface-active);
|
||||
}
|
||||
html[data-theme="dark"] .tb-choice {
|
||||
border-color: var(--tb-border);
|
||||
background: var(--tb-surface);
|
||||
}
|
||||
html[data-theme="dark"] .tb-choice:hover {
|
||||
border-color: var(--tb-primary);
|
||||
background: rgba(78, 168, 245, 0.08);
|
||||
}
|
||||
html[data-theme="dark"] .tb-choice:has(input:checked) {
|
||||
border-color: var(--tb-primary);
|
||||
background: rgba(78, 168, 245, 0.14);
|
||||
}
|
||||
|
||||
.tb-custom-input {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.tb-text-counter {
|
||||
margin-top: 2px;
|
||||
text-align: right;
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.tb-choice { padding: 10px 12px; }
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-body uk-margin-bottom">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 10px;">
|
||||
|
||||
<img class="uk-border-circle" src="https://r2.337845818.best/tamabox/picture/2026/08/19/9af3e38222d972ff9141e9cfdb0475" style="width: 40px; height: 40px;">
|
||||
<div>
|
||||
<a class="uk-text-bold" href="/_admin6">admin6</a>
|
||||
<div class="uk-text-meta uk-text-small">の投票</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-auto-left">
|
||||
|
||||
|
||||
<span class="uk-label uk-label-success">進行中</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="uk-margin-remove-top uk-margin-small-bottom">测试5</h3>
|
||||
|
||||
<p class="uk-margin-remove-top">测试一下flash</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="uk-alert uk-alert-primary uk-text-small">匿名での参加が可能で、あなたの身元は記録されません(同一端末で最大1回)。</div>
|
||||
|
||||
|
||||
<form method="post" action="/vote/C84m7PoENWsG/submit" id="vote-form" onsubmit="return validateVoteForm()">
|
||||
<input type="hidden" name="_csrf" value="f3nSTDvVifkh5vl5c233H4QoL9Y6MTc5MjM4NDM2NDc4MTM1MDY0Mg">
|
||||
<input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response" value="">
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-body uk-margin-bottom">
|
||||
|
||||
|
||||
<label class="tb-choice">
|
||||
<input class="uk-radio" type="radio" name="option_id" value="11" data-vote-required data-vote-label="测试5"><span>1</span>
|
||||
</label>
|
||||
|
||||
<label class="tb-choice">
|
||||
<input class="uk-radio" type="radio" name="option_id" value="12" data-vote-required data-vote-label="测试5"><span>2</span>
|
||||
</label>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
|
||||
<button type="button" class="uk-button uk-button-primary math-captcha-trigger" onclick="return voteValidate(event)">投票する</button>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
var MAX_CUSTOM_LEN = 200 ;
|
||||
|
||||
|
||||
|
||||
function countChars(s) { return Array.from(String(s || '')).length; }
|
||||
|
||||
|
||||
function setupTextCounters() {
|
||||
var form = document.getElementById('vote-form');
|
||||
if (!form) { return; }
|
||||
form.querySelectorAll('[data-tb-text-counter]').forEach(function (input) {
|
||||
var max = parseInt(input.getAttribute('data-tb-text-max'), 10);
|
||||
if (!max || max < 1) { max = MAX_CUSTOM_LEN; }
|
||||
var counter = document.createElement('div');
|
||||
counter.className = 'uk-text-meta uk-text-small tb-text-counter';
|
||||
if (input.parentNode) { input.parentNode.insertBefore(counter, input.nextSibling); }
|
||||
var update = function () {
|
||||
var n = countChars(input.value);
|
||||
counter.textContent = n + ' / ' + max;
|
||||
if (n > max) {
|
||||
counter.classList.add('uk-text-danger');
|
||||
input.setAttribute('data-tb-too-long', '1');
|
||||
} else {
|
||||
counter.classList.remove('uk-text-danger');
|
||||
input.removeAttribute('data-tb-too-long');
|
||||
}
|
||||
};
|
||||
input.addEventListener('input', update);
|
||||
update();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
function validateVoteForm() {
|
||||
var form = document.getElementById('vote-form');
|
||||
if (!form) { return true; }
|
||||
|
||||
var tooLong = form.querySelector('[data-tb-text-counter][data-tb-too-long]');
|
||||
if (tooLong) {
|
||||
alert('自由記入オプションは 200 字以内にしてください');
|
||||
tooLong.focus();
|
||||
return false;
|
||||
}
|
||||
|
||||
var groups = {};
|
||||
form.querySelectorAll('input[data-vote-required][type="radio"], input[data-vote-required][type="checkbox"]').forEach(function (el) {
|
||||
(groups[el.name] = groups[el.name] || []).push(el);
|
||||
});
|
||||
for (var name in groups) {
|
||||
var any = groups[name].some(function (el) { return el.checked; });
|
||||
if (!any) {
|
||||
alert('入力してください「' + groups[name][0].getAttribute('data-vote-label') + '」');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var els = form.querySelectorAll('[data-vote-required]:not(input[type="radio"]):not(input[type="checkbox"])');
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
var el = els[i];
|
||||
if (el.disabled) { continue; }
|
||||
if ((el.value || '').trim() === '') {
|
||||
alert('入力してください「' + el.getAttribute('data-vote-label') + '」');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function voteValidate(e) {
|
||||
if (!validateVoteForm()) {
|
||||
if (e) { e.stopPropagation(); e.preventDefault(); }
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
if (validateVoteForm()) {
|
||||
document.getElementById('vote-form').submit();
|
||||
}
|
||||
}
|
||||
|
||||
(function () {
|
||||
var form = document.getElementById('vote-form');
|
||||
if (!form) { return; }
|
||||
setupTextCounters();
|
||||
var maxChoices = 0;
|
||||
if (maxChoices > 0) {
|
||||
var boxes = form.querySelectorAll('input[type="checkbox"][name="option_ids"]');
|
||||
boxes.forEach(function (box) {
|
||||
box.addEventListener('change', function () {
|
||||
var checked = form.querySelectorAll('input[type="checkbox"][name="option_ids"]:checked').length;
|
||||
if (checked > maxChoices) { this.checked = false; }
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var CUSTOM_MARKER = "__tb_custom_option__";
|
||||
form.querySelectorAll('[data-vote-custom-input]').forEach(function (input) {
|
||||
var fid = input.getAttribute('data-vote-custom-input');
|
||||
var group = form.querySelectorAll('input[name="field_' + fid + '"]');
|
||||
var select = form.querySelector('select[name="field_' + fid + '"]');
|
||||
var sync = function () {
|
||||
var on = false;
|
||||
if (select) {
|
||||
on = (select.value === CUSTOM_MARKER);
|
||||
} else {
|
||||
group.forEach(function (r) { if (r.value === CUSTOM_MARKER && r.checked) { on = true; } });
|
||||
}
|
||||
input.disabled = !on;
|
||||
if (!on) { input.value = ''; }
|
||||
};
|
||||
if (select) { select.addEventListener('change', sync); } else { group.forEach(function (r) { r.addEventListener('change', sync); }); }
|
||||
sync();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<p class=" uk-text-right uk-text-muted uk-text-small">
|
||||
<br>
|
||||
<a href="/rules">ルール</a> |
|
||||
|
||||
<a href="https://box.shiroko.one/_/tamakyi" target="_blank">管理者へ</a>
|
||||
<br>
|
||||
<a href="https://share.shiroko.one" target="_blank">ドライブ</a>
|
||||
| <a href="https://blog.shiroko.one" target="_blank">お知らせ</a>
|
||||
| <a href="https://chat.shiroko.one" target="_blank">チャット</a>
|
||||
| <a href="https://status.shiroko.one" target="_blank">ステータス</a>
|
||||
| <a href="https://shiroko.one" target="_blank">リンク</a>
|
||||
<br>Powered by NekoBox | 狼ICP备 20230101
|
||||
<br>質問箱は稼働中:<span id="box_runtime"></span>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
(function () {
|
||||
var create = Math.round(Date.UTC(2023, 6, 1, 18, 15, 43) / 1000);
|
||||
function tick() {
|
||||
var el = document.getElementById("box_runtime");
|
||||
if (!el) return;
|
||||
var s = Math.round((Date.now() + 8 * 3600 * 1000) / 1000) - create;
|
||||
var t = [0, 0, 0, 0, 0];
|
||||
if (s >= 31536000) { t[0] = s / 31536000 | 0; s %= 31536000; }
|
||||
if (s >= 86400) { t[1] = s / 86400 | 0; s %= 86400; }
|
||||
if (s >= 3600) { t[2] = s / 3600 | 0; s %= 3600; }
|
||||
if (s >= 60) { t[3] = s / 60 | 0; s %= 60; }
|
||||
if (s > 0) { t[4] = s; }
|
||||
el.innerHTML = t[0] + '年 ' + t[1] + '天 ' + t[2] + '时 ' + t[3] + '分 ' + t[4] + '秒 ';
|
||||
}
|
||||
tick();
|
||||
setInterval(tick, 1000);
|
||||
})();
|
||||
</script>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
var SUBMIT_I18N = {
|
||||
submitting: '送信中...',
|
||||
uploading: 'アップロード中...'
|
||||
};
|
||||
|
||||
function tbResetSubmitButtons() {
|
||||
document.querySelectorAll('button[data-tb-submitting]').forEach(function(b) {
|
||||
b.disabled = false;
|
||||
b.removeAttribute('data-tb-submitting');
|
||||
var orig = b.getAttribute('data-tb-restore');
|
||||
if (orig !== null) {
|
||||
b.innerHTML = orig;
|
||||
b.removeAttribute('data-tb-restore');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('submit', function(e) {
|
||||
var form = e.target;
|
||||
if (!form || form.tagName !== 'FORM') return;
|
||||
|
||||
|
||||
|
||||
if (e.defaultPrevented || form.getAttribute('data-tb-skip-submit-feedback') === '1') {
|
||||
form.removeAttribute('data-tb-skip-submit-feedback');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (form.getAttribute('target') === '_blank') return;
|
||||
|
||||
|
||||
var trigger = e.submitter || form.querySelector('button[type="submit"]');
|
||||
|
||||
|
||||
var hasFile = false;
|
||||
form.querySelectorAll('input[type="file"]').forEach(function(f) {
|
||||
if (f.files && f.files.length > 0) hasFile = true;
|
||||
});
|
||||
var label = hasFile ? SUBMIT_I18N.uploading : SUBMIT_I18N.submitting;
|
||||
|
||||
if (trigger && trigger.tagName === 'BUTTON') {
|
||||
trigger.setAttribute('data-tb-restore', trigger.innerHTML);
|
||||
trigger.innerHTML = '<span uk-spinner="ratio: 0.6"></span> ' + label;
|
||||
}
|
||||
|
||||
|
||||
form.querySelectorAll('button').forEach(function(b) {
|
||||
b.disabled = true;
|
||||
b.setAttribute('data-tb-submitting', '1');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener('pageshow', tbResetSubmitButtons);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,901 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>明天吃什么</title>
|
||||
<meta name="msvalidate.01" content="2F185E8E63C93635F50B3574F3B31E42" />
|
||||
<meta name="description" content="狼の質問箱は登録不要で使える匿名質問箱。誰でも匿名で質問でき、安心してやり取りできる場所です。">
|
||||
<meta name="keywords" content="匿名質問箱,質問箱,匿名質問,狼の質問箱,匿名で質問,匿名Q&A">
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
if (m && m[1] === 'dark') document.documentElement.setAttribute('data-theme', 'dark');
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://r2.337845818.best" crossorigin>
|
||||
<link rel="preconnect" href="https://cdnjs.snrat.com" crossorigin>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/css/uikit.min.css"/>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/base.css?v=20261019c"/>
|
||||
|
||||
<link rel="stylesheet" href="https://r2.337845818.best/tamabox/cdn/waline/client/v2/waline-no-commits.css" media="print" onload="this.media='all'"/>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit-icons.min.js"></script>
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/dayjs/1.10.8/dayjs.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/alpinejs/3.9.0/cdn.min.js"></script>
|
||||
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/waline/2.15.8/waline.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.captcha-equation-box {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: #f0f2f5;
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 8px;
|
||||
padding: 8px 8px 8px 16px;
|
||||
gap: 6px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
.captcha-equation-box:focus-within {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 3px rgba(30,135,240,0.12);
|
||||
}
|
||||
.math-captcha-modal-question {
|
||||
font-size: 1.4rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
letter-spacing: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
width: 80px;
|
||||
padding: 6px 10px;
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 600;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
transition: border-color 0.15s, box-shadow 0.15s;
|
||||
background: #fff;
|
||||
}
|
||||
#captcha-modal-answer:focus {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 2px rgba(30,135,240,0.2);
|
||||
}
|
||||
|
||||
#captcha-modal-answer::-webkit-inner-spin-button,
|
||||
#captcha-modal-answer::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta property="og:site_name" content="狼の質問箱 | 匿名質問箱" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content="狼の質問箱 | 匿名質問箱" />
|
||||
<meta property="og:url" content="https://box-dev-api.337845818.best/vote/GJkdls4fH78y" />
|
||||
<meta property="og:description" content="狼の質問箱は登録不要で使える匿名質問箱。誰でも匿名で質問でき、安心してやり取りできる場所です。" />
|
||||
<meta name="robots" content="noindex">
|
||||
|
||||
<meta itemprop="image" content="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<meta name="msapplication-TileImage" content="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<link rel="shortcut icon" href="https://r2.337845818.best/tamabox/tamabox_low.png" />
|
||||
<link rel="apple-touch-icon" href="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<link rel="icon" sizes="192x192" href="https://r2.337845818.best/tamabox/tamabox_low.png">
|
||||
<meta name="twitter:image:src" content="https://r2.337845818.best/tamabox/tamabox_low.png" />
|
||||
|
||||
|
||||
|
||||
<meta name="google-site-verification" content="fEPwRRJfiGsgwc5SINBQwZhPK8F0cwRaOvRx0YRurI4" />
|
||||
|
||||
<script>
|
||||
window.addEventListener("load", function () {
|
||||
var s = document.createElement("script");
|
||||
s.src = "https://mami.shiroko.one/tamami.js";
|
||||
s.setAttribute("data-website-id", "c42ebe8b-9281-4da0-83a4-8f18b3e710fe");
|
||||
document.body.appendChild(s);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window.tbRenderQR = function (el, getOptions) {
|
||||
if (!el || typeof QRCode === 'undefined') return;
|
||||
var opts = getOptions();
|
||||
function remoteOf(o, key) {
|
||||
var v = o[key];
|
||||
return (typeof v === 'string' && v.indexOf('http') === 0) ? v : '';
|
||||
}
|
||||
var good = window._tbQrGood || (window._tbQrGood = {});
|
||||
var bad = window._tbQrBad || (window._tbQrBad = {});
|
||||
|
||||
function layerState(url) { return !url ? '' : (good[url] ? 1 : (bad[url] ? 0 : null)); }
|
||||
var layers = [
|
||||
{ url: remoteOf(opts, 'logo'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.logo = undefined; o.logoWidth = undefined; o.logoHeight = undefined; o.logoBackgroundTransparent = undefined; }
|
||||
} },
|
||||
{ url: remoteOf(opts, 'backgroundImage'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.backgroundImage = undefined; o.backgroundImageAlpha = undefined; }
|
||||
} }
|
||||
];
|
||||
var needProbe = false;
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
layers[i].st = layerState(layers[i].url);
|
||||
if (layers[i].st === null) needProbe = true;
|
||||
}
|
||||
function paint(states) {
|
||||
var o = {};
|
||||
for (var k in opts) o[k] = opts[k];
|
||||
for (var j = 0; j < layers.length; j++) layers[j].present(o, states[j] === 1);
|
||||
el.innerHTML = '';
|
||||
new QRCode(el, o);
|
||||
}
|
||||
|
||||
var initStates = [];
|
||||
for (var n = 0; n < layers.length; n++) initStates.push(layers[n].st === 1 ? 1 : 0);
|
||||
paint(initStates);
|
||||
if (!needProbe) return;
|
||||
|
||||
var pending = 0, cross = opts.crossOrigin || 'anonymous';
|
||||
layers.forEach(function (L) {
|
||||
if (L.st !== null) return;
|
||||
pending++;
|
||||
var im = new Image();
|
||||
im.onload = function () { good[L.url] = true; L.st = 1; onDone(); };
|
||||
im.onerror = function () { bad[L.url] = true; L.st = 0; onDone(); };
|
||||
if (cross) im.crossOrigin = cross;
|
||||
im.src = L.url;
|
||||
});
|
||||
function onDone() {
|
||||
if (--pending > 0) return;
|
||||
var finalStates = [];
|
||||
for (var m = 0; m < layers.length; m++) finalStates.push(layers[m].st === 1 ? 1 : 0);
|
||||
var changed = false;
|
||||
for (var q = 0; q < finalStates.length; q++) if (finalStates[q] !== initStates[q]) changed = true;
|
||||
if (changed) paint(finalStates);
|
||||
}
|
||||
|
||||
setTimeout(function () { if (pending > 0) { pending = 0; onDone(); } }, 3000);
|
||||
};
|
||||
</script>
|
||||
<nav class="uk-navbar-container uk-margin tb-navbar" uk-navbar>
|
||||
<div class="uk-navbar-center">
|
||||
<div class="uk-navbar-center-left">
|
||||
<div>
|
||||
<ul class="uk-navbar-nav">
|
||||
|
||||
<li><a href="/explore">探索</a></li>
|
||||
|
||||
|
||||
<li class="tb-mobile-balancer" aria-hidden="true"><a tabindex="-1" style="visibility:hidden">マイ</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="uk-navbar-item uk-logo" href="/"><span class="emoji-placeholder" aria-label="random animal">🐺</span>の質問箱</a>
|
||||
|
||||
<div class="uk-navbar-center-right">
|
||||
<div>
|
||||
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/register">登録</a></li>
|
||||
</ul>
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/login">ログイン</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" aria-label="言語" title="言語"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="9"/><path d="M3.2 9h17.6M3.2 15h17.6"/><ellipse cx="12" cy="12" rx="4" ry="9"/></svg></a>
|
||||
<div class="uk-navbar-dropdown" uk-drop="mode: click; pos: bottom-right">
|
||||
<ul class="uk-nav uk-navbar-dropdown-nav">
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/zh-CN?to=%2Fvote%2FGJkdls4fH78y">简体中文</a>
|
||||
</li>
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/zh-TW?to=%2Fvote%2FGJkdls4fH78y">繁體中文</a>
|
||||
</li>
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/en?to=%2Fvote%2FGJkdls4fH78y">English</a>
|
||||
</li>
|
||||
|
||||
<li class="uk-active">
|
||||
<a href="/i18n/ja?to=%2Fvote%2FGJkdls4fH78y">日本語</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" id="theme-toggle" title="ダーク/ライトモード切替" aria-label="ダーク/ライトモード切替">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const emojis = ["🐺","🐗","🐻","🐨","🐼","🐹","🐭","🐰","🦊","🐮","🐷","🐽","🐸","🐒","🦍","🐔","🐧","🐦","🐤","🐦⬛","🦅","🦉","🦇","🐴","🦄","🐝","🦎","🦖","🦕","🐙","🦑","🦐","🦞","🦀","🐡","🐠","🐟","🐬","🐳","🐋","🦈","🐊","🐅","🐆","🦓","🦍","🦧","🐘","🦛","🦏","🐪","🐫","🦒","🦘","🐃","🐂","🐄","🐎","🐖","🐏","🐑","🦙","🐐","🦌","🐕","🐩","🦮","🐕🦺","🐈","🐋","🐳","🐬","🐉","🐲"];
|
||||
const placeholder = document.querySelector('.emoji-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.textContent = emojis[Math.floor(Math.random() * emojis.length)];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="tb-mobile-utils">
|
||||
|
||||
<select id="mobile-lang-select" class="uk-select uk-form-small" aria-label="言語">
|
||||
|
||||
<option value="zh-CN" >简体中文</option>
|
||||
|
||||
<option value="zh-TW" >繁體中文</option>
|
||||
|
||||
<option value="en" >English</option>
|
||||
|
||||
<option value="ja" selected>日本語</option>
|
||||
|
||||
</select>
|
||||
|
||||
<button type="button" id="theme-toggle-mobile" class="uk-button uk-button-default uk-button-small"
|
||||
title="ダーク/ライトモード切替" aria-label="ダーク/ライトモード切替">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
var THEME_COOKIE = 'theme';
|
||||
function getTheme() {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
return m ? m[1] : '';
|
||||
}
|
||||
function applyTheme(theme) {
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
}
|
||||
}
|
||||
function toggleTheme() {
|
||||
var next = getTheme() === 'dark' ? 'light' : 'dark';
|
||||
applyTheme(next);
|
||||
var expires = new Date(Date.now() + 365 * 24 * 3600 * 1000).toUTCString();
|
||||
document.cookie = THEME_COOKIE + '=' + next + '; path=/; max-age=' + (365 * 24 * 3600) + '; SameSite=Lax';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
var buttons = document.querySelectorAll('#theme-toggle, #theme-toggle-mobile');
|
||||
buttons.forEach(function(btn) {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
toggleTheme();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var langSel = document.getElementById('mobile-lang-select');
|
||||
if (langSel) {
|
||||
langSel.addEventListener('change', function() {
|
||||
if (!this.value) return;
|
||||
var to = window.location.pathname + window.location.search;
|
||||
window.location.href = '/i18n/' + encodeURIComponent(this.value) + '?to=' + encodeURIComponent(to);
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-container uk-container-xsmall">
|
||||
|
||||
|
||||
|
||||
<div id="math-captcha-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body uk-text-center">
|
||||
<h3 class="uk-modal-title">人機認証</h3>
|
||||
<p class="uk-text-meta">以下の計算問題を解いて、ロボットでないことを証明してください</p>
|
||||
<div class="captcha-equation-box">
|
||||
<span id="captcha-modal-question" class="math-captcha-modal-question">読み込み中...</span>
|
||||
<input type="number" id="captcha-modal-answer" placeholder="?" autocomplete="off" inputmode="numeric">
|
||||
</div>
|
||||
<div style="margin-top:6px;">
|
||||
<button type="button" class="uk-button uk-button-text uk-text-small" id="captcha-modal-refresh">別の問題</button>
|
||||
</div>
|
||||
<div id="captcha-modal-error" class="uk-text-danger uk-text-small" style="display:none;min-height:20px;"></div>
|
||||
<div class="uk-margin-small-top">
|
||||
<button type="button" class="uk-button uk-button-primary" id="captcha-modal-submit">送信</button>
|
||||
<button type="button" class="uk-button uk-button-default uk-modal-close">キャンセル</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var CAPTCHA_I18N = {
|
||||
loading: "読み込み中...",
|
||||
loadFailed: "読み込み失敗",
|
||||
loadRetry: "読み込み失敗、再試行してください",
|
||||
inputAnswer: "答えを入力してください",
|
||||
wrongAnswer: "答えが違います。もう一度計算してください",
|
||||
verifyFailed: "認証失敗、再試行してください",
|
||||
needPassword: "この質問箱にはパスワードが必要です",
|
||||
needEmail: "通知を受け取るメールアドレスを入力してください"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var captchaId = '';
|
||||
var pendingForm = null;
|
||||
var pendingNeedPassword = false;
|
||||
var verifying = false;
|
||||
|
||||
function fetchCaptcha() {
|
||||
var qEl = document.getElementById('captcha-modal-question');
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
var ansEl = document.getElementById('captcha-modal-answer');
|
||||
qEl.textContent = CAPTCHA_I18N.loading;
|
||||
fetch('/api/captcha/generate')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.code === 0 && data.data) {
|
||||
captchaId = data.data.id;
|
||||
qEl.textContent = data.data.question;
|
||||
if (errEl) errEl.style.display = 'none';
|
||||
if (ansEl) { ansEl.value = ''; ansEl.focus(); }
|
||||
} else {
|
||||
qEl.textContent = CAPTCHA_I18N.loadFailed;
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
qEl.textContent = CAPTCHA_I18N.loadRetry;
|
||||
});
|
||||
}
|
||||
|
||||
function getCSRFToken() {
|
||||
var input = document.querySelector('input[name="_csrf"]');
|
||||
return input ? input.value : '';
|
||||
}
|
||||
|
||||
function doSubmit(form) {
|
||||
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
var hidden = form.querySelector('[name="g-recaptcha-response"]');
|
||||
if (hidden) hidden.value = captchaId + ':' + (ans || '0');
|
||||
|
||||
UIkit.modal('#math-captcha-modal').hide();
|
||||
|
||||
|
||||
if (pendingNeedPassword) {
|
||||
UIkit.modal.prompt(CAPTCHA_I18N.needPassword, '', 'password')
|
||||
.then(function(password) {
|
||||
if (password) {
|
||||
var pwInput = document.getElementById('ask_password_input');
|
||||
if (pwInput) pwInput.value = password;
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-submit').addEventListener('click', function() {
|
||||
if (verifying) return;
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
if (!ans) {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.inputAnswer;
|
||||
errEl.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
verifying = true;
|
||||
fetch('/api/captcha/verify', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-Token': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify({ id: captchaId, answer: parseInt(ans, 10) })
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
verifying = false;
|
||||
if (data.correct) {
|
||||
if (pendingForm) doSubmit(pendingForm);
|
||||
} else {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.wrongAnswer;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
verifying = false;
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.verifyFailed;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-answer').addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
document.getElementById('captcha-modal-submit').click();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-refresh').addEventListener('click', fetchCaptcha);
|
||||
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target.closest('.math-captcha-trigger');
|
||||
if (!btn) return;
|
||||
e.preventDefault();
|
||||
|
||||
var form = btn.closest('form');
|
||||
if (!form) return;
|
||||
pendingForm = form;
|
||||
|
||||
|
||||
pendingNeedPassword = !!(form.querySelector('#ask_password_input'));
|
||||
|
||||
|
||||
var notifyCb = document.getElementById('notify-checkbox');
|
||||
var emailInput = document.getElementById('email-input');
|
||||
if (notifyCb && notifyCb.checked && emailInput && emailInput.value.trim() === '') {
|
||||
UIkit.modal.alert(CAPTCHA_I18N.needEmail);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchCaptcha();
|
||||
UIkit.modal('#math-captcha-modal').show();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<style>
|
||||
|
||||
.tb-field-head {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 6px 8px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.tb-field-head .tb-field-label {
|
||||
flex-basis: 100%;
|
||||
font-weight: 600;
|
||||
line-height: 1.5;
|
||||
word-break: break-word;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.tb-choice {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
padding: 12px 14px;
|
||||
margin-bottom: 8px;
|
||||
border: 1px solid var(--tb-border);
|
||||
border-radius: 8px;
|
||||
background: var(--tb-surface);
|
||||
cursor: pointer;
|
||||
transition: border-color 0.2s ease, background 0.2s ease;
|
||||
}
|
||||
.tb-choice:last-child { margin-bottom: 0; }
|
||||
.tb-choice input[type="radio"], .tb-choice input[type="checkbox"] {
|
||||
margin-top: 3px;
|
||||
}
|
||||
.tb-choice span {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
line-height: 1.5;
|
||||
word-break: break-word;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.tb-choice:hover {
|
||||
border-color: var(--tb-primary);
|
||||
background: var(--tb-surface-hover);
|
||||
}
|
||||
.tb-choice:has(input:checked) {
|
||||
border-color: var(--tb-primary);
|
||||
background: var(--tb-surface-active);
|
||||
}
|
||||
html[data-theme="dark"] .tb-choice {
|
||||
border-color: var(--tb-border);
|
||||
background: var(--tb-surface);
|
||||
}
|
||||
html[data-theme="dark"] .tb-choice:hover {
|
||||
border-color: var(--tb-primary);
|
||||
background: rgba(78, 168, 245, 0.08);
|
||||
}
|
||||
html[data-theme="dark"] .tb-choice:has(input:checked) {
|
||||
border-color: var(--tb-primary);
|
||||
background: rgba(78, 168, 245, 0.14);
|
||||
}
|
||||
|
||||
.tb-custom-input {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.tb-text-counter {
|
||||
margin-top: 2px;
|
||||
text-align: right;
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.tb-choice { padding: 10px 12px; }
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-body uk-margin-bottom">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 10px;">
|
||||
|
||||
<img class="uk-border-circle" src="https://r2.337845818.best/tamabox/picture/2026/08/19/9af3e38222d972ff9141e9cfdb0475" style="width: 40px; height: 40px;">
|
||||
<div>
|
||||
<a class="uk-text-bold" href="/_admin6">admin6</a>
|
||||
<div class="uk-text-meta uk-text-small">の投票</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-auto-left">
|
||||
|
||||
|
||||
<span class="uk-label uk-label-success">進行中</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="uk-margin-remove-top uk-margin-small-bottom">明天吃什么</h3>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="uk-alert uk-alert-warning">
|
||||
この投票は登録ユーザーのみ参加できます。ログインしてください。 <a href="/login?to=%2fvote%2fGJkdls4fH78y">ログイン</a>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<form method="post" action="/vote/GJkdls4fH78y/submit" id="vote-form" onsubmit="return validateVoteForm()">
|
||||
<input type="hidden" name="_csrf" value="5fJHChziBfIAQvsCMpKn1Gjfvmg6MTc5MjM4NDM2ODY0NzQwNzkyMQ">
|
||||
<input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response" value="">
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-body uk-margin-bottom">
|
||||
|
||||
<label class="uk-form-label">評価</label>
|
||||
<select class="uk-select" name="rating_value" style="max-width: 200px;" data-vote-required data-vote-label="明天吃什么">
|
||||
<option value=""></option>
|
||||
|
||||
<option value="1">1 点</option>
|
||||
|
||||
<option value="2">2 点</option>
|
||||
|
||||
<option value="3">3 点</option>
|
||||
|
||||
<option value="4">4 点</option>
|
||||
|
||||
<option value="5">5 点</option>
|
||||
|
||||
<option value="6">6 点</option>
|
||||
|
||||
<option value="7">7 点</option>
|
||||
|
||||
<option value="8">8 点</option>
|
||||
|
||||
<option value="9">9 点</option>
|
||||
|
||||
<option value="10">10 点</option>
|
||||
|
||||
</select>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
|
||||
<button type="button" class="uk-button uk-button-primary math-captcha-trigger" onclick="return voteValidate(event)">投票する</button>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
var MAX_CUSTOM_LEN = 200 ;
|
||||
|
||||
|
||||
|
||||
function countChars(s) { return Array.from(String(s || '')).length; }
|
||||
|
||||
|
||||
function setupTextCounters() {
|
||||
var form = document.getElementById('vote-form');
|
||||
if (!form) { return; }
|
||||
form.querySelectorAll('[data-tb-text-counter]').forEach(function (input) {
|
||||
var max = parseInt(input.getAttribute('data-tb-text-max'), 10);
|
||||
if (!max || max < 1) { max = MAX_CUSTOM_LEN; }
|
||||
var counter = document.createElement('div');
|
||||
counter.className = 'uk-text-meta uk-text-small tb-text-counter';
|
||||
if (input.parentNode) { input.parentNode.insertBefore(counter, input.nextSibling); }
|
||||
var update = function () {
|
||||
var n = countChars(input.value);
|
||||
counter.textContent = n + ' / ' + max;
|
||||
if (n > max) {
|
||||
counter.classList.add('uk-text-danger');
|
||||
input.setAttribute('data-tb-too-long', '1');
|
||||
} else {
|
||||
counter.classList.remove('uk-text-danger');
|
||||
input.removeAttribute('data-tb-too-long');
|
||||
}
|
||||
};
|
||||
input.addEventListener('input', update);
|
||||
update();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
function validateVoteForm() {
|
||||
var form = document.getElementById('vote-form');
|
||||
if (!form) { return true; }
|
||||
|
||||
var tooLong = form.querySelector('[data-tb-text-counter][data-tb-too-long]');
|
||||
if (tooLong) {
|
||||
alert('自由記入オプションは 200 字以内にしてください');
|
||||
tooLong.focus();
|
||||
return false;
|
||||
}
|
||||
|
||||
var groups = {};
|
||||
form.querySelectorAll('input[data-vote-required][type="radio"], input[data-vote-required][type="checkbox"]').forEach(function (el) {
|
||||
(groups[el.name] = groups[el.name] || []).push(el);
|
||||
});
|
||||
for (var name in groups) {
|
||||
var any = groups[name].some(function (el) { return el.checked; });
|
||||
if (!any) {
|
||||
alert('入力してください「' + groups[name][0].getAttribute('data-vote-label') + '」');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var els = form.querySelectorAll('[data-vote-required]:not(input[type="radio"]):not(input[type="checkbox"])');
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
var el = els[i];
|
||||
if (el.disabled) { continue; }
|
||||
if ((el.value || '').trim() === '') {
|
||||
alert('入力してください「' + el.getAttribute('data-vote-label') + '」');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function voteValidate(e) {
|
||||
if (!validateVoteForm()) {
|
||||
if (e) { e.stopPropagation(); e.preventDefault(); }
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
if (validateVoteForm()) {
|
||||
document.getElementById('vote-form').submit();
|
||||
}
|
||||
}
|
||||
|
||||
(function () {
|
||||
var form = document.getElementById('vote-form');
|
||||
if (!form) { return; }
|
||||
setupTextCounters();
|
||||
var maxChoices = 0;
|
||||
if (maxChoices > 0) {
|
||||
var boxes = form.querySelectorAll('input[type="checkbox"][name="option_ids"]');
|
||||
boxes.forEach(function (box) {
|
||||
box.addEventListener('change', function () {
|
||||
var checked = form.querySelectorAll('input[type="checkbox"][name="option_ids"]:checked').length;
|
||||
if (checked > maxChoices) { this.checked = false; }
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var CUSTOM_MARKER = "__tb_custom_option__";
|
||||
form.querySelectorAll('[data-vote-custom-input]').forEach(function (input) {
|
||||
var fid = input.getAttribute('data-vote-custom-input');
|
||||
var group = form.querySelectorAll('input[name="field_' + fid + '"]');
|
||||
var select = form.querySelector('select[name="field_' + fid + '"]');
|
||||
var sync = function () {
|
||||
var on = false;
|
||||
if (select) {
|
||||
on = (select.value === CUSTOM_MARKER);
|
||||
} else {
|
||||
group.forEach(function (r) { if (r.value === CUSTOM_MARKER && r.checked) { on = true; } });
|
||||
}
|
||||
input.disabled = !on;
|
||||
if (!on) { input.value = ''; }
|
||||
};
|
||||
if (select) { select.addEventListener('change', sync); } else { group.forEach(function (r) { r.addEventListener('change', sync); }); }
|
||||
sync();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<p class=" uk-text-right uk-text-muted uk-text-small">
|
||||
<br>
|
||||
<a href="/rules">ルール</a> |
|
||||
|
||||
<a href="https://box.shiroko.one/_/tamakyi" target="_blank">管理者へ</a>
|
||||
<br>
|
||||
<a href="https://share.shiroko.one" target="_blank">ドライブ</a>
|
||||
| <a href="https://blog.shiroko.one" target="_blank">お知らせ</a>
|
||||
| <a href="https://chat.shiroko.one" target="_blank">チャット</a>
|
||||
| <a href="https://status.shiroko.one" target="_blank">ステータス</a>
|
||||
| <a href="https://shiroko.one" target="_blank">リンク</a>
|
||||
<br>Powered by NekoBox | 狼ICP备 20230101
|
||||
<br>質問箱は稼働中:<span id="box_runtime"></span>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
(function () {
|
||||
var create = Math.round(Date.UTC(2023, 6, 1, 18, 15, 43) / 1000);
|
||||
function tick() {
|
||||
var el = document.getElementById("box_runtime");
|
||||
if (!el) return;
|
||||
var s = Math.round((Date.now() + 8 * 3600 * 1000) / 1000) - create;
|
||||
var t = [0, 0, 0, 0, 0];
|
||||
if (s >= 31536000) { t[0] = s / 31536000 | 0; s %= 31536000; }
|
||||
if (s >= 86400) { t[1] = s / 86400 | 0; s %= 86400; }
|
||||
if (s >= 3600) { t[2] = s / 3600 | 0; s %= 3600; }
|
||||
if (s >= 60) { t[3] = s / 60 | 0; s %= 60; }
|
||||
if (s > 0) { t[4] = s; }
|
||||
el.innerHTML = t[0] + '年 ' + t[1] + '天 ' + t[2] + '时 ' + t[3] + '分 ' + t[4] + '秒 ';
|
||||
}
|
||||
tick();
|
||||
setInterval(tick, 1000);
|
||||
})();
|
||||
</script>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
var SUBMIT_I18N = {
|
||||
submitting: '送信中...',
|
||||
uploading: 'アップロード中...'
|
||||
};
|
||||
|
||||
function tbResetSubmitButtons() {
|
||||
document.querySelectorAll('button[data-tb-submitting]').forEach(function(b) {
|
||||
b.disabled = false;
|
||||
b.removeAttribute('data-tb-submitting');
|
||||
var orig = b.getAttribute('data-tb-restore');
|
||||
if (orig !== null) {
|
||||
b.innerHTML = orig;
|
||||
b.removeAttribute('data-tb-restore');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('submit', function(e) {
|
||||
var form = e.target;
|
||||
if (!form || form.tagName !== 'FORM') return;
|
||||
|
||||
|
||||
|
||||
if (e.defaultPrevented || form.getAttribute('data-tb-skip-submit-feedback') === '1') {
|
||||
form.removeAttribute('data-tb-skip-submit-feedback');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (form.getAttribute('target') === '_blank') return;
|
||||
|
||||
|
||||
var trigger = e.submitter || form.querySelector('button[type="submit"]');
|
||||
|
||||
|
||||
var hasFile = false;
|
||||
form.querySelectorAll('input[type="file"]').forEach(function(f) {
|
||||
if (f.files && f.files.length > 0) hasFile = true;
|
||||
});
|
||||
var label = hasFile ? SUBMIT_I18N.uploading : SUBMIT_I18N.submitting;
|
||||
|
||||
if (trigger && trigger.tagName === 'BUTTON') {
|
||||
trigger.setAttribute('data-tb-restore', trigger.innerHTML);
|
||||
trigger.innerHTML = '<span uk-spinner="ratio: 0.6"></span> ' + label;
|
||||
}
|
||||
|
||||
|
||||
form.querySelectorAll('button').forEach(function(b) {
|
||||
b.disabled = true;
|
||||
b.setAttribute('data-tb-submitting', '1');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener('pageshow', tbResetSubmitButtons);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,887 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>吃什么</title>
|
||||
<meta name="msvalidate.01" content="2F185E8E63C93635F50B3574F3B31E42" />
|
||||
<meta name="description" content="狼の質問箱は登録不要で使える匿名質問箱。誰でも匿名で質問でき、安心してやり取りできる場所です。">
|
||||
<meta name="keywords" content="匿名質問箱,質問箱,匿名質問,狼の質問箱,匿名で質問,匿名Q&A">
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
if (m && m[1] === 'dark') document.documentElement.setAttribute('data-theme', 'dark');
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://r2.337845818.best" crossorigin>
|
||||
<link rel="preconnect" href="https://cdnjs.snrat.com" crossorigin>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/css/uikit.min.css"/>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/base.css?v=20261019c"/>
|
||||
|
||||
<link rel="stylesheet" href="https://r2.337845818.best/tamabox/cdn/waline/client/v2/waline-no-commits.css" media="print" onload="this.media='all'"/>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit-icons.min.js"></script>
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/dayjs/1.10.8/dayjs.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/alpinejs/3.9.0/cdn.min.js"></script>
|
||||
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/waline/2.15.8/waline.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.captcha-equation-box {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: #f0f2f5;
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 8px;
|
||||
padding: 8px 8px 8px 16px;
|
||||
gap: 6px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
.captcha-equation-box:focus-within {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 3px rgba(30,135,240,0.12);
|
||||
}
|
||||
.math-captcha-modal-question {
|
||||
font-size: 1.4rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
letter-spacing: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
width: 80px;
|
||||
padding: 6px 10px;
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 600;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
transition: border-color 0.15s, box-shadow 0.15s;
|
||||
background: #fff;
|
||||
}
|
||||
#captcha-modal-answer:focus {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 2px rgba(30,135,240,0.2);
|
||||
}
|
||||
|
||||
#captcha-modal-answer::-webkit-inner-spin-button,
|
||||
#captcha-modal-answer::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta property="og:site_name" content="狼の質問箱 | 匿名質問箱" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content="狼の質問箱 | 匿名質問箱" />
|
||||
<meta property="og:url" content="https://box-dev-api.337845818.best/vote/t86urUZo26xE" />
|
||||
<meta property="og:description" content="狼の質問箱は登録不要で使える匿名質問箱。誰でも匿名で質問でき、安心してやり取りできる場所です。" />
|
||||
<meta name="robots" content="noindex">
|
||||
|
||||
<meta itemprop="image" content="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<meta name="msapplication-TileImage" content="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<link rel="shortcut icon" href="https://r2.337845818.best/tamabox/tamabox_low.png" />
|
||||
<link rel="apple-touch-icon" href="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<link rel="icon" sizes="192x192" href="https://r2.337845818.best/tamabox/tamabox_low.png">
|
||||
<meta name="twitter:image:src" content="https://r2.337845818.best/tamabox/tamabox_low.png" />
|
||||
|
||||
|
||||
|
||||
<meta name="google-site-verification" content="fEPwRRJfiGsgwc5SINBQwZhPK8F0cwRaOvRx0YRurI4" />
|
||||
|
||||
<script>
|
||||
window.addEventListener("load", function () {
|
||||
var s = document.createElement("script");
|
||||
s.src = "https://mami.shiroko.one/tamami.js";
|
||||
s.setAttribute("data-website-id", "c42ebe8b-9281-4da0-83a4-8f18b3e710fe");
|
||||
document.body.appendChild(s);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window.tbRenderQR = function (el, getOptions) {
|
||||
if (!el || typeof QRCode === 'undefined') return;
|
||||
var opts = getOptions();
|
||||
function remoteOf(o, key) {
|
||||
var v = o[key];
|
||||
return (typeof v === 'string' && v.indexOf('http') === 0) ? v : '';
|
||||
}
|
||||
var good = window._tbQrGood || (window._tbQrGood = {});
|
||||
var bad = window._tbQrBad || (window._tbQrBad = {});
|
||||
|
||||
function layerState(url) { return !url ? '' : (good[url] ? 1 : (bad[url] ? 0 : null)); }
|
||||
var layers = [
|
||||
{ url: remoteOf(opts, 'logo'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.logo = undefined; o.logoWidth = undefined; o.logoHeight = undefined; o.logoBackgroundTransparent = undefined; }
|
||||
} },
|
||||
{ url: remoteOf(opts, 'backgroundImage'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.backgroundImage = undefined; o.backgroundImageAlpha = undefined; }
|
||||
} }
|
||||
];
|
||||
var needProbe = false;
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
layers[i].st = layerState(layers[i].url);
|
||||
if (layers[i].st === null) needProbe = true;
|
||||
}
|
||||
function paint(states) {
|
||||
var o = {};
|
||||
for (var k in opts) o[k] = opts[k];
|
||||
for (var j = 0; j < layers.length; j++) layers[j].present(o, states[j] === 1);
|
||||
el.innerHTML = '';
|
||||
new QRCode(el, o);
|
||||
}
|
||||
|
||||
var initStates = [];
|
||||
for (var n = 0; n < layers.length; n++) initStates.push(layers[n].st === 1 ? 1 : 0);
|
||||
paint(initStates);
|
||||
if (!needProbe) return;
|
||||
|
||||
var pending = 0, cross = opts.crossOrigin || 'anonymous';
|
||||
layers.forEach(function (L) {
|
||||
if (L.st !== null) return;
|
||||
pending++;
|
||||
var im = new Image();
|
||||
im.onload = function () { good[L.url] = true; L.st = 1; onDone(); };
|
||||
im.onerror = function () { bad[L.url] = true; L.st = 0; onDone(); };
|
||||
if (cross) im.crossOrigin = cross;
|
||||
im.src = L.url;
|
||||
});
|
||||
function onDone() {
|
||||
if (--pending > 0) return;
|
||||
var finalStates = [];
|
||||
for (var m = 0; m < layers.length; m++) finalStates.push(layers[m].st === 1 ? 1 : 0);
|
||||
var changed = false;
|
||||
for (var q = 0; q < finalStates.length; q++) if (finalStates[q] !== initStates[q]) changed = true;
|
||||
if (changed) paint(finalStates);
|
||||
}
|
||||
|
||||
setTimeout(function () { if (pending > 0) { pending = 0; onDone(); } }, 3000);
|
||||
};
|
||||
</script>
|
||||
<nav class="uk-navbar-container uk-margin tb-navbar" uk-navbar>
|
||||
<div class="uk-navbar-center">
|
||||
<div class="uk-navbar-center-left">
|
||||
<div>
|
||||
<ul class="uk-navbar-nav">
|
||||
|
||||
<li><a href="/explore">探索</a></li>
|
||||
|
||||
|
||||
<li class="tb-mobile-balancer" aria-hidden="true"><a tabindex="-1" style="visibility:hidden">マイ</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="uk-navbar-item uk-logo" href="/"><span class="emoji-placeholder" aria-label="random animal">🐺</span>の質問箱</a>
|
||||
|
||||
<div class="uk-navbar-center-right">
|
||||
<div>
|
||||
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/register">登録</a></li>
|
||||
</ul>
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/login">ログイン</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" aria-label="言語" title="言語"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="9"/><path d="M3.2 9h17.6M3.2 15h17.6"/><ellipse cx="12" cy="12" rx="4" ry="9"/></svg></a>
|
||||
<div class="uk-navbar-dropdown" uk-drop="mode: click; pos: bottom-right">
|
||||
<ul class="uk-nav uk-navbar-dropdown-nav">
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/zh-CN?to=%2Fvote%2Ft86urUZo26xE">简体中文</a>
|
||||
</li>
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/zh-TW?to=%2Fvote%2Ft86urUZo26xE">繁體中文</a>
|
||||
</li>
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/en?to=%2Fvote%2Ft86urUZo26xE">English</a>
|
||||
</li>
|
||||
|
||||
<li class="uk-active">
|
||||
<a href="/i18n/ja?to=%2Fvote%2Ft86urUZo26xE">日本語</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" id="theme-toggle" title="ダーク/ライトモード切替" aria-label="ダーク/ライトモード切替">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const emojis = ["🐺","🐗","🐻","🐨","🐼","🐹","🐭","🐰","🦊","🐮","🐷","🐽","🐸","🐒","🦍","🐔","🐧","🐦","🐤","🐦⬛","🦅","🦉","🦇","🐴","🦄","🐝","🦎","🦖","🦕","🐙","🦑","🦐","🦞","🦀","🐡","🐠","🐟","🐬","🐳","🐋","🦈","🐊","🐅","🐆","🦓","🦍","🦧","🐘","🦛","🦏","🐪","🐫","🦒","🦘","🐃","🐂","🐄","🐎","🐖","🐏","🐑","🦙","🐐","🦌","🐕","🐩","🦮","🐕🦺","🐈","🐋","🐳","🐬","🐉","🐲"];
|
||||
const placeholder = document.querySelector('.emoji-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.textContent = emojis[Math.floor(Math.random() * emojis.length)];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="tb-mobile-utils">
|
||||
|
||||
<select id="mobile-lang-select" class="uk-select uk-form-small" aria-label="言語">
|
||||
|
||||
<option value="zh-CN" >简体中文</option>
|
||||
|
||||
<option value="zh-TW" >繁體中文</option>
|
||||
|
||||
<option value="en" >English</option>
|
||||
|
||||
<option value="ja" selected>日本語</option>
|
||||
|
||||
</select>
|
||||
|
||||
<button type="button" id="theme-toggle-mobile" class="uk-button uk-button-default uk-button-small"
|
||||
title="ダーク/ライトモード切替" aria-label="ダーク/ライトモード切替">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
var THEME_COOKIE = 'theme';
|
||||
function getTheme() {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
return m ? m[1] : '';
|
||||
}
|
||||
function applyTheme(theme) {
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
}
|
||||
}
|
||||
function toggleTheme() {
|
||||
var next = getTheme() === 'dark' ? 'light' : 'dark';
|
||||
applyTheme(next);
|
||||
var expires = new Date(Date.now() + 365 * 24 * 3600 * 1000).toUTCString();
|
||||
document.cookie = THEME_COOKIE + '=' + next + '; path=/; max-age=' + (365 * 24 * 3600) + '; SameSite=Lax';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
var buttons = document.querySelectorAll('#theme-toggle, #theme-toggle-mobile');
|
||||
buttons.forEach(function(btn) {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
toggleTheme();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var langSel = document.getElementById('mobile-lang-select');
|
||||
if (langSel) {
|
||||
langSel.addEventListener('change', function() {
|
||||
if (!this.value) return;
|
||||
var to = window.location.pathname + window.location.search;
|
||||
window.location.href = '/i18n/' + encodeURIComponent(this.value) + '?to=' + encodeURIComponent(to);
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-container uk-container-xsmall">
|
||||
|
||||
|
||||
|
||||
<div id="math-captcha-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body uk-text-center">
|
||||
<h3 class="uk-modal-title">人機認証</h3>
|
||||
<p class="uk-text-meta">以下の計算問題を解いて、ロボットでないことを証明してください</p>
|
||||
<div class="captcha-equation-box">
|
||||
<span id="captcha-modal-question" class="math-captcha-modal-question">読み込み中...</span>
|
||||
<input type="number" id="captcha-modal-answer" placeholder="?" autocomplete="off" inputmode="numeric">
|
||||
</div>
|
||||
<div style="margin-top:6px;">
|
||||
<button type="button" class="uk-button uk-button-text uk-text-small" id="captcha-modal-refresh">別の問題</button>
|
||||
</div>
|
||||
<div id="captcha-modal-error" class="uk-text-danger uk-text-small" style="display:none;min-height:20px;"></div>
|
||||
<div class="uk-margin-small-top">
|
||||
<button type="button" class="uk-button uk-button-primary" id="captcha-modal-submit">送信</button>
|
||||
<button type="button" class="uk-button uk-button-default uk-modal-close">キャンセル</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var CAPTCHA_I18N = {
|
||||
loading: "読み込み中...",
|
||||
loadFailed: "読み込み失敗",
|
||||
loadRetry: "読み込み失敗、再試行してください",
|
||||
inputAnswer: "答えを入力してください",
|
||||
wrongAnswer: "答えが違います。もう一度計算してください",
|
||||
verifyFailed: "認証失敗、再試行してください",
|
||||
needPassword: "この質問箱にはパスワードが必要です",
|
||||
needEmail: "通知を受け取るメールアドレスを入力してください"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var captchaId = '';
|
||||
var pendingForm = null;
|
||||
var pendingNeedPassword = false;
|
||||
var verifying = false;
|
||||
|
||||
function fetchCaptcha() {
|
||||
var qEl = document.getElementById('captcha-modal-question');
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
var ansEl = document.getElementById('captcha-modal-answer');
|
||||
qEl.textContent = CAPTCHA_I18N.loading;
|
||||
fetch('/api/captcha/generate')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.code === 0 && data.data) {
|
||||
captchaId = data.data.id;
|
||||
qEl.textContent = data.data.question;
|
||||
if (errEl) errEl.style.display = 'none';
|
||||
if (ansEl) { ansEl.value = ''; ansEl.focus(); }
|
||||
} else {
|
||||
qEl.textContent = CAPTCHA_I18N.loadFailed;
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
qEl.textContent = CAPTCHA_I18N.loadRetry;
|
||||
});
|
||||
}
|
||||
|
||||
function getCSRFToken() {
|
||||
var input = document.querySelector('input[name="_csrf"]');
|
||||
return input ? input.value : '';
|
||||
}
|
||||
|
||||
function doSubmit(form) {
|
||||
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
var hidden = form.querySelector('[name="g-recaptcha-response"]');
|
||||
if (hidden) hidden.value = captchaId + ':' + (ans || '0');
|
||||
|
||||
UIkit.modal('#math-captcha-modal').hide();
|
||||
|
||||
|
||||
if (pendingNeedPassword) {
|
||||
UIkit.modal.prompt(CAPTCHA_I18N.needPassword, '', 'password')
|
||||
.then(function(password) {
|
||||
if (password) {
|
||||
var pwInput = document.getElementById('ask_password_input');
|
||||
if (pwInput) pwInput.value = password;
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-submit').addEventListener('click', function() {
|
||||
if (verifying) return;
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
if (!ans) {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.inputAnswer;
|
||||
errEl.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
verifying = true;
|
||||
fetch('/api/captcha/verify', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-Token': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify({ id: captchaId, answer: parseInt(ans, 10) })
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
verifying = false;
|
||||
if (data.correct) {
|
||||
if (pendingForm) doSubmit(pendingForm);
|
||||
} else {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.wrongAnswer;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
verifying = false;
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.verifyFailed;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-answer').addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
document.getElementById('captcha-modal-submit').click();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-refresh').addEventListener('click', fetchCaptcha);
|
||||
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target.closest('.math-captcha-trigger');
|
||||
if (!btn) return;
|
||||
e.preventDefault();
|
||||
|
||||
var form = btn.closest('form');
|
||||
if (!form) return;
|
||||
pendingForm = form;
|
||||
|
||||
|
||||
pendingNeedPassword = !!(form.querySelector('#ask_password_input'));
|
||||
|
||||
|
||||
var notifyCb = document.getElementById('notify-checkbox');
|
||||
var emailInput = document.getElementById('email-input');
|
||||
if (notifyCb && notifyCb.checked && emailInput && emailInput.value.trim() === '') {
|
||||
UIkit.modal.alert(CAPTCHA_I18N.needEmail);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchCaptcha();
|
||||
UIkit.modal('#math-captcha-modal').show();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<style>
|
||||
|
||||
.tb-field-head {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 6px 8px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.tb-field-head .tb-field-label {
|
||||
flex-basis: 100%;
|
||||
font-weight: 600;
|
||||
line-height: 1.5;
|
||||
word-break: break-word;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.tb-choice {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
padding: 12px 14px;
|
||||
margin-bottom: 8px;
|
||||
border: 1px solid var(--tb-border);
|
||||
border-radius: 8px;
|
||||
background: var(--tb-surface);
|
||||
cursor: pointer;
|
||||
transition: border-color 0.2s ease, background 0.2s ease;
|
||||
}
|
||||
.tb-choice:last-child { margin-bottom: 0; }
|
||||
.tb-choice input[type="radio"], .tb-choice input[type="checkbox"] {
|
||||
margin-top: 3px;
|
||||
}
|
||||
.tb-choice span {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
line-height: 1.5;
|
||||
word-break: break-word;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.tb-choice:hover {
|
||||
border-color: var(--tb-primary);
|
||||
background: var(--tb-surface-hover);
|
||||
}
|
||||
.tb-choice:has(input:checked) {
|
||||
border-color: var(--tb-primary);
|
||||
background: var(--tb-surface-active);
|
||||
}
|
||||
html[data-theme="dark"] .tb-choice {
|
||||
border-color: var(--tb-border);
|
||||
background: var(--tb-surface);
|
||||
}
|
||||
html[data-theme="dark"] .tb-choice:hover {
|
||||
border-color: var(--tb-primary);
|
||||
background: rgba(78, 168, 245, 0.08);
|
||||
}
|
||||
html[data-theme="dark"] .tb-choice:has(input:checked) {
|
||||
border-color: var(--tb-primary);
|
||||
background: rgba(78, 168, 245, 0.14);
|
||||
}
|
||||
|
||||
.tb-custom-input {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.tb-text-counter {
|
||||
margin-top: 2px;
|
||||
text-align: right;
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.tb-choice { padding: 10px 12px; }
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-body uk-margin-bottom">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 10px;">
|
||||
|
||||
<img class="uk-border-circle" src="https://r2.337845818.best/tamabox/picture/2026/08/19/9af3e38222d972ff9141e9cfdb0475" style="width: 40px; height: 40px;">
|
||||
<div>
|
||||
<a class="uk-text-bold" href="/_admin6">admin6</a>
|
||||
<div class="uk-text-meta uk-text-small">の投票</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-auto-left">
|
||||
|
||||
|
||||
<span class="uk-label uk-label-success">進行中</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="uk-margin-remove-top uk-margin-small-bottom">吃什么</h3>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="uk-alert uk-alert-warning">
|
||||
この投票は登録ユーザーのみ参加できます。ログインしてください。 <a href="/login?to=%2fvote%2ft86urUZo26xE">ログイン</a>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<form method="post" action="/vote/t86urUZo26xE/submit" id="vote-form" onsubmit="return validateVoteForm()">
|
||||
<input type="hidden" name="_csrf" value="B1O7d1hhDznoA36CR6ndXmkVkLM6MTc5MjM4NDM3MTkzODQ1ODUwNw">
|
||||
<input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response" value="">
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-body uk-margin-bottom">
|
||||
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="tb-field-head">
|
||||
<span class="uk-label">1</span>
|
||||
<span class="uk-label ">一行テキスト</span>
|
||||
<div class="tb-field-label">是啊,吃什么?</div>
|
||||
</div>
|
||||
|
||||
<input class="uk-input" type="text" name="field_41" >
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
|
||||
<button type="button" class="uk-button uk-button-primary math-captcha-trigger" onclick="return voteValidate(event)">投票する</button>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
var MAX_CUSTOM_LEN = 200 ;
|
||||
|
||||
|
||||
|
||||
function countChars(s) { return Array.from(String(s || '')).length; }
|
||||
|
||||
|
||||
function setupTextCounters() {
|
||||
var form = document.getElementById('vote-form');
|
||||
if (!form) { return; }
|
||||
form.querySelectorAll('[data-tb-text-counter]').forEach(function (input) {
|
||||
var max = parseInt(input.getAttribute('data-tb-text-max'), 10);
|
||||
if (!max || max < 1) { max = MAX_CUSTOM_LEN; }
|
||||
var counter = document.createElement('div');
|
||||
counter.className = 'uk-text-meta uk-text-small tb-text-counter';
|
||||
if (input.parentNode) { input.parentNode.insertBefore(counter, input.nextSibling); }
|
||||
var update = function () {
|
||||
var n = countChars(input.value);
|
||||
counter.textContent = n + ' / ' + max;
|
||||
if (n > max) {
|
||||
counter.classList.add('uk-text-danger');
|
||||
input.setAttribute('data-tb-too-long', '1');
|
||||
} else {
|
||||
counter.classList.remove('uk-text-danger');
|
||||
input.removeAttribute('data-tb-too-long');
|
||||
}
|
||||
};
|
||||
input.addEventListener('input', update);
|
||||
update();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
function validateVoteForm() {
|
||||
var form = document.getElementById('vote-form');
|
||||
if (!form) { return true; }
|
||||
|
||||
var tooLong = form.querySelector('[data-tb-text-counter][data-tb-too-long]');
|
||||
if (tooLong) {
|
||||
alert('自由記入オプションは 200 字以内にしてください');
|
||||
tooLong.focus();
|
||||
return false;
|
||||
}
|
||||
|
||||
var groups = {};
|
||||
form.querySelectorAll('input[data-vote-required][type="radio"], input[data-vote-required][type="checkbox"]').forEach(function (el) {
|
||||
(groups[el.name] = groups[el.name] || []).push(el);
|
||||
});
|
||||
for (var name in groups) {
|
||||
var any = groups[name].some(function (el) { return el.checked; });
|
||||
if (!any) {
|
||||
alert('入力してください「' + groups[name][0].getAttribute('data-vote-label') + '」');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var els = form.querySelectorAll('[data-vote-required]:not(input[type="radio"]):not(input[type="checkbox"])');
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
var el = els[i];
|
||||
if (el.disabled) { continue; }
|
||||
if ((el.value || '').trim() === '') {
|
||||
alert('入力してください「' + el.getAttribute('data-vote-label') + '」');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function voteValidate(e) {
|
||||
if (!validateVoteForm()) {
|
||||
if (e) { e.stopPropagation(); e.preventDefault(); }
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
if (validateVoteForm()) {
|
||||
document.getElementById('vote-form').submit();
|
||||
}
|
||||
}
|
||||
|
||||
(function () {
|
||||
var form = document.getElementById('vote-form');
|
||||
if (!form) { return; }
|
||||
setupTextCounters();
|
||||
var maxChoices = 0;
|
||||
if (maxChoices > 0) {
|
||||
var boxes = form.querySelectorAll('input[type="checkbox"][name="option_ids"]');
|
||||
boxes.forEach(function (box) {
|
||||
box.addEventListener('change', function () {
|
||||
var checked = form.querySelectorAll('input[type="checkbox"][name="option_ids"]:checked').length;
|
||||
if (checked > maxChoices) { this.checked = false; }
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var CUSTOM_MARKER = "__tb_custom_option__";
|
||||
form.querySelectorAll('[data-vote-custom-input]').forEach(function (input) {
|
||||
var fid = input.getAttribute('data-vote-custom-input');
|
||||
var group = form.querySelectorAll('input[name="field_' + fid + '"]');
|
||||
var select = form.querySelector('select[name="field_' + fid + '"]');
|
||||
var sync = function () {
|
||||
var on = false;
|
||||
if (select) {
|
||||
on = (select.value === CUSTOM_MARKER);
|
||||
} else {
|
||||
group.forEach(function (r) { if (r.value === CUSTOM_MARKER && r.checked) { on = true; } });
|
||||
}
|
||||
input.disabled = !on;
|
||||
if (!on) { input.value = ''; }
|
||||
};
|
||||
if (select) { select.addEventListener('change', sync); } else { group.forEach(function (r) { r.addEventListener('change', sync); }); }
|
||||
sync();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<p class=" uk-text-right uk-text-muted uk-text-small">
|
||||
<br>
|
||||
<a href="/rules">ルール</a> |
|
||||
|
||||
<a href="https://box.shiroko.one/_/tamakyi" target="_blank">管理者へ</a>
|
||||
<br>
|
||||
<a href="https://share.shiroko.one" target="_blank">ドライブ</a>
|
||||
| <a href="https://blog.shiroko.one" target="_blank">お知らせ</a>
|
||||
| <a href="https://chat.shiroko.one" target="_blank">チャット</a>
|
||||
| <a href="https://status.shiroko.one" target="_blank">ステータス</a>
|
||||
| <a href="https://shiroko.one" target="_blank">リンク</a>
|
||||
<br>Powered by NekoBox | 狼ICP备 20230101
|
||||
<br>質問箱は稼働中:<span id="box_runtime"></span>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
(function () {
|
||||
var create = Math.round(Date.UTC(2023, 6, 1, 18, 15, 43) / 1000);
|
||||
function tick() {
|
||||
var el = document.getElementById("box_runtime");
|
||||
if (!el) return;
|
||||
var s = Math.round((Date.now() + 8 * 3600 * 1000) / 1000) - create;
|
||||
var t = [0, 0, 0, 0, 0];
|
||||
if (s >= 31536000) { t[0] = s / 31536000 | 0; s %= 31536000; }
|
||||
if (s >= 86400) { t[1] = s / 86400 | 0; s %= 86400; }
|
||||
if (s >= 3600) { t[2] = s / 3600 | 0; s %= 3600; }
|
||||
if (s >= 60) { t[3] = s / 60 | 0; s %= 60; }
|
||||
if (s > 0) { t[4] = s; }
|
||||
el.innerHTML = t[0] + '年 ' + t[1] + '天 ' + t[2] + '时 ' + t[3] + '分 ' + t[4] + '秒 ';
|
||||
}
|
||||
tick();
|
||||
setInterval(tick, 1000);
|
||||
})();
|
||||
</script>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
var SUBMIT_I18N = {
|
||||
submitting: '送信中...',
|
||||
uploading: 'アップロード中...'
|
||||
};
|
||||
|
||||
function tbResetSubmitButtons() {
|
||||
document.querySelectorAll('button[data-tb-submitting]').forEach(function(b) {
|
||||
b.disabled = false;
|
||||
b.removeAttribute('data-tb-submitting');
|
||||
var orig = b.getAttribute('data-tb-restore');
|
||||
if (orig !== null) {
|
||||
b.innerHTML = orig;
|
||||
b.removeAttribute('data-tb-restore');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('submit', function(e) {
|
||||
var form = e.target;
|
||||
if (!form || form.tagName !== 'FORM') return;
|
||||
|
||||
|
||||
|
||||
if (e.defaultPrevented || form.getAttribute('data-tb-skip-submit-feedback') === '1') {
|
||||
form.removeAttribute('data-tb-skip-submit-feedback');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (form.getAttribute('target') === '_blank') return;
|
||||
|
||||
|
||||
var trigger = e.submitter || form.querySelector('button[type="submit"]');
|
||||
|
||||
|
||||
var hasFile = false;
|
||||
form.querySelectorAll('input[type="file"]').forEach(function(f) {
|
||||
if (f.files && f.files.length > 0) hasFile = true;
|
||||
});
|
||||
var label = hasFile ? SUBMIT_I18N.uploading : SUBMIT_I18N.submitting;
|
||||
|
||||
if (trigger && trigger.tagName === 'BUTTON') {
|
||||
trigger.setAttribute('data-tb-restore', trigger.innerHTML);
|
||||
trigger.innerHTML = '<span uk-spinner="ratio: 0.6"></span> ' + label;
|
||||
}
|
||||
|
||||
|
||||
form.querySelectorAll('button').forEach(function(b) {
|
||||
b.disabled = true;
|
||||
b.setAttribute('data-tb-submitting', '1');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener('pageshow', tbResetSubmitButtons);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,924 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>测试4</title>
|
||||
<meta name="msvalidate.01" content="2F185E8E63C93635F50B3574F3B31E42" />
|
||||
<meta name="description" content="狼の質問箱は登録不要で使える匿名質問箱。誰でも匿名で質問でき、安心してやり取りできる場所です。">
|
||||
<meta name="keywords" content="匿名質問箱,質問箱,匿名質問,狼の質問箱,匿名で質問,匿名Q&A">
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
if (m && m[1] === 'dark') document.documentElement.setAttribute('data-theme', 'dark');
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://r2.337845818.best" crossorigin>
|
||||
<link rel="preconnect" href="https://cdnjs.snrat.com" crossorigin>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/css/uikit.min.css"/>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/base.css?v=20261019c"/>
|
||||
|
||||
<link rel="stylesheet" href="https://r2.337845818.best/tamabox/cdn/waline/client/v2/waline-no-commits.css" media="print" onload="this.media='all'"/>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit-icons.min.js"></script>
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/dayjs/1.10.8/dayjs.min.js"></script>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/alpinejs/3.9.0/cdn.min.js"></script>
|
||||
|
||||
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/waline/2.15.8/waline.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.captcha-equation-box {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: #f0f2f5;
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 8px;
|
||||
padding: 8px 8px 8px 16px;
|
||||
gap: 6px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
.captcha-equation-box:focus-within {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 3px rgba(30,135,240,0.12);
|
||||
}
|
||||
.math-captcha-modal-question {
|
||||
font-size: 1.4rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
letter-spacing: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
width: 80px;
|
||||
padding: 6px 10px;
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
font-family: "Courier New", monospace;
|
||||
font-weight: 600;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
transition: border-color 0.15s, box-shadow 0.15s;
|
||||
background: #fff;
|
||||
}
|
||||
#captcha-modal-answer:focus {
|
||||
border-color: #1e87f0;
|
||||
box-shadow: 0 0 0 2px rgba(30,135,240,0.2);
|
||||
}
|
||||
|
||||
#captcha-modal-answer::-webkit-inner-spin-button,
|
||||
#captcha-modal-answer::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
#captcha-modal-answer {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta property="og:site_name" content="狼の質問箱 | 匿名質問箱" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content="狼の質問箱 | 匿名質問箱" />
|
||||
<meta property="og:url" content="https://box-dev-api.337845818.best/vote/z9F8mIqPtDOA" />
|
||||
<meta property="og:description" content="狼の質問箱は登録不要で使える匿名質問箱。誰でも匿名で質問でき、安心してやり取りできる場所です。" />
|
||||
<meta name="robots" content="noindex">
|
||||
|
||||
<meta itemprop="image" content="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<meta name="msapplication-TileImage" content="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<link rel="shortcut icon" href="https://r2.337845818.best/tamabox/tamabox_low.png" />
|
||||
<link rel="apple-touch-icon" href="https://r2.337845818.best/tamabox/tamabox_low.png"/>
|
||||
<link rel="icon" sizes="192x192" href="https://r2.337845818.best/tamabox/tamabox_low.png">
|
||||
<meta name="twitter:image:src" content="https://r2.337845818.best/tamabox/tamabox_low.png" />
|
||||
|
||||
|
||||
|
||||
<meta name="google-site-verification" content="fEPwRRJfiGsgwc5SINBQwZhPK8F0cwRaOvRx0YRurI4" />
|
||||
|
||||
<script>
|
||||
window.addEventListener("load", function () {
|
||||
var s = document.createElement("script");
|
||||
s.src = "https://mami.shiroko.one/tamami.js";
|
||||
s.setAttribute("data-website-id", "c42ebe8b-9281-4da0-83a4-8f18b3e710fe");
|
||||
document.body.appendChild(s);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window.tbRenderQR = function (el, getOptions) {
|
||||
if (!el || typeof QRCode === 'undefined') return;
|
||||
var opts = getOptions();
|
||||
function remoteOf(o, key) {
|
||||
var v = o[key];
|
||||
return (typeof v === 'string' && v.indexOf('http') === 0) ? v : '';
|
||||
}
|
||||
var good = window._tbQrGood || (window._tbQrGood = {});
|
||||
var bad = window._tbQrBad || (window._tbQrBad = {});
|
||||
|
||||
function layerState(url) { return !url ? '' : (good[url] ? 1 : (bad[url] ? 0 : null)); }
|
||||
var layers = [
|
||||
{ url: remoteOf(opts, 'logo'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.logo = undefined; o.logoWidth = undefined; o.logoHeight = undefined; o.logoBackgroundTransparent = undefined; }
|
||||
} },
|
||||
{ url: remoteOf(opts, 'backgroundImage'), st: null, present: function (o, on) {
|
||||
if (on) { } else { o.backgroundImage = undefined; o.backgroundImageAlpha = undefined; }
|
||||
} }
|
||||
];
|
||||
var needProbe = false;
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
layers[i].st = layerState(layers[i].url);
|
||||
if (layers[i].st === null) needProbe = true;
|
||||
}
|
||||
function paint(states) {
|
||||
var o = {};
|
||||
for (var k in opts) o[k] = opts[k];
|
||||
for (var j = 0; j < layers.length; j++) layers[j].present(o, states[j] === 1);
|
||||
el.innerHTML = '';
|
||||
new QRCode(el, o);
|
||||
}
|
||||
|
||||
var initStates = [];
|
||||
for (var n = 0; n < layers.length; n++) initStates.push(layers[n].st === 1 ? 1 : 0);
|
||||
paint(initStates);
|
||||
if (!needProbe) return;
|
||||
|
||||
var pending = 0, cross = opts.crossOrigin || 'anonymous';
|
||||
layers.forEach(function (L) {
|
||||
if (L.st !== null) return;
|
||||
pending++;
|
||||
var im = new Image();
|
||||
im.onload = function () { good[L.url] = true; L.st = 1; onDone(); };
|
||||
im.onerror = function () { bad[L.url] = true; L.st = 0; onDone(); };
|
||||
if (cross) im.crossOrigin = cross;
|
||||
im.src = L.url;
|
||||
});
|
||||
function onDone() {
|
||||
if (--pending > 0) return;
|
||||
var finalStates = [];
|
||||
for (var m = 0; m < layers.length; m++) finalStates.push(layers[m].st === 1 ? 1 : 0);
|
||||
var changed = false;
|
||||
for (var q = 0; q < finalStates.length; q++) if (finalStates[q] !== initStates[q]) changed = true;
|
||||
if (changed) paint(finalStates);
|
||||
}
|
||||
|
||||
setTimeout(function () { if (pending > 0) { pending = 0; onDone(); } }, 3000);
|
||||
};
|
||||
</script>
|
||||
<nav class="uk-navbar-container uk-margin tb-navbar" uk-navbar>
|
||||
<div class="uk-navbar-center">
|
||||
<div class="uk-navbar-center-left">
|
||||
<div>
|
||||
<ul class="uk-navbar-nav">
|
||||
|
||||
<li><a href="/explore">探索</a></li>
|
||||
|
||||
|
||||
<li class="tb-mobile-balancer" aria-hidden="true"><a tabindex="-1" style="visibility:hidden">マイ</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="uk-navbar-item uk-logo" href="/"><span class="emoji-placeholder" aria-label="random animal">🐺</span>の質問箱</a>
|
||||
|
||||
<div class="uk-navbar-center-right">
|
||||
<div>
|
||||
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/register">登録</a></li>
|
||||
</ul>
|
||||
<ul class="uk-navbar-nav">
|
||||
<li><a href="/login">ログイン</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" aria-label="言語" title="言語"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="9"/><path d="M3.2 9h17.6M3.2 15h17.6"/><ellipse cx="12" cy="12" rx="4" ry="9"/></svg></a>
|
||||
<div class="uk-navbar-dropdown" uk-drop="mode: click; pos: bottom-right">
|
||||
<ul class="uk-nav uk-navbar-dropdown-nav">
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/zh-CN?to=%2Fvote%2Fz9F8mIqPtDOA">简体中文</a>
|
||||
</li>
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/zh-TW?to=%2Fvote%2Fz9F8mIqPtDOA">繁體中文</a>
|
||||
</li>
|
||||
|
||||
<li class="">
|
||||
<a href="/i18n/en?to=%2Fvote%2Fz9F8mIqPtDOA">English</a>
|
||||
</li>
|
||||
|
||||
<li class="uk-active">
|
||||
<a href="/i18n/ja?to=%2Fvote%2Fz9F8mIqPtDOA">日本語</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<ul class="uk-navbar-nav tb-nav-utils">
|
||||
<li>
|
||||
<a href="#" id="theme-toggle" title="ダーク/ライトモード切替" aria-label="ダーク/ライトモード切替">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const emojis = ["🐺","🐗","🐻","🐨","🐼","🐹","🐭","🐰","🦊","🐮","🐷","🐽","🐸","🐒","🦍","🐔","🐧","🐦","🐤","🐦⬛","🦅","🦉","🦇","🐴","🦄","🐝","🦎","🦖","🦕","🐙","🦑","🦐","🦞","🦀","🐡","🐠","🐟","🐬","🐳","🐋","🦈","🐊","🐅","🐆","🦓","🦍","🦧","🐘","🦛","🦏","🐪","🐫","🦒","🦘","🐃","🐂","🐄","🐎","🐖","🐏","🐑","🦙","🐐","🦌","🐕","🐩","🦮","🐕🦺","🐈","🐋","🐳","🐬","🐉","🐲"];
|
||||
const placeholder = document.querySelector('.emoji-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.textContent = emojis[Math.floor(Math.random() * emojis.length)];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="tb-mobile-utils">
|
||||
|
||||
<select id="mobile-lang-select" class="uk-select uk-form-small" aria-label="言語">
|
||||
|
||||
<option value="zh-CN" >简体中文</option>
|
||||
|
||||
<option value="zh-TW" >繁體中文</option>
|
||||
|
||||
<option value="en" >English</option>
|
||||
|
||||
<option value="ja" selected>日本語</option>
|
||||
|
||||
</select>
|
||||
|
||||
<button type="button" id="theme-toggle-mobile" class="uk-button uk-button-default uk-button-small"
|
||||
title="ダーク/ライトモード切替" aria-label="ダーク/ライトモード切替">
|
||||
<span class="tb-icon-light"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M20.5 14.3A8.6 8.6 0 0 1 9.7 3.5a8.6 8.6 0 1 0 10.8 10.8z"/></svg></span><span class="tb-icon-dark"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4"/></svg></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
var THEME_COOKIE = 'theme';
|
||||
function getTheme() {
|
||||
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
|
||||
return m ? m[1] : '';
|
||||
}
|
||||
function applyTheme(theme) {
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
}
|
||||
}
|
||||
function toggleTheme() {
|
||||
var next = getTheme() === 'dark' ? 'light' : 'dark';
|
||||
applyTheme(next);
|
||||
var expires = new Date(Date.now() + 365 * 24 * 3600 * 1000).toUTCString();
|
||||
document.cookie = THEME_COOKIE + '=' + next + '; path=/; max-age=' + (365 * 24 * 3600) + '; SameSite=Lax';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
var buttons = document.querySelectorAll('#theme-toggle, #theme-toggle-mobile');
|
||||
buttons.forEach(function(btn) {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
toggleTheme();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var langSel = document.getElementById('mobile-lang-select');
|
||||
if (langSel) {
|
||||
langSel.addEventListener('change', function() {
|
||||
if (!this.value) return;
|
||||
var to = window.location.pathname + window.location.search;
|
||||
window.location.href = '/i18n/' + encodeURIComponent(this.value) + '?to=' + encodeURIComponent(to);
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="uk-container uk-container-xsmall">
|
||||
|
||||
|
||||
|
||||
<div id="math-captcha-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body uk-text-center">
|
||||
<h3 class="uk-modal-title">人機認証</h3>
|
||||
<p class="uk-text-meta">以下の計算問題を解いて、ロボットでないことを証明してください</p>
|
||||
<div class="captcha-equation-box">
|
||||
<span id="captcha-modal-question" class="math-captcha-modal-question">読み込み中...</span>
|
||||
<input type="number" id="captcha-modal-answer" placeholder="?" autocomplete="off" inputmode="numeric">
|
||||
</div>
|
||||
<div style="margin-top:6px;">
|
||||
<button type="button" class="uk-button uk-button-text uk-text-small" id="captcha-modal-refresh">別の問題</button>
|
||||
</div>
|
||||
<div id="captcha-modal-error" class="uk-text-danger uk-text-small" style="display:none;min-height:20px;"></div>
|
||||
<div class="uk-margin-small-top">
|
||||
<button type="button" class="uk-button uk-button-primary" id="captcha-modal-submit">送信</button>
|
||||
<button type="button" class="uk-button uk-button-default uk-modal-close">キャンセル</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var CAPTCHA_I18N = {
|
||||
loading: "読み込み中...",
|
||||
loadFailed: "読み込み失敗",
|
||||
loadRetry: "読み込み失敗、再試行してください",
|
||||
inputAnswer: "答えを入力してください",
|
||||
wrongAnswer: "答えが違います。もう一度計算してください",
|
||||
verifyFailed: "認証失敗、再試行してください",
|
||||
needPassword: "この質問箱にはパスワードが必要です",
|
||||
needEmail: "通知を受け取るメールアドレスを入力してください"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var captchaId = '';
|
||||
var pendingForm = null;
|
||||
var pendingNeedPassword = false;
|
||||
var verifying = false;
|
||||
|
||||
function fetchCaptcha() {
|
||||
var qEl = document.getElementById('captcha-modal-question');
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
var ansEl = document.getElementById('captcha-modal-answer');
|
||||
qEl.textContent = CAPTCHA_I18N.loading;
|
||||
fetch('/api/captcha/generate')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.code === 0 && data.data) {
|
||||
captchaId = data.data.id;
|
||||
qEl.textContent = data.data.question;
|
||||
if (errEl) errEl.style.display = 'none';
|
||||
if (ansEl) { ansEl.value = ''; ansEl.focus(); }
|
||||
} else {
|
||||
qEl.textContent = CAPTCHA_I18N.loadFailed;
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
qEl.textContent = CAPTCHA_I18N.loadRetry;
|
||||
});
|
||||
}
|
||||
|
||||
function getCSRFToken() {
|
||||
var input = document.querySelector('input[name="_csrf"]');
|
||||
return input ? input.value : '';
|
||||
}
|
||||
|
||||
function doSubmit(form) {
|
||||
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
var hidden = form.querySelector('[name="g-recaptcha-response"]');
|
||||
if (hidden) hidden.value = captchaId + ':' + (ans || '0');
|
||||
|
||||
UIkit.modal('#math-captcha-modal').hide();
|
||||
|
||||
|
||||
if (pendingNeedPassword) {
|
||||
UIkit.modal.prompt(CAPTCHA_I18N.needPassword, '', 'password')
|
||||
.then(function(password) {
|
||||
if (password) {
|
||||
var pwInput = document.getElementById('ask_password_input');
|
||||
if (pwInput) pwInput.value = password;
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-submit').addEventListener('click', function() {
|
||||
if (verifying) return;
|
||||
var ans = document.getElementById('captcha-modal-answer').value.trim();
|
||||
if (!ans) {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.inputAnswer;
|
||||
errEl.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
verifying = true;
|
||||
fetch('/api/captcha/verify', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-Token': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify({ id: captchaId, answer: parseInt(ans, 10) })
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
verifying = false;
|
||||
if (data.correct) {
|
||||
if (pendingForm) doSubmit(pendingForm);
|
||||
} else {
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.wrongAnswer;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
verifying = false;
|
||||
var errEl = document.getElementById('captcha-modal-error');
|
||||
errEl.textContent = CAPTCHA_I18N.verifyFailed;
|
||||
errEl.style.display = 'block';
|
||||
fetchCaptcha();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-answer').addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
document.getElementById('captcha-modal-submit').click();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('captcha-modal-refresh').addEventListener('click', fetchCaptcha);
|
||||
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target.closest('.math-captcha-trigger');
|
||||
if (!btn) return;
|
||||
e.preventDefault();
|
||||
|
||||
var form = btn.closest('form');
|
||||
if (!form) return;
|
||||
pendingForm = form;
|
||||
|
||||
|
||||
pendingNeedPassword = !!(form.querySelector('#ask_password_input'));
|
||||
|
||||
|
||||
var notifyCb = document.getElementById('notify-checkbox');
|
||||
var emailInput = document.getElementById('email-input');
|
||||
if (notifyCb && notifyCb.checked && emailInput && emailInput.value.trim() === '') {
|
||||
UIkit.modal.alert(CAPTCHA_I18N.needEmail);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchCaptcha();
|
||||
UIkit.modal('#math-captcha-modal').show();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<style>
|
||||
|
||||
.tb-field-head {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 6px 8px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.tb-field-head .tb-field-label {
|
||||
flex-basis: 100%;
|
||||
font-weight: 600;
|
||||
line-height: 1.5;
|
||||
word-break: break-word;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.tb-choice {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
padding: 12px 14px;
|
||||
margin-bottom: 8px;
|
||||
border: 1px solid var(--tb-border);
|
||||
border-radius: 8px;
|
||||
background: var(--tb-surface);
|
||||
cursor: pointer;
|
||||
transition: border-color 0.2s ease, background 0.2s ease;
|
||||
}
|
||||
.tb-choice:last-child { margin-bottom: 0; }
|
||||
.tb-choice input[type="radio"], .tb-choice input[type="checkbox"] {
|
||||
margin-top: 3px;
|
||||
}
|
||||
.tb-choice span {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
line-height: 1.5;
|
||||
word-break: break-word;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.tb-choice:hover {
|
||||
border-color: var(--tb-primary);
|
||||
background: var(--tb-surface-hover);
|
||||
}
|
||||
.tb-choice:has(input:checked) {
|
||||
border-color: var(--tb-primary);
|
||||
background: var(--tb-surface-active);
|
||||
}
|
||||
html[data-theme="dark"] .tb-choice {
|
||||
border-color: var(--tb-border);
|
||||
background: var(--tb-surface);
|
||||
}
|
||||
html[data-theme="dark"] .tb-choice:hover {
|
||||
border-color: var(--tb-primary);
|
||||
background: rgba(78, 168, 245, 0.08);
|
||||
}
|
||||
html[data-theme="dark"] .tb-choice:has(input:checked) {
|
||||
border-color: var(--tb-primary);
|
||||
background: rgba(78, 168, 245, 0.14);
|
||||
}
|
||||
|
||||
.tb-custom-input {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.tb-text-counter {
|
||||
margin-top: 2px;
|
||||
text-align: right;
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.tb-choice { padding: 10px 12px; }
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-body uk-margin-bottom">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 10px;">
|
||||
|
||||
<img class="uk-border-circle" src="https://r2.337845818.best/tamabox/picture/2026/08/19/9af3e38222d972ff9141e9cfdb0475" style="width: 40px; height: 40px;">
|
||||
<div>
|
||||
<a class="uk-text-bold" href="/_admin6">admin6</a>
|
||||
<div class="uk-text-meta uk-text-small">の投票</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-auto-left">
|
||||
|
||||
|
||||
<span class="uk-label uk-label-success">進行中</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="uk-margin-remove-top uk-margin-small-bottom">测试4</h3>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="uk-alert uk-alert-primary uk-text-small">匿名での参加が可能で、あなたの身元は記録されません(同一端末で最大1回)。</div>
|
||||
|
||||
|
||||
<form method="post" action="/vote/z9F8mIqPtDOA/submit" id="vote-form" onsubmit="return validateVoteForm()">
|
||||
<input type="hidden" name="_csrf" value="TD5S4OBFG6peqyV4W7wTpxW79go6MTc5MjM4NDM3OTQ4OTI2NTY0NQ">
|
||||
<input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response" value="">
|
||||
|
||||
<div class="uk-card uk-card-default uk-card-body uk-margin-bottom">
|
||||
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="tb-field-head">
|
||||
<span class="uk-label">1</span>
|
||||
<span class="uk-label uk-label-primary">単一選択</span>
|
||||
<div class="tb-field-label">这里显示第一题</div>
|
||||
</div>
|
||||
|
||||
|
||||
<label class="tb-choice">
|
||||
<input class="uk-radio" type="radio" name="field_19" value="A" ><span>A</span>
|
||||
</label>
|
||||
|
||||
<label class="tb-choice">
|
||||
<input class="uk-radio" type="radio" name="field_19" value="B" ><span>B</span>
|
||||
</label>
|
||||
|
||||
<label class="tb-choice">
|
||||
<input class="uk-radio" type="radio" name="field_19" value="C" ><span>C</span>
|
||||
</label>
|
||||
|
||||
<label class="tb-choice">
|
||||
<input class="uk-radio" type="radio" name="field_19" value="D" ><span>D</span>
|
||||
</label>
|
||||
|
||||
<label class="tb-choice">
|
||||
<input class="uk-radio" type="radio" name="field_19" value="E" ><span>E</span>
|
||||
</label>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<div class="tb-field-head">
|
||||
<span class="uk-label">2</span>
|
||||
<span class="uk-label uk-label-primary">単一選択</span>
|
||||
<div class="tb-field-label">11</div>
|
||||
</div>
|
||||
|
||||
|
||||
<label class="tb-choice">
|
||||
<input class="uk-radio" type="radio" name="field_20" value="1" ><span>1</span>
|
||||
</label>
|
||||
|
||||
<label class="tb-choice">
|
||||
<input class="uk-radio" type="radio" name="field_20" value="2" ><span>2</span>
|
||||
</label>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
|
||||
<button type="button" class="uk-button uk-button-primary math-captcha-trigger" onclick="return voteValidate(event)">投票する</button>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
var MAX_CUSTOM_LEN = 200 ;
|
||||
|
||||
|
||||
|
||||
function countChars(s) { return Array.from(String(s || '')).length; }
|
||||
|
||||
|
||||
function setupTextCounters() {
|
||||
var form = document.getElementById('vote-form');
|
||||
if (!form) { return; }
|
||||
form.querySelectorAll('[data-tb-text-counter]').forEach(function (input) {
|
||||
var max = parseInt(input.getAttribute('data-tb-text-max'), 10);
|
||||
if (!max || max < 1) { max = MAX_CUSTOM_LEN; }
|
||||
var counter = document.createElement('div');
|
||||
counter.className = 'uk-text-meta uk-text-small tb-text-counter';
|
||||
if (input.parentNode) { input.parentNode.insertBefore(counter, input.nextSibling); }
|
||||
var update = function () {
|
||||
var n = countChars(input.value);
|
||||
counter.textContent = n + ' / ' + max;
|
||||
if (n > max) {
|
||||
counter.classList.add('uk-text-danger');
|
||||
input.setAttribute('data-tb-too-long', '1');
|
||||
} else {
|
||||
counter.classList.remove('uk-text-danger');
|
||||
input.removeAttribute('data-tb-too-long');
|
||||
}
|
||||
};
|
||||
input.addEventListener('input', update);
|
||||
update();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
function validateVoteForm() {
|
||||
var form = document.getElementById('vote-form');
|
||||
if (!form) { return true; }
|
||||
|
||||
var tooLong = form.querySelector('[data-tb-text-counter][data-tb-too-long]');
|
||||
if (tooLong) {
|
||||
alert('自由記入オプションは 200 字以内にしてください');
|
||||
tooLong.focus();
|
||||
return false;
|
||||
}
|
||||
|
||||
var groups = {};
|
||||
form.querySelectorAll('input[data-vote-required][type="radio"], input[data-vote-required][type="checkbox"]').forEach(function (el) {
|
||||
(groups[el.name] = groups[el.name] || []).push(el);
|
||||
});
|
||||
for (var name in groups) {
|
||||
var any = groups[name].some(function (el) { return el.checked; });
|
||||
if (!any) {
|
||||
alert('入力してください「' + groups[name][0].getAttribute('data-vote-label') + '」');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var els = form.querySelectorAll('[data-vote-required]:not(input[type="radio"]):not(input[type="checkbox"])');
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
var el = els[i];
|
||||
if (el.disabled) { continue; }
|
||||
if ((el.value || '').trim() === '') {
|
||||
alert('入力してください「' + el.getAttribute('data-vote-label') + '」');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function voteValidate(e) {
|
||||
if (!validateVoteForm()) {
|
||||
if (e) { e.stopPropagation(); e.preventDefault(); }
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
if (validateVoteForm()) {
|
||||
document.getElementById('vote-form').submit();
|
||||
}
|
||||
}
|
||||
|
||||
(function () {
|
||||
var form = document.getElementById('vote-form');
|
||||
if (!form) { return; }
|
||||
setupTextCounters();
|
||||
var maxChoices = 0;
|
||||
if (maxChoices > 0) {
|
||||
var boxes = form.querySelectorAll('input[type="checkbox"][name="option_ids"]');
|
||||
boxes.forEach(function (box) {
|
||||
box.addEventListener('change', function () {
|
||||
var checked = form.querySelectorAll('input[type="checkbox"][name="option_ids"]:checked').length;
|
||||
if (checked > maxChoices) { this.checked = false; }
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var CUSTOM_MARKER = "__tb_custom_option__";
|
||||
form.querySelectorAll('[data-vote-custom-input]').forEach(function (input) {
|
||||
var fid = input.getAttribute('data-vote-custom-input');
|
||||
var group = form.querySelectorAll('input[name="field_' + fid + '"]');
|
||||
var select = form.querySelector('select[name="field_' + fid + '"]');
|
||||
var sync = function () {
|
||||
var on = false;
|
||||
if (select) {
|
||||
on = (select.value === CUSTOM_MARKER);
|
||||
} else {
|
||||
group.forEach(function (r) { if (r.value === CUSTOM_MARKER && r.checked) { on = true; } });
|
||||
}
|
||||
input.disabled = !on;
|
||||
if (!on) { input.value = ''; }
|
||||
};
|
||||
if (select) { select.addEventListener('change', sync); } else { group.forEach(function (r) { r.addEventListener('change', sync); }); }
|
||||
sync();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<p class=" uk-text-right uk-text-muted uk-text-small">
|
||||
<br>
|
||||
<a href="/rules">ルール</a> |
|
||||
|
||||
<a href="https://box.shiroko.one/_/tamakyi" target="_blank">管理者へ</a>
|
||||
<br>
|
||||
<a href="https://share.shiroko.one" target="_blank">ドライブ</a>
|
||||
| <a href="https://blog.shiroko.one" target="_blank">お知らせ</a>
|
||||
| <a href="https://chat.shiroko.one" target="_blank">チャット</a>
|
||||
| <a href="https://status.shiroko.one" target="_blank">ステータス</a>
|
||||
| <a href="https://shiroko.one" target="_blank">リンク</a>
|
||||
<br>Powered by NekoBox | 狼ICP备 20230101
|
||||
<br>質問箱は稼働中:<span id="box_runtime"></span>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
(function () {
|
||||
var create = Math.round(Date.UTC(2023, 6, 1, 18, 15, 43) / 1000);
|
||||
function tick() {
|
||||
var el = document.getElementById("box_runtime");
|
||||
if (!el) return;
|
||||
var s = Math.round((Date.now() + 8 * 3600 * 1000) / 1000) - create;
|
||||
var t = [0, 0, 0, 0, 0];
|
||||
if (s >= 31536000) { t[0] = s / 31536000 | 0; s %= 31536000; }
|
||||
if (s >= 86400) { t[1] = s / 86400 | 0; s %= 86400; }
|
||||
if (s >= 3600) { t[2] = s / 3600 | 0; s %= 3600; }
|
||||
if (s >= 60) { t[3] = s / 60 | 0; s %= 60; }
|
||||
if (s > 0) { t[4] = s; }
|
||||
el.innerHTML = t[0] + '年 ' + t[1] + '天 ' + t[2] + '时 ' + t[3] + '分 ' + t[4] + '秒 ';
|
||||
}
|
||||
tick();
|
||||
setInterval(tick, 1000);
|
||||
})();
|
||||
</script>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
|
||||
var SUBMIT_I18N = {
|
||||
submitting: '送信中...',
|
||||
uploading: 'アップロード中...'
|
||||
};
|
||||
|
||||
function tbResetSubmitButtons() {
|
||||
document.querySelectorAll('button[data-tb-submitting]').forEach(function(b) {
|
||||
b.disabled = false;
|
||||
b.removeAttribute('data-tb-submitting');
|
||||
var orig = b.getAttribute('data-tb-restore');
|
||||
if (orig !== null) {
|
||||
b.innerHTML = orig;
|
||||
b.removeAttribute('data-tb-restore');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('submit', function(e) {
|
||||
var form = e.target;
|
||||
if (!form || form.tagName !== 'FORM') return;
|
||||
|
||||
|
||||
|
||||
if (e.defaultPrevented || form.getAttribute('data-tb-skip-submit-feedback') === '1') {
|
||||
form.removeAttribute('data-tb-skip-submit-feedback');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (form.getAttribute('target') === '_blank') return;
|
||||
|
||||
|
||||
var trigger = e.submitter || form.querySelector('button[type="submit"]');
|
||||
|
||||
|
||||
var hasFile = false;
|
||||
form.querySelectorAll('input[type="file"]').forEach(function(f) {
|
||||
if (f.files && f.files.length > 0) hasFile = true;
|
||||
});
|
||||
var label = hasFile ? SUBMIT_I18N.uploading : SUBMIT_I18N.submitting;
|
||||
|
||||
if (trigger && trigger.tagName === 'BUTTON') {
|
||||
trigger.setAttribute('data-tb-restore', trigger.innerHTML);
|
||||
trigger.innerHTML = '<span uk-spinner="ratio: 0.6"></span> ' + label;
|
||||
}
|
||||
|
||||
|
||||
form.querySelectorAll('button').forEach(function(b) {
|
||||
b.disabled = true;
|
||||
b.setAttribute('data-tb-submitting', '1');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener('pageshow', tbResetSubmitButtons);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
<a href="/user/questions#votes">Found</a>.
|
||||
|
||||
@@ -616,11 +616,13 @@ a.tb-chip:hover {
|
||||
border-radius: var(--tb-radius-xs);
|
||||
}
|
||||
.uk-progress::-webkit-progress-value {
|
||||
/* 两端都圆:值 100% 时若只圆左边,右端方角会顶出轨道圆角 */
|
||||
background-color: var(--tb-primary);
|
||||
border-radius: var(--tb-radius-xs) 0 0 var(--tb-radius-xs);
|
||||
border-radius: var(--tb-radius-xs);
|
||||
}
|
||||
.uk-progress::-moz-progress-bar {
|
||||
background-color: var(--tb-primary);
|
||||
border-radius: var(--tb-radius-xs);
|
||||
}
|
||||
|
||||
/* 移动端底部操作栏:固定底栏承载语言切换与深色模式,桌面端隐藏 */
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<!-- UIkit 3.3.3 切到公共 CDN(cdnjs.snrat.com,国内实测全量下载 ~0.25s,原 R2 自建 ~1.4-2.0s) -->
|
||||
<link rel="stylesheet" href="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/css/uikit.min.css"/>
|
||||
<!-- 全站基础样式(由原内联块抽出,可被浏览器缓存):改 static/css/base.css 后把 v 版本号 +1 -->
|
||||
<link rel="stylesheet" href="/static/css/base.css?v=20261019c"/>
|
||||
<link rel="stylesheet" href="/static/css/base.css?v=20261019d"/>
|
||||
<!-- Waline 评论区样式:非阻塞加载,不阻塞首屏渲染 -->
|
||||
<link rel="stylesheet" href="https://r2.337845818.best/tamabox/cdn/waline/client/v2/waline-no-commits.css" media="print" onload="this.media='all'"/>
|
||||
<script defer src="https://cdnjs.snrat.com/ajax/libs/uikit/3.3.3/js/uikit.min.js"></script>
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
{{ range $si, $stat := .Results.FormFieldStats }}
|
||||
<div class="uk-margin">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 8px;">
|
||||
<span class="uk-label">{{ add $si 1 }}</span>
|
||||
<span class="uk-label {{ fieldTypeLabelClass $stat.Field.FieldType }}">{{ fieldTypeLabel $.LangCode $stat.Field.FieldType }}</span>
|
||||
<span class="tb-chip">{{ add $si 1 }}</span>
|
||||
<span class="tb-chip">{{ fieldTypeLabel $.LangCode $stat.Field.FieldType }}</span>
|
||||
<span class="uk-text-bold">{{ $stat.Field.Label }}</span>
|
||||
<span class="uk-text-meta uk-text-small">{{t $.LangCode "vote.resultsAnswered"}}: {{ $stat.Total }}</span>
|
||||
</div>
|
||||
|
||||
@@ -168,8 +168,8 @@
|
||||
{{ range $fi, $f := .FormFields }}
|
||||
<div class="uk-margin">
|
||||
<div class="tb-field-head">
|
||||
<span class="uk-label">{{ add $fi 1 }}</span>
|
||||
<span class="uk-label {{ fieldTypeLabelClass $f.FieldType }}">{{ fieldTypeLabel $.LangCode $f.FieldType }}</span>
|
||||
<span class="tb-chip">{{ add $fi 1 }}</span>
|
||||
<span class="tb-chip">{{ fieldTypeLabel $.LangCode $f.FieldType }}</span>
|
||||
<div class="tb-field-label">{{ $f.Label }}{{ if $f.Required }} <span class="uk-text-danger">*</span>{{ end }}</div>
|
||||
</div>
|
||||
{{ if eq $f.FieldType "text" }}
|
||||
@@ -310,8 +310,8 @@
|
||||
{{ range $si, $stat := .Results.FormFieldStats }}
|
||||
<div class="uk-margin-top">
|
||||
<div class="uk-flex uk-flex-middle uk-margin-small-bottom" style="gap: 8px;">
|
||||
<span class="uk-label">{{ add $si 1 }}</span>
|
||||
<span class="uk-label {{ fieldTypeLabelClass $stat.Field.FieldType }}">{{ fieldTypeLabel $.LangCode $stat.Field.FieldType }}</span>
|
||||
<span class="tb-chip">{{ add $si 1 }}</span>
|
||||
<span class="tb-chip">{{ fieldTypeLabel $.LangCode $stat.Field.FieldType }}</span>
|
||||
<span class="uk-text-bold">{{ $stat.Field.Label }}</span>
|
||||
<span class="uk-text-meta uk-text-small">{{t $.LangCode "vote.resultsAnswered"}}: {{ $stat.Total }}</span>
|
||||
</div>
|
||||
|
||||