Compare commits
839 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b8d33826b | ||
|
|
9e9a1efe06 | ||
|
|
a5d7cb9074 | ||
|
|
053b5870cf | ||
|
|
4ab90f3152 | ||
|
|
dc75a3513e | ||
|
|
40ceb747ae | ||
|
|
6996e3abc4 | ||
|
|
5118ffb3f8 | ||
|
|
287a49f196 | ||
|
|
698ed1d42e | ||
|
|
a0deb532e3 | ||
|
|
0e1e6201ca | ||
|
|
6ea75236fa | ||
|
|
61281190bb | ||
|
|
2355528b46 | ||
|
|
db5b8ec309 | ||
|
|
a0a0a6feca | ||
|
|
787bef7625 | ||
|
|
e57d4ea921 | ||
|
|
c6c9c3f53b | ||
|
|
f7eb634aa1 | ||
|
|
74f07c3a6c | ||
|
|
95864559fb | ||
|
|
5155205e8c | ||
|
|
d91b0d3e99 | ||
|
|
3df355abdb | ||
|
|
850e5bccae | ||
|
|
713fe21190 | ||
|
|
3d683ab87e | ||
|
|
a4053f0f1a | ||
|
|
87e29cc117 | ||
|
|
c17d0fb0bb | ||
|
|
985863deb2 | ||
|
|
a9d2c0425d | ||
|
|
76cb2341ce | ||
|
|
ceb6f09a3f | ||
|
|
adf3540556 | ||
|
|
2ce8a38b0b | ||
|
|
e62d959b0b | ||
|
|
4216a777a3 | ||
|
|
5873b41e00 | ||
|
|
14635e9472 | ||
|
|
422f3de11d | ||
|
|
64b5531fed | ||
|
|
17f3b25e51 | ||
|
|
60f0c19a9f | ||
|
|
f4f2479b8a | ||
|
|
3506d7f975 | ||
|
|
9acca366d0 | ||
|
|
70fd791545 | ||
|
|
9f3c41fb0b | ||
|
|
2ff6088605 | ||
|
|
54644e0da2 | ||
|
|
dbd05c30c3 | ||
|
|
587cdf4e75 | ||
|
|
76d75b260f | ||
|
|
35ff3759f4 | ||
|
|
671db6e483 | ||
|
|
32566bfd84 | ||
|
|
4b02ad6d89 | ||
|
|
a5c2f8d86f | ||
|
|
6e1e7440dc | ||
|
|
0b460eeb5d | ||
|
|
2a32bb75d5 | ||
|
|
cf91d8ffa5 | ||
|
|
375713390e | ||
|
|
f823b0e612 | ||
|
|
cb1821189a | ||
|
|
1a5862213c | ||
|
|
96c019324d | ||
|
|
1e905b6bbf | ||
|
|
7c6726b5fc | ||
|
|
24d18ff599 | ||
|
|
16d0489cd7 | ||
|
|
5875347966 | ||
|
|
b2c1d9eb26 | ||
|
|
a0bc39aaa5 | ||
|
|
b887d07172 | ||
|
|
1f48c58f6b | ||
|
|
e8eec5862f | ||
|
|
bf7213bf09 | ||
|
|
b2201c4ef7 | ||
|
|
a4747b9965 | ||
|
|
5ec4c823fe | ||
|
|
00d0be952f | ||
|
|
c448777fe9 | ||
|
|
30b54c17fa | ||
|
|
e954c57da6 | ||
|
|
d5d30893e5 | ||
|
|
72947dbbcc | ||
|
|
1c632666ab | ||
|
|
5cf12f37a5 | ||
|
|
9c038021b5 | ||
|
|
4a8861761d | ||
|
|
13e0010419 | ||
|
|
e461462bd6 | ||
|
|
8101e67b10 | ||
|
|
63edd14243 | ||
|
|
d2142f7c83 | ||
|
|
28b1864841 | ||
|
|
5fa1e76971 | ||
|
|
40eeb116de | ||
|
|
a502259ba9 | ||
|
|
cac18a5e44 | ||
|
|
c86f573440 | ||
|
|
6f5130d8fd | ||
|
|
17b8101349 | ||
|
|
5e53ae6f04 | ||
|
|
50c395aad4 | ||
|
|
18bf12e556 | ||
|
|
bc1c038468 | ||
|
|
7117a25f9a | ||
|
|
ef69bda0d7 | ||
|
|
ab6ac43851 | ||
|
|
28feb5a84e | ||
|
|
9e3e0cc443 | ||
|
|
c573fb646b | ||
|
|
93b3e0f83f | ||
|
|
7dda235ab1 | ||
|
|
09e7969479 | ||
|
|
cb37a45b67 | ||
|
|
e25d6ab370 | ||
|
|
e2194d3fbd | ||
|
|
fdc4234d08 | ||
|
|
0c0160da6d | ||
|
|
fd82218e5f | ||
|
|
091d74af52 | ||
|
|
e690b7dd9c | ||
|
|
a856af693f | ||
|
|
3668eb7822 | ||
|
|
3cc04a6cad | ||
|
|
e6967a75e7 | ||
|
|
679ee50342 | ||
|
|
b73c219e6b | ||
|
|
1b474af875 | ||
|
|
77a72c5770 | ||
|
|
a52fe21743 | ||
|
|
42c70990a0 | ||
|
|
0980903b6e | ||
|
|
47737dd205 | ||
|
|
a22330f920 | ||
|
|
05b4695398 | ||
|
|
415fb3c4a8 | ||
|
|
5138c31e58 | ||
|
|
052259c9d1 | ||
|
|
7276e28bb7 | ||
|
|
2adf2d5127 | ||
|
|
242094193f | ||
|
|
2ffc7a80e6 | ||
|
|
3da1ab157d | ||
|
|
17d2654f26 | ||
|
|
f155b0e9a1 | ||
|
|
c97296700f | ||
|
|
3951432bad | ||
|
|
da5c44d4fd | ||
|
|
a35889ca18 | ||
|
|
c171e62d52 | ||
|
|
75a3cf5ede | ||
|
|
2d25b349f7 | ||
|
|
29149eb452 | ||
|
|
57232aeaf0 | ||
|
|
2ced2b73c7 | ||
|
|
0dce01cd6d | ||
|
|
5d05f62db5 | ||
|
|
fe9de25dcd | ||
|
|
2c2bfce762 | ||
|
|
68bc36c0db | ||
|
|
5c353e94f0 | ||
|
|
d1d2ade366 | ||
|
|
a007f314e8 | ||
|
|
9728cf697b | ||
|
|
67cd4ab112 | ||
|
|
435bfa17d5 | ||
|
|
b9373e44a1 | ||
|
|
00153e3957 | ||
|
|
588e19e93c | ||
|
|
e9592b6021 | ||
|
|
42ef4c4df1 | ||
|
|
dbb119bd8b | ||
|
|
9e3e597088 | ||
|
|
e50099b7c0 | ||
|
|
55baec7af7 | ||
|
|
4ab24625fa | ||
|
|
1eed2cdd1a | ||
|
|
43a81a6a4d | ||
|
|
43dcbad33c | ||
|
|
89b51773eb | ||
|
|
47b722a825 | ||
|
|
76b6bad8a5 | ||
|
|
648b66cbbe | ||
|
|
1f2c644bf6 | ||
|
|
8aed629be6 | ||
|
|
9042f0f3b0 | ||
|
|
a425ffea8f | ||
|
|
a4a4eb7c2a | ||
|
|
a01d5b0cee | ||
|
|
9f8ce5ab95 | ||
|
|
880d1e10e3 | ||
|
|
ff745ada70 | ||
|
|
68d7ec783d | ||
|
|
a17f91fea1 | ||
|
|
c5cf5ba4f9 | ||
|
|
9f9bebf99c | ||
|
|
6ea1b2d3b4 | ||
|
|
acc727b901 | ||
|
|
594cc4929a | ||
|
|
e0f15b73fb | ||
|
|
0ac0d7d1ff | ||
|
|
9a6a4247ce | ||
|
|
22e384f2d1 | ||
|
|
7c668c5184 | ||
|
|
91b6dbe9b2 | ||
|
|
21566eb0d9 | ||
|
|
cc382572c6 | ||
|
|
6e029cea0d | ||
|
|
c92b78c754 | ||
|
|
32eae178fb | ||
|
|
8a1936fade | ||
|
|
edd44c73bf | ||
|
|
b3d346c61f | ||
|
|
ef124fe7f2 | ||
|
|
38f9db2f57 | ||
|
|
e45c172e62 | ||
|
|
705f3b9df0 | ||
|
|
1f4e6c8ecb | ||
|
|
0831c250c4 | ||
|
|
ecb462c0c3 | ||
|
|
6092f4e78e | ||
|
|
316729774a | ||
|
|
c4f8fd118d | ||
|
|
543108e0d6 | ||
|
|
6631b881b0 | ||
|
|
2d39c33f05 | ||
|
|
b32ff7b6ac | ||
|
|
9583b80ac5 | ||
|
|
71b46ef1f2 | ||
|
|
5f0a353482 | ||
|
|
6eb84bf55e | ||
|
|
e057ee1812 | ||
|
|
279e9c18c9 | ||
|
|
191dbc860c | ||
|
|
a9403410c8 | ||
|
|
6e2f245f24 | ||
|
|
6d20a991f8 | ||
|
|
d20de6b9b5 | ||
|
|
fbb14cc719 | ||
|
|
6bb1f4978e | ||
|
|
40d372efe3 | ||
|
|
51672e81c3 | ||
|
|
5b06abe63d | ||
|
|
8ebe2d2d26 | ||
|
|
b020d13304 | ||
|
|
aa9ae3d32f | ||
|
|
53046ad1d2 | ||
|
|
a851eddccf | ||
|
|
a2c33bc649 | ||
|
|
e868b2c73b | ||
|
|
4de2b15959 | ||
|
|
a57a3b283c | ||
|
|
b9efd55a57 | ||
|
|
87097b7a06 | ||
|
|
c50aecc34d | ||
|
|
74e0d479a6 | ||
|
|
4420a65dfd | ||
|
|
b73ad00865 | ||
|
|
945e609dff | ||
|
|
2c63c3d0ad | ||
|
|
c86d58a44b | ||
|
|
12ae47b9b6 | ||
|
|
27e19f3591 | ||
|
|
50a8ddd458 | ||
|
|
5690e80758 | ||
|
|
489b21fd04 | ||
|
|
f9b08aa467 | ||
|
|
85938d1f6b | ||
|
|
a1d02708fa | ||
|
|
f3f051fbf1 | ||
|
|
d078e58774 | ||
|
|
d8ecf670d5 | ||
|
|
1bd84c839e | ||
|
|
5bfa14ba1a | ||
|
|
7d258d9f3b | ||
|
|
57d8fd4841 | ||
|
|
a8653a472e | ||
|
|
45c0cf142d | ||
|
|
f53d9b8a5b | ||
|
|
42ea131dff | ||
|
|
57ca993189 | ||
|
|
9d4b43c7e9 | ||
|
|
8802d5feef | ||
|
|
b8d58ab3e3 | ||
|
|
00e2e4d03d | ||
|
|
9ed02e4df0 | ||
|
|
59a8e244a0 | ||
|
|
3bd9e85682 | ||
|
|
3749445531 | ||
|
|
5337fea89f | ||
|
|
77e1f16624 | ||
|
|
28b8c5059c | ||
|
|
285f5c271a | ||
|
|
e143a78e20 | ||
|
|
b9905ebae4 | ||
|
|
89dee3b72d | ||
|
|
18ea50ab18 | ||
|
|
1fb23dd34a | ||
|
|
6ce938b86a | ||
|
|
a853409230 | ||
|
|
cfeb11b545 | ||
|
|
963b893e39 | ||
|
|
a75c22aecb | ||
|
|
ca2d87e303 | ||
|
|
bf143f07f7 | ||
|
|
850e61d923 | ||
|
|
c5937bc3f7 | ||
|
|
4436c62fe2 | ||
|
|
71bb46cb5b | ||
|
|
f06daf111a | ||
|
|
93434f3bf6 | ||
|
|
90aaad39bf | ||
|
|
8492cc35fa | ||
|
|
5087a0de7a | ||
|
|
dfe6eae59f | ||
|
|
030a9e58e8 | ||
|
|
7a73cf3d55 | ||
|
|
8e1eb8620c | ||
|
|
546f4d413f | ||
|
|
aa04d1d3ba | ||
|
|
27eae6750c | ||
|
|
3174aaad22 | ||
|
|
89c4fe4a96 | ||
|
|
4f204fd873 | ||
|
|
7612b629ad | ||
|
|
0d5b0ddb0b | ||
|
|
b41d2fa532 | ||
|
|
52239bebc3 | ||
|
|
a7a97709fe | ||
|
|
e0789c8f90 | ||
|
|
c5e90ec550 | ||
|
|
6840c28cb8 | ||
|
|
41caf046a0 | ||
|
|
deb5a36c0d | ||
|
|
920ddb64b3 | ||
|
|
af59a38a40 | ||
|
|
8bca301e55 | ||
|
|
8401c5a25d | ||
|
|
ab44cb2457 | ||
|
|
e831a56809 | ||
|
|
84cac4ceec | ||
|
|
e372893373 | ||
|
|
4f0ae8fec3 | ||
|
|
7f445f81fc | ||
|
|
28c18afaf9 | ||
|
|
6008c94949 | ||
|
|
8dc1218934 | ||
|
|
11204cba16 | ||
|
|
e3928bc6c2 | ||
|
|
c2bd325be6 | ||
|
|
941c4a3a9f | ||
|
|
261493af0b | ||
|
|
1791fc475b | ||
|
|
de7cec2c43 | ||
|
|
e7c90c647d | ||
|
|
9596c1e27e | ||
|
|
c86732ba5c | ||
|
|
2a7c15241f | ||
|
|
d2d81ccbd0 | ||
|
|
78a5138409 | ||
|
|
bdd9ae9ae4 | ||
|
|
a8a98b03fb | ||
|
|
4a5fd4aba0 | ||
|
|
2de7c633d4 | ||
|
|
56c72d1d74 | ||
|
|
f3793852a2 | ||
|
|
382875509b | ||
|
|
5da696d1c8 | ||
|
|
7f1800a0c6 | ||
|
|
504c9ae84e | ||
|
|
63a3511c84 | ||
|
|
309d8e6c45 | ||
|
|
403c404ced | ||
|
|
133b032f1d | ||
|
|
ac0b171f19 | ||
|
|
0e57fe057f | ||
|
|
6e4398f0c2 | ||
|
|
136a0878af | ||
|
|
813c00e3ea | ||
|
|
d8625a1cb5 | ||
|
|
c7d322c09d | ||
|
|
f7e8359f7b | ||
|
|
3283e53c5c | ||
|
|
fb2b80335e | ||
|
|
96f6044489 | ||
|
|
8f1a497f13 | ||
|
|
272fe26b26 | ||
|
|
dec1a3e78d | ||
|
|
85ce14091a | ||
|
|
faf5071740 | ||
|
|
aadf8a9bfa | ||
|
|
6ccb829fb9 | ||
|
|
3be1c3e081 | ||
|
|
3e20e100f5 | ||
|
|
f227786e33 | ||
|
|
82d71588e9 | ||
|
|
521c135498 | ||
|
|
ae45d3e516 | ||
|
|
363bf49799 | ||
|
|
8782dffeae | ||
|
|
da4e56fe25 | ||
|
|
eb9a8e5174 | ||
|
|
bd45322509 | ||
|
|
2705a111c6 | ||
|
|
bb748f9a74 | ||
|
|
1ef0430392 | ||
|
|
2415c10029 | ||
|
|
f6f84f25c8 | ||
|
|
23c4f455d5 | ||
|
|
b1ebd3826a | ||
|
|
914c69215e | ||
|
|
fdb34a7816 | ||
|
|
21b80ecc8d | ||
|
|
d0d1bed10a | ||
|
|
2613c57bf8 | ||
|
|
43bb6e4c5c | ||
|
|
7136b176ee | ||
|
|
7767b6d436 | ||
|
|
98b2834bd1 | ||
|
|
d1f540f99a | ||
|
|
7bdb104fcf | ||
|
|
9e68e626c9 | ||
|
|
7df2e6c83b | ||
|
|
9aca55ec71 | ||
|
|
9f55486107 | ||
|
|
4e161a5d70 | ||
|
|
ee3b067555 | ||
|
|
64c5b1589b | ||
|
|
7b3a6329a6 | ||
|
|
fab83592b7 | ||
|
|
7b8d229b64 | ||
|
|
b2d0bfea8c | ||
|
|
9ce09c34c3 | ||
|
|
fdd9bab210 | ||
|
|
ee73b907de | ||
|
|
27192b0248 | ||
|
|
45267caa0a | ||
|
|
f6576aa899 | ||
|
|
ce8180c804 | ||
|
|
5375252783 | ||
|
|
cc5806a035 | ||
|
|
1fa694282b | ||
|
|
f94491e38d | ||
|
|
df4b263f39 | ||
|
|
3fb94baaca | ||
|
|
be7831cd10 | ||
|
|
7daa0f8520 | ||
|
|
7afd47805a | ||
|
|
def0a4a5c5 | ||
|
|
3fdda45425 | ||
|
|
56a345949d | ||
|
|
2a08f73db4 | ||
|
|
52bafb364d | ||
|
|
a4c70fe77b | ||
|
|
58d32b5d1d | ||
|
|
a389c8b82d | ||
|
|
c8e8ab95cd | ||
|
|
331fed1731 | ||
|
|
5bcbe255b1 | ||
|
|
ba045b6903 | ||
|
|
187eef590d | ||
|
|
06ff6554d4 | ||
|
|
d217776201 | ||
|
|
76949151de | ||
|
|
a6f418d3a9 | ||
|
|
fa27cc64ef | ||
|
|
e042d0fef7 | ||
|
|
2eefe2e301 | ||
|
|
b1c1e4fab3 | ||
|
|
68a83205ab | ||
|
|
950441ef45 | ||
|
|
e01002ed25 | ||
|
|
9d7eceb927 | ||
|
|
2b28431568 | ||
|
|
0df3fe43e0 | ||
|
|
1a3fe3af66 | ||
|
|
6d6ba47b2c | ||
|
|
d47d390536 | ||
|
|
157d1f8cb9 | ||
|
|
5df2ecac0c | ||
|
|
1452be84bf | ||
|
|
d5d005e74b | ||
|
|
846fe26ec5 | ||
|
|
940ac4dec0 | ||
|
|
3a26c3e38e | ||
|
|
0a4a3b4f8a | ||
|
|
11f096e195 | ||
|
|
02330805e9 | ||
|
|
ed5be31c22 | ||
|
|
d99a222434 | ||
|
|
01bd911084 | ||
|
|
79ae266424 | ||
|
|
e9db85c5b6 | ||
|
|
d82f2e3732 | ||
|
|
2d9aac039c | ||
|
|
917b15156c | ||
|
|
b03b18b05f | ||
|
|
7527e4c978 | ||
|
|
702dcf7997 | ||
|
|
5cd2c3d43a | ||
|
|
3e4d128b9c | ||
|
|
ecb223ebc4 | ||
|
|
61e390daf0 | ||
|
|
4264004eaf | ||
|
|
ac4eb96a69 | ||
|
|
d59cb4f9a8 | ||
|
|
ad1ff687f6 | ||
|
|
480c40ce4f | ||
|
|
a1142aa670 | ||
|
|
6fddac0245 | ||
|
|
531da63e7b | ||
|
|
d52a63586f | ||
|
|
3710ed884e | ||
|
|
9019bf2e9a | ||
|
|
de6d2964f9 | ||
|
|
12f5e67bb4 | ||
|
|
b71d62ca35 | ||
|
|
fffe030fa2 | ||
|
|
74099cb5f2 | ||
|
|
d55716dc9b | ||
|
|
dabbf4d143 | ||
|
|
048300d6e4 | ||
|
|
3a1a24f6da | ||
|
|
5fccdeba45 | ||
|
|
72e10a8734 | ||
|
|
b78054a751 | ||
|
|
c394114c4e | ||
|
|
7aa6eb28b2 | ||
|
|
a96b4d0585 | ||
|
|
c8217dad84 | ||
|
|
926aa0b69f | ||
|
|
a51f9a77e6 | ||
|
|
f0fd23e6a9 | ||
|
|
85dc5da83a | ||
|
|
1b7526ff2f | ||
|
|
982cbf2eb1 | ||
|
|
c455edcd59 | ||
|
|
ed489f9d89 | ||
|
|
07d6bc2cd7 | ||
|
|
cdcd0ce68d | ||
|
|
861acbbe0a | ||
|
|
7e47470cea | ||
|
|
d1bf4cc7f3 | ||
|
|
e2968dbd97 | ||
|
|
ed62c4e879 | ||
|
|
a02c6f040e | ||
|
|
7022dbf8c1 | ||
|
|
14cf2cbe5b | ||
|
|
6a73f5d727 | ||
|
|
5a069dbb9a | ||
|
|
77be791ce7 | ||
|
|
d69ee3a8d0 | ||
|
|
115e2884c1 | ||
|
|
f9ab15e271 | ||
|
|
6c5aed6a3c | ||
|
|
cc0a0bc269 | ||
|
|
fe2fb50775 | ||
|
|
a423b6bfe6 | ||
|
|
7441463de3 | ||
|
|
2dea0917d1 | ||
|
|
d059971dcc | ||
|
|
fd60d92728 | ||
|
|
4737932a3e | ||
|
|
32c5df4ffd | ||
|
|
dede4299dc | ||
|
|
57afa2ce4b | ||
|
|
4a79b1c998 | ||
|
|
5443e06b38 | ||
|
|
69f08dbb58 | ||
|
|
9f5409a66a | ||
|
|
6ff21ebaeb | ||
|
|
14fe9fe916 | ||
|
|
5c66f4684a | ||
|
|
6797e68ddd | ||
|
|
86088b52e8 | ||
|
|
b44c711483 | ||
|
|
d38ff65c22 | ||
|
|
02cafc2cc5 | ||
|
|
d956f5334c | ||
|
|
3799c8caa1 | ||
|
|
bcb12ecb0f | ||
|
|
b89ca0dc72 | ||
|
|
893491ce25 | ||
|
|
51d031566a | ||
|
|
a54b928a67 | ||
|
|
8ac1c210f2 | ||
|
|
8d83e4dbaf | ||
|
|
d4a200e921 | ||
|
|
e1f9efffbc | ||
|
|
61de708062 | ||
|
|
411230f48a | ||
|
|
5530ae113e | ||
|
|
29b2db8198 | ||
|
|
bc239360ea | ||
|
|
558553a587 | ||
|
|
23752f0996 | ||
|
|
317bbbf457 | ||
|
|
177082fded | ||
|
|
323f2f150c | ||
|
|
44ff1d2fb6 | ||
|
|
390574ed45 | ||
|
|
60dec3db4a | ||
|
|
00a69ad685 | ||
|
|
2959be4564 | ||
|
|
5d14475373 | ||
|
|
62e59d4201 | ||
|
|
af02424d20 | ||
|
|
33c6c33af2 | ||
|
|
7a67e38bf1 | ||
|
|
9a75911ab7 | ||
|
|
8181d174a5 | ||
|
|
c618440878 | ||
|
|
0bc6298cc0 | ||
|
|
93b452c497 | ||
|
|
b2d46c9021 | ||
|
|
f972d91137 | ||
|
|
f8a6b32b5f | ||
|
|
439ab7583a | ||
|
|
5800b1bf1d | ||
|
|
1ba53b7688 | ||
|
|
dd2eb90230 | ||
|
|
2319327917 | ||
|
|
89dfe68b32 | ||
|
|
c4dadd21fc | ||
|
|
812d7cfd9d | ||
|
|
415f0d6e39 | ||
|
|
08d97147b8 | ||
|
|
23614275eb | ||
|
|
1eca5c59e3 | ||
|
|
91953148e8 | ||
|
|
c5a5fb57d9 | ||
|
|
5b8d338840 | ||
|
|
5bc7c92e71 | ||
|
|
f32bd8c946 | ||
|
|
ca333e06ac | ||
|
|
9aab7addb1 | ||
|
|
0b984d0dcd | ||
|
|
73b254367f | ||
|
|
a9c09e57e9 | ||
|
|
d8b57e2189 | ||
|
|
7ce22cefb7 | ||
|
|
2de555f176 | ||
|
|
68c071e318 | ||
|
|
077b61270c | ||
|
|
5975383349 | ||
|
|
46ca31066f | ||
|
|
9db627d07f | ||
|
|
014dbdfa95 | ||
|
|
ea06f5498f | ||
|
|
c2d60063ee | ||
|
|
0ebd2241e5 | ||
|
|
0aca177c86 | ||
|
|
9bb45cd896 | ||
|
|
7458a884d5 | ||
|
|
6392a606c4 | ||
|
|
693bcdeffd | ||
|
|
81a398ab26 | ||
|
|
7296bc6944 | ||
|
|
e97c4bab53 | ||
|
|
2c03b8fd6b | ||
|
|
2f3742fa7c | ||
|
|
ff816fd556 | ||
|
|
585d4cbff1 | ||
|
|
0d388b19ee | ||
|
|
a8e870a099 | ||
|
|
32c4dcbe69 | ||
|
|
a3571f541b | ||
|
|
39dbe314d6 | ||
|
|
63e2614983 | ||
|
|
0623077a40 | ||
|
|
f05d43af89 | ||
|
|
68b73ff1dd | ||
|
|
0613350420 | ||
|
|
37af910c89 | ||
|
|
6286a6529c | ||
|
|
51bdf9609f | ||
|
|
b5d60f1431 | ||
|
|
56f8fc8b91 | ||
|
|
e0de5dfbf5 | ||
|
|
d122da98b5 | ||
|
|
e6a38af5ee | ||
|
|
abf3da5900 | ||
|
|
a40aad33d1 | ||
|
|
9a6f3ef4ed | ||
|
|
372a8767ee | ||
|
|
f7a31012e8 | ||
|
|
5cf11d50d4 | ||
|
|
a4f3e4ffa4 | ||
|
|
60de698f2c | ||
|
|
1c4f4630c2 | ||
|
|
9974628f62 | ||
|
|
2ea928417d | ||
|
|
eede0c55dc | ||
|
|
c6780cfd27 | ||
|
|
34b2e18587 | ||
|
|
38d3bc4481 | ||
|
|
e556d6d2be | ||
|
|
22a3564f22 | ||
|
|
b695d97e82 | ||
|
|
64e4c3320d | ||
|
|
7c7d07434d | ||
|
|
d2b9e76389 | ||
|
|
f91bd642a5 | ||
|
|
9459e1758d | ||
|
|
24b2bd8e15 | ||
|
|
8ad13c8e45 | ||
|
|
c6e6c2e5d6 | ||
|
|
9690156fbf | ||
|
|
dea611c1ba | ||
|
|
0e0f35e6dc | ||
|
|
5370898da9 | ||
|
|
1020fae1dd | ||
|
|
6bcfff0269 | ||
|
|
5fbf75a77d | ||
|
|
86744c9349 | ||
|
|
24b6d87381 | ||
|
|
649cc96269 | ||
|
|
a9e377563d | ||
|
|
9229aa62bd | ||
|
|
f9c9028a0b | ||
|
|
5fa12dcda8 | ||
|
|
8c0a4ac6b0 | ||
|
|
bd279547d2 | ||
|
|
1ad6432576 | ||
|
|
4b007fa759 | ||
|
|
abe985b6c5 | ||
|
|
6091934884 | ||
|
|
7db701b23a | ||
|
|
00816c1a95 | ||
|
|
713f8a7d19 | ||
|
|
da42b8fc7d | ||
|
|
27bf7de803 | ||
|
|
4fd443dce4 | ||
|
|
f8d3f85a4d | ||
|
|
007851056f | ||
|
|
f97b5a56e5 | ||
|
|
7495c3e843 | ||
|
|
713ff950e7 | ||
|
|
64a7a6e6aa | ||
|
|
6aa9475c91 | ||
|
|
a9ac1207c0 | ||
|
|
539033ec6d | ||
|
|
80041baf1e | ||
|
|
b83b21df59 | ||
|
|
69c30e0685 | ||
|
|
0ed2bad9f1 | ||
|
|
41d3cb467b | ||
|
|
476ae002c2 | ||
|
|
6f0b518391 | ||
|
|
f673a10768 | ||
|
|
8668d1aa08 | ||
|
|
d2babe367b | ||
|
|
3b5937f2d9 | ||
|
|
1896060218 | ||
|
|
9d2461c716 | ||
|
|
85d60a1928 | ||
|
|
6eb42d4cf7 | ||
|
|
37df9ef131 | ||
|
|
450d07d6e5 | ||
|
|
047a63ec20 | ||
|
|
3821562cf6 | ||
|
|
85a968ad40 | ||
|
|
c169616471 | ||
|
|
c0d5800bd4 | ||
|
|
6bd5518249 | ||
|
|
b3da008694 | ||
|
|
3a2529561f | ||
|
|
110e607839 | ||
|
|
54fa915aeb | ||
|
|
273d28d237 | ||
|
|
ec56bbe8f9 | ||
|
|
9340b9088e | ||
|
|
329eca6af3 | ||
|
|
06d4535eaa | ||
|
|
9f78414098 | ||
|
|
97faee8d1d | ||
|
|
33d95c2ef3 | ||
|
|
97ee132989 | ||
|
|
ab3da1edee | ||
|
|
ba0f5471a3 | ||
|
|
9f84ab4ca9 | ||
|
|
3274536134 | ||
|
|
bc5b22f7a1 | ||
|
|
0199230489 | ||
|
|
98bb655a3c | ||
|
|
c4090303ec | ||
|
|
0be5982d39 | ||
|
|
c7975c67ef | ||
|
|
59173f055e | ||
|
|
0b8c977aad | ||
|
|
2c0426d1a4 | ||
|
|
e6de8a1d20 | ||
|
|
9ebe7d7c5d | ||
|
|
84626f6f96 | ||
|
|
3a35dc5575 | ||
|
|
13b8a18e21 | ||
|
|
4557503256 | ||
|
|
689ced2ae4 | ||
|
|
ccc5972e67 | ||
|
|
e07260d068 | ||
|
|
7854b0b81d | ||
|
|
177e0156cc | ||
|
|
10d47779d3 | ||
|
|
d26d6ecacb | ||
|
|
85200d9284 | ||
|
|
8bcd0b790c | ||
|
|
68e4e9162f | ||
|
|
05d1290344 | ||
|
|
d1bb6b59b0 | ||
|
|
64111298f6 | ||
|
|
6df6fd807a | ||
|
|
d140c9ee99 | ||
|
|
50fafb4531 | ||
|
|
5591b56df0 | ||
|
|
6041a7d608 | ||
|
|
111522d08e | ||
|
|
7d89ab06c7 | ||
|
|
cab35af8c4 | ||
|
|
5abbe123c3 | ||
|
|
404d9952f2 | ||
|
|
a6b7235b12 | ||
|
|
55f4461475 | ||
|
|
bb1c6890ac | ||
|
|
e545bab034 | ||
|
|
21ec8e5f3a | ||
|
|
35c6875b00 | ||
|
|
45f217fa78 | ||
|
|
e6ca1b07ed | ||
|
|
3e3680c9be | ||
|
|
7501dae72e | ||
|
|
93328cb480 |
29
.gitignore
vendored
@@ -8,10 +8,35 @@
|
||||
.\#*
|
||||
|
||||
# srnd config files
|
||||
*.ini
|
||||
srnd.ini
|
||||
feeds.ini
|
||||
|
||||
# default article store directory
|
||||
articles
|
||||
|
||||
# generated files
|
||||
webroot
|
||||
webroot
|
||||
|
||||
# built binaries
|
||||
go
|
||||
srndv2
|
||||
|
||||
# private key
|
||||
*.key
|
||||
*.txt
|
||||
|
||||
# certificates
|
||||
certs
|
||||
|
||||
|
||||
rebuild.sh
|
||||
vendor
|
||||
.gx
|
||||
|
||||
# generated js
|
||||
contrib/static/nntpchan.js
|
||||
contrib/static/js/nntpchan.js
|
||||
contrib/static/miner-js.js
|
||||
|
||||
#docs trash
|
||||
doc/.trash
|
||||
|
||||
34
.gxignore
Normal file
@@ -0,0 +1,34 @@
|
||||
#
|
||||
# .gxignore for nntpchan repo
|
||||
#
|
||||
|
||||
# emacs temp files
|
||||
*~
|
||||
\#*
|
||||
.\#*
|
||||
|
||||
# srnd config files
|
||||
srnd.ini
|
||||
feeds.ini
|
||||
|
||||
# default article store directory
|
||||
articles/
|
||||
|
||||
# generated files
|
||||
webroot/
|
||||
|
||||
# built binaries
|
||||
go/
|
||||
srndv2
|
||||
nntpchan
|
||||
|
||||
# private key
|
||||
*.key
|
||||
*.txt
|
||||
|
||||
# certificates
|
||||
certs/
|
||||
|
||||
rebuild.sh
|
||||
|
||||
.git
|
||||
57
README.md
@@ -1,33 +1,56 @@
|
||||
# NNTPChan #
|
||||
NNTPChan
|
||||
========
|
||||
|
||||
NNTPChan (previously known as overchan) is a decentralized imageboard that uses nntp to synchronize content between many different servers. It utilizes cryptographically signed posts to perform optional/opt-in decentralized moderation.
|
||||
**NNTPChan** (previously known as overchan) is a decentralized imageboard that uses the [NNTP protocol](https://en.wikipedia.org/wiki/Network_News_Transfer_Protocol) (network-news transfer protocol) to synchronize content between many different servers. It utilizes cryptographically signed posts to perform optional/opt-in decentralized moderation.
|
||||
|
||||
This repository contains resources used by the core daemon which is located [here](https://github.com/majestrate/srndv2) along with general documentation, [here](doc/)
|
||||
This repository contains resources used by the core daemon which is located on [GitHub](https://github.com/majestrate/srndv2) (for now) along with general documentation, [here](doc/).
|
||||
|
||||
## getting started ##
|
||||
##Getting started
|
||||
|
||||
Get the dependancies
|
||||
[This](doc) is a step-by-step guide for getting up-and-running with NNTPChan as well as documentation for developers who want to either work on NNTPChan directly or use NNTPChan in their aplications with the API.
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get --no-install-recommends install imagemagick libsodium-dev ffmpegthumbnailer sox build-essential git golang ca-certificates
|
||||
##Bugs and issues
|
||||
|
||||
Check out this repo and build it
|
||||
*PLEASE* report any bugs you find while building, setting-up or using NNTPChan on the [GitHub issue tracker](https://github.com/majestrate/nntpchan/issues) or on the [GitGud issue tracker](https://gitgud.io/uguu/nntpchan/issues) so that the probelms can be resolved or discussed.
|
||||
|
||||
git clone https://github.com/majestrate/nntpchan
|
||||
cd nntpchan
|
||||
./build.sh
|
||||
##Active NNTPChan nodes
|
||||
|
||||
Now configure the database. [Next](doc/database.md)
|
||||
Below is a list of known NNTPChan nodes:
|
||||
|
||||
1. [2hu-ch.org](https://2hu-ch.org)
|
||||
2. [nsfl.tk](https://nsfl.tk)
|
||||
3. [gchan](https://gchan.xyz/)
|
||||
|
||||
Tor node list:
|
||||
|
||||
1. [textpunk](http://ucavviu7wl6azuw7.onion/)
|
||||
2. [chan](http://ev7fnjzjdbtu3miq.onion/)
|
||||
3. [oniichan](http://sfw.oniichanylo2tsi4.onion/)
|
||||
|
||||
##Clients
|
||||
|
||||
NNTP (confirmed working):
|
||||
|
||||
* Thunderbird
|
||||
|
||||
Web:
|
||||
|
||||
* [Yukko](https://github.com/faissaloo/Yukko): ncurses based nntpchan web ui reader
|
||||
|
||||
|
||||
---
|
||||
##Support
|
||||
|
||||
*PLEASE* report any bugs you find while setting up or building [(here)](https://github.com/majestrate/nntpchan/issues) so that the problems get fixed :^)
|
||||
Need help? Join us on IRC.
|
||||
|
||||
For peering requests, questions or support find me on [rizon](https://qchat.rizon.net/?channels=#nntpchan) as \__uguu\__
|
||||
1. [freenode: #nntpchan](https://webchat.freenode.net/?channels=#nntpchan)
|
||||
2. [rizon: #nntpchan](https://qchat.rizon.net/?channels=#nntpchan) - Most active
|
||||
|
||||
##Donations
|
||||
|
||||
Like this project? Fund it:
|
||||
Like this project? Why not help by funding it?
|
||||
|
||||
bitcoin: 15yuMzuueV8y5vPQQ39ZqQVz5Ey98DNrjE
|
||||
Bitcoin: [15yuMzuueV8y5vPQQ39ZqQVz5Ey98DNrjE](bitcoin://15yuMzuueV8y5vPQQ39ZqQVz5Ey98DNrjE)
|
||||
|
||||
##Acknowledgements
|
||||
|
||||
* [Deavmi](https://deavmi.carteronline.net/) - Making the documentation beautiful.
|
||||
|
||||
5
TODO.md
@@ -1,6 +1,7 @@
|
||||
## TODO ##
|
||||
|
||||
* extra stylesheets
|
||||
* alternative templates
|
||||
* more alternative templates
|
||||
* javascript free mod panel
|
||||
* liveui
|
||||
* liveui
|
||||
* easier peering
|
||||
|
||||
119
build-js.sh
Executable file
@@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
neochan="yes"
|
||||
if [ "$1" == "--disable-neochan" ] ; then
|
||||
neochan="no"
|
||||
fi
|
||||
|
||||
root=$(readlink -e "$(dirname "$0")")
|
||||
set -e
|
||||
if [ "x" == "x$root" ] ; then
|
||||
root=$PWD/${0##*}
|
||||
fi
|
||||
cd "$root"
|
||||
|
||||
if [ -z "$GOPATH" ]; then
|
||||
export GOPATH=$root/go
|
||||
mkdir -p "$GOPATH"
|
||||
fi
|
||||
|
||||
if [ ! -f "$GOPATH/bin/minify" ]; then
|
||||
echo "set up minifiy"
|
||||
go get -v github.com/tdewolff/minify/cmd/minify
|
||||
fi
|
||||
|
||||
outfile="$PWD/contrib/static/nntpchan.js"
|
||||
neochan_js_outfile="$PWD/contrib/static/neochan.js"
|
||||
neochan_css_outfile="$PWD/contrib/static/neochan.css"
|
||||
|
||||
mini() {
|
||||
echo "minify $1"
|
||||
echo "" >> $2
|
||||
echo "/* begin $1 */" >> $2
|
||||
"$GOPATH/bin/minify" --mime=text/javascript >> $2 < $1
|
||||
echo "" >> $2
|
||||
echo "/* end $1 */" >> $2
|
||||
}
|
||||
|
||||
css() {
|
||||
echo "minify $1"
|
||||
echo "" >> $2
|
||||
echo "/* begin $1 */" >> $2
|
||||
lessc $1 >> $2
|
||||
echo "" >> $2
|
||||
echo "/* end $1 */" >> $2
|
||||
}
|
||||
|
||||
initfile() {
|
||||
|
||||
rm -f "$1"
|
||||
|
||||
echo '/*' >> "$1"
|
||||
echo ' * For source code and license information please check https://github.com/majestrate/nntpchan' >> "$1"
|
||||
brandingfile=./contrib/branding.txt
|
||||
if [ -e "$brandingfile" ] ; then
|
||||
echo ' *' >> "$1"
|
||||
while read line; do
|
||||
echo -n ' * ' >> "$1";
|
||||
echo $line >> "$1";
|
||||
done < $brandingfile;
|
||||
fi
|
||||
echo ' */' >> "$1"
|
||||
}
|
||||
echo
|
||||
echo "building nntpchan.js ..."
|
||||
echo
|
||||
initfile "$outfile"
|
||||
|
||||
if [ -e ./contrib/js/contrib/*.js ] ; then
|
||||
for f in ./contrib/js/contrib/*.js ; do
|
||||
mini "$f" "$outfile"
|
||||
done
|
||||
fi
|
||||
|
||||
mini ./contrib/js/entry.js "$outfile"
|
||||
|
||||
# local js
|
||||
for f in ./contrib/js/nntpchan/*.js ; do
|
||||
mini "$f" "$outfile"
|
||||
done
|
||||
|
||||
# vendor js
|
||||
for f in ./contrib/js/vendor/*.js ; do
|
||||
mini "$f" "$outfile"
|
||||
done
|
||||
|
||||
if [ "$neochan" == "yes" ] ; then
|
||||
set +e
|
||||
for exe in lessc coffee ; do
|
||||
which $exe &> /dev/null
|
||||
if [ "$?" != "0" ] ; then
|
||||
echo "$exe not installed";
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
echo "building neochan.js ..."
|
||||
echo
|
||||
|
||||
initfile "$neochan_js_outfile"
|
||||
for f in ./contrib/js/neochan/*.coffee ; do
|
||||
echo "compile $f"
|
||||
coffee -cs < "$f" > "$f.js"
|
||||
done
|
||||
for f in ./contrib/js/neochan/*.js ; do
|
||||
mini "$f" "$neochan_js_outfile"
|
||||
done
|
||||
|
||||
echo
|
||||
echo "building neochan.css ..."
|
||||
echo
|
||||
initfile "$neochan_css_outfile"
|
||||
for f in ./contrib/js/neochan/*.less ; do
|
||||
css "$f" "$neochan_css_outfile"
|
||||
done
|
||||
|
||||
fi
|
||||
echo
|
||||
echo "ok"
|
||||
110
build.sh
@@ -1,8 +1,106 @@
|
||||
#!/usr/bin/env bash
|
||||
root=$(readlink -e "$(dirname "$0")")
|
||||
set -e
|
||||
root=$(readlink -e $(dirname $0))
|
||||
cd $root
|
||||
export GOPATH=$root/go
|
||||
mkdir -p $GOPATH
|
||||
go get -u github.com/majestrate/srndv2
|
||||
cp -a $GOPATH/bin/srndv2 $root
|
||||
if [ "" == "$root" ] ; then
|
||||
root=$PWD/${0##*}
|
||||
fi
|
||||
cd "$root"
|
||||
|
||||
tags="-tags disable_redis"
|
||||
|
||||
help_text="usage: $0 [--disable-neochan]"
|
||||
|
||||
# check for help flags first
|
||||
for arg in "$@" ; do
|
||||
case $arg in
|
||||
-h|--help)
|
||||
echo "$help_text"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
rev="QmPAqM7anxdr1ngPmJz9J9AAxDLinDz2Eh9aAzLF9T7LNa"
|
||||
ipfs="no"
|
||||
rebuildjs="yes"
|
||||
_next=""
|
||||
unstable="no"
|
||||
neochan="yes"
|
||||
# check for build flags
|
||||
for arg in "$@" ; do
|
||||
case $arg in
|
||||
"--disable-neochan")
|
||||
neochan="no"
|
||||
;;
|
||||
"--unstable")
|
||||
unstable="yes"
|
||||
;;
|
||||
"--no-js")
|
||||
rebuildjs="no"
|
||||
;;
|
||||
"--ipfs")
|
||||
ipfs="yes"
|
||||
;;
|
||||
"--revision")
|
||||
_next="rev"
|
||||
;;
|
||||
"--revision=*")
|
||||
rev=$(echo "$arg" | cut -d'=' -f2)
|
||||
;;
|
||||
*)
|
||||
if [ "x$_next" == "xrev" ] ; then
|
||||
rev="$arg"
|
||||
fi
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$rev" == "" ] ; then
|
||||
echo "revision not specified"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$root"
|
||||
if [ "$rebuildjs" == "yes" ] ; then
|
||||
echo "rebuilding generated js..."
|
||||
if [ "$neochan" == "no" ] ; then
|
||||
./build-js.sh --disable-neochan
|
||||
else
|
||||
./build-js.sh
|
||||
fi
|
||||
fi
|
||||
|
||||
unset GOPATH
|
||||
export GOPATH=$PWD/go
|
||||
mkdir -p "$GOPATH"
|
||||
|
||||
if [ "$ipfs" == "yes" ] ; then
|
||||
if [ ! -e "$GOPATH/bin/gx" ] ; then
|
||||
echo "obtaining gx"
|
||||
go get -u -v github.com/whyrusleeping/gx
|
||||
fi
|
||||
if [ ! -e "$GOPATH/bin/gx-go" ] ; then
|
||||
echo "obtaining gx-go"
|
||||
go get -u -v github.com/whyrusleeping/gx-go
|
||||
fi
|
||||
echo "building stable revision, this will take a bit. to speed this part up install and run ipfs locally"
|
||||
mkdir -p "$GOPATH/src/gx/ipfs"
|
||||
cd "$GOPATH/src/gx/ipfs"
|
||||
"$GOPATH/bin/gx" get "$rev"
|
||||
cd "$root"
|
||||
go get -d -v
|
||||
go build -v .
|
||||
mv nntpchan srndv2
|
||||
echo -e "Built\n"
|
||||
echo "Now configure NNTPChan with ./srndv2 setup"
|
||||
else
|
||||
if [ "$unstable" == "yes" ] ; then
|
||||
go get -u -v github.com/majestrate/srndv2/cmd/nntpchan
|
||||
cp "$GOPATH/bin/nntpchan" "$root"
|
||||
echo "built unstable, if you don't know what to do, run without --unstable"
|
||||
else
|
||||
go get -u -v github.com/majestrate/srndv2
|
||||
cp "$GOPATH/bin/srndv2" "$root"
|
||||
echo -e "Built\n"
|
||||
echo "Now configure NNTPChan with ./srndv2 setup"
|
||||
fi
|
||||
fi
|
||||
|
||||
13
contrib/configs/systemd/nntpchan.service
Normal file
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=NNTPChan Server
|
||||
Requires=redis_6379.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=/opt/nntpchan
|
||||
ExecStart=/opt/nntpchan/srndv2 run
|
||||
ExecStop=/bin/kill -15 $MAINPID
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
89
contrib/frontends/php/vichan/post2nntp.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
function gennntp($headers, $files) {
|
||||
if (count($files) == 0) {
|
||||
}
|
||||
else if (count($files) == 1 && $files[0]['type'] == 'text/plain') {
|
||||
$content = $files[0]['text'] . "\r\n";
|
||||
$headers['Content-Type'] = "text/plain; charset=UTF-8";
|
||||
}
|
||||
else {
|
||||
$boundary = sha1($headers['Message-Id']);
|
||||
$content = "";
|
||||
$headers['Content-Type'] = "multipart/mixed; boundary=$boundary";
|
||||
foreach ($files as $file) {
|
||||
$content .= "--$boundary\r\n";
|
||||
if (isset($file['name'])) {
|
||||
$file['name'] = preg_replace('/[\r\n\0"]/', '', $file['name']);
|
||||
$content .= "Content-Disposition: form-data; filename=\"$file[name]\"; name=\"attachment\"\r\n";
|
||||
}
|
||||
$type = explode('/', $file['type'])[0];
|
||||
if ($type == 'text') {
|
||||
$file['type'] .= '; charset=UTF-8';
|
||||
}
|
||||
$content .= "Content-Type: $file[type]\r\n";
|
||||
if ($type != 'text' && $type != 'message') {
|
||||
$file['text'] = base64_encode($file['text']);
|
||||
$content .= "Content-Transfer-Encoding: base64\r\n";
|
||||
}
|
||||
$content .= "\r\n";
|
||||
$content .= $file['text'];
|
||||
$content .= "\r\n";
|
||||
}
|
||||
$content .= "--$boundary--\r\n";
|
||||
}
|
||||
|
||||
//$headers['Content-Length'] = strlen($content);
|
||||
$headers['Mime-Version'] = '1.0';
|
||||
$headers['Date'] = date('r', $headers['Date']);
|
||||
|
||||
$out = "";
|
||||
foreach ($headers as $id => $val) {
|
||||
$val = str_replace("\n", "\n\t", $val);
|
||||
$out .= "$id: $val\r\n";
|
||||
}
|
||||
$out .= "\r\n";
|
||||
$out .= $content;
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
function shoveitup($msg, $id) {
|
||||
$s = fsockopen("tcp://localhost:1119");
|
||||
fgets($s);
|
||||
fputs($s, "MODE STREAM\r\n");
|
||||
fgets($s);
|
||||
fputs($s, "TAKETHIS $id\r\n");
|
||||
fputs($s, $msg);
|
||||
fputs($s, "\r\n.\r\n");
|
||||
fgets($s);
|
||||
fclose($s);
|
||||
}
|
||||
|
||||
$time = time();
|
||||
|
||||
echo "\n@@@@ Thread:\n";
|
||||
echo $m0 = gennntp(["From" => "czaks <marcin@6irc.net>", "Message-Id" => "<1234.0000.".$time."@example.vichan.net>", "Newsgroups" => "overchan.test", "Date" => time(), "Subject" => "None"],
|
||||
[['type' => 'text/plain', 'text' => "THIS IS A NEW TEST THREAD"]]);
|
||||
|
||||
echo "\n@@@@ Single msg:\n";
|
||||
echo $m1 = gennntp(["From" => "czaks <marcin@6irc.net>", "Message-Id" => "<1234.1234.".$time."@example.vichan.net>", "Newsgroups" => "overchan.test", "Date" => time(), "Subject" => "None", "References" => "<1234.0000.".$time."@example.vichan.net>"],
|
||||
[['type' => 'text/plain', 'text' => "hello world, with no image :("]]);
|
||||
|
||||
echo "\n@@@@ Single msg and pseudoimage:\n";
|
||||
echo $m2 = gennntp(["From" => "czaks <marcin@6irc.net>", "Message-Id" => "<1234.2137.".$time."@example.vichan.net>", "Newsgroups" => "overchan.test", "Date" => time(), "Subject" => "None", "References" => "<1234.0000.".$time."@example.vichan.net>"],
|
||||
[['type' => 'text/plain', 'text' => "hello world, now with an image!"],
|
||||
['type' => 'image/gif', 'text' => base64_decode("R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="), 'name' => "urgif.gif"]]);
|
||||
|
||||
echo "\n@@@@ Single msg and two pseudoimages:\n";
|
||||
echo $m3 = gennntp(["From" => "czaks <marcin@6irc.net>", "Message-Id" => "<1234.1488.".$time."@example.vichan.net>", "Newsgroups" => "overchan.test", "Date" => time(), "Subject" => "None", "References" => "<1234.0000.".$time."@example.vichan.net>"],
|
||||
[['type' => 'text/plain', 'text' => "hello world, now WITH TWO IMAGES!!!"],
|
||||
['type' => 'image/gif', 'text' => base64_decode("R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="), 'name' => "urgif.gif"],
|
||||
['type' => 'image/gif', 'text' => base64_decode("R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="), 'name' => "urgif2.gif"]]);
|
||||
|
||||
shoveitup($m0, "<1234.0000.".$time."@example.vichan.net>");
|
||||
sleep(1);
|
||||
shoveitup($m1, "<1234.1234.".$time."@example.vichan.net>");
|
||||
sleep(1);
|
||||
shoveitup($m2, "<1234.2137.".$time."@example.vichan.net>");
|
||||
shoveitup($m3, "<1234.2131.".$time."@example.vichan.net>");
|
||||
9842
contrib/js/contrib/jquery.js
vendored
Normal file
1
contrib/js/contrib/readme.md
Normal file
@@ -0,0 +1 @@
|
||||
3rd party javascript
|
||||
11
contrib/js/entry.js
Normal file
@@ -0,0 +1,11 @@
|
||||
onready_callbacks = [];
|
||||
function onready(fnc) {
|
||||
onready_callbacks.push(fnc);
|
||||
}
|
||||
|
||||
function ready() {
|
||||
for (var i = 0; i < onready_callbacks.length; i++) {
|
||||
onready_callbacks[i]();
|
||||
}
|
||||
}
|
||||
|
||||
1
contrib/js/neochan/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.coffee.js
|
||||
1
contrib/js/neochan/default.less
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
0
contrib/js/neochan/init.coffee
Normal file
3
contrib/js/neochan/readme.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# neochan javascript directory
|
||||
|
||||
sass files for neochan templates
|
||||
41
contrib/js/nntpchan/api.js
Normal file
@@ -0,0 +1,41 @@
|
||||
// call an api method
|
||||
// handler(json_object) on success
|
||||
// handler(null) on fail
|
||||
function nntpchan_apicall(url, handler, err_handler) {
|
||||
var ajax = new XMLHttpRequest();
|
||||
ajax.onreadystatechange = function() {
|
||||
if (ajax.readyState == XMLHttpRequest.DONE ) {
|
||||
var status = ajax.status;
|
||||
var j = null;
|
||||
if (status == 200) {
|
||||
// found
|
||||
try {
|
||||
j = JSON.parse(ajax.responseText);
|
||||
} catch (e) {} // ignore parse error
|
||||
} else if (status == 410) {
|
||||
if (err_handler) {err_handler("cannot fetch post: api disabled");}
|
||||
return;
|
||||
}
|
||||
handler(j);
|
||||
}
|
||||
};
|
||||
ajax.open("GET", url);
|
||||
ajax.send();
|
||||
}
|
||||
|
||||
// build post from json
|
||||
// inject into parent
|
||||
// if j is null then inject "not found" post
|
||||
function nntpchan_buildpost(parent, j) {
|
||||
var post = document.createElement("div");
|
||||
if (j) {
|
||||
// huehuehue
|
||||
post.innerHTML = j.PostMarkup;
|
||||
inject_hover_for_element(post);
|
||||
} else {
|
||||
post.setAttribute("class", "notfound post");
|
||||
post.appendChild(document.createTextNode("post not found"));
|
||||
}
|
||||
parent.appendChild(post);
|
||||
}
|
||||
|
||||
13
contrib/js/nntpchan/banner.js
Normal file
@@ -0,0 +1,13 @@
|
||||
var banner_count = 5;
|
||||
|
||||
// inject a banner into an element
|
||||
function nntpchan_inject_banners(elem, prefix) {
|
||||
var n = Math.floor(Math.random() * banner_count);
|
||||
var banner = prefix + "static/banner_"+n+".jpg";
|
||||
var e = document.createElement("img");
|
||||
e.src = banner;
|
||||
e.id = "nntpchan_banner";
|
||||
elem.appendChild(e);
|
||||
}
|
||||
|
||||
|
||||
20
contrib/js/nntpchan/captcha-reload.js
Normal file
@@ -0,0 +1,20 @@
|
||||
function setSrcQuery(e, q) {
|
||||
var src = e.src;
|
||||
var p = src.indexOf('?');
|
||||
if (p >= 0) {
|
||||
src = src.substr(0, p);
|
||||
}
|
||||
e.src = src + "?" + q
|
||||
}
|
||||
|
||||
|
||||
function reload(el) {
|
||||
setSrcQuery(el, "reload=" + (new Date()).getTime());
|
||||
return false;
|
||||
}
|
||||
|
||||
onready(function(){
|
||||
document.getElementById("captcha_img").onclick = function() {
|
||||
reload(document.getElementById("captcha_img"));
|
||||
};
|
||||
});
|
||||
70
contrib/js/nntpchan/expand-image.js
Normal file
@@ -0,0 +1,70 @@
|
||||
//
|
||||
// expand images inline
|
||||
//
|
||||
// released into the public domain by Jeff on 2016-04-30
|
||||
//
|
||||
|
||||
// is the filename matching an image?
|
||||
function filenameIsImage(fname) {
|
||||
return /\.(gif|jpeg|jpg|png|webp)/.test(fname.toLowerCase());
|
||||
}
|
||||
|
||||
// setup image inlining for 1 element
|
||||
function setupInlineImage(thumb, url) {
|
||||
if(thumb.inlineIsSetUp) return;
|
||||
thumb.inlineIsSetUp = true;
|
||||
var img = thumb.querySelector("img.thumbnail");
|
||||
var expanded = false;
|
||||
var oldurl = img.src;
|
||||
thumb.onclick = function() {
|
||||
if (expanded) {
|
||||
img.setAttribute("class", "thumbnail");
|
||||
img.src = oldurl;
|
||||
expanded = false;
|
||||
} else {
|
||||
img.setAttribute("class", "expanded-thumbnail");
|
||||
img.src = url;
|
||||
expanded = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// set up image inlining for all applicable children in an element
|
||||
function setupInlineImageIn(element) {
|
||||
var thumbs = element.querySelectorAll("a.file");
|
||||
for ( var i = 0 ; i < thumbs.length ; i++ ) {
|
||||
var url = thumbs[i].href;
|
||||
if (filenameIsImage(url)) {
|
||||
// match
|
||||
console.log("matched url", url);
|
||||
setupInlineImage(thumbs[i], url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onready(function(){
|
||||
|
||||
// Setup Javascript events for document
|
||||
setupInlineImageIn(document);
|
||||
|
||||
|
||||
// Setup Javascript events via updatoer
|
||||
if (window.MutationObserver) {
|
||||
var observer = new MutationObserver(function(mutations) {
|
||||
for (var i = 0; i < mutations.length; i++) {
|
||||
var additions = mutations[i].addedNodes;
|
||||
if (additions == null) continue;
|
||||
for (var j = 0; j < additions.length; j++) {
|
||||
var node = additions[j];
|
||||
if (node.nodeType == 1) {
|
||||
setupInlineImageIn(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
observer.observe(document.body, {childList: true, subtree: true});
|
||||
}
|
||||
|
||||
});
|
||||
246
contrib/js/nntpchan/expand-video.js
Normal file
@@ -0,0 +1,246 @@
|
||||
/* This file is dedicated to the public domain; you may do as you wish with it. */
|
||||
/* Note: This code expects the global variable configRoot to be set. */
|
||||
var configRoot = "";
|
||||
|
||||
|
||||
if (typeof _ == 'undefined') {
|
||||
var _ = function(a) { return a; };
|
||||
}
|
||||
|
||||
function setupVideo(thumb, url) {
|
||||
if (thumb.videoAlreadySetUp) return;
|
||||
thumb.videoAlreadySetUp = true;
|
||||
|
||||
var video = null;
|
||||
var videoContainer, videoHide;
|
||||
var expanded = false;
|
||||
var hovering = false;
|
||||
//var loop = setting("videoloop");
|
||||
var loop = true;
|
||||
var loopControls = [document.createElement("span"), document.createElement("span")];
|
||||
var fileInfo = thumb.parentNode.querySelector(".fileinfo");
|
||||
var mouseDown = false;
|
||||
|
||||
function unexpand() {
|
||||
if (expanded) {
|
||||
expanded = false;
|
||||
if (video.pause) video.pause();
|
||||
videoContainer.style.display = "none";
|
||||
thumb.style.display = "inline";
|
||||
video.style.maxWidth = "inherit";
|
||||
video.style.maxHeight = "inherit";
|
||||
}
|
||||
}
|
||||
|
||||
function unhover() {
|
||||
if (hovering) {
|
||||
hovering = false;
|
||||
if (video.pause) video.pause();
|
||||
videoContainer.style.display = "none";
|
||||
video.style.maxWidth = "inherit";
|
||||
video.style.maxHeight = "inherit";
|
||||
}
|
||||
}
|
||||
|
||||
// Create video element if does not exist yet
|
||||
function getVideo() {
|
||||
if (video == null) {
|
||||
video = document.createElement("video");
|
||||
video.src = url;
|
||||
video.loop = loop;
|
||||
video.innerText = _("Your browser does not support HTML5 video.");
|
||||
|
||||
videoHide = document.createElement("img");
|
||||
videoHide.src = configRoot + "static/collapse.gif";
|
||||
videoHide.alt = "[ - ]";
|
||||
videoHide.title = "Collapse video";
|
||||
videoHide.style.marginLeft = "-15px";
|
||||
videoHide.style.cssFloat = "left";
|
||||
videoHide.addEventListener("click", unexpand, false);
|
||||
|
||||
videoContainer = document.createElement("div");
|
||||
videoContainer.style.paddingLeft = "15px";
|
||||
videoContainer.style.display = "none";
|
||||
videoContainer.appendChild(videoHide);
|
||||
videoContainer.appendChild(video);
|
||||
thumb.parentNode.insertBefore(videoContainer, thumb.nextSibling);
|
||||
|
||||
// Dragging to the left collapses the video
|
||||
video.addEventListener("mousedown", function(e) {
|
||||
if (e.button == 0) mouseDown = true;
|
||||
}, false);
|
||||
video.addEventListener("mouseup", function(e) {
|
||||
if (e.button == 0) mouseDown = false;
|
||||
}, false);
|
||||
video.addEventListener("mouseenter", function(e) {
|
||||
mouseDown = false;
|
||||
}, false);
|
||||
video.addEventListener("mouseout", function(e) {
|
||||
if (mouseDown && e.clientX - video.getBoundingClientRect().left <= 0) {
|
||||
unexpand();
|
||||
}
|
||||
mouseDown = false;
|
||||
}, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Clicking on thumbnail expands video
|
||||
thumb.addEventListener("click", function(e) {
|
||||
if (!e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey) {
|
||||
getVideo();
|
||||
expanded = true;
|
||||
hovering = false;
|
||||
|
||||
video.style.position = "static";
|
||||
video.style.pointerEvents = "inherit";
|
||||
video.style.display = "inline";
|
||||
videoHide.style.display = "inline";
|
||||
videoContainer.style.display = "block";
|
||||
videoContainer.style.position = "static";
|
||||
video.parentNode.parentNode.removeAttribute('style');
|
||||
thumb.style.display = "none";
|
||||
|
||||
//video.muted = (setting("videovolume") == 0);
|
||||
//video.volume = setting("videovolume");
|
||||
video.controls = true;
|
||||
if (video.readyState == 0) {
|
||||
video.addEventListener("loadedmetadata", expand2, false);
|
||||
} else {
|
||||
setTimeout(expand2, 0);
|
||||
}
|
||||
video.play();
|
||||
e.preventDefault();
|
||||
}
|
||||
}, false);
|
||||
|
||||
function expand2() {
|
||||
video.style.maxWidth = "100%";
|
||||
video.style.maxHeight = window.innerHeight + "px";
|
||||
var bottom = video.getBoundingClientRect().bottom;
|
||||
if (bottom > window.innerHeight) {
|
||||
window.scrollBy(0, bottom - window.innerHeight);
|
||||
}
|
||||
// work around Firefox volume control bug
|
||||
//video.volume = Math.max(setting("videovolume") - 0.001, 0);
|
||||
//video.volume = setting("videovolume");
|
||||
}
|
||||
|
||||
// Hovering over thumbnail displays video
|
||||
thumb.addEventListener("mouseover", function(e) {
|
||||
//if (setting("videohover")) {
|
||||
if (false) { // DOESN'T WORK YET
|
||||
getVideo();
|
||||
expanded = false;
|
||||
hovering = true;
|
||||
|
||||
var docRight = document.documentElement.getBoundingClientRect().right;
|
||||
var thumbRight = thumb.querySelector("img, video").getBoundingClientRect().right;
|
||||
var maxWidth = docRight - thumbRight - 20;
|
||||
if (maxWidth < 250) maxWidth = 250;
|
||||
|
||||
video.style.position = "fixed";
|
||||
video.style.right = "0px";
|
||||
video.style.top = "0px";
|
||||
var docRight = document.documentElement.getBoundingClientRect().right;
|
||||
var thumbRight = thumb.querySelector("img, video").getBoundingClientRect().right;
|
||||
video.style.maxWidth = maxWidth + "px";
|
||||
video.style.maxHeight = "100%";
|
||||
video.style.pointerEvents = "none";
|
||||
|
||||
video.style.display = "inline";
|
||||
videoHide.style.display = "none";
|
||||
videoContainer.style.display = "inline";
|
||||
videoContainer.style.position = "fixed";
|
||||
|
||||
//video.muted = (setting("videovolume") == 0);
|
||||
//video.volume = setting("videovolume");
|
||||
video.controls = false;
|
||||
video.play();
|
||||
}
|
||||
}, false);
|
||||
|
||||
thumb.addEventListener("mouseout", unhover, false);
|
||||
|
||||
// Scroll wheel on thumbnail adjusts default volume
|
||||
thumb.addEventListener("wheel", function(e) {
|
||||
//if (setting("videohover")) {
|
||||
if (true) {
|
||||
//var volume = setting("videovolume");
|
||||
if (e.deltaY > 0) volume -= 0.1;
|
||||
if (e.deltaY < 0) volume += 0.1;
|
||||
if (volume < 0) volume = 0;
|
||||
if (volume > 1) volume = 1;
|
||||
if (video != null) {
|
||||
video.muted = (volume == 0);
|
||||
video.volume = volume;
|
||||
}
|
||||
//changeSetting("videovolume", volume);
|
||||
e.preventDefault();
|
||||
}
|
||||
}, false);
|
||||
|
||||
// [play once] vs [loop] controls
|
||||
/*function setupLoopControl(i) {
|
||||
loopControls[i].addEventListener("click", function(e) {
|
||||
loop = (i != 0);
|
||||
thumb.href = thumb.href.replace(/([\?&])loop=\d+/, "$1loop=" + i);
|
||||
if (video != null) {
|
||||
video.loop = loop;
|
||||
if (loop && video.currentTime >= video.duration) {
|
||||
video.currentTime = 0;
|
||||
}
|
||||
}
|
||||
loopControls[i].style.fontWeight = "bold";
|
||||
loopControls[1-i].style.fontWeight = "inherit";
|
||||
}, false);
|
||||
}
|
||||
|
||||
loopControls[0].textContent = _("[play once]");
|
||||
loopControls[1].textContent = _("[loop]");
|
||||
loopControls[(setting("videoloop") ? 1 : 0)].style.fontWeight = "bold";
|
||||
for (var i = 0; i < 2; i++) {
|
||||
setupLoopControl(i);
|
||||
loopControls[i].style.whiteSpace = "nowrap";
|
||||
fileInfo.appendChild(document.createTextNode(" "));
|
||||
fileInfo.appendChild(loopControls[i]);
|
||||
}*/
|
||||
}
|
||||
|
||||
function setupVideosIn(element) {
|
||||
var thumbs = element.querySelectorAll("a.file");
|
||||
for (var i = 0; i < thumbs.length; i++) {
|
||||
if (/(\.webm)|(\.mp4)$/.test(thumbs[i].pathname)) {
|
||||
setupVideo(thumbs[i], thumbs[i].href);
|
||||
} else {
|
||||
var url = thumbs[i].href;
|
||||
if (/(\.webm)|(\.mp4)$/.test(url)) setupVideo(thumbs[i], url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onready(function(){
|
||||
// Insert menu from settings.js
|
||||
if (typeof settingsMenu != "undefined" && typeof Options == "undefined")
|
||||
document.body.insertBefore(settingsMenu, document.getElementsByTagName("hr")[0]);
|
||||
|
||||
// Setup Javascript events for videos in document now
|
||||
setupVideosIn(document);
|
||||
|
||||
// Setup Javascript events for videos added by updater
|
||||
if (window.MutationObserver) {
|
||||
var observer = new MutationObserver(function(mutations) {
|
||||
for (var i = 0; i < mutations.length; i++) {
|
||||
var additions = mutations[i].addedNodes;
|
||||
if (additions == null) continue;
|
||||
for (var j = 0; j < additions.length; j++) {
|
||||
var node = additions[j];
|
||||
if (node.nodeType == 1) {
|
||||
setupVideosIn(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
observer.observe(document.body, {childList: true, subtree: true});
|
||||
}
|
||||
});
|
||||
|
||||
206
contrib/js/nntpchan/hide-post.js
Normal file
@@ -0,0 +1,206 @@
|
||||
/** hidepost.js -- hides posts from page given $things */
|
||||
|
||||
|
||||
function get_hidden_posts() {
|
||||
var st = get_storage();
|
||||
var prefix = "nntpchan_hide_post_";
|
||||
return {
|
||||
all : function() {
|
||||
var msgids = [];
|
||||
for ( var k in st) {
|
||||
if (k.indexOf(prefix) == 0) {
|
||||
var m = k.substring(prefix.length);
|
||||
msgids.push(m);
|
||||
}
|
||||
}
|
||||
return msgids;
|
||||
},
|
||||
|
||||
add : function (msg) {
|
||||
st[prefix+msg] = "post";
|
||||
},
|
||||
|
||||
del : function (msg) {
|
||||
st.removeItem(prefix+msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// is a post elem an OP?
|
||||
function postIsOP(elem) {
|
||||
var ds = elem.dataset;
|
||||
return ds && ds.rootmsgid == ds.msgid ;
|
||||
}
|
||||
|
||||
function _hide_elem(elem, fade) {
|
||||
if(!fade) {
|
||||
if (elem.style) {
|
||||
elem.style.display = "none";
|
||||
} else {
|
||||
elem.style = {display: "none" };
|
||||
}
|
||||
elem.dataset.userhide = "yes";
|
||||
} else {
|
||||
$(elem).fadeOut(400, function() {
|
||||
_hide_elem(elem);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function _unhide_elem(elem) {
|
||||
$(elem).fadeIn();
|
||||
elem.dataset.userhide = "no";
|
||||
}
|
||||
|
||||
// return true if element is hidden
|
||||
function _elemIsHidden(elem) {
|
||||
return elem.dataset && elem.dataset.userhide == "yes";
|
||||
}
|
||||
|
||||
// hide a post
|
||||
function hidepost(elem, nofade) {
|
||||
console.log("hidepost("+elem.dataset.msgid+")");
|
||||
var posts = get_hidden_posts();
|
||||
if (posts) {
|
||||
// add to persitant hide
|
||||
posts.add(elem.dataset.msgidhash);
|
||||
}
|
||||
if(postIsOP(elem)) {
|
||||
// hide thread it's an OP
|
||||
var thread = document.getElementById("thread_"+elem.dataset.rootmsgidhash);
|
||||
if (thread) {
|
||||
var e = thread.getElementsByClassName("post");
|
||||
for ( var idx = 0; idx < e.length ; idx ++ ) {
|
||||
if (e[idx].dataset.msgid == elem.dataset.msgid) continue; // don't apply
|
||||
hidepost(e[idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// hide attachments and post body
|
||||
var es = elem.getElementsByClassName("attachments");
|
||||
for (var idx = 0; idx < es.length ; idx ++ ) {
|
||||
_hide_elem(es[idx], !nofade);
|
||||
}
|
||||
es = elem.getElementsByClassName("post_body");
|
||||
for (var idx = 0; idx < es.length ; idx ++ ) {
|
||||
_hide_elem(es[idx], !nofade);
|
||||
}
|
||||
es = elem.getElementsByClassName("postheader");
|
||||
for (var idx = 0; idx < es.length ; idx ++ ) {
|
||||
_hide_elem(es[idx], !nofade);
|
||||
}
|
||||
elem.dataset.userhide = "yes";
|
||||
elem.setHideLabel("[show]");
|
||||
}
|
||||
|
||||
// unhide a post
|
||||
function unhidepost(elem) {
|
||||
console.log("unhidepost("+elem.dataset.msgid+")");
|
||||
var posts = get_hidden_posts();
|
||||
if (posts) {
|
||||
// remove from persiting hide
|
||||
posts.del(elem.dataset.msgidhash);
|
||||
}
|
||||
if(postIsOP(elem)) {
|
||||
var thread = document.getElementById("thread_"+elem.dataset.rootmsgidhash);
|
||||
if(thread) {
|
||||
var e = thread.getElementsByClassName("post");
|
||||
for ( var idx = 0; idx < e.length ; idx ++ ) {
|
||||
if(e[idx].dataset.msgid == elem.dataset.msgid) continue;
|
||||
unhidepost(e[idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// unhide attachments and post body
|
||||
var es = elem.getElementsByClassName("attachments");
|
||||
for (var idx = 0; idx < es.length ; idx ++ ) {
|
||||
_unhide_elem(es[idx]);
|
||||
}
|
||||
es = elem.getElementsByClassName("post_body");
|
||||
for (var idx = 0; idx < es.length ; idx ++ ) {
|
||||
_unhide_elem(es[idx]);
|
||||
}
|
||||
es = elem.getElementsByClassName("postheader");
|
||||
for (var idx = 0; idx < es.length ; idx ++ ) {
|
||||
_unhide_elem(es[idx]);
|
||||
}
|
||||
|
||||
elem.dataset.userhide = "no";
|
||||
elem.setHideLabel("[hide]");
|
||||
}
|
||||
|
||||
// hide a post given a callback that checks each post
|
||||
function hideposts(check_func) {
|
||||
var es = document.getElementsByClassName("post");
|
||||
for ( var idx = 0; idx < es.length ; idx ++ ) {
|
||||
var elem = es[idx];
|
||||
if(check_func && elem && check_func(elem)) {
|
||||
hidepost(elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unhide all posts given callback
|
||||
// if callback is null unhide all
|
||||
function unhideall(check_func) {
|
||||
var es = document.getElementsByClassName("post");
|
||||
for (var idx=0 ; idx < es.length; idx ++ ) {
|
||||
var elem = es[idx];
|
||||
if(!check_func) { unhide(elem); }
|
||||
else if(check_func(elem)) { unhide(elem); }
|
||||
}
|
||||
}
|
||||
|
||||
// inject posthide into page
|
||||
onready(function() {
|
||||
var posts = document.getElementsByClassName("post");
|
||||
for (var idx = 0 ; idx < posts.length; idx++ ) {
|
||||
console.log("inject hide: "+posts[idx].dataset.msgid);
|
||||
var inject = function (elem) {
|
||||
var hider = document.createElement("a");
|
||||
hider.setAttribute("class", "hider");
|
||||
elem.setHideLabel = function (txt) {
|
||||
var e_hider = hider;
|
||||
e_hider.innerHTML = txt;
|
||||
}
|
||||
elem.hidepost = function() {
|
||||
var e_self = elem;
|
||||
var e_hider = hider;
|
||||
hidepost(e_self);
|
||||
}
|
||||
elem.unhidepost = function() {
|
||||
var e_self = elem;
|
||||
var e_hider = hider;
|
||||
unhidepost(e_self);
|
||||
}
|
||||
elem.isHiding = function() {
|
||||
var e_self = elem;
|
||||
return _elemIsHidden(e_self);
|
||||
}
|
||||
hider.appendChild(document.createTextNode("[hide]"));
|
||||
hider.onclick = function() {
|
||||
var e_self = elem;
|
||||
if(e_self.isHiding()) {
|
||||
e_self.unhidepost();
|
||||
} else {
|
||||
e_self.hidepost();
|
||||
}
|
||||
}
|
||||
elem.appendChild(hider);
|
||||
};
|
||||
inject(posts[idx]);
|
||||
}
|
||||
// apply persiting hidden posts
|
||||
var posts = get_hidden_posts();
|
||||
if(posts) {
|
||||
var all = posts.all();
|
||||
for ( var idx = 0 ; idx < all.length; idx ++ ) {
|
||||
var id = all[idx];
|
||||
var elem = document.getElementById(id);
|
||||
if(elem)
|
||||
hidepost(elem, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
1432
contrib/js/nntpchan/livechan.js
Normal file
10
contrib/js/nntpchan/local_storage.js
Normal file
@@ -0,0 +1,10 @@
|
||||
function get_storage() {
|
||||
var st = null;
|
||||
if (window.localStorage) {
|
||||
st = window.localStorage;
|
||||
} else if (localStorage) {
|
||||
st = localStorage;
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
65
contrib/js/nntpchan/old-livechan.js
Normal file
@@ -0,0 +1,65 @@
|
||||
function livechan_got_post(widget, j) {
|
||||
// do scroll
|
||||
while (widget.children.length > 5) {
|
||||
// remove top element
|
||||
widget.removeChild(widget.children[0]);
|
||||
}
|
||||
nntpchan_buildpost(widget, j);
|
||||
// scroll to bottom
|
||||
widget.scrollTop = widget.scrollHeight;
|
||||
}
|
||||
|
||||
// inject post form into an element
|
||||
function inject_postform(prefix, parent) {
|
||||
|
||||
}
|
||||
|
||||
// inject livechan widget into parent
|
||||
function inject_livechan_widget(prefix, parent) {
|
||||
if ( "WebSocket" in window ) {
|
||||
var url = "ws://"+document.location.host+prefix+"live";
|
||||
if ( document.location.protocol == "https:" ) {
|
||||
url = "wss://"+document.location.host+prefix+"live";
|
||||
}
|
||||
var socket = new WebSocket(url);
|
||||
var progress = function(str) {
|
||||
parent.innerHTML = "<pre>livechan: "+str+"</pre>";
|
||||
};
|
||||
progress("initialize");
|
||||
socket.onopen = function () {
|
||||
progress("streaming");
|
||||
}
|
||||
socket.onmessage = function(ev) {
|
||||
var j = null;
|
||||
try {
|
||||
j = JSON.parse(ev.data);
|
||||
} catch(e) {
|
||||
// ignore
|
||||
}
|
||||
if (j) {
|
||||
livechan_got_post(parent, j);
|
||||
}
|
||||
}
|
||||
socket.onclose = function(ev) {
|
||||
progress("connection closed");
|
||||
setTimeout(function() {
|
||||
inject_livechan_widget(prefix, parent);
|
||||
}, 1000);
|
||||
}
|
||||
} else {
|
||||
parent.innerHTML = "<pre>livechan mode requires websocket support</pre>";
|
||||
setTimeout(function() {
|
||||
parent.innerHTML = "";
|
||||
}, 5000);
|
||||
}
|
||||
}
|
||||
|
||||
function ukko_livechan(prefix) {
|
||||
var ukko = document.getElementById("ukko_threads");
|
||||
if (ukko) {
|
||||
// remove children
|
||||
ukko.innerHTML = "";
|
||||
inject_livechan_widget(prefix, ukko);
|
||||
}
|
||||
}
|
||||
|
||||
1
contrib/js/nntpchan/readme.md
Normal file
@@ -0,0 +1 @@
|
||||
main nntpchan javascript files
|
||||
426
contrib/js/nntpchan/reply.js
Normal file
@@ -0,0 +1,426 @@
|
||||
|
||||
function getReplyTo() {
|
||||
if(!document.dynreply) {
|
||||
var e = document.getElementById("postform_container");
|
||||
if (e) {
|
||||
// use existing postform
|
||||
document.dynreply = new DynReply(e);
|
||||
} else {
|
||||
// build a new postform
|
||||
document.dynreply = new DynReply();
|
||||
}
|
||||
e = document.dynreply.elem;
|
||||
e.style.position = "fixed";
|
||||
e.setAttribute("class", "shadow");
|
||||
}
|
||||
return document.dynreply;
|
||||
}
|
||||
|
||||
function table_insert_row(table, header, items) {
|
||||
var tr = document.createElement("tr");
|
||||
// insert header element
|
||||
var th = document.createElement("th");
|
||||
th.appendChild(header);
|
||||
tr.appendChild(th);
|
||||
// insert the rest of the elements
|
||||
for (var idx = 0; idx < items.length; idx ++ ) {
|
||||
var elem = document.createElement("td");
|
||||
elem.appendChild(items[idx]);
|
||||
tr.appendChild(elem);
|
||||
}
|
||||
table.appendChild(tr);
|
||||
}
|
||||
|
||||
/**
|
||||
build dynamic reply box
|
||||
*/
|
||||
function DynReply(existingElem) {
|
||||
if (existingElem) {
|
||||
// wrap existing post form
|
||||
// XXX: wrap it here
|
||||
this.elem = existingElem;
|
||||
this.form = this.elem.querySelector("form");
|
||||
this._error = document.getElementById("postform_msg");
|
||||
this.url = this.form.action + "?t=json";
|
||||
this.x = 1;
|
||||
this.y = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// build new post form
|
||||
|
||||
var elem = document.createElement("div");
|
||||
elem.setAttribute("id", "postform_container");
|
||||
this.elem = elem;
|
||||
// build post form
|
||||
this.form = document.createElement("form");
|
||||
this.form.enctype = "multipart/form-data";
|
||||
this.form.name = "post";
|
||||
this.form.method = "post";
|
||||
// reference
|
||||
elem = document.createElement("input");
|
||||
elem.setAttribute("id", "postform_reference");
|
||||
elem.name = "reference";
|
||||
elem.type = "hidden";
|
||||
this.form.appendChild(elem);
|
||||
|
||||
var table = document.createElement("table");
|
||||
table.setAttribute("class", "postform");
|
||||
var tbody = document.createElement("tbody");
|
||||
|
||||
var span = document.createElement("span");
|
||||
// name
|
||||
elem = document.createElement("input");
|
||||
elem.setAttribute("name", "name");
|
||||
elem.setAttribute("value", "Anonymous");
|
||||
elem.setAttribute("id", "postform_name");
|
||||
span.appendChild(elem);
|
||||
// error message
|
||||
var err_elem = document.createElement("span");
|
||||
err_elem.setAttribute("id", "postform_msg");
|
||||
span.appendChild(err_elem);
|
||||
this._error = err_elem;
|
||||
table_insert_row(tbody, document.createTextNode("Name"), [span])
|
||||
|
||||
// subject
|
||||
elem = document.createElement("input");
|
||||
elem.setAttribute("name", "subject");
|
||||
elem.setAttribute("value", "");
|
||||
elem.setAttribute("id", "postform_subject");
|
||||
// submit
|
||||
var submit = document.createElement("input");
|
||||
submit.setAttribute("value", "reply");
|
||||
submit.setAttribute("class", "button");
|
||||
submit.setAttribute("type", "submit");
|
||||
submit.setAttribute("id", "postform_submit");
|
||||
table_insert_row(tbody, document.createTextNode("Subject"), [elem, submit]);
|
||||
|
||||
|
||||
// Comment
|
||||
elem = document.createElement("textarea");
|
||||
elem.setAttribute("id", "postform_message");
|
||||
elem.setAttribute("name", "message");
|
||||
elem.setAttribute("cols", "40");
|
||||
elem.setAttribute("rows", "5");
|
||||
table_insert_row(tbody, document.createTextNode("Comment"), [elem]);
|
||||
|
||||
// file
|
||||
elem = document.createElement("input");
|
||||
elem.setAttribute("class", "postform_attachment");
|
||||
elem.setAttribute("id", "postform_attachments");
|
||||
elem.setAttribute("type", "file");
|
||||
elem.setAttribute("name", "attachment_uploaded");
|
||||
elem.setAttribute("multiple", "multiple");
|
||||
table_insert_row(tbody, document.createTextNode("Files"), [elem]);
|
||||
|
||||
// dubs
|
||||
elem = document.createElement("input");
|
||||
elem.setAttribute("type", "checkbox");
|
||||
elem.setAttribute("name", "dubs");
|
||||
table_insert_row(tbody, document.createTextNode("Get Dubs"), [elem]);
|
||||
|
||||
// captcha
|
||||
elem = document.createElement("img");
|
||||
elem.setAttribute("id", "captcha_img");
|
||||
elem.alt = "captcha";
|
||||
table_insert_row(tbody, document.createTextNode("Captcha"), [elem]);
|
||||
|
||||
// captcha solution
|
||||
elem = document.createElement("input");
|
||||
elem.name = "captcha";
|
||||
elem.autocomplete = "off";
|
||||
elem.setAttribute("id", "captcha_solution");
|
||||
table_insert_row(tbody, document.createTextNode("Solution"), [elem])
|
||||
|
||||
table.appendChild(tbody);
|
||||
this.form.appendChild(table);
|
||||
this.elem.appendChild(this.form);
|
||||
document.body.appendChild(this.elem);
|
||||
this.board = null;
|
||||
this.roothash = null;
|
||||
this.prefix = null;
|
||||
this.url = null;
|
||||
this.x = 1;
|
||||
this.y = 1;
|
||||
|
||||
}
|
||||
|
||||
DynReply.prototype.update = function() {
|
||||
if (this.prefix) {
|
||||
// update captcha
|
||||
this.updateCaptcha();
|
||||
if (this.board) {
|
||||
// update post form
|
||||
var ref = document.getElementById("postform_reference");
|
||||
|
||||
if (this.roothash) {
|
||||
ref.setAttribute("value", this.roothash);
|
||||
} else {
|
||||
ref.setAttribute("value", "");
|
||||
}
|
||||
this.url = this.prefix + "post/" + this.board + "?t=json";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DynReply.prototype.show = function() {
|
||||
console.log("show dynreply");
|
||||
this.update();
|
||||
this.elem.style.display = 'inline';
|
||||
}
|
||||
|
||||
DynReply.prototype.hide = function() {
|
||||
console.log("hide dynreply");
|
||||
this.elem.style.display = "none";
|
||||
}
|
||||
|
||||
// clear all fields
|
||||
DynReply.prototype.clear = function() {
|
||||
this.clearSolution();
|
||||
this.clearPostbox();
|
||||
}
|
||||
|
||||
|
||||
// clear captcha solution
|
||||
DynReply.prototype.clearSolution = function() {
|
||||
var e = document.getElementById("captcha_solution");
|
||||
// reset value
|
||||
e.value = "";
|
||||
}
|
||||
|
||||
// clear postform elements
|
||||
DynReply.prototype.clearPostbox = function() {
|
||||
var e = document.getElementById("postform_subject");
|
||||
e.value = "";
|
||||
e = document.getElementById("postform_message");
|
||||
e.value = "";
|
||||
e = document.getElementById("postform_attachments");
|
||||
e.value = null;
|
||||
}
|
||||
|
||||
DynReply.prototype.post = function(cb, err_cb) {
|
||||
if (this.url && this.form) {
|
||||
var data = new FormData(this.form);
|
||||
var ajax = new XMLHttpRequest();
|
||||
ajax.onreadystatechange = function(ev) {
|
||||
if (ajax.readyState == XMLHttpRequest.DONE) {
|
||||
var j = null;
|
||||
try {
|
||||
j = JSON.parse(ajax.responseText);
|
||||
cb(j);
|
||||
} catch (e) {
|
||||
if(err_cb) {
|
||||
err_cb(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ajax.open("POST", this.url);
|
||||
ajax.send(data);
|
||||
}
|
||||
}
|
||||
|
||||
DynReply.prototype.updateCaptcha = function() {
|
||||
if (this.prefix) {
|
||||
var captcha_img = document.getElementById("captcha_img");
|
||||
captcha_img.src = this.prefix + "captcha/img";
|
||||
}
|
||||
this.clearSolution();
|
||||
}
|
||||
|
||||
DynReply.prototype.setPrefix = function(prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
DynReply.prototype.hide = function() {
|
||||
this.elem.style.display = 'none';
|
||||
}
|
||||
|
||||
|
||||
DynReply.prototype.setBoard = function(boardname) {
|
||||
if (boardname) {
|
||||
this.board = boardname;
|
||||
}
|
||||
}
|
||||
|
||||
DynReply.prototype.setRoot = function(roothash) {
|
||||
if (roothash) {
|
||||
this.roothash = roothash;
|
||||
}
|
||||
}
|
||||
|
||||
DynReply.prototype.showError = function(msg) {
|
||||
console.log("error in dynreply: "+msg);
|
||||
this._error.setAttribute("class", "error message");
|
||||
this._error.appendChild(document.createTextNode(msg));
|
||||
this.updateCaptcha();
|
||||
}
|
||||
|
||||
DynReply.prototype.showMessage = function(msg) {
|
||||
this._error.setAttribute("class", "message");
|
||||
this._error.innerHTML = "";
|
||||
this._error.appendChild(document.createTextNode(msg));
|
||||
var e = this._error;
|
||||
setTimeout(function() {
|
||||
// clear it
|
||||
e.innerHTML = "";
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
|
||||
// reply box function
|
||||
function nntpchan_reply(parent, shorthash) {
|
||||
if (parent && document.dynreply) {
|
||||
var boardname = parent.getAttribute("boardname");
|
||||
var roothash = parent.getAttribute("root");
|
||||
var replyto = getReplyTo();
|
||||
// set target
|
||||
replyto.setBoard(boardname);
|
||||
replyto.setRoot(roothash);
|
||||
// show it
|
||||
replyto.show();
|
||||
}
|
||||
var elem = document.getElementById("postform_message");
|
||||
if ( elem )
|
||||
{
|
||||
elem.value += ">>" + shorthash.substr(0,10) + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// inject post hover behavior
|
||||
function inject_hover(prefix, el, parent) {
|
||||
if (!prefix) { throw "prefix is not defined"; }
|
||||
var linkhash = el.getAttribute("backlinkhash");
|
||||
if (!linkhash) { throw "linkhash undefined"; }
|
||||
console.log("rewrite linkhash "+linkhash);
|
||||
|
||||
var elem = document.createElement("span");
|
||||
elem.setAttribute("class", "backlink_rewritten");
|
||||
elem.appendChild(document.createTextNode(">>"+linkhash.substr(0,10)));
|
||||
if (!parent) {
|
||||
parent = el.parentNode;
|
||||
}
|
||||
parent.removeChild(el);
|
||||
parent.appendChild(elem);
|
||||
|
||||
elem.onclick = function(ev) {
|
||||
if(parent.backlink) {
|
||||
nntpchan_apicall(prefix+"api/find?hash="+linkhash, function(j) {
|
||||
var wrapper = document.createElement("div");
|
||||
wrapper.setAttribute("class", "hover "+linkhash);
|
||||
if (j == null) {
|
||||
// not found?
|
||||
wrapper.setAttribute("class", "hover notfound-hover "+linkhash);
|
||||
wrapper.appendChild(document.createTextNode("not found"));
|
||||
} else {
|
||||
// wrap backlink
|
||||
nntpchan_buildpost(wrapper, j);
|
||||
}
|
||||
parent.appendChild(wrapper);
|
||||
parent.backlink = false;
|
||||
}, function(msg) {
|
||||
var wrapper = document.createElement("div");
|
||||
wrapper.setAttribute("class", "hover "+linkhash);
|
||||
wrapper.appendChild(document.createTextNode(msg));
|
||||
parent.appendChild(wrapper);
|
||||
parent.backlink = false;
|
||||
});
|
||||
} else {
|
||||
var elems = document.getElementsByClassName(linkhash);
|
||||
if (!elems) throw "bad state, no backlinks open?";
|
||||
for (var idx = 0 ; idx < elems.length; idx ++ ) {
|
||||
elems[idx].parentNode.removeChild(elems[idx]);
|
||||
}
|
||||
parent.backlink = true;
|
||||
}
|
||||
};
|
||||
parent.backlink = true;
|
||||
}
|
||||
|
||||
// inject post hover for all backlinks in an element
|
||||
function inject_hover_for_element(elem) {
|
||||
var elems = elem.getElementsByClassName("backlink");
|
||||
var ls = [];
|
||||
var l = elems.length;
|
||||
for ( var idx = 0 ; idx < l ; idx ++ ) {
|
||||
var e = elems[idx];
|
||||
ls.push(e);
|
||||
}
|
||||
for( var elem in ls ) {
|
||||
inject_hover(prefix, ls[elem]);
|
||||
}
|
||||
}
|
||||
|
||||
function init(prefix) {
|
||||
// because no one cares about this feature :|
|
||||
return;
|
||||
// inject posthover ...
|
||||
inject_hover_for_element(document);
|
||||
if ( /\.html$/.test(document.location.pathname) && ! (/ukko/.test(document.location.pathname)) ) {
|
||||
// board / thread page
|
||||
console.log("not loading reply widget");
|
||||
} else {
|
||||
// ukko / livechan page
|
||||
var rpl = getReplyTo();
|
||||
rpl.setPrefix(prefix);
|
||||
// set livechan
|
||||
rpl.setBoard("overchan.random");
|
||||
rpl.update();
|
||||
rpl.updateCaptcha();
|
||||
|
||||
// position replyto widget
|
||||
var e = rpl.elem;
|
||||
var mouseDownX, mouseDownY;
|
||||
|
||||
var $dragging = null;
|
||||
|
||||
$(rpl.elem).on("mousemove", function(ev) {
|
||||
if ($dragging) {
|
||||
var x = ev.pageX - $(this).width() / 2,
|
||||
y = ev.pageY - $(this).height() / 2;
|
||||
$dragging.offset({
|
||||
top: y,
|
||||
left: x
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$(rpl.elem).on("mousedown", e, function (ev) {
|
||||
$dragging = $(rpl.elem);
|
||||
});
|
||||
|
||||
$(rpl.elem).on("mouseup", function (e) {
|
||||
$dragging = null;
|
||||
});
|
||||
|
||||
// add replyto post handlers
|
||||
e = document.getElementById("postform_submit");
|
||||
var postit = function() {
|
||||
var f = document.querySelector("form");
|
||||
// do ajax request to post data
|
||||
var r = getReplyTo();
|
||||
r.showMessage("posting... ");
|
||||
r.post(function(j) {
|
||||
if(j.error) {
|
||||
// an error happened
|
||||
r.showError(j.error);
|
||||
} else {
|
||||
// we're good
|
||||
r.showMessage("posted :^)");
|
||||
r.updateCaptcha();
|
||||
r.clear();
|
||||
}
|
||||
}, function(err) {
|
||||
r.showError(err);
|
||||
r.clearSolution();
|
||||
});
|
||||
}
|
||||
var f = document.querySelector("form");
|
||||
f.onsubmit = function() {
|
||||
postit();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
15
contrib/js/nntpchan/theme.js
Normal file
@@ -0,0 +1,15 @@
|
||||
function enable_theme(prefix, name) {
|
||||
if (prefix && name) {
|
||||
var theme = document.getElementById("current_theme");
|
||||
if (theme) {
|
||||
theme.href = prefix + "static/"+ name + ".css";
|
||||
var st = get_storage();
|
||||
st.nntpchan_prefix = prefix;
|
||||
st.nntpchan_theme = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// apply themes
|
||||
var st = get_storage();
|
||||
enable_theme(st.nntpchan_prefix, st.nntpchan_theme);
|
||||
66
contrib/js/nntpchan/unused/cuckoo_miner.js
Normal file
@@ -0,0 +1,66 @@
|
||||
var easiness = 55.0;
|
||||
var miner_threads = 4;
|
||||
var randoffs = 64;
|
||||
|
||||
/*
|
||||
onready(function(){
|
||||
document.getElementById("start_miner").onclick = function() {
|
||||
var btn = document.getElementById("start_miner");
|
||||
var label = btn.value;
|
||||
btn.value = "..."
|
||||
btn.disabled = true;
|
||||
|
||||
|
||||
var b = new Uint8Array(randoffs);
|
||||
window.crypto.getRandomValues(b);
|
||||
var b_cur = 0;
|
||||
var b_i = 0;
|
||||
var tmp = new Uint8Array(randoffs+b_i+1);
|
||||
tmp.set(b)
|
||||
tmp[b.length]=0
|
||||
b = tmp;
|
||||
|
||||
var workers = new Array(miner_threads);
|
||||
|
||||
var worker_cb = function(e) {
|
||||
if (e.data[0] == "ok") {
|
||||
miner_cb(e.data[1]);
|
||||
btn.value=label;
|
||||
btn.disabled = false;
|
||||
for (i=0; i<miner_threads; i++) {
|
||||
workers[i].terminate();
|
||||
}
|
||||
} else {
|
||||
if (b_cur >= 256) {
|
||||
var tmp = new Uint8Array(randoffs+b_i+1);
|
||||
tmp.set(b)
|
||||
tmp[b.length]=0
|
||||
b = tmp;
|
||||
b_i++;
|
||||
b_cur=0;
|
||||
}
|
||||
b[randoffs+b_i]=b_cur;
|
||||
b_cur++;
|
||||
var params = [b, easiness, e.data[2]];
|
||||
workers[e.data[2]].postMessage(params);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
for (i=0; i<miner_threads; i++) {
|
||||
b[randoffs+b_i]=b_cur;
|
||||
b_cur++;
|
||||
var params = [b, easiness, i];
|
||||
workers[i] = new Worker("./static/mineworker.js");
|
||||
workers[i].onmessage = worker_cb;
|
||||
workers[i].postMessage(params); // Start the worker.
|
||||
}
|
||||
b_cur=4;
|
||||
};
|
||||
});
|
||||
function miner_cb(s) {
|
||||
document.getElementById("miner_result").value = s;
|
||||
}
|
||||
*/
|
||||
|
||||
2
contrib/js/nntpchan/unused/readme.md
Normal file
@@ -0,0 +1,2 @@
|
||||
this directory holds unused javascript files for nntpchan
|
||||
don't delete files move them here
|
||||
2
contrib/js/readme.md
Normal file
@@ -0,0 +1,2 @@
|
||||
javascript files for nntpchan
|
||||
|
||||
3
contrib/static/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
nntpchan.js
|
||||
neochan.js
|
||||
neochan.css
|
||||
BIN
contrib/static/404.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
contrib/static/banner_0.jpg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
contrib/static/banner_1.jpg
Normal file
|
After Width: | Height: | Size: 45 KiB |
BIN
contrib/static/banner_2.jpg
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
contrib/static/banner_3.jpg
Normal file
|
After Width: | Height: | Size: 62 KiB |
BIN
contrib/static/banner_4.jpg
Normal file
|
After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 550 B After Width: | Height: | Size: 135 B |
112
contrib/static/bloodgod.css
Normal file
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
bloodgod theme css override
|
||||
*/
|
||||
|
||||
body {
|
||||
color: #666;
|
||||
background: #111;
|
||||
}
|
||||
|
||||
.post_body > pre {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
input, textarea, button, input[type="text"], input[type="password"],
|
||||
input[type="checkbox"], input[type="file"], input[type="submit"],
|
||||
input[type="button"] {
|
||||
color: #666;
|
||||
background: #050505;
|
||||
border-color: #D80000;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
background: #980000;
|
||||
color: black;
|
||||
}
|
||||
|
||||
#captcha_img {
|
||||
background: #D80000;
|
||||
}
|
||||
|
||||
.reply, .ukko_thread_header {
|
||||
border-color: #0c0c0c;
|
||||
}
|
||||
|
||||
.ukko_thread_header {
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
|
||||
hr, .name {
|
||||
color: #6B1919;
|
||||
}
|
||||
|
||||
hr {
|
||||
height: 0px;
|
||||
border-width: 1px medium medium;
|
||||
border-color: #0C0C0C;
|
||||
border-style: solid none none;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.subject {
|
||||
color: #4E0000;
|
||||
}
|
||||
|
||||
.reply , .ukko_thread_header {
|
||||
background: #0C0C0C;
|
||||
}
|
||||
|
||||
.op {
|
||||
background-color: #1a1a1a;
|
||||
border-style: hidden;
|
||||
}
|
||||
|
||||
.pagelist {
|
||||
background: #0c0c0c;
|
||||
border-style: hidden;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #500707;
|
||||
}
|
||||
|
||||
.post:target {
|
||||
background-color: #1a1a1a;
|
||||
}
|
||||
|
||||
.postno, .postnol {
|
||||
color: #B70000;
|
||||
}
|
||||
|
||||
.postform >tr, th {
|
||||
background: #6B1919;
|
||||
}
|
||||
|
||||
#postform_container {
|
||||
background-color: #111;
|
||||
}
|
||||
table tbody tr:nth-of-type( even ) {
|
||||
background-color: #430000;
|
||||
}
|
||||
|
||||
table thead th {
|
||||
color: #6B1919;
|
||||
background: #430000;
|
||||
border-color: #270000;
|
||||
}
|
||||
|
||||
.navbar-sep {
|
||||
color: #270000;
|
||||
}
|
||||
|
||||
.navbar-link > label:hover {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.origin > img , .not_found > img {
|
||||
-webkit-filter: invert(1);
|
||||
filter: invert(1);
|
||||
}
|
||||
52
contrib/static/chen-chan-faq.html
Normal file
@@ -0,0 +1,52 @@
|
||||
<!doctype html><html><head><link rel="stylesheet" href="/static/chen-chan.css"><title>nntpchan faq</title></head><body>
|
||||
<audio loop controls><source src="/static/about.mp3" type="audio/mpeg">[can't play audio.]</audio>
|
||||
<p>nntpchan faq</p>
|
||||
<dl>
|
||||
<dt>What is nntpchan?</dt>
|
||||
<dd>NNTPCchan is a federated imageboard that spans across several networks including tor, i2p and anonet. There are no central servers so that as long as 1 server is left the forum will continue to function.</dd>
|
||||
<br>
|
||||
<dt>How is this different from *chan?</dt>
|
||||
<dd>NNTPChan is by design invulnerable to global censorship. All moderation is local to each server.</dd>
|
||||
<br>
|
||||
<dt>How does moderation work then?</dt>
|
||||
<dd>Moderation is done with our special tripcodes (ed25519-sha512 signed posts). Anyone can give moderation suggestions, but that doesn't mean anyone will accept them. Those who trust the actions of a moderator can have their frontend whitelist the moderation actions and have them performed without oversight by another moderator.</dd>
|
||||
<br>
|
||||
<dt>How can I remove content from nntpchan completely?</dt>
|
||||
<dd>‾\(._.)/‾ I don't know. You probably can't unless every server agrees to remove the content, even then, nothing prevents someone from reposting it. You can't delete what you post on the internet.</dd>
|
||||
<br>
|
||||
<dt>do you allow child porn?</dt>
|
||||
<dd>no.</dd>
|
||||
<br>
|
||||
<dt>Do you allow XYZ content?</dt>
|
||||
<dd>If it violates USA Law or causes problems with my host, no. Otherwise, probably.</dd>
|
||||
<br>
|
||||
<dt>Someone posted something I don't like but it's not illegal</dt>
|
||||
<dd>That is not my problem. All posts on this site are the responsibility of the individual poster and not the administration of this server</dd>
|
||||
<br>
|
||||
<dt>code, bugs, feature requests</dt>
|
||||
<dd><a href="https://github.com/majestrate/nntpchan/">frontend</a> <a href="https://github.com/majestrate/srndv2/">core</a></dd>
|
||||
<br></dl>
|
||||
<p>Please send any gripes/questions/inqueries/suggestions/complaints to ampernand [|at\] gmail {dot} com with subject starting with "nntpchan question"</p>
|
||||
<hr>
|
||||
<p>ucavviu7wl6azuw7.onion frontend specific</p>
|
||||
<dl>
|
||||
<dt>admin's pubkey</dt>
|
||||
<dd>06833a90237c61f59558c1726fbe71c63e972722b2cf1147867be286cb020b32<br>
|
||||
▆☃►☐▣◼◡♵☕◘♁◲◯☾◱♆▾☗▧▢☲♏░◇☆◻♢☆♋▂▋▲</dd>
|
||||
<br>
|
||||
<dt>peering</dt>
|
||||
<dd>just open a thread for now.</dd>
|
||||
<br>
|
||||
<dt>rules</dt>
|
||||
<dd>basically no stuff that will fuck with the functioning of the site.<br>
|
||||
- stuff that will get me in trouble like cp.<br>
|
||||
- flood/spam. duplicate posts may also get baleeted.
|
||||
</dd>
|
||||
<br>
|
||||
<dt>guidelines and things to keep in mind</dt>
|
||||
<dd>
|
||||
- i don't owe you shiieet. you don't owe me shieet.<br>
|
||||
- administration style: benevolent dictatorship.
|
||||
</dd>
|
||||
</dl>
|
||||
</body></html>
|
||||
7
contrib/static/chen-chan.css
Normal file
@@ -0,0 +1,7 @@
|
||||
body{font-family:monospace}
|
||||
dl{max-width:84ch}
|
||||
dd{margin-left:4ch;overflow:auto}
|
||||
.memearrows{color:green}
|
||||
pre{margin: 0 0 0 0}
|
||||
table,th,td{border:1px solid gray}
|
||||
table {border-collapse:collapse}
|
||||
BIN
contrib/static/collapse.gif
Normal file
|
After Width: | Height: | Size: 60 B |
38
contrib/static/dayman.css
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
dayman
|
||||
fighter of the night man
|
||||
champion of the sun
|
||||
*/
|
||||
|
||||
body {
|
||||
background-color: #FFEFC9;
|
||||
background-repeat: no-repeat;
|
||||
background-attachment: fixed;
|
||||
background-size: 100% 100%;
|
||||
background-image: url('maymface.png');
|
||||
}
|
||||
|
||||
.reply, .ukko_thread_header, th, .postform > tr , tbody > tr:nth-of-type( even ) {
|
||||
background: #FBFFC9;
|
||||
}
|
||||
|
||||
#postform_container {
|
||||
background-color: rgba(0,0,0,0);
|
||||
}
|
||||
|
||||
.post:target {
|
||||
background-color: #ffda9b;
|
||||
box-shadow: 0px 0px 5px 1px;
|
||||
}
|
||||
|
||||
img#nntpchan_banner {
|
||||
box-shadow: 0px 0px 10px 0px #FFECBE;
|
||||
}
|
||||
|
||||
#postform_inner {
|
||||
box-shadow: 0px 1px 5px 1px;
|
||||
}
|
||||
|
||||
.navbar, table, thead, th, table, pre, .op {
|
||||
background: #FFECBE;
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
<!DOCTYPE html5>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="site.css" />
|
||||
<title> NNTPChan Frequently Asked Questions </title>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<h2>NNTPChan faq </h2>
|
||||
@@ -47,14 +49,6 @@
|
||||
<div><a href="https://github.com/majestrate/nntpchan/issues">github</a></div>
|
||||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
<div>Please send any gripes/questions/inqueries/suggestions/complaints to ampernand [|at\] gmail {dot} com with subject starting with "nntpchan question" </div>
|
||||
</p>
|
||||
<hr />
|
||||
</div>
|
||||
<audio autoplay="autoplay" loop="loop">
|
||||
<source src="about.mp3" type="audio/mpeg">
|
||||
<embed src="about.mp3">
|
||||
</audio>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
107
contrib/static/feed.js
Normal file
@@ -0,0 +1,107 @@
|
||||
|
||||
function createConnectionElement(j) {
|
||||
var e = document.createElement("div");
|
||||
e.setAttribute("class", "connection");
|
||||
var auth = document.createElement("div");
|
||||
auth.appendChild(document.createTextNode("Connection: "+j.name));
|
||||
// authentication state
|
||||
if (j.authed) {
|
||||
auth.setAttribute("class", "authed");
|
||||
auth.appendChild(document.createTextNode("(authenticated)"));
|
||||
} else {
|
||||
auth.appendChild(document.createTextNode("(not authenticated)"));
|
||||
}
|
||||
e.appendChild(auth);
|
||||
|
||||
// connection mode
|
||||
var mode = document.createElement("div");
|
||||
mode.setAttribute("class", "mode");
|
||||
mode.appendChild(document.createTextNode("mode: "+j.mode));
|
||||
e.appendChild(mode);
|
||||
|
||||
var pending = document.createElement("div");
|
||||
pending.setAttribute("class", "pending");
|
||||
// pending articles
|
||||
var articles = Object.keys(j.pending);
|
||||
pending.appendChild(document.createTextNode("pending articles: "+articles.length));
|
||||
for ( var idx = 0 ; idx < articles.length; idx ++ ) {
|
||||
var msgid = articles[idx];
|
||||
var state = j.pending[msgid];
|
||||
var elem = document.createElement("div");
|
||||
elem.appendChild(document.createTextNode(msgid + ": " + state));
|
||||
elem.setAttribute("class", "pending_item "+state);
|
||||
pending.appendChild(elem);
|
||||
}
|
||||
e.appendChild(pending);
|
||||
// e.appendChild(document.createTextNode(JSON.stringify(j)));
|
||||
return e;
|
||||
}
|
||||
|
||||
function inject_nntp_feed_element(feed, elem) {
|
||||
elem.appendChild(document.createElement("hr"));
|
||||
var name = document.createElement("div");
|
||||
name.setAttribute("class", "feeds_name");
|
||||
name_elem = document.createTextNode("Name: "+feed.State.Config.Name);
|
||||
name.appendChild(name_elem);
|
||||
elem.appendChild(name);
|
||||
var conns = document.createElement("div");
|
||||
conns.setAttribute("class", "connections");
|
||||
for ( var idx = 0 ; idx < feed.Conns.length; idx ++ ) {
|
||||
conns.appendChild(createConnectionElement(feed.Conns[idx]));
|
||||
}
|
||||
elem.appendChild(conns);
|
||||
}
|
||||
|
||||
function update_nntpchan_feed_ticker(elem, result_elem) {
|
||||
nntpchan_admin("feed.list", null, function(j) {
|
||||
if (j) {
|
||||
if (j.error) {
|
||||
console.log("nntpchan_feed_ticker: error, "+j.error);
|
||||
} else {
|
||||
// remove all children
|
||||
while(elem.children.length) {
|
||||
elem.children[0].remove();
|
||||
}
|
||||
var result = j.result;
|
||||
for (var idx = 0; idx < result.length; idx++) {
|
||||
var item = result[idx];
|
||||
var entry = document.createElement("div");
|
||||
inject_nntp_feed_element(item, entry);
|
||||
elem.appendChild(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, result_elem);
|
||||
}
|
||||
|
||||
|
||||
function nntp_feed_add() {
|
||||
var param = {};
|
||||
|
||||
var e = document.getElementById("add_feed_name");
|
||||
param.name = e.value;
|
||||
e = document.getElementById("add_feed_host");
|
||||
param.host = e.value;
|
||||
e = document.getElementById("add_feed_port");
|
||||
param.port = parseInt(e.value);
|
||||
|
||||
e = document.getElementById("nntpchan_feed_result");
|
||||
nntpchan_admin("feed.add", param, null, e);
|
||||
}
|
||||
|
||||
function nntp_feed_del() {
|
||||
var e = document.getElementById("del_feed_name");
|
||||
var name = e.value;
|
||||
e = document.getElementById("nntpchan_feed_result");
|
||||
nntpchan_admin("feed.del", {name: name}, null, e);
|
||||
}
|
||||
|
||||
function nntp_feed_update() {
|
||||
var e = document.getElementById("nntpchan_feeds");
|
||||
if (e) {
|
||||
setInterval(function(){
|
||||
var e1 = document.getElementById("nntpchan_feed_result");
|
||||
update_nntpchan_feed_ticker(e, e1);
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.6 KiB |
249
contrib/static/livechan.css
Normal file
@@ -0,0 +1,249 @@
|
||||
input {
|
||||
-moz-border-radius: 0px;
|
||||
-webkit-border-radius: 0px;
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
.livechan_captcha_input {
|
||||
color: black;
|
||||
}
|
||||
|
||||
textarea, select {
|
||||
-moz-border-radius: 0px;
|
||||
-webkit-border-radius: 0px;
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
|
||||
.livechan_chat_input {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: #d6daf0;
|
||||
}
|
||||
|
||||
.livechan_chat_input_name, .livechan_chat_input_convo {
|
||||
padding: 0;
|
||||
padding-left: none;
|
||||
margin: 0;
|
||||
width: 80%;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.livechan_chat_input_left {
|
||||
width: 19%;
|
||||
}
|
||||
|
||||
.livechan_chat_input_message_div {
|
||||
padding:0;
|
||||
margin:0;
|
||||
position: absolute;
|
||||
width: 70%;
|
||||
left: 20%;
|
||||
top: 3px;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.livechan_chat_input_message {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border:none;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.livechan_chat_input_submit {
|
||||
position: absolute;
|
||||
width: 8%;
|
||||
top: 3px;
|
||||
right: 1px;
|
||||
bottom: 0;
|
||||
border: none;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.livechan_chat_output {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 60px;
|
||||
overflow: auto;
|
||||
width: 89%;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.livechan_chat_output_chat {
|
||||
max-height: 200px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.livechan_chat_output_date {
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
.livechan_chat_output_count:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.livechan_chat_capcode {
|
||||
margin: 0 4px;
|
||||
font-style: italic;
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
.livechan_image_thumb {
|
||||
max-width: 300px;
|
||||
max-height: 200px;
|
||||
float: left;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.livechan_captcha {
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
right: 0px;
|
||||
position: fixed;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.livechan_captcha_inner {
|
||||
padding: 200px;
|
||||
}
|
||||
|
||||
.livechan_captcha_image {
|
||||
}
|
||||
|
||||
.livechan_captcha_input {
|
||||
float: down;
|
||||
}
|
||||
|
||||
.livechan_spoiler {
|
||||
color: black;
|
||||
background: black;
|
||||
}
|
||||
|
||||
.livechan_chat_output_chat {
|
||||
background: #d6daf0;
|
||||
}
|
||||
|
||||
.livechan_spoiler:hover {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.livechan_convo_label {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.livechan_convobar_root {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 0;
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
.livechan_convobar_item {
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
background: #d6daf0;
|
||||
}
|
||||
|
||||
.livechan_navbar {
|
||||
z-index: 3;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.livechan_navbar_mod_indicator_inactive, .livechan_navbar_mod_indicator_active, .livechan_navbar_status, .livechan_navbar_channel_label {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
background: #d6daf0;
|
||||
}
|
||||
|
||||
|
||||
.hover {
|
||||
position: relative;
|
||||
padding: 1px;
|
||||
left: -1000px
|
||||
border: 1px dashed black;
|
||||
visibility: hidden;
|
||||
}
|
||||
.hover > img {
|
||||
position: fixed;
|
||||
top: 0%;
|
||||
right: 0;
|
||||
max-width: 75%;
|
||||
max-height: 75%;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.livechan_captcha, .livechan_convobar_root, #chat {
|
||||
background: #EEF2FF;
|
||||
}
|
||||
|
||||
.livechan_chat_output_chat {
|
||||
font-family: monospace;
|
||||
margin: 4px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.livechan_chat_output_name {
|
||||
font-weight: bold;
|
||||
color: green;
|
||||
}
|
||||
|
||||
.livechan_chat_output_count:hover {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.livechan_greentext {
|
||||
color: #789922;
|
||||
}
|
||||
|
||||
.livechan_boldtext {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.livechan_internallink , a {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.livechan_internallink:hover , a {
|
||||
color: red;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.livechan_chat_selected {
|
||||
background: blue;
|
||||
}
|
||||
|
||||
|
||||
.livechan_navbar_mod_indicator_active {
|
||||
background: #4a4ad4;
|
||||
color: #34d434;
|
||||
}
|
||||
|
||||
.livechan_navbar_mod_indicator_admin {
|
||||
background: #4a4ad4;
|
||||
color: red;
|
||||
}
|
||||
|
||||
.livechan_navbar_mod_indicator_inactive {
|
||||
color: #aaaaaa;
|
||||
background: #EEF2FF;
|
||||
}
|
||||
|
||||
|
||||
.livechan_redtext {
|
||||
color: #af0a0f;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
BIN
contrib/static/maymface.png
Normal file
|
After Width: | Height: | Size: 84 KiB |
8
contrib/static/mineworker.js
Normal file
@@ -0,0 +1,8 @@
|
||||
importScripts('./siphash-lib.js');
|
||||
importScripts('./miner-js.js');
|
||||
|
||||
onmessage = function(e) {
|
||||
var s = cuckoo["mine_cuckoo"](e.data[0], e.data[1]);
|
||||
s.push(e.data[2]);
|
||||
postMessage(s);
|
||||
}
|
||||
@@ -64,28 +64,51 @@ function nntpchan_key_add() {
|
||||
});
|
||||
}
|
||||
|
||||
function get_nntp_username() {
|
||||
var e = document.getElementById("nntpchan_nntp_username");
|
||||
return e.value;
|
||||
}
|
||||
|
||||
function get_nntp_passwd() {
|
||||
var e = document.getElementById("nntpchan_nntp_passwd");
|
||||
return e.value;
|
||||
}
|
||||
|
||||
function nntpchan_admin_nntp(method) {
|
||||
nntpchan_admin(method, {
|
||||
username: get_nntp_username(),
|
||||
passwd: get_nntp_passwd()
|
||||
})
|
||||
}
|
||||
|
||||
function nntpchan_admin_board(method) {
|
||||
nntpchan_admin(method, {
|
||||
newsgroup: get_board_target()
|
||||
})
|
||||
}
|
||||
|
||||
function nntpchan_admin(method, param) {
|
||||
nntpchan_mod({
|
||||
name:"admin",
|
||||
parser: function(target) {
|
||||
return method;
|
||||
},
|
||||
handle: function(j) {
|
||||
function nntpchan_admin(method, param, handler_cb, result_elem) {
|
||||
if (handler_cb) {
|
||||
// we got a handler already set
|
||||
} else {
|
||||
// no handler set
|
||||
var handler_cb = function(j) {
|
||||
if (j.result) {
|
||||
return document.createTextNode(j.result);
|
||||
} else {
|
||||
return "nothing happened?";
|
||||
}
|
||||
}
|
||||
}
|
||||
nntpchan_mod({
|
||||
name:"admin",
|
||||
parser: function(target) {
|
||||
return method;
|
||||
},
|
||||
handle: handler_cb,
|
||||
method: ( param && "POST" ) || "GET",
|
||||
data: param
|
||||
})
|
||||
}, result_elem)
|
||||
}
|
||||
|
||||
|
||||
@@ -119,70 +142,83 @@ function nntpchan_delete() {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function nntpchan_mod(mod_action) {
|
||||
|
||||
function nntpchan_mod(mod_action, result_elem) {
|
||||
|
||||
// get the element
|
||||
var input = document.getElementById("nntpchan_mod_target");
|
||||
var target = input.value;
|
||||
var target = null;
|
||||
if (input) {
|
||||
target = input.value;
|
||||
}
|
||||
if (mod_action.parser) {
|
||||
target = mod_action.parser(target);
|
||||
}
|
||||
|
||||
var elem = document.getElementById("nntpchan_mod_result");
|
||||
var elem;
|
||||
if (result_elem) {
|
||||
elem = result_elem;
|
||||
} else {
|
||||
elem = document.getElementById("nntpchan_mod_result");
|
||||
}
|
||||
|
||||
// clear old results
|
||||
while( elem.firstChild ) {
|
||||
elem.removeChild(elem.firstChild);
|
||||
}
|
||||
|
||||
|
||||
// fire off ajax
|
||||
var ajax = new XMLHttpRequest();
|
||||
ajax.onreadystatechange = function() {
|
||||
if (ajax.readyState == XMLHttpRequest.DONE) {
|
||||
var status = ajax.status;
|
||||
// we gud?
|
||||
if (status == 200) {
|
||||
// yah
|
||||
var txt = ajax.responseText;
|
||||
var j = JSON.parse(txt);
|
||||
if (j.error) {
|
||||
var e = document.createTextNode(j.error);
|
||||
elem.appendChild(e);
|
||||
} else {
|
||||
if (mod_action.handle) {
|
||||
var result = mod_action.handle(j);
|
||||
if (result) {
|
||||
elem.appendChild(result);
|
||||
var csrf_ajax = new XMLHttpRequest();
|
||||
csrf_ajax.onreadystatechange = function() {
|
||||
if (csrf_ajax.readyState == XMLHttpRequest.DONE) {
|
||||
// get csrf token
|
||||
var csrf = csrf_ajax.getResponseHeader("X-CSRF-Token");
|
||||
// fire off ajax
|
||||
var ajax = new XMLHttpRequest();
|
||||
ajax.onreadystatechange = function() {
|
||||
if (ajax.readyState == XMLHttpRequest.DONE) {
|
||||
var status = ajax.status;
|
||||
// we gud?
|
||||
if (status == 200) {
|
||||
// yah
|
||||
var txt = ajax.responseText;
|
||||
var j = JSON.parse(txt);
|
||||
if (j.error) {
|
||||
var e = document.createTextNode(j.error);
|
||||
elem.appendChild(e);
|
||||
} else {
|
||||
// fail
|
||||
alert("mod action failed, handler returned nothing");
|
||||
if (mod_action.handle) {
|
||||
var result = mod_action.handle(j);
|
||||
if (result) {
|
||||
elem.appendChild(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// fail
|
||||
alert("mod action has no handler");
|
||||
} else if (status) {
|
||||
// nah
|
||||
// http error
|
||||
elem.innerHTML = "error: HTTP "+status;
|
||||
}
|
||||
// clear input
|
||||
if (input) {
|
||||
input.value = "";
|
||||
}
|
||||
}
|
||||
} else if (status) {
|
||||
// nah
|
||||
// http error
|
||||
elem.innerHTML = "error: HTTP "+status;
|
||||
}
|
||||
// clear input
|
||||
input.value = "";
|
||||
if (mod_action.name) {
|
||||
|
||||
var url = mod_action.name + "/" + target;
|
||||
ajax.open(mod_action.method || "GET", url);
|
||||
ajax.setRequestHeader("X-CSRF-Token", csrf);
|
||||
var data = mod_action.data;
|
||||
if (data) {
|
||||
ajax.setRequestHeader("Content-type","text/json");
|
||||
ajax.send(JSON.stringify(data));
|
||||
} else {
|
||||
ajax.send();
|
||||
}
|
||||
} else {
|
||||
alert("mod action has no name");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mod_action.name) {
|
||||
var url = mod_action.name + "/" + target;
|
||||
ajax.open(mod_action.method || "GET", url);
|
||||
var data = mod_action.data;
|
||||
if (data) {
|
||||
ajax.setRequestHeader("Content-type","text/json");
|
||||
ajax.send(JSON.stringify(data));
|
||||
} else {
|
||||
ajax.send();
|
||||
}
|
||||
} else {
|
||||
alert("mod action has no name");
|
||||
}
|
||||
csrf_ajax.open("GET", "");
|
||||
csrf_ajax.send();
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
//
|
||||
// nntpchan.js -- frontend ui niceness
|
||||
//
|
||||
|
||||
|
||||
// insert a backlink for a post given its short hash
|
||||
function nntpchan_backlink(shorthash)
|
||||
{
|
||||
var elem = document.getElementById("postform_message");
|
||||
if ( elem )
|
||||
{
|
||||
elem.value += ">>" + shorthash.substr(0,10) + "\n";
|
||||
}
|
||||
}
|
||||
BIN
contrib/static/placeholder.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
94
contrib/static/siphash-lib.js
Normal file
@@ -0,0 +1,94 @@
|
||||
var SipHash = (function() {
|
||||
function u8to64(p , i) {
|
||||
return { l: (p[i] | p[i+1]<<8 | p[i+2]<<16 | p[i+3]<<24) , h: (p[i+4] | p[i+5]<<8 | p[i+6]<<16 | p[i+7]<<24) };
|
||||
}
|
||||
|
||||
|
||||
function _add(a, b) {
|
||||
var rl = a.l + b.l,
|
||||
a2 = { h: a.h + b.h + (rl / 2 >>> 31) >>> 0,
|
||||
l: rl >>> 0 };
|
||||
a.h = a2.h; a.l = a2.l;
|
||||
}
|
||||
|
||||
function _xor(a, b) {
|
||||
a.h ^= b.h; a.h >>>= 0;
|
||||
a.l ^= b.l; a.l >>>= 0;
|
||||
}
|
||||
|
||||
function _rotl(a, n) {
|
||||
var a2 = {
|
||||
h: a.h << n | a.l >>> (32 - n),
|
||||
l: a.l << n | a.h >>> (32 - n)
|
||||
};
|
||||
a.h = a2.h; a.l = a2.l;
|
||||
}
|
||||
|
||||
function _rotl32(a) {
|
||||
var al = a.l;
|
||||
a.l = a.h; a.h = al;
|
||||
}
|
||||
|
||||
function _compress(v0, v1, v2, v3) {
|
||||
_add(v0, v1);
|
||||
_add(v2, v3);
|
||||
_rotl(v1, 13);
|
||||
_rotl(v3, 16);
|
||||
_xor(v1, v0);
|
||||
_xor(v3, v2);
|
||||
_rotl32(v0);
|
||||
_add(v2, v1);
|
||||
_add(v0, v3);
|
||||
_rotl(v1, 17);
|
||||
_rotl(v3, 21);
|
||||
_xor(v1, v2);
|
||||
_xor(v3, v0);
|
||||
_rotl32(v2);
|
||||
}
|
||||
|
||||
|
||||
function hash(v0h, v0l, v1h, v1l, v2h, v2l, v3h, v3l, mh, ml) {
|
||||
var mi = { h: mh, l: ml };
|
||||
|
||||
var v0 = { h: v0h, l: v0l };
|
||||
var v1 = { h: v1h, l: v1l };
|
||||
var v2 = { h: v2h, l: v2l };
|
||||
var v3 = { h: v3h, l: v3l };
|
||||
|
||||
/*var k0 = u8to64(key, 0);
|
||||
var k1 = u8to64(key, 8);
|
||||
|
||||
var v0 = { h: k0.h, l: k0.l }, v2 = k0;
|
||||
var v1 = { h: k1.h, l: k1.l }, v3 = k1;
|
||||
|
||||
_xor(v0, { h: 0x736f6d65, l: 0x70736575 });
|
||||
_xor(v1, { h: 0x646f7261, l: 0x6e646f6d });
|
||||
_xor(v2, { h: 0x6c796765, l: 0x6e657261 });
|
||||
_xor(v3, { h: 0x74656462, l: 0x79746573 });*/
|
||||
|
||||
_xor(v3, mi);
|
||||
_compress(v0, v1, v2, v3);
|
||||
_compress(v0, v1, v2, v3);
|
||||
_xor(v0, mi);
|
||||
_xor(v2, { h: 0, l: 0xff });
|
||||
_compress(v0, v1, v2, v3);
|
||||
_compress(v0, v1, v2, v3);
|
||||
_compress(v0, v1, v2, v3);
|
||||
_compress(v0, v1, v2, v3);
|
||||
|
||||
var h = v0;
|
||||
_xor(h, v1);
|
||||
_xor(h, v2);
|
||||
_xor(h, v3);
|
||||
|
||||
var res = new Uint32Array(2);
|
||||
res[0]=h.h; res[1]=h.l;
|
||||
return res;
|
||||
};
|
||||
|
||||
return {
|
||||
hash: hash,
|
||||
};
|
||||
})();
|
||||
|
||||
var module = module || { }, exports = module.exports = SipHash;
|
||||
@@ -1,10 +1,58 @@
|
||||
body {
|
||||
background: #EEF2FF url('bg.png') repeat-x 50% 0%;
|
||||
color: black;
|
||||
font-family: arial,helvetica,sans-serif;
|
||||
font-size: 10pt;
|
||||
margin: 0 4px;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
.frontend , .subject {
|
||||
color: #928BFF;
|
||||
|
||||
main,
|
||||
aside,
|
||||
section {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.hover {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.notfound-hover {
|
||||
background: #EEF2FF;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#postform_container {
|
||||
background-color: #EEF2FF;
|
||||
}
|
||||
|
||||
.shadow {
|
||||
box-shadow: 0 0 10px rgba(0,0,0,0.55);
|
||||
}
|
||||
|
||||
.hover > div > .post , .notfound-hover {
|
||||
background-color: #D6DAF0;
|
||||
box-shadow: 0 0 10px rgba(0,0,0,0.55);
|
||||
}
|
||||
|
||||
.frontend , .subject, .catalog_subject {
|
||||
color: #0F0C5D;
|
||||
}
|
||||
|
||||
.name {
|
||||
color: #117743;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.postno {
|
||||
padding-right: 5px;
|
||||
}
|
||||
.error {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.name , .subject {
|
||||
@@ -15,13 +63,6 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
input.button {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 350px;
|
||||
@@ -35,35 +76,112 @@ textarea {
|
||||
padding: 10px 10px;
|
||||
}
|
||||
|
||||
.download_link,.fname_link {
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-size: 90%;
|
||||
height: auto
|
||||
padding: 0.5em 0;
|
||||
margin: auto;
|
||||
max-width: 200px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-height: 2.4em;
|
||||
}
|
||||
|
||||
.post_body > pre {
|
||||
font-size: 10pt;
|
||||
font-weight: unset;
|
||||
}
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
background: #3f3f3f;
|
||||
color: #d17600;
|
||||
align: center;
|
||||
font-size: 12pt;
|
||||
color: black;
|
||||
display: inline-block;
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
font-weight: bold;
|
||||
|
||||
font-family: sans;
|
||||
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
td {
|
||||
background-color: dimgrey;
|
||||
table {
|
||||
margin: auto;
|
||||
}
|
||||
table.board-list-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.board_td {
|
||||
position: relative; left: 2px;
|
||||
table tbody td {
|
||||
margin: 0;
|
||||
padding: 4px 15px 4px 4px;
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
}
|
||||
table thead th {
|
||||
border: 1px solid #000333;
|
||||
padding: 4px 15px 5px 5px;
|
||||
|
||||
background: #98E;
|
||||
color: #000333;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
}
|
||||
table tbody tr:nth-of-type( even ) {
|
||||
background-color: #D6DAF0;
|
||||
}
|
||||
|
||||
.posts_td {
|
||||
position: relative; left: -2px;
|
||||
.postform > tr, th {
|
||||
background: #98E;
|
||||
font-size: 10pt;
|
||||
text-align: left;
|
||||
padding-right: 10px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
#overview_graph {
|
||||
position: relative;
|
||||
top: 2px;
|
||||
background: dimgrey;
|
||||
.postform td{
|
||||
padding: 0px 15px 0px 4px;
|
||||
}
|
||||
|
||||
.button {
|
||||
max-width: 10em;
|
||||
height: 2em;
|
||||
}
|
||||
|
||||
tr {
|
||||
background-color: transparent!important;
|
||||
}
|
||||
|
||||
input[type="text"],input[type="password"],textarea {
|
||||
border: 1px solid #a9a9a9;
|
||||
text-indent: 0;
|
||||
text-shadow: none;
|
||||
text-transform: none;
|
||||
word-spacing: normal;
|
||||
font-size: inherit;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
#board_td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.reply, .pagelist, .op {
|
||||
background: #D6DAF0;
|
||||
border-width: 1px;
|
||||
border-style: none solid solid none;
|
||||
border-color: #B7C5D9;
|
||||
max-width: 94%!important;
|
||||
}
|
||||
|
||||
.reply, .ukko_thread_header {
|
||||
background: #202331;
|
||||
background: #D6DAF0;
|
||||
margin-left: 24px;
|
||||
}
|
||||
|
||||
legend {
|
||||
@@ -75,18 +193,78 @@ hr {
|
||||
border-width: 1px medium medium;
|
||||
border-color: #b7c5d9;
|
||||
border-style: solid none none;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
a:hover , a:visited:hover {
|
||||
color: #f13333;
|
||||
.board_header {
|
||||
font-family: tahoma;
|
||||
letter-spacing: -2px;
|
||||
font-size: 20pt;
|
||||
margin: 0;
|
||||
color: #AF0A0F;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0C2FF3;
|
||||
.board_header_catalog {
|
||||
text-align: center;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: #5E00A0;
|
||||
.catalog_thread {
|
||||
display: inline-block;
|
||||
width: 180px;
|
||||
text-align: center;
|
||||
padding: 0.25em;
|
||||
height: 240px;
|
||||
overflow: hidden;
|
||||
background-color: rgba(182, 182, 182 ,0.12);
|
||||
margin: 0.1em;
|
||||
border: 2px solid rgba(111, 111, 111, 0.34);
|
||||
}
|
||||
|
||||
.catalog_thread:hover {
|
||||
background-color: #D6DAF0;
|
||||
}
|
||||
|
||||
#catalog_container {
|
||||
width: 95%;
|
||||
margin: 1em auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.catalog_header, .catalog_subject {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.linkThumb img {
|
||||
max-height: 128px;
|
||||
max-width: 128px;
|
||||
box-shadow: 0 0 4px rgba(0,0,0,0.55);
|
||||
border: 2px solid rgba(153,153,153,0);
|
||||
}
|
||||
|
||||
a:hover , a:visited:hover, .navbar-link > label:hover {
|
||||
color: #ff0000;
|
||||
}
|
||||
|
||||
a, a:visited, .navbar-link > label {
|
||||
color: #34345C;
|
||||
}
|
||||
|
||||
.postno {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.postno, .postnol, .postnol:visited {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.postno:hover, .postnol:hover, .postnol:visited:hover {
|
||||
color: #ff0000;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
@@ -96,70 +274,97 @@ a:visited {
|
||||
right: 0px;
|
||||
margin-top: 0px;
|
||||
z-index: 20;
|
||||
box-shadow: 0px 1px 20px rgba(0, 0, 0, 0.15);
|
||||
background: #202331;
|
||||
color: #616383;
|
||||
box-shadow: 1px 10px 20px rgba(0, 0, 0, 0.15);
|
||||
border-bottom: 1px solid;
|
||||
background: #D6DAF0;
|
||||
color: #34345C;
|
||||
min-height: 20px;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.navbar-sep {
|
||||
color: black;
|
||||
color: darkgray;
|
||||
}
|
||||
|
||||
.navbar-link > label {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#postform_container {
|
||||
margin-top: 5em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.navLinks {
|
||||
padding-bottom: 50px;
|
||||
}
|
||||
|
||||
.ukko_thread_header {
|
||||
padding: 5px 5px;
|
||||
margin: 5px 5px;
|
||||
float: left;
|
||||
clear: both;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
th {
|
||||
background: #4DA6BD;
|
||||
font-size: 10pt;
|
||||
padding-left: 10px;
|
||||
padding-right: 15px;
|
||||
}
|
||||
|
||||
input, textarea {
|
||||
color: whitesmoke;
|
||||
background: #2d2d2d;
|
||||
border-color: #4D28CA;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
html {
|
||||
color: #ededed;
|
||||
background: black;
|
||||
height: 100%;
|
||||
font-family: arial,helvetica,sans-serif;
|
||||
font-size: 10pt;
|
||||
margin: 0 4px;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
.reply {
|
||||
margin-left: 1.8em;
|
||||
display: inline-block;
|
||||
border-radius: 3px;
|
||||
|
||||
input, textarea {
|
||||
|
||||
}
|
||||
|
||||
.ukko_thread_header {
|
||||
border-color: #C0C3D4;
|
||||
border-top-left-radius: 0px;
|
||||
border-top-right-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
border-bottom-left-radius: 0px;
|
||||
border-style: dashed;
|
||||
}
|
||||
|
||||
.frontend {
|
||||
margin-top: 0px;
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.op , .reply {
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.op {
|
||||
margin-right: 20px;
|
||||
margin-bottom: 10px;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
|
||||
.post:target {
|
||||
background-color: #A99AFF;
|
||||
}
|
||||
|
||||
.postreply {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.post {
|
||||
display: inline;
|
||||
margin-bottom: 5px;
|
||||
background-color: #D6DAF0;
|
||||
|
||||
border: 1px solid #B7C5D9;
|
||||
border-left: none;
|
||||
border-top: none;
|
||||
display: table;
|
||||
padding: 2px;
|
||||
margin: 2px;
|
||||
|
||||
display: inline-block;
|
||||
float: left;
|
||||
clear: both;
|
||||
|
||||
min-width: 500px;
|
||||
}
|
||||
|
||||
.postheader {
|
||||
width: 100%;
|
||||
padding-top: 3px;
|
||||
padding-right: 5px
|
||||
}
|
||||
|
||||
.tripcode {
|
||||
@@ -187,14 +392,16 @@ html {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
|
||||
.memearrows {
|
||||
color: #29D029;
|
||||
color: #789922;
|
||||
margin-left: none;
|
||||
}
|
||||
|
||||
.redtext {
|
||||
color: #d50505;
|
||||
color: #AF0A0F;
|
||||
font-size: 12pt;
|
||||
font-weight: bold;
|
||||
margin-left: none;
|
||||
}
|
||||
|
||||
.spoiler {
|
||||
@@ -219,34 +426,69 @@ html {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.file-thumbnail {
|
||||
display: block;
|
||||
margin: 5px 20px 10px;
|
||||
.expanded-thumbnail {
|
||||
display: inline;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
margin: 10px 10px 10px;
|
||||
}
|
||||
|
||||
.thumbnail {
|
||||
display: block;
|
||||
margin: 5px 20px;
|
||||
border: medium none;
|
||||
max-width: 300px;
|
||||
max-height: 200px;
|
||||
}
|
||||
|
||||
.reply, .ukko_thread_header , pre {
|
||||
padding: 7px 7px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 1px 1px 3px black;
|
||||
}
|
||||
|
||||
.post_body > p {
|
||||
margin: 0px 0px;
|
||||
.reply {
|
||||
padding: 3px 5px 3px 5px;
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.post_body {
|
||||
display: inline;
|
||||
margin-left: 15px;
|
||||
margin-top: 3px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.post_body_line {
|
||||
margin-left: inherit;
|
||||
margin-top: 2px;
|
||||
margin-bottom: 2px;
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
.post {
|
||||
.pagelist {
|
||||
display: inline-block;
|
||||
width: 80%;
|
||||
overflow: hidden;
|
||||
margin-left: 15px;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 50px;
|
||||
padding: 10px 10px 10px 10px;
|
||||
font-size: 12pt;
|
||||
font-weight: medium;
|
||||
|
||||
}
|
||||
|
||||
#postform_attachment {
|
||||
.backlink_rewritten {
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.backlink, .backlink:hover, .backlink:visited, .backlink:visited:hover, .backlink_rewritten {
|
||||
margin-left: none;
|
||||
color: #D00
|
||||
}
|
||||
|
||||
|
||||
.origin > img{
|
||||
height: 25px;
|
||||
vertical-align: text-top;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.postform_attachment {
|
||||
max-width: 330px;
|
||||
}
|
||||
|
||||
@@ -257,45 +499,27 @@ html {
|
||||
}
|
||||
|
||||
#captcha_img {
|
||||
background: #4DA6BD;
|
||||
background: white;
|
||||
}
|
||||
|
||||
figure {
|
||||
float: left;
|
||||
margin: 1ex;
|
||||
}
|
||||
figure img {
|
||||
max-width:256px;
|
||||
max-height:128px;
|
||||
max-width:100%;
|
||||
}
|
||||
fieldset {
|
||||
overflow: auto;
|
||||
border-radius: 5px 0px 5px 0px;
|
||||
img.thumbnail {
|
||||
max-width: 350px;
|
||||
max-height: 350px;
|
||||
}
|
||||
|
||||
fieldset > img {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.thread {
|
||||
float: left;
|
||||
width: 90%;
|
||||
padding-left: 10px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
background-color: #252525;
|
||||
}
|
||||
|
||||
.replybar {
|
||||
float: left;
|
||||
position: fixed;
|
||||
top: 2ex;
|
||||
right: 0;
|
||||
width: 34%
|
||||
}
|
||||
width: 500px;
|
||||
}
|
||||
@media (max-width: 100ex) {
|
||||
.replybar, .thread {
|
||||
.replybar {
|
||||
width: 100%;
|
||||
position: static;
|
||||
}
|
||||
@@ -318,6 +542,44 @@ textarea#reply-text {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
hr {
|
||||
padding-bottom: 20px;
|
||||
#nntpchan_banner {
|
||||
align: center;
|
||||
}
|
||||
|
||||
.legal {
|
||||
font-size: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.attachments {
|
||||
float: left;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.navbar-links, .navbar-link, .navbar-name {
|
||||
padding-left: 2px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
|
||||
.board_title {
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
.thread {
|
||||
padding-left: 10px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.hider {
|
||||
float: right;
|
||||
|
||||
}
|
||||
@keyframes rotate {
|
||||
0% { transform:rotate(0deg); }
|
||||
25% { transform:rotate(-1deg); }
|
||||
50% { transform:rotate(0deg); }
|
||||
75% { transform:rotate(1deg); }
|
||||
|
||||
}
|
||||
|
||||
649
contrib/static/tomorrow.css
Normal file
@@ -0,0 +1,649 @@
|
||||
body
|
||||
{
|
||||
background: #0B0B0B;
|
||||
color: #DADADA;
|
||||
font-family: arial, helvetica, sans-serif;
|
||||
font-size: 10pt;
|
||||
margin: 0 4px;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
.post_body > pre {
|
||||
color: #DADADA;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
|
||||
main,
|
||||
aside,
|
||||
section
|
||||
{
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.frontend,
|
||||
.subject,
|
||||
.catalog_subject
|
||||
{
|
||||
color: #A03F4C;
|
||||
}
|
||||
|
||||
.name
|
||||
{
|
||||
color: #117743;
|
||||
}
|
||||
|
||||
.name,
|
||||
.subject
|
||||
{
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#postform-outer
|
||||
{
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea
|
||||
{
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
#postform-inner
|
||||
{
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.post
|
||||
{
|
||||
padding: 10px 10px;
|
||||
}
|
||||
|
||||
pre
|
||||
{
|
||||
white-space: pre-wrap;
|
||||
text-align: center;
|
||||
font-size: 13pt;
|
||||
background: #98E;
|
||||
color: black;
|
||||
display: inline-block;
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
font-weight: bold;
|
||||
padding: 20px 20px 20px 20px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
table
|
||||
{
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
table.board-list-table
|
||||
{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table tbody td
|
||||
{
|
||||
margin: 0;
|
||||
padding: 4px 15px 4px 4px;
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
table thead th
|
||||
{
|
||||
background-color: #121212;
|
||||
border: solid 1px #535353;
|
||||
color: #DADADA;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
table tbody tr:nth-of-type( even)
|
||||
{
|
||||
background-color: #121212;
|
||||
border: solid 1px #535353;
|
||||
}
|
||||
|
||||
.postform >tr,
|
||||
th
|
||||
{
|
||||
background-color: #121212;
|
||||
border: solid 1px #535353;
|
||||
color: #DADADA;
|
||||
font-size: 10pt;
|
||||
text-align: left;
|
||||
padding-right: 10px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
#postform-inner tr
|
||||
{
|
||||
background-color: transparent!important;
|
||||
}
|
||||
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
textarea
|
||||
{
|
||||
text-indent: 0;
|
||||
text-shadow: none;
|
||||
text-transform: none;
|
||||
word-spacing: normal;
|
||||
font-size: inherit;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
#board_td
|
||||
{
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.reply,
|
||||
.pagelist
|
||||
{
|
||||
background: #D6DAF0;
|
||||
border-width: 1px;
|
||||
border-style: none solid solid none;
|
||||
border-color: #B7C5D9;
|
||||
display: inline-block;
|
||||
max-width: 94%!important;
|
||||
}
|
||||
|
||||
.reply,
|
||||
.ukko_thread_header
|
||||
{
|
||||
background-color: #121212;
|
||||
border: solid 1px #535353;
|
||||
color: #DADADA;
|
||||
margin-left: 24px;
|
||||
}
|
||||
|
||||
hr
|
||||
{
|
||||
height: 0px;
|
||||
border-width: 1px medium medium;
|
||||
border-color: #b7c5d9;
|
||||
border-style: solid none none;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.board_header
|
||||
{
|
||||
font-family: tahoma;
|
||||
letter-spacing: -2px;
|
||||
font-size: 20pt;
|
||||
margin: 0;
|
||||
color: #AF0A0F;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
.board_header_catalog
|
||||
{
|
||||
text-align: center;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.catalog_thread
|
||||
{
|
||||
display: inline-block;
|
||||
width: 180px;
|
||||
text-align: center;
|
||||
padding: 0.25em;
|
||||
height: 240px;
|
||||
overflow: hidden;
|
||||
background-color: rgba(182, 182, 182, 0.12);
|
||||
margin: 0.1em;
|
||||
border: 2px solid rgba(111, 111, 111, 0.34);
|
||||
}
|
||||
|
||||
.catalog_thread:hover
|
||||
{
|
||||
background-color: #D6DAF0;
|
||||
}
|
||||
|
||||
#catalog_container
|
||||
{
|
||||
width: 95%;
|
||||
margin: 1em auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.catalog_header,
|
||||
.catalog_subject
|
||||
{
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.linkThumb img
|
||||
{
|
||||
max-height: 128px;
|
||||
max-width: 128px;
|
||||
box-shadow: 0 0 4px rgba(0, 0, 0, 0.55);
|
||||
border: 2px solid rgba(153, 153, 153, 0);
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
a:hover,
|
||||
a:visited:hover,
|
||||
.navbar-link > label:hover
|
||||
{
|
||||
color: #ff0000;
|
||||
}
|
||||
|
||||
a,
|
||||
a:visited,
|
||||
.navbar-link > label
|
||||
{
|
||||
color: #B8B8F7;
|
||||
;
|
||||
}
|
||||
|
||||
.postno
|
||||
{
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.postno,
|
||||
.postnol,
|
||||
.postnol:visited
|
||||
{
|
||||
color: #B8B8F7;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.postno:hover,
|
||||
.postnol:hover,
|
||||
.postnol:visited:hover
|
||||
{
|
||||
color: #ff0000;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.navbar
|
||||
{
|
||||
position: fixed;
|
||||
padding: 0.25em;
|
||||
text-align: center;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
margin-top: 0px;
|
||||
z-index: 20;
|
||||
background-color: #121212;
|
||||
border-bottom: solid 1px #535353;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
|
||||
color: #B8B8F7;
|
||||
}
|
||||
|
||||
.navbar-sep
|
||||
{
|
||||
color: darkgray;
|
||||
}
|
||||
|
||||
.navbar-link > label
|
||||
{
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#postform_container
|
||||
{
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.navLinks
|
||||
{
|
||||
padding-bottom: 50px;
|
||||
}
|
||||
|
||||
.ukko_thread_header
|
||||
{
|
||||
float: left;
|
||||
clear: both;
|
||||
display: inline-block;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
input,
|
||||
textarea
|
||||
{
|
||||
background-color: #121212;
|
||||
border: solid 1px #535353;
|
||||
color: #DADADA;
|
||||
}
|
||||
|
||||
.ukko_thread_header
|
||||
{
|
||||
border-color: #C0C3D4;
|
||||
border-top-left-radius: 0px;
|
||||
border-top-right-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
border-bottom-left-radius: 0px;
|
||||
border-style: dashed;
|
||||
}
|
||||
|
||||
.frontend
|
||||
{
|
||||
margin-top: 0px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.op
|
||||
{
|
||||
margin-bottom: 1px;
|
||||
float: left;
|
||||
clear: both;
|
||||
background-color: #0f0f0f;
|
||||
border-color: #242424;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: #0f0f0f;
|
||||
}
|
||||
|
||||
.post
|
||||
{
|
||||
margin-bottom: 5px;
|
||||
min-width: 500px;
|
||||
}
|
||||
|
||||
.postheader
|
||||
{
|
||||
padding-top: 3px;
|
||||
padding-right: 5px
|
||||
}
|
||||
|
||||
.tripcode
|
||||
{
|
||||
color: #de04ef;
|
||||
}
|
||||
|
||||
@keyframes psych
|
||||
{
|
||||
0%
|
||||
{
|
||||
background-color: red;
|
||||
color: blue;
|
||||
}
|
||||
10%
|
||||
{
|
||||
background-color: yellow;
|
||||
color: red;
|
||||
}
|
||||
20%
|
||||
{
|
||||
background-color: blue;
|
||||
color: green;
|
||||
}
|
||||
30%
|
||||
{
|
||||
background-color: green;
|
||||
color: yellow;
|
||||
}
|
||||
40%
|
||||
{
|
||||
background-color: red;
|
||||
color: blue;
|
||||
}
|
||||
50%
|
||||
{
|
||||
background-color: yellow;
|
||||
color: green;
|
||||
}
|
||||
60%
|
||||
{
|
||||
background-color: blue;
|
||||
color: yellow;
|
||||
}
|
||||
70%
|
||||
{
|
||||
background-color: green;
|
||||
color: blue;
|
||||
}
|
||||
80%
|
||||
{
|
||||
background-color: red;
|
||||
color: green;
|
||||
}
|
||||
90%
|
||||
{
|
||||
background-color: yellow;
|
||||
color: red;
|
||||
}
|
||||
95%
|
||||
{
|
||||
background-color: blue;
|
||||
color: yellow;
|
||||
}
|
||||
100%
|
||||
{
|
||||
background-color: green;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.psy
|
||||
{
|
||||
animation: psych 2s linear infinite;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.memearrows
|
||||
{
|
||||
color: #789922;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.redtext
|
||||
{
|
||||
color: #AF0A0F;
|
||||
font-size: 12pt;
|
||||
font-weight: bold;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.spoiler
|
||||
{
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.spoiler > p
|
||||
{
|
||||
background: black;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.spoiler:hover > p
|
||||
{
|
||||
background: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.intro
|
||||
{
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
|
||||
.file:not(.multiple) .file-thumbnail
|
||||
{
|
||||
float: left;
|
||||
}
|
||||
|
||||
.file-thumbnail
|
||||
{
|
||||
display: block;
|
||||
margin: 5px 20px 10px;
|
||||
border: medium none;
|
||||
max-width: 300px;
|
||||
max-height: 200px;
|
||||
}
|
||||
|
||||
.reply
|
||||
{
|
||||
padding: 3px 5px 3px 5px;
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.post_body
|
||||
{
|
||||
margin-left: 15px;
|
||||
margin-top: 3px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.post_body_line
|
||||
{
|
||||
margin-left: inherit;
|
||||
margin-top: 2px;
|
||||
margin-bottom: 2px;
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
.post
|
||||
{
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.pagelist
|
||||
{
|
||||
display: inline-block;
|
||||
background-color: #121212;
|
||||
border: solid 1px #535353;
|
||||
color: #DADADA;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
margin-left: 2em;
|
||||
padding: 10px 10px 10px 10px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.backlink,
|
||||
.backlink:hover,
|
||||
.backlink:visited,
|
||||
.backlink:visited:hover
|
||||
{
|
||||
margin-left: 0;
|
||||
color: #D00
|
||||
}
|
||||
|
||||
.origin > img
|
||||
{
|
||||
height: 20px;
|
||||
vertical-align: text-top;
|
||||
}
|
||||
|
||||
.postform_attachment
|
||||
{
|
||||
max-width: 330px;
|
||||
}
|
||||
|
||||
#faq > div
|
||||
{
|
||||
margin-left: 20%;
|
||||
width: 50%;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#captcha_img
|
||||
{
|
||||
background-color: #121212;
|
||||
border: solid 1px #535353;
|
||||
}
|
||||
|
||||
figure
|
||||
{
|
||||
float: left;
|
||||
margin: 1ex;
|
||||
}
|
||||
|
||||
img.thumbnail
|
||||
{
|
||||
max-width: 350px;
|
||||
max-height: 350px;
|
||||
}
|
||||
|
||||
.replybar
|
||||
{
|
||||
float: left;
|
||||
position: fixed;
|
||||
top: 2ex;
|
||||
right: 0;
|
||||
width: 34%
|
||||
}
|
||||
|
||||
@media (max-width: 100ex)
|
||||
{
|
||||
.replybar
|
||||
{
|
||||
width: 100%;
|
||||
position: static;
|
||||
}
|
||||
}
|
||||
|
||||
.hide-reply:checked ~ div
|
||||
{
|
||||
width: 100%;
|
||||
position: static;
|
||||
}
|
||||
|
||||
textarea#reply-text
|
||||
{
|
||||
width: 100%;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.hide-reply
|
||||
{
|
||||
float: right;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
#nntpchan_banner
|
||||
{
|
||||
text-align: center;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.legal
|
||||
{
|
||||
font-size: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.attachments
|
||||
{
|
||||
float: left;
|
||||
}
|
||||
|
||||
hr
|
||||
{
|
||||
border: 1px solid #535353;
|
||||
height: 1px
|
||||
}
|
||||
|
||||
img#nntpchan_banner {
|
||||
box-shadow: 0px 0px 10px 0px;
|
||||
}
|
||||
|
||||
#postform_container {
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.post:target {
|
||||
background-color: #2c2d3e;
|
||||
box-shadow: 0px 0px 10px 2px;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 1.6 KiB |
27
contrib/templates/chen-chan/board.mustache
Normal file
@@ -0,0 +1,27 @@
|
||||
{{!
|
||||
board.mustache, displays the contents of page N of the board
|
||||
|
||||
template parameters:
|
||||
- board ( the model of the current page )
|
||||
- page ( the page number of the current page )
|
||||
|
||||
board has the properties:
|
||||
- Prefix ( absolute path like //site.tld/ or /path/ )
|
||||
- Board ( the name of the board )
|
||||
- Navbar ( a function that renders the navbar, should not be escaped )
|
||||
- Threads ( a list of Thread Models with the last few replies )
|
||||
}}
|
||||
<!doctype html><html><head><link rel="stylesheet" href="/static/chen-chan.css"><title>{{board.Board}}</title></head><body>
|
||||
{{{board.Navbar}}}
|
||||
{{{form}}}
|
||||
<dl>
|
||||
<hr>
|
||||
{{#board.Threads}}
|
||||
{{{OP.Truncate.RenderPost}}}
|
||||
{{#Truncate.Replies}}
|
||||
{{{Truncate.RenderPost}}}
|
||||
{{/Truncate.Replies}}
|
||||
<hr>
|
||||
{{/board.Threads}}
|
||||
</dl>
|
||||
</body></html>
|
||||
33
contrib/templates/chen-chan/boardlist.mustache
Normal file
@@ -0,0 +1,33 @@
|
||||
{{!
|
||||
boardlist.mustache -- full list of every board
|
||||
template parameters:
|
||||
- graph ( a list of 4 string tuples: (board, posts_per_hour, posts_per_day, total_posts) )
|
||||
- frontend ( the name of the frontend )
|
||||
- prefix ( the site's prefix )
|
||||
}}
|
||||
<!doctype html><html><head><link rel="stylesheet" href="/static/chen-chan.css"><title>{{frontend}} boards</title></head><body>
|
||||
<table>
|
||||
<tr>
|
||||
<th>board</th>
|
||||
<th>posts per hour</th>
|
||||
<th>posts per day</th>
|
||||
<th>total</th>
|
||||
</tr>
|
||||
{{# graph}}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{{prefix}}{{Board}}-0.html">{{Board}}</a>
|
||||
</td>
|
||||
<td>
|
||||
{{Hour}}
|
||||
</td>
|
||||
<td>
|
||||
{{Day}}
|
||||
</td>
|
||||
<td>
|
||||
{{All}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/ graph}}
|
||||
</table>
|
||||
</body></html>
|
||||
11
contrib/templates/chen-chan/frontpage.mustache
Normal file
@@ -0,0 +1,11 @@
|
||||
{{!
|
||||
frontpage.mustache -- template for index.html
|
||||
template parameters:
|
||||
- boardgraph ( a boardPageRows instance, see srnd/model.go )
|
||||
- postgraph ( a postsGraph instance , see srnd/model.go )
|
||||
- overview ( an overviewModel instance, see srnd/model.go )
|
||||
- totalposts ( the number of total posts we have ever seen )
|
||||
- frontend ( the name of the frontend )
|
||||
- prefix ( the site's prefix )
|
||||
}}
|
||||
<!doctype html><html><head><link rel="stylesheet" href="/static/chen-chan.css"><title>{{frontend}} on nntpchan</title></head><body><p>{{frontend}} on nntpchan</p><p><a href="ukko.html">overboard</a> <a href="{{prefix}}boards.html">boards</a> <a href="{{prefix}}static/chen-chan-faq.html">faq</a></p><dl><dt>last posts:</dt><dd>{{{overview.Render}}}</dd></dl><dl><dt>board stats:</dt><dd><table><tr><th>board</th><th>posts this hour</th><th>posts today</th><th>total</th></tr>{{# boardgraph}}<tr><td><a href="{{prefix}}{{Board}}-0.html">{{Board}}</a></td><td>{{Hour}}</td><td>{{Day}}</td><td>{{All}}</td></tr>{{/ boardgraph}}</table></dd></dl><dl><dt>total stats:</dt><dd>{{{postsgraph.Render}}}</dd></dl><p>{{totalposts}} posts total since 2015-12-23</p></body></html>
|
||||
36
contrib/templates/chen-chan/graph_history.mustache
Normal file
@@ -0,0 +1,36 @@
|
||||
{{!
|
||||
graph_history.mustache
|
||||
template parameters:
|
||||
- history ( a list of PostEntry instances, see srnd/model.go )
|
||||
|
||||
}}
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"></meta>
|
||||
<link rel="stylesheet" href="{{prefix}}site.css" />
|
||||
<link rel="stylesheet" href="{{prefix}}user.css" />
|
||||
<title> Post History</title>
|
||||
</head>
|
||||
<body>
|
||||
<td>
|
||||
<table id="history_graph">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Month</th>
|
||||
<th>Posts</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#history.Scale}}
|
||||
<tr>
|
||||
<td>{{Date}}</td>
|
||||
<td class="history_num">{{Num}}</td>
|
||||
<td>{{OvercockGraph}}</td>
|
||||
</tr>
|
||||
{{/history.Scale}}
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</body>
|
||||
</html>
|
||||
15
contrib/templates/chen-chan/keygen.mustache
Normal file
@@ -0,0 +1,15 @@
|
||||
{{!
|
||||
keygen.mustache -- page containing a newly generated tripcode
|
||||
template parameters:
|
||||
- prefix ( the site prefix )
|
||||
- public ( the public key in hex )
|
||||
- secret ( the secret key in hex )
|
||||
- tripcode ( html version of the public key )
|
||||
}}
|
||||
<!doctype html><html><head><title>new tripcode</title></head><body><pre>
|
||||
new tripcode
|
||||
|
||||
secret: {{secret}}
|
||||
public: {{public}}
|
||||
tripcode: {{{tripcode}}}
|
||||
</pre></body></html>
|
||||
7
contrib/templates/chen-chan/modlogin.mustache
Normal file
@@ -0,0 +1,7 @@
|
||||
<!doctype html><html><head><link rel="stylesheet" href="{{prefix}}static/chen-chan.css"><title>login</title></head><body>
|
||||
<form action="login" method="POST" name="modlogin">
|
||||
<label for="mod_key">secret</label>
|
||||
<input type="password" id="mod_key" name="privkey">
|
||||
<input type="submit" value="login">
|
||||
</form>
|
||||
</body></html>
|
||||
9
contrib/templates/chen-chan/modlogin_result.mustache
Normal file
@@ -0,0 +1,9 @@
|
||||
{{!
|
||||
modlogin_result.mustache -- shows the result of a login attempt
|
||||
template parameters:
|
||||
- prefix ( the site prefix )
|
||||
- mod_prefix ( the prefix to the mod panel, could be something like https://mod.site.tld/ or /mod/ )
|
||||
- message ( the message returned from the login attempt )
|
||||
- fail ( present if the login failed ) // not yet added
|
||||
}}
|
||||
<!doctype html><html><head><meta http-equiv="refresh" content="1; {{mod_prefix}}"><title>login</title></head><body><p>{{message}}</p></body></html>
|
||||
79
contrib/templates/chen-chan/modpage.mustache
Normal file
@@ -0,0 +1,79 @@
|
||||
{{!
|
||||
modpage.mustache -- the moderator panel when logged in
|
||||
template parameters:
|
||||
- prefix ( the site's prefix )
|
||||
}}
|
||||
<!doctype html><html><head>
|
||||
<link rel="stylesheet" href="{{prefix}}static/chen-chan.css">
|
||||
<!-- yes it uses js -->
|
||||
<script src="{{prefix}}static/mod.js"></script>
|
||||
<title>nntpchan mod page</title>
|
||||
</head><body>
|
||||
<dl>
|
||||
<dt>post actions</dt>
|
||||
<dd>
|
||||
<div>
|
||||
<label for="nntpchan_mod_target">target</label>
|
||||
<input id="nntpchan_mod_target" type="text">
|
||||
</div>
|
||||
<div>
|
||||
<button onclick="nntpchan_ban()">ban (url)</button>
|
||||
<button onclick="nntpchan_delete()">delete (url)</button>
|
||||
<button onclick="nntpchan_unban()">unban (ip)</button>
|
||||
</div>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>key actions</dt>
|
||||
<dd>
|
||||
<div>
|
||||
<label for="nntpchan_board_target">pubkey:</label>
|
||||
<input type="text" id="nntpchan_key_target" />
|
||||
</div>
|
||||
<div>
|
||||
<button onclick="nntpchan_key_add()">add key</button>
|
||||
<button onclick="nntpchan_key_del()">remove key</button>
|
||||
</div>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>board actions</dt>
|
||||
<dd>
|
||||
<div>
|
||||
<label for="nntpchan_board_target">board name:</label>
|
||||
<input type="text" id="nntpchan_board_target">
|
||||
</div>
|
||||
<div>
|
||||
<button onclick="nntpchan_admin_board('frontend.add')">add board</button>
|
||||
<button onclick="nntpchan_admin_board('frontend.regen')">regenerate</button>
|
||||
<button onclick="nntpchan_admin_board('frontend.ban')">ban</button>
|
||||
<button onclick="nntpchan_admin_board('frontend.unban')">unban</button>
|
||||
<button onclick="nntpchan_admin_board('frontend.nuke')">nuke</button>
|
||||
</div>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>lightweight actions</dt>
|
||||
<dd>
|
||||
<button onclick="nntpchan_admin('template.reload')">reload all templates</button>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>very load heavy actions, use with care</dt>
|
||||
<dd>
|
||||
<div>
|
||||
<button onclick="nntpchan_admin('frontend.regen')">regenerate all pages</button>
|
||||
<button onclick="nntpchan_admin('thumbnail.regen')">regenerate all thumbnails</button>
|
||||
</div>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>status</dt>
|
||||
<dd>
|
||||
<div id="nntpchan_mod_result"></div>
|
||||
<noscript>
|
||||
<b>enable js to use the mod panel kthx</b>
|
||||
</noscript>
|
||||
</dd>
|
||||
</dl>
|
||||
</body></html>
|
||||
12
contrib/templates/chen-chan/navbar.mustache
Normal file
@@ -0,0 +1,12 @@
|
||||
{{!
|
||||
navbar.mustache -- element on the top of each nod-mod page
|
||||
|
||||
TODO: make this not suck, have a board list, have board page list
|
||||
|
||||
template parameters:
|
||||
- name ( the name of whatever resource we are on, board/thread )
|
||||
- frontend ( the name of the frontend we are on )
|
||||
- links ( a list of Link Models to display )
|
||||
- prefix ( site prefix )
|
||||
}}
|
||||
<p>{{name}} on {{frontend}} | {{# links}} <a href="{{LinkURL}}">{{Text}}</a> {{/ links}} | <a href="{{prefix}}">front page</a> <a href="{{prefix}}ukko.html">overboard</a></p>
|
||||
1
contrib/templates/chen-chan/newboard.mustache
Normal file
@@ -0,0 +1 @@
|
||||
no apparently.
|
||||
7
contrib/templates/chen-chan/overview.mustache
Normal file
@@ -0,0 +1,7 @@
|
||||
{{! overview.mustache
|
||||
paramters:
|
||||
|
||||
- overview (list of PostModels in order of last posted)
|
||||
|
||||
}}
|
||||
<table><tr><th>date</th><th>board</th><th>subject</th></tr>{{#overview}}<tr><td>{{Date}}</td><td><a href="{{Prefix}}{{Board}}-0.html">{{Board}}</a></td><td><a href="{{PostURL}}">{{Truncate.Subject}}</a></td></tr>{{/overview}}</table>
|
||||
15
contrib/templates/chen-chan/post.mustache
Normal file
@@ -0,0 +1,15 @@
|
||||
<dt id="{{PostHash}}">
|
||||
<a onclick="nntpchan_backlink('{{ShortHash}}');" title="{{MessageID}}">{{ShortHash}}</a>
|
||||
{{Date}}
|
||||
{{#IsI2P}}i2p{{/IsI2P}}{{#IsTor}}tor{{/IsTor}}{{#IsClearnet}}clr{{/IsClearnet}}
|
||||
{{Subject}}
|
||||
{{Name}}
|
||||
{{{Pubkey}}}
|
||||
<a href="{{PostURL}}">[reply]</a>
|
||||
</dt>
|
||||
<dd>
|
||||
{{{RenderBody}}}
|
||||
{{#Attachments}}
|
||||
file: <a href="{{Source}}" target="_blank">{{Filename}}</a><br><br>
|
||||
{{/Attachments}}
|
||||
</dd>
|
||||
3
contrib/templates/chen-chan/post_fail.mustache
Normal file
@@ -0,0 +1,3 @@
|
||||
<!doctype html><html><head>
|
||||
<meta http-equiv="refresh" content="1; {{redirect_url}}"></head>
|
||||
<body><p>fail: {{reason}}</p></body></html>
|
||||
40
contrib/templates/chen-chan/post_retry.mustache
Normal file
@@ -0,0 +1,40 @@
|
||||
<html><head><link rel="stylesheet" href="/static/chen-chan.css"><title>try again</title></head><body>
|
||||
<form enctype="multipart/form-data" name="post" method="post">
|
||||
{{#attachment}}
|
||||
<input type="hidden" name="attachment_data" value="{{attachment}}">
|
||||
<input type="hidden" name="attachment_filename" value="{{attachment_filename}}">
|
||||
<input type="hidden" name="attachment_mime" value="{{attachment_type}}">
|
||||
{{/attachment}}
|
||||
<input type="hidden" name="reference" value="{{reference}}">
|
||||
<input type="hidden" name="name" value="{{name}}">
|
||||
<input type="hidden" name="subject" value="{{subject}}">
|
||||
<input type="hidden" name="captcha_id" value="{{captcha_id}}">
|
||||
<input type="hidden" name="message" value="{{message}}">
|
||||
<div id="postform-outer">
|
||||
<div id="postform-inner">
|
||||
<div>{{fail_message}}</div>
|
||||
<table class="postform">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>
|
||||
Captcha
|
||||
</th>
|
||||
<td>
|
||||
<img id="captcha_img" src="{{prefix}}captcha/{{captcha_id}}.png" alt="captcha" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
Solution
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="captcha" />
|
||||
<input type="submit" value="Post" class="button" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</body></html>
|
||||
7
contrib/templates/chen-chan/post_success.mustache
Normal file
@@ -0,0 +1,7 @@
|
||||
{{!
|
||||
post_success.mustache -- shown when we do a successful post
|
||||
template parameters:
|
||||
- redirect_url ( the url of the next page we should redirect to )
|
||||
- message_id ( the value of the Message-ID header in the post we made, the truncated sha1 of this is the >>posthash )
|
||||
}}
|
||||
<!doctype html><html><head><meta http-equiv="refresh" content="2; {{redirect_url}}"></head><body><pre>posted as {{message_id}}</pre></body></html>
|
||||
20
contrib/templates/chen-chan/postform.mustache
Normal file
@@ -0,0 +1,20 @@
|
||||
{{!
|
||||
postform.mustache -- the form for posting
|
||||
|
||||
template parameters:
|
||||
- post_url ( the url of the post form )
|
||||
- reference ( the post we are replying to, or empty string if it's an op )
|
||||
- button ( the text for the reply button )
|
||||
}}
|
||||
<form action="{{post_url}}" enctype="multipart/form-data" name="post" method="post" style="overflow:auto">
|
||||
<input type="hidden" name="reference" value="{{reference}}">
|
||||
<textarea id="postform_message" name="message" placeholder="text" cols="40" rows="10" style="float:left" ></textarea><br>
|
||||
<div style="float:left">
|
||||
<input type="file" name="attachment"><br>
|
||||
<input type="text" name="subject" placeholder="subject"><br>
|
||||
<input type="text" name="name" placeholder="name"><br>
|
||||
<input type="text" name="captcha" placeholder="captcha"><br>
|
||||
<input type="submit" value="{{button}}" class="button"><br>
|
||||
</div>
|
||||
<img id="captcha_img" src="{{prefix}}captcha/img" alt="captcha" style="float:left">
|
||||
</form>
|
||||
7
contrib/templates/chen-chan/posts_graph.mustache
Normal file
@@ -0,0 +1,7 @@
|
||||
{{!
|
||||
posts graph.mustache -- post frequence graph
|
||||
parameters:
|
||||
|
||||
* graph - a postsGraph instance (see srnd/model.go)
|
||||
}}
|
||||
<table><tr><th>date</th><th>posts</th><th>cock</th></tr>{{#graph.Scale}}<tr><td>{{Day}}</td><td>{{Num}}</td><td>{{OvercockGraph}}</td></tr>{{/graph.Scale}}</table>
|
||||
23
contrib/templates/chen-chan/thread.mustache
Normal file
@@ -0,0 +1,23 @@
|
||||
{{!
|
||||
thread.mustache -- renders to a thread-*.html page, shows the entire thread
|
||||
template parameters:
|
||||
- board ( the Board Model of the board this thread was posted in )
|
||||
- thread ( the Thread Model of the current thread being rendered )
|
||||
- form ( the post form markup )
|
||||
|
||||
Thread Model attributes:
|
||||
- OP , the Post Model of the original poster
|
||||
- Replies , a list of all the replies or empty if none
|
||||
- Board , the name of the Board this thread is on
|
||||
- BoardURL , the url that points to the board index page
|
||||
}}
|
||||
<!doctype html><html><head><link rel="stylesheet" href="/static/chen-chan.css"><title>{{thread.OP.Subject}}</title><script src="{{thread.Prefix}}static/nntpchan.js"></script></head><body>
|
||||
{{{thread.Navbar}}}
|
||||
{{{form}}}
|
||||
<dl>
|
||||
{{{thread.OP.RenderPost}}}
|
||||
{{# thread.Replies}}
|
||||
{{{RenderPost}}}
|
||||
{{/ thread.Replies}}
|
||||
</dl>
|
||||
</body></html>
|
||||
19
contrib/templates/chen-chan/ukko.mustache
Normal file
@@ -0,0 +1,19 @@
|
||||
{{!
|
||||
ukko.mustache -- overboard, contains the last threads posted regardless of newsgroup
|
||||
template parameters:
|
||||
- prefix ( site prefix )
|
||||
- threads ( a list of Thread Models that represent the latest threads )
|
||||
}}
|
||||
<!doctype html><html><head><link rel="stylesheet" href="/static/chen-chan.css"><title>ukko/overboard</title></head><body>
|
||||
<a href="/">frontpage</a>
|
||||
{{#threads}}
|
||||
<hr>
|
||||
<p>posted on <a href="{{{BoardURL}}}">{{OP.Board}}</a></p>
|
||||
<dl>
|
||||
{{{OP.Truncate.RenderPost}}}
|
||||
{{#Truncate.Replies}}
|
||||
{{{Truncate.RenderPost}}}
|
||||
{{/Truncate.Replies}}
|
||||
</dl>
|
||||
{{/threads}}
|
||||
</body></html>
|
||||
25
contrib/templates/default/404.mustache
Normal file
@@ -0,0 +1,25 @@
|
||||
{{!
|
||||
404.mustache -- 404 page
|
||||
template parameters:
|
||||
- prefix (the site prefix)
|
||||
}}
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title> 404 </title>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="stylesheet" href="{{prefix}}static/site.css" />
|
||||
<link id="current_theme" rel="stylesheet" href="{{prefix}}static/user.css" />
|
||||
<script type="text/javascript" src="{{prefix}}static/nntpchan.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<center>
|
||||
<div class="not_found">
|
||||
<img src="{{prefix}}static/404.png"></img>
|
||||
<div class="not_found_message">
|
||||
{{#i18n.Translations}}{{resource_not_found}}{{/i18n.Translations}}
|
||||
</div>
|
||||
</div>
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
||||
@@ -11,12 +11,13 @@
|
||||
- Navbar ( a function that renders the navbar, should not be escaped )
|
||||
- Threads ( a list of Thread Models with the last few replies )
|
||||
}}
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="initial-scale=1" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/site.css" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/user.css" />
|
||||
<link id="current_theme" rel="stylesheet" href="{{board.Prefix}}static/user.css" />
|
||||
<script type="text/javascript" src="{{board.Prefix}}static/nntpchan.js"></script>
|
||||
<title>{{board.Board}}</title>
|
||||
</head>
|
||||
@@ -24,7 +25,12 @@
|
||||
<!-- begin navbar -->
|
||||
{{{board.Navbar}}}
|
||||
<!-- end navbar -->
|
||||
|
||||
<center>
|
||||
<div id="nntpchan_banner">
|
||||
</div>
|
||||
</center>
|
||||
<div class="board_header">{{board.Board}}</div>
|
||||
<div class="board_header_catalog"><a href="{{board.Prefix}}catalog-{{board.Name}}.html"> {{#i18n.Translations}}{{catalog_label}}{{/i18n.Translations}} </a></div>
|
||||
<!-- postform -->
|
||||
<div id="postform_container">
|
||||
{{{form}}}
|
||||
@@ -33,15 +39,33 @@
|
||||
<div id="threads_container">
|
||||
{{#board.Threads}}
|
||||
<div class="thread" id="thread_{{OP.PostHash}}">
|
||||
<div clsss="thread_header">
|
||||
<div class="thread_header">
|
||||
</div>
|
||||
{{{OP.Truncate.RenderPost}}}
|
||||
{{#Truncate.Replies}}
|
||||
{{{Truncate.RenderPost}}}
|
||||
<br />
|
||||
{{/Truncate.Replies}}
|
||||
<hr />
|
||||
</div>
|
||||
{{/board.Threads}}
|
||||
</div>
|
||||
<div class="pagelist">{{# board.PageList }}[<a href="{{LinkURL}}"> {{Text}} </a>] {{/ board.PageList }}
|
||||
<span class="navbar-sep">
|
||||
|
|
||||
</span>
|
||||
<a href="{{board.Prefix}}catalog-{{board.Name}}.html"> {{#i18n.Translations}}{{catalog_label}}{{/i18n.Translations}} </a>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
var prefix = "{{board.Prefix}}";
|
||||
var e = document.getElementById("nntpchan_banner");
|
||||
nntpchan_inject_banners(e, prefix);
|
||||
init(prefix);
|
||||
ready();
|
||||
</script>
|
||||
<hr/>
|
||||
<footer>
|
||||
<p class="legal">All posts on this site are the responsibility of the individual poster and not the administration, pursuant to 47 U.S.C. § 230.</p>
|
||||
<p class="legal">To make a DMCA request or report illegal content, please contact the administration</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -5,25 +5,27 @@
|
||||
- frontend ( the name of the frontend )
|
||||
- prefix ( the site's prefix )
|
||||
}}
|
||||
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="{{prefix}}static/site.css"></link>
|
||||
<link rel="stylesheet" href="{{prefix}}static/user.css"></link>
|
||||
<title> {{frontend}} board list </title>
|
||||
<link id="current_theme" rel="stylesheet" href="{{prefix}}static/user.css"></link>
|
||||
<title> {{frontend}} {{#i18n.Translations}}{{board_list_title}}{{/i18n.Translations}} </title>
|
||||
</head>
|
||||
<body>
|
||||
<center>
|
||||
<div class="index-outer">
|
||||
<div class="index-inner">
|
||||
<table id="board_graph">
|
||||
<tbody>
|
||||
<thead>
|
||||
<tr>
|
||||
<th> Board </th>
|
||||
<th> Post per Hour </th>
|
||||
<th> Post per Day </th>
|
||||
<th> Total </th>
|
||||
<th> {{#i18n.Translations}}{{board_label}}{{/i18n.Translations}} </th>
|
||||
<th> {{#i18n.Translations}}{{pph_label}}{{/i18n.Translations}} </th>
|
||||
<th> {{#i18n.Translations}}{{ppd_label}}{{/i18n.Translations}} </th>
|
||||
<th> {{#i18n.Translations}}{{total}}{{/i18n.Translations}} </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{# graph}}
|
||||
<tr>
|
||||
<td>
|
||||
@@ -46,4 +48,4 @@
|
||||
</div>
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
47
contrib/templates/default/catalog.mustache
Normal file
@@ -0,0 +1,47 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="initial-scale=1" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/site.css" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/user.css" />
|
||||
<link id="current_theme" rel="stylesheet" href="{{board.Prefix}}static/user.css" />
|
||||
<script type="text/javascript" src="{{board.Prefix}}static/nntpchan.js"></script>
|
||||
<title>{{#i18n.Translations}}{{catalog_title}}{{/i18n.Translations}} {{board.Name}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<!-- begin navbar -->
|
||||
{{{board.Navbar}}}
|
||||
<!-- end navbar -->
|
||||
<center>
|
||||
<div id="nntpchan_banner">
|
||||
</div>
|
||||
</center>
|
||||
<div class="board_header">{{#i18n.Translations}}{{catalog_title}}{{/i18n.Translations}} {{board.Name}}</div>
|
||||
<!-- postform -->
|
||||
<hr />
|
||||
<div id="catalog_container">
|
||||
{{#board.Threads}}
|
||||
<div class="catalog_thread">
|
||||
<a class="linkThumb" href="{{OP.PostURL}}"><img src="{{OP.RepresentativeThumb}}"></a>
|
||||
<div class="catalog_header">{{#i18n.Translations}}{{replies_short_label}}{{/i18n.Translations}}: {{ReplyCount}} / {{#i18n.Translations}}{{pictures_short_label}}{{/i18n.Translations}}: {{Page}}</div>
|
||||
<div class="catalog_subject">{{OP.Subject}}</div>
|
||||
<div class="catalog_body">
|
||||
{{{OP.RenderBody}}}
|
||||
</div>
|
||||
</div>
|
||||
{{/board.Threads}}
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
|
||||
var e = document.getElementById("nntpchan_banner");
|
||||
nntpchan_inject_banners(e, "{{board.Prefix}}");
|
||||
|
||||
</script>
|
||||
<hr/>
|
||||
<footer>
|
||||
<p class="legal">All posts on this site are the responsibility of the individual poster and not the administration, pursuant to 47 U.S.C. § 230.</p>
|
||||
<p class="legal">To make a DMCA request or report illegal content, please contact the administration</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,9 +1,9 @@
|
||||
{{!
|
||||
frontpage.mustache -- template for index.html
|
||||
template parameters:
|
||||
- boardgraph ( a boardPageRows instance, see srnd/model.go )
|
||||
- postgraph ( a postsGraph instance , see srnd/model.go )
|
||||
- overview ( an overviewModel instance, see srnd/model.go )
|
||||
- boardgraph ( markup of boardPageRows instance, see srnd/model.go )
|
||||
- postgraph ( markup of postsGraph instance , see srnd/model.go )
|
||||
- overview ( markup of overviewModel instance , see srnd/model.go )
|
||||
- totalposts ( the number of total posts we have ever seen )
|
||||
- frontend ( the name of the frontend )
|
||||
- prefix ( the site's prefix )
|
||||
@@ -12,64 +12,77 @@
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="{{prefix}}static/site.css" />
|
||||
<link rel="stylesheet" href="{{prefix}}static/user.css" />
|
||||
<link id="current_theme" rel="stylesheet" href="{{prefix}}static/user.css" />
|
||||
<script src="{{prefix}}static/nntpchan.js" type="text/javascript"></script>
|
||||
<title> {{frontend}} on nntpchan </title>
|
||||
</head>
|
||||
<body>
|
||||
{{{navbar}}}
|
||||
<center>
|
||||
<div class="index-outer">
|
||||
<div class="index-inner">
|
||||
<h1> {{frontend}} on nntpchan </h1>
|
||||
<h2>View the <a href="ukko.html">overboard</a></h2>
|
||||
<h3>Read the <a href="{{prefix}}static/faq.html">FAQ</a></h3>
|
||||
<h3>Join the IRC on <a href="https://qchat.rizon.net/?channels=#nntpchan">rizon</a> or <a href="irc://127.0.0.1:6668/overchan">irc2p</a></h3>
|
||||
<h3>Lurk on <a href="irc://allyour4nert7pkh.onion/overchan">URC</a></h3>
|
||||
<h3>Check out the <a href="{{prefix}}boards.html">board list</a></h3>
|
||||
<h3>Fork on github: <a href="https://github.com/majestrate/nntpchan/">frontend</a> and <a href="https://github.com/majestrate/srndv2/">core</a></h3>
|
||||
<h4>We've Had {{totalposts}} Posts Since August 01 2015 </h4>
|
||||
</div>
|
||||
<div class="index-inner">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="posts_td">
|
||||
{{{postsgraph.Render}}}
|
||||
</td>
|
||||
<td class="board_td">
|
||||
{{! todo: move boardgraph into its own file like postsgraph }}
|
||||
<table id="board_graph">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th> Board </th>
|
||||
<th> Posts this Hour </th>
|
||||
<th> Posts Today </th>
|
||||
<th> Total </th>
|
||||
</tr>
|
||||
{{# boardgraph}}
|
||||
<div class="index-outer">
|
||||
<div id="nntpchan_banner">
|
||||
</div>
|
||||
<div class="index-inner">
|
||||
<div>{{frontend}} on nntpchan</div>
|
||||
<div>View the <a href="{{prefix}}ukko.html">overboard</a></div>
|
||||
<div>Join the IRC on <a href="https://qchat.rizon.net/?channels=#nntpchan">rizon</a> or <a href="irc://127.0.0.1:6668/overchan">irc2p</a></div>
|
||||
<div>Check out the <a href="{{prefix}}boards.html">board list</a></div>
|
||||
<div>Fork on github: <a href="https://github.com/majestrate/nntpchan/">frontend</a> and <a href="https://github.com/majestrate/srndv2/">core</a></div>
|
||||
<div>We've Had {{totalposts}} Posts Since August 01 2015 </div>
|
||||
</div>
|
||||
<div class="index-inner">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="posts_td">
|
||||
{{{postsgraph}}}
|
||||
</td>
|
||||
<td class="board_td">
|
||||
{{! todo: move boardgraph into its own file like postsgraph }}
|
||||
<table id="board_graph">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{{prefix}}{{Board}}-0.html">{{Board}}</a>
|
||||
</td>
|
||||
<td>
|
||||
{{Hour}}
|
||||
</td>
|
||||
<td>
|
||||
{{Day}}
|
||||
</td>
|
||||
<td>
|
||||
{{All}}
|
||||
</td>
|
||||
<th> {{#i18n.Translations}}{{board_label}}{{/i18n.Translations}} </th>
|
||||
<th> {{#i18n.Translations}}{{posts_hour}}{{/i18n.Translations}} </th>
|
||||
<th> {{#i18n.Translations}}{{posts_today}}{{/i18n.Translations}} </th>
|
||||
<th> {{#i18n.Translations}}{{total}}{{/i18n.Translations}} </th>
|
||||
</tr>
|
||||
{{/ boardgraph}}
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{{{overview.Render}}}
|
||||
</thead>
|
||||
<tbody>
|
||||
{{# boardgraph}}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{{prefix}}{{Board}}-0.html">{{Board}}</a>
|
||||
</td>
|
||||
<td>
|
||||
{{Hour}}
|
||||
</td>
|
||||
<td>
|
||||
{{Day}}
|
||||
</td>
|
||||
<td>
|
||||
{{All}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/ boardgraph}}
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{{{overview}}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</center>
|
||||
<script type="text/javascript">
|
||||
var e = document.getElementById("nntpchan_banner");
|
||||
nntpchan_inject_banners(e, "{{prefix}}");
|
||||
</script>
|
||||
<hr/>
|
||||
<footer>
|
||||
<p class="legal">All posts on this site are the responsibility of the individual poster and not the administration, pursuant to 47 U.S.C. § 230.</p>
|
||||
<p class="legal">To make a DMCA request or report illegal content, please contact the administration</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -4,20 +4,21 @@ template parameters:
|
||||
- history ( a list of PostEntry instances, see srnd/model.go )
|
||||
|
||||
}}
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"></meta>
|
||||
<link rel="stylesheet" href="{{prefix}}static/site.css" />
|
||||
<link rel="stylesheet" href="{{prefix}}static/user.css" />
|
||||
<title> Post History</title>
|
||||
<title>{{#i18n.Translations}}{{post_history_title}}{{/i18n.Translations}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<td>
|
||||
<table id="history_graph">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Month</th>
|
||||
<th>Posts</th>
|
||||
<th>{{#i18n.Translations}}{{month}}{{/i18n.Translations}}</th>
|
||||
<th>{{#i18n.Translations}}{{posts}}{{/i18n.Translations}}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
64
contrib/templates/default/inst_api.mustache
Normal file
@@ -0,0 +1,64 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="initial-scale=1" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/site.css" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/user.css" />
|
||||
<script type="text/javascript" src="{{board.Prefix}}static/nntpchan.js"></script>
|
||||
<title>{{#i18n.Translations}}{{api_install_title}}{{/i18n.Translations}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="installer_header">{{#i18n.Translations}}{{api_install_title}}{{/i18n.Translations}}</div>
|
||||
{{#dialog.HasError}}
|
||||
<p class="installer_error">{{dialog.Error}}</p>
|
||||
{{/dialog.HasError}}
|
||||
<form action="" method="post" autocomplete="off">
|
||||
<div id="install-outer">
|
||||
<div id="installer-inner">
|
||||
<table class="installer-tab">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{api_username}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="user" value="{{dialog.User}}">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{api_password_name}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="password" name="pass" value="">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{api_secret_name}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="secret" value="{{dialog.Secret}}">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{#dialog.HasNext}}
|
||||
<input type="submit" value="{{#i18n.Translations}}{{next_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
{{/dialog.HasNext}}
|
||||
{{^dialog.HasNext}}
|
||||
<input type="submit" value="{{#i18n.Translations}}{{finish_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
{{/dialog.HasNext}}
|
||||
</div>
|
||||
</form>
|
||||
{{#dialog.HasPrevious}}
|
||||
<div class="back_button">
|
||||
<form action="" method="post">
|
||||
<input type="hidden" name="back" value="true" />
|
||||
<input type="submit" value="{{#i18n.Translations}}{{previous_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
</form>
|
||||
</div>
|
||||
{{/dialog.HasPrevious}}
|
||||
</body>
|
||||
</html>
|
||||
64
contrib/templates/default/inst_bins.mustache
Normal file
@@ -0,0 +1,64 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="initial-scale=1" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/site.css" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/user.css" />
|
||||
<script type="text/javascript" src="{{board.Prefix}}static/nntpchan.js"></script>
|
||||
<title>{{#i18n.Translations}}{{binary_install_title}}{{/i18n.Translations}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="installer_header">{{#i18n.Translations}}{{binary_install_title}}{{/i18n.Translations}}</div>
|
||||
{{#dialog.HasError}}
|
||||
<p class="installer_error">{{dialog.Error}}</p>
|
||||
{{/dialog.HasError}}
|
||||
<form action="" method="post" autocomplete="off">
|
||||
<div id="install-outer">
|
||||
<div id="installer-inner">
|
||||
<table class="installer-tab">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{convert_prompt}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="convert" value="{{dialog.Convert}}">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{ffmpeg_prompt}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="ffmpeg" value="{{dialog.FFmpeg}}">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{sox_prompt}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="sox" value="{{dialog.Sox}}">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{#dialog.HasNext}}
|
||||
<input type="submit" value="{{#i18n.Translations}}{{next_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
{{/dialog.HasNext}}
|
||||
{{^dialog.HasNext}}
|
||||
<input type="submit" value="{{#i18n.Translations}}{{finish_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
{{/dialog.HasNext}}
|
||||
</div>
|
||||
</form>
|
||||
{{#dialog.HasPrevious}}
|
||||
<div class="back_button">
|
||||
<form action="" method="post">
|
||||
<input type="hidden" name="back" value="true" />
|
||||
<input type="submit" value="{{#i18n.Translations}}{{previous_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
</form>
|
||||
</div>
|
||||
{{/dialog.HasPrevious}}
|
||||
</body>
|
||||
</html>
|
||||
64
contrib/templates/default/inst_cache.mustache
Normal file
@@ -0,0 +1,64 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="initial-scale=1" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/site.css" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/user.css" />
|
||||
<script type="text/javascript" src="{{board.Prefix}}static/nntpchan.js"></script>
|
||||
<title>{{#i18n.Translations}}{{cache_install_title}}{{/i18n.Translations}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="installer_header">{{#i18n.Translations}}{{cache_install_title}}{{/i18n.Translations}}</div>
|
||||
{{#dialog.HasError}}
|
||||
<p class="installer_error">{{dialog.Error}}</p>
|
||||
{{/dialog.HasError}}
|
||||
<form action="" method="post">
|
||||
<div id="install-outer">
|
||||
<div id="installer-inner">
|
||||
<table class="installer-tab">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>
|
||||
|
||||
</th>
|
||||
<td>
|
||||
<input type="radio" name="cache" value="file" checked> {{#i18n.Translations}}{{file_cache_name}}{{/i18n.Translations}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
|
||||
</th>
|
||||
<td>
|
||||
<input type="radio" name="cache" value="null"> {{#i18n.Translations}}{{null_cache_name}}{{/i18n.Translations}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
|
||||
</th>
|
||||
<td>
|
||||
<input type="radio" name="cache" value="redis"> {{#i18n.Translations}}{{redis_cache_name}}{{/i18n.Translations}}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{#dialog.HasNext}}
|
||||
<input type="submit" value="{{#i18n.Translations}}{{next_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
{{/dialog.HasNext}}
|
||||
{{^dialog.HasNext}}
|
||||
<input type="submit" value="{{#i18n.Translations}}{{finish_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
{{/dialog.HasNext}}
|
||||
</div>
|
||||
</form>
|
||||
{{#dialog.HasPrevious}}
|
||||
<div class="back_button">
|
||||
<form action="" method="post">
|
||||
<input type="hidden" name="back" value="true" />
|
||||
<input type="submit" value="{{#i18n.Translations}}{{previous_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
</form>
|
||||
</div>
|
||||
{{/dialog.HasPrevious}}
|
||||
</body>
|
||||
</html>
|
||||
56
contrib/templates/default/inst_crypto.mustache
Normal file
@@ -0,0 +1,56 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="initial-scale=1" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/site.css" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/user.css" />
|
||||
<script type="text/javascript" src="{{board.Prefix}}static/nntpchan.js"></script>
|
||||
<title>{{#i18n.Translations}}{{crypto_install_title}}{{/i18n.Translations}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="installer_header">{{#i18n.Translations}}{{crypto_install_title}}{{/i18n.Translations}}</div>
|
||||
{{#dialog.HasError}}
|
||||
<p class="installer_error">{{dialog.Error}}</p>
|
||||
{{/dialog.HasError}}
|
||||
<form action="" method="post" autocomplete="off">
|
||||
<div id="install-outer">
|
||||
<div id="installer-inner">
|
||||
<table class="installer-tab">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{host_name}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="host" value="{{dialog.Host}}">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{key_name}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="key" value="{{dialog.Key}}">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{#dialog.HasNext}}
|
||||
<input type="submit" value="{{#i18n.Translations}}{{next_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
{{/dialog.HasNext}}
|
||||
{{^dialog.HasNext}}
|
||||
<input type="submit" value="{{#i18n.Translations}}{{finish_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
{{/dialog.HasNext}}
|
||||
</div>
|
||||
</form>
|
||||
{{#dialog.HasPrevious}}
|
||||
<div class="back_button">
|
||||
<form action="" method="post">
|
||||
<input type="hidden" name="back" value="true" />
|
||||
<input type="submit" value="{{#i18n.Translations}}{{previous_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
</form>
|
||||
</div>
|
||||
{{/dialog.HasPrevious}}
|
||||
</body>
|
||||
</html>
|
||||
56
contrib/templates/default/inst_db.mustache
Normal file
@@ -0,0 +1,56 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="initial-scale=1" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/site.css" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/user.css" />
|
||||
<script type="text/javascript" src="{{board.Prefix}}static/nntpchan.js"></script>
|
||||
<title>{{#i18n.Translations}}{{db_install_title}}{{/i18n.Translations}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="installer_header">{{#i18n.Translations}}{{db_install_title}}{{/i18n.Translations}}</div>
|
||||
{{#dialog.HasError}}
|
||||
<p class="installer_error">{{dialog.Error}}</p>
|
||||
{{/dialog.HasError}}
|
||||
<form action="" method="post">
|
||||
<div id="install-outer">
|
||||
<div id="installer-inner">
|
||||
<table class="installer-tab">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>
|
||||
|
||||
</th>
|
||||
<td>
|
||||
<input type="radio" name="db" value="postgres"> {{#i18n.Translations}}{{postgres_name}}{{/i18n.Translations}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
|
||||
</th>
|
||||
<td>
|
||||
<input type="radio" name="db" value="redis" checked> {{#i18n.Translations}}{{redis_name}}{{/i18n.Translations}}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{#dialog.HasNext}}
|
||||
<input type="submit" value="{{#i18n.Translations}}{{next_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
{{/dialog.HasNext}}
|
||||
{{^dialog.HasNext}}
|
||||
<input type="submit" value="{{#i18n.Translations}}{{finish_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
{{/dialog.HasNext}}
|
||||
</div>
|
||||
</form>
|
||||
{{#dialog.HasPrevious}}
|
||||
<div class="back_button">
|
||||
<form action="" method="post">
|
||||
<input type="hidden" name="back" value="true" />
|
||||
<input type="submit" value="{{#i18n.Translations}}{{previous_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
</form>
|
||||
</div>
|
||||
{{/dialog.HasPrevious}}
|
||||
</body>
|
||||
</html>
|
||||
72
contrib/templates/default/inst_frontend.mustache
Normal file
@@ -0,0 +1,72 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="initial-scale=1" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/site.css" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/user.css" />
|
||||
<script type="text/javascript" src="{{board.Prefix}}static/nntpchan.js"></script>
|
||||
<title>{{#i18n.Translations}}{{frontend_install_title}}{{/i18n.Translations}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="installer_header">{{#i18n.Translations}}{{frontend_install_title}}{{/i18n.Translations}}</div>
|
||||
{{#dialog.HasError}}
|
||||
<p class="installer_error">{{dialog.Error}}</p>
|
||||
{{/dialog.HasError}}
|
||||
<form action="" method="post" autocomplete="off">
|
||||
<div id="install-outer">
|
||||
<div id="installer-inner">
|
||||
<table class="installer-tab">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{frontend_name}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="name" value="{{dialog.Name}}">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{locale_name}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="locale" value="{{dialog.Locale}}">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{allow_files_prompt}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="checkbox" name="allow_files" value="1" checked>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{enable_json_prompt}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="checkbox" name="json" value="1">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{#dialog.HasNext}}
|
||||
<input type="submit" value="{{#i18n.Translations}}{{next_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
{{/dialog.HasNext}}
|
||||
{{^dialog.HasNext}}
|
||||
<input type="submit" value="{{#i18n.Translations}}{{finish_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
{{/dialog.HasNext}}
|
||||
</div>
|
||||
</form>
|
||||
{{#dialog.HasPrevious}}
|
||||
<div class="back_button">
|
||||
<form action="" method="post">
|
||||
<input type="hidden" name="back" value="true" />
|
||||
<input type="submit" value="{{#i18n.Translations}}{{previous_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
</form>
|
||||
</div>
|
||||
{{/dialog.HasPrevious}}
|
||||
</body>
|
||||
</html>
|
||||
56
contrib/templates/default/inst_key.mustache
Normal file
@@ -0,0 +1,56 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="initial-scale=1" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/site.css" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/user.css" />
|
||||
<script type="text/javascript" src="{{board.Prefix}}static/nntpchan.js"></script>
|
||||
<title>{{#i18n.Translations}}{{key_install_title}}{{/i18n.Translations}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="installer_header">{{#i18n.Translations}}{{key_install_title}}{{/i18n.Translations}}</div>
|
||||
{{#dialog.HasError}}
|
||||
<p class="installer_error">{{dialog.Error}}</p>
|
||||
{{/dialog.HasError}}
|
||||
<form action="" method="post" autocomplete="off">
|
||||
<div id="install-outer">
|
||||
<div id="installer-inner">
|
||||
<table class="installer-tab">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{pubkey_name}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="public" value="{{dialog.Public}}" size="65" readonly>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{secretkey_name}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="secret" value="{{dialog.Secret}}" size="65" readonly>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{#dialog.HasNext}}
|
||||
<input type="submit" value="{{#i18n.Translations}}{{next_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
{{/dialog.HasNext}}
|
||||
{{^dialog.HasNext}}
|
||||
<input type="submit" value="{{#i18n.Translations}}{{finish_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
{{/dialog.HasNext}}
|
||||
</div>
|
||||
</form>
|
||||
{{#dialog.HasPrevious}}
|
||||
<div class="back_button">
|
||||
<form action="" method="post">
|
||||
<input type="hidden" name="back" value="true" />
|
||||
<input type="submit" value="{{#i18n.Translations}}{{previous_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
</form>
|
||||
</div>
|
||||
{{/dialog.HasPrevious}}
|
||||
</body>
|
||||
</html>
|
||||
80
contrib/templates/default/inst_nntp.mustache
Normal file
@@ -0,0 +1,80 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="initial-scale=1" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/site.css" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/user.css" />
|
||||
<script type="text/javascript" src="{{board.Prefix}}static/nntpchan.js"></script>
|
||||
<title>{{#i18n.Translations}}{{nntp_install_title}}{{/i18n.Translations}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="installer_header">{{#i18n.Translations}}{{nntp_install_title}}{{/i18n.Translations}}</div>
|
||||
{{#dialog.HasError}}
|
||||
<p class="installer_error">{{dialog.Error}}</p>
|
||||
{{/dialog.HasError}}
|
||||
<form action="" method="post" autocomplete="off">
|
||||
<div id="install-outer">
|
||||
<div id="installer-inner">
|
||||
<table class="installer-tab">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{nntp_name}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="nntp_name" value="{{dialog.Name}}">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{allow_attachments_prompt}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="checkbox" name="allow_attachments" value="1" checked>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{allow_anon_prompt}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="checkbox" name="allow_anon" value="1" checked>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{allow_anon_attachments_prompt}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="checkbox" name="allow_anon_attachments" value="1">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{require_tls_prompt}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="checkbox" name="require_tls" value="1" checked>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{#dialog.HasNext}}
|
||||
<input type="submit" value="{{#i18n.Translations}}{{next_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
{{/dialog.HasNext}}
|
||||
{{^dialog.HasNext}}
|
||||
<input type="submit" value="{{#i18n.Translations}}{{finish_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
{{/dialog.HasNext}}
|
||||
</div>
|
||||
</form>
|
||||
{{#dialog.HasPrevious}}
|
||||
<div class="back_button">
|
||||
<form action="" method="post">
|
||||
<input type="hidden" name="back" value="true" />
|
||||
<input type="submit" value="{{#i18n.Translations}}{{previous_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
</form>
|
||||
</div>
|
||||
{{/dialog.HasPrevious}}
|
||||
</body>
|
||||
</html>
|
||||
72
contrib/templates/default/inst_postgres_db.mustache
Normal file
@@ -0,0 +1,72 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="initial-scale=1" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/site.css" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/user.css" />
|
||||
<script type="text/javascript" src="{{board.Prefix}}static/nntpchan.js"></script>
|
||||
<title>{{#i18n.Translations}}{{postgres_db_install_title}}{{/i18n.Translations}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="installer_header">{{#i18n.Translations}}{{postgres_db_install_title}}{{/i18n.Translations}}</div>
|
||||
{{#dialog.HasError}}
|
||||
<p class="installer_error">{{dialog.Error}}</p>
|
||||
{{/dialog.HasError}}
|
||||
<form action="" method="post" autocomplete="off">
|
||||
<div id="install-outer">
|
||||
<div id="installer-inner">
|
||||
<table class="installer-tab">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{host_name}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="host" value="{{dialog.Host}}">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{port_name}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="port" value="{{dialog.Port}}">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{username_name}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="user" value="{{dialog.Username}}">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{password_name}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="password" name="password" value="">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{#dialog.HasNext}}
|
||||
<input type="submit" value="{{#i18n.Translations}}{{next_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
{{/dialog.HasNext}}
|
||||
{{^dialog.HasNext}}
|
||||
<input type="submit" value="{{#i18n.Translations}}{{finish_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
{{/dialog.HasNext}}
|
||||
</div>
|
||||
</form>
|
||||
{{#dialog.HasPrevious}}
|
||||
<div class="back_button">
|
||||
<form action="" method="post">
|
||||
<input type="hidden" name="back" value="true" />
|
||||
<input type="submit" value="{{#i18n.Translations}}{{previous_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
</form>
|
||||
</div>
|
||||
{{/dialog.HasPrevious}}
|
||||
</body>
|
||||
</html>
|
||||
64
contrib/templates/default/inst_redis_cache.mustache
Normal file
@@ -0,0 +1,64 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="initial-scale=1" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/site.css" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/user.css" />
|
||||
<script type="text/javascript" src="{{board.Prefix}}static/nntpchan.js"></script>
|
||||
<title>{{#i18n.Translations}}{{redis_db_install_title}}{{/i18n.Translations}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="installer_header">{{#i18n.Translations}}{{redis_db_install_title}}{{/i18n.Translations}}</div>
|
||||
{{#dialog.HasError}}
|
||||
<p class="installer_error">{{dialog.Error}}</p>
|
||||
{{/dialog.HasError}}
|
||||
<form action="" method="post" autocomplete="off">
|
||||
<div id="install-outer">
|
||||
<div id="installer-inner">
|
||||
<table class="installer-tab">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{host_name}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="host" value="{{dialog.Host}}">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{port_name}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="port" value="{{dialog.Port}}">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{password_name}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="password" name="password" value="">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{#dialog.HasNext}}
|
||||
<input type="submit" value="{{#i18n.Translations}}{{next_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
{{/dialog.HasNext}}
|
||||
{{^dialog.HasNext}}
|
||||
<input type="submit" value="{{#i18n.Translations}}{{finish_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
{{/dialog.HasNext}}
|
||||
</div>
|
||||
</form>
|
||||
{{#dialog.HasPrevious}}
|
||||
<div class="back_button">
|
||||
<form action="" method="post">
|
||||
<input type="hidden" name="back" value="true" />
|
||||
<input type="submit" value="{{#i18n.Translations}}{{previous_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
</form>
|
||||
</div>
|
||||
{{/dialog.HasPrevious}}
|
||||
</body>
|
||||
</html>
|
||||
64
contrib/templates/default/inst_redis_db.mustache
Normal file
@@ -0,0 +1,64 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="initial-scale=1" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/site.css" />
|
||||
<link rel="stylesheet" href="{{board.Prefix}}static/user.css" />
|
||||
<script type="text/javascript" src="{{board.Prefix}}static/nntpchan.js"></script>
|
||||
<title>{{#i18n.Translations}}{{redis_db_install_title}}{{/i18n.Translations}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="installer_header">{{#i18n.Translations}}{{redis_db_install_title}}{{/i18n.Translations}}</div>
|
||||
{{#dialog.HasError}}
|
||||
<p class="installer_error">{{dialog.Error}}</p>
|
||||
{{/dialog.HasError}}
|
||||
<form action="" method="post" autocomplete="off">
|
||||
<div id="install-outer">
|
||||
<div id="installer-inner">
|
||||
<table class="installer-tab">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{host_name}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="host" value="{{dialog.Host}}">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{port_name}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="port" value="{{dialog.Port}}">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{{#i18n.Translations}}{{password_name}}{{/i18n.Translations}}
|
||||
</th>
|
||||
<td>
|
||||
<input type="password" name="password" value="">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{#dialog.HasNext}}
|
||||
<input type="submit" value="{{#i18n.Translations}}{{next_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
{{/dialog.HasNext}}
|
||||
{{^dialog.HasNext}}
|
||||
<input type="submit" value="{{#i18n.Translations}}{{finish_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
{{/dialog.HasNext}}
|
||||
</div>
|
||||
</form>
|
||||
{{#dialog.HasPrevious}}
|
||||
<div class="back_button">
|
||||
<form action="" method="post">
|
||||
<input type="hidden" name="back" value="true" />
|
||||
<input type="submit" value="{{#i18n.Translations}}{{previous_prompt}}{{/i18n.Translations}}" class="button" />
|
||||
</form>
|
||||
</div>
|
||||
{{/dialog.HasPrevious}}
|
||||
</body>
|
||||
</html>
|
||||
@@ -5,17 +5,19 @@
|
||||
- public ( the public key in hex )
|
||||
- secret ( the secret key in hex )
|
||||
- tripcode ( html version of the public key )
|
||||
}}
|
||||
}}
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"></meta>
|
||||
<link rel="stylesheet" href="{{prefix}}static/site.css" />
|
||||
<link rel="stylesheet" href="{{prefix}}static/user.css" />
|
||||
<title> here is a new tripcode </title>
|
||||
<link id="current_theme" rel="stylesheet" href="{{prefix}}static/user.css" />
|
||||
<script type="text/javascript" src="{{prefix}}static/nntpchan.js"></script>
|
||||
<title>{{#i18n.Translations}}{{new_tripcode_title}}{{/i18n.Translations}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<pre>New Tripcode:
|
||||
<div id="secret_key">secret: {{secret}}</div><div id="public_key">public: {{public}}</div><div>tripcode: <span class="tripcode" id="capcode_key">{{{tripcode}}}</span></div>
|
||||
<pre>{{#i18n.Translations}}{{new_tripcode_label}}{{/i18n.Translations}}:
|
||||
<div id="secret_key">{{#i18n.Translations}}{{secret_key}}{{/i18n.Translations}}: {{secret}}</div><div id="public_key">{{#i18n.Translations}}{{public_key}}{{/i18n.Translations}}: {{public}}</div><div>{{#i18n.Translations}}{{tripcode}}{{/i18n.Translations}}: <span class="tripcode" id="capcode_key">{{{tripcode}}}</span></div>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
32
contrib/templates/default/live.mustache
Normal file
@@ -0,0 +1,32 @@
|
||||
{{!
|
||||
live.mustache -- live ui
|
||||
template parameters:
|
||||
- prefix ( site prefix )
|
||||
}}
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title> {{#i18n.Translations}}{{overboard_title}}{{/i18n.Translations}} </title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="initial-scale = 1.0,maximum-scale = 1.0" />
|
||||
<link rel="stylesheet" href="{{prefix}}static/livechan.css" />
|
||||
<link id="current_theme" rel="stylesheet" href="{{prefix}}static/user.css" />
|
||||
<style type="text/css" id="convo_filter">
|
||||
</style>
|
||||
<script type="text/javascript" src="{{prefix}}static/nntpchan.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>you need js for livechan mode</noscript>
|
||||
<script type="text/javascript" >
|
||||
var e = document.createElement("div");
|
||||
e.setAttribute("id", "chat");
|
||||
e.setAttribute("style", "position:fixed;left:0;right:0;top:0;bottom:0;width:100%;height:100%;");
|
||||
document.body.appendChild(e);
|
||||
var board = "";
|
||||
if (location.hash != "" ) {
|
||||
board = location.hash.substr(1);
|
||||
}
|
||||
new Chat(e, board, { prefix : "{{prefix}}" });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
49
contrib/templates/default/modfeed.mustache
Normal file
@@ -0,0 +1,49 @@
|
||||
{{!
|
||||
modpage.mustache -- the moderator panel when logged in
|
||||
template parameters:
|
||||
- prefix ( the site's prefix )
|
||||
|
||||
}}
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="{{prefix}}static/site.css" />
|
||||
<link id="current_theme" rel="stylesheet" href="{{prefix}}static/user.css" />
|
||||
<!-- yes it uses js -->
|
||||
<script type="text/javascript" src="{{prefix}}static/nntpchan.js"></script>
|
||||
<script type="text/javascript" src="{{prefix}}static/mod.js"></script>
|
||||
<script type="text/javascript" src="{{prefix}}static/feed.js"></script>
|
||||
<title> {{#i18n.Translations}}{{modpage_title}}{{/i18n.Translations}} </title>
|
||||
</head>
|
||||
<body onload="main()">
|
||||
<div id="nntpchan_mod_result"></div>
|
||||
<div class="nntpchan_feed_pane">
|
||||
<pre> Add Feed </pre>
|
||||
<label for="add_feed_host">Host</label>
|
||||
<input id="add_feed_host" />
|
||||
<label for="add_feed_host">Port</label>
|
||||
<input id="add_feed_port" />
|
||||
<label for="add_feed_name">Name</label>
|
||||
<input id="add_feed_name" />
|
||||
<button onclick="nntp_feed_add()">Add</button>
|
||||
</div>
|
||||
<div class="nntpchan_feed_pane">
|
||||
<pre> Remove Feed </pre>
|
||||
<label for="del_feed_name">Name</label>
|
||||
<input id="del_feed_name" />
|
||||
<button onclick="nntp_feed_del()">Remove</button>
|
||||
</div>
|
||||
<div class="nntpchan_feed_pane">
|
||||
<pre> Sync Feeds </pre>
|
||||
<button onclick="nntpchan_admin('feed.sync')">Sync All</button>
|
||||
</div>
|
||||
<div id="nntpchan_feed_result"></div>
|
||||
<div id="nntpchan_feeds"></div>
|
||||
<script>
|
||||
nntp_feed_update();
|
||||
</script>
|
||||
<noscript>
|
||||
<b>{{#i18n.Translations}}{{nojs_info}}{{/i18n.Translations}}</b>
|
||||
</noscript>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,14 +1,16 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="{{prefix}}static/site.css" />
|
||||
<link rel="stylesheet" href="{{prefix}}static/user.css" />
|
||||
<title>login</title>
|
||||
<link id="current_theme" rel="stylesheet" href="{{prefix}}static/user.css" />
|
||||
<title>{{#i18n.Translations}}{{login}}{{/i18n.Translations}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<form action="login" method="POST" name="modlogin">
|
||||
<label for="mod_key">secret</label>
|
||||
<label for="mod_key">{{#i18n.Translations}}{{secret_key}}{{/i18n.Translations}}</label>
|
||||
<input type="password" id="mod_key" name="privkey" />
|
||||
<input type="submit" value="login" />
|
||||
<input type="submit" value="{{#i18n.Translations}}{{login}}{{/i18n.Translations}}" />
|
||||
{{{csrfField}}}
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -5,15 +5,16 @@
|
||||
- mod_prefix ( the prefix to the mod panel, could be something like https://mod.site.tld/ or /mod/ )
|
||||
- message ( the message returned from the login attempt )
|
||||
- fail ( present if the login failed ) // not yet added
|
||||
}}
|
||||
}}
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="{{prefix}}static/site.css" />
|
||||
<link rel="stylesheet" href="{{prefix}}static/user.css" />
|
||||
<meta http-equiv="refresh" content="1; {{mod_prefix}}"></meta>
|
||||
<title>login</title>
|
||||
<title>{{#i18n.Translations}}{{login}}{{/i18n.Translations}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>{{message}}</p>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -3,82 +3,107 @@
|
||||
template parameters:
|
||||
- prefix ( the site's prefix )
|
||||
|
||||
}}
|
||||
}}
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="{{prefix}}static/site.css" />
|
||||
<link rel="stylesheet" href="{{prefix}}static/user.css" />
|
||||
<link id="current_theme" rel="stylesheet" href="{{prefix}}static/user.css" />
|
||||
<!-- yes it uses js -->
|
||||
<script type="text/javascript" src="{{prefix}}static/nntpchan.js"></script>
|
||||
<script type="text/javascript" src="{{prefix}}static/mod.js"></script>
|
||||
<title> nntpchan mod page </title>
|
||||
<title> {{#i18n.Translations}}{{modpage_title}}{{/i18n.Translations}} </title>
|
||||
</head>
|
||||
<body>
|
||||
<body onload="main()">
|
||||
<div>
|
||||
<div> post actions </div>
|
||||
<div> {{#i18n.Translations}}{{post_actions_label}}{{/i18n.Translations}} </div>
|
||||
<hr />
|
||||
<div>
|
||||
<label for="nntpchan_mod_target">target</label>
|
||||
<label for="nntpchan_mod_target">{{#i18n.Translations}}{{target_label}}{{/i18n.Translations}}</label>
|
||||
<input id="nntpchan_mod_target" type="text" />
|
||||
</div>
|
||||
<div>
|
||||
<button onclick="nntpchan_ban()">ban (url)</button>
|
||||
<button onclick="nntpchan_delete()">delete (url)</button>
|
||||
<button onclick="nntpchan_unban()">unban (ip)</button>
|
||||
<button onclick="nntpchan_ban()">{{#i18n.Translations}}{{ban_url_prompt}}{{/i18n.Translations}}</button>
|
||||
<button onclick="nntpchan_delete()">{{#i18n.Translations}}{{delete_url_prompt}}{{/i18n.Translations}}</button>
|
||||
<button onclick="nntpchan_unban()">{{#i18n.Translations}}{{unban_ip_prompt}}{{/i18n.Translations}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<div>
|
||||
<div> key actions </div>
|
||||
<div> {{#i18n.Translations}}{{key_actions_label}}{{/i18n.Translations}} </div>
|
||||
<div>
|
||||
<label for="nntpchan_board_target">pubkey:</label>
|
||||
<label for="nntpchan_board_target">{{#i18n.Translations}}{{pubkey_label}}{{/i18n.Translations}}:</label>
|
||||
<input type="text" id="nntpchan_key_target" />
|
||||
</div>
|
||||
<div>
|
||||
<button onclick="nntpchan_key_add()">add key</button>
|
||||
<button onclick="nntpchan_key_del()">remove key</button>
|
||||
<button onclick="nntpchan_key_add()">{{#i18n.Translations}}{{add_key_prompt}}{{/i18n.Translations}}</button>
|
||||
<button onclick="nntpchan_key_del()">{{#i18n.Translations}}{{remove_key_prompt}}{{/i18n.Translations}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<div>
|
||||
<div> board actions </div>
|
||||
<div> {{#i18n.Translations}}{{nntp_login_label}}{{/i18n.Translations}} </div>
|
||||
<div>
|
||||
<label for="nntpchan_board_target">board name:</label>
|
||||
<input type="text" id="nntpchan_board_target" />
|
||||
<label for="nntpchan_nntp_username">{{#i18n.Translations}}{{username}}{{/i18n.Translations}}:</label>
|
||||
<input id="nntpchan_nntp_username" />
|
||||
</div>
|
||||
<div>
|
||||
<button onclick="nntpchan_admin_board('frontend.add')">add board</button>
|
||||
<label for="nntpchan_nntp_passwd">{{#i18n.Translations}}{{password}}{{/i18n.Translations}}:</label>
|
||||
<input type="password" id="nntpchan_nntp_passwd" />
|
||||
</div>
|
||||
<div>
|
||||
<button onclick="nntpchan_admin_board('frontend.regen')">regenerate</button>
|
||||
<button onclick="nntpchan_admin_nntp('nntp.login.add')">{{#i18n.Translations}}{{add_user_prompt}}{{/i18n.Translations}}</button>
|
||||
</div>
|
||||
<div>
|
||||
<button onclick="nntpchan_admin_nntp('nntp.login.del')">{{#i18n.Translations}}{{remove_user_prompt}}{{/i18n.Translations}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<div>
|
||||
<div> {{#i18n.Translations}}{{board_actions_label}}{{/i18n.Translations}} </div>
|
||||
<div>
|
||||
<label for="nntpchan_board_target">{{#i18n.Translations}}{{board_name_title}}{{/i18n.Translations}}:</label>
|
||||
<input id="nntpchan_board_target" />
|
||||
</div>
|
||||
<div>
|
||||
<button onclick="nntpchan_admin_board('frontend.add')">{{#i18n.Translations}}{{add_board_prompt}}{{/i18n.Translations}}</button>
|
||||
</div>
|
||||
<div>
|
||||
<button onclick="nntpchan_admin_board('frontend.regen')">{{#i18n.Translations}}{{regenerate_prompt}}{{/i18n.Translations}}</button>
|
||||
</div>
|
||||
<div>
|
||||
<button onclick="nntpchan_admin_board('frontend.ban')">ban</button>
|
||||
<button onclick="nntpchan_admin_board('frontend.unban')">unban</button>
|
||||
<button onclick="nntpchan_admin_board('frontend.ban')">{{#i18n.Translations}}{{ban_prompt}}{{/i18n.Translations}}</button>
|
||||
<button onclick="nntpchan_admin_board('frontend.unban')">{{#i18n.Translations}}{{unban_prompt}}{{/i18n.Translations}}</button>
|
||||
</div>
|
||||
<div>
|
||||
<button onclick="nntpchan_admin_board('frontend.nuke')">nuke</button>
|
||||
<button onclick="nntpchan_admin_board('frontend.nuke')">{{#i18n.Translations}}{{nuke_prompt}}{{/i18n.Translations}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<div>
|
||||
<div>
|
||||
lightweight actions
|
||||
{{#i18n.Translations}}{{light_actions_label}}{{/i18n.Translations}}
|
||||
</div>
|
||||
<div>
|
||||
<button onclick="nntpchan_admin('template.reload')">reload all templates</button>
|
||||
<button onclick="nntpchan_admin('template.reload')">{{#i18n.Translations}}{{reload_templates_prompt}}{{/i18n.Translations}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<div>
|
||||
<label>very load heavy actions, use with care</label>
|
||||
<label>{{#i18n.Translations}}{{heavy_actions_label}}{{/i18n.Translations}}</label>
|
||||
<div>
|
||||
<button onclick="nntpchan_admin('frontend.regen')">regenerate all pages</button>
|
||||
<button onclick="nntpchan_admin('thumbnail.regen')">regenerate all thumbnails</button>
|
||||
<button onclick="nntpchan_admin('frontend.regen')">{{#i18n.Translations}}{{regenerate_markup_prompt}}{{/i18n.Translations}}</button>
|
||||
<button onclick="nntpchan_admin('thumbnail.regen')">{{#i18n.Translations}}{{regenerate_thumbs_prompt}}{{/i18n.Translations}}</button>
|
||||
<button onclick="nntpchan_admin('feed.sync')">{{#i18n.Translations}}{{feed_sync_prompt}}{{/i18n.Translations}}</button>
|
||||
<button onclick="nntpchan_admin('store.expire')">{{#i18n.Translations}}{{expire_old_prompt}}{{/i18n.Translations}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<a href="{{prefix}}mod/feeds">nntp feed management</a>
|
||||
</div>
|
||||
<div id="nntpchan_mod_result"></div>
|
||||
<noscript>
|
||||
<b>enable js to use the mod panel kthx</b>
|
||||
<b>{{#i18n.Translations}}{{nojs_info}}{{/i18n.Translations}}</b>
|
||||
</noscript>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<div class="navbar">
|
||||
<span class="navbar-name">
|
||||
<span class="board_title">{{name}}</span>
|
||||
on
|
||||
{{#i18n.Translations}}{{navbar_on}}{{/i18n.Translations}}
|
||||
<span class="frontend_title">{{frontend}}</span>
|
||||
</span>
|
||||
<span class="navbar-sep">
|
||||
@@ -31,16 +31,25 @@
|
||||
|
|
||||
</span>
|
||||
<span class="navbar-links">
|
||||
<span class="navbar-link"><a href="{{prefix}}">front page</a></span>
|
||||
<span class="navbar-link"><a href="{{prefix}}">{{#i18n.Translations}}{{front_page_title}}{{/i18n.Translations}}</a></span>
|
||||
</span>
|
||||
<span class="navbar-sep">
|
||||
|
|
||||
</span>
|
||||
<span class="navbar-links">
|
||||
<span class="navbar-link"><a href="{{prefix}}ukko.html">overboard</a></span>
|
||||
<span class="navbar-link"><a href="{{prefix}}ukko.html">{{#i18n.Translations}}{{overboard_title}}{{/i18n.Translations}}</a></span>
|
||||
</span>
|
||||
<span class="navbar-sep">
|
||||
|
|
||||
</span>
|
||||
<span class="navbar-links">
|
||||
<span class="navbar-link"><label onclick="enable_theme('{{prefix}}','bloodgod')">bloodgod</a></span>
|
||||
<span class="navbar-link"><label onclick="enable_theme('{{prefix}}','dayman')">dayman</a></span>
|
||||
<span class="navbar-link"><label onclick="enable_theme('{{prefix}}','tomorrow')">tomorrow</a></span>
|
||||
<span class="navbar-link"><label onclick="enable_theme('{{prefix}}','site')">yotsuba</a></span>
|
||||
</span>
|
||||
<span class="navbar-sep">
|
||||
|
|
||||
</span>
|
||||
</div>
|
||||
<hr />
|
||||
<hr />
|
||||
|
||||