Compare commits
434 Commits
disable-no
...
throw-erro
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bb7f7bb4d1 | ||
|
|
389e49183c | ||
|
|
4c1a5f84fa | ||
|
|
b0bb156918 | ||
|
|
5565204273 | ||
|
|
d950a0ef5d | ||
|
|
b2c0f7efc3 | ||
|
|
9e58bc19c4 | ||
|
|
0d7e2afba4 | ||
|
|
e0d063d306 | ||
|
|
ed0ad587dc | ||
|
|
56fe591eee | ||
|
|
7b9693bca4 | ||
|
|
fd0417b14c | ||
|
|
89c12f2585 | ||
|
|
5c71adb137 | ||
|
|
4c23062d1e | ||
|
|
190b45086c | ||
|
|
008983c8e3 | ||
|
|
cb8a375c5e | ||
|
|
848a60aa9b | ||
|
|
88ea794fdb | ||
|
|
870350fd61 | ||
|
|
1e25894f7e | ||
|
|
223e74569a | ||
|
|
0a4d793556 | ||
|
|
5503914abe | ||
|
|
906466d7fb | ||
|
|
e2532de766 | ||
|
|
3ac4390d11 | ||
|
|
389ae7a573 | ||
|
|
176247091d | ||
|
|
e22cc73f32 | ||
|
|
c23ad25899 | ||
|
|
9cc0418769 | ||
|
|
925a2c8e77 | ||
|
|
390734d86e | ||
|
|
218f7be1a7 | ||
|
|
246955b68a | ||
|
|
d24506baed | ||
|
|
b0be2237fa | ||
|
|
945394fb1a | ||
|
|
19886f71f5 | ||
|
|
23855c09dc | ||
|
|
618ab01cd7 | ||
|
|
349d90b60e | ||
|
|
9e7c2dcdbb | ||
|
|
f353589a53 | ||
|
|
fc97929dee | ||
|
|
3d77642a1e | ||
|
|
b55c1a35bf | ||
|
|
5df700a56e | ||
|
|
0c64a86ebe | ||
|
|
644ba46945 | ||
|
|
4ab54f284c | ||
|
|
210c2a8855 | ||
|
|
0ed4f1a9a4 | ||
|
|
7e648840a1 | ||
|
|
5e090778ae | ||
|
|
049ed114fd | ||
|
|
88007a08f2 | ||
|
|
6c4ed282bb | ||
|
|
c8765385df | ||
|
|
0ed22c0be0 | ||
|
|
3ffef4b9fb | ||
|
|
ceeebceb3a | ||
|
|
0338b26d5c | ||
|
|
6577cc0c8c | ||
|
|
586000ca3d | ||
|
|
abc81ebd08 | ||
|
|
cd6c73e487 | ||
|
|
69ad57338f | ||
|
|
cbcf31a4f9 | ||
|
|
b19beac5b4 | ||
|
|
dc6d088e30 | ||
|
|
b0ad27af23 | ||
|
|
5f23c6358a | ||
|
|
da776c935f | ||
|
|
0a315783ef | ||
|
|
65061b0514 | ||
|
|
063e5e359e | ||
|
|
f460afca35 | ||
|
|
66a08ace1d | ||
|
|
68e65e968a | ||
|
|
1ba0ab982b | ||
|
|
8752b8bb3f | ||
|
|
168f86ef89 | ||
|
|
85927853f9 | ||
|
|
57f60bf173 | ||
|
|
d16c3ed40a | ||
|
|
e90f4a2cbf | ||
|
|
d00839ec68 | ||
|
|
ea35d92493 | ||
|
|
beb9894c47 | ||
|
|
5556a996cd | ||
|
|
f7b1dcc271 | ||
|
|
eb226e1dcf | ||
|
|
8332ad0f16 | ||
|
|
06af5a004e | ||
|
|
ce32873ef8 | ||
|
|
99bc230fe6 | ||
|
|
0e3820b634 | ||
|
|
eba84dcd78 | ||
|
|
864f27ef72 | ||
|
|
a8b72d8342 | ||
|
|
15d2cfba90 | ||
|
|
2851d993ad | ||
|
|
3f1d88282e | ||
|
|
cc9ce916c6 | ||
|
|
c7d468578f | ||
|
|
e0f6988eb5 | ||
|
|
09ff370ddc | ||
|
|
32ecf30c82 | ||
|
|
a62adccd3d | ||
|
|
c75bf35f59 | ||
|
|
3013782b7b | ||
|
|
81abebd144 | ||
|
|
140b6c1227 | ||
|
|
ac685f65e9 | ||
|
|
f6b1cbd5d0 | ||
|
|
7db6e43e3f | ||
|
|
6c73614a47 | ||
|
|
b5c54b4e41 | ||
|
|
8f1c84e6d4 | ||
|
|
d1df4af734 | ||
|
|
23cd04fe88 | ||
|
|
dbc7c97e0b | ||
|
|
2313ca8f72 | ||
|
|
9418ba1687 | ||
|
|
233491940c | ||
|
|
7708e7ab08 | ||
|
|
600bd38630 | ||
|
|
f7290dfcb6 | ||
|
|
e22f7583eb | ||
|
|
c0e85f5687 | ||
|
|
3593f67eb6 | ||
|
|
1b251264a6 | ||
|
|
93c1a1d42e | ||
|
|
d7f6b6b018 | ||
|
|
fd99f20404 | ||
|
|
2b1e1b11a3 | ||
|
|
96ac7f9f35 | ||
|
|
33da64a669 | ||
|
|
38eb4ccbc4 | ||
|
|
a57414307e | ||
|
|
7ad111e2f6 | ||
|
|
a402128a7d | ||
|
|
d3ab4a5145 | ||
|
|
4ae77bcef9 | ||
|
|
e84416e56d | ||
|
|
59ccc9d73e | ||
|
|
1533a28817 | ||
|
|
7e4840867e | ||
|
|
f2f3f045e5 | ||
|
|
b12149bafd | ||
|
|
307c1b0b62 | ||
|
|
b201745988 | ||
|
|
352266481e | ||
|
|
c201ea53ba | ||
|
|
958867e92b | ||
|
|
b50de2f2ed | ||
|
|
ad37db4c82 | ||
|
|
c2d91c9544 | ||
|
|
6eedca6e7e | ||
|
|
0bd1d0bb05 | ||
|
|
1f359f5a13 | ||
|
|
fe53b5503c | ||
|
|
d66ef8fe22 | ||
|
|
6ff3a633f7 | ||
|
|
46891437e9 | ||
|
|
b729597728 | ||
|
|
f99d139025 | ||
|
|
b72b917af2 | ||
|
|
749869fdca | ||
|
|
e56a694878 | ||
|
|
8cb4d1dc28 | ||
|
|
68f1351507 | ||
|
|
66205286e4 | ||
|
|
32be373552 | ||
|
|
b1128c17f1 | ||
|
|
319bbd2f81 | ||
|
|
d8fb4f0a87 | ||
|
|
2e195575a6 | ||
|
|
28efeaa4f2 | ||
|
|
137534f901 | ||
|
|
c9594d46af | ||
|
|
1097648f0a | ||
|
|
17e6213448 | ||
|
|
2ea423032e | ||
|
|
2dead1a19b | ||
|
|
e18b10297b | ||
|
|
fd66084388 | ||
|
|
ca27e096f3 | ||
|
|
125997f45f | ||
|
|
da8a2c7bbb | ||
|
|
81ca205caa | ||
|
|
f06d5b973b | ||
|
|
fd890f9c0a | ||
|
|
835237382f | ||
|
|
7dd699370f | ||
|
|
ef8c7184de | ||
|
|
92026c1f98 | ||
|
|
9bd9dcc41c | ||
|
|
81b97ba52f | ||
|
|
ae36777d14 | ||
|
|
3d7ad82f3e | ||
|
|
059796c60d | ||
|
|
b0342b7449 | ||
|
|
b867dd82ca | ||
|
|
a122286d48 | ||
|
|
837db800bc | ||
|
|
44fe39821a | ||
|
|
fbc6b14424 | ||
|
|
9c00140464 | ||
|
|
00d8deda0e | ||
|
|
b84ce6a556 | ||
|
|
f5fb4c6c64 | ||
|
|
ac686fefe1 | ||
|
|
e690e166b0 | ||
|
|
6a02dd8842 | ||
|
|
66e2c01a3e | ||
|
|
7f2176d7fc | ||
|
|
4434889270 | ||
|
|
96afc1a45d | ||
|
|
dbe49610a1 | ||
|
|
62fadb54ee | ||
|
|
3832383936 | ||
|
|
595c3fb833 | ||
|
|
1d25c55c0b | ||
|
|
6376e78e0b | ||
|
|
1f08d2929c | ||
|
|
04953d97ad | ||
|
|
64fe4de3fb | ||
|
|
58008445e2 | ||
|
|
b7f0b054b8 | ||
|
|
3bbd709bd6 | ||
|
|
dbb1e3f5d8 | ||
|
|
8144308aee | ||
|
|
0503d2a9f3 | ||
|
|
fafd4d9396 | ||
|
|
3431a1b1de | ||
|
|
026ea52445 | ||
|
|
1e60b9a322 | ||
|
|
7450cb1f21 | ||
|
|
cdd5a9e935 | ||
|
|
c4cc50ca39 | ||
|
|
9b09d369d9 | ||
|
|
12ab11413f | ||
|
|
352f3640cf | ||
|
|
7940e91cbe | ||
|
|
577a2356a0 | ||
|
|
38ef0b10e7 | ||
|
|
c72d3c4a0e | ||
|
|
eb7e48b059 | ||
|
|
ab62fa1c4f | ||
|
|
a7cf1f6cca | ||
|
|
80d89f31fe | ||
|
|
a0f566fef3 | ||
|
|
c93d362dd4 | ||
|
|
db72f5d011 | ||
|
|
03704384a8 | ||
|
|
5b17ec0b56 | ||
|
|
d4acd03698 | ||
|
|
2ea986326d | ||
|
|
da53de2097 | ||
|
|
cf755dec22 | ||
|
|
d25e5e1849 | ||
|
|
593648780f | ||
|
|
bb04ff5942 | ||
|
|
12db276eb8 | ||
|
|
596fc3e908 | ||
|
|
9c54b94265 | ||
|
|
3c1cfce95a | ||
|
|
2f9f3142e2 | ||
|
|
92070e502c | ||
|
|
48b1154a71 | ||
|
|
bcdfb98454 | ||
|
|
f26c1f8095 | ||
|
|
790a24bdeb | ||
|
|
5d2b9392d5 | ||
|
|
6be242fc15 | ||
|
|
8158c5042b | ||
|
|
c70cdd88c7 | ||
|
|
bc6d6b6550 | ||
|
|
9584d8e16d | ||
|
|
4693c678d0 | ||
|
|
2c7d668f81 | ||
|
|
de2f963717 | ||
|
|
e83da76dc7 | ||
|
|
643730221d | ||
|
|
ab63f9ef31 | ||
|
|
dc870c4cc4 | ||
|
|
dd709dec18 | ||
|
|
cd5b71aedd | ||
|
|
d33cc025ee | ||
|
|
e7159f2803 | ||
|
|
56b8a18820 | ||
|
|
5832794034 | ||
|
|
a26b197687 | ||
|
|
12dba0955a | ||
|
|
7bd425bb3d | ||
|
|
845ad17a04 | ||
|
|
67e8fcaf93 | ||
|
|
aa07ee22cf | ||
|
|
3702e8c6fe | ||
|
|
21bd4edee4 | ||
|
|
31de39a7a4 | ||
|
|
d0fc2569ff | ||
|
|
4fd1631b30 | ||
|
|
0a1614a872 | ||
|
|
1f66d7ef74 | ||
|
|
84b6429ca6 | ||
|
|
212e5ebab5 | ||
|
|
a6106077bd | ||
|
|
fa4ce6b4e6 | ||
|
|
4130136718 | ||
|
|
c7c1b8d4f1 | ||
|
|
25b60a1b90 | ||
|
|
dda4dadfa3 | ||
|
|
570dbc7b47 | ||
|
|
6c122248f5 | ||
|
|
4a369bb3c0 | ||
|
|
95cf57e3bd | ||
|
|
0e6f7a4dc1 | ||
|
|
6f21834e71 | ||
|
|
cf6ad254fb | ||
|
|
fabbecf4c2 | ||
|
|
8262aa4138 | ||
|
|
95d86ebf22 | ||
|
|
6aa7db2358 | ||
|
|
5637c6e651 | ||
|
|
6f705b053a | ||
|
|
1f3f2788d4 | ||
|
|
ed3c202099 | ||
|
|
0396eec398 | ||
|
|
62dcec49e4 | ||
|
|
2f6afb5e86 | ||
|
|
a3a2b2aafb | ||
|
|
4900ce24fa | ||
|
|
135aaf56fd | ||
|
|
62d7abdd9e | ||
|
|
91b079f4df | ||
|
|
2c6cd74dc1 | ||
|
|
68ac18dc98 | ||
|
|
dbc74164ab | ||
|
|
76c7b2ee9c | ||
|
|
d6913c1eb9 | ||
|
|
9aa00b2f0a | ||
|
|
af02917766 | ||
|
|
d93a7b315d | ||
|
|
a813955ad3 | ||
|
|
1e3425fdee | ||
|
|
a2b326e306 | ||
|
|
0fa0e8e3f3 | ||
|
|
dbae7502e5 | ||
|
|
f47552c0c4 | ||
|
|
74836828c9 | ||
|
|
c152243b4d | ||
|
|
2a40c9a595 | ||
|
|
3cea493d49 | ||
|
|
6991d0851f | ||
|
|
fb2a331f79 | ||
|
|
c888524523 | ||
|
|
75c9dbaf6b | ||
|
|
c01a29fe76 | ||
|
|
80417281c4 | ||
|
|
f9b8bc006f | ||
|
|
2c22b0839f | ||
|
|
ec3e67e0d2 | ||
|
|
611e7e9dd8 | ||
|
|
f4e19ac05c | ||
|
|
70663af190 | ||
|
|
ed265cfdcd | ||
|
|
5b82370bc3 | ||
|
|
47690fffc1 | ||
|
|
aa09bbe23d | ||
|
|
a09fbad8b0 | ||
|
|
357ba2f4f6 | ||
|
|
b32dd746a6 | ||
|
|
b4ea1ccc23 | ||
|
|
2aecbfbb67 | ||
|
|
6d3b907307 | ||
|
|
55da1e3e92 | ||
|
|
f3aa0d6428 | ||
|
|
ad89be7523 | ||
|
|
49a7c16de5 | ||
|
|
e414476c6e | ||
|
|
391690d570 | ||
|
|
1be4af733b | ||
|
|
e3222d99ac | ||
|
|
5b19d33387 | ||
|
|
272c85c062 | ||
|
|
7101af764a | ||
|
|
e582d25654 | ||
|
|
9991c4507d | ||
|
|
37b3248202 | ||
|
|
0585131f78 | ||
|
|
7e351b21bc | ||
|
|
440549fcc5 | ||
|
|
f7b557eed1 | ||
|
|
bdfe317e20 | ||
|
|
19805b91d9 | ||
|
|
420c458b6a | ||
|
|
6de449811d | ||
|
|
081fd541af | ||
|
|
7dcd5035c0 | ||
|
|
0f1bb3fb3b | ||
|
|
78c447829a | ||
|
|
3da0287ede | ||
|
|
ea3331840d | ||
|
|
3fc0f72f3a | ||
|
|
ea3abe6069 | ||
|
|
e66b317f02 | ||
|
|
aa8758dec2 | ||
|
|
ad6b29c09f | ||
|
|
09a585c93b | ||
|
|
8e4959a621 | ||
|
|
1e3f4ed398 | ||
|
|
7048193f00 | ||
|
|
17ae2648ed | ||
|
|
c952754c8c | ||
|
|
bf054dfda5 | ||
|
|
59654289cb | ||
|
|
cf13c11236 | ||
|
|
8ec992a8a3 | ||
|
|
f8b29674b2 | ||
|
|
fe55141a7b | ||
|
|
9205ccc124 | ||
|
|
00df3e2c40 | ||
|
|
a2578ac6b4 | ||
|
|
1fee636afa | ||
|
|
154bca4635 | ||
|
|
c584e31657 | ||
|
|
66340281e6 |
@@ -77,10 +77,6 @@ Metrics/CyclomaticComplexity:
|
||||
# process_video_params(query, preferences) => [20/10]
|
||||
- src/invidious/videos.cr
|
||||
|
||||
# produce_search_params(page, sort, ...) => [29/10]
|
||||
# process_search_query(query, page, ...) => [14/10]
|
||||
- src/invidious/search.cr
|
||||
|
||||
|
||||
|
||||
#src/invidious/playlists.cr:327:5
|
||||
|
||||
23
.github/workflows/ci.yml
vendored
23
.github/workflows/ci.yml
vendored
@@ -38,23 +38,26 @@ jobs:
|
||||
matrix:
|
||||
stable: [true]
|
||||
crystal:
|
||||
- 1.0.0
|
||||
- 1.1.1
|
||||
- 1.2.2
|
||||
- 1.3.2
|
||||
- 1.4.0
|
||||
- 1.5.0
|
||||
include:
|
||||
- crystal: nightly
|
||||
stable: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Install Crystal
|
||||
uses: crystal-lang/install-crystal@v1.5.3
|
||||
uses: crystal-lang/install-crystal@v1.6.0
|
||||
with:
|
||||
crystal: ${{ matrix.crystal }}
|
||||
|
||||
- name: Cache Shards
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ./lib
|
||||
key: shards-${{ hashFiles('shard.lock') }}
|
||||
@@ -84,7 +87,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Build Docker
|
||||
run: docker-compose build --build-arg release=0
|
||||
@@ -100,18 +103,18 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
uses: docker/setup-qemu-action@v2
|
||||
with:
|
||||
platforms: arm64
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Build Docker ARM64 image
|
||||
uses: docker/build-push-action@v2
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: .
|
||||
file: docker/Dockerfile.arm64
|
||||
|
||||
16
.github/workflows/container-release.yml
vendored
16
.github/workflows/container-release.yml
vendored
@@ -22,12 +22,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Crystal
|
||||
uses: oprypin/install-crystal@v1.2.4
|
||||
uses: crystal-lang/install-crystal@v1.6.0
|
||||
with:
|
||||
crystal: 1.2.2
|
||||
crystal: 1.5.0
|
||||
|
||||
- name: Run lint
|
||||
run: |
|
||||
@@ -38,15 +38,15 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
uses: docker/setup-qemu-action@v2
|
||||
with:
|
||||
platforms: arm64
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Login to registry
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: quay.io
|
||||
username: ${{ secrets.QUAY_USERNAME }}
|
||||
@@ -54,7 +54,7 @@ jobs:
|
||||
|
||||
- name: Build and push Docker AMD64 image for Push Event
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: docker/build-push-action@v2
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: .
|
||||
file: docker/Dockerfile
|
||||
@@ -66,7 +66,7 @@ jobs:
|
||||
|
||||
- name: Build and push Docker ARM64 image for Push Event
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: docker/build-push-action@v2
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: .
|
||||
file: docker/Dockerfile.arm64
|
||||
|
||||
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v3
|
||||
- uses: actions/stale@v5
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 365
|
||||
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "mocks"]
|
||||
path = mocks
|
||||
url = ../mocks
|
||||
14
README.md
14
README.md
@@ -31,7 +31,7 @@
|
||||
•
|
||||
<a href="https://instances.invidious.io/">Instances list</a>
|
||||
•
|
||||
<a href="https://docs.invidious.io/FAQ.md">FAQ</a>
|
||||
<a href="https://docs.invidious.io/faq/">FAQ</a>
|
||||
•
|
||||
<a href="https://docs.invidious.io/">Documentation</a>
|
||||
•
|
||||
@@ -48,7 +48,7 @@
|
||||
</a>
|
||||
<br>
|
||||
<a rel="me" href="https://social.tchncs.de/@invidious">
|
||||
<img alt="Mastodon: @invidious@social.tchncs.de" src="https://img.shields.io/badge/Mastodon-%40invidious%40social.tchncs.de-darkgreen">
|
||||
<img alt="Fediverse: @invidious@social.tchncs.de" src="https://img.shields.io/badge/Fediverse-%40invidious%40social.tchncs.de-darkgreen">
|
||||
</a>
|
||||
<br>
|
||||
<a href="https://invidious.io/contact/">
|
||||
@@ -88,7 +88,7 @@
|
||||
|
||||
**Technical features**
|
||||
- Embedded video support
|
||||
- [Developer API](https://docs.invidious.io/API.md)
|
||||
- [Developer API](https://docs.invidious.io/api/)
|
||||
- Does not use official YouTube APIs
|
||||
- No Contributor License Agreement (CLA)
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
|
||||
**Hosting invidious:**
|
||||
|
||||
- [Follow the installation instructions](https://docs.invidious.io/Installation.md)
|
||||
- [Follow the installation instructions](https://docs.invidious.io/installation/)
|
||||
|
||||
|
||||
## Documentation
|
||||
@@ -119,7 +119,7 @@ embedded youtube videos on other websites with invidious.
|
||||
|
||||
The documentation contains a list of browser extensions that we recommended to use along with Invidious.
|
||||
|
||||
You can read more here: https://docs.invidious.io/Extensions.md
|
||||
You can read more here: https://docs.invidious.io/applications/
|
||||
|
||||
|
||||
## Contribute
|
||||
@@ -150,6 +150,10 @@ Weblate also allows you to log-in with major SSO providers like Github, Gitlab,
|
||||
- [PeerTubeify](https://gitlab.com/Cha_deL/peertubeify): On YouTube, displays a link to the same video on PeerTube, if it exists.
|
||||
- [MusicPiped](https://github.com/deep-gaurav/MusicPiped): A material design music player that streams music from YouTube.
|
||||
- [HoloPlay](https://github.com/stephane-r/HoloPlay): Funny Android application connecting on Invidious API's with search, playlists and favorites.
|
||||
- [WatchTube](https://github.com/WatchTubeTeam/WatchTube): Powerful YouTube client for Apple Watch.
|
||||
- [Yattee](https://github.com/yattee/yattee): Alternative YouTube frontend for iPhone, iPad, Mac and Apple TV.
|
||||
- [TubiTui](https://codeberg.org/777/TubiTui): A lightweight, libre, TUI-based YouTube client.
|
||||
- [Ytfzf](https://github.com/pystardust/ytfzf): A posix script to find and watch youtube videos from the terminal. (Without API)
|
||||
|
||||
|
||||
## Liability
|
||||
|
||||
@@ -15,6 +15,11 @@ body {
|
||||
background-color: rgb(255, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.underlined {
|
||||
border-bottom: 1px solid;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.channel-profile > * {
|
||||
font-size: 1.17em;
|
||||
font-weight: bold;
|
||||
@@ -199,7 +204,8 @@ img.thumbnail {
|
||||
margin: 1px;
|
||||
|
||||
border: 1px solid;
|
||||
border-color: #0000 #0000 #CCC #0000;
|
||||
border-color: rgba(0,0,0,0);
|
||||
border-bottom-color: #CCC;
|
||||
border-radius: 0;
|
||||
|
||||
box-shadow: none;
|
||||
@@ -209,7 +215,8 @@ img.thumbnail {
|
||||
.searchbar input[type="search"]:focus {
|
||||
margin: 0 0 0.5px 0;
|
||||
border: 2px solid;
|
||||
border-color: #0000 #0000 #FED #0000;
|
||||
border-color: rgba(0,0,0,0);
|
||||
border-bottom-color: #FED;
|
||||
}
|
||||
|
||||
/* https://stackoverflow.com/a/55170420 */
|
||||
@@ -229,7 +236,7 @@ input[type="search"]::-webkit-search-cancel-button {
|
||||
}
|
||||
|
||||
.user-field div {
|
||||
width: initial;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.user-field div:not(:last-child) {
|
||||
@@ -286,7 +293,7 @@ input[type="search"]::-webkit-search-cancel-button {
|
||||
|
||||
.flexible { display: flex; }
|
||||
.flex-left { flex: 1 1 100%; flex-wrap: wrap; }
|
||||
.flex-right { flex: 1 0 max-content; flex-wrap: nowrap; }
|
||||
.flex-right { flex: 1 0 auto; flex-wrap: nowrap; }
|
||||
|
||||
p.channel-name { margin: 0; }
|
||||
p.video-data { margin: 0; font-weight: bold; font-size: 80%; }
|
||||
@@ -475,30 +482,6 @@ body.dark-theme {
|
||||
}
|
||||
}
|
||||
|
||||
#filters {
|
||||
display: inline;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
#filters > div {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#filters > summary {
|
||||
display: block;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
#filters > summary::before {
|
||||
content: "[ + ]";
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
#filters[open] > summary::before {
|
||||
content: "[ - ]";
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
/*With commit d9528f5 all contents of the page is now within a flexbox. However,
|
||||
the hr element is rendered improperly within one.
|
||||
See https://stackoverflow.com/a/34372979 for more info */
|
||||
@@ -546,3 +529,9 @@ p,
|
||||
|
||||
/* Center the "invidious" logo on the search page */
|
||||
#logo > h1 { text-align: center; }
|
||||
|
||||
/* IE11 fixes */
|
||||
:-ms-input-placeholder { color: #888; }
|
||||
|
||||
/* Wider settings name to less word wrap */
|
||||
.pure-form-aligned .pure-control-group label { width: 19em; }
|
||||
|
||||
@@ -70,6 +70,9 @@
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.video-js.player-style-youtube .vjs-progress-control .vjs-progress-holder, .video-js.player-style-youtube .vjs-progress-control {height: 5px;
|
||||
margin-bottom: 10px;}
|
||||
|
||||
ul.vjs-menu-content::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
@@ -98,23 +101,27 @@ ul.vjs-menu-content::-webkit-scrollbar {
|
||||
order: 2;
|
||||
}
|
||||
|
||||
.vjs-quality-selector,
|
||||
.video-js .vjs-http-source-selector {
|
||||
.vjs-audio-button {
|
||||
order: 3;
|
||||
}
|
||||
|
||||
.vjs-playback-rate {
|
||||
.vjs-quality-selector,
|
||||
.video-js .vjs-http-source-selector {
|
||||
order: 4;
|
||||
}
|
||||
|
||||
.vjs-share-control {
|
||||
.vjs-playback-rate {
|
||||
order: 5;
|
||||
}
|
||||
|
||||
.vjs-fullscreen-control {
|
||||
.vjs-share-control {
|
||||
order: 6;
|
||||
}
|
||||
|
||||
.vjs-fullscreen-control {
|
||||
order: 7;
|
||||
}
|
||||
|
||||
.vjs-playback-rate > .vjs-menu {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
121
assets/css/search.css
Normal file
121
assets/css/search.css
Normal file
@@ -0,0 +1,121 @@
|
||||
summary {
|
||||
/* This should hide the marker */
|
||||
display: block;
|
||||
|
||||
font-size: 1.17em;
|
||||
font-weight: bold;
|
||||
margin: 0 auto 10px auto;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
summary::-webkit-details-marker,
|
||||
summary::marker { display: none; }
|
||||
|
||||
summary:before {
|
||||
border-radius: 5px;
|
||||
content: "[ + ]";
|
||||
margin: -2px 10px 0 10px;
|
||||
padding: 1px 0 3px 0;
|
||||
text-align: center;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
details[open] > summary:before { content: "[ − ]"; }
|
||||
|
||||
|
||||
#filters-box {
|
||||
padding: 10px 20px 20px 10px;
|
||||
margin: 10px 15px;
|
||||
}
|
||||
#filters-flex {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
align-content: flex-start;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
|
||||
fieldset, legend {
|
||||
display: contents !important;
|
||||
border: none !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
|
||||
.filter-column {
|
||||
display: inline-block;
|
||||
display: inline-flex;
|
||||
width: max-content;
|
||||
min-width: max-content;
|
||||
max-width: 16em;
|
||||
margin: 15px;
|
||||
flex-grow: 2;
|
||||
flex-basis: auto;
|
||||
flex-direction: column;
|
||||
}
|
||||
.filter-name, .filter-options {
|
||||
display: block;
|
||||
padding: 5px 10px;
|
||||
margin: 0;
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
.filter-options div { margin: 6px 0; }
|
||||
.filter-options div * { vertical-align: middle; }
|
||||
.filter-options label { margin: 0 10px; }
|
||||
|
||||
|
||||
#filters-apply {
|
||||
text-align: right; /* IE11 only */
|
||||
text-align: end; /* Override for compatible browsers */
|
||||
}
|
||||
|
||||
/* Error message */
|
||||
|
||||
.no-results-error {
|
||||
text-align: center;
|
||||
line-height: 180%;
|
||||
font-size: 110%;
|
||||
padding: 15px 15px 125px 15px;
|
||||
}
|
||||
|
||||
/* Responsive rules */
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
summary { font-size: 1.30em; }
|
||||
#filters-box {
|
||||
margin: 10px 0 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
#filters-apply {
|
||||
text-align: center;
|
||||
padding: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Light theme */
|
||||
|
||||
.light-theme #filters-box {
|
||||
background: #dfdfdf;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
.no-theme #filters-box {
|
||||
background: #dfdfdf;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dark theme */
|
||||
|
||||
.dark-theme #filters-box {
|
||||
background: #373737;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.no-theme #filters-box {
|
||||
background: #373737;
|
||||
}
|
||||
}
|
||||
249
assets/js/_helpers.js
Normal file
249
assets/js/_helpers.js
Normal file
@@ -0,0 +1,249 @@
|
||||
'use strict';
|
||||
// Contains only auxiliary methods
|
||||
// May be included and executed unlimited number of times without any consequences
|
||||
|
||||
// Polyfills for IE11
|
||||
Array.prototype.find = Array.prototype.find || function (condition) {
|
||||
return this.filter(condition)[0];
|
||||
};
|
||||
Array.from = Array.from || function (source) {
|
||||
return Array.prototype.slice.call(source);
|
||||
};
|
||||
NodeList.prototype.forEach = NodeList.prototype.forEach || function (callback) {
|
||||
Array.from(this).forEach(callback);
|
||||
};
|
||||
String.prototype.includes = String.prototype.includes || function (searchString) {
|
||||
return this.indexOf(searchString) >= 0;
|
||||
};
|
||||
String.prototype.startsWith = String.prototype.startsWith || function (prefix) {
|
||||
return this.substr(0, prefix.length) === prefix;
|
||||
};
|
||||
Math.sign = Math.sign || function(x) {
|
||||
x = +x;
|
||||
if (!x) return x; // 0 and NaN
|
||||
return x > 0 ? 1 : -1;
|
||||
};
|
||||
if (!window.hasOwnProperty('HTMLDetailsElement') && !window.hasOwnProperty('mockHTMLDetailsElement')) {
|
||||
window.mockHTMLDetailsElement = true;
|
||||
const style = 'details:not([open]) > :not(summary) {display: none}';
|
||||
document.head.appendChild(document.createElement('style')).textContent = style;
|
||||
|
||||
addEventListener('click', function (e) {
|
||||
if (e.target.nodeName !== 'SUMMARY') return;
|
||||
const details = e.target.parentElement;
|
||||
if (details.hasAttribute('open'))
|
||||
details.removeAttribute('open');
|
||||
else
|
||||
details.setAttribute('open', '');
|
||||
});
|
||||
}
|
||||
|
||||
// Monstrous global variable for handy code
|
||||
// Includes: clamp, xhr, storage.{get,set,remove}
|
||||
window.helpers = window.helpers || {
|
||||
/**
|
||||
* https://en.wikipedia.org/wiki/Clamping_(graphics)
|
||||
* @param {Number} num Source number
|
||||
* @param {Number} min Low border
|
||||
* @param {Number} max High border
|
||||
* @returns {Number} Clamped value
|
||||
*/
|
||||
clamp: function (num, min, max) {
|
||||
if (max < min) {
|
||||
var t = max; max = min; min = t; // swap max and min
|
||||
}
|
||||
|
||||
if (max < num)
|
||||
return max;
|
||||
if (min > num)
|
||||
return min;
|
||||
return num;
|
||||
},
|
||||
|
||||
/** @private */
|
||||
_xhr: function (method, url, options, callbacks) {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open(method, url);
|
||||
|
||||
// Default options
|
||||
xhr.responseType = 'json';
|
||||
xhr.timeout = 10000;
|
||||
// Default options redefining
|
||||
if (options.responseType)
|
||||
xhr.responseType = options.responseType;
|
||||
if (options.timeout)
|
||||
xhr.timeout = options.timeout;
|
||||
|
||||
if (method === 'POST')
|
||||
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||
|
||||
// better than onreadystatechange because of 404 codes https://stackoverflow.com/a/36182963
|
||||
xhr.onloadend = function () {
|
||||
if (xhr.status === 200) {
|
||||
if (callbacks.on200) {
|
||||
// fix for IE11. It doesn't convert response to JSON
|
||||
if (xhr.responseType === '' && typeof(xhr.response) === 'string')
|
||||
callbacks.on200(JSON.parse(xhr.response));
|
||||
else
|
||||
callbacks.on200(xhr.response);
|
||||
}
|
||||
} else {
|
||||
// handled by onerror
|
||||
if (xhr.status === 0) return;
|
||||
|
||||
if (callbacks.onNon200)
|
||||
callbacks.onNon200(xhr);
|
||||
}
|
||||
};
|
||||
|
||||
xhr.ontimeout = function () {
|
||||
if (callbacks.onTimeout)
|
||||
callbacks.onTimeout(xhr);
|
||||
};
|
||||
|
||||
xhr.onerror = function () {
|
||||
if (callbacks.onError)
|
||||
callbacks.onError(xhr);
|
||||
};
|
||||
|
||||
if (options.payload)
|
||||
xhr.send(options.payload);
|
||||
else
|
||||
xhr.send();
|
||||
},
|
||||
/** @private */
|
||||
_xhrRetry: function(method, url, options, callbacks) {
|
||||
if (options.retries <= 0) {
|
||||
console.warn('Failed to pull', options.entity_name);
|
||||
if (callbacks.onTotalFail)
|
||||
callbacks.onTotalFail();
|
||||
return;
|
||||
}
|
||||
helpers._xhr(method, url, options, callbacks);
|
||||
},
|
||||
/**
|
||||
* @callback callbackXhrOn200
|
||||
* @param {Object} response - xhr.response
|
||||
*/
|
||||
/**
|
||||
* @callback callbackXhrError
|
||||
* @param {XMLHttpRequest} xhr
|
||||
*/
|
||||
/**
|
||||
* @param {'GET'|'POST'} method - 'GET' or 'POST'
|
||||
* @param {String} url - URL to send request to
|
||||
* @param {Object} options - other XHR options
|
||||
* @param {XMLHttpRequestBodyInit} [options.payload=null] - payload for POST-requests
|
||||
* @param {'arraybuffer'|'blob'|'document'|'json'|'text'} [options.responseType=json]
|
||||
* @param {Number} [options.timeout=10000]
|
||||
* @param {Number} [options.retries=1]
|
||||
* @param {String} [options.entity_name='unknown'] - string to log
|
||||
* @param {Number} [options.retry_timeout=1000]
|
||||
* @param {Object} callbacks - functions to execute on events fired
|
||||
* @param {callbackXhrOn200} [callbacks.on200]
|
||||
* @param {callbackXhrError} [callbacks.onNon200]
|
||||
* @param {callbackXhrError} [callbacks.onTimeout]
|
||||
* @param {callbackXhrError} [callbacks.onError]
|
||||
* @param {callbackXhrError} [callbacks.onTotalFail] - if failed after all retries
|
||||
*/
|
||||
xhr: function(method, url, options, callbacks) {
|
||||
if (!options.retries || options.retries <= 1) {
|
||||
helpers._xhr(method, url, options, callbacks);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!options.entity_name) options.entity_name = 'unknown';
|
||||
if (!options.retry_timeout) options.retry_timeout = 1000;
|
||||
const retries_total = options.retries;
|
||||
let currentTry = 1;
|
||||
|
||||
const retry = function () {
|
||||
console.warn('Pulling ' + options.entity_name + ' failed... ' + (currentTry++) + '/' + retries_total);
|
||||
setTimeout(function () {
|
||||
options.retries--;
|
||||
helpers._xhrRetry(method, url, options, callbacks);
|
||||
}, options.retry_timeout);
|
||||
};
|
||||
|
||||
// Pack retry() call into error handlers
|
||||
callbacks._onError = callbacks.onError;
|
||||
callbacks.onError = function (xhr) {
|
||||
if (callbacks._onError)
|
||||
callbacks._onError(xhr);
|
||||
retry();
|
||||
};
|
||||
callbacks._onTimeout = callbacks.onTimeout;
|
||||
callbacks.onTimeout = function (xhr) {
|
||||
if (callbacks._onTimeout)
|
||||
callbacks._onTimeout(xhr);
|
||||
retry();
|
||||
};
|
||||
|
||||
helpers._xhrRetry(method, url, options, callbacks);
|
||||
},
|
||||
|
||||
/**
|
||||
* @typedef {Object} invidiousStorage
|
||||
* @property {(key:String) => Object} get
|
||||
* @property {(key:String, value:Object)} set
|
||||
* @property {(key:String)} remove
|
||||
*/
|
||||
|
||||
/**
|
||||
* Universal storage, stores and returns JS objects. Uses inside localStorage or cookies
|
||||
* @type {invidiousStorage}
|
||||
*/
|
||||
storage: (function () {
|
||||
// access to localStorage throws exception in Tor Browser, so try is needed
|
||||
let localStorageIsUsable = false;
|
||||
try{localStorageIsUsable = !!localStorage.setItem;}catch(e){}
|
||||
|
||||
if (localStorageIsUsable) {
|
||||
return {
|
||||
get: function (key) {
|
||||
if (!localStorage[key]) return;
|
||||
try {
|
||||
return JSON.parse(decodeURIComponent(localStorage[key]));
|
||||
} catch(e) {
|
||||
// Erase non parsable value
|
||||
helpers.storage.remove(key);
|
||||
}
|
||||
},
|
||||
set: function (key, value) { localStorage[key] = encodeURIComponent(JSON.stringify(value)); },
|
||||
remove: function (key) { localStorage.removeItem(key); }
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: fire 'storage' event for cookies
|
||||
console.info('Storage: localStorage is disabled or unaccessible. Cookies used as fallback');
|
||||
return {
|
||||
get: function (key) {
|
||||
const cookiePrefix = key + '=';
|
||||
function findCallback(cookie) {return cookie.startsWith(cookiePrefix);}
|
||||
const matchedCookie = document.cookie.split('; ').find(findCallback);
|
||||
if (matchedCookie) {
|
||||
const cookieBody = matchedCookie.replace(cookiePrefix, '');
|
||||
if (cookieBody.length === 0) return;
|
||||
try {
|
||||
return JSON.parse(decodeURIComponent(cookieBody));
|
||||
} catch(e) {
|
||||
// Erase non parsable value
|
||||
helpers.storage.remove(key);
|
||||
}
|
||||
}
|
||||
},
|
||||
set: function (key, value) {
|
||||
const cookie_data = encodeURIComponent(JSON.stringify(value));
|
||||
|
||||
// Set expiration in 2 year
|
||||
const date = new Date();
|
||||
date.setFullYear(date.getFullYear()+2);
|
||||
|
||||
document.cookie = key + '=' + cookie_data + '; expires=' + date.toGMTString();
|
||||
},
|
||||
remove: function (key) {
|
||||
document.cookie = key + '=; Max-Age=0';
|
||||
}
|
||||
};
|
||||
})()
|
||||
};
|
||||
@@ -1,19 +1,13 @@
|
||||
var community_data = JSON.parse(document.getElementById('community_data').innerHTML);
|
||||
|
||||
String.prototype.supplant = function (o) {
|
||||
return this.replace(/{([^{}]*)}/g, function (a, b) {
|
||||
var r = o[b];
|
||||
return typeof r === 'string' || typeof r === 'number' ? r : a;
|
||||
});
|
||||
}
|
||||
'use strict';
|
||||
var community_data = JSON.parse(document.getElementById('community_data').textContent);
|
||||
|
||||
function hide_youtube_replies(event) {
|
||||
var target = event.target;
|
||||
|
||||
sub_text = target.getAttribute('data-inner-text');
|
||||
inner_text = target.getAttribute('data-sub-text');
|
||||
var sub_text = target.getAttribute('data-inner-text');
|
||||
var inner_text = target.getAttribute('data-sub-text');
|
||||
|
||||
body = target.parentNode.parentNode.children[1];
|
||||
var body = target.parentNode.parentNode.children[1];
|
||||
body.style.display = 'none';
|
||||
|
||||
target.innerHTML = sub_text;
|
||||
@@ -25,10 +19,10 @@ function hide_youtube_replies(event) {
|
||||
function show_youtube_replies(event) {
|
||||
var target = event.target;
|
||||
|
||||
sub_text = target.getAttribute('data-inner-text');
|
||||
inner_text = target.getAttribute('data-sub-text');
|
||||
var sub_text = target.getAttribute('data-inner-text');
|
||||
var inner_text = target.getAttribute('data-sub-text');
|
||||
|
||||
body = target.parentNode.parentNode.children[1];
|
||||
var body = target.parentNode.parentNode.children[1];
|
||||
body.style.display = '';
|
||||
|
||||
target.innerHTML = sub_text;
|
||||
@@ -37,13 +31,6 @@ function show_youtube_replies(event) {
|
||||
target.setAttribute('data-sub-text', sub_text);
|
||||
}
|
||||
|
||||
function number_with_separator(val) {
|
||||
while (/(\d+)(\d{3})/.test(val.toString())) {
|
||||
val = val.toString().replace(/(\d+)(\d{3})/, '$1' + ',' + '$2');
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
function get_youtube_replies(target, load_more) {
|
||||
var continuation = target.getAttribute('data-continuation');
|
||||
|
||||
@@ -57,47 +44,39 @@ function get_youtube_replies(target, load_more) {
|
||||
'&hl=' + community_data.preferences.locale +
|
||||
'&thin_mode=' + community_data.preferences.thin_mode +
|
||||
'&continuation=' + continuation;
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.responseType = 'json';
|
||||
xhr.timeout = 10000;
|
||||
xhr.open('GET', url, true);
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 4) {
|
||||
if (xhr.status == 200) {
|
||||
if (load_more) {
|
||||
body = body.parentNode.parentNode;
|
||||
body.removeChild(body.lastElementChild);
|
||||
body.innerHTML += xhr.response.contentHtml;
|
||||
} else {
|
||||
body.removeChild(body.lastElementChild);
|
||||
|
||||
var p = document.createElement('p');
|
||||
var a = document.createElement('a');
|
||||
p.appendChild(a);
|
||||
|
||||
a.href = 'javascript:void(0)';
|
||||
a.onclick = hide_youtube_replies;
|
||||
a.setAttribute('data-sub-text', community_data.hide_replies_text);
|
||||
a.setAttribute('data-inner-text', community_data.show_replies_text);
|
||||
a.innerText = community_data.hide_replies_text;
|
||||
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = xhr.response.contentHtml;
|
||||
|
||||
body.appendChild(p);
|
||||
body.appendChild(div);
|
||||
}
|
||||
helpers.xhr('GET', url, {}, {
|
||||
on200: function (response) {
|
||||
if (load_more) {
|
||||
body = body.parentNode.parentNode;
|
||||
body.removeChild(body.lastElementChild);
|
||||
body.innerHTML += response.contentHtml;
|
||||
} else {
|
||||
body.innerHTML = fallback;
|
||||
body.removeChild(body.lastElementChild);
|
||||
|
||||
var p = document.createElement('p');
|
||||
var a = document.createElement('a');
|
||||
p.appendChild(a);
|
||||
|
||||
a.href = 'javascript:void(0)';
|
||||
a.onclick = hide_youtube_replies;
|
||||
a.setAttribute('data-sub-text', community_data.hide_replies_text);
|
||||
a.setAttribute('data-inner-text', community_data.show_replies_text);
|
||||
a.textContent = community_data.hide_replies_text;
|
||||
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = response.contentHtml;
|
||||
|
||||
body.appendChild(p);
|
||||
body.appendChild(div);
|
||||
}
|
||||
},
|
||||
onNon200: function (xhr) {
|
||||
body.innerHTML = fallback;
|
||||
},
|
||||
onTimeout: function (xhr) {
|
||||
console.warn('Pulling comments failed');
|
||||
body.innerHTML = fallback;
|
||||
}
|
||||
}
|
||||
|
||||
xhr.ontimeout = function () {
|
||||
console.log('Pulling comments failed.');
|
||||
body.innerHTML = fallback;
|
||||
}
|
||||
|
||||
xhr.send();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,103 +1,62 @@
|
||||
var video_data = JSON.parse(document.getElementById('video_data').innerHTML);
|
||||
|
||||
function get_playlist(plid, retries) {
|
||||
if (retries == undefined) retries = 5;
|
||||
|
||||
if (retries <= 0) {
|
||||
console.log('Failed to pull playlist');
|
||||
return;
|
||||
}
|
||||
'use strict';
|
||||
var video_data = JSON.parse(document.getElementById('video_data').textContent);
|
||||
|
||||
function get_playlist(plid) {
|
||||
var plid_url;
|
||||
if (plid.startsWith('RD')) {
|
||||
var plid_url = '/api/v1/mixes/' + plid +
|
||||
plid_url = '/api/v1/mixes/' + plid +
|
||||
'?continuation=' + video_data.id +
|
||||
'&format=html&hl=' + video_data.preferences.locale;
|
||||
} else {
|
||||
var plid_url = '/api/v1/playlists/' + plid +
|
||||
plid_url = '/api/v1/playlists/' + plid +
|
||||
'?index=' + video_data.index +
|
||||
'&continuation' + video_data.id +
|
||||
'&format=html&hl=' + video_data.preferences.locale;
|
||||
}
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.responseType = 'json';
|
||||
xhr.timeout = 10000;
|
||||
xhr.open('GET', plid_url, true);
|
||||
helpers.xhr('GET', plid_url, {retries: 5, entity_name: 'playlist'}, {
|
||||
on200: function (response) {
|
||||
if (!response.nextVideo)
|
||||
return;
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status === 200) {
|
||||
if (xhr.response.nextVideo) {
|
||||
player.on('ended', function () {
|
||||
var url = new URL('https://example.com/embed/' + xhr.response.nextVideo);
|
||||
player.on('ended', function () {
|
||||
var url = new URL('https://example.com/embed/' + response.nextVideo);
|
||||
|
||||
url.searchParams.set('list', plid);
|
||||
if (!plid.startsWith('RD')) {
|
||||
url.searchParams.set('index', xhr.response.index);
|
||||
}
|
||||
url.searchParams.set('list', plid);
|
||||
if (!plid.startsWith('RD'))
|
||||
url.searchParams.set('index', response.index);
|
||||
if (video_data.params.autoplay || video_data.params.continue_autoplay)
|
||||
url.searchParams.set('autoplay', '1');
|
||||
if (video_data.params.listen !== video_data.preferences.listen)
|
||||
url.searchParams.set('listen', video_data.params.listen);
|
||||
if (video_data.params.speed !== video_data.preferences.speed)
|
||||
url.searchParams.set('speed', video_data.params.speed);
|
||||
if (video_data.params.local !== video_data.preferences.local)
|
||||
url.searchParams.set('local', video_data.params.local);
|
||||
|
||||
if (video_data.params.autoplay || video_data.params.continue_autoplay) {
|
||||
url.searchParams.set('autoplay', '1');
|
||||
}
|
||||
|
||||
if (video_data.params.listen !== video_data.preferences.listen) {
|
||||
url.searchParams.set('listen', video_data.params.listen);
|
||||
}
|
||||
|
||||
if (video_data.params.speed !== video_data.preferences.speed) {
|
||||
url.searchParams.set('speed', video_data.params.speed);
|
||||
}
|
||||
|
||||
if (video_data.params.local !== video_data.preferences.local) {
|
||||
url.searchParams.set('local', video_data.params.local);
|
||||
}
|
||||
|
||||
location.assign(url.pathname + url.search);
|
||||
});
|
||||
}
|
||||
}
|
||||
location.assign(url.pathname + url.search);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
xhr.onerror = function () {
|
||||
console.log('Pulling playlist failed... ' + retries + '/5');
|
||||
setTimeout(function () { get_playlist(plid, retries - 1) }, 1000);
|
||||
}
|
||||
|
||||
xhr.ontimeout = function () {
|
||||
console.log('Pulling playlist failed... ' + retries + '/5');
|
||||
get_playlist(plid, retries - 1);
|
||||
}
|
||||
|
||||
xhr.send();
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('load', function (e) {
|
||||
addEventListener('load', function (e) {
|
||||
if (video_data.plid) {
|
||||
get_playlist(video_data.plid);
|
||||
} else if (video_data.video_series) {
|
||||
player.on('ended', function () {
|
||||
var url = new URL('https://example.com/embed/' + video_data.video_series.shift());
|
||||
|
||||
if (video_data.params.autoplay || video_data.params.continue_autoplay) {
|
||||
if (video_data.params.autoplay || video_data.params.continue_autoplay)
|
||||
url.searchParams.set('autoplay', '1');
|
||||
}
|
||||
|
||||
if (video_data.params.listen !== video_data.preferences.listen) {
|
||||
if (video_data.params.listen !== video_data.preferences.listen)
|
||||
url.searchParams.set('listen', video_data.params.listen);
|
||||
}
|
||||
|
||||
if (video_data.params.speed !== video_data.preferences.speed) {
|
||||
if (video_data.params.speed !== video_data.preferences.speed)
|
||||
url.searchParams.set('speed', video_data.params.speed);
|
||||
}
|
||||
|
||||
if (video_data.params.local !== video_data.preferences.local) {
|
||||
if (video_data.params.local !== video_data.preferences.local)
|
||||
url.searchParams.set('local', video_data.params.local);
|
||||
}
|
||||
|
||||
if (video_data.video_series.length !== 0) {
|
||||
url.searchParams.set('playlist', video_data.video_series.join(','))
|
||||
}
|
||||
if (video_data.video_series.length !== 0)
|
||||
url.searchParams.set('playlist', video_data.video_series.join(','));
|
||||
|
||||
location.assign(url.pathname + url.search);
|
||||
});
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
(function () {
|
||||
var n2a = function (n) { return Array.prototype.slice.call(n); };
|
||||
|
||||
var video_player = document.getElementById('player_html5_api');
|
||||
if (video_player) {
|
||||
video_player.onmouseenter = function () { video_player['data-title'] = video_player['title']; video_player['title'] = ''; };
|
||||
@@ -11,140 +9,124 @@
|
||||
}
|
||||
|
||||
// For dynamically inserted elements
|
||||
document.addEventListener('click', function (e) {
|
||||
if (!e || !e.target) { return; }
|
||||
e = e.target;
|
||||
var handler_name = e.getAttribute('data-onclick');
|
||||
addEventListener('click', function (e) {
|
||||
if (!e || !e.target) return;
|
||||
|
||||
var t = e.target;
|
||||
var handler_name = t.getAttribute('data-onclick');
|
||||
|
||||
switch (handler_name) {
|
||||
case 'jump_to_time':
|
||||
var time = e.getAttribute('data-jump-time');
|
||||
e.preventDefault();
|
||||
var time = t.getAttribute('data-jump-time');
|
||||
player.currentTime(time);
|
||||
break;
|
||||
case 'get_youtube_replies':
|
||||
var load_more = e.getAttribute('data-load-more') !== null;
|
||||
var load_replies = e.getAttribute('data-load-replies') !== null;
|
||||
get_youtube_replies(e, load_more, load_replies);
|
||||
var load_more = t.getAttribute('data-load-more') !== null;
|
||||
var load_replies = t.getAttribute('data-load-replies') !== null;
|
||||
get_youtube_replies(t, load_more, load_replies);
|
||||
break;
|
||||
case 'toggle_parent':
|
||||
toggle_parent(e);
|
||||
e.preventDefault();
|
||||
toggle_parent(t);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
n2a(document.querySelectorAll('[data-mouse="switch_classes"]')).forEach(function (e) {
|
||||
var classes = e.getAttribute('data-switch-classes').split(',');
|
||||
var ec = classes[0];
|
||||
var lc = classes[1];
|
||||
var onoff = function (on, off) {
|
||||
var cs = e.getAttribute('class');
|
||||
cs = cs.split(off).join(on);
|
||||
e.setAttribute('class', cs);
|
||||
};
|
||||
e.onmouseenter = function () { onoff(ec, lc); };
|
||||
e.onmouseleave = function () { onoff(lc, ec); };
|
||||
document.querySelectorAll('[data-mouse="switch_classes"]').forEach(function (el) {
|
||||
var classes = el.getAttribute('data-switch-classes').split(',');
|
||||
var classOnEnter = classes[0];
|
||||
var classOnLeave = classes[1];
|
||||
function toggle_classes(toAdd, toRemove) {
|
||||
el.classList.add(toAdd);
|
||||
el.classList.remove(toRemove);
|
||||
}
|
||||
el.onmouseenter = function () { toggle_classes(classOnEnter, classOnLeave); };
|
||||
el.onmouseleave = function () { toggle_classes(classOnLeave, classOnEnter); };
|
||||
});
|
||||
|
||||
n2a(document.querySelectorAll('[data-onsubmit="return_false"]')).forEach(function (e) {
|
||||
e.onsubmit = function () { return false; };
|
||||
document.querySelectorAll('[data-onsubmit="return_false"]').forEach(function (el) {
|
||||
el.onsubmit = function () { return false; };
|
||||
});
|
||||
|
||||
n2a(document.querySelectorAll('[data-onclick="mark_watched"]')).forEach(function (e) {
|
||||
e.onclick = function () { mark_watched(e); };
|
||||
document.querySelectorAll('[data-onclick="mark_watched"]').forEach(function (el) {
|
||||
el.onclick = function () { mark_watched(el); };
|
||||
});
|
||||
n2a(document.querySelectorAll('[data-onclick="mark_unwatched"]')).forEach(function (e) {
|
||||
e.onclick = function () { mark_unwatched(e); };
|
||||
document.querySelectorAll('[data-onclick="mark_unwatched"]').forEach(function (el) {
|
||||
el.onclick = function () { mark_unwatched(el); };
|
||||
});
|
||||
n2a(document.querySelectorAll('[data-onclick="add_playlist_video"]')).forEach(function (e) {
|
||||
e.onclick = function () { add_playlist_video(e); };
|
||||
document.querySelectorAll('[data-onclick="add_playlist_video"]').forEach(function (el) {
|
||||
el.onclick = function () { add_playlist_video(el); };
|
||||
});
|
||||
n2a(document.querySelectorAll('[data-onclick="add_playlist_item"]')).forEach(function (e) {
|
||||
e.onclick = function () { add_playlist_item(e); };
|
||||
document.querySelectorAll('[data-onclick="add_playlist_item"]').forEach(function (el) {
|
||||
el.onclick = function () { add_playlist_item(el); };
|
||||
});
|
||||
n2a(document.querySelectorAll('[data-onclick="remove_playlist_item"]')).forEach(function (e) {
|
||||
e.onclick = function () { remove_playlist_item(e); };
|
||||
document.querySelectorAll('[data-onclick="remove_playlist_item"]').forEach(function (el) {
|
||||
el.onclick = function () { remove_playlist_item(el); };
|
||||
});
|
||||
n2a(document.querySelectorAll('[data-onclick="revoke_token"]')).forEach(function (e) {
|
||||
e.onclick = function () { revoke_token(e); };
|
||||
document.querySelectorAll('[data-onclick="revoke_token"]').forEach(function (el) {
|
||||
el.onclick = function () { revoke_token(el); };
|
||||
});
|
||||
n2a(document.querySelectorAll('[data-onclick="remove_subscription"]')).forEach(function (e) {
|
||||
e.onclick = function () { remove_subscription(e); };
|
||||
document.querySelectorAll('[data-onclick="remove_subscription"]').forEach(function (el) {
|
||||
el.onclick = function () { remove_subscription(el); };
|
||||
});
|
||||
n2a(document.querySelectorAll('[data-onclick="notification_requestPermission"]')).forEach(function (e) {
|
||||
e.onclick = function () { Notification.requestPermission(); };
|
||||
document.querySelectorAll('[data-onclick="notification_requestPermission"]').forEach(function (el) {
|
||||
el.onclick = function () { Notification.requestPermission(); };
|
||||
});
|
||||
|
||||
n2a(document.querySelectorAll('[data-onrange="update_volume_value"]')).forEach(function (e) {
|
||||
var cb = function () { update_volume_value(e); }
|
||||
e.oninput = cb;
|
||||
e.onchange = cb;
|
||||
document.querySelectorAll('[data-onrange="update_volume_value"]').forEach(function (el) {
|
||||
function update_volume_value() {
|
||||
document.getElementById('volume-value').textContent = el.value;
|
||||
}
|
||||
el.oninput = update_volume_value;
|
||||
el.onchange = update_volume_value;
|
||||
});
|
||||
|
||||
function update_volume_value(element) {
|
||||
document.getElementById('volume-value').innerText = element.value;
|
||||
}
|
||||
|
||||
function revoke_token(target) {
|
||||
var row = target.parentNode.parentNode.parentNode.parentNode.parentNode;
|
||||
row.style.display = 'none';
|
||||
var count = document.getElementById('count');
|
||||
count.innerText = count.innerText - 1;
|
||||
count.textContent--;
|
||||
|
||||
var referer = window.encodeURIComponent(document.location.href);
|
||||
var url = '/token_ajax?action_revoke_token=1&redirect=false' +
|
||||
'&referer=' + referer +
|
||||
'&referer=' + encodeURIComponent(location.href) +
|
||||
'&session=' + target.getAttribute('data-session');
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.responseType = 'json';
|
||||
xhr.timeout = 10000;
|
||||
xhr.open('POST', url, true);
|
||||
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 4) {
|
||||
if (xhr.status != 200) {
|
||||
count.innerText = parseInt(count.innerText) + 1;
|
||||
row.style.display = '';
|
||||
}
|
||||
var payload = 'csrf_token=' + target.parentNode.querySelector('input[name="csrf_token"]').value;
|
||||
|
||||
helpers.xhr('POST', url, {payload: payload}, {
|
||||
onNon200: function (xhr) {
|
||||
count.textContent++;
|
||||
row.style.display = '';
|
||||
}
|
||||
}
|
||||
|
||||
var csrf_token = target.parentNode.querySelector('input[name="csrf_token"]').value;
|
||||
xhr.send('csrf_token=' + csrf_token);
|
||||
});
|
||||
}
|
||||
|
||||
function remove_subscription(target) {
|
||||
var row = target.parentNode.parentNode.parentNode.parentNode.parentNode;
|
||||
row.style.display = 'none';
|
||||
var count = document.getElementById('count');
|
||||
count.innerText = count.innerText - 1;
|
||||
count.textContent--;
|
||||
|
||||
var referer = window.encodeURIComponent(document.location.href);
|
||||
var url = '/subscription_ajax?action_remove_subscriptions=1&redirect=false' +
|
||||
'&referer=' + referer +
|
||||
'&referer=' + encodeURIComponent(location.href) +
|
||||
'&c=' + target.getAttribute('data-ucid');
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.responseType = 'json';
|
||||
xhr.timeout = 10000;
|
||||
xhr.open('POST', url, true);
|
||||
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 4) {
|
||||
if (xhr.status != 200) {
|
||||
count.innerText = parseInt(count.innerText) + 1;
|
||||
row.style.display = '';
|
||||
}
|
||||
var payload = 'csrf_token=' + target.parentNode.querySelector('input[name="csrf_token"]').value;
|
||||
|
||||
helpers.xhr('POST', url, {payload: payload}, {
|
||||
onNon200: function (xhr) {
|
||||
count.textContent++;
|
||||
row.style.display = '';
|
||||
}
|
||||
}
|
||||
|
||||
var csrf_token = target.parentNode.querySelector('input[name="csrf_token"]').value;
|
||||
xhr.send('csrf_token=' + csrf_token);
|
||||
});
|
||||
}
|
||||
|
||||
// Handle keypresses
|
||||
window.addEventListener('keydown', (event) => {
|
||||
addEventListener('keydown', function (event) {
|
||||
// Ignore modifier keys
|
||||
if (event.ctrlKey || event.metaKey) return;
|
||||
|
||||
@@ -152,14 +134,14 @@
|
||||
let focused_tag = document.activeElement.tagName.toLowerCase();
|
||||
const allowed = /^(button|checkbox|file|radio|submit)$/;
|
||||
|
||||
if (focused_tag === "textarea") return;
|
||||
if (focused_tag === "input") {
|
||||
if (focused_tag === 'textarea') return;
|
||||
if (focused_tag === 'input') {
|
||||
let focused_type = document.activeElement.type.toLowerCase();
|
||||
if (!focused_type.match(allowed)) return;
|
||||
}
|
||||
|
||||
// Focus search bar on '/'
|
||||
if (event.key == "/") {
|
||||
if (event.key === '/') {
|
||||
document.getElementById('searchbox').focus();
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
@@ -1,46 +1,30 @@
|
||||
var notification_data = JSON.parse(document.getElementById('notification_data').innerHTML);
|
||||
'use strict';
|
||||
var notification_data = JSON.parse(document.getElementById('notification_data').textContent);
|
||||
|
||||
/** Boolean meaning 'some tab have stream' */
|
||||
const STORAGE_KEY_STREAM = 'stream';
|
||||
/** Number of notifications. May be increased or reset */
|
||||
const STORAGE_KEY_NOTIF_COUNT = 'notification_count';
|
||||
|
||||
var notifications, delivered;
|
||||
var notifications_mock = { close: function () { } };
|
||||
|
||||
function get_subscriptions(callback, retries) {
|
||||
if (retries == undefined) retries = 5;
|
||||
|
||||
if (retries <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.responseType = 'json';
|
||||
xhr.timeout = 10000;
|
||||
xhr.open('GET', '/api/v1/auth/subscriptions?fields=authorId', true);
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status === 200) {
|
||||
subscriptions = xhr.response;
|
||||
callback(subscriptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xhr.onerror = function () {
|
||||
console.log('Pulling subscriptions failed... ' + retries + '/5');
|
||||
setTimeout(function () { get_subscriptions(callback, retries - 1) }, 1000);
|
||||
}
|
||||
|
||||
xhr.ontimeout = function () {
|
||||
console.log('Pulling subscriptions failed... ' + retries + '/5');
|
||||
get_subscriptions(callback, retries - 1);
|
||||
}
|
||||
|
||||
xhr.send();
|
||||
function get_subscriptions() {
|
||||
helpers.xhr('GET', '/api/v1/auth/subscriptions?fields=authorId', {
|
||||
retries: 5,
|
||||
entity_name: 'subscriptions'
|
||||
}, {
|
||||
on200: create_notification_stream
|
||||
});
|
||||
}
|
||||
|
||||
function create_notification_stream(subscriptions) {
|
||||
// sse.js can't be replaced to EventSource in place as it lack support of payload and headers
|
||||
// see https://developer.mozilla.org/en-US/docs/Web/API/EventSource/EventSource
|
||||
notifications = new SSE(
|
||||
'/api/v1/auth/notifications?fields=videoId,title,author,authorId,publishedText,published,authorThumbnails,liveNow', {
|
||||
withCredentials: true,
|
||||
payload: 'topics=' + subscriptions.map(function (subscription) { return subscription.authorId }).join(','),
|
||||
payload: 'topics=' + subscriptions.map(function (subscription) { return subscription.authorId; }).join(','),
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
|
||||
});
|
||||
delivered = [];
|
||||
@@ -48,96 +32,100 @@ function create_notification_stream(subscriptions) {
|
||||
var start_time = Math.round(new Date() / 1000);
|
||||
|
||||
notifications.onmessage = function (event) {
|
||||
if (!event.id) {
|
||||
return;
|
||||
}
|
||||
if (!event.id) return;
|
||||
|
||||
var notification = JSON.parse(event.data);
|
||||
console.log('Got notification:', notification);
|
||||
console.info('Got notification:', notification);
|
||||
|
||||
if (start_time < notification.published && !delivered.includes(notification.videoId)) {
|
||||
if (Notification.permission === 'granted') {
|
||||
var system_notification =
|
||||
new Notification((notification.liveNow ? notification_data.live_now_text : notification_data.upload_text).replace('`x`', notification.author), {
|
||||
body: notification.title,
|
||||
icon: '/ggpht' + new URL(notification.authorThumbnails[2].url).pathname,
|
||||
img: '/ggpht' + new URL(notification.authorThumbnails[4].url).pathname,
|
||||
tag: notification.videoId
|
||||
});
|
||||
// Ignore not actual and delivered notifications
|
||||
if (start_time > notification.published || delivered.includes(notification.videoId)) return;
|
||||
|
||||
system_notification.onclick = function (event) {
|
||||
window.open('/watch?v=' + event.currentTarget.tag, '_blank');
|
||||
}
|
||||
}
|
||||
delivered.push(notification.videoId);
|
||||
|
||||
delivered.push(notification.videoId);
|
||||
localStorage.setItem('notification_count', parseInt(localStorage.getItem('notification_count') || '0') + 1);
|
||||
var notification_ticker = document.getElementById('notification_ticker');
|
||||
let notification_count = helpers.storage.get(STORAGE_KEY_NOTIF_COUNT) || 0;
|
||||
notification_count++;
|
||||
helpers.storage.set(STORAGE_KEY_NOTIF_COUNT, notification_count);
|
||||
|
||||
if (parseInt(localStorage.getItem('notification_count')) > 0) {
|
||||
notification_ticker.innerHTML =
|
||||
'<span id="notification_count">' + localStorage.getItem('notification_count') + '</span> <i class="icon ion-ios-notifications"></i>';
|
||||
} else {
|
||||
notification_ticker.innerHTML =
|
||||
'<i class="icon ion-ios-notifications-outline"></i>';
|
||||
}
|
||||
update_ticker_count();
|
||||
|
||||
// permission for notifications handled on settings page. JS handler is in handlers.js
|
||||
if (window.Notification && Notification.permission === 'granted') {
|
||||
var notification_text = notification.liveNow ? notification_data.live_now_text : notification_data.upload_text;
|
||||
notification_text = notification_text.replace('`x`', notification.author);
|
||||
|
||||
var system_notification = new Notification(notification_text, {
|
||||
body: notification.title,
|
||||
icon: '/ggpht' + new URL(notification.authorThumbnails[2].url).pathname,
|
||||
img: '/ggpht' + new URL(notification.authorThumbnails[4].url).pathname
|
||||
});
|
||||
|
||||
system_notification.onclick = function (e) {
|
||||
open('/watch?v=' + notification.videoId, '_blank');
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
notifications.addEventListener('error', function (e) {
|
||||
console.warn('Something went wrong with notifications, trying to reconnect...');
|
||||
notifications = notifications_mock;
|
||||
setTimeout(get_subscriptions, 1000);
|
||||
});
|
||||
|
||||
notifications.addEventListener('error', handle_notification_error);
|
||||
notifications.stream();
|
||||
}
|
||||
|
||||
function handle_notification_error(event) {
|
||||
console.log('Something went wrong with notifications, trying to reconnect...');
|
||||
notifications = { close: function () { } };
|
||||
setTimeout(function () { get_subscriptions(create_notification_stream) }, 1000);
|
||||
function update_ticker_count() {
|
||||
var notification_ticker = document.getElementById('notification_ticker');
|
||||
|
||||
const notification_count = helpers.storage.get(STORAGE_KEY_STREAM);
|
||||
if (notification_count > 0) {
|
||||
notification_ticker.innerHTML =
|
||||
'<span id="notification_count">' + notification_count + '</span> <i class="icon ion-ios-notifications"></i>';
|
||||
} else {
|
||||
notification_ticker.innerHTML =
|
||||
'<i class="icon ion-ios-notifications-outline"></i>';
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('load', function (e) {
|
||||
localStorage.setItem('notification_count', document.getElementById('notification_count') ? document.getElementById('notification_count').innerText : '0');
|
||||
|
||||
if (localStorage.getItem('stream')) {
|
||||
localStorage.removeItem('stream');
|
||||
} else {
|
||||
setTimeout(function () {
|
||||
if (!localStorage.getItem('stream')) {
|
||||
notifications = { close: function () { } };
|
||||
localStorage.setItem('stream', true);
|
||||
get_subscriptions(create_notification_stream);
|
||||
}
|
||||
}, Math.random() * 1000 + 50);
|
||||
}
|
||||
|
||||
window.addEventListener('storage', function (e) {
|
||||
if (e.key === 'stream' && !e.newValue) {
|
||||
if (notifications) {
|
||||
localStorage.setItem('stream', true);
|
||||
} else {
|
||||
setTimeout(function () {
|
||||
if (!localStorage.getItem('stream')) {
|
||||
notifications = { close: function () { } };
|
||||
localStorage.setItem('stream', true);
|
||||
get_subscriptions(create_notification_stream);
|
||||
}
|
||||
}, Math.random() * 1000 + 50);
|
||||
}
|
||||
} else if (e.key === 'notification_count') {
|
||||
var notification_ticker = document.getElementById('notification_ticker');
|
||||
|
||||
if (parseInt(e.newValue) > 0) {
|
||||
notification_ticker.innerHTML =
|
||||
'<span id="notification_count">' + e.newValue + '</span> <i class="icon ion-ios-notifications"></i>';
|
||||
} else {
|
||||
notification_ticker.innerHTML =
|
||||
'<i class="icon ion-ios-notifications-outline"></i>';
|
||||
}
|
||||
function start_stream_if_needed() {
|
||||
// random wait for other tabs set 'stream' flag
|
||||
setTimeout(function () {
|
||||
if (!helpers.storage.get(STORAGE_KEY_STREAM)) {
|
||||
// if no one set 'stream', set it by yourself and start stream
|
||||
helpers.storage.set(STORAGE_KEY_STREAM, true);
|
||||
notifications = notifications_mock;
|
||||
get_subscriptions();
|
||||
}
|
||||
});
|
||||
});
|
||||
}, Math.random() * 1000 + 50); // [0.050 .. 1.050) second
|
||||
}
|
||||
|
||||
window.addEventListener('unload', function (e) {
|
||||
if (notifications) {
|
||||
localStorage.removeItem('stream');
|
||||
|
||||
addEventListener('storage', function (e) {
|
||||
if (e.key === STORAGE_KEY_NOTIF_COUNT)
|
||||
update_ticker_count();
|
||||
|
||||
// if 'stream' key was removed
|
||||
if (e.key === STORAGE_KEY_STREAM && !helpers.storage.get(STORAGE_KEY_STREAM)) {
|
||||
if (notifications) {
|
||||
// restore it if we have active stream
|
||||
helpers.storage.set(STORAGE_KEY_STREAM, true);
|
||||
} else {
|
||||
start_stream_if_needed();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
addEventListener('load', function () {
|
||||
var notification_count_el = document.getElementById('notification_count');
|
||||
var notification_count = notification_count_el ? parseInt(notification_count_el.textContent) : 0;
|
||||
helpers.storage.set(STORAGE_KEY_NOTIF_COUNT, notification_count);
|
||||
|
||||
if (helpers.storage.get(STORAGE_KEY_STREAM))
|
||||
helpers.storage.remove(STORAGE_KEY_STREAM);
|
||||
start_stream_if_needed();
|
||||
});
|
||||
|
||||
addEventListener('unload', function () {
|
||||
// let chance to other tabs to be a streamer via firing 'storage' event
|
||||
if (notifications) helpers.storage.remove(STORAGE_KEY_STREAM);
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
var player_data = JSON.parse(document.getElementById('player_data').innerHTML);
|
||||
var video_data = JSON.parse(document.getElementById('video_data').innerHTML);
|
||||
'use strict';
|
||||
var player_data = JSON.parse(document.getElementById('player_data').textContent);
|
||||
var video_data = JSON.parse(document.getElementById('video_data').textContent);
|
||||
|
||||
var options = {
|
||||
preload: 'auto',
|
||||
@@ -16,6 +17,7 @@ var options = {
|
||||
'remainingTimeDisplay',
|
||||
'Spacer',
|
||||
'captionsButton',
|
||||
'audioTrackButton',
|
||||
'qualitySelector',
|
||||
'playbackRateMenuButton',
|
||||
'fullscreenToggle'
|
||||
@@ -27,7 +29,7 @@ var options = {
|
||||
overrideNative: true
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (player_data.aspect_ratio) {
|
||||
options.aspectRatio = player_data.aspect_ratio;
|
||||
@@ -38,21 +40,66 @@ embed_url.searchParams.delete('v');
|
||||
var short_url = location.origin + '/' + video_data.id + embed_url.search;
|
||||
embed_url = location.origin + '/embed/' + video_data.id + embed_url.search;
|
||||
|
||||
var save_player_pos_key = "save_player_pos";
|
||||
var save_player_pos_key = 'save_player_pos';
|
||||
|
||||
videojs.Vhs.xhr.beforeRequest = function(options) {
|
||||
if (options.uri.indexOf('videoplayback') === -1 && options.uri.indexOf('local=true') === -1) {
|
||||
options.uri = options.uri + '?local=true';
|
||||
// set local if requested not videoplayback
|
||||
if (!options.uri.includes('videoplayback')) {
|
||||
if (!options.uri.includes('local=true'))
|
||||
options.uri += '?local=true';
|
||||
}
|
||||
return options;
|
||||
};
|
||||
|
||||
var player = videojs('player', options);
|
||||
|
||||
player.on('error', function () {
|
||||
if (video_data.params.quality === 'dash') return;
|
||||
|
||||
var localNotDisabled = (
|
||||
!player.currentSrc().includes('local=true') && !video_data.local_disabled
|
||||
);
|
||||
var reloadMakesSense = (
|
||||
player.error().code === MediaError.MEDIA_ERR_NETWORK ||
|
||||
player.error().code === MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED
|
||||
);
|
||||
|
||||
if (localNotDisabled) {
|
||||
// add local=true to all current sources
|
||||
player.src(player.currentSources().map(function (source) {
|
||||
source.src += '&local=true';
|
||||
return source;
|
||||
}));
|
||||
} else if (reloadMakesSense) {
|
||||
setTimeout(function () {
|
||||
console.warn('An error occurred in the player, reloading...');
|
||||
|
||||
// After load() all parameters are reset. Save them
|
||||
var currentTime = player.currentTime();
|
||||
var playbackRate = player.playbackRate();
|
||||
var paused = player.paused();
|
||||
|
||||
player.load();
|
||||
|
||||
if (currentTime > 0.5) currentTime -= 0.5;
|
||||
|
||||
player.currentTime(currentTime);
|
||||
player.playbackRate(playbackRate);
|
||||
if (!paused) player.play();
|
||||
}, 5000);
|
||||
}
|
||||
});
|
||||
|
||||
if (video_data.params.quality === 'dash') {
|
||||
player.reloadSourceOnError({
|
||||
errorInterval: 10
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for add time argument to url
|
||||
* @param {String} url
|
||||
* @returns urlWithTimeArg
|
||||
* @returns {URL} urlWithTimeArg
|
||||
*/
|
||||
function addCurrentTimeToURL(url) {
|
||||
var urlUsed = new URL(url);
|
||||
@@ -75,18 +122,12 @@ var shareOptions = {
|
||||
description: player_data.description,
|
||||
image: player_data.thumbnail,
|
||||
get embedCode() {
|
||||
// Single quotes inside here required. HTML inserted as is into value attribute of input
|
||||
return "<iframe id='ivplayer' width='640' height='360' src='" +
|
||||
addCurrentTimeToURL(embed_url) + "' style='border:none;'></iframe>";
|
||||
}
|
||||
};
|
||||
|
||||
const storage = (() => {
|
||||
try { if (localStorage.length !== -1) return localStorage; }
|
||||
catch (e) { console.info('No storage available: ' + e); }
|
||||
|
||||
return undefined;
|
||||
})();
|
||||
|
||||
if (location.pathname.startsWith('/embed/')) {
|
||||
var overlay_content = '<h1><a rel="noopener" target="_blank" href="' + location.origin + '/watch?v=' + video_data.id + '">' + player_data.title + '</a></h1>';
|
||||
player.overlay({
|
||||
@@ -101,78 +142,58 @@ if (location.pathname.startsWith('/embed/')) {
|
||||
// Detection code taken from https://stackoverflow.com/a/20293441
|
||||
|
||||
function isMobile() {
|
||||
try{ document.createEvent("TouchEvent"); return true; }
|
||||
try{ document.createEvent('TouchEvent'); return true; }
|
||||
catch(e){ return false; }
|
||||
}
|
||||
|
||||
if (isMobile()) {
|
||||
player.mobileUi();
|
||||
player.mobileUi({ touchControls: { seekSeconds: 5 * player.playbackRate() } });
|
||||
|
||||
buttons = ["playToggle", "volumePanel", "captionsButton"];
|
||||
var buttons = ['playToggle', 'volumePanel', 'captionsButton'];
|
||||
|
||||
if (video_data.params.quality !== 'dash') buttons.push("qualitySelector")
|
||||
if (!video_data.params.listen && video_data.params.quality === 'dash') buttons.push('audioTrackButton');
|
||||
if (video_data.params.listen || video_data.params.quality !== 'dash') buttons.push('qualitySelector');
|
||||
|
||||
// Create new control bar object for operation buttons
|
||||
const ControlBar = videojs.getComponent("controlBar");
|
||||
const ControlBar = videojs.getComponent('controlBar');
|
||||
let operations_bar = new ControlBar(player, {
|
||||
children: [],
|
||||
playbackRates: [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0]
|
||||
});
|
||||
buttons.slice(1).forEach(child => operations_bar.addChild(child))
|
||||
buttons.slice(1).forEach(function (child) {operations_bar.addChild(child);});
|
||||
|
||||
// Remove operation buttons from primary control bar
|
||||
primary_control_bar = player.getChild("controlBar");
|
||||
buttons.forEach(child => primary_control_bar.removeChild(child));
|
||||
var primary_control_bar = player.getChild('controlBar');
|
||||
buttons.forEach(function (child) {primary_control_bar.removeChild(child);});
|
||||
|
||||
operations_bar_element = operations_bar.el();
|
||||
operations_bar_element.className += " mobile-operations-bar"
|
||||
player.addChild(operations_bar)
|
||||
var operations_bar_element = operations_bar.el();
|
||||
operations_bar_element.classList.add('mobile-operations-bar');
|
||||
player.addChild(operations_bar);
|
||||
|
||||
// Playback menu doesn't work when it's initialized outside of the primary control bar
|
||||
playback_element = document.getElementsByClassName("vjs-playback-rate")[0]
|
||||
operations_bar_element.append(playback_element)
|
||||
var playback_element = document.getElementsByClassName('vjs-playback-rate')[0];
|
||||
operations_bar_element.append(playback_element);
|
||||
|
||||
// The share and http source selector element can't be fetched till the players ready.
|
||||
player.one("playing", () => {
|
||||
share_element = document.getElementsByClassName("vjs-share-control")[0]
|
||||
operations_bar_element.append(share_element)
|
||||
player.one('playing', function () {
|
||||
var share_element = document.getElementsByClassName('vjs-share-control')[0];
|
||||
operations_bar_element.append(share_element);
|
||||
|
||||
if (video_data.params.quality === 'dash') {
|
||||
http_source_selector = document.getElementsByClassName("vjs-http-source-selector vjs-menu-button")[0]
|
||||
operations_bar_element.append(http_source_selector)
|
||||
}
|
||||
})
|
||||
if (!video_data.params.listen && video_data.params.quality === 'dash') {
|
||||
var http_source_selector = document.getElementsByClassName('vjs-http-source-selector vjs-menu-button')[0];
|
||||
operations_bar_element.append(http_source_selector);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
player.on('error', function (event) {
|
||||
if (player.error().code === 2 || player.error().code === 4) {
|
||||
setTimeout(function (event) {
|
||||
console.log('An error occurred in the player, reloading...');
|
||||
|
||||
var currentTime = player.currentTime();
|
||||
var playbackRate = player.playbackRate();
|
||||
var paused = player.paused();
|
||||
|
||||
player.load();
|
||||
|
||||
if (currentTime > 0.5) currentTime -= 0.5;
|
||||
|
||||
player.currentTime(currentTime);
|
||||
player.playbackRate(playbackRate);
|
||||
|
||||
if (!paused) player.play();
|
||||
}, 5000);
|
||||
}
|
||||
});
|
||||
|
||||
// Enable VR video support
|
||||
if (!video_data.params.listen && video_data.vr && video_data.params.vr_mode) {
|
||||
player.crossOrigin("anonymous")
|
||||
player.crossOrigin('anonymous');
|
||||
switch (video_data.projection_type) {
|
||||
case "EQUIRECTANGULAR":
|
||||
player.vr({projection: "equirectangular"});
|
||||
default: // Should only be "MESH" but we'll use this as a fallback.
|
||||
player.vr({projection: "EAC"});
|
||||
case 'EQUIRECTANGULAR':
|
||||
player.vr({projection: 'equirectangular'});
|
||||
default: // Should only be 'MESH' but we'll use this as a fallback.
|
||||
player.vr({projection: 'EAC'});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,9 +221,76 @@ if (video_data.params.video_start > 0 || video_data.params.video_end > 0) {
|
||||
player.volume(video_data.params.volume / 100);
|
||||
player.playbackRate(video_data.params.speed);
|
||||
|
||||
/**
|
||||
* Method for getting the contents of a cookie
|
||||
*
|
||||
* @param {String} name Name of cookie
|
||||
* @returns {String|null} cookieValue
|
||||
*/
|
||||
function getCookieValue(name) {
|
||||
var cookiePrefix = name + '=';
|
||||
var matchedCookie = document.cookie.split(';').find(function (item) {return item.includes(cookiePrefix);});
|
||||
if (matchedCookie)
|
||||
return matchedCookie.replace(cookiePrefix, '');
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for updating the 'PREFS' cookie (or creating it if missing)
|
||||
*
|
||||
* @param {number} newVolume New volume defined (null if unchanged)
|
||||
* @param {number} newSpeed New speed defined (null if unchanged)
|
||||
*/
|
||||
function updateCookie(newVolume, newSpeed) {
|
||||
var volumeValue = newVolume !== null ? newVolume : video_data.params.volume;
|
||||
var speedValue = newSpeed !== null ? newSpeed : video_data.params.speed;
|
||||
|
||||
var cookieValue = getCookieValue('PREFS');
|
||||
var cookieData;
|
||||
|
||||
if (cookieValue !== null) {
|
||||
var cookieJson = JSON.parse(decodeURIComponent(cookieValue));
|
||||
cookieJson.volume = volumeValue;
|
||||
cookieJson.speed = speedValue;
|
||||
cookieData = encodeURIComponent(JSON.stringify(cookieJson));
|
||||
} else {
|
||||
cookieData = encodeURIComponent(JSON.stringify({ 'volume': volumeValue, 'speed': speedValue }));
|
||||
}
|
||||
|
||||
// Set expiration in 2 year
|
||||
var date = new Date();
|
||||
date.setFullYear(date.getFullYear() + 2);
|
||||
|
||||
var ipRegex = /^((\d+\.){3}\d+|[A-Fa-f0-9]*:[A-Fa-f0-9:]*:[A-Fa-f0-9:]+)$/;
|
||||
var domainUsed = location.hostname;
|
||||
|
||||
// Fix for a bug in FF where the leading dot in the FQDN is not ignored
|
||||
if (domainUsed.charAt(0) !== '.' && !ipRegex.test(domainUsed) && domainUsed !== 'localhost')
|
||||
domainUsed = '.' + location.hostname;
|
||||
|
||||
var secure = location.protocol.startsWith("https") ? " Secure;" : "";
|
||||
|
||||
document.cookie = 'PREFS=' + cookieData + '; SameSite=Lax; path=/; domain=' +
|
||||
domainUsed + '; expires=' + date.toGMTString() + ';' + secure;
|
||||
|
||||
video_data.params.volume = volumeValue;
|
||||
video_data.params.speed = speedValue;
|
||||
}
|
||||
|
||||
player.on('ratechange', function () {
|
||||
updateCookie(null, player.playbackRate());
|
||||
if (isMobile()) {
|
||||
player.mobileUi({ touchControls: { seekSeconds: 5 * player.playbackRate() } });
|
||||
}
|
||||
});
|
||||
|
||||
player.on('volumechange', function () {
|
||||
updateCookie(Math.ceil(player.volume() * 100), null);
|
||||
});
|
||||
|
||||
player.on('waiting', function () {
|
||||
if (player.playbackRate() > 1 && player.liveTracker.isLive() && player.liveTracker.atLiveEdge()) {
|
||||
console.log('Player has caught up to source, resetting playbackRate.')
|
||||
console.info('Player has caught up to source, resetting playbackRate');
|
||||
player.playbackRate(1);
|
||||
}
|
||||
});
|
||||
@@ -213,13 +301,13 @@ if (video_data.premiere_timestamp && Math.round(new Date() / 1000) < video_data.
|
||||
|
||||
if (video_data.params.save_player_pos) {
|
||||
const url = new URL(location);
|
||||
const hasTimeParam = url.searchParams.has("t");
|
||||
const remeberedTime = get_video_time();
|
||||
const hasTimeParam = url.searchParams.has('t');
|
||||
const rememberedTime = get_video_time();
|
||||
let lastUpdated = 0;
|
||||
|
||||
if(!hasTimeParam) set_seconds_after_start(remeberedTime);
|
||||
if(!hasTimeParam) set_seconds_after_start(rememberedTime);
|
||||
|
||||
const updateTime = () => {
|
||||
player.on('timeupdate', function () {
|
||||
const raw = player.currentTime();
|
||||
const time = Math.floor(raw);
|
||||
|
||||
@@ -227,9 +315,7 @@ if (video_data.params.save_player_pos) {
|
||||
save_video_time(time);
|
||||
lastUpdated = time;
|
||||
}
|
||||
};
|
||||
|
||||
player.on("timeupdate", updateTime);
|
||||
});
|
||||
}
|
||||
else remove_all_video_times();
|
||||
|
||||
@@ -239,13 +325,13 @@ if (video_data.params.autoplay) {
|
||||
|
||||
player.ready(function () {
|
||||
new Promise(function (resolve, reject) {
|
||||
setTimeout(() => resolve(1), 1);
|
||||
setTimeout(function () {resolve(1);}, 1);
|
||||
}).then(function (result) {
|
||||
var promise = player.play();
|
||||
|
||||
if (promise !== undefined) {
|
||||
promise.then(_ => {
|
||||
}).catch(error => {
|
||||
promise.then(function () {
|
||||
}).catch(function (error) {
|
||||
bpb.show();
|
||||
});
|
||||
}
|
||||
@@ -256,67 +342,47 @@ if (video_data.params.autoplay) {
|
||||
if (!video_data.params.listen && video_data.params.quality === 'dash') {
|
||||
player.httpSourceSelector();
|
||||
|
||||
if (video_data.params.quality_dash != "auto") {
|
||||
player.ready(() => {
|
||||
player.on("loadedmetadata", () => {
|
||||
const qualityLevels = Array.from(player.qualityLevels()).sort((a, b) => a.height - b.height);
|
||||
if (video_data.params.quality_dash !== 'auto') {
|
||||
player.ready(function () {
|
||||
player.on('loadedmetadata', function () {
|
||||
const qualityLevels = Array.from(player.qualityLevels()).sort(function (a, b) {return a.height - b.height;});
|
||||
let targetQualityLevel;
|
||||
switch (video_data.params.quality_dash) {
|
||||
case "best":
|
||||
case 'best':
|
||||
targetQualityLevel = qualityLevels.length - 1;
|
||||
break;
|
||||
case "worst":
|
||||
case 'worst':
|
||||
targetQualityLevel = 0;
|
||||
break;
|
||||
default:
|
||||
const targetHeight = Number.parseInt(video_data.params.quality_dash, 10);
|
||||
const targetHeight = parseInt(video_data.params.quality_dash);
|
||||
for (let i = 0; i < qualityLevels.length; i++) {
|
||||
if (qualityLevels[i].height <= targetHeight) {
|
||||
if (qualityLevels[i].height <= targetHeight)
|
||||
targetQualityLevel = i;
|
||||
} else {
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < qualityLevels.length; i++) {
|
||||
qualityLevels[i].enabled = (i == targetQualityLevel);
|
||||
}
|
||||
qualityLevels.forEach(function (level, index) {
|
||||
level.enabled = (index === targetQualityLevel);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
player.vttThumbnails({
|
||||
src: location.origin + '/api/v1/storyboards/' + video_data.id + '?height=90',
|
||||
src: '/api/v1/storyboards/' + video_data.id + '?height=90',
|
||||
showTimestamp: true
|
||||
});
|
||||
|
||||
// Enable annotations
|
||||
if (!video_data.params.listen && video_data.params.annotations) {
|
||||
window.addEventListener('load', function (e) {
|
||||
var video_container = document.getElementById('player');
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.responseType = 'text';
|
||||
xhr.timeout = 60000;
|
||||
xhr.open('GET', '/api/v1/annotations/' + video_data.id, true);
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status === 200) {
|
||||
videojs.registerPlugin('youtubeAnnotationsPlugin', youtubeAnnotationsPlugin);
|
||||
if (!player.paused()) {
|
||||
player.youtubeAnnotationsPlugin({ annotationXml: xhr.response, videoContainer: video_container });
|
||||
} else {
|
||||
player.one('play', function (event) {
|
||||
player.youtubeAnnotationsPlugin({ annotationXml: xhr.response, videoContainer: video_container });
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('__ar_annotation_click', e => {
|
||||
const { url, target, seconds } = e.detail;
|
||||
addEventListener('load', function (e) {
|
||||
addEventListener('__ar_annotation_click', function (e) {
|
||||
const url = e.detail.url,
|
||||
target = e.detail.target,
|
||||
seconds = e.detail.seconds;
|
||||
var path = new URL(url);
|
||||
|
||||
if (path.href.startsWith('https://www.youtube.com/watch?') && seconds) {
|
||||
@@ -326,41 +392,48 @@ if (!video_data.params.listen && video_data.params.annotations) {
|
||||
path = path.pathname + path.search;
|
||||
|
||||
if (target === 'current') {
|
||||
window.location.href = path;
|
||||
location.href = path;
|
||||
} else if (target === 'new') {
|
||||
window.open(path, '_blank');
|
||||
open(path, '_blank');
|
||||
}
|
||||
});
|
||||
|
||||
helpers.xhr('GET', '/api/v1/annotations/' + video_data.id, {
|
||||
responseType: 'text',
|
||||
timeout: 60000
|
||||
}, {
|
||||
on200: function (response) {
|
||||
var video_container = document.getElementById('player');
|
||||
videojs.registerPlugin('youtubeAnnotationsPlugin', youtubeAnnotationsPlugin);
|
||||
if (player.paused()) {
|
||||
player.one('play', function (event) {
|
||||
player.youtubeAnnotationsPlugin({ annotationXml: response, videoContainer: video_container });
|
||||
});
|
||||
} else {
|
||||
player.youtubeAnnotationsPlugin({ annotationXml: response, videoContainer: video_container });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
xhr.send();
|
||||
});
|
||||
}
|
||||
|
||||
function increase_volume(delta) {
|
||||
function change_volume(delta) {
|
||||
const curVolume = player.volume();
|
||||
let newVolume = curVolume + delta;
|
||||
if (newVolume > 1) {
|
||||
newVolume = 1;
|
||||
} else if (newVolume < 0) {
|
||||
newVolume = 0;
|
||||
}
|
||||
newVolume = helpers.clamp(newVolume, 0, 1);
|
||||
player.volume(newVolume);
|
||||
}
|
||||
|
||||
function toggle_muted() {
|
||||
const isMuted = player.muted();
|
||||
player.muted(!isMuted);
|
||||
player.muted(!player.muted());
|
||||
}
|
||||
|
||||
function skip_seconds(delta) {
|
||||
const duration = player.duration();
|
||||
const curTime = player.currentTime();
|
||||
let newTime = curTime + delta;
|
||||
if (newTime > duration) {
|
||||
newTime = duration;
|
||||
} else if (newTime < 0) {
|
||||
newTime = 0;
|
||||
}
|
||||
newTime = helpers.clamp(newTime, 0, duration);
|
||||
player.currentTime(newTime);
|
||||
}
|
||||
|
||||
@@ -370,57 +443,21 @@ function set_seconds_after_start(delta) {
|
||||
}
|
||||
|
||||
function save_video_time(seconds) {
|
||||
const videoId = video_data.id;
|
||||
const all_video_times = get_all_video_times();
|
||||
|
||||
all_video_times[videoId] = seconds;
|
||||
|
||||
set_all_video_times(all_video_times);
|
||||
all_video_times[video_data.id] = seconds;
|
||||
helpers.storage.set(save_player_pos_key, all_video_times);
|
||||
}
|
||||
|
||||
function get_video_time() {
|
||||
try {
|
||||
const videoId = video_data.id;
|
||||
const all_video_times = get_all_video_times();
|
||||
const timestamp = all_video_times[videoId];
|
||||
|
||||
return timestamp || 0;
|
||||
}
|
||||
catch {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function set_all_video_times(times) {
|
||||
if (storage) {
|
||||
if (times) {
|
||||
try {
|
||||
storage.setItem(save_player_pos_key, JSON.stringify(times));
|
||||
} catch (e) {
|
||||
console.debug('set_all_video_times: ' + e);
|
||||
}
|
||||
} else {
|
||||
storage.removeItem(save_player_pos_key);
|
||||
}
|
||||
}
|
||||
return get_all_video_times()[video_data.id] || 0;
|
||||
}
|
||||
|
||||
function get_all_video_times() {
|
||||
if (storage) {
|
||||
const raw = storage.getItem(save_player_pos_key);
|
||||
if (raw !== null) {
|
||||
try {
|
||||
return JSON.parse(raw);
|
||||
} catch (e) {
|
||||
console.debug('get_all_video_times: ' + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
return helpers.storage.get(save_player_pos_key) || {};
|
||||
}
|
||||
|
||||
function remove_all_video_times() {
|
||||
set_all_video_times(null);
|
||||
helpers.storage.remove(save_player_pos_key);
|
||||
}
|
||||
|
||||
function set_time_percent(percent) {
|
||||
@@ -436,21 +473,23 @@ function toggle_play() { player.paused() ? play() : pause(); }
|
||||
|
||||
const toggle_captions = (function () {
|
||||
let toggledTrack = null;
|
||||
const onChange = function (e) {
|
||||
toggledTrack = null;
|
||||
};
|
||||
const bindChange = function (onOrOff) {
|
||||
player.textTracks()[onOrOff]('change', onChange);
|
||||
};
|
||||
|
||||
function bindChange(onOrOff) {
|
||||
player.textTracks()[onOrOff]('change', function (e) {
|
||||
toggledTrack = null;
|
||||
});
|
||||
}
|
||||
|
||||
// Wrapper function to ignore our own emitted events and only listen
|
||||
// to events emitted by Video.js on click on the captions menu items.
|
||||
const setMode = function (track, mode) {
|
||||
function setMode(track, mode) {
|
||||
bindChange('off');
|
||||
track.mode = mode;
|
||||
window.setTimeout(function () {
|
||||
setTimeout(function () {
|
||||
bindChange('on');
|
||||
}, 0);
|
||||
};
|
||||
}
|
||||
|
||||
bindChange('on');
|
||||
return function () {
|
||||
if (toggledTrack !== null) {
|
||||
@@ -498,15 +537,11 @@ function increase_playback_rate(steps) {
|
||||
const maxIndex = options.playbackRates.length - 1;
|
||||
const curIndex = options.playbackRates.indexOf(player.playbackRate());
|
||||
let newIndex = curIndex + steps;
|
||||
if (newIndex > maxIndex) {
|
||||
newIndex = maxIndex;
|
||||
} else if (newIndex < 0) {
|
||||
newIndex = 0;
|
||||
}
|
||||
newIndex = helpers.clamp(newIndex, 0, maxIndex);
|
||||
player.playbackRate(options.playbackRates[newIndex]);
|
||||
}
|
||||
|
||||
window.addEventListener('keydown', e => {
|
||||
addEventListener('keydown', function (e) {
|
||||
if (e.target.tagName.toLowerCase() === 'input') {
|
||||
// Ignore input when focus is on certain elements, e.g. form fields.
|
||||
return;
|
||||
@@ -539,10 +574,10 @@ window.addEventListener('keydown', e => {
|
||||
case 'MediaStop': action = stop; break;
|
||||
|
||||
case 'ArrowUp':
|
||||
if (isPlayerFocused) action = increase_volume.bind(this, 0.1);
|
||||
if (isPlayerFocused) action = change_volume.bind(this, 0.1);
|
||||
break;
|
||||
case 'ArrowDown':
|
||||
if (isPlayerFocused) action = increase_volume.bind(this, -0.1);
|
||||
if (isPlayerFocused) action = change_volume.bind(this, -0.1);
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
@@ -593,12 +628,11 @@ window.addEventListener('keydown', e => {
|
||||
// TODO: Add support to play back previous video.
|
||||
break;
|
||||
|
||||
case '.':
|
||||
// TODO: Add support for next-frame-stepping.
|
||||
break;
|
||||
case ',':
|
||||
// TODO: Add support for previous-frame-stepping.
|
||||
break;
|
||||
// TODO: More precise step. Now FPS is taken equal to 29.97
|
||||
// Common FPS: https://forum.videohelp.com/threads/81868#post323588
|
||||
// Possible solution is new HTMLVideoElement.requestVideoFrameCallback() https://wicg.github.io/video-rvfc/
|
||||
case ',': action = function () { pause(); skip_seconds(-1/29.97); }; break;
|
||||
case '.': action = function () { pause(); skip_seconds( 1/29.97); }; break;
|
||||
|
||||
case '>': action = increase_playback_rate.bind(this, 1); break;
|
||||
case '<': action = increase_playback_rate.bind(this, -1); break;
|
||||
@@ -617,84 +651,77 @@ window.addEventListener('keydown', e => {
|
||||
// Add support for controlling the player volume by scrolling over it. Adapted from
|
||||
// https://github.com/ctd1500/videojs-hotkeys/blob/bb4a158b2e214ccab87c2e7b95f42bc45c6bfd87/videojs.hotkeys.js#L292-L328
|
||||
(function () {
|
||||
const volumeStep = 0.05;
|
||||
const enableVolumeScroll = true;
|
||||
const enableHoverScroll = true;
|
||||
const doc = document;
|
||||
const pEl = document.getElementById('player');
|
||||
|
||||
var volumeHover = false;
|
||||
var volumeSelector = pEl.querySelector('.vjs-volume-menu-button') || pEl.querySelector('.vjs-volume-panel');
|
||||
if (volumeSelector != null) {
|
||||
if (volumeSelector !== null) {
|
||||
volumeSelector.onmouseover = function () { volumeHover = true; };
|
||||
volumeSelector.onmouseout = function () { volumeHover = false; };
|
||||
}
|
||||
|
||||
var mouseScroll = function mouseScroll(event) {
|
||||
var activeEl = doc.activeElement;
|
||||
if (enableHoverScroll) {
|
||||
// If we leave this undefined then it can match non-existent elements below
|
||||
activeEl = 0;
|
||||
}
|
||||
|
||||
function mouseScroll(event) {
|
||||
// When controls are disabled, hotkeys will be disabled as well
|
||||
if (player.controls()) {
|
||||
if (volumeHover) {
|
||||
if (enableVolumeScroll) {
|
||||
event = window.event || event;
|
||||
var delta = Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail)));
|
||||
event.preventDefault();
|
||||
if (!player.controls() || !volumeHover) return;
|
||||
|
||||
if (delta == 1) {
|
||||
increase_volume(volumeStep);
|
||||
} else if (delta == -1) {
|
||||
increase_volume(-volumeStep);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
event.preventDefault();
|
||||
var wheelMove = event.wheelDelta || -event.detail;
|
||||
var volumeSign = Math.sign(wheelMove);
|
||||
|
||||
change_volume(volumeSign * 0.05); // decrease/increase by 5%
|
||||
}
|
||||
|
||||
player.on('mousewheel', mouseScroll);
|
||||
player.on("DOMMouseScroll", mouseScroll);
|
||||
player.on('DOMMouseScroll', mouseScroll);
|
||||
}());
|
||||
|
||||
// Since videojs-share can sometimes be blocked, we defer it until last
|
||||
if (player.share) {
|
||||
player.share(shareOptions);
|
||||
}
|
||||
if (player.share) player.share(shareOptions);
|
||||
|
||||
// show the preferred caption by default
|
||||
if (player_data.preferred_caption_found) {
|
||||
player.ready(() => {
|
||||
player.textTracks()[1].mode = 'showing';
|
||||
player.ready(function () {
|
||||
if (!video_data.params.listen && video_data.params.quality === 'dash') {
|
||||
// play.textTracks()[0] on DASH mode is showing some debug messages
|
||||
player.textTracks()[1].mode = 'showing';
|
||||
} else {
|
||||
player.textTracks()[0].mode = 'showing';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Safari audio double duration fix
|
||||
if (navigator.vendor == "Apple Computer, Inc." && video_data.params.listen) {
|
||||
if (navigator.vendor === 'Apple Computer, Inc.' && video_data.params.listen) {
|
||||
player.on('loadedmetadata', function () {
|
||||
player.on('timeupdate', function () {
|
||||
if (player.remainingTime() < player.duration() / 2) {
|
||||
player.currentTime(player.duration() + 1);
|
||||
if (player.remainingTime() < player.duration() / 2 && player.remainingTime() >= 2) {
|
||||
player.currentTime(player.duration() - 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Watch on Invidious link
|
||||
if (window.location.pathname.startsWith("/embed/")) {
|
||||
if (location.pathname.startsWith('/embed/')) {
|
||||
const Button = videojs.getComponent('Button');
|
||||
let watch_on_invidious_button = new Button(player);
|
||||
|
||||
// Create hyperlink for current instance
|
||||
redirect_element = document.createElement("a");
|
||||
redirect_element.setAttribute("href", `http://${window.location.host}/watch?v=${window.location.pathname.replace("/embed/","")}`)
|
||||
redirect_element.appendChild(document.createTextNode("Invidious"))
|
||||
var redirect_element = document.createElement('a');
|
||||
redirect_element.setAttribute('href', location.pathname.replace('/embed/', '/watch?v='));
|
||||
redirect_element.appendChild(document.createTextNode('Invidious'));
|
||||
|
||||
watch_on_invidious_button.el().appendChild(redirect_element)
|
||||
watch_on_invidious_button.addClass("watch-on-invidious")
|
||||
watch_on_invidious_button.el().appendChild(redirect_element);
|
||||
watch_on_invidious_button.addClass('watch-on-invidious');
|
||||
|
||||
cb = player.getChild('ControlBar')
|
||||
cb.addChild(watch_on_invidious_button)
|
||||
};
|
||||
var cb = player.getChild('ControlBar');
|
||||
cb.addChild(watch_on_invidious_button);
|
||||
}
|
||||
|
||||
addEventListener('DOMContentLoaded', function () {
|
||||
// Save time during redirection on another instance
|
||||
const changeInstanceLink = document.querySelector('#watch-on-another-invidious-instance > a');
|
||||
if (changeInstanceLink) changeInstanceLink.addEventListener('click', function () {
|
||||
changeInstanceLink.href = addCurrentTimeToURL(changeInstanceLink.href);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
var playlist_data = JSON.parse(document.getElementById('playlist_data').innerHTML);
|
||||
'use strict';
|
||||
var playlist_data = JSON.parse(document.getElementById('playlist_data').textContent);
|
||||
var payload = 'csrf_token=' + playlist_data.csrf_token;
|
||||
|
||||
function add_playlist_video(target) {
|
||||
var select = target.parentNode.children[0].children[1];
|
||||
@@ -7,21 +9,12 @@ function add_playlist_video(target) {
|
||||
var url = '/playlist_ajax?action_add_video=1&redirect=false' +
|
||||
'&video_id=' + target.getAttribute('data-id') +
|
||||
'&playlist_id=' + option.getAttribute('data-plid');
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.responseType = 'json';
|
||||
xhr.timeout = 10000;
|
||||
xhr.open('POST', url, true);
|
||||
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 4) {
|
||||
if (xhr.status == 200) {
|
||||
option.innerText = '✓' + option.innerText;
|
||||
}
|
||||
helpers.xhr('POST', url, {payload: payload}, {
|
||||
on200: function (response) {
|
||||
option.textContent = '✓' + option.textContent;
|
||||
}
|
||||
}
|
||||
|
||||
xhr.send('csrf_token=' + playlist_data.csrf_token);
|
||||
});
|
||||
}
|
||||
|
||||
function add_playlist_item(target) {
|
||||
@@ -31,21 +24,12 @@ function add_playlist_item(target) {
|
||||
var url = '/playlist_ajax?action_add_video=1&redirect=false' +
|
||||
'&video_id=' + target.getAttribute('data-id') +
|
||||
'&playlist_id=' + target.getAttribute('data-plid');
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.responseType = 'json';
|
||||
xhr.timeout = 10000;
|
||||
xhr.open('POST', url, true);
|
||||
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 4) {
|
||||
if (xhr.status != 200) {
|
||||
tile.style.display = '';
|
||||
}
|
||||
helpers.xhr('POST', url, {payload: payload}, {
|
||||
onNon200: function (xhr) {
|
||||
tile.style.display = '';
|
||||
}
|
||||
}
|
||||
|
||||
xhr.send('csrf_token=' + playlist_data.csrf_token);
|
||||
});
|
||||
}
|
||||
|
||||
function remove_playlist_item(target) {
|
||||
@@ -55,19 +39,10 @@ function remove_playlist_item(target) {
|
||||
var url = '/playlist_ajax?action_remove_video=1&redirect=false' +
|
||||
'&set_video_id=' + target.getAttribute('data-index') +
|
||||
'&playlist_id=' + target.getAttribute('data-plid');
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.responseType = 'json';
|
||||
xhr.timeout = 10000;
|
||||
xhr.open('POST', url, true);
|
||||
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 4) {
|
||||
if (xhr.status != 200) {
|
||||
tile.style.display = '';
|
||||
}
|
||||
helpers.xhr('POST', url, {payload: payload}, {
|
||||
onNon200: function (xhr) {
|
||||
tile.style.display = '';
|
||||
}
|
||||
}
|
||||
|
||||
xhr.send('csrf_token=' + playlist_data.csrf_token);
|
||||
});
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -1,7 +1,9 @@
|
||||
var subscribe_data = JSON.parse(document.getElementById('subscribe_data').innerHTML);
|
||||
'use strict';
|
||||
var subscribe_data = JSON.parse(document.getElementById('subscribe_data').textContent);
|
||||
var payload = 'csrf_token=' + subscribe_data.csrf_token;
|
||||
|
||||
var subscribe_button = document.getElementById('subscribe');
|
||||
subscribe_button.parentNode['action'] = 'javascript:void(0)';
|
||||
subscribe_button.parentNode.action = 'javascript:void(0)';
|
||||
|
||||
if (subscribe_button.getAttribute('data-type') === 'subscribe') {
|
||||
subscribe_button.onclick = subscribe;
|
||||
@@ -9,82 +11,34 @@ if (subscribe_button.getAttribute('data-type') === 'subscribe') {
|
||||
subscribe_button.onclick = unsubscribe;
|
||||
}
|
||||
|
||||
function subscribe(retries = 5) {
|
||||
if (retries <= 0) {
|
||||
console.log('Failed to subscribe.');
|
||||
return;
|
||||
}
|
||||
|
||||
var url = '/subscription_ajax?action_create_subscription_to_channel=1&redirect=false' +
|
||||
'&c=' + subscribe_data.ucid;
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.responseType = 'json';
|
||||
xhr.timeout = 10000;
|
||||
xhr.open('POST', url, true);
|
||||
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||
|
||||
function subscribe() {
|
||||
var fallback = subscribe_button.innerHTML;
|
||||
subscribe_button.onclick = unsubscribe;
|
||||
subscribe_button.innerHTML = '<b>' + subscribe_data.unsubscribe_text + ' | ' + subscribe_data.sub_count_text + '</b>';
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 4) {
|
||||
if (xhr.status != 200) {
|
||||
subscribe_button.onclick = subscribe;
|
||||
subscribe_button.innerHTML = fallback;
|
||||
}
|
||||
var url = '/subscription_ajax?action_create_subscription_to_channel=1&redirect=false' +
|
||||
'&c=' + subscribe_data.ucid;
|
||||
|
||||
helpers.xhr('POST', url, {payload: payload, retries: 5, entity_name: 'subscribe request'}, {
|
||||
onNon200: function (xhr) {
|
||||
subscribe_button.onclick = subscribe;
|
||||
subscribe_button.innerHTML = fallback;
|
||||
}
|
||||
}
|
||||
|
||||
xhr.onerror = function () {
|
||||
console.log('Subscribing failed... ' + retries + '/5');
|
||||
setTimeout(function () { subscribe(retries - 1) }, 1000);
|
||||
}
|
||||
|
||||
xhr.ontimeout = function () {
|
||||
console.log('Subscribing failed... ' + retries + '/5');
|
||||
subscribe(retries - 1);
|
||||
}
|
||||
|
||||
xhr.send('csrf_token=' + subscribe_data.csrf_token);
|
||||
});
|
||||
}
|
||||
|
||||
function unsubscribe(retries = 5) {
|
||||
if (retries <= 0) {
|
||||
console.log('Failed to subscribe');
|
||||
return;
|
||||
}
|
||||
|
||||
var url = '/subscription_ajax?action_remove_subscriptions=1&redirect=false' +
|
||||
'&c=' + subscribe_data.ucid;
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.responseType = 'json';
|
||||
xhr.timeout = 10000;
|
||||
xhr.open('POST', url, true);
|
||||
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||
|
||||
function unsubscribe() {
|
||||
var fallback = subscribe_button.innerHTML;
|
||||
subscribe_button.onclick = subscribe;
|
||||
subscribe_button.innerHTML = '<b>' + subscribe_data.subscribe_text + ' | ' + subscribe_data.sub_count_text + '</b>';
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 4) {
|
||||
if (xhr.status != 200) {
|
||||
subscribe_button.onclick = unsubscribe;
|
||||
subscribe_button.innerHTML = fallback;
|
||||
}
|
||||
var url = '/subscription_ajax?action_remove_subscriptions=1&redirect=false' +
|
||||
'&c=' + subscribe_data.ucid;
|
||||
|
||||
helpers.xhr('POST', url, {payload: payload, retries: 5, entity_name: 'unsubscribe request'}, {
|
||||
onNon200: function (xhr) {
|
||||
subscribe_button.onclick = unsubscribe;
|
||||
subscribe_button.innerHTML = fallback;
|
||||
}
|
||||
}
|
||||
|
||||
xhr.onerror = function () {
|
||||
console.log('Unsubscribing failed... ' + retries + '/5');
|
||||
setTimeout(function () { unsubscribe(retries - 1) }, 1000);
|
||||
}
|
||||
|
||||
xhr.ontimeout = function () {
|
||||
console.log('Unsubscribing failed... ' + retries + '/5');
|
||||
unsubscribe(retries - 1);
|
||||
}
|
||||
|
||||
xhr.send('csrf_token=' + subscribe_data.csrf_token);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,91 +1,44 @@
|
||||
'use strict';
|
||||
var toggle_theme = document.getElementById('toggle_theme');
|
||||
toggle_theme.href = 'javascript:void(0);';
|
||||
toggle_theme.href = 'javascript:void(0)';
|
||||
|
||||
const STORAGE_KEY_THEME = 'dark_mode';
|
||||
const THEME_DARK = 'dark';
|
||||
const THEME_LIGHT = 'light';
|
||||
|
||||
// TODO: theme state controlled by system
|
||||
toggle_theme.addEventListener('click', function () {
|
||||
var dark_mode = document.body.classList.contains("light-theme");
|
||||
|
||||
var url = '/toggle_theme?redirect=false';
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.responseType = 'json';
|
||||
xhr.timeout = 10000;
|
||||
xhr.open('GET', url, true);
|
||||
|
||||
set_mode(dark_mode);
|
||||
try {
|
||||
window.localStorage.setItem('dark_mode', dark_mode ? 'dark' : 'light');
|
||||
} catch {}
|
||||
|
||||
xhr.send();
|
||||
const isDarkTheme = helpers.storage.get(STORAGE_KEY_THEME) === THEME_DARK;
|
||||
const newTheme = isDarkTheme ? THEME_LIGHT : THEME_DARK;
|
||||
setTheme(newTheme);
|
||||
helpers.storage.set(STORAGE_KEY_THEME, newTheme);
|
||||
helpers.xhr('GET', '/toggle_theme?redirect=false', {}, {});
|
||||
});
|
||||
|
||||
window.addEventListener('storage', function (e) {
|
||||
if (e.key === 'dark_mode') {
|
||||
update_mode(e.newValue);
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('DOMContentLoaded', function () {
|
||||
const dark_mode = document.getElementById('dark_mode_pref').textContent;
|
||||
try {
|
||||
// Update localStorage if dark mode preference changed on preferences page
|
||||
window.localStorage.setItem('dark_mode', dark_mode);
|
||||
} catch {}
|
||||
update_mode(dark_mode);
|
||||
});
|
||||
|
||||
|
||||
var darkScheme = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
var lightScheme = window.matchMedia('(prefers-color-scheme: light)');
|
||||
|
||||
darkScheme.addListener(scheme_switch);
|
||||
lightScheme.addListener(scheme_switch);
|
||||
|
||||
function scheme_switch (e) {
|
||||
// ignore this method if we have a preference set
|
||||
try {
|
||||
if (localStorage.getItem('dark_mode')) {
|
||||
return;
|
||||
}
|
||||
} catch {}
|
||||
if (e.matches) {
|
||||
if (e.media.includes("dark")) {
|
||||
set_mode(true);
|
||||
} else if (e.media.includes("light")) {
|
||||
set_mode(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function set_mode (bool) {
|
||||
if (bool) {
|
||||
// dark
|
||||
toggle_theme.children[0].setAttribute('class', 'icon ion-ios-sunny');
|
||||
document.body.classList.remove('no-theme');
|
||||
document.body.classList.remove('light-theme');
|
||||
document.body.classList.add('dark-theme');
|
||||
/** @param {THEME_DARK|THEME_LIGHT} theme */
|
||||
function setTheme(theme) {
|
||||
// By default body element has .no-theme class that uses OS theme via CSS @media rules
|
||||
// It rewrites using hard className below
|
||||
if (theme === THEME_DARK) {
|
||||
toggle_theme.children[0].className = 'icon ion-ios-sunny';
|
||||
document.body.className = 'dark-theme';
|
||||
} else {
|
||||
// light
|
||||
toggle_theme.children[0].setAttribute('class', 'icon ion-ios-moon');
|
||||
document.body.classList.remove('no-theme');
|
||||
document.body.classList.remove('dark-theme');
|
||||
document.body.classList.add('light-theme');
|
||||
toggle_theme.children[0].className = 'icon ion-ios-moon';
|
||||
document.body.className = 'light-theme';
|
||||
}
|
||||
}
|
||||
|
||||
function update_mode (mode) {
|
||||
if (mode === 'true' /* for backwards compatibility */ || mode === 'dark') {
|
||||
// If preference for dark mode indicated
|
||||
set_mode(true);
|
||||
}
|
||||
else if (mode === 'false' /* for backwards compatibility */ || mode === 'light') {
|
||||
// If preference for light mode indicated
|
||||
set_mode(false);
|
||||
}
|
||||
else if (document.getElementById('dark_mode_pref').textContent === '' && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
// If no preference indicated here and no preference indicated on the preferences page (backend), but the browser tells us that the operating system has a dark theme
|
||||
set_mode(true);
|
||||
}
|
||||
// else do nothing, falling back to the mode defined by the `dark_mode` preference on the preferences page (backend)
|
||||
}
|
||||
|
||||
// Handles theme change event caused by other tab
|
||||
addEventListener('storage', function (e) {
|
||||
if (e.key === STORAGE_KEY_THEME)
|
||||
setTheme(helpers.storage.get(STORAGE_KEY_THEME));
|
||||
});
|
||||
|
||||
// Set theme from preferences on page load
|
||||
addEventListener('DOMContentLoaded', function () {
|
||||
const prefTheme = document.getElementById('dark_mode_pref').textContent;
|
||||
if (prefTheme) {
|
||||
setTheme(prefTheme);
|
||||
helpers.storage.set(STORAGE_KEY_THEME, prefTheme);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,32 +1,35 @@
|
||||
var video_data = JSON.parse(document.getElementById('video_data').innerHTML);
|
||||
'use strict';
|
||||
var video_data = JSON.parse(document.getElementById('video_data').textContent);
|
||||
var spinnerHTML = '<h3 style="text-align:center"><div class="loading"><i class="icon ion-ios-refresh"></i></div></h3>';
|
||||
var spinnerHTMLwithHR = spinnerHTML + '<hr>';
|
||||
|
||||
String.prototype.supplant = function (o) {
|
||||
return this.replace(/{([^{}]*)}/g, function (a, b) {
|
||||
var r = o[b];
|
||||
return typeof r === 'string' || typeof r === 'number' ? r : a;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function toggle_parent(target) {
|
||||
body = target.parentNode.parentNode.children[1];
|
||||
if (body.style.display === null || body.style.display === '') {
|
||||
target.innerHTML = '[ + ]';
|
||||
body.style.display = 'none';
|
||||
} else {
|
||||
target.innerHTML = '[ - ]';
|
||||
var body = target.parentNode.parentNode.children[1];
|
||||
if (body.style.display === 'none') {
|
||||
target.textContent = '[ − ]';
|
||||
body.style.display = '';
|
||||
} else {
|
||||
target.textContent = '[ + ]';
|
||||
body.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
function toggle_comments(event) {
|
||||
var target = event.target;
|
||||
body = target.parentNode.parentNode.parentNode.children[1];
|
||||
if (body.style.display === null || body.style.display === '') {
|
||||
target.innerHTML = '[ + ]';
|
||||
body.style.display = 'none';
|
||||
} else {
|
||||
target.innerHTML = '[ - ]';
|
||||
var body = target.parentNode.parentNode.parentNode.children[1];
|
||||
if (body.style.display === 'none') {
|
||||
target.textContent = '[ − ]';
|
||||
body.style.display = '';
|
||||
} else {
|
||||
target.textContent = '[ + ]';
|
||||
body.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,13 +46,13 @@ function swap_comments(event) {
|
||||
function hide_youtube_replies(event) {
|
||||
var target = event.target;
|
||||
|
||||
sub_text = target.getAttribute('data-inner-text');
|
||||
inner_text = target.getAttribute('data-sub-text');
|
||||
var sub_text = target.getAttribute('data-inner-text');
|
||||
var inner_text = target.getAttribute('data-sub-text');
|
||||
|
||||
body = target.parentNode.parentNode.children[1];
|
||||
var body = target.parentNode.parentNode.children[1];
|
||||
body.style.display = 'none';
|
||||
|
||||
target.innerHTML = sub_text;
|
||||
target.textContent = sub_text;
|
||||
target.onclick = show_youtube_replies;
|
||||
target.setAttribute('data-inner-text', inner_text);
|
||||
target.setAttribute('data-sub-text', sub_text);
|
||||
@@ -58,13 +61,13 @@ function hide_youtube_replies(event) {
|
||||
function show_youtube_replies(event) {
|
||||
var target = event.target;
|
||||
|
||||
sub_text = target.getAttribute('data-inner-text');
|
||||
inner_text = target.getAttribute('data-sub-text');
|
||||
var sub_text = target.getAttribute('data-inner-text');
|
||||
var inner_text = target.getAttribute('data-sub-text');
|
||||
|
||||
body = target.parentNode.parentNode.children[1];
|
||||
var body = target.parentNode.parentNode.children[1];
|
||||
body.style.display = '';
|
||||
|
||||
target.innerHTML = sub_text;
|
||||
target.textContent = sub_text;
|
||||
target.onclick = hide_youtube_replies;
|
||||
target.setAttribute('data-inner-text', inner_text);
|
||||
target.setAttribute('data-sub-text', sub_text);
|
||||
@@ -78,287 +81,186 @@ if (continue_button) {
|
||||
function next_video() {
|
||||
var url = new URL('https://example.com/watch?v=' + video_data.next_video);
|
||||
|
||||
if (video_data.params.autoplay || video_data.params.continue_autoplay) {
|
||||
if (video_data.params.autoplay || video_data.params.continue_autoplay)
|
||||
url.searchParams.set('autoplay', '1');
|
||||
}
|
||||
|
||||
if (video_data.params.listen !== video_data.preferences.listen) {
|
||||
if (video_data.params.listen !== video_data.preferences.listen)
|
||||
url.searchParams.set('listen', video_data.params.listen);
|
||||
}
|
||||
|
||||
if (video_data.params.speed !== video_data.preferences.speed) {
|
||||
if (video_data.params.speed !== video_data.preferences.speed)
|
||||
url.searchParams.set('speed', video_data.params.speed);
|
||||
}
|
||||
|
||||
if (video_data.params.local !== video_data.preferences.local) {
|
||||
if (video_data.params.local !== video_data.preferences.local)
|
||||
url.searchParams.set('local', video_data.params.local);
|
||||
}
|
||||
|
||||
url.searchParams.set('continue', '1');
|
||||
|
||||
location.assign(url.pathname + url.search);
|
||||
}
|
||||
|
||||
function continue_autoplay(event) {
|
||||
if (event.target.checked) {
|
||||
player.on('ended', function () {
|
||||
next_video();
|
||||
});
|
||||
player.on('ended', next_video);
|
||||
} else {
|
||||
player.off('ended');
|
||||
}
|
||||
}
|
||||
|
||||
function number_with_separator(val) {
|
||||
while (/(\d+)(\d{3})/.test(val.toString())) {
|
||||
val = val.toString().replace(/(\d+)(\d{3})/, '$1' + ',' + '$2');
|
||||
}
|
||||
return val;
|
||||
}
|
||||
function get_playlist(plid) {
|
||||
var playlist = document.getElementById('playlist');
|
||||
|
||||
function get_playlist(plid, retries) {
|
||||
if (retries == undefined) retries = 5;
|
||||
playlist = document.getElementById('playlist');
|
||||
|
||||
if (retries <= 0) {
|
||||
console.log('Failed to pull playlist');
|
||||
playlist.innerHTML = '';
|
||||
return;
|
||||
}
|
||||
|
||||
playlist.innerHTML = ' \
|
||||
<h3 style="text-align:center"><div class="loading"><i class="icon ion-ios-refresh"></i></div></h3> \
|
||||
<hr>'
|
||||
playlist.innerHTML = spinnerHTMLwithHR;
|
||||
|
||||
var plid_url;
|
||||
if (plid.startsWith('RD')) {
|
||||
var plid_url = '/api/v1/mixes/' + plid +
|
||||
plid_url = '/api/v1/mixes/' + plid +
|
||||
'?continuation=' + video_data.id +
|
||||
'&format=html&hl=' + video_data.preferences.locale;
|
||||
} else {
|
||||
var plid_url = '/api/v1/playlists/' + plid +
|
||||
plid_url = '/api/v1/playlists/' + plid +
|
||||
'?index=' + video_data.index +
|
||||
'&continuation=' + video_data.id +
|
||||
'&format=html&hl=' + video_data.preferences.locale;
|
||||
}
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.responseType = 'json';
|
||||
xhr.timeout = 10000;
|
||||
xhr.open('GET', plid_url, true);
|
||||
helpers.xhr('GET', plid_url, {retries: 5, entity_name: 'playlist'}, {
|
||||
on200: function (response) {
|
||||
playlist.innerHTML = response.playlistHtml;
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 4) {
|
||||
if (xhr.status == 200) {
|
||||
playlist.innerHTML = xhr.response.playlistHtml;
|
||||
var nextVideo = document.getElementById(xhr.response.nextVideo);
|
||||
nextVideo.parentNode.parentNode.scrollTop = nextVideo.offsetTop;
|
||||
if (!response.nextVideo) return;
|
||||
|
||||
if (xhr.response.nextVideo) {
|
||||
player.on('ended', function () {
|
||||
var url = new URL('https://example.com/watch?v=' + xhr.response.nextVideo);
|
||||
var nextVideo = document.getElementById(response.nextVideo);
|
||||
nextVideo.parentNode.parentNode.scrollTop = nextVideo.offsetTop;
|
||||
|
||||
url.searchParams.set('list', plid);
|
||||
if (!plid.startsWith('RD')) {
|
||||
url.searchParams.set('index', xhr.response.index);
|
||||
}
|
||||
player.on('ended', function () {
|
||||
var url = new URL('https://example.com/watch?v=' + response.nextVideo);
|
||||
|
||||
if (video_data.params.autoplay || video_data.params.continue_autoplay) {
|
||||
url.searchParams.set('autoplay', '1');
|
||||
}
|
||||
url.searchParams.set('list', plid);
|
||||
if (!plid.startsWith('RD'))
|
||||
url.searchParams.set('index', response.index);
|
||||
if (video_data.params.autoplay || video_data.params.continue_autoplay)
|
||||
url.searchParams.set('autoplay', '1');
|
||||
if (video_data.params.listen !== video_data.preferences.listen)
|
||||
url.searchParams.set('listen', video_data.params.listen);
|
||||
if (video_data.params.speed !== video_data.preferences.speed)
|
||||
url.searchParams.set('speed', video_data.params.speed);
|
||||
if (video_data.params.local !== video_data.preferences.local)
|
||||
url.searchParams.set('local', video_data.params.local);
|
||||
|
||||
if (video_data.params.listen !== video_data.preferences.listen) {
|
||||
url.searchParams.set('listen', video_data.params.listen);
|
||||
}
|
||||
|
||||
if (video_data.params.speed !== video_data.preferences.speed) {
|
||||
url.searchParams.set('speed', video_data.params.speed);
|
||||
}
|
||||
|
||||
if (video_data.params.local !== video_data.preferences.local) {
|
||||
url.searchParams.set('local', video_data.params.local);
|
||||
}
|
||||
|
||||
location.assign(url.pathname + url.search);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
playlist.innerHTML = '';
|
||||
document.getElementById('continue').style.display = '';
|
||||
}
|
||||
location.assign(url.pathname + url.search);
|
||||
});
|
||||
},
|
||||
onNon200: function (xhr) {
|
||||
playlist.innerHTML = '';
|
||||
document.getElementById('continue').style.display = '';
|
||||
},
|
||||
onError: function (xhr) {
|
||||
playlist.innerHTML = spinnerHTMLwithHR;
|
||||
},
|
||||
onTimeout: function (xhr) {
|
||||
playlist.innerHTML = spinnerHTMLwithHR;
|
||||
}
|
||||
}
|
||||
|
||||
xhr.onerror = function () {
|
||||
playlist = document.getElementById('playlist');
|
||||
playlist.innerHTML =
|
||||
'<h3 style="text-align:center"><div class="loading"><i class="icon ion-ios-refresh"></i></div></h3><hr>';
|
||||
|
||||
console.log('Pulling playlist timed out... ' + retries + '/5');
|
||||
setTimeout(function () { get_playlist(plid, retries - 1) }, 1000);
|
||||
}
|
||||
|
||||
xhr.ontimeout = function () {
|
||||
playlist = document.getElementById('playlist');
|
||||
playlist.innerHTML =
|
||||
'<h3 style="text-align:center"><div class="loading"><i class="icon ion-ios-refresh"></i></div></h3><hr>';
|
||||
|
||||
console.log('Pulling playlist timed out... ' + retries + '/5');
|
||||
get_playlist(plid, retries - 1);
|
||||
}
|
||||
|
||||
xhr.send();
|
||||
});
|
||||
}
|
||||
|
||||
function get_reddit_comments(retries) {
|
||||
if (retries == undefined) retries = 5;
|
||||
comments = document.getElementById('comments');
|
||||
|
||||
if (retries <= 0) {
|
||||
console.log('Failed to pull comments');
|
||||
comments.innerHTML = '';
|
||||
return;
|
||||
}
|
||||
function get_reddit_comments() {
|
||||
var comments = document.getElementById('comments');
|
||||
|
||||
var fallback = comments.innerHTML;
|
||||
comments.innerHTML =
|
||||
'<h3 style="text-align:center"><div class="loading"><i class="icon ion-ios-refresh"></i></div></h3>';
|
||||
comments.innerHTML = spinnerHTML;
|
||||
|
||||
var url = '/api/v1/comments/' + video_data.id +
|
||||
'?source=reddit&format=html' +
|
||||
'&hl=' + video_data.preferences.locale;
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.responseType = 'json';
|
||||
xhr.timeout = 10000;
|
||||
xhr.open('GET', url, true);
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 4) {
|
||||
if (xhr.status == 200) {
|
||||
comments.innerHTML = ' \
|
||||
<div> \
|
||||
<h3> \
|
||||
<a href="javascript:void(0)">[ - ]</a> \
|
||||
{title} \
|
||||
</h3> \
|
||||
<p> \
|
||||
<b> \
|
||||
<a href="javascript:void(0)" data-comments="youtube"> \
|
||||
{youtubeCommentsText} \
|
||||
</a> \
|
||||
</b> \
|
||||
</p> \
|
||||
var onNon200 = function (xhr) { comments.innerHTML = fallback; };
|
||||
if (video_data.params.comments[1] === 'youtube')
|
||||
onNon200 = function (xhr) {};
|
||||
|
||||
helpers.xhr('GET', url, {retries: 5, entity_name: ''}, {
|
||||
on200: function (response) {
|
||||
comments.innerHTML = ' \
|
||||
<div> \
|
||||
<h3> \
|
||||
<a href="javascript:void(0)">[ − ]</a> \
|
||||
{title} \
|
||||
</h3> \
|
||||
<p> \
|
||||
<b> \
|
||||
<a rel="noopener" target="_blank" href="https://reddit.com{permalink}">{redditPermalinkText}</a> \
|
||||
<a href="javascript:void(0)" data-comments="youtube"> \
|
||||
{youtubeCommentsText} \
|
||||
</a> \
|
||||
</b> \
|
||||
</div> \
|
||||
<div>{contentHtml}</div> \
|
||||
<hr>'.supplant({
|
||||
title: xhr.response.title,
|
||||
youtubeCommentsText: video_data.youtube_comments_text,
|
||||
redditPermalinkText: video_data.reddit_permalink_text,
|
||||
permalink: xhr.response.permalink,
|
||||
contentHtml: xhr.response.contentHtml
|
||||
});
|
||||
</p> \
|
||||
<b> \
|
||||
<a rel="noopener" target="_blank" href="https://reddit.com{permalink}">{redditPermalinkText}</a> \
|
||||
</b> \
|
||||
</div> \
|
||||
<div>{contentHtml}</div> \
|
||||
<hr>'.supplant({
|
||||
title: response.title,
|
||||
youtubeCommentsText: video_data.youtube_comments_text,
|
||||
redditPermalinkText: video_data.reddit_permalink_text,
|
||||
permalink: response.permalink,
|
||||
contentHtml: response.contentHtml
|
||||
});
|
||||
|
||||
comments.children[0].children[0].children[0].onclick = toggle_comments;
|
||||
comments.children[0].children[1].children[0].onclick = swap_comments;
|
||||
} else {
|
||||
if (video_data.params.comments[1] === 'youtube') {
|
||||
console.log('Pulling comments failed... ' + retries + '/5');
|
||||
setTimeout(function () { get_youtube_comments(retries - 1) }, 1000);
|
||||
} else {
|
||||
comments.innerHTML = fallback;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xhr.onerror = function () {
|
||||
console.log('Pulling comments failed... ' + retries + '/5');
|
||||
setTimeout(function () { get_reddit_comments(retries - 1) }, 1000);
|
||||
}
|
||||
|
||||
xhr.ontimeout = function () {
|
||||
console.log('Pulling comments failed... ' + retries + '/5');
|
||||
get_reddit_comments(retries - 1);
|
||||
}
|
||||
|
||||
xhr.send();
|
||||
comments.children[0].children[0].children[0].onclick = toggle_comments;
|
||||
comments.children[0].children[1].children[0].onclick = swap_comments;
|
||||
},
|
||||
onNon200: onNon200, // declared above
|
||||
});
|
||||
}
|
||||
|
||||
function get_youtube_comments(retries) {
|
||||
if (retries == undefined) retries = 5;
|
||||
comments = document.getElementById('comments');
|
||||
|
||||
if (retries <= 0) {
|
||||
console.log('Failed to pull comments');
|
||||
comments.innerHTML = '';
|
||||
return;
|
||||
}
|
||||
function get_youtube_comments() {
|
||||
var comments = document.getElementById('comments');
|
||||
|
||||
var fallback = comments.innerHTML;
|
||||
comments.innerHTML =
|
||||
'<h3 style="text-align:center"><div class="loading"><i class="icon ion-ios-refresh"></i></div></h3>';
|
||||
comments.innerHTML = spinnerHTML;
|
||||
|
||||
var url = '/api/v1/comments/' + video_data.id +
|
||||
'?format=html' +
|
||||
'&hl=' + video_data.preferences.locale +
|
||||
'&thin_mode=' + video_data.preferences.thin_mode;
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.responseType = 'json';
|
||||
xhr.timeout = 10000;
|
||||
xhr.open('GET', url, true);
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 4) {
|
||||
if (xhr.status == 200) {
|
||||
comments.innerHTML = ' \
|
||||
<div> \
|
||||
<h3> \
|
||||
<a href="javascript:void(0)">[ - ]</a> \
|
||||
{commentsText} \
|
||||
</h3> \
|
||||
<b> \
|
||||
<a href="javascript:void(0)" data-comments="reddit"> \
|
||||
{redditComments} \
|
||||
</a> \
|
||||
</b> \
|
||||
</div> \
|
||||
<div>{contentHtml}</div> \
|
||||
<hr>'.supplant({
|
||||
contentHtml: xhr.response.contentHtml,
|
||||
redditComments: video_data.reddit_comments_text,
|
||||
commentsText: video_data.comments_text.supplant(
|
||||
{ commentCount: number_with_separator(xhr.response.commentCount) }
|
||||
)
|
||||
});
|
||||
var onNon200 = function (xhr) { comments.innerHTML = fallback; };
|
||||
if (video_data.params.comments[1] === 'youtube')
|
||||
onNon200 = function (xhr) {};
|
||||
|
||||
comments.children[0].children[0].children[0].onclick = toggle_comments;
|
||||
comments.children[0].children[1].children[0].onclick = swap_comments;
|
||||
} else {
|
||||
if (video_data.params.comments[1] === 'youtube') {
|
||||
setTimeout(function () { get_youtube_comments(retries - 1) }, 1000);
|
||||
} else {
|
||||
comments.innerHTML = '';
|
||||
}
|
||||
}
|
||||
helpers.xhr('GET', url, {retries: 5, entity_name: 'comments'}, {
|
||||
on200: function (response) {
|
||||
comments.innerHTML = ' \
|
||||
<div> \
|
||||
<h3> \
|
||||
<a href="javascript:void(0)">[ − ]</a> \
|
||||
{commentsText} \
|
||||
</h3> \
|
||||
<b> \
|
||||
<a href="javascript:void(0)" data-comments="reddit"> \
|
||||
{redditComments} \
|
||||
</a> \
|
||||
</b> \
|
||||
</div> \
|
||||
<div>{contentHtml}</div> \
|
||||
<hr>'.supplant({
|
||||
contentHtml: response.contentHtml,
|
||||
redditComments: video_data.reddit_comments_text,
|
||||
commentsText: video_data.comments_text.supplant({
|
||||
// toLocaleString correctly splits number with local thousands separator. e.g.:
|
||||
// '1,234,567.89' for user with English locale
|
||||
// '1 234 567,89' for user with Russian locale
|
||||
// '1.234.567,89' for user with Portuguese locale
|
||||
commentCount: response.commentCount.toLocaleString()
|
||||
})
|
||||
});
|
||||
|
||||
comments.children[0].children[0].children[0].onclick = toggle_comments;
|
||||
comments.children[0].children[1].children[0].onclick = swap_comments;
|
||||
},
|
||||
onNon200: onNon200, // declared above
|
||||
onError: function (xhr) {
|
||||
comments.innerHTML = spinnerHTML;
|
||||
},
|
||||
onTimeout: function (xhr) {
|
||||
comments.innerHTML = spinnerHTML;
|
||||
}
|
||||
}
|
||||
|
||||
xhr.onerror = function () {
|
||||
comments.innerHTML =
|
||||
'<h3 style="text-align:center"><div class="loading"><i class="icon ion-ios-refresh"></i></div></h3>';
|
||||
console.log('Pulling comments failed... ' + retries + '/5');
|
||||
setTimeout(function () { get_youtube_comments(retries - 1) }, 1000);
|
||||
}
|
||||
|
||||
xhr.ontimeout = function () {
|
||||
comments.innerHTML =
|
||||
'<h3 style="text-align:center"><div class="loading"><i class="icon ion-ios-refresh"></i></div></h3>';
|
||||
console.log('Pulling comments failed... ' + retries + '/5');
|
||||
get_youtube_comments(retries - 1);
|
||||
}
|
||||
|
||||
xhr.send();
|
||||
});
|
||||
}
|
||||
|
||||
function get_youtube_replies(target, load_more, load_replies) {
|
||||
@@ -366,91 +268,72 @@ function get_youtube_replies(target, load_more, load_replies) {
|
||||
|
||||
var body = target.parentNode.parentNode;
|
||||
var fallback = body.innerHTML;
|
||||
body.innerHTML =
|
||||
'<h3 style="text-align:center"><div class="loading"><i class="icon ion-ios-refresh"></i></div></h3>';
|
||||
body.innerHTML = spinnerHTML;
|
||||
|
||||
var url = '/api/v1/comments/' + video_data.id +
|
||||
'?format=html' +
|
||||
'&hl=' + video_data.preferences.locale +
|
||||
'&thin_mode=' + video_data.preferences.thin_mode +
|
||||
'&continuation=' + continuation
|
||||
if (load_replies) {
|
||||
url += '&action=action_get_comment_replies';
|
||||
}
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.responseType = 'json';
|
||||
xhr.timeout = 10000;
|
||||
xhr.open('GET', url, true);
|
||||
'&continuation=' + continuation;
|
||||
if (load_replies) url += '&action=action_get_comment_replies';
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 4) {
|
||||
if (xhr.status == 200) {
|
||||
if (load_more) {
|
||||
body = body.parentNode.parentNode;
|
||||
body.removeChild(body.lastElementChild);
|
||||
body.innerHTML += xhr.response.contentHtml;
|
||||
} else {
|
||||
body.removeChild(body.lastElementChild);
|
||||
|
||||
var p = document.createElement('p');
|
||||
var a = document.createElement('a');
|
||||
p.appendChild(a);
|
||||
|
||||
a.href = 'javascript:void(0)';
|
||||
a.onclick = hide_youtube_replies;
|
||||
a.setAttribute('data-sub-text', video_data.hide_replies_text);
|
||||
a.setAttribute('data-inner-text', video_data.show_replies_text);
|
||||
a.innerText = video_data.hide_replies_text;
|
||||
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = xhr.response.contentHtml;
|
||||
|
||||
body.appendChild(p);
|
||||
body.appendChild(div);
|
||||
}
|
||||
helpers.xhr('GET', url, {}, {
|
||||
on200: function (response) {
|
||||
if (load_more) {
|
||||
body = body.parentNode.parentNode;
|
||||
body.removeChild(body.lastElementChild);
|
||||
body.innerHTML += response.contentHtml;
|
||||
} else {
|
||||
body.innerHTML = fallback;
|
||||
body.removeChild(body.lastElementChild);
|
||||
|
||||
var p = document.createElement('p');
|
||||
var a = document.createElement('a');
|
||||
p.appendChild(a);
|
||||
|
||||
a.href = 'javascript:void(0)';
|
||||
a.onclick = hide_youtube_replies;
|
||||
a.setAttribute('data-sub-text', video_data.hide_replies_text);
|
||||
a.setAttribute('data-inner-text', video_data.show_replies_text);
|
||||
a.textContent = video_data.hide_replies_text;
|
||||
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = response.contentHtml;
|
||||
|
||||
body.appendChild(p);
|
||||
body.appendChild(div);
|
||||
}
|
||||
},
|
||||
onNon200: function (xhr) {
|
||||
body.innerHTML = fallback;
|
||||
},
|
||||
onTimeout: function (xhr) {
|
||||
console.warn('Pulling comments failed');
|
||||
body.innerHTML = fallback;
|
||||
}
|
||||
}
|
||||
|
||||
xhr.ontimeout = function () {
|
||||
console.log('Pulling comments failed.');
|
||||
body.innerHTML = fallback;
|
||||
}
|
||||
|
||||
xhr.send();
|
||||
});
|
||||
}
|
||||
|
||||
if (video_data.play_next) {
|
||||
player.on('ended', function () {
|
||||
var url = new URL('https://example.com/watch?v=' + video_data.next_video);
|
||||
|
||||
if (video_data.params.autoplay || video_data.params.continue_autoplay) {
|
||||
if (video_data.params.autoplay || video_data.params.continue_autoplay)
|
||||
url.searchParams.set('autoplay', '1');
|
||||
}
|
||||
|
||||
if (video_data.params.listen !== video_data.preferences.listen) {
|
||||
if (video_data.params.listen !== video_data.preferences.listen)
|
||||
url.searchParams.set('listen', video_data.params.listen);
|
||||
}
|
||||
|
||||
if (video_data.params.speed !== video_data.preferences.speed) {
|
||||
if (video_data.params.speed !== video_data.preferences.speed)
|
||||
url.searchParams.set('speed', video_data.params.speed);
|
||||
}
|
||||
|
||||
if (video_data.params.local !== video_data.preferences.local) {
|
||||
if (video_data.params.local !== video_data.preferences.local)
|
||||
url.searchParams.set('local', video_data.params.local);
|
||||
}
|
||||
|
||||
url.searchParams.set('continue', '1');
|
||||
|
||||
location.assign(url.pathname + url.search);
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('load', function (e) {
|
||||
if (video_data.plid) {
|
||||
addEventListener('load', function (e) {
|
||||
if (video_data.plid)
|
||||
get_playlist(video_data.plid);
|
||||
}
|
||||
|
||||
if (video_data.params.comments[0] === 'youtube') {
|
||||
get_youtube_comments();
|
||||
@@ -461,7 +344,7 @@ window.addEventListener('load', function (e) {
|
||||
} else if (video_data.params.comments[1] === 'reddit') {
|
||||
get_reddit_comments();
|
||||
} else {
|
||||
comments = document.getElementById('comments');
|
||||
var comments = document.getElementById('comments');
|
||||
comments.innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
var watched_data = JSON.parse(document.getElementById('watched_data').innerHTML);
|
||||
'use strict';
|
||||
var watched_data = JSON.parse(document.getElementById('watched_data').textContent);
|
||||
var payload = 'csrf_token=' + watched_data.csrf_token;
|
||||
|
||||
function mark_watched(target) {
|
||||
var tile = target.parentNode.parentNode.parentNode.parentNode.parentNode;
|
||||
@@ -6,45 +8,27 @@ function mark_watched(target) {
|
||||
|
||||
var url = '/watch_ajax?action_mark_watched=1&redirect=false' +
|
||||
'&id=' + target.getAttribute('data-id');
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.responseType = 'json';
|
||||
xhr.timeout = 10000;
|
||||
xhr.open('POST', url, true);
|
||||
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 4) {
|
||||
if (xhr.status != 200) {
|
||||
tile.style.display = '';
|
||||
}
|
||||
helpers.xhr('POST', url, {payload: payload}, {
|
||||
onNon200: function (xhr) {
|
||||
tile.style.display = '';
|
||||
}
|
||||
}
|
||||
|
||||
xhr.send('csrf_token=' + watched_data.csrf_token);
|
||||
});
|
||||
}
|
||||
|
||||
function mark_unwatched(target) {
|
||||
var tile = target.parentNode.parentNode.parentNode.parentNode.parentNode;
|
||||
tile.style.display = 'none';
|
||||
var count = document.getElementById('count')
|
||||
count.innerText = count.innerText - 1;
|
||||
var count = document.getElementById('count');
|
||||
count.textContent--;
|
||||
|
||||
var url = '/watch_ajax?action_mark_unwatched=1&redirect=false' +
|
||||
'&id=' + target.getAttribute('data-id');
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.responseType = 'json';
|
||||
xhr.timeout = 10000;
|
||||
xhr.open('POST', url, true);
|
||||
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 4) {
|
||||
if (xhr.status != 200) {
|
||||
count.innerText = count.innerText - 1 + 2;
|
||||
tile.style.display = '';
|
||||
}
|
||||
helpers.xhr('POST', url, {payload: payload}, {
|
||||
onNon200: function (xhr) {
|
||||
count.textContent++;
|
||||
tile.style.display = '';
|
||||
}
|
||||
}
|
||||
|
||||
xhr.send('csrf_token=' + watched_data.csrf_token);
|
||||
});
|
||||
}
|
||||
@@ -349,13 +349,16 @@ feed_threads: 1
|
||||
## Enable/Disable the polling job that keeps the decryption
|
||||
## function (for "secured" videos) up to date.
|
||||
##
|
||||
## Note: This part of the code is currently broken, so changing
|
||||
## Note: This part of the code generate a small amount of data every minute.
|
||||
## This may not be desired if you have bandwidth limits set by your ISP.
|
||||
##
|
||||
## Note 2: This part of the code is currently broken, so changing
|
||||
## this setting has no impact.
|
||||
##
|
||||
## Accepted values: true, false
|
||||
## Default: true
|
||||
## Default: false
|
||||
##
|
||||
#decrypt_polling: true
|
||||
#decrypt_polling: false
|
||||
|
||||
|
||||
# -----------------------------
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Using it will build an image from the locally cloned repository.
|
||||
#
|
||||
# If you want to use Invidious in production, see the docker-compose.yml file provided
|
||||
# in the installation documentation: https://docs.invidious.io/Installation.md
|
||||
# in the installation documentation: https://docs.invidious.io/installation/
|
||||
|
||||
version: "3"
|
||||
services:
|
||||
@@ -39,7 +39,7 @@ services:
|
||||
- invidious-db
|
||||
|
||||
invidious-db:
|
||||
image: docker.io/library/postgres:14
|
||||
image: docker.io/library/postgres:13
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- postgresdata:/var/lib/postgresql/data
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM crystallang/crystal:1.2.2-alpine AS builder
|
||||
FROM crystallang/crystal:1.4.1-alpine AS builder
|
||||
RUN apk add --no-cache sqlite-static yaml-static
|
||||
|
||||
ARG release
|
||||
@@ -42,7 +42,7 @@ RUN addgroup -g 1000 -S invidious && \
|
||||
adduser -u 1000 -S invidious -G invidious
|
||||
COPY --chown=invidious ./config/config.* ./config/
|
||||
RUN mv -n config/config.example.yml config/config.yml
|
||||
RUN sed -i 's/host: \(127.0.0.1\|localhost\)/host: postgres/' config/config.yml
|
||||
RUN sed -i 's/host: \(127.0.0.1\|localhost\)/host: invidious-db/' config/config.yml
|
||||
COPY ./config/sql/ ./config/sql/
|
||||
COPY ./locales/ ./locales/
|
||||
COPY --from=builder /invidious/assets ./assets/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
FROM alpine:3.15 AS builder
|
||||
RUN apk add --no-cache 'crystal=1.2.2-r0' shards sqlite-static yaml-static yaml-dev libxml2-dev zlib-static openssl-libs-static openssl-dev musl-dev
|
||||
FROM alpine:3.16 AS builder
|
||||
RUN apk add --no-cache 'crystal=1.4.1-r0' shards sqlite-static yaml-static yaml-dev libxml2-dev zlib-static openssl-libs-static openssl-dev musl-dev
|
||||
|
||||
ARG release
|
||||
|
||||
@@ -34,14 +34,14 @@ RUN if [ ${release} == 1 ] ; then \
|
||||
--link-flags "-lxml2 -llzma"; \
|
||||
fi
|
||||
|
||||
FROM alpine:3.15
|
||||
FROM alpine:3.16
|
||||
RUN apk add --no-cache librsvg ttf-opensans
|
||||
WORKDIR /invidious
|
||||
RUN addgroup -g 1000 -S invidious && \
|
||||
adduser -u 1000 -S invidious -G invidious
|
||||
COPY --chown=invidious ./config/config.* ./config/
|
||||
RUN mv -n config/config.example.yml config/config.yml
|
||||
RUN sed -i 's/host: \(127.0.0.1\|localhost\)/host: postgres/' config/config.yml
|
||||
RUN sed -i 's/host: \(127.0.0.1\|localhost\)/host: invidious-db/' config/config.yml
|
||||
COPY ./config/sql/ ./config/sql/
|
||||
COPY ./locales/ ./locales/
|
||||
COPY --from=builder /invidious/assets ./assets/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
dependencies:
|
||||
- name: postgresql
|
||||
repository: https://kubernetes-charts.storage.googleapis.com/
|
||||
version: 8.3.0
|
||||
digest: sha256:1feec3c396cbf27573dc201831ccd3376a4a6b58b2e7618ce30a89b8f5d707fd
|
||||
generated: "2020-02-07T13:39:38.624846+01:00"
|
||||
repository: https://charts.bitnami.com/bitnami/
|
||||
version: 11.1.3
|
||||
digest: sha256:79061645472b6fb342d45e8e5b3aacd018ef5067193e46a060bccdc99fe7f6e1
|
||||
generated: "2022-03-02T05:57:20.081432389+13:00"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
apiVersion: v2
|
||||
name: invidious
|
||||
description: Invidious is an alternative front-end to YouTube
|
||||
version: 1.1.0
|
||||
version: 1.1.1
|
||||
appVersion: 0.20.1
|
||||
keywords:
|
||||
- youtube
|
||||
@@ -17,6 +17,6 @@ maintainers:
|
||||
email: mail@leonklingele.de
|
||||
dependencies:
|
||||
- name: postgresql
|
||||
version: ~8.3.0
|
||||
repository: "https://kubernetes-charts.storage.googleapis.com/"
|
||||
version: ~11.1.3
|
||||
repository: "https://charts.bitnami.com/bitnami/"
|
||||
engine: gotpl
|
||||
|
||||
@@ -14,7 +14,7 @@ autoscaling:
|
||||
targetCPUUtilizationPercentage: 50
|
||||
|
||||
service:
|
||||
type: clusterIP
|
||||
type: ClusterIP
|
||||
port: 3000
|
||||
#loadBalancerIP:
|
||||
|
||||
@@ -32,14 +32,19 @@ securityContext:
|
||||
runAsGroup: 1000
|
||||
fsGroup: 1000
|
||||
|
||||
# See https://github.com/helm/charts/tree/master/stable/postgresql
|
||||
# See https://github.com/bitnami/charts/tree/master/bitnami/postgresql
|
||||
postgresql:
|
||||
postgresqlUsername: kemal
|
||||
postgresqlPassword: kemal
|
||||
postgresqlDatabase: invidious
|
||||
initdbUsername: kemal
|
||||
initdbPassword: kemal
|
||||
initdbScriptsConfigMap: invidious-postgresql-init
|
||||
image:
|
||||
registry: quay.io
|
||||
auth:
|
||||
username: kemal
|
||||
password: kemal
|
||||
database: invidious
|
||||
primary:
|
||||
initdb:
|
||||
username: kemal
|
||||
password: kemal
|
||||
scriptsConfigMap: invidious-postgresql-init
|
||||
|
||||
# Adapted from ../config/config.yml
|
||||
config:
|
||||
|
||||
198
locales/ar.json
198
locales/ar.json
@@ -21,15 +21,15 @@
|
||||
"No": "لا",
|
||||
"Import and Export Data": "اِستيراد البيانات وتصديرها",
|
||||
"Import": "استيراد",
|
||||
"Import Invidious data": "استيراد بيانات انفيدياس",
|
||||
"Import YouTube subscriptions": "استيراد اشتراكات يوتيوب",
|
||||
"Import Invidious data": "استيراد بيانات JSON Invidious",
|
||||
"Import YouTube subscriptions": "استيراد اشتراكات YouTube/OPML",
|
||||
"Import FreeTube subscriptions (.db)": "استيراد اشتراكات فريتيوب (.db)",
|
||||
"Import NewPipe subscriptions (.json)": "استيراد اشتراكات نيو بايب (.json)",
|
||||
"Import NewPipe data (.zip)": "استيراد بيانات نيو بايب (.zip)",
|
||||
"Export": "تصدير",
|
||||
"Export subscriptions as OPML": "تصدير الاشتراكات كـOPML",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "تصدير الاشتراكات كـOPML (لِنيو بايب و فريتيوب)",
|
||||
"Export data as JSON": "تصدير البيانات بتنسيق JSON",
|
||||
"Export data as JSON": "تصدير بيانات Invidious كـ JSON",
|
||||
"Delete account?": "حذف الحساب؟",
|
||||
"History": "السِّجل",
|
||||
"An alternative front-end to YouTube": "واجهة أمامية بديلة لموقع يوتيوب",
|
||||
@@ -66,7 +66,7 @@
|
||||
"preferences_related_videos_label": "اعرض الفيديوهات ذات الصلة: ",
|
||||
"preferences_annotations_label": "اعرض الملاحظات في الفيديو تلقائيا: ",
|
||||
"preferences_extend_desc_label": "توسيع وصف الفيديو تلقائيا: ",
|
||||
"preferences_vr_mode_label": "مقاطع فيديو تفاعلية ب درجة 360: ",
|
||||
"preferences_vr_mode_label": "مقاطع فيديو تفاعلية بزاوية 360 درجة (تتطلب WebGL): ",
|
||||
"preferences_category_visual": "التفضيلات المرئية",
|
||||
"preferences_player_style_label": "شكل مشغل الفيديوهات: ",
|
||||
"Dark mode: ": "الوضع الليلي: ",
|
||||
@@ -108,9 +108,9 @@
|
||||
"preferences_show_nick_label": "إظهار اللقب في الأعلى: ",
|
||||
"Top enabled: ": "تفعيل 'الأفضل' ؟ ",
|
||||
"CAPTCHA enabled: ": "تفعيل الكابتشا: ",
|
||||
"Login enabled: ": "تفعيل الولوج: ",
|
||||
"Login enabled: ": "تمكين تسجيل الدخول: ",
|
||||
"Registration enabled: ": "تفعيل التسجيل: ",
|
||||
"Report statistics: ": "الإبلاغ عن الإحصائيات: ",
|
||||
"Report statistics: ": "تقرير الإحصائيات: ",
|
||||
"Save preferences": "حفظ الإعدادات",
|
||||
"Subscription manager": "مدير الاشتراكات",
|
||||
"Token manager": "إداره الرمز",
|
||||
@@ -121,7 +121,7 @@
|
||||
"Subscriptions": "الاشتراكات",
|
||||
"search": "بحث",
|
||||
"Log out": "تسجيل الخروج",
|
||||
"Released under the AGPLv3 on Github.": "صدر تحت AGPLv3 على Github.",
|
||||
"Released under the AGPLv3 on Github.": "صدر تحت AGPLv3 على GitHub.",
|
||||
"Source available here.": "الأكواد متوفرة هنا.",
|
||||
"View JavaScript license information.": "مشاهدة معلومات حول تراخيص الجافاسكريبت.",
|
||||
"View privacy policy.": "عرض سياسة الخصوصية.",
|
||||
@@ -141,7 +141,6 @@
|
||||
"Show less": "عرض اقل",
|
||||
"Watch on YouTube": "مشاهدة الفيديو على اليوتيوب",
|
||||
"Switch Invidious Instance": "تبديل المثيل Invidious",
|
||||
"Broken? Try another Invidious Instance": "معطل؟ جرب مثيل Invidious آخر",
|
||||
"Hide annotations": "إخفاء الملاحظات في الفيديو",
|
||||
"Show annotations": "عرض الملاحظات في الفيديو",
|
||||
"Genre: ": "النوع: ",
|
||||
@@ -175,7 +174,7 @@
|
||||
"User ID is a required field": "مكان اسم المستخدم مطلوب",
|
||||
"Password is a required field": "مكان كلمة السر مطلوب",
|
||||
"Wrong username or password": "اسم المستخدم او كلمة السر غير صحيح",
|
||||
"Please sign in using 'Log in with Google'": "الرجاء تسجيل الدخول 'تسجيل الدخول بواسطة جوجل'",
|
||||
"Please sign in using 'Log in with Google'": "الرجاء تسجيل الدخول باستخدام \"تسجيل الدخول باستخدام Google\"",
|
||||
"Password cannot be empty": "لا يمكن أن تكون كلمة السر فارغة",
|
||||
"Password cannot be longer than 55 characters": "يجب أن لا تتعدى كلمة السر 55 حرفًا",
|
||||
"Please log in": "الرجاء تسجيل الدخول",
|
||||
@@ -187,7 +186,7 @@
|
||||
"Could not fetch comments": "لم يتمكن من إحضار التعليقات",
|
||||
"`x` ago": "`x` منذ",
|
||||
"Load more": "عرض المزيد",
|
||||
"Could not create mix.": "لم يستطع عمل خلط.",
|
||||
"Could not create mix.": "تعذر إنشاء مزيج.",
|
||||
"Empty playlist": "قائمة التشغيل فارغة",
|
||||
"Not a playlist.": "قائمة التشغيل غير صالحة.",
|
||||
"Playlist does not exist.": "قائمة التشغيل غير موجودة.",
|
||||
@@ -195,7 +194,7 @@
|
||||
"Hidden field \"challenge\" is a required field": "مكان مخفي \"تحدي\" مكان مطلوب",
|
||||
"Hidden field \"token\" is a required field": "مكان مخفي \"رمز\" مكان مطلوب",
|
||||
"Erroneous challenge": "تحدي غير صالح",
|
||||
"Erroneous token": "روز غير صالح",
|
||||
"Erroneous token": "رمز مميز خاطئ",
|
||||
"No such user": "مستخدم غير صالح",
|
||||
"Token is expired, please try again": "الرمز منتهى الصلاحية، الرجاء المحاولة مرة اخرى",
|
||||
"English": "إنجليزي",
|
||||
@@ -329,48 +328,47 @@
|
||||
"Videos": "الفيديوهات",
|
||||
"Playlists": "قوائم التشغيل",
|
||||
"Community": "المجتمع",
|
||||
"relevance": "ملاؤم",
|
||||
"rating": "تقييم",
|
||||
"date": "التاريخ",
|
||||
"views": "مشاهدات",
|
||||
"content_type": "نوع المحتوى",
|
||||
"duration": "المدة الزمنية",
|
||||
"features": "الميزات",
|
||||
"sort": "فرز",
|
||||
"hour": "ساعة",
|
||||
"today": "اليوم",
|
||||
"week": "هذا الأسبوع",
|
||||
"month": "هذا الشهر",
|
||||
"year": "هذه السنة",
|
||||
"video": "فيديو",
|
||||
"channel": "قناة",
|
||||
"playlist": "قائمة التشغيل",
|
||||
"movie": "فيلم",
|
||||
"show": "عرض",
|
||||
"hd": "عالية الدقة",
|
||||
"subtitles": "ترجمات",
|
||||
"creative_commons": "المشاع الإبداعي",
|
||||
"3d": "ثلاثي الأبعاد",
|
||||
"live": "مباشر",
|
||||
"4k": "4k",
|
||||
"location": "الأماكن",
|
||||
"hdr": "وضع التباين العالي",
|
||||
"filter": "معامل الفرز",
|
||||
"search_filters_sort_option_relevance": "ملاؤم",
|
||||
"search_filters_sort_option_rating": "تقييم",
|
||||
"search_filters_sort_option_date": "التاريخ",
|
||||
"search_filters_sort_option_views": "مشاهدات",
|
||||
"search_filters_type_label": "نوع المحتوى",
|
||||
"search_filters_duration_label": "المدة الزمنية",
|
||||
"search_filters_features_label": "الميزات",
|
||||
"search_filters_sort_label": "فرز",
|
||||
"search_filters_date_option_hour": "آخر ساعة",
|
||||
"search_filters_date_option_today": "اليوم",
|
||||
"search_filters_date_option_week": "هذا الأسبوع",
|
||||
"search_filters_date_option_month": "هذا الشهر",
|
||||
"search_filters_date_option_year": "هذه السنة",
|
||||
"search_filters_type_option_video": "فيديو",
|
||||
"search_filters_type_option_channel": "قناة",
|
||||
"search_filters_type_option_playlist": "قائمة التشغيل",
|
||||
"search_filters_type_option_movie": "فيلم",
|
||||
"search_filters_type_option_show": "عرض",
|
||||
"search_filters_features_option_hd": "عالية الدقة",
|
||||
"search_filters_features_option_subtitles": "ترجمات",
|
||||
"search_filters_features_option_c_commons": "المشاع الإبداعي",
|
||||
"search_filters_features_option_three_d": "ثلاثي الأبعاد",
|
||||
"search_filters_features_option_live": "مباشر",
|
||||
"search_filters_features_option_four_k": "4k",
|
||||
"search_filters_features_option_location": "الأماكن",
|
||||
"search_filters_features_option_hdr": "وضع التباين العالي",
|
||||
"Current version: ": "الإصدار الحالي: ",
|
||||
"next_steps_error_message": "بعد ذلك يجب أن تحاول: ",
|
||||
"next_steps_error_message_refresh": "تحديث",
|
||||
"next_steps_error_message_go_to_youtube": "انتقل إلى يوتيوب",
|
||||
"short": "قصير (< 4 دقائق)",
|
||||
"long": "طويل (> 20 دقيقة)",
|
||||
"search_filters_duration_option_short": "قصير (< 4 دقائق)",
|
||||
"search_filters_duration_option_long": "طويل (> 20 دقيقة)",
|
||||
"footer_source_code": "شفرة المصدر",
|
||||
"footer_original_source_code": "شفرة المصدر الأصلية",
|
||||
"footer_original_source_code": "كود المصدر الأصلي",
|
||||
"footer_modfied_source_code": "شفرة المصدر المعدلة",
|
||||
"adminprefs_modified_source_code_url_label": "URL إلى مستودع التعليمات البرمجية المصدرية المعدلة",
|
||||
"footer_documentation": "التوثيق",
|
||||
"footer_donate_page": "تبرّع",
|
||||
"preferences_region_label": "بلد المحتوى: ",
|
||||
"preferences_quality_dash_label": "جودة فيديو DASH المفضلة: ",
|
||||
"preferences_quality_option_dash": "DASH (جودة تكييفية)",
|
||||
"preferences_quality_option_dash": "DASH (الجودة التلقائية)",
|
||||
"preferences_quality_option_hd720": "HD720",
|
||||
"preferences_quality_option_medium": "متوسطة",
|
||||
"preferences_quality_option_small": "صغيرة",
|
||||
@@ -386,7 +384,7 @@
|
||||
"preferences_quality_dash_option_360p": "360p",
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"purchased": "تم شراؤها",
|
||||
"search_filters_features_option_purchased": "تم شراؤها",
|
||||
"none": "لاشيء",
|
||||
"videoinfo_started_streaming_x_ago": "بدأ البث منذ `x`",
|
||||
"videoinfo_watch_on_youTube": "مشاهدة على يوتيوب",
|
||||
@@ -395,10 +393,10 @@
|
||||
"user_created_playlists": "'x' إنشاء قوائم التشغيل",
|
||||
"user_saved_playlists": "قوائم التشغيل المحفوظة 'x'",
|
||||
"Video unavailable": "الفيديو غير متوفر",
|
||||
"360": "360°",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"download_subtitles": "ترجمات - 'x' (.vtt)",
|
||||
"invidious": "الخيالي",
|
||||
"preferences_save_player_pos_label": "احفظ وقت الفيديو الحالي: ",
|
||||
"preferences_save_player_pos_label": "حفظ موضع التشغيل: ",
|
||||
"crash_page_you_found_a_bug": "يبدو أنك قد وجدت خطأً برمجيًّا في Invidious!",
|
||||
"generic_videos_count_0": "لا فيديوهات",
|
||||
"generic_videos_count_1": "فيديو واحد",
|
||||
@@ -429,5 +427,113 @@
|
||||
"generic_playlists_count_2": "قائمتا تشغيل",
|
||||
"generic_playlists_count_3": "{{count}} قوائم تشغيل",
|
||||
"generic_playlists_count_4": "{{count}} قائمة تشغيل",
|
||||
"generic_playlists_count_5": "{{count}} قائمة تشغيل"
|
||||
"generic_playlists_count_5": "{{count}} قائمة تشغيل",
|
||||
"English (United States)": "الإنجليزية (الولايات المتحدة)",
|
||||
"Indonesian (auto-generated)": "إندونيسي (مُنشأ تلقائيًا)",
|
||||
"Interlingue": "إنترلينغوي",
|
||||
"Italian (auto-generated)": "الإيطالية (مُنشأة تلقائيًا)",
|
||||
"Spanish (auto-generated)": "الأسبانية (تم إنشاؤه تلقائيًا)",
|
||||
"crash_page_before_reporting": "قبل الإبلاغ عن خطأ، تأكد من وجود:",
|
||||
"French (auto-generated)": "الفرنسية (مُنشأة تلقائيًا)",
|
||||
"Portuguese (auto-generated)": "البرتغالية (تم إنشاؤه تلقائيًا)",
|
||||
"Turkish (auto-generated)": "التركية (تم إنشاؤها تلقائيًا)",
|
||||
"crash_page_refresh": "حاول <a href=\"`x`\"> تحديث الصفحة </a>",
|
||||
"crash_page_switch_instance": "حاول <a href=\"`x`\"> استخدام مثيل آخر </a>",
|
||||
"Korean (auto-generated)": "كوري (تم إنشاؤه تلقائيًا)",
|
||||
"Spanish (Mexico)": "الإسبانية (المكسيك)",
|
||||
"Vietnamese (auto-generated)": "فيتنامي (تم إنشاؤه تلقائيًا)",
|
||||
"crash_page_report_issue": "إذا لم يساعد أي مما سبق، يرجى فتح <a href=\"`x`\"> مشكلة جديدة على GitHub </a> (ويفضل أن يكون باللغة الإنجليزية) وتضمين النص التالي في رسالتك (لا تترجم هذا النص):",
|
||||
"crash_page_read_the_faq": "قراءة <a href=\"`x`\"> الأسئلة المتكررة (الأسئلة الشائعة) </a>",
|
||||
"preferences_watch_history_label": "تمكين سجل المشاهدة: ",
|
||||
"English (United Kingdom)": "الإنجليزية (المملكة المتحدة)",
|
||||
"Cantonese (Hong Kong)": "الكانتونية (هونغ كونغ)",
|
||||
"Chinese": "الصينية",
|
||||
"Chinese (China)": "الصينية (الصين)",
|
||||
"Chinese (Hong Kong)": "الصينية (هونج كونج)",
|
||||
"Chinese (Taiwan)": "الصينية (تايوان)",
|
||||
"Dutch (auto-generated)": "هولندي (تم إنشاؤه تلقائيًا)",
|
||||
"German (auto-generated)": "ألماني (تم إنشاؤه تلقائيًا)",
|
||||
"Japanese (auto-generated)": "اليابانية (مُنشأة تلقائيًا)",
|
||||
"Portuguese (Brazil)": "البرتغالية (البرازيل)",
|
||||
"Russian (auto-generated)": "الروسية (منشأة تلقائيا)",
|
||||
"Spanish (Spain)": "الإسبانية (إسبانيا)",
|
||||
"crash_page_search_issue": "بحثت عن <a href=\"`x`\"> المشكلات الموجودة على GitHub </a>",
|
||||
"search_filters_title": "معامل الفرز",
|
||||
"search_message_no_results": "لا توجد نتائج.",
|
||||
"search_message_change_filters_or_query": "حاول توسيع استعلام البحث و / أو تغيير عوامل التصفية.",
|
||||
"search_filters_date_label": "تاريخ الرفع",
|
||||
"generic_count_weeks_0": "{{count}} أسبوع",
|
||||
"generic_count_weeks_1": "{{count}} أسبوع",
|
||||
"generic_count_weeks_2": "{{count}} أسبوع",
|
||||
"generic_count_weeks_3": "{{count}} أسبوع",
|
||||
"generic_count_weeks_4": "{{count}} أسابيع",
|
||||
"generic_count_weeks_5": "{{count}} أسبوع",
|
||||
"Popular enabled: ": "تم تمكين الشعبية: ",
|
||||
"search_filters_duration_option_medium": "متوسط (4-20 دقيقة)",
|
||||
"search_filters_date_option_none": "أي تاريخ",
|
||||
"search_filters_type_option_all": "أي نوع",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"generic_count_minutes_0": "{{count}} دقيقة",
|
||||
"generic_count_minutes_1": "{{count}} دقيقة",
|
||||
"generic_count_minutes_2": "{{count}} دقيقة",
|
||||
"generic_count_minutes_3": "{{count}} دقيقة",
|
||||
"generic_count_minutes_4": "{{count}} دقائق",
|
||||
"generic_count_minutes_5": "{{count}} دقيقة",
|
||||
"generic_count_hours_0": "{{count}} ساعة",
|
||||
"generic_count_hours_1": "{{count}} ساعة",
|
||||
"generic_count_hours_2": "{{count}} ساعة",
|
||||
"generic_count_hours_3": "{{count}} ساعة",
|
||||
"generic_count_hours_4": "{{count}} ساعات",
|
||||
"generic_count_hours_5": "{{count}} ساعة",
|
||||
"comments_view_x_replies_0": "عرض رد {{count}}",
|
||||
"comments_view_x_replies_1": "عرض رد {{count}}",
|
||||
"comments_view_x_replies_2": "عرض رد {{count}}",
|
||||
"comments_view_x_replies_3": "عرض رد {{count}}",
|
||||
"comments_view_x_replies_4": "عرض الردود {{count}}",
|
||||
"comments_view_x_replies_5": "عرض رد {{count}}",
|
||||
"search_message_use_another_instance": " يمكنك أيضًا البحث عن <a href=\"`x`\"> في مثيل آخر </a>.",
|
||||
"comments_points_count_0": "{{count}} نقطة",
|
||||
"comments_points_count_1": "{{count}} نقطة",
|
||||
"comments_points_count_2": "{{count}} نقطة",
|
||||
"comments_points_count_3": "{{count}} نقطة",
|
||||
"comments_points_count_4": "{{count}} نقاط",
|
||||
"comments_points_count_5": "{{count}} نقطة",
|
||||
"generic_count_years_0": "{{count}} السنة",
|
||||
"generic_count_years_1": "{{count}} السنة",
|
||||
"generic_count_years_2": "{{count}} السنة",
|
||||
"generic_count_years_3": "{{count}} السنة",
|
||||
"generic_count_years_4": "{{count}} سنوات",
|
||||
"generic_count_years_5": "{{count}} السنة",
|
||||
"tokens_count_0": "الرمز المميز {{count}}",
|
||||
"tokens_count_1": "الرمز المميز {{count}}",
|
||||
"tokens_count_2": "الرمز المميز {{count}}",
|
||||
"tokens_count_3": "الرمز المميز {{count}}",
|
||||
"tokens_count_4": "الرموز المميزة {{count}}",
|
||||
"tokens_count_5": "الرمز المميز {{count}}",
|
||||
"search_filters_apply_button": "تطبيق الفلاتر المحددة",
|
||||
"search_filters_duration_option_none": "أي مدة",
|
||||
"subscriptions_unseen_notifs_count_0": "{{count}} إشعار غير مرئي",
|
||||
"subscriptions_unseen_notifs_count_1": "{{count}} إشعار غير مرئي",
|
||||
"subscriptions_unseen_notifs_count_2": "{{count}} إشعار غير مرئي",
|
||||
"subscriptions_unseen_notifs_count_3": "{{count}} إشعار غير مرئي",
|
||||
"subscriptions_unseen_notifs_count_4": "{{count}} إشعارات غير مرئية",
|
||||
"subscriptions_unseen_notifs_count_5": "{{count}} إشعار غير مرئي",
|
||||
"generic_count_days_0": "{{count}} يوم",
|
||||
"generic_count_days_1": "{{count}} يوم",
|
||||
"generic_count_days_2": "{{count}} يوم",
|
||||
"generic_count_days_3": "{{count}} يوم",
|
||||
"generic_count_days_4": "{{count}} أيام",
|
||||
"generic_count_days_5": "{{count}} يوم",
|
||||
"generic_count_months_0": "{{count}} شهر",
|
||||
"generic_count_months_1": "{{count}} شهر",
|
||||
"generic_count_months_2": "{{count}} شهر",
|
||||
"generic_count_months_3": "{{count}} شهر",
|
||||
"generic_count_months_4": "{{count}} شهور",
|
||||
"generic_count_months_5": "{{count}} شهر",
|
||||
"generic_count_seconds_0": "{{count}} ثانية",
|
||||
"generic_count_seconds_1": "{{count}} ثانية",
|
||||
"generic_count_seconds_2": "{{count}} ثانية",
|
||||
"generic_count_seconds_3": "{{count}} ثانية",
|
||||
"generic_count_seconds_4": "{{count}} ثوانٍ",
|
||||
"generic_count_seconds_5": "{{count}} ثانية"
|
||||
}
|
||||
|
||||
97
locales/bn.json
Normal file
97
locales/bn.json
Normal file
@@ -0,0 +1,97 @@
|
||||
{
|
||||
"Subscribe": "সাবস্ক্রাইব",
|
||||
"View channel on YouTube": "ইউটিউবে চ্যানেল দেখুন",
|
||||
"View playlist on YouTube": "ইউটিউবে প্লেলিস্ট দেখুন",
|
||||
"newest": "সর্ব-নতুন",
|
||||
"oldest": "পুরানতম",
|
||||
"popular": "জনপ্রিয়",
|
||||
"last": "শেষটা",
|
||||
"Next page": "পরের পৃষ্ঠা",
|
||||
"Previous page": "আগের পৃষ্ঠা",
|
||||
"Clear watch history?": "দেখার ইতিহাস সাফ করবেন?",
|
||||
"New password": "নতুন পাসওয়ার্ড",
|
||||
"New passwords must match": "নতুন পাসওয়ার্ড অবশ্যই মিলতে হবে",
|
||||
"Cannot change password for Google accounts": "গুগল অ্যাকাউন্টগুলোর জন্য পাসওয়ার্ড পরিবর্তন করা যায় না",
|
||||
"Authorize token?": "টোকেন অনুমোদন করবেন?",
|
||||
"Authorize token for `x`?": "`x` -এর জন্য টোকেন অনুমোদন?",
|
||||
"Yes": "হ্যাঁ",
|
||||
"No": "না",
|
||||
"Import and Export Data": "তথ্য আমদানি ও রপ্তানি",
|
||||
"Import": "আমদানি",
|
||||
"Import Invidious data": "ইনভিডিয়াস তথ্য আমদানি",
|
||||
"Import YouTube subscriptions": "ইউটিউব সাবস্ক্রিপশন আনুন",
|
||||
"Import FreeTube subscriptions (.db)": "ফ্রিটিউব সাবস্ক্রিপশন (.db) আনুন",
|
||||
"Import NewPipe subscriptions (.json)": "নতুন পাইপ সাবস্ক্রিপশন আনুন (.json)",
|
||||
"Import NewPipe data (.zip)": "নিউপাইপ তথ্য আনুন (.zip)",
|
||||
"Export": "তথ্য বের করুন",
|
||||
"Export subscriptions as OPML": "সাবস্ক্রিপশন OPML হিসাবে আনুন",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "OPML-এ সাবস্ক্রিপশন বের করুন(নিউ পাইপ এবং ফ্রিউটিউব এর জন্য)",
|
||||
"Export data as JSON": "JSON হিসাবে তথ্য বের করুন",
|
||||
"Delete account?": "অ্যাকাউন্ট মুছে ফেলবেন?",
|
||||
"History": "ইতিহাস",
|
||||
"An alternative front-end to YouTube": "ইউটিউবের একটি বিকল্পস্বরূপ সম্মুখ-প্রান্ত",
|
||||
"JavaScript license information": "জাভাস্ক্রিপ্ট লাইসেন্সের তথ্য",
|
||||
"source": "সূত্র",
|
||||
"Log in": "লগ ইন",
|
||||
"Log in/register": "লগ ইন/রেজিস্টার",
|
||||
"Log in with Google": "গুগল দিয়ে লগ ইন করুন",
|
||||
"User ID": "ইউজার আইডি",
|
||||
"Password": "পাসওয়ার্ড",
|
||||
"Time (h:mm:ss):": "সময় (ঘণ্টা:মিনিট:সেকেন্ড):",
|
||||
"Text CAPTCHA": "টেক্সট ক্যাপচা",
|
||||
"Image CAPTCHA": "চিত্র ক্যাপচা",
|
||||
"Sign In": "সাইন ইন",
|
||||
"Register": "নিবন্ধন",
|
||||
"E-mail": "ই-মেইল",
|
||||
"Google verification code": "গুগল যাচাইকরণ কোড",
|
||||
"Preferences": "পছন্দসমূহ",
|
||||
"preferences_category_player": "প্লেয়ারের পছন্দসমূহ",
|
||||
"preferences_video_loop_label": "সর্বদা লুপ: ",
|
||||
"preferences_autoplay_label": "স্বয়ংক্রিয় চালু: ",
|
||||
"preferences_continue_label": "ডিফল্টভাবে পরবর্তী চালাও: ",
|
||||
"preferences_continue_autoplay_label": "পরবর্তী ভিডিও স্বয়ংক্রিয়ভাবে চালাও: ",
|
||||
"preferences_listen_label": "সহজাতভাবে শোনো: ",
|
||||
"preferences_local_label": "ভিডিও প্রক্সি করো: ",
|
||||
"preferences_speed_label": "সহজাত গতি: ",
|
||||
"preferences_quality_label": "পছন্দের ভিডিও মান: ",
|
||||
"preferences_volume_label": "প্লেয়ার শব্দের মাত্রা: ",
|
||||
"LIVE": "লাইভ",
|
||||
"Shared `x` ago": "`x` আগে শেয়ার করা হয়েছে",
|
||||
"Unsubscribe": "আনসাবস্ক্রাইব",
|
||||
"generic_views_count": "{{count}}জন দেখেছে",
|
||||
"generic_views_count_plural": "{{count}}জন দেখেছে",
|
||||
"generic_videos_count": "{{count}}টি ভিডিও",
|
||||
"generic_videos_count_plural": "{{count}}টি ভিডিও",
|
||||
"generic_subscribers_count": "{{count}}জন অনুসরণকারী",
|
||||
"generic_subscribers_count_plural": "{{count}}জন অনুসরণকারী",
|
||||
"preferences_watch_history_label": "দেখার ইতিহাস চালু করো: ",
|
||||
"preferences_quality_option_dash": "ড্যাশ (সময়োপযোগী মান)",
|
||||
"preferences_quality_dash_option_auto": "স্বয়ংক্রিয়",
|
||||
"preferences_quality_dash_option_best": "সেরা",
|
||||
"preferences_quality_dash_option_worst": "মন্দতম",
|
||||
"preferences_quality_dash_option_4320p": "৪৩২০পি",
|
||||
"preferences_quality_dash_option_2160p": "২১৬০পি",
|
||||
"preferences_quality_dash_option_1440p": "১৪৪০পি",
|
||||
"preferences_quality_dash_option_480p": "৪৮০পি",
|
||||
"preferences_quality_dash_option_360p": "৩৬০পি",
|
||||
"preferences_quality_dash_option_240p": "২৪০পি",
|
||||
"preferences_quality_dash_option_144p": "১৪৪পি",
|
||||
"preferences_comments_label": "সহজাত মন্তব্য: ",
|
||||
"youtube": "ইউটিউব",
|
||||
"Fallback captions: ": "বিকল্প উপাখ্যান: ",
|
||||
"preferences_related_videos_label": "সম্পর্কিত ভিডিও দেখাও: ",
|
||||
"preferences_annotations_label": "সহজাতভাবে টীকা দেখাও ",
|
||||
"preferences_quality_option_hd720": "উচ্চ৭২০",
|
||||
"preferences_quality_dash_label": "পছন্দের ড্যাশ ভিডিও মান: ",
|
||||
"preferences_captions_label": "সহজাত উপাখ্যান: ",
|
||||
"generic_playlists_count": "{{count}}টি চালুতালিকা",
|
||||
"generic_playlists_count_plural": "{{count}}টি চালুতালিকা",
|
||||
"reddit": "রেডিট",
|
||||
"invidious": "ইনভিডিয়াস",
|
||||
"generic_subscriptions_count": "{{count}}টি অনুসরণ",
|
||||
"generic_subscriptions_count_plural": "{{count}}টি অনুসরণ",
|
||||
"preferences_quality_option_medium": "মধ্যম",
|
||||
"preferences_quality_option_small": "ছোট",
|
||||
"preferences_quality_dash_option_1080p": "১০৮০পি",
|
||||
"preferences_quality_dash_option_720p": "৭২০পি"
|
||||
}
|
||||
@@ -52,16 +52,16 @@
|
||||
"Download": "Descarrega",
|
||||
"Download as: ": "Descarrega com: ",
|
||||
"Videos": "Vídeos",
|
||||
"content_type": "Tipus",
|
||||
"duration": "Duració",
|
||||
"sort": "Ordena per",
|
||||
"week": "Aquesta setmana",
|
||||
"month": "Aquest mes",
|
||||
"year": "Aquest any",
|
||||
"video": "Vídeo",
|
||||
"channel": "Canal",
|
||||
"short": "Curt (< 4 minuts)",
|
||||
"long": "Llarg (> 20 minuts)",
|
||||
"search_filters_type_label": "Tipus",
|
||||
"search_filters_duration_label": "Duració",
|
||||
"search_filters_sort_label": "Ordena per",
|
||||
"search_filters_date_option_week": "Aquesta setmana",
|
||||
"search_filters_date_option_month": "Aquest mes",
|
||||
"search_filters_date_option_year": "Aquest any",
|
||||
"search_filters_type_option_video": "Vídeo",
|
||||
"search_filters_type_option_channel": "Canal",
|
||||
"search_filters_duration_option_short": "Curt (< 4 minuts)",
|
||||
"search_filters_duration_option_long": "Llarg (> 20 minuts)",
|
||||
"Current version: ": "Versió actual: ",
|
||||
"Malay": "Malai",
|
||||
"Persian": "Persa",
|
||||
@@ -93,11 +93,11 @@
|
||||
"Spanish": "Castellà",
|
||||
"Vietnamese": "Vietnamita",
|
||||
"News": "Notícies",
|
||||
"show": "Mostra",
|
||||
"search_filters_type_option_show": "Mostra",
|
||||
"footer_documentation": "Documentació",
|
||||
"Thai": "Tailandès",
|
||||
"Music": "Música",
|
||||
"relevance": "Rellevància",
|
||||
"hour": "Última hora",
|
||||
"today": "Avui"
|
||||
"search_filters_sort_option_relevance": "Rellevància",
|
||||
"search_filters_date_option_hour": "Última hora",
|
||||
"search_filters_date_option_today": "Avui"
|
||||
}
|
||||
|
||||
301
locales/cs.json
301
locales/cs.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"LIVE": "ŽIVĚ",
|
||||
"Shared `x` ago": "Sdíleno před `x`",
|
||||
"Shared `x` ago": "Zveřejněno před `x`",
|
||||
"Unsubscribe": "Odhlásit odběr",
|
||||
"Subscribe": "Odebírat",
|
||||
"View channel on YouTube": "Otevřít kanál na YouTube",
|
||||
@@ -19,17 +19,17 @@
|
||||
"Authorize token for `x`?": "Autorizovat token pro `x`?",
|
||||
"Yes": "Ano",
|
||||
"No": "Ne",
|
||||
"Import and Export Data": "Import a Export údajů",
|
||||
"Import": "Inport",
|
||||
"Import Invidious data": "Importovat údaje Invidious",
|
||||
"Import YouTube subscriptions": "Importovat odběry z YouTube",
|
||||
"Import and Export Data": "Import a export dat",
|
||||
"Import": "Importovat",
|
||||
"Import Invidious data": "Importovat JSON údaje Invidious",
|
||||
"Import YouTube subscriptions": "Importovat odběry z YouTube/OPML",
|
||||
"Import FreeTube subscriptions (.db)": "Importovat odběry z FreeTube (.db)",
|
||||
"Import NewPipe subscriptions (.json)": "Importovat odběry z NewPipe (.json)",
|
||||
"Import NewPipe data (.zip)": "Importovat údeje z NewPipe (.zip)",
|
||||
"Export": "Exportovat",
|
||||
"Export subscriptions as OPML": "Exportovat odběry jako OPML",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Exportovat údaje jako OPML (na NewPipe a FreeTube)",
|
||||
"Export data as JSON": "Exportovat data jako JSON",
|
||||
"Export data as JSON": "Exportovat data Invidious jako JSON",
|
||||
"Delete account?": "Smazat účet?",
|
||||
"History": "Historie",
|
||||
"An alternative front-end to YouTube": "Alternativní front-end pro YouTube",
|
||||
@@ -38,7 +38,7 @@
|
||||
"Log in": "Přihlásit se",
|
||||
"Log in/register": "Přihlásit se/vytvořit účet",
|
||||
"Log in with Google": "Přihlásit se s Googlem",
|
||||
"User ID": "Uživatelské IČ",
|
||||
"User ID": "ID uživatele",
|
||||
"Password": "Heslo",
|
||||
"Time (h:mm:ss):": "Čas (h:mm:ss):",
|
||||
"Text CAPTCHA": "Textové CAPTCHA",
|
||||
@@ -51,17 +51,17 @@
|
||||
"preferences_category_player": "Nastavení přehravače",
|
||||
"preferences_video_loop_label": "Vždy opakovat: ",
|
||||
"preferences_autoplay_label": "Automatické přehrávání: ",
|
||||
"preferences_continue_label": "Přehrát další ve výchozím stavu: ",
|
||||
"preferences_continue_label": "Automaticky přehrát další: ",
|
||||
"preferences_continue_autoplay_label": "Automaticky přehrát další video: ",
|
||||
"preferences_listen_label": "Poslouchat ve výchozím nastavení: ",
|
||||
"preferences_local_label": "Video přes proxy: ",
|
||||
"preferences_speed_label": "Základní Rychlost: ",
|
||||
"preferences_speed_label": "Výchozí rychlost: ",
|
||||
"preferences_quality_label": "Preferovaná kvalita videa: ",
|
||||
"preferences_volume_label": "Hlasitost přehrávače: ",
|
||||
"preferences_comments_label": "Předpřipravené komentáře: ",
|
||||
"youtube": "YouTube",
|
||||
"reddit": "reddit",
|
||||
"preferences_captions_label": "Standartní Titulky: ",
|
||||
"reddit": "Reddit",
|
||||
"preferences_captions_label": "Výchozí titulky: ",
|
||||
"Fallback captions: ": "Záložní titulky: ",
|
||||
"preferences_related_videos_label": "Zobrazit podobné videa: ",
|
||||
"preferences_annotations_label": "Zobrazovat poznámky ve výchozím nastavení: ",
|
||||
@@ -88,28 +88,28 @@
|
||||
"Only show latest unwatched video from channel: ": "Zobrazit jen nejnovější nezhlédnuté video z daného kanálu: ",
|
||||
"preferences_unseen_only_label": "Zobrazit jen již nezhlédnuté: ",
|
||||
"preferences_notifications_only_label": "Zobrazit pouze upozornění (pokud nějaká jsou): ",
|
||||
"Enable web notifications": "Povolit webové upozornění",
|
||||
"Enable web notifications": "Povolit webová upozornění",
|
||||
"`x` uploaded a video": "`x` nahrál(a) video",
|
||||
"`x` is live": "`x` je živě",
|
||||
"preferences_category_data": "Nastavení dat",
|
||||
"Clear watch history": "Smazat historii",
|
||||
"Import/export data": "importovat/exportovat data",
|
||||
"Import/export data": "Importovat/exportovat data",
|
||||
"Change password": "Změnit heslo",
|
||||
"Manage subscriptions": "Spravovat odebírané kanály",
|
||||
"Manage tokens": "Spravovat klíče",
|
||||
"Watch history": "Historie Sledování",
|
||||
"Delete account": "Smazat Účet",
|
||||
"Manage tokens": "Spravovat tokeny",
|
||||
"Watch history": "Historie sledování",
|
||||
"Delete account": "Smazat účet",
|
||||
"preferences_category_admin": "Administrátorská nastavení",
|
||||
"preferences_default_home_label": "Základní domovská stránka: ",
|
||||
"preferences_feed_menu_label": "Menu doporučených: ",
|
||||
"CAPTCHA enabled: ": "CAPTCHA povolen: ",
|
||||
"CAPTCHA enabled: ": "CAPTCHA povolena: ",
|
||||
"Login enabled: ": "Přihlášení povoleno: ",
|
||||
"Registration enabled: ": "Registrace povolena ",
|
||||
"Report statistics: ": "Oznámit statistiky: ",
|
||||
"Save preferences": "Uložit nastavení",
|
||||
"Subscription manager": "Správa Odběrů",
|
||||
"Token manager": "Správa klíčů",
|
||||
"Token": "Klíč",
|
||||
"Subscription manager": "Správa odběrů",
|
||||
"Token manager": "Správa tokenů",
|
||||
"Token": "Token",
|
||||
"Import/export": "Importovat/exportovat",
|
||||
"unsubscribe": "odhlásit odběr",
|
||||
"revoke": "vrátit zpět",
|
||||
@@ -118,10 +118,10 @@
|
||||
"Log out": "Odhlásit se",
|
||||
"Source available here.": "Zdrojový kód dostupný zde.",
|
||||
"View JavaScript license information.": "Zobrazit informace o licenci JavaScript .",
|
||||
"View privacy policy.": "Zobrazit Zásady ochrany osobních údajů.",
|
||||
"View privacy policy.": "Zobrazit zásady ochrany osobních údajů.",
|
||||
"Trending": "Trendy",
|
||||
"Public": "Veřejné",
|
||||
"Unlisted": "Nevypsáno",
|
||||
"Unlisted": "Neveřejné",
|
||||
"Private": "Soukromé",
|
||||
"View all playlists": "Zobrazit všechny playlisty",
|
||||
"Updated `x` ago": "Aktualizováno před `x`",
|
||||
@@ -133,12 +133,12 @@
|
||||
"Show more": "Zobrazit více",
|
||||
"Show less": "Zobrazit méně",
|
||||
"Watch on YouTube": "Sledovat na YouTube",
|
||||
"Hide annotations": "Skrýt vysvětlivky",
|
||||
"Show annotations": "Zobrazit vysvětlivky",
|
||||
"Hide annotations": "Skrýt poznámky",
|
||||
"Show annotations": "Zobrazit poznámky",
|
||||
"Genre: ": "Žánr: ",
|
||||
"License: ": "Licence: ",
|
||||
"Family friendly? ": "Vhodné pro děti? ",
|
||||
"Engagement: ": "Závaznost: ",
|
||||
"Family friendly? ": "Vhodné pro rodiny? ",
|
||||
"Engagement: ": "Zapojení: ",
|
||||
"English": "Angličtina",
|
||||
"English (auto-generated)": "Angličtina (automaticky generováno)",
|
||||
"Afrikaans": "Afrikánština",
|
||||
@@ -262,27 +262,230 @@
|
||||
"Video mode": "Videový režim",
|
||||
"Videos": "Videa",
|
||||
"Community": "Komunita",
|
||||
"rating": "hodnocení",
|
||||
"date": "datum",
|
||||
"views": "zhlédnutí",
|
||||
"duration": "délka",
|
||||
"hour": "hodina",
|
||||
"today": "dnes",
|
||||
"week": "týden",
|
||||
"month": "měsíc",
|
||||
"year": "rok",
|
||||
"video": "video",
|
||||
"channel": "kanál",
|
||||
"playlist": "playlist",
|
||||
"movie": "film",
|
||||
"show": "zobrazit",
|
||||
"hd": "HD",
|
||||
"subtitles": "titulky",
|
||||
"creative_commons": "Creative Commons",
|
||||
"3d": "3D",
|
||||
"live": "živě",
|
||||
"4k": "4k",
|
||||
"location": "umístění",
|
||||
"hdr": "HDR",
|
||||
"filter": "filtr"
|
||||
"search_filters_sort_option_rating": "Hodnocení",
|
||||
"search_filters_sort_option_date": "Datum nahrání",
|
||||
"search_filters_sort_option_views": "Počet zhlédnutí",
|
||||
"search_filters_duration_label": "Délka",
|
||||
"search_filters_date_option_hour": "Poslední hodina",
|
||||
"search_filters_date_option_today": "Dnes",
|
||||
"search_filters_date_option_week": "Tento týden",
|
||||
"search_filters_date_option_month": "Tento měsíc",
|
||||
"search_filters_date_option_year": "Tento rok",
|
||||
"search_filters_type_option_video": "Video",
|
||||
"search_filters_type_option_channel": "Kanál",
|
||||
"search_filters_type_option_playlist": "Playlist",
|
||||
"search_filters_type_option_movie": "Film",
|
||||
"search_filters_type_option_show": "Seriál",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "Titulky",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_live": "Živě",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_location": "Umístění",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"generic_count_days_0": "{{count}} dnem",
|
||||
"generic_count_days_1": "{{count}} dny",
|
||||
"generic_count_days_2": "{{count}} dny",
|
||||
"generic_count_hours_0": "{{count}} hodinou",
|
||||
"generic_count_hours_1": "{{count}} hodinami",
|
||||
"generic_count_hours_2": "{{count}} hodinami",
|
||||
"crash_page_refresh": "zkusili <a href=\"`x`\">obnovit stránku</a>",
|
||||
"crash_page_switch_instance": "zkusili <a href=\"`x`\">použít jinou instanci</a>",
|
||||
"preferences_vr_mode_label": "Interaktivní 360-stupňová videa (vyžaduje WebGL): ",
|
||||
"English (United Kingdom)": "Angličtina (Spojené království)",
|
||||
"Chinese (China)": "Čínština (Čína)",
|
||||
"Chinese (Hong Kong)": "Čínština (Hong Kong)",
|
||||
"Chinese (Taiwan)": "Čínština (Taiwan)",
|
||||
"Portuguese (auto-generated)": "Portugalština (automaticky generováno)",
|
||||
"Spanish (auto-generated)": "Španělština (automaticky generováno)",
|
||||
"Spanish (Mexico)": "Španělština (Mexiko)",
|
||||
"Spanish (Spain)": "Španělština (Španělsko)",
|
||||
"generic_count_years_0": "{{count}} rokem",
|
||||
"generic_count_years_1": "{{count}} lety",
|
||||
"generic_count_years_2": "{{count}} lety",
|
||||
"Fallback comments: ": "Záložní komentáře: ",
|
||||
"Search": "Hledat",
|
||||
"Top": "Nejlepší",
|
||||
"Playlists": "Playlisty",
|
||||
"videoinfo_started_streaming_x_ago": "Stream spuštěn před `x`",
|
||||
"videoinfo_watch_on_youTube": "Sledovat na YouTube",
|
||||
"videoinfo_youTube_embed_link": "Vložení",
|
||||
"crash_page_read_the_faq": "si přečetli <a href=\"`x`\">často kladené otázky (FAQ)</a>",
|
||||
"crash_page_before_reporting": "Před nahlášením chyby se ujistěte, že jste:",
|
||||
"preferences_quality_option_hd720": "HD720",
|
||||
"preferences_quality_option_dash": "DASH (adaptivní kvalita)",
|
||||
"generic_views_count_0": "{{count}} zhlédnutí",
|
||||
"generic_views_count_1": "{{count}} zhlédnutí",
|
||||
"generic_views_count_2": "{{count}} zhlédnutí",
|
||||
"generic_subscriptions_count_0": "{{count}} odběr",
|
||||
"generic_subscriptions_count_1": "{{count}} odběry",
|
||||
"generic_subscriptions_count_2": "{{count}} odběrů",
|
||||
"preferences_quality_dash_option_4320p": "4320p",
|
||||
"generic_videos_count_0": "{{count}} video",
|
||||
"generic_videos_count_1": "{{count}} videa",
|
||||
"generic_videos_count_2": "{{count}} videí",
|
||||
"preferences_quality_option_small": "Nízká",
|
||||
"preferences_quality_dash_option_2160p": "2160p",
|
||||
"preferences_quality_dash_option_1080p": "1080p",
|
||||
"preferences_quality_dash_option_720p": "720p",
|
||||
"preferences_quality_dash_option_360p": "360p",
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"preferences_quality_option_medium": "Střední",
|
||||
"preferences_quality_dash_option_1440p": "1440p",
|
||||
"invidious": "Invidious",
|
||||
"View more comments on Reddit": "Zobrazit více komentářů na Redditu",
|
||||
"Invalid TFA code": "Nesprávný TFA kód",
|
||||
"generic_playlists_count_0": "{{count}} playlist",
|
||||
"generic_playlists_count_1": "{{count}} playlisty",
|
||||
"generic_playlists_count_2": "{{count}} playlistů",
|
||||
"generic_subscribers_count_0": "{{count}} odběratel",
|
||||
"generic_subscribers_count_1": "{{count}} odběratelé",
|
||||
"generic_subscribers_count_2": "{{count}} odběratelů",
|
||||
"preferences_watch_history_label": "Povolit historii sledování: ",
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"preferences_region_label": "Země obsahu: ",
|
||||
"subscriptions_unseen_notifs_count_0": "{{count}} nezobrazené oznámení",
|
||||
"subscriptions_unseen_notifs_count_1": "{{count}} nezobrazená oznámení",
|
||||
"subscriptions_unseen_notifs_count_2": "{{count}} nezobrazených oznámení",
|
||||
"Show replies": "Zobrazit odpovědi",
|
||||
"Quota exceeded, try again in a few hours": "Kvóta překročena, zkuste to znovu za pár hodin",
|
||||
"Password cannot be longer than 55 characters": "Heslo nesmí být delší než 55 znaků",
|
||||
"comments_view_x_replies_0": "Zobrazit {{count}} odpověď",
|
||||
"comments_view_x_replies_1": "Zobrazit {{count}} odpovědi",
|
||||
"comments_view_x_replies_2": "Zobrazit {{count}} odpovědí",
|
||||
"comments_points_count_0": "{{count}} bod",
|
||||
"comments_points_count_1": "{{count}} body",
|
||||
"comments_points_count_2": "{{count}} bodů",
|
||||
"German (auto-generated)": "Němčina (automaticky generováno)",
|
||||
"Indonesian (auto-generated)": "Indonéština (automaticky generováno)",
|
||||
"Interlingue": "Interlingue",
|
||||
"Italian (auto-generated)": "Italština (automaticky generováno)",
|
||||
"Japanese (auto-generated)": "Japonština (automaticky generováno)",
|
||||
"Korean (auto-generated)": "Korejština (automaticky generováno)",
|
||||
"Russian (auto-generated)": "Ruština (automaticky generováno)",
|
||||
"generic_count_months_0": "{{count}} měsícem",
|
||||
"generic_count_months_1": "{{count}} měsíci",
|
||||
"generic_count_months_2": "{{count}} měsíci",
|
||||
"generic_count_weeks_0": "{{count}} týdnem",
|
||||
"generic_count_weeks_1": "{{count}} týdny",
|
||||
"generic_count_weeks_2": "{{count}} týdny",
|
||||
"generic_count_minutes_0": "{{count}} minutou",
|
||||
"generic_count_minutes_1": "{{count}} minutami",
|
||||
"generic_count_minutes_2": "{{count}} minutami",
|
||||
"footer_documentation": "Dokumentace",
|
||||
"next_steps_error_message_refresh": "Obnovit stránku",
|
||||
"Chinese": "Čínština",
|
||||
"Dutch (auto-generated)": "Nizozemština (automaticky generováno)",
|
||||
"Erroneous token": "Chybný token",
|
||||
"tokens_count_0": "{{count}} token",
|
||||
"tokens_count_1": "{{count}} tokeny",
|
||||
"tokens_count_2": "{{count}} tokenů",
|
||||
"Portuguese (Brazil)": "Portugalština (Brazílie)",
|
||||
"Token is expired, please try again": "Token vypršel, zkuste to prosím znovu",
|
||||
"English (United States)": "Angličtina (Spojené státy)",
|
||||
"Cantonese (Hong Kong)": "Kantonština (Hong Kong)",
|
||||
"French (auto-generated)": "Francouzština (automaticky generováno)",
|
||||
"Turkish (auto-generated)": "Turečtina (automaticky generováno)",
|
||||
"Vietnamese (auto-generated)": "Vietnamština (automaticky generováno)",
|
||||
"Current version: ": "Aktuální verze: ",
|
||||
"next_steps_error_message": "Měli byste zkusit: ",
|
||||
"footer_donate_page": "Přispět",
|
||||
"download_subtitles": "Titulky - `x` (.vtt)",
|
||||
"%A %B %-d, %Y": "%A %B %-d, %Y",
|
||||
"YouTube comment permalink": "Permanentní odkaz YouTube komentáře",
|
||||
"permalink": "permalink",
|
||||
"footer_original_source_code": "Původní zdrojový kód",
|
||||
"adminprefs_modified_source_code_url_label": "URL repozitáře s upraveným zdrojovým kódem",
|
||||
"Video unavailable": "Video není dostupné",
|
||||
"next_steps_error_message_go_to_youtube": "Jít na YouTube",
|
||||
"footer_modfied_source_code": "Upravený zdrojový kód",
|
||||
"none": "žádné",
|
||||
"videoinfo_invidious_embed_link": "Odkaz na vložení",
|
||||
"user_saved_playlists": "`x` uložených playlistů",
|
||||
"crash_page_you_found_a_bug": "Vypadá to, že jste našli chybu v Invidious!",
|
||||
"user_created_playlists": "`x` vytvořených playlistů",
|
||||
"crash_page_search_issue": "vyhledali <a href=\"`x`\">existující problémy na GitHubu</a>",
|
||||
"crash_page_report_issue": "Pokud nepomohlo nic z výše uvedeného, <a href=\"`x`\">otevřete prosím nový problém na GitHubu</a> (pokud možno v angličtině) a zahrňte do zprávy následující text (NEpřekládejte jej):",
|
||||
"preferences_quality_dash_label": "Preferovaná kvalita videí DASH: ",
|
||||
"preferences_quality_dash_option_auto": "Automatická",
|
||||
"preferences_quality_dash_option_best": "Nejlepší",
|
||||
"preferences_quality_dash_option_worst": "Nejhorší",
|
||||
"preferences_quality_dash_option_480p": "480p",
|
||||
"Top enabled: ": "Povoleny nejlepší: ",
|
||||
"generic_count_seconds_0": "{{count}} sekundou",
|
||||
"generic_count_seconds_1": "{{count}} sekundami",
|
||||
"generic_count_seconds_2": "{{count}} sekundami",
|
||||
"preferences_save_player_pos_label": "Uložit pozici přehrávání: ",
|
||||
"Incorrect password": "Nesprávné heslo",
|
||||
"View as playlist": "Zobrazit jako playlist",
|
||||
"View Reddit comments": "Zobrazit komentáře z Redditu",
|
||||
"No such user": "Uživatel nenalezen",
|
||||
"Playlist privacy": "Soukromí playlistu",
|
||||
"Wrong answer": "Špatná odpověď",
|
||||
"Could not pull trending pages.": "Nepodařilo se získat trendy stránky.",
|
||||
"Erroneous CAPTCHA": "Chybná CAPTCHA",
|
||||
"Password is a required field": "Heslo je vyžadované pole",
|
||||
"preferences_automatic_instance_redirect_label": "Automatické přesměrování instance (fallback na redirect.invidious.io): ",
|
||||
"Switch Invidious Instance": "Přepnout instanci Invidious",
|
||||
"Empty playlist": "Prázdný playlist",
|
||||
"footer_source_code": "Zdrojový kód",
|
||||
"View YouTube comments": "Zobrazit YouTube komentáře",
|
||||
"Blacklisted regions: ": "Oblasti na černé listině: ",
|
||||
"Wrong username or password": "Nesprávné uživatelské jméno nebo heslo",
|
||||
"Please sign in using 'Log in with Google'": "Přihlaste se prosím pomocí Googlu",
|
||||
"Password cannot be empty": "Heslo nemůže být prázné",
|
||||
"preferences_category_misc": "Různá nastavení",
|
||||
"preferences_show_nick_label": "Zobrazit přezdívku na vrchu: ",
|
||||
"Whitelisted regions: ": "Oblasti na bílé listině: ",
|
||||
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Zdravíme! Zdá se, že máte vypnutý JavaScript. Klikněte sem pro zobrazení komentářů - nezapomeňte, že se mohou načítat trochu déle.",
|
||||
"User ID is a required field": "ID uživatele je vyžadované pole",
|
||||
"Please log in": "Přihlaste se prosím",
|
||||
"Invidious Private Feed for `x`": "Soukromý kanál Invidious pro `x`",
|
||||
"Deleted or invalid channel": "Smazaný nebo neplatný kanál",
|
||||
"This channel does not exist.": "Tento kanál neexistuje.",
|
||||
"Hidden field \"token\" is a required field": "Skryté pole \"token\" je vyžadované",
|
||||
"Wilson score: ": "Skóre Wilson: ",
|
||||
"Shared `x`": "Zveřejněno `x`",
|
||||
"Premieres in `x`": "Premiéra za `x`",
|
||||
"View `x` comments": {
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "Zobrazit `x` komentář",
|
||||
"": "Zobrazit `x` komentářů"
|
||||
},
|
||||
"Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Nepodařilo se přihlásit, ujistěte se, že je povoleno dvoufázové ověřování (autentifikátor nebo SMS).",
|
||||
"Login failed. This may be because two-factor authentication is not turned on for your account.": "Přihlášení selhalo. Toto se může stát, když není na vašem účtu povolené dvoufázové ověřování.",
|
||||
"Could not get channel info.": "Nepodařilo se získat informace o kanálu.",
|
||||
"Could not fetch comments": "Nepodařilo se získat komentáře",
|
||||
"Could not create mix.": "Nepodařilo se vytvořit mix.",
|
||||
"Hidden field \"challenge\" is a required field": "Skryté pole \"challenge\" je vyžadované",
|
||||
"Released under the AGPLv3 on Github.": "Vydáno pod licencí AGPLv3 na GitHubu.",
|
||||
"Hide replies": "Skrýt odpovědi",
|
||||
"channel:`x`": "kanál: `x`",
|
||||
"Load more": "Načíst další",
|
||||
"Not a playlist.": "Není playlist.",
|
||||
"Playlist does not exist.": "Playlist neexistuje.",
|
||||
"Erroneous challenge": "Chybná výzva",
|
||||
"Premieres `x`": "Premiéra `x`",
|
||||
"CAPTCHA is a required field": "CAPTCHA je vyžadované pole",
|
||||
"`x` ago": "Před `x`",
|
||||
"search_message_change_filters_or_query": "Zkuste rozšířit vyhledávaný dotaz a/nebo změnit filtry.",
|
||||
"search_filters_date_option_none": "Jakékoli datum",
|
||||
"search_filters_date_label": "Datum nahrání",
|
||||
"search_filters_type_option_all": "Jakýkoli typ",
|
||||
"search_filters_duration_option_none": "Jakákoli délka",
|
||||
"search_filters_type_label": "Typ",
|
||||
"search_filters_duration_option_short": "Krátká (< 4 minuty)",
|
||||
"search_message_no_results": "Nenalezeny žádné výsledky.",
|
||||
"search_filters_title": "Filtry",
|
||||
"search_filters_duration_option_medium": "Střední (4 - 20 minut)",
|
||||
"search_filters_duration_option_long": "Dlouhá (> 20 minut)",
|
||||
"search_message_use_another_instance": " Můžete také <a href=\"`x`\">hledat na jiné instanci</a>.",
|
||||
"search_filters_features_label": "Vlastnosti",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"search_filters_features_option_purchased": "Zakoupeno",
|
||||
"search_filters_sort_label": "Řadit dle",
|
||||
"search_filters_sort_option_relevance": "Relevantnost",
|
||||
"search_filters_apply_button": "Použít vybrané filtry",
|
||||
"Popular enabled: ": "Populární povoleno: "
|
||||
}
|
||||
|
||||
140
locales/da.json
140
locales/da.json
@@ -21,15 +21,15 @@
|
||||
"No": "Nej",
|
||||
"Import and Export Data": "Importer og Eksporter Data",
|
||||
"Import": "Importer",
|
||||
"Import Invidious data": "Importer Invidious data",
|
||||
"Import YouTube subscriptions": "Importer YouTube abonnementer",
|
||||
"Import Invidious data": "Importer Invidious JSON-data",
|
||||
"Import YouTube subscriptions": "Importer YouTube/OPML-abonnementer",
|
||||
"Import FreeTube subscriptions (.db)": "Importer FreeTube abonnementer (.db)",
|
||||
"Import NewPipe subscriptions (.json)": "Importer NewPipe abonnementer (.json)",
|
||||
"Import NewPipe data (.zip)": "Importer NewPipe data (.zip)",
|
||||
"Export": "Exporter",
|
||||
"Export subscriptions as OPML": "Exporter abonnementer som OPML",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Exporter abonnementer som OPML (til NewPipe & FreeTube)",
|
||||
"Export data as JSON": "Exporter data som JSON",
|
||||
"Export data as JSON": "Eksporter Invidious-data som JSON",
|
||||
"Delete account?": "Slet konto?",
|
||||
"History": "Historik",
|
||||
"An alternative front-end to YouTube": "Et alternativt front-end til YouTube",
|
||||
@@ -66,7 +66,7 @@
|
||||
"preferences_related_videos_label": "Vis relaterede videoer: ",
|
||||
"preferences_annotations_label": "Vis annotationer som standard: ",
|
||||
"preferences_extend_desc_label": "Automatisk udvid videoens beskrivelse: ",
|
||||
"preferences_vr_mode_label": "Interaktiv 360 graders videoer: ",
|
||||
"preferences_vr_mode_label": "Interaktive 360 graders videoer (kræver WebGL): ",
|
||||
"preferences_category_visual": "Visuelle præferencer",
|
||||
"preferences_player_style_label": "Afspiller stil: ",
|
||||
"Dark mode: ": "Mørk tilstand: ",
|
||||
@@ -202,7 +202,7 @@
|
||||
"Hidden field \"challenge\" is a required field": "Det skjulte felt \"challenge\" er et påkrævet felt",
|
||||
"Albanian": "Albansk",
|
||||
"preferences_quality_dash_label": "Fortrukket DASH video kvalitet: ",
|
||||
"live": "Direkte",
|
||||
"search_filters_features_option_live": "Direkte",
|
||||
"Lao": "Lao-tse",
|
||||
"Filipino": "Filippinsk",
|
||||
"Greek": "Græsk",
|
||||
@@ -213,23 +213,22 @@
|
||||
"preferences_locale_label": "Sprog: ",
|
||||
"News": "Nyheder",
|
||||
"permalink": "permalink",
|
||||
"date": "Upload dato",
|
||||
"features": "Funktioner",
|
||||
"filter": "Filter",
|
||||
"search_filters_sort_option_date": "Upload dato",
|
||||
"search_filters_features_label": "Funktioner",
|
||||
"Khmer": "Khmer",
|
||||
"Finnish": "Finsk",
|
||||
"week": "Denne uge",
|
||||
"search_filters_date_option_week": "Denne uge",
|
||||
"Korean": "Koreansk",
|
||||
"Telugu": "Telugu",
|
||||
"Malayalam": "Malayalam",
|
||||
"View as playlist": "Se som spilleliste",
|
||||
"Hungarian": "Ungarsk",
|
||||
"Welsh": "Walisisk",
|
||||
"subtitles": "Undertekster/CC",
|
||||
"search_filters_features_option_subtitles": "Undertekster/CC",
|
||||
"Bosnian": "Bosnisk",
|
||||
"Yiddish": "Jiddisch",
|
||||
"Belarusian": "Belarussisk",
|
||||
"today": "I dag",
|
||||
"search_filters_date_option_today": "I dag",
|
||||
"Shona": "Shona",
|
||||
"Slovenian": "Slovensk",
|
||||
"Gaming": "Gaming",
|
||||
@@ -246,35 +245,35 @@
|
||||
"footer_documentation": "Dokumentation",
|
||||
"Pashto": "Pashto",
|
||||
"footer_modfied_source_code": "Modificeret Kildekode",
|
||||
"Released under the AGPLv3 on Github.": "Udgivet under AGPLv3 på Github.",
|
||||
"Released under the AGPLv3 on Github.": "Udgivet under AGPLv3 på GitHub.",
|
||||
"Tajik": "Tadsjikisk",
|
||||
"month": "Denne måned",
|
||||
"search_filters_date_option_month": "Denne måned",
|
||||
"Hebrew": "Hebraisk",
|
||||
"Kannada": "Kannada",
|
||||
"Current version: ": "Nuværende version: ",
|
||||
"Amharic": "Amharisk",
|
||||
"Swedish": "Svensk",
|
||||
"Corsican": "Korsikansk",
|
||||
"movie": "Film",
|
||||
"search_filters_type_option_movie": "Film",
|
||||
"Could not pull trending pages.": "Kunne ikke hente trending sider.",
|
||||
"English": "Engelsk",
|
||||
"hd": "HD",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"Hausa": "Islandsk",
|
||||
"year": "Dette år",
|
||||
"search_filters_date_option_year": "Dette år",
|
||||
"Japanese": "Japansk",
|
||||
"content_type": "Type",
|
||||
"search_filters_type_label": "Type",
|
||||
"Icelandic": "Islandsk",
|
||||
"Basque": "Baskisk",
|
||||
"rating": "Bedømmelse",
|
||||
"search_filters_sort_option_rating": "Bedømmelse",
|
||||
"Yoruba": "Yoruba",
|
||||
"Erroneous token": "Fejlagtig token",
|
||||
"Videos": "Videoer",
|
||||
"show": "Vis",
|
||||
"search_filters_type_option_show": "Vis",
|
||||
"Luxembourgish": "Luxemboursk",
|
||||
"Vietnamese": "Vietnamesisk",
|
||||
"Latvian": "Lettisk",
|
||||
"Indonesian": "Indonesisk",
|
||||
"duration": "Varighed",
|
||||
"search_filters_duration_label": "Varighed",
|
||||
"footer_original_source_code": "Original kildekode",
|
||||
"Search": "Søg",
|
||||
"Serbian": "Serbisk",
|
||||
@@ -289,8 +288,8 @@
|
||||
"Rating: ": "Bedømmelse: ",
|
||||
"Movies": "Film",
|
||||
"YouTube comment permalink": "Youtube kommentarer permalink",
|
||||
"location": "Lokation",
|
||||
"hdr": "HDR",
|
||||
"search_filters_features_option_location": "Lokation",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"Cebuano": "Cebuano (Sugbuanon)",
|
||||
"Nyanja": "Nyanja",
|
||||
"Chinese (Simplified)": "Kinesisk (forenklet)",
|
||||
@@ -306,11 +305,11 @@
|
||||
"German": "Tysk",
|
||||
"Maori": "Maori",
|
||||
"Slovak": "Slovakisk",
|
||||
"relevance": "Relevans",
|
||||
"hour": "Sidste time",
|
||||
"playlist": "Spilleliste",
|
||||
"long": "Lang (> 20 minutter)",
|
||||
"creative_commons": "Creative Commons",
|
||||
"search_filters_sort_option_relevance": "Relevans",
|
||||
"search_filters_date_option_hour": "Sidste time",
|
||||
"search_filters_type_option_playlist": "Spilleliste",
|
||||
"search_filters_duration_option_long": "Lang (> 20 minutter)",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"Marathi": "Marathi",
|
||||
"Sindhi": "Sindhi",
|
||||
"preferences_category_misc": "Diverse indstillinger",
|
||||
@@ -327,8 +326,8 @@
|
||||
"Western Frisian": "Vestfrisisk",
|
||||
"Top": "Top",
|
||||
"Music": "Musik",
|
||||
"views": "Antal visninger",
|
||||
"sort": "Sorter efter",
|
||||
"search_filters_sort_option_views": "Antal visninger",
|
||||
"search_filters_sort_label": "Sorter efter",
|
||||
"Zulu": "Zulu",
|
||||
"Invidious Private Feed for `x`": "Invidious Privat Feed til `x`",
|
||||
"English (auto-generated)": "Engelsk (autogenereret)",
|
||||
@@ -349,7 +348,6 @@
|
||||
"next_steps_error_message": "Efter det burde du prøve at: ",
|
||||
"Sinhala": "Singalesisk (Sinhala)",
|
||||
"Thai": "Thai",
|
||||
"Broken? Try another Invidious Instance": "I stykker? Prøv en anden Invidious instans",
|
||||
"No such user": "Brugeren findes ikke",
|
||||
"Token is expired, please try again": "Token er udløbet, prøv igen",
|
||||
"Catalan": "Catalansk",
|
||||
@@ -359,16 +357,16 @@
|
||||
"Scottish Gaelic": "Skotsk Gælisk",
|
||||
"Default": "Standard",
|
||||
"Video mode": "Videotilstand",
|
||||
"short": "Kort (< 4 minutter)",
|
||||
"search_filters_duration_option_short": "Kort (< 4 minutter)",
|
||||
"Hidden field \"token\" is a required field": "Det skjulte felt \"token\" er et påkrævet felt",
|
||||
"Azerbaijani": "Aserbajdsjansk",
|
||||
"Georgian": "Georgisk",
|
||||
"Italian": "Italiensk",
|
||||
"Audio mode": "Lydtilstand",
|
||||
"video": "Video",
|
||||
"channel": "Kanal",
|
||||
"3d": "3D",
|
||||
"4k": "4K",
|
||||
"search_filters_type_option_video": "Video",
|
||||
"search_filters_type_option_channel": "Kanal",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"Hmong": "Hmong",
|
||||
"preferences_quality_option_medium": "Medium",
|
||||
"preferences_quality_option_small": "Lille",
|
||||
@@ -381,8 +379,8 @@
|
||||
"preferences_quality_dash_option_360p": "360p",
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"invidious": "Invidious",
|
||||
"purchased": "Købt",
|
||||
"360": "360°",
|
||||
"search_filters_features_option_purchased": "Købt",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"none": "ingen",
|
||||
"videoinfo_started_streaming_x_ago": "Streamen blev startet for `x`siden",
|
||||
"videoinfo_watch_on_youTube": "Se på YouTube",
|
||||
@@ -392,11 +390,75 @@
|
||||
"user_created_playlists": "`x`opretede spillelister",
|
||||
"user_saved_playlists": "´x`gemte spillelister",
|
||||
"Video unavailable": "Video ikke tilgængelig",
|
||||
"preferences_save_player_pos_label": "Gem den nuværende videotid: ",
|
||||
"preferences_save_player_pos_label": "Gem afspilningsposition: ",
|
||||
"preferences_quality_dash_option_auto": "Auto",
|
||||
"preferences_quality_option_hd720": "HD720",
|
||||
"preferences_quality_dash_option_2160p": "2160p",
|
||||
"preferences_quality_option_dash": "DASH (adaptiv kvalitet)",
|
||||
"preferences_quality_dash_option_1440p": "1440p",
|
||||
"preferences_quality_dash_option_240p": "240p"
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"subscriptions_unseen_notifs_count": "{{count}} uset notifikation",
|
||||
"subscriptions_unseen_notifs_count_plural": "{{count}} usete notifikationer",
|
||||
"comments_view_x_replies": "Vis {{count}} svar",
|
||||
"comments_view_x_replies_plural": "Vis {{count}} svar",
|
||||
"comments_points_count": "{{count}} point",
|
||||
"comments_points_count_plural": "{{count}} point",
|
||||
"generic_count_years": "{{count}} år",
|
||||
"generic_count_years_plural": "{{count}} år",
|
||||
"generic_count_months": "{{count}} måned",
|
||||
"generic_count_months_plural": "{{count}} måneder",
|
||||
"generic_count_days": "{{count}} dag",
|
||||
"generic_count_days_plural": "{{count}} dage",
|
||||
"generic_count_minutes": "{{count}} minut",
|
||||
"generic_count_minutes_plural": "{{count}} minutter",
|
||||
"generic_count_seconds": "{{count}} sekund",
|
||||
"generic_count_seconds_plural": "{{count}} sekunder",
|
||||
"generic_subscribers_count": "{{count}} abonnent",
|
||||
"generic_subscribers_count_plural": "{{count}} abonnenter",
|
||||
"generic_subscriptions_count": "{{count}} abonnement",
|
||||
"generic_subscriptions_count_plural": "{{count}} abonnementer",
|
||||
"generic_videos_count": "{{count}} video",
|
||||
"generic_videos_count_plural": "{{count}} videoer",
|
||||
"English (United States)": "Engelsk (USA)",
|
||||
"French (auto-generated)": "Fransk (autogenereret)",
|
||||
"Spanish (auto-generated)": "Spansk (autogenereret)",
|
||||
"crash_page_before_reporting": "Før du rapporterer en fejl, skal du sikre dig, at du har:",
|
||||
"crash_page_refresh": "forsøgte at <a href=\"`x`\">opdatere siden</a>",
|
||||
"generic_playlists_count": "{{count}} spilleliste",
|
||||
"generic_playlists_count_plural": "{{count}} spillelister",
|
||||
"preferences_watch_history_label": "Aktiver afspilningshistorik: ",
|
||||
"tokens_count": "{{count}} token",
|
||||
"tokens_count_plural": "{{count}} tokens",
|
||||
"Cantonese (Hong Kong)": "Kantonesisk (Hongkong)",
|
||||
"Chinese": "Kinesisk",
|
||||
"Chinese (China)": "Kinesisk (Kina)",
|
||||
"Chinese (Hong Kong)": "Kinesisk (Hongkong)",
|
||||
"Chinese (Taiwan)": "Kinesisk (Taiwan)",
|
||||
"Dutch (auto-generated)": "Hollandsk (autogenereret)",
|
||||
"Indonesian (auto-generated)": "Indonesisk (autogenereret)",
|
||||
"Interlingue": "Interlingue",
|
||||
"Japanese (auto-generated)": "Japansk (autogenereret)",
|
||||
"Korean (auto-generated)": "Koreansk (autogenereret)",
|
||||
"Russian (auto-generated)": "Russisk (autogenereret)",
|
||||
"Turkish (auto-generated)": "Tyrkisk (autogenereret)",
|
||||
"Vietnamese (auto-generated)": "Vietnamesisk (autogenereret)",
|
||||
"crash_page_report_issue": "Hvis intet af ovenstående hjalp, bedes du <a href=\"`x`\">åbne et nyt problem på GitHub</a> (helst på engelsk) og inkludere følgende tekst i din besked (oversæt IKKE denne tekst):",
|
||||
"English (United Kingdom)": "Engelsk (Storbritannien)",
|
||||
"Italian (auto-generated)": "Italiensk (autogenereret)",
|
||||
"Portuguese (auto-generated)": "Portugisisk (autogenereret)",
|
||||
"Portuguese (Brazil)": "Portugisisk (Brasilien)",
|
||||
"generic_views_count": "{{count}} visning",
|
||||
"generic_views_count_plural": "{{count}} visninger",
|
||||
"generic_count_hours": "{{count}} time",
|
||||
"generic_count_hours_plural": "{{count}} timer",
|
||||
"Spanish (Spain)": "Spansk (Spanien)",
|
||||
"crash_page_switch_instance": "forsøgte at <a href=\"`x`\">bruge en anden instans</a>",
|
||||
"German (auto-generated)": "Tysk (autogenereret)",
|
||||
"Spanish (Mexico)": "Spansk (Mexico)",
|
||||
"generic_count_weeks": "{{count}} uge",
|
||||
"generic_count_weeks_plural": "{{count}} uger",
|
||||
"crash_page_you_found_a_bug": "Det ser ud til, at du har fundet en fejl i Invidious!",
|
||||
"crash_page_read_the_faq": "læs <a href=\"`x`\">Ofte stillede spørgsmål (FAQ)</a>",
|
||||
"crash_page_search_issue": "søgte efter <a href=\"`x`\">eksisterende problemer på GitHub</a>",
|
||||
"search_filters_title": "Filter"
|
||||
}
|
||||
|
||||
165
locales/de.json
165
locales/de.json
@@ -21,15 +21,15 @@
|
||||
"No": "Nein",
|
||||
"Import and Export Data": "Daten importieren und exportieren",
|
||||
"Import": "Importieren",
|
||||
"Import Invidious data": "Invidious Daten importieren",
|
||||
"Import YouTube subscriptions": "YouTube Abonnements importieren",
|
||||
"Import Invidious data": "Invidious-JSON-Daten importieren",
|
||||
"Import YouTube subscriptions": "YouTube-/OPML-Abonnements importieren",
|
||||
"Import FreeTube subscriptions (.db)": "FreeTube Abonnements importieren (.db)",
|
||||
"Import NewPipe subscriptions (.json)": "NewPipe Abonnements importieren (.json)",
|
||||
"Import NewPipe data (.zip)": "NewPipe Daten importieren (.zip)",
|
||||
"Export": "Exportieren",
|
||||
"Export subscriptions as OPML": "Abonnements als OPML exportieren",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Abonnements als OPML exportieren (für NewPipe & FreeTube)",
|
||||
"Export data as JSON": "Daten als JSON exportieren",
|
||||
"Export data as JSON": "Invidious-Daten als JSON exportieren",
|
||||
"Delete account?": "Konto löschen?",
|
||||
"History": "Verlauf",
|
||||
"An alternative front-end to YouTube": "Eine alternative Oberfläche für YouTube",
|
||||
@@ -51,10 +51,10 @@
|
||||
"preferences_category_player": "Wiedergabeeinstellungen",
|
||||
"preferences_video_loop_label": "Immer wiederholen: ",
|
||||
"preferences_autoplay_label": "Automatisch abspielen: ",
|
||||
"preferences_continue_label": "Immer automatisch nächstes Video spielen: ",
|
||||
"preferences_continue_autoplay_label": "nächstes Video automatisch abspielen: ",
|
||||
"preferences_continue_label": "Immer automatisch nächstes Video abspielen: ",
|
||||
"preferences_continue_autoplay_label": "Nächstes Video automatisch abspielen: ",
|
||||
"preferences_listen_label": "Nur Ton als Standard: ",
|
||||
"preferences_local_label": "Proxy-Videos: ",
|
||||
"preferences_local_label": "Videos durch Proxy leiten: ",
|
||||
"preferences_speed_label": "Standardgeschwindigkeit: ",
|
||||
"preferences_quality_label": "Bevorzugte Videoqualität: ",
|
||||
"preferences_volume_label": "Wiedergabelautstärke: ",
|
||||
@@ -63,12 +63,12 @@
|
||||
"reddit": "Reddit",
|
||||
"preferences_captions_label": "Standarduntertitel: ",
|
||||
"Fallback captions: ": "Ersatzuntertitel: ",
|
||||
"preferences_related_videos_label": "Ähnliche Videos anzeigen? ",
|
||||
"preferences_annotations_label": "Standardmäßig Anmerkungen anzeigen? ",
|
||||
"preferences_related_videos_label": "Ähnliche Videos anzeigen: ",
|
||||
"preferences_annotations_label": "Anmerkungen standardmäßig anzeigen: ",
|
||||
"preferences_extend_desc_label": "Videobeschreibung automatisch erweitern: ",
|
||||
"preferences_vr_mode_label": "Interaktive 360 Grad Videos: ",
|
||||
"preferences_vr_mode_label": "Interaktive 360-Grad-Videos (erfordert WebGL): ",
|
||||
"preferences_category_visual": "Anzeigeeinstellungen",
|
||||
"preferences_player_style_label": "Abspielgeräterstil: ",
|
||||
"preferences_player_style_label": "Player-Stil: ",
|
||||
"Dark mode: ": "Nachtmodus: ",
|
||||
"preferences_dark_mode_label": "Modus: ",
|
||||
"dark": "Nachtmodus",
|
||||
@@ -121,7 +121,7 @@
|
||||
"Subscriptions": "Abonnements",
|
||||
"search": "Suchen",
|
||||
"Log out": "Abmelden",
|
||||
"Released under the AGPLv3 on Github.": "Auf Github unter der AGPLv3 Lizenz veröffentlicht.",
|
||||
"Released under the AGPLv3 on Github.": "Auf GitHub unter der AGPLv3 Lizenz veröffentlicht.",
|
||||
"Source available here.": "Quellcode verfügbar hier.",
|
||||
"View JavaScript license information.": "Javascript Lizenzinformationen anzeigen.",
|
||||
"View privacy policy.": "Datenschutzerklärung einsehen.",
|
||||
@@ -141,7 +141,6 @@
|
||||
"Show less": "Weniger anzeigen",
|
||||
"Watch on YouTube": "Video auf YouTube ansehen",
|
||||
"Switch Invidious Instance": "Invidious Instanz wechseln",
|
||||
"Broken? Try another Invidious Instance": "Funktioniert nicht? Probiere eine andere Invidious Instanz aus",
|
||||
"Hide annotations": "Anmerkungen ausblenden",
|
||||
"Show annotations": "Anmerkungen anzeigen",
|
||||
"Genre: ": "Genre: ",
|
||||
@@ -329,47 +328,46 @@
|
||||
"Videos": "Videos",
|
||||
"Playlists": "Wiedergabelisten",
|
||||
"Community": "Gemeinschaft",
|
||||
"relevance": "Relevanz",
|
||||
"rating": "Bewertung",
|
||||
"date": "Datum",
|
||||
"views": "Aufrufe",
|
||||
"content_type": "Inhaltstyp",
|
||||
"duration": "Dauer",
|
||||
"features": "Eigenschaften",
|
||||
"sort": "sortieren",
|
||||
"hour": "Letzte Stunde",
|
||||
"today": "Heute",
|
||||
"week": "Diese Woche",
|
||||
"month": "Diesen Monat",
|
||||
"year": "Dieses Jahr",
|
||||
"video": "Video",
|
||||
"channel": "Kanal",
|
||||
"playlist": "Wiedergabeliste",
|
||||
"movie": "Film",
|
||||
"show": "Anzeigen",
|
||||
"hd": "HD",
|
||||
"subtitles": "Untertitel / CC",
|
||||
"creative_commons": "Creative Commons",
|
||||
"3d": "3D",
|
||||
"live": "Live",
|
||||
"4k": "4K",
|
||||
"location": "Standort",
|
||||
"hdr": "HDR",
|
||||
"filter": "Filtern",
|
||||
"search_filters_sort_option_relevance": "Relevanz",
|
||||
"search_filters_sort_option_rating": "Bewertung",
|
||||
"search_filters_sort_option_date": "Datum",
|
||||
"search_filters_sort_option_views": "Aufrufe",
|
||||
"search_filters_type_label": "Inhaltstyp",
|
||||
"search_filters_duration_label": "Dauer",
|
||||
"search_filters_features_label": "Eigenschaften",
|
||||
"search_filters_sort_label": "sortieren",
|
||||
"search_filters_date_option_hour": "Letzte Stunde",
|
||||
"search_filters_date_option_today": "Heute",
|
||||
"search_filters_date_option_week": "Diese Woche",
|
||||
"search_filters_date_option_month": "Diesen Monat",
|
||||
"search_filters_date_option_year": "Dieses Jahr",
|
||||
"search_filters_type_option_video": "Video",
|
||||
"search_filters_type_option_channel": "Kanal",
|
||||
"search_filters_type_option_playlist": "Wiedergabeliste",
|
||||
"search_filters_type_option_movie": "Film",
|
||||
"search_filters_type_option_show": "Anzeigen",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "Untertitel / CC",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_live": "Live",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_location": "Standort",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"Current version: ": "Aktuelle Version: ",
|
||||
"next_steps_error_message": "Danach folgendes versuchen: ",
|
||||
"next_steps_error_message_refresh": "Aktualisieren",
|
||||
"next_steps_error_message_go_to_youtube": "Zu YouTube gehen",
|
||||
"footer_donate_page": "Spende",
|
||||
"long": "Lang (> 20 Minuten)",
|
||||
"search_filters_duration_option_long": "Lang (> 20 Minuten)",
|
||||
"footer_original_source_code": "Original Quellcode",
|
||||
"footer_modfied_source_code": "Modifizierter Quellcode",
|
||||
"footer_documentation": "Dokumentation",
|
||||
"footer_source_code": "Quellcode",
|
||||
"adminprefs_modified_source_code_url_label": "URL zum Repositorie des modifizierten Quellcodes",
|
||||
"short": "Kurz (< 4 Minuten)",
|
||||
"search_filters_duration_option_short": "Kurz (< 4 Minuten)",
|
||||
"preferences_region_label": "Land der Inhalte: ",
|
||||
"preferences_quality_option_dash": "DASH (automatische Qualität)",
|
||||
"preferences_quality_option_dash": "DASH (adaptive Qualität)",
|
||||
"preferences_quality_option_hd720": "HD720",
|
||||
"preferences_quality_option_medium": "Mittel",
|
||||
"preferences_quality_option_small": "Niedrig",
|
||||
@@ -388,15 +386,90 @@
|
||||
"Video unavailable": "Video nicht verfügbar",
|
||||
"user_created_playlists": "`x` Wiedergabelisten erstellt",
|
||||
"user_saved_playlists": "`x` Wiedergabelisten gespeichert",
|
||||
"preferences_save_player_pos_label": "Aktuelle Position speichern: ",
|
||||
"360": "360°",
|
||||
"preferences_save_player_pos_label": "Wiedergabeposition speichern: ",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"preferences_quality_dash_option_best": "Höchste",
|
||||
"preferences_quality_dash_option_worst": "Niedrigste",
|
||||
"preferences_quality_dash_option_1440p": "1440p",
|
||||
"videoinfo_youTube_embed_link": "Eingebettet",
|
||||
"purchased": "Gekauft",
|
||||
"search_filters_features_option_purchased": "Gekauft",
|
||||
"none": "keine",
|
||||
"videoinfo_started_streaming_x_ago": "Stream begann vor `x`",
|
||||
"videoinfo_watch_on_youTube": "Auf YouTube ansehen",
|
||||
"preferences_quality_dash_label": "Bevorzugte DASH-Videoqualität: "
|
||||
"preferences_quality_dash_label": "Bevorzugte DASH-Videoqualität: ",
|
||||
"generic_subscribers_count": "{{count}} Abonnent",
|
||||
"generic_subscribers_count_plural": "{{count}} Abonnenten",
|
||||
"generic_videos_count": "{{count}} Video",
|
||||
"generic_videos_count_plural": "{{count}} Videos",
|
||||
"subscriptions_unseen_notifs_count": "{{count}} ungesehene Benachrichtung",
|
||||
"subscriptions_unseen_notifs_count_plural": "{{count}} ungesehene Benachrichtungen",
|
||||
"crash_page_refresh": "Versucht haben, <a href=\"`x`\">die Seite neu zu laden</a>",
|
||||
"comments_view_x_replies": "{{count}} Antwort anzeigen",
|
||||
"comments_view_x_replies_plural": "{{count}} Antworten anzeigen",
|
||||
"generic_count_years": "{{count}} Jahr",
|
||||
"generic_count_years_plural": "{{count}} Jahre",
|
||||
"generic_count_weeks": "{{count}} Woche",
|
||||
"generic_count_weeks_plural": "{{count}} Wochen",
|
||||
"generic_count_days": "{{count}} Tag",
|
||||
"generic_count_days_plural": "{{count}} Tage",
|
||||
"crash_page_before_reporting": "Bevor Sie einen Bug melden, stellen Sie sicher, dass Sie:",
|
||||
"crash_page_switch_instance": "Eine <a href=\"`x`\">andere Instanz</a> versucht haben",
|
||||
"generic_count_hours": "{{count}} Stunde",
|
||||
"generic_count_hours_plural": "{{count}} Stunden",
|
||||
"generic_count_minutes": "{{count}} Minute",
|
||||
"generic_count_minutes_plural": "{{count}} Minuten",
|
||||
"crash_page_read_the_faq": "Das <a href=\"`x`\">FAQ</a> gelesen haben",
|
||||
"crash_page_search_issue": "Nach <a href=\"`x`\">bereits gemeldeten Bugs auf GitHub</a> gesucht haben",
|
||||
"crash_page_report_issue": "Wenn all dies nicht geholfen hat, <a href=\"`x`\">öffnen Sie bitte ein neues Problem (issue) auf Github</a> (vorzugsweise auf Englisch) und fügen Sie den folgenden Text in Ihre Nachricht ein (bitte übersetzen Sie diesen Text NICHT):",
|
||||
"generic_views_count": "{{count}} Aufruf",
|
||||
"generic_views_count_plural": "{{count}} Aufrufe",
|
||||
"generic_count_seconds": "{{count}} Sekunde",
|
||||
"generic_count_seconds_plural": "{{count}} Sekunden",
|
||||
"generic_subscriptions_count": "{{count}} Abo",
|
||||
"generic_subscriptions_count_plural": "{{count}} Abos",
|
||||
"tokens_count": "{{count}} Token",
|
||||
"tokens_count_plural": "{{count}} Tokens",
|
||||
"comments_points_count": "{{count}} Punkt",
|
||||
"comments_points_count_plural": "{{count}} Punkte",
|
||||
"crash_page_you_found_a_bug": "Anscheinend haben Sie einen Fehler in Invidious gefunden!",
|
||||
"generic_count_months": "{{count}} Monat",
|
||||
"generic_count_months_plural": "{{count}} Monate",
|
||||
"Cantonese (Hong Kong)": "Kantonesisch (Hong Kong)",
|
||||
"Chinese (Hong Kong)": "Chinesisch (Hong Kong)",
|
||||
"generic_playlists_count": "{{count}} Wiedergabeliste",
|
||||
"generic_playlists_count_plural": "{{count}} Wiedergabelisten",
|
||||
"preferences_watch_history_label": "Wiedergabeverlauf aktivieren: ",
|
||||
"English (United Kingdom)": "Englisch (Vereinigtes Königreich)",
|
||||
"English (United States)": "Englisch (Vereinigte Staaten)",
|
||||
"Dutch (auto-generated)": "Niederländisch (automatisch generiert)",
|
||||
"French (auto-generated)": "Französisch (automatisch generiert)",
|
||||
"German (auto-generated)": "Deutsch (automatisch generiert)",
|
||||
"Indonesian (auto-generated)": "Indonesisch (automatisch generiert)",
|
||||
"Interlingue": "Interlingue",
|
||||
"Italian (auto-generated)": "Italienisch (automatisch generiert)",
|
||||
"Japanese (auto-generated)": "Japanisch (automatisch generiert)",
|
||||
"Spanish (Mexico)": "Spanisch (Mexiko)",
|
||||
"Spanish (Spain)": "Spanisch (Spanien)",
|
||||
"Vietnamese (auto-generated)": "Vietnamesisch (automatisch generiert)",
|
||||
"Russian (auto-generated)": "Russisch (automatisch generiert)",
|
||||
"Chinese": "Chinesisch",
|
||||
"Portuguese (Brazil)": "Portugiesisch (Brasilien)",
|
||||
"Spanish (auto-generated)": "Spanisch (automatisch generiert)",
|
||||
"Turkish (auto-generated)": "Türkisch (automatisch generiert)",
|
||||
"Chinese (China)": "Chinesisch (China)",
|
||||
"Chinese (Taiwan)": "Chinesisch (Taiwan)",
|
||||
"Korean (auto-generated)": "Koreanisch (automatisch generiert)",
|
||||
"Portuguese (auto-generated)": "Portugiesisch (automatisch generiert)",
|
||||
"search_filters_title": "Filtern",
|
||||
"search_message_change_filters_or_query": "Versuchen Sie, Ihre Suchanfrage zu erweitern und/oder die Filter zu ändern.",
|
||||
"search_message_use_another_instance": " Sie können auch <a href=\"`x`\">auf einer anderen Instanz suchen</a>.",
|
||||
"Popular enabled: ": "„Beliebt“-Seite aktiviert: ",
|
||||
"search_message_no_results": "Keine Ergebnisse gefunden.",
|
||||
"search_filters_duration_option_medium": "Mittel (4 - 20 Minuten)",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"search_filters_type_option_all": "Beliebiger Typ",
|
||||
"search_filters_apply_button": "Ausgewählte Filter anwenden",
|
||||
"search_filters_duration_option_none": "Beliebige Länge",
|
||||
"search_filters_date_label": "Upload-Datum",
|
||||
"search_filters_date_option_none": "Beliebiges Datum"
|
||||
}
|
||||
|
||||
@@ -358,7 +358,7 @@
|
||||
"crash_page_before_reporting": "Πριν αναφέρετε ένα σφάλμα, βεβαιωθείτε ότι έχετε:",
|
||||
"crash_page_refresh": "προσπαθήσει να <a href=\"`x`\">ανανεώσετε τη σελίδα</a>",
|
||||
"crash_page_read_the_faq": "διαβάσει τις <a href=\"`x`\">Συχνές Ερωτήσεις (ΣΕ)</a>",
|
||||
"crash_page_search_issue": "αναζητήσει για <a href=\"`x`\">υπάρχοντα θέματα στο Github</a>",
|
||||
"crash_page_search_issue": "αναζητήσει για <a href=\"`x`\">υπάρχοντα θέματα στο GitHub</a>",
|
||||
"generic_views_count": "{{count}} προβολή",
|
||||
"generic_views_count_plural": "{{count}} προβολές",
|
||||
"generic_videos_count": "{{count}} βίντεο",
|
||||
@@ -373,51 +373,50 @@
|
||||
"preferences_region_label": "Χώρα περιεχομένου: ",
|
||||
"preferences_category_misc": "Διάφορες προτιμήσεις",
|
||||
"Show more": "Εμφάνιση περισσότερων",
|
||||
"today": "Σήμερα",
|
||||
"360": "360°",
|
||||
"search_filters_date_option_today": "Σήμερα",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"videoinfo_started_streaming_x_ago": "Ξεκίνησε η ροή `x` πριν από",
|
||||
"videoinfo_watch_on_youTube": "Παρακολουθήστε στο YouTube",
|
||||
"download_subtitles": "Υπότιτλοι - `x` (.vtt)",
|
||||
"user_created_playlists": "`x` δημιουργημένες λίστες αναπαραγωγής",
|
||||
"user_saved_playlists": "`x` αποθηκευμένες λίστες αναπαραγωγής",
|
||||
"rating": "Αξιολόγηση",
|
||||
"relevance": "Συνάφεια",
|
||||
"purchased": "Αγορασμένο",
|
||||
"date": "Ημερομηνία μεταφόρτωσης",
|
||||
"content_type": "Τύπος",
|
||||
"duration": "Διάρκεια",
|
||||
"week": "Αυτή την εβδομάδα",
|
||||
"year": "Φέτος",
|
||||
"channel": "Κανάλι",
|
||||
"playlist": "Λίστα αναπαραγωγής",
|
||||
"long": "Μεγάλο (> 20 λεπτά)",
|
||||
"hd": "HD",
|
||||
"location": "Τοποθεσία",
|
||||
"3d": "3D",
|
||||
"search_filters_sort_option_rating": "Αξιολόγηση",
|
||||
"search_filters_sort_option_relevance": "Συνάφεια",
|
||||
"search_filters_features_option_purchased": "Αγορασμένο",
|
||||
"search_filters_sort_option_date": "Ημερομηνία μεταφόρτωσης",
|
||||
"search_filters_type_label": "Τύπος",
|
||||
"search_filters_duration_label": "Διάρκεια",
|
||||
"search_filters_date_option_week": "Αυτή την εβδομάδα",
|
||||
"search_filters_date_option_year": "Φέτος",
|
||||
"search_filters_type_option_channel": "Κανάλι",
|
||||
"search_filters_type_option_playlist": "Λίστα αναπαραγωγής",
|
||||
"search_filters_duration_option_long": "Μεγάλο (> 20 λεπτά)",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_location": "Τοποθεσία",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"next_steps_error_message": "Μετά από αυτό θα πρέπει να προσπαθήσετε να: ",
|
||||
"next_steps_error_message_go_to_youtube": "Μεταβείτε στο YouTube",
|
||||
"footer_donate_page": "Δωρεά",
|
||||
"footer_original_source_code": "Πρωτότυπος πηγαίος κώδικας",
|
||||
"preferences_show_nick_label": "Εμφάνιση ψευδώνυμου στην κορυφή: ",
|
||||
"hour": "Τελευταία ώρα",
|
||||
"search_filters_date_option_hour": "Τελευταία ώρα",
|
||||
"adminprefs_modified_source_code_url_label": "URL σε αποθετήριο τροποποιημένου πηγαίου κώδικα",
|
||||
"subtitles": "Υπότιτλοι/CC",
|
||||
"month": "Αυτόν τον μήνα",
|
||||
"Released under the AGPLv3 on Github.": "Κυκλοφορεί υπό την AGPLv3 στο Github.",
|
||||
"sort": "Ταξινόμηση κατά",
|
||||
"filter": "Φίλτρο",
|
||||
"movie": "Ταινία",
|
||||
"search_filters_features_option_subtitles": "Υπότιτλοι/CC",
|
||||
"search_filters_date_option_month": "Αυτόν τον μήνα",
|
||||
"Released under the AGPLv3 on Github.": "Κυκλοφορεί υπό την AGPLv3 στο GitHub.",
|
||||
"search_filters_sort_label": "Ταξινόμηση κατά",
|
||||
"search_filters_type_option_movie": "Ταινία",
|
||||
"footer_modfied_source_code": "Τροποποιημένος πηγαίος κώδικας",
|
||||
"features": "Χαρακτηριστικά",
|
||||
"4k": "4K",
|
||||
"search_filters_features_label": "Χαρακτηριστικά",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"footer_documentation": "Τεκμηρίωση",
|
||||
"short": "Σύντομο (< 4 λεπτά)",
|
||||
"search_filters_duration_option_short": "Σύντομο (< 4 λεπτά)",
|
||||
"next_steps_error_message_refresh": "Ανανέωση",
|
||||
"video": "Βίντεο",
|
||||
"live": "Ζωντανά",
|
||||
"creative_commons": "Creative Commons",
|
||||
"search_filters_type_option_video": "Βίντεο",
|
||||
"search_filters_features_option_live": "Ζωντανά",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"Search": "Αναζήτηση",
|
||||
"hdr": "HDR",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"preferences_extend_desc_label": "Αυτόματη επέκταση της περιγραφής του βίντεο: ",
|
||||
"preferences_vr_mode_label": "Διαδραστικά βίντεο 360 μοιρών (απαιτεί WebGL): ",
|
||||
"Show less": "Εμφάνιση λιγότερων",
|
||||
@@ -448,5 +447,8 @@
|
||||
"none": "κανένα",
|
||||
"videoinfo_youTube_embed_link": "Ενσωμάτωση",
|
||||
"videoinfo_invidious_embed_link": "Σύνδεσμος Ενσωμάτωσης",
|
||||
"show": "Μπάρα προόδου διαβάσματος"
|
||||
"search_filters_type_option_show": "Μπάρα προόδου διαβάσματος",
|
||||
"preferences_watch_history_label": "Ενεργοποίηση ιστορικού παρακολούθησης: ",
|
||||
"search_filters_title": "Φίλτρο",
|
||||
"search_message_no_results": "Δεν"
|
||||
}
|
||||
|
||||
@@ -66,10 +66,9 @@
|
||||
"preferences_listen_label": "Listen by default: ",
|
||||
"preferences_local_label": "Proxy videos: ",
|
||||
"preferences_watch_history_label": "Enable watch history: ",
|
||||
"preferences_notifications_label": "Enable notifications: ",
|
||||
"preferences_speed_label": "Default speed: ",
|
||||
"preferences_quality_label": "Preferred video quality: ",
|
||||
"preferences_quality_option_dash": "DASH (adaptative quality)",
|
||||
"preferences_quality_option_dash": "DASH (adaptive quality)",
|
||||
"preferences_quality_option_hd720": "HD720",
|
||||
"preferences_quality_option_medium": "Medium",
|
||||
"preferences_quality_option_small": "Small",
|
||||
@@ -137,6 +136,7 @@
|
||||
"preferences_default_home_label": "Default homepage: ",
|
||||
"preferences_feed_menu_label": "Feed menu: ",
|
||||
"preferences_show_nick_label": "Show nickname on top: ",
|
||||
"Popular enabled: ": "Popular enabled: ",
|
||||
"Top enabled: ": "Top enabled: ",
|
||||
"CAPTCHA enabled: ": "CAPTCHA enabled: ",
|
||||
"Login enabled: ": "Login enabled: ",
|
||||
@@ -156,7 +156,7 @@
|
||||
"subscriptions_unseen_notifs_count_plural": "{{count}} unseen notifications",
|
||||
"search": "search",
|
||||
"Log out": "Log out",
|
||||
"Released under the AGPLv3 on Github.": "Released under the AGPLv3 on Github.",
|
||||
"Released under the AGPLv3 on Github.": "Released under the AGPLv3 on GitHub.",
|
||||
"Source available here.": "Source available here.",
|
||||
"View JavaScript license information.": "View JavaScript license information.",
|
||||
"View privacy policy.": "View privacy policy.",
|
||||
@@ -176,7 +176,9 @@
|
||||
"Show less": "Show less",
|
||||
"Watch on YouTube": "Watch on YouTube",
|
||||
"Switch Invidious Instance": "Switch Invidious Instance",
|
||||
"Broken? Try another Invidious Instance": "Broken? Try another Invidious Instance",
|
||||
"search_message_no_results": "No results found.",
|
||||
"search_message_change_filters_or_query": "Try widening your search query and/or changing the filters.",
|
||||
"search_message_use_another_instance": " You can also <a href=\"`x`\">search on another instance</a>.",
|
||||
"Hide annotations": "Hide annotations",
|
||||
"Show annotations": "Show annotations",
|
||||
"Genre: ": "Genre: ",
|
||||
@@ -405,37 +407,44 @@
|
||||
"Videos": "Videos",
|
||||
"Playlists": "Playlists",
|
||||
"Community": "Community",
|
||||
"relevance": "Relevance",
|
||||
"rating": "Rating",
|
||||
"date": "Upload date",
|
||||
"views": "View count",
|
||||
"content_type": "Type",
|
||||
"duration": "Duration",
|
||||
"features": "Features",
|
||||
"sort": "Sort By",
|
||||
"hour": "Last Hour",
|
||||
"today": "Today",
|
||||
"week": "This week",
|
||||
"month": "This month",
|
||||
"year": "This year",
|
||||
"video": "Video",
|
||||
"channel": "Channel",
|
||||
"playlist": "Playlist",
|
||||
"movie": "Movie",
|
||||
"show": "Show",
|
||||
"short": "Short (< 4 minutes)",
|
||||
"long": "Long (> 20 minutes)",
|
||||
"hd": "HD",
|
||||
"subtitles": "Subtitles/CC",
|
||||
"creative_commons": "Creative Commons",
|
||||
"3d": "3D",
|
||||
"live": "Live",
|
||||
"4k": "4K",
|
||||
"location": "Location",
|
||||
"hdr": "HDR",
|
||||
"purchased": "Purchased",
|
||||
"360": "360°",
|
||||
"filter": "Filter",
|
||||
"search_filters_title": "Filters",
|
||||
"search_filters_date_label": "Upload date",
|
||||
"search_filters_date_option_none": "Any date",
|
||||
"search_filters_date_option_hour": "Last Hour",
|
||||
"search_filters_date_option_today": "Today",
|
||||
"search_filters_date_option_week": "This week",
|
||||
"search_filters_date_option_month": "This month",
|
||||
"search_filters_date_option_year": "This year",
|
||||
"search_filters_type_label": "Type",
|
||||
"search_filters_type_option_all": "Any type",
|
||||
"search_filters_type_option_video": "Video",
|
||||
"search_filters_type_option_channel": "Channel",
|
||||
"search_filters_type_option_playlist": "Playlist",
|
||||
"search_filters_type_option_movie": "Movie",
|
||||
"search_filters_type_option_show": "Show",
|
||||
"search_filters_duration_label": "Duration",
|
||||
"search_filters_duration_option_none": "Any duration",
|
||||
"search_filters_duration_option_short": "Short (< 4 minutes)",
|
||||
"search_filters_duration_option_medium": "Medium (4 - 20 minutes)",
|
||||
"search_filters_duration_option_long": "Long (> 20 minutes)",
|
||||
"search_filters_features_label": "Features",
|
||||
"search_filters_features_option_live": "Live",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "Subtitles/CC",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"search_filters_features_option_location": "Location",
|
||||
"search_filters_features_option_purchased": "Purchased",
|
||||
"search_filters_sort_label": "Sort By",
|
||||
"search_filters_sort_option_relevance": "Relevance",
|
||||
"search_filters_sort_option_rating": "Rating",
|
||||
"search_filters_sort_option_date": "Upload Date",
|
||||
"search_filters_sort_option_views": "View count",
|
||||
"search_filters_apply_button": "Apply selected filters",
|
||||
"Current version: ": "Current version: ",
|
||||
"next_steps_error_message": "After which you should try to: ",
|
||||
"next_steps_error_message_refresh": "Refresh",
|
||||
@@ -460,7 +469,7 @@
|
||||
"crash_page_before_reporting": "Before reporting a bug, make sure that you have:",
|
||||
"crash_page_refresh": "tried to <a href=\"`x`\">refresh the page</a>",
|
||||
"crash_page_switch_instance": "tried to <a href=\"`x`\">use another instance</a>",
|
||||
"crash_page_read_the_faq": "read the <a href=\"`x`\">Frenquently Asked Questions (FAQ)</a>",
|
||||
"crash_page_search_issue": "searched for <a href=\"`x`\">existing issues on Github</a>",
|
||||
"crash_page_read_the_faq": "read the <a href=\"`x`\">Frequently Asked Questions (FAQ)</a>",
|
||||
"crash_page_search_issue": "searched for <a href=\"`x`\">existing issues on GitHub</a>",
|
||||
"crash_page_report_issue": "If none of the above helped, please <a href=\"`x`\">open a new issue on GitHub</a> (preferably in English) and include the following text in your message (do NOT translate that text):"
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
"Subscriptions": "Abonoj",
|
||||
"search": "serĉi",
|
||||
"Log out": "Elsaluti",
|
||||
"Released under the AGPLv3 on Github.": "Eldonita sub la AGPLv3 en Github.",
|
||||
"Released under the AGPLv3 on Github.": "Eldonita sub la AGPLv3 en GitHub.",
|
||||
"Source available here.": "Fonto havebla ĉi tie.",
|
||||
"View JavaScript license information.": "Vidi Ĝavoskriptan licencan informon.",
|
||||
"View privacy policy.": "Vidi regularon pri privateco.",
|
||||
@@ -141,7 +141,6 @@
|
||||
"Show less": "Montri malpli",
|
||||
"Watch on YouTube": "Vidi filmeton en JuTubo",
|
||||
"Switch Invidious Instance": "Ŝanĝi instalaĵon de Indivious",
|
||||
"Broken? Try another Invidious Instance": "Ĉu misfunkcio? Provu alian instalaĵon de Indivious",
|
||||
"Hide annotations": "Kaŝi prinotojn",
|
||||
"Show annotations": "Montri prinotojn",
|
||||
"Genre: ": "Ĝenro: ",
|
||||
@@ -329,39 +328,38 @@
|
||||
"Videos": "Filmetoj",
|
||||
"Playlists": "Ludlistoj",
|
||||
"Community": "Komunumo",
|
||||
"relevance": "rilateco",
|
||||
"rating": "takso",
|
||||
"date": "dato",
|
||||
"views": "vidoj",
|
||||
"content_type": "enhavtipo",
|
||||
"duration": "daŭro",
|
||||
"features": "trajtoj",
|
||||
"sort": "ordigi",
|
||||
"hour": "horo",
|
||||
"today": "hodiaŭ",
|
||||
"week": "semajno",
|
||||
"month": "monato",
|
||||
"year": "jaro",
|
||||
"video": "filmeto",
|
||||
"channel": "kanalo",
|
||||
"playlist": "ludlisto",
|
||||
"movie": "filmo",
|
||||
"show": "spektaĵo",
|
||||
"hd": "altdistingiva",
|
||||
"subtitles": "subtekstoj",
|
||||
"creative_commons": "Krea Komunaĵo",
|
||||
"3d": "3D",
|
||||
"live": "nuna",
|
||||
"4k": "4k",
|
||||
"location": "loko",
|
||||
"hdr": "granddinamikgama",
|
||||
"filter": "filtri",
|
||||
"search_filters_sort_option_relevance": "rilateco",
|
||||
"search_filters_sort_option_rating": "takso",
|
||||
"search_filters_sort_option_date": "dato",
|
||||
"search_filters_sort_option_views": "vidoj",
|
||||
"search_filters_type_label": "enhavtipo",
|
||||
"search_filters_duration_label": "daŭro",
|
||||
"search_filters_features_label": "trajtoj",
|
||||
"search_filters_sort_label": "ordigi",
|
||||
"search_filters_date_option_hour": "horo",
|
||||
"search_filters_date_option_today": "hodiaŭ",
|
||||
"search_filters_date_option_week": "semajno",
|
||||
"search_filters_date_option_month": "monato",
|
||||
"search_filters_date_option_year": "jaro",
|
||||
"search_filters_type_option_video": "filmeto",
|
||||
"search_filters_type_option_channel": "kanalo",
|
||||
"search_filters_type_option_playlist": "ludlisto",
|
||||
"search_filters_type_option_movie": "filmo",
|
||||
"search_filters_type_option_show": "spektaĵo",
|
||||
"search_filters_features_option_hd": "altdistingiva",
|
||||
"search_filters_features_option_subtitles": "subtekstoj",
|
||||
"search_filters_features_option_c_commons": "Krea Komunaĵo",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_live": "nuna",
|
||||
"search_filters_features_option_four_k": "4k",
|
||||
"search_filters_features_option_location": "loko",
|
||||
"search_filters_features_option_hdr": "granddinamikgama",
|
||||
"Current version: ": "Nuna versio: ",
|
||||
"next_steps_error_message": "Poste, vi provu: ",
|
||||
"next_steps_error_message_refresh": "Reŝargi",
|
||||
"next_steps_error_message_go_to_youtube": "Iri al JuTubo",
|
||||
"long": "Longa (> 20 minutos)",
|
||||
"short": "Mallonga (< 4 minutos)",
|
||||
"search_filters_duration_option_long": "Longa (> 20 minutos)",
|
||||
"search_filters_duration_option_short": "Mallonga (< 4 minutos)",
|
||||
"footer_documentation": "Dokumentaro",
|
||||
"footer_source_code": "Fontkodo",
|
||||
"adminprefs_modified_source_code_url_label": "URL al modifita deponejo de fontkodo",
|
||||
@@ -369,5 +367,6 @@
|
||||
"footer_original_source_code": "Originala fontkodo",
|
||||
"footer_donate_page": "Donaci",
|
||||
"preferences_region_label": "Lando de la enhavo: ",
|
||||
"preferences_quality_dash_label": "Preferata DASH-a videkvalito: "
|
||||
"preferences_quality_dash_label": "Preferata DASH-a videkvalito: ",
|
||||
"search_filters_title": "Filtri"
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
"Subscriptions": "Suscripciones",
|
||||
"search": "buscar",
|
||||
"Log out": "Cerrar la sesión",
|
||||
"Released under the AGPLv3 on Github.": "Publicado bajo la AGPLv3 en Github.",
|
||||
"Released under the AGPLv3 on Github.": "Publicado bajo la AGPLv3 en GitHub.",
|
||||
"Source available here.": "Código fuente disponible aquí.",
|
||||
"View JavaScript license information.": "Ver información de licencia de JavaScript.",
|
||||
"View privacy policy.": "Ver la política de privacidad.",
|
||||
@@ -141,7 +141,6 @@
|
||||
"Show less": "Mostrar menos",
|
||||
"Watch on YouTube": "Ver el vídeo en YouTube",
|
||||
"Switch Invidious Instance": "Cambiar Instancia de Invidious",
|
||||
"Broken? Try another Invidious Instance": "¿Algún error? Prueba otra instancia de Invidious",
|
||||
"Hide annotations": "Ocultar anotaciones",
|
||||
"Show annotations": "Mostrar anotaciones",
|
||||
"Genre: ": "Género: ",
|
||||
@@ -196,7 +195,7 @@
|
||||
"Hidden field \"token\" is a required field": "El campo oculto «símbolo» es un campo obligatorio",
|
||||
"Erroneous challenge": "Desafío no válido",
|
||||
"Erroneous token": "Símbolo no válido",
|
||||
"No such user": "Usuario no válido",
|
||||
"No such user": "Usuario no existe",
|
||||
"Token is expired, please try again": "El símbolo ha caducado, inténtelo de nuevo",
|
||||
"English": "Inglés",
|
||||
"English (auto-generated)": "Inglés (generados automáticamente)",
|
||||
@@ -329,39 +328,38 @@
|
||||
"Videos": "Vídeos",
|
||||
"Playlists": "Listas de reproducción",
|
||||
"Community": "Comunidad",
|
||||
"relevance": "relevancia",
|
||||
"rating": "valoración",
|
||||
"date": "fecha",
|
||||
"views": "visualizaciones",
|
||||
"content_type": "content_type",
|
||||
"duration": "duración",
|
||||
"features": "funcionalidades",
|
||||
"sort": "ordenar",
|
||||
"hour": "hora",
|
||||
"today": "hoy",
|
||||
"week": "semana",
|
||||
"month": "mes",
|
||||
"year": "año",
|
||||
"video": "vídeo",
|
||||
"channel": "canal",
|
||||
"playlist": "lista de reproducción",
|
||||
"movie": "película",
|
||||
"show": "programa",
|
||||
"hd": "hd",
|
||||
"subtitles": "subtítulos",
|
||||
"creative_commons": "creative_commons",
|
||||
"3d": "3d",
|
||||
"live": "directo",
|
||||
"4k": "4k",
|
||||
"location": "ubicación",
|
||||
"hdr": "hdr",
|
||||
"filter": "filtro",
|
||||
"search_filters_sort_option_relevance": "relevancia",
|
||||
"search_filters_sort_option_rating": "valoración",
|
||||
"search_filters_sort_option_date": "fecha",
|
||||
"search_filters_sort_option_views": "visualizaciones",
|
||||
"search_filters_type_label": "content_type",
|
||||
"search_filters_duration_label": "duración",
|
||||
"search_filters_features_label": "funcionalidades",
|
||||
"search_filters_sort_label": "ordenar",
|
||||
"search_filters_date_option_hour": "hora",
|
||||
"search_filters_date_option_today": "hoy",
|
||||
"search_filters_date_option_week": "semana",
|
||||
"search_filters_date_option_month": "mes",
|
||||
"search_filters_date_option_year": "año",
|
||||
"search_filters_type_option_video": "vídeo",
|
||||
"search_filters_type_option_channel": "canal",
|
||||
"search_filters_type_option_playlist": "lista de reproducción",
|
||||
"search_filters_type_option_movie": "película",
|
||||
"search_filters_type_option_show": "programa",
|
||||
"search_filters_features_option_hd": "hd",
|
||||
"search_filters_features_option_subtitles": "subtítulos",
|
||||
"search_filters_features_option_c_commons": "creative_commons",
|
||||
"search_filters_features_option_three_d": "3d",
|
||||
"search_filters_features_option_live": "directo",
|
||||
"search_filters_features_option_four_k": "4k",
|
||||
"search_filters_features_option_location": "ubicación",
|
||||
"search_filters_features_option_hdr": "hdr",
|
||||
"Current version: ": "Versión actual: ",
|
||||
"next_steps_error_message": "Después de lo cual deberías intentar: ",
|
||||
"next_steps_error_message_refresh": "Recargar",
|
||||
"next_steps_error_message_refresh": "Recargar la página",
|
||||
"next_steps_error_message_go_to_youtube": "Ir a YouTube",
|
||||
"short": "Corto (< 4 minutos)",
|
||||
"long": "Largo (> 20 minutos)",
|
||||
"search_filters_duration_option_short": "Corto (< 4 minutos)",
|
||||
"search_filters_duration_option_long": "Largo (> 20 minutos)",
|
||||
"footer_documentation": "Documentación",
|
||||
"footer_original_source_code": "Código fuente original",
|
||||
"adminprefs_modified_source_code_url_label": "URL al repositorio de código fuente modificado",
|
||||
@@ -395,8 +393,8 @@
|
||||
"preferences_quality_dash_option_worst": "La peor",
|
||||
"videoinfo_invidious_embed_link": "Enlace para Insertar",
|
||||
"preferences_quality_dash_option_1080p": "1080p",
|
||||
"purchased": "Comprado",
|
||||
"360": "360°",
|
||||
"search_filters_features_option_purchased": "Comprado",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"videoinfo_watch_on_youTube": "Ver en YouTube",
|
||||
"preferences_save_player_pos_label": "Guardar posición de reproducción: ",
|
||||
"generic_views_count": "{{count}} visualización",
|
||||
@@ -432,7 +430,7 @@
|
||||
"crash_page_before_reporting": "Antes de notificar un error asegúrate de que has:",
|
||||
"crash_page_switch_instance": "probado a <a href=\"`x`\">usar otra instancia</a>",
|
||||
"crash_page_read_the_faq": "leído las <a href=\"`x`\">Preguntas Frecuentes</a>",
|
||||
"crash_page_search_issue": "buscado <a href=\"`x`\">problemas existentes en Github</a>",
|
||||
"crash_page_search_issue": "buscado <a href=\"`x`\">problemas existentes en GitHub</a>",
|
||||
"crash_page_you_found_a_bug": "¡Parece que has encontrado un error en Invidious!",
|
||||
"crash_page_refresh": "probado a <a href=\"`x`\">recargar la página</a>",
|
||||
"crash_page_report_issue": "Si nada de lo anterior ha sido de ayuda, por favor, <a href=\"`x`\">abre una nueva incidencia en GitHub</a> (preferiblemente en inglés) e incluye el siguiente texto en tu mensaje (NO traduzcas este texto):",
|
||||
@@ -459,5 +457,18 @@
|
||||
"Korean (auto-generated)": "Coreano (generados automáticamente)",
|
||||
"Spanish (Mexico)": "Español (Méjico)",
|
||||
"Spanish (auto-generated)": "Español (generados automáticamente)",
|
||||
"preferences_watch_history_label": "Habilitar historial de reproducciones: "
|
||||
"preferences_watch_history_label": "Habilitar historial de reproducciones: ",
|
||||
"search_message_no_results": "No se han encontrado resultados.",
|
||||
"search_message_change_filters_or_query": "Pruebe ampliar la consulta de búsqueda y/o a cambiar los filtros.",
|
||||
"search_filters_title": "Filtros",
|
||||
"search_filters_date_label": "Fecha de subida",
|
||||
"search_filters_date_option_none": "Cualquier fecha",
|
||||
"search_filters_type_option_all": "Cualquier tipo",
|
||||
"search_filters_duration_option_none": "Cualquier duración",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"search_filters_apply_button": "Aplicar filtros seleccionados",
|
||||
"tokens_count": "{{count}} token",
|
||||
"tokens_count_plural": "{{count}} tokens",
|
||||
"search_message_use_another_instance": " También puede <a href=\"`x`\">buscar en otra instancia</a>.",
|
||||
"search_filters_duration_option_medium": "Medio (4 - 20 minutes)"
|
||||
}
|
||||
|
||||
338
locales/et.json
Normal file
338
locales/et.json
Normal file
@@ -0,0 +1,338 @@
|
||||
{
|
||||
"generic_playlists_count": "{{count}} esitusloend",
|
||||
"generic_playlists_count_plural": "{{count}} esindusloendit",
|
||||
"LIVE": "OTSEÜLEKANNE",
|
||||
"View channel on YouTube": "Vaata kanalit YouTube'is",
|
||||
"Log in": "Logi sisse",
|
||||
"Log in/register": "Logi sisse/registreeru",
|
||||
"Dark mode: ": "Tume režiim: ",
|
||||
"generic_videos_count": "{{count}} video",
|
||||
"generic_videos_count_plural": "{{count}} videot",
|
||||
"generic_subscribers_count": "{{count}} tellija",
|
||||
"generic_subscribers_count_plural": "{{count}} tellijat",
|
||||
"generic_subscriptions_count": "{{count}} tellimus",
|
||||
"generic_subscriptions_count_plural": "{{count}} tellimust",
|
||||
"Shared `x` ago": "Jagatud `x` tagasi",
|
||||
"Unsubscribe": "Loobu tellimusest",
|
||||
"Subscribe": "Telli",
|
||||
"View playlist on YouTube": "Vaata esitusloendit YouTube'is",
|
||||
"newest": "uusimad",
|
||||
"oldest": "vanimad",
|
||||
"popular": "populaarsed",
|
||||
"last": "viimane",
|
||||
"Next page": "Järgmine leht",
|
||||
"Previous page": "Eelmine leht",
|
||||
"Clear watch history?": "Kustuta vaatamiste ajalugu?",
|
||||
"New password": "Uus salasõna",
|
||||
"New passwords must match": "Uued salasõnad peavad ühtima",
|
||||
"Cannot change password for Google accounts": "Google'i kasutaja salasõna ei saa muuta",
|
||||
"Import and Export Data": "Impordi ja ekspordi andmed",
|
||||
"Import": "Impordi",
|
||||
"Import YouTube subscriptions": "Impordi tellimused Youtube'ist/OPML-ist",
|
||||
"Import FreeTube subscriptions (.db)": "Impordi tellimused FreeTube'ist (.db)",
|
||||
"Import NewPipe data (.zip)": "Impordi NewPipe'i andmed (.zip)",
|
||||
"Export": "Ekspordi",
|
||||
"Export subscriptions as OPML": "Ekspordi tellimused OPML-ina",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Ekspordi tellimused OPML-ina (NewPipe'i ja FreeTube'i jaoks)",
|
||||
"Delete account?": "Kustuta kasutaja?",
|
||||
"History": "Ajalugu",
|
||||
"JavaScript license information": "JavaScripti litsentsi info",
|
||||
"source": "allikas",
|
||||
"Log in with Google": "Logi sisse Google'iga",
|
||||
"User ID": "Kasutada ID",
|
||||
"Password": "Salasõna",
|
||||
"Time (h:mm:ss):": "Aeg (h:mm:ss):",
|
||||
"Text CAPTCHA": "CAPTCHA-tekst",
|
||||
"Image CAPTCHA": "CAPTCHA-foto",
|
||||
"Sign In": "Logi sisse",
|
||||
"Register": "Registreeru",
|
||||
"E-mail": "E-post",
|
||||
"Preferences": "Eelistused",
|
||||
"preferences_category_player": "Mängija eelistused",
|
||||
"preferences_continue_autoplay_label": "Mängi järgmine video automaatselt: ",
|
||||
"preferences_quality_label": "Eelistatud videokvaliteet: ",
|
||||
"preferences_quality_option_dash": "DASH (kohanduv kvaliteet)",
|
||||
"preferences_quality_option_hd720": "HD720",
|
||||
"preferences_quality_option_medium": "Keskmine",
|
||||
"preferences_quality_option_small": "Väike",
|
||||
"preferences_quality_dash_label": "Eelistatav DASH-video kvaliteet: ",
|
||||
"preferences_quality_dash_option_auto": "Automaatne",
|
||||
"preferences_quality_dash_option_best": "Parim",
|
||||
"preferences_quality_dash_option_worst": "Halvim",
|
||||
"preferences_volume_label": "Video helitugevus: ",
|
||||
"youtube": "YouTube",
|
||||
"reddit": "Reddit",
|
||||
"preferences_related_videos_label": "Näita sarnaseid videosid: ",
|
||||
"preferences_vr_mode_label": "Interaktiivne 360-kraadine video (vajalik WebGL): ",
|
||||
"preferences_dark_mode_label": "Teema: ",
|
||||
"dark": "tume",
|
||||
"light": "hele",
|
||||
"preferences_category_subscription": "Tellimuse seaded",
|
||||
"preferences_max_results_label": "Avalehel näidatavate videote arv: ",
|
||||
"preferences_sort_label": "Sorteeri: ",
|
||||
"published": "avaldatud",
|
||||
"alphabetically": "tähestikulises järjekorras",
|
||||
"alphabetically - reverse": "vastupidi tähestikulises järjekorras",
|
||||
"channel name": "kanali nimi",
|
||||
"preferences_unseen_only_label": "Näita ainult vaatamata videosid: ",
|
||||
"Only show latest video from channel: ": "Näita ainult viimast videot: ",
|
||||
"preferences_notifications_only_label": "Näita ainult teavitusi (kui neid on): ",
|
||||
"Enable web notifications": "Luba veebiteavitused",
|
||||
"`x` uploaded a video": "`x` laadis video üles",
|
||||
"`x` is live": "`x` teeb otseülekannet",
|
||||
"preferences_category_data": "Andme-eelistused",
|
||||
"Clear watch history": "Puhasta vaatamisajalugu",
|
||||
"Import/export data": "Impordi/ekspordi andmed",
|
||||
"Change password": "Muuda salasõna",
|
||||
"Watch history": "Vaatamisajalugu",
|
||||
"Delete account": "Kustuta kasutaja",
|
||||
"Save preferences": "Salvesta eelistused",
|
||||
"Token": "Token",
|
||||
"Import/export": "Imprort/eksport",
|
||||
"unsubscribe": "loobu tellimusest",
|
||||
"Subscriptions": "Tellimused",
|
||||
"search": "otsi",
|
||||
"Source available here.": "Allikas on kättesaadaval siin.",
|
||||
"View privacy policy.": "Vaata privaatsuspoliitikat.",
|
||||
"Public": "Avalik",
|
||||
"Private": "Privaatne",
|
||||
"View all playlists": "Vaata kõiki esitusloendeid",
|
||||
"Updated `x` ago": "Uuendas `x` tagasi",
|
||||
"Delete playlist `x`?": "Kustuta esitusloend `x`?",
|
||||
"Delete playlist": "Kustuta esitusloend",
|
||||
"Create playlist": "Loo esitlusloend",
|
||||
"Title": "Pealkiri",
|
||||
"Playlist privacy": "Esitusloendi privaatsus",
|
||||
"Show more": "Näita rohkem",
|
||||
"Show less": "Näita vähem",
|
||||
"Watch on YouTube": "Vaata YouTube'is",
|
||||
"search_message_no_results": "Tulemusi ei leitud.",
|
||||
"search_message_change_filters_or_query": "Proovi otsingut laiendada või filtreid muuta.",
|
||||
"Genre: ": "Žanr: ",
|
||||
"License: ": "Litsents: ",
|
||||
"Family friendly? ": "Peresõbralik? ",
|
||||
"Shared `x`": "Jagas `x`",
|
||||
"Premieres in `x`": "Esilinastub `x`",
|
||||
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Tundub, et oled JavaScripti välja lülitanud. Vajuta siia, et kommentaare vaadata; nende laadimine võib võtta natukene rohkem aega.",
|
||||
"View Reddit comments": "Vaata Redditi kommentaare",
|
||||
"Hide replies": "Peida vastused",
|
||||
"Show replies": "Näita vastuseid",
|
||||
"Incorrect password": "Vale salasõna",
|
||||
"Login failed. This may be because two-factor authentication is not turned on for your account.": "Sisselogimine ei õnnestunud. Asi võib olla selles, et",
|
||||
"Wrong answer": "Vale vastus",
|
||||
"User ID is a required field": "Kasutaja ID on kohustuslik väli",
|
||||
"Password is a required field": "Salasõna on kohustuslik väli",
|
||||
"Wrong username or password": "Vale kasutajanimi või salasõna",
|
||||
"Please sign in using 'Log in with Google'": "Palun kasutage 'Logi sisse Google'iga'",
|
||||
"Password cannot be longer than 55 characters": "Salasõna ei tohi olla pikem kui 55 tähemärki",
|
||||
"Password cannot be empty": "Salasõna ei tohi olla tühi",
|
||||
"Please log in": "Palun logige sisse",
|
||||
"channel:`x`": "kanal:`x`",
|
||||
"Deleted or invalid channel": "Kanal on kustutatud või seda ei leitud",
|
||||
"This channel does not exist.": "Sellist kanalit pole olemas.",
|
||||
"comments_view_x_replies": "{{count}} vastus",
|
||||
"comments_view_x_replies_plural": "{{count}} vastust",
|
||||
"`x` ago": "`x` tagasi",
|
||||
"Load more": "Laadi rohkem",
|
||||
"Empty playlist": "Tühi esitusloend",
|
||||
"Not a playlist.": "Tegu pole esitusloendiga.",
|
||||
"Playlist does not exist.": "Seda esitusloendit pole olemas.",
|
||||
"No such user": "Sellist kasutajat pole",
|
||||
"English": "Inglise",
|
||||
"English (United Kingdom)": "Inglise (Suurbritannia)",
|
||||
"English (United States)": "Inglise (USA)",
|
||||
"English (auto-generated)": "Inglise (automaatselt koostatud)",
|
||||
"Afrikaans": "Afrikaani",
|
||||
"Albanian": "Albaania",
|
||||
"Arabic": "Araabia",
|
||||
"Armenian": "Armeenia",
|
||||
"Bangla": "Bengali",
|
||||
"Basque": "Baski",
|
||||
"Belarusian": "Valgevene",
|
||||
"Bulgarian": "Bulgaaria",
|
||||
"Burmese": "Birma",
|
||||
"Cantonese (Hong Kong)": "Kantoni (Hong Konk)",
|
||||
"Chinese (China)": "Hiina (Hiina)",
|
||||
"Chinese (Hong Kong)": "Hiina (Hong Kong)",
|
||||
"Chinese (Simplified)": "Hiina (lihtsustatud)",
|
||||
"Chinese (Taiwan)": "Hiina (Taiwan)",
|
||||
"Croatian": "Horvaatia",
|
||||
"Czech": "Tšehhi",
|
||||
"Danish": "Taani",
|
||||
"Dutch": "Hollandi",
|
||||
"Esperanto": "Esperanto",
|
||||
"Estonian": "Eesti",
|
||||
"Filipino": "Filipiini",
|
||||
"Finnish": "Soome",
|
||||
"French": "Prantsuse",
|
||||
"French (auto-generated)": "Prantsuse (automaatne)",
|
||||
"Dutch (auto-generated)": "Hollandi (automaatne)",
|
||||
"Galician": "Kaliitsia",
|
||||
"Georgian": "Gruusia",
|
||||
"Haitian Creole": "Haiti kreool",
|
||||
"Hausa": "Hausa",
|
||||
"Hawaiian": "Havaii",
|
||||
"Hebrew": "Heebrea",
|
||||
"Hindi": "Hindi",
|
||||
"Hungarian": "Ungari",
|
||||
"Icelandic": "Islandi",
|
||||
"Indonesian": "Indoneesia",
|
||||
"Japanese (auto-generated)": "Jaapani (automaatne)",
|
||||
"Kannada": "Kannada",
|
||||
"Kazakh": "Kasahhi",
|
||||
"Luxembourgish": "Luksemburgi",
|
||||
"Macedonian": "Makedoonia",
|
||||
"Malay": "Malai",
|
||||
"Maltese": "Malta",
|
||||
"Maori": "Maori",
|
||||
"Marathi": "Marathi",
|
||||
"Mongolian": "Mongoli",
|
||||
"Nepali": "Nepaali",
|
||||
"Norwegian Bokmål": "Norra (Bokmål)",
|
||||
"Persian": "Pärsia",
|
||||
"Polish": "Poola",
|
||||
"Portuguese": "Portugali",
|
||||
"Portuguese (auto-generated)": "Portugali (automaatne)",
|
||||
"Portuguese (Brazil)": "Portugali (Brasiilia)",
|
||||
"Romanian": "Rumeenia",
|
||||
"Russian": "Vene",
|
||||
"Russian (auto-generated)": "Vene (automaatne)",
|
||||
"Scottish Gaelic": "Šoti (Gaeli)",
|
||||
"Serbian": "Serbia",
|
||||
"Slovak": "Slovaki",
|
||||
"Slovenian": "Sloveeni",
|
||||
"Somali": "Somaali",
|
||||
"Spanish": "Hispaania",
|
||||
"Spanish (auto-generated)": "Hispaania (automaatne)",
|
||||
"Spanish (Latin America)": "Hispaania (Ladina-Ameerika)",
|
||||
"Spanish (Mexico)": "Hispaania (Mehhiko)",
|
||||
"Spanish (Spain)": "Hispaania (Hispaania)",
|
||||
"Swahili": "Suahili",
|
||||
"Swedish": "Rootsi",
|
||||
"Tajik": "Tadžiki",
|
||||
"Tamil": "Tamiili",
|
||||
"Thai": "Tai",
|
||||
"Turkish": "Türgi",
|
||||
"Turkish (auto-generated)": "Türgi (automaatne)",
|
||||
"Ukrainian": "Ukraina",
|
||||
"Uzbek": "Usbeki",
|
||||
"Vietnamese": "Vietnami",
|
||||
"Vietnamese (auto-generated)": "Vietnami (automaatne)",
|
||||
"generic_count_years": "{{count}} aasta",
|
||||
"generic_count_years_plural": "{{count}} aastat",
|
||||
"generic_count_months": "{{count}} kuu",
|
||||
"generic_count_months_plural": "{{count}} kuud",
|
||||
"generic_count_weeks": "{{count}} nädal",
|
||||
"generic_count_weeks_plural": "{{count}} nädalat",
|
||||
"generic_count_days": "{{count}} päev",
|
||||
"generic_count_days_plural": "{{count}} päeva",
|
||||
"generic_count_hours": "{{count}} tund",
|
||||
"generic_count_hours_plural": "{{count}} tundi",
|
||||
"generic_count_minutes": "{{count}} minut",
|
||||
"generic_count_minutes_plural": "{{count}} minutit",
|
||||
"Popular": "Populaarne",
|
||||
"Search": "Otsi",
|
||||
"Top": "Top",
|
||||
"About": "Leheküljest",
|
||||
"preferences_locale_label": "Keel: ",
|
||||
"View as playlist": "Vaata esitusloendina",
|
||||
"Movies": "Filmid",
|
||||
"Download as: ": "Laadi kui: ",
|
||||
"(edited)": "(muudetud)",
|
||||
"`x` marked it with a ❤": "`x` märkis ❤",
|
||||
"Audio mode": "Audiorežiim",
|
||||
"Video mode": "Videorežiim",
|
||||
"search_filters_date_label": "Üleslaadimise kuupäev",
|
||||
"search_filters_date_option_none": "Ükskõik mis kuupäev",
|
||||
"search_filters_date_option_today": "Täna",
|
||||
"search_filters_date_option_week": "Sel nädalal",
|
||||
"search_filters_date_option_hour": "Viimasel tunnil",
|
||||
"search_filters_date_option_month": "Sel kuul",
|
||||
"search_filters_date_option_year": "Sel aastal",
|
||||
"search_filters_type_label": "Tüüp",
|
||||
"search_filters_type_option_all": "Ükskõik mis tüüp",
|
||||
"search_filters_duration_label": "Kestus",
|
||||
"search_filters_type_option_show": "Näita",
|
||||
"search_filters_duration_option_none": "Ükskõik mis kestus",
|
||||
"search_filters_duration_option_short": "Lühike (alla 4 minuti)",
|
||||
"search_filters_duration_option_medium": "Keskmine (4 - 20 minutit)",
|
||||
"search_filters_duration_option_long": "Pikk (üle 20 minuti)",
|
||||
"search_filters_features_option_live": "Otseülekanne",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "Subtiitrid",
|
||||
"search_filters_features_option_location": "Asukoht",
|
||||
"search_filters_sort_label": "Sorteeri",
|
||||
"search_filters_sort_option_views": "Vaatamiste arv",
|
||||
"next_steps_error_message": "Pärast mida võiksite proovida: ",
|
||||
"videoinfo_started_streaming_x_ago": "Alustas otseülekannet `x` tagasi",
|
||||
"Yes": "Jah",
|
||||
"generic_views_count": "{{count}} vaatamine",
|
||||
"generic_views_count_plural": "{{count}} vaatamist",
|
||||
"Import NewPipe subscriptions (.json)": "Impordi tellimused NewPipe'ist (.json)",
|
||||
"No": "Ei",
|
||||
"preferences_region_label": "Riik: ",
|
||||
"View YouTube comments": "Vaata YouTube'i kommentaare",
|
||||
"preferences_extend_desc_label": "Ava video kirjeldus automaatselt: ",
|
||||
"German (auto-generated)": "Saksa (automaatne)",
|
||||
"Italian": "Itaalia",
|
||||
"preferences_player_style_label": "Mängija stiil: ",
|
||||
"subscriptions_unseen_notifs_count": "{{count}} lugemata teavitus",
|
||||
"subscriptions_unseen_notifs_count_plural": "{{count}} lugemata teavitust",
|
||||
"View more comments on Reddit": "Vaata teisi kommentaare Redditis",
|
||||
"Only show latest unwatched video from channel: ": "Näita ainult viimast vaatamata videot: ",
|
||||
"tokens_count": "{{count}} token",
|
||||
"tokens_count_plural": "{{count}} tokenit",
|
||||
"Log out": "Logi välja",
|
||||
"Premieres `x`": "Linastub`x`",
|
||||
"View `x` comments": {
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "Vaata `x` kommentaari",
|
||||
"": "Vaata `x` kommentaare"
|
||||
},
|
||||
"Khmer": "Khmeeri",
|
||||
"Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Sisselogimine ei õnnestunud. Kontrollige, kas two-factor authentication (Authenticator või SMS) on sisselülitatud.",
|
||||
"Invalid TFA code": "Vale TFA-kood",
|
||||
"Bosnian": "Bosnia",
|
||||
"Corsican": "Korsika",
|
||||
"Javanese": "Jaava",
|
||||
"Lithuanian": "Leedu",
|
||||
"Videos": "Videod",
|
||||
"Community": "Kogukond",
|
||||
"CAPTCHA is a required field": "CAPTCHA on kohustuslik väli",
|
||||
"comments_points_count": "{{count}} punkt",
|
||||
"comments_points_count_plural": "{{count}} punkti",
|
||||
"Chinese": "Hiina",
|
||||
"German": "Saksa",
|
||||
"Indonesian (auto-generated)": "Indoneesia (automaatne)",
|
||||
"Italian (auto-generated)": "Itaalia (automaatne)",
|
||||
"Kyrgyz": "Kirkiisi",
|
||||
"Latin": "Ladina",
|
||||
"generic_count_seconds": "{{count}} sekund",
|
||||
"generic_count_seconds_plural": "{{count}} sekundit",
|
||||
"Catalan": "Katalaani",
|
||||
"Chinese (Traditional)": "Hiina (traditsiooniline)",
|
||||
"Greek": "Kreeka",
|
||||
"Kurdish": "Kurdi",
|
||||
"Latvian": "Läti",
|
||||
"Irish": "Iiri",
|
||||
"Korean": "Korea",
|
||||
"Japanese": "Jaapani",
|
||||
"Korean (auto-generated)": "Korea (automaatne)",
|
||||
"Music": "Muusika",
|
||||
"Playlists": "Esitusloendid",
|
||||
"search_filters_type_option_video": "Video",
|
||||
"search_filters_sort_option_date": "Üleslaadimise kuupäev",
|
||||
"Current version: ": "Praegune versioon: ",
|
||||
"footer_documentation": "Dokumentatsioon",
|
||||
"Gaming": "Mängud",
|
||||
"News": "Uudised",
|
||||
"Download": "Laadi alla",
|
||||
"search_filters_title": "Filtrid",
|
||||
"search_filters_type_option_channel": "Kanal",
|
||||
"search_filters_type_option_playlist": "Esitusloend",
|
||||
"search_filters_type_option_movie": "Film",
|
||||
"next_steps_error_message_go_to_youtube": "Minna YouTube'i",
|
||||
"next_steps_error_message_refresh": "Laadida uuesti",
|
||||
"footer_donate_page": "Anneta",
|
||||
"videoinfo_watch_on_youTube": "Vaata YouTube'is"
|
||||
}
|
||||
221
locales/eu.json
221
locales/eu.json
@@ -20,15 +20,15 @@
|
||||
"No": "Ez",
|
||||
"Import and Export Data": "Datuak inportatu eta esportatu",
|
||||
"Import": "Inportatu",
|
||||
"Import Invidious data": "Inportatu Invidiouseko datuak",
|
||||
"Import YouTube subscriptions": "Inportatu YouTubeko harpidetzak",
|
||||
"Import Invidious data": "Inportatu Invidiouseko JSON datuak",
|
||||
"Import YouTube subscriptions": "Inportatu YouTubeko/OPML harpidetzak",
|
||||
"Import FreeTube subscriptions (.db)": "Inportatu FreeTubeko harpidetzak (.db)",
|
||||
"Import NewPipe subscriptions (.json)": "Inportatu NewPipeko harpidetzak (.json)",
|
||||
"Import NewPipe data (.zip)": "Inportatu NewPipeko datuak (.zip)",
|
||||
"Export": "Esportatu",
|
||||
"Export subscriptions as OPML": "Esportatu harpidetzak OPML bezala",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Esportatu harpidetzak OPML bezala (NewPipe eta FreeTuberako)",
|
||||
"Export data as JSON": "Esportatu datuak JSON bezala",
|
||||
"Export data as JSON": "Esportatu Invidious datuak JSON gisa",
|
||||
"Delete account?": "Kontua ezabatu?",
|
||||
"History": "Historia",
|
||||
"An alternative front-end to YouTube": "YouTuberako interfaze alternatibo bat",
|
||||
@@ -53,7 +53,7 @@
|
||||
"preferences_volume_label": "Erreproduzigailuaren bolumena: ",
|
||||
"preferences_comments_label": "Lehenetsitako iruzkinak: ",
|
||||
"youtube": "YouTube",
|
||||
"reddit": "reddit",
|
||||
"reddit": "Reddit",
|
||||
"preferences_captions_label": "Lehenetsitako azpitituluak: ",
|
||||
"preferences_related_videos_label": "Erakutsi erlazionatutako bideoak: ",
|
||||
"preferences_annotations_label": "Erakutsi oharrak modu lehenetsian: ",
|
||||
@@ -62,5 +62,216 @@
|
||||
"Dark mode: ": "Gai iluna: ",
|
||||
"preferences_dark_mode_label": "Gaia: ",
|
||||
"dark": "iluna",
|
||||
"light": "argia"
|
||||
"light": "argia",
|
||||
"generic_subscriptions_count": "{{count}} harpidetza",
|
||||
"generic_subscriptions_count_plural": "{{count}} harpidetzak",
|
||||
"tokens_count": "{{count}} tokena",
|
||||
"tokens_count_plural": "{{count}} tokenak",
|
||||
"comments_points_count": "{{count}} puntua",
|
||||
"comments_points_count_plural": "{{count}} puntuak",
|
||||
"View more comments on Reddit": "Iruzkin gehiago Redditen",
|
||||
"Fallback captions: ": "Ordezko azpitituluak: ",
|
||||
"generic_subscribers_count": "{{count}} harpidedun",
|
||||
"generic_subscribers_count_plural": "{{count}} harpidedunak",
|
||||
"preferences_quality_option_dash": "DASH (kalitate egokitua)",
|
||||
"preferences_listen_label": "Lehenetsiz jo: ",
|
||||
"preferences_speed_label": "Abiadura lehenetsia: ",
|
||||
"preferences_quality_dash_option_2160p": "2160p",
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"preferences_quality_dash_option_auto": "Auto",
|
||||
"preferences_quality_dash_option_worst": "Txarrena",
|
||||
"preferences_quality_dash_option_best": "Hoberena",
|
||||
"preferences_quality_dash_option_4320p": "4320p",
|
||||
"preferences_quality_dash_option_480p": "480p",
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"preferences_extend_desc_label": "Bideoaren azalpena automatikoki zabaldu: ",
|
||||
"preferences_annotations_subscribed_label": "Harpidetutako kanalen oharrak erakutsi lehenetsiz? ",
|
||||
"Redirect homepage to feed: ": "Hasierako orrira bidali jarraitzeko: ",
|
||||
"channel name - reverse": "kanalaren izena - alderantziz",
|
||||
"preferences_notifications_only_label": "Jakinarazpenak soilik erakutsi (baldin badago): ",
|
||||
"Top enabled: ": "Goikoa gaitu: ",
|
||||
"Import/export data": "Inportatu/exportatu data",
|
||||
"Create playlist": "Zerrenda sortu",
|
||||
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Aditu! JavaScript itzalita dakazula ematen du. Hemen sakatu iruzkinak ikusteko. Denbora luza leikeela kontuan hartu.",
|
||||
"Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Ezinezkoa izena eman. Ziurtatu berresteko bi faktoreak (Authenticator edo SMS) piztuta daudela.",
|
||||
"generic_views_count": "{{count}}ikusia",
|
||||
"generic_views_count_plural": "{{count}}ikusiak",
|
||||
"generic_playlists_count": "{{count}}zerrenda",
|
||||
"generic_playlists_count_plural": "{{count}}zerrendak",
|
||||
"Could not fetch comments": "Iruzkinei ezin heldu",
|
||||
"Erroneous token": "Token okerra",
|
||||
"Albanian": "Albaniarra",
|
||||
"Azerbaijani": "Azerbaitarra",
|
||||
"No such user": "Ez dago erabiltzailerik",
|
||||
"Bulgarian": "Bulgariarra",
|
||||
"Filipino": "Filipinera",
|
||||
"French": "Frantsesa",
|
||||
"French (auto-generated)": "Frantsesa (auto-sortua)",
|
||||
"Show more": "Erakutsi gehiago",
|
||||
"Show less": "Erakutsi gutxiago",
|
||||
"Delete playlist": "Zerrenda ezabatu",
|
||||
"Delete account": "Kontua ezabatu",
|
||||
"User ID is a required field": "Erabiltzailearen IDa beharrezkoa da",
|
||||
"English (United Kingdom)": "Ingelesa (Britania Handia",
|
||||
"preferences_vr_mode_label": "360 graduko bideo interaktiboak (WebGL beharko): ",
|
||||
"English (United States)": "Estatu batuarra (AEB)",
|
||||
"English (auto-generated)": "Ingelesa (autosortua)",
|
||||
"Arabic": "Arabiarra",
|
||||
"Armenian": "Armeniarra",
|
||||
"Bangla": "Banglera",
|
||||
"Belarusian": "Bielorrusiara",
|
||||
"Burmese": "Burmesera",
|
||||
"Chinese (Simplified)": "Txinera (sinplifikatua)",
|
||||
"preferences_watch_history_label": "Baimendu historia ikusi ",
|
||||
"generic_videos_count": "{{count}}bideo",
|
||||
"generic_videos_count_plural": "{{count}}bideoak",
|
||||
"View privacy policy.": "Pribatutasun politika ikusi.",
|
||||
"Cantonese (Hong Kong)": "Kantoniera (Hong Kong)",
|
||||
"subscriptions_unseen_notifs_count": "{{count}} ezikusitako oharra",
|
||||
"subscriptions_unseen_notifs_count_plural": "{{count}} ezikusitako oharrak",
|
||||
"Trending": "Joera",
|
||||
"Playlist privacy": "Zerrendaren privatutasuna",
|
||||
"Switch Invidious Instance": "Invidious adibidea aldatu",
|
||||
"Genre: ": "Genero: ",
|
||||
"License: ": "Lizentzia: ",
|
||||
"Family friendly? ": "Adeikorra familiarekin? ",
|
||||
"Wilson score: ": "Wilsonen puntuazioa: ",
|
||||
"Quota exceeded, try again in a few hours": "Kuota gaindituta, ordu batzuren bueltan berriro saiatu",
|
||||
"comments_view_x_replies": "{{count}} erantzuna ikusi",
|
||||
"comments_view_x_replies_plural": "{{count}} erantzunak ikusi",
|
||||
"Catalan": "Katalaniera",
|
||||
"Chinese": "Txinera",
|
||||
"Chinese (China)": "Txinatarra",
|
||||
"Chinese (Hong Kong)": "Hongkondarra",
|
||||
"Chinese (Taiwan)": "Taiwandarra",
|
||||
"Corsican": "Korsikera",
|
||||
"Dutch (auto-generated)": "Alemaniera (auto-sortua)",
|
||||
"Estonian": "Estoniera",
|
||||
"Finnish": "Finlandiera",
|
||||
"Galician": "Galizera",
|
||||
"German (auto-generated)": "Alemaiera (auto-sortua)",
|
||||
"Greek": "Greziera",
|
||||
"crash_page_report_issue": "Aurreko ezerk ez badizu lagundu, arren <a href=\"`x`\"> GitHuben gai berri bat zabaldu </a> (ingelesez ahal bada) eta zure mezuan hurrengo testua sartu (testuari EZ itzulpena egin):",
|
||||
"crash_page_search_issue": "GitHuben dauden gaiak <a href=\"`x`\"> buruz</a>",
|
||||
"preferences_quality_option_medium": "Erdixka",
|
||||
"preferences_quality_option_small": "Txikia",
|
||||
"preferences_quality_dash_label": "DASH bideo kalitate lehenetsia: ",
|
||||
"preferences_quality_dash_option_1440p": "1440p",
|
||||
"preferences_quality_dash_option_1080p": "1080p",
|
||||
"preferences_quality_dash_option_720p": "720p",
|
||||
"preferences_quality_option_hd720": "HD720",
|
||||
"preferences_quality_dash_option_360p": "360p",
|
||||
"invidious": "Invidious",
|
||||
"Source available here.": "Iturburua hemen eskura.",
|
||||
"View JavaScript license information.": "JavaScriptaren lizentzi adierazpena ikusi.",
|
||||
"Blacklisted regions: ": "zerrenda beltzaren zonaldeak: ",
|
||||
"Premieres `x`": "'x' estrenaldiak",
|
||||
"Wrong answer": "Erantzun ez zuzena",
|
||||
"Password is a required field": "Pasahitza beharrezkoa da",
|
||||
"Wrong username or password": "Pasahitza edo ezizena gaizki",
|
||||
"Password cannot be longer than 55 characters": "Pasahitza 55 karaktere baino luzeagoa ezin da izan",
|
||||
"This channel does not exist.": "Kanal hau ez dago.",
|
||||
"`x` ago": "duela 'x'",
|
||||
"Czech": "Txekiera",
|
||||
"preferences_region_label": "Herrialdeko edukiera: ",
|
||||
"preferences_sort_label": "Bideoak ordenatu: ",
|
||||
"published": "argitaratuta",
|
||||
"Only show latest video from channel: ": "Kanalaren azken bideoa soilik erakutsi ",
|
||||
"preferences_category_admin": "Administratzailearen lehentasunak",
|
||||
"Registration enabled: ": "Harpidetza gaituta: ",
|
||||
"Save preferences": "Baloreak gorde",
|
||||
"Token manager": "Token kudeatzailea",
|
||||
"unsubscribe": "Baja eman",
|
||||
"search": "Bilatu",
|
||||
"Log out": "Irten",
|
||||
"English": "Ingelesa",
|
||||
"Afrikaans": "Afrikarra",
|
||||
"Amharic": "Amharerra",
|
||||
"Basque": "Euskera",
|
||||
"Bosnian": "Bosniarra",
|
||||
"Cebuano": "Zebuera",
|
||||
"Chinese (Traditional)": "Txinera (Tradizionala)",
|
||||
"Croatian": "Croaziera",
|
||||
"Danish": "Daniera",
|
||||
"Dutch": "Alemaniera",
|
||||
"Esperanto": "Esperanto",
|
||||
"Erroneous challenge": "Erronka okerra",
|
||||
"View all playlists": "Zerrenda guztiak ikusi",
|
||||
"Show annotations": "Oharrak erakutsi",
|
||||
"Empty playlist": "Zerrenda hutsik",
|
||||
"Please log in": "Sartu, mesedez",
|
||||
"CAPTCHA is a required field": "CAPTCHA beharrezko eremua da",
|
||||
"preferences_category_data": "Dataren lehentasunak",
|
||||
"preferences_default_home_label": "Homepage lehenetsia: ",
|
||||
"preferences_automatic_instance_redirect_label": "berbideratze adibide automatikoa (atzera egin berbideratzeko: invidious.io) ",
|
||||
"Please sign in using 'Log in with Google'": "'Log in Googlerekin' erabili",
|
||||
"`x` uploaded a video": "' x'(e)k bideo bat igo du",
|
||||
"published - reverse": "argitaratuta - alderantziz",
|
||||
"Could not get channel info.": "Kanalaren adierazpena ezin lortu.",
|
||||
"alphabetically - reverse": "alfabetikoki - alderantziz",
|
||||
"Public": "Orokorra",
|
||||
"Unlisted": "Ez zerrendatua",
|
||||
"Subscription manager": "Harpidetzen kudeatzailea",
|
||||
"Updated `x` ago": "Duela 'x' eguneratua",
|
||||
"Hide replies": "Erantzunak izkutatu",
|
||||
"preferences_thin_mode_label": "Urri eran: ",
|
||||
"Show replies": "Erantzunak erakutsi",
|
||||
"Watch on YouTube": "YouTuben ikusi",
|
||||
"Premieres in `x`": "'x'eko estrenaldiak",
|
||||
"Delete playlist `x`?": "'x' zerrenda ezabatu nahi?",
|
||||
"Token is expired, please try again": "Token kadukatua, saiatu berriro",
|
||||
"Invalid TFA code": "TFA kodea ez da zuzena",
|
||||
"CAPTCHA enabled: ": "CAPTCHA gaitu: ",
|
||||
"Released under the AGPLv3 on Github.": "GitHubeko AGPLv3pean argitaratuta.",
|
||||
"channel:`x`": "Kanal: 'x'",
|
||||
"Georgian": "Georgiera",
|
||||
"Incorrect password": "Pasahitza gaizki",
|
||||
"Playlist does not exist.": "Zerrenda ez da existitzen.",
|
||||
"preferences_category_misc": "Askotariko lehentasunak",
|
||||
"View `x` comments": {
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "'x' iruzkina ikusi",
|
||||
"": "'x' iruzkinak ikusi"
|
||||
},
|
||||
"Report statistics: ": "Estatistikak adierazi: ",
|
||||
"preferences_max_results_label": "Jotzeko bideo zerrendaren luzera: ",
|
||||
"Subscriptions": "Harpidetzak",
|
||||
"Load more": "Gehiago atera",
|
||||
"Change password": "Pasahitza aldatu",
|
||||
"preferences_show_nick_label": "Erakutsi ezizena goian: ",
|
||||
"View Reddit comments": "Redditeko iruzkinak ikusi",
|
||||
"preferences_category_subscription": "Harpidetzaren lehentasunak",
|
||||
"Hidden field \"challenge\" is a required field": "\"challenge\" eremu ezkutua beharrezkoa da",
|
||||
"German": "Alemaniarra",
|
||||
"Login failed. This may be because two-factor authentication is not turned on for your account.": "Ezin izena eman. Izan leike zure konturako berresteko bi faktoreak piztuta ez daudela.",
|
||||
"View YouTube comments": "YouTubeko iruzkinak ikusi",
|
||||
"Google verification code": "Googleren berresteko kodea",
|
||||
"`x` is live": "'x' bizirik darrai",
|
||||
"Password cannot be empty": "Pasahitza ezin da hutsik utzi",
|
||||
"preferences_video_loop_label": "Beti begiztatu: ",
|
||||
"Only show latest unwatched video from channel: ": "kanalaren azken bideo ezikusia erakutsi soilik ",
|
||||
"Enable web notifications": "Webaren jakinarazpenak baimendu",
|
||||
"revoke": "ukatu",
|
||||
"preferences_continue_label": "Hurrengo lehenetsia jo: ",
|
||||
"Whitelisted regions: ": "Zuri zerrendaren zonaldeak: ",
|
||||
"Erroneous CAPTCHA": "CAPTCHA gaizki",
|
||||
"Deleted or invalid channel": "Ezgai edota ezabatutako kanala",
|
||||
"Could not create mix.": "Nahastea ezin sortu.",
|
||||
"Not a playlist.": "Ez da zerrenda.",
|
||||
"Hidden field \"token\" is a required field": "\"token\" eremu ezkutua beharrezkoa da",
|
||||
"Import/export": "Inportatu/esportatu",
|
||||
"alphabetically": "alfabetikoki",
|
||||
"preferences_unseen_only_label": "Ezikusiak besterik ez erakutsi: ",
|
||||
"Clear watch history": "Historia ezabatu",
|
||||
"Manage subscriptions": "Harpidetzak kudeatu",
|
||||
"Manage tokens": "Fitxak kudeatu",
|
||||
"Watch history": "Historia ikusi",
|
||||
"Login enabled: ": "Login gaitu: ",
|
||||
"Hide annotations": "Oharrak izkutatu",
|
||||
"Title": "Titulua",
|
||||
"channel name": "Kanalaren izena",
|
||||
"Authorize token for `x`?": "Baimendu tokena 'x'tzako?",
|
||||
"Private": "Pribatua",
|
||||
"Editing playlist `x`": "'x' zerrenda editatu",
|
||||
"Could not pull trending pages.": "Ezin ekarri orri arrakastatsuak.",
|
||||
"crash_page_read_the_faq": "Bide <a href=\"`x`\"> (FAQ) ohiko galderak</a>"
|
||||
}
|
||||
|
||||
@@ -148,7 +148,6 @@
|
||||
"Show less": "نمایش کمتر",
|
||||
"Watch on YouTube": "تماشا در یوتیوب",
|
||||
"Switch Invidious Instance": "تعویض نمونه اینویدیوس",
|
||||
"Broken? Try another Invidious Instance": "کار نمیکند؟ نمونه دیگری از اینویدیوس را امتحان کنید",
|
||||
"Hide annotations": "مخفی کردن حاشیه نویسی ها",
|
||||
"Show annotations": "نمایش حاشیه نویسی ها",
|
||||
"Genre: ": "ژانر: ",
|
||||
@@ -345,33 +344,32 @@
|
||||
"Videos": "ویدیو ها",
|
||||
"Playlists": "سیاهههای پخش",
|
||||
"Community": "اجتماع",
|
||||
"relevance": "مرتبط بودن",
|
||||
"rating": "امتیاز",
|
||||
"date": "تاریخ بارگذاری",
|
||||
"views": "تعداد بازدید",
|
||||
"content_type": "نوع",
|
||||
"duration": "مدت",
|
||||
"features": "ویژگیها",
|
||||
"sort": "به ترتیب",
|
||||
"hour": "یک ساعت گذشته",
|
||||
"today": "امروز",
|
||||
"week": "این هفته",
|
||||
"month": "این ماه",
|
||||
"year": "امسال",
|
||||
"video": "ویدئو",
|
||||
"channel": "کانال",
|
||||
"playlist": "سیاههٔ پخش",
|
||||
"movie": "فیلم",
|
||||
"show": "نمایش",
|
||||
"hd": "HD",
|
||||
"subtitles": "زیرنویس",
|
||||
"creative_commons": "کریتیو کامونز",
|
||||
"3d": "سهبعدی",
|
||||
"live": "زنده",
|
||||
"4k": "4K",
|
||||
"location": "مکان",
|
||||
"hdr": "HDR",
|
||||
"filter": "پالایه",
|
||||
"search_filters_sort_option_relevance": "مرتبط بودن",
|
||||
"search_filters_sort_option_rating": "امتیاز",
|
||||
"search_filters_sort_option_date": "تاریخ بارگذاری",
|
||||
"search_filters_sort_option_views": "تعداد بازدید",
|
||||
"search_filters_type_label": "نوع",
|
||||
"search_filters_duration_label": "مدت",
|
||||
"search_filters_features_label": "ویژگیها",
|
||||
"search_filters_sort_label": "به ترتیب",
|
||||
"search_filters_date_option_hour": "یک ساعت گذشته",
|
||||
"search_filters_date_option_today": "امروز",
|
||||
"search_filters_date_option_week": "این هفته",
|
||||
"search_filters_date_option_month": "این ماه",
|
||||
"search_filters_date_option_year": "امسال",
|
||||
"search_filters_type_option_video": "ویدئو",
|
||||
"search_filters_type_option_channel": "کانال",
|
||||
"search_filters_type_option_playlist": "سیاههٔ پخش",
|
||||
"search_filters_type_option_movie": "فیلم",
|
||||
"search_filters_type_option_show": "نمایش",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "زیرنویس",
|
||||
"search_filters_features_option_c_commons": "کریتیو کامونز",
|
||||
"search_filters_features_option_three_d": "سهبعدی",
|
||||
"search_filters_features_option_live": "زنده",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_location": "مکان",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"Current version: ": "نسخه فعلی: ",
|
||||
"next_steps_error_message": "اکنون بایستی یکی از این موارد را امتحان کنید: ",
|
||||
"next_steps_error_message_refresh": "تازهسازی",
|
||||
@@ -393,7 +391,7 @@
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"invidious": "اینویدیوس",
|
||||
"360": "360°",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"footer_donate_page": "کمک مالی",
|
||||
"footer_source_code": "کد منبع",
|
||||
"footer_modfied_source_code": "کد منبع ویرایش شده",
|
||||
@@ -405,12 +403,13 @@
|
||||
"download_subtitles": "زیرنویسها - `x` (.vtt)",
|
||||
"Video unavailable": "ویدئو دردسترس نیست",
|
||||
"preferences_save_player_pos_label": "ذخیره زمان کنونی ویدئو: ",
|
||||
"purchased": "خریداری شده",
|
||||
"search_filters_features_option_purchased": "خریداری شده",
|
||||
"preferences_quality_dash_label": "کیفیت ترجیحی ویدئو DASH: ",
|
||||
"preferences_region_label": "کشور محتوا: ",
|
||||
"footer_documentation": "مستندات",
|
||||
"footer_original_source_code": "کد منبع اصلی",
|
||||
"long": "بلند (> 20 دقیقه)",
|
||||
"search_filters_duration_option_long": "بلند (> 20 دقیقه)",
|
||||
"adminprefs_modified_source_code_url_label": "URL مخزن کد منبع ویریش شده",
|
||||
"short": "کوتاه (< 4 دقیقه)"
|
||||
"search_filters_duration_option_short": "کوتاه (< 4 دقیقه)",
|
||||
"search_filters_title": "پالایه"
|
||||
}
|
||||
|
||||
110
locales/fi.json
110
locales/fi.json
@@ -21,15 +21,15 @@
|
||||
"No": "Ei",
|
||||
"Import and Export Data": "Tuo ja vie tietoja",
|
||||
"Import": "Tuo",
|
||||
"Import Invidious data": "Tuo Invidious-tietoja",
|
||||
"Import YouTube subscriptions": "Tuo YouTube-tilaukset",
|
||||
"Import Invidious data": "Tuo Invidiousin JSON-tietoja",
|
||||
"Import YouTube subscriptions": "Tuo YouTube/OPML-tilaukset",
|
||||
"Import FreeTube subscriptions (.db)": "Tuo FreeTube-tilaukset (.db)",
|
||||
"Import NewPipe subscriptions (.json)": "Tuo NewPipe-tilaukset (.json)",
|
||||
"Import NewPipe data (.zip)": "Tuo NewPipe-tietoja (.zip)",
|
||||
"Export": "Vie",
|
||||
"Export subscriptions as OPML": "Vie tilaukset OPML-muodossa",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Vie tilaukset OPML-muodossa (NewPipe & FreeTube)",
|
||||
"Export data as JSON": "Vie data JSON-muodossa",
|
||||
"Export data as JSON": "Vie Invidious-data JSON-muodossa",
|
||||
"Delete account?": "Poista tili?",
|
||||
"History": "Historia",
|
||||
"An alternative front-end to YouTube": "Vaihtoehtoinen front-end YouTubelle",
|
||||
@@ -66,7 +66,7 @@
|
||||
"preferences_related_videos_label": "Näytä aiheeseen liittyviä videoita: ",
|
||||
"preferences_annotations_label": "Näytä huomautukset oletuksena: ",
|
||||
"preferences_extend_desc_label": "Laajenna automaattisesti videon kuvausta: ",
|
||||
"preferences_vr_mode_label": "Interaktiiviset 360-asteiset videot: ",
|
||||
"preferences_vr_mode_label": "Interaktiiviset 360-asteiset videot (vaatii WebGL:n): ",
|
||||
"preferences_category_visual": "Visuaaliset asetukset",
|
||||
"preferences_player_style_label": "Soittimen tyyli: ",
|
||||
"Dark mode: ": "Tumma tila: ",
|
||||
@@ -140,7 +140,6 @@
|
||||
"Show less": "Näytä vähemmän",
|
||||
"Watch on YouTube": "Katso YouTubessa",
|
||||
"Switch Invidious Instance": "Vaihda Invidious-instanssia",
|
||||
"Broken? Try another Invidious Instance": "Rikki? Kokeile toista Invidious-instanssia",
|
||||
"Hide annotations": "Piilota merkkaukset",
|
||||
"Show annotations": "Näytä merkkaukset",
|
||||
"Genre: ": "Genre: ",
|
||||
@@ -328,33 +327,32 @@
|
||||
"Videos": "Videot",
|
||||
"Playlists": "Soittolistat",
|
||||
"Community": "Yhteisö",
|
||||
"relevance": "Osuvuus",
|
||||
"rating": "Arvostelu",
|
||||
"date": "Latauspäivämäärä",
|
||||
"views": "Katselukerrat",
|
||||
"content_type": "Tyyppi",
|
||||
"duration": "Kesto",
|
||||
"features": "Ominaisuudet",
|
||||
"sort": "Luokittele",
|
||||
"hour": "Viimeisin tunti",
|
||||
"today": "Tänään",
|
||||
"week": "Tämä viikko",
|
||||
"month": "Tämä kuukausi",
|
||||
"year": "Tämä vuosi",
|
||||
"video": "Video",
|
||||
"channel": "Kanava",
|
||||
"playlist": "Soittolista",
|
||||
"movie": "Elokuva",
|
||||
"show": "Ohjelma",
|
||||
"hd": "HD",
|
||||
"subtitles": "Tekstitys/CC",
|
||||
"creative_commons": "Creative Commons",
|
||||
"3d": "3D",
|
||||
"live": "Suora lähetys",
|
||||
"4k": "4K",
|
||||
"location": "Sijainti",
|
||||
"hdr": "HDR",
|
||||
"filter": "Suodatin",
|
||||
"search_filters_sort_option_relevance": "Osuvuus",
|
||||
"search_filters_sort_option_rating": "Arvostelu",
|
||||
"search_filters_sort_option_date": "Latauspäivämäärä",
|
||||
"search_filters_sort_option_views": "Katselukerrat",
|
||||
"search_filters_type_label": "Tyyppi",
|
||||
"search_filters_duration_label": "Kesto",
|
||||
"search_filters_features_label": "Ominaisuudet",
|
||||
"search_filters_sort_label": "Luokittele",
|
||||
"search_filters_date_option_hour": "Viimeisin tunti",
|
||||
"search_filters_date_option_today": "Tänään",
|
||||
"search_filters_date_option_week": "Tämä viikko",
|
||||
"search_filters_date_option_month": "Tämä kuukausi",
|
||||
"search_filters_date_option_year": "Tämä vuosi",
|
||||
"search_filters_type_option_video": "Video",
|
||||
"search_filters_type_option_channel": "Kanava",
|
||||
"search_filters_type_option_playlist": "Soittolista",
|
||||
"search_filters_type_option_movie": "Elokuva",
|
||||
"search_filters_type_option_show": "Ohjelma",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "Tekstitys/CC",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_live": "Suora lähetys",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_location": "Sijainti",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"Current version: ": "Tämänhetkinen versio: ",
|
||||
"next_steps_error_message": "Sinun tulisi kokeilla seuraavia: ",
|
||||
"next_steps_error_message_refresh": "Päivitä",
|
||||
@@ -390,7 +388,7 @@
|
||||
"crash_page_before_reporting": "Varmista ennen bugin ilmoittamista, että sinä olet:",
|
||||
"crash_page_refresh": "yrittänyt <a href=\"`x`\">päivittää sivun</a>",
|
||||
"crash_page_read_the_faq": "lukenut <a href=\"`x`\">Usein kysytyt kysymykset (FAQ)</a>",
|
||||
"crash_page_search_issue": "etsinyt <a href=\"`x`\">olemassa olevia issueita Githubissa</a>",
|
||||
"crash_page_search_issue": "etsinyt <a href=\"`x`\">olemassa olevia issueita GitHubissa</a>",
|
||||
"generic_views_count": "{{count}} katselu",
|
||||
"generic_views_count_plural": "{{count}} katselua",
|
||||
"preferences_quality_dash_option_720p": "720p",
|
||||
@@ -423,8 +421,8 @@
|
||||
"preferences_quality_dash_label": "Haluttava DASH-videolaatu: ",
|
||||
"generic_count_years": "{{count}} vuosi",
|
||||
"generic_count_years_plural": "{{count}} vuotta",
|
||||
"purchased": "Ostettu",
|
||||
"360": "360°",
|
||||
"search_filters_features_option_purchased": "Ostettu",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"videoinfo_watch_on_youTube": "Katso YouTubessa",
|
||||
"none": "ei mikään",
|
||||
"videoinfo_started_streaming_x_ago": "Striimaaminen aloitettu `x` sitten",
|
||||
@@ -433,9 +431,45 @@
|
||||
"footer_source_code": "Lähdekoodi",
|
||||
"adminprefs_modified_source_code_url_label": "URL muokattuun lähdekoodirepositoryyn",
|
||||
"Released under the AGPLv3 on Github.": "Julkaistu AGPLv3-lisenssin alla GitHubissa.",
|
||||
"short": "Lyhyt (< 4 minuuttia)",
|
||||
"long": "Pitkä (> 20 minuuttia)",
|
||||
"search_filters_duration_option_short": "Lyhyt (< 4 minuuttia)",
|
||||
"search_filters_duration_option_long": "Pitkä (> 20 minuuttia)",
|
||||
"footer_documentation": "Dokumentaatio",
|
||||
"footer_original_source_code": "Alkuperäinen lähdekoodi",
|
||||
"footer_modfied_source_code": "Muokattu lähdekoodi"
|
||||
"footer_modfied_source_code": "Muokattu lähdekoodi",
|
||||
"Japanese (auto-generated)": "Japani (automaattisesti luotu)",
|
||||
"German (auto-generated)": "Saksa (automaattisesti luotu)",
|
||||
"Portuguese (auto-generated)": "portugali (automaattisesti luotu)",
|
||||
"Russian (auto-generated)": "Venäjä (automaattisesti luotu)",
|
||||
"preferences_watch_history_label": "Ota katseluhistoria käyttöön: ",
|
||||
"English (United Kingdom)": "Englanti (Iso-Britannia)",
|
||||
"English (United States)": "Englanti (Yhdysvallat)",
|
||||
"Cantonese (Hong Kong)": "Kantoninkiina (Hong Kong)",
|
||||
"Chinese": "Kiina",
|
||||
"Chinese (China)": "Kiina (Kiina)",
|
||||
"Chinese (Hong Kong)": "Kiina (Hong Kong)",
|
||||
"Chinese (Taiwan)": "Kiina (Taiwan)",
|
||||
"Dutch (auto-generated)": "Hollanti (automaattisesti luotu)",
|
||||
"French (auto-generated)": "Ranska (automaattisesti luotu)",
|
||||
"Indonesian (auto-generated)": "Indonesia (automaattisesti luotu)",
|
||||
"Interlingue": "Interlingue",
|
||||
"Italian (auto-generated)": "Italia (automaattisesti luotu)",
|
||||
"Korean (auto-generated)": "Korea (automaattisesti luotu)",
|
||||
"Portuguese (Brazil)": "portugali (Brasilia)",
|
||||
"Spanish (auto-generated)": "Espanja (automaattisesti luotu)",
|
||||
"Spanish (Mexico)": "Espanja (Meksiko)",
|
||||
"Spanish (Spain)": "Espanja (Espanja)",
|
||||
"Turkish (auto-generated)": "Turkki (automaattisesti luotu)",
|
||||
"Vietnamese (auto-generated)": "Vietnam (automaattisesti luotu)",
|
||||
"search_filters_title": "Suodatin",
|
||||
"search_message_no_results": "Ei tuloksia löydetty.",
|
||||
"search_message_change_filters_or_query": "Yritä hakukyselysi laajentamista ja/tai suodattimien muuttamista.",
|
||||
"search_filters_duration_option_none": "Mikä tahansa kesto",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"search_filters_apply_button": "Ota valitut suodattimet käyttöön",
|
||||
"search_filters_date_label": "Latausaika",
|
||||
"search_filters_duration_option_medium": "Keskipituinen (4 - 20 minuuttia)",
|
||||
"search_message_use_another_instance": " Voit myös <a href=\"`x`\">hakea toisella instanssilla</a>.",
|
||||
"search_filters_date_option_none": "Milloin tahansa",
|
||||
"search_filters_type_option_all": "Mikä tahansa tyyppi",
|
||||
"Popular enabled: ": "Suosittu käytössä: "
|
||||
}
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
"preferences_default_home_label": "Page d'accueil par défaut : ",
|
||||
"preferences_feed_menu_label": "Préferences des abonnements : ",
|
||||
"preferences_show_nick_label": "Afficher le nom d'utilisateur en haut à droite : ",
|
||||
"Popular enabled: ": "Page \"populaire\" activée: ",
|
||||
"Top enabled: ": "Top activé : ",
|
||||
"CAPTCHA enabled: ": "CAPTCHA activé : ",
|
||||
"Login enabled: ": "Autoriser l'ouverture de sessions utilisateur : ",
|
||||
@@ -135,7 +136,7 @@
|
||||
"subscriptions_unseen_notifs_count_plural": "{{count}} notifications non vues",
|
||||
"search": "rechercher",
|
||||
"Log out": "Se déconnecter",
|
||||
"Released under the AGPLv3 on Github.": "Publié sous licence AGPLv3 sur Github.",
|
||||
"Released under the AGPLv3 on Github.": "Publié sous licence AGPLv3 sur GitHub.",
|
||||
"Source available here.": "Code source disponible ici.",
|
||||
"View JavaScript license information.": "Informations des licences JavaScript.",
|
||||
"View privacy policy.": "Politique de confidentialité.",
|
||||
@@ -155,7 +156,6 @@
|
||||
"Show less": "Afficher moins",
|
||||
"Watch on YouTube": "Voir la vidéo sur Youtube",
|
||||
"Switch Invidious Instance": "Changer d'instance",
|
||||
"Broken? Try another Invidious Instance": "Instance Invidious défectueuse ? Essayez-en une autre",
|
||||
"Hide annotations": "Masquer les annotations",
|
||||
"Show annotations": "Afficher les annotations",
|
||||
"Genre: ": "Genre : ",
|
||||
@@ -361,33 +361,32 @@
|
||||
"Videos": "Vidéos",
|
||||
"Playlists": "Listes de lecture",
|
||||
"Community": "Communauté",
|
||||
"relevance": "pertinence",
|
||||
"rating": "évaluation",
|
||||
"date": "date",
|
||||
"views": "nombre de vues",
|
||||
"content_type": "type",
|
||||
"duration": "durée",
|
||||
"features": "fonctionnalités",
|
||||
"sort": "Trier par",
|
||||
"hour": "dernière heure",
|
||||
"today": "aujourd'hui",
|
||||
"week": "semaine",
|
||||
"month": "mois",
|
||||
"year": "année",
|
||||
"video": "vidéo",
|
||||
"channel": "chaîne",
|
||||
"playlist": "liste de lecture",
|
||||
"movie": "film",
|
||||
"show": "émission",
|
||||
"hd": "HD",
|
||||
"subtitles": "sous-titres / CC",
|
||||
"creative_commons": "Creative Commons",
|
||||
"3d": "3D",
|
||||
"live": "en direct",
|
||||
"4k": "4K",
|
||||
"location": "emplacement",
|
||||
"hdr": "HDR",
|
||||
"filter": "filtrer",
|
||||
"search_filters_sort_option_relevance": "Pertinence",
|
||||
"search_filters_sort_option_rating": "Notation",
|
||||
"search_filters_sort_option_date": "Date d'ajout",
|
||||
"search_filters_sort_option_views": "Nombre de vues",
|
||||
"search_filters_type_label": "Type de contenu",
|
||||
"search_filters_duration_label": "Durée",
|
||||
"search_filters_features_label": "Fonctionnalités",
|
||||
"search_filters_sort_label": "Trier par",
|
||||
"search_filters_date_option_hour": "Dernière heure",
|
||||
"search_filters_date_option_today": "Aujourd'hui",
|
||||
"search_filters_date_option_week": "Cette semaine",
|
||||
"search_filters_date_option_month": "Ce mois-ci",
|
||||
"search_filters_date_option_year": "Cette année",
|
||||
"search_filters_type_option_video": "Vidéo",
|
||||
"search_filters_type_option_channel": "Chaîne",
|
||||
"search_filters_type_option_playlist": "Liste de lecture",
|
||||
"search_filters_type_option_movie": "Film",
|
||||
"search_filters_type_option_show": "Émission",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "Sous-titres (CC)",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_live": "En direct",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_location": "emplacement",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"Current version: ": "Version actuelle : ",
|
||||
"next_steps_error_message": "Vous pouvez essayer de : ",
|
||||
"next_steps_error_message_refresh": "Rafraîchir la page",
|
||||
@@ -397,8 +396,8 @@
|
||||
"preferences_region_label": "Pays du contenu : ",
|
||||
"footer_donate_page": "Faire un don",
|
||||
"footer_modfied_source_code": "Code source modifié",
|
||||
"short": "Courte (< 4 minutes)",
|
||||
"long": "Longue (> 20 minutes)",
|
||||
"search_filters_duration_option_short": "Courte (< 4 minutes)",
|
||||
"search_filters_duration_option_long": "Longue (> 20 minutes)",
|
||||
"adminprefs_modified_source_code_url_label": "URL du dépôt du code source modifié",
|
||||
"footer_documentation": "Documentation",
|
||||
"footer_original_source_code": "Code source original",
|
||||
@@ -415,12 +414,12 @@
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"invidious": "Invidious",
|
||||
"360": "360°",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"none": "aucun",
|
||||
"videoinfo_started_streaming_x_ago": "En stream depuis `x`",
|
||||
"videoinfo_watch_on_youTube": "Regarder sur YouTube",
|
||||
"videoinfo_youTube_embed_link": "Intégrer",
|
||||
"purchased": "Acheter",
|
||||
"search_filters_features_option_purchased": "Acheté",
|
||||
"videoinfo_invidious_embed_link": "Lien intégré",
|
||||
"download_subtitles": "Sous-titres - `x` (.vtt)",
|
||||
"user_saved_playlists": "`x` listes de lecture sauvegardées",
|
||||
@@ -435,7 +434,7 @@
|
||||
"crash_page_refresh": "tenté de <a href=\"`x`\">rafraîchir la page</a>",
|
||||
"crash_page_switch_instance": "essayé d'<a href=\"`x`\">utiliser une autre instance</a>",
|
||||
"crash_page_read_the_faq": "lu la <a href=\"`x`\">Foire Aux Questions (FAQ)</a>",
|
||||
"crash_page_search_issue": "<a href=\"`x`\">cherché ce bug sur Github</a>",
|
||||
"crash_page_search_issue": "<a href=\"`x`\">cherché ce bug sur GitHub</a>",
|
||||
"crash_page_before_reporting": "Avant de signaler un bug, veuillez vous assurez que vous avez :",
|
||||
"crash_page_report_issue": "Si aucune des solutions proposées ci-dessus ne vous a aidé, veuillez <a href=\"`x`\">ouvrir une \"issue\" sur GitHub</a> (de préférence en anglais) et d'y inclure le message suivant (ne PAS traduire le texte) :",
|
||||
"English (United States)": "Anglais (Etats-Unis)",
|
||||
@@ -461,5 +460,16 @@
|
||||
"Vietnamese (auto-generated)": "Vietnamien (auto-généré)",
|
||||
"Russian (auto-generated)": "Russe (auto-généré)",
|
||||
"Spanish (Spain)": "Espagnol (Espagne)",
|
||||
"preferences_watch_history_label": "Activer l'historique de visionnage : "
|
||||
"preferences_watch_history_label": "Activer l'historique de visionnage : ",
|
||||
"search_filters_title": "Filtres",
|
||||
"search_message_change_filters_or_query": "Essayez d'élargir votre recherche et/ou de changer les filtres.",
|
||||
"search_filters_date_option_none": "Toutes les dates",
|
||||
"search_filters_duration_option_medium": "Moyenne (de 4 à 20 minutes)",
|
||||
"search_filters_apply_button": "Appliquer les filtres",
|
||||
"search_message_no_results": "Aucun résultat.",
|
||||
"search_message_use_another_instance": " Vous pouvez également <a href=\"`x`\">effectuer votre recherche sur une autre instance</a>.",
|
||||
"search_filters_type_option_all": "Tous les types",
|
||||
"search_filters_date_label": "Date d'ajout",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"search_filters_duration_option_none": "Toutes les durées"
|
||||
}
|
||||
|
||||
@@ -274,32 +274,32 @@
|
||||
"Videos": "סרטונים",
|
||||
"Playlists": "פלייליסטים",
|
||||
"Community": "קהילה",
|
||||
"relevance": "רלוונטיות",
|
||||
"rating": "דירוג",
|
||||
"date": "תאריך העלאה",
|
||||
"views": "מספר צפיות",
|
||||
"content_type": "סוג",
|
||||
"duration": "משך זמן",
|
||||
"features": "תכונות",
|
||||
"sort": "מיון לפי",
|
||||
"hour": "השעה האחרונה",
|
||||
"today": "היום",
|
||||
"week": "השבוע",
|
||||
"month": "החודש",
|
||||
"year": "השנה",
|
||||
"video": "סרטון",
|
||||
"channel": "ערוץ",
|
||||
"playlist": "פלייליסט",
|
||||
"movie": "סרט",
|
||||
"show": "תכנית טלוויזיה",
|
||||
"hd": "HD",
|
||||
"subtitles": "כתוביות",
|
||||
"creative_commons": "Creative Commons",
|
||||
"3d": "3D",
|
||||
"live": "Live",
|
||||
"4k": "4K",
|
||||
"location": "מיקום",
|
||||
"hdr": "HDR",
|
||||
"filter": "סינון",
|
||||
"Current version: ": "הגרסה הנוכחית: "
|
||||
"search_filters_sort_option_relevance": "רלוונטיות",
|
||||
"search_filters_sort_option_rating": "דירוג",
|
||||
"search_filters_sort_option_date": "תאריך העלאה",
|
||||
"search_filters_sort_option_views": "מספר צפיות",
|
||||
"search_filters_type_label": "סוג",
|
||||
"search_filters_duration_label": "משך זמן",
|
||||
"search_filters_features_label": "תכונות",
|
||||
"search_filters_sort_label": "מיון לפי",
|
||||
"search_filters_date_option_hour": "השעה האחרונה",
|
||||
"search_filters_date_option_today": "היום",
|
||||
"search_filters_date_option_week": "השבוע",
|
||||
"search_filters_date_option_month": "החודש",
|
||||
"search_filters_date_option_year": "השנה",
|
||||
"search_filters_type_option_video": "סרטון",
|
||||
"search_filters_type_option_channel": "ערוץ",
|
||||
"search_filters_type_option_playlist": "פלייליסט",
|
||||
"search_filters_type_option_movie": "סרט",
|
||||
"search_filters_type_option_show": "תכנית טלוויזיה",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "כתוביות",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_live": "Live",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_location": "מיקום",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"Current version: ": "הגרסה הנוכחית: ",
|
||||
"search_filters_title": "סינון"
|
||||
}
|
||||
|
||||
474
locales/hi.json
Normal file
474
locales/hi.json
Normal file
@@ -0,0 +1,474 @@
|
||||
{
|
||||
"last": "आखिरी",
|
||||
"Yes": "हाँ",
|
||||
"No": "नहीं",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "OPML के रूप में सदस्यताएँ निर्यात करें (NewPipe और FreeTube के लिए)",
|
||||
"Log in/register": "लॉग-इन/पंजीकृत करें",
|
||||
"Log in with Google": "Google के साथ लॉग-इन करें",
|
||||
"preferences_autoplay_label": "अपने आप चलाने की सुविधा: ",
|
||||
"preferences_dark_mode_label": "थीम: ",
|
||||
"preferences_default_home_label": "डिफ़ॉल्ट मुखपृष्ठ: ",
|
||||
"Could not fetch comments": "टिप्पणियाँ प्राप्त न की जा सकीं",
|
||||
"comments_points_count": "{{count}} पॉइंट",
|
||||
"comments_points_count_plural": "{{count}} पॉइंट्स",
|
||||
"Subscription manager": "सदस्यता प्रबंधन",
|
||||
"License: ": "लाइसेंस: ",
|
||||
"Wilson score: ": "Wilson स्कोर: ",
|
||||
"Wrong answer": "गलत जवाब",
|
||||
"Erroneous CAPTCHA": "गलत CAPTCHA",
|
||||
"Please log in": "कृपया लॉग-इन करें",
|
||||
"Bosnian": "बोस्नियाई",
|
||||
"Bulgarian": "बुल्गारियाई",
|
||||
"Burmese": "बर्मी",
|
||||
"Chinese (Traditional)": "चीनी (पारंपरिक)",
|
||||
"Kurdish": "कुर्द",
|
||||
"Punjabi": "पंजाबी",
|
||||
"Sinhala": "सिंहली",
|
||||
"Slovak": "स्लोवाक",
|
||||
"generic_count_days": "{{count}} दिन",
|
||||
"generic_count_days_plural": "{{count}} दिन",
|
||||
"generic_count_hours": "{{count}} घंटे",
|
||||
"generic_count_hours_plural": "{{count}} घंटे",
|
||||
"generic_count_minutes": "{{count}} मिनट",
|
||||
"generic_count_minutes_plural": "{{count}} मिनट",
|
||||
"generic_count_seconds": "{{count}} सेकंड",
|
||||
"generic_count_seconds_plural": "{{count}} सेकंड",
|
||||
"generic_playlists_count": "{{count}} प्लेलिस्ट",
|
||||
"generic_playlists_count_plural": "{{count}} प्लेलिस्ट्स",
|
||||
"crash_page_report_issue": "अगर इनमें से कुछ भी काम नहीं करता, कृपया <a href=\"`x`\">GitHub पर एक नया मुद्दा खोल दें</a> (अंग्रेज़ी में) और अपने संदेश में यह टेक्स्ट दर्ज करें (इसे अनुवादित न करें!):",
|
||||
"generic_views_count": "{{count}} बार देखा गया",
|
||||
"generic_views_count_plural": "{{count}} बार देखा गया",
|
||||
"generic_videos_count": "{{count}} वीडियो",
|
||||
"generic_videos_count_plural": "{{count}} वीडियो",
|
||||
"generic_subscribers_count": "{{count}} सदस्य",
|
||||
"generic_subscribers_count_plural": "{{count}} सदस्य",
|
||||
"generic_subscriptions_count": "{{count}} सदस्यता",
|
||||
"generic_subscriptions_count_plural": "{{count}} सदस्यताएँ",
|
||||
"LIVE": "लाइव",
|
||||
"Shared `x` ago": "`x` पहले बाँटा गया",
|
||||
"Unsubscribe": "सदस्यता छोड़ें",
|
||||
"Subscribe": "सदस्यता लें",
|
||||
"View channel on YouTube": "चैनल YouTube पर देखें",
|
||||
"View playlist on YouTube": "प्लेलिस्ट YouTube पर देखें",
|
||||
"newest": "सबसे नया",
|
||||
"oldest": "सबसे पुराना",
|
||||
"popular": "सर्वाधिक लोकप्रिय",
|
||||
"Next page": "अगला पृष्ठ",
|
||||
"Previous page": "पिछला पृष्ठ",
|
||||
"Clear watch history?": "देखने का इतिहास मिटाएँ?",
|
||||
"New password": "नया पासवर्ड",
|
||||
"New passwords must match": "पासवर्ड्स को मेल खाना होगा",
|
||||
"Cannot change password for Google accounts": "Google खातों के लिए पासवर्ड नहीं बदल सकते",
|
||||
"Authorize token?": "टोकन को प्रमाणित करें?",
|
||||
"Authorize token for `x`?": "`x` के लिए टोकन को प्रमाणित करें?",
|
||||
"Import and Export Data": "डेटा को आयात और निर्यात करें",
|
||||
"Import": "आयात करें",
|
||||
"Import Invidious data": "Invidious JSON डेटा आयात करें",
|
||||
"Import YouTube subscriptions": "YouTube/OPML सदस्यताएँ आयात करें",
|
||||
"Import FreeTube subscriptions (.db)": "FreeTube सदस्यताएँ आयात करें (.db)",
|
||||
"Import NewPipe subscriptions (.json)": "NewPipe सदस्यताएँ आयात करें (.json)",
|
||||
"Import NewPipe data (.zip)": "NewPipe डेटा आयात करें (.zip)",
|
||||
"Export": "निर्यात करें",
|
||||
"Export subscriptions as OPML": "OPML के रूप में सदस्यताएँ निर्यात करें",
|
||||
"Export data as JSON": "Invidious डेटा को JSON के रूप में निर्यात करें",
|
||||
"Delete account?": "खाता हटाएँ?",
|
||||
"History": "देखे गए वीडियो",
|
||||
"An alternative front-end to YouTube": "YouTube का एक वैकल्पिक फ्रंट-एंड",
|
||||
"JavaScript license information": "जावास्क्रिप्ट लाइसेंस की जानकारी",
|
||||
"source": "स्रोत",
|
||||
"Log in": "लॉग-इन करें",
|
||||
"User ID": "सदस्य ID",
|
||||
"Password": "पासवर्ड",
|
||||
"Register": "पंजीकृत करें",
|
||||
"E-mail": "ईमेल",
|
||||
"Google verification code": "Google प्रमाणीकरण कोड",
|
||||
"Time (h:mm:ss):": "समय (घं:मिमि:सेसे):",
|
||||
"Text CAPTCHA": "टेक्स्ट CAPTCHA",
|
||||
"Image CAPTCHA": "चित्र CAPTCHA",
|
||||
"Sign In": "साइन इन करें",
|
||||
"Preferences": "प्राथमिकताएँ",
|
||||
"preferences_category_player": "प्लेयर की प्राथमिकताएँ",
|
||||
"preferences_video_loop_label": "हमेशा लूप करें: ",
|
||||
"preferences_continue_label": "डिफ़ॉल्ट से अगला चलाएँ: ",
|
||||
"preferences_continue_autoplay_label": "अगला वीडियो अपने आप चलाएँ: ",
|
||||
"preferences_listen_label": "डिफ़ॉल्ट से सुनें: ",
|
||||
"preferences_local_label": "प्रॉक्सी वीडियो: ",
|
||||
"preferences_watch_history_label": "देखने का इतिहास सक्षम करें: ",
|
||||
"preferences_speed_label": "वीडियो चलाने की डिफ़ॉल्ट रफ़्तार: ",
|
||||
"preferences_quality_label": "वीडियो की प्राथमिक क्वालिटी: ",
|
||||
"preferences_quality_option_dash": "DASH (अनुकूली गुणवत्ता)",
|
||||
"preferences_quality_option_hd720": "HD720",
|
||||
"preferences_quality_option_medium": "मध्यम",
|
||||
"preferences_quality_option_small": "छोटा",
|
||||
"preferences_quality_dash_label": "प्राथमिक DASH वीडियो क्वालिटी: ",
|
||||
"preferences_quality_dash_option_720p": "720p",
|
||||
"preferences_quality_dash_option_auto": "अपने-आप",
|
||||
"preferences_quality_dash_option_best": "सबसे अच्छा",
|
||||
"preferences_quality_dash_option_worst": "सबसे खराब",
|
||||
"preferences_quality_dash_option_4320p": "4320p",
|
||||
"preferences_quality_dash_option_2160p": "2160p",
|
||||
"preferences_quality_dash_option_1440p": "1440p",
|
||||
"preferences_quality_dash_option_1080p": "1080p",
|
||||
"preferences_quality_dash_option_480p": "480p",
|
||||
"preferences_quality_dash_option_360p": "360p",
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"preferences_comments_label": "डिफ़ॉल्ट टिप्पणियाँ: ",
|
||||
"preferences_volume_label": "प्लेयर का वॉल्यूम: ",
|
||||
"youtube": "YouTube",
|
||||
"reddit": "Reddit",
|
||||
"invidious": "Invidious",
|
||||
"preferences_captions_label": "डिफ़ॉल्ट कैप्शन: ",
|
||||
"Fallback captions: ": "वैकल्पिक कैप्शन: ",
|
||||
"preferences_related_videos_label": "संबंधित वीडियो दिखाएँ: ",
|
||||
"preferences_annotations_label": "डिफ़ॉल्ट से टिप्पणियाँ दिखाएँ: ",
|
||||
"preferences_extend_desc_label": "अपने आप वीडियो के विवरण का विस्तार करें: ",
|
||||
"preferences_vr_mode_label": "उत्तरदायी 360 डिग्री वीडियो (WebGL की ज़रूरत है): ",
|
||||
"preferences_category_visual": "यथादृश्य प्राथमिकताएँ",
|
||||
"preferences_region_label": "सामग्री का राष्ट्र: ",
|
||||
"preferences_player_style_label": "प्लेयर का स्टाइल: ",
|
||||
"Dark mode: ": "डार्क मोड: ",
|
||||
"dark": "डार्क",
|
||||
"light": "लाइट",
|
||||
"preferences_thin_mode_label": "हल्का मोड: ",
|
||||
"preferences_category_misc": "विविध प्राथमिकताएँ",
|
||||
"preferences_automatic_instance_redirect_label": "अपने आप अनुप्रेषित करें (redirect.invidious.io पर फ़ॉलबैक करें): ",
|
||||
"preferences_category_subscription": "सदस्यताओं की प्राथमिकताएँ",
|
||||
"preferences_annotations_subscribed_label": "सदस्यता लिए गए चैनलों पर डिफ़ॉल्ट से टिप्पणियाँ दिखाएँ? ",
|
||||
"Redirect homepage to feed: ": "फ़ीड पर मुखपृष्ठ को अनुप्रेषित करें: ",
|
||||
"preferences_max_results_label": "फ़ीड में दिखाए जाने वाले वीडियों की संख्या: ",
|
||||
"preferences_sort_label": "वीडियों को इस मानदंड पर छाँटें: ",
|
||||
"published": "प्रकाशित",
|
||||
"published - reverse": "प्रकाशित - उल्टा",
|
||||
"Only show latest video from channel: ": "चैनल से सिर्फ नवीनतम वीडियो ही दिखाएँ: ",
|
||||
"alphabetically": "वर्णक्रमानुसार",
|
||||
"Only show latest unwatched video from channel: ": "चैनल से सिर्फ न देखा गया नवीनतम वीडियो ही दिखाएँ: ",
|
||||
"alphabetically - reverse": "वर्णक्रमानुसार - उल्टा",
|
||||
"channel name": "चैनल का नाम",
|
||||
"channel name - reverse": "चैनल का नाम - उल्टा",
|
||||
"preferences_unseen_only_label": "सिर्फ न देखे गए वीडियो ही दिखाएँ: ",
|
||||
"preferences_notifications_only_label": "सिर्फ सूचनाएँ दिखाएँ (अगर हो तो): ",
|
||||
"Enable web notifications": "वेब सूचनाएँ सक्षम करें",
|
||||
"`x` uploaded a video": "`x` ने वीडियो अपलोड किया",
|
||||
"`x` is live": "`x` लाइव हैं",
|
||||
"preferences_category_data": "डेटा की प्राथमिकताएँ",
|
||||
"Clear watch history": "देखने का इतिहास साफ़ करें",
|
||||
"Import/export data": "डेटा को आयात/निर्यात करें",
|
||||
"Change password": "पासवर्ड बदलें",
|
||||
"Manage subscriptions": "सदस्यताएँ प्रबंधित करें",
|
||||
"Manage tokens": "टोकन प्रबंधित करें",
|
||||
"Watch history": "देखने का इतिहास",
|
||||
"Delete account": "खाता हटाएँ",
|
||||
"preferences_category_admin": "प्रबंधक प्राथमिकताएँ",
|
||||
"preferences_feed_menu_label": "फ़ीड मेन्यू: ",
|
||||
"preferences_show_nick_label": "ऊपर उपनाम दिखाएँ: ",
|
||||
"Top enabled: ": "ऊपर का हिस्सा सक्षम है: ",
|
||||
"CAPTCHA enabled: ": "CAPTCHA सक्षम है: ",
|
||||
"Login enabled: ": "लॉग-इन सक्षम है: ",
|
||||
"Registration enabled: ": "पंजीकरण सक्षम है: ",
|
||||
"Report statistics: ": "सांख्यिकी रिपोर्ट करें: ",
|
||||
"Released under the AGPLv3 on Github.": "GitHub पर AGPLv3 के अंतर्गत प्रकाशित।",
|
||||
"Save preferences": "प्राथमिकताएँ सहेजें",
|
||||
"Token manager": "टोकन प्रबंधन",
|
||||
"Token": "टोकन",
|
||||
"tokens_count": "{{count}} टोकन",
|
||||
"tokens_count_plural": "{{count}} टोकन",
|
||||
"Import/export": "आयात/निर्यात करें",
|
||||
"unsubscribe": "सदस्यता छोड़ें",
|
||||
"revoke": "हटाएँ",
|
||||
"Subscriptions": "सदस्यताएँ",
|
||||
"subscriptions_unseen_notifs_count": "{{count}} अपठित सूचना",
|
||||
"subscriptions_unseen_notifs_count_plural": "{{count}} अपठित सूचना",
|
||||
"search": "खोजें",
|
||||
"Log out": "लॉग-आउट करें",
|
||||
"Source available here.": "स्रोत यहाँ उपलब्ध है।",
|
||||
"View JavaScript license information.": "जावास्क्रिप्ट लाइसेंस की जानकारी देखें।",
|
||||
"View privacy policy.": "निजता नीति देखें।",
|
||||
"Trending": "रुझान में",
|
||||
"Public": "सार्वजनिक",
|
||||
"Unlisted": "सबके लिए उपलब्ध नहीं",
|
||||
"Private": "निजी",
|
||||
"View all playlists": "सभी प्लेलिस्ट देखें",
|
||||
"Create playlist": "प्लेलिस्ट बनाएँ",
|
||||
"Updated `x` ago": "`x` पहले अपडेट किया गया",
|
||||
"Delete playlist `x`?": "प्लेलिस्ट `x` हटाएँ?",
|
||||
"Delete playlist": "प्लेलिस्ट हटाएँ",
|
||||
"Title": "शीर्षक",
|
||||
"Playlist privacy": "प्लेलिस्ट की निजता",
|
||||
"Editing playlist `x`": "प्लेलिस्ट `x` को संपादित किया जा रहा है",
|
||||
"Show more": "अधिक देखें",
|
||||
"Show less": "कम देखें",
|
||||
"Watch on YouTube": "YouTube पर देखें",
|
||||
"Switch Invidious Instance": "Invidious उदाहरण बदलें",
|
||||
"search_message_no_results": "कोई परिणाम नहीं मिला।",
|
||||
"search_message_change_filters_or_query": "अपने खोज क्वेरी को और चौड़ा करें और/या फ़िल्टर बदलें।",
|
||||
"search_message_use_another_instance": " आप <a href=\"`x`\">दूसरे उदाहरण पर भी खोज सकते हैं</a>।",
|
||||
"Hide annotations": "टिप्पणियाँ छिपाएँ",
|
||||
"Show annotations": "टिप्पणियाँ दिखाएँ",
|
||||
"Genre: ": "श्रेणी: ",
|
||||
"Family friendly? ": "परिवार के लिए ठीक है? ",
|
||||
"Engagement: ": "सगाई: ",
|
||||
"Whitelisted regions: ": "स्वीकृत क्षेत्र: ",
|
||||
"Blacklisted regions: ": "अस्वीकृत क्षेत्र: ",
|
||||
"Shared `x`": "`x` बाँटा गया",
|
||||
"Premieres in `x`": "`x` बाद प्रीमियर होगा",
|
||||
"Premieres `x`": "`x` को प्रीमिर होगा",
|
||||
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "नमस्कार! ऐसा लगता है कि आपका जावास्क्रिप्ट अक्षम है। टिप्पणियाँ देखने के लिए यहाँ क्लिक करें, लेकिन याद रखें कि इन्हें लोड होने में थोड़ा ज़्यादा समय लग सकता है।",
|
||||
"View YouTube comments": "YouTube टिप्पणियाँ देखें",
|
||||
"View more comments on Reddit": "Reddit पर अधिक टिप्पणियाँ देखें",
|
||||
"View `x` comments": {
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` टिप्पणी देखें",
|
||||
"": "`x` टिप्पणियाँ देखें"
|
||||
},
|
||||
"View Reddit comments": "Reddit पर टिप्पणियाँ",
|
||||
"Hide replies": "जवाब छिपाएँ",
|
||||
"Show replies": "जवाब दिखाएँ",
|
||||
"Incorrect password": "गलत पासवर्ड",
|
||||
"Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "लॉग-इन नहीं किया जा सका, सुनिश्चित करें कि दो-कारक प्रमाणीकरण (Authenticator या SMS) सक्षम है।",
|
||||
"Invalid TFA code": "अमान्य TFA कोड",
|
||||
"Login failed. This may be because two-factor authentication is not turned on for your account.": "लॉग-इन नाकाम रहा। ऐसा इसलिए हो सकता है कि दो-कारक प्रमाणीकरण आपके खाते पर सक्षम नहीं है।",
|
||||
"Quota exceeded, try again in a few hours": "कोटा पार हो चुका है, कृपया कुछ घंटों में फिर कोशिश करें",
|
||||
"CAPTCHA is a required field": "CAPTCHA एक ज़रूरी फ़ील्ड है",
|
||||
"User ID is a required field": "सदस्य ID एक ज़रूरी फ़ील्ड है",
|
||||
"Password is a required field": "पासवर्ड एक ज़रूरी फ़ील्ड है",
|
||||
"Wrong username or password": "गलत सदस्यनाम या पासवर्ड",
|
||||
"Please sign in using 'Log in with Google'": "कृपया 'Google के साथ लॉग-इन करें' के साथ साइन-इन करें",
|
||||
"Password cannot be empty": "पासवर्ड खाली नहीं हो सकता",
|
||||
"Password cannot be longer than 55 characters": "पासवर्ड में अधिकतम 55 अक्षर हो सकते हैं",
|
||||
"Invidious Private Feed for `x`": "`x` के लिए Invidious निजी फ़ीड",
|
||||
"channel:`x`": "चैनल:`x`",
|
||||
"Deleted or invalid channel": "हटाया गया या अमान्य चैनल",
|
||||
"This channel does not exist.": "यह चैनल मौजूद नहीं है।",
|
||||
"Could not get channel info.": "चैनल की जानकारी प्राप्त न की जा सकी।",
|
||||
"comments_view_x_replies": "{{count}} टिप्पणी देखें",
|
||||
"comments_view_x_replies_plural": "{{count}} टिप्पणियाँ देखें",
|
||||
"`x` ago": "`x` पहले",
|
||||
"Load more": "अधिक लोड करें",
|
||||
"Could not create mix.": "मिक्स न बनाया जा सका।",
|
||||
"Empty playlist": "खाली प्लेलिस्ट",
|
||||
"Not a playlist.": "यह प्लेलिस्ट नहीं है।",
|
||||
"Playlist does not exist.": "प्लेलिस्ट मौजूद नहीं है।",
|
||||
"Could not pull trending pages.": "रुझान के पृष्ठ प्राप्त न किए जा सके।",
|
||||
"Hidden field \"challenge\" is a required field": "छिपाया गया फ़ील्ड \"चुनौती\" एक आवश्यक फ़ील्ड है",
|
||||
"Hidden field \"token\" is a required field": "छिपाया गया फ़ील्ड \"टोकन\" एक आवश्यक फ़ील्ड है",
|
||||
"Erroneous challenge": "त्रुटिपूर्ण चुनौती",
|
||||
"Erroneous token": "त्रुटिपूर्ण टोकन",
|
||||
"No such user": "यह सदस्य मौजूद नहीं हैं",
|
||||
"Token is expired, please try again": "टोकन की समय-सीमा समाप्त हो चुकी है, कृपया दोबारा कोशिश करें",
|
||||
"English": "अंग्रेज़ी",
|
||||
"English (United Kingdom)": "अंग्रेज़ी (यूनाइटेड किंग्डम)",
|
||||
"English (United States)": "अंग्रेज़ी (संयुक्त राष्ट्र)",
|
||||
"English (auto-generated)": "अंग्रेज़ी (अपने-आप जनरेट हुआ)",
|
||||
"Afrikaans": "अफ़्रीकी",
|
||||
"Albanian": "अल्बानियाई",
|
||||
"Amharic": "अम्हेरी",
|
||||
"Arabic": "अरबी",
|
||||
"Armenian": "आर्मेनियाई",
|
||||
"Belarusian": "बेलारूसी",
|
||||
"Azerbaijani": "अज़रबैजानी",
|
||||
"Bangla": "बंगाली",
|
||||
"Basque": "बास्क",
|
||||
"Cantonese (Hong Kong)": "कैंटोनीज़ (हाँग काँग)",
|
||||
"Catalan": "कातालान",
|
||||
"Cebuano": "सेबुआनो",
|
||||
"Chinese": "चीनी",
|
||||
"Chinese (China)": "चीनी (चीन)",
|
||||
"Chinese (Hong Kong)": "चीनी (हाँग काँग)",
|
||||
"Chinese (Simplified)": "चीनी (सरलीकृत)",
|
||||
"Chinese (Taiwan)": "चीनी (ताइवान)",
|
||||
"Corsican": "कोर्सिकन",
|
||||
"Croatian": "क्रोएशियाई",
|
||||
"Czech": "चेक",
|
||||
"Danish": "डेनिश",
|
||||
"Dutch": "डच",
|
||||
"Dutch (auto-generated)": "डच (अपने-आप जनरेट हुआ)",
|
||||
"Esperanto": "एस्पेरांतो",
|
||||
"Estonian": "एस्टोनियाई",
|
||||
"Filipino": "फ़िलिपीनो",
|
||||
"Finnish": "फ़िनिश",
|
||||
"French": "फ़्रेंच",
|
||||
"French (auto-generated)": "फ़्रेंच (अपने-आप जनरेट हुआ)",
|
||||
"Galician": "गैलिशियन",
|
||||
"Georgian": "जॉर्जियाई",
|
||||
"German": "जर्मन",
|
||||
"German (auto-generated)": "जर्मन (अपने-आप जनरेट हुआ)",
|
||||
"Greek": "यूनानी",
|
||||
"Gujarati": "गुजराती",
|
||||
"Haitian Creole": "हैती क्रियोल",
|
||||
"Hausa": "हौसा",
|
||||
"Hawaiian": "हवाई",
|
||||
"Hebrew": "हीब्रू",
|
||||
"Hindi": "हिन्दी",
|
||||
"Hmong": "हमोंग",
|
||||
"Hungarian": "हंगेरी",
|
||||
"Icelandic": "आइसलैंडिक",
|
||||
"Igbo": "इग्बो",
|
||||
"Indonesian": "इंडोनेशियाई",
|
||||
"Indonesian (auto-generated)": "इंडोनेशियाई (अपने-आप जनरेट हुआ)",
|
||||
"Interlingue": "इंटरलिंगुआ",
|
||||
"Irish": "आयरिश",
|
||||
"Italian": "इतालवी",
|
||||
"Italian (auto-generated)": "इतालवी (अपने-आप जनरेट हुआ)",
|
||||
"Japanese": "जापानी",
|
||||
"Japanese (auto-generated)": "जापानी (अपने-आप जनरेट हुआ)",
|
||||
"Javanese": "जावानीज़",
|
||||
"Kannada": "कन्नड़",
|
||||
"Kazakh": "कज़ाख़",
|
||||
"Khmer": "खमेर",
|
||||
"Korean": "कोरियाई",
|
||||
"Korean (auto-generated)": "कोरियाई (अपने-आप जनरेट हुआ)",
|
||||
"Kyrgyz": "किर्गीज़",
|
||||
"Lao": "लाओ",
|
||||
"Latin": "लैटिन",
|
||||
"Latvian": "लातवियाई",
|
||||
"Lithuanian": "लिथुएनियाई",
|
||||
"Luxembourgish": "लग्ज़मबर्गी",
|
||||
"Macedonian": "मकादूनियाई",
|
||||
"Malagasy": "मालागासी",
|
||||
"Malay": "मलय",
|
||||
"Malayalam": "मलयालम",
|
||||
"Maltese": "माल्टीज़",
|
||||
"Maori": "माओरी",
|
||||
"Marathi": "मराठी",
|
||||
"Mongolian": "मंगोलियाई",
|
||||
"Nepali": "नेपाली",
|
||||
"Norwegian Bokmål": "नॉर्वेजियाई",
|
||||
"Nyanja": "न्यानजा",
|
||||
"Pashto": "पश्तो",
|
||||
"Persian": "फ़ारसी",
|
||||
"Polish": "पोलिश",
|
||||
"Portuguese": "पुर्तगाली",
|
||||
"Portuguese (auto-generated)": "पुर्तगाली (अपने-आप जनरेट हुआ)",
|
||||
"Portuguese (Brazil)": "पुर्तगाली (ब्राज़ील)",
|
||||
"Romanian": "रोमेनियाई",
|
||||
"Russian": "रूसी",
|
||||
"Russian (auto-generated)": "रूसी (अपने-आप जनरेट हुआ)",
|
||||
"Samoan": "सामोन",
|
||||
"Scottish Gaelic": "स्कॉटिश गाएलिक",
|
||||
"Serbian": "सर्बियाई",
|
||||
"Shona": "शोणा",
|
||||
"Sindhi": "सिंधी",
|
||||
"Slovenian": "स्लोवेनियाई",
|
||||
"Somali": "सोमाली",
|
||||
"Southern Sotho": "दक्षिणी सोथो",
|
||||
"Spanish": "स्पेनी",
|
||||
"Spanish (auto-generated)": "स्पेनी (अपने-आप जनरेट हुआ)",
|
||||
"Spanish (Latin America)": "स्पेनी (लातिन अमेरिकी)",
|
||||
"Spanish (Mexico)": "स्पेनी (मेक्सिको)",
|
||||
"Spanish (Spain)": "स्पेनी (स्पेन)",
|
||||
"Sundanese": "सुंडानी",
|
||||
"Swahili": "स्वाहिली",
|
||||
"Swedish": "स्वीडिश",
|
||||
"Tajik": "ताजीक",
|
||||
"Tamil": "तमिल",
|
||||
"Telugu": "तेलुगु",
|
||||
"Thai": "थाई",
|
||||
"Turkish": "तुर्की",
|
||||
"Turkish (auto-generated)": "तुर्की (अपने-आप जनरेट हुआ)",
|
||||
"Ukrainian": "यूक्रेनी",
|
||||
"Urdu": "उर्दू",
|
||||
"Uzbek": "उज़्बेक",
|
||||
"Vietnamese": "वियतनामी",
|
||||
"Vietnamese (auto-generated)": "वियतनामी (अपने-आप जनरेट हुआ)",
|
||||
"Welsh": "Welsh",
|
||||
"Western Frisian": "पश्चिमी फ़्रिसियाई",
|
||||
"Xhosa": "खोसा",
|
||||
"Yiddish": "यहूदी",
|
||||
"generic_count_years": "{{count}} वर्ष",
|
||||
"generic_count_years_plural": "{{count}} वर्ष",
|
||||
"Yoruba": "योरुबा",
|
||||
"generic_count_months": "{{count}} महीने",
|
||||
"generic_count_months_plural": "{{count}} महीने",
|
||||
"Zulu": "ज़ूलू",
|
||||
"generic_count_weeks": "{{count}} हफ़्ते",
|
||||
"generic_count_weeks_plural": "{{count}} हफ़्ते",
|
||||
"Fallback comments: ": "फ़ॉलबैक टिप्पणियाँ: ",
|
||||
"Popular": "प्रसिद्ध",
|
||||
"Search": "खोजें",
|
||||
"Top": "ऊपर",
|
||||
"About": "जानकारी",
|
||||
"Rating: ": "रेटिंग: ",
|
||||
"preferences_locale_label": "भाषा: ",
|
||||
"View as playlist": "प्लेलिस्ट के रूप में देखें",
|
||||
"Default": "डिफ़ॉल्ट",
|
||||
"Download": "डाउनलोड करें",
|
||||
"Download as: ": "इस रूप में डाउनलोड करें: ",
|
||||
"%A %B %-d, %Y": "%A %B %-d, %Y",
|
||||
"Music": "संगीत",
|
||||
"Gaming": "गेमिंग",
|
||||
"News": "समाचार",
|
||||
"Movies": "फ़िल्में",
|
||||
"(edited)": "(संपादित)",
|
||||
"YouTube comment permalink": "YouTube पर टिप्पणी की स्थायी कड़ी",
|
||||
"permalink": "स्थायी कड़ी",
|
||||
"Videos": "वीडियो",
|
||||
"`x` marked it with a ❤": "`x` ने इसे एक ❤ से चिह्नित किया",
|
||||
"Audio mode": "ऑडियो मोड",
|
||||
"Playlists": "प्लेलिस्ट्स",
|
||||
"Video mode": "वीडियो मोड",
|
||||
"Community": "समुदाय",
|
||||
"search_filters_title": "फ़िल्टर",
|
||||
"search_filters_date_label": "अपलोड करने का समय",
|
||||
"search_filters_date_option_none": "कोई भी समय",
|
||||
"search_filters_date_option_week": "इस हफ़्ते",
|
||||
"search_filters_date_option_month": "इस महीने",
|
||||
"search_filters_date_option_hour": "पिछला घंटा",
|
||||
"search_filters_date_option_today": "आज",
|
||||
"search_filters_date_option_year": "इस साल",
|
||||
"search_filters_type_label": "प्रकार",
|
||||
"search_filters_type_option_all": "कोई भी प्रकार",
|
||||
"search_filters_type_option_video": "वीडियो",
|
||||
"search_filters_type_option_channel": "चैनल",
|
||||
"search_filters_sort_option_relevance": "प्रासंगिकता",
|
||||
"search_filters_type_option_playlist": "प्लेलिस्ट",
|
||||
"search_filters_type_option_movie": "फ़िल्म",
|
||||
"search_filters_type_option_show": "शो",
|
||||
"search_filters_duration_label": "अवधि",
|
||||
"search_filters_duration_option_none": "कोई भी अवधि",
|
||||
"search_filters_duration_option_short": "4 मिनट से कम",
|
||||
"search_filters_duration_option_medium": "4 से 20 मिनट तक",
|
||||
"search_filters_duration_option_long": "20 मिनट से ज़्यादा",
|
||||
"search_filters_features_label": "सुविधाएँ",
|
||||
"search_filters_features_option_live": "लाइव",
|
||||
"search_filters_sort_option_rating": "रेटिंग",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "उपशीर्षक/कैप्शन",
|
||||
"search_filters_features_option_c_commons": "क्रिएटिव कॉमन्स",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"search_filters_features_option_location": "जगह",
|
||||
"search_filters_features_option_purchased": "खरीदा गया",
|
||||
"search_filters_sort_label": "इस क्रम से लगाएँ",
|
||||
"search_filters_sort_option_date": "अपलोड की ताऱीख",
|
||||
"search_filters_sort_option_views": "देखे जाने की संख्या",
|
||||
"search_filters_apply_button": "चयनित फ़िल्टर लागू करें",
|
||||
"footer_documentation": "प्रलेख",
|
||||
"footer_source_code": "स्रोत कोड",
|
||||
"footer_original_source_code": "मूल स्रोत कोड",
|
||||
"footer_modfied_source_code": "बदला गया स्रोत कोड",
|
||||
"Current version: ": "वर्तमान संस्करण: ",
|
||||
"next_steps_error_message": "इसके बाद आपके ये आज़माने चाहिए: ",
|
||||
"next_steps_error_message_refresh": "साफ़ करें",
|
||||
"next_steps_error_message_go_to_youtube": "YouTube पर जाएँ",
|
||||
"footer_donate_page": "दान करें",
|
||||
"adminprefs_modified_source_code_url_label": "बदले गए स्रोत कोड के रिपॉज़िटरी का URL",
|
||||
"none": "कुछ नहीं",
|
||||
"videoinfo_started_streaming_x_ago": "`x` पहले स्ट्रीम करना शुरू किया",
|
||||
"videoinfo_watch_on_youTube": "YouTube पर देखें",
|
||||
"Video unavailable": "वीडियो उपलब्ध नहीं है",
|
||||
"preferences_save_player_pos_label": "यहाँ से चलाना शुरू करें: ",
|
||||
"crash_page_you_found_a_bug": "शायद आपको Invidious में कोई बग नज़र आ गया है!",
|
||||
"videoinfo_youTube_embed_link": "एम्बेड करें",
|
||||
"videoinfo_invidious_embed_link": "एम्बेड करने की कड़ी",
|
||||
"download_subtitles": "उपशीर्षक - `x` (.vtt)",
|
||||
"user_created_playlists": "बनाए गए `x` प्लेलिस्ट्स",
|
||||
"user_saved_playlists": "सहेजे गए `x` प्लेलिस्ट्स",
|
||||
"crash_page_before_reporting": "बग रिपोर्ट करने से पहले:",
|
||||
"crash_page_switch_instance": "<a href=\"`x`\">किसी दूसरे उदाहरण का इस्तेमाल करें</a>",
|
||||
"crash_page_read_the_faq": "<a href=\"`x`\">अक्सर पूछे जाने वाले प्रश्न (FAQ)</a> पढ़ें",
|
||||
"crash_page_refresh": "<a href=\"`x`\">पृष्ठ को एक बार साफ़ करें</a>",
|
||||
"crash_page_search_issue": "<a href=\"`x`\">GitHub पर मौजूदा मुद्दे</a> ढूँढ़ें"
|
||||
}
|
||||
@@ -88,7 +88,7 @@
|
||||
"channel name": "ime kanala",
|
||||
"channel name - reverse": "ime kanala – obrnuto",
|
||||
"Only show latest video from channel: ": "Prikaži samo najnovija videa kanala: ",
|
||||
"Only show latest unwatched video from channel: ": "Prikaži samo najnovija nepogledana videa kanala: ",
|
||||
"Only show latest unwatched video from channel: ": "Prikaži samo najnovija nepogledana videa od kanala: ",
|
||||
"preferences_unseen_only_label": "Prikaži samo nepogledane: ",
|
||||
"preferences_notifications_only_label": "Prikaži samo obavijesti (ako ih ima): ",
|
||||
"Enable web notifications": "Aktiviraj web-obavijesti",
|
||||
@@ -107,7 +107,7 @@
|
||||
"preferences_feed_menu_label": "Izbornik za feedove: ",
|
||||
"preferences_show_nick_label": "Prikaži nadimak na vrhu: ",
|
||||
"Top enabled: ": "Najbolji aktivirani: ",
|
||||
"CAPTCHA enabled: ": "Aktivirani CAPTCHA: ",
|
||||
"CAPTCHA enabled: ": "CAPTCHA aktiviran: ",
|
||||
"Login enabled: ": "Prijava aktivirana: ",
|
||||
"Registration enabled: ": "Registracija aktivirana: ",
|
||||
"Report statistics: ": "Izvještaj o statistici: ",
|
||||
@@ -121,7 +121,7 @@
|
||||
"Subscriptions": "Pretplate",
|
||||
"search": "traži",
|
||||
"Log out": "Odjavi se",
|
||||
"Released under the AGPLv3 on Github.": "Izdano pod licencom AGPLv3 na Github-u.",
|
||||
"Released under the AGPLv3 on Github.": "Izdano pod licencom AGPLv3 na GitHub-u.",
|
||||
"Source available here.": "Izvor je ovdje dostupan.",
|
||||
"View JavaScript license information.": "Prikaži informacije o JavaScript licenci.",
|
||||
"View privacy policy.": "Prikaži politiku privatnosti.",
|
||||
@@ -137,11 +137,10 @@
|
||||
"Title": "Naslov",
|
||||
"Playlist privacy": "Privatnost zbirke",
|
||||
"Editing playlist `x`": "Uređivanje zbirke `x`",
|
||||
"Show more": "Pokaži više",
|
||||
"Show less": "Pokaži manje",
|
||||
"Show more": "Prikaži više",
|
||||
"Show less": "Prikaži manje",
|
||||
"Watch on YouTube": "Gledaj na YouTubeu",
|
||||
"Switch Invidious Instance": "Promijeni Invidious instancu",
|
||||
"Broken? Try another Invidious Instance": "Pokvarena? Probaj jednu drugu Invidious instancu",
|
||||
"Hide annotations": "Sakrij napomene",
|
||||
"Show annotations": "Prikaži napomene",
|
||||
"Genre: ": "Žanr: ",
|
||||
@@ -319,7 +318,7 @@
|
||||
"Movies": "Filmovi",
|
||||
"Download": "Preuzmi",
|
||||
"Download as: ": "Preuzmi kao: ",
|
||||
"%A %B %-d, %Y": "%A, %-d. %B %Y",
|
||||
"%A %B %-d, %Y": "%A, %-d. %B %Y.",
|
||||
"(edited)": "(uređeno)",
|
||||
"YouTube comment permalink": "Stalna poveznica YouTube komentara",
|
||||
"permalink": "stalna poveznica",
|
||||
@@ -329,41 +328,40 @@
|
||||
"Videos": "Videa",
|
||||
"Playlists": "Zbirke",
|
||||
"Community": "Zajednica",
|
||||
"relevance": "značaj",
|
||||
"rating": "ocjena",
|
||||
"date": "datum",
|
||||
"views": "prikazi",
|
||||
"content_type": "vrsta_sadržaja",
|
||||
"duration": "trajanje",
|
||||
"features": "funkcije",
|
||||
"sort": "redoslijed",
|
||||
"hour": "sat",
|
||||
"today": "danas",
|
||||
"week": "tjedan",
|
||||
"month": "mjesec",
|
||||
"year": "godina",
|
||||
"video": "video",
|
||||
"channel": "kanal",
|
||||
"playlist": "Zbirka",
|
||||
"movie": "film",
|
||||
"show": "emisija",
|
||||
"hd": "hd",
|
||||
"subtitles": "titlovi",
|
||||
"creative_commons": "creative_commons",
|
||||
"3d": "3d",
|
||||
"live": "uživo",
|
||||
"4k": "4k",
|
||||
"location": "lokacija",
|
||||
"hdr": "hdr",
|
||||
"filter": "filtar",
|
||||
"search_filters_sort_option_relevance": "Značaj",
|
||||
"search_filters_sort_option_rating": "Ocjena",
|
||||
"search_filters_sort_option_date": "Datum prijenosa",
|
||||
"search_filters_sort_option_views": "Broj gledanja",
|
||||
"search_filters_type_label": "Vrsta",
|
||||
"search_filters_duration_label": "Trajanje",
|
||||
"search_filters_features_label": "Funkcije",
|
||||
"search_filters_sort_label": "Redoslijed",
|
||||
"search_filters_date_option_hour": "Zadnjih sat vremena",
|
||||
"search_filters_date_option_today": "Danas",
|
||||
"search_filters_date_option_week": "Ovaj tjedan",
|
||||
"search_filters_date_option_month": "Ovaj mjesec",
|
||||
"search_filters_date_option_year": "Ova godina",
|
||||
"search_filters_type_option_video": "Video",
|
||||
"search_filters_type_option_channel": "Kanal",
|
||||
"search_filters_type_option_playlist": "Zbirka",
|
||||
"search_filters_type_option_movie": "Film",
|
||||
"search_filters_type_option_show": "Emisija",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "Titlovi/CC",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_live": "Uživo",
|
||||
"search_filters_features_option_four_k": "4k",
|
||||
"search_filters_features_option_location": "Lokacija",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"Current version: ": "Trenutačna verzija: ",
|
||||
"next_steps_error_message": "Nakon toga bi trebali pokušati sljedeće: ",
|
||||
"next_steps_error_message_refresh": "Aktualiziraj stranicu",
|
||||
"next_steps_error_message_go_to_youtube": "Idi na YouTube",
|
||||
"footer_donate_page": "Doniraj",
|
||||
"adminprefs_modified_source_code_url_label": "URL do repozitorija izmijenjenog izvornog koda",
|
||||
"short": "Kratki (< 4 minute)",
|
||||
"long": "Dugi (> 20 minute)",
|
||||
"search_filters_duration_option_short": "Kratko (< 4 minute)",
|
||||
"search_filters_duration_option_long": "Dugo (> 20 minute)",
|
||||
"footer_source_code": "Izvorni kod",
|
||||
"footer_modfied_source_code": "Izmijenjeni izvorni kod",
|
||||
"footer_documentation": "Dokumentacija",
|
||||
@@ -382,12 +380,12 @@
|
||||
"preferences_quality_dash_option_240p": "240 p",
|
||||
"preferences_quality_dash_option_144p": "144 p",
|
||||
"invidious": "Invidious",
|
||||
"purchased": "Kupljeno",
|
||||
"360": "360 °",
|
||||
"search_filters_features_option_purchased": "Kupljeno",
|
||||
"search_filters_features_option_three_sixty": "360 °",
|
||||
"none": "bez",
|
||||
"videoinfo_youTube_embed_link": "Ugradi",
|
||||
"user_created_playlists": "`x` stvorene zbirke",
|
||||
"user_saved_playlists": "`x` spremljene zbirke",
|
||||
"user_created_playlists": "`x` je stvorio/la zbirke",
|
||||
"user_saved_playlists": "`x` je spremio/la zbirke",
|
||||
"Video unavailable": "Video nedostupan",
|
||||
"preferences_save_player_pos_label": "Spremi mjesto reprodukcije: ",
|
||||
"videoinfo_watch_on_youTube": "Gledaj na YouTubeu",
|
||||
@@ -434,7 +432,7 @@
|
||||
"generic_subscriptions_count_2": "{{count}} pretplata",
|
||||
"generic_playlists_count_0": "{{count}} zbirka",
|
||||
"generic_playlists_count_1": "{{count}} zbirke",
|
||||
"generic_playlists_count_2": "{{count}} zbirka",
|
||||
"generic_playlists_count_2": "{{count}} zbiraka",
|
||||
"generic_videos_count_0": "{{count}} video",
|
||||
"generic_videos_count_1": "{{count}} videa",
|
||||
"generic_videos_count_2": "{{count}} videa",
|
||||
@@ -452,7 +450,7 @@
|
||||
"crash_page_refresh": "pokušaj <a href=\"`x`\">aktualizirati stranicu</a>",
|
||||
"crash_page_switch_instance": "pokušaj <a href=\"`x`\">koristiti jednu drugu instancu</a>",
|
||||
"crash_page_read_the_faq": "pročitaj <a href=\"`x`\">Često postavljena pitanja (ČPP)</a>",
|
||||
"crash_page_search_issue": "pretraži <a href=\"`x`\">postojeće probleme na Github-u</a>",
|
||||
"crash_page_search_issue": "pretraži <a href=\"`x`\">postojeće probleme na GitHub-u</a>",
|
||||
"crash_page_report_issue": "Ako ništa od gore navedenog ne pomaže, <a href=\"`x`\">prijavi novi problem na GitHub-u</a> (po mogućnosti na engleskom) i uključi sljedeći tekst u poruku (NEMOJ prevoditi taj tekst):",
|
||||
"English (United Kingdom)": "Engleski (Ujedinjeno Kraljevstvo)",
|
||||
"English (United States)": "Engleski (Sjedinjene Američke Države)",
|
||||
@@ -476,5 +474,18 @@
|
||||
"Chinese (Hong Kong)": "Kineski (Hong Kong)",
|
||||
"Korean (auto-generated)": "Korejski (automatski generiran)",
|
||||
"Portuguese (auto-generated)": "Portugalski (automatski generiran)",
|
||||
"Spanish (auto-generated)": "Španjolski (automatski generiran)"
|
||||
"Spanish (auto-generated)": "Španjolski (automatski generiran)",
|
||||
"preferences_watch_history_label": "Aktiviraj povijest gledanja: ",
|
||||
"search_filters_title": "Filtri",
|
||||
"search_filters_date_option_none": "Bilo koji datum",
|
||||
"search_filters_date_label": "Datum prijenosa",
|
||||
"search_message_no_results": "Nema rezultata.",
|
||||
"search_message_use_another_instance": " Također možeš <a href=\"`x`\">tražiti na jednoj drugoj instanci</a>.",
|
||||
"search_message_change_filters_or_query": "Pokušaj proširiti upit za pretragu i/ili promijeni filtre.",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"search_filters_duration_option_none": "Bilo koje duljine",
|
||||
"search_filters_duration_option_medium": "Srednje (4 – 20 minuta)",
|
||||
"search_filters_apply_button": "Primijeni odabrane filtre",
|
||||
"search_filters_type_option_all": "Bilo koja vrsta",
|
||||
"Popular enabled: ": "Popularni aktivirani: "
|
||||
}
|
||||
|
||||
@@ -31,15 +31,15 @@
|
||||
"No": "Nem",
|
||||
"Import and Export Data": "Adatok importálása és exportálása",
|
||||
"Import": "Importálás",
|
||||
"Import Invidious data": "Az Invidious adatainak importálása",
|
||||
"Import YouTube subscriptions": "YouTube-feliratkozások importálása",
|
||||
"Import Invidious data": "Az Invidious JSON-adatainak importálása",
|
||||
"Import YouTube subscriptions": "YouTube- vagy OPML-feliratkozások importálása",
|
||||
"Import FreeTube subscriptions (.db)": "FreeTube-feliratkozások importálása (.db)",
|
||||
"Import NewPipe subscriptions (.json)": "NewPipe-feliratkozások importálása (.json)",
|
||||
"Import NewPipe data (.zip)": "NewPipe adatainak importálása (.zip)",
|
||||
"Export": "Exportálás",
|
||||
"Export subscriptions as OPML": "Feliratkozások exportálása OPML-ként",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Feliratkozások exportálása OPML-ként (NewPipe-hoz és FreeTube-hoz)",
|
||||
"Export data as JSON": "Adat exportálása JSON-ként",
|
||||
"Export data as JSON": "Az Invidious JSON-adatainak exportálása",
|
||||
"Delete account?": "Törlésre kerüljön a fiók?",
|
||||
"History": "Megnézett videók naplója",
|
||||
"An alternative front-end to YouTube": "Ez az oldal egyike a YouTube alternatív kezelőfelületeinek",
|
||||
@@ -159,7 +159,7 @@
|
||||
"Engagement: ": "Visszajelzési mutató: ",
|
||||
"Whitelisted regions: ": "Engedélyezett régiók: ",
|
||||
"Blacklisted regions: ": "Tiltott régiók: ",
|
||||
"Shared `x`": "`x` napon osztották meg",
|
||||
"Shared `x`": "`x` dátummal osztották meg",
|
||||
"Premieres in `x`": "`x` később lesz a premierje",
|
||||
"Premieres `x`": "`x` lesz a premierje",
|
||||
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Helló! Úgy tűnik a JavaScript ki van kapcsolva a böngészőben. Ide kattintva lehet olvasni a hozzászólásokat, de a betöltésük így kicsit több időbe telik.",
|
||||
@@ -365,14 +365,14 @@
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"invidious": "Invidious",
|
||||
"videoinfo_started_streaming_x_ago": "`x` ezelőtt kezdte streamelni",
|
||||
"views": "Mennyien látták",
|
||||
"purchased": "Megvásárolva",
|
||||
"360": "360°-os",
|
||||
"search_filters_sort_option_views": "Mennyien látták",
|
||||
"search_filters_features_option_purchased": "Megvásárolt",
|
||||
"search_filters_features_option_three_sixty": "360°-os virtuális valóság",
|
||||
"footer_original_source_code": "Eredeti forráskód",
|
||||
"none": "egyik sem",
|
||||
"videoinfo_watch_on_youTube": "YouTube-on megnézni",
|
||||
"videoinfo_youTube_embed_link": "beágyazva",
|
||||
"videoinfo_invidious_embed_link": "Beágyazás linkje",
|
||||
"videoinfo_invidious_embed_link": "Beágyazott hivatkozás",
|
||||
"download_subtitles": "Felirat – `x` (.vtt)",
|
||||
"user_created_playlists": "`x` létrehozott lejátszási lista",
|
||||
"user_saved_playlists": "`x` mentett lejátszási lista",
|
||||
@@ -382,14 +382,13 @@
|
||||
"preferences_quality_dash_option_1440p": "1440p",
|
||||
"preferences_quality_dash_label": "DASH-videó minősége: ",
|
||||
"preferences_quality_option_small": "Rossz",
|
||||
"date": "Feltöltés dátuma",
|
||||
"search_filters_sort_option_date": "Feltöltés dátuma",
|
||||
"Video unavailable": "A videó nem érhető el",
|
||||
"preferences_save_player_pos_label": "A videó folytatása onnan, ahol félbe lett hagyva: ",
|
||||
"preferences_show_nick_label": "Becenév mutatása felül: ",
|
||||
"Released under the AGPLv3 on Github.": "AGPLv3 licenc alapján a GitHubon",
|
||||
"3d": "3D-ben",
|
||||
"live": "Élőben",
|
||||
"filter": "Szűrők",
|
||||
"search_filters_features_option_three_d": "3D-ben",
|
||||
"search_filters_features_option_live": "Élőben",
|
||||
"next_steps_error_message_refresh": "Újratöltés",
|
||||
"footer_donate_page": "Adakozás",
|
||||
"footer_source_code": "Forráskód",
|
||||
@@ -397,40 +396,39 @@
|
||||
"adminprefs_modified_source_code_url_label": "A módosított forráskód repositoryjának URL-je:",
|
||||
"preferences_automatic_instance_redirect_label": "Váltáskor másik Invidious oldal automatikus betöltése (redirect.invidious.io töltődik, ha nem működne): ",
|
||||
"preferences_region_label": "Ország tartalmainak mutatása: ",
|
||||
"relevance": "Relevancia",
|
||||
"rating": "Pontszám",
|
||||
"content_type": "Típus",
|
||||
"today": "Mai napon",
|
||||
"channel": "Csatorna",
|
||||
"video": "Videó",
|
||||
"playlist": "Lejátszási lista",
|
||||
"creative_commons": "Creative Commons",
|
||||
"features": "Jellemzők",
|
||||
"sort": "Rendezés módja",
|
||||
"search_filters_sort_option_relevance": "Relevancia",
|
||||
"search_filters_sort_option_rating": "Pontszám",
|
||||
"search_filters_type_label": "Típus",
|
||||
"search_filters_date_option_today": "Mai napon",
|
||||
"search_filters_type_option_channel": "Csatorna",
|
||||
"search_filters_type_option_video": "Videó",
|
||||
"search_filters_type_option_playlist": "Lejátszási lista",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_label": "Jellemzők",
|
||||
"search_filters_sort_label": "Rendezés módja",
|
||||
"preferences_category_misc": "További beállítások",
|
||||
"%A %B %-d, %Y": "%Y. %B %-d %A",
|
||||
"long": "Hosszú (20 percnél hosszabb)",
|
||||
"year": "Ebben az évben",
|
||||
"hour": "Az elmúlt órában",
|
||||
"movie": "Film",
|
||||
"hdr": "HDR",
|
||||
"Broken? Try another Invidious Instance": "Nem működik? Próbáld meg egy másik Invidious oldallal.",
|
||||
"duration": "Játékidő",
|
||||
"search_filters_duration_option_long": "Hosszú (20 percnél hosszabb)",
|
||||
"search_filters_date_option_year": "Ebben az évben",
|
||||
"search_filters_date_option_hour": "Az elmúlt órában",
|
||||
"search_filters_type_option_movie": "Film",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"search_filters_duration_label": "Játékidő",
|
||||
"next_steps_error_message": "Az alábbi lehetőségek állnak rendelkezésre: ",
|
||||
"Xhosa": "xhosza",
|
||||
"Switch Invidious Instance": "Váltás másik Invidious-oldalra",
|
||||
"Urdu": "urdu",
|
||||
"week": "Ezen a héten",
|
||||
"search_filters_date_option_week": "Ezen a héten",
|
||||
"Invalid TFA code": "A kétlépéses hitelesítés kódja nem megfelelő",
|
||||
"footer_documentation": "Dokumentáció",
|
||||
"hd": "HD",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"next_steps_error_message_go_to_youtube": "Ugrás a YouTube-ra",
|
||||
"show": "Műsor",
|
||||
"4k": "4K",
|
||||
"short": "Rövid (4 percnél nem több)",
|
||||
"month": "Ebben a hónapban",
|
||||
"subtitles": "Felirattal",
|
||||
"location": "Közelben",
|
||||
"search_filters_type_option_show": "Műsor",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_duration_option_short": "Rövid (4 percnél nem több)",
|
||||
"search_filters_date_option_month": "Ebben a hónapban",
|
||||
"search_filters_features_option_subtitles": "Felirattal",
|
||||
"search_filters_features_option_location": "Közelben",
|
||||
"crash_page_you_found_a_bug": "Úgy néz ki, találtál egy hibát az Invidiousban.",
|
||||
"crash_page_before_reporting": "Mielőtt jelentenéd a hibát:",
|
||||
"crash_page_read_the_faq": "olvasd el a <a href=\"`x`\">Gyakran Ismételt Kérdéseket (GYIK)</a>",
|
||||
@@ -460,5 +458,17 @@
|
||||
"Italian (auto-generated)": "olasz (automatikusan generált)",
|
||||
"Dutch (auto-generated)": "holland (automatikusan generált)",
|
||||
"French (auto-generated)": "francia (automatikusan generált)",
|
||||
"Vietnamese (auto-generated)": "vietnámi (automatikusan generált)"
|
||||
"Vietnamese (auto-generated)": "vietnámi (automatikusan generált)",
|
||||
"search_filters_title": "Szűrők",
|
||||
"preferences_watch_history_label": "Megnézett videók naplózása: ",
|
||||
"search_message_no_results": "Nincs találat.",
|
||||
"search_message_change_filters_or_query": "Próbálj meg bővebben rákeresni vagy a szűrőkön állítani.",
|
||||
"search_message_use_another_instance": " Megpróbálhatod <a href=\"`x`\">egy másik</a> Invidious-oldalon is a keresést.",
|
||||
"search_filters_date_label": "Feltöltés ideje",
|
||||
"search_filters_date_option_none": "Mindegy mikor",
|
||||
"search_filters_type_option_all": "Bármilyen",
|
||||
"search_filters_duration_option_none": "Mindegy",
|
||||
"search_filters_duration_option_medium": "Átlagos (4 és 20 perc között)",
|
||||
"search_filters_features_option_vr180": "180°-os virtuális valóság",
|
||||
"search_filters_apply_button": "Keresés a megadott szűrőkkel"
|
||||
}
|
||||
|
||||
110
locales/id.json
110
locales/id.json
@@ -26,15 +26,15 @@
|
||||
"No": "Tidak",
|
||||
"Import and Export Data": "Impor dan Ekspor Data",
|
||||
"Import": "Impor",
|
||||
"Import Invidious data": "Impor data Invidious",
|
||||
"Import YouTube subscriptions": "Impor langganan YouTube",
|
||||
"Import Invidious data": "Impor JSON data Invidious",
|
||||
"Import YouTube subscriptions": "Impor langganan YouTube/OPML",
|
||||
"Import FreeTube subscriptions (.db)": "Impor langganan FreeTube (.db)",
|
||||
"Import NewPipe subscriptions (.json)": "Impor langganan NewPipe (.json)",
|
||||
"Import NewPipe data (.zip)": "Impor data NewPipe (.zip)",
|
||||
"Export": "Ekspor",
|
||||
"Export subscriptions as OPML": "Ekspor langganan sebagai OPML",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Ekspor langganan sebagai OPML (untuk NewPipe & FreeTube)",
|
||||
"Export data as JSON": "Ekspor data sebagai JSON",
|
||||
"Export data as JSON": "Ekspor data Invidious sebagai JSON",
|
||||
"Delete account?": "Hapus akun?",
|
||||
"History": "Riwayat",
|
||||
"An alternative front-end to YouTube": "Sebuah alternatif layar depan untuk YouTube",
|
||||
@@ -71,7 +71,7 @@
|
||||
"preferences_related_videos_label": "Tampilkan video terkait: ",
|
||||
"preferences_annotations_label": "Tampilkan anotasi secara baku: ",
|
||||
"preferences_extend_desc_label": "Perluas deskripsi video secara otomatis: ",
|
||||
"preferences_vr_mode_label": "Video interaktif 360°: ",
|
||||
"preferences_vr_mode_label": "Video interaktif 360° (memerlukan WebGL): ",
|
||||
"preferences_category_visual": "Preferensi visual",
|
||||
"preferences_player_style_label": "Gaya pemutar: ",
|
||||
"Dark mode: ": "Mode gelap: ",
|
||||
@@ -126,9 +126,9 @@
|
||||
"revoke": "cabut",
|
||||
"Subscriptions": "Langganan",
|
||||
"subscriptions_unseen_notifs_count_0": "{{count}} pemberitahuan belum dilihat",
|
||||
"search": "cari",
|
||||
"search": "Telusuri",
|
||||
"Log out": "Keluar",
|
||||
"Released under the AGPLv3 on Github.": "Dirilis di bawah AGPLv3 di Github.",
|
||||
"Released under the AGPLv3 on Github.": "Dirilis di bawah AGPLv3 di GitHub.",
|
||||
"Source available here.": "Sumber tersedia di sini.",
|
||||
"View JavaScript license information.": "Tampilkan informasi lisensi JavaScript.",
|
||||
"View privacy policy.": "Lihat kebijakan privasi.",
|
||||
@@ -148,7 +148,6 @@
|
||||
"Show less": "Tampilkan lebih sedikit",
|
||||
"Watch on YouTube": "Tonton di YouTube",
|
||||
"Switch Invidious Instance": "Ganti peladen Invidious",
|
||||
"Broken? Try another Invidious Instance": "Rusak? Coba peladen Invidious yang lain",
|
||||
"Hide annotations": "Sembunyikan anotasi",
|
||||
"Show annotations": "Tampilkan anotasi",
|
||||
"Genre: ": "Genre: ",
|
||||
@@ -345,33 +344,32 @@
|
||||
"Videos": "Video",
|
||||
"Playlists": "Daftar putar",
|
||||
"Community": "Komunitas",
|
||||
"relevance": "Relevansi",
|
||||
"rating": "Penilaian",
|
||||
"date": "Tanggal unggah",
|
||||
"views": "Jumlah ditonton",
|
||||
"content_type": "Tipe",
|
||||
"duration": "Durasi",
|
||||
"features": "Fitur",
|
||||
"sort": "Urut Berdasarkan",
|
||||
"hour": "Jam Terakhir",
|
||||
"today": "Hari Ini",
|
||||
"week": "Pekan Ini",
|
||||
"month": "Bulan Ini",
|
||||
"year": "Tahun Ini",
|
||||
"video": "Video",
|
||||
"channel": "Kanal",
|
||||
"playlist": "Daftar Putar",
|
||||
"movie": "Film",
|
||||
"show": "Pertunjukan/Acara",
|
||||
"hd": "HD",
|
||||
"subtitles": "Takarir",
|
||||
"creative_commons": "Creative Commons",
|
||||
"3d": "3D",
|
||||
"live": "Siaran Langsung",
|
||||
"4k": "4K",
|
||||
"location": "Lokasi",
|
||||
"hdr": "HDR",
|
||||
"filter": "Saring",
|
||||
"search_filters_sort_option_relevance": "Relevansi",
|
||||
"search_filters_sort_option_rating": "Penilaian",
|
||||
"search_filters_sort_option_date": "Tanggal Unggah",
|
||||
"search_filters_sort_option_views": "Jumlah ditonton",
|
||||
"search_filters_type_label": "Tipe",
|
||||
"search_filters_duration_label": "Durasi",
|
||||
"search_filters_features_label": "Fitur",
|
||||
"search_filters_sort_label": "Urut Berdasarkan",
|
||||
"search_filters_date_option_hour": "Jam Terakhir",
|
||||
"search_filters_date_option_today": "Hari Ini",
|
||||
"search_filters_date_option_week": "Pekan Ini",
|
||||
"search_filters_date_option_month": "Bulan Ini",
|
||||
"search_filters_date_option_year": "Tahun Ini",
|
||||
"search_filters_type_option_video": "Video",
|
||||
"search_filters_type_option_channel": "Kanal",
|
||||
"search_filters_type_option_playlist": "Daftar Putar",
|
||||
"search_filters_type_option_movie": "Film",
|
||||
"search_filters_type_option_show": "Pertunjukan/Acara",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "Takarir",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_live": "Siaran Langsung",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_location": "Lokasi",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"Current version: ": "Versi saat ini: ",
|
||||
"next_steps_error_message": "Setelah itu Anda harus mencoba: ",
|
||||
"next_steps_error_message_refresh": "Segarkan",
|
||||
@@ -380,8 +378,8 @@
|
||||
"adminprefs_modified_source_code_url_label": "URL ke repositori kode sumber yang dimodifikasi",
|
||||
"footer_source_code": "Kode sumber",
|
||||
"footer_original_source_code": "Kode sumber yang asli",
|
||||
"short": "Pendek (< 4 menit)",
|
||||
"long": "Panjang (> 20 menit)",
|
||||
"search_filters_duration_option_short": "Pendek (< 4 menit)",
|
||||
"search_filters_duration_option_long": "Panjang (> 20 menit)",
|
||||
"footer_modfied_source_code": "Kode sumber yang dimodifikasi",
|
||||
"footer_documentation": "Dokumentasi",
|
||||
"preferences_region_label": "Konten dari negara: ",
|
||||
@@ -398,8 +396,8 @@
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"invidious": "Invidious",
|
||||
"purchased": "Dibeli",
|
||||
"360": "360°",
|
||||
"search_filters_features_option_purchased": "Dibeli",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"none": "tidak ada",
|
||||
"videoinfo_watch_on_youTube": "Tonton di YouTube",
|
||||
"videoinfo_youTube_embed_link": "Tersemat",
|
||||
@@ -416,5 +414,39 @@
|
||||
"Video unavailable": "Video tidak tersedia",
|
||||
"preferences_save_player_pos_label": "Simpan posisi pemutaran: ",
|
||||
"crash_page_you_found_a_bug": "Sepertinya kamu telah menemukan masalah di invidious!",
|
||||
"crash_page_before_reporting": "Sebelum melaporkan masalah, pastikan anda memiliki:"
|
||||
"crash_page_before_reporting": "Sebelum melaporkan masalah, pastikan anda memiliki:",
|
||||
"English (United States)": "Inggris (US)",
|
||||
"preferences_watch_history_label": "Aktifkan riwayat tontonan: ",
|
||||
"English (United Kingdom)": "Inggris (UK)",
|
||||
"search_filters_title": "Saring",
|
||||
"search_message_no_results": "Tidak ada hasil yang ditemukan.",
|
||||
"search_message_change_filters_or_query": "Coba perbanyak kueri pencarian dan/atau ubah filter Anda.",
|
||||
"search_message_use_another_instance": " Anda juga bisa <a href=\"`x`\">mencari di peladen lain</a>.",
|
||||
"Indonesian (auto-generated)": "Indonesia (dibuat secara otomatis)",
|
||||
"Japanese (auto-generated)": "Jepang (dibuat secara otomatis)",
|
||||
"Korean (auto-generated)": "Korea (dibuat secara otomatis)",
|
||||
"Portuguese (Brazil)": "Portugis (Brasil)",
|
||||
"Russian (auto-generated)": "Rusia (dibuat secara otomatis)",
|
||||
"Spanish (Mexico)": "Spanyol (Meksiko)",
|
||||
"Spanish (Spain)": "Spanyol (Spanyol)",
|
||||
"Vietnamese (auto-generated)": "Vietnam (dibuat secara otomatis)",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"Spanish (auto-generated)": "Spanyol (dibuat secara otomatis)",
|
||||
"Chinese": "Bahasa Cina",
|
||||
"Chinese (Taiwan)": "Bahasa Cina (Taiwan)",
|
||||
"Chinese (Hong Kong)": "Bahasa Cina (Hong Kong)",
|
||||
"Chinese (China)": "Bahasa Cina (China)",
|
||||
"French (auto-generated)": "Perancis (dibuat secara otomatis)",
|
||||
"German (auto-generated)": "Jerman (dibuat secara otomatis)",
|
||||
"Italian (auto-generated)": "Italia (dibuat secara otomatis)",
|
||||
"Portuguese (auto-generated)": "Portugis (dibuat secara otomatis)",
|
||||
"Turkish (auto-generated)": "Turki (dibuat secara otomatis)",
|
||||
"search_filters_date_label": "Tanggal unggah",
|
||||
"search_filters_type_option_all": "Segala jenis",
|
||||
"search_filters_apply_button": "Terapkan saringan yang dipilih",
|
||||
"Dutch (auto-generated)": "Belanda (dihasilkan secara otomatis)",
|
||||
"search_filters_date_option_none": "Tanggal berapa pun",
|
||||
"search_filters_duration_option_none": "Durasi berapa pun",
|
||||
"search_filters_duration_option_medium": "Sedang (4 - 20 menit)",
|
||||
"Cantonese (Hong Kong)": "Bahasa Kanton (Hong Kong)"
|
||||
}
|
||||
|
||||
171
locales/it.json
171
locales/it.json
@@ -14,7 +14,7 @@
|
||||
"newest": "più recente",
|
||||
"oldest": "più vecchio",
|
||||
"popular": "Tendenze",
|
||||
"last": "durare",
|
||||
"last": "ultimo",
|
||||
"Next page": "Pagina successiva",
|
||||
"Previous page": "Pagina precedente",
|
||||
"Clear watch history?": "Eliminare la cronologia dei video guardati?",
|
||||
@@ -27,15 +27,15 @@
|
||||
"No": "No",
|
||||
"Import and Export Data": "Importazione ed esportazione dati",
|
||||
"Import": "Importa",
|
||||
"Import Invidious data": "Importa dati Invidious",
|
||||
"Import YouTube subscriptions": "Importa le iscrizioni da YouTube",
|
||||
"Import Invidious data": "Importa dati Invidious in formato JSON",
|
||||
"Import YouTube subscriptions": "Importa le iscrizioni da YouTube/OPML",
|
||||
"Import FreeTube subscriptions (.db)": "Importa le iscrizioni da FreeTube (.db)",
|
||||
"Import NewPipe subscriptions (.json)": "Importa le iscrizioni da NewPipe (.json)",
|
||||
"Import NewPipe data (.zip)": "Importa i dati di NewPipe (.zip)",
|
||||
"Export": "Esporta",
|
||||
"Export subscriptions as OPML": "Esporta gli abbonamenti come OPML",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Esporta gli abbonamenti come OPML (per NewPipe e FreeTube)",
|
||||
"Export data as JSON": "Esporta i dati in formato JSON",
|
||||
"Export data as JSON": "Esporta i dati Invidious in formato JSON",
|
||||
"Delete account?": "Eliminare l'account?",
|
||||
"History": "Cronologia",
|
||||
"An alternative front-end to YouTube": "Un'interfaccia alternativa per YouTube",
|
||||
@@ -158,7 +158,7 @@
|
||||
"generic_views_count_plural": "{{count}} visualizzazioni",
|
||||
"Premieres in `x`": "In anteprima in `x`",
|
||||
"Premieres `x`": "In anteprima `x`",
|
||||
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Ciao! Sembra che tu abbia disattivato JavaScript. Clicca qui per visualizzare i commenti. Considera che potrebbe volerci più tempo.",
|
||||
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Ciao, Sembra che tu abbia disattivato JavaScript. Clicca qui per visualizzare i commenti, ma considera che il caricamento potrebbe richiedere più tempo.",
|
||||
"View YouTube comments": "Visualizza i commenti da YouTube",
|
||||
"View more comments on Reddit": "Visualizza più commenti su Reddit",
|
||||
"View `x` comments": {
|
||||
@@ -212,7 +212,7 @@
|
||||
"Azerbaijani": "Azero",
|
||||
"Bangla": "Bengalese",
|
||||
"Basque": "Basco",
|
||||
"Belarusian": "Biellorusso",
|
||||
"Belarusian": "Bielorusso",
|
||||
"Bosnian": "Bosniaco",
|
||||
"Bulgarian": "Bulgaro",
|
||||
"Burmese": "Birmano",
|
||||
@@ -238,10 +238,10 @@
|
||||
"Haitian Creole": "Creolo haitiano",
|
||||
"Hausa": "Lingua hausa",
|
||||
"Hawaiian": "Hawaiano",
|
||||
"Hebrew": "Ebreo",
|
||||
"Hebrew": "Ebraico",
|
||||
"Hindi": "Hindi",
|
||||
"Hmong": "Hmong",
|
||||
"Hungarian": "Ungarese",
|
||||
"Hungarian": "Ungherese",
|
||||
"Icelandic": "Islandese",
|
||||
"Igbo": "Igbo",
|
||||
"Indonesian": "Indonesiano",
|
||||
@@ -254,7 +254,7 @@
|
||||
"Khmer": "Khmer",
|
||||
"Korean": "Coreano",
|
||||
"Kurdish": "Curdo",
|
||||
"Kyrgyz": "Kirghize",
|
||||
"Kyrgyz": "Kirghiso",
|
||||
"Lao": "Lao",
|
||||
"Latin": "Latino",
|
||||
"Latvian": "Lettone",
|
||||
@@ -269,7 +269,7 @@
|
||||
"Marathi": "Marathi",
|
||||
"Mongolian": "Mongolo",
|
||||
"Nepali": "Nepalese",
|
||||
"Norwegian Bokmål": "Norvegese",
|
||||
"Norwegian Bokmål": "Norvegese bokmål",
|
||||
"Nyanja": "Nyanja",
|
||||
"Pashto": "Pashtu",
|
||||
"Persian": "Persiano",
|
||||
@@ -278,7 +278,7 @@
|
||||
"Punjabi": "Punjabi",
|
||||
"Romanian": "Rumeno",
|
||||
"Russian": "Russo",
|
||||
"Samoan": "Samoan",
|
||||
"Samoan": "Samoano",
|
||||
"Scottish Gaelic": "Gaelico scozzese",
|
||||
"Serbian": "Serbo",
|
||||
"Shona": "Shona",
|
||||
@@ -293,15 +293,15 @@
|
||||
"Sundanese": "Sudanese",
|
||||
"Swahili": "Swahili",
|
||||
"Swedish": "Svedese",
|
||||
"Tajik": "Tajik",
|
||||
"Tajik": "Tagico",
|
||||
"Tamil": "Tamil",
|
||||
"Telugu": "Telugu",
|
||||
"Thai": "Thaï",
|
||||
"Thai": "Thailandese",
|
||||
"Turkish": "Turco",
|
||||
"Ukrainian": "Ucraino",
|
||||
"Urdu": "Urdu",
|
||||
"Uzbek": "Uzbeco",
|
||||
"Vietnamese": "Vietnamese",
|
||||
"Vietnamese": "Vietnamita",
|
||||
"Welsh": "Gallese",
|
||||
"Western Frisian": "Frisone occidentale",
|
||||
"Xhosa": "Xhosa",
|
||||
@@ -340,39 +340,38 @@
|
||||
"%A %B %-d, %Y": "%A %-d %B %Y",
|
||||
"(edited)": "(modificato)",
|
||||
"YouTube comment permalink": "Link permanente al commento di YouTube",
|
||||
"permalink": "permalink",
|
||||
"permalink": "perma-collegamento",
|
||||
"`x` marked it with a ❤": "`x` l'ha contrassegnato con un ❤",
|
||||
"Audio mode": "Modalità audio",
|
||||
"Video mode": "Modalità video",
|
||||
"Videos": "Video",
|
||||
"Playlists": "Playlist",
|
||||
"Community": "Comunità",
|
||||
"relevance": "Pertinenza",
|
||||
"rating": "Valutazione",
|
||||
"date": "Data di caricamento",
|
||||
"views": "Numero di visualizzazioni",
|
||||
"content_type": "Tipo",
|
||||
"duration": "Durata",
|
||||
"features": "Caratteristiche",
|
||||
"sort": "Ordina per",
|
||||
"hour": "Ultima ora",
|
||||
"today": "Oggi",
|
||||
"week": "Questa settimana",
|
||||
"month": "Questo mese",
|
||||
"year": "Quest'anno",
|
||||
"video": "Video",
|
||||
"channel": "Canale",
|
||||
"playlist": "Playlist",
|
||||
"movie": "Film",
|
||||
"hd": "AD",
|
||||
"subtitles": "Sottotitoli / CC",
|
||||
"creative_commons": "Creative Commons",
|
||||
"3d": "3D",
|
||||
"live": "In diretta",
|
||||
"4k": "4K",
|
||||
"location": "Posizione",
|
||||
"hdr": "HDR",
|
||||
"filter": "Filtra",
|
||||
"search_filters_sort_option_relevance": "Pertinenza",
|
||||
"search_filters_sort_option_rating": "Valutazione",
|
||||
"search_filters_sort_option_date": "Data di caricamento",
|
||||
"search_filters_sort_option_views": "Numero di visualizzazioni",
|
||||
"search_filters_type_label": "Tipo",
|
||||
"search_filters_duration_label": "Durata",
|
||||
"search_filters_features_label": "Caratteristiche",
|
||||
"search_filters_sort_label": "Ordina per",
|
||||
"search_filters_date_option_hour": "Ultima ora",
|
||||
"search_filters_date_option_today": "Oggi",
|
||||
"search_filters_date_option_week": "Questa settimana",
|
||||
"search_filters_date_option_month": "Questo mese",
|
||||
"search_filters_date_option_year": "Quest'anno",
|
||||
"search_filters_type_option_video": "Video",
|
||||
"search_filters_type_option_channel": "Canale",
|
||||
"search_filters_type_option_playlist": "Playlist",
|
||||
"search_filters_type_option_movie": "Film",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "Sottotitoli / CC",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_live": "In diretta",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_location": "Posizione",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"Current version: ": "Versione attuale: ",
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"preferences_quality_dash_option_360p": "360p",
|
||||
@@ -382,15 +381,95 @@
|
||||
"preferences_quality_dash_option_1440p": "1440p",
|
||||
"preferences_quality_dash_option_2160p": "2160p",
|
||||
"preferences_quality_dash_option_4320p": "4320p",
|
||||
"360": "360°",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"Released under the AGPLv3 on Github.": "Rilasciato su Github con licenza AGPLv3.",
|
||||
"Released under the AGPLv3 on Github.": "Pubblicato su GitHub con licenza AGPLv3.",
|
||||
"preferences_quality_option_medium": "Media",
|
||||
"preferences_quality_option_small": "Piccola",
|
||||
"preferences_quality_option_small": "Limitata",
|
||||
"preferences_quality_dash_option_best": "Migliore",
|
||||
"preferences_quality_dash_option_worst": "Peggiore",
|
||||
"invidious": "Invidious",
|
||||
"preferences_quality_dash_label": "Qualità video DASH preferita ",
|
||||
"preferences_quality_dash_label": "Qualità video DASH preferita: ",
|
||||
"preferences_quality_option_hd720": "HD720",
|
||||
"preferences_quality_dash_option_auto": "Automatica"
|
||||
"preferences_quality_dash_option_auto": "Automatica",
|
||||
"videoinfo_watch_on_youTube": "Guarda su YouTube",
|
||||
"preferences_extend_desc_label": "Estendi automaticamente la descrizione del video: ",
|
||||
"preferences_vr_mode_label": "Video interattivi a 360 gradi: ",
|
||||
"Show less": "Mostra di meno",
|
||||
"Switch Invidious Instance": "Cambia istanza Invidious",
|
||||
"next_steps_error_message_go_to_youtube": "Andare su YouTube",
|
||||
"footer_documentation": "Documentazione",
|
||||
"footer_original_source_code": "Codice sorgente originale",
|
||||
"footer_modfied_source_code": "Codice sorgente modificato",
|
||||
"none": "nessuno",
|
||||
"videoinfo_started_streaming_x_ago": "Ha iniziato a trasmettere `x` fa",
|
||||
"download_subtitles": "Sottotitoli - `x` (.vtt)",
|
||||
"user_saved_playlists": "playlist salvate da `x`",
|
||||
"preferences_automatic_instance_redirect_label": "Reindirizzamento automatico dell'istanza (ripiego su redirect.invidious.io): ",
|
||||
"Video unavailable": "Video non disponibile",
|
||||
"preferences_show_nick_label": "Mostra nickname in alto: ",
|
||||
"videoinfo_youTube_embed_link": "Incorpora",
|
||||
"videoinfo_invidious_embed_link": "Incorpora collegamento",
|
||||
"user_created_playlists": "playlist create da `x`",
|
||||
"preferences_save_player_pos_label": "Memorizza il minutaggio raggiunto dal video: ",
|
||||
"preferences_quality_option_dash": "DASH (qualità adattiva)",
|
||||
"preferences_region_label": "Nazione del contenuto: ",
|
||||
"preferences_category_misc": "Preferenze varie",
|
||||
"next_steps_error_message": "Dopodiché dovresti provare a: ",
|
||||
"next_steps_error_message_refresh": "Aggiornare",
|
||||
"footer_donate_page": "Dona",
|
||||
"footer_source_code": "Codice sorgente",
|
||||
"adminprefs_modified_source_code_url_label": "Link per il repository del codice sorgente modificato",
|
||||
"Show more": "Mostra di più",
|
||||
"search_filters_title": "Filtra",
|
||||
"search_filters_type_option_show": "Serie",
|
||||
"search_filters_duration_option_short": "Corto (< 4 minuti)",
|
||||
"search_filters_duration_option_long": "Lungo (> 20 minuti)",
|
||||
"search_filters_features_option_purchased": "Acquistato",
|
||||
"comments_view_x_replies": "Vedi {{count}} risposta",
|
||||
"comments_view_x_replies_plural": "Vedi {{count}} risposte",
|
||||
"comments_points_count": "{{count}} punto",
|
||||
"comments_points_count_plural": "{{count}} punti",
|
||||
"Portuguese (auto-generated)": "Portoghese (generati automaticamente)",
|
||||
"crash_page_you_found_a_bug": "Sembra che tu abbia trovato un bug in Invidious!",
|
||||
"crash_page_switch_instance": "provato a <a href=\"`x`\">usare un'altra istanza</a>",
|
||||
"crash_page_before_reporting": "Prima di segnalare un bug, assicurati di aver:",
|
||||
"crash_page_read_the_faq": "letto le <a href=\"`x`\">domande più frequenti (FAQ)</a>",
|
||||
"crash_page_search_issue": "cercato tra <a href=\"`x`\"> i problemi esistenti su GitHub</a>",
|
||||
"crash_page_report_issue": "Se niente di tutto ciò ha aiutato, per favore <a href=\"`x`\">apri un nuovo problema su GitHub</a> (preferibilmente in inglese) e includi il seguente testo nel tuo messaggio (NON tradurre il testo):",
|
||||
"Popular enabled: ": "Popolare attivato: ",
|
||||
"English (United Kingdom)": "Inglese (Regno Unito)",
|
||||
"Portuguese (Brazil)": "Portoghese (Brasile)",
|
||||
"preferences_watch_history_label": "Attiva cronologia di riproduzione: ",
|
||||
"French (auto-generated)": "Francese (generati automaticamente)",
|
||||
"search_message_use_another_instance": " Puoi anche <a href=\"`x`\">cercare in un'altra istanza</a>.",
|
||||
"search_message_no_results": "Nessun risultato trovato.",
|
||||
"search_message_change_filters_or_query": "Prova ad ampliare la ricerca e/o modificare i filtri.",
|
||||
"English (United States)": "Inglese (Stati Uniti)",
|
||||
"Cantonese (Hong Kong)": "Cantonese (Hong Kong)",
|
||||
"Chinese": "Cinese",
|
||||
"Chinese (China)": "Cinese (Cina)",
|
||||
"Chinese (Hong Kong)": "Cinese (Hong Kong)",
|
||||
"Chinese (Taiwan)": "Cinese (Taiwan)",
|
||||
"Dutch (auto-generated)": "Olandese (generati automaticamente)",
|
||||
"German (auto-generated)": "Tedesco (generati automaticamente)",
|
||||
"Indonesian (auto-generated)": "Indonesiano (generati automaticamente)",
|
||||
"Interlingue": "Interlingua",
|
||||
"Italian (auto-generated)": "Italiano (generati automaticamente)",
|
||||
"Japanese (auto-generated)": "Giapponese (generati automaticamente)",
|
||||
"Korean (auto-generated)": "Coreano (generati automaticamente)",
|
||||
"Russian (auto-generated)": "Russo (generati automaticamente)",
|
||||
"Spanish (auto-generated)": "Spagnolo (generati automaticamente)",
|
||||
"Spanish (Mexico)": "Spagnolo (Messico)",
|
||||
"Spanish (Spain)": "Spagnolo (Spagna)",
|
||||
"Turkish (auto-generated)": "Turco (auto-generato)",
|
||||
"Vietnamese (auto-generated)": "Vietnamita (auto-generato)",
|
||||
"search_filters_date_label": "Data caricamento",
|
||||
"search_filters_date_option_none": "Qualunque data",
|
||||
"search_filters_type_option_all": "Qualunque tipo",
|
||||
"search_filters_duration_option_none": "Qualunque durata",
|
||||
"search_filters_duration_option_medium": "Media (4 - 20 minuti)",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"search_filters_apply_button": "Applica filtri selezionati",
|
||||
"crash_page_refresh": "provato a <a href=\"`x`\">ricaricare la pagina</a>"
|
||||
}
|
||||
|
||||
@@ -26,15 +26,15 @@
|
||||
"No": "いいえ",
|
||||
"Import and Export Data": "データのインポートとエクスポート",
|
||||
"Import": "インポート",
|
||||
"Import Invidious data": "Invidious データをインポート",
|
||||
"Import YouTube subscriptions": "YouTube 登録チャンネルをインポート",
|
||||
"Import Invidious data": "Invidious JSONデータをインポート",
|
||||
"Import YouTube subscriptions": "YouTube/OPML 登録チャンネルをインポート",
|
||||
"Import FreeTube subscriptions (.db)": "FreeTube 登録チャンネルをインポート (.db)",
|
||||
"Import NewPipe subscriptions (.json)": "NewPipe 登録チャンネルをインポート (.json)",
|
||||
"Import NewPipe data (.zip)": "NewPipe データをインポート (.zip)",
|
||||
"Export": "エクスポート",
|
||||
"Export subscriptions as OPML": "登録チャンネルを OPML でエクスポート",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "登録チャンネルを OPML でエクスポート (NewPipe & FreeTube 用)",
|
||||
"Export data as JSON": "データを JSON でエクスポート",
|
||||
"Export data as JSON": "Invidious のデータを JSON でエクスポート",
|
||||
"Delete account?": "アカウントを削除しますか?",
|
||||
"History": "履歴",
|
||||
"An alternative front-end to YouTube": "YouTube 向けの代用フロントエンド",
|
||||
@@ -71,7 +71,7 @@
|
||||
"preferences_related_videos_label": "関連動画を表示: ",
|
||||
"preferences_annotations_label": "デフォルトでアノテーションを表示: ",
|
||||
"preferences_extend_desc_label": "動画の説明文を自動的に拡張: ",
|
||||
"preferences_vr_mode_label": "対話的な360°動画: ",
|
||||
"preferences_vr_mode_label": "対話的な360°動画 (WebGL が必要): ",
|
||||
"preferences_category_visual": "外観設定",
|
||||
"preferences_player_style_label": "プレイヤースタイル: ",
|
||||
"Dark mode: ": "ダークモード: ",
|
||||
@@ -148,7 +148,6 @@
|
||||
"Show less": "表示を減らす",
|
||||
"Watch on YouTube": "YouTube で視聴",
|
||||
"Switch Invidious Instance": "Invidiousインスタンスの変更",
|
||||
"Broken? Try another Invidious Instance": "壊れる?違うInvidiousインスタンスを試してみる",
|
||||
"Hide annotations": "アノテーションを隠す",
|
||||
"Show annotations": "アノテーションを表示",
|
||||
"Genre: ": "ジャンル: ",
|
||||
@@ -345,44 +344,43 @@
|
||||
"Videos": "動画",
|
||||
"Playlists": "プレイリスト",
|
||||
"Community": "コミュニティ",
|
||||
"relevance": "関連",
|
||||
"rating": "評価",
|
||||
"date": "時刻",
|
||||
"views": "再生回数",
|
||||
"content_type": "コンテンツの種類",
|
||||
"duration": "再生時間",
|
||||
"features": "機能",
|
||||
"sort": "順番",
|
||||
"hour": "1時間前",
|
||||
"today": "今日",
|
||||
"week": "今週",
|
||||
"month": "今月",
|
||||
"year": "今年",
|
||||
"video": "動画",
|
||||
"channel": "チャンネル",
|
||||
"playlist": "再生リスト",
|
||||
"movie": "映画",
|
||||
"show": "番組",
|
||||
"hd": "HD",
|
||||
"subtitles": "字幕",
|
||||
"creative_commons": "クリエイティブ・コモンズ",
|
||||
"3d": "3D",
|
||||
"live": "生配信",
|
||||
"4k": "4K",
|
||||
"location": "場所",
|
||||
"hdr": "HDR",
|
||||
"filter": "フィルタ",
|
||||
"search_filters_sort_option_relevance": "関連",
|
||||
"search_filters_sort_option_rating": "評価",
|
||||
"search_filters_sort_option_date": "時刻",
|
||||
"search_filters_sort_option_views": "再生回数",
|
||||
"search_filters_type_label": "コンテンツの種類",
|
||||
"search_filters_duration_label": "再生時間",
|
||||
"search_filters_features_label": "機能",
|
||||
"search_filters_sort_label": "順番",
|
||||
"search_filters_date_option_hour": "1時間前",
|
||||
"search_filters_date_option_today": "今日",
|
||||
"search_filters_date_option_week": "今週",
|
||||
"search_filters_date_option_month": "今月",
|
||||
"search_filters_date_option_year": "今年",
|
||||
"search_filters_type_option_video": "動画",
|
||||
"search_filters_type_option_channel": "チャンネル",
|
||||
"search_filters_type_option_playlist": "再生リスト",
|
||||
"search_filters_type_option_movie": "映画",
|
||||
"search_filters_type_option_show": "番組",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "字幕",
|
||||
"search_filters_features_option_c_commons": "クリエイティブ・コモンズ",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_live": "生配信",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_location": "場所",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"Current version: ": "現在のバージョン: ",
|
||||
"next_steps_error_message": "下記のものを試して下さい: ",
|
||||
"next_steps_error_message_refresh": "再読込",
|
||||
"next_steps_error_message_go_to_youtube": "YouTubeへ",
|
||||
"short": "4 分未満",
|
||||
"search_filters_duration_option_short": "4 分未満",
|
||||
"footer_documentation": "文書",
|
||||
"footer_source_code": "ソースコード",
|
||||
"footer_original_source_code": "ソースコード(元)",
|
||||
"footer_modfied_source_code": "ソースコード(編集)",
|
||||
"adminprefs_modified_source_code_url_label": "編集したソースコードのレポジトリーURL",
|
||||
"long": "20 分以上",
|
||||
"search_filters_duration_option_long": "20 分以上",
|
||||
"preferences_region_label": "地域: ",
|
||||
"footer_donate_page": "寄付する",
|
||||
"preferences_quality_dash_label": "優先するDash画質 : ",
|
||||
@@ -404,12 +402,41 @@
|
||||
"videoinfo_invidious_embed_link": "埋め込みリンク",
|
||||
"none": "なし",
|
||||
"download_subtitles": "字幕 - `x` (.vtt)",
|
||||
"purchased": "購入済み",
|
||||
"search_filters_features_option_purchased": "購入済み",
|
||||
"preferences_quality_option_dash": "DASH (適切な品質)",
|
||||
"preferences_quality_dash_option_worst": "最悪",
|
||||
"preferences_quality_dash_option_best": "最高",
|
||||
"videoinfo_started_streaming_x_ago": "`x`分前に配信を開始",
|
||||
"videoinfo_watch_on_youTube": "YouTube上で見る",
|
||||
"user_created_playlists": "`x`が作成したプレイリスト",
|
||||
"Video unavailable": "ビデオは利用できません"
|
||||
"Video unavailable": "ビデオは利用できません",
|
||||
"Chinese": "中国語",
|
||||
"Chinese (Taiwan)": "中国語 (台湾)",
|
||||
"Korean (auto-generated)": "韓国語 (自動生成)",
|
||||
"Portuguese (auto-generated)": "ポルトガル語 (自動生成)",
|
||||
"Turkish (auto-generated)": "トルコ語 (自動生成)",
|
||||
"English (United Kingdom)": "英語 (イギリス)",
|
||||
"Cantonese (Hong Kong)": "広東語 (香港)",
|
||||
"Chinese (China)": "中国語 (中国)",
|
||||
"Chinese (Hong Kong)": "中国語 (香港)",
|
||||
"Dutch (auto-generated)": "オランダ語 (自動生成)",
|
||||
"French (auto-generated)": "フランス語 (自動生成)",
|
||||
"German (auto-generated)": "ドイツ語 (自動生成)",
|
||||
"Indonesian (auto-generated)": "インドネシア語 (自動生成)",
|
||||
"Italian (auto-generated)": "イタリア語 (自動生成)",
|
||||
"Japanese (auto-generated)": "日本語 (自動生成)",
|
||||
"Interlingue": "インターリング",
|
||||
"Portuguese (Brazil)": "ポルトガル語 (ブラジル)",
|
||||
"Russian (auto-generated)": "ロシア語 (自動生成)",
|
||||
"Spanish (auto-generated)": "スペイン語 (自動生成)",
|
||||
"Spanish (Mexico)": "スペイン語 (メキシコ)",
|
||||
"Spanish (Spain)": "スペイン語 (スペイン)",
|
||||
"Vietnamese (auto-generated)": "ベトナム語 (自動生成)",
|
||||
"search_filters_title": "フィルタ",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"search_message_change_filters_or_query": "別のキーワードを試してみるか、検索フィルタを削除してください",
|
||||
"search_message_no_results": "一致する検索結果はありませんでした",
|
||||
"English (United States)": "英語 (アメリカ)",
|
||||
"search_filters_date_label": "アップロード日",
|
||||
"search_filters_features_option_vr180": "VR180"
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
"generic_playlists_count_0": "{{count}} 재생목록",
|
||||
"generic_subscribers_count_0": "{{count}} 구독자",
|
||||
"generic_subscriptions_count_0": "{{count}} 구독",
|
||||
"playlist": "재생목록",
|
||||
"search_filters_type_option_playlist": "재생목록",
|
||||
"Korean": "한국어",
|
||||
"Japanese": "일본어",
|
||||
"Greek": "그리스어",
|
||||
@@ -129,7 +129,7 @@
|
||||
"Delete playlist": "재생목록 삭제",
|
||||
"Delete playlist `x`?": "재생목록 `x` 를 삭제 하시겠습니까?",
|
||||
"Updated `x` ago": "`x` 전에 업데이트됨",
|
||||
"Released under the AGPLv3 on Github.": "Github에 AGPLv3 으로 배포됩니다.",
|
||||
"Released under the AGPLv3 on Github.": "GitHub에 AGPLv3 으로 배포됩니다.",
|
||||
"View all playlists": "모든 재생목록 보기",
|
||||
"Private": "비공개",
|
||||
"Unlisted": "목록에 없음",
|
||||
@@ -195,16 +195,15 @@
|
||||
"Maori": "마오리어",
|
||||
"Maltese": "몰타어",
|
||||
"Wrong answer": "잘못된 답변",
|
||||
"live": "실시간",
|
||||
"3d": "3D",
|
||||
"location": "지역",
|
||||
"4k": "4K",
|
||||
"filter": "필터",
|
||||
"hdr": "HDR",
|
||||
"search_filters_features_option_live": "실시간",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_location": "지역",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"Current version: ": "현재 버전: ",
|
||||
"next_steps_error_message_refresh": "새로 고침",
|
||||
"next_steps_error_message_go_to_youtube": "YouTube로 가기",
|
||||
"subtitles": "자막",
|
||||
"search_filters_features_option_subtitles": "자막",
|
||||
"`x` marked it with a ❤": "`x`님의 ❤",
|
||||
"Download as: ": "다음으로 다운로드: ",
|
||||
"Download": "다운로드",
|
||||
@@ -219,7 +218,7 @@
|
||||
"Latvian": "라트비아어",
|
||||
"Latin": "라틴어",
|
||||
"Lao": "라오어",
|
||||
"channel": "채널",
|
||||
"search_filters_type_option_channel": "채널",
|
||||
"Kyrgyz": "키르기스어",
|
||||
"Kurdish": "쿠르드어",
|
||||
"Khmer": "크메르어",
|
||||
@@ -279,7 +278,7 @@
|
||||
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "JavaScript가 꺼져 있는 것 같습니다! 댓글을 보려면 여기를 클릭하세요. 댓글을 로드하는 데 시간이 조금 더 걸릴 수 있습니다.",
|
||||
"Shared `x`": "공유된 `x`",
|
||||
"Whitelisted regions: ": "차단되지 않은 지역: ",
|
||||
"views": "조회수",
|
||||
"search_filters_sort_option_views": "조회수",
|
||||
"Please log in": "로그인하세요",
|
||||
"Password cannot be longer than 55 characters": "비밀번호는 55자 이하여야 합니다",
|
||||
"Password cannot be empty": "비밀번호는 비워둘 수 없습니다",
|
||||
@@ -298,7 +297,6 @@
|
||||
"Empty playlist": "재생목록 비어 있음",
|
||||
"Show annotations": "주석 보이기",
|
||||
"Hide annotations": "주석 숨기기",
|
||||
"Broken? Try another Invidious Instance": "안되나요? 다른 Invidious 인스턴스를 시도해보세요",
|
||||
"Switch Invidious Instance": "Invidious 인스턴스 변경",
|
||||
"Spanish": "스페인어",
|
||||
"Southern Sotho": "소토어",
|
||||
@@ -343,12 +341,12 @@
|
||||
"Premieres `x`": "최초 공개 `x`",
|
||||
"Premieres in `x`": "`x` 에 최초 공개",
|
||||
"next_steps_error_message": "다음 방법을 시도해 보세요: ",
|
||||
"creative_commons": "크리에이티브 커먼즈",
|
||||
"duration": "길이",
|
||||
"content_type": "구분",
|
||||
"date": "업로드 날짜",
|
||||
"rating": "평점",
|
||||
"relevance": "관련성",
|
||||
"search_filters_features_option_c_commons": "크리에이티브 커먼즈",
|
||||
"search_filters_duration_label": "길이",
|
||||
"search_filters_type_label": "구분",
|
||||
"search_filters_sort_option_date": "업로드 날짜",
|
||||
"search_filters_sort_option_rating": "평점",
|
||||
"search_filters_sort_option_relevance": "관련성",
|
||||
"Community": "커뮤니티",
|
||||
"Videos": "동영상",
|
||||
"Video mode": "비디오 모드",
|
||||
@@ -365,22 +363,23 @@
|
||||
"Rating: ": "평점: ",
|
||||
"About": "정보",
|
||||
"Top": "최고",
|
||||
"hd": "HD",
|
||||
"show": "쇼",
|
||||
"movie": "영화",
|
||||
"video": "동영상",
|
||||
"year": "올해",
|
||||
"month": "이번 달",
|
||||
"week": "이번 주",
|
||||
"today": "오늘",
|
||||
"hour": "지난 1시간",
|
||||
"sort": "정렬기준",
|
||||
"features": "기능별",
|
||||
"short": "4분 미만",
|
||||
"long": "20분 초과",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_type_option_show": "쇼",
|
||||
"search_filters_type_option_movie": "영화",
|
||||
"search_filters_type_option_video": "동영상",
|
||||
"search_filters_date_option_year": "올해",
|
||||
"search_filters_date_option_month": "이번 달",
|
||||
"search_filters_date_option_week": "이번 주",
|
||||
"search_filters_date_option_today": "오늘",
|
||||
"search_filters_date_option_hour": "지난 1시간",
|
||||
"search_filters_sort_label": "정렬기준",
|
||||
"search_filters_features_label": "기능별",
|
||||
"search_filters_duration_option_short": "4분 미만",
|
||||
"search_filters_duration_option_long": "20분 초과",
|
||||
"footer_documentation": "문서",
|
||||
"footer_source_code": "소스 코드",
|
||||
"footer_original_source_code": "원본 소스 코드",
|
||||
"footer_modfied_source_code": "수정된 소스 코드",
|
||||
"adminprefs_modified_source_code_url_label": "수정된 소스 코드 저장소의 URL"
|
||||
"adminprefs_modified_source_code_url_label": "수정된 소스 코드 저장소의 URL",
|
||||
"search_filters_title": "필터"
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
"Subscriptions": "Prenumeratos",
|
||||
"search": "ieškoti",
|
||||
"Log out": "Atsijungti",
|
||||
"Released under the AGPLv3 on Github.": "Išleista pagal AGPLv3 licenciją Github.",
|
||||
"Released under the AGPLv3 on Github.": "Išleista pagal AGPLv3 licenciją GitHub.",
|
||||
"Source available here.": "Kodas prieinamas čia.",
|
||||
"View JavaScript license information.": "Žiūrėti JavaScript licencijos informaciją.",
|
||||
"View privacy policy.": "Žiūrėti privatumo politiką.",
|
||||
@@ -141,7 +141,6 @@
|
||||
"Show less": "Rodyti mažiau",
|
||||
"Watch on YouTube": "Žiaurėti Youtube",
|
||||
"Switch Invidious Instance": "Keisti Invidious šaltinį",
|
||||
"Broken? Try another Invidious Instance": "Neveikia? Bandyk kitą Invidious šaltinį",
|
||||
"Hide annotations": "Slėpti anotacijas",
|
||||
"Show annotations": "Rodyti anotacijas",
|
||||
"Genre: ": "Žanras: ",
|
||||
@@ -329,39 +328,38 @@
|
||||
"Videos": "Vaizdo įrašai",
|
||||
"Playlists": "Grojaraiščiai",
|
||||
"Community": "Bendruomenė",
|
||||
"relevance": "Aktualumas",
|
||||
"rating": "Reitingas",
|
||||
"date": "Įkėlimo data",
|
||||
"views": "Peržiūrų skaičius",
|
||||
"content_type": "Tipas",
|
||||
"duration": "Trukmė",
|
||||
"features": "Funkcijos",
|
||||
"sort": "Rūšiuoti pagal",
|
||||
"hour": "Per paskutinę valandą",
|
||||
"today": "Šiandien",
|
||||
"week": "Šią savaitę",
|
||||
"month": "Šį mėnesį",
|
||||
"year": "Šiais metais",
|
||||
"video": "Vaizdo įrašas",
|
||||
"channel": "Kanalas",
|
||||
"playlist": "Grojaraštis",
|
||||
"movie": "Filmas",
|
||||
"show": "Serialas",
|
||||
"hd": "HD",
|
||||
"subtitles": "Subtitrai/CC",
|
||||
"creative_commons": "Creative Commons",
|
||||
"3d": "3D",
|
||||
"live": "Tiesiogiai",
|
||||
"4k": "4K",
|
||||
"location": "Vietovė",
|
||||
"hdr": "HDR",
|
||||
"filter": "Filtras",
|
||||
"search_filters_sort_option_relevance": "Aktualumas",
|
||||
"search_filters_sort_option_rating": "Reitingas",
|
||||
"search_filters_sort_option_date": "Įkėlimo data",
|
||||
"search_filters_sort_option_views": "Peržiūrų skaičius",
|
||||
"search_filters_type_label": "Tipas",
|
||||
"search_filters_duration_label": "Trukmė",
|
||||
"search_filters_features_label": "Funkcijos",
|
||||
"search_filters_sort_label": "Rūšiuoti pagal",
|
||||
"search_filters_date_option_hour": "Per paskutinę valandą",
|
||||
"search_filters_date_option_today": "Šiandien",
|
||||
"search_filters_date_option_week": "Šią savaitę",
|
||||
"search_filters_date_option_month": "Šį mėnesį",
|
||||
"search_filters_date_option_year": "Šiais metais",
|
||||
"search_filters_type_option_video": "Vaizdo įrašas",
|
||||
"search_filters_type_option_channel": "Kanalas",
|
||||
"search_filters_type_option_playlist": "Grojaraštis",
|
||||
"search_filters_type_option_movie": "Filmas",
|
||||
"search_filters_type_option_show": "Serialas",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "Subtitrai/CC",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_live": "Tiesiogiai",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_location": "Vietovė",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"Current version: ": "Dabartinė versija: ",
|
||||
"next_steps_error_message": "Po to turėtumėte pabandyti: ",
|
||||
"next_steps_error_message_refresh": "Atnaujinti",
|
||||
"next_steps_error_message_go_to_youtube": "Eiti į YouTube",
|
||||
"short": "Trumpas (< 4 minučių)",
|
||||
"long": "Ilgas (> 20 minučių)",
|
||||
"search_filters_duration_option_short": "Trumpas (< 4 minučių)",
|
||||
"search_filters_duration_option_long": "Ilgas (> 20 minučių)",
|
||||
"footer_documentation": "Dokumentacija",
|
||||
"footer_source_code": "Pirminis kodas",
|
||||
"footer_original_source_code": "Pradinis pirminis kodas",
|
||||
@@ -369,5 +367,9 @@
|
||||
"footer_modfied_source_code": "Pakeistas pirminis kodas",
|
||||
"footer_donate_page": "Paaukoti",
|
||||
"preferences_region_label": "Turinio šalis: ",
|
||||
"preferences_quality_dash_label": "Pageidaujama DASH vaizdo kokybė: "
|
||||
"preferences_quality_dash_label": "Pageidaujama DASH vaizdo kokybė: ",
|
||||
"preferences_quality_dash_option_best": "Geriausia",
|
||||
"preferences_quality_dash_option_worst": "Blogiausia",
|
||||
"preferences_quality_dash_option_auto": "Automatinis",
|
||||
"search_filters_title": "Filtras"
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"Export": "Eksporter",
|
||||
"Export subscriptions as OPML": "Eksporter abonnementer som OPML",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Eksporter abonnementer som OPML (for NewPipe og FreeTube)",
|
||||
"Export data as JSON": "Eksporter data som JSON",
|
||||
"Export data as JSON": "Eksporter Invidiousdata som JSON",
|
||||
"Delete account?": "Slett konto?",
|
||||
"History": "Historikk",
|
||||
"An alternative front-end to YouTube": "En alternativ grenseflate for YouTube",
|
||||
@@ -66,7 +66,7 @@
|
||||
"preferences_related_videos_label": "Vis relaterte videoer? ",
|
||||
"preferences_annotations_label": "Vis merknader som forvalg? ",
|
||||
"preferences_extend_desc_label": "Utvid videobeskrivelse automatisk: ",
|
||||
"preferences_vr_mode_label": "Interaktive 360-gradersfilmer: ",
|
||||
"preferences_vr_mode_label": "Interaktive 360-gradersfilmer (krever WebGL): ",
|
||||
"preferences_category_visual": "Visuelle innstillinger",
|
||||
"preferences_player_style_label": "Avspillerstil: ",
|
||||
"Dark mode: ": "Mørk drakt: ",
|
||||
@@ -121,7 +121,7 @@
|
||||
"Subscriptions": "Abonnement",
|
||||
"search": "søk",
|
||||
"Log out": "Logg ut",
|
||||
"Released under the AGPLv3 on Github.": "Tilgjengelig med AGPLv3-lisens på Github.",
|
||||
"Released under the AGPLv3 on Github.": "Tilgjengelig med AGPLv3-lisens på GitHub.",
|
||||
"Source available here.": "Kildekode tilgjengelig her.",
|
||||
"View JavaScript license information.": "Vis JavaScript-lisensinfo.",
|
||||
"View privacy policy.": "Vis personvernspraksis.",
|
||||
@@ -141,7 +141,6 @@
|
||||
"Show less": "Vis mindre",
|
||||
"Watch on YouTube": "Vis video på YouTube",
|
||||
"Switch Invidious Instance": "Bytt Invidious-instans",
|
||||
"Broken? Try another Invidious Instance": "Knekt? Forsøk en annen Invidious-instans",
|
||||
"Hide annotations": "Skjul merknader",
|
||||
"Show annotations": "Vis merknader",
|
||||
"Genre: ": "Sjanger: ",
|
||||
@@ -199,7 +198,7 @@
|
||||
"No such user": "Ugyldig bruker",
|
||||
"Token is expired, please try again": "Symbol utløpt, prøv igjen",
|
||||
"English": "Engelsk",
|
||||
"English (auto-generated)": "Engelsk (auto-generert)",
|
||||
"English (auto-generated)": "Engelsk (laget automatisk)",
|
||||
"Afrikaans": "Afrikansk",
|
||||
"Albanian": "Albansk",
|
||||
"Amharic": "Amharisk",
|
||||
@@ -329,40 +328,39 @@
|
||||
"Videos": "Videoer",
|
||||
"Playlists": "Spillelister",
|
||||
"Community": "Gemenskap",
|
||||
"relevance": "relevans",
|
||||
"rating": "vurdering",
|
||||
"date": "dato",
|
||||
"views": "visninger",
|
||||
"content_type": "innholdstype",
|
||||
"duration": "varighet",
|
||||
"features": "funksjoner",
|
||||
"sort": "sorter",
|
||||
"hour": "time",
|
||||
"today": "i dag",
|
||||
"week": "uke",
|
||||
"month": "måned",
|
||||
"year": "år",
|
||||
"video": "video",
|
||||
"channel": "kanal",
|
||||
"playlist": "spilleliste",
|
||||
"movie": "film",
|
||||
"show": "vis",
|
||||
"hd": "HD",
|
||||
"subtitles": "undertekster",
|
||||
"creative_commons": "Creative Commons",
|
||||
"3d": "3D",
|
||||
"live": "direkte",
|
||||
"4k": "4k",
|
||||
"location": "sted",
|
||||
"hdr": "HDR",
|
||||
"filter": "filtrer",
|
||||
"search_filters_sort_option_relevance": "relevans",
|
||||
"search_filters_sort_option_rating": "vurdering",
|
||||
"search_filters_sort_option_date": "dato",
|
||||
"search_filters_sort_option_views": "visninger",
|
||||
"search_filters_type_label": "innholdstype",
|
||||
"search_filters_duration_label": "varighet",
|
||||
"search_filters_features_label": "funksjoner",
|
||||
"search_filters_sort_label": "sorter",
|
||||
"search_filters_date_option_hour": "time",
|
||||
"search_filters_date_option_today": "i dag",
|
||||
"search_filters_date_option_week": "uke",
|
||||
"search_filters_date_option_month": "måned",
|
||||
"search_filters_date_option_year": "år",
|
||||
"search_filters_type_option_video": "video",
|
||||
"search_filters_type_option_channel": "kanal",
|
||||
"search_filters_type_option_playlist": "spilleliste",
|
||||
"search_filters_type_option_movie": "film",
|
||||
"search_filters_type_option_show": "vis",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "undertekster",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_live": "direkte",
|
||||
"search_filters_features_option_four_k": "4k",
|
||||
"search_filters_features_option_location": "sted",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"Current version: ": "Gjeldende versjon: ",
|
||||
"next_steps_error_message": "Etterpå bør du prøve dette: ",
|
||||
"next_steps_error_message_refresh": "Gjenoppfrisk",
|
||||
"next_steps_error_message_go_to_youtube": "Gå til YouTube",
|
||||
"long": "Lang (> 20 minutter)",
|
||||
"search_filters_duration_option_long": "Lang (> 20 minutter)",
|
||||
"footer_donate_page": "Doner",
|
||||
"short": "Kort (< 4 minutter)",
|
||||
"search_filters_duration_option_short": "Kort (< 4 minutter)",
|
||||
"footer_documentation": "Dokumentasjon",
|
||||
"footer_source_code": "Kildekode",
|
||||
"footer_original_source_code": "Opprinnelig kildekode",
|
||||
@@ -384,8 +382,8 @@
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"invidious": "Invidious",
|
||||
"purchased": "Kjøpt",
|
||||
"360": "360°",
|
||||
"search_filters_features_option_purchased": "Kjøpt",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"none": "intet",
|
||||
"videoinfo_watch_on_youTube": "Se på YouTube",
|
||||
"videoinfo_youTube_embed_link": "Bak inn",
|
||||
@@ -432,10 +430,46 @@
|
||||
"generic_count_years": "{{count}} år",
|
||||
"generic_count_years_plural": "{{count}} år",
|
||||
"crash_page_read_the_faq": "lest de <a href=\"`x`\">Ofte stilte spørsmålene (OSS/FAQ)</a>",
|
||||
"crash_page_search_issue": "søkt etter <a href=\"`x`\">eksisterende utfordringer på Github</a>",
|
||||
"crash_page_search_issue": "søkt etter <a href=\"`x`\">eksisterende utfordringer på GitHub</a>",
|
||||
"crash_page_you_found_a_bug": "Det ser ut til at du fant en feil i Invidious!",
|
||||
"crash_page_refresh": "forsøkt å <a href=\"`x`\">laste siden på nytt</a>",
|
||||
"crash_page_switch_instance": "forsøkt et <a href=\"`x`\">annet eksemplar</a>",
|
||||
"crash_page_before_reporting": "Før du rapporterer en feil, sikre at du har:",
|
||||
"crash_page_report_issue": "Hvis intet av det overnevnte hjalp, <a href=\"`x`\">lag en ny utfordring på Github</a> (fortrinnsvis på engelsk) og ta med følgende tekstbit i meldingen dit (IKKE oversett denne teksten):"
|
||||
"crash_page_report_issue": "Sett at det overnevnte ikke hjalp, <a href=\"`x`\">lag en ny utfordring på GitHub</a> (fortrinnsvis på engelsk) og få med følgende tekstbit i meldingen dithen (IKKE oversett denne teksten):",
|
||||
"English (United Kingdom)": "Engelsk (Storbritannia)",
|
||||
"English (United States)": "Engelsk (USA)",
|
||||
"Cantonese (Hong Kong)": "Kantonesisk (Hong Kong)",
|
||||
"Portuguese (Brazil)": "Portugisisk (Brasil)",
|
||||
"Spanish (Mexico)": "Spansk (Mexico)",
|
||||
"Spanish (Spain)": "Spansk (Spania)",
|
||||
"Spanish (auto-generated)": "Spansk (laget automatisk)",
|
||||
"Vietnamese (auto-generated)": "Vietnamesisk (laget automatisk)",
|
||||
"preferences_watch_history_label": "Aktiver seerhistorikk: ",
|
||||
"Chinese": "Kinesisk",
|
||||
"Chinese (China)": "Kinesisk (Kina)",
|
||||
"Chinese (Hong Kong)": "Kinesisk (Hong Kong)",
|
||||
"Chinese (Taiwan)": "Kinesisk (Taiwan)",
|
||||
"French (auto-generated)": "Fransk (laget automatisk)",
|
||||
"German (auto-generated)": "Tysk (laget automatisk)",
|
||||
"Indonesian (auto-generated)": "Indonesisk (laget automatisk)",
|
||||
"Interlingue": "Interlingue",
|
||||
"Italian (auto-generated)": "Italiensk (laget automatisk)",
|
||||
"Japanese (auto-generated)": "Japansk (laget automatisk)",
|
||||
"Korean (auto-generated)": "Koreansk (laget automatisk)",
|
||||
"Portuguese (auto-generated)": "Portugisisk (laget automatisk)",
|
||||
"Russian (auto-generated)": "Russisk (laget automatisk)",
|
||||
"Dutch (auto-generated)": "Nederlandsk (laget automatisk)",
|
||||
"Turkish (auto-generated)": "Tyrkisk (laget automatisk)",
|
||||
"search_filters_title": "Filtrer",
|
||||
"Popular enabled: ": "Populære aktiv: ",
|
||||
"search_message_change_filters_or_query": "Prøv ett mindre snevert søk og/eller endre filterne.",
|
||||
"search_filters_duration_option_medium": "Middels (4–20 minutter)",
|
||||
"search_message_no_results": "Resultatløst.",
|
||||
"search_filters_type_option_all": "Alle typer",
|
||||
"search_filters_duration_option_none": "Enhver varighet",
|
||||
"search_message_use_another_instance": " Du kan også <a href=\"`x`\">søke på en annen instans</a>.",
|
||||
"search_filters_date_label": "Opplastningsdato",
|
||||
"search_filters_apply_button": "Bruk valgte filtre",
|
||||
"search_filters_date_option_none": "Siden begynnelsen",
|
||||
"search_filters_features_option_vr180": "VR180"
|
||||
}
|
||||
|
||||
148
locales/nl.json
148
locales/nl.json
@@ -21,15 +21,15 @@
|
||||
"No": "Nee",
|
||||
"Import and Export Data": "Gegevens im- en exporteren",
|
||||
"Import": "Importeren",
|
||||
"Import Invidious data": "Invidious-gegevens importeren",
|
||||
"Import YouTube subscriptions": "YouTube-abonnementen importeren",
|
||||
"Import Invidious data": "JSON-gegevens Invidious importeren",
|
||||
"Import YouTube subscriptions": "YouTube-/OPML-abonnementen importeren",
|
||||
"Import FreeTube subscriptions (.db)": "FreeTube-abonnementen importeren (.db)",
|
||||
"Import NewPipe subscriptions (.json)": "NewPipe-abonnementen importeren (.json)",
|
||||
"Import NewPipe data (.zip)": "NewPipe-gegevens importeren (.zip)",
|
||||
"Export": "Exporteren",
|
||||
"Export subscriptions as OPML": "Abonnementen exporteren als OPML",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Abonnementen exporteren als OPML (voor NewPipe en FreeTube)",
|
||||
"Export data as JSON": "Gegevens exporteren als JSON",
|
||||
"Export data as JSON": "Invidious-gegevens naar JSON exporteren",
|
||||
"Delete account?": "Wilt u uw account verwijderen?",
|
||||
"History": "Geschiedenis",
|
||||
"An alternative front-end to YouTube": "Een alternatief front-end voor YouTube",
|
||||
@@ -66,7 +66,7 @@
|
||||
"preferences_related_videos_label": "Gerelateerde video's tonen? ",
|
||||
"preferences_annotations_label": "Standaard annotaties tonen? ",
|
||||
"preferences_extend_desc_label": "Breid videobeschrijving automatisch uit: ",
|
||||
"preferences_vr_mode_label": "Interactieve 360-graden-video's ",
|
||||
"preferences_vr_mode_label": "Interactieve 360-graden-video's (vereist WebGL) ",
|
||||
"preferences_category_visual": "Visuele instellingen",
|
||||
"preferences_player_style_label": "Speler vormgeving ",
|
||||
"Dark mode: ": "Donkere modus: ",
|
||||
@@ -323,33 +323,32 @@
|
||||
"Videos": "Video's",
|
||||
"Playlists": "Afspeellijsten",
|
||||
"Community": "Gemeenschap",
|
||||
"relevance": "relevantie",
|
||||
"rating": "beoordeling",
|
||||
"date": "datum",
|
||||
"views": "keren bekeken",
|
||||
"content_type": "Type inhoud",
|
||||
"duration": "duur",
|
||||
"features": "eigenschappen",
|
||||
"sort": "sorteren",
|
||||
"hour": "uur",
|
||||
"today": "vandaag",
|
||||
"week": "week",
|
||||
"month": "maand",
|
||||
"year": "jaar",
|
||||
"video": "video",
|
||||
"channel": "kanaal",
|
||||
"playlist": "afspeellijst",
|
||||
"movie": "film",
|
||||
"show": "show",
|
||||
"hd": "HD",
|
||||
"subtitles": "ondertitels",
|
||||
"creative_commons": "Creative Commons",
|
||||
"3d": "3D",
|
||||
"live": "Live",
|
||||
"4k": "4K",
|
||||
"location": "locatie",
|
||||
"hdr": "HDR",
|
||||
"filter": "verfijnen",
|
||||
"search_filters_sort_option_relevance": "relevantie",
|
||||
"search_filters_sort_option_rating": "beoordeling",
|
||||
"search_filters_sort_option_date": "datum",
|
||||
"search_filters_sort_option_views": "keren bekeken",
|
||||
"search_filters_type_label": "Type inhoud",
|
||||
"search_filters_duration_label": "duur",
|
||||
"search_filters_features_label": "eigenschappen",
|
||||
"search_filters_sort_label": "sorteren",
|
||||
"search_filters_date_option_hour": "uur",
|
||||
"search_filters_date_option_today": "vandaag",
|
||||
"search_filters_date_option_week": "week",
|
||||
"search_filters_date_option_month": "maand",
|
||||
"search_filters_date_option_year": "jaar",
|
||||
"search_filters_type_option_video": "video",
|
||||
"search_filters_type_option_channel": "kanaal",
|
||||
"search_filters_type_option_playlist": "afspeellijst",
|
||||
"search_filters_type_option_movie": "film",
|
||||
"search_filters_type_option_show": "show",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "ondertitels",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_live": "Live",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_location": "locatie",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"Current version: ": "Huidige versie: ",
|
||||
"Switch Invidious Instance": "Schakel tussen de Invidious Instanties",
|
||||
"preferences_automatic_instance_redirect_label": "Automatische instantie-omleiding (terugval naar redirect.invidious.io): ",
|
||||
@@ -357,8 +356,8 @@
|
||||
"preferences_region_label": "Inhoud land: ",
|
||||
"preferences_category_misc": "Diverse voorkeuren",
|
||||
"preferences_show_nick_label": "Toon bijnaam bovenaan: ",
|
||||
"Released under the AGPLv3 on Github.": "Uitgebracht onder de AGPLv3 op Github.",
|
||||
"short": "Kort (<4 minuten)",
|
||||
"Released under the AGPLv3 on Github.": "Uitgebracht onder de AGPLv3 op GitHub.",
|
||||
"search_filters_duration_option_short": "Kort (<4 minuten)",
|
||||
"next_steps_error_message_refresh": "Vernieuwen",
|
||||
"next_steps_error_message_go_to_youtube": "Ga naar YouTube",
|
||||
"footer_donate_page": "Doneren",
|
||||
@@ -366,10 +365,9 @@
|
||||
"footer_original_source_code": "Originele bron-code",
|
||||
"footer_modfied_source_code": "Gewijzigde bron-code",
|
||||
"adminprefs_modified_source_code_url_label": "URL naar gewijzigde bron-code-opslagplaats",
|
||||
"Broken? Try another Invidious Instance": "Kapot? Probeer een andere Invidious Instantie",
|
||||
"next_steps_error_message": "Waarna u moet proberen om: ",
|
||||
"footer_source_code": "Bron-code",
|
||||
"long": "Lang (> 20 minuten)",
|
||||
"search_filters_duration_option_long": "Lang (> 20 minuten)",
|
||||
"preferences_quality_option_dash": "DASH (adaptieve kwaliteit)",
|
||||
"preferences_quality_option_hd720": "HD720",
|
||||
"preferences_quality_option_medium": "Gemiddeld",
|
||||
@@ -395,8 +393,82 @@
|
||||
"user_created_playlists": "`x` afspeellijsten aangemaakt",
|
||||
"user_saved_playlists": "`x` afspeellijsten opgeslagen",
|
||||
"Video unavailable": "Video onbeschikbaar",
|
||||
"preferences_save_player_pos_label": "Huidig afspeeltijdstip opslaan: ",
|
||||
"preferences_save_player_pos_label": "Afspeelpositie opslaan: ",
|
||||
"none": "geen",
|
||||
"purchased": "Gekocht",
|
||||
"360": "360º"
|
||||
"search_filters_features_option_purchased": "Gekocht",
|
||||
"search_filters_features_option_three_sixty": "360º",
|
||||
"search_filters_title": "Verfijnen",
|
||||
"generic_count_days": "{{count}} dag",
|
||||
"generic_count_days_plural": "{{count}} dagen",
|
||||
"Chinese (Taiwan)": "Chinees (Taiwan)",
|
||||
"Dutch (auto-generated)": "Nederlands (automatisch gegenereerd)",
|
||||
"tokens_count": "{{count}} token",
|
||||
"tokens_count_plural": "{{count}} tokens",
|
||||
"generic_count_seconds": "{{count}} second",
|
||||
"generic_count_seconds_plural": "{{count}} seconden",
|
||||
"generic_count_weeks": "{{count}} week",
|
||||
"generic_count_weeks_plural": "{{count}} weken",
|
||||
"English (United States)": "Engels (Verenigde Staten)",
|
||||
"generic_views_count": "{{count}} keer bekeken",
|
||||
"generic_views_count_plural": "{{count}} keren bekeken",
|
||||
"generic_videos_count": "{{count}} video",
|
||||
"generic_videos_count_plural": "{{count}} video's",
|
||||
"generic_subscriptions_count": "{{count}} abonnement",
|
||||
"generic_subscriptions_count_plural": "{{count}} abonnementen",
|
||||
"subscriptions_unseen_notifs_count": "{{count}} ongeziene melding",
|
||||
"subscriptions_unseen_notifs_count_plural": "{{count}} ongeziene meldingen",
|
||||
"preferences_watch_history_label": "Kijkgeschiedenis inschakelen: ",
|
||||
"crash_page_switch_instance": "geprobeerd hebt om <a href=\"`x`\">een andere instantie te gebruiken</a>",
|
||||
"Portuguese (auto-generated)": "Portugees (automatisch gegenereerd)",
|
||||
"Russian (auto-generated)": "Russisch (automatisch gegenereerd)",
|
||||
"Vietnamese (auto-generated)": "Vietnamees (automatisch gegenereerd)",
|
||||
"comments_points_count": "{{count}} punt",
|
||||
"comments_points_count_plural": "{{count}} punten",
|
||||
"crash_page_before_reporting": "Voor je een bug rapporteert, kijk even na of je:",
|
||||
"Chinese": "Chinees",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"search_filters_date_label": "Uploaddatum",
|
||||
"Portuguese (Brazil)": "Portugees (Brazilië)",
|
||||
"Interlingue": "Interlingue",
|
||||
"Turkish (auto-generated)": "Turks (automatisch gegenereerd)",
|
||||
"search_filters_date_option_none": "Alle datums",
|
||||
"generic_subscribers_count": "{{count}} abonnee",
|
||||
"generic_subscribers_count_plural": "{{count}} abonnees",
|
||||
"search_message_no_results": "Geen resultaten teruggevonden.",
|
||||
"search_message_change_filters_or_query": "Probeer je zoekopdracht uit te breiden en/of de filters aan te passen.",
|
||||
"English (United Kingdom)": "Engels (Verenigd Koninkrijk)",
|
||||
"German (auto-generated)": "Duits (automatisch gegenereerd)",
|
||||
"Spanish (Mexico)": "Spaans (Mexico)",
|
||||
"Spanish (Spain)": "Spaans (Spanje)",
|
||||
"search_filters_type_option_all": "Alle types",
|
||||
"crash_page_refresh": "geprobeerd hebt om <a href=\"`x`\">de pagina te herladen</a>",
|
||||
"comments_view_x_replies": "{{count}} reactie bekijken",
|
||||
"comments_view_x_replies_plural": "{{count}} reacties bekijken",
|
||||
"generic_count_years": "{{count}} jaar",
|
||||
"generic_count_years_plural": "{{count}} jaren",
|
||||
"generic_count_months": "{{count}} maand",
|
||||
"generic_count_months_plural": "{{count}} maanden",
|
||||
"generic_count_hours": "{{count}} uur",
|
||||
"generic_count_hours_plural": "{{count}} uren",
|
||||
"generic_count_minutes": "{{count}} minuut",
|
||||
"generic_count_minutes_plural": "{{count}} minuten",
|
||||
"French (auto-generated)": "Frans (automatisch gegenereerd)",
|
||||
"generic_playlists_count": "{{count}} afspeellijst",
|
||||
"generic_playlists_count_plural": "{{count}} afspeellijsten",
|
||||
"Chinese (Hong Kong)": "Chinees (Hongkong)",
|
||||
"Korean (auto-generated)": "Koreaans (automatisch gegenereerd)",
|
||||
"search_filters_apply_button": "Geselecteerd filters toepassen",
|
||||
"search_message_use_another_instance": " Je kan ook <a href=\"`x`\">zoeken op een andere instantie</a>.",
|
||||
"Cantonese (Hong Kong)": "Kantonees (Hongkong)",
|
||||
"Chinese (China)": "Chinees (China)",
|
||||
"crash_page_read_the_faq": "de <a href=\"`x`\">veelgestelde vragen (FAQ)</a> gelezen hebt",
|
||||
"crash_page_search_issue": "gezocht hebt op <a href=\"`x`\">bestaande problemen op GitHub</a>",
|
||||
"search_filters_duration_option_none": "Alle lengtes",
|
||||
"Indonesian (auto-generated)": "Indonesisch (automatisch gegenereerd)",
|
||||
"Italian (auto-generated)": "Italiaans (automatisch gegenereerd)",
|
||||
"Japanese (auto-generated)": "Japans (automatisch gegenereerd)",
|
||||
"Spanish (auto-generated)": "Spaans (automatisch gegenereerd)",
|
||||
"crash_page_you_found_a_bug": "Je lijkt een bug in Invidious tegengekomen te zijn!",
|
||||
"search_filters_duration_option_medium": "Gemiddeld (4 - 20 minuten)",
|
||||
"crash_page_report_issue": "Indien het bovenstaande niet hielp, gelieve dan <a href=\"`x`\">een nieuw ticket op GitHub</a> te openen (liefst in het Engels) en neem de volgende tekst op in je bericht (gelieve deze NIET te vertalen):"
|
||||
}
|
||||
|
||||
@@ -140,7 +140,6 @@
|
||||
"Show less": "Pokaż mniej",
|
||||
"Watch on YouTube": "Zobacz film na YouTube",
|
||||
"Switch Invidious Instance": "Przełącz instancję Invidious",
|
||||
"Broken? Try another Invidious Instance": "Nie działa? Spróbuj innej instancji Invidious",
|
||||
"Hide annotations": "Ukryj adnotacje",
|
||||
"Show annotations": "Pokaż adnotacje",
|
||||
"Genre: ": "Gatunek: ",
|
||||
@@ -328,33 +327,32 @@
|
||||
"Videos": "Filmy",
|
||||
"Playlists": "Playlisty",
|
||||
"Community": "Społeczność",
|
||||
"relevance": "Trafność",
|
||||
"rating": "Ocena",
|
||||
"date": "data",
|
||||
"views": "Liczba wyświetleń",
|
||||
"content_type": "Typ",
|
||||
"duration": "Długość",
|
||||
"features": "Funkcje",
|
||||
"sort": "sortuj",
|
||||
"hour": "godzina",
|
||||
"today": "dzisiaj",
|
||||
"week": "tydzień",
|
||||
"month": "miesiąc",
|
||||
"year": "rok",
|
||||
"video": "Film",
|
||||
"channel": "kanał",
|
||||
"playlist": "playlista",
|
||||
"movie": "film",
|
||||
"show": "pokaż",
|
||||
"hd": "hd",
|
||||
"subtitles": "napisy",
|
||||
"creative_commons": "creative_commons",
|
||||
"3d": "3d",
|
||||
"live": "Na żywo",
|
||||
"4k": "4k",
|
||||
"location": "Lokalizacja",
|
||||
"hdr": "hdr",
|
||||
"filter": "filtr",
|
||||
"search_filters_sort_option_relevance": "Trafność",
|
||||
"search_filters_sort_option_rating": "Ocena",
|
||||
"search_filters_sort_option_date": "data",
|
||||
"search_filters_sort_option_views": "Liczba wyświetleń",
|
||||
"search_filters_type_label": "Typ",
|
||||
"search_filters_duration_label": "Długość",
|
||||
"search_filters_features_label": "Funkcje",
|
||||
"search_filters_sort_label": "sortuj",
|
||||
"search_filters_date_option_hour": "godzina",
|
||||
"search_filters_date_option_today": "dzisiaj",
|
||||
"search_filters_date_option_week": "tydzień",
|
||||
"search_filters_date_option_month": "miesiąc",
|
||||
"search_filters_date_option_year": "rok",
|
||||
"search_filters_type_option_video": "Film",
|
||||
"search_filters_type_option_channel": "kanał",
|
||||
"search_filters_type_option_playlist": "playlista",
|
||||
"search_filters_type_option_movie": "film",
|
||||
"search_filters_type_option_show": "pokaż",
|
||||
"search_filters_features_option_hd": "hd",
|
||||
"search_filters_features_option_subtitles": "napisy",
|
||||
"search_filters_features_option_c_commons": "creative_commons",
|
||||
"search_filters_features_option_three_d": "3d",
|
||||
"search_filters_features_option_live": "Na żywo",
|
||||
"search_filters_features_option_four_k": "4k",
|
||||
"search_filters_features_option_location": "Lokalizacja",
|
||||
"search_filters_features_option_hdr": "hdr",
|
||||
"Current version: ": "Aktualna wersja: ",
|
||||
"next_steps_error_message": "Po czym powinien*ś spróbować: ",
|
||||
"next_steps_error_message_refresh": "Odśwież",
|
||||
@@ -432,8 +430,8 @@
|
||||
"preferences_quality_dash_label": "Preferowana jakość filmu DASH: ",
|
||||
"preferences_quality_dash_option_4320p": "4320p",
|
||||
"preferences_quality_dash_option_2160p": "2160p",
|
||||
"purchased": "Zakupione",
|
||||
"360": "360°",
|
||||
"search_filters_features_option_purchased": "Zakupione",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"footer_donate_page": "Dotacja",
|
||||
"none": "żadne",
|
||||
"videoinfo_started_streaming_x_ago": "Transmisja rozpoczęta `x` temu",
|
||||
@@ -446,9 +444,9 @@
|
||||
"Video unavailable": "Film niedostępny",
|
||||
"preferences_save_player_pos_label": "Zapisz pozycję odtwarzania: ",
|
||||
"preferences_region_label": "Region zawartości: ",
|
||||
"Released under the AGPLv3 on Github.": "Wydany na licencji AGPLv3 na Github.",
|
||||
"short": "Krótkie (< 4 minutes)",
|
||||
"long": "Długie (> 20 minutes)",
|
||||
"Released under the AGPLv3 on Github.": "Wydany na licencji AGPLv3 na GitHub.",
|
||||
"search_filters_duration_option_short": "Krótkie (< 4 minutes)",
|
||||
"search_filters_duration_option_long": "Długie (> 20 minutes)",
|
||||
"footer_documentation": "Dokumentacja",
|
||||
"footer_source_code": "Kod źródłowy",
|
||||
"footer_modfied_source_code": "Zmodyfikowany Kod źródłowy",
|
||||
@@ -476,5 +474,6 @@
|
||||
"Japanese (auto-generated)": "japoński (wygenerowany automatycznie)",
|
||||
"Russian (auto-generated)": "rosyjski (wygenerowany automatycznie)",
|
||||
"Portuguese (auto-generated)": "portugalski (wygenerowany automatycznie)",
|
||||
"Portuguese (Brazil)": "portugalski (Brazylia)"
|
||||
"Portuguese (Brazil)": "portugalski (Brazylia)",
|
||||
"search_filters_title": "Filtr"
|
||||
}
|
||||
|
||||
@@ -21,15 +21,15 @@
|
||||
"No": "Não",
|
||||
"Import and Export Data": "Importar e Exportar Dados",
|
||||
"Import": "Importar",
|
||||
"Import Invidious data": "Importar dados do Invidious",
|
||||
"Import YouTube subscriptions": "Importar inscrições do YouTube",
|
||||
"Import Invidious data": "Importar dados em JSON do Invidious",
|
||||
"Import YouTube subscriptions": "Importar inscrições do YouTube/OPML",
|
||||
"Import FreeTube subscriptions (.db)": "Importar inscrições do FreeTube (.db)",
|
||||
"Import NewPipe subscriptions (.json)": "Importar inscrições do NewPipe (.json)",
|
||||
"Import NewPipe data (.zip)": "Importar dados do NewPipe (.zip)",
|
||||
"Export": "Exportar",
|
||||
"Export subscriptions as OPML": "Exportar inscrições como OPML",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Exportar inscrições como OPML (para NewPipe e FreeTube)",
|
||||
"Export data as JSON": "Exportar dados como JSON",
|
||||
"Export data as JSON": "Exportar dados Invidious como JSON",
|
||||
"Delete account?": "Excluir conta?",
|
||||
"History": "Histórico",
|
||||
"An alternative front-end to YouTube": "Uma interface alternativa para o YouTube",
|
||||
@@ -66,7 +66,7 @@
|
||||
"preferences_related_videos_label": "Mostrar vídeos relacionados: ",
|
||||
"preferences_annotations_label": "Sempre mostrar anotações: ",
|
||||
"preferences_extend_desc_label": "Estenda automaticamente a descrição do vídeo: ",
|
||||
"preferences_vr_mode_label": "Vídeos interativos de 360 graus: ",
|
||||
"preferences_vr_mode_label": "Vídeos interativos de 360 graus (requer WebGL): ",
|
||||
"preferences_category_visual": "Preferências visuais",
|
||||
"preferences_player_style_label": "Estilo do tocador: ",
|
||||
"Dark mode: ": "Modo escuro: ",
|
||||
@@ -123,7 +123,7 @@
|
||||
"Subscriptions": "Inscrições",
|
||||
"search": "Pesquisar",
|
||||
"Log out": "Sair",
|
||||
"Released under the AGPLv3 on Github.": "Lançado sob a AGPLv3 no Github.",
|
||||
"Released under the AGPLv3 on Github.": "Lançado sob a AGPLv3 no GitHub.",
|
||||
"Source available here.": "Código-fonte disponível aqui.",
|
||||
"View JavaScript license information.": "Ver informações da licença do JavaScript.",
|
||||
"View privacy policy.": "Ver a política de privacidade.",
|
||||
@@ -143,7 +143,6 @@
|
||||
"Show less": "Mostrar menos",
|
||||
"Watch on YouTube": "Assistir no YouTube",
|
||||
"Switch Invidious Instance": "Mudar a instância do Invidious",
|
||||
"Broken? Try another Invidious Instance": "Quebrou? Tente outra Instância do Invidious",
|
||||
"Hide annotations": "Ocultar anotações",
|
||||
"Show annotations": "Mostrar anotações",
|
||||
"Genre: ": "Gênero: ",
|
||||
@@ -345,41 +344,40 @@
|
||||
"Videos": "Vídeos",
|
||||
"Playlists": "Listas de reprodução",
|
||||
"Community": "Comunidade",
|
||||
"relevance": "relevância",
|
||||
"rating": "avaliação",
|
||||
"date": "data",
|
||||
"views": "visualizações",
|
||||
"content_type": "content_type",
|
||||
"duration": "duração",
|
||||
"features": "recursos",
|
||||
"sort": "ordenar",
|
||||
"hour": "hora",
|
||||
"today": "hoje",
|
||||
"week": "semana",
|
||||
"month": "mês",
|
||||
"year": "ano",
|
||||
"video": "vídeo",
|
||||
"channel": "Canal",
|
||||
"playlist": "playlist",
|
||||
"movie": "filme",
|
||||
"show": "show",
|
||||
"hd": "hd",
|
||||
"subtitles": "legendas",
|
||||
"creative_commons": "creative_commons",
|
||||
"3d": "3d",
|
||||
"live": "ao vivo",
|
||||
"4k": "4k",
|
||||
"location": "localização",
|
||||
"hdr": "hdr",
|
||||
"filter": "filtro",
|
||||
"search_filters_sort_option_relevance": "relevância",
|
||||
"search_filters_sort_option_rating": "avaliação",
|
||||
"search_filters_sort_option_date": "data",
|
||||
"search_filters_sort_option_views": "visualizações",
|
||||
"search_filters_type_label": "content_type",
|
||||
"search_filters_duration_label": "duração",
|
||||
"search_filters_features_label": "recursos",
|
||||
"search_filters_sort_label": "ordenar",
|
||||
"search_filters_date_option_hour": "hora",
|
||||
"search_filters_date_option_today": "hoje",
|
||||
"search_filters_date_option_week": "semana",
|
||||
"search_filters_date_option_month": "mês",
|
||||
"search_filters_date_option_year": "ano",
|
||||
"search_filters_type_option_video": "vídeo",
|
||||
"search_filters_type_option_channel": "Canal",
|
||||
"search_filters_type_option_playlist": "playlist",
|
||||
"search_filters_type_option_movie": "filme",
|
||||
"search_filters_type_option_show": "show",
|
||||
"search_filters_features_option_hd": "hd",
|
||||
"search_filters_features_option_subtitles": "legendas",
|
||||
"search_filters_features_option_c_commons": "creative_commons",
|
||||
"search_filters_features_option_three_d": "3d",
|
||||
"search_filters_features_option_live": "ao vivo",
|
||||
"search_filters_features_option_four_k": "4k",
|
||||
"search_filters_features_option_location": "localização",
|
||||
"search_filters_features_option_hdr": "hdr",
|
||||
"Current version: ": "Versão atual: ",
|
||||
"next_steps_error_message": "Depois disso, você deve tentar: ",
|
||||
"next_steps_error_message_refresh": "Atualizar",
|
||||
"next_steps_error_message_go_to_youtube": "Ir para o YouTube",
|
||||
"footer_donate_page": "Doe",
|
||||
"adminprefs_modified_source_code_url_label": "URL para repositório de código fonte modificado",
|
||||
"long": "Longo (> 20 minutos)",
|
||||
"short": "Curto (< 4 minutos)",
|
||||
"search_filters_duration_option_long": "Longo (> 20 minutos)",
|
||||
"search_filters_duration_option_short": "Curto (< 4 minutos)",
|
||||
"footer_documentation": "Documentação",
|
||||
"footer_source_code": "Código fonte",
|
||||
"footer_original_source_code": "Código fonte original",
|
||||
@@ -404,15 +402,15 @@
|
||||
"crash_page_you_found_a_bug": "Parece que você encontrou um erro no Invidious!",
|
||||
"crash_page_before_reporting": "Antes de reportar um erro, verifique se você:",
|
||||
"preferences_save_player_pos_label": "Salvar a posição de reprodução: ",
|
||||
"purchased": "Comprado",
|
||||
"search_filters_features_option_purchased": "Comprado",
|
||||
"crash_page_refresh": "tentou <a href=\"`x`\">recarregar a página</a>",
|
||||
"crash_page_switch_instance": "tentou <a href=\"`x`\">usar outra instância</a>",
|
||||
"crash_page_search_issue": "procurou por um <a href=\"`x`\">erro existente no Github</a>",
|
||||
"crash_page_search_issue": "procurou por um <a href=\"`x`\">erro existente no GitHub</a>",
|
||||
"crash_page_report_issue": "Se nenhuma opção acima ajudou, por favor <a href=\"`x`\">abra um novo problema no Github</a> (preferencialmente em inglês) e inclua o seguinte texto (NÃO traduza):",
|
||||
"crash_page_read_the_faq": "leu as <a href=\"`x`\">Perguntas Frequentes (FAQ)</a>",
|
||||
"crash_page_read_the_faq": "leia as <a href=\"`x`\">Perguntas frequentes (FAQ)</a>",
|
||||
"generic_views_count": "{{count}} visualização",
|
||||
"generic_views_count_plural": "{{count}} visualizações",
|
||||
"preferences_quality_option_dash": "DASH (qualidade adaptiva)",
|
||||
"preferences_quality_option_dash": "DASH (qualidade adaptável)",
|
||||
"preferences_quality_option_hd720": "HD720",
|
||||
"preferences_quality_option_small": "Pequeno",
|
||||
"preferences_quality_dash_option_auto": "Auto",
|
||||
@@ -428,7 +426,7 @@
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"invidious": "Invidious",
|
||||
"preferences_quality_option_medium": "Médio",
|
||||
"360": "360°",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"none": "none",
|
||||
"videoinfo_watch_on_youTube": "Assistir no YouTube",
|
||||
"videoinfo_youTube_embed_link": "Embutir",
|
||||
@@ -437,5 +435,41 @@
|
||||
"user_created_playlists": "`x` listas de reprodução criadas",
|
||||
"user_saved_playlists": "`x` listas de reprodução salvas",
|
||||
"Video unavailable": "Vídeo indisponível",
|
||||
"videoinfo_started_streaming_x_ago": "Iniciou a transmissão a `x`"
|
||||
"videoinfo_started_streaming_x_ago": "Iniciou a transmissão a `x`",
|
||||
"search_filters_title": "Filtro",
|
||||
"preferences_watch_history_label": "Ative o histórico de exibição: ",
|
||||
"search_message_no_results": "Nenhum resultado encontrado.",
|
||||
"search_message_change_filters_or_query": "Tente ampliar sua consulta de pesquisa e/ou alterar os filtros.",
|
||||
"English (United Kingdom)": "Inglês (Reino Unido)",
|
||||
"English (United States)": "Inglês (Estados Unidos)",
|
||||
"German (auto-generated)": "Alemão (gerado automaticamente)",
|
||||
"Chinese": "Chinês",
|
||||
"Chinese (China)": "Chinês (China)",
|
||||
"Cantonese (Hong Kong)": "Cantonês (Hong Kong)",
|
||||
"Interlingue": "Interlíngua",
|
||||
"search_filters_type_option_all": "Qualquer tipo",
|
||||
"search_filters_apply_button": "Aplicar filtros selecionados",
|
||||
"Chinese (Hong Kong)": "Chinês (Hong Kong)",
|
||||
"Chinese (Taiwan)": "Chinês (Taiwan)",
|
||||
"Japanese (auto-generated)": "Japonês (gerado automaticamente)",
|
||||
"Korean (auto-generated)": "Coreano (gerado automaticamente)",
|
||||
"Portuguese (auto-generated)": "Português (gerado automaticamente)",
|
||||
"Portuguese (Brazil)": "Português (Brasil)",
|
||||
"Russian (auto-generated)": "Russo (gerado automaticamente)",
|
||||
"Vietnamese (auto-generated)": "Vietnamita (gerado automaticamente)",
|
||||
"search_filters_date_label": "Data de upload",
|
||||
"search_filters_date_option_none": "Qualquer data",
|
||||
"Dutch (auto-generated)": "Holandês (gerado automaticamente)",
|
||||
"French (auto-generated)": "Francês (gerado automaticamente)",
|
||||
"Indonesian (auto-generated)": "Indonésio (gerado automaticamente)",
|
||||
"Italian (auto-generated)": "Italiano (gerado automaticamente)",
|
||||
"Spanish (auto-generated)": "Espanhol (gerado automaticamente)",
|
||||
"Spanish (Mexico)": "Espanhol (México)",
|
||||
"search_filters_duration_option_none": "Qualquer duração",
|
||||
"search_message_use_another_instance": " Você também pode <a href=\"`x`\">pesquisar em outra instância</a>.",
|
||||
"Spanish (Spain)": "Espanhol (Espanha)",
|
||||
"Turkish (auto-generated)": "Turco (gerado automaticamente)",
|
||||
"search_filters_duration_option_medium": "Médio (4 - 20 minutos)",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"Popular enabled: ": "Popular habilitado: "
|
||||
}
|
||||
|
||||
@@ -21,15 +21,15 @@
|
||||
"No": "Não",
|
||||
"Import and Export Data": "Importar e exportar dados",
|
||||
"Import": "Importar",
|
||||
"Import Invidious data": "Importar dados do Invidious",
|
||||
"Import YouTube subscriptions": "Importar subscrições do YouTube",
|
||||
"Import Invidious data": "Importar dados JSON do Invidious",
|
||||
"Import YouTube subscriptions": "Importar subscrições OPML ou do YouTube",
|
||||
"Import FreeTube subscriptions (.db)": "Importar subscrições do FreeTube (.db)",
|
||||
"Import NewPipe subscriptions (.json)": "Importar subscrições do NewPipe (.json)",
|
||||
"Import NewPipe data (.zip)": "Importar dados do NewPipe (.zip)",
|
||||
"Export": "Exportar",
|
||||
"Export subscriptions as OPML": "Exportar subscrições como OPML",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Exportar subscrições como OPML (para NewPipe e FreeTube)",
|
||||
"Export data as JSON": "Exportar dados como JSON",
|
||||
"Export data as JSON": "Exportar dados do Invidious como JSON",
|
||||
"Delete account?": "Eliminar conta?",
|
||||
"History": "Histórico",
|
||||
"An alternative front-end to YouTube": "Uma interface alternativa ao YouTube",
|
||||
@@ -60,13 +60,13 @@
|
||||
"preferences_volume_label": "Volume da reprodução: ",
|
||||
"preferences_comments_label": "Preferência dos comentários: ",
|
||||
"youtube": "YouTube",
|
||||
"reddit": "reddit",
|
||||
"reddit": "Reddit",
|
||||
"preferences_captions_label": "Legendas predefinidas: ",
|
||||
"Fallback captions: ": "Legendas alternativas: ",
|
||||
"preferences_related_videos_label": "Mostrar vídeos relacionados: ",
|
||||
"preferences_annotations_label": "Mostrar anotações sempre: ",
|
||||
"preferences_extend_desc_label": "Estender automaticamente a descrição do vídeo: ",
|
||||
"preferences_vr_mode_label": "Vídeos interativos de 360 graus: ",
|
||||
"preferences_vr_mode_label": "Vídeos interativos de 360 graus (necessita de WebGL): ",
|
||||
"preferences_category_visual": "Preferências visuais",
|
||||
"preferences_player_style_label": "Estilo do reprodutor: ",
|
||||
"Dark mode: ": "Modo escuro: ",
|
||||
@@ -123,7 +123,7 @@
|
||||
"Subscriptions": "Subscrições",
|
||||
"search": "pesquisar",
|
||||
"Log out": "Terminar sessão",
|
||||
"Released under the AGPLv3 on Github.": "Lançado sob a AGPLv3 no Github.",
|
||||
"Released under the AGPLv3 on Github.": "Lançado sob a AGPLv3 no GitHub.",
|
||||
"Source available here.": "Código-fonte disponível aqui.",
|
||||
"View JavaScript license information.": "Ver informações da licença do JavaScript.",
|
||||
"View privacy policy.": "Ver a política de privacidade.",
|
||||
@@ -143,7 +143,6 @@
|
||||
"Show less": "Mostrar menos",
|
||||
"Watch on YouTube": "Ver no YouTube",
|
||||
"Switch Invidious Instance": "Mudar a instância do Invidious",
|
||||
"Broken? Try another Invidious Instance": "Falhou? Tente outra Instância do Invidious",
|
||||
"Hide annotations": "Ocultar anotações",
|
||||
"Show annotations": "Mostrar anotações",
|
||||
"Genre: ": "Género: ",
|
||||
@@ -345,35 +344,123 @@
|
||||
"Videos": "Vídeos",
|
||||
"Playlists": "Listas de reprodução",
|
||||
"Community": "Comunidade",
|
||||
"relevance": "Relevância",
|
||||
"rating": "Avaliação",
|
||||
"date": "Data de envio",
|
||||
"views": "Visualizações",
|
||||
"content_type": "Tipo",
|
||||
"duration": "Duração",
|
||||
"features": "Funcionalidades",
|
||||
"sort": "Ordenar por",
|
||||
"hour": "Última hora",
|
||||
"today": "Hoje",
|
||||
"week": "Esta semana",
|
||||
"month": "Este mês",
|
||||
"year": "Este ano",
|
||||
"video": "Vídeo",
|
||||
"channel": "Canal",
|
||||
"playlist": "Lista de reprodução",
|
||||
"movie": "Filme",
|
||||
"show": "Espetáculo",
|
||||
"hd": "HD",
|
||||
"subtitles": "Legendas",
|
||||
"creative_commons": "Creative Commons",
|
||||
"3d": "3D",
|
||||
"live": "Em direto",
|
||||
"4k": "4K",
|
||||
"location": "Localização",
|
||||
"hdr": "HDR",
|
||||
"filter": "Filtro",
|
||||
"search_filters_sort_option_relevance": "Relevância",
|
||||
"search_filters_sort_option_rating": "Avaliação",
|
||||
"search_filters_sort_option_date": "Data de envio",
|
||||
"search_filters_sort_option_views": "Visualizações",
|
||||
"search_filters_type_label": "Tipo",
|
||||
"search_filters_duration_label": "Duração",
|
||||
"search_filters_features_label": "Funcionalidades",
|
||||
"search_filters_sort_label": "Ordenar por",
|
||||
"search_filters_date_option_hour": "Última hora",
|
||||
"search_filters_date_option_today": "Hoje",
|
||||
"search_filters_date_option_week": "Esta semana",
|
||||
"search_filters_date_option_month": "Este mês",
|
||||
"search_filters_date_option_year": "Este ano",
|
||||
"search_filters_type_option_video": "Vídeo",
|
||||
"search_filters_type_option_channel": "Canal",
|
||||
"search_filters_type_option_playlist": "Lista de reprodução",
|
||||
"search_filters_type_option_movie": "Filme",
|
||||
"search_filters_type_option_show": "Espetáculo",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "Legendas",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_live": "Em direto",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_location": "Localização",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"Current version: ": "Versão atual: ",
|
||||
"next_steps_error_message": "Pode tentar as seguintes opções: ",
|
||||
"next_steps_error_message_refresh": "Atualizar",
|
||||
"next_steps_error_message_go_to_youtube": "Ir ao YouTube"
|
||||
"next_steps_error_message_go_to_youtube": "Ir ao YouTube",
|
||||
"search_filters_title": "Filtro",
|
||||
"generic_videos_count": "{{count}} vídeo",
|
||||
"generic_videos_count_plural": "{{count}} vídeos",
|
||||
"generic_playlists_count": "{{count}} lista de reprodução",
|
||||
"generic_playlists_count_plural": "{{count}} listas de reprodução",
|
||||
"generic_subscriptions_count": "{{count}} subscrição",
|
||||
"generic_subscriptions_count_plural": "{{count}} subscrições",
|
||||
"generic_views_count": "{{count}} visualização",
|
||||
"generic_views_count_plural": "{{count}} visualizações",
|
||||
"generic_subscribers_count": "{{count}} subscritor",
|
||||
"generic_subscribers_count_plural": "{{count}} subscritores",
|
||||
"preferences_quality_dash_option_4320p": "4320p",
|
||||
"preferences_quality_dash_label": "Qualidade de vídeo DASH preferencial ",
|
||||
"preferences_quality_dash_option_2160p": "2160p",
|
||||
"subscriptions_unseen_notifs_count": "{{count}} notificação por ver",
|
||||
"subscriptions_unseen_notifs_count_plural": "{{count}} notificações por ver",
|
||||
"Popular enabled: ": "Página \"Popular\" ativada: ",
|
||||
"search_message_no_results": "Nenhum resultado encontrado.",
|
||||
"preferences_quality_dash_option_auto": "Automática",
|
||||
"preferences_region_label": "País para o conteúdo: ",
|
||||
"preferences_quality_dash_option_1440p": "1440p",
|
||||
"preferences_quality_dash_option_720p": "720p",
|
||||
"preferences_watch_history_label": "Ativar histórico de visualizações ",
|
||||
"preferences_quality_dash_option_best": "Melhor",
|
||||
"preferences_quality_dash_option_worst": "Pior",
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"invidious": "Invidious",
|
||||
"preferences_quality_option_hd720": "HD720",
|
||||
"preferences_quality_option_dash": "DASH (qualidade adaptativa)",
|
||||
"preferences_quality_option_medium": "Média",
|
||||
"preferences_quality_option_small": "Pequena",
|
||||
"preferences_quality_dash_option_1080p": "1080p",
|
||||
"preferences_quality_dash_option_480p": "480p",
|
||||
"preferences_quality_dash_option_360p": "360p",
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"Video unavailable": "Vídeo indisponível",
|
||||
"Russian (auto-generated)": "Russo (geradas automaticamente)",
|
||||
"comments_view_x_replies": "Ver {{count}} resposta",
|
||||
"comments_view_x_replies_plural": "Ver {{count}} respostas",
|
||||
"comments_points_count": "{{count}} ponto",
|
||||
"comments_points_count_plural": "{{count}} pontos",
|
||||
"English (United Kingdom)": "Inglês (Reino Unido)",
|
||||
"Chinese (Hong Kong)": "Chinês (Hong Kong)",
|
||||
"Chinese (Taiwan)": "Chinês (Taiwan)",
|
||||
"Dutch (auto-generated)": "Holandês (geradas automaticamente)",
|
||||
"French (auto-generated)": "Francês (geradas automaticamente)",
|
||||
"German (auto-generated)": "Alemão (geradas automaticamente)",
|
||||
"Indonesian (auto-generated)": "Indonésio (geradas automaticamente)",
|
||||
"Interlingue": "Interlingue",
|
||||
"Italian (auto-generated)": "Italiano (geradas automaticamente)",
|
||||
"Japanese (auto-generated)": "Japonês (geradas automaticamente)",
|
||||
"Korean (auto-generated)": "Coreano (geradas automaticamente)",
|
||||
"Portuguese (auto-generated)": "Português (geradas automaticamente)",
|
||||
"Portuguese (Brazil)": "Português (Brasil)",
|
||||
"Spanish (Spain)": "Espanhol (Espanha)",
|
||||
"Vietnamese (auto-generated)": "Vietnamita (geradas automaticamente)",
|
||||
"search_filters_type_option_all": "Qualquer tipo",
|
||||
"search_filters_duration_option_none": "Qualquer duração",
|
||||
"search_filters_duration_option_short": "Curto (< 4 minutos)",
|
||||
"search_filters_duration_option_medium": "Médio (4 - 20 minutos)",
|
||||
"search_filters_duration_option_long": "Longo (> 20 minutos)",
|
||||
"search_filters_features_option_purchased": "Comprado",
|
||||
"search_filters_apply_button": "Aplicar filtros selecionados",
|
||||
"videoinfo_watch_on_youTube": "Ver no YouTube",
|
||||
"videoinfo_youTube_embed_link": "Embutir",
|
||||
"adminprefs_modified_source_code_url_label": "URL do repositório do código-fonte modificado",
|
||||
"videoinfo_invidious_embed_link": "Ligação embutida",
|
||||
"none": "nenhum",
|
||||
"videoinfo_started_streaming_x_ago": "Entrou em direto há `x`",
|
||||
"download_subtitles": "Legendas - `x` (.vtt)",
|
||||
"user_created_playlists": "`x` listas de reprodução criadas",
|
||||
"user_saved_playlists": "`x` listas de reprodução guardadas",
|
||||
"preferences_save_player_pos_label": "Guardar posição de reprodução: ",
|
||||
"Turkish (auto-generated)": "Turco (geradas automaticamente)",
|
||||
"Cantonese (Hong Kong)": "Cantonês (Hong Kong)",
|
||||
"Chinese (China)": "Chinês (China)",
|
||||
"Spanish (auto-generated)": "Espanhol (geradas automaticamente)",
|
||||
"Spanish (Mexico)": "Espanhol (México)",
|
||||
"English (United States)": "Inglês (Estados Unidos)",
|
||||
"footer_donate_page": "Doar",
|
||||
"footer_documentation": "Documentação",
|
||||
"footer_source_code": "Código-fonte",
|
||||
"footer_original_source_code": "Código-fonte original",
|
||||
"footer_modfied_source_code": "Código-fonte modificado",
|
||||
"Chinese": "Chinês",
|
||||
"search_filters_date_label": "Data de carregamento",
|
||||
"search_filters_date_option_none": "Qualquer data",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"search_filters_features_option_vr180": "VR180"
|
||||
}
|
||||
|
||||
114
locales/pt.json
114
locales/pt.json
@@ -1,44 +1,42 @@
|
||||
{
|
||||
"show": "Espetáculo",
|
||||
"views": "Visualizações",
|
||||
"date": "Data de envio",
|
||||
"rating": "Avaliação",
|
||||
"relevance": "Relevância",
|
||||
"Broken? Try another Invidious Instance": "Falhou? Tente outra Instância do Invidious",
|
||||
"search_filters_type_option_show": "Espetáculo",
|
||||
"search_filters_sort_option_views": "Visualizações",
|
||||
"search_filters_sort_option_date": "Data de envio",
|
||||
"search_filters_sort_option_rating": "Avaliação",
|
||||
"search_filters_sort_option_relevance": "Relevância",
|
||||
"Switch Invidious Instance": "Mudar a instância do Invidious",
|
||||
"Show less": "Mostrar menos",
|
||||
"Show more": "Mostrar mais",
|
||||
"Released under the AGPLv3 on Github.": "Lançado sob a AGPLv3 no Github.",
|
||||
"Released under the AGPLv3 on Github.": "Lançado sob a AGPLv3 no GitHub.",
|
||||
"preferences_show_nick_label": "Mostrar nome de utilizador em cima: ",
|
||||
"preferences_automatic_instance_redirect_label": "Redirecionamento de instância automática (solução de último recurso para redirect.invidious.io): ",
|
||||
"preferences_category_misc": "Preferências diversas",
|
||||
"preferences_vr_mode_label": "Vídeos interativos de 360 graus: ",
|
||||
"preferences_vr_mode_label": "Vídeos interativos de 360 graus (necessita de WebGL): ",
|
||||
"preferences_extend_desc_label": "Estender automaticamente a descrição do vídeo: ",
|
||||
"next_steps_error_message_go_to_youtube": "Ir ao YouTube",
|
||||
"next_steps_error_message": "Pode tentar as seguintes opções: ",
|
||||
"next_steps_error_message_refresh": "Atualizar",
|
||||
"filter": "Filtro",
|
||||
"hdr": "HDR",
|
||||
"location": "Localização",
|
||||
"4k": "4K",
|
||||
"live": "Em direto",
|
||||
"3d": "3D",
|
||||
"creative_commons": "Creative Commons",
|
||||
"subtitles": "Legendas",
|
||||
"hd": "HD",
|
||||
"movie": "Filme",
|
||||
"playlist": "Lista de reprodução",
|
||||
"channel": "Canal",
|
||||
"video": "Vídeo",
|
||||
"year": "Este ano",
|
||||
"month": "Este mês",
|
||||
"week": "Esta semana",
|
||||
"today": "Hoje",
|
||||
"hour": "Última hora",
|
||||
"sort": "Ordenar por",
|
||||
"features": "Funcionalidades",
|
||||
"duration": "Duração",
|
||||
"content_type": "Tipo",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"search_filters_features_option_location": "Localização",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_live": "Em direto",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_subtitles": "Legendas",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_type_option_movie": "Filme",
|
||||
"search_filters_type_option_playlist": "Lista de reprodução",
|
||||
"search_filters_type_option_channel": "Canal",
|
||||
"search_filters_type_option_video": "Vídeo",
|
||||
"search_filters_date_option_year": "Este ano",
|
||||
"search_filters_date_option_month": "Este mês",
|
||||
"search_filters_date_option_week": "Esta semana",
|
||||
"search_filters_date_option_today": "Hoje",
|
||||
"search_filters_date_option_hour": "Última hora",
|
||||
"search_filters_sort_label": "Ordenar por",
|
||||
"search_filters_features_label": "Funcionalidades",
|
||||
"search_filters_duration_label": "Duração",
|
||||
"search_filters_type_label": "Tipo",
|
||||
"permalink": "hiperligação permanente",
|
||||
"YouTube comment permalink": "Hiperligação permanente do comentário no YouTube",
|
||||
"Download as: ": "Descarregar como: ",
|
||||
@@ -248,15 +246,15 @@
|
||||
"JavaScript license information": "Informação de licença do JavaScript",
|
||||
"An alternative front-end to YouTube": "Uma interface alternativa ao YouTube",
|
||||
"History": "Histórico",
|
||||
"Export data as JSON": "Exportar dados como JSON",
|
||||
"Export data as JSON": "Exportar dados Invidious como JSON",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Exportar subscrições como OPML (para NewPipe e FreeTube)",
|
||||
"Export subscriptions as OPML": "Exportar subscrições como OPML",
|
||||
"Export": "Exportar",
|
||||
"Import NewPipe data (.zip)": "Importar dados do NewPipe (.zip)",
|
||||
"Import NewPipe subscriptions (.json)": "Importar subscrições do NewPipe (.json)",
|
||||
"Import FreeTube subscriptions (.db)": "Importar subscrições do FreeTube (.db)",
|
||||
"Import YouTube subscriptions": "Importar subscrições do YouTube",
|
||||
"Import Invidious data": "Importar dados do Invidious",
|
||||
"Import YouTube subscriptions": "Importar subscrições do YouTube/OPML",
|
||||
"Import Invidious data": "Importar dados JSON do Invidious",
|
||||
"Import": "Importar",
|
||||
"No": "Não",
|
||||
"Yes": "Sim",
|
||||
@@ -376,8 +374,8 @@
|
||||
"Unsubscribe": "Anular subscrição",
|
||||
"Shared `x` ago": "Partilhado `x` atrás",
|
||||
"LIVE": "Em direto",
|
||||
"short": "Curto (< 4 minutos)",
|
||||
"long": "Longo (> 20 minutos)",
|
||||
"search_filters_duration_option_short": "Curto (< 4 minutos)",
|
||||
"search_filters_duration_option_long": "Longo (> 20 minutos)",
|
||||
"footer_source_code": "Código-fonte",
|
||||
"footer_original_source_code": "Código-fonte original",
|
||||
"adminprefs_modified_source_code_url_label": "URL do repositório do código-fonte alterado",
|
||||
@@ -397,8 +395,8 @@
|
||||
"preferences_quality_dash_option_360p": "360p",
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"purchased": "Comprado",
|
||||
"360": "360°",
|
||||
"search_filters_features_option_purchased": "Comprado",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"videoinfo_invidious_embed_link": "Incorporar hiperligação",
|
||||
"Video unavailable": "Vídeo não disponível",
|
||||
"invidious": "Invidious",
|
||||
@@ -434,8 +432,44 @@
|
||||
"crash_page_before_reporting": "Antes de reportar um erro, verifique se:",
|
||||
"crash_page_refresh": "tentou <a href=\"`x`\">recarregar a página</a>",
|
||||
"crash_page_switch_instance": "tentou <a href=\"`x`\">usar outra instância</a>",
|
||||
"crash_page_read_the_faq": "leu as <a href=\"`x`\">Perguntas frequentes (FAQ)</a>",
|
||||
"crash_page_search_issue": "procurou se <a href=\"`x`\">o erro já foi reportado no Github</a>",
|
||||
"crash_page_read_the_faq": "leia as <a href=\"`x`\">Perguntas frequentes (FAQ)</a>",
|
||||
"crash_page_search_issue": "procurou se <a href=\"`x`\">o erro já foi reportado no GitHub</a>",
|
||||
"crash_page_report_issue": "Se nenhuma opção acima ajudou, por favor <a href=\"`x`\">abra um novo problema no Github</a> (preferencialmente em inglês) e inclua o seguinte texto tal qual (NÃO o traduza):",
|
||||
"user_created_playlists": "`x` listas de reprodução criadas"
|
||||
"user_created_playlists": "`x` listas de reprodução criadas",
|
||||
"search_filters_title": "Filtro",
|
||||
"Chinese (Taiwan)": "Chinês (Taiwan)",
|
||||
"search_message_no_results": "Nenhum resultado encontrado.",
|
||||
"search_message_change_filters_or_query": "Tente alargar os termos genéricos da pesquisa e/ou alterar os filtros.",
|
||||
"search_message_use_another_instance": " Também pode <a href=\"`x`\">pesquisar noutra instância</a>.",
|
||||
"English (United Kingdom)": "Inglês (Reino Unido)",
|
||||
"English (United States)": "Inglês (Estados Unidos)",
|
||||
"Cantonese (Hong Kong)": "Cantonês (Hong Kong)",
|
||||
"Chinese": "Chinês",
|
||||
"Chinese (Hong Kong)": "Chinês (Hong Kong)",
|
||||
"Dutch (auto-generated)": "Holandês (gerado automaticamente)",
|
||||
"French (auto-generated)": "Francês (gerado automaticamente)",
|
||||
"German (auto-generated)": "Alemão (gerado automaticamente)",
|
||||
"Indonesian (auto-generated)": "Indonésio (gerado automaticamente)",
|
||||
"Interlingue": "Interlíngua",
|
||||
"Italian (auto-generated)": "Italiano (gerado automaticamente)",
|
||||
"Japanese (auto-generated)": "Japonês (gerado automaticamente)",
|
||||
"Korean (auto-generated)": "Coreano (gerado automaticamente)",
|
||||
"Portuguese (auto-generated)": "Português (gerado automaticamente)",
|
||||
"Portuguese (Brazil)": "Português (Brasil)",
|
||||
"Turkish (auto-generated)": "Turco (gerado automaticamente)",
|
||||
"Vietnamese (auto-generated)": "Vietnamita (gerado automaticamente)",
|
||||
"search_filters_duration_option_medium": "Médio (4 - 20 minutos)",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"search_filters_apply_button": "Aplicar filtros selecionados",
|
||||
"Spanish (auto-generated)": "Espanhol (gerado automaticamente)",
|
||||
"Spanish (Mexico)": "Espanhol (México)",
|
||||
"preferences_watch_history_label": "Ativar histórico de reprodução: ",
|
||||
"Chinese (China)": "Chinês (China)",
|
||||
"Russian (auto-generated)": "Russo (gerado automaticamente)",
|
||||
"Spanish (Spain)": "Espanhol (Espanha)",
|
||||
"search_filters_date_label": "Data de publicação",
|
||||
"search_filters_date_option_none": "Qualquer data",
|
||||
"search_filters_type_option_all": "Qualquer tipo",
|
||||
"search_filters_duration_option_none": "Qualquer duração",
|
||||
"Popular enabled: ": "Página \"popular\" ativada: "
|
||||
}
|
||||
|
||||
182
locales/ro.json
182
locales/ro.json
@@ -21,7 +21,7 @@
|
||||
"No": "Nu",
|
||||
"Import and Export Data": "Importați și Exportați Datele",
|
||||
"Import": "Importați",
|
||||
"Import Invidious data": "Importați Datele de pe Invidious",
|
||||
"Import Invidious data": "Importați datele JSON de pe Invidious",
|
||||
"Import YouTube subscriptions": "Importați abonamentele de pe YouTube",
|
||||
"Import FreeTube subscriptions (.db)": "Importați abonamentele de pe FreeTube (.db)",
|
||||
"Import NewPipe subscriptions (.json)": "Importați abonamentele de pe NewPipe (.json)",
|
||||
@@ -29,7 +29,7 @@
|
||||
"Export": "Exportați",
|
||||
"Export subscriptions as OPML": "Exportați abonamentele în format OPML",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Exportați abonamentele în format OPML (pentru NewPipe și FreeTube)",
|
||||
"Export data as JSON": "Exportați datele în format JSON",
|
||||
"Export data as JSON": "Exportați datele Invidious în format JSON",
|
||||
"Delete account?": "Sunteți siguri că doriți să vă ștergeți contul?",
|
||||
"History": "Istoric",
|
||||
"An alternative front-end to YouTube": "O alternativă front-end pentru YouTube",
|
||||
@@ -155,7 +155,7 @@
|
||||
"Hide replies": "Ascundeți replicile",
|
||||
"Show replies": "Afișați replicile",
|
||||
"Incorrect password": "Parolă incorectă",
|
||||
"Quota exceeded, try again in a few hours": "Numărul de tentative de conectare a fost depășit. Va rugăm să încercați din nou în câteva ore.",
|
||||
"Quota exceeded, try again in a few hours": "Numărul de tentative de conectare a fost depășit. Va rugăm să încercați din nou în câteva ore",
|
||||
"Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Conectare eșuată. Dacă nu reușiți să vă conectați, verificați dacă ați activat autentificarea cu doi factori (Autentificator sau SMS).",
|
||||
"Invalid TFA code": "Codul de autentificare cu doi factori este invalid",
|
||||
"Login failed. This may be because two-factor authentication is not turned on for your account.": "Conectare eșuată. Acest lucru ar putea fi cauzat de faptul că nu ați activat autentificarea cu doi factori.",
|
||||
@@ -174,7 +174,7 @@
|
||||
"Deleted or invalid channel": "Canal șters sau invalid",
|
||||
"This channel does not exist.": "Acest canal nu există.",
|
||||
"Could not get channel info.": "Nu am putut primi informații despre acest canal.",
|
||||
"Could not fetch comments": "Încărcarea comentariilor a eșuat.",
|
||||
"Could not fetch comments": "Încărcarea comentariilor a eșuat",
|
||||
"`x` ago": "acum `x`",
|
||||
"Load more": "Vedeți mai mult",
|
||||
"Could not create mix.": "Nu am putut crea această listă de redare.",
|
||||
@@ -187,7 +187,7 @@
|
||||
"Erroneous challenge": "Challenge invalid",
|
||||
"Erroneous token": "Token invalid",
|
||||
"No such user": "Acest utilizator nu există",
|
||||
"Token is expired, please try again": "Token-ul este expirat, vă rugăm să reîncercați.",
|
||||
"Token is expired, please try again": "Jetonul a expirat, vă rugăm să încercați din nou",
|
||||
"English": "Engleză",
|
||||
"English (auto-generated)": "Engleză (generată automat)",
|
||||
"Afrikaans": "Afrikaans",
|
||||
@@ -295,7 +295,7 @@
|
||||
"Yoruba": "Yoruba",
|
||||
"Zulu": "Zoulou",
|
||||
"Fallback comments: ": "Comentarii alternative: ",
|
||||
"Popular": "Popular",
|
||||
"Popular": "Populare",
|
||||
"Top": "Top",
|
||||
"About": "Despre",
|
||||
"Rating: ": "Evaluare: ",
|
||||
@@ -318,5 +318,173 @@
|
||||
"Videos": "Videoclipuri",
|
||||
"Playlists": "Liste de redare",
|
||||
"Community": "Comunitate",
|
||||
"Current version: ": "Versiunea actuală: "
|
||||
"Current version: ": "Versiunea actuală: ",
|
||||
"crash_page_read_the_faq": "citit lista <a href=\"`x`\">Întrebărilor Frecvente (FAQ)</a>",
|
||||
"generic_count_days_0": "{{count}} zi",
|
||||
"generic_count_days_1": "{{count}} zile",
|
||||
"generic_count_days_2": "{{count}} de zile",
|
||||
"generic_count_hours_0": "{{count}} oră",
|
||||
"generic_count_hours_1": "{{count}} ore",
|
||||
"generic_count_hours_2": "{{count}} de ore",
|
||||
"generic_count_minutes_0": "{{count}} minut",
|
||||
"generic_count_minutes_1": "{{count}} minute",
|
||||
"generic_count_minutes_2": "{{count}} de minute",
|
||||
"generic_views_count_0": "{{count}} vizionare",
|
||||
"generic_views_count_1": "{{count}} vizionări",
|
||||
"generic_views_count_2": "{{count}} de vizionări",
|
||||
"subscriptions_unseen_notifs_count_0": "{{count}} notificare neverificată",
|
||||
"subscriptions_unseen_notifs_count_1": "{{count}} notificări neverificate",
|
||||
"subscriptions_unseen_notifs_count_2": "{{count}} de notificări neverificate",
|
||||
"crash_page_refresh": "încercat să <a href=\"`x`\">reîmprospătați pagina</a>",
|
||||
"crash_page_switch_instance": "am încercat să <a href=\"`x`\">folosim o altă instanță</a>",
|
||||
"preferences_watch_history_label": "Activează istoricul: ",
|
||||
"invidious": "Invidious",
|
||||
"preferences_vr_mode_label": "Videoclipuri interactive de 360 de grade (necesită WebGL): ",
|
||||
"English (United Kingdom)": "Engleză (Regatul Unit)",
|
||||
"English (United States)": "Engleză (Statele Unite ale Americii)",
|
||||
"Chinese": "Chineză",
|
||||
"Chinese (China)": "Chineză (China)",
|
||||
"Chinese (Hong Kong)": "Chineză (Hong Kong)",
|
||||
"Chinese (Taiwan)": "Chineză (Taiwan)",
|
||||
"Cantonese (Hong Kong)": "Cantoneză (Hong Kong)",
|
||||
"Portuguese (auto-generated)": "Portugheză (generată automat)",
|
||||
"Portuguese (Brazil)": "Portugheză (Brazilia)",
|
||||
"Russian (auto-generated)": "Rusă (generată automat)",
|
||||
"Turkish (auto-generated)": "Turcă (generată automat)",
|
||||
"Vietnamese (auto-generated)": "Vietnameză (generată automat)",
|
||||
"videoinfo_started_streaming_x_ago": "În direct de acum `x`",
|
||||
"preferences_quality_dash_option_2160p": "2160p",
|
||||
"footer_modfied_source_code": "Codul sursă modificat",
|
||||
"preferences_quality_dash_label": "Calitatea video DASH preferată: ",
|
||||
"generic_videos_count_0": "{{count}} videoclip",
|
||||
"generic_videos_count_1": "{{count}} videoclipuri",
|
||||
"generic_videos_count_2": "{{count}} de videoclipuri",
|
||||
"generic_playlists_count_0": "{{count}} playlist",
|
||||
"generic_playlists_count_1": "{{count}} playlisturi",
|
||||
"generic_playlists_count_2": "{{count}} de playlisturi",
|
||||
"tokens_count_0": "{{count}} jeton",
|
||||
"tokens_count_1": "{{count}} jetoane",
|
||||
"tokens_count_2": "{{count}} de jetoane",
|
||||
"comments_points_count_0": "{{count}} punct",
|
||||
"comments_points_count_1": "{{count}} puncte",
|
||||
"comments_points_count_2": "{{count}} de puncte",
|
||||
"Spanish (Spain)": "Spaniolă (Spania)",
|
||||
"Video unavailable": "Videoclip indisponibil",
|
||||
"crash_page_search_issue": "căutat <a href=\"`x`\">sugestiile existente pe GitHub</a>",
|
||||
"Show more": "Afișați mai mult",
|
||||
"Released under the AGPLv3 on Github.": "Lansat sub licența AGPLv3 pe GitHub.",
|
||||
"preferences_quality_option_dash": "DASH (calitate adaptativă)",
|
||||
"preferences_quality_option_hd720": "HD720",
|
||||
"preferences_quality_option_small": "Mică",
|
||||
"preferences_quality_dash_option_1440p": "1440p",
|
||||
"preferences_quality_dash_option_1080p": "1080p",
|
||||
"preferences_category_misc": "Setări diverse",
|
||||
"preferences_automatic_instance_redirect_label": "Redirecționare automată de instanță (trecere prin redirect.invidious.io): ",
|
||||
"preferences_quality_dash_option_480p": "480p",
|
||||
"preferences_quality_option_medium": "Medie",
|
||||
"Switch Invidious Instance": "Schimbă instanța Invidious",
|
||||
"preferences_quality_dash_option_720p": "720p",
|
||||
"preferences_quality_dash_option_auto": "Automatică",
|
||||
"preferences_quality_dash_option_best": "Cea mai bună",
|
||||
"preferences_quality_dash_option_worst": "Cea mai redusă",
|
||||
"preferences_quality_dash_option_4320p": "4320p",
|
||||
"preferences_quality_dash_option_360p": "360p",
|
||||
"preferences_region_label": "Țară de conținut: ",
|
||||
"preferences_extend_desc_label": "Extindeți automat descrierea: ",
|
||||
"preferences_show_nick_label": "Afișați numele de utilizator pe partea de sus: ",
|
||||
"generic_subscribers_count_0": "{{count}} abonat",
|
||||
"generic_subscribers_count_1": "{{count}} abonați",
|
||||
"generic_subscribers_count_2": "{{count}} de abonați",
|
||||
"generic_subscriptions_count_0": "{{count}} abonament",
|
||||
"generic_subscriptions_count_1": "{{count}} abonamente",
|
||||
"generic_subscriptions_count_2": "{{count}} de abonamente",
|
||||
"Search": "Căutați",
|
||||
"search_filters_title": "Filtre",
|
||||
"search_filters_date_label": "Data încărcării",
|
||||
"none": "niciunul",
|
||||
"search_message_use_another_instance": " Puteți <a href=\"`x`\">căuta într-o altă instanță</a>.",
|
||||
"comments_view_x_replies_0": "Afișați {{count}} răspuns",
|
||||
"comments_view_x_replies_1": "Afișați {{count}} răspunsuri",
|
||||
"comments_view_x_replies_2": "Afișați {{count}} de răspunsuri",
|
||||
"search_message_no_results": "Nu s-au găsit rezultate.",
|
||||
"Dutch (auto-generated)": "Olandeză (generată automat)",
|
||||
"Indonesian (auto-generated)": "Indoneziană (generată automat)",
|
||||
"German (auto-generated)": "Germană (generată automat)",
|
||||
"French (auto-generated)": "Franceză (generată automat)",
|
||||
"Interlingue": "Interlingue",
|
||||
"Italian (auto-generated)": "Italiană (generată automat)",
|
||||
"Japanese (auto-generated)": "Japoneză (generată automat)",
|
||||
"Korean (auto-generated)": "Coreeană (generată automat)",
|
||||
"Spanish (auto-generated)": "Spaniolă (generată automat)",
|
||||
"search_filters_date_option_none": "Oricând",
|
||||
"search_filters_date_option_year": "an",
|
||||
"search_filters_type_option_channel": "canal",
|
||||
"Spanish (Mexico)": "Spaniolă (Mexic)",
|
||||
"generic_count_weeks_0": "{{count}} săptămână",
|
||||
"generic_count_weeks_1": "{{count}} săptămâni",
|
||||
"generic_count_weeks_2": "{{count}} de săptămâni",
|
||||
"generic_count_seconds_0": "{{count}} secundă",
|
||||
"generic_count_seconds_1": "{{count}} secunde",
|
||||
"generic_count_seconds_2": "{{count}} de secunde",
|
||||
"search_filters_type_option_video": "videoclip",
|
||||
"generic_count_years_0": "{{count}} an",
|
||||
"generic_count_years_1": "{{count}} ani",
|
||||
"generic_count_years_2": "{{count}} de ani",
|
||||
"generic_count_months_0": "{{count}} lună",
|
||||
"generic_count_months_1": "{{count}} luni",
|
||||
"generic_count_months_2": "{{count}} de luni",
|
||||
"search_filters_duration_label": "durată",
|
||||
"search_filters_date_option_month": "lună",
|
||||
"search_filters_type_label": "Tip",
|
||||
"search_filters_date_option_today": "azi",
|
||||
"search_filters_date_option_week": "săptămână",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"search_filters_type_option_playlist": "playlist",
|
||||
"search_filters_type_option_movie": "film",
|
||||
"search_filters_type_option_show": "emisiune",
|
||||
"search_filters_duration_option_short": "Scurt (< 4 minute)",
|
||||
"search_filters_duration_option_medium": "Medie (4 - 20 de minute)",
|
||||
"search_filters_duration_option_none": "Fără limită",
|
||||
"search_filters_duration_option_long": "Lungă (> 20 de minute)",
|
||||
"search_filters_features_label": "atribute",
|
||||
"search_filters_features_option_live": "în direct",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_subtitles": "subtitrări/CC",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"search_filters_features_option_purchased": "Cumpărate",
|
||||
"next_steps_error_message": "După ce ar trebui să încercați să: ",
|
||||
"user_saved_playlists": "`x` playlisturi salvate",
|
||||
"search_filters_features_option_location": "locație",
|
||||
"search_filters_sort_label": "Sortați după",
|
||||
"search_filters_sort_option_relevance": "relevanță",
|
||||
"search_filters_sort_option_rating": "clasificare",
|
||||
"search_filters_sort_option_date": "Data încărcării",
|
||||
"search_filters_sort_option_views": "Numărul de vizionări",
|
||||
"footer_source_code": "Codul sursă",
|
||||
"search_filters_apply_button": "Aplicați filtrele selectate",
|
||||
"footer_original_source_code": "Codul sursă original",
|
||||
"next_steps_error_message_refresh": "Reîmprospătează",
|
||||
"next_steps_error_message_go_to_youtube": "Mergeți pe YouTube",
|
||||
"footer_donate_page": "Donați",
|
||||
"adminprefs_modified_source_code_url_label": "URL către depozitul de cod sursă modificat",
|
||||
"footer_documentation": "Documentație",
|
||||
"videoinfo_youTube_embed_link": "Încorporați",
|
||||
"videoinfo_watch_on_youTube": "Vizionați pe YouTube",
|
||||
"videoinfo_invidious_embed_link": "Link de încorporare",
|
||||
"download_subtitles": "Subtitrări - `x` (.vtt)",
|
||||
"user_created_playlists": "`x` playlisturi create",
|
||||
"preferences_save_player_pos_label": "Salvați poziția de redare: ",
|
||||
"crash_page_you_found_a_bug": "Se pare că ați găsit un bug în aplicația Invidious!",
|
||||
"crash_page_before_reporting": "Înainte de a reporta bugul, asigurați-vă că ați:",
|
||||
"search_filters_date_option_hour": "oră",
|
||||
"search_message_change_filters_or_query": "Încercați să lărgiți căutarea sau să modificați filtrele.",
|
||||
"crash_page_report_issue": "Dacă niciuna dintre sugestiile de mai sus v-a ajutat, vă rugăm să <a href=\"`x`\">postați o nouă sugestie pe GitHub</a> (cel mai bine în engleză), și să includeți următorul text în post (să nu îl traduceți):",
|
||||
"search_filters_type_option_all": "orice tip",
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"Show less": "Afișați mai puțin"
|
||||
}
|
||||
|
||||
205
locales/ru.json
205
locales/ru.json
@@ -5,8 +5,8 @@
|
||||
"Subscribe": "Подписаться",
|
||||
"View channel on YouTube": "Смотреть канал на YouTube",
|
||||
"View playlist on YouTube": "Посмотреть плейлист на YouTube",
|
||||
"newest": "самые свежие",
|
||||
"oldest": "самые старые",
|
||||
"newest": "сначала новые",
|
||||
"oldest": "сначала старые",
|
||||
"popular": "популярные",
|
||||
"last": "недавние",
|
||||
"Next page": "Следующая страница",
|
||||
@@ -41,8 +41,8 @@
|
||||
"User ID": "ID пользователя",
|
||||
"Password": "Пароль",
|
||||
"Time (h:mm:ss):": "Время (ч:мм:сс):",
|
||||
"Text CAPTCHA": "Текст капчи",
|
||||
"Image CAPTCHA": "Изображение капчи",
|
||||
"Text CAPTCHA": "Текстовая капча (англ.)",
|
||||
"Image CAPTCHA": "Капча-картинка",
|
||||
"Sign In": "Войти",
|
||||
"Register": "Зарегистрироваться",
|
||||
"E-mail": "Электронная почта",
|
||||
@@ -51,7 +51,7 @@
|
||||
"preferences_category_player": "Настройки проигрывателя",
|
||||
"preferences_video_loop_label": "Всегда повторять: ",
|
||||
"preferences_autoplay_label": "Автовоспроизведение: ",
|
||||
"preferences_continue_label": "Всегда включать следующее видео? ",
|
||||
"preferences_continue_label": "Переходить к следующему видео? ",
|
||||
"preferences_continue_autoplay_label": "Автопроигрывание следующего видео: ",
|
||||
"preferences_listen_label": "Режим «только аудио» по умолчанию: ",
|
||||
"preferences_local_label": "Проигрывать видео через прокси? ",
|
||||
@@ -71,15 +71,15 @@
|
||||
"preferences_player_style_label": "Стиль проигрывателя: ",
|
||||
"Dark mode: ": "Тёмное оформление: ",
|
||||
"preferences_dark_mode_label": "Тема: ",
|
||||
"dark": "темная",
|
||||
"dark": "тёмная",
|
||||
"light": "светлая",
|
||||
"preferences_thin_mode_label": "Облегчённое оформление: ",
|
||||
"preferences_category_misc": "Прочие предпочтения",
|
||||
"preferences_automatic_instance_redirect_label": "Автоматическое перенаправление на зеркало сайта (резервный вариант redirect.invidious.io): ",
|
||||
"preferences_category_misc": "Прочие настройки",
|
||||
"preferences_automatic_instance_redirect_label": "Автоматическая смена зеркала (переход на redirect.invidious.io): ",
|
||||
"preferences_category_subscription": "Настройки подписок",
|
||||
"preferences_annotations_subscribed_label": "Всегда показывать аннотации в видео каналов, на которые вы подписаны? ",
|
||||
"Redirect homepage to feed: ": "Отображать видео с каналов, на которые вы подписаны, как главную страницу: ",
|
||||
"preferences_max_results_label": "Число видео, на которые вы подписаны, в ленте: ",
|
||||
"preferences_annotations_subscribed_label": "Всегда показывать аннотации на каналах из ваших подписок? ",
|
||||
"Redirect homepage to feed: ": "Показывать подписки на главной странице: ",
|
||||
"preferences_max_results_label": "Число видео в ленте: ",
|
||||
"preferences_sort_label": "Сортировать видео: ",
|
||||
"published": "по дате публикации",
|
||||
"published - reverse": "по дате публикации в обратном порядке",
|
||||
@@ -96,24 +96,24 @@
|
||||
"`x` is live": "`x` в прямом эфире",
|
||||
"preferences_category_data": "Настройки данных",
|
||||
"Clear watch history": "Очистить историю просмотров",
|
||||
"Import/export data": "Импорт/Экспорт данных",
|
||||
"Import/export data": "Импорт и экспорт данных",
|
||||
"Change password": "Изменить пароль",
|
||||
"Manage subscriptions": "Управлять подписками",
|
||||
"Manage tokens": "Управлять токенами",
|
||||
"Manage subscriptions": "Управление подписками",
|
||||
"Manage tokens": "Управление токенами",
|
||||
"Watch history": "История просмотров",
|
||||
"Delete account": "Удалить аккаунт",
|
||||
"preferences_category_admin": "Администраторские настройки",
|
||||
"preferences_category_admin": "Настройки администратора",
|
||||
"preferences_default_home_label": "Главная страница по умолчанию: ",
|
||||
"preferences_feed_menu_label": "Меню ленты видео: ",
|
||||
"preferences_show_nick_label": "Показать ник вверху: ",
|
||||
"Top enabled: ": "Включить топ видео? ",
|
||||
"CAPTCHA enabled: ": "Включить капчу? ",
|
||||
"Login enabled: ": "Включить авторизацию? ",
|
||||
"Login enabled: ": "Включить авторизацию: ",
|
||||
"Registration enabled: ": "Включить регистрацию? ",
|
||||
"Report statistics: ": "Сообщать статистику? ",
|
||||
"Save preferences": "Сохранить настройки",
|
||||
"Subscription manager": "Менеджер подписок",
|
||||
"Token manager": "Менеджер токенов",
|
||||
"Subscription manager": "Управление подписками",
|
||||
"Token manager": "Управление токенами",
|
||||
"Token": "Токен",
|
||||
"Import/export": "Импорт и экспорт",
|
||||
"unsubscribe": "отписаться",
|
||||
@@ -121,10 +121,10 @@
|
||||
"Subscriptions": "Подписки",
|
||||
"search": "поиск",
|
||||
"Log out": "Выйти",
|
||||
"Released under the AGPLv3 on Github.": "Выпущено под лицензией AGPLv3 на Github.",
|
||||
"Source available here.": "Исходный код доступен здесь.",
|
||||
"View JavaScript license information.": "Посмотреть информацию по лицензии JavaScript.",
|
||||
"View privacy policy.": "Посмотреть политику конфиденциальности.",
|
||||
"Released under the AGPLv3 on Github.": "Выпущено под лицензией AGPLv3 на GitHub.",
|
||||
"Source available here.": "Исходный код.",
|
||||
"View JavaScript license information.": "Информация о лицензиях JavaScript.",
|
||||
"View privacy policy.": "Политика конфиденциальности.",
|
||||
"Trending": "В тренде",
|
||||
"Public": "Публичный",
|
||||
"Unlisted": "Нет в списке",
|
||||
@@ -135,43 +135,42 @@
|
||||
"Delete playlist": "Удалить плейлист",
|
||||
"Create playlist": "Создать плейлист",
|
||||
"Title": "Заголовок",
|
||||
"Playlist privacy": "Конфиденциальность плейлиста",
|
||||
"Playlist privacy": "Видимость плейлиста",
|
||||
"Editing playlist `x`": "Редактирование плейлиста `x`",
|
||||
"Show more": "Показать больше",
|
||||
"Show less": "Показать меньше",
|
||||
"Show more": "Развернуть",
|
||||
"Show less": "Свернуть",
|
||||
"Watch on YouTube": "Смотреть на YouTube",
|
||||
"Switch Invidious Instance": "Сменить экземпляр Invidious",
|
||||
"Broken? Try another Invidious Instance": "Сломался? Попробуйте другой экземпляр Invidious",
|
||||
"Switch Invidious Instance": "Сменить зеркало Invidious",
|
||||
"Hide annotations": "Скрыть аннотации",
|
||||
"Show annotations": "Показать аннотации",
|
||||
"Genre: ": "Жанр: ",
|
||||
"License: ": "Лицензия: ",
|
||||
"Family friendly? ": "Семейный просмотр: ",
|
||||
"Wilson score: ": "Рейтинг Уилсона: ",
|
||||
"Wilson score: ": "Оценка Уилсона: ",
|
||||
"Engagement: ": "Вовлечённость: ",
|
||||
"Whitelisted regions: ": "Доступно в регионах: ",
|
||||
"Blacklisted regions: ": "Недоступно в регионах: ",
|
||||
"Shared `x`": "Опубликовано `x`",
|
||||
"Premieres in `x`": "Премьера через `x`",
|
||||
"Premieres `x`": "Премьера `x`",
|
||||
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Похоже, у вас отключён JavaScript. Чтобы увидить комментарии, нажмите сюда, но учтите: они могут загружаться немного медленнее.",
|
||||
"View YouTube comments": "Смотреть комментарии с YouTube",
|
||||
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Похоже, у вас отключён JavaScript. Нажмите сюда, чтобы увидеть комментарии. Но учтите: они могут загружаться немного медленнее.",
|
||||
"View YouTube comments": "Показать комментарии с YouTube",
|
||||
"View more comments on Reddit": "Посмотреть больше комментариев на Reddit",
|
||||
"View `x` comments": {
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "Показать `x` комментариев",
|
||||
"": "Показать `x` комментариев"
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "Показано `x` комментариев",
|
||||
"": "Показано `x` комментариев"
|
||||
},
|
||||
"View Reddit comments": "Смотреть комментарии с Reddit",
|
||||
"Hide replies": "Скрыть ответы",
|
||||
"Show replies": "Показать ответы",
|
||||
"Incorrect password": "Неправильный пароль",
|
||||
"Quota exceeded, try again in a few hours": "Лимит превышен, попробуйте снова через несколько часов",
|
||||
"Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Войти не удаётся. Проверьте, не включена ли двухфакторная аутентификация (по коду или смс).",
|
||||
"Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Не удалось войти. Проверьте, не включена ли двухфакторная аутентификация (по коду или смс).",
|
||||
"Invalid TFA code": "Неправильный код двухфакторной аутентификации",
|
||||
"Login failed. This may be because two-factor authentication is not turned on for your account.": "Не удаётся войти. Это может быть из-за того, что в вашем аккаунте не включена двухфакторная аутентификация.",
|
||||
"Login failed. This may be because two-factor authentication is not turned on for your account.": "Не удалось войти. Это может быть из-за того, что в вашем аккаунте не включена двухфакторная аутентификация.",
|
||||
"Wrong answer": "Неправильный ответ",
|
||||
"Erroneous CAPTCHA": "Неправильная капча",
|
||||
"CAPTCHA is a required field": "Необходимо пройти капчу",
|
||||
"CAPTCHA is a required field": "Необходимо решить капчу",
|
||||
"User ID is a required field": "Необходимо ввести ID пользователя",
|
||||
"Password is a required field": "Необходимо ввести пароль",
|
||||
"Wrong username or password": "Неправильный логин или пароль",
|
||||
@@ -186,8 +185,8 @@
|
||||
"Could not get channel info.": "Не удаётся получить информацию об этом канале.",
|
||||
"Could not fetch comments": "Не удаётся загрузить комментарии",
|
||||
"`x` ago": "`x` назад",
|
||||
"Load more": "Загрузить больше",
|
||||
"Could not create mix.": "Не удаётся создать микс.",
|
||||
"Load more": "Загрузить ещё",
|
||||
"Could not create mix.": "Не удалось создать микс.",
|
||||
"Empty playlist": "Плейлист пуст",
|
||||
"Not a playlist.": "Некорректный плейлист.",
|
||||
"Playlist does not exist.": "Плейлист не существует.",
|
||||
@@ -196,7 +195,7 @@
|
||||
"Hidden field \"token\" is a required field": "Необходимо заполнить скрытое поле «токен»",
|
||||
"Erroneous challenge": "Неправильный ответ в «challenge»",
|
||||
"Erroneous token": "Неправильный токен",
|
||||
"No such user": "Недопустимое имя пользователя",
|
||||
"No such user": "Пользователь не найден",
|
||||
"Token is expired, please try again": "Срок действия токена истёк, попробуйте позже",
|
||||
"English": "Английский",
|
||||
"English (auto-generated)": "Английский (созданы автоматически)",
|
||||
@@ -220,7 +219,7 @@
|
||||
"Croatian": "Хорватский",
|
||||
"Czech": "Чешский",
|
||||
"Danish": "Датский",
|
||||
"Dutch": "Нидерландский",
|
||||
"Dutch": "Голландский",
|
||||
"Esperanto": "Эсперанто",
|
||||
"Estonian": "Эстонский",
|
||||
"Filipino": "Филиппинский",
|
||||
@@ -230,8 +229,8 @@
|
||||
"Georgian": "Грузинский",
|
||||
"German": "Немецкий",
|
||||
"Greek": "Греческий",
|
||||
"Gujarati": "Гуджаратский",
|
||||
"Haitian Creole": "Гаит. креольский",
|
||||
"Gujarati": "Гуджарати",
|
||||
"Haitian Creole": "Гаитянский креольский",
|
||||
"Hausa": "Хауса",
|
||||
"Hawaiian": "Гавайский",
|
||||
"Hebrew": "Иврит",
|
||||
@@ -252,7 +251,7 @@
|
||||
"Kurdish": "Курдский",
|
||||
"Kyrgyz": "Киргизский",
|
||||
"Lao": "Лаосский",
|
||||
"Latin": "Латинский",
|
||||
"Latin": "Латынь",
|
||||
"Latvian": "Латышский",
|
||||
"Lithuanian": "Литовский",
|
||||
"Luxembourgish": "Люксембургский",
|
||||
@@ -263,9 +262,9 @@
|
||||
"Maltese": "Мальтийский",
|
||||
"Maori": "Маори",
|
||||
"Marathi": "Маратхи",
|
||||
"Mongolian": "Монгольская",
|
||||
"Mongolian": "Монгольский",
|
||||
"Nepali": "Непальский",
|
||||
"Norwegian Bokmål": "Норвежский",
|
||||
"Norwegian Bokmål": "Норвежский букмол",
|
||||
"Nyanja": "Ньянджа",
|
||||
"Pashto": "Пушту",
|
||||
"Persian": "Персидский",
|
||||
@@ -300,7 +299,7 @@
|
||||
"Vietnamese": "Вьетнамский",
|
||||
"Welsh": "Валлийский",
|
||||
"Western Frisian": "Западнофризский",
|
||||
"Xhosa": "Коса",
|
||||
"Xhosa": "Коса (кхоса)",
|
||||
"Yiddish": "Идиш",
|
||||
"Yoruba": "Йоруба",
|
||||
"Zulu": "Зулусский",
|
||||
@@ -312,7 +311,7 @@
|
||||
"Rating: ": "Рейтинг: ",
|
||||
"preferences_locale_label": "Язык: ",
|
||||
"View as playlist": "Смотреть как плейлист",
|
||||
"Default": "По-умолчанию",
|
||||
"Default": "По умолчанию",
|
||||
"Music": "Музыка",
|
||||
"Gaming": "Игры",
|
||||
"News": "Новости",
|
||||
@@ -329,39 +328,38 @@
|
||||
"Videos": "Видео",
|
||||
"Playlists": "Плейлисты",
|
||||
"Community": "Сообщество",
|
||||
"relevance": "Актуальность",
|
||||
"rating": "Рейтинг",
|
||||
"date": "Дата загрузки",
|
||||
"views": "Просмотры",
|
||||
"content_type": "Тип",
|
||||
"duration": "Длительность",
|
||||
"features": "Функции",
|
||||
"sort": "Сортировать по",
|
||||
"hour": "Последний час",
|
||||
"today": "Сегодня",
|
||||
"week": "Эта неделя",
|
||||
"month": "Этот месяц",
|
||||
"year": "Этот год",
|
||||
"video": "Видео",
|
||||
"channel": "Канал",
|
||||
"playlist": "Плейлист",
|
||||
"movie": "Фильм",
|
||||
"show": "Показать",
|
||||
"hd": "HD",
|
||||
"subtitles": "Субтитры",
|
||||
"creative_commons": "Creative Commons",
|
||||
"3d": "3D",
|
||||
"live": "Прямой эфир",
|
||||
"4k": "4K",
|
||||
"location": "Местоположение",
|
||||
"hdr": "HDR",
|
||||
"filter": "Фильтр",
|
||||
"search_filters_sort_option_relevance": "по актуальности",
|
||||
"search_filters_sort_option_rating": "по рейтингу",
|
||||
"search_filters_sort_option_date": "по дате загрузки",
|
||||
"search_filters_sort_option_views": "по просмотрам",
|
||||
"search_filters_type_label": "Тип",
|
||||
"search_filters_duration_label": "Длительность",
|
||||
"search_filters_features_label": "Дополнительно",
|
||||
"search_filters_sort_label": "Сортировать",
|
||||
"search_filters_date_option_hour": "Последний час",
|
||||
"search_filters_date_option_today": "Сегодня",
|
||||
"search_filters_date_option_week": "Эта неделя",
|
||||
"search_filters_date_option_month": "Этот месяц",
|
||||
"search_filters_date_option_year": "Этот год",
|
||||
"search_filters_type_option_video": "Видео",
|
||||
"search_filters_type_option_channel": "Канал",
|
||||
"search_filters_type_option_playlist": "Плейлист",
|
||||
"search_filters_type_option_movie": "Фильм",
|
||||
"search_filters_type_option_show": "Сериал",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "Субтитры",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_live": "Прямой эфир",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_location": "Местоположение",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"Current version: ": "Текущая версия: ",
|
||||
"next_steps_error_message": "После чего следует попробовать: ",
|
||||
"next_steps_error_message_refresh": "Обновить",
|
||||
"next_steps_error_message_go_to_youtube": "Перейти на YouTube",
|
||||
"short": "Короткие (< 4 минут)",
|
||||
"long": "Длинные (> 20 минут)",
|
||||
"search_filters_duration_option_short": "Короткие (< 4 минут)",
|
||||
"search_filters_duration_option_long": "Длинные (> 20 минут)",
|
||||
"preferences_quality_dash_option_best": "Наилучшее",
|
||||
"generic_count_weeks_0": "{{count}} неделя",
|
||||
"generic_count_weeks_1": "{{count}} недели",
|
||||
@@ -370,28 +368,28 @@
|
||||
"English (United States)": "Английский (США)",
|
||||
"Cantonese (Hong Kong)": "Кантонский (Гонконг)",
|
||||
"Chinese (Taiwan)": "Китайский (Тайвань)",
|
||||
"Dutch (auto-generated)": "Голландский (автоматический)",
|
||||
"German (auto-generated)": "Немецкий (автоматический)",
|
||||
"Indonesian (auto-generated)": "Индонезийский (автоматический)",
|
||||
"Italian (auto-generated)": "Итальянский (автоматический)",
|
||||
"Dutch (auto-generated)": "Голландский (созданы автоматически)",
|
||||
"German (auto-generated)": "Немецкий (созданы автоматически)",
|
||||
"Indonesian (auto-generated)": "Индонезийский (созданы автоматически)",
|
||||
"Italian (auto-generated)": "Итальянский (созданы автоматически)",
|
||||
"Interlingue": "Окциденталь",
|
||||
"Russian (auto-generated)": "Русский (автоматический)",
|
||||
"Spanish (auto-generated)": "Испанский (автоматический)",
|
||||
"Russian (auto-generated)": "Русский (созданы автоматически)",
|
||||
"Spanish (auto-generated)": "Испанский (созданы автоматически)",
|
||||
"Spanish (Spain)": "Испанский (Испания)",
|
||||
"Turkish (auto-generated)": "Турецкий (автоматический)",
|
||||
"Vietnamese (auto-generated)": "Вьетнамский (автоматический)",
|
||||
"Turkish (auto-generated)": "Турецкий (созданы автоматически)",
|
||||
"Vietnamese (auto-generated)": "Вьетнамский (созданы автоматически)",
|
||||
"footer_documentation": "Документация",
|
||||
"adminprefs_modified_source_code_url_label": "Ссылка на нашу ветку репозитория",
|
||||
"none": "ничего",
|
||||
"videoinfo_watch_on_youTube": "Смотреть на YouTube",
|
||||
"videoinfo_youTube_embed_link": "Встраиваемый элемент",
|
||||
"videoinfo_invidious_embed_link": "Встраиваемая ссылка",
|
||||
"videoinfo_youTube_embed_link": "Версия для встраивания",
|
||||
"videoinfo_invidious_embed_link": "Ссылка для встраивания",
|
||||
"download_subtitles": "Субтитры - `x` (.vtt)",
|
||||
"user_created_playlists": "`x` созданных плейлистов",
|
||||
"crash_page_you_found_a_bug": "Похоже вы нашли баг в Invidious!",
|
||||
"crash_page_you_found_a_bug": "Похоже, вы нашли ошибку в Invidious!",
|
||||
"crash_page_before_reporting": "Прежде чем сообщать об ошибке, убедитесь, что вы:",
|
||||
"crash_page_refresh": "пробовали <a href=\"`x`\"> перезагрузить страницу</a>",
|
||||
"crash_page_report_issue": "Если ни один вариант не помог, пожалуйста <a href=\"`x`\">откройте новую проблему на GitHub</a> (желательно на английском) и приложите следующий текст к вашему сообщению (НЕ переводите его):",
|
||||
"crash_page_report_issue": "Если ни один вариант не помог, пожалуйста <a href=\"`x`\">откройте новую проблему на GitHub</a> (на английском, пжлста) и приложите следующий текст к вашему сообщению (НЕ переводите его):",
|
||||
"generic_videos_count_0": "{{count}} видео",
|
||||
"generic_videos_count_1": "{{count}} видео",
|
||||
"generic_videos_count_2": "{{count}} видео",
|
||||
@@ -419,8 +417,8 @@
|
||||
"generic_views_count_0": "{{count}} просмотр",
|
||||
"generic_views_count_1": "{{count}} просмотра",
|
||||
"generic_views_count_2": "{{count}} просмотров",
|
||||
"French (auto-generated)": "Французский (автоматический)",
|
||||
"Portuguese (auto-generated)": "Португальский (автоматический)",
|
||||
"French (auto-generated)": "Французский (созданы автоматически)",
|
||||
"Portuguese (auto-generated)": "Португальский (созданы автоматически)",
|
||||
"generic_count_days_0": "{{count}} день",
|
||||
"generic_count_days_1": "{{count}} дня",
|
||||
"generic_count_days_2": "{{count}} дней",
|
||||
@@ -437,15 +435,15 @@
|
||||
"generic_count_seconds_0": "{{count}} секунда",
|
||||
"generic_count_seconds_1": "{{count}} секунды",
|
||||
"generic_count_seconds_2": "{{count}} секунд",
|
||||
"purchased": "Приобретено",
|
||||
"search_filters_features_option_purchased": "Приобретено",
|
||||
"videoinfo_started_streaming_x_ago": "Трансляция началась `x` назад",
|
||||
"crash_page_switch_instance": "пробовали <a href=\"`x`\">использовать другое зеркало</a>",
|
||||
"crash_page_read_the_faq": "прочли <a href=\"`x`\">Частые Вопросы (ЧаВо)</a>",
|
||||
"crash_page_read_the_faq": "прочли ответы на <a href=\"`x`\">Частые Вопросы (ЧаВо)</a>",
|
||||
"Chinese": "Китайский",
|
||||
"Chinese (Hong Kong)": "Китайский (Гонконг)",
|
||||
"Japanese (auto-generated)": "Японский (автоматический)",
|
||||
"Japanese (auto-generated)": "Японский (созданы автоматически)",
|
||||
"Chinese (China)": "Китайский (Китай)",
|
||||
"Korean (auto-generated)": "Корейский (автоматический)",
|
||||
"Korean (auto-generated)": "Корейский (созданы автоматически)",
|
||||
"generic_count_months_0": "{{count}} месяц",
|
||||
"generic_count_months_1": "{{count}} месяца",
|
||||
"generic_count_months_2": "{{count}} месяцев",
|
||||
@@ -457,7 +455,7 @@
|
||||
"footer_original_source_code": "Оригинальный исходный код",
|
||||
"footer_modfied_source_code": "Изменённый исходный код",
|
||||
"user_saved_playlists": "`x` сохранённых плейлистов",
|
||||
"crash_page_search_issue": "искали <a href=\"`x`\">похожую проблему на Github</a>",
|
||||
"crash_page_search_issue": "поискали <a href=\"`x`\">похожую проблему на GitHub</a>",
|
||||
"comments_points_count_0": "{{count}} плюс",
|
||||
"comments_points_count_1": "{{count}} плюса",
|
||||
"comments_points_count_2": "{{count}} плюсов",
|
||||
@@ -466,15 +464,28 @@
|
||||
"preferences_quality_option_dash": "DASH (автоматическое качество)",
|
||||
"preferences_quality_option_hd720": "HD720",
|
||||
"preferences_quality_option_medium": "Среднее",
|
||||
"preferences_quality_dash_label": "Предпочтительное автоматическое качество видео: ",
|
||||
"preferences_quality_dash_label": "Предпочтительное качество для DASH: ",
|
||||
"preferences_quality_dash_option_worst": "Очень низкое",
|
||||
"preferences_quality_dash_option_4320p": "4320p",
|
||||
"preferences_quality_dash_option_2160p": "2160p",
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"invidious": "Invidious",
|
||||
"360": "360°",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"Video unavailable": "Видео недоступно",
|
||||
"preferences_save_player_pos_label": "Запоминать позицию: ",
|
||||
"preferences_region_label": "Страна: "
|
||||
"preferences_region_label": "Страна: ",
|
||||
"preferences_watch_history_label": "Включить историю просмотров: ",
|
||||
"search_filters_title": "Фильтр",
|
||||
"search_filters_duration_option_none": "Любой длины",
|
||||
"search_filters_type_option_all": "Любого типа",
|
||||
"search_filters_date_option_none": "Любая дата",
|
||||
"search_filters_date_label": "Дата загрузки",
|
||||
"search_message_no_results": "Ничего не найдено.",
|
||||
"search_message_use_another_instance": " Дополнительно вы можете <a href=\"`x`\">поискать на других зеркалах</a>.",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"search_message_change_filters_or_query": "Попробуйте расширить поисковый запрос или изменить фильтры.",
|
||||
"search_filters_duration_option_medium": "Средние (4 - 20 минут)",
|
||||
"search_filters_apply_button": "Применить фильтры",
|
||||
"Popular enabled: ": "Популярное включено: "
|
||||
}
|
||||
|
||||
126
locales/si.json
Normal file
126
locales/si.json
Normal file
@@ -0,0 +1,126 @@
|
||||
{
|
||||
"generic_views_count": "බැලීම් {{count}}",
|
||||
"generic_views_count_plural": "බැලීම් {{count}}",
|
||||
"generic_videos_count": "{{count}} වීඩියෝව",
|
||||
"generic_videos_count_plural": "වීඩියෝ {{count}}",
|
||||
"generic_subscribers_count": "ග්රාහකයන් {{count}}",
|
||||
"generic_subscribers_count_plural": "ග්රාහකයන් {{count}}",
|
||||
"generic_subscriptions_count": "දායකත්ව {{count}}",
|
||||
"generic_subscriptions_count_plural": "දායකත්ව {{count}}",
|
||||
"Shared `x` ago": "`x` පෙර බෙදා ගන්නා ලදී",
|
||||
"Unsubscribe": "දායක නොවන්න",
|
||||
"View playlist on YouTube": "YouTube හි ධාවන ලැයිස්තුව බලන්න",
|
||||
"newest": "අලුත්ම",
|
||||
"oldest": "පැරණිතම",
|
||||
"popular": "ජනප්රිය",
|
||||
"last": "අවසන්",
|
||||
"Cannot change password for Google accounts": "Google ගිණුම් සඳහා මුරපදය වෙනස් කළ නොහැක",
|
||||
"Authorize token?": "ටෝකනය අනුමත කරනවා ද?",
|
||||
"Authorize token for `x`?": "`x` සඳහා ටෝකනය අනුමත කරනවා ද?",
|
||||
"Yes": "ඔව්",
|
||||
"Import and Export Data": "දත්ත ආනයනය සහ අපනයනය කිරීම",
|
||||
"Import": "ආනයන",
|
||||
"Import Invidious data": "Invidious JSON දත්ත ආයාත කරන්න",
|
||||
"Import FreeTube subscriptions (.db)": "FreeTube දායකත්වයන් (.db) ආයාත කරන්න",
|
||||
"Import NewPipe subscriptions (.json)": "NewPipe දායකත්වයන් (.json) ආයාත කරන්න",
|
||||
"Import NewPipe data (.zip)": "NewPipe දත්ත (.zip) ආයාත කරන්න",
|
||||
"Export": "අපනයන",
|
||||
"Export data as JSON": "Invidious දත්ත JSON ලෙස අපනයනය කරන්න",
|
||||
"Delete account?": "ගිණුම මකාදමනවා ද?",
|
||||
"History": "ඉතිහාසය",
|
||||
"An alternative front-end to YouTube": "YouTube සඳහා විකල්ප ඉදිරිපස අන්තයක්",
|
||||
"source": "මූලාශ්රය",
|
||||
"Log in/register": "පුරන්න/ලියාපදිංචිවන්න",
|
||||
"Log in with Google": "Google සමඟ පුරන්න",
|
||||
"Password": "මුරපදය",
|
||||
"Time (h:mm:ss):": "වේලාව (h:mm:ss):",
|
||||
"Sign In": "පුරන්න",
|
||||
"Preferences": "මනාපයන්",
|
||||
"preferences_category_player": "වීඩියෝ ධාවක මනාපයන්",
|
||||
"preferences_video_loop_label": "නැවත නැවතත්: ",
|
||||
"preferences_autoplay_label": "ස්වයංක්රීය වාදනය: ",
|
||||
"preferences_continue_label": "මීලඟට වාදනය කරන්න: ",
|
||||
"preferences_continue_autoplay_label": "මීළඟ වීඩියෝව ස්වයංක්රීයව ධාවනය කරන්න: ",
|
||||
"preferences_local_label": "Proxy වීඩියෝ: ",
|
||||
"preferences_watch_history_label": "නැරඹුම් ඉතිහාසය සබල කරන්න: ",
|
||||
"preferences_speed_label": "පෙරනිමි වේගය: ",
|
||||
"preferences_quality_option_dash": "DASH (අනුවර්තිත ගුණත්වය)",
|
||||
"preferences_quality_option_medium": "මධ්යස්ථ",
|
||||
"preferences_quality_dash_label": "කැමති DASH වීඩියෝ ගුණත්වය: ",
|
||||
"preferences_quality_dash_option_4320p": "4320p",
|
||||
"preferences_quality_dash_option_1080p": "1080p",
|
||||
"preferences_quality_dash_option_480p": "480p",
|
||||
"preferences_quality_dash_option_360p": "360p",
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"preferences_volume_label": "ධාවකයේ හඬ: ",
|
||||
"preferences_comments_label": "පෙරනිමි අදහස්: ",
|
||||
"youtube": "YouTube",
|
||||
"reddit": "Reddit",
|
||||
"invidious": "Invidious",
|
||||
"preferences_captions_label": "පෙරනිමි උපසිරැසි: ",
|
||||
"preferences_related_videos_label": "අදාළ වීඩියෝ පෙන්වන්න: ",
|
||||
"preferences_annotations_label": "අනුසටහන් පෙන්වන්න: ",
|
||||
"preferences_vr_mode_label": "අන්තර්ක්රියාකාරී අංශක 360 වීඩියෝ (WebGL අවශ්යයි): ",
|
||||
"preferences_region_label": "අන්තර්ගත රට: ",
|
||||
"preferences_player_style_label": "වීඩියෝ ධාවක විලාසය: ",
|
||||
"Dark mode: ": "අඳුරු මාදිලිය: ",
|
||||
"preferences_dark_mode_label": "තේමාව: ",
|
||||
"light": "ආලෝකමත්",
|
||||
"generic_playlists_count": "{{count}} ධාවන ලැයිස්තුව",
|
||||
"generic_playlists_count_plural": "ධාවන ලැයිස්තු {{count}}",
|
||||
"LIVE": "සජීව",
|
||||
"Subscribe": "දායක වන්න",
|
||||
"View channel on YouTube": "YouTube හි නාලිකාව බලන්න",
|
||||
"Next page": "ඊළඟ පිටුව",
|
||||
"Previous page": "පෙර පිටුව",
|
||||
"Clear watch history?": "නැරඹුම් ඉතිහාසය මකාදමනවා ද?",
|
||||
"No": "නැත",
|
||||
"Log in": "පුරන්න",
|
||||
"New password": "නව මුරපදය",
|
||||
"Import YouTube subscriptions": "YouTube/OPML දායකත්වයන් ආයාත කරන්න",
|
||||
"Register": "ලියාපදිංචිවන්න",
|
||||
"New passwords must match": "නව මුරපද ගැලපිය යුතුය",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "OPML ලෙස දායකත්වයන් අපනයනය කරන්න (NewPipe සහ FreeTube සඳහා)",
|
||||
"Export subscriptions as OPML": "දායකත්වයන් OPML ලෙස අපනයනය කරන්න",
|
||||
"JavaScript license information": "JavaScript බලපත්ර තොරතුරු",
|
||||
"User ID": "පරිශීලක කේතය",
|
||||
"Text CAPTCHA": "CAPTCHA පෙල",
|
||||
"Image CAPTCHA": "CAPTCHA රූපය",
|
||||
"Google verification code": "Google සත්යාපන කේතය",
|
||||
"E-mail": "විද්යුත් තැපෑල",
|
||||
"preferences_quality_label": "කැමති වීඩියෝ ගුණත්වය: ",
|
||||
"preferences_quality_option_hd720": "HD720",
|
||||
"preferences_quality_dash_option_auto": "ස්වයංක්රීය",
|
||||
"preferences_quality_option_small": "කුඩා",
|
||||
"preferences_quality_dash_option_best": "උසස්",
|
||||
"preferences_quality_dash_option_2160p": "2160p",
|
||||
"preferences_quality_dash_option_1440p": "1440p",
|
||||
"preferences_quality_dash_option_720p": "720p",
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"preferences_extend_desc_label": "වීඩියෝ විස්තරය ස්වයංක්රීයව දිගහරින්න: ",
|
||||
"preferences_category_visual": "දෘශ්ය මනාපයන්",
|
||||
"dark": "අඳුරු",
|
||||
"preferences_category_misc": "විවිධ මනාප",
|
||||
"preferences_category_subscription": "දායකත්ව මනාප",
|
||||
"Redirect homepage to feed: ": "මුල් පිටුව පෝෂණය වෙත හරවා යවන්න: ",
|
||||
"preferences_max_results_label": "සංග්රහයේ පෙන්වන වීඩියෝ ගණන: ",
|
||||
"preferences_sort_label": "වීඩියෝ වර්ග කරන්න: ",
|
||||
"alphabetically": "අකාරාදී ලෙස",
|
||||
"alphabetically - reverse": "අකාරාදී - ආපසු",
|
||||
"channel name": "නාලිකාවේ නම",
|
||||
"Only show latest video from channel: ": "නාලිකාවේ නවතම වීඩියෝව පමණක් පෙන්වන්න: ",
|
||||
"preferences_unseen_only_label": "නොබැලූ පමණක් පෙන්වන්න: ",
|
||||
"Enable web notifications": "වෙබ් දැනුම්දීම් සබල කරන්න",
|
||||
"Import/export data": "දත්ත ආනයනය / අපනයනය",
|
||||
"Change password": "මුරපදය වෙනස් කරන්න",
|
||||
"Manage subscriptions": "දායකත්ව කළමනාකරණය",
|
||||
"Manage tokens": "ටෝකන කළමනාකරණය",
|
||||
"Watch history": "නැරඹුම් ඉතිහාසය",
|
||||
"Save preferences": "මනාප සුරකින්න",
|
||||
"Token": "ටෝකනය",
|
||||
"View privacy policy.": "රහස්යතා ප්රතිපත්තිය බලන්න.",
|
||||
"Only show latest unwatched video from channel: ": "නාලිකාවේ නවතම නැරඹන නොලද වීඩියෝව පමණක් පෙන්වන්න: ",
|
||||
"preferences_category_data": "දත්ත මනාප",
|
||||
"Clear watch history": "නැරඹුම් ඉතිහාසය මකාදැමීම",
|
||||
"Subscriptions": "දායකත්ව"
|
||||
}
|
||||
@@ -18,15 +18,15 @@
|
||||
"No": "Nie",
|
||||
"Import and Export Data": "Import a Export údajov",
|
||||
"Import": "Import",
|
||||
"Import Invidious data": "Importovať údaje Invidious",
|
||||
"Import YouTube subscriptions": "Importovať odbery YouTube",
|
||||
"Import Invidious data": "Importovať JSON údaje Invidious",
|
||||
"Import YouTube subscriptions": "Importovať odbery YouTube/OPML",
|
||||
"Import FreeTube subscriptions (.db)": "Importovať odbery FreeTube (.db)",
|
||||
"Import NewPipe subscriptions (.json)": "Importovať odbery NewPipe (.json)",
|
||||
"Import NewPipe data (.zip)": "Importovať údaje NewPipe (.zip)",
|
||||
"Export": "Export",
|
||||
"Export subscriptions as OPML": "Exportovať odbery ako OPML",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Exportovať odbery ako OPML (pre NewPipe a FreeTube)",
|
||||
"Export data as JSON": "Export údajov ako JSON",
|
||||
"Export data as JSON": "Exportovať údaje Invidious ako JSON",
|
||||
"Delete account?": "Zrušiť účet?",
|
||||
"History": "História",
|
||||
"An alternative front-end to YouTube": "Alternatívny front-end pre YouTube",
|
||||
@@ -84,5 +84,23 @@
|
||||
"preferences_unseen_only_label": "Zobraziť iba neprehrané: ",
|
||||
"preferences_notifications_only_label": "Zobraziť iba upozornenia (ak existujú): ",
|
||||
"Enable web notifications": "Povoliť webové upozornenia",
|
||||
"`x` uploaded a video": "`x` nahral(a) video"
|
||||
"`x` uploaded a video": "`x` nahral(a) video",
|
||||
"generic_views_count_0": "{{count}} zhliadnutie",
|
||||
"generic_views_count_1": "{{count}} zhliadnutia",
|
||||
"generic_views_count_2": "{{count}} zhliadnutí",
|
||||
"generic_subscribers_count_0": "{{count}} odberateľ",
|
||||
"generic_subscribers_count_1": "{{count}} odberatelia",
|
||||
"generic_subscribers_count_2": "{{count}} odberateľov",
|
||||
"Shared `x` ago": "Zverejnené pred `x`",
|
||||
"generic_playlists_count_0": "{{count}} playlist",
|
||||
"generic_playlists_count_1": "{{count}} playlisty",
|
||||
"generic_playlists_count_2": "{{count}} playlistov",
|
||||
"generic_videos_count_0": "{{count}} video",
|
||||
"generic_videos_count_1": "{{count}} videá",
|
||||
"generic_videos_count_2": "{{count}} videí",
|
||||
"generic_subscriptions_count_0": "{{count}} odber",
|
||||
"generic_subscriptions_count_1": "{{count}} odbery",
|
||||
"generic_subscriptions_count_2": "{{count}} odberov",
|
||||
"Authorize token for `x`?": "Autorizovať token pre `x`?",
|
||||
"View playlist on YouTube": "Zobraziť playlist na YouTube"
|
||||
}
|
||||
|
||||
507
locales/sl.json
Normal file
507
locales/sl.json
Normal file
@@ -0,0 +1,507 @@
|
||||
{
|
||||
"No": "Ne",
|
||||
"Subscribe": "Naroči se",
|
||||
"View playlist on YouTube": "Ogled seznama predvajanja v YouTubu",
|
||||
"last": "zadnji",
|
||||
"Next page": "Naslednja stran",
|
||||
"Previous page": "Prejšnja stran",
|
||||
"Clear watch history?": "Izbrisati zgodovino ogledov?",
|
||||
"New password": "Novo geslo",
|
||||
"New passwords must match": "Nova gesla se morajo ujemati",
|
||||
"Cannot change password for Google accounts": "Ni mogoče spremeniti gesla za račune Google",
|
||||
"Authorize token?": "Naj odobrim žeton?",
|
||||
"Yes": "Da",
|
||||
"Import and Export Data": "Uvoz in izvoz podatkov",
|
||||
"Import": "Uvozi",
|
||||
"Import Invidious data": "Uvozi Invidious JSON podatke",
|
||||
"Import YouTube subscriptions": "Uvozi YouTube/OPML naročnine",
|
||||
"Import FreeTube subscriptions (.db)": "Uvozi FreeTube (.db) naročnine",
|
||||
"Import NewPipe data (.zip)": "Uvozi NewPipe (.zip) podatke",
|
||||
"Export": "Izvozi",
|
||||
"Export subscriptions as OPML": "Izvozi naročnine kot OPML",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Izvozi naročnine kot OPML (za NewPipe in FreeTube)",
|
||||
"Log in": "Prijava",
|
||||
"Log in/register": "Prijava/registracija",
|
||||
"Log in with Google": "Prijavi se z Googlom",
|
||||
"User ID": "ID uporabnika",
|
||||
"Password": "Geslo",
|
||||
"Time (h:mm:ss):": "Čas (h:mm:ss):",
|
||||
"Text CAPTCHA": "Besedilo CAPTCHA",
|
||||
"source": "izvorna koda",
|
||||
"Image CAPTCHA": "Slika CAPTCHA",
|
||||
"Sign In": "Prijavi se",
|
||||
"Register": "Registriraj se",
|
||||
"E-mail": "E-pošta",
|
||||
"Google verification code": "Googlova koda za preverjanje",
|
||||
"Preferences": "Nastavitve",
|
||||
"preferences_video_loop_label": "Vedno v zanki: ",
|
||||
"preferences_autoplay_label": "Samodejno predvajanje: ",
|
||||
"preferences_continue_autoplay_label": "Samodejno predvajanje naslednjega videoposnetka: ",
|
||||
"preferences_listen_label": "Privzeto poslušaj: ",
|
||||
"preferences_local_label": "Proxy za videoposnetke: ",
|
||||
"preferences_speed_label": "Privzeta hitrost: ",
|
||||
"preferences_quality_label": "Prednostna kakovost videoposnetka: ",
|
||||
"preferences_quality_option_hd720": "HD720",
|
||||
"preferences_quality_dash_option_best": "najboljša",
|
||||
"preferences_quality_dash_option_4320p": "4320p",
|
||||
"preferences_quality_dash_option_1440p": "1440p",
|
||||
"preferences_quality_dash_option_1080p": "1080p",
|
||||
"preferences_quality_dash_option_720p": "720p",
|
||||
"preferences_quality_dash_option_480p": "480p",
|
||||
"preferences_quality_dash_option_360p": "360p",
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"preferences_volume_label": "Glasnost predvajalnika: ",
|
||||
"reddit": "Reddit",
|
||||
"preferences_player_style_label": "Slog predvajalnika: ",
|
||||
"dark": "temna",
|
||||
"light": "svetla",
|
||||
"preferences_thin_mode_label": "Tanki način: ",
|
||||
"preferences_automatic_instance_redirect_label": "Samodejna preusmeritev (na redirect.invidious.io): ",
|
||||
"preferences_annotations_subscribed_label": "Privzeto prikazati opombe za naročene kanale? ",
|
||||
"Redirect homepage to feed: ": "Preusmeri domačo stran na vir: ",
|
||||
"preferences_max_results_label": "Število videoposnetkov, prikazanih v viru: ",
|
||||
"preferences_sort_label": "Razvrsti videoposnetke po: ",
|
||||
"published": "datumu objave",
|
||||
"published - reverse": "datumu objave - obratno",
|
||||
"alphabetically": "abecednem vrstnem redu",
|
||||
"alphabetically - reverse": "po abecednem vrstnem redu - obratno",
|
||||
"channel name": "imenu kanala",
|
||||
"channel name - reverse": "imenu kanala - obratno",
|
||||
"Only show latest video from channel: ": "Pokaži samo najnovejši videoposnetek iz kanala: ",
|
||||
"Only show latest unwatched video from channel: ": "Pokaži samo najnovejši še neogledani videoposnetek iz kanala: ",
|
||||
"preferences_unseen_only_label": "Pokaži samo neogledane: ",
|
||||
"preferences_notifications_only_label": "Pokaži samo obvestila (če obstajajo): ",
|
||||
"preferences_category_data": "Nastavitve podatkov",
|
||||
"Clear watch history": "Počisti zgodovino ogledov",
|
||||
"Import/export data": "Uvoz/izvoz podatkov",
|
||||
"Change password": "Spremeni geslo",
|
||||
"Watch history": "Oglej si zgodovino",
|
||||
"Delete account": "Izbriši račun",
|
||||
"preferences_category_admin": "Skrbniške nastavitve",
|
||||
"preferences_default_home_label": "Privzeta domača stran: ",
|
||||
"preferences_feed_menu_label": "Meni vira: ",
|
||||
"Top enabled: ": "Vrh omogočen: ",
|
||||
"CAPTCHA enabled: ": "CAPTCHA omogočeni: ",
|
||||
"Login enabled: ": "Prijava je omogočena: ",
|
||||
"Registration enabled: ": "Registracija je omogočena: ",
|
||||
"Token manager": "Upravitelj žetonov",
|
||||
"Token": "Žeton",
|
||||
"tokens_count_0": "{{count}} žeton",
|
||||
"tokens_count_1": "{{count}} žetona",
|
||||
"tokens_count_2": "{{count}} žetoni",
|
||||
"tokens_count_3": "{{count}} žetonov",
|
||||
"Import/export": "Uvoz/izvoz",
|
||||
"unsubscribe": "odjava",
|
||||
"revoke": "prekliči",
|
||||
"search": "iskanje",
|
||||
"Log out": "Odjava",
|
||||
"Released under the AGPLv3 on Github.": "Objavljeno pod licenco AGPLv3 na GitHubu.",
|
||||
"Trending": "Trendi",
|
||||
"Private": "Zasebno",
|
||||
"View all playlists": "Oglej si vse sezname predvajanja",
|
||||
"Updated `x` ago": "Posodobljeno pred `x`",
|
||||
"Delete playlist `x`?": "Brisanje seznama predvajanja `x`?",
|
||||
"Delete playlist": "Izbriši seznam predvajanja",
|
||||
"Title": "Naslov",
|
||||
"Playlist privacy": "Zasebnost seznama predvajanja",
|
||||
"Editing playlist `x`": "Urejanje seznama predvajanja `x`",
|
||||
"Show more": "Pokaži več",
|
||||
"Switch Invidious Instance": "Preklopi Invidious instanco",
|
||||
"search_message_change_filters_or_query": "Poskusi razširiti iskalno poizvedbo in/ali spremeniti filtre.",
|
||||
"search_message_use_another_instance": " Lahko tudi <a href=\"`x`\">iščeš v drugi istanci</a>.",
|
||||
"Wilson score: ": "Wilsonov rezultat: ",
|
||||
"Engagement: ": "Sodelovanje: ",
|
||||
"Blacklisted regions: ": "Regije na seznamu nedovoljenih: ",
|
||||
"Shared `x`": "V skupni rabi od: `x`",
|
||||
"Premieres `x`": "Premiere `x`",
|
||||
"View YouTube comments": "Oglej si YouTube komentarje",
|
||||
"View more comments on Reddit": "Prikaži več komentarjev na Reddit",
|
||||
"View `x` comments": {
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "Poglej `x` komentar",
|
||||
"": "Poglej `x` komentarjev"
|
||||
},
|
||||
"Quota exceeded, try again in a few hours": "Kvota je presežena, poskusi znova čez nekaj ur",
|
||||
"Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Ne morem se prijaviti, preveri, ali je vklopljeno dvofaktorsko preverjanje pristnosti (avtentikator ali SMS).",
|
||||
"Please sign in using 'Log in with Google'": "Prijavi se z uporabo »Prijava z Googlom«",
|
||||
"Password cannot be empty": "Geslo ne sme biti prazno",
|
||||
"`x` ago": "`x` nazaj",
|
||||
"Load more": "Naloži več",
|
||||
"comments_points_count_0": "{{count}} točka",
|
||||
"comments_points_count_1": "{{count}} točki",
|
||||
"comments_points_count_2": "{{count}} točke",
|
||||
"comments_points_count_3": "{{count}} točk",
|
||||
"Hidden field \"token\" is a required field": "Skrito polje »žeton« je zahtevano polje",
|
||||
"Erroneous challenge": "Napačen izziv",
|
||||
"English": "angleščina",
|
||||
"English (United States)": "angleščina (Združene države)",
|
||||
"Albanian": "albanščina",
|
||||
"Amharic": "amharščina",
|
||||
"Azerbaijani": "azerbajdžanščina",
|
||||
"Bangla": "bengalščina",
|
||||
"Belarusian": "beloruščina",
|
||||
"Burmese": "birmanščina",
|
||||
"Cebuano": "cebuanščina",
|
||||
"Chinese (Hong Kong)": "kitajščina (Hongkong)",
|
||||
"Chinese (Simplified)": "kitajščina (poenostavljena)",
|
||||
"Chinese (Taiwan)": "kitajščina (Tajvan)",
|
||||
"Corsican": "korzijščina",
|
||||
"Croatian": "hrvaščina",
|
||||
"Danish": "danščina",
|
||||
"Dutch": "nizozemščina",
|
||||
"Estonian": "estonščina",
|
||||
"Filipino": "filipinščina",
|
||||
"Finnish": "finščina",
|
||||
"French": "francoščina",
|
||||
"French (auto-generated)": "francoščina (samodejno ustvarjeno)",
|
||||
"Georgian": "gruzinščina",
|
||||
"German": "nemščina",
|
||||
"Greek": "grščina",
|
||||
"Gujarati": "gudžaratščina",
|
||||
"Haitian Creole": "haitijska kreolščina",
|
||||
"Hausa": "havščina",
|
||||
"Hawaiian": "havajščina",
|
||||
"Hmong": "hmonščina",
|
||||
"Hungarian": "madžarščina",
|
||||
"Icelandic": "islandščina",
|
||||
"Igbo": "igbo",
|
||||
"Interlingue": "interlingua",
|
||||
"Italian (auto-generated)": "italijanščina (samodejno ustvarjeno)",
|
||||
"Japanese": "japonščina",
|
||||
"Japanese (auto-generated)": "japonščina (samodejno ustvarjeno)",
|
||||
"Khmer": "kmerščina",
|
||||
"Korean": "korejščina",
|
||||
"Korean (auto-generated)": "korejščina (samodejno ustvarjeno)",
|
||||
"Kurdish": "kurdščina",
|
||||
"Kannada": "kanadejščina",
|
||||
"Latvian": "latvijščina",
|
||||
"Lithuanian": "litovščina",
|
||||
"Luxembourgish": "luksemburščina",
|
||||
"Macedonian": "makedonščina",
|
||||
"Malagasy": "malgaščina",
|
||||
"Malay": "malajščina",
|
||||
"Nepali": "nepalščina",
|
||||
"Norwegian Bokmål": "norveščina bokmal",
|
||||
"Nyanja": "njanščina",
|
||||
"Punjabi": "pandžabščina",
|
||||
"Romanian": "romunščina",
|
||||
"Russian": "ruščina",
|
||||
"Samoan": "samoanščina",
|
||||
"Scottish Gaelic": "škotska galščina",
|
||||
"Shona": "šonaščina",
|
||||
"Sundanese": "sudanščina",
|
||||
"Thai": "tajščina",
|
||||
"Turkish": "turščina",
|
||||
"Turkish (auto-generated)": "turščina (samodejno ustvarjeno)",
|
||||
"Ukrainian": "ukrajinščina",
|
||||
"Urdu": "urdujščina",
|
||||
"Telugu": "telugu",
|
||||
"Vietnamese": "vietnamščina",
|
||||
"Welsh": "valižanščina",
|
||||
"Western Frisian": "zahodnofrizijščina",
|
||||
"Yiddish": "jidiš",
|
||||
"Yoruba": "joruba",
|
||||
"Xhosa": "xhosa",
|
||||
"generic_count_years_0": "{{count}} letom",
|
||||
"generic_count_years_1": "{{count}} leti",
|
||||
"generic_count_years_2": "{{count}} leti",
|
||||
"generic_count_years_3": "{{count}} leti",
|
||||
"generic_count_days_0": "{{count}} dnevom",
|
||||
"generic_count_days_1": "{{count}} dnevi",
|
||||
"generic_count_days_2": "{{count}} dnevi",
|
||||
"generic_count_days_3": "{{count}} dnevi",
|
||||
"generic_count_hours_0": "{{count}} uro",
|
||||
"generic_count_hours_1": "{{count}} urami",
|
||||
"generic_count_hours_2": "{{count}} urami",
|
||||
"generic_count_hours_3": "{{count}} urami",
|
||||
"generic_count_minutes_0": "{{count}} minuto",
|
||||
"generic_count_minutes_1": "{{count}} minutami",
|
||||
"generic_count_minutes_2": "{{count}} minutami",
|
||||
"generic_count_minutes_3": "{{count}} minutami",
|
||||
"Search": "Iskanje",
|
||||
"Top": "Vrh",
|
||||
"About": "O aplikaciji",
|
||||
"%A %B %-d, %Y": "%A %-d %B %Y",
|
||||
"Audio mode": "Avdio način",
|
||||
"Videos": "Videoposnetki",
|
||||
"search_filters_date_label": "Datum nalaganja",
|
||||
"search_filters_date_option_today": "Danes",
|
||||
"search_filters_date_option_week": "Ta teden",
|
||||
"search_filters_type_label": "Vrsta",
|
||||
"search_filters_type_option_all": "Katerakoli vrsta",
|
||||
"search_filters_type_option_playlist": "Seznami predvajanja",
|
||||
"search_filters_features_option_subtitles": "Podnapisi/CC",
|
||||
"search_filters_features_option_location": "Lokacija",
|
||||
"footer_donate_page": "Prispevaj",
|
||||
"footer_documentation": "Dokumentacija",
|
||||
"footer_original_source_code": "Izvirna izvorna koda",
|
||||
"none": "ni",
|
||||
"videoinfo_started_streaming_x_ago": "Začetek pretakanja `x` nazaj",
|
||||
"videoinfo_watch_on_youTube": "Oglej si v YouTubu",
|
||||
"user_saved_playlists": "`x` shranjenih seznamov predvajanja",
|
||||
"Video unavailable": "Video ni na voljo",
|
||||
"preferences_save_player_pos_label": "Shrani položaj predvajanja: ",
|
||||
"crash_page_you_found_a_bug": "Videti je, da si v Invidiousu našel hrošča!",
|
||||
"crash_page_read_the_faq": "prebral/a <a href=\"`x`\">Pogosto zastavljena vprašanja (FAQ)</a>",
|
||||
"generic_videos_count_0": "{{count}} video",
|
||||
"generic_videos_count_1": "{{count}} videa",
|
||||
"generic_videos_count_2": "{{count}} videi",
|
||||
"generic_videos_count_3": "{{count}} videov",
|
||||
"generic_views_count_0": "{{count}} ogled",
|
||||
"generic_views_count_1": "{{count}} ogleda",
|
||||
"generic_views_count_2": "{{count}} ogledi",
|
||||
"generic_views_count_3": "{{count}} ogledov",
|
||||
"generic_playlists_count_0": "{{count}} seznam predvajanja",
|
||||
"generic_playlists_count_1": "{{count}} seznama predvajanja",
|
||||
"generic_playlists_count_2": "{{count}} seznami predvajanja",
|
||||
"generic_playlists_count_3": "{{count}} seznamov predvajanja",
|
||||
"generic_subscribers_count_0": "{{count}} naročnik",
|
||||
"generic_subscribers_count_1": "{{count}} naročnika",
|
||||
"generic_subscribers_count_2": "{{count}} naročniki",
|
||||
"generic_subscribers_count_3": "{{count}} naročnikov",
|
||||
"generic_subscriptions_count_0": "{{count}} naročnina",
|
||||
"generic_subscriptions_count_1": "{{count}} naročnini",
|
||||
"generic_subscriptions_count_2": "{{count}} naročnine",
|
||||
"generic_subscriptions_count_3": "{{count}} naročnin",
|
||||
"LIVE": "V ŽIVO",
|
||||
"Shared `x` ago": "Deljeno pred `x`",
|
||||
"View channel on YouTube": "Ogled kanala v YouTubu",
|
||||
"newest": "najnovejši",
|
||||
"Unsubscribe": "Odjavi se",
|
||||
"Authorize token for `x`?": "Odobriti žeton za `x`?",
|
||||
"Import NewPipe subscriptions (.json)": "Uvozi NewPipe (.json) naročnine",
|
||||
"History": "Zgodovina",
|
||||
"JavaScript license information": "Podatki o licenci JavaScript",
|
||||
"oldest": "najstarejši",
|
||||
"popular": "priljubljen",
|
||||
"Export data as JSON": "Izvozi Invidious podatke kot JSON",
|
||||
"Delete account?": "Izbrisati račun?",
|
||||
"An alternative front-end to YouTube": "Alternativni vmesnik za YouTube",
|
||||
"preferences_category_player": "Nastavitve predvajalnika",
|
||||
"preferences_continue_label": "Privzeto predvajaj naslednjega: ",
|
||||
"preferences_watch_history_label": "Omogoči zgodovino ogledov: ",
|
||||
"preferences_quality_option_medium": "srednja",
|
||||
"preferences_quality_option_dash": "DASH (prilagodljiva kakovost)",
|
||||
"preferences_quality_option_small": "majhna",
|
||||
"preferences_quality_dash_option_worst": "najslabša",
|
||||
"preferences_quality_dash_label": "Prednostna kakovost videoposnetkov DASH: ",
|
||||
"preferences_comments_label": "Privzeti komentarji: ",
|
||||
"preferences_quality_dash_option_auto": "samodejna",
|
||||
"preferences_quality_dash_option_2160p": "2160p",
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"youtube": "YouTube",
|
||||
"invidious": "Invidious",
|
||||
"preferences_vr_mode_label": "Interaktivni videoposnetki na 360 stopinj (zahteva WebGL): ",
|
||||
"preferences_captions_label": "Privzeti napisi: ",
|
||||
"Fallback captions: ": "Pomožni napisi: ",
|
||||
"preferences_extend_desc_label": "Samodejno razširi opis videoposnetka: ",
|
||||
"preferences_related_videos_label": "Prikaži povezane videoposnetke: ",
|
||||
"preferences_annotations_label": "Privzeto prikaži opombe: ",
|
||||
"preferences_category_visual": "Vizualne nastavitve",
|
||||
"preferences_region_label": "Država vsebine: ",
|
||||
"Dark mode: ": "Temni način: ",
|
||||
"preferences_dark_mode_label": "Tema: ",
|
||||
"preferences_category_misc": "Različne nastavitve",
|
||||
"preferences_category_subscription": "Nastavitve naročnine",
|
||||
"Unlisted": "Nerazporejeno",
|
||||
"Enable web notifications": "Omogoči spletna obvestila",
|
||||
"`x` is live": "`x` je v živo",
|
||||
"Manage subscriptions": "Upravljaj naročnine",
|
||||
"Manage tokens": "Upravljaj žetone",
|
||||
"Subscription manager": "Upravitelj naročnin",
|
||||
"`x` uploaded a video": "`x` je naložil/a videoposnetek",
|
||||
"preferences_show_nick_label": "Prikaži vzdevek na vrhu: ",
|
||||
"search_message_no_results": "Ni zadetkov.",
|
||||
"Save preferences": "Shrani nastavitve",
|
||||
"Subscriptions": "Naročnine",
|
||||
"Report statistics: ": "Poročilo o statistiki: ",
|
||||
"subscriptions_unseen_notifs_count_0": "{{count}} neogledano obvestilo",
|
||||
"subscriptions_unseen_notifs_count_1": "{{count}} neogledani obvestili",
|
||||
"subscriptions_unseen_notifs_count_2": "{{count}} neogledana obvestila",
|
||||
"subscriptions_unseen_notifs_count_3": "{{count}} neogledanih obvestil",
|
||||
"View JavaScript license information.": "Oglej si informacije o licenci za JavaScript.",
|
||||
"Show less": "Pokaži manj",
|
||||
"Watch on YouTube": "Oglej si v YouTubu",
|
||||
"Source available here.": "Izvorna koda na voljo tukaj.",
|
||||
"License: ": "Licenca: ",
|
||||
"View privacy policy.": "Oglej si pravilnik o zasebnosti.",
|
||||
"Public": "Javno",
|
||||
"Create playlist": "Ustvari seznam predvajanja",
|
||||
"Hide annotations": "Skrij opombe",
|
||||
"Show annotations": "Pokaži opombe",
|
||||
"Genre: ": "Žanr: ",
|
||||
"Family friendly? ": "Družinam prijazno? ",
|
||||
"Whitelisted regions: ": "Regije na seznamu dovoljenih: ",
|
||||
"Premieres in `x`": "Premiere v `x`",
|
||||
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Živjo! Izgleda, da imaš izklopljene JavaScripte . Klikni tukaj, če si želiš ogledati komentarje, vendar vedi, da bo lahko nalaganje trajajo nekoliko dlje.",
|
||||
"Show replies": "Pokaži odgovore",
|
||||
"Erroneous CAPTCHA": "Napačna CAPTCHA",
|
||||
"User ID is a required field": "ID uporabnika je obvezno polje",
|
||||
"Password is a required field": "Geslo je obvezno polje",
|
||||
"Wrong username or password": "Napačno uporabniško ime ali geslo",
|
||||
"Password cannot be longer than 55 characters": "Geslo ne sme biti daljše od 55 znakov",
|
||||
"channel:`x`": "kanal: `x`",
|
||||
"Could not fetch comments": "Ni bilo mogoče pridobiti komentarjev",
|
||||
"Could not pull trending pages.": "Ni bilo mogoče povleči trendovskih strani.",
|
||||
"Please log in": "Prosim, prijavi se",
|
||||
"Playlist does not exist.": "Seznam predvajanja ne obstaja.",
|
||||
"Incorrect password": "Napačno geslo",
|
||||
"View Reddit comments": "Oglej si komentarje na Redditu",
|
||||
"This channel does not exist.": "Ta kanal ne obstaja.",
|
||||
"Hide replies": "Skrij odgovore",
|
||||
"Invalid TFA code": "Neveljavna koda TFA",
|
||||
"Login failed. This may be because two-factor authentication is not turned on for your account.": "Prijava ni uspela. To je lahko zato, ker za tvoj račun ni vklopljeno dvofaktorsko preverjanje pristnosti.",
|
||||
"Invidious Private Feed for `x`": "Invidious zasebni vir za `x`",
|
||||
"Deleted or invalid channel": "Izbrisan ali neveljaven kanal",
|
||||
"Empty playlist": "Prazen seznam predvajanja",
|
||||
"No such user": "Ni tega uporabnika",
|
||||
"Token is expired, please try again": "Žeton je potekel, poskusi znova",
|
||||
"English (United Kingdom)": "angleščina (Združeno kraljestvo)",
|
||||
"Wrong answer": "Napačen odgovor",
|
||||
"CAPTCHA is a required field": "CAPTCHA je obvezno polje",
|
||||
"Could not get channel info.": "Ni bilo mogoče dobiti informacij o kanalu.",
|
||||
"comments_view_x_replies_0": "Poglej {{count}} odgovor",
|
||||
"comments_view_x_replies_1": "Poglej {{count}} odgovora",
|
||||
"comments_view_x_replies_2": "Poglej {{count}} odgovore",
|
||||
"comments_view_x_replies_3": "Poglej {{count}} odgovorov",
|
||||
"Could not create mix.": "Ni bilo mogoče ustvariti mixa.",
|
||||
"Not a playlist.": "Ni seznam predvajanja.",
|
||||
"Hidden field \"challenge\" is a required field": "Skrito polje »izziv« je obvezno polje",
|
||||
"Erroneous token": "Napačen žeton",
|
||||
"Afrikaans": "afrikanščina",
|
||||
"Arabic": "arabščina",
|
||||
"Armenian": "armenščina",
|
||||
"English (auto-generated)": "angleščina (samodejno ustvarjeno)",
|
||||
"Bulgarian": "bolgarščina",
|
||||
"Catalan": "katalonščina",
|
||||
"Cantonese (Hong Kong)": "kantonščina (Hongkong)",
|
||||
"Chinese (Traditional)": "kitajščina (tradicionalna)",
|
||||
"Basque": "baskovščina",
|
||||
"Czech": "češčina",
|
||||
"Bosnian": "bosanščina",
|
||||
"Chinese": "kitajščina",
|
||||
"Chinese (China)": "kitajščina (Kitajska)",
|
||||
"Dutch (auto-generated)": "nizozemščina (samodejno ustvarjeno)",
|
||||
"Esperanto": "esperanto",
|
||||
"Galician": "galicijščina",
|
||||
"German (auto-generated)": "nemščina (samodejno ustvarjeno)",
|
||||
"Hebrew": "hebrejščina",
|
||||
"Malayalam": "malajalamščina",
|
||||
"Hindi": "hindijščina",
|
||||
"Indonesian": "indonezijščina",
|
||||
"Kazakh": "kazahstanščina",
|
||||
"Indonesian (auto-generated)": "indonezijščina (samodejno generirano)",
|
||||
"Irish": "irščina",
|
||||
"Persian": "perzijščina",
|
||||
"Slovak": "slovaščina",
|
||||
"Italian": "italijanščina",
|
||||
"Maori": "maorščina",
|
||||
"Portuguese": "portugalščina",
|
||||
"Javanese": "javanščina",
|
||||
"Kyrgyz": "kirgiščina",
|
||||
"Lao": "laoščina",
|
||||
"Latin": "latinščina",
|
||||
"Mongolian": "mongolščina",
|
||||
"Portuguese (auto-generated)": "portugalščina (samodejno ustvarjeno)",
|
||||
"Sindhi": "sindščina",
|
||||
"Maltese": "malteščina",
|
||||
"Marathi": "maratščina",
|
||||
"Pashto": "paštu",
|
||||
"Polish": "poljščina",
|
||||
"Portuguese (Brazil)": "portugalščina (Brazilija)",
|
||||
"Fallback comments: ": "Nadomestni komentarji: ",
|
||||
"Gaming": "Igralništvo",
|
||||
"Russian (auto-generated)": "ruščina (samodejno ustvarjeno)",
|
||||
"Serbian": "srbščina",
|
||||
"Sinhala": "singalščina",
|
||||
"Slovenian": "slovenščina",
|
||||
"Somali": "somalijščina",
|
||||
"Spanish": "španščina",
|
||||
"Southern Sotho": "južni sotho",
|
||||
"Spanish (auto-generated)": "španščina (samodejno ustvarjeno)",
|
||||
"Spanish (Mexico)": "španščina (Mehika)",
|
||||
"Spanish (Latin America)": "španščina (Latinska Amerika)",
|
||||
"Spanish (Spain)": "španščina (Španija)",
|
||||
"Tajik": "tadžiščina",
|
||||
"Tamil": "tamilščina",
|
||||
"generic_count_weeks_0": "{{count}} tednom",
|
||||
"generic_count_weeks_1": "{{count}} tedni",
|
||||
"generic_count_weeks_2": "{{count}} tedni",
|
||||
"generic_count_weeks_3": "{{count}} tedni",
|
||||
"Swahili": "svahilščina",
|
||||
"Swedish": "švedščina",
|
||||
"Vietnamese (auto-generated)": "vietnamščina (samodejno ustvarjeno)",
|
||||
"generic_count_months_0": "{{count}} mesecem",
|
||||
"generic_count_months_1": "{{count}} meseci",
|
||||
"generic_count_months_2": "{{count}} meseci",
|
||||
"generic_count_months_3": "{{count}} meseci",
|
||||
"Uzbek": "uzbeščina",
|
||||
"Zulu": "zulujščina",
|
||||
"generic_count_seconds_0": "{{count}} sekundo",
|
||||
"generic_count_seconds_1": "{{count}} sekundami",
|
||||
"generic_count_seconds_2": "{{count}} sekundami",
|
||||
"generic_count_seconds_3": "{{count}} sekundami",
|
||||
"Popular": "Priljubljeni",
|
||||
"Music": "Glasba",
|
||||
"Movies": "Filmi",
|
||||
"YouTube comment permalink": "Stalna povezava za komentar na YouTubu",
|
||||
"search_filters_title": "Filtri",
|
||||
"preferences_locale_label": "Jezik: ",
|
||||
"Rating: ": "Ocena: ",
|
||||
"Default": "Privzeto",
|
||||
"News": "Novice",
|
||||
"Download as: ": "Prenesi kot: ",
|
||||
"(edited)": "(urejeno)",
|
||||
"View as playlist": "Poglej kot seznam predvajanja",
|
||||
"Download": "Prenesi",
|
||||
"permalink": "stalna povezava",
|
||||
"`x` marked it with a ❤": "`x` ga je označil/a z ❤",
|
||||
"Community": "Skupnost",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"Video mode": "Video način",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"Playlists": "Seznami predvajanja",
|
||||
"search_filters_date_option_none": "Katerikoli datum",
|
||||
"search_filters_date_option_month": "Ta mesec",
|
||||
"search_filters_date_option_year": "Letos",
|
||||
"search_filters_type_option_movie": "Film",
|
||||
"search_filters_duration_option_long": "Dolg (> 20 minut)",
|
||||
"search_filters_features_label": "Lastnosti",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"next_steps_error_message_refresh": "Osveži",
|
||||
"search_filters_date_option_hour": "Zadnja ura",
|
||||
"search_filters_features_option_purchased": "Kupljeno",
|
||||
"search_filters_sort_label": "Razvrsti po",
|
||||
"search_filters_sort_option_views": "številu ogledov",
|
||||
"Current version: ": "Trenutna različica: ",
|
||||
"search_filters_features_option_live": "V živo",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_type_option_channel": "Kanal",
|
||||
"search_filters_type_option_show": "Pokaži",
|
||||
"search_filters_duration_label": "Trajanje",
|
||||
"search_filters_duration_option_none": "Poljubno trajanje",
|
||||
"search_filters_duration_option_short": "Kratek (< 4 minute)",
|
||||
"search_filters_duration_option_medium": "Srednji (4 - 20 minut)",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"search_filters_sort_option_date": "datumu nalaganja",
|
||||
"search_filters_type_option_video": "Videoposnetek",
|
||||
"search_filters_sort_option_relevance": "ustreznosti",
|
||||
"search_filters_sort_option_rating": "oceni",
|
||||
"search_filters_apply_button": "Uporabi izbrane filtre",
|
||||
"next_steps_error_message": "Po tem moraš poskusiti: ",
|
||||
"next_steps_error_message_go_to_youtube": "Pojdi na YouTube",
|
||||
"footer_source_code": "Izvorna koda",
|
||||
"footer_modfied_source_code": "Spremenjena izvorna koda",
|
||||
"user_created_playlists": "`x` ustvarjenih seznamov predvajanja",
|
||||
"adminprefs_modified_source_code_url_label": "URL do shrambe spremenjene izvorne kode",
|
||||
"videoinfo_youTube_embed_link": "Vdelati",
|
||||
"videoinfo_invidious_embed_link": "Povezava za vdelavo",
|
||||
"crash_page_switch_instance": "poskušal/a <a href=\"`x`\">uporabiti drugo instanco</a>",
|
||||
"download_subtitles": "Podnapisi - `x` (.vtt)",
|
||||
"crash_page_refresh": "poskušal/a <a href=\"`x`\">osvežiti stran</a>",
|
||||
"crash_page_before_reporting": "Preden prijaviš napako, se prepričaj, da si:",
|
||||
"crash_page_search_issue": "preiskal/a <a href=\"`x`\">obstoječe težave na GitHubu</a>",
|
||||
"crash_page_report_issue": "Če nič od navedenega ni pomagalo, prosim <a href=\"`x`\">odpri novo težavo v GitHubu</a> (po možnosti v angleščini) in v svoje sporočilo vključi naslednje besedilo (tega besedila NE prevajaj):",
|
||||
"Popular enabled: ": "Priljubljeni omogočeni: "
|
||||
}
|
||||
@@ -26,11 +26,11 @@
|
||||
"Tamil": "Tamilisht",
|
||||
"Telugu": "Telugu",
|
||||
"Vietnamese": "Vietnamisht",
|
||||
"creative_commons": "Creative Commons",
|
||||
"3d": "3D",
|
||||
"live": "Drejtpërsëdrejti",
|
||||
"4k": "4K",
|
||||
"location": "Vendndodhja",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_live": "Drejtpërsëdrejti",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_location": "Vendndodhja",
|
||||
"videoinfo_watch_on_youTube": "Shiheni në YouTube",
|
||||
"videoinfo_youTube_embed_link": "Trupëzojeni",
|
||||
"videoinfo_invidious_embed_link": "Lidhje Trupëzimi",
|
||||
@@ -127,7 +127,7 @@
|
||||
"Subscriptions": "Pajtime",
|
||||
"search": "kërko",
|
||||
"Log out": "Dilni",
|
||||
"Released under the AGPLv3 on Github.": "Hedhur në qarkullim në Github sipas licencës AGPLv3.",
|
||||
"Released under the AGPLv3 on Github.": "Hedhur në qarkullim në GitHub sipas licencës AGPLv3.",
|
||||
"Source available here.": "Burimi i passhëm që këtu.",
|
||||
"View JavaScript license information.": "Shihni hollësi licence JavaScript.",
|
||||
"View privacy policy.": "Shihni rregulla privatësie.",
|
||||
@@ -147,7 +147,6 @@
|
||||
"Show less": "Shfaq më pak",
|
||||
"Watch on YouTube": "Shiheni në YouTube",
|
||||
"Switch Invidious Instance": "Ndërroni Instancë Invidious",
|
||||
"Broken? Try another Invidious Instance": "E prishur? Provoni një tjetër Instancë Invidious",
|
||||
"Hide annotations": "Fshihi shënimet",
|
||||
"Show annotations": "Shfaq shënime",
|
||||
"License: ": "Licencë: ",
|
||||
@@ -261,32 +260,32 @@
|
||||
"Audio mode": "Mënyrë për audion",
|
||||
"Playlists": "Luajlista",
|
||||
"Community": "Bashkësi",
|
||||
"relevance": "Rëndësi",
|
||||
"search_filters_sort_option_relevance": "Rëndësi",
|
||||
"Video mode": "Mënyrë video",
|
||||
"Videos": "Video",
|
||||
"rating": "Vlerësim",
|
||||
"date": "Datë ngarkimi",
|
||||
"views": "Numër parjesh",
|
||||
"content_type": "Lloj",
|
||||
"duration": "Kohëzgjatje",
|
||||
"features": "Veçori",
|
||||
"sort": "Renditi Sipas",
|
||||
"hour": "Orën e Fundit",
|
||||
"today": "Sot",
|
||||
"long": "E gjatë (> 20 minuta)",
|
||||
"hd": "HD",
|
||||
"subtitles": "Titra/CC",
|
||||
"hdr": "HDR",
|
||||
"week": "Këtë javë",
|
||||
"month": "Këtë muaj",
|
||||
"year": "Këtë vit",
|
||||
"video": "Video",
|
||||
"channel": "Kanal",
|
||||
"playlist": "Luajlistë",
|
||||
"movie": "Film",
|
||||
"show": "Shfaqe",
|
||||
"short": "E shkurtër (< 4 minuta)",
|
||||
"purchased": "Të blera",
|
||||
"search_filters_sort_option_rating": "Vlerësim",
|
||||
"search_filters_sort_option_date": "Datë ngarkimi",
|
||||
"search_filters_sort_option_views": "Numër parjesh",
|
||||
"search_filters_type_label": "Lloj",
|
||||
"search_filters_duration_label": "Kohëzgjatje",
|
||||
"search_filters_features_label": "Veçori",
|
||||
"search_filters_sort_label": "Renditi Sipas",
|
||||
"search_filters_date_option_hour": "Orën e Fundit",
|
||||
"search_filters_date_option_today": "Sot",
|
||||
"search_filters_duration_option_long": "E gjatë (> 20 minuta)",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "Titra/CC",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"search_filters_date_option_week": "Këtë javë",
|
||||
"search_filters_date_option_month": "Këtë muaj",
|
||||
"search_filters_date_option_year": "Këtë vit",
|
||||
"search_filters_type_option_video": "Video",
|
||||
"search_filters_type_option_channel": "Kanal",
|
||||
"search_filters_type_option_playlist": "Luajlistë",
|
||||
"search_filters_type_option_movie": "Film",
|
||||
"search_filters_type_option_show": "Shfaqe",
|
||||
"search_filters_duration_option_short": "E shkurtër (< 4 minuta)",
|
||||
"search_filters_features_option_purchased": "Të blera",
|
||||
"footer_modfied_source_code": "Kod Burim i ndryshuar",
|
||||
"adminprefs_modified_source_code_url_label": "URL e depos së ndryshuar të kodit burim",
|
||||
"none": "asnjë",
|
||||
@@ -370,8 +369,7 @@
|
||||
"Mongolian": "Mongolisht",
|
||||
"Nepali": "Nepaleze",
|
||||
"Norwegian Bokmål": "Norvegjishte Bokmål",
|
||||
"360": "360°",
|
||||
"filter": "Filtroji",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"Current version: ": "Versioni i tanishëm: ",
|
||||
"next_steps_error_message": "Pas të cilës duhet të provoni të: ",
|
||||
"next_steps_error_message_refresh": "Rifreskoje",
|
||||
@@ -437,7 +435,7 @@
|
||||
"Spanish (Spain)": "Spanjisht (Spanjë)",
|
||||
"Turkish (auto-generated)": "Turqisht (të prodhuara automatikisht)",
|
||||
"Vietnamese (auto-generated)": "Vietnamisht (të prodhuara automatikisht)",
|
||||
"crash_page_search_issue": "kërkuar për <a href=\"`x`\">çështje ekzistuese në Github</a>",
|
||||
"crash_page_search_issue": "kërkuar për <a href=\"`x`\">çështje ekzistuese në GitHub</a>",
|
||||
"crash_page_report_issue": "Nëse asnjë nga sa më sipër s’ndihmoi, ju lutemi, <a href=\"`x`\">hapni një çështje në GitHub</a> (mundësisht në anglisht) dhe përfshini në mesazhin tuaj tekstin vijues (MOS e përktheni këtë tekst):",
|
||||
"generic_subscriptions_count": "{{count}} pajtim",
|
||||
"generic_subscriptions_count_plural": "{{count}} pajtime",
|
||||
@@ -448,5 +446,6 @@
|
||||
"Import YouTube subscriptions": "Importoni pajtime YouTube/OPML",
|
||||
"Export data as JSON": "Eksportoji të dhënat Invidious si JSON",
|
||||
"preferences_vr_mode_label": "Video me ndërveprim 360 gradë (lyp WebGL): ",
|
||||
"Shared `x`": "Ndau me të tjerë `x`"
|
||||
"Shared `x`": "Ndau me të tjerë `x`",
|
||||
"search_filters_title": "Filtra"
|
||||
}
|
||||
|
||||
@@ -131,26 +131,25 @@
|
||||
"YouTube comment permalink": "YouTube komentar trajna veza",
|
||||
"Audio mode": "Audio mod",
|
||||
"Playlists": "Plej liste",
|
||||
"relevance": "Relevantnost",
|
||||
"rating": "Ocene",
|
||||
"date": "Datum otpremanja",
|
||||
"views": "Broj pregleda",
|
||||
"search_filters_sort_option_relevance": "Relevantnost",
|
||||
"search_filters_sort_option_rating": "Ocene",
|
||||
"search_filters_sort_option_date": "Datum otpremanja",
|
||||
"search_filters_sort_option_views": "Broj pregleda",
|
||||
"`x` marked it with a ❤": "`x` je označio/la ovo sa ❤",
|
||||
"duration": "Trajanje",
|
||||
"features": "Karakteristike",
|
||||
"hour": "Poslednji sat",
|
||||
"week": "Ove sedmice",
|
||||
"month": "Ovaj mesec",
|
||||
"year": "Ove godine",
|
||||
"video": "Video",
|
||||
"playlist": "Plej lista",
|
||||
"movie": "Film",
|
||||
"long": "Dugo (> 20 minuta)",
|
||||
"hd": "HD",
|
||||
"creative_commons": "Creative Commons (Licenca)",
|
||||
"3d": "3D",
|
||||
"hdr": "Video Visoke Rezolucije",
|
||||
"filter": "Filter",
|
||||
"search_filters_duration_label": "Trajanje",
|
||||
"search_filters_features_label": "Karakteristike",
|
||||
"search_filters_date_option_hour": "Poslednji sat",
|
||||
"search_filters_date_option_week": "Ove sedmice",
|
||||
"search_filters_date_option_month": "Ovaj mesec",
|
||||
"search_filters_date_option_year": "Ove godine",
|
||||
"search_filters_type_option_video": "Video",
|
||||
"search_filters_type_option_playlist": "Plej lista",
|
||||
"search_filters_type_option_movie": "Film",
|
||||
"search_filters_duration_option_long": "Dugo (> 20 minuta)",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_c_commons": "Creative Commons (Licenca)",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_hdr": "Video Visoke Rezolucije",
|
||||
"next_steps_error_message": "Nakon čega bi trebali probati: ",
|
||||
"next_steps_error_message_go_to_youtube": "Idi na YouTube",
|
||||
"footer_documentation": "Dokumentacija",
|
||||
@@ -225,13 +224,12 @@
|
||||
"preferences_category_visual": "Vizuelne preference",
|
||||
"preferences_captions_label": "Podrazumevani titl: ",
|
||||
"Music": "Muzika",
|
||||
"content_type": "Tip",
|
||||
"Broken? Try another Invidious Instance": "Ne funkcioniše ispravno? Probajte drugu Invidious instancu",
|
||||
"search_filters_type_label": "Tip",
|
||||
"Tamil": "Tamilski",
|
||||
"Save preferences": "Sačuvaj podešavanja",
|
||||
"Only show latest unwatched video from channel: ": "Prikaži samo poslednje video klipove koji nisu pogledani sa kanala: ",
|
||||
"Xhosa": "Kosa (Jezik)",
|
||||
"channel": "Kanal",
|
||||
"search_filters_type_option_channel": "Kanal",
|
||||
"Hungarian": "Mađarski",
|
||||
"Maori": "Maori (Jezik)",
|
||||
"Manage subscriptions": "Upravljaj zapisima",
|
||||
@@ -243,7 +241,7 @@
|
||||
"preferences_default_home_label": "Podrazumevana početna stranica: ",
|
||||
"Serbian": "Srpski",
|
||||
"License: ": "Licenca: ",
|
||||
"live": "Uživo",
|
||||
"search_filters_features_option_live": "Uživo",
|
||||
"Report statistics: ": "Izveštavaj o statistici: ",
|
||||
"Only show latest video from channel: ": "Prikazuj poslednje video klipove samo sa kanala: ",
|
||||
"channel name - reverse": "ime kanala - obrnuto",
|
||||
@@ -266,14 +264,14 @@
|
||||
"alphabetically": "po alfabetu",
|
||||
"No such user": "Nepostojeći korisnik",
|
||||
"Subscriptions": "Praćenja",
|
||||
"today": "Danas",
|
||||
"search_filters_date_option_today": "Danas",
|
||||
"Finnish": "Finski",
|
||||
"Lao": "Laoski",
|
||||
"Login enabled: ": "Prijava omogućena: ",
|
||||
"Shona": "Šona",
|
||||
"location": "Lokacija",
|
||||
"search_filters_features_option_location": "Lokacija",
|
||||
"Load more": "Učitaj više",
|
||||
"Released under the AGPLv3 on Github.": "Izbačeno pod licencom AGPLv3 na Github-u.",
|
||||
"Released under the AGPLv3 on Github.": "Izbačeno pod licencom AGPLv3 na GitHub-u.",
|
||||
"Slovenian": "Slovenački",
|
||||
"View JavaScript license information.": "Pogledaj informacije licence vezane za JavaScript.",
|
||||
"Chinese (Simplified)": "Kineski (Pojednostavljeni)",
|
||||
@@ -292,7 +290,7 @@
|
||||
"Czech": "Češki",
|
||||
"Latin": "Latinski",
|
||||
"Videos": "Video klipovi",
|
||||
"4k": "4К",
|
||||
"search_filters_features_option_four_k": "4К",
|
||||
"footer_donate_page": "Doniraj",
|
||||
"English": "Engleski",
|
||||
"Arabic": "Arapski",
|
||||
@@ -310,7 +308,7 @@
|
||||
"Swahili": "Svahili",
|
||||
"Yiddish": "Jidiš",
|
||||
"Zulu": "Zulu",
|
||||
"subtitles": "Titl/Prevod",
|
||||
"search_filters_features_option_subtitles": "Titl/Prevod",
|
||||
"Password cannot be longer than 55 characters": "Lozinka ne može biti duža od 55 karaktera",
|
||||
"This channel does not exist.": "Ovaj kanal ne postoji.",
|
||||
"Belarusian": "Beloruski",
|
||||
@@ -329,9 +327,9 @@
|
||||
"Clear watch history": "Obriši istoriju gledanja",
|
||||
"preferences_category_admin": "Administratorska podešavanja",
|
||||
"published": "objavljeno",
|
||||
"sort": "Poredaj prema",
|
||||
"show": "Emisija",
|
||||
"short": "Kratko (< 4 minute)",
|
||||
"search_filters_sort_label": "Poredaj prema",
|
||||
"search_filters_type_option_show": "Emisija",
|
||||
"search_filters_duration_option_short": "Kratko (< 4 minute)",
|
||||
"Current version: ": "Trenutna verzija: ",
|
||||
"Top enabled: ": "Vrh omogućen: ",
|
||||
"Public": "Javno",
|
||||
@@ -369,5 +367,6 @@
|
||||
"unsubscribe": "prekini sa praćenjem",
|
||||
"Blacklisted regions: ": "Zabranjene oblasti: ",
|
||||
"Polish": "Poljski",
|
||||
"Yoruba": "Joruba"
|
||||
"Yoruba": "Joruba",
|
||||
"search_filters_title": "Filter"
|
||||
}
|
||||
|
||||
@@ -182,14 +182,13 @@
|
||||
"Georgian": "Грузијски",
|
||||
"Greek": "Грчки",
|
||||
"Hausa": "Хауса",
|
||||
"video": "Видео",
|
||||
"playlist": "Плеј листа",
|
||||
"movie": "Филм",
|
||||
"long": "Дуго (> 20 минута)",
|
||||
"creative_commons": "Creative Commons (Лиценца)",
|
||||
"live": "Уживо",
|
||||
"location": "Локација",
|
||||
"filter": "Филтер",
|
||||
"search_filters_type_option_video": "Видео",
|
||||
"search_filters_type_option_playlist": "Плеј листа",
|
||||
"search_filters_type_option_movie": "Филм",
|
||||
"search_filters_duration_option_long": "Дуго (> 20 минута)",
|
||||
"search_filters_features_option_c_commons": "Creative Commons (Лиценца)",
|
||||
"search_filters_features_option_live": "Уживо",
|
||||
"search_filters_features_option_location": "Локација",
|
||||
"next_steps_error_message": "Након чега би требали пробати: ",
|
||||
"footer_donate_page": "Донирај",
|
||||
"footer_documentation": "Документација",
|
||||
@@ -247,9 +246,9 @@
|
||||
"`x` marked it with a ❤": "`x` је означио/ла ово са ❤",
|
||||
"Audio mode": "Аудио мод",
|
||||
"Videos": "Видео клипови",
|
||||
"views": "Број прегледа",
|
||||
"features": "Карактеристике",
|
||||
"today": "Данас",
|
||||
"search_filters_sort_option_views": "Број прегледа",
|
||||
"search_filters_features_label": "Карактеристике",
|
||||
"search_filters_date_option_today": "Данас",
|
||||
"%A %B %-d, %Y": "%A %B %-d, %Y",
|
||||
"preferences_locale_label": "Језик: ",
|
||||
"Persian": "Перзијски",
|
||||
@@ -257,7 +256,7 @@
|
||||
"": "Прикажи `x` коментара",
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "Прикажи `x` коментар"
|
||||
},
|
||||
"channel": "Канал",
|
||||
"search_filters_type_option_channel": "Канал",
|
||||
"Haitian Creole": "Хаићански Креолски",
|
||||
"Armenian": "Јерменски",
|
||||
"next_steps_error_message_go_to_youtube": "Иди на YouTube",
|
||||
@@ -265,10 +264,10 @@
|
||||
"preferences_vr_mode_label": "Интерактивни видео клипови у 360 степени: ",
|
||||
"Switch Invidious Instance": "Промени Invidious инстанцу",
|
||||
"Portuguese": "Португалски",
|
||||
"week": "Ове седмице",
|
||||
"show": "Емисија",
|
||||
"search_filters_date_option_week": "Ове седмице",
|
||||
"search_filters_type_option_show": "Емисија",
|
||||
"Fallback comments: ": "Коментари у случају отказивања: ",
|
||||
"hdr": "Видео Високе Резолуције",
|
||||
"search_filters_features_option_hdr": "Видео Високе Резолуције",
|
||||
"About": "О програму",
|
||||
"Kazakh": "Казашки",
|
||||
"Shared `x`": "Подељено `x`",
|
||||
@@ -277,7 +276,7 @@
|
||||
"Erroneous challenge": "Погрешан изазов",
|
||||
"Danish": "Дански",
|
||||
"Could not get channel info.": "Узимање података о каналу није успело.",
|
||||
"hd": "HD",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"Slovenian": "Словеначки",
|
||||
"Load more": "Учитај више",
|
||||
"German": "Немачки",
|
||||
@@ -288,12 +287,12 @@
|
||||
"Southern Sotho": "Јужни Сото",
|
||||
"Popular": "Популарно",
|
||||
"Gujarati": "Гуџарати",
|
||||
"year": "Ове године",
|
||||
"search_filters_date_option_year": "Ове године",
|
||||
"Irish": "Ирски",
|
||||
"YouTube comment permalink": "YouTube коментар трајна веза",
|
||||
"Malagasy": "Малгашки",
|
||||
"Token is expired, please try again": "Жетон је истекао, молимо вас да покушате поново",
|
||||
"short": "Кратко (< 4 минуте)",
|
||||
"search_filters_duration_option_short": "Кратко (< 4 минуте)",
|
||||
"Samoan": "Самоански",
|
||||
"Tamil": "Тамилски",
|
||||
"Ukrainian": "Украјински",
|
||||
@@ -307,22 +306,22 @@
|
||||
"Lithuanian": "Литвански",
|
||||
"Icelandic": "Исландски",
|
||||
"Thai": "Тајски",
|
||||
"month": "Овај месец",
|
||||
"content_type": "Тип",
|
||||
"hour": "Последњи сат",
|
||||
"search_filters_date_option_month": "Овај месец",
|
||||
"search_filters_type_label": "Тип",
|
||||
"search_filters_date_option_hour": "Последњи сат",
|
||||
"Spanish": "Шпански",
|
||||
"date": "Датум отпремања",
|
||||
"search_filters_sort_option_date": "Датум отпремања",
|
||||
"View as playlist": "Погледај као плеј листу",
|
||||
"relevance": "Релевантност",
|
||||
"search_filters_sort_option_relevance": "Релевантност",
|
||||
"Estonian": "Естонски",
|
||||
"Sinhala": "Синхалешки",
|
||||
"Corsican": "Корзикански",
|
||||
"Filipino": "Филипино",
|
||||
"Gaming": "Игрице",
|
||||
"Movies": "Филмови",
|
||||
"rating": "Оцене",
|
||||
"search_filters_sort_option_rating": "Оцене",
|
||||
"Top enabled: ": "Врх омогућен: ",
|
||||
"Released under the AGPLv3 on Github.": "Избачено под лиценцом AGPLv3 на Github-у.",
|
||||
"Released under the AGPLv3 on Github.": "Избачено под лиценцом AGPLv3 на GitHub-у.",
|
||||
"Afrikaans": "Африканс",
|
||||
"preferences_automatic_instance_redirect_label": "Аутоматско пребацивање на другу инстанцу у случају отказивања (пречи ће назад на редирецт.инвидиоус.ио): ",
|
||||
"Invalid TFA code": "Неважећа TFA кода",
|
||||
@@ -340,12 +339,11 @@
|
||||
"Swedish": "Шведски",
|
||||
"Music": "Музика",
|
||||
"Download as: ": "Преузми као: ",
|
||||
"duration": "Трајање",
|
||||
"sort": "Поредај према",
|
||||
"subtitles": "Титл/Превод",
|
||||
"search_filters_duration_label": "Трајање",
|
||||
"search_filters_sort_label": "Поредај према",
|
||||
"search_filters_features_option_subtitles": "Титл/Превод",
|
||||
"preferences_extend_desc_label": "Аутоматски прикажи цео опис видеа: ",
|
||||
"Show less": "Прикажи мање",
|
||||
"Broken? Try another Invidious Instance": "Не функционише исправно? Пробајте другу Invidious инстанцу",
|
||||
"Family friendly? ": "Погодно за породицу? ",
|
||||
"Premieres `x`": "Премерe у `x`",
|
||||
"Bosnian": "Босански",
|
||||
@@ -359,8 +357,8 @@
|
||||
"Top": "Врх",
|
||||
"Video mode": "Видео мод",
|
||||
"footer_source_code": "Изворна Кода",
|
||||
"3d": "3D",
|
||||
"4k": "4K",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"Erroneous CAPTCHA": "Погрешна CAPTCHA",
|
||||
"`x` ago": "пре `x`",
|
||||
"Arabic": "Арапски",
|
||||
@@ -369,5 +367,6 @@
|
||||
"Hebrew": "Хебрејски",
|
||||
"Korean": "Корејски",
|
||||
"Kurdish": "Курдски",
|
||||
"Malay": "Малајски"
|
||||
"Malay": "Малајски",
|
||||
"search_filters_title": "Филтер"
|
||||
}
|
||||
|
||||
@@ -139,7 +139,6 @@
|
||||
"Show less": "Visa mindre",
|
||||
"Watch on YouTube": "Titta på YouTube",
|
||||
"Switch Invidious Instance": "Byt Invidious Instans",
|
||||
"Broken? Try another Invidious Instance": "Trasig? Prova en annan Invidious Instance",
|
||||
"Hide annotations": "Dölj länkar-i-video",
|
||||
"Show annotations": "Visa länkar-i-video",
|
||||
"Genre: ": "Genre: ",
|
||||
@@ -327,39 +326,39 @@
|
||||
"Videos": "Videor",
|
||||
"Playlists": "Spellistor",
|
||||
"Community": "Gemenskap",
|
||||
"relevance": "relevans",
|
||||
"rating": "rankning",
|
||||
"date": "datum",
|
||||
"views": "visningar",
|
||||
"content_type": "Typ",
|
||||
"duration": "Varaktighet",
|
||||
"features": "Funktioner",
|
||||
"sort": "Sortera efter",
|
||||
"hour": "timme",
|
||||
"today": "idag",
|
||||
"week": "vecka",
|
||||
"month": "månad",
|
||||
"year": "år",
|
||||
"video": "video",
|
||||
"channel": "kanal",
|
||||
"playlist": "spellista",
|
||||
"movie": "film",
|
||||
"show": "tv-serie",
|
||||
"hd": "hd",
|
||||
"subtitles": "undertexter",
|
||||
"creative_commons": "creative_commons",
|
||||
"3d": "3d",
|
||||
"live": "live",
|
||||
"4k": "4k",
|
||||
"location": "plats",
|
||||
"hdr": "hdr",
|
||||
"filter": "Filter",
|
||||
"search_filters_sort_option_relevance": "Relevans",
|
||||
"search_filters_sort_option_rating": "Rankning",
|
||||
"search_filters_sort_option_date": "Datum",
|
||||
"search_filters_sort_option_views": "Visningar",
|
||||
"search_filters_type_label": "Typ",
|
||||
"search_filters_duration_label": "Varaktighet",
|
||||
"search_filters_features_label": "Funktioner",
|
||||
"search_filters_sort_label": "Sortera efter",
|
||||
"search_filters_date_option_hour": "timme",
|
||||
"search_filters_date_option_today": "idag",
|
||||
"search_filters_date_option_week": "vecka",
|
||||
"search_filters_date_option_month": "månad",
|
||||
"search_filters_date_option_year": "år",
|
||||
"search_filters_type_option_video": "video",
|
||||
"search_filters_type_option_channel": "kanal",
|
||||
"search_filters_type_option_playlist": "spellista",
|
||||
"search_filters_type_option_movie": "film",
|
||||
"search_filters_type_option_show": "tv-serie",
|
||||
"search_filters_features_option_hd": "hd",
|
||||
"search_filters_features_option_subtitles": "undertexter",
|
||||
"search_filters_features_option_c_commons": "creative_commons",
|
||||
"search_filters_features_option_three_d": "3d",
|
||||
"search_filters_features_option_live": "live",
|
||||
"search_filters_features_option_four_k": "4k",
|
||||
"search_filters_features_option_location": "plats",
|
||||
"search_filters_features_option_hdr": "hdr",
|
||||
"Current version: ": "Nuvarande version: ",
|
||||
"next_steps_error_message_refresh": "Uppdatera",
|
||||
"next_steps_error_message_go_to_youtube": "Gå till Youtube",
|
||||
"Released under the AGPLv3 on Github.": "Publicerad under AGPLv3 på Github.",
|
||||
"Released under the AGPLv3 on Github.": "Publicerad under AGPLv3 på GitHub.",
|
||||
"footer_source_code": "Källkod",
|
||||
"long": "Lång (> 20 minuter)",
|
||||
"search_filters_duration_option_long": "Lång (> 20 minuter)",
|
||||
"footer_documentation": "Dokumentation",
|
||||
"short": "Kort (< 4 minuter)"
|
||||
"search_filters_duration_option_short": "Kort (< 4 minuter)",
|
||||
"search_filters_title": "Filter"
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
"Subscriptions": "Abonelikler",
|
||||
"search": "ara",
|
||||
"Log out": "Çıkış yap",
|
||||
"Released under the AGPLv3 on Github.": "Github'da AGPLv3 altında yayınlandı.",
|
||||
"Released under the AGPLv3 on Github.": "GitHub'da AGPLv3 altında yayınlandı.",
|
||||
"Source available here.": "Kaynak kodları burada bulunabilir.",
|
||||
"View JavaScript license information.": "JavaScript lisans bilgilerini görüntüle.",
|
||||
"View privacy policy.": "Gizlilik politikasını görüntüle.",
|
||||
@@ -141,7 +141,6 @@
|
||||
"Show less": "Daha az göster",
|
||||
"Watch on YouTube": "YouTube'da izle",
|
||||
"Switch Invidious Instance": "Invidious Örneğini Değiştir",
|
||||
"Broken? Try another Invidious Instance": "Bozuk mu? Başka bir Invidious örneğini deneyin",
|
||||
"Hide annotations": "Ek açıklamaları gizle",
|
||||
"Show annotations": "Ek açıklamaları göster",
|
||||
"Genre: ": "Tür: ",
|
||||
@@ -329,39 +328,38 @@
|
||||
"Videos": "Videolar",
|
||||
"Playlists": "Oynatma listeleri",
|
||||
"Community": "Topluluk",
|
||||
"relevance": "İlgi",
|
||||
"rating": "Değerlendirme",
|
||||
"date": "Yükleme tarihi",
|
||||
"views": "Görüntüleme sayısı",
|
||||
"content_type": "Tür",
|
||||
"duration": "Süre",
|
||||
"features": "Özellikler",
|
||||
"sort": "Sıralama Ölçütü",
|
||||
"hour": "Son Saat",
|
||||
"today": "Bugün",
|
||||
"week": "Bu hafta",
|
||||
"month": "Bu ay",
|
||||
"year": "Bu yıl",
|
||||
"video": "Video",
|
||||
"channel": "Kanal",
|
||||
"playlist": "Oynatma listesi",
|
||||
"movie": "Film",
|
||||
"show": "Gösteri",
|
||||
"hd": "HD",
|
||||
"subtitles": "Alt yazılar",
|
||||
"creative_commons": "Creative Commons",
|
||||
"3d": "3B",
|
||||
"live": "Canlı",
|
||||
"4k": "4K",
|
||||
"location": "Konum",
|
||||
"hdr": "HDR",
|
||||
"filter": "Filtrele",
|
||||
"search_filters_sort_option_relevance": "İlgi",
|
||||
"search_filters_sort_option_rating": "Değerlendirme",
|
||||
"search_filters_sort_option_date": "Yükleme tarihi",
|
||||
"search_filters_sort_option_views": "Görüntüleme sayısı",
|
||||
"search_filters_type_label": "Tür",
|
||||
"search_filters_duration_label": "Süre",
|
||||
"search_filters_features_label": "Özellikler",
|
||||
"search_filters_sort_label": "Sıralama Ölçütü",
|
||||
"search_filters_date_option_hour": "Son Saat",
|
||||
"search_filters_date_option_today": "Bugün",
|
||||
"search_filters_date_option_week": "Bu hafta",
|
||||
"search_filters_date_option_month": "Bu ay",
|
||||
"search_filters_date_option_year": "Bu yıl",
|
||||
"search_filters_type_option_video": "Video",
|
||||
"search_filters_type_option_channel": "Kanal",
|
||||
"search_filters_type_option_playlist": "Oynatma listesi",
|
||||
"search_filters_type_option_movie": "Film",
|
||||
"search_filters_type_option_show": "Gösteri",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "Alt yazılar",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_three_d": "3B",
|
||||
"search_filters_features_option_live": "Canlı",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_location": "Konum",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"Current version: ": "Şu anki sürüm: ",
|
||||
"next_steps_error_message": "Bundan sonra şunları denemelisiniz: ",
|
||||
"next_steps_error_message_refresh": "Yenile",
|
||||
"next_steps_error_message_go_to_youtube": "YouTube'a git",
|
||||
"short": "Kısa (4 dakikadan az)",
|
||||
"long": "Uzun (20 dakikadan fazla)",
|
||||
"search_filters_duration_option_short": "Kısa (4 dakikadan az)",
|
||||
"search_filters_duration_option_long": "Uzun (20 dakikadan fazla)",
|
||||
"footer_documentation": "Belgelendirme",
|
||||
"footer_source_code": "Kaynak kodları",
|
||||
"footer_original_source_code": "Orijinal kaynak kodları",
|
||||
@@ -394,8 +392,8 @@
|
||||
"Video unavailable": "Video kullanılamıyor",
|
||||
"preferences_quality_option_dash": "DASH (uyarlanabilir kalite)",
|
||||
"preferences_quality_dash_option_auto": "Otomatik",
|
||||
"purchased": "Satın alınan",
|
||||
"360": "360°",
|
||||
"search_filters_features_option_purchased": "Satın alınan",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"videoinfo_watch_on_youTube": "YouTube'da izle",
|
||||
"download_subtitles": "Alt yazılar - `x` (.vtt)",
|
||||
"preferences_save_player_pos_label": "Oynatma konumunu kaydet: ",
|
||||
@@ -436,7 +434,7 @@
|
||||
"crash_page_refresh": "<a href=\"`x`\">sayfayı yenilemeye</a> çalıştınız",
|
||||
"crash_page_switch_instance": "<a href=\"`x`\">başka bir örnek kullanmaya</a> çalıştınız",
|
||||
"crash_page_read_the_faq": "<a href=\"`x`\">Sık Sorulan Soruları (SSS)</a> okudunuz",
|
||||
"crash_page_search_issue": "<a href=\"`x`\">Github'daki sorunlarda</a> aradınız",
|
||||
"crash_page_search_issue": "<a href=\"`x`\">GitHub'daki sorunlarda</a> aradınız",
|
||||
"crash_page_report_issue": "Yukarıdakilerin hiçbiri yardımcı olmadıysa, lütfen <a href=\"`x`\">GitHub'da yeni bir sorun açın</a> (tercihen İngilizce) ve mesajınıza aşağıdaki metni ekleyin (bu metni ÇEVİRMEYİN):",
|
||||
"English (United Kingdom)": "İngilizce (Birleşik Krallık)",
|
||||
"Chinese": "Çince",
|
||||
@@ -461,5 +459,17 @@
|
||||
"Portuguese (auto-generated)": "Portekizce (otomatik oluşturuldu)",
|
||||
"Spanish (Spain)": "İspanyolca (İspanya)",
|
||||
"Vietnamese (auto-generated)": "Vietnamca (otomatik oluşturuldu)",
|
||||
"preferences_watch_history_label": "İzleme geçmişini etkinleştir: "
|
||||
"preferences_watch_history_label": "İzleme geçmişini etkinleştir: ",
|
||||
"search_message_use_another_instance": " Ayrıca <a href=\"`x`\">başka bir örnekte arayabilirsiniz</a>.",
|
||||
"search_filters_type_option_all": "Herhangi bir tür",
|
||||
"search_filters_duration_option_none": "Herhangi bir süre",
|
||||
"search_message_no_results": "Sonuç bulunamadı.",
|
||||
"search_filters_date_label": "Yükleme tarihi",
|
||||
"search_filters_apply_button": "Seçili filtreleri uygula",
|
||||
"search_filters_date_option_none": "Herhangi bir tarih",
|
||||
"search_filters_duration_option_medium": "Orta (4 - 20 dakika)",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"search_filters_title": "Filtreler",
|
||||
"search_message_change_filters_or_query": "Arama sorgunuzu genişletmeyi ve/veya filtreleri değiştirmeyi deneyin.",
|
||||
"Popular enabled: ": "Popüler etkin: "
|
||||
}
|
||||
|
||||
201
locales/uk.json
201
locales/uk.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"LIVE": "ПРЯМИЙ ЕФІР",
|
||||
"Shared `x` ago": "Розміщено `x` назад",
|
||||
"LIVE": "НАЖИВО",
|
||||
"Shared `x` ago": "Розміщено `x` тому",
|
||||
"Unsubscribe": "Відписатися",
|
||||
"Subscribe": "Підписатися",
|
||||
"View channel on YouTube": "Подивитися канал на YouTube",
|
||||
@@ -21,16 +21,16 @@
|
||||
"No": "Ні",
|
||||
"Import and Export Data": "Імпорт і експорт даних",
|
||||
"Import": "Імпорт",
|
||||
"Import Invidious data": "Імпортувати дані Invidious",
|
||||
"Import YouTube subscriptions": "Імпортувати підписки з YouTube",
|
||||
"Import Invidious data": "Імпортувати JSON-дані Invidious",
|
||||
"Import YouTube subscriptions": "Імпортувати підписки з YouTube чи OPML",
|
||||
"Import FreeTube subscriptions (.db)": "Імпортувати підписки з FreeTube (.db)",
|
||||
"Import NewPipe subscriptions (.json)": "Імпортувати підписки з NewPipe (.json)",
|
||||
"Import NewPipe data (.zip)": "Імпортувати дані з NewPipe (.zip)",
|
||||
"Export": "Експорт",
|
||||
"Export subscriptions as OPML": "Експортувати підписки у форматі OPML",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Експортувати підписки у форматі OPML (для NewPipe та FreeTube)",
|
||||
"Export data as JSON": "Експортувати дані у форматі JSON",
|
||||
"Delete account?": "Видалити обліківку?",
|
||||
"Export data as JSON": "Експортувати дані Invidious у форматі JSON",
|
||||
"Delete account?": "Видалити обліковий запис?",
|
||||
"History": "Історія",
|
||||
"An alternative front-end to YouTube": "Альтернативний фронтенд до YouTube",
|
||||
"JavaScript license information": "Інформація щодо ліцензій JavaScript",
|
||||
@@ -40,9 +40,9 @@
|
||||
"Log in with Google": "Увійти через Google",
|
||||
"User ID": "ID користувача",
|
||||
"Password": "Пароль",
|
||||
"Time (h:mm:ss):": "Час (г:мм:сс):",
|
||||
"Text CAPTCHA": "Текст капчі",
|
||||
"Image CAPTCHA": "Зображення капчі",
|
||||
"Time (h:mm:ss):": "Час (г:хх:сс):",
|
||||
"Text CAPTCHA": "Текст CAPTCHA",
|
||||
"Image CAPTCHA": "Зображення CAPTCHA",
|
||||
"Sign In": "Увійти",
|
||||
"Register": "Зареєструватися",
|
||||
"E-mail": "Електронна пошта",
|
||||
@@ -142,7 +142,7 @@
|
||||
"Whitelisted regions: ": "Доступно у регіонах: ",
|
||||
"Blacklisted regions: ": "Недоступно у регіонах: ",
|
||||
"Shared `x`": "Розміщено `x`",
|
||||
"Premieres in `x`": "Прем’єра через `x`",
|
||||
"Premieres in `x`": "Прем’єра за `x`",
|
||||
"Premieres `x`": "Прем’єра `x`",
|
||||
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Схоже, у вас відключений JavaScript. Щоб побачити коментарі, натисніть сюда, але майте на увазі, що вони можуть завантажуватися трохи довше.",
|
||||
"View YouTube comments": "Переглянути коментарі з YouTube",
|
||||
@@ -157,11 +157,11 @@
|
||||
"Incorrect password": "Неправильний пароль",
|
||||
"Quota exceeded, try again in a few hours": "Ліміт перевищено, спробуйте знову за декілька годин",
|
||||
"Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Не вдається увійти. Перевірте, чи не ввімкнена двофакторна аутентифікація (за кодом чи смс).",
|
||||
"Invalid TFA code": "Неправильний код двофакторної аутентифікації",
|
||||
"Invalid TFA code": "Неправильний код двофакторної автентифікації",
|
||||
"Login failed. This may be because two-factor authentication is not turned on for your account.": "Не вдається увійти. Це може бути через те, що у вашій обліківці не ввімкнена двофакторна аутентифікація.",
|
||||
"Wrong answer": "Неправильна відповідь",
|
||||
"Erroneous CAPTCHA": "Неправильна капча",
|
||||
"CAPTCHA is a required field": "Необхідно пройти капчу",
|
||||
"CAPTCHA is a required field": "Необхідно пройти CAPTCHA",
|
||||
"User ID is a required field": "Необхідно ввести ID користувача",
|
||||
"Password is a required field": "Необхідно ввести пароль",
|
||||
"Wrong username or password": "Неправильний логін чи пароль",
|
||||
@@ -169,7 +169,7 @@
|
||||
"Password cannot be empty": "Пароль не може бути порожнім",
|
||||
"Password cannot be longer than 55 characters": "Пароль не може бути довшим за 55 знаків",
|
||||
"Please log in": "Будь ласка, увійдіть",
|
||||
"Invidious Private Feed for `x`": "Приватний поток відео Invidious для `x`",
|
||||
"Invidious Private Feed for `x`": "Приватний потік відео Invidious для `x`",
|
||||
"channel:`x`": "канал: `x`",
|
||||
"Deleted or invalid channel": "Канал видалено або не знайдено",
|
||||
"This channel does not exist.": "Такого каналу не існує.",
|
||||
@@ -189,7 +189,7 @@
|
||||
"No such user": "Недопустиме ім’я користувача",
|
||||
"Token is expired, please try again": "Термін дії токена закінчився, спробуйте пізніше",
|
||||
"English": "Англійська",
|
||||
"English (auto-generated)": "Англійська (сгенеровано автоматично)",
|
||||
"English (auto-generated)": "Англійська (автогенератор)",
|
||||
"Afrikaans": "Африкаанс",
|
||||
"Albanian": "Албанська",
|
||||
"Amharic": "Амхарська",
|
||||
@@ -275,7 +275,7 @@
|
||||
"Somali": "Сомалійська",
|
||||
"Southern Sotho": "Сесото (південна сото)",
|
||||
"Spanish": "Іспанська",
|
||||
"Spanish (Latin America)": "Испанська (Латинська Америка)",
|
||||
"Spanish (Latin America)": "Іспанська (Латинська Америка)",
|
||||
"Sundanese": "Сунданська",
|
||||
"Swahili": "Суахілі",
|
||||
"Swedish": "Шведська",
|
||||
@@ -318,5 +318,174 @@
|
||||
"Videos": "Відео",
|
||||
"Playlists": "Плейлисти",
|
||||
"Community": "Спільнота",
|
||||
"Current version: ": "Поточна версія: "
|
||||
"Current version: ": "Поточна версія: ",
|
||||
"generic_views_count_0": "{{count}} перегляд",
|
||||
"generic_views_count_1": "{{count}} перегляди",
|
||||
"generic_views_count_2": "{{count}} переглядів",
|
||||
"generic_videos_count_0": "{{count}} відео",
|
||||
"generic_videos_count_1": "{{count}} відео",
|
||||
"generic_videos_count_2": "{{count}} відео",
|
||||
"generic_playlists_count_0": "{{count}} список відтворення",
|
||||
"generic_playlists_count_1": "{{count}} списки відтворення",
|
||||
"generic_playlists_count_2": "{{count}} списків відтворення",
|
||||
"generic_subscribers_count_0": "{{count}} стежить",
|
||||
"generic_subscribers_count_1": "{{count}} стежать",
|
||||
"generic_subscribers_count_2": "{{count}} стежать",
|
||||
"generic_subscriptions_count_0": "{{count}} підписка",
|
||||
"generic_subscriptions_count_1": "{{count}} підписки",
|
||||
"generic_subscriptions_count_2": "{{count}} підписок",
|
||||
"tokens_count_0": "{{count}} токен",
|
||||
"tokens_count_1": "{{count}} токени",
|
||||
"tokens_count_2": "{{count}} токенів",
|
||||
"subscriptions_unseen_notifs_count_0": "{{count}} нове сповіщення",
|
||||
"subscriptions_unseen_notifs_count_1": "{{count}} нові сповіщення",
|
||||
"subscriptions_unseen_notifs_count_2": "{{count}} нових сповіщень",
|
||||
"comments_view_x_replies_0": "Переглянути {{count}} відповідь",
|
||||
"comments_view_x_replies_1": "Переглянути {{count}} відповіді",
|
||||
"comments_view_x_replies_2": "Переглянути {{count}} відповідей",
|
||||
"generic_count_years_0": "{{count}} рік",
|
||||
"generic_count_years_1": "{{count}} роки",
|
||||
"generic_count_years_2": "{{count}} років",
|
||||
"generic_count_weeks_0": "{{count}} тиждень",
|
||||
"generic_count_weeks_1": "{{count}} тижні",
|
||||
"generic_count_weeks_2": "{{count}} тижнів",
|
||||
"generic_count_days_0": "{{count}} день",
|
||||
"generic_count_days_1": "{{count}} дні",
|
||||
"generic_count_days_2": "{{count}} днів",
|
||||
"generic_count_hours_0": "{{count}} годину",
|
||||
"generic_count_hours_1": "{{count}} години",
|
||||
"generic_count_hours_2": "{{count}} годин",
|
||||
"crash_page_switch_instance": "спробуйте <a href=\"`x`\">використати інший сервер</a>",
|
||||
"crash_page_read_the_faq": "прочитайте <a href=\"`x`\">часті питання (ЧаП)</a>",
|
||||
"crash_page_search_issue": "перегляньте <a href=\"`x`\">наявні обговорення на GitHub</a>",
|
||||
"crash_page_report_issue": "Якщо нічого не допомогло, просимо <a href=\"`x`\">створити обговорення на GitHub</a> (бажано англійською), додавши наступний текст у повідомлення (НЕ перекладайте цього тексту):",
|
||||
"Chinese (Hong Kong)": "Китайська (Гонконг)",
|
||||
"Cantonese (Hong Kong)": "Кантонська (Гонконг)",
|
||||
"Chinese": "Китайська",
|
||||
"Chinese (China)": "Китайська (Китай)",
|
||||
"Interlingue": "Інтерлінгва",
|
||||
"Italian (auto-generated)": "Італійська (автогенератор)",
|
||||
"Turkish (auto-generated)": "Турецька (автогенератор)",
|
||||
"Vietnamese (auto-generated)": "В'єтнамська (автогенератор)",
|
||||
"user_created_playlists": "Створено списків відтворення: `x`",
|
||||
"user_saved_playlists": "Збережено списків відтворення: `x`",
|
||||
"Video unavailable": "Відео недоступне",
|
||||
"preferences_watch_history_label": "Історія переглядів: ",
|
||||
"preferences_quality_dash_label": "Бажана DASH-якість відео: ",
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"preferences_vr_mode_label": "Взаємодія з 360-градусними відео (потребує WebGL): ",
|
||||
"Released under the AGPLv3 on Github.": "Випущено під AGPLv3 на GitHub.",
|
||||
"English (United Kingdom)": "Англійська (Сполучене Королівство)",
|
||||
"English (United States)": "Англійська (США)",
|
||||
"French (auto-generated)": "Французька (автогенератор)",
|
||||
"German (auto-generated)": "Німецька (автогенератор)",
|
||||
"Portuguese (auto-generated)": "Португальська (автогенератор)",
|
||||
"Portuguese (Brazil)": "Португальська (Бразилія)",
|
||||
"Russian (auto-generated)": ":^)",
|
||||
"Spanish (auto-generated)": "Іспанська (автогенератор)",
|
||||
"Spanish (Mexico)": "Іспанська (Мексика)",
|
||||
"Spanish (Spain)": "Іспанська (Іспанія)",
|
||||
"next_steps_error_message_go_to_youtube": "Перейти до YouTube",
|
||||
"footer_donate_page": "Пожертвувати",
|
||||
"footer_documentation": "Документація",
|
||||
"footer_source_code": "Вихідний код",
|
||||
"footer_original_source_code": "Оригінал вихідного коду",
|
||||
"footer_modfied_source_code": "Змінений вихідний код",
|
||||
"adminprefs_modified_source_code_url_label": "URL-адреса репозиторію зміненого вихідного коду",
|
||||
"none": "нема",
|
||||
"videoinfo_started_streaming_x_ago": "Трансляцію розпочато `x` тому",
|
||||
"crash_page_you_found_a_bug": "Схоже, ви знайшли ваду в Invidious!",
|
||||
"crash_page_before_reporting": "Перш ніж прозвітувати про ваду:",
|
||||
"crash_page_refresh": "спробуйте <a href=\"`x`\">оновити сторінку</a>",
|
||||
"preferences_quality_dash_option_auto": "Авто",
|
||||
"preferences_quality_dash_option_best": "Найкраща",
|
||||
"preferences_quality_dash_option_worst": "Найгірша",
|
||||
"preferences_quality_dash_option_1440p": "1440p",
|
||||
"preferences_quality_dash_option_1080p": "1080p",
|
||||
"preferences_save_player_pos_label": "Зберегти позицію відтворення: ",
|
||||
"preferences_show_nick_label": "Псевдонім угорі: ",
|
||||
"Show more": "Докладніше",
|
||||
"next_steps_error_message": "Після чого спробуйте: ",
|
||||
"next_steps_error_message_refresh": "Оновити сторінку",
|
||||
"Search": "Пошук",
|
||||
"preferences_extend_desc_label": "Автоматично розширювати опис відео: ",
|
||||
"preferences_category_misc": "Різноманітні параметри",
|
||||
"Show less": "Коротше",
|
||||
"preferences_quality_option_small": "Низька",
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"preferences_quality_option_medium": "Середня",
|
||||
"preferences_quality_dash_option_4320p": "4320p",
|
||||
"invidious": "Invidious",
|
||||
"preferences_quality_dash_option_720p": "720p",
|
||||
"preferences_quality_dash_option_360p": "360p",
|
||||
"preferences_region_label": "Ваша країна: ",
|
||||
"preferences_quality_option_dash": "DASH (змінна якість)",
|
||||
"preferences_quality_option_hd720": "HD720",
|
||||
"preferences_quality_dash_option_2160p": "2160p",
|
||||
"preferences_automatic_instance_redirect_label": "Автоматична зміна сервера (redirect.invidious.io як резерв): ",
|
||||
"Switch Invidious Instance": "Інший сервер Invidious",
|
||||
"preferences_quality_dash_option_480p": "480p",
|
||||
"Chinese (Taiwan)": "Китайська (Тайвань)",
|
||||
"Dutch (auto-generated)": "Нідерландська (автогенератор)",
|
||||
"Indonesian (auto-generated)": "Індонезійська (автогенератор)",
|
||||
"Japanese (auto-generated)": "Японська (автогенератор)",
|
||||
"Korean (auto-generated)": "Корейська (автогенератор)",
|
||||
"generic_count_months_0": "{{count}} місяць",
|
||||
"generic_count_months_1": "{{count}} місяці",
|
||||
"generic_count_months_2": "{{count}} місяців",
|
||||
"videoinfo_youTube_embed_link": "Вкласти",
|
||||
"generic_count_minutes_0": "{{count}} хвилину",
|
||||
"generic_count_minutes_1": "{{count}} хвилини",
|
||||
"generic_count_minutes_2": "{{count}} хвилин",
|
||||
"generic_count_seconds_0": "{{count}} секунду",
|
||||
"generic_count_seconds_1": "{{count}} секунди",
|
||||
"generic_count_seconds_2": "{{count}} секунд",
|
||||
"videoinfo_watch_on_youTube": "Переглянути на YouTube",
|
||||
"videoinfo_invidious_embed_link": "Вкласти посилання",
|
||||
"download_subtitles": "Субтитри — `x` (.vtt)",
|
||||
"comments_points_count_0": "{{count}} пункт",
|
||||
"comments_points_count_1": "{{count}} пункти",
|
||||
"comments_points_count_2": "{{count}} пунктів",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_location": "Геомітка",
|
||||
"search_filters_duration_option_none": "Будь-які",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_message_change_filters_or_query": "Спробуйте ширший запит і/або інші фільтри.",
|
||||
"search_filters_type_option_all": "Будь-що",
|
||||
"search_filters_type_option_movie": "Фільм",
|
||||
"search_filters_type_option_show": "Шоу",
|
||||
"search_filters_duration_label": "Тривалість",
|
||||
"search_filters_duration_option_short": "Короткі (до 4 хвилин)",
|
||||
"search_message_no_results": "Результатів не знайдено.",
|
||||
"search_filters_date_label": "Дата вивантаження",
|
||||
"search_filters_date_option_none": "Будь-яка дата",
|
||||
"search_filters_date_option_today": "Сьогодні",
|
||||
"search_filters_date_option_week": "Цей тиждень",
|
||||
"search_filters_type_label": "Тип",
|
||||
"search_filters_type_option_channel": "Канал",
|
||||
"search_message_use_another_instance": " Можете також <a href=\"`x`\">пошукати іншим сервером</a>.",
|
||||
"search_filters_title": "Фільтри",
|
||||
"search_filters_date_option_hour": "Остання година",
|
||||
"search_filters_date_option_month": "Цей місяць",
|
||||
"search_filters_date_option_year": "Цей рік",
|
||||
"search_filters_type_option_video": "Відео",
|
||||
"search_filters_type_option_playlist": "Добірка",
|
||||
"search_filters_duration_option_medium": "Середні (4–20 хвилин)",
|
||||
"search_filters_duration_option_long": "Довгі (понад 20 хвилин)",
|
||||
"search_filters_features_label": "Особливості",
|
||||
"search_filters_features_option_live": "Наживо",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_subtitles": "Субтитри",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"search_filters_sort_label": "Спершу",
|
||||
"search_filters_sort_option_date": "Нещодавні",
|
||||
"search_filters_apply_button": "Застосувати фільтри",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"search_filters_features_option_purchased": "Придбано",
|
||||
"search_filters_sort_option_relevance": "Відповідні",
|
||||
"search_filters_sort_option_rating": "Рейтингові",
|
||||
"search_filters_sort_option_views": "Популярні",
|
||||
"Popular enabled: ": "Популярне ввімкнено: "
|
||||
}
|
||||
|
||||
@@ -138,7 +138,6 @@
|
||||
"Show less": "Hiện ít hơn",
|
||||
"Watch on YouTube": "Xem trên YouTube",
|
||||
"Switch Invidious Instance": "Chuyển phiên bản Invidious",
|
||||
"Broken? Try another Invidious Instance": "Bị hỏng? Hãy thử một Phiên bản Invidious khác",
|
||||
"Hide annotations": "Ẩn chú thích",
|
||||
"Show annotations": "Hiển thị chú thích",
|
||||
"Genre: ": "Thể loại: ",
|
||||
@@ -315,32 +314,32 @@
|
||||
"Videos": "Video",
|
||||
"Playlists": "Danh sách phát",
|
||||
"Community": "Cộng đồng",
|
||||
"relevance": "liên quan",
|
||||
"rating": "Xếp hạng",
|
||||
"date": "ngày",
|
||||
"views": "lượt xem",
|
||||
"content_type": "content_type",
|
||||
"duration": "thời lượng",
|
||||
"features": "đặc trưng",
|
||||
"sort": "sắp xếp",
|
||||
"hour": "giờ",
|
||||
"today": "hôm nay",
|
||||
"week": "tuần",
|
||||
"month": "tháng",
|
||||
"year": "năm",
|
||||
"video": "video",
|
||||
"channel": "kênh",
|
||||
"playlist": "danh sách phát",
|
||||
"movie": "bộ phim",
|
||||
"show": "chỉ",
|
||||
"hd": "hd",
|
||||
"subtitles": "phụ đề",
|
||||
"creative_commons": "Commons sáng tạo",
|
||||
"3d": "3d",
|
||||
"live": "trực tiếp",
|
||||
"4k": "4k",
|
||||
"location": "vị trí",
|
||||
"hdr": "hdr",
|
||||
"filter": "bộ lọc",
|
||||
"Current version: ": "Phiên bản hiện tại: "
|
||||
"search_filters_sort_option_relevance": "liên quan",
|
||||
"search_filters_sort_option_rating": "Xếp hạng",
|
||||
"search_filters_sort_option_date": "ngày",
|
||||
"search_filters_sort_option_views": "lượt xem",
|
||||
"search_filters_type_label": "content_type",
|
||||
"search_filters_duration_label": "thời lượng",
|
||||
"search_filters_features_label": "đặc trưng",
|
||||
"search_filters_sort_label": "sắp xếp",
|
||||
"search_filters_date_option_hour": "giờ",
|
||||
"search_filters_date_option_today": "hôm nay",
|
||||
"search_filters_date_option_week": "tuần",
|
||||
"search_filters_date_option_month": "tháng",
|
||||
"search_filters_date_option_year": "năm",
|
||||
"search_filters_type_option_video": "video",
|
||||
"search_filters_type_option_channel": "kênh",
|
||||
"search_filters_type_option_playlist": "danh sách phát",
|
||||
"search_filters_type_option_movie": "bộ phim",
|
||||
"search_filters_type_option_show": "chỉ",
|
||||
"search_filters_features_option_hd": "hd",
|
||||
"search_filters_features_option_subtitles": "phụ đề",
|
||||
"search_filters_features_option_c_commons": "Commons sáng tạo",
|
||||
"search_filters_features_option_three_d": "3d",
|
||||
"search_filters_features_option_live": "trực tiếp",
|
||||
"search_filters_features_option_four_k": "4k",
|
||||
"search_filters_features_option_location": "vị trí",
|
||||
"search_filters_features_option_hdr": "hdr",
|
||||
"Current version: ": "Phiên bản hiện tại: ",
|
||||
"search_filters_title": "bộ lọc"
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@
|
||||
"subscriptions_unseen_notifs_count_0": "{{count}} 条未读通知",
|
||||
"search": "搜索",
|
||||
"Log out": "登出",
|
||||
"Released under the AGPLv3 on Github.": "依据 AGPLv3 许可证发布于 Github。",
|
||||
"Released under the AGPLv3 on Github.": "依据 AGPLv3 许可证发布于 GitHub。",
|
||||
"Source available here.": "源码可在此查看。",
|
||||
"View JavaScript license information.": "查看 JavaScript 协议信息。",
|
||||
"View privacy policy.": "查看隐私政策。",
|
||||
@@ -148,7 +148,6 @@
|
||||
"Show less": "显示较少",
|
||||
"Watch on YouTube": "在 YouTube 观看",
|
||||
"Switch Invidious Instance": "切换 Invidious 实例",
|
||||
"Broken? Try another Invidious Instance": "无法正常工作? 尝试另一个 Invidious 实例",
|
||||
"Hide annotations": "隐藏注释",
|
||||
"Show annotations": "显示注释",
|
||||
"Genre: ": "风格: ",
|
||||
@@ -345,39 +344,38 @@
|
||||
"Videos": "视频",
|
||||
"Playlists": "播放列表",
|
||||
"Community": "社区",
|
||||
"relevance": "相关度",
|
||||
"rating": "评分",
|
||||
"date": "上传日期",
|
||||
"views": "观看次数",
|
||||
"content_type": "类型",
|
||||
"duration": "持续时间",
|
||||
"features": "功能",
|
||||
"sort": "排序依据",
|
||||
"hour": "上个小时",
|
||||
"today": "今日",
|
||||
"week": "本周",
|
||||
"month": "本月",
|
||||
"year": "今年",
|
||||
"video": "视频",
|
||||
"channel": "频道",
|
||||
"playlist": "播放列表",
|
||||
"movie": "电影",
|
||||
"show": "真人秀",
|
||||
"hd": "高清",
|
||||
"subtitles": "字幕",
|
||||
"creative_commons": "creative_commons 许可",
|
||||
"3d": "3d",
|
||||
"live": "直播",
|
||||
"4k": "4k",
|
||||
"location": "位置",
|
||||
"hdr": "hdr",
|
||||
"filter": "过滤器",
|
||||
"search_filters_sort_option_relevance": "相关度",
|
||||
"search_filters_sort_option_rating": "评分",
|
||||
"search_filters_sort_option_date": "上传日期",
|
||||
"search_filters_sort_option_views": "观看次数",
|
||||
"search_filters_type_label": "类型",
|
||||
"search_filters_duration_label": "持续时间",
|
||||
"search_filters_features_label": "功能",
|
||||
"search_filters_sort_label": "排序依据",
|
||||
"search_filters_date_option_hour": "上个小时",
|
||||
"search_filters_date_option_today": "今日",
|
||||
"search_filters_date_option_week": "本周",
|
||||
"search_filters_date_option_month": "本月",
|
||||
"search_filters_date_option_year": "今年",
|
||||
"search_filters_type_option_video": "视频",
|
||||
"search_filters_type_option_channel": "频道",
|
||||
"search_filters_type_option_playlist": "播放列表",
|
||||
"search_filters_type_option_movie": "电影",
|
||||
"search_filters_type_option_show": "真人秀",
|
||||
"search_filters_features_option_hd": "高清",
|
||||
"search_filters_features_option_subtitles": "字幕",
|
||||
"search_filters_features_option_c_commons": "creative_commons 许可",
|
||||
"search_filters_features_option_three_d": "3d",
|
||||
"search_filters_features_option_live": "直播",
|
||||
"search_filters_features_option_four_k": "4k",
|
||||
"search_filters_features_option_location": "位置",
|
||||
"search_filters_features_option_hdr": "hdr",
|
||||
"Current version: ": "当前版本: ",
|
||||
"next_steps_error_message": "在此之后你应尝试: ",
|
||||
"next_steps_error_message_refresh": "刷新",
|
||||
"next_steps_error_message_go_to_youtube": "转到 YouTube",
|
||||
"short": "短(少于4分钟)",
|
||||
"long": "长(多于 20 分钟)",
|
||||
"search_filters_duration_option_short": "短(少于4分钟)",
|
||||
"search_filters_duration_option_long": "长(多于 20 分钟)",
|
||||
"footer_documentation": "文档",
|
||||
"footer_source_code": "源代码",
|
||||
"footer_modfied_source_code": "修改的源代码",
|
||||
@@ -391,7 +389,7 @@
|
||||
"crash_page_refresh": "试着 <a href=\"`x`\">刷新页面</a>",
|
||||
"crash_page_switch_instance": "试着<a href=\"`x`\">使用另一个实例</a>",
|
||||
"crash_page_read_the_faq": "阅读<a href=\"`x`\">常见问题</a>",
|
||||
"crash_page_search_issue": "搜索过 <a href=\"`x`\">Github 上的现有 issue</a>",
|
||||
"crash_page_search_issue": "搜索过 <a href=\"`x`\">GitHub 上的现有 issue</a>",
|
||||
"crash_page_report_issue": "如果以上这些都没用的话,请<a href=\"`x`\">在 Github 上新开一个 issue</a>(最好用英语撰写),并在你的消息中包含以下文本(不要翻译该文本):",
|
||||
"videoinfo_invidious_embed_link": "嵌入链接",
|
||||
"download_subtitles": "字幕 - `x` (.vtt)",
|
||||
@@ -418,8 +416,8 @@
|
||||
"user_created_playlists": "`x` 创建了播放列表",
|
||||
"user_saved_playlists": "`x` 保存了播放列表",
|
||||
"Video unavailable": "视频不可用",
|
||||
"purchased": "已购买",
|
||||
"360": "360°",
|
||||
"search_filters_features_option_purchased": "已购买",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"none": "无",
|
||||
"preferences_save_player_pos_label": "保存播放位置: ",
|
||||
"Spanish (Mexico)": "西班牙语 (墨西哥)",
|
||||
@@ -445,5 +443,17 @@
|
||||
"French (auto-generated)": "法语 (自动生成)",
|
||||
"Turkish (auto-generated)": "土耳其语 (自动生成)",
|
||||
"Spanish (Spain)": "西班牙语 (西班牙)",
|
||||
"preferences_watch_history_label": "启用观看历史: "
|
||||
"preferences_watch_history_label": "启用观看历史: ",
|
||||
"search_message_use_another_instance": " 你也可以 <a href=\"`x`\">在另一实例上搜索</a>。",
|
||||
"search_filters_title": "过滤器",
|
||||
"search_filters_date_label": "上传日期",
|
||||
"search_filters_apply_button": "应用所选过滤器",
|
||||
"search_message_no_results": "没找到结果。",
|
||||
"search_filters_duration_option_medium": "中等(4-20 分钟)",
|
||||
"search_filters_date_option_none": "任意日期",
|
||||
"search_message_change_filters_or_query": "尝试扩大你的搜索查询和/或更改过滤器。",
|
||||
"search_filters_duration_option_none": "任意时长",
|
||||
"search_filters_type_option_all": "任意类型",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"Popular enabled: ": "已启用流行度: "
|
||||
}
|
||||
|
||||
@@ -148,7 +148,6 @@
|
||||
"Show less": "顯示較少",
|
||||
"Watch on YouTube": "在 YouTube 上觀看",
|
||||
"Switch Invidious Instance": "切換 Invidious 站台",
|
||||
"Broken? Try another Invidious Instance": "故障了嗎?試試看其他 Invidious 站台吧",
|
||||
"Hide annotations": "隱藏註釋",
|
||||
"Show annotations": "顯示註釋",
|
||||
"Genre: ": "風格: ",
|
||||
@@ -345,39 +344,38 @@
|
||||
"Videos": "影片",
|
||||
"Playlists": "播放清單",
|
||||
"Community": "社群",
|
||||
"relevance": "關聯",
|
||||
"rating": "評分",
|
||||
"date": "日期",
|
||||
"views": "檢視",
|
||||
"content_type": "內容類型",
|
||||
"duration": "時長",
|
||||
"features": "特色",
|
||||
"sort": "排序",
|
||||
"hour": "小時",
|
||||
"today": "今天",
|
||||
"week": "週",
|
||||
"month": "月",
|
||||
"year": "年",
|
||||
"video": "影片",
|
||||
"channel": "頻道",
|
||||
"playlist": "播放清單",
|
||||
"movie": "電影",
|
||||
"show": "秀",
|
||||
"hd": "HD",
|
||||
"subtitles": "字幕",
|
||||
"creative_commons": "創用 CC",
|
||||
"3d": "3D",
|
||||
"live": "直播",
|
||||
"4k": "4K",
|
||||
"location": "位置",
|
||||
"hdr": "HDR",
|
||||
"filter": "篩選條件",
|
||||
"search_filters_sort_option_relevance": "關聯",
|
||||
"search_filters_sort_option_rating": "評分",
|
||||
"search_filters_sort_option_date": "日期",
|
||||
"search_filters_sort_option_views": "檢視",
|
||||
"search_filters_type_label": "內容類型",
|
||||
"search_filters_duration_label": "時長",
|
||||
"search_filters_features_label": "特色",
|
||||
"search_filters_sort_label": "排序",
|
||||
"search_filters_date_option_hour": "小時",
|
||||
"search_filters_date_option_today": "今天",
|
||||
"search_filters_date_option_week": "週",
|
||||
"search_filters_date_option_month": "月",
|
||||
"search_filters_date_option_year": "年",
|
||||
"search_filters_type_option_video": "影片",
|
||||
"search_filters_type_option_channel": "頻道",
|
||||
"search_filters_type_option_playlist": "播放清單",
|
||||
"search_filters_type_option_movie": "電影",
|
||||
"search_filters_type_option_show": "秀",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "字幕",
|
||||
"search_filters_features_option_c_commons": "創用 CC",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_live": "直播",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_location": "位置",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"Current version: ": "目前版本: ",
|
||||
"next_steps_error_message": "之後您應該嘗試: ",
|
||||
"next_steps_error_message_refresh": "重新整理",
|
||||
"next_steps_error_message_go_to_youtube": "到 YouTube",
|
||||
"short": "短(小於4分鐘)",
|
||||
"long": "長(多於20分鐘)",
|
||||
"search_filters_duration_option_short": "短(小於4分鐘)",
|
||||
"search_filters_duration_option_long": "長(多於20分鐘)",
|
||||
"footer_documentation": "文件",
|
||||
"footer_source_code": "原始碼",
|
||||
"footer_original_source_code": "原本的原始碼",
|
||||
@@ -398,8 +396,8 @@
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"invidious": "Invidious",
|
||||
"purchased": "已購買",
|
||||
"360": "360°",
|
||||
"search_filters_features_option_purchased": "已購買",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"none": "無",
|
||||
"videoinfo_started_streaming_x_ago": "`x` 前開始串流",
|
||||
"videoinfo_watch_on_youTube": "在 YouTube 上觀看",
|
||||
@@ -445,5 +443,17 @@
|
||||
"Portuguese (Brazil)": "葡萄牙語(巴西)",
|
||||
"Japanese (auto-generated)": "日語(自動產生)",
|
||||
"Portuguese (auto-generated)": "葡萄牙語(自動產生)",
|
||||
"preferences_watch_history_label": "啟用觀看紀錄: "
|
||||
"preferences_watch_history_label": "啟用觀看紀錄: ",
|
||||
"search_message_change_filters_or_query": "嘗試擴大您的查詢字詞與/或變更過濾條件。",
|
||||
"search_filters_apply_button": "套用選定的過濾條件",
|
||||
"search_message_no_results": "找不到結果。",
|
||||
"search_filters_duration_option_none": "任何時長",
|
||||
"search_filters_duration_option_medium": "中等(4到20分鐘)",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"search_message_use_another_instance": " 您也可以<a href=\"`x`\">在其他站台上搜尋</a>。",
|
||||
"search_filters_title": "過濾條件",
|
||||
"search_filters_date_label": "上傳日期",
|
||||
"search_filters_type_option_all": "任何類型",
|
||||
"search_filters_date_option_none": "任何日期",
|
||||
"Popular enabled: ": "已啟用人氣: "
|
||||
}
|
||||
|
||||
1
mocks
Submodule
1
mocks
Submodule
Submodule mocks added at c401dd9203
60
scripts/deploy-database.sh
Normal file
60
scripts/deploy-database.sh
Normal file
@@ -0,0 +1,60 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Parameters
|
||||
#
|
||||
|
||||
interactive=true
|
||||
|
||||
if [ "$1" = "--no-interactive" ]; then
|
||||
interactive=false
|
||||
fi
|
||||
|
||||
#
|
||||
# Enable and start Postgres
|
||||
#
|
||||
|
||||
sudo systemctl start postgresql.service
|
||||
sudo systemctl enable postgresql.service
|
||||
|
||||
#
|
||||
# Create databse and user
|
||||
#
|
||||
|
||||
if [ "$interactive" = "true" ]; then
|
||||
sudo -u postgres -- createuser -P kemal
|
||||
sudo -u postgres -- createdb -O kemal invidious
|
||||
else
|
||||
# Generate a DB password
|
||||
if [ -z "$POSTGRES_PASS" ]; then
|
||||
echo "Generating database password"
|
||||
POSTGRES_PASS=$(tr -dc 'A-Za-z0-9.;!?{[()]}\\/' < /dev/urandom | head -c16)
|
||||
fi
|
||||
|
||||
# hostname:port:database:username:password
|
||||
echo "Writing .pgpass"
|
||||
echo "127.0.0.1:*:invidious:kemal:${POSTGRES_PASS}" > "$HOME/.pgpass"
|
||||
|
||||
sudo -u postgres -- psql -c "CREATE USER kemal WITH PASSWORD '$POSTGRES_PASS';"
|
||||
sudo -u postgres -- psql -c "CREATE DATABASE invidious WITH OWNER kemal;"
|
||||
sudo -u postgres -- psql -c "GRANT ALL ON DATABASE invidious TO kemal;"
|
||||
fi
|
||||
|
||||
|
||||
#
|
||||
# Instructions for modification of pg_hba.conf
|
||||
#
|
||||
|
||||
if [ "$interactive" = "true" ]; then
|
||||
echo
|
||||
echo "-------------"
|
||||
echo " NOTICE "
|
||||
echo "-------------"
|
||||
echo
|
||||
echo "Make sure that your postgreSQL's pg_hba.conf file contains the follwong"
|
||||
echo "lines before previous 'host' configurations:"
|
||||
echo
|
||||
echo "host invidious kemal 127.0.0.1/32 md5"
|
||||
echo "host invidious kemal ::1/128 md5"
|
||||
echo
|
||||
fi
|
||||
174
scripts/install-dependencies.sh
Normal file
174
scripts/install-dependencies.sh
Normal file
@@ -0,0 +1,174 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Script that installs the various dependencies of invidious
|
||||
#
|
||||
# Dependencies:
|
||||
# - crystal => Language in which Invidious is developed
|
||||
# - postgres => Database server
|
||||
# - git => required to clone Invidious
|
||||
# - librsvg2-bin => For login captcha (provides 'rsvg-convert')
|
||||
#
|
||||
# - libssl-dev => Used by Crystal's SSL module (standard library)
|
||||
# - libxml2-dev => Used by Crystal's XML module (standard library)
|
||||
# - libyaml-dev => Used by Crystal's YAML module (standard library)
|
||||
# - libgmp-dev => Used by Crystal's BigNumbers module (standard library)
|
||||
# - libevent-dev => Used by crystal's internal scheduler (?)
|
||||
# - libpcre3-dev => Used by Crystal's regex engine (?)
|
||||
#
|
||||
# - libsqlite3-dev => Used to open .db files from NewPipe exports
|
||||
# - zlib1g-dev => TBD
|
||||
# - libreadline-dev => TBD
|
||||
#
|
||||
#
|
||||
# Tested on:
|
||||
# - OpenSUSE Leap 15.3
|
||||
|
||||
#
|
||||
# Load system details
|
||||
#
|
||||
|
||||
if [ -e /etc/os-release ]; then
|
||||
. /etc/os-release
|
||||
elif [ -e /usr/lib/os-release ]; then
|
||||
. /usr/lib/os-release
|
||||
else
|
||||
echo "Unsupported Linux system"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
#
|
||||
# Some variables
|
||||
#
|
||||
|
||||
repo_base_url="https://download.opensuse.org/repositories/devel:/languages:/crystal/"
|
||||
repo_end_url="devel:languages:crystal.repo"
|
||||
|
||||
apt_gpg_key="/usr/share/keyrings/crystal.gpg"
|
||||
apt_list_file="/etc/apt/sources.list.d/crystal.list"
|
||||
|
||||
yum_repo_file="/etc/yum.repos.d/crystal.repo"
|
||||
|
||||
#
|
||||
# Major install functions
|
||||
#
|
||||
|
||||
make_repo_url() {
|
||||
echo "${repo_base_url}/${1}/${repo_end_url}"
|
||||
}
|
||||
|
||||
|
||||
install_apt() {
|
||||
repo="$1"
|
||||
|
||||
echo "Adding Crystal repository"
|
||||
|
||||
curl -fsSL "${repo_base_url}/${repo}/Release.key" \
|
||||
| gpg --dearmor \
|
||||
| sudo tee "${apt_gpg_key}" > /dev/null
|
||||
|
||||
echo "deb [signed-by=${apt_gpg_key}] ${repo_base_url}/${repo}/ /" \
|
||||
| sudo tee "$apt_list_file"
|
||||
|
||||
sudo apt-get update
|
||||
|
||||
sudo apt-get install --yes --no-install-recommends \
|
||||
libssl-dev libxml2-dev libyaml-dev libgmp-dev libevent-dev \
|
||||
libpcre3-dev libreadline-dev libsqlite3-dev zlib1g-dev \
|
||||
crystal postgresql-13 git librsvg2-bin make
|
||||
}
|
||||
|
||||
install_yum() {
|
||||
repo=$(make_repo_url "$1")
|
||||
|
||||
echo "Adding Crystal repository"
|
||||
|
||||
cat << END | sudo tee "${yum_repo_file}" > /dev/null
|
||||
[crystal]
|
||||
name=Crystal
|
||||
type=rpm-md
|
||||
baseurl=${repo}/
|
||||
gpgcheck=1
|
||||
gpgkey=${repo}/repodata/repomd.xml.key
|
||||
enabled=1
|
||||
END
|
||||
|
||||
sudo yum -y install \
|
||||
openssl-devel libxml2-devel libyaml-devel gmp-devel \
|
||||
readline-devel sqlite-devel \
|
||||
crystal postgresql postgresql-server git librsvg2-tools make
|
||||
}
|
||||
|
||||
install_pacman() {
|
||||
# TODO: find an alternative to --no-confirm?
|
||||
sudo pacman -S --no-confirm \
|
||||
base-devel librsvg postgresql crystal
|
||||
}
|
||||
|
||||
install_zypper()
|
||||
{
|
||||
repo=$(make_repo_url "$1")
|
||||
|
||||
echo "Adding Crystal repository"
|
||||
sudo zypper --non-interactive addrepo -f "$repo"
|
||||
|
||||
sudo zypper --non-interactive --gpg-auto-import-keys install --no-recommends \
|
||||
libopenssl-devel libxml2-devel libyaml-devel gmp-devel libevent-devel \
|
||||
pcre-devel readline-devel sqlite3-devel zlib-devel \
|
||||
crystal postgresql postgresql-server git rsvg-convert make
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# System-specific logic
|
||||
#
|
||||
|
||||
case "$ID" in
|
||||
archlinux) install_pacman;;
|
||||
|
||||
centos) install_dnf "CentOS_${VERSION_ID}";;
|
||||
|
||||
debian)
|
||||
case "$VERSION_CODENAME" in
|
||||
sid) install_apt "Debian_Unstable";;
|
||||
bookworm) install_apt "Debian_Testing";;
|
||||
*) install_apt "Debian_${VERSION_ID}";;
|
||||
esac
|
||||
;;
|
||||
|
||||
fedora)
|
||||
if [ "$VERSION" == *"Prerelease"* ]; then
|
||||
install_dnf "Fedora_Rawhide"
|
||||
else
|
||||
install_dnf "Fedora_${VERSION}"
|
||||
fi
|
||||
;;
|
||||
|
||||
opensuse-leap) install_zypper "openSUSE_Leap_${VERSION}";;
|
||||
|
||||
opensuse-tumbleweed) install_zypper "openSUSE_Tumbleweed";;
|
||||
|
||||
rhel) install_dnf "RHEL_${VERSION_ID}";;
|
||||
|
||||
ubuntu)
|
||||
# Small workaround for recently released 22.04
|
||||
case "$VERSION_ID" in
|
||||
22.04) install_apt "xUbuntu_21.04";;
|
||||
*) install_apt "xUbuntu_${VERSION_ID}";;
|
||||
esac
|
||||
;;
|
||||
|
||||
*)
|
||||
# Try to match on ID_LIKE instead
|
||||
# Not guaranteed to 100% work
|
||||
case "$ID_LIKE" in
|
||||
archlinux) install_pacman;;
|
||||
centos) install_dnf "CentOS_${VERSION_ID}";;
|
||||
debian) install_apt "Debian_${VERSION_ID}";;
|
||||
*)
|
||||
echo "Error: distribution ${CODENAME} is not supported"
|
||||
echo "Please install dependencies manually"
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
@@ -14,11 +14,11 @@ shards:
|
||||
|
||||
exception_page:
|
||||
git: https://github.com/crystal-loot/exception_page.git
|
||||
version: 0.2.0
|
||||
version: 0.2.2
|
||||
|
||||
kemal:
|
||||
git: https://github.com/kemalcr/kemal.git
|
||||
version: 1.1.0
|
||||
version: 1.1.2
|
||||
|
||||
kilt:
|
||||
git: https://github.com/jeromegn/kilt.git
|
||||
|
||||
@@ -18,7 +18,10 @@ dependencies:
|
||||
version: ~> 0.18.0
|
||||
kemal:
|
||||
github: kemalcr/kemal
|
||||
version: ~> 1.1.0
|
||||
version: ~> 1.1.2
|
||||
kilt:
|
||||
github: jeromegn/kilt
|
||||
version: ~> 0.6.1
|
||||
protodec:
|
||||
github: iv-org/protodec
|
||||
version: ~> 0.1.4
|
||||
|
||||
109
spec/invidious/hashtag_spec.cr
Normal file
109
spec/invidious/hashtag_spec.cr
Normal file
@@ -0,0 +1,109 @@
|
||||
require "../parsers_helper.cr"
|
||||
|
||||
Spectator.describe Invidious::Hashtag do
|
||||
it "parses richItemRenderer containers (test 1)" do
|
||||
# Enable mock
|
||||
test_content = load_mock("hashtag/martingarrix_page1")
|
||||
videos = extract_items(test_content)
|
||||
|
||||
expect(typeof(videos)).to eq(Array(SearchItem))
|
||||
expect(videos.size).to eq(60)
|
||||
|
||||
#
|
||||
# Random video check 1
|
||||
#
|
||||
expect(typeof(videos[11])).to eq(SearchItem)
|
||||
|
||||
video_11 = videos[11].as(SearchVideo)
|
||||
|
||||
expect(video_11.id).to eq("06eSsOWcKYA")
|
||||
expect(video_11.title).to eq("Martin Garrix - Live @ Tomorrowland 2018")
|
||||
|
||||
expect(video_11.ucid).to eq("UC5H_KXkPbEsGs0tFt8R35mA")
|
||||
expect(video_11.author).to eq("Martin Garrix")
|
||||
expect(video_11.author_verified).to be_true
|
||||
|
||||
expect(video_11.published).to be_close(Time.utc - 3.years, 1.second)
|
||||
expect(video_11.length_seconds).to eq((56.minutes + 41.seconds).total_seconds.to_i32)
|
||||
expect(video_11.views).to eq(40_504_893)
|
||||
|
||||
expect(video_11.live_now).to be_false
|
||||
expect(video_11.premium).to be_false
|
||||
expect(video_11.premiere_timestamp).to be_nil
|
||||
|
||||
#
|
||||
# Random video check 2
|
||||
#
|
||||
expect(typeof(videos[35])).to eq(SearchItem)
|
||||
|
||||
video_35 = videos[35].as(SearchVideo)
|
||||
|
||||
expect(video_35.id).to eq("b9HpOAYjY9I")
|
||||
expect(video_35.title).to eq("Martin Garrix feat. Mike Yung - Dreamer (Official Video)")
|
||||
|
||||
expect(video_35.ucid).to eq("UC5H_KXkPbEsGs0tFt8R35mA")
|
||||
expect(video_35.author).to eq("Martin Garrix")
|
||||
expect(video_35.author_verified).to be_true
|
||||
|
||||
expect(video_35.published).to be_close(Time.utc - 3.years, 1.second)
|
||||
expect(video_35.length_seconds).to eq((3.minutes + 14.seconds).total_seconds.to_i32)
|
||||
expect(video_35.views).to eq(30_790_049)
|
||||
|
||||
expect(video_35.live_now).to be_false
|
||||
expect(video_35.premium).to be_false
|
||||
expect(video_35.premiere_timestamp).to be_nil
|
||||
end
|
||||
|
||||
it "parses richItemRenderer containers (test 2)" do
|
||||
# Enable mock
|
||||
test_content = load_mock("hashtag/martingarrix_page2")
|
||||
videos = extract_items(test_content)
|
||||
|
||||
expect(typeof(videos)).to eq(Array(SearchItem))
|
||||
expect(videos.size).to eq(60)
|
||||
|
||||
#
|
||||
# Random video check 1
|
||||
#
|
||||
expect(typeof(videos[41])).to eq(SearchItem)
|
||||
|
||||
video_41 = videos[41].as(SearchVideo)
|
||||
|
||||
expect(video_41.id).to eq("qhstH17zAjs")
|
||||
expect(video_41.title).to eq("Martin Garrix Radio - Episode 391")
|
||||
|
||||
expect(video_41.ucid).to eq("UC5H_KXkPbEsGs0tFt8R35mA")
|
||||
expect(video_41.author).to eq("Martin Garrix")
|
||||
expect(video_41.author_verified).to be_true
|
||||
|
||||
expect(video_41.published).to be_close(Time.utc - 2.months, 1.second)
|
||||
expect(video_41.length_seconds).to eq((1.hour).total_seconds.to_i32)
|
||||
expect(video_41.views).to eq(63_240)
|
||||
|
||||
expect(video_41.live_now).to be_false
|
||||
expect(video_41.premium).to be_false
|
||||
expect(video_41.premiere_timestamp).to be_nil
|
||||
|
||||
#
|
||||
# Random video check 2
|
||||
#
|
||||
expect(typeof(videos[48])).to eq(SearchItem)
|
||||
|
||||
video_48 = videos[48].as(SearchVideo)
|
||||
|
||||
expect(video_48.id).to eq("lqGvW0NIfdc")
|
||||
expect(video_48.title).to eq("Martin Garrix SENTIO Full Album Mix by Sakul")
|
||||
|
||||
expect(video_48.ucid).to eq("UC3833PXeLTS6yRpwGMQpp4Q")
|
||||
expect(video_48.author).to eq("SAKUL")
|
||||
expect(video_48.author_verified).to be_false
|
||||
|
||||
expect(video_48.published).to be_close(Time.utc - 3.weeks, 1.second)
|
||||
expect(video_48.length_seconds).to eq((35.minutes + 46.seconds).total_seconds.to_i32)
|
||||
expect(video_48.views).to eq(68_704)
|
||||
|
||||
expect(video_48.live_now).to be_false
|
||||
expect(video_48.premium).to be_false
|
||||
expect(video_48.premiere_timestamp).to be_nil
|
||||
end
|
||||
end
|
||||
@@ -29,20 +29,6 @@ Spectator.describe "Helper" do
|
||||
end
|
||||
end
|
||||
|
||||
describe "#produce_search_params" do
|
||||
it "correctly produces token for searching with specified filters" do
|
||||
expect(produce_search_params).to eq("CAASAhABSAA%3D")
|
||||
|
||||
expect(produce_search_params(sort: "upload_date", content_type: "video")).to eq("CAISAhABSAA%3D")
|
||||
|
||||
expect(produce_search_params(content_type: "playlist")).to eq("CAASAhADSAA%3D")
|
||||
|
||||
expect(produce_search_params(sort: "date", content_type: "video", features: ["hd", "cc", "purchased", "hdr"])).to eq("CAISCxABIAEwAUgByAEBSAA%3D")
|
||||
|
||||
expect(produce_search_params(content_type: "channel")).to eq("CAASAhACSAA%3D")
|
||||
end
|
||||
end
|
||||
|
||||
describe "#produce_comment_continuation" do
|
||||
it "correctly produces a continuation token for comments" do
|
||||
expect(produce_comment_continuation("_cE8xSu6swE", "ADSJ_i2qvJeFtL0htmS5_K5Ctj3eGFVBMWL9Wd42o3kmUL6_mAzdLp85-liQZL0mYr_16BhaggUqX652Sv9JqV6VXinShSP-ZT6rL4NolPBaPXVtJsO5_rA_qE3GubAuLFw9uzIIXU2-HnpXbdgPLWTFavfX206hqWmmpHwUOrmxQV_OX6tYkM3ux3rPAKCDrT8eWL7MU3bLiNcnbgkW8o0h8KYLL_8BPa8LcHbTv8pAoNkjerlX1x7K4pqxaXPoyz89qNlnh6rRx6AXgAzzoHH1dmcyQ8CIBeOHg-m4i8ZxdX4dP88XWrIFg-jJGhpGP8JUMDgZgavxVx225hUEYZMyrLGler5em4FgbG62YWC51moLDLeYEA")).to eq("EkMSC19jRTh4U3U2c3dFyAEA4AEBogINKP___________wFAAMICHQgEGhdodHRwczovL3d3dy55b3V0dWJlLmNvbSIAGAYyjAMK9gJBRFNKX2kycXZKZUZ0TDBodG1TNV9LNUN0ajNlR0ZWQk1XTDlXZDQybzNrbVVMNl9tQXpkTHA4NS1saVFaTDBtWXJfMTZCaGFnZ1VxWDY1MlN2OUpxVjZWWGluU2hTUC1aVDZyTDROb2xQQmFQWFZ0SnNPNV9yQV9xRTNHdWJBdUxGdzl1eklJWFUyLUhucFhiZGdQTFdURmF2ZlgyMDZocVdtbXBId1VPcm14UVZfT1g2dFlrTTN1eDNyUEFLQ0RyVDhlV0w3TVUzYkxpTmNuYmdrVzhvMGg4S1lMTF84QlBhOExjSGJUdjhwQW9Oa2plcmxYMXg3SzRwcXhhWFBveXo4OXFObG5oNnJSeDZBWGdBenpvSEgxZG1jeVE4Q0lCZU9IZy1tNGk4WnhkWDRkUDg4WFdySUZnLWpKR2hwR1A4SlVNRGdaZ2F2eFZ4MjI1aFVFWVpNeXJMR2xlcjVlbTRGZ2JHNjJZV0M1MW1vTERMZVlFQSIPIgtfY0U4eFN1NnN3RTAAKBQ%3D")
|
||||
|
||||
371
spec/invidious/search/iv_filters_spec.cr
Normal file
371
spec/invidious/search/iv_filters_spec.cr
Normal file
@@ -0,0 +1,371 @@
|
||||
require "../../../src/invidious/search/filters"
|
||||
|
||||
require "http/params"
|
||||
require "spectator"
|
||||
|
||||
Spectator.configure do |config|
|
||||
config.fail_blank
|
||||
config.randomize
|
||||
end
|
||||
|
||||
FEATURES_TEXT = {
|
||||
Invidious::Search::Filters::Features::Live => "live",
|
||||
Invidious::Search::Filters::Features::FourK => "4k",
|
||||
Invidious::Search::Filters::Features::HD => "hd",
|
||||
Invidious::Search::Filters::Features::Subtitles => "subtitles",
|
||||
Invidious::Search::Filters::Features::CCommons => "commons",
|
||||
Invidious::Search::Filters::Features::ThreeSixty => "360",
|
||||
Invidious::Search::Filters::Features::VR180 => "vr180",
|
||||
Invidious::Search::Filters::Features::ThreeD => "3d",
|
||||
Invidious::Search::Filters::Features::HDR => "hdr",
|
||||
Invidious::Search::Filters::Features::Location => "location",
|
||||
Invidious::Search::Filters::Features::Purchased => "purchased",
|
||||
}
|
||||
|
||||
Spectator.describe Invidious::Search::Filters do
|
||||
# -------------------
|
||||
# Decode (legacy)
|
||||
# -------------------
|
||||
|
||||
describe "#from_legacy_filters" do
|
||||
it "Decodes channel: filter" do
|
||||
query = "test channel:UC123456 request"
|
||||
|
||||
fltr, chan, qury, subs = described_class.from_legacy_filters(query)
|
||||
|
||||
expect(fltr).to eq(described_class.new)
|
||||
expect(chan).to eq("UC123456")
|
||||
expect(qury).to eq("test request")
|
||||
expect(subs).to be_false
|
||||
end
|
||||
|
||||
it "Decodes user: filter" do
|
||||
query = "user:LinusTechTips broke something (again)"
|
||||
|
||||
fltr, chan, qury, subs = described_class.from_legacy_filters(query)
|
||||
|
||||
expect(fltr).to eq(described_class.new)
|
||||
expect(chan).to eq("LinusTechTips")
|
||||
expect(qury).to eq("broke something (again)")
|
||||
expect(subs).to be_false
|
||||
end
|
||||
|
||||
it "Decodes type: filter" do
|
||||
Invidious::Search::Filters::Type.each do |value|
|
||||
query = "Eiffel 65 - Blue [1 Hour] type:#{value}"
|
||||
|
||||
fltr, chan, qury, subs = described_class.from_legacy_filters(query)
|
||||
|
||||
expect(fltr).to eq(described_class.new(type: value))
|
||||
expect(chan).to eq("")
|
||||
expect(qury).to eq("Eiffel 65 - Blue [1 Hour]")
|
||||
expect(subs).to be_false
|
||||
end
|
||||
end
|
||||
|
||||
it "Decodes content_type: filter" do
|
||||
Invidious::Search::Filters::Type.each do |value|
|
||||
query = "I like to watch content_type:#{value}"
|
||||
|
||||
fltr, chan, qury, subs = described_class.from_legacy_filters(query)
|
||||
|
||||
expect(fltr).to eq(described_class.new(type: value))
|
||||
expect(chan).to eq("")
|
||||
expect(qury).to eq("I like to watch")
|
||||
expect(subs).to be_false
|
||||
end
|
||||
end
|
||||
|
||||
it "Decodes date: filter" do
|
||||
Invidious::Search::Filters::Date.each do |value|
|
||||
query = "This date:#{value} is old!"
|
||||
|
||||
fltr, chan, qury, subs = described_class.from_legacy_filters(query)
|
||||
|
||||
expect(fltr).to eq(described_class.new(date: value))
|
||||
expect(chan).to eq("")
|
||||
expect(qury).to eq("This is old!")
|
||||
expect(subs).to be_false
|
||||
end
|
||||
end
|
||||
|
||||
it "Decodes duration: filter" do
|
||||
Invidious::Search::Filters::Duration.each do |value|
|
||||
query = "This duration:#{value} is old!"
|
||||
|
||||
fltr, chan, qury, subs = described_class.from_legacy_filters(query)
|
||||
|
||||
expect(fltr).to eq(described_class.new(duration: value))
|
||||
expect(chan).to eq("")
|
||||
expect(qury).to eq("This is old!")
|
||||
expect(subs).to be_false
|
||||
end
|
||||
end
|
||||
|
||||
it "Decodes feature: filter" do
|
||||
Invidious::Search::Filters::Features.each do |value|
|
||||
string = FEATURES_TEXT[value]
|
||||
query = "I like my precious feature:#{string} ^^"
|
||||
|
||||
fltr, chan, qury, subs = described_class.from_legacy_filters(query)
|
||||
|
||||
expect(fltr).to eq(described_class.new(features: value))
|
||||
expect(chan).to eq("")
|
||||
expect(qury).to eq("I like my precious ^^")
|
||||
expect(subs).to be_false
|
||||
end
|
||||
end
|
||||
|
||||
it "Decodes features: filter" do
|
||||
query = "This search has many features:vr180,cc,hdr :o"
|
||||
|
||||
fltr, chan, qury, subs = described_class.from_legacy_filters(query)
|
||||
|
||||
features = Invidious::Search::Filters::Features.flags(HDR, VR180, CCommons)
|
||||
|
||||
expect(fltr).to eq(described_class.new(features: features))
|
||||
expect(chan).to eq("")
|
||||
expect(qury).to eq("This search has many :o")
|
||||
expect(subs).to be_false
|
||||
end
|
||||
|
||||
it "Decodes sort: filter" do
|
||||
Invidious::Search::Filters::Sort.each do |value|
|
||||
query = "Computer? sort:#{value} my files!"
|
||||
|
||||
fltr, chan, qury, subs = described_class.from_legacy_filters(query)
|
||||
|
||||
expect(fltr).to eq(described_class.new(sort: value))
|
||||
expect(chan).to eq("")
|
||||
expect(qury).to eq("Computer? my files!")
|
||||
expect(subs).to be_false
|
||||
end
|
||||
end
|
||||
|
||||
it "Decodes subscriptions: filter" do
|
||||
query = "enable subscriptions:true"
|
||||
|
||||
fltr, chan, qury, subs = described_class.from_legacy_filters(query)
|
||||
|
||||
expect(fltr).to eq(described_class.new)
|
||||
expect(chan).to eq("")
|
||||
expect(qury).to eq("enable")
|
||||
expect(subs).to be_true
|
||||
end
|
||||
|
||||
it "Ignores junk data" do
|
||||
query = "duration:I sort:like type:cleaning features:stuff date:up!"
|
||||
|
||||
fltr, chan, qury, subs = described_class.from_legacy_filters(query)
|
||||
|
||||
expect(fltr).to eq(described_class.new)
|
||||
expect(chan).to eq("")
|
||||
expect(qury).to eq("")
|
||||
expect(subs).to be_false
|
||||
end
|
||||
|
||||
it "Keeps unknown keys" do
|
||||
query = "to:be or:not to:be"
|
||||
|
||||
fltr, chan, qury, subs = described_class.from_legacy_filters(query)
|
||||
|
||||
expect(fltr).to eq(described_class.new)
|
||||
expect(chan).to eq("")
|
||||
expect(qury).to eq("to:be or:not to:be")
|
||||
expect(subs).to be_false
|
||||
end
|
||||
end
|
||||
|
||||
# -------------------
|
||||
# Decode (URL)
|
||||
# -------------------
|
||||
|
||||
describe "#from_iv_params" do
|
||||
it "Decodes type= filter" do
|
||||
Invidious::Search::Filters::Type.each do |value|
|
||||
params = HTTP::Params.parse("type=#{value}")
|
||||
|
||||
expect(described_class.from_iv_params(params))
|
||||
.to eq(described_class.new(type: value))
|
||||
end
|
||||
end
|
||||
|
||||
it "Decodes date= filter" do
|
||||
Invidious::Search::Filters::Date.each do |value|
|
||||
params = HTTP::Params.parse("date=#{value}")
|
||||
|
||||
expect(described_class.from_iv_params(params))
|
||||
.to eq(described_class.new(date: value))
|
||||
end
|
||||
end
|
||||
|
||||
it "Decodes duration= filter" do
|
||||
Invidious::Search::Filters::Duration.each do |value|
|
||||
params = HTTP::Params.parse("duration=#{value}")
|
||||
|
||||
expect(described_class.from_iv_params(params))
|
||||
.to eq(described_class.new(duration: value))
|
||||
end
|
||||
end
|
||||
|
||||
it "Decodes features= filter (single)" do
|
||||
Invidious::Search::Filters::Features.each do |value|
|
||||
string = described_class.format_features(value)
|
||||
params = HTTP::Params.parse("features=#{string}")
|
||||
|
||||
expect(described_class.from_iv_params(params))
|
||||
.to eq(described_class.new(features: value))
|
||||
end
|
||||
end
|
||||
|
||||
it "Decodes features= filter (multiple - comma separated)" do
|
||||
features = Invidious::Search::Filters::Features.flags(HDR, VR180, CCommons)
|
||||
params = HTTP::Params.parse("features=vr180%2Ccc%2Chdr") # %2C is a comma
|
||||
|
||||
expect(described_class.from_iv_params(params))
|
||||
.to eq(described_class.new(features: features))
|
||||
end
|
||||
|
||||
it "Decodes features= filter (multiple - URL parameters)" do
|
||||
features = Invidious::Search::Filters::Features.flags(ThreeSixty, HD, FourK)
|
||||
params = HTTP::Params.parse("features=4k&features=360&features=hd")
|
||||
|
||||
expect(described_class.from_iv_params(params))
|
||||
.to eq(described_class.new(features: features))
|
||||
end
|
||||
|
||||
it "Decodes sort= filter" do
|
||||
Invidious::Search::Filters::Sort.each do |value|
|
||||
params = HTTP::Params.parse("sort=#{value}")
|
||||
|
||||
expect(described_class.from_iv_params(params))
|
||||
.to eq(described_class.new(sort: value))
|
||||
end
|
||||
end
|
||||
|
||||
it "Ignores junk data" do
|
||||
params = HTTP::Params.parse("foo=bar&sort=views&answer=42&type=channel")
|
||||
|
||||
expect(described_class.from_iv_params(params)).to eq(
|
||||
described_class.new(
|
||||
sort: Invidious::Search::Filters::Sort::Views,
|
||||
type: Invidious::Search::Filters::Type::Channel
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# -------------------
|
||||
# Encode (URL)
|
||||
# -------------------
|
||||
|
||||
describe "#to_iv_params" do
|
||||
it "Encodes date filter" do
|
||||
Invidious::Search::Filters::Date.each do |value|
|
||||
filters = described_class.new(date: value)
|
||||
params = filters.to_iv_params
|
||||
|
||||
if value.none?
|
||||
expect("#{params}").to eq("")
|
||||
else
|
||||
expect("#{params}").to eq("date=#{value.to_s.underscore}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "Encodes type filter" do
|
||||
Invidious::Search::Filters::Type.each do |value|
|
||||
filters = described_class.new(type: value)
|
||||
params = filters.to_iv_params
|
||||
|
||||
if value.all?
|
||||
expect("#{params}").to eq("")
|
||||
else
|
||||
expect("#{params}").to eq("type=#{value.to_s.underscore}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "Encodes duration filter" do
|
||||
Invidious::Search::Filters::Duration.each do |value|
|
||||
filters = described_class.new(duration: value)
|
||||
params = filters.to_iv_params
|
||||
|
||||
if value.none?
|
||||
expect("#{params}").to eq("")
|
||||
else
|
||||
expect("#{params}").to eq("duration=#{value.to_s.underscore}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "Encodes features filter (single)" do
|
||||
Invidious::Search::Filters::Features.each do |value|
|
||||
string = described_class.format_features(value)
|
||||
filters = described_class.new(features: value)
|
||||
|
||||
expect("#{filters.to_iv_params}")
|
||||
.to eq("features=" + FEATURES_TEXT[value])
|
||||
end
|
||||
end
|
||||
|
||||
it "Encodes features filter (multiple)" do
|
||||
features = Invidious::Search::Filters::Features.flags(Subtitles, Live, ThreeSixty)
|
||||
filters = described_class.new(features: features)
|
||||
|
||||
expect("#{filters.to_iv_params}")
|
||||
.to eq("features=live%2Csubtitles%2C360") # %2C is a comma
|
||||
end
|
||||
|
||||
it "Encodes sort filter" do
|
||||
Invidious::Search::Filters::Sort.each do |value|
|
||||
filters = described_class.new(sort: value)
|
||||
params = filters.to_iv_params
|
||||
|
||||
if value.relevance?
|
||||
expect("#{params}").to eq("")
|
||||
else
|
||||
expect("#{params}").to eq("sort=#{value.to_s.underscore}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "Encodes multiple filters" do
|
||||
filters = described_class.new(
|
||||
date: Invidious::Search::Filters::Date::Today,
|
||||
duration: Invidious::Search::Filters::Duration::Medium,
|
||||
features: Invidious::Search::Filters::Features.flags(Location, Purchased),
|
||||
sort: Invidious::Search::Filters::Sort::Relevance
|
||||
)
|
||||
|
||||
params = filters.to_iv_params
|
||||
|
||||
# Check the `date` param
|
||||
expect(params).to have_key("date")
|
||||
expect(params.fetch_all("date")).to contain_exactly("today")
|
||||
|
||||
# Check the `type` param
|
||||
expect(params).to_not have_key("type")
|
||||
expect(params["type"]?).to be_nil
|
||||
|
||||
# Check the `duration` param
|
||||
expect(params).to have_key("duration")
|
||||
expect(params.fetch_all("duration")).to contain_exactly("medium")
|
||||
|
||||
# Check the `features` param
|
||||
expect(params).to have_key("features")
|
||||
expect(params.fetch_all("features")).to contain_exactly("location,purchased")
|
||||
|
||||
# Check the `sort` param
|
||||
expect(params).to_not have_key("sort")
|
||||
expect(params["sort"]?).to be_nil
|
||||
|
||||
# Check if there aren't other parameters
|
||||
params.delete("date")
|
||||
params.delete("duration")
|
||||
params.delete("features")
|
||||
|
||||
expect(params).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
242
spec/invidious/search/query_spec.cr
Normal file
242
spec/invidious/search/query_spec.cr
Normal file
@@ -0,0 +1,242 @@
|
||||
require "../../../src/invidious/search/filters"
|
||||
require "../../../src/invidious/search/query"
|
||||
|
||||
require "http/params"
|
||||
require "spectator"
|
||||
|
||||
Spectator.configure do |config|
|
||||
config.fail_blank
|
||||
config.randomize
|
||||
end
|
||||
|
||||
Spectator.describe Invidious::Search::Query do
|
||||
describe Type::Regular do
|
||||
# -------------------
|
||||
# Query parsing
|
||||
# -------------------
|
||||
|
||||
it "parses query with URL prameters (q)" do
|
||||
query = described_class.new(
|
||||
HTTP::Params.parse("q=What+is+Love+10+hour&type=video&duration=long"),
|
||||
Invidious::Search::Query::Type::Regular, nil
|
||||
)
|
||||
|
||||
expect(query.type).to eq(Invidious::Search::Query::Type::Regular)
|
||||
expect(query.channel).to be_empty
|
||||
expect(query.text).to eq("What is Love 10 hour")
|
||||
|
||||
expect(query.filters).to eq(
|
||||
Invidious::Search::Filters.new(
|
||||
type: Invidious::Search::Filters::Type::Video,
|
||||
duration: Invidious::Search::Filters::Duration::Long
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
it "parses query with URL prameters (search_query)" do
|
||||
query = described_class.new(
|
||||
HTTP::Params.parse("search_query=What+is+Love+10+hour&type=video&duration=long"),
|
||||
Invidious::Search::Query::Type::Regular, nil
|
||||
)
|
||||
|
||||
expect(query.type).to eq(Invidious::Search::Query::Type::Regular)
|
||||
expect(query.channel).to be_empty
|
||||
expect(query.text).to eq("What is Love 10 hour")
|
||||
|
||||
expect(query.filters).to eq(
|
||||
Invidious::Search::Filters.new(
|
||||
type: Invidious::Search::Filters::Type::Video,
|
||||
duration: Invidious::Search::Filters::Duration::Long
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
it "parses query with legacy filters (q)" do
|
||||
query = described_class.new(
|
||||
HTTP::Params.parse("q=Nyan+cat+duration:long"),
|
||||
Invidious::Search::Query::Type::Regular, nil
|
||||
)
|
||||
|
||||
expect(query.type).to eq(Invidious::Search::Query::Type::Regular)
|
||||
expect(query.channel).to be_empty
|
||||
expect(query.text).to eq("Nyan cat")
|
||||
|
||||
expect(query.filters).to eq(
|
||||
Invidious::Search::Filters.new(
|
||||
duration: Invidious::Search::Filters::Duration::Long
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
it "parses query with legacy filters (search_query)" do
|
||||
query = described_class.new(
|
||||
HTTP::Params.parse("search_query=Nyan+cat+duration:long"),
|
||||
Invidious::Search::Query::Type::Regular, nil
|
||||
)
|
||||
|
||||
expect(query.type).to eq(Invidious::Search::Query::Type::Regular)
|
||||
expect(query.channel).to be_empty
|
||||
expect(query.text).to eq("Nyan cat")
|
||||
|
||||
expect(query.filters).to eq(
|
||||
Invidious::Search::Filters.new(
|
||||
duration: Invidious::Search::Filters::Duration::Long
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
it "parses query with both URL params and legacy filters" do
|
||||
query = described_class.new(
|
||||
HTTP::Params.parse("q=Vamos+a+la+playa+duration:long&type=Video&date=year"),
|
||||
Invidious::Search::Query::Type::Regular, nil
|
||||
)
|
||||
|
||||
expect(query.type).to eq(Invidious::Search::Query::Type::Regular)
|
||||
expect(query.channel).to be_empty
|
||||
expect(query.text).to eq("Vamos a la playa duration:long")
|
||||
|
||||
expect(query.filters).to eq(
|
||||
Invidious::Search::Filters.new(
|
||||
type: Invidious::Search::Filters::Type::Video,
|
||||
date: Invidious::Search::Filters::Date::Year
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
# -------------------
|
||||
# Type switching
|
||||
# -------------------
|
||||
|
||||
it "switches to channel search (URL param)" do
|
||||
query = described_class.new(
|
||||
HTTP::Params.parse("q=thunderbolt+4&channel=UC0vBXGSyV14uvJ4hECDOl0Q"),
|
||||
Invidious::Search::Query::Type::Regular, nil
|
||||
)
|
||||
|
||||
expect(query.type).to eq(Invidious::Search::Query::Type::Channel)
|
||||
expect(query.channel).to eq("UC0vBXGSyV14uvJ4hECDOl0Q")
|
||||
expect(query.text).to eq("thunderbolt 4")
|
||||
expect(query.filters.default?).to be_true
|
||||
end
|
||||
|
||||
it "switches to channel search (legacy)" do
|
||||
query = described_class.new(
|
||||
HTTP::Params.parse("q=channel%3AUCRPdsCVuH53rcbTcEkuY4uQ+rdna3"),
|
||||
Invidious::Search::Query::Type::Regular, nil
|
||||
)
|
||||
|
||||
expect(query.type).to eq(Invidious::Search::Query::Type::Channel)
|
||||
expect(query.channel).to eq("UCRPdsCVuH53rcbTcEkuY4uQ")
|
||||
expect(query.text).to eq("rdna3")
|
||||
expect(query.filters.default?).to be_true
|
||||
end
|
||||
|
||||
it "switches to subscriptions search" do
|
||||
query = described_class.new(
|
||||
HTTP::Params.parse("q=subscriptions:true+tunak+tunak+tun"),
|
||||
Invidious::Search::Query::Type::Regular, nil
|
||||
)
|
||||
|
||||
expect(query.type).to eq(Invidious::Search::Query::Type::Subscriptions)
|
||||
expect(query.channel).to be_empty
|
||||
expect(query.text).to eq("tunak tunak tun")
|
||||
expect(query.filters.default?).to be_true
|
||||
end
|
||||
end
|
||||
|
||||
describe Type::Channel do
|
||||
it "ignores extra parameters" do
|
||||
query = described_class.new(
|
||||
HTTP::Params.parse("q=Take+on+me+channel%3AUC12345679&type=video&date=year"),
|
||||
Invidious::Search::Query::Type::Channel, nil
|
||||
)
|
||||
|
||||
expect(query.type).to eq(Invidious::Search::Query::Type::Channel)
|
||||
expect(query.channel).to be_empty
|
||||
expect(query.text).to eq("Take on me")
|
||||
expect(query.filters.default?).to be_true
|
||||
end
|
||||
end
|
||||
|
||||
describe Type::Subscriptions do
|
||||
it "works" do
|
||||
query = described_class.new(
|
||||
HTTP::Params.parse("q=Harlem+shake&type=video&date=year"),
|
||||
Invidious::Search::Query::Type::Subscriptions, nil
|
||||
)
|
||||
|
||||
expect(query.type).to eq(Invidious::Search::Query::Type::Subscriptions)
|
||||
expect(query.channel).to be_empty
|
||||
expect(query.text).to eq("Harlem shake")
|
||||
|
||||
expect(query.filters).to eq(
|
||||
Invidious::Search::Filters.new(
|
||||
type: Invidious::Search::Filters::Type::Video,
|
||||
date: Invidious::Search::Filters::Date::Year
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe Type::Playlist do
|
||||
it "ignores extra parameters" do
|
||||
query = described_class.new(
|
||||
HTTP::Params.parse("q=Harlem+shake+type:video+date:year&channel=UC12345679"),
|
||||
Invidious::Search::Query::Type::Playlist, nil
|
||||
)
|
||||
|
||||
expect(query.type).to eq(Invidious::Search::Query::Type::Playlist)
|
||||
expect(query.channel).to be_empty
|
||||
expect(query.text).to eq("Harlem shake")
|
||||
|
||||
expect(query.filters).to eq(
|
||||
Invidious::Search::Filters.new(
|
||||
type: Invidious::Search::Filters::Type::Video,
|
||||
date: Invidious::Search::Filters::Date::Year
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#to_http_params" do
|
||||
it "formats regular search" do
|
||||
query = described_class.new(
|
||||
HTTP::Params.parse("q=The+Simpsons+hiding+in+bush&duration=short"),
|
||||
Invidious::Search::Query::Type::Regular, nil
|
||||
)
|
||||
|
||||
params = query.to_http_params
|
||||
|
||||
expect(params).to have_key("duration")
|
||||
expect(params["duration"]?).to eq("short")
|
||||
|
||||
expect(params).to have_key("q")
|
||||
expect(params["q"]?).to eq("The Simpsons hiding in bush")
|
||||
|
||||
# Check if there aren't other parameters
|
||||
params.delete("duration")
|
||||
params.delete("q")
|
||||
expect(params).to be_empty
|
||||
end
|
||||
|
||||
it "formats channel search" do
|
||||
query = described_class.new(
|
||||
HTTP::Params.parse("q=channel:UC2DjFE7Xf11URZqWBigcVOQ%20multimeter"),
|
||||
Invidious::Search::Query::Type::Regular, nil
|
||||
)
|
||||
|
||||
params = query.to_http_params
|
||||
|
||||
expect(params).to have_key("channel")
|
||||
expect(params["channel"]?).to eq("UC2DjFE7Xf11URZqWBigcVOQ")
|
||||
|
||||
expect(params).to have_key("q")
|
||||
expect(params["q"]?).to eq("multimeter")
|
||||
|
||||
# Check if there aren't other parameters
|
||||
params.delete("channel")
|
||||
params.delete("q")
|
||||
expect(params).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
143
spec/invidious/search/yt_filters_spec.cr
Normal file
143
spec/invidious/search/yt_filters_spec.cr
Normal file
@@ -0,0 +1,143 @@
|
||||
require "../../../src/invidious/search/filters"
|
||||
|
||||
require "http/params"
|
||||
require "spectator"
|
||||
|
||||
Spectator.configure do |config|
|
||||
config.fail_blank
|
||||
config.randomize
|
||||
end
|
||||
|
||||
# Encoded filter values are extracted from the search
|
||||
# page of Youtube with any browser devtools HTML inspector.
|
||||
|
||||
DATE_FILTERS = {
|
||||
Invidious::Search::Filters::Date::Hour => "EgIIAQ%3D%3D",
|
||||
Invidious::Search::Filters::Date::Today => "EgIIAg%3D%3D",
|
||||
Invidious::Search::Filters::Date::Week => "EgIIAw%3D%3D",
|
||||
Invidious::Search::Filters::Date::Month => "EgIIBA%3D%3D",
|
||||
Invidious::Search::Filters::Date::Year => "EgIIBQ%3D%3D",
|
||||
}
|
||||
|
||||
TYPE_FILTERS = {
|
||||
Invidious::Search::Filters::Type::Video => "EgIQAQ%3D%3D",
|
||||
Invidious::Search::Filters::Type::Channel => "EgIQAg%3D%3D",
|
||||
Invidious::Search::Filters::Type::Playlist => "EgIQAw%3D%3D",
|
||||
Invidious::Search::Filters::Type::Movie => "EgIQBA%3D%3D",
|
||||
}
|
||||
|
||||
DURATION_FILTERS = {
|
||||
Invidious::Search::Filters::Duration::Short => "EgIYAQ%3D%3D",
|
||||
Invidious::Search::Filters::Duration::Medium => "EgIYAw%3D%3D",
|
||||
Invidious::Search::Filters::Duration::Long => "EgIYAg%3D%3D",
|
||||
}
|
||||
|
||||
FEATURE_FILTERS = {
|
||||
Invidious::Search::Filters::Features::Live => "EgJAAQ%3D%3D",
|
||||
Invidious::Search::Filters::Features::FourK => "EgJwAQ%3D%3D",
|
||||
Invidious::Search::Filters::Features::HD => "EgIgAQ%3D%3D",
|
||||
Invidious::Search::Filters::Features::Subtitles => "EgIoAQ%3D%3D",
|
||||
Invidious::Search::Filters::Features::CCommons => "EgIwAQ%3D%3D",
|
||||
Invidious::Search::Filters::Features::ThreeSixty => "EgJ4AQ%3D%3D",
|
||||
Invidious::Search::Filters::Features::VR180 => "EgPQAQE%3D",
|
||||
Invidious::Search::Filters::Features::ThreeD => "EgI4AQ%3D%3D",
|
||||
Invidious::Search::Filters::Features::HDR => "EgPIAQE%3D",
|
||||
Invidious::Search::Filters::Features::Location => "EgO4AQE%3D",
|
||||
Invidious::Search::Filters::Features::Purchased => "EgJIAQ%3D%3D",
|
||||
}
|
||||
|
||||
SORT_FILTERS = {
|
||||
Invidious::Search::Filters::Sort::Relevance => "",
|
||||
Invidious::Search::Filters::Sort::Date => "CAI%3D",
|
||||
Invidious::Search::Filters::Sort::Views => "CAM%3D",
|
||||
Invidious::Search::Filters::Sort::Rating => "CAE%3D",
|
||||
}
|
||||
|
||||
Spectator.describe Invidious::Search::Filters do
|
||||
# -------------------
|
||||
# Encode YT params
|
||||
# -------------------
|
||||
|
||||
describe "#to_yt_params" do
|
||||
sample DATE_FILTERS do |value, result|
|
||||
it "Encodes upload date filter '#{value}'" do
|
||||
expect(described_class.new(date: value).to_yt_params).to eq(result)
|
||||
end
|
||||
end
|
||||
|
||||
sample TYPE_FILTERS do |value, result|
|
||||
it "Encodes content type filter '#{value}'" do
|
||||
expect(described_class.new(type: value).to_yt_params).to eq(result)
|
||||
end
|
||||
end
|
||||
|
||||
sample DURATION_FILTERS do |value, result|
|
||||
it "Encodes duration filter '#{value}'" do
|
||||
expect(described_class.new(duration: value).to_yt_params).to eq(result)
|
||||
end
|
||||
end
|
||||
|
||||
sample FEATURE_FILTERS do |value, result|
|
||||
it "Encodes feature filter '#{value}'" do
|
||||
expect(described_class.new(features: value).to_yt_params).to eq(result)
|
||||
end
|
||||
end
|
||||
|
||||
sample SORT_FILTERS do |value, result|
|
||||
it "Encodes sort filter '#{value}'" do
|
||||
expect(described_class.new(sort: value).to_yt_params).to eq(result)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# -------------------
|
||||
# Decode YT params
|
||||
# -------------------
|
||||
|
||||
describe "#from_yt_params" do
|
||||
sample DATE_FILTERS do |value, encoded|
|
||||
it "Decodes upload date filter '#{value}'" do
|
||||
params = HTTP::Params.parse("sp=#{encoded}")
|
||||
|
||||
expect(described_class.from_yt_params(params))
|
||||
.to eq(described_class.new(date: value))
|
||||
end
|
||||
end
|
||||
|
||||
sample TYPE_FILTERS do |value, encoded|
|
||||
it "Decodes content type filter '#{value}'" do
|
||||
params = HTTP::Params.parse("sp=#{encoded}")
|
||||
|
||||
expect(described_class.from_yt_params(params))
|
||||
.to eq(described_class.new(type: value))
|
||||
end
|
||||
end
|
||||
|
||||
sample DURATION_FILTERS do |value, encoded|
|
||||
it "Decodes duration filter '#{value}'" do
|
||||
params = HTTP::Params.parse("sp=#{encoded}")
|
||||
|
||||
expect(described_class.from_yt_params(params))
|
||||
.to eq(described_class.new(duration: value))
|
||||
end
|
||||
end
|
||||
|
||||
sample FEATURE_FILTERS do |value, encoded|
|
||||
it "Decodes feature filter '#{value}'" do
|
||||
params = HTTP::Params.parse("sp=#{encoded}")
|
||||
|
||||
expect(described_class.from_yt_params(params))
|
||||
.to eq(described_class.new(features: value))
|
||||
end
|
||||
end
|
||||
|
||||
sample SORT_FILTERS do |value, encoded|
|
||||
it "Decodes sort filter '#{value}'" do
|
||||
params = HTTP::Params.parse("sp=#{encoded}")
|
||||
|
||||
expect(described_class.from_yt_params(params))
|
||||
.to eq(described_class.new(sort: value))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
113
spec/invidious/videos/scheduled_live_extract_spec.cr
Normal file
113
spec/invidious/videos/scheduled_live_extract_spec.cr
Normal file
@@ -0,0 +1,113 @@
|
||||
require "../../parsers_helper.cr"
|
||||
|
||||
Spectator.describe Invidious::Hashtag do
|
||||
it "parses scheduled livestreams data (test 1)" do
|
||||
# Enable mock
|
||||
_player = load_mock("video/scheduled_live_nintendo.player")
|
||||
_next = load_mock("video/scheduled_live_nintendo.next")
|
||||
|
||||
raw_data = _player.merge!(_next)
|
||||
info = parse_video_info("QMGibBzTu0g", raw_data)
|
||||
|
||||
# Some basic verifications
|
||||
expect(typeof(info)).to eq(Hash(String, JSON::Any))
|
||||
|
||||
expect(info["shortDescription"].as_s).to eq(
|
||||
"Tune in on 6/22 at 7 a.m. PT for a livestreamed Xenoblade Chronicles 3 Direct presentation featuring roughly 20 minutes of information about the upcoming RPG adventure for Nintendo Switch."
|
||||
)
|
||||
expect(info["descriptionHtml"].as_s).to eq(
|
||||
"Tune in on 6/22 at 7 a.m. PT for a livestreamed Xenoblade Chronicles 3 Direct presentation featuring roughly 20 minutes of information about the upcoming RPG adventure for Nintendo Switch."
|
||||
)
|
||||
|
||||
expect(info["likes"].as_i).to eq(2_283)
|
||||
|
||||
expect(info["genre"].as_s).to eq("Gaming")
|
||||
expect(info["genreUrl"].raw).to be_nil
|
||||
expect(info["genreUcid"].as_s).to be_empty
|
||||
expect(info["license"].as_s).to be_empty
|
||||
|
||||
expect(info["authorThumbnail"].as_s).to eq(
|
||||
"https://yt3.ggpht.com/ytc/AKedOLTt4vtjREUUNdHlyu9c4gtJjG90M9jQheRlLKy44A=s48-c-k-c0x00ffffff-no-rj"
|
||||
)
|
||||
|
||||
expect(info["authorVerified"].as_bool).to be_true
|
||||
expect(info["subCountText"].as_s).to eq("8.5M")
|
||||
|
||||
expect(info["relatedVideos"].as_a.size).to eq(20)
|
||||
|
||||
# related video #1
|
||||
expect(info["relatedVideos"][3]["id"].as_s).to eq("a-SN3lLIUEo")
|
||||
expect(info["relatedVideos"][3]["author"].as_s).to eq("Nintendo")
|
||||
expect(info["relatedVideos"][3]["ucid"].as_s).to eq("UCGIY_O-8vW4rfX98KlMkvRg")
|
||||
expect(info["relatedVideos"][3]["view_count"].as_s).to eq("147796")
|
||||
expect(info["relatedVideos"][3]["short_view_count"].as_s).to eq("147K")
|
||||
expect(info["relatedVideos"][3]["author_verified"].as_s).to eq("true")
|
||||
|
||||
# Related video #2
|
||||
expect(info["relatedVideos"][16]["id"].as_s).to eq("l_uC1jFK0lo")
|
||||
expect(info["relatedVideos"][16]["author"].as_s).to eq("Nintendo")
|
||||
expect(info["relatedVideos"][16]["ucid"].as_s).to eq("UCGIY_O-8vW4rfX98KlMkvRg")
|
||||
expect(info["relatedVideos"][16]["view_count"].as_s).to eq("53510")
|
||||
expect(info["relatedVideos"][16]["short_view_count"].as_s).to eq("53K")
|
||||
expect(info["relatedVideos"][16]["author_verified"].as_s).to eq("true")
|
||||
end
|
||||
|
||||
it "parses scheduled livestreams data (test 2)" do
|
||||
# Enable mock
|
||||
_player = load_mock("video/scheduled_live_PBD-Podcast.player")
|
||||
_next = load_mock("video/scheduled_live_PBD-Podcast.next")
|
||||
|
||||
raw_data = _player.merge!(_next)
|
||||
info = parse_video_info("RG0cjYbXxME", raw_data)
|
||||
|
||||
# Some basic verifications
|
||||
expect(typeof(info)).to eq(Hash(String, JSON::Any))
|
||||
|
||||
expect(info["shortDescription"].as_s).to start_with(
|
||||
<<-TXT
|
||||
PBD Podcast Episode 171. In this episode, Patrick Bet-David is joined by Dr. Patrick Moore and Adam Sosnick.
|
||||
|
||||
Join the channel to get exclusive access to perks: https://bit.ly/3Q9rSQL
|
||||
TXT
|
||||
)
|
||||
expect(info["descriptionHtml"].as_s).to start_with(
|
||||
<<-TXT
|
||||
PBD Podcast Episode 171. In this episode, Patrick Bet-David is joined by Dr. Patrick Moore and Adam Sosnick.
|
||||
|
||||
Join the channel to get exclusive access to perks: <a href="https://bit.ly/3Q9rSQL">bit.ly/3Q9rSQL</a>
|
||||
TXT
|
||||
)
|
||||
|
||||
expect(info["likes"].as_i).to eq(22)
|
||||
|
||||
expect(info["genre"].as_s).to eq("Entertainment")
|
||||
expect(info["genreUrl"].raw).to be_nil
|
||||
expect(info["genreUcid"].as_s).to be_empty
|
||||
expect(info["license"].as_s).to be_empty
|
||||
|
||||
expect(info["authorThumbnail"].as_s).to eq(
|
||||
"https://yt3.ggpht.com/61ArDiQshJrvSXcGLhpFfIO3hlMabe2fksitcf6oGob0Mdr5gztdkXxRljICUodL4iuTSrtxW4A=s48-c-k-c0x00ffffff-no-rj"
|
||||
)
|
||||
|
||||
expect(info["authorVerified"].as_bool).to be_false
|
||||
expect(info["subCountText"].as_s).to eq("227K")
|
||||
|
||||
expect(info["relatedVideos"].as_a.size).to eq(20)
|
||||
|
||||
# related video #1
|
||||
expect(info["relatedVideos"][2]["id"]).to eq("La9oLLoI5Rc")
|
||||
expect(info["relatedVideos"][2]["author"]).to eq("Tom Bilyeu")
|
||||
expect(info["relatedVideos"][2]["ucid"]).to eq("UCnYMOamNKLGVlJgRUbamveA")
|
||||
expect(info["relatedVideos"][2]["view_count"]).to eq("13329149")
|
||||
expect(info["relatedVideos"][2]["short_view_count"]).to eq("13M")
|
||||
expect(info["relatedVideos"][2]["author_verified"]).to eq("true")
|
||||
|
||||
# Related video #2
|
||||
expect(info["relatedVideos"][9]["id"]).to eq("IQ_4fvpzYuA")
|
||||
expect(info["relatedVideos"][9]["author"]).to eq("Business Today")
|
||||
expect(info["relatedVideos"][9]["ucid"]).to eq("UCaPHWiExfUWaKsUtENLCv5w")
|
||||
expect(info["relatedVideos"][9]["view_count"]).to eq("26432")
|
||||
expect(info["relatedVideos"][9]["short_view_count"]).to eq("26K")
|
||||
expect(info["relatedVideos"][9]["author_verified"]).to eq("true")
|
||||
end
|
||||
end
|
||||
34
spec/parsers_helper.cr
Normal file
34
spec/parsers_helper.cr
Normal file
@@ -0,0 +1,34 @@
|
||||
require "db"
|
||||
require "json"
|
||||
require "kemal"
|
||||
|
||||
require "protodec/utils"
|
||||
|
||||
require "spectator"
|
||||
|
||||
require "../src/invidious/exceptions"
|
||||
require "../src/invidious/helpers/macros"
|
||||
require "../src/invidious/helpers/logger"
|
||||
require "../src/invidious/helpers/utils"
|
||||
|
||||
require "../src/invidious/videos"
|
||||
require "../src/invidious/comments"
|
||||
|
||||
require "../src/invidious/helpers/serialized_yt_data"
|
||||
require "../src/invidious/yt_backend/extractors"
|
||||
require "../src/invidious/yt_backend/extractors_utils"
|
||||
|
||||
OUTPUT = File.open(File::NULL, "w")
|
||||
LOGGER = Invidious::LogHandler.new(OUTPUT, LogLevel::Off)
|
||||
|
||||
def load_mock(file) : Hash(String, JSON::Any)
|
||||
file = File.join(__DIR__, "..", "mocks", file + ".json")
|
||||
content = File.read(file)
|
||||
|
||||
return JSON.parse(content).as_h
|
||||
end
|
||||
|
||||
Spectator.configure do |config|
|
||||
config.fail_blank
|
||||
config.randomize
|
||||
end
|
||||
@@ -8,7 +8,7 @@ require "../src/invidious/channels/*"
|
||||
require "../src/invidious/videos"
|
||||
require "../src/invidious/comments"
|
||||
require "../src/invidious/playlists"
|
||||
require "../src/invidious/search"
|
||||
require "../src/invidious/search/ctoken"
|
||||
require "../src/invidious/trending"
|
||||
require "spectator"
|
||||
|
||||
|
||||
16
src/ext/kemal_content_for.cr
Normal file
16
src/ext/kemal_content_for.cr
Normal file
@@ -0,0 +1,16 @@
|
||||
# Overrides for Kemal's `content_for` macro in order to keep using
|
||||
# kilt as it was before Kemal v1.1.1 (Kemal PR #618).
|
||||
|
||||
require "kemal"
|
||||
require "kilt"
|
||||
|
||||
macro content_for(key, file = __FILE__)
|
||||
%proc = ->() {
|
||||
__kilt_io__ = IO::Memory.new
|
||||
{{ yield }}
|
||||
__kilt_io__.to_s
|
||||
}
|
||||
|
||||
CONTENT_FOR_BLOCKS[{{key}}] = Tuple.new {{file}}, %proc
|
||||
nil
|
||||
end
|
||||
@@ -111,7 +111,7 @@ module Kemal
|
||||
if @fallthrough
|
||||
call_next(context)
|
||||
else
|
||||
context.response.status_code = 405
|
||||
context.response.status = HTTP::Status::METHOD_NOT_ALLOWED
|
||||
context.response.headers.add("Allow", "GET, HEAD")
|
||||
end
|
||||
return
|
||||
@@ -124,7 +124,7 @@ module Kemal
|
||||
# File path cannot contains '\0' (NUL) because all filesystem I know
|
||||
# don't accept '\0' character as file name.
|
||||
if request_path.includes? '\0'
|
||||
context.response.status_code = 400
|
||||
context.response.status = HTTP::Status::BAD_REQUEST
|
||||
return
|
||||
end
|
||||
|
||||
@@ -143,13 +143,15 @@ module Kemal
|
||||
add_cache_headers(context.response.headers, last_modified)
|
||||
|
||||
if cache_request?(context, last_modified)
|
||||
context.response.status_code = 304
|
||||
context.response.status = HTTP::Status::NOT_MODIFIED
|
||||
return
|
||||
end
|
||||
|
||||
send_file(context, file_path, file[:data], file[:filestat])
|
||||
else
|
||||
is_dir = Dir.exists? file_path
|
||||
file_info = File.info?(file_path)
|
||||
is_dir = file_info.try &.directory? || false
|
||||
is_file = file_info.try &.file? || false
|
||||
|
||||
if request_path != expanded_path
|
||||
redirect_to context, expanded_path
|
||||
@@ -157,19 +159,21 @@ module Kemal
|
||||
redirect_to context, expanded_path + '/'
|
||||
end
|
||||
|
||||
if Dir.exists?(file_path)
|
||||
return call_next(context) if file_info.nil?
|
||||
|
||||
if is_dir
|
||||
if config.is_a?(Hash) && config["dir_listing"] == true
|
||||
context.response.content_type = "text/html"
|
||||
directory_listing(context.response, request_path, file_path)
|
||||
else
|
||||
call_next(context)
|
||||
end
|
||||
elsif File.exists?(file_path)
|
||||
last_modified = modification_time(file_path)
|
||||
elsif is_file
|
||||
last_modified = file_info.modification_time
|
||||
add_cache_headers(context.response.headers, last_modified)
|
||||
|
||||
if cache_request?(context, last_modified)
|
||||
context.response.status_code = 304
|
||||
context.response.status = HTTP::Status::NOT_MODIFIED
|
||||
return
|
||||
end
|
||||
|
||||
@@ -177,14 +181,12 @@ module Kemal
|
||||
data = Bytes.new(size)
|
||||
File.open(file_path, &.read(data))
|
||||
|
||||
filestat = File.info(file_path)
|
||||
|
||||
@cached_files[file_path] = {data: data, filestat: filestat}
|
||||
send_file(context, file_path, data, filestat)
|
||||
@cached_files[file_path] = {data: data, filestat: file_info}
|
||||
send_file(context, file_path, data, file_info)
|
||||
else
|
||||
send_file(context, file_path)
|
||||
end
|
||||
else
|
||||
else # Not a normal file (FIFO/device/socket)
|
||||
call_next(context)
|
||||
end
|
||||
end
|
||||
312
src/invidious.cr
312
src/invidious.cr
@@ -16,7 +16,13 @@
|
||||
|
||||
require "digest/md5"
|
||||
require "file_utils"
|
||||
|
||||
# Require kemal, kilt, then our own overrides
|
||||
require "kemal"
|
||||
require "kilt"
|
||||
require "./ext/kemal_content_for.cr"
|
||||
require "./ext/kemal_static_file_handler.cr"
|
||||
|
||||
require "athena-negotiation"
|
||||
require "openssl/hmac"
|
||||
require "option_parser"
|
||||
@@ -27,6 +33,7 @@ require "compress/zip"
|
||||
require "protodec/utils"
|
||||
|
||||
require "./invidious/database/*"
|
||||
require "./invidious/database/migrations/*"
|
||||
require "./invidious/helpers/*"
|
||||
require "./invidious/yt_backend/*"
|
||||
require "./invidious/frontend/*"
|
||||
@@ -34,6 +41,7 @@ require "./invidious/frontend/*"
|
||||
require "./invidious/*"
|
||||
require "./invidious/channels/*"
|
||||
require "./invidious/user/*"
|
||||
require "./invidious/search/*"
|
||||
require "./invidious/routes/**"
|
||||
require "./invidious/jobs/**"
|
||||
|
||||
@@ -102,6 +110,10 @@ Kemal.config.extra_options do |parser|
|
||||
puts SOFTWARE.to_pretty_json
|
||||
exit
|
||||
end
|
||||
parser.on("--migrate", "Run any migrations (beta, use at your own risk!!") do
|
||||
Invidious::Database::Migrator.new(PG_DB).migrate
|
||||
exit
|
||||
end
|
||||
end
|
||||
|
||||
Kemal::CLI.new ARGV
|
||||
@@ -121,12 +133,13 @@ Invidious::Database.check_integrity(CONFIG)
|
||||
# Running the script by itself would show some colorful feedback while this doesn't.
|
||||
# Perhaps we should just move the script to runtime in order to get that feedback?
|
||||
|
||||
{% puts "\nChecking player dependencies...\n" %}
|
||||
{% puts "\nChecking player dependencies, this may take more than 20 minutes... If it is stuck, check your internet connection.\n" %}
|
||||
{% if flag?(:minified_player_dependencies) %}
|
||||
{% puts run("../scripts/fetch-player-dependencies.cr", "--minified").stringify %}
|
||||
{% else %}
|
||||
{% puts run("../scripts/fetch-player-dependencies.cr").stringify %}
|
||||
{% end %}
|
||||
{% puts "\nDone checking player dependencies, now compiling Invidious...\n" %}
|
||||
{% end %}
|
||||
|
||||
# Start jobs
|
||||
@@ -165,304 +178,19 @@ def popular_videos
|
||||
Invidious::Jobs::PullPopularVideosJob::POPULAR_VIDEOS.get
|
||||
end
|
||||
|
||||
# Routing
|
||||
|
||||
before_all do |env|
|
||||
preferences = Preferences.from_json("{}")
|
||||
|
||||
begin
|
||||
if prefs_cookie = env.request.cookies["PREFS"]?
|
||||
preferences = Preferences.from_json(URI.decode_www_form(prefs_cookie.value))
|
||||
else
|
||||
if language_header = env.request.headers["Accept-Language"]?
|
||||
if language = ANG.language_negotiator.best(language_header, LOCALES.keys)
|
||||
preferences.locale = language.header
|
||||
end
|
||||
end
|
||||
end
|
||||
rescue
|
||||
preferences = Preferences.from_json("{}")
|
||||
end
|
||||
|
||||
env.set "preferences", preferences
|
||||
env.response.headers["X-XSS-Protection"] = "1; mode=block"
|
||||
env.response.headers["X-Content-Type-Options"] = "nosniff"
|
||||
|
||||
# Allow media resources to be loaded from google servers
|
||||
# TODO: check if *.youtube.com can be removed
|
||||
if CONFIG.disabled?("local") || !preferences.local
|
||||
extra_media_csp = " https://*.googlevideo.com:443 https://*.youtube.com:443"
|
||||
else
|
||||
extra_media_csp = ""
|
||||
end
|
||||
|
||||
# Only allow the pages at /embed/* to be embedded
|
||||
if env.request.resource.starts_with?("/embed")
|
||||
frame_ancestors = "'self' http: https:"
|
||||
else
|
||||
frame_ancestors = "'none'"
|
||||
end
|
||||
|
||||
# TODO: Remove style-src's 'unsafe-inline', requires to remove all
|
||||
# inline styles (<style> [..] </style>, style=" [..] ")
|
||||
env.response.headers["Content-Security-Policy"] = {
|
||||
"default-src 'none'",
|
||||
"script-src 'self'",
|
||||
"style-src 'self' 'unsafe-inline'",
|
||||
"img-src 'self' data:",
|
||||
"font-src 'self' data:",
|
||||
"connect-src 'self'",
|
||||
"manifest-src 'self'",
|
||||
"media-src 'self' blob:" + extra_media_csp,
|
||||
"child-src 'self' blob:",
|
||||
"frame-src 'self'",
|
||||
"frame-ancestors " + frame_ancestors,
|
||||
}.join("; ")
|
||||
|
||||
env.response.headers["Referrer-Policy"] = "same-origin"
|
||||
|
||||
# Ask the chrom*-based browsers to disable FLoC
|
||||
# See: https://blog.runcloud.io/google-floc/
|
||||
env.response.headers["Permissions-Policy"] = "interest-cohort=()"
|
||||
|
||||
if (Kemal.config.ssl || CONFIG.https_only) && CONFIG.hsts
|
||||
env.response.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains; preload"
|
||||
end
|
||||
|
||||
next if {
|
||||
"/sb/",
|
||||
"/vi/",
|
||||
"/s_p/",
|
||||
"/yts/",
|
||||
"/ggpht/",
|
||||
"/api/manifest/",
|
||||
"/videoplayback",
|
||||
"/latest_version",
|
||||
"/download",
|
||||
}.any? { |r| env.request.resource.starts_with? r }
|
||||
|
||||
if env.request.cookies.has_key? "SID"
|
||||
sid = env.request.cookies["SID"].value
|
||||
|
||||
if sid.starts_with? "v1:"
|
||||
raise "Cannot use token as SID"
|
||||
end
|
||||
|
||||
# Invidious users only have SID
|
||||
if !env.request.cookies.has_key? "SSID"
|
||||
if email = Invidious::Database::SessionIDs.select_email(sid)
|
||||
user = Invidious::Database::Users.select!(email: email)
|
||||
csrf_token = generate_response(sid, {
|
||||
":authorize_token",
|
||||
":playlist_ajax",
|
||||
":signout",
|
||||
":subscription_ajax",
|
||||
":token_ajax",
|
||||
":watch_ajax",
|
||||
}, HMAC_KEY, 1.week)
|
||||
|
||||
preferences = user.preferences
|
||||
env.set "preferences", preferences
|
||||
|
||||
env.set "sid", sid
|
||||
env.set "csrf_token", csrf_token
|
||||
env.set "user", user
|
||||
end
|
||||
else
|
||||
headers = HTTP::Headers.new
|
||||
headers["Cookie"] = env.request.headers["Cookie"]
|
||||
|
||||
begin
|
||||
user, sid = get_user(sid, headers, false)
|
||||
csrf_token = generate_response(sid, {
|
||||
":authorize_token",
|
||||
":playlist_ajax",
|
||||
":signout",
|
||||
":subscription_ajax",
|
||||
":token_ajax",
|
||||
":watch_ajax",
|
||||
}, HMAC_KEY, 1.week)
|
||||
|
||||
preferences = user.preferences
|
||||
env.set "preferences", preferences
|
||||
|
||||
env.set "sid", sid
|
||||
env.set "csrf_token", csrf_token
|
||||
env.set "user", user
|
||||
rescue ex
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
dark_mode = convert_theme(env.params.query["dark_mode"]?) || preferences.dark_mode.to_s
|
||||
thin_mode = env.params.query["thin_mode"]? || preferences.thin_mode.to_s
|
||||
thin_mode = thin_mode == "true"
|
||||
locale = env.params.query["hl"]? || preferences.locale
|
||||
|
||||
preferences.dark_mode = dark_mode
|
||||
preferences.thin_mode = thin_mode
|
||||
preferences.locale = locale
|
||||
env.set "preferences", preferences
|
||||
|
||||
current_page = env.request.path
|
||||
if env.request.query
|
||||
query = HTTP::Params.parse(env.request.query.not_nil!)
|
||||
|
||||
if query["referer"]?
|
||||
query["referer"] = get_referer(env, "/")
|
||||
end
|
||||
|
||||
current_page += "?#{query}"
|
||||
end
|
||||
|
||||
env.set "current_page", URI.encode_www_form(current_page)
|
||||
Invidious::Routes::BeforeAll.handle(env)
|
||||
end
|
||||
|
||||
{% unless flag?(:api_only) %}
|
||||
Invidious::Routing.get "/", Invidious::Routes::Misc, :home
|
||||
Invidious::Routing.get "/privacy", Invidious::Routes::Misc, :privacy
|
||||
Invidious::Routing.get "/licenses", Invidious::Routes::Misc, :licenses
|
||||
|
||||
Invidious::Routing.get "/channel/:ucid", Invidious::Routes::Channels, :home
|
||||
Invidious::Routing.get "/channel/:ucid/home", Invidious::Routes::Channels, :home
|
||||
Invidious::Routing.get "/channel/:ucid/videos", Invidious::Routes::Channels, :videos
|
||||
Invidious::Routing.get "/channel/:ucid/playlists", Invidious::Routes::Channels, :playlists
|
||||
Invidious::Routing.get "/channel/:ucid/community", Invidious::Routes::Channels, :community
|
||||
Invidious::Routing.get "/channel/:ucid/about", Invidious::Routes::Channels, :about
|
||||
Invidious::Routing.get "/channel/:ucid/live", Invidious::Routes::Channels, :live
|
||||
Invidious::Routing.get "/user/:user/live", Invidious::Routes::Channels, :live
|
||||
Invidious::Routing.get "/c/:user/live", Invidious::Routes::Channels, :live
|
||||
|
||||
["", "/videos", "/playlists", "/community", "/about"].each do |path|
|
||||
# /c/LinusTechTips
|
||||
Invidious::Routing.get "/c/:user#{path}", Invidious::Routes::Channels, :brand_redirect
|
||||
# /user/linustechtips | Not always the same as /c/
|
||||
Invidious::Routing.get "/user/:user#{path}", Invidious::Routes::Channels, :brand_redirect
|
||||
# /attribution_link?a=anything&u=/channel/UCZYTClx2T1of7BRZ86-8fow
|
||||
Invidious::Routing.get "/attribution_link#{path}", Invidious::Routes::Channels, :brand_redirect
|
||||
# /profile?user=linustechtips
|
||||
Invidious::Routing.get "/profile/#{path}", Invidious::Routes::Channels, :profile
|
||||
end
|
||||
|
||||
Invidious::Routing.get "/watch", Invidious::Routes::Watch, :handle
|
||||
Invidious::Routing.post "/watch_ajax", Invidious::Routes::Watch, :mark_watched
|
||||
Invidious::Routing.get "/watch/:id", Invidious::Routes::Watch, :redirect
|
||||
Invidious::Routing.get "/shorts/:id", Invidious::Routes::Watch, :redirect
|
||||
Invidious::Routing.get "/clip/:clip", Invidious::Routes::Watch, :clip
|
||||
Invidious::Routing.get "/w/:id", Invidious::Routes::Watch, :redirect
|
||||
Invidious::Routing.get "/v/:id", Invidious::Routes::Watch, :redirect
|
||||
Invidious::Routing.get "/e/:id", Invidious::Routes::Watch, :redirect
|
||||
Invidious::Routing.get "/redirect", Invidious::Routes::Misc, :cross_instance_redirect
|
||||
|
||||
Invidious::Routing.post "/download", Invidious::Routes::Watch, :download
|
||||
|
||||
Invidious::Routing.get "/embed/", Invidious::Routes::Embed, :redirect
|
||||
Invidious::Routing.get "/embed/:id", Invidious::Routes::Embed, :show
|
||||
|
||||
Invidious::Routing.get "/create_playlist", Invidious::Routes::Playlists, :new
|
||||
Invidious::Routing.post "/create_playlist", Invidious::Routes::Playlists, :create
|
||||
Invidious::Routing.get "/subscribe_playlist", Invidious::Routes::Playlists, :subscribe
|
||||
Invidious::Routing.get "/delete_playlist", Invidious::Routes::Playlists, :delete_page
|
||||
Invidious::Routing.post "/delete_playlist", Invidious::Routes::Playlists, :delete
|
||||
Invidious::Routing.get "/edit_playlist", Invidious::Routes::Playlists, :edit
|
||||
Invidious::Routing.post "/edit_playlist", Invidious::Routes::Playlists, :update
|
||||
Invidious::Routing.get "/add_playlist_items", Invidious::Routes::Playlists, :add_playlist_items_page
|
||||
Invidious::Routing.post "/playlist_ajax", Invidious::Routes::Playlists, :playlist_ajax
|
||||
Invidious::Routing.get "/playlist", Invidious::Routes::Playlists, :show
|
||||
Invidious::Routing.get "/mix", Invidious::Routes::Playlists, :mix
|
||||
Invidious::Routing.get "/watch_videos", Invidious::Routes::Playlists, :watch_videos
|
||||
|
||||
Invidious::Routing.get "/opensearch.xml", Invidious::Routes::Search, :opensearch
|
||||
Invidious::Routing.get "/results", Invidious::Routes::Search, :results
|
||||
Invidious::Routing.get "/search", Invidious::Routes::Search, :search
|
||||
|
||||
# User routes
|
||||
define_user_routes()
|
||||
|
||||
# Feeds
|
||||
Invidious::Routing.get "/view_all_playlists", Invidious::Routes::Feeds, :view_all_playlists_redirect
|
||||
Invidious::Routing.get "/feed/playlists", Invidious::Routes::Feeds, :playlists
|
||||
Invidious::Routing.get "/feed/popular", Invidious::Routes::Feeds, :popular
|
||||
Invidious::Routing.get "/feed/trending", Invidious::Routes::Feeds, :trending
|
||||
Invidious::Routing.get "/feed/subscriptions", Invidious::Routes::Feeds, :subscriptions
|
||||
Invidious::Routing.get "/feed/history", Invidious::Routes::Feeds, :history
|
||||
|
||||
# RSS Feeds
|
||||
Invidious::Routing.get "/feed/channel/:ucid", Invidious::Routes::Feeds, :rss_channel
|
||||
Invidious::Routing.get "/feed/private", Invidious::Routes::Feeds, :rss_private
|
||||
Invidious::Routing.get "/feed/playlist/:plid", Invidious::Routes::Feeds, :rss_playlist
|
||||
Invidious::Routing.get "/feeds/videos.xml", Invidious::Routes::Feeds, :rss_videos
|
||||
|
||||
# Support push notifications via PubSubHubbub
|
||||
Invidious::Routing.get "/feed/webhook/:token", Invidious::Routes::Feeds, :push_notifications_get
|
||||
Invidious::Routing.post "/feed/webhook/:token", Invidious::Routes::Feeds, :push_notifications_post
|
||||
|
||||
Invidious::Routing.get "/modify_notifications", Invidious::Routes::Notifications, :modify
|
||||
|
||||
Invidious::Routing.post "/subscription_ajax", Invidious::Routes::Subscriptions, :toggle_subscription
|
||||
Invidious::Routing.get "/subscription_manager", Invidious::Routes::Subscriptions, :subscription_manager
|
||||
{% end %}
|
||||
|
||||
Invidious::Routing.get "/ggpht/*", Invidious::Routes::Images, :ggpht
|
||||
Invidious::Routing.options "/sb/:authority/:id/:storyboard/:index", Invidious::Routes::Images, :options_storyboard
|
||||
Invidious::Routing.get "/sb/:authority/:id/:storyboard/:index", Invidious::Routes::Images, :get_storyboard
|
||||
Invidious::Routing.get "/s_p/:id/:name", Invidious::Routes::Images, :s_p_image
|
||||
Invidious::Routing.get "/yts/img/:name", Invidious::Routes::Images, :yts_image
|
||||
Invidious::Routing.get "/vi/:id/:name", Invidious::Routes::Images, :thumbnails
|
||||
|
||||
# API routes (macro)
|
||||
define_v1_api_routes()
|
||||
|
||||
# Video playback (macros)
|
||||
define_api_manifest_routes()
|
||||
define_video_playback_routes()
|
||||
Invidious::Routing.register_all
|
||||
|
||||
error 404 do |env|
|
||||
if md = env.request.path.match(/^\/(?<id>([a-zA-Z0-9_-]{11})|(\w+))$/)
|
||||
item = md["id"]
|
||||
|
||||
# Check if item is branding URL e.g. https://youtube.com/gaming
|
||||
response = YT_POOL.client &.get("/#{item}")
|
||||
|
||||
if response.status_code == 301
|
||||
response = YT_POOL.client &.get(URI.parse(response.headers["Location"]).request_target)
|
||||
end
|
||||
|
||||
if response.body.empty?
|
||||
env.response.headers["Location"] = "/"
|
||||
halt env, status_code: 302
|
||||
end
|
||||
|
||||
html = XML.parse_html(response.body)
|
||||
ucid = html.xpath_node(%q(//link[@rel="canonical"])).try &.["href"].split("/")[-1]
|
||||
|
||||
if ucid
|
||||
env.response.headers["Location"] = "/channel/#{ucid}"
|
||||
halt env, status_code: 302
|
||||
end
|
||||
|
||||
params = [] of String
|
||||
env.params.query.each do |k, v|
|
||||
params << "#{k}=#{v}"
|
||||
end
|
||||
params = params.join("&")
|
||||
|
||||
url = "/watch?v=#{item}"
|
||||
if !params.empty?
|
||||
url += "&#{params}"
|
||||
end
|
||||
|
||||
# Check if item is video ID
|
||||
if item.match(/^[a-zA-Z0-9_-]{11}$/) && YT_POOL.client &.head("/watch?v=#{item}").status_code != 404
|
||||
env.response.headers["Location"] = url
|
||||
halt env, status_code: 302
|
||||
end
|
||||
end
|
||||
|
||||
env.response.headers["Location"] = "/"
|
||||
halt env, status_code: 302
|
||||
Invidious::Routes::ErrorRoutes.error_404(env)
|
||||
end
|
||||
|
||||
error 500 do |env, ex|
|
||||
locale = env.get("preferences").as(Preferences).locale
|
||||
error_template(500, ex)
|
||||
end
|
||||
|
||||
@@ -470,6 +198,8 @@ static_headers do |response|
|
||||
response.headers.add("Cache-Control", "max-age=2629800")
|
||||
end
|
||||
|
||||
# Init Kemal
|
||||
|
||||
public_folder "assets"
|
||||
|
||||
Kemal.config.powered_by_header = false
|
||||
|
||||
@@ -6,13 +6,15 @@ record AboutChannel,
|
||||
author_url : String,
|
||||
author_thumbnail : String,
|
||||
banner : String?,
|
||||
description : String,
|
||||
description_html : String,
|
||||
total_views : Int64,
|
||||
sub_count : Int32,
|
||||
joined : Time,
|
||||
is_family_friendly : Bool,
|
||||
allowed_regions : Array(String),
|
||||
tabs : Array(String)
|
||||
tabs : Array(String),
|
||||
verified : Bool
|
||||
|
||||
record AboutRelatedChannel,
|
||||
ucid : String,
|
||||
@@ -29,7 +31,12 @@ def get_about_info(ucid, locale) : AboutChannel
|
||||
end
|
||||
|
||||
if initdata.dig?("alerts", 0, "alertRenderer", "type") == "ERROR"
|
||||
raise InfoException.new(initdata["alerts"][0]["alertRenderer"]["text"]["simpleText"].as_s)
|
||||
error_message = initdata["alerts"][0]["alertRenderer"]["text"]["simpleText"].as_s
|
||||
if error_message == "This channel does not exist."
|
||||
raise NotFoundException.new(error_message)
|
||||
else
|
||||
raise InfoException.new(error_message)
|
||||
end
|
||||
end
|
||||
|
||||
if browse_endpoint = initdata["onResponseReceivedActions"]?.try &.[0]?.try &.["navigateAction"]?.try &.["endpoint"]?.try &.["browseEndpoint"]?
|
||||
@@ -51,15 +58,12 @@ def get_about_info(ucid, locale) : AboutChannel
|
||||
banners = initdata["header"]["interactiveTabbedHeaderRenderer"]?.try &.["banner"]?.try &.["thumbnails"]?
|
||||
banner = banners.try &.[-1]?.try &.["url"].as_s?
|
||||
|
||||
description = initdata["header"]["interactiveTabbedHeaderRenderer"]["description"]["simpleText"].as_s
|
||||
description_html = HTML.escape(description)
|
||||
|
||||
is_family_friendly = initdata["microformat"]["microformatDataRenderer"]["familySafe"].as_bool
|
||||
allowed_regions = initdata["microformat"]["microformatDataRenderer"]["availableCountries"].as_a.map(&.as_s)
|
||||
description_node = initdata["header"]["interactiveTabbedHeaderRenderer"]["description"]
|
||||
else
|
||||
author = initdata["metadata"]["channelMetadataRenderer"]["title"].as_s
|
||||
author_url = initdata["metadata"]["channelMetadataRenderer"]["channelUrl"].as_s
|
||||
author_thumbnail = initdata["metadata"]["channelMetadataRenderer"]["avatar"]["thumbnails"][0]["url"].as_s
|
||||
author_verified = has_verified_badge?(initdata.dig?("header", "c4TabbedHeaderRenderer", "badges"))
|
||||
|
||||
ucid = initdata["metadata"]["channelMetadataRenderer"]["externalId"].as_s
|
||||
|
||||
@@ -71,11 +75,26 @@ def get_about_info(ucid, locale) : AboutChannel
|
||||
# banner = nil
|
||||
# end
|
||||
|
||||
description = initdata["metadata"]["channelMetadataRenderer"]?.try &.["description"]?.try &.as_s? || ""
|
||||
description_html = HTML.escape(description)
|
||||
description_node = initdata["metadata"]["channelMetadataRenderer"]?.try &.["description"]?
|
||||
end
|
||||
|
||||
is_family_friendly = initdata["microformat"]["microformatDataRenderer"]["familySafe"].as_bool
|
||||
allowed_regions = initdata["microformat"]["microformatDataRenderer"]["availableCountries"].as_a.map(&.as_s)
|
||||
is_family_friendly = initdata["microformat"]["microformatDataRenderer"]["familySafe"].as_bool
|
||||
|
||||
allowed_regions = initdata
|
||||
.dig?("microformat", "microformatDataRenderer", "availableCountries")
|
||||
.try &.as_a.map(&.as_s) || [] of String
|
||||
|
||||
description = !description_node.nil? ? description_node.as_s : ""
|
||||
description_html = HTML.escape(description)
|
||||
|
||||
if !description_node.nil?
|
||||
if description_node.as_h?.nil?
|
||||
description_node = text_to_parsed_content(description_node.as_s)
|
||||
end
|
||||
description_html = parse_content(description_node)
|
||||
if description_html == "" && description != ""
|
||||
description_html = HTML.escape(description)
|
||||
end
|
||||
end
|
||||
|
||||
total_views = 0_i64
|
||||
@@ -121,6 +140,7 @@ def get_about_info(ucid, locale) : AboutChannel
|
||||
author_url: author_url,
|
||||
author_thumbnail: author_thumbnail,
|
||||
banner: banner,
|
||||
description: description,
|
||||
description_html: description_html,
|
||||
total_views: total_views,
|
||||
sub_count: sub_count,
|
||||
@@ -128,6 +148,7 @@ def get_about_info(ucid, locale) : AboutChannel
|
||||
is_family_friendly: is_family_friendly,
|
||||
allowed_regions: allowed_regions,
|
||||
tabs: tabs,
|
||||
verified: author_verified || false,
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -226,7 +226,7 @@ def fetch_channel(ucid, pull_all_videos : Bool)
|
||||
# meaning the above timestamp is always null
|
||||
was_insert = Invidious::Database::ChannelVideos.insert(video)
|
||||
|
||||
if preferences.notifications && was_insert
|
||||
if was_insert
|
||||
LOGGER.trace("fetch_channel: #{ucid} : video #{video_id} : Inserted, updating subscriptions")
|
||||
Invidious::Database::Users.add_notification(video)
|
||||
else
|
||||
@@ -264,9 +264,7 @@ def fetch_channel(ucid, pull_all_videos : Bool)
|
||||
# so since they don't provide a published date here we can safely ignore them.
|
||||
if Time.utc - video.published > 1.minute
|
||||
was_insert = Invidious::Database::ChannelVideos.insert(video)
|
||||
if preferences.notifications && was_insert
|
||||
Invidious::Database::Users.add_notification(video)
|
||||
end
|
||||
Invidious::Database::Users.add_notification(video) if was_insert
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -6,20 +6,18 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode)
|
||||
end
|
||||
|
||||
if response.status_code != 200
|
||||
raise InfoException.new("This channel does not exist.")
|
||||
raise NotFoundException.new("This channel does not exist.")
|
||||
end
|
||||
|
||||
ucid = response.body.match(/https:\/\/www.youtube.com\/channel\/(?<ucid>UC[a-zA-Z0-9_-]{22})/).not_nil!["ucid"]
|
||||
|
||||
if !continuation || continuation.empty?
|
||||
initial_data = extract_initial_data(response.body)
|
||||
body = initial_data["contents"]?.try &.["twoColumnBrowseResultsRenderer"]["tabs"].as_a.select { |tab| tab["tabRenderer"]?.try &.["selected"].as_bool.== true }[0]?
|
||||
body = extract_selected_tab(initial_data["contents"]["twoColumnBrowseResultsRenderer"]["tabs"])["content"]["sectionListRenderer"]["contents"][0]["itemSectionRenderer"]
|
||||
|
||||
if !body
|
||||
raise InfoException.new("Could not extract community tab.")
|
||||
end
|
||||
|
||||
body = body["tabRenderer"]["content"]["sectionListRenderer"]["contents"][0]["itemSectionRenderer"]
|
||||
else
|
||||
continuation = produce_channel_community_continuation(ucid, continuation)
|
||||
|
||||
@@ -49,7 +47,11 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode)
|
||||
error_message = (message["text"]["simpleText"]? ||
|
||||
message["text"]["runs"]?.try &.[0]?.try &.["text"]?)
|
||||
.try &.as_s || ""
|
||||
raise InfoException.new(error_message)
|
||||
if error_message == "This channel does not exist."
|
||||
raise NotFoundException.new(error_message)
|
||||
else
|
||||
raise InfoException.new(error_message)
|
||||
end
|
||||
end
|
||||
|
||||
response = JSON.build do |json|
|
||||
|
||||
@@ -95,7 +95,7 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b
|
||||
contents = body["contents"]?
|
||||
header = body["header"]?
|
||||
else
|
||||
raise InfoException.new("Could not fetch comments")
|
||||
raise NotFoundException.new("Comments not found.")
|
||||
end
|
||||
|
||||
if !contents
|
||||
@@ -143,9 +143,11 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b
|
||||
node_comment = node["commentRenderer"]
|
||||
end
|
||||
|
||||
content_html = node_comment["contentText"]?.try { |t| parse_content(t) } || ""
|
||||
content_html = node_comment["contentText"]?.try { |t| parse_content(t, id) } || ""
|
||||
author = node_comment["authorText"]?.try &.["simpleText"]? || ""
|
||||
|
||||
json.field "verified", (node_comment["authorCommentBadge"]? != nil)
|
||||
|
||||
json.field "author", author
|
||||
json.field "authorThumbnails" do
|
||||
json.array do
|
||||
@@ -288,7 +290,7 @@ def fetch_reddit_comments(id, sort_by = "confidence")
|
||||
|
||||
thread = result[0].data.as(RedditListing).children[0].data.as(RedditLink)
|
||||
else
|
||||
raise InfoException.new("Could not fetch comments")
|
||||
raise NotFoundException.new("Comments not found.")
|
||||
end
|
||||
|
||||
client.close
|
||||
@@ -329,7 +331,11 @@ def template_youtube_comments(comments, locale, thin_mode, is_replies = false)
|
||||
end
|
||||
|
||||
author_name = HTML.escape(child["author"].as_s)
|
||||
|
||||
if child["verified"]?.try &.as_bool && child["authorIsChannelOwner"]?.try &.as_bool
|
||||
author_name += " <i class=\"icon ion ion-md-checkmark-circle\"></i>"
|
||||
elsif child["verified"]?.try &.as_bool
|
||||
author_name += " <i class=\"icon ion ion-md-checkmark\"></i>"
|
||||
end
|
||||
html << <<-END_HTML
|
||||
<div class="pure-g" style="width:100%">
|
||||
<div class="channel-profile pure-u-4-24 pure-u-md-2-24">
|
||||
@@ -475,7 +481,7 @@ def template_reddit_comments(root, locale)
|
||||
|
||||
html << <<-END_HTML
|
||||
<p>
|
||||
<a href="javascript:void(0)" data-onclick="toggle_parent">[ - ]</a>
|
||||
<a href="javascript:void(0)" data-onclick="toggle_parent">[ − ]</a>
|
||||
<b><a href="https://www.reddit.com/user/#{child.author}">#{child.author}</a></b>
|
||||
#{translate_count(locale, "comments_points_count", child.score, NumberFormatting::Separator)}
|
||||
<span title="#{child.created_utc.to_s(translate(locale, "%a %B %-d %T %Y UTC"))}">#{translate(locale, "`x` ago", recode_date(child.created_utc, locale))}</span>
|
||||
@@ -494,6 +500,12 @@ def template_reddit_comments(root, locale)
|
||||
end
|
||||
|
||||
def replace_links(html)
|
||||
# Check if the document is empty
|
||||
# Prevents edge-case bug with Reddit comments, see issue #3115
|
||||
if html.nil? || html.empty?
|
||||
return html
|
||||
end
|
||||
|
||||
html = XML.parse_html(html)
|
||||
|
||||
html.xpath_nodes(%q(//a)).each do |anchor|
|
||||
@@ -535,6 +547,12 @@ def replace_links(html)
|
||||
end
|
||||
|
||||
def fill_links(html, scheme, host)
|
||||
# Check if the document is empty
|
||||
# Prevents edge-case bug with Reddit comments, see issue #3115
|
||||
if html.nil? || html.empty?
|
||||
return html
|
||||
end
|
||||
|
||||
html = XML.parse_html(html)
|
||||
|
||||
html.xpath_nodes("//a").each do |match|
|
||||
@@ -554,26 +572,65 @@ def fill_links(html, scheme, host)
|
||||
return html.to_xml(options: XML::SaveOptions::NO_DECL)
|
||||
end
|
||||
|
||||
def parse_content(content : JSON::Any) : String
|
||||
content["simpleText"]?.try &.as_s.rchop('\ufeff').try { |b| HTML.escape(b) }.to_s ||
|
||||
content["runs"]?.try &.as_a.try { |r| content_to_comment_html(r).try &.to_s.gsub("\n", "<br>") } || ""
|
||||
def text_to_parsed_content(text : String) : JSON::Any
|
||||
nodes = [] of JSON::Any
|
||||
# For each line convert line to array of nodes
|
||||
text.split('\n').each do |line|
|
||||
# In first case line is just a simple node before
|
||||
# check patterns inside line
|
||||
# { 'text': line }
|
||||
currentNodes = [] of JSON::Any
|
||||
initialNode = {"text" => line}
|
||||
currentNodes << (JSON.parse(initialNode.to_json))
|
||||
|
||||
# For each match with url pattern, get last node and preserve
|
||||
# last node before create new node with url information
|
||||
# { 'text': match, 'navigationEndpoint': { 'urlEndpoint' : 'url': match } }
|
||||
line.scan(/https?:\/\/[^ ]*/).each do |urlMatch|
|
||||
# Retrieve last node and update node without match
|
||||
lastNode = currentNodes[currentNodes.size - 1].as_h
|
||||
splittedLastNode = lastNode["text"].as_s.split(urlMatch[0])
|
||||
lastNode["text"] = JSON.parse(splittedLastNode[0].to_json)
|
||||
currentNodes[currentNodes.size - 1] = JSON.parse(lastNode.to_json)
|
||||
# Create new node with match and navigation infos
|
||||
currentNode = {"text" => urlMatch[0], "navigationEndpoint" => {"urlEndpoint" => {"url" => urlMatch[0]}}}
|
||||
currentNodes << (JSON.parse(currentNode.to_json))
|
||||
# If text remain after match create new simple node with text after match
|
||||
afterNode = {"text" => splittedLastNode.size > 0 ? splittedLastNode[1] : ""}
|
||||
currentNodes << (JSON.parse(afterNode.to_json))
|
||||
end
|
||||
|
||||
# After processing of matches inside line
|
||||
# Add \n at end of last node for preserve carriage return
|
||||
lastNode = currentNodes[currentNodes.size - 1].as_h
|
||||
lastNode["text"] = JSON.parse("#{currentNodes[currentNodes.size - 1]["text"]}\n".to_json)
|
||||
currentNodes[currentNodes.size - 1] = JSON.parse(lastNode.to_json)
|
||||
|
||||
# Finally add final nodes to nodes returned
|
||||
currentNodes.each do |node|
|
||||
nodes << (node)
|
||||
end
|
||||
end
|
||||
return JSON.parse({"runs" => nodes}.to_json)
|
||||
end
|
||||
|
||||
def content_to_comment_html(content)
|
||||
comment_html = content.map do |run|
|
||||
def parse_content(content : JSON::Any, video_id : String? = "") : String
|
||||
content["simpleText"]?.try &.as_s.rchop('\ufeff').try { |b| HTML.escape(b) }.to_s ||
|
||||
content["runs"]?.try &.as_a.try { |r| content_to_comment_html(r, video_id).try &.to_s.gsub("\n", "<br>") } || ""
|
||||
end
|
||||
|
||||
def content_to_comment_html(content, video_id : String? = "")
|
||||
html_array = content.map do |run|
|
||||
# Sometimes, there is an empty element.
|
||||
# See: https://github.com/iv-org/invidious/issues/3096
|
||||
next if run.as_h.empty?
|
||||
|
||||
text = HTML.escape(run["text"].as_s)
|
||||
|
||||
if run["bold"]?
|
||||
text = "<b>#{text}</b>"
|
||||
end
|
||||
|
||||
if run["italics"]?
|
||||
text = "<i>#{text}</i>"
|
||||
end
|
||||
|
||||
if run["navigationEndpoint"]?
|
||||
if url = run["navigationEndpoint"]["urlEndpoint"]?.try &.["url"].as_s
|
||||
url = URI.parse(url)
|
||||
displayed_url = text
|
||||
|
||||
if url.host == "youtu.be"
|
||||
url = "/watch?v=#{url.request_target.lstrip('/')}"
|
||||
@@ -581,31 +638,53 @@ def content_to_comment_html(content)
|
||||
if url.path == "/redirect"
|
||||
# Sometimes, links can be corrupted (why?) so make sure to fallback
|
||||
# nicely. See https://github.com/iv-org/invidious/issues/2682
|
||||
url = HTTP::Params.parse(url.query.not_nil!)["q"]? || ""
|
||||
url = url.query_params["q"]? || ""
|
||||
displayed_url = url
|
||||
else
|
||||
url = url.request_target
|
||||
displayed_url = "youtube.com#{url}"
|
||||
end
|
||||
end
|
||||
|
||||
text = %(<a href="#{url}">#{text}</a>)
|
||||
text = %(<a href="#{url}">#{reduce_uri(displayed_url)}</a>)
|
||||
elsif watch_endpoint = run["navigationEndpoint"]["watchEndpoint"]?
|
||||
length_seconds = watch_endpoint["startTimeSeconds"]?
|
||||
video_id = watch_endpoint["videoId"].as_s
|
||||
start_time = watch_endpoint["startTimeSeconds"]?.try &.as_i
|
||||
link_video_id = watch_endpoint["videoId"].as_s
|
||||
|
||||
if length_seconds && length_seconds.as_i > 0
|
||||
text = %(<a href="javascript:void(0)" data-onclick="jump_to_time" data-jump-time="#{length_seconds}">#{text}</a>)
|
||||
url = "/watch?v=#{link_video_id}"
|
||||
url += "&t=#{start_time}" if !start_time.nil?
|
||||
|
||||
# If the current video ID (passed through from the caller function)
|
||||
# is the same as the video ID in the link, add HTML attributes for
|
||||
# the JS handler function that bypasses page reload.
|
||||
#
|
||||
# See: https://github.com/iv-org/invidious/issues/3063
|
||||
if link_video_id == video_id
|
||||
start_time ||= 0
|
||||
text = %(<a href="#{url}" data-onclick="jump_to_time" data-jump-time="#{start_time}">#{reduce_uri(text)}</a>)
|
||||
else
|
||||
text = %(<a href="/watch?v=#{video_id}">#{text}</a>)
|
||||
text = %(<a href="#{url}">#{text}</a>)
|
||||
end
|
||||
elsif url = run.dig?("navigationEndpoint", "commandMetadata", "webCommandMetadata", "url").try &.as_s
|
||||
text = %(<a href="#{url}">#{text}</a>)
|
||||
if text.starts_with?(/\s?[@#]/)
|
||||
# Handle "pings" in comments and hasthags differently
|
||||
# See:
|
||||
# - https://github.com/iv-org/invidious/issues/3038
|
||||
# - https://github.com/iv-org/invidious/issues/3062
|
||||
text = %(<a href="#{url}">#{text}</a>)
|
||||
else
|
||||
text = %(<a href="#{url}">#{reduce_uri(url)}</a>)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
text
|
||||
end.join("").delete('\ufeff')
|
||||
text = "<b>#{text}</b>" if run["bold"]?
|
||||
text = "<i>#{text}</i>" if run["italics"]?
|
||||
|
||||
return comment_html
|
||||
text
|
||||
end
|
||||
|
||||
return html_array.join("").delete('\ufeff')
|
||||
end
|
||||
|
||||
def produce_comment_continuation(video_id, cursor = "", sort_by = "top")
|
||||
|
||||
@@ -24,7 +24,6 @@ struct ConfigPreferences
|
||||
property local : Bool = false
|
||||
property locale : String = "en-US"
|
||||
property watch_history : Bool = true
|
||||
property notifications : Bool = true
|
||||
property max_results : Int32 = 40
|
||||
property notifications_only : Bool = false
|
||||
property player_style : String = "invidious"
|
||||
@@ -76,7 +75,7 @@ class Config
|
||||
@[YAML::Field(converter: Preferences::URIConverter)]
|
||||
property database_url : URI = URI.parse("")
|
||||
# Use polling to keep decryption function up to date
|
||||
property decrypt_polling : Bool = true
|
||||
property decrypt_polling : Bool = false
|
||||
# Used for crawling channels: threads should check all videos uploaded by a channel
|
||||
property full_refresh : Bool = false
|
||||
# Used to tell Invidious it is behind a proxy, so links to resources should be https://
|
||||
@@ -162,16 +161,13 @@ class Config
|
||||
{% env_id = "INVIDIOUS_#{ivar.id.upcase}" %}
|
||||
|
||||
if ENV.has_key?({{env_id}})
|
||||
# puts %(Config.{{ivar.id}} : Loading from env var {{env_id}})
|
||||
env_value = ENV.fetch({{env_id}})
|
||||
success = false
|
||||
|
||||
# Use YAML converter if specified
|
||||
{% ann = ivar.annotation(::YAML::Field) %}
|
||||
{% if ann && ann[:converter] %}
|
||||
puts %(Config.{{ivar.id}} : Parsing "#{env_value}" as {{ivar.type}} with {{ann[:converter]}} converter)
|
||||
config.{{ivar.id}} = {{ann[:converter]}}.from_yaml(YAML::ParseContext.new, YAML::Nodes.parse(ENV.fetch({{env_id}})).nodes[0])
|
||||
puts %(Config.{{ivar.id}} : Set to #{config.{{ivar.id}}})
|
||||
success = true
|
||||
|
||||
# Use regular YAML parser otherwise
|
||||
@@ -182,9 +178,7 @@ class Config
|
||||
{{ivar_types}}.each do |ivar_type|
|
||||
if !success
|
||||
begin
|
||||
# puts %(Config.{{ivar.id}} : Trying to parse "#{env_value}" as #{ivar_type})
|
||||
config.{{ivar.id}} = ivar_type.from_yaml(env_value)
|
||||
puts %(Config.{{ivar.id}} : Set to #{config.{{ivar.id}}} (#{ivar_type}))
|
||||
success = true
|
||||
rescue
|
||||
# nop
|
||||
|
||||
38
src/invidious/database/migration.cr
Normal file
38
src/invidious/database/migration.cr
Normal file
@@ -0,0 +1,38 @@
|
||||
abstract class Invidious::Database::Migration
|
||||
macro inherited
|
||||
Migrator.migrations << self
|
||||
end
|
||||
|
||||
@@version : Int64?
|
||||
|
||||
def self.version(version : Int32 | Int64)
|
||||
@@version = version.to_i64
|
||||
end
|
||||
|
||||
getter? completed = false
|
||||
|
||||
def initialize(@db : DB::Database)
|
||||
end
|
||||
|
||||
abstract def up(conn : DB::Connection)
|
||||
|
||||
def migrate
|
||||
# migrator already ignores completed migrations
|
||||
# but this is an extra check to make sure a migration doesn't run twice
|
||||
return if completed?
|
||||
|
||||
@db.transaction do |txn|
|
||||
up(txn.connection)
|
||||
track(txn.connection)
|
||||
@completed = true
|
||||
end
|
||||
end
|
||||
|
||||
def version : Int64
|
||||
@@version.not_nil!
|
||||
end
|
||||
|
||||
private def track(conn : DB::Connection)
|
||||
conn.exec("INSERT INTO #{Migrator::MIGRATIONS_TABLE} (version) VALUES ($1)", version)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
module Invidious::Database::Migrations
|
||||
class CreateChannelsTable < Migration
|
||||
version 1
|
||||
|
||||
def up(conn : DB::Connection)
|
||||
conn.exec <<-SQL
|
||||
CREATE TABLE IF NOT EXISTS public.channels
|
||||
(
|
||||
id text NOT NULL,
|
||||
author text,
|
||||
updated timestamp with time zone,
|
||||
deleted boolean,
|
||||
subscribed timestamp with time zone,
|
||||
CONSTRAINT channels_id_key UNIQUE (id)
|
||||
);
|
||||
SQL
|
||||
|
||||
conn.exec <<-SQL
|
||||
GRANT ALL ON TABLE public.channels TO current_user;
|
||||
SQL
|
||||
|
||||
conn.exec <<-SQL
|
||||
CREATE INDEX IF NOT EXISTS channels_id_idx
|
||||
ON public.channels
|
||||
USING btree
|
||||
(id COLLATE pg_catalog."default");
|
||||
SQL
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,28 @@
|
||||
module Invidious::Database::Migrations
|
||||
class CreateVideosTable < Migration
|
||||
version 2
|
||||
|
||||
def up(conn : DB::Connection)
|
||||
conn.exec <<-SQL
|
||||
CREATE UNLOGGED TABLE IF NOT EXISTS public.videos
|
||||
(
|
||||
id text NOT NULL,
|
||||
info text,
|
||||
updated timestamp with time zone,
|
||||
CONSTRAINT videos_pkey PRIMARY KEY (id)
|
||||
);
|
||||
SQL
|
||||
|
||||
conn.exec <<-SQL
|
||||
GRANT ALL ON TABLE public.videos TO current_user;
|
||||
SQL
|
||||
|
||||
conn.exec <<-SQL
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS id_idx
|
||||
ON public.videos
|
||||
USING btree
|
||||
(id COLLATE pg_catalog."default");
|
||||
SQL
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,35 @@
|
||||
module Invidious::Database::Migrations
|
||||
class CreateChannelVideosTable < Migration
|
||||
version 3
|
||||
|
||||
def up(conn : DB::Connection)
|
||||
conn.exec <<-SQL
|
||||
CREATE TABLE IF NOT EXISTS public.channel_videos
|
||||
(
|
||||
id text NOT NULL,
|
||||
title text,
|
||||
published timestamp with time zone,
|
||||
updated timestamp with time zone,
|
||||
ucid text,
|
||||
author text,
|
||||
length_seconds integer,
|
||||
live_now boolean,
|
||||
premiere_timestamp timestamp with time zone,
|
||||
views bigint,
|
||||
CONSTRAINT channel_videos_id_key UNIQUE (id)
|
||||
);
|
||||
SQL
|
||||
|
||||
conn.exec <<-SQL
|
||||
GRANT ALL ON TABLE public.channel_videos TO current_user;
|
||||
SQL
|
||||
|
||||
conn.exec <<-SQL
|
||||
CREATE INDEX IF NOT EXISTS channel_videos_ucid_idx
|
||||
ON public.channel_videos
|
||||
USING btree
|
||||
(ucid COLLATE pg_catalog."default");
|
||||
SQL
|
||||
end
|
||||
end
|
||||
end
|
||||
34
src/invidious/database/migrations/0004_create_users_table.cr
Normal file
34
src/invidious/database/migrations/0004_create_users_table.cr
Normal file
@@ -0,0 +1,34 @@
|
||||
module Invidious::Database::Migrations
|
||||
class CreateUsersTable < Migration
|
||||
version 4
|
||||
|
||||
def up(conn : DB::Connection)
|
||||
conn.exec <<-SQL
|
||||
CREATE TABLE IF NOT EXISTS public.users
|
||||
(
|
||||
updated timestamp with time zone,
|
||||
notifications text[],
|
||||
subscriptions text[],
|
||||
email text NOT NULL,
|
||||
preferences text,
|
||||
password text,
|
||||
token text,
|
||||
watched text[],
|
||||
feed_needs_update boolean,
|
||||
CONSTRAINT users_email_key UNIQUE (email)
|
||||
);
|
||||
SQL
|
||||
|
||||
conn.exec <<-SQL
|
||||
GRANT ALL ON TABLE public.users TO current_user;
|
||||
SQL
|
||||
|
||||
conn.exec <<-SQL
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS email_unique_idx
|
||||
ON public.users
|
||||
USING btree
|
||||
(lower(email) COLLATE pg_catalog."default");
|
||||
SQL
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,28 @@
|
||||
module Invidious::Database::Migrations
|
||||
class CreateSessionIdsTable < Migration
|
||||
version 5
|
||||
|
||||
def up(conn : DB::Connection)
|
||||
conn.exec <<-SQL
|
||||
CREATE TABLE IF NOT EXISTS public.session_ids
|
||||
(
|
||||
id text NOT NULL,
|
||||
email text,
|
||||
issued timestamp with time zone,
|
||||
CONSTRAINT session_ids_pkey PRIMARY KEY (id)
|
||||
);
|
||||
SQL
|
||||
|
||||
conn.exec <<-SQL
|
||||
GRANT ALL ON TABLE public.session_ids TO current_user;
|
||||
SQL
|
||||
|
||||
conn.exec <<-SQL
|
||||
CREATE INDEX IF NOT EXISTS session_ids_id_idx
|
||||
ON public.session_ids
|
||||
USING btree
|
||||
(id COLLATE pg_catalog."default");
|
||||
SQL
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,27 @@
|
||||
module Invidious::Database::Migrations
|
||||
class CreateNoncesTable < Migration
|
||||
version 6
|
||||
|
||||
def up(conn : DB::Connection)
|
||||
conn.exec <<-SQL
|
||||
CREATE TABLE IF NOT EXISTS public.nonces
|
||||
(
|
||||
nonce text,
|
||||
expire timestamp with time zone,
|
||||
CONSTRAINT nonces_id_key UNIQUE (nonce)
|
||||
);
|
||||
SQL
|
||||
|
||||
conn.exec <<-SQL
|
||||
GRANT ALL ON TABLE public.nonces TO current_user;
|
||||
SQL
|
||||
|
||||
conn.exec <<-SQL
|
||||
CREATE INDEX IF NOT EXISTS nonces_nonce_idx
|
||||
ON public.nonces
|
||||
USING btree
|
||||
(nonce COLLATE pg_catalog."default");
|
||||
SQL
|
||||
end
|
||||
end
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user