Compare commits

...

141 Commits

Author SHA1 Message Date
Jakob Borg
5f8c0ca932 cmd/syncthing: Fix incorrect shadowing preventing first startup (fixes #4471) 2017-10-28 21:15:32 +02:00
Simon Frei
2953fe40d1 lib/model: Add initial noop watch cancel func (fixes #4464)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4465
2017-10-26 13:50:30 +02:00
Audrius Butkevicius
ff0a83fe5b vendor: Fix kcp deadlock
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4461
2017-10-25 21:57:51 +02:00
Simon Frei
dc42db444b lib/model, lib/config: Refactor folder health/error handling (fixes #4445, fixes #4451)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4455
LGTM: AudriusButkevicius, calmh
2017-10-24 07:58:55 +00:00
Audrius Butkevicius
a9c221189b lib/connections: Stun resolves server adress beforehand (fixes #4453)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4454
2017-10-22 18:48:06 +00:00
Audrius Butkevicius
b2966957e0 lib/connections: Add KCP blacklist period 2017-10-22 13:56:52 +01:00
Audrius Butkevicius
0d30166357 lib/connections: Use own KCP fork, move listener setup earlier (ref #4446)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4452
2017-10-22 12:36:36 +00:00
Jakob Borg
d65f1fb08a lib/config: Improve debug logging around folder marker 2017-10-22 00:04:51 +02:00
Audrius Butkevicius
622b614f31 all: Ignore Sync errors on directories (fixes #4432)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4449
2017-10-21 22:00:46 +00:00
Audrius Butkevicius
b1ade6d0c0 gui: Do not prompt for UR changes if disabled (fixes #4444)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4448
2017-10-21 18:46:07 +00:00
Simon Frei
46becc5338 build: Handle split GOPATH
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4447
2017-10-21 17:37:06 +00:00
Simon Frei
20fac4bb80 main: Improve logging for initial config loading (ref #4431)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4436
2017-10-21 09:00:24 +00:00
Simon Frei
d84b6bb822 build: Warn when being executed outside of gopath
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4425
2017-10-20 23:10:55 +00:00
Simon Frei
55b63941b8 cmd/syncthing: Add fswatcher and remove useAPIKey stats
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4438
2017-10-20 16:25:20 +00:00
Simon Frei
e70003737b lib/fs: make watcher tests even more darwin slowness resistant
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4439
2017-10-20 15:59:18 +00:00
Michael Ploujnikov
f98c21b68e all: Add filesystem notification support
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3986
2017-10-20 14:52:55 +00:00
Simon Frei
c704ba9ef9 gui: "versioner" -> "versioning" and add missing translations
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4435
2017-10-20 13:55:22 +00:00
Jakob Borg
dfad6a2aa9 gui, man: Update docs & translations 2017-10-18 07:45:20 +02:00
Audrius Butkevicius
fb7264a663 cmd/syncthing: Enable KCP by default
Also, use upstream library, as my changes have been merged.
2017-10-17 23:17:10 +01:00
Audrius Butkevicius
889814a1af gui: Add uncamel filter
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4428
LGTM: imsodin, calmh
2017-10-17 07:56:36 +00:00
Simon Frei
694a7de59d build: Correct import paths for vet tools
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4420
2017-10-15 10:39:50 +00:00
Audrius Butkevicius
059185b325 cmd/syncthing: Expand usage stats even more (ref #3628)
Also add diffing functionality

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4422
2017-10-15 07:45:15 +00:00
Audrius Butkevicius
1e9e9cbebb cmd/syncthing: Uptime should be an integer 2017-10-14 18:22:30 +01:00
Felix Ableitner
cdbb32d0f0 build: Support passing -pkgdir
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4417
2017-10-13 09:24:38 +00:00
Audrius Butkevicius
becbb3b123 lib/model: Fix tests not to require Go 1.9 2017-10-12 22:36:20 +01:00
Jakob Borg
06da67e6fc issue_template: Clarify what to post and not post
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4416
2017-10-12 07:14:21 +00:00
Jakob Borg
2f08f8021f lib/beacon: Don't exit after a single write failure (fixes #4414)
With VPNs and stuff we can get a single failure on an interface that
supposedly supports broadcasts without it being fatal.

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4415
2017-10-12 07:13:44 +00:00
Audrius Butkevicius
9d3f3847ed lib/model: Fix removal of paused folders, improve tests (fixes #4405) 2017-10-12 08:23:33 +02:00
Audrius Butkevicius
74c8d34805 lib/model: Centralize error reporting, modified files are errors (fixes #4392) 2017-10-12 08:23:33 +02:00
Audrius Butkevicius
5ec1490be0 lib/fs: Ignore directory fsync failures 2017-10-12 08:22:29 +02:00
Audrius Butkevicius
2760d032ca cmd/syncthing: Add more stats to usage reports (ref #3628)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4347
2017-10-12 06:16:46 +00:00
Jakob Borg
813e6ddf83 gui, man: Update docs & translations 2017-10-11 07:45:19 +02:00
Matteo Ruina
6ffb95f6c8 etc: Add FreeBSD rc.d script
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4408
2017-10-08 17:29:51 +00:00
Jakob Borg
0b5c11bf93 gui, man: Update docs & translations 2017-10-04 07:45:19 +02:00
Tobias Tom
5aade9a4a5 Add -device-id command line option (fixes #4387)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4390
2017-09-25 06:05:21 +00:00
Jakob Borg
9717c3d292 authors: Add tobiastom 2017-09-25 07:51:21 +02:00
Jakob Borg
a365ae51c4 lib/model: Hide temporary files on Windows while they are in use (fixes #4382)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4394
2017-09-23 13:47:51 +00:00
Jakob Borg
97222797a0 lib/config: Make folder marker change non fatal 2017-09-23 15:29:55 +02:00
Simon Frei
e588bb29b9 lib/model: remove unused folderFs member from Model
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4389
2017-09-21 09:03:36 +00:00
Jakob Borg
2dd9450793 lib/protocol, vendor: Import luhn code directly
I've changed it incompatibly to fix a correctness bug. Nonetheless, we
should remain incorrect indefinitely.
2017-09-20 21:34:32 +02:00
Jakob Borg
3ee12464b4 lib/config, lib/model: Make sure to hide our special files (fixes #4382)
The folder marker conversion forgot to hide the .stfolder. This adds
that, for those who have not yet been converted.

Also adds Hide() calls to the folder start, to mend historical
unhidedness. (I'm sure this will upset someone who is manually managing
their .stignores in the other direction...)

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4384
2017-09-20 06:49:04 +00:00
Jakob Borg
59ebcea356 gui, man: Update docs & translations 2017-09-20 07:45:17 +02:00
Sly_tom_cat
27d4896a13 gui: Fix title attribute for popups on shared folders / devices (fixes #4377)
Skip-check: authors

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4378
2017-09-19 15:37:26 +00:00
Simon Frei
1088eb12ea lib/model: Fix logging inconsistencies (fixes #4375)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4376
2017-09-18 11:56:19 +00:00
Jakob Borg
f40d219370 gui, man: Update docs & translations 2017-09-13 07:45:17 +02:00
Jakob Borg
429cc20eb7 cmd/syncthing: Add some common security releated HTTP headers (fixes #4360)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4361
2017-09-10 08:28:12 +00:00
Audrius Butkevicius
e85ce7c94e lib/model: Support removing paused folders (fixes #4357)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4358
LGTM: imsodin, calmh
2017-09-09 15:08:59 +00:00
Jakob Borg
283c8d95e2 lib/protocol: Comment typo 2017-09-08 15:25:14 +02:00
wangguoliang
a9aa375109 lib/fs: Comment typo
Skip-check: authors

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4354
2017-09-07 09:40:46 +00:00
Simon Frei
f7d2c58783 lib/model: Deduplicate folder loops
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4352
LGTM: AudriusButkevicius, calmh
2017-09-07 06:17:47 +00:00
Jakob Borg
4d3e0de4ba cmd/syncthing, lib/sha256: Skip CPU benchmarks when user decided (fixes #4348)
When STHASHING is set, don't benchmark as it's already decided. If weak
hashing isn't set to "auto", don't benchmark that either.

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4349
2017-09-06 06:55:47 +00:00
Simon Frei
9dbc509996 lib/ignore: Consistent behaviour for nil *Matcher
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4310
2017-09-06 06:39:18 +00:00
Jakob Borg
baec3f909c gui, man: Update docs & translations 2017-09-06 07:45:19 +02:00
Simon Frei
c41aaad3bb lib/ignore: Ignore duplicate lines in .stignore
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4350
LGTM: AudriusButkevicius, calmh
2017-09-04 12:46:19 +00:00
Jakob Borg
9682bbfbda lib/protocol: Optimize luhn and chunk functions
These functions were very naive and slow. We haven't done much about
them because they pretty much don't matter at all for Syncthing
performance. They are however called very often in the discovery server
and these optimizations have a huge effect on the CPU load on the
public discovery servers.

The code isn't exactly obvious, but we have good test coverage on all
these functions.

benchmark                 old ns/op     new ns/op     delta
BenchmarkLuhnify-8        12458         1045          -91.61%
BenchmarkUnluhnify-8      12598         1074          -91.47%
BenchmarkChunkify-8       10792         104           -99.04%

benchmark                 old allocs     new allocs     delta
BenchmarkLuhnify-8        18             1              -94.44%
BenchmarkUnluhnify-8      18             1              -94.44%
BenchmarkChunkify-8       44             2              -95.45%

benchmark                 old bytes     new bytes     delta
BenchmarkLuhnify-8        1278          64            -94.99%
BenchmarkUnluhnify-8      1278          64            -94.99%
BenchmarkChunkify-8       42552         128           -99.70%

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4346
2017-09-03 10:26:12 +00:00
Audrius Butkevicius
9e6a1fdcd4 vendor: Update kcp, removes closeConn (fixes #4343) 2017-09-02 16:11:48 +02:00
Jakob Borg
49bddfbe53 cmd/syncthing: Add test for truncate behavior of log file (ref #4255)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4342
2017-09-02 06:56:35 +00:00
Simon Frei
55e0ac3e24 lib/model: Make puller retrying and logging less aggressive
Currently all errors during pulling and the first of these errors again on
finishing are logged to info. Besides that the errors logged when finishing
are stored in f.errors. This PR moves all logging during pulling to the debug
channel (they might still be relevant in some obscure debugging case) and
uses the stored errors to log the main error per fail when all pulling
iterations are done and failed.

Additional instead of trying 11 times it now only tries 3 times.

This is the first part of what is discussed here:
https://forum.syncthing.net/t/reduce-verboseness-of-puller/10261

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4338
2017-09-02 06:05:55 +00:00
Audrius Butkevicius
cbcc3ea132 lib/connections: Use our own fork of kcp (fixes #4063)
This updates kcp and uses our own fork which:

1. Keys sessions not just by remote address, but by remote address +
conversation id 2. Allows not to close connections that were passed directly
to the library. 3. Resets cache key if the session gets terminated.

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4339
LGTM: calmh
2017-09-02 06:04:35 +00:00
Audrius Butkevicius
ab132ff6fe lib: Folder marker is now a folder
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4341
LGTM: calmh
2017-09-02 05:52:38 +00:00
Jakob Borg
19e52a10df readme: Update badges for new build server 2017-09-01 14:23:17 +02:00
Jakob Borg
a8145e187f lib/model: Fixup because I suck and shouldn't commit directly to master 2017-08-31 10:49:17 +02:00
Jakob Borg
e33fa10115 lib/model: Use same batch size constants in db updater as for protocol 2017-08-31 10:47:39 +02:00
Jakob Borg
4b6e7e7867 lib/tlsutil: Remove undesired bufio from UnionedConnection (ref #4245)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4335
2017-08-31 07:34:48 +00:00
Jakob Borg
70d121a94b cmd/strelaysrv: Smaller, adjustable network buffer 2017-08-30 18:52:28 +02:00
Jakob Borg
33ffb07d31 cmd/strelaysrv: Don't leak tickers 2017-08-30 18:46:50 +02:00
Jakob Borg
7aaa92ac47 cmd/strelaysrv: Add profiling support, default disabled 2017-08-30 16:07:15 +02:00
Jakob Borg
5883eb9a25 gui, man: Update docs & translations 2017-08-30 10:50:19 +02:00
MaximAL
e60efa2b3d gui: Correct quotes in title attribute
Skip-check: authors

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4332
2017-08-30 06:02:46 +00:00
Simon Frei
ddf6d64faa lib/model: Create folders via newFolder
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4329
2017-08-25 19:47:01 +00:00
Simon Frei
c7221b035d gui: Round down in devices completion (consistent with folders)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4325
2017-08-24 04:26:12 +00:00
Audrius Butkevicius
a69ba18f62 lib/model: Some platforms do not support usage checks (fixes #4321)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4322
2017-08-22 18:13:58 +00:00
Jakob Borg
b31611a8d1 gui, man: Update docs & translations
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4320
2017-08-22 09:00:52 +00:00
Simon Frei
0ca0e3e9bd lib/model: GetIgnores: Don't return error for no .stignore file
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4311
2017-08-22 06:48:25 +00:00
Audrius Butkevicius
0a96a1150b lib/model, lib/ignores: Properly handle out of folder ignores and free space checks (fixes #4313, fixes #4314)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4318
2017-08-22 06:45:00 +00:00
Audrius Butkevicius
b8c249cddc lib/model: Move stale scan check info finisher (ref #4305, fix #3742)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4317
2017-08-22 06:42:09 +00:00
Audrius Butkevicius
e8ba6d4771 lib/upnp: Fix build
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4316
2017-08-21 11:41:40 +00:00
Audrius Butkevicius
606fce09ca lib/upnp: Disable confusing messages
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4312
2017-08-21 10:03:25 +00:00
Audrius Butkevicius
3d8b4a42b7 all: Convert folders to use filesystem abstraction
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4228
2017-08-19 14:36:56 +00:00
Simon Frei
ab8c2fb5c7 lib/model: Fix race in GetIgnores (fixes #4300)
In addition this function returned an error when .stignore file was not
present, which is perfectly valid. Also removed inconsistent nil check in
ignores.go (only relevant for tests) and adjusted walk.go to do what it says
in comments (check if Matcher is nil) to prevent nil deref in tests.

Originally reported in:
https://forum.syncthing.net/t/reason-for-panic-maybe-too-little-ram/10346

Regression from #3996

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4301
2017-08-12 17:10:43 +00:00
Simon Frei
77578e8aac gui: Don't set default path editing existing folders without label (fixes #4297)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4298
LGTM: calmh
2017-08-10 15:31:25 +00:00
Jakob Borg
1fc2ab444b lib/model: Remove ineffective symlink recovery attempt 2017-08-08 15:30:28 +02:00
Jakob Borg
fa5c890ff6 lib/versioner: Clean the versions dir of symlinks, not the full folder
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4289
2017-08-08 13:13:08 +00:00
Jakob Borg
a3c17f8f81 lib/model: Disable symlink attack test on Windows 2017-08-08 08:05:24 +02:00
Jakob Borg
f1f21bf220 lib/model, lib/versioner: Prevent symlink attack via versioning (fixes #4286)
Prior to this, the following is possible:

- Create a symlink "foo -> /somewhere", it gets synced
- Delete "foo", it gets versioned
- Create "foo/bar", it gets synced
- Delete "foo/bar", it gets versioned in "/somewhere/bar"

With this change, versioners should never version symlinks.
2017-08-07 07:57:10 +02:00
MaximAL
54155cb42d gui: Add title attributes for shared devices/folders
Skip-check: authors

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4266
LGTM: AudriusButkevicius
2017-07-27 17:31:14 +00:00
Jakob Borg
414c58174b build: Move -installsuffix behind an explicit option (fixes #4272) 2017-07-27 12:55:07 +02:00
Audrius Butkevicius
94acc20dd6 cmd/strelaysrv: Fix a few connection and routine leaks (fixes #4245)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4273
2017-07-26 19:18:00 +00:00
NoLooseEnds
8e9119eedf assets: Add Mac folder icon
Skip-check: authors

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4238
2017-07-20 13:23:54 +00:00
Simon Frei
a04b92332f gui, lib/config: Add default path for new folders (fixes #2157)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4192
2017-07-20 13:16:54 +00:00
HairyFotr
0ad10b0fee all: Typos
Skip-check: authors

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4263
2017-07-20 13:10:46 +00:00
Ross Smith II
0ca2ed7ad7 build: Use maximum compression when archiving
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4229
2017-07-17 13:20:13 +00:00
Jakob Borg
fa4226cae4 authors: Add rasa 2017-07-17 15:06:47 +02:00
Jakob Borg
cc63236a2e build: Use Go's default GOPATH if it's valid
As of Go 1.8 it's valid to not have a GOPATH set. We ask the Go tool
what the GOPATH seems to be, and if we find ourselves (or a valid copy
of ourselves...) in that location we do not fiddle with the GOPATH.
2017-07-16 21:39:29 +01:00
Jakob Borg
6623657ef3 build: The default build step already includes linting 2017-07-15 17:06:22 +02:00
Jose Manuel Delicado
4405117bea gui: HTML accessibility updates
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4258
LGTM: calmh
2017-07-15 09:54:37 +00:00
Jakob Borg
e371800878 authors: Fixup jmdaweb 2017-07-14 07:53:18 +02:00
Jakob Borg
7a47646534 authors: Add jmdaweb 2017-07-14 07:49:08 +02:00
Jakob Borg
d475ad7ce1 gui, man: Update docs & translations 2017-07-13 08:55:12 +02:00
Jakob Borg
7c8418f493 build: Support builds outside of GOPATH
This adds support for building with the source placed anywhere and no
GOPATH set. The build script handles this by creating a temporary GOPATH
in the system temp dir (or another specified location) and mirroring the
source there before building. The resulting binaries etc still end up in
the same place as usual, meaning at least the "build", "install", "tar",
"zip", "deb", "snap", "test", "vet", "lint", "metalint" and "clean"
commands work without a GOPATH. To this end these commands internally
use fully qualified package paths like
"github.com/syncthing/syncthing/cmd/..." instead of "./cmd/..." like
before.

There is a new command "gopath" that prepares and echoes the directory
of the temporary GOPATH. This can be used to run other non-build go
commands:

export GOPATH=$(go run build.go gopath)  // GOPATH is now set
go test -v -race github.com/syncthing/syncthing/cmd/...

There is a new option "-no-build-gopath" that prevents the
check-and-copy step, instead assuming the temporary GOPATH is already
created and up to date. This is a performance optimization for build
servers running multiple builds commands in sequence:

go run build.go gopath // creates a temporary GOPATH
go run build.go -no-build-gopath -goos=... tar // reuses GOPATH
go run build.go -no-build-gopath -goos=... tar // reuses GOPATH

The temporary GOPATH is placed in the system temporary directory
(os.TempDir()) unless overridden by the STTMPDIR variable. It is named
after the hash of the current directory where build.go is run. The
reason for this is that the name should be unique to a source checkout
without risk for conflict, but still persistent between runs of
build.go.

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4253
LGTM: AudriusButkevicius, imsodin
2017-07-11 07:57:58 +00:00
Jakob Borg
200a7fc844 meta: Move metadata checks into meta directory, make them tests
This moves a few things from script/ to a new directory meta/, and makes
them real Go tests. These are the authors, copyright, metalint and gofmt
checks. That means that they can now be run by

go test -v ./meta

and optionally filtered by the usual -run thing to go test. Also -short
will cut down on the metalint stuff and exclude the authors check (which
is slow because it runs git lots of times).

Mainly this makes everything easier on things like build servers where
we can now just run tests instead of do a bunch of scripting.

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4252
2017-07-07 20:43:26 +00:00
Jakob Borg
5a38e0ba3f script: Trivial lint error in changelog.go 2017-07-07 21:56:12 +02:00
Jakob Borg
c77490c32d authors: Fixup author email mistakes 2017-07-07 21:42:50 +02:00
Simon Frei
b75c9f2bbb lib/ignores: Don't add text from includes to lines (fixes #4249)
Otherwise all the lines from includes will be shown in the web UI instead of
just the #include ... line. This problem was introduced in #3996.

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4248
LGTM: calmh
2017-07-06 11:44:11 +00:00
Siyuan Liu
322bedbb04 gui: Show remaining bytes in remote device panel (fixes #4227)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4246
LGTM: AudriusButkevicius, calmh
2017-07-05 09:19:29 +00:00
Jakob Borg
487655b365 gui, man: Update docs & translations 2017-07-05 07:45:22 +02:00
Siyuan Liu
03c678a810 lib/versioner: Interpret versions path relative to folder path (fixes #4188)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4243
2017-07-03 14:50:51 +00:00
Jakob Borg
b79f8aceb8 authors: Fixup liusy182 2017-07-03 16:40:02 +02:00
Jakob Borg
92e8c4303a authors: Add liusy182 2017-07-03 16:33:41 +02:00
Jakob Borg
e735a3a25c build: Builds from "release" branch are not branch builds 2017-06-30 14:02:16 +02:00
Simon Frei
8d13e01342 gui: Fix discovered devices list (follow-up to #4186)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4239
2017-06-29 13:47:42 +00:00
Jakob Borg
34f8cc8620 gui: Rename assets/lang/README-FIRST to README for greater visibility
README is rendered in the GitHub web UI
2017-06-28 18:58:41 +02:00
Jakob Borg
add10c98fa lib/db: Fix test for Go 1.9's smarter time.Time values 2017-06-28 14:36:04 +02:00
Jakob Borg
6503326073 gui, man: Update docs & translations 2017-06-28 07:45:20 +02:00
Jakob Borg
db1dc9985a lib/upgrade: 0.x to 1.0 is a minor upgrade
This removes the special handling of minor versions as major when the
actual major is zero, and adds the special case that upgrades from 0.x
to 1.x are considered minor. 0.x to 2.x or 1.x to 2.x etc are still
considered major.

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4226
2017-06-25 14:17:43 +00:00
Jakob Borg
3641c97667 gui, man: Update docs & translations 2017-06-21 07:45:20 +02:00
Jakob Borg
8f214fe4a9 lib/config: Ignored folders that are added to the config should not remain ignored (fixes #4219)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4220
2017-06-17 18:40:28 +00:00
Simon Frei
98cfc204ca gui: Add dropdown menu to choose discovered devices to device modal (fixes #4157)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4186
LGTM: AudriusButkevicius, calmh
2017-06-16 15:27:09 +00:00
Jakob Borg
d0061c172c gui, man: Update docs & translations 2017-06-14 07:45:21 +02:00
Jakob Borg
93a04158fd vendor: Update github.com/gogo/protobuf, keeping all files
gvt fetch -a, because we need the protobuf files etc for regeneration
2017-06-14 05:24:09 +02:00
Jakob Borg
d862e79133 gui: Fix minor breakage from 9c417571 2017-06-12 08:54:08 +02:00
Jakob Borg
68c1a0b9b4 lib/ignore, lib/model: Use an interface to detect file changes, improving tests
This solves the erratic test failures on model.TestIgnores by ensuring
that the ignore patterns are reloaded even in the face of unchanged
timestamps.

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4208
2017-06-11 10:27:12 +00:00
Jakob Borg
2a38d2a3d2 build: Build Debian packages for non-syncthing targets (fixes #4193)
Things like the package name "syncthing" was hardcoded, which is not
awesome. With this in place we can build debs called syncthing-discosrv,
syncthing-relaysrv and syncthing-relaypoolsrv. I don't actually intend
to build and publish the relaypoolsrv, but the others can be good. Using
the "syncthing-" prefix to make the obvious "apt-cache search syncthing"
actually show them etc.

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4206
LGTM: AudriusButkevicius, calmh
2017-06-09 08:53:45 +00:00
Simon Frei
9c4175715a gui: Reset ignore input field when adding remote share (fixes #4203)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4204
LGTM: AudriusButkevicius, calmh
2017-06-09 05:41:19 +00:00
Audrius Butkevicius
d637148cca cmd/strelaypoolsrv: Show popup on row hover
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4201
2017-06-07 22:06:00 +00:00
snugghash
3395992abd gui: Make icons and directory information in local device summary consistent with folders (fixes #4100)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4200
2017-06-07 10:34:45 +00:00
Jakob Borg
7a15fef3b8 authors, nicks: Add snugghash 2017-06-07 12:23:16 +02:00
Audrius Butkevicius
9667a0a618 lib/connections: Fix race (fixes #4177) 2017-06-07 10:17:01 +02:00
Jakob Borg
7346113742 gui, man: Update docs & translations 2017-06-07 07:45:21 +02:00
Lars K.W. Gohlke
3f1fa04725 build, jenkins: Move test coverage stuff to jenkins/
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4178
2017-06-02 07:18:59 +00:00
Simon Frei
719c313b23 cmd/syncthing, lib/logger: Set debug flags on SetDebug for tests
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4187
2017-06-02 07:04:06 +00:00
Jakob Borg
3d11efc9e0 gui, man: Update docs & translations 2017-06-01 12:25:17 +02:00
Jakob Borg
3dca7cd694 build: Update prerelease command 2017-06-01 12:09:20 +02:00
Jakob Borg
803da92ca9 cmd/syncthing: Start CPU usage monitoring not from init (fixes #4183)
Starting stuff from init() is an antipattern, and the innerProcess
variable isn't 100% reliable. We should sort out the other uses of it as
well in due time.

Also removing the hack on innerProcess as I happened to see it and the
affected versions are now <1% users.

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4185
2017-05-31 18:14:04 +00:00
nrm21
b49bbe82dd gui, lib/config, lib/model: Add ability to ignore folders offered by other nodes (fixes #3993)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4179
LGTM: AudriusButkevicius, calmh
2017-05-31 18:04:00 +00:00
Jakob Borg
3959eb26fb lib/model: Events should have "folder" key, not "folderID" 2017-05-30 08:57:18 +02:00
nrm21
1235cead35 lib/model: Add name of latest modifying device to conflict file (fixes #3524)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4161
LGTM: AudriusButkevicius, calmh
2017-05-25 10:26:41 +00:00
Simon Frei
dd6bb6d5fd gui: Reset warnings about nested folder roots (fixes #3433)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4173
2017-05-23 19:54:56 +00:00
Audrius Butkevicius
91d37f35bc lib/model: Use up to date device name, do not provide name to unknown devices (fixes #4164)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4168
2017-05-22 19:58:33 +00:00
Audrius Butkevicius
51518490c6 lib/connections: Fix KCP from locking up the service (fixes #4072) 2017-05-21 22:16:21 +02:00
Audrius Butkevicius
2c10beed0b gui: Add (?d) and (?i) to ignores guide 2017-05-21 22:16:21 +02:00
937 changed files with 777568 additions and 7152 deletions

View File

@@ -62,15 +62,17 @@ Jaya Chithra (jayachithra) <s.k.jayachithra@gmail.com>
Jens Diemer (jedie) <github.com@jensdiemer.de> <git@jensdiemer.de>
Jochen Voss (seehuhn) <voss@seehuhn.de>
Johan Vromans (sciurius) <jvromans@squirrel.nl>
Jose Manuel Delicado (jmdaweb) <jmdaweb@hotmail.com> <jmdaweb@users.noreply.github.com>
Karol Różycki (krozycki) <rozycki.karol@gmail.com>
Kelong Cong (kc1212) <kc04bc@gmx.com> <kc1212@users.noreply.github.com>
Ken'ichi Kamada (kamadak) <kamada@nanohz.org>
Kevin Allen (ironmig) <kma1660@gmail.com>
Kevin White, Jr. (kwhite17) <kevinwhite1710@gmail.com>
Kurt Fitzner (Kudalufi) <kurt@va1der.ca>
Kurt Fitzner (Kudalufi) <kurt@va1der.ca> <kurt.fitzner@gmail.com>
Lars K.W. Gohlke (lkwg82) <lkwg82@gmx.de>
Laurent Etiemble (letiemble) <laurent.etiemble@gmail.com> <laurent.etiemble@monobjc.net>
Leo Arias (elopio) <yo@elopio.net>
Liu Siyuan (liusy182) <liusy182@gmail.com> <liusy182@hotmail.com>
Lode Hoste (Zillode) <zillode@zillode.be>
Lord Landon Agahnim (LordLandon) <lordlandon@gmail.com>
Majed Abdulaziz (majedev) <majed.alhajry@gmail.com>
@@ -93,6 +95,7 @@ Phill Luby (pluby) <phill.luby@newredo.com>
Piotr Bejda (piobpl) <piotrb10@gmail.com>
Robert Carosi (nov1n) <robert@carosi.nl>
Roman Zaynetdinov (zaynetro) <romanznet@gmail.com>
Ross Smith II (rasa) <ross@smithii.com>
Ryan Sullivan (KayoticSully) <kayoticsully@gmail.com>
Sacheendra Talluri (sacheendra) <sacheendra.t@gmail.com>
Scott Klupfel (kluppy) <kluppy@going2blue.com>
@@ -100,9 +103,11 @@ Sergey Mishin (ralder) <ralder@yandex.ru>
Simon Frei (imsodin) <freisim93@gmail.com>
Stefan Kuntz (Stefan-Code) <stefan.github@gmail.com> <Stefan.github@gmail.com>
Stefan Tatschner (rumpelsepp) <stefan@sevenbyte.org> <rumpelsepp@sevenbyte.org>
Suhas Gundimeda (snugghash) <suhas.gundimeda@gmail.com> <snugghash@gmail.com>
Tim Abell (timabell) <tim@timwise.co.uk>
Tim Howes (timhowes) <timhowes@berkeley.edu>
Tobias Nygren (tnn2) <tnn@nygren.pp.se>
Tobias Tom (tobiastom) <t.tom@succont.de>
Tomas Cerveny (kozec) <kozec@kozec.com>
Tully Robinson (tojrobinson) <tully@tojr.org>
Tyler Brazier (tylerbrazier) <tyler@tylerbrazier.com>
@@ -111,6 +116,6 @@ Veeti Paananen (veeti) <veeti.paananen@rojekti.fi>
Victor Buinsky (buinsky) <vix_booja@tut.by>
Vil Brekin (Vilbrekin) <vilbrekin@gmail.com>
William A. Kennington III (wkennington) <william@wkennington.com>
Wulf Weich (wweich) <wweich@users.noreply.github.com> <wweich@gmx.de>
Wulf Weich (wweich) <wweich@users.noreply.github.com> <wweich@gmx.de> <wulf@weich-kr.de>
Xavier O. (damajor) <damajor@gmail.com>
Yannic A. (eipiminus1) <eipiminusone+github@gmail.com> <eipiminus1@users.noreply.github.com>

View File

@@ -1,11 +1,17 @@
Do not report security issues in this bug tracker. Instead, contact
security@syncthing.net directly - see https://syncthing.net/security.html
for more information.
### DO NOT REPORT SECURITY ISSUES IN THIS ISSUE TRACKER
If your issue is a support request ("How do I get my devices to connect?"
or similar), please use the support forum at https://forum.syncthing.net/
where a large number of helpful people hang out. This issue tracker is for
reporting bugs or feature requests directly to the developers.
Instead, contact security@syncthing.net directly - see
https://syncthing.net/security.html for more information.
### DO NOT POST SUPPORT REQUESTS OR GENERAL QUESTIONS IN THIS ISSUE TRACKER
Please use the forum at https://forum.syncthing.net/ where a large number of
helpful people hang out. This issue tracker is for reporting bugs or feature
requests directly to the developers. Worst case you might get a short
"that's a bug, please report it on GitHub" response on the forum, in which
case we thank you for your patience and following our advice. :)
### Please do post actual bug reports and feature requests.
If your issue is a bug report, replace this boilerplate with a description
of the problem, being sure to include at least:

10
NICKS
View File

@@ -57,6 +57,8 @@ jayachithra <s.k.jayachithra@gmail.com>
jedie <github.com@jensdiemer.de>
jedie <git@jensdiemer.de>
jgke <jgke@jgke.fi>
jmdaweb <jmdaweb@hotmail.com>
jmdaweb <jmdaweb@users.noreply.github.com>
jpjp <jamespatterson@operamail.com>
jpjp <jpjp@users.noreply.github.com>
kamadak <kamada@nanohz.org>
@@ -70,9 +72,12 @@ kralo <max.schulze@online.de>
kralo <kralo@users.noreply.github.com>
krozycki <rozycki.karol@gmail.com>
Kudalufi <kurt@va1der.ca>
Kudalufi <kurt.fitzner@gmail.com>
kwhite17 <kevinwhite1710@gmail.com>
letiemble <laurent.etiemble@gmail.com>
letiemble <laurent.etiemble@monobjc.net>
liusy182 <liusy182@gmail.com>
liusy182 <liusy182@hotmail.com>
lkwg82 <lkwg82@gmx.de>
LordLandon <lordlandon@gmail.com>
majedev <majed.alhajry@gmail.com>
@@ -106,6 +111,7 @@ ProactiveServices <ProactiveServices@users.noreply.github.com>
pyfisch <pyfisch@gmail.com>
qbit <qbit@deftly.net>
ralder <ralder@yandex.ru>
rasa <ross@smithii.com>
Rewt0r <rewt0r@gmx.com>
Rewt0r <Rewt0r@users.noreply.github.com>
rumpelsepp <stefan@sevenbyte.org>
@@ -116,11 +122,14 @@ sciurius <jvromans@squirrel.nl>
seehuhn <voss@seehuhn.de>
Smiley73 <heiko@zuerker.org>
snnd <dw@risu.io>
snugghash <suhas.gundimeda@gmail.com>
snugghash <snugghash@gmail.com>
Stefan-Code <stefan.github@gmail.com>
Stefan-Code <Stefan.github@gmail.com>
timabell <tim@timwise.co.uk>
timhowes <timhowes@berkeley.edu>
tnn2 <tnn@nygren.pp.se>
tobiastom <t.tom@succont.de>
tojrobinson <tully@tojr.org>
tpng <benny.tpng@gmail.com>
tylerbrazier <tyler@tylerbrazier.com>
@@ -134,6 +143,7 @@ wkennington <william@wkennington.com>
WSGCSysadmin <e.meitner@willystreet.coop>
wweich <wweich@users.noreply.github.com>
wweich <wweich@gmx.de>
wweich <wulf@weich-kr.de>
xduugu <cedric@gmx.ca>
zaynetro <romanznet@gmail.com>
Zillode <zillode@zillode.be>

View File

@@ -2,11 +2,10 @@
---
[![Latest Linux & Cross Build](https://img.shields.io/jenkins/s/http/build.syncthing.net/syncthing.svg?style=flat-square&label=linux+%26+cross)](https://build.syncthing.net/job/syncthing/lastBuild/)
[![Latest Windows Build](https://img.shields.io/jenkins/s/http/build.syncthing.net/syncthing-windows.svg?style=flat-square&label=windows)](https://build.syncthing.net/job/syncthing/lastBuild/)
[![Latest Mac Build](https://img.shields.io/jenkins/s/http/build.syncthing.net/syncthing-mac.svg?style=flat-square&label=mac)](https://build.syncthing.net/job/syncthing/lastBuild/)
[![Latest Solaris Build](https://img.shields.io/jenkins/s/http/build.syncthing.net/syncthing-solaris.svg?style=flat-square&label=solaris)](https://build.syncthing.net/job/syncthing/lastBuild/)
[![API Documentation](https://img.shields.io/badge/api-Godoc-blue.svg?style=flat-square)](https://godoc.org/github.com/syncthing/syncthing)
[![Latest Downloads](https://img.shields.io/badge/latest-downloads-brightgreen.svg?style=flat-square)](https://build.syncthing.net/latest/)
[![Latest Linux & Cross Build](https://img.shields.io/teamcity/https/build.syncthing.net/s/Syncthing_BuildLinuxCross.svg?style=flat-square&label=linux+%26+cross+build)](https://build.syncthing.net/viewType.html?buildTypeId=Syncthing_BuildLinuxCross&guest=1)
[![Latest Windows Build](https://img.shields.io/teamcity/https/build.syncthing.net/s/Syncthing_BuildWindows.svg?style=flat-square&label=windows+build)](https://build.syncthing.net/viewType.html?buildTypeId=Syncthing_BuildWindows&guest=1)
[![Latest Mac Build](https://img.shields.io/teamcity/https/build.syncthing.net/s/Syncthing_BuildMac.svg?style=flat-square&label=mac+build)](https://build.syncthing.net/viewType.html?buildTypeId=Syncthing_BuildMac&guest=1)
[![MPLv2 License](https://img.shields.io/badge/license-MPLv2-blue.svg?style=flat-square)](https://www.mozilla.org/MPL/2.0/)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/88/badge)](https://bestpractices.coreinfrastructure.org/projects/88)
[![Go Report Card](https://goreportcard.com/badge/github.com/syncthing/syncthing)](https://goreportcard.com/report/github.com/syncthing/syncthing)
@@ -100,7 +99,7 @@ All code is licensed under the [MPLv2 License][7].
[1]: https://docs.syncthing.net/specs/bep-v1.html
[2]: https://docs.syncthing.net/intro/getting-started.html
[3]: https://github.com/syncthing/syncthing/blob/master/etc
[4]: http://www.freenode.net/
[4]: https://www.freenode.net/
[5]: https://docs.syncthing.net/dev/building.html
[6]: https://docs.syncthing.net/
[7]: https://github.com/syncthing/syncthing/blob/master/LICENSE
@@ -111,4 +110,4 @@ All code is licensed under the [MPLv2 License][7].
[12]: https://www.bountysource.com/teams/syncthing/issues
[13]: https://github.com/syncthing/syncthing/blob/master/GOALS.md
[14]: assets/logo-text-128.png
[15]: https://syncthing.net/
[15]: https://syncthing.net/

View File

Binary file not shown.

464
build.go
View File

@@ -12,7 +12,9 @@ import (
"archive/tar"
"archive/zip"
"bytes"
"compress/flate"
"compress/gzip"
"crypto/sha256"
"errors"
"flag"
"fmt"
@@ -32,18 +34,26 @@ import (
)
var (
versionRe = regexp.MustCompile(`-[0-9]{1,3}-g[0-9a-f]{5,10}`)
goarch string
goos string
noupgrade bool
version string
goVersion float64
race bool
debug = os.Getenv("BUILDDEBUG") != ""
versionRe = regexp.MustCompile(`-[0-9]{1,3}-g[0-9a-f]{5,10}`)
goarch string
goos string
noupgrade bool
version string
goVersion float64
race bool
debug = os.Getenv("BUILDDEBUG") != ""
noBuildGopath bool
extraTags string
installSuffix string
pkgdir string
)
type target struct {
name string
debname string
debdeps []string
debpost string
description string
buildPkg string
binaryName string
archiveFiles []archiveFile
@@ -61,14 +71,18 @@ var targets = map[string]target{
"all": {
// Only valid for the "build" and "install" commands as it lacks all
// the archive creation stuff.
buildPkg: "./cmd/...",
buildPkg: "github.com/syncthing/syncthing/cmd/...",
tags: []string{"purego"},
},
"syncthing": {
// The default target for "build", "install", "tar", "zip", "deb", etc.
name: "syncthing",
buildPkg: "./cmd/syncthing",
binaryName: "syncthing", // .exe will be added automatically for Windows builds
name: "syncthing",
debname: "syncthing",
debdeps: []string{"libc6", "procps"},
debpost: "script/post-upgrade",
description: "Open Source Continuous File Synchronization",
buildPkg: "github.com/syncthing/syncthing/cmd/syncthing",
binaryName: "syncthing", // .exe will be added automatically for Windows builds
archiveFiles: []archiveFile{
{src: "{{binary}}", dst: "{{binary}}", perm: 0755},
{src: "README.md", dst: "README.txt", perm: 0644},
@@ -98,9 +112,12 @@ var targets = map[string]target{
},
},
"stdiscosrv": {
name: "stdiscosrv",
buildPkg: "./cmd/stdiscosrv",
binaryName: "stdiscosrv", // .exe will be added automatically for Windows builds
name: "stdiscosrv",
debname: "syncthing-discosrv",
debdeps: []string{"libc6"},
description: "Syncthing Discovery Server",
buildPkg: "github.com/syncthing/syncthing/cmd/stdiscosrv",
binaryName: "stdiscosrv", // .exe will be added automatically for Windows builds
archiveFiles: []archiveFile{
{src: "{{binary}}", dst: "{{binary}}", perm: 0755},
{src: "cmd/stdiscosrv/README.md", dst: "README.txt", perm: 0644},
@@ -109,17 +126,20 @@ var targets = map[string]target{
},
installationFiles: []archiveFile{
{src: "{{binary}}", dst: "deb/usr/bin/{{binary}}", perm: 0755},
{src: "cmd/stdiscosrv/README.md", dst: "deb/usr/share/doc/stdiscosrv/README.txt", perm: 0644},
{src: "cmd/stdiscosrv/LICENSE", dst: "deb/usr/share/doc/stdiscosrv/LICENSE.txt", perm: 0644},
{src: "AUTHORS", dst: "deb/usr/share/doc/stdiscosrv/AUTHORS.txt", perm: 0644},
{src: "cmd/stdiscosrv/README.md", dst: "deb/usr/share/doc/syncthing-discosrv/README.txt", perm: 0644},
{src: "cmd/stdiscosrv/LICENSE", dst: "deb/usr/share/doc/syncthing-discosrv/LICENSE.txt", perm: 0644},
{src: "AUTHORS", dst: "deb/usr/share/doc/syncthing-discosrv/AUTHORS.txt", perm: 0644},
{src: "man/stdiscosrv.1", dst: "deb/usr/share/man/man1/stdiscosrv.1", perm: 0644},
},
tags: []string{"purego"},
},
"strelaysrv": {
name: "strelaysrv",
buildPkg: "./cmd/strelaysrv",
binaryName: "strelaysrv", // .exe will be added automatically for Windows builds
name: "strelaysrv",
debname: "syncthing-relaysrv",
debdeps: []string{"libc6"},
description: "Syncthing Relay Server",
buildPkg: "github.com/syncthing/syncthing/cmd/strelaysrv",
binaryName: "strelaysrv", // .exe will be added automatically for Windows builds
archiveFiles: []archiveFile{
{src: "{{binary}}", dst: "{{binary}}", perm: 0755},
{src: "cmd/strelaysrv/README.md", dst: "README.txt", perm: 0644},
@@ -128,16 +148,19 @@ var targets = map[string]target{
},
installationFiles: []archiveFile{
{src: "{{binary}}", dst: "deb/usr/bin/{{binary}}", perm: 0755},
{src: "cmd/strelaysrv/README.md", dst: "deb/usr/share/doc/strelaysrv/README.txt", perm: 0644},
{src: "cmd/strelaysrv/LICENSE", dst: "deb/usr/share/doc/strelaysrv/LICENSE.txt", perm: 0644},
{src: "AUTHORS", dst: "deb/usr/share/doc/strelaysrv/AUTHORS.txt", perm: 0644},
{src: "cmd/strelaysrv/README.md", dst: "deb/usr/share/doc/syncthing-relaysrv/README.txt", perm: 0644},
{src: "cmd/strelaysrv/LICENSE", dst: "deb/usr/share/doc/syncthing-relaysrv/LICENSE.txt", perm: 0644},
{src: "AUTHORS", dst: "deb/usr/share/doc/syncthing-relaysrv/AUTHORS.txt", perm: 0644},
{src: "man/strelaysrv.1", dst: "deb/usr/share/man/man1/strelaysrv.1", perm: 0644},
},
},
"strelaypoolsrv": {
name: "strelaypoolsrv",
buildPkg: "./cmd/strelaypoolsrv",
binaryName: "strelaypoolsrv", // .exe will be added automatically for Windows builds
name: "strelaypoolsrv",
debname: "syncthing-relaypoolsrv",
debdeps: []string{"libc6"},
description: "Syncthing Relay Pool Server",
buildPkg: "github.com/syncthing/syncthing/cmd/strelaypoolsrv",
binaryName: "strelaypoolsrv", // .exe will be added automatically for Windows builds
archiveFiles: []archiveFile{
{src: "{{binary}}", dst: "{{binary}}", perm: 0755},
{src: "cmd/strelaypoolsrv/README.md", dst: "README.txt", perm: 0644},
@@ -146,48 +169,13 @@ var targets = map[string]target{
},
installationFiles: []archiveFile{
{src: "{{binary}}", dst: "deb/usr/bin/{{binary}}", perm: 0755},
{src: "cmd/strelaypoolsrv/README.md", dst: "deb/usr/share/doc/relaysrv/README.txt", perm: 0644},
{src: "cmd/strelaypoolsrv/LICENSE", dst: "deb/usr/share/doc/relaysrv/LICENSE.txt", perm: 0644},
{src: "AUTHORS", dst: "deb/usr/share/doc/relaysrv/AUTHORS.txt", perm: 0644},
{src: "cmd/strelaypoolsrv/README.md", dst: "deb/usr/share/doc/syncthing-relaypoolsrv/README.txt", perm: 0644},
{src: "cmd/strelaypoolsrv/LICENSE", dst: "deb/usr/share/doc/syncthing-relaypoolsrv/LICENSE.txt", perm: 0644},
{src: "AUTHORS", dst: "deb/usr/share/doc/syncthing-relaypoolsrv/AUTHORS.txt", perm: 0644},
},
},
}
var (
// fast linters complete in a fraction of a second and might as well be
// run always as part of the build
fastLinters = []string{
"deadcode",
"golint",
"ineffassign",
"vet",
}
// slow linters take several seconds and are run only as part of the
// "metalint" command.
slowLinters = []string{
"gosimple",
"staticcheck",
"structcheck",
"unused",
"varcheck",
}
// Which parts of the tree to lint
lintDirs = []string{".", "./lib/...", "./cmd/..."}
// Messages to ignore
lintExcludes = []string{
".pb.go",
"should have comment",
"protocol.Vector composite literal uses unkeyed fields",
"cli.Requires composite literal uses unkeyed fields",
"Use DialContext instead", // Go 1.7
"os.SEEK_SET is deprecated", // Go 1.7
"SA4017", // staticcheck "is a pure function but its return value is ignored"
}
)
func init() {
// The "syncthing" target includes a few more files found in the "etc"
// and "extra" dirs.
@@ -205,9 +193,10 @@ func init() {
}
func main() {
log.SetOutput(os.Stdout)
log.SetFlags(0)
parseFlags()
if debug {
t0 := time.Now()
defer func() {
@@ -215,16 +204,39 @@ func main() {
}()
}
if os.Getenv("GOPATH") == "" {
setGoPath()
if gopath := gopath(); gopath == "" {
gopath, err := temporaryBuildDir()
if err != nil {
log.Fatal(err)
}
if !noBuildGopath {
lazyRebuildAssets()
if err := buildGOPATH(gopath); err != nil {
log.Fatal(err)
}
}
os.Setenv("GOPATH", gopath)
log.Println("GOPATH is", gopath)
} else {
inside := false
wd, _ := os.Getwd()
wd, _ = filepath.EvalSymlinks(wd)
for _, p := range filepath.SplitList(gopath) {
p, _ = filepath.EvalSymlinks(p)
if filepath.Join(p, "src/github.com/syncthing/syncthing") == wd {
inside = true
break
}
}
if !inside {
fmt.Println("You seem to have GOPATH set but the Syncthing source not placed correctly within it, which may cause problems.")
}
}
// Set path to $GOPATH/bin:$PATH so that we can for sure find tools we
// might have installed during "build.go setup".
os.Setenv("PATH", fmt.Sprintf("%s%cbin%c%s", os.Getenv("GOPATH"), os.PathSeparator, os.PathListSeparator, os.Getenv("PATH")))
parseFlags()
checkArchitecture()
// Invoking build.go with no parameters at all builds everything (incrementally),
@@ -267,22 +279,23 @@ func runCommand(cmd string, target target) {
if noupgrade {
tags = []string{"noupgrade"}
}
tags = append(tags, strings.Fields(extraTags)...)
install(target, tags)
metalint(fastLinters, lintDirs)
metalintShort()
case "build":
var tags []string
if noupgrade {
tags = []string{"noupgrade"}
}
tags = append(tags, strings.Fields(extraTags)...)
build(target, tags)
metalint(fastLinters, lintDirs)
case "test":
test("./lib/...", "./cmd/...")
test("github.com/syncthing/syncthing/lib/...", "github.com/syncthing/syncthing/cmd/...")
case "bench":
bench("./lib/...", "./cmd/...")
bench("github.com/syncthing/syncthing/lib/...", "github.com/syncthing/syncthing/cmd/...")
case "assets":
rebuildAssets()
@@ -312,41 +325,39 @@ func runCommand(cmd string, target target) {
clean()
case "vet":
metalint(fastLinters, lintDirs)
metalintShort()
case "lint":
metalint(fastLinters, lintDirs)
metalintShort()
case "metalint":
metalint(fastLinters, lintDirs)
metalint(slowLinters, lintDirs)
metalint()
case "version":
fmt.Println(getVersion())
case "gopath":
gopath, err := temporaryBuildDir()
if err != nil {
log.Fatal(err)
}
fmt.Println(gopath)
default:
log.Fatalf("Unknown command %q", cmd)
}
}
// setGoPath sets GOPATH correctly with the assumption that we are
// in $GOPATH/src/github.com/syncthing/syncthing.
func setGoPath() {
cwd, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
gopath := filepath.Clean(filepath.Join(cwd, "../../../../"))
log.Println("GOPATH is", gopath)
os.Setenv("GOPATH", gopath)
}
func parseFlags() {
flag.StringVar(&goarch, "goarch", runtime.GOARCH, "GOARCH")
flag.StringVar(&goos, "goos", runtime.GOOS, "GOOS")
flag.BoolVar(&noupgrade, "no-upgrade", noupgrade, "Disable upgrade functionality")
flag.StringVar(&version, "version", getVersion(), "Set compiled in version string")
flag.BoolVar(&race, "race", race, "Use race detector")
flag.BoolVar(&noBuildGopath, "no-build-gopath", noBuildGopath, "Don't build GOPATH, assume it's OK")
flag.StringVar(&extraTags, "tags", extraTags, "Extra tags, space separated")
flag.StringVar(&installSuffix, "installsuffix", installSuffix, "Install suffix, optional")
flag.StringVar(&pkgdir, "pkgdir", "", "Set -pkgdir parameter for `go build`")
flag.Parse()
}
@@ -364,16 +375,16 @@ func setup() {
"github.com/tsenart/deadcode",
"golang.org/x/net/html",
"golang.org/x/tools/cmd/cover",
"honnef.co/go/simple/cmd/gosimple",
"honnef.co/go/staticcheck/cmd/staticcheck",
"honnef.co/go/unused/cmd/unused",
"honnef.co/go/tools/cmd/gosimple",
"honnef.co/go/tools/cmd/staticcheck",
"honnef.co/go/tools/cmd/unused",
}
for _, pkg := range packages {
fmt.Println(pkg)
runPrint("go", "get", "-u", pkg)
}
runPrint("go", "install", "-v", "./vendor/github.com/gogo/protobuf/protoc-gen-gogofast")
runPrint("go", "install", "-v", "github.com/syncthing/syncthing/vendor/github.com/gogo/protobuf/protoc-gen-gogofast")
}
func test(pkgs ...string) {
@@ -409,9 +420,15 @@ func install(target target, tags []string) {
}
os.Setenv("GOBIN", filepath.Join(cwd, "bin"))
args := []string{"install", "-v", "-ldflags", ldflags()}
if pkgdir != "" {
args = append(args, "-pkgdir", pkgdir)
}
if len(tags) > 0 {
args = append(args, "-tags", strings.Join(tags, " "))
}
if installSuffix != "" {
args = append(args, "-installsuffix", installSuffix)
}
if race {
args = append(args, "-race")
}
@@ -427,11 +444,17 @@ func build(target target, tags []string) {
tags = append(target.tags, tags...)
rmr(target.binaryName)
rmr(target.BinaryName())
args := []string{"build", "-i", "-v", "-ldflags", ldflags()}
if pkgdir != "" {
args = append(args, "-pkgdir", pkgdir)
}
if len(tags) > 0 {
args = append(args, "-tags", strings.Join(tags, " "))
}
if installSuffix != "" {
args = append(args, "-installsuffix", installSuffix)
}
if race {
args = append(args, "-race")
}
@@ -455,22 +478,20 @@ func buildTar(target target) {
build(target, tags)
if goos == "darwin" {
macosCodesign(target.binaryName)
macosCodesign(target.BinaryName())
}
for i := range target.archiveFiles {
target.archiveFiles[i].src = strings.Replace(target.archiveFiles[i].src, "{{binary}}", target.binaryName, 1)
target.archiveFiles[i].dst = strings.Replace(target.archiveFiles[i].dst, "{{binary}}", target.binaryName, 1)
target.archiveFiles[i].src = strings.Replace(target.archiveFiles[i].src, "{{binary}}", target.BinaryName(), 1)
target.archiveFiles[i].dst = strings.Replace(target.archiveFiles[i].dst, "{{binary}}", target.BinaryName(), 1)
target.archiveFiles[i].dst = name + "/" + target.archiveFiles[i].dst
}
tarGz(filename, target.archiveFiles)
log.Println(filename)
fmt.Println(filename)
}
func buildZip(target target) {
target.binaryName += ".exe"
name := archiveName(target)
filename := name + ".zip"
@@ -483,13 +504,13 @@ func buildZip(target target) {
build(target, tags)
for i := range target.archiveFiles {
target.archiveFiles[i].src = strings.Replace(target.archiveFiles[i].src, "{{binary}}", target.binaryName, 1)
target.archiveFiles[i].dst = strings.Replace(target.archiveFiles[i].dst, "{{binary}}", target.binaryName, 1)
target.archiveFiles[i].src = strings.Replace(target.archiveFiles[i].src, "{{binary}}", target.BinaryName(), 1)
target.archiveFiles[i].dst = strings.Replace(target.archiveFiles[i].dst, "{{binary}}", target.BinaryName(), 1)
target.archiveFiles[i].dst = name + "/" + target.archiveFiles[i].dst
}
zipFile(filename, target.archiveFiles)
log.Println(filename)
fmt.Println(filename)
}
func buildDeb(target target) {
@@ -509,8 +530,8 @@ func buildDeb(target target) {
build(target, []string{"noupgrade"})
for i := range target.installationFiles {
target.installationFiles[i].src = strings.Replace(target.installationFiles[i].src, "{{binary}}", target.binaryName, 1)
target.installationFiles[i].dst = strings.Replace(target.installationFiles[i].dst, "{{binary}}", target.binaryName, 1)
target.installationFiles[i].src = strings.Replace(target.installationFiles[i].src, "{{binary}}", target.BinaryName(), 1)
target.installationFiles[i].dst = strings.Replace(target.installationFiles[i].dst, "{{binary}}", target.BinaryName(), 1)
}
for _, af := range target.installationFiles {
@@ -528,15 +549,26 @@ func buildDeb(target target) {
// than just 0.14.26. This rectifies that.
debver = strings.Replace(debver, "-", "~", -1)
}
runPrint("fpm", "-t", "deb", "-s", "dir", "-C", "deb",
"-n", "syncthing", "-v", debver, "-a", debarch,
"--vendor", maintainer, "-m", maintainer,
"-d", "libc6",
"-d", "procps", // because postinst script
args := []string{
"-t", "deb",
"-s", "dir",
"-C", "deb",
"-n", target.debname,
"-v", debver,
"-a", debarch,
"-m", maintainer,
"--vendor", maintainer,
"--description", target.description,
"--url", "https://syncthing.net/",
"--description", "Open Source Continuous File Synchronization",
"--after-upgrade", "script/post-upgrade",
"--license", "MPL-2")
"--license", "MPL-2",
}
for _, dep := range target.debdeps {
args = append(args, "-d", dep)
}
if target.debpost != "" {
args = append(args, "--after-upgrade", target.debpost)
}
runPrint("fpm", args...)
}
func buildSnap(target target) {
@@ -577,21 +609,36 @@ func buildSnap(target target) {
runPrint("snapcraft")
}
// copyFile copies a file from src to dst, ensuring the containing directory
// exists. The permission bits are copied as well. If dst already exists and
// the contents are identical to src the modification time is not updated.
func copyFile(src, dst string, perm os.FileMode) error {
dstDir := filepath.Dir(dst)
os.MkdirAll(dstDir, 0755) // ignore error
srcFd, err := os.Open(src)
in, err := ioutil.ReadFile(src)
if err != nil {
return err
}
defer srcFd.Close()
dstFd, err := os.OpenFile(dst, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, perm)
out, err := ioutil.ReadFile(dst)
if err != nil {
// The destination probably doesn't exist, we should create
// it.
goto copy
}
if bytes.Equal(in, out) {
// The permission bits may have changed without the contents
// changing so we always mirror them.
os.Chmod(dst, perm)
return nil
}
copy:
os.MkdirAll(filepath.Dir(dst), 0777)
if err := ioutil.WriteFile(dst, in, perm); err != nil {
return err
}
defer dstFd.Close()
_, err = io.Copy(dstFd, srcFd)
return err
return nil
}
func listFiles(dir string) []string {
@@ -646,7 +693,7 @@ func shouldRebuildAssets(target, srcdir string) bool {
}
func proto() {
runPrint("go", "generate", "./lib/...")
runPrint("go", "generate", "github.com/syncthing/syncthing/lib/...")
}
func translate() {
@@ -773,8 +820,9 @@ func getBranchSuffix() string {
}
branch = parts[len(parts)-1]
if branch == "master" {
// master builds are the default.
switch branch {
case "master", "release":
// these are not special
return ""
}
@@ -898,7 +946,10 @@ func tarGz(out string, files []archiveFile) {
log.Fatal(err)
}
gw := gzip.NewWriter(fd)
gw, err := gzip.NewWriterLevel(fd, gzip.BestCompression)
if err != nil {
log.Fatal(err)
}
tw := tar.NewWriter(gw)
for _, f := range files {
@@ -951,6 +1002,21 @@ func zipFile(out string, files []archiveFile) {
zw := zip.NewWriter(fd)
var fw *flate.Writer
// Register the deflator.
zw.RegisterCompressor(zip.Deflate, func(out io.Writer) (io.WriteCloser, error) {
var err error
if fw == nil {
// Creating a flate compressor for every file is
// expensive, create one and reuse it.
fw, err = flate.NewWriter(out, flate.BestCompression)
} else {
fw.Reset(out)
}
return fw, err
})
for _, f := range files {
sf, err := os.Open(f.src)
if err != nil {
@@ -1026,59 +1092,129 @@ func macosCodesign(file string) {
}
}
func metalint(linters []string, dirs []string) {
ok := true
if isGometalinterInstalled() {
if !gometalinter(linters, dirs, lintExcludes...) {
ok = false
}
}
if !ok {
log.Fatal("Build succeeded, but there were lint warnings")
}
func metalint() {
lazyRebuildAssets()
runPrint("go", "test", "-run", "Metalint", "./meta")
}
func isGometalinterInstalled() bool {
if _, err := runError("gometalinter", "--disable-all"); err != nil {
log.Println("gometalinter is not installed")
return false
}
return true
func metalintShort() {
lazyRebuildAssets()
runPrint("go", "test", "-short", "-run", "Metalint", "./meta")
}
func gometalinter(linters []string, dirs []string, excludes ...string) bool {
params := []string{"--disable-all", "--concurrency=2", "--deadline=300s"}
func temporaryBuildDir() (string, error) {
// The base of our temp dir is "syncthing-xxxxxxxx" where the x:es
// are eight bytes from the sha256 of our working directory. We do
// this because we want a name in the global temp dir that doesn't
// conflict with someone else building syncthing on the same
// machine, yet is persistent between runs from the same source
// directory.
wd, err := os.Getwd()
if err != nil {
return "", err
}
hash := sha256.Sum256([]byte(wd))
base := fmt.Sprintf("syncthing-%x", hash[:4])
for _, linter := range linters {
params = append(params, "--enable="+linter)
// The temp dir is taken from $STTMPDIR if set, otherwise the system
// default (potentially infrluenced by $TMPDIR on unixes).
var tmpDir string
if t := os.Getenv("STTMPDIR"); t != "" {
tmpDir = t
} else {
tmpDir = os.TempDir()
}
for _, exclude := range excludes {
params = append(params, "--exclude="+exclude)
return filepath.Join(tmpDir, base), nil
}
func buildGOPATH(gopath string) error {
pkg := filepath.Join(gopath, "src/github.com/syncthing/syncthing")
dirs := []string{"cmd", "lib", "meta", "script", "test", "vendor"}
if debug {
t0 := time.Now()
log.Println("build temporary GOPATH in", gopath)
defer func() {
log.Println("... in", time.Since(t0))
}()
}
// Walk the sources and copy the files into the temporary GOPATH.
// Remember which files are supposed to be present so we can clean
// out everything else in the next step. The copyFile() step will
// only actually copy the file if it doesn't exist or the contents
// differ.
exists := map[string]struct{}{}
for _, dir := range dirs {
params = append(params, dir)
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
dst := filepath.Join(pkg, path)
exists[dst] = struct{}{}
if err := copyFile(path, dst, info.Mode()); err != nil {
return err
}
return nil
})
if err != nil {
return err
}
}
bs, _ := runError("gometalinter", params...)
// Walk the temporary GOPATH and remove any files that we wouldn't
// have copied there in the previous step.
nerr := 0
lines := make(map[string]struct{})
for _, line := range strings.Split(string(bs), "\n") {
if line == "" {
continue
filepath.Walk(pkg, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if _, ok := lines[line]; ok {
continue
if info.IsDir() {
return nil
}
log.Println(line)
if strings.Contains(line, "executable file not found") {
log.Println(` - Try "go run build.go setup" to install missing tools`)
if _, ok := exists[path]; !ok {
os.Remove(path)
}
lines[line] = struct{}{}
nerr++
}
return nil
})
return nerr == 0
return nil
}
func gopath() string {
if gopath := os.Getenv("GOPATH"); gopath != "" {
// The env var is set, use that.
return gopath
}
// Ask Go what it thinks.
bs, err := runError("go", "env", "GOPATH")
if err != nil {
return ""
}
// We got something. Check if we are in fact available in that location.
gopath := string(bs)
if _, err := os.Stat(filepath.Join(gopath, "src/github.com/syncthing/syncthing/build.go")); err == nil {
// That seems to be the gopath.
return gopath
}
// The gopath is not valid.
return ""
}
func (t target) BinaryName() string {
if goos == "windows" {
return t.binaryName + ".exe"
}
return t.binaryName
}

View File

@@ -61,9 +61,9 @@ case "${1:-default}" in
prerelease)
go run script/authors.go
build transifex
git add -A gui/default/assets/ lib/auto/
pushd man ; ./refresh.sh ; popd
git add -A man
git add -A gui man
git commit -m 'gui, man: Update docs & translations'
;;
noupgrade)
@@ -93,40 +93,6 @@ case "${1:-default}" in
done
;;
test-cov)
ulimit -t 600 &>/dev/null || true
ulimit -d 512000 &>/dev/null || true
ulimit -m 512000 &>/dev/null || true
echo "mode: set" > coverage.out
fail=0
# For every package in the repo
for dir in $(go list ./lib/... ./cmd/...) ; do
# run the tests
GOPATH="$(pwd)/Godeps/_workspace:$GOPATH" go test -coverprofile=profile.out $dir
if [ -f profile.out ] ; then
# and if there was test output, append it to coverage.out
grep -v "mode: " profile.out >> coverage.out
rm profile.out
fi
done
notCovered=$(egrep -c '\s0$' coverage.out)
total=$(wc -l coverage.out | awk '{print $1}')
coverPct=$(awk "BEGIN{print (1 - $notCovered / $total) * 100}")
echo "Total coverage is $coverPct%"
gocov convert coverage.out | gocov-xml > coverage.xml
# This is usually run from within Jenkins. If it is, we need to
# tweak the paths in coverage.xml so cobertura finds the
# source.
if [[ "${WORKSPACE:-default}" != "default" ]] ; then
sed "s#$WORKSPACE##g" < coverage.xml > coverage.xml.new && mv coverage.xml.new coverage.xml
fi
;;
test-xunit)
ulimit -t 600 &>/dev/null || true
ulimit -d 512000 &>/dev/null || true

View File

@@ -9,6 +9,7 @@ import (
"github.com/AudriusButkevicius/cli"
"github.com/syncthing/syncthing/lib/config"
"github.com/syncthing/syncthing/lib/fs"
)
func init() {
@@ -102,8 +103,10 @@ func foldersList(c *cli.Context) {
if !first {
fmt.Fprintln(writer)
}
fs := folder.Filesystem()
fmt.Fprintln(writer, "ID:\t", folder.ID, "\t")
fmt.Fprintln(writer, "Path:\t", folder.RawPath, "\t(directory)")
fmt.Fprintln(writer, "Path:\t", fs.URI(), "\t(directory)")
fmt.Fprintln(writer, "Path type:\t", fs.Type(), "\t(directory-type)")
fmt.Fprintln(writer, "Folder type:\t", folder.Type, "\t(type)")
fmt.Fprintln(writer, "Ignore permissions:\t", folder.IgnorePerms, "\t(permissions)")
fmt.Fprintln(writer, "Rescan interval in seconds:\t", folder.RescanIntervalS, "\t(rescan)")
@@ -124,8 +127,9 @@ func foldersAdd(c *cli.Context) {
abs, err := filepath.Abs(c.Args()[1])
die(err)
folder := config.FolderConfiguration{
ID: c.Args()[0],
RawPath: filepath.Clean(abs),
ID: c.Args()[0],
Path: filepath.Clean(abs),
FilesystemType: fs.FilesystemTypeBasic,
}
cfg.Folders = append(cfg.Folders, folder)
setConfig(c, cfg)
@@ -185,7 +189,9 @@ func foldersGet(c *cli.Context) {
}
switch arg {
case "directory":
fmt.Println(folder.RawPath)
fmt.Println(folder.Filesystem().URI())
case "directory-type":
fmt.Println(folder.Filesystem().Type())
case "type":
fmt.Println(folder.Type)
case "permissions":
@@ -197,7 +203,7 @@ func foldersGet(c *cli.Context) {
fmt.Println(folder.Versioning.Type)
}
default:
die("Invalid property: " + c.Args()[1] + "\nAvailable properties: directory, type, permissions, versioning, versioning-<key>")
die("Invalid property: " + c.Args()[1] + "\nAvailable properties: directory, directory-type, type, permissions, versioning, versioning-<key>")
}
return
}
@@ -220,7 +226,11 @@ func foldersSet(c *cli.Context) {
}
switch arg {
case "directory":
cfg.Folders[i].RawPath = val
cfg.Folders[i].Path = val
case "directory-type":
var fsType fs.FilesystemType
fsType.UnmarshalText([]byte(val))
cfg.Folders[i].FilesystemType = fsType
case "type":
var t config.FolderType
if err := t.UnmarshalText([]byte(val)); err != nil {

View File

@@ -88,10 +88,10 @@ func startWalker(dir string, res chan<- fileInfo, abort <-chan struct{}) chan er
}
rn, _ := filepath.Rel(dir, path)
if rn == "." || rn == ".stfolder" {
if rn == "." {
return nil
}
if rn == ".stversions" {
if rn == ".stversions" || rn == ".stfolder" {
return filepath.SkipDir
}

View File

@@ -12,7 +12,7 @@ import (
"path/filepath"
"runtime"
"github.com/syncthing/syncthing/lib/osutil"
"github.com/syncthing/syncthing/lib/fs"
)
func nulString(bs []byte) string {
@@ -33,7 +33,7 @@ func defaultConfigDir() string {
return filepath.Join(os.Getenv("AppData"), "Syncthing")
case "darwin":
dir, err := osutil.ExpandTilde("~/Library/Application Support/Syncthing")
dir, err := fs.ExpandTilde("~/Library/Application Support/Syncthing")
if err != nil {
log.Fatal(err)
}
@@ -43,7 +43,7 @@ func defaultConfigDir() string {
if xdgCfg := os.Getenv("XDG_CONFIG_HOME"); xdgCfg != "" {
return filepath.Join(xdgCfg, "syncthing")
}
dir, err := osutil.ExpandTilde("~/.config/syncthing")
dir, err := fs.ExpandTilde("~/.config/syncthing")
if err != nil {
log.Fatal(err)
}

View File

@@ -2,15 +2,15 @@
<html lang="en" ng-app="syncthing" ng-controller="relayDataController">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="description" content=""/>
<meta name="author" content=""/>
<title>Relay stats</title>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css">
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css"/>
<style>
#map {
@@ -36,9 +36,9 @@
<body class="ng-cloak">
<div class="container">
<h1>Relay Pool Data</h2>
<h1>Relay Pool Data</h1>
<div ng-if="relays === undefined" class="text-center">
<img src="//cdnjs.cloudflare.com/ajax/libs/galleriffic/2.0.1/css/loader.gif"/>
<img src="//cdnjs.cloudflare.com/ajax/libs/galleriffic/2.0.1/css/loader.gif" alt=""/>
<p>Please wait while we gather data</p>
</div>
<div>
@@ -138,7 +138,7 @@
</tr>
</thead>
<tbody>
<tr ng-repeat="relay in relays | orderBy:sortType:sortReverse:sortCompare">
<tr ng-repeat="relay in relays | orderBy:sortType:sortReverse:sortCompare" ng-mouseover="relay.showMarker()" ng-mouseleave="relay.hideMarker()">
<td>{{ relay.address }}</td>
<td ng-if="relay.status === undefined" colspan="11" class="text-center">Looking up...</td>
<td ng-if-start="relay.status !== undefined">{{ relay.status.numActiveSessions }}</td>
@@ -184,10 +184,10 @@
</div>
<script src="//code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="//maps.googleapis.com/maps/api/js"></script>
<script type="text/javascript" src="//code.jquery.com/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<script type="text/javascript" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script type="text/javascript" src="//maps.googleapis.com/maps/api/js"></script>
</body>
<script>
@@ -307,13 +307,16 @@
content: $compile($scope.tooltipTemplate)(scope)[0],
});
relay.marker.addListener('mouseover', function() {
relay.showMarker = function() {
relay.marker.info.open($scope.map, relay.marker);
});
}
relay.marker.addListener('mouseout', function() {
relay.hideMarker = function() {
relay.marker.info.close();
});
}
relay.marker.addListener('mouseover', relay.showMarker);
relay.marker.addListener('mouseout', relay.hideMarker);
$scope.mapBounds.extend(relay.marker.position);
}
@@ -392,12 +395,12 @@
<span ng-if="relay.status.options['global-rate'] != undefined">
<span ng-if="relay.status.options['global-rate'] > 0">Global rate limit: {{ relay.status.options['global-rate'] | bytes }}/s</span>
<span ng-if="relay.status.options['global-rate'] == 0">Global rate limit: unlimited</span>
</br>
<br/>
</span>
<span ng-if="relay.status.options['per-session-rate'] != undefined">
<span ng-if="relay.status.options['per-session-rate'] > 0">Session rate limit: {{ relay.status.options['per-session-rate'] | bytes }}/s</span>
<span ng-if="relay.status.options['per-session-rate'] == 0">Session rate limit: unlimited</span>
</br>
<br/>
</span>
</div>
<div ng-if="!relay.status">

View File

@@ -59,6 +59,13 @@ func listener(proto, addr string, config *tls.Config) {
func protocolConnectionHandler(tcpConn net.Conn, config *tls.Config) {
conn := tls.Server(tcpConn, config)
if err := conn.SetDeadline(time.Now().Add(messageTimeout)); err != nil {
if debug {
log.Println("Weird error setting deadline:", err, "on", conn.RemoteAddr())
}
conn.Close()
return
}
err := conn.Handshake()
if err != nil {
if debug {
@@ -81,6 +88,7 @@ func protocolConnectionHandler(tcpConn net.Conn, config *tls.Config) {
conn.Close()
return
}
conn.SetDeadline(time.Time{})
id := syncthingprotocol.NewDeviceID(certs[0].Raw)
@@ -96,7 +104,9 @@ func protocolConnectionHandler(tcpConn net.Conn, config *tls.Config) {
go messageReader(conn, messages, errors)
pingTicker := time.NewTicker(pingInterval)
defer pingTicker.Stop()
timeoutTicker := time.NewTimer(networkTimeout)
defer timeoutTicker.Stop()
joined := false
for {
@@ -277,6 +287,7 @@ func sessionConnectionHandler(conn net.Conn) {
if debug {
log.Println("Weird error setting deadline:", err, "on", conn.RemoteAddr())
}
conn.Close()
return
}

View File

@@ -64,12 +64,13 @@ var (
limitCheckTimer *time.Timer
sessionLimitBps int
globalLimitBps int
overLimit int32
descriptorLimit int64
sessionLimiter *rate.Limiter
globalLimiter *rate.Limiter
sessionLimitBps int
globalLimitBps int
overLimit int32
descriptorLimit int64
sessionLimiter *rate.Limiter
globalLimiter *rate.Limiter
networkBufferSize int
statusAddr string
poolAddrs string
@@ -81,6 +82,8 @@ var (
natLease int
natRenewal int
natTimeout int
pprofEnabled bool
)
func main() {
@@ -105,6 +108,8 @@ func main() {
flag.IntVar(&natLease, "nat-lease", 60, "NAT lease length in minutes")
flag.IntVar(&natRenewal, "nat-renewal", 30, "NAT renewal frequency in minutes")
flag.IntVar(&natTimeout, "nat-timeout", 10, "NAT discovery timeout in seconds")
flag.BoolVar(&pprofEnabled, "pprof", false, "Enable the built in profiling on the status server")
flag.IntVar(&networkBufferSize, "network-buffer", 2048, "Network buffer size (two of these per proxied connection)")
flag.Parse()
if extAddress == "" {

View File

@@ -254,7 +254,7 @@ func (s *session) proxy(c1, c2 net.Conn) error {
atomic.AddInt64(&numProxies, 1)
defer atomic.AddInt64(&numProxies, -1)
buf := make([]byte, 65536)
buf := make([]byte, networkBufferSize)
for {
c1.SetReadDeadline(time.Now().Add(networkTimeout))
n, err := c1.Read(buf)

View File

@@ -6,6 +6,7 @@ import (
"encoding/json"
"log"
"net/http"
"net/http/pprof"
"runtime"
"sync/atomic"
"time"
@@ -16,8 +17,19 @@ var rc *rateCalculator
func statusService(addr string) {
rc = newRateCalculator(360, 10*time.Second, &bytesProxied)
http.HandleFunc("/status", getStatus)
if err := http.ListenAndServe(addr, nil); err != nil {
handler := http.NewServeMux()
handler.HandleFunc("/status", getStatus)
if pprofEnabled {
handler.HandleFunc("/debug/pprof/", pprof.Index)
}
srv := http.Server{
Addr: addr,
Handler: handler,
ReadTimeout: 15 * time.Second,
}
srv.SetKeepAlivesEnabled(false)
if err := srv.ListenAndServe(); err != nil {
log.Fatal(err)
}
}

59
cmd/syncthing/cpuusage.go Normal file
View File

@@ -0,0 +1,59 @@
// Copyright (C) 2017 The Syncthing Authors.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
package main
import (
"math"
"time"
metrics "github.com/rcrowley/go-metrics"
)
const cpuTickRate = 5 * time.Second
type cpuService struct {
avg metrics.EWMA
stop chan struct{}
}
func newCPUService() *cpuService {
return &cpuService{
// 10 second average. Magic alpha value comes from looking at EWMA package
// definitions of EWMA1, EWMA5. The tick rate *must* be five seconds (hard
// coded in the EWMA package).
avg: metrics.NewEWMA(1 - math.Exp(-float64(cpuTickRate)/float64(time.Second)/10.0)),
stop: make(chan struct{}),
}
}
func (s *cpuService) Serve() {
// Initialize prevUsage to an actual value returned by cpuUsage
// instead of zero, because at least Windows returns a huge negative
// number here that then slowly increments...
prevUsage := cpuUsage()
ticker := time.NewTicker(cpuTickRate)
defer ticker.Stop()
for {
select {
case <-ticker.C:
curUsage := cpuUsage()
s.avg.Update(int64((curUsage - prevUsage) / time.Millisecond))
prevUsage = curUsage
s.avg.Tick()
case <-s.stop:
return
}
}
}
func (s *cpuService) Stop() {
close(s.stop)
}
func (s *cpuService) Rate() float64 {
return s.avg.Rate()
}

View File

@@ -11,7 +11,6 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
"math"
"net"
"net/http"
"os"
@@ -29,9 +28,9 @@ import (
"github.com/syncthing/syncthing/lib/db"
"github.com/syncthing/syncthing/lib/discover"
"github.com/syncthing/syncthing/lib/events"
"github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/logger"
"github.com/syncthing/syncthing/lib/model"
"github.com/syncthing/syncthing/lib/osutil"
"github.com/syncthing/syncthing/lib/protocol"
"github.com/syncthing/syncthing/lib/rand"
"github.com/syncthing/syncthing/lib/stats"
@@ -69,6 +68,7 @@ type apiService struct {
configChanged chan struct{} // signals intentional listener close due to config change
started chan string // signals startup complete by sending the listener address, for testing only
startedOnce chan struct{} // the service has started successfully at least once
cpu rater
guiErrors logger.Recorder
systemLog logger.Recorder
@@ -100,6 +100,7 @@ type modelIntf interface {
CurrentSequence(folder string) (int64, bool)
RemoteSequence(folder string) (int64, bool)
State(folder string) (string, time.Time, error)
UsageReportingStats(version int) map[string]interface{}
}
type configIntf interface {
@@ -119,9 +120,14 @@ type configIntf interface {
type connectionsIntf interface {
Status() map[string]interface{}
NATType() string
}
func newAPIService(id protocol.DeviceID, cfg configIntf, httpsCertFile, httpsKeyFile, assetDir string, m modelIntf, defaultSub, diskSub events.BufferedSubscription, discoverer discover.CachingMux, connectionsService connectionsIntf, errors, systemLog logger.Recorder) *apiService {
type rater interface {
Rate() float64
}
func newAPIService(id protocol.DeviceID, cfg configIntf, httpsCertFile, httpsKeyFile, assetDir string, m modelIntf, defaultSub, diskSub events.BufferedSubscription, discoverer discover.CachingMux, connectionsService connectionsIntf, errors, systemLog logger.Recorder, cpu rater) *apiService {
service := &apiService{
id: id,
cfg: cfg,
@@ -142,6 +148,7 @@ func newAPIService(id protocol.DeviceID, cfg configIntf, httpsCertFile, httpsKey
startedOnce: make(chan struct{}),
guiErrors: errors,
systemLog: systemLog,
cpu: cpu,
}
return service
@@ -327,7 +334,7 @@ func (s *apiService) Serve() {
}
// Add the CORS handling
handler = corsMiddleware(handler)
handler = corsMiddleware(handler, guiCfg.InsecureAllowFrameLoading)
if addressIsLocalhost(guiCfg.Address()) && !guiCfg.InsecureSkipHostCheck {
// Verify source host
@@ -454,7 +461,7 @@ func debugMiddleware(h http.Handler) http.Handler {
})
}
func corsMiddleware(next http.Handler) http.Handler {
func corsMiddleware(next http.Handler, allowFrameLoading bool) http.Handler {
// Handle CORS headers and CORS OPTIONS request.
// CORS OPTIONS request are typically sent by browser during AJAX preflight
// when the browser initiate a POST request.
@@ -481,6 +488,27 @@ func corsMiddleware(next http.Handler) http.Handler {
return
}
// Other security related headers that should be present.
// https://www.owasp.org/index.php/Security_Headers
if !allowFrameLoading {
// We don't want to be rendered in an <iframe>,
// <frame> or <object>. (Unless we do it ourselves.
// This is also an escape hatch for people who serve
// Syncthing GUI as part of their own website
// through a proxy, so they don't need to set the
// allowFrameLoading bool.)
w.Header().Set("X-Frame-Options", "SAMEORIGIN")
}
// If the browser senses an XSS attack it's allowed to take
// action. (How this would not always be the default I
// don't fully understand.)
w.Header().Set("X-XSS-Protection", "1; mode=block")
// Our content type headers are correct. Don't guess.
w.Header().Set("X-Content-Type-Options", "nosniff")
// For everything else, pass to the next handler
next.ServeHTTP(w, r)
return
@@ -774,18 +802,6 @@ func (s *apiService) postSystemConfig(w http.ResponseWriter, r *http.Request) {
}
}
// Fixup usage reporting settings
if curAcc := s.cfg.Options().URAccepted; to.Options.URAccepted > curAcc {
// UR was enabled
to.Options.URAccepted = usageReportVersion
to.Options.URUniqueID = rand.String(8)
} else if to.Options.URAccepted < curAcc {
// UR was disabled
to.Options.URAccepted = -1
to.Options.URUniqueID = ""
}
// Activate and save
if err := s.cfg.Replace(to); err != nil {
@@ -847,35 +863,11 @@ func (s *apiService) flushResponse(resp string, w http.ResponseWriter) {
f.Flush()
}
// 10 second average. Magic alpha value comes from looking at EWMA package
// definitions of EWMA1, EWMA5. The tick rate *must* be five seconds (hard
// coded in the EWMA package).
var cpuTickRate = 5 * time.Second
var cpuAverage = metrics.NewEWMA(1 - math.Exp(-float64(cpuTickRate)/float64(time.Second)/10.0))
func init() {
if !innerProcess {
return
}
go func() {
// Initialize prevUsage to an actual value returned by cpuUsage
// instead of zero, because at least Windows returns a huge negative
// number here that then slowly increments...
prevUsage := cpuUsage()
for range time.NewTicker(cpuTickRate).C {
curUsage := cpuUsage()
cpuAverage.Update(int64((curUsage - prevUsage) / time.Millisecond))
prevUsage = curUsage
cpuAverage.Tick()
}
}()
}
func (s *apiService) getSystemStatus(w http.ResponseWriter, r *http.Request) {
var m runtime.MemStats
runtime.ReadMemStats(&m)
tilde, _ := osutil.ExpandTilde("~")
tilde, _ := fs.ExpandTilde("~")
res := make(map[string]interface{})
res["myID"] = myID.String()
res["goroutines"] = runtime.NumGoroutine()
@@ -899,8 +891,9 @@ func (s *apiService) getSystemStatus(w http.ResponseWriter, r *http.Request) {
res["connectionServiceStatus"] = s.connectionsService.Status()
// cpuUsage.Rate() is in milliseconds per second, so dividing by ten
// gives us percent
res["cpuPercent"] = cpuAverage.Rate() / 10 / float64(runtime.NumCPU())
res["cpuPercent"] = s.cpu.Rate() / 10 / float64(runtime.NumCPU())
res["pathSeparator"] = string(filepath.Separator)
res["urVersionMax"] = usageReportVersion
res["uptime"] = int(time.Since(startTime).Seconds())
res["startTime"] = startTime
@@ -979,7 +972,11 @@ func (s *apiService) getSystemDiscovery(w http.ResponseWriter, r *http.Request)
}
func (s *apiService) getReport(w http.ResponseWriter, r *http.Request) {
sendJSON(w, reportData(s.cfg, s.model))
version := usageReportVersion
if val, _ := strconv.Atoi(r.URL.Query().Get("version")); val > 0 {
version = val
}
sendJSON(w, reportData(s.cfg, s.model, s.connectionsService, version))
}
func (s *apiService) getRandomString(w http.ResponseWriter, r *http.Request) {
@@ -1278,23 +1275,35 @@ func (s *apiService) getPeerCompletion(w http.ResponseWriter, r *http.Request) {
func (s *apiService) getSystemBrowse(w http.ResponseWriter, r *http.Request) {
qs := r.URL.Query()
current := qs.Get("current")
// Default value or in case of error unmarshalling ends up being basic fs.
var fsType fs.FilesystemType
fsType.UnmarshalText([]byte(qs.Get("filesystem")))
if current == "" {
if roots, err := osutil.GetFilesystemRoots(); err == nil {
filesystem := fs.NewFilesystem(fsType, "")
if roots, err := filesystem.Roots(); err == nil {
sendJSON(w, roots)
} else {
http.Error(w, err.Error(), 500)
}
return
}
search, _ := osutil.ExpandTilde(current)
pathSeparator := string(os.PathSeparator)
search, _ := fs.ExpandTilde(current)
pathSeparator := string(fs.PathSeparator)
if strings.HasSuffix(current, pathSeparator) && !strings.HasSuffix(search, pathSeparator) {
search = search + pathSeparator
}
subdirectories, _ := osutil.Glob(search + "*")
searchDir := filepath.Dir(search)
searchFile := filepath.Base(search)
fs := fs.NewFilesystem(fsType, searchDir)
subdirectories, _ := fs.Glob(searchFile + "*")
ret := make([]string, 0, len(subdirectories))
for _, subdirectory := range subdirectories {
info, err := os.Stat(subdirectory)
info, err := fs.Stat(subdirectory)
if err == nil && info.IsDir() {
ret = append(ret, subdirectory+pathSeparator)
}

View File

@@ -141,17 +141,17 @@ func (s *staticsServer) serveThemes(w http.ResponseWriter, r *http.Request) {
func (s *staticsServer) mimeTypeForFile(file string) string {
// We use a built in table of the common types since the system
// TypeByExtension might be unreliable. But if we don't know, we delegate
// to the system.
// to the system. All our files are UTF-8.
ext := filepath.Ext(file)
switch ext {
case ".htm", ".html":
return "text/html"
return "text/html; charset=utf-8"
case ".css":
return "text/css"
return "text/css; charset=utf-8"
case ".js":
return "application/javascript"
return "application/javascript; charset=utf-8"
case ".json":
return "application/json"
return "application/json; charset=utf-8"
case ".png":
return "image/png"
case ".ttf":
@@ -159,7 +159,7 @@ func (s *staticsServer) mimeTypeForFile(file string) string {
case ".woff":
return "application/x-font-woff"
case ".svg":
return "image/svg+xml"
return "image/svg+xml; charset=utf-8"
default:
return mime.TypeByExtension(ext)
}

View File

@@ -71,7 +71,7 @@ func TestStopAfterBrokenConfig(t *testing.T) {
}
w := config.Wrap("/dev/null", cfg)
srv := newAPIService(protocol.LocalDeviceID, w, "../../test/h1/https-cert.pem", "../../test/h1/https-key.pem", "", nil, nil, nil, nil, nil, nil, nil)
srv := newAPIService(protocol.LocalDeviceID, w, "../../test/h1/https-cert.pem", "../../test/h1/https-key.pem", "", nil, nil, nil, nil, nil, nil, nil, nil)
srv.started = make(chan string)
sup := suture.NewSimple("test")
@@ -475,11 +475,12 @@ func startHTTP(cfg *mockedConfig) (string, error) {
connections := new(mockedConnections)
errorLog := new(mockedLoggerRecorder)
systemLog := new(mockedLoggerRecorder)
cpu := new(mockedCPUService)
addrChan := make(chan string)
// Instantiate the API service
svc := newAPIService(protocol.LocalDeviceID, cfg, httpsCertFile, httpsKeyFile, assetDir, model,
eventSub, diskEventSub, discoverer, connections, errorLog, systemLog)
eventSub, diskEventSub, discoverer, connections, errorLog, systemLog, cpu)
svc.started = addrChan
// Actually start the API service
@@ -930,7 +931,7 @@ func TestEventMasks(t *testing.T) {
cfg := new(mockedConfig)
defSub := new(mockedEventSub)
diskSub := new(mockedEventSub)
svc := newAPIService(protocol.LocalDeviceID, cfg, "", "", "", nil, defSub, diskSub, nil, nil, nil, nil)
svc := newAPIService(protocol.LocalDeviceID, cfg, "", "", "", nil, defSub, diskSub, nil, nil, nil, nil, nil)
if mask := svc.getEventMask(""); mask != defaultEventMask {
t.Errorf("incorrect default mask %x != %x", int64(mask), int64(defaultEventMask))
@@ -942,7 +943,7 @@ func TestEventMasks(t *testing.T) {
}
expected = 0
if mask := svc.getEventMask("WeirdEvent,something else that doens't exist"); mask != expected {
if mask := svc.getEventMask("WeirdEvent,something else that doesn't exist"); mask != expected {
t.Errorf("incorrect parsed mask %x != %x", int64(mask), int64(expected))
}

View File

@@ -13,7 +13,7 @@ import (
"strings"
"time"
"github.com/syncthing/syncthing/lib/osutil"
"github.com/syncthing/syncthing/lib/fs"
)
type locationEnum string
@@ -65,7 +65,7 @@ func expandLocations() error {
dir = strings.Replace(dir, "${"+varName+"}", value, -1)
}
var err error
dir, err = osutil.ExpandTilde(dir)
dir, err = fs.ExpandTilde(dir)
if err != nil {
return err
}
@@ -86,7 +86,7 @@ func defaultConfigDir() string {
return filepath.Join(os.Getenv("AppData"), "Syncthing")
case "darwin":
dir, err := osutil.ExpandTilde("~/Library/Application Support/Syncthing")
dir, err := fs.ExpandTilde("~/Library/Application Support/Syncthing")
if err != nil {
l.Fatalln(err)
}
@@ -96,7 +96,7 @@ func defaultConfigDir() string {
if xdgCfg := os.Getenv("XDG_CONFIG_HOME"); xdgCfg != "" {
return filepath.Join(xdgCfg, "syncthing")
}
dir, err := osutil.ExpandTilde("~/.config/syncthing")
dir, err := fs.ExpandTilde("~/.config/syncthing")
if err != nil {
l.Fatalln(err)
}
@@ -106,7 +106,7 @@ func defaultConfigDir() string {
// homeDir returns the user's home directory, or dies trying.
func homeDir() string {
home, err := osutil.ExpandTilde("~")
home, err := fs.ExpandTilde("~")
if err != nil {
l.Fatalln(err)
}

View File

@@ -37,6 +37,7 @@ import (
"github.com/syncthing/syncthing/lib/dialer"
"github.com/syncthing/syncthing/lib/discover"
"github.com/syncthing/syncthing/lib/events"
"github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/logger"
"github.com/syncthing/syncthing/lib/model"
"github.com/syncthing/syncthing/lib/osutil"
@@ -235,6 +236,7 @@ type RuntimeOptions struct {
resetDeltaIdxs bool
showVersion bool
showPaths bool
showDeviceId bool
doUpgrade bool
doUpgradeCheck bool
upgradeTo string
@@ -269,7 +271,7 @@ func defaultRuntimeOptions() RuntimeOptions {
}
if os.Getenv("STTRACE") != "" {
options.logFlags = log.Ltime | log.Ldate | log.Lmicroseconds | log.Lshortfile
options.logFlags = logger.DebugFlags
}
if runtime.GOOS != "windows" {
@@ -300,6 +302,7 @@ func parseCommandLineOptions() RuntimeOptions {
flag.BoolVar(&options.doUpgradeCheck, "upgrade-check", false, "Check for available upgrade")
flag.BoolVar(&options.showVersion, "version", false, "Show version")
flag.BoolVar(&options.showPaths, "paths", false, "Show configuration paths")
flag.BoolVar(&options.showDeviceId, "device-id", false, "Show the device ID")
flag.StringVar(&options.upgradeTo, "upgrade-to", options.upgradeTo, "Force upgrade directly from specified URL")
flag.BoolVar(&options.auditEnabled, "audit", false, "Write events to audit file")
flag.BoolVar(&options.verbose, "verbose", false, "Print verbose log output")
@@ -389,6 +392,17 @@ func main() {
return
}
if options.showDeviceId {
cert, err := tls.LoadX509KeyPair(locations[locCertFile], locations[locKeyFile])
if err != nil {
l.Fatalln("Error reading device ID:", err)
}
myID = protocol.NewDeviceID(cert.Certificate[0])
fmt.Println(myID)
return
}
if options.browserOnly {
openGUI()
return
@@ -427,34 +441,6 @@ func main() {
return
}
// ---BEGIN TEMPORARY HACK---
//
// Remove once v0.14.21-v0.14.22 are rare enough. Those versions,
// essentially:
//
// 1. os.Setenv("STMONITORED", "yes")
// 2. os.Setenv("STNORESTART", "")
//
// where the intention was for 2 to cancel out 1 instead of setting
// STNORESTART to the empty value. We check for exactly this combination
// and pretend that neither was set. Looking through os.Environ lets us
// distinguish. Luckily, we weren't smart enough to use os.Unsetenv.
matches := 0
for _, str := range os.Environ() {
if str == "STNORESTART=" {
matches++
}
if str == "STMONITORED=yes" {
matches++
}
}
if matches == 2 {
innerProcess = false
}
// ---END TEMPORARY HACK---
if innerProcess || options.noRestart {
syncthingMain(options)
} else {
@@ -463,7 +449,7 @@ func main() {
}
func openGUI() {
cfg, _ := loadConfig()
cfg, _ := loadOrDefaultConfig()
if cfg.GUI().Enabled {
openURL(cfg.GUI().URL())
} else {
@@ -472,7 +458,7 @@ func openGUI() {
}
func generate(generateDir string) {
dir, err := osutil.ExpandTilde(generateDir)
dir, err := fs.ExpandTilde(generateDir)
if err != nil {
l.Fatalln("generate:", err)
}
@@ -502,9 +488,7 @@ func generate(generateDir string) {
l.Warnln("Config exists; will not overwrite.")
return
}
var myName, _ = os.Hostname()
var newCfg = defaultConfig(myName)
var cfg = config.Wrap(cfgFile, newCfg)
var cfg = defaultConfig(cfgFile)
err = cfg.Save()
if err != nil {
l.Warnln("Failed to save config", err)
@@ -534,7 +518,7 @@ func debugFacilities() string {
}
func checkUpgrade() upgrade.Release {
cfg, _ := loadConfig()
cfg, _ := loadOrDefaultConfig()
opts := cfg.Options()
release, err := upgrade.LatestRelease(opts.ReleasesURL, Version, opts.UpgradeToPreReleases)
if err != nil {
@@ -572,7 +556,7 @@ func performUpgrade(release upgrade.Release) {
}
func upgradeViaRest() error {
cfg, _ := loadConfig()
cfg, _ := loadOrDefaultConfig()
u, err := url.Parse(cfg.GUI().URL())
if err != nil {
return err
@@ -665,12 +649,10 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
l.Infoln(LongVersion)
l.Infoln("My ID:", myID)
// Select SHA256 implementation and report. Affected by the
// STHASHING environment variable.
sha256.SelectAlgo()
sha256.Report()
perfWithWeakHash := cpuBench(3, 150*time.Millisecond, true)
l.Infof("Hashing performance with weak hash is %.02f MB/s", perfWithWeakHash)
perfWithoutWeakHash := cpuBench(3, 150*time.Millisecond, false)
l.Infof("Hashing performance without weak hash is %.02f MB/s", perfWithoutWeakHash)
// Emit the Starting event, now that we know who we are.
@@ -679,7 +661,7 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
"myID": myID.String(),
})
cfg := loadOrCreateConfig()
cfg := loadConfigAtStartup()
if err := checkShortIDs(cfg); err != nil {
l.Fatalln("Short device IDs are in conflict. Unlucky!\n Regenerate the device ID of one of the following:\n ", err)
@@ -723,6 +705,11 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
opts := cfg.Options()
if opts.WeakHashSelectionMethod == config.WeakHashAuto {
perfWithWeakHash := cpuBench(3, 150*time.Millisecond, true)
l.Infof("Hashing performance with weak hash is %.02f MB/s", perfWithWeakHash)
perfWithoutWeakHash := cpuBench(3, 150*time.Millisecond, false)
l.Infof("Hashing performance without weak hash is %.02f MB/s", perfWithoutWeakHash)
if perfWithoutWeakHash*0.8 > perfWithWeakHash {
l.Infof("Weak hash disabled, as it has an unacceptable performance impact.")
weakhash.Enabled = false
@@ -795,7 +782,7 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
ldb.ConvertSymlinkTypes()
}
m := model.NewModel(cfg, myID, myDeviceName(cfg), "syncthing", Version, ldb, protectedFiles)
m := model.NewModel(cfg, myID, "syncthing", Version, ldb, protectedFiles)
if t := os.Getenv("STDEADLOCKTIMEOUT"); len(t) > 0 {
it, err := strconv.Atoi(t)
@@ -893,24 +880,14 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
// Unique ID will be set and config saved below if necessary.
}
if opts.URAccepted > 0 && opts.URAccepted < usageReportVersion {
l.Infoln("Anonymous usage report has changed; revoking acceptance")
opts.URAccepted = 0
opts.URUniqueID = ""
cfg.SetOptions(opts)
}
if opts.URAccepted >= usageReportVersion && opts.URUniqueID == "" {
// Generate and save a new unique ID if it is missing.
if opts.URUniqueID == "" {
opts.URUniqueID = rand.String(8)
cfg.SetOptions(opts)
cfg.Save()
}
// The usageReportingManager registers itself to listen to configuration
// changes, and there's nothing more we need to tell it from the outside.
// Hence we don't keep the returned pointer.
newUsageReportingManager(cfg, m)
usageReportingSvc := newUsageReportingService(cfg, m, connectionsService)
mainService.Add(usageReportingSvc)
if opts.RestartOnWakeup {
go standbyMonitor()
@@ -964,15 +941,6 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
os.Exit(code)
}
func myDeviceName(cfg *config.Wrapper) string {
devices := cfg.Devices()
myName := devices[myID].Name
if myName == "" {
myName, _ = os.Hostname()
}
return myName
}
func setupSignalHandling() {
// Exit cleanly with "restarting" code on SIGHUP.
@@ -995,26 +963,28 @@ func setupSignalHandling() {
}()
}
func loadConfig() (*config.Wrapper, error) {
func loadOrDefaultConfig() (*config.Wrapper, error) {
cfgFile := locations[locConfigFile]
cfg, err := config.Load(cfgFile, myID)
if err != nil {
myName, _ := os.Hostname()
newCfg := defaultConfig(myName)
cfg = config.Wrap(cfgFile, newCfg)
cfg = defaultConfig(cfgFile)
}
return cfg, err
}
func loadOrCreateConfig() *config.Wrapper {
cfg, err := loadConfig()
func loadConfigAtStartup() *config.Wrapper {
cfgFile := locations[locConfigFile]
cfg, err := config.Load(cfgFile, myID)
if os.IsNotExist(err) {
cfg = defaultConfig(cfgFile)
cfg.Save()
l.Infof("Defaults saved. Edit %s to taste or use the GUI\n", cfg.ConfigPath())
l.Infof("Default config saved. Edit %s to taste or use the GUI\n", cfg.ConfigPath())
} else if err == io.EOF {
l.Fatalln("Failed to load config: unexpected end of file. Truncated or empty configuration?")
} else if err != nil {
l.Fatalln("Config:", err)
l.Fatalln("Failed to load config:", err)
}
if cfg.RawCopy().OriginalVersion != config.CurrentVersion {
@@ -1102,26 +1072,32 @@ func setupGUI(mainService *suture.Supervisor, cfg *config.Wrapper, m *model.Mode
l.Warnln("Insecure admin access is enabled.")
}
api := newAPIService(myID, cfg, locations[locHTTPSCertFile], locations[locHTTPSKeyFile], runtimeOptions.assetDir, m, defaultSub, diskSub, discoverer, connectionsService, errors, systemLog)
cpu := newCPUService()
mainService.Add(cpu)
api := newAPIService(myID, cfg, locations[locHTTPSCertFile], locations[locHTTPSKeyFile], runtimeOptions.assetDir, m, defaultSub, diskSub, discoverer, connectionsService, errors, systemLog, cpu)
cfg.Subscribe(api)
mainService.Add(api)
if cfg.Options().StartBrowser && !runtimeOptions.noBrowser && !runtimeOptions.stRestarting {
// Can potentially block if the utility we are invoking doesn't
// fork, and just execs, hence keep it in it's own routine.
// fork, and just execs, hence keep it in its own routine.
<-api.startedOnce
go openURL(guiCfg.URL())
}
}
func defaultConfig(myName string) config.Configuration {
func defaultConfig(cfgFile string) *config.Wrapper {
myName, _ := os.Hostname()
var defaultFolder config.FolderConfiguration
if !noDefaultFolder {
l.Infoln("Default folder created and/or linked to new config")
defaultFolder = config.NewFolderConfiguration("default", locations[locDefFolder])
defaultFolder = config.NewFolderConfiguration("default", fs.FilesystemTypeBasic, locations[locDefFolder])
defaultFolder.Label = "Default Folder"
defaultFolder.RescanIntervalS = 60
defaultFolder.FSWatcherDelayS = 10
defaultFolder.MinDiskFree = config.Size{Value: 1, Unit: "%"}
defaultFolder.Devices = []config.FolderDeviceConfiguration{{DeviceID: myID}}
defaultFolder.AutoNormalize = true
@@ -1158,7 +1134,7 @@ func defaultConfig(myName string) config.Configuration {
}
}
return newCfg
return config.Wrap(cfgFile, newCfg)
}
func resetDB() error {
@@ -1175,19 +1151,20 @@ func shutdown() {
stop <- exitSuccess
}
func ensureDir(dir string, mode os.FileMode) {
err := osutil.MkdirAll(dir, mode)
func ensureDir(dir string, mode fs.FileMode) {
fs := fs.NewFilesystem(fs.FilesystemTypeBasic, dir)
err := fs.MkdirAll(".", mode)
if err != nil {
l.Fatalln(err)
}
if fi, err := os.Stat(dir); err == nil {
if fi, err := fs.Stat("."); err == nil {
// Apprently the stat may fail even though the mkdirall passed. If it
// does, we'll just assume things are in order and let other things
// fail (like loading or creating the config...).
currentMode := fi.Mode() & 0777
if currentMode != mode {
err := os.Chmod(dir, mode)
err := fs.Chmod(".", mode)
// This can fail on crappy filesystems, nothing we can do about it.
if err != nil {
l.Warnln(err)
@@ -1310,22 +1287,22 @@ func cleanConfigDirectory() {
}
for pat, dur := range patterns {
pat = filepath.Join(baseDirs["config"], pat)
files, err := osutil.Glob(pat)
fs := fs.NewFilesystem(fs.FilesystemTypeBasic, baseDirs["config"])
files, err := fs.Glob(pat)
if err != nil {
l.Infoln("Cleaning:", err)
continue
}
for _, file := range files {
info, err := osutil.Lstat(file)
info, err := fs.Lstat(file)
if err != nil {
l.Infoln("Cleaning:", err)
continue
}
if time.Since(info.ModTime()) > dur {
if err = os.RemoveAll(file); err != nil {
if err = fs.RemoveAll(file); err != nil {
l.Infoln("Cleaning:", err)
} else {
l.Infoln("Cleaned away old file", filepath.Base(file))

View File

@@ -11,3 +11,7 @@ type mockedConnections struct{}
func (m *mockedConnections) Status() map[string]interface{} {
return nil
}
func (m *mockedConnections) NATType() string {
return ""
}

View File

@@ -1,13 +1,13 @@
// Copyright (C) 2016 The Syncthing Authors.
// Copyright (C) 2017 The Syncthing Authors.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
// +build !windows
package main
package osutil
type mockedCPUService struct{}
func GetFilesystemRoots() ([]string, error) {
return []string{"/"}, nil
func (*mockedCPUService) Rate() float64 {
return 42
}

View File

@@ -114,3 +114,7 @@ func (m *mockedModel) RemoteSequence(folder string) (int64, bool) {
func (m *mockedModel) State(folder string) (string, time.Time, error) {
return "", time.Time{}, nil
}
func (m *mockedModel) UsageReportingStats(version int) map[string]interface{} {
return nil
}

View File

@@ -0,0 +1,88 @@
// Copyright (C) 2017 The Syncthing Authors.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
package main
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
"time"
)
func TestAutoClosedFile(t *testing.T) {
os.RemoveAll("_autoclose")
defer os.RemoveAll("_autoclose")
os.Mkdir("_autoclose", 0755)
file := filepath.FromSlash("_autoclose/tmp")
data := []byte("hello, world\n")
// An autoclosed file that closes very quickly
ac := newAutoclosedFile(file, time.Millisecond, time.Millisecond)
// Write some data.
if _, err := ac.Write(data); err != nil {
t.Fatal(err)
}
// Wait for it to close
start := time.Now()
for {
time.Sleep(time.Millisecond)
ac.mut.Lock()
fd := ac.fd
ac.mut.Unlock()
if fd == nil {
break
}
if time.Since(start) > time.Second {
t.Fatal("File should have been closed after first write")
}
}
// Write more data, which should be an append.
if _, err := ac.Write(data); err != nil {
t.Fatal(err)
}
// Close.
if err := ac.Close(); err != nil {
t.Fatal(err)
}
// The file should have both writes in it.
bs, err := ioutil.ReadFile(file)
if err != nil {
t.Fatal(err)
}
if len(bs) != 2*len(data) {
t.Fatalf("Writes failed, expected %d bytes, not %d", 2*len(data), len(bs))
}
// Open the file again.
ac = newAutoclosedFile(file, time.Second, time.Second)
// Write something
if _, err := ac.Write(data); err != nil {
t.Fatal(err)
}
// It should now contain only one write, because the first open
// should be a truncate.
bs, err = ioutil.ReadFile(file)
if err != nil {
t.Fatal(err)
}
if len(bs) != len(data) {
t.Fatalf("Write failed, expected %d bytes, not %d", len(data), len(bs))
}
// Close.
if err := ac.Close(); err != nil {
t.Fatal(err)
}
}

View File

@@ -12,7 +12,7 @@ import (
"crypto/rand"
"crypto/tls"
"encoding/json"
"fmt"
"net"
"net/http"
"runtime"
"sort"
@@ -20,71 +20,25 @@ import (
"time"
"github.com/syncthing/syncthing/lib/config"
"github.com/syncthing/syncthing/lib/connections"
"github.com/syncthing/syncthing/lib/dialer"
"github.com/syncthing/syncthing/lib/model"
"github.com/syncthing/syncthing/lib/protocol"
"github.com/syncthing/syncthing/lib/scanner"
"github.com/syncthing/syncthing/lib/upgrade"
"github.com/thejerf/suture"
)
// Current version number of the usage report, for acceptance purposes. If
// fields are added or changed this integer must be incremented so that users
// are prompted for acceptance of the new report.
const usageReportVersion = 2
type usageReportingManager struct {
cfg *config.Wrapper
model *model.Model
sup *suture.Supervisor
}
func newUsageReportingManager(cfg *config.Wrapper, m *model.Model) *usageReportingManager {
mgr := &usageReportingManager{
cfg: cfg,
model: m,
}
// Start UR if it's enabled.
mgr.CommitConfiguration(config.Configuration{}, cfg.RawCopy())
// Listen to future config changes so that we can start and stop as
// appropriate.
cfg.Subscribe(mgr)
return mgr
}
func (m *usageReportingManager) VerifyConfiguration(from, to config.Configuration) error {
return nil
}
func (m *usageReportingManager) CommitConfiguration(from, to config.Configuration) bool {
if to.Options.URAccepted >= usageReportVersion && m.sup == nil {
// Usage reporting was turned on; lets start it.
service := newUsageReportingService(m.cfg, m.model)
m.sup = suture.NewSimple("usageReporting")
m.sup.Add(service)
m.sup.ServeBackground()
} else if to.Options.URAccepted < usageReportVersion && m.sup != nil {
// Usage reporting was turned off
m.sup.Stop()
m.sup = nil
}
return true
}
func (m *usageReportingManager) String() string {
return fmt.Sprintf("usageReportingManager@%p", m)
}
const usageReportVersion = 3
// reportData returns the data to be sent in a usage report. It's used in
// various places, so not part of the usageReportingManager object.
func reportData(cfg configIntf, m modelIntf) map[string]interface{} {
func reportData(cfg configIntf, m modelIntf, connectionsService connectionsIntf, version int) map[string]interface{} {
opts := cfg.Options()
res := make(map[string]interface{})
res["urVersion"] = usageReportVersion
res["urVersion"] = version
res["uniqueID"] = opts.URUniqueID
res["version"] = Version
res["longVersion"] = LongVersion
@@ -227,25 +181,162 @@ func reportData(cfg configIntf, m modelIntf) map[string]interface{} {
res["upgradeAllowedAuto"] = !(upgrade.DisabledByCompilation || noUpgradeFromEnv) && opts.AutoUpgradeIntervalH > 0
res["upgradeAllowedPre"] = !(upgrade.DisabledByCompilation || noUpgradeFromEnv) && opts.AutoUpgradeIntervalH > 0 && opts.UpgradeToPreReleases
if version >= 3 {
res["uptime"] = int(time.Now().Sub(startTime).Seconds())
res["natType"] = connectionsService.NATType()
res["alwaysLocalNets"] = len(opts.AlwaysLocalNets) > 0
res["cacheIgnoredFiles"] = opts.CacheIgnoredFiles
res["overwriteRemoteDeviceNames"] = opts.OverwriteRemoteDevNames
res["progressEmitterEnabled"] = opts.ProgressUpdateIntervalS > -1
res["customDefaultFolderPath"] = opts.DefaultFolderPath != "~"
res["weakHashSelection"] = opts.WeakHashSelectionMethod.String()
res["customTrafficClass"] = opts.TrafficClass != 0
res["customTempIndexMinBlocks"] = opts.TempIndexMinBlocks != 10
res["temporariesDisabled"] = opts.KeepTemporariesH == 0
res["temporariesCustom"] = opts.KeepTemporariesH != 24
res["limitBandwidthInLan"] = opts.LimitBandwidthInLan
res["customReleaseURL"] = opts.ReleasesURL != "https://upgrades.syncthing.net/meta.json"
res["restartOnWakeup"] = opts.RestartOnWakeup
res["customStunServers"] = len(opts.StunServers) == 0 || opts.StunServers[0] != "default" || len(opts.StunServers) > 1
folderUsesV3 := map[string]int{
"scanProgressDisabled": 0,
"conflictsDisabled": 0,
"conflictsUnlimited": 0,
"conflictsOther": 0,
"disableSparseFiles": 0,
"disableTempIndexes": 0,
"alwaysWeakHash": 0,
"customWeakHashThreshold": 0,
"fsWatcherEnabled": 0,
}
pullOrder := make(map[string]int)
filesystemType := make(map[string]int)
var fsWatcherDelays []int
for _, cfg := range cfg.Folders() {
if cfg.ScanProgressIntervalS < 0 {
folderUsesV3["scanProgressDisabled"]++
}
if cfg.MaxConflicts == 0 {
folderUsesV3["conflictsDisabled"]++
} else if cfg.MaxConflicts < 0 {
folderUsesV3["conflictsUnlimited"]++
} else {
folderUsesV3["conflictsOther"]++
}
if cfg.DisableSparseFiles {
folderUsesV3["disableSparseFiles"]++
}
if cfg.DisableTempIndexes {
folderUsesV3["disableTempIndexes"]++
}
if cfg.WeakHashThresholdPct < 0 {
folderUsesV3["alwaysWeakHash"]++
} else if cfg.WeakHashThresholdPct != 25 {
folderUsesV3["customWeakHashThreshold"]++
}
if cfg.FSWatcherEnabled {
folderUsesV3["fsWatcherEnabled"]++
}
pullOrder[cfg.Order.String()]++
filesystemType[cfg.FilesystemType.String()]++
fsWatcherDelays = append(fsWatcherDelays, cfg.FSWatcherDelayS)
}
sort.Ints(fsWatcherDelays)
folderUsesV3Interface := map[string]interface{}{
"pullOrder": pullOrder,
"filesystemType": filesystemType,
"fsWatcherDelays": fsWatcherDelays,
}
for key, value := range folderUsesV3 {
folderUsesV3Interface[key] = value
}
res["folderUsesV3"] = folderUsesV3Interface
guiCfg := cfg.GUI()
// Anticipate multiple GUI configs in the future, hence store counts.
guiStats := map[string]int{
"enabled": 0,
"useTLS": 0,
"useAuth": 0,
"insecureAdminAccess": 0,
"debugging": 0,
"insecureSkipHostCheck": 0,
"insecureAllowFrameLoading": 0,
"listenLocal": 0,
"listenUnspecified": 0,
}
theme := make(map[string]int)
if guiCfg.Enabled {
guiStats["enabled"]++
if guiCfg.UseTLS() {
guiStats["useTLS"]++
}
if len(guiCfg.User) > 0 && len(guiCfg.Password) > 0 {
guiStats["useAuth"]++
}
if guiCfg.InsecureAdminAccess {
guiStats["insecureAdminAccess"]++
}
if guiCfg.Debugging {
guiStats["debugging"]++
}
if guiCfg.InsecureSkipHostCheck {
guiStats["insecureSkipHostCheck"]++
}
if guiCfg.InsecureAllowFrameLoading {
guiStats["insecureAllowFrameLoading"]++
}
addr, err := net.ResolveTCPAddr("tcp", guiCfg.Address())
if err == nil {
if addr.IP.IsLoopback() {
guiStats["listenLocal"]++
} else if addr.IP.IsUnspecified() {
guiStats["listenUnspecified"]++
}
}
theme[guiCfg.Theme]++
}
guiStatsInterface := map[string]interface{}{
"theme": theme,
}
for key, value := range guiStats {
guiStatsInterface[key] = value
}
res["guiStats"] = guiStatsInterface
}
for key, value := range m.UsageReportingStats(version) {
res[key] = value
}
return res
}
type usageReportingService struct {
cfg *config.Wrapper
model *model.Model
stop chan struct{}
cfg *config.Wrapper
model *model.Model
connectionsService *connections.Service
forceRun chan struct{}
stop chan struct{}
}
func newUsageReportingService(cfg *config.Wrapper, model *model.Model) *usageReportingService {
return &usageReportingService{
cfg: cfg,
model: model,
stop: make(chan struct{}),
func newUsageReportingService(cfg *config.Wrapper, model *model.Model, connectionsService *connections.Service) *usageReportingService {
svc := &usageReportingService{
cfg: cfg,
model: model,
connectionsService: connectionsService,
forceRun: make(chan struct{}),
stop: make(chan struct{}),
}
cfg.Subscribe(svc)
return svc
}
func (s *usageReportingService) sendUsageReport() error {
d := reportData(s.cfg, s.model)
d := reportData(s.cfg, s.model, s.connectionsService, s.cfg.Options().URAccepted)
var b bytes.Buffer
json.NewEncoder(&b).Encode(d)
@@ -264,27 +355,45 @@ func (s *usageReportingService) sendUsageReport() error {
func (s *usageReportingService) Serve() {
s.stop = make(chan struct{})
l.Infoln("Starting usage reporting")
defer l.Infoln("Stopping usage reporting")
t := time.NewTimer(time.Duration(s.cfg.Options().URInitialDelayS) * time.Second) // time to initial report at start
t := time.NewTimer(time.Duration(s.cfg.Options().URInitialDelayS) * time.Second)
for {
select {
case <-s.stop:
return
case <-s.forceRun:
t.Reset(0)
case <-t.C:
err := s.sendUsageReport()
if err != nil {
l.Infoln("Usage report:", err)
if s.cfg.Options().URAccepted >= 2 {
err := s.sendUsageReport()
if err != nil {
l.Infoln("Usage report:", err)
} else {
l.Infof("Sent usage report (version %d)", s.cfg.Options().URAccepted)
}
}
t.Reset(24 * time.Hour) // next report tomorrow
}
}
}
func (s *usageReportingService) VerifyConfiguration(from, to config.Configuration) error {
return nil
}
func (s *usageReportingService) CommitConfiguration(from, to config.Configuration) bool {
if from.Options.URAccepted != to.Options.URAccepted || from.Options.URUniqueID != to.Options.URUniqueID || from.Options.URURL != to.Options.URURL {
s.forceRun <- struct{}{}
}
return true
}
func (s *usageReportingService) Stop() {
close(s.stop)
close(s.forceRun)
}
func (usageReportingService) String() string {
return "usageReportingService"
}
// cpuBench returns CPU performance as a measure of single threaded SHA-256 MiB/s

16
etc/freebsd-rc/README.md Normal file
View File

@@ -0,0 +1,16 @@
This directory contains an example for running Syncthing with a `rc.d` script in FreeBSD.
* Install `syncthing` in `/usr/local/bin/syncthing`.
* Copy the `syncthing` rc.d script in `/usr/local/etc/rc.d/syncthing`.
* To automatically start `syncthing` at boot time, add the following line to `/etc/rc.conf`:
```
syncthing_enable=YES
```
* Optional configuration options are:
```
syncthing_home=</path/to/syncthing/config/dir>
syncthing_log_file=</path/to/syncthing/log/file>
syncthing_user=<syncthing_user>
syncthing_group=<syncthing_group>
```
See the rc.d script for more informations.

54
etc/freebsd-rc/syncthing Normal file
View File

@@ -0,0 +1,54 @@
#!/bin/sh
#
#
# PROVIDE: syncthing
# REQUIRE: DAEMON
# KEYWORD: shutdown
#
# Add the following lines to /etc/rc.conf to enable this service:
#
# syncthing_enable: Set to NO by default. Set it to YES to enable it.
# syncthing_home: Directory where syncthing configuration
# data is stored.
# Default: /usr/local/etc/syncthing
# syncthing_log_file: Syncthing log file
# Default: /var/log/syncthing.log
# syncthing_user: The user account syncthing daemon runs as what
# you want it to be.
# Default: syncthing
# syncthing_group: The group account syncthing daemon runs as what
# you want it to be.
# Default: syncthing
. /etc/rc.subr
name=syncthing
rcvar=syncthing_enable
start_cmd="${name}_start"
load_rc_config $name
: ${syncthing_enable:=NO}
: ${syncthing_home=/usr/local/etc/syncthing}
: ${syncthing_log_file=/var/log/syncthing.log}
: ${syncthing_user:=syncthing}
syncthing_group=${syncthing_group:-$syncthing_user}
command=/usr/local/bin/syncthing
pidfile=/var/run/syncthing.pid
syncthing_flags="${syncthing_home:+-home=${syncthing_home}} ${syncthing_log_file:+-logfile=${syncthing_log_file}}"
syncthing_start() {
echo "Starting syncthing"
touch ${pidfile} && chown ${syncthing_user} ${pidfile}
touch ${syncthing_log_file} && chown ${syncthing_user} ${syncthing_log_file}
/usr/sbin/daemon -cf -p ${pidfile} -u ${syncthing_user} ${command} ${syncthing_flags}
}
syncthing_cleanup() {
[ -f ${pidfile} ] && rm ${pidfile}
}
run_rc_command $1

View File

@@ -5,7 +5,7 @@ the "Upstart" service manager on Linux. To have syncthing start when you login
place "user/syncthing.conf" in the "/home/[username]/.config/upstart/" folder.
To have syncthing start when the system boots place "system/syncthing.conf"
in the "/etc/init/" folder.
To manualy start syncthing via Upstart when using the system configuration use:
To manually start syncthing via Upstart when using the system configuration use:
```
sudo initctl start syncthing

View File

@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Моля прочети бележките по обновяването преди да започнеш.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Моля задайте потребителско име и парола за потребителския интерфейс в секцията Настройки.",
"Please wait": "Моля изчакай",
"Prefix indicating that the file can be deleted if preventing directory removal": "Представка, която индикира, че файлът може да бъде изтрит ако пречи на премахването на папка",
"Prefix indicating that the pattern should be matched without case sensitivity": "Представка, която индикира, че зададения шаблон трябва да бъде проверен без значение за главни/малки букви",
"Preview": "Преглед",
"Preview Usage Report": "Разгледай доклада за използване",
"Quick guide to supported patterns": "Бърз наръчник към поддържаните шаблони",
@@ -181,6 +183,7 @@
"Save": "Запази",
"Scan Time Remaining": "Оставащо време за сканиране",
"Scanning": "Сканиране",
"See external versioner help for supported templated command line parameters.": "Прегледайте документацията на външното приложение за версии и поддържаните от него командни параметри. ",
"Select the devices to share this folder with.": "Изберете устройствата, с които да споделите папката.",
"Select the folders to share with this device.": "Изберете папките за споделяне с това устройство.",
"Send & Receive": "Изпращане & получаване",
@@ -271,6 +274,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "Когато добавяш ново устройство помни, че твоето устройство също трябва да бъде добавено от другата страна.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Когато добавяш нов идентификатор на папка помни, че той се използва за свързване на папките на различни устройства. Главни/малки букви са от значение и трябва да са еднакви на всички устройства.",
"Yes": "Да",
"You can also select one of these nearby devices:": "Също така може да изберете едно от следните устройтва намиращи се наблизо:",
"You can change your choice at any time in the Settings dialog.": "Може да промените решението си по всяко време в прозореца Настройки.",
"You can read more about the two release channels at the link below.": "Може да научите допълнително за двата канала на версии, следвайки връзката по-долу.",
"You must keep at least one version.": "Трябва да пазиш поне една версия.",

View File

@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Per favor, consultar les notes de la versió abans de fer una actualització important.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Per favor, estableix un usuari i password per a l'Interfície Gràfica d'Usuari en el menú d'Adjustos.",
"Please wait": "Per favor, espere",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefix indicating that the file can be deleted if preventing directory removal",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefix indicating that the pattern should be matched without case sensitivity",
"Preview": "Vista prèvia",
"Preview Usage Report": "Informe d'ús de vista prèvia",
"Quick guide to supported patterns": "Guía ràpida de patrons suportats",
@@ -181,6 +183,7 @@
"Save": "Gravar",
"Scan Time Remaining": "Temps d'escaneig restant",
"Scanning": "Rastrejant",
"See external versioner help for supported templated command line parameters.": "See external versioner help for supported templated command line parameters.",
"Select the devices to share this folder with.": "Selecciona els dispositius amb els que compartir aquesta carpeta.",
"Select the folders to share with this device.": "Selecciona les carpetes per a compartir amb aquest dispositiu.",
"Send & Receive": "Enviar i Rebre",
@@ -271,6 +274,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "Quant s'afig un nou dispositiu, hi ha que tindre en compte que aquest dispositiu deu ser afegit també en l'altre costat.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Quant s'afig una nova carpeta, hi ha que tindre en compte que l'ID de la carpeta s'utilitza per a juntar les carpetes entre dispositius. Són sensibles a les majúscules i deuen coincidir exactament entre tots els dispositius.",
"Yes": "Sí",
"You can also select one of these nearby devices:": "You can also select one of these nearby devices:",
"You can change your choice at any time in the Settings dialog.": "Pots canviar la teua elecció en qualsevol moment en el dialog Ajustos",
"You can read more about the two release channels at the link below.": "Pots llegir més sobre els dos canals de versions en l'enllaç de baix.",
"You must keep at least one version.": "Es deu mantindre al menys una versió.",

View File

@@ -10,7 +10,7 @@
"Add Device": "Přidat přístroj",
"Add Folder": "Přidat adresář",
"Add Remote Device": "Přidat vzdálené zařízení",
"Add devices from the introducer to our device list, for mutually shared folders.": "Přidat zařízení ze zavaděče do našeho seznamu zařízení (pro vzájemně sdílené adresáře.)",
"Add devices from the introducer to our device list, for mutually shared folders.": "Přidat zařízení ze zavaděče do našeho seznamu zařízení, pro vzájemně sdílené adresáře.",
"Add new folder?": "Přidat nový adresář?",
"Address": "Adresa",
"Addresses": "Adresy",
@@ -69,7 +69,7 @@
"Enable NAT traversal": "Povolit NAT přenos",
"Enable Relaying": "Povolit přenašeče",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Zadajte kladné číslo (např. \"2.35\") a zvolte jednotku. Percenta znamenají část celkové velikosti disku.",
"Enter a non-privileged port number (1024 - 65535).": "Enter a non-privileged port number (1024 - 65535).",
"Enter a non-privileged port number (1024 - 65535).": "Zadejte číslo neprivilegovaného portu (1024-65535).",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Zadejte adresy oddělené čárkou (\"tcp://ip:port\", \"tcp://host:port\") nebo \"dynamic\" pro automatické zjišťování adres.",
"Enter ignore patterns, one per line.": "Vložit ignorované vzory, jeden na řádek.",
"Error": "Chyba",
@@ -93,7 +93,7 @@
"GUI": "GUI",
"GUI Authentication Password": "Přihlašovací heslo pro GUI",
"GUI Authentication User": "Přihlašovací jméno pro GUI",
"GUI Listen Address": "GUI Listen Address",
"GUI Listen Address": "Adresa naslouchání GUI",
"GUI Listen Addresses": "Adresa naslouchání GUI",
"GUI Theme": "Grafické téma",
"Generate": "Generovat",
@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Před spuštěním důležité aktualizace si nejdříve přečtěte poznámky k vydání nové verze.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Zadejte prosím přihlašovací jméno a heslo pro GUI v dialogu nastavení.",
"Please wait": "Chvíli strpení",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefix indicating that the file can be deleted if preventing directory removal",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefix indicating that the pattern should be matched without case sensitivity",
"Preview": "Náhled",
"Preview Usage Report": "Náhled záznamu o využítí",
"Quick guide to supported patterns": "Rychlá nápověda k podporovaným vzorům",
@@ -181,6 +183,7 @@
"Save": "Uložit",
"Scan Time Remaining": "Zbývající čas skenování",
"Scanning": "Skenování",
"See external versioner help for supported templated command line parameters.": "See external versioner help for supported templated command line parameters.",
"Select the devices to share this folder with.": "Vybrat přístroje, se kterými sdílet tento adresář.",
"Select the folders to share with this device.": "Vybrat adresáře sdílené s tímto přístrojem.",
"Send & Receive": "Odeslat a přijmout",
@@ -271,6 +274,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "Při přidávání nového přístroje mějte na paměti, že je ho třeba také zadat na druhé straně.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Při přidávání nového adresáře mějte na paměti, že jeho ID je použito ke svázání adresářů napříč přístoji. Rozlišují se malá a velká písmena a musí přesně souhlasit mezi všemi přístroji.",
"Yes": "Ano",
"You can also select one of these nearby devices:": "Také můžete vybrat jedno z těchto okolních zařízení:",
"You can change your choice at any time in the Settings dialog.": "Vaši volbu můžete kdykoliv změnit v dialogu nastavení.",
"You can read more about the two release channels at the link below.": "O kandidátech na vydání si můžete přečíst více v odkazu níže.",
"You must keep at least one version.": "Je třeba ponechat alespoň jednu verzi.",

View File

@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Tjek venligst udgivelsesnoterne før opgradering til en ny version.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Sæt vensligt en GUI bruger og kodeord i opsætningsdialogen.",
"Please wait": "Vent venligst",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefix indicating that the file can be deleted if preventing directory removal",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefix indicating that the pattern should be matched without case sensitivity",
"Preview": "Forhåndsvisning",
"Preview Usage Report": "Forhåndsvisning af forbrugsrapport",
"Quick guide to supported patterns": "Hurtig guide til supporteret mønstre",
@@ -181,6 +183,7 @@
"Save": "Gem",
"Scan Time Remaining": "Tid tilbage af skanningen",
"Scanning": "Opdaterer",
"See external versioner help for supported templated command line parameters.": "See external versioner help for supported templated command line parameters.",
"Select the devices to share this folder with.": "Vælg hvilke enheder du vil dele denne mappe med",
"Select the folders to share with this device.": "Vælg hvilke mapper du vil dele med denne enhed.",
"Send & Receive": "Send & Modtag",
@@ -271,6 +274,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "Når der tilføjes en ny enhed, vær da opmærksom på, at denne enhed også skal tilføjes på den anden side.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Når der tilføjes en ny enhed, vær da opmærksom på at samme ID bruges til at forbinde mapperne på de forskellige enheder. Der er forskel på store og små bogstaver, og ID skal være fuldstændig identisk på alle enheder.",
"Yes": "Ja",
"You can also select one of these nearby devices:": "You can also select one of these nearby devices:",
"You can change your choice at any time in the Settings dialog.": "Du kan altid ændre dit valg under indstillinger.",
"You can read more about the two release channels at the link below.": "Du kan læse mere om de to udgivelseskanaler på links herunder.",
"You must keep at least one version.": "Du skal beholde mindst én version.",

View File

@@ -10,7 +10,7 @@
"Add Device": "Gerät hinzufügen",
"Add Folder": "Ordner hinzufügen",
"Add Remote Device": "Gerät hinzufügen",
"Add devices from the introducer to our device list, for mutually shared folders.": "Add devices from the introducer to our device list, for mutually shared folders.",
"Add devices from the introducer to our device list, for mutually shared folders.": "Fügt Geräte vom Verteilergerät zu der eigenen Geräteliste hinzu, um gegenseitig geteilte Ordner zu ermöglichen.",
"Add new folder?": "Neuen Ordner hinzufügen?",
"Address": "Adresse",
"Addresses": "Adressen",
@@ -21,10 +21,10 @@
"Allow Anonymous Usage Reporting?": "Übertragung von anonymen Nutzungsberichten erlauben?",
"Allowed Networks": "Erlaubte Netzwerke",
"Alphabetic": "Alphabetisch",
"An external command handles the versioning. It has to remove the file from the shared folder.": "Ein externer Befehl führt die Versionierung durch. Dazu muss die Datei aus dem geteilten Ordner entfernt werden.",
"An external command handles the versioning. It has to remove the file from the shared folder.": "Ein externer Befehl führt die Versionierung durch. Er muss die Datei aus dem geteilten Ordner entfernen.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Ein externer Programmaufruf handhabt die Versionierung. Es muss die Datei aus dem zu synchronisierendem Ordner entfernen.",
"Anonymous Usage Reporting": "Anonymer Nutzungsbericht",
"Any devices configured on an introducer device will be added to this device as well.": "Alle Geräte, die beim Verteiler eingetragen sind, werden auch bei diesem Gerät eingetragen",
"Any devices configured on an introducer device will be added to this device as well.": "Alle Geräte, die beim Verteilergerät eingetragen sind, werden auch bei diesem Gerät hinzugefügt.",
"Automatic upgrade now offers the choice between stable releases and release candidates.": "Die automatische Aktualisierung bietet jetzt die Wahl zwischen stabilen Veröffentlichungen und Veröffentlichungskandidaten.",
"Automatic upgrades": "Automatische Updates aktivieren",
"Be careful!": "Vorsicht!",
@@ -32,7 +32,7 @@
"CPU Utilization": "Prozessorauslastung",
"Changelog": "Änderungsprotokoll",
"Clean out after": "Löschen nach",
"Click to see discovery failures": "Zum Anzeigen von Gerätesuchfehlern klicken",
"Click to see discovery failures": "Klick um Gerätesuchfehler anzuzeigen",
"Close": "Schließen",
"Command": "Befehl",
"Comment, when used at the start of a line": "Kommentar, wenn am Anfang der Zeile benutzt.",
@@ -44,7 +44,7 @@
"Copied from original": "Vom Original kopiert",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 der folgenden Unterstützer:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 der folgenden Unterstützer:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Erstelle Ignoriermuster, welche die existierende Datei {{path}} überschreiben.",
"Danger!": "Achtung!",
"Deleted": "Gelöscht",
"Device": "Gerät",
@@ -65,24 +65,24 @@
"Edit Device": "Gerät bearbeiten",
"Edit Folder": "Ordner bearbeiten",
"Editing": "Bearbeitet",
"Editing {%path%}.": "{{path}} wird bearbeitet.",
"Editing {%path%}.": "Bearbeite {{path}}.",
"Enable NAT traversal": "NAT-Durchdringung aktivieren",
"Enable Relaying": "Weiterleitung aktivieren",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.",
"Enter a non-privileged port number (1024 - 65535).": "Enter a non-privileged port number (1024 - 65535).",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Geben Sie eine positive Zahl ein (z.B. \"2.35\") und wählen Sie eine Einheit. Prozentsätze sind Teil der gesamten Festplattengröße.",
"Enter a non-privileged port number (1024 - 65535).": "Geben Sie eine nichtprivilegierte Portnummer ein (1024 - 65535).",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Kommagetrennte Adressen (\"tcp://ip:port\", \"tcp://host:port\") oder \"dynamic\" eingeben, um die Adresse automatisch zu ermitteln.",
"Enter ignore patterns, one per line.": "Geben Sie Ignoriermuster ein, eines pro Zeile.",
"Error": "Fehler",
"External File Versioning": "Externe Dateiversionierung",
"Failed Items": "Fehlgeschlagene Objekte",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Es wird ein Verbindungsfehler zu IPv6-Servern erwartet, wenn es keine IPv6-Konnektivität gibt.",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Ein Verbindungsfehler zu IPv6-Servern ist zu erwarten, wenn es keine IPv6-Konnektivität gibt.",
"File Pull Order": "Dateiübertragungsreihenfolge",
"File Versioning": "Dateiversionierung",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Dateizugriffsrechte beim Suchen nach Veränderungen ignorieren. Bei FAT-Dateisystemen zu verwenden.",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Dateien werden in das .stversions-Verzeichnis verschoben, wenn sie von Syncthing ersetzt oder gelöscht werden.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Wenn Syncthing Dateien ersetzt oder löscht, werden sie in den Ordner .stversions verschoben.",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Dateien werden mit einem Datumsstempel im Namen versehen und in ein .stversions-Verzeichnis verschoben, wenn sie von Syncthing ersetzt oder gelöscht werden.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Dateien werden, bevor Syncthing sie löscht oder ersetzt, datiert in den Ordner .stversions verschoben.",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Dateien werden in den .stversions Ordner verschoben, wenn sie von Syncthing ersetzt oder gelöscht werden.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Dateien werden in den .stversions Ordner verschoben, wenn sie von Syncthing ersetzt oder gelöscht werden.",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Dateien werden mit Datumsstempel versioniert und in den .stversions Ordner verschoben, wenn sie von Syncthing ersetzt oder gelöscht werden.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Dateien werden mit Datumsstempel versioniert und in den .stversions Ordner verschoben, wenn sie von Syncthing ersetzt oder gelöscht werden.",
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Dateien sind auf diesem Gerät schreibgeschützt. Auf diesem Gerät durchgeführte Veränderungen werden aber auf den Rest des Verbunds übertragen.",
"Folder": "Ordner",
"Folder ID": "Ordnerkennung",
@@ -93,9 +93,9 @@
"GUI": "GUI",
"GUI Authentication Password": "Passwort für Zugang zur Benutzeroberfläche",
"GUI Authentication User": "Nutzername für Zugang zur Benutzeroberfläche",
"GUI Listen Address": "GUI Listen Address",
"GUI Listen Addresses": "Adresse(n) für die Benutzeroberfläche",
"GUI Theme": "GUI-Theme",
"GUI Listen Address": "Addresse der Benutzeroberfläche",
"GUI Listen Addresses": "Adressen der Benutzeroberfläche",
"GUI Theme": "GUI Design",
"Generate": "Generieren",
"Global Changes": "Globale Änderungen",
"Global Discovery": "Globale Gerätesuche",
@@ -123,7 +123,7 @@
"Local Discovery": "Lokale Gerätesuche",
"Local State": "Lokaler Status",
"Local State (Total)": "Lokaler Status (Gesamt)",
"Major Upgrade": "Hauptversionsupgrade",
"Major Upgrade": "Hauptversionsupdate",
"Master": "Master",
"Maximum Age": "Höchstalter",
"Metadata Only": "Nur Metadaten",
@@ -136,7 +136,7 @@
"Newest First": "Neueste zuerst",
"No": "Nein",
"No File Versioning": "Keine Dateiversionierung",
"No upgrades": "Keine Upgrades",
"No upgrades": "Keine Updates",
"Normal": "Normal",
"Notice": "Hinweis",
"OK": "OK",
@@ -150,14 +150,16 @@
"Override Changes": "Änderungen überschreiben",
"Path": "Pfad",
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "Pfad zum Ordner auf dem lokalen Gerät. Ordner wird erzeugt, wenn er nicht existiert. Das Tilden-Zeichen (~) kann als Abkürzung benutzt werden für",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "Pfad, in dem Versionen gespeichert werden sollen (leer lassen, wenn das Standard-.stversions-Verzeichnis im geteilten Ordner verwendet werden soll).",
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Pfad in dem alte Dateiversionen gespeichert werden sollen (ohne Angabe wird der Ordner .stversions im Ordner verwendet).",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "Pfad in dem Versionen gespeichert werden sollen (leer lassen, wenn der Standard .stversions Ordner für den geteilten Ordner verwendet werden soll).",
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Pfad in dem Versionen gespeichert werden sollen (leer lassen, wenn der Standard .stversions Ordner für den geteilten Ordner verwendet werden soll).",
"Pause": "Pause",
"Pause All": "Alles pausieren",
"Paused": "Pausiert",
"Please consult the release notes before performing a major upgrade.": "Bitte lesen Sie die Veröffentlichungsnotizen bevor Sie eine neue Hauptversion installieren.",
"Please consult the release notes before performing a major upgrade.": "Bitte lesen Sie die Veröffentlichungsnotizen bevor Sie ein neues Hauptversionsupdate installieren.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Bitte setze einen Benutzer und ein Passwort für das GUI in den Einstellungen.",
"Please wait": "Bitte warten",
"Prefix indicating that the file can be deleted if preventing directory removal": "Präfix, das anzeigt, dass die Datei gelöscht werden kann, wenn sie die Entfernung des Ordners verhindert",
"Prefix indicating that the pattern should be matched without case sensitivity": "Präfix, das anzeigt, dass das Muster ohne Beachtung der Groß-/Kleinschreibung übereinstimmen soll",
"Preview": "Vorschau",
"Preview Usage Report": "Vorschau des Nutzungsberichts",
"Quick guide to supported patterns": "Schnellanleitung zu den unterstützten Mustern",
@@ -165,7 +167,7 @@
"Random": "Zufall",
"Reduced by ignore patterns": "Durch Ignoriermuster reduziert",
"Release Notes": "Veröffentlichungsnotizen",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Veröffentlichungskandidaten enthalten die neuesten Funktionen und Verbesserungen. Sie ähneln den traditionellen zweiwöchentlichen Syncthing-Veröffentlichungen.",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Veröffentlichungskandidaten enthalten die neuesten Funktionen und Verbesserungen. Sie gleichen den üblichen zweiwöchentlichen Syncthing-Veröffentlichungen.",
"Remote Devices": "Fern-Geräte",
"Remove": "Entfernen",
"Required identifier for the folder. Must be the same on all cluster devices.": "Erforderlicher Bezeichner für den Ordner. Muss auf allen Verbund-Geräten gleich sein.",
@@ -181,6 +183,7 @@
"Save": "Speichern",
"Scan Time Remaining": "Zeit für Scan verbleibend",
"Scanning": "Scannen",
"See external versioner help for supported templated command line parameters.": "Siehe externe Versionshilfe für unterstützte Befehlszeilenparameter.",
"Select the devices to share this folder with.": "Wähle die Geräte aus, mit denen Du diesen Ordner teilen willst.",
"Select the folders to share with this device.": "Wähle die Ordner aus, die Du mit diesem Gerät teilen möchtest",
"Send & Receive": "Senden & empfangen",
@@ -203,8 +206,8 @@
"Smallest First": "Kleinstes zuerst",
"Source Code": "Quellcode",
"Stable releases and release candidates": "Stabile Veröffentlichungen und Veröffentlichungskandidaten",
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "Stabile Veröffentlichungen werden ca. 2 Wochen zurückgehalten. Während dieser Zeit durchlaufen sie eine Testphase als Veröffentlichungskandidaten.",
"Stable releases only": "Ausschließlich stabile Veröffentlichungen",
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "Stabile Veröffentlichungen werden ca. 2 Wochen verzögert. Während dieser Zeit durchlaufen sie eine Testphase als Veröffentlichungskandidaten.",
"Stable releases only": "Nur stabile Veröffentlichungen",
"Staggered File Versioning": "Stufenweise Dateiversionierung",
"Start Browser": "Browser starten",
"Statistics": "Statistiken",
@@ -244,8 +247,8 @@
"They are retried automatically and will be synced when the error is resolved.": "Sie werden automatisch heruntergeladen und werden synchronisiert, wenn der Fehler behoben wurde.",
"This Device": "Dieses Gerät",
"This can easily give hackers access to read and change any files on your computer.": "Dies kann dazu führen, dass Unberechtigte relativ einfach auf Ihre Dateien zugreifen und diese ändern können.",
"This is a major version upgrade.": "Dies ist eine neue Hauptversion.",
"This setting controls the free space required on the home (i.e., index database) disk.": "This setting controls the free space required on the home (i.e., index database) disk.",
"This is a major version upgrade.": "Dies ist ein neues Hauptversionsupdate.",
"This setting controls the free space required on the home (i.e., index database) disk.": "Diese Einstellung regelt den freien Speicherplatz, der für den Systemordner (d.h. Indexdatenbank) erforderlich ist.",
"Time": "Zeit",
"Trash Can File Versioning": "Papierkorb Dateiversionierung",
"Type": "Typ",
@@ -254,12 +257,12 @@
"Unused": "Ungenutzt",
"Up to Date": "Aktuell",
"Updated": "Aktualisiert",
"Upgrade": "Upgrade",
"Upgrade": "Update",
"Upgrade To {%version%}": "Update auf {{version}}",
"Upgrading": "Wird aktualisiert",
"Upload Rate": "Upload",
"Uptime": "Betriebszeit",
"Usage reporting is always enabled for candidate releases.": "Nutzungsauswertung ist für Veröffentlichungskandidaten immer aktiviert.",
"Usage reporting is always enabled for candidate releases.": "Nutzungsbericht ist für Veröffentlichungskandidaten immer aktiviert.",
"Use HTTPS for GUI": "HTTPS für Benutzeroberfläche benutzen",
"Version": "Version",
"Versions Path": "Versionierungspfad",
@@ -271,8 +274,9 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "Beachte beim Hinzufügen eines neuen Gerätes, dass dieses Gerät auch auf den anderen Geräten hinzugefügt werden muss.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Beachte bitte beim Hinzufügen eines neuen Ordners, dass die Ordnerkennung dazu verwendet wird, Ordner zwischen Geräten zu verbinden. Die Kennung muss also auf allen Geräten gleich sein, die Groß- und Kleinschreibung muss dabei beachtet werden.",
"Yes": "Ja",
"You can also select one of these nearby devices:": "Sie können auch ein in der Nähe befindliches Geräte auswählen:",
"You can change your choice at any time in the Settings dialog.": "Sie können Ihre Wahl jederzeit in den Einstellungen ändern.",
"You can read more about the two release channels at the link below.": "Über den untenstehenden Link können Sie mehr über die zwei Veröffentlichungskanäle erfahren.",
"You can read more about the two release channels at the link below.": "Über den folgenden Link können Sie mehr über die zwei Veröffentlichungskanäle erfahren.",
"You must keep at least one version.": "Du musst mindestens eine Version behalten.",
"days": "Tage",
"directories": "Ordner",

View File

@@ -77,7 +77,7 @@
"Failed Items": "Αρχεία που απέτυχαν",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Είναι φυσιολογική η αποτυχία σύνδεσης σε εξυπηρετητές IPv6 όταν δεν υπάρχει συνδεσιμότητα IPv6.",
"File Pull Order": "Σειρά με την οποία θα κατεβαίνουν τα αρχεία",
"File Versioning": "Τήρηση εκδόσεων",
"File Versioning": "Τήρηση εκδόσεων αρχείων",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Τα δικαιώματα των αρχείων θα αγνοούνται όταν κοιτάζω για αλλαγές. Αφορά συστήματα αρχείων FAT.",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Τα αρχεία που σβήνονται ή αντικαθίστανται από το Syncthing μετακινούνται στον κατάλογο .stversions.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Τα αρχεία που σβήνονται ή αντικαθιστούνται από το Syncthing μετακινούνται σε έναν φάκελο .stversions με χρονοσφραγίδα.",
@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Παρακαλούμε, πριν από την εκτέλεση μιας σημαντικής αναβάθμισης, να συμβουλευτείς το σημείωμα που τη συνοδεύει. ",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Παρακαλώ όρισε στις ρυθμίσεις έναν χρήστη και έναν κωδικό πρόσβασης για τη διεπαφή.",
"Please wait": "Παρακαλώ περιμένετε",
"Prefix indicating that the file can be deleted if preventing directory removal": "Πρόθεμα που δείχνει ότι το αρχείο θα μπορεί να διαγραφεί αν εμποδίζει τη διαγραφή καταλόγου",
"Prefix indicating that the pattern should be matched without case sensitivity": "Πρόθεμα που δείχνει ότι η αντιστοίχιση προτύπου θα γίνεται χωρίς διάκριση πεζών και κεφαλαίων χαρακτήρων",
"Preview": "Προεπισκόπηση",
"Preview Usage Report": "Προεπισκόπηση αναφοράς χρήσης",
"Quick guide to supported patterns": "Σύντομη βοήθεια σχετικά με τα πρότυπα αναζήτησης που υποστηρίζονται",
@@ -181,6 +183,7 @@
"Save": "Αποθήκευση",
"Scan Time Remaining": "Εναπομείναντας χρόνος για τον έλεγχο ",
"Scanning": "Έλεγχος για αλλαγές",
"See external versioner help for supported templated command line parameters.": "Ανατρέξτε στην τεκμηρίωση της εξωτερικής τήρησης εκδόσεων για πληροφορίες σχετικά με τις υποστηριζόμενες παραμέτρους της γραμμής εντολών.",
"Select the devices to share this folder with.": "Διάλεξε τις συσκευές προς τις οποίες θα διαμοιράζεται αυτός ο φάκελος.",
"Select the folders to share with this device.": "Διάλεξε ποιοι φάκελοι θα διαμοιράζονται προς αυτή τη συσκευή.",
"Send & Receive": "Αποστολή και λήψη",
@@ -235,7 +238,7 @@
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Η μέγιστη ηλικία παλιότερων εκδόσεων (σε ημέρες, αν δώσεις 0 οι παλιότερες εκδόσεις θα διατηρούνται για πάντα).",
"The minimum free disk space percentage must be a non-negative number between 0 and 100 (inclusive).": "Το ποσοστό του ελάχιστου διαθέσιμου αποθηκευτικόυ χώρου πρέπει να είναι έναν μη-αρνητικός αριθμός μεταξύ του 0 και του 100 (συμπεριλαμβανομένων)",
"The number of days must be a number and cannot be blank.": "Ο αριθμός ημερών πρέπει να είναι αριθμός και σίγουρα όχι κενό.",
"The number of days to keep files in the trash can. Zero means forever.": "Ο αριθμός ημερών που θα διατηρούντα τα αρχεία στον κάδο. Μηδέν σημαίνει διατήρηση για πάντα.",
"The number of days to keep files in the trash can. Zero means forever.": "Ο αριθμός ημερών που θα διατηρούνται τα αρχεία στον κάδο. Μηδέν σημαίνει διατήρηση για πάντα.",
"The number of old versions to keep, per file.": "Πόσες παλιότερες εκδόσεις θα διατηρούνται, ανά αρχείο.",
"The number of versions must be a number and cannot be blank.": "Ο αριθμός εκδόσεων πρέπει να είναι αριθμός και σίγουρα όχι κενό.",
"The path cannot be blank.": "Το μονοπάτι δεν μπορεί να είναι κενό.",
@@ -271,6 +274,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "Θυμήσου πως όταν προσθέτεις μια νέα συσκευή, ετούτη η συσκευή θα πρέπει να προστεθεί και στην άλλη πλευρά.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Όταν προσθέτεις έναν νέο φάκελο, θυμήσου πως η ταυτότητα ενός φακέλου χρησιμοποιείται για να να συσχετίσει φακέλους μεταξύ συσκευών. Η ταυτότητα του φακέλου θα πρέπει να είναι η ίδια σε όλες τις συσκευές και έχουν σημασία τα πεζά ή κεφαλαία γράμματα.",
"Yes": "Ναι",
"You can also select one of these nearby devices:": "Μπορείτε επίσης να επιλέξετε μια από αυτές τις γειτονικές συσκευές:",
"You can change your choice at any time in the Settings dialog.": "Μπορείτε να αλλάξετε τη ρύθμιση αυτή ανά πάσα στιγμή στο παράθυρο «Ρυθμίσεις».",
"You can read more about the two release channels at the link below.": "Μπορείτε να διαβάσετε περισσότερα για τα δύο κανάλια εκδόσεων στον παρακάτω σύνδεσμο.",
"You must keep at least one version.": "Πρέπει να τηρήσεις τουλάχιστον μια έκδοση.",

View File

@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Please consult the release notes before performing a major upgrade.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Please set a GUI Authentication User and Password in the Settings dialogue.",
"Please wait": "Please wait",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefix indicating that the file can be deleted if preventing directory removal",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefix indicating that the pattern should be matched without case sensitivity",
"Preview": "Preview",
"Preview Usage Report": "Preview Usage Report",
"Quick guide to supported patterns": "Quick guide to supported patterns",
@@ -165,7 +167,7 @@
"Random": "Random",
"Reduced by ignore patterns": "Reduced by ignore patterns",
"Release Notes": "Release Notes",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Release candidates contain the latest features and fixes. They are similar to the traditional fortnightly Syncthing releases.",
"Remote Devices": "Remote Devices",
"Remove": "Remove",
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
@@ -181,6 +183,7 @@
"Save": "Save",
"Scan Time Remaining": "Scan Time Remaining",
"Scanning": "Scanning",
"See external versioner help for supported templated command line parameters.": "See external versioner help for supported templated command line parameters.",
"Select the devices to share this folder with.": "Select the devices to share this folder with.",
"Select the folders to share with this device.": "Select the folders to share with this device.",
"Send & Receive": "Send & Receive",
@@ -271,7 +274,8 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "When adding a new device, keep in mind that this device must be added on the other side too.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.",
"Yes": "Yes",
"You can change your choice at any time in the Settings dialog.": "You can change your choice at any time in the Settings dialog.",
"You can also select one of these nearby devices:": "You can also select one of these nearby devices:",
"You can change your choice at any time in the Settings dialog.": "You can change your choice at any time in the Settings dialogue.",
"You can read more about the two release channels at the link below.": "You can read more about the two release channels at the link below.",
"You must keep at least one version.": "You must keep at least one version.",
"days": "days",

View File

@@ -24,6 +24,7 @@
"An external command handles the versioning. It has to remove the file from the shared folder.": "An external command handles the versioning. It has to remove the file from the shared folder.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "An external command handles the versioning. It has to remove the file from the synced folder.",
"Anonymous Usage Reporting": "Anonymous Usage Reporting",
"Anonymous usage report format has changed. Would you like to move to the new format?": "Anonymous usage report format has changed. Would you like to move to the new format?",
"Any devices configured on an introducer device will be added to this device as well.": "Any devices configured on an introducer device will be added to this device as well.",
"Automatic upgrade now offers the choice between stable releases and release candidates.": "Automatic upgrade now offers the choice between stable releases and release candidates.",
"Automatic upgrades": "Automatic upgrades",
@@ -53,6 +54,7 @@
"Device Identification": "Device Identification",
"Device Name": "Device Name",
"Devices": "Devices",
"Disabled": "Disabled",
"Disconnected": "Disconnected",
"Discovered": "Discovered",
"Discovery": "Discovery",
@@ -158,6 +160,8 @@
"Please consult the release notes before performing a major upgrade.": "Please consult the release notes before performing a major upgrade.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Please set a GUI Authentication User and Password in the Settings dialog.",
"Please wait": "Please wait",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefix indicating that the file can be deleted if preventing directory removal",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefix indicating that the pattern should be matched without case sensitivity",
"Preview": "Preview",
"Preview Usage Report": "Preview Usage Report",
"Quick guide to supported patterns": "Quick guide to supported patterns",
@@ -181,6 +185,9 @@
"Save": "Save",
"Scan Time Remaining": "Scan Time Remaining",
"Scanning": "Scanning",
"See external versioner help for supported templated command line parameters.": "See external versioner help for supported templated command line parameters.",
"See external versioning help for supported templated command line parameters.": "See external versioning help for supported templated command line parameters.",
"Select a version": "Select a version",
"Select the devices to share this folder with.": "Select the devices to share this folder with.",
"Select the folders to share with this device.": "Select the folders to share with this device.",
"Send \u0026 Receive": "Send \u0026 Receive",
@@ -194,6 +201,7 @@
"Shared With": "Shared With",
"Show ID": "Show ID",
"Show QR": "Show QR",
"Show diff with previous version": "Show diff with previous version",
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.",
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.",
"Shutdown": "Shutdown",
@@ -249,6 +257,7 @@
"Time": "Time",
"Trash Can File Versioning": "Trash Can File Versioning",
"Type": "Type",
"Undecided (will prompt)": "Undecided (will prompt)",
"Unknown": "Unknown",
"Unshared": "Unshared",
"Unused": "Unused",
@@ -271,6 +280,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "When adding a new device, keep in mind that this device must be added on the other side too.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.",
"Yes": "Yes",
"You can also select one of these nearby devices:": "You can also select one of these nearby devices:",
"You can change your choice at any time in the Settings dialog.": "You can change your choice at any time in the Settings dialog.",
"You can read more about the two release channels at the link below.": "You can read more about the two release channels at the link below.",
"You must keep at least one version.": "You must keep at least one version.",

View File

@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Bonvolu konsulti la eldonitajn notojn antaŭ elfari ĉefan ĝisdatigon.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Bonvolu agordi GUI Authentication Uzanto kaj Pasvorto en la agordoj dialogo.",
"Please wait": "Bonvolu atendi",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefix indicating that the file can be deleted if preventing directory removal",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefix indicating that the pattern should be matched without case sensitivity",
"Preview": "Antaŭrigardo",
"Preview Usage Report": "Antaŭrigardo Uzada Raporto",
"Quick guide to supported patterns": "Rapida gvidisto al subtenata ŝablonoj",
@@ -181,6 +183,7 @@
"Save": "Konservu",
"Scan Time Remaining": "Skanada Restanta Tempo",
"Scanning": "Skanado",
"See external versioner help for supported templated command line parameters.": "See external versioner help for supported templated command line parameters.",
"Select the devices to share this folder with.": "Elekti la aparatojn por komunigi ĉi tiun dosierujon.",
"Select the folders to share with this device.": "Elekti la dosierujojn por komunigi kun ĉi tiu aparato.",
"Send & Receive": "Sendi kaj Ricevi",
@@ -271,6 +274,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "Dum la aldonado de nova aparato, memoru ke ĉi tiu aparato devas esti aldonita en la alia flanko ankaŭ.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Dum la aldonado de nova dosierujo, memoru ke la Dosieruja ID estas uzita por ligi la dosierujojn kune inter aparatoj. Ili estas literfakodistingaj kaj devas kongrui precize inter ĉiuj aparatoj.",
"Yes": "Jes",
"You can also select one of these nearby devices:": "You can also select one of these nearby devices:",
"You can change your choice at any time in the Settings dialog.": "Vi povas ŝanĝi vian elekton iam ajn en la Agorda dialogo.",
"You can read more about the two release channels at the link below.": "Vi povas legi plu pri la du eldonkanaloj per la malsupra ligilo.",
"You must keep at least one version.": "Vi devas konservi almenaŭ unu version.",

View File

@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Por favor, consultar las notas de la versión antes de realizar una actualización importante.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Por favor, introduzca un Usuario y Contraseña para la Autenticación de la Interfaz de Usuario en el panel de Ajustes.",
"Please wait": "Por favor, espere",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefix indicating that the file can be deleted if preventing directory removal",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefix indicating that the pattern should be matched without case sensitivity",
"Preview": "Vista previa",
"Preview Usage Report": "Informe de uso de vista previa",
"Quick guide to supported patterns": "Guía rápida de patrones soportados",
@@ -181,6 +183,7 @@
"Save": "Guardar",
"Scan Time Remaining": "Tiempo Restante de Escaneo",
"Scanning": "Analizando",
"See external versioner help for supported templated command line parameters.": "See external versioner help for supported templated command line parameters.",
"Select the devices to share this folder with.": "Selecciona los dispositivos con los que compartir esta carpeta.",
"Select the folders to share with this device.": "Selecciona las carpetas para compartir con este dispositivo.",
"Send & Receive": "Enviar y Recibir",
@@ -271,6 +274,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "Cuando añada un nuevo dispositivo, tenga en cuenta que este debe añadirse también en el otro lado.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Cuando añada una nueva carpeta, tenga en cuenta que su ID se usa para unir carpetas entre dispositivos. Son sensibles a las mayúsculas y deben coincidir exactamente entre todos los dispositivos.",
"Yes": "Si",
"You can also select one of these nearby devices:": "You can also select one of these nearby devices:",
"You can change your choice at any time in the Settings dialog.": "Puedes cambiar tu elección en cualquier momento en el panel de Ajustes.",
"You can read more about the two release channels at the link below.": "Puedes leer más sobre los dos método de publicación de versiones en el siguiente enlace.",
"You must keep at least one version.": "Debes mantener al menos una versión.",

View File

@@ -1,284 +1,288 @@
{
"A device with that ID is already added.": "Ya se ha agregado un dispositivo con esa ID.",
"A device with that ID is already added.": "Ya se ha agregado un equipo con ese ID.",
"A negative number of days doesn't make sense.": "Un número negativo de días no tiene sentido.",
"A new major version may not be compatible with previous versions.": "Una versión más reciente puede no ser compatible con las versiones anteriores.",
"API Key": "Clave API",
"A new major version may not be compatible with previous versions.": "Una nueva versión con cambios importantes puede no ser compatible con versiones anteriores.",
"API Key": "Clave del API",
"About": "Acerca de",
"Action": "Acción ",
"Action": "Acción",
"Actions": "Acciones",
"Add": "Agregar",
"Add Device": "Agregar Dispositivo",
"Add Folder": "Agregar Repositorio",
"Add Remote Device": "Agregar Dispositivo Remoto",
"Add devices from the introducer to our device list, for mutually shared folders.": "Add devices from the introducer to our device list, for mutually shared folders.",
"Add new folder?": "¿Agregar nueva carpeta?",
"Add Device": "Agregar el dispositivo",
"Add Folder": "Agregar Carpeta",
"Add Remote Device": "Añadir un dispositivo",
"Add devices from the introducer to our device list, for mutually shared folders.": "Añadir dispositivos desde el introductor a nuestra lista de dispositivos, para las carpetas compartidas mutuamente.",
"Add new folder?": "¿Agregar una carpeta nueva?",
"Address": "Dirección",
"Addresses": "Direcciones",
"Advanced": "Avanzada",
"Advanced Configuration": "Configuración avanzada",
"Advanced settings": "Optiones avanzadas",
"Advanced": "Avanzado",
"Advanced Configuration": "Configuración Avanzada",
"Advanced settings": "Ajustes avanzados",
"All Data": "Todos los datos",
"Allow Anonymous Usage Reporting?": "Permitir reporte anónimo de uso?",
"Allowed Networks": "Allowed Networks",
"Allow Anonymous Usage Reporting?": "¿Deseas permitir el envío anónimo de informes de uso?",
"Allowed Networks": "Redes permitidas",
"Alphabetic": "Alfabético",
"An external command handles the versioning. It has to remove the file from the shared folder.": "An external command handles the versioning. It has to remove the file from the shared folder.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Un comando exterior maneja el control de versiones. Éste tiene que eliminar el archivo de la carpeta sincronizada.",
"Anonymous Usage Reporting": "Reporte anónimo de uso",
"Any devices configured on an introducer device will be added to this device as well.": "Cualquier dispositivo configurado en un dispositivo introductor será también agregado a tu propio dispositivo.",
"Automatic upgrade now offers the choice between stable releases and release candidates.": "La actualización automática ofrece la opción entre versiones estables y versiones preliminares.",
"An external command handles the versioning. It has to remove the file from the shared folder.": "Un comando externo gestiona las versiones. Tiene que eliminar el fichero de la carpeta compartida.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Un comando externo controla la versión. El fichero debe ser eliminado de la carpeta sincronizada.",
"Anonymous Usage Reporting": "Informe anónimo de uso",
"Any devices configured on an introducer device will be added to this device as well.": "Cualquier dispositivo configurado en un dispositivo de introducción será añadido también.",
"Automatic upgrade now offers the choice between stable releases and release candidates.": "Ahora la actualización automática permite elegir entre versiones estables o versiones candidatas.",
"Automatic upgrades": "Actualizaciones automáticas",
"Be careful!": cuidadoso!",
"Be careful!": Ten cuidado!",
"Bugs": "Errores",
"CPU Utilization": "Uso de CPU",
"Changelog": "Registro de cambios",
"Clean out after": "Limpiar después",
"Click to see discovery failures": "Click to see discovery failures",
"Clean out after": "Limpiar tras",
"Click to see discovery failures": "Clica para ver fallos de descubrimiento.",
"Close": "Cerrar",
"Command": "Comando",
"Comment, when used at the start of a line": "Comentario, cuando es utilizado al inicio de una línea.",
"Command": "Acción",
"Comment, when used at the start of a line": "Comentar, cuando se usa al comienzo de una línea",
"Compression": "Compresión",
"Configured": "Configurado",
"Connection Error": "Error de conexión",
"Connection Type": "Tipo de conexión",
"Copied from elsewhere": "Copiado desde otra parte.",
"Copied from elsewhere": "Copiado de otro sitio",
"Copied from original": "Copiado del original",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 los siguientes contribuidores:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 los siguientes contribuidores:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "Peligro!",
"Deleted": "Suprimido",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 los siguientes Colaboradores:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 Los siguientes colaboradores:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Crear patrones a ignorar, sobreescribiendo un fichero existente en {{path}}.",
"Danger!": "¡Peligro!",
"Deleted": "Eliminado",
"Device": "Dispositivo",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Dispositivo \"{{name}}\" ({{device}} en {{address}}) quiere conectar. ¿Añadir nuevo dispositivo?",
"Device ID": "ID del dispositivo",
"Device Identification": "Identificación del dispositivo",
"Device Name": "Nombre del dispositivo",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "El dispositivo \"{{name}}\" ({{device}} en la dirección {{address}}) quiere conectarse. Añadir nuevo dispositivo?",
"Device ID": "ID del Dispositivo",
"Device Identification": "Identificación del Dispositivo",
"Device Name": "Nombre del Dispositivo",
"Devices": "Dispositivos",
"Disconnected": "Desconectado",
"Discovered": "Descubierto",
"Discovery": "Búsqueda",
"Discovery Failures": "Discovery Failures",
"Discovery": "Descubrimiento",
"Discovery Failures": "Fallos de Descubrimiento",
"Documentation": "Documentación",
"Download Rate": "Tasa de descarga",
"Download Rate": "Velocidad de descarga",
"Downloaded": "Descargado",
"Downloading": "Descargando",
"Edit": "Editar",
"Edit Device": "Cambiando dispositivo",
"Edit Folder": "Cambiando repositorio",
"Edit Device": "Editar Dispositivo",
"Edit Folder": "Editar Carpeta",
"Editing": "Editando",
"Editing {%path%}.": "Editing {{path}}.",
"Enable NAT traversal": "Habilitar NAT trasversal",
"Editing {%path%}.": "Editando {{path}}.",
"Enable NAT traversal": "Permitir NAT transversal",
"Enable Relaying": "Habilitar Retransmisión",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.",
"Enter a non-privileged port number (1024 - 65535).": "Enter a non-privileged port number (1024 - 65535).",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Introduce las direcciones (\"tcp://ip:puerto\", \"tcp://huésped:puerto\") separadas por comas, o \"dynamic\" para ejecutar un descubrimiento automático de la dirección. ",
"Enter ignore patterns, one per line.": "Añadir patrones de exclusión, uno por línea.",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Introduce un número no negativo (por ejemplo, \"2.35\") y selecciona una unidad. Los porcentajes son como parte del tamaño total del disco.",
"Enter a non-privileged port number (1024 - 65535).": "Introduce un puerto sin privilegios (1024 - 65535).",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Introduzca las direcciones, separadas por comas (\"tcp://ip:port\", \"tcp://host:port\"), o \"dynamic\" para llevar a cabo el descubrimiento automático de la dirección.",
"Enter ignore patterns, one per line.": "Introducir patrones a ignorar, uno por línea.",
"Error": "Error",
"External File Versioning": "Control de versiones externo",
"Failed Items": "Artículos fallidos",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.",
"File Pull Order": "Orden para coger ficheros",
"File Versioning": "Control de versiones",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Los permisos de archivo son ignorados al buscar cambios. Usar el sistemas de archivos FAT.",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Files are moved to .stversions directory when replaced or deleted by Syncthing.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Los archivos son movidos al directorio .stversions cuando son reemplazados o eliminados por Syncthing. Sus caminos de accesos relativos son recreados aquí si necesidad. ",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Lo archivos son movidos al directorio .stversions y renombrados a versiones marcadas por fecha cuando son reemplazados o eliminados por Syncthing, Sus caminos de accesos relativos son recreados aquí si necesidad.",
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Los archivos están protegidos frente a los cambios realizados en otros dispositivos, peros los cambios realizados en este dispositivo serán envíados al resto del grupo",
"Folder": "Repositorio",
"Folder ID": "ID del repositorio",
"Folder Label": "Etiqueta de Carpeta",
"Folder Path": "Ruta del repositorio",
"Folder Type": "Tipo de Carpeta",
"Folders": "Repositorios",
"External File Versioning": "Versionado externo de fichero",
"Failed Items": "Elementos fallidos",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Se espera un fallo al conectar a los servidores IPv6 si no hay conectividad IPv6.",
"File Pull Order": "Orden de obtención de los ficheros",
"File Versioning": "Versionado de ficheros",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Los bits de permiso de ficheros son ignorados cuando se buscan cambios. Utilizar en sistemas de ficheros FAT.",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Los ficheros son movidos a la carpeta .stversions cuando son reemplazados o borrados por Syncthing.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Los archivos serán movidos a la carpeta .stversions cuando sean reemplazados o borrados por Syncthing.",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Los ficheros son movidos a una carpeta .stversions a versiones con control de fecha cuando son reemplazados o borrados por Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Los ficheros son cambiados a versiones con indicación de fecha en una carpeta \".stversions\" cuando son reemplazados o borrados por Syncthing.",
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Los ficheros son protegidos por los cambios hechos en otros dispositivos, pero los cambios hechos en este dispositivo serán enviados al resto del grupo (cluster).",
"Folder": "Carpeta",
"Folder ID": "ID de carpeta",
"Folder Label": "Etiqueta de la Carpeta",
"Folder Path": "Ruta de la carpeta",
"Folder Type": "Tipo de carpeta",
"Folders": "Carpetas",
"GUI": "GUI",
"GUI Authentication Password": "Contraseña de autenticación de la GUI",
"GUI Authentication User": "Usuario de la GUI",
"GUI Listen Address": "GUI Listen Address",
"GUI Listen Addresses": "Direcciones de escucha para la GUI.",
"GUI Theme": "Apariencia de la GUI",
"GUI Authentication Password": "Password de la Interfaz Gráfica de Usuario (GUI)",
"GUI Authentication User": "Autentificación de usuario de la Interfaz Gráfica de Usuario (GUI)",
"GUI Listen Address": "Dirección de Escucha del GUI.",
"GUI Listen Addresses": "Direcciones de escucha de la Interfaz Gráfica de Usuario (GUI)",
"GUI Theme": "Tema GUI",
"Generate": "Generar",
"Global Changes": "Últimas modificaciones",
"Global Discovery": "Búsqueda en internet",
"Global Discovery Servers": "Servidores globales de identificación",
"Global Changes": "Cambios globales",
"Global Discovery": "Descubrimiento global",
"Global Discovery Servers": "Servidores Globales de Descubrimiento",
"Global State": "Estado global",
"Help": "Ayuda",
"Home page": "Pagina de inicio",
"Home page": "Página de inicio",
"Ignore": "Ignorar",
"Ignore Patterns": "Patrones de exclusión",
"Ignore Permissions": "Ignorar permisos",
"Incoming Rate Limit (KiB/s)": "Límite de velocidad de entrada (KiB/s)",
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "Configuración incorrecta puede dañar los contenidos de la carpeta y hacer Syncthing inoperable.",
"Ignore Patterns": "Patrones a ignorar",
"Ignore Permissions": "Permisos a ignorar",
"Incoming Rate Limit (KiB/s)": "Límite de descarga (KiB/s)",
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "Una configuración incorrecta puede dañar los contenidos de la carpeta y hacer que Syncthing no funcione.",
"Introduced By": "Introducido por",
"Introducer": "Dispositivo introductor",
"Inversion of the given condition (i.e. do not exclude)": "Inversión de la condición dada (es decir, no excluir)",
"Keep Versions": "Conservar versiones",
"Introducer": "Presentador",
"Inversion of the given condition (i.e. do not exclude)": "Inversión de la condición dada (por ejemplo, \"no excluir\")",
"Keep Versions": "Mantener versiones",
"Largest First": "Más grande primero",
"Last File Received": "Última actualización",
"Last Scan": "Último escaneo",
"Last seen": "Visto por ultima vez",
"Last seen": "Visto por última vez",
"Later": "Más tarde",
"Latest Change": "Último cambio",
"Latest Change": "Último Cambio",
"Learn more": "Saber más",
"Listeners": "Receptor",
"Local Discovery": "Búsqueda en red local",
"Listeners": "Oyentes",
"Local Discovery": "Descubrimiento local",
"Local State": "Estado local",
"Local State (Total)": "Estado local (total)",
"Major Upgrade": "Actualización mayor",
"Local State (Total)": "Estado Local (Total)",
"Major Upgrade": "Actualización importante",
"Master": "Maestro",
"Maximum Age": "Edad máxima",
"Metadata Only": "Sólo metadatos",
"Minimum Free Disk Space": "Espacio mínimo libre en disco",
"Move to top of queue": "Mover al principio de la cola.",
"Multi level wildcard (matches multiple directory levels)": "Carácter comodín multinivel (coincide en el directorio y sus subdirectorios)",
"Move to top of queue": "Mover al principio de la cola",
"Multi level wildcard (matches multiple directory levels)": "Comodín multinivel (coincide con múltiples niveles de directorio)",
"Never": "Nunca",
"New Device": "Nuevo dispositivo",
"New Folder": "Nuevo repositorio",
"Newest First": "Nuevo primero",
"New Device": "Nuevo Dispositivo",
"New Folder": "Nueva Carpeta",
"Newest First": "El más nuevo primero",
"No": "No",
"No File Versioning": "Sin control de versiones de archivos",
"No upgrades": "No actualizaciones",
"No File Versioning": "Sin versionado de fichero",
"No upgrades": "Sin actualizaciones",
"Normal": "Normal",
"Notice": "Aviso",
"OK": "OK",
"Off": "Apagado",
"Oldest First": "Antiguo primero",
"Off": "Desconectar",
"Oldest First": "El más antiguo primero",
"Optional descriptive label for the folder. Can be different on each device.": "Etiqueta descriptiva opcional para la carpeta. Puede ser diferente en cada dispositivo.",
"Options": "Opciones",
"Out of Sync": "Fuera de sincronización",
"Out of Sync Items": "Ítems no sincronizados",
"Outgoing Rate Limit (KiB/s)": "Tasa máxima de envío (KiB/s)",
"Override Changes": "Reemplazar los cambios",
"Path": "Ruta",
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "Ruta del repositorio en el equipo local. Se creado si no existe. El carácter tilde (~) puede ser utilizado como atajo de ",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).",
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Ruta donde serán guardas las versiones (dejar vacío para usar el directorio predifinido \".stversions\" en el repositorio)",
"Pause": "Pausa",
"Pause All": "Todos en pausa",
"Paused": "En pausa",
"Please consult the release notes before performing a major upgrade.": "Por favor consulta las notas de lanzamiento antes de realizar una actualizacón mayor.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Por favor, establece un Usuario y Contraseña de Autenticación en la GUI en el diálogo de Configuración",
"Please wait": "Aguarde por favor",
"Out of Sync": "No sincronizado",
"Out of Sync Items": "Elementos no sincronizados",
"Outgoing Rate Limit (KiB/s)": "Límite de subida (KiB/s)",
"Override Changes": "Anular cambios",
"Path": "Parche",
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "Ruta a la carpeta en la máquina local. Se crea si no existe. El carácter de la tilde (~) puede usarse como atajo.",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "La ruta donde las versiones deben ser almacenadas (dejar vacío para el directorio .stversions por defecto en la carpeta compartida).",
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Ruta donde se almacenarán las versiones (dejar vacío para usar la carpeta por defecto \".stversions\").",
"Pause": "Pausar",
"Pause All": "Pausar todo",
"Paused": "Pausado",
"Please consult the release notes before performing a major upgrade.": "Por favor, consultar las notas de la versión antes de realizar una actualización importante.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Por favor, introduzca un Usuario y Contraseña para la Autenticación de la Interfaz de Usuario en el panel de Ajustes.",
"Please wait": "Por favor, espere",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefix indicating that the file can be deleted if preventing directory removal",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefix indicating that the pattern should be matched without case sensitivity",
"Preview": "Vista previa",
"Preview Usage Report": "Ver reporte de uso",
"Quick guide to supported patterns": "Guía rápida sobre los patrones soportados",
"RAM Utilization": "Utilización de RAM",
"Preview Usage Report": "Informe de uso de vista previa",
"Quick guide to supported patterns": "Guía rápida de patrones soportados",
"RAM Utilization": "Uso de RAM",
"Random": "Aleatorio",
"Reduced by ignore patterns": "(Restringido por patrones de exclusión)",
"Release Notes": "Notas de lanzamiento",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Las versiones preliminares contienen las últimas funcionalidades y los últimos correctivos. Son idénticas a las actualizaciones bimensuales tradicionales.",
"Reduced by ignore patterns": "Reducido por patrones de ignorar",
"Release Notes": "Notas de la versión",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Las versiones candidatas contienen las últimas funcionalidades y correcciones. Son similares a las tradicionales versiones bisemanales de Syncthing.",
"Remote Devices": "Otros dispositivos",
"Remove": "Eliminar",
"Required identifier for the folder. Must be the same on all cluster devices.": "Identificación requerida para la carpeta. Debe ser la misma en todos los dispositivos del grupo.",
"Rescan": "Reescanear",
"Rescan All": "Reescanear todo",
"Rescan Interval": "Intervalo de reescaneo",
"Required identifier for the folder. Must be the same on all cluster devices.": "Identificador requerido para la carpeta. Debe ser el mismo en todos los dispositivos del clúster.",
"Rescan": "Volver a analizar",
"Rescan All": "Volver a analizar Todo",
"Rescan Interval": "Intervalo de análisis",
"Restart": "Reiniciar",
"Restart Needed": "Es necesario reiniciar",
"Restart Needed": "Reinicio necesario",
"Restarting": "Reiniciando",
"Resume": "Reanudar",
"Resume All": "Reanudar todos",
"Resume": "Continuar",
"Resume All": "Continuar todo",
"Reused": "Reutilizado",
"Save": "Guardar",
"Scan Time Remaining": "Tiempo de Escaneo Restante",
"Scanning": "Actualización",
"Select the devices to share this folder with.": "Seleccione los dispositivos con los cuales compartir este repositorio.",
"Select the folders to share with this device.": "Seleccione los repositorios para compartir con este dispositivo.",
"Send & Receive": "Envío y recepción",
"Send Only": "Envío (lectura sola)",
"Settings": "Configuración",
"Scan Time Remaining": "Tiempo Restante de Escaneo",
"Scanning": "Analizando",
"See external versioner help for supported templated command line parameters.": "See external versioner help for supported templated command line parameters.",
"Select the devices to share this folder with.": "Selecciona los dispositivos con los que compartir esta carpeta.",
"Select the folders to share with this device.": "Selecciona las carpetas para compartir con este dispositivo.",
"Send & Receive": "Enviar y Recibir",
"Send Only": "Solo Enviar",
"Settings": "Ajustes",
"Share": "Compartir",
"Share Folder": "Compartir repositorio",
"Share Folders With Device": "Compartir repositorios con dispositivo",
"Share With Devices": "Compartir con los dispositivos",
"Share this folder?": "¿Compartir este repositorio?",
"Shared With": "Compartido con",
"Share Folder": "Compartir carpeta",
"Share Folders With Device": "Compartir carpetas con dispositivo",
"Share With Devices": "Compartir con dispositivos",
"Share this folder?": "¿Deseas compartir esta carpeta?",
"Shared With": "Compartir con",
"Show ID": "Mostrar ID",
"Show QR": "Mostrar QR",
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Mostrado en lugar de la ID del dispositivo en el estado del grupo. Será sugerido a otros dispositivos como nombre fácil de usar predeterminado opcional.",
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Mostrado en lugar de la ID del dispositivo en el estado del grupo. Si se deja en blanco, será llenado por el nombre fácil de usar sugerido por el dispositivo.",
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Se muestra en lugar del ID del dispositivo en el estado del grupo (cluster). Se notificará a los otros dispositivos como nombre opcional por defecto.",
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Se muestra en lugar del ID del dispositivo en el estado del grupo (cluster). Se actualizará al nombre que el dispositivo anuncia si se deja vacío.",
"Shutdown": "Apagar",
"Shutdown Complete": "Apagado completado",
"Simple File Versioning": "Versiones simple de archivos",
"Single level wildcard (matches within a directory only)": "Carácter comodín de un solo nivel (coincide sólo dentro de un directorio)",
"Smallest First": "Más pequeño primero",
"Shutdown Complete": "Apagar completamente",
"Simple File Versioning": "Versionado simple de fichero",
"Single level wildcard (matches within a directory only)": "Comodín de nivel único (coincide solamente dentro de un directorio)",
"Smallest First": "El más pequeño primero",
"Source Code": "Código fuente",
"Stable releases and release candidates": "Versiones stables y preliminares",
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "Las versiones estables son trasladadas de cerca de dos semanas. Durante este tiempo son sometidas a un test como versiones preliminares.",
"Stable releases only": "Versiones estables solamente",
"Staggered File Versioning": "Versiones del archivo escalonado",
"Start Browser": "Iniciar navegador",
"Stable releases and release candidates": "Versiones estables y versiones candidatas",
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "Las versiones estables son publicadas cada dos semanas. Durante este tiempo son probadas como versiones candidatas.",
"Stable releases only": "Solo versiones estables",
"Staggered File Versioning": "Versionado escalonado de fichero",
"Start Browser": "Iniciar el navegador",
"Statistics": "Estadísticas",
"Stopped": "Parado",
"Stopped": "Detenido",
"Support": "Forum",
"Sync Protocol Listen Addresses": "Dirección de escucha del protocolo de sincronización",
"Syncing": "Sincronización",
"Syncthing has been shut down.": "La sincronización esta apagada",
"Syncthing includes the following software or portions thereof:": "Syncthing incluye los siguientes softwares o partes de ellos:",
"Syncthing is restarting.": "Syncthing está reiniciando.",
"Sync Protocol Listen Addresses": "Direcciones de escucha del protocolo de sincronización",
"Syncing": "Sincronizando",
"Syncthing has been shut down.": "Syncthing se ha detenido.",
"Syncthing includes the following software or portions thereof:": "Syncthing incluye el siguiente software o partes de él:",
"Syncthing is restarting.": "Syncthing se está reiniciando.",
"Syncthing is upgrading.": "Syncthing se está actualizando.",
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing parece estar apagado, o hay un problema con su conexión de Internet. Reintentando...",
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing parece estar experimentando un problema al procesar su solicitud. Por favor, recargue el navegador o reinicie Syncthing si el problema persiste.",
"The Syncthing admin interface is configured to allow remote access without a password.": "La interfaz administrativa del Syncthing está configurada para permitir acceso remoto sin una contraseña.",
"The aggregated statistics are publicly available at the URL below.": "Las estadísticas agregadas están disponibles públicamente en la dirección de abajo.",
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "La configuración ha sido guardada pero no activada.\nSyncthing debe reiniciarse para activar la nueva configuración.",
"The device ID cannot be blank.": "La ID del dispositivo no puede estar en blanco.",
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "La ID de dispositivo a introducir ser puede encontrar en el menú \"Acciones > Mostrar ID\" en el otro dispositivo. Espacios y guiones son opcionales (ignorados). ",
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.": "El informe de uso se envía encriptado diariamente. Se utiliza para hacer un seguimiento de plataformas comunes, tamaño de repositorios y versiones de la aplicación. Si el conjunto de datos cambia será notificado mediante este dialogo nuevamente.",
"The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.": "La ID del dispositivo introducida no es válida. Debe ser una cadena de 52 o 56 caracteres consistente en letras y números, con espacios y guiones opcionales.",
"The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "El primer argumento es la ruta de la carpeta y el segundo argumento es la ruta relativa de esta carpeta.",
"The folder ID cannot be blank.": "La ID del repositorio no puede estar en blanco.",
"The folder ID must be unique.": "La ID del repositorio debe ser única.",
"The folder path cannot be blank.": "La ruta del repositorio no puede estar vacía.",
"The following intervals are used: for the first hour a version is kept every 30 seconds, for the first day a version is kept every hour, for the first 30 days a version is kept every day, until the maximum age a version is kept every week.": "Los siguientes intervalos se utilizan: para la primera hora una versión se mantiene cada 30 segundos, para el primer día de una versión se mantiene cada hora, durante los primeros 30 días de la versión se mantiene todos los días, hasta que la edad máxima de una versión se mantiene cada semana.",
"The following items could not be synchronized.": "Los siguientes artículos no pueden ser sincronizados.",
"The maximum age must be a number and cannot be blank.": "La edad máxima debe ser un número y no puede estar en blanco.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "El tiempo máximo para mantener una versión (en días, establece en 0 para mantener versiones para siempre).",
"The minimum free disk space percentage must be a non-negative number between 0 and 100 (inclusive).": "El porcentaje de espacio libre en disco mínimo debe ser un número no negativo entre 0 y 100 (incluidos).",
"The number of days must be a number and cannot be blank.": "El número de días debe ser un número y no puede estar vacío.",
"The number of days to keep files in the trash can. Zero means forever.": "El tiempo máximo para mantener un archivo en el cubo de basura (en días, establece en 0 para mantener versiones para siempre).",
"The number of old versions to keep, per file.": "El numero de versiones anteriores a conservar, por archivo.",
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing parece no estar activo o hay un problema con tu conexión de internet. Reintentando...",
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing tiene problemas para procesar tu solicitud. Por favor, actualiza la página o reinicia Syncthing si el problema persiste.",
"The Syncthing admin interface is configured to allow remote access without a password.": "El panel de administración de Syncthing está configurado para permitir el acceso remoto sin contraseña.",
"The aggregated statistics are publicly available at the URL below.": "Las estadísticas agragadas están disponibles públicamente en la URL de abajo.",
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "La configuración ha sido grabada pero no activada. Syncthing debe reiniciarse para activar la nueva configuración.",
"The device ID cannot be blank.": "La ID del dispositivo no puede estar vacía.",
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "El ID del dispositivo que hay que introducir aquí se puede encontrar en el diálogo \"Acciones > Mostrar ID\" en el otro dispositivo. Los espacios y las barras son opcionales (ignorados).",
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.": "El informe encriptado de uso se envía diariamente. Se usa para rastrear plataformas comunes, tamaños de carpetas y versiones de la aplicación. Si el conjunto de datos enviados en el informes se cambia, se le pedirá a usted autorización de nuevo.",
"The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.": "La ID del dispositivo introducida no parece válida. Debe ser una cadena de 52 ó 56 caracteres formada por letras y números, con espacios y guiones opcionales.",
"The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "El primer parámetro del comando es la ruta de la carpeta y el segundo es la ruta relativa en la carpeta.",
"The folder ID cannot be blank.": "La ID de la carpeta no puede estar vacía.",
"The folder ID must be unique.": "La ID de la carpeta debe ser única.",
"The folder path cannot be blank.": "La ruta de la carpeta no puede estar en blanco.",
"The following intervals are used: for the first hour a version is kept every 30 seconds, for the first day a version is kept every hour, for the first 30 days a version is kept every day, until the maximum age a version is kept every week.": "Se utilizan los siguientes intervalos: para la primera hora se mantiene una versión cada 30 segundos, para el primer día se mantiene una versión cada hora, para los primeros 30 días se mantiene una versión diaria hasta la edad máxima de una semana.",
"The following items could not be synchronized.": "Los siguientes elementos no pueden ser sincronizados.",
"The maximum age must be a number and cannot be blank.": "La edad máxima debe ser un número y no puede estar vacía.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "El tiempo máximo para mantener una versión en días (introducir 0 para mantener las versiones indefinidamente).",
"The minimum free disk space percentage must be a non-negative number between 0 and 100 (inclusive).": "El porcentaje de espacio libre mínimo debe ser un número no negativo entre 0 y 100 (ambos inclusive).",
"The number of days must be a number and cannot be blank.": "El número de días debe ser un número y no puede estar en blanco.",
"The number of days to keep files in the trash can. Zero means forever.": "El número de días para mantener los archivos en la papelera. Cero significa \"para siempre\".",
"The number of old versions to keep, per file.": "El número de versiones a antiguas a mantener para cada fichero.",
"The number of versions must be a number and cannot be blank.": "El número de versiones debe ser un número y no puede estar vacío.",
"The path cannot be blank.": "La ruta no puede estar vacía.",
"The rate limit must be a non-negative number (0: no limit)": "El intervalo de reescaneo debe ser un número no negativo de segundos. (0: no limit)",
"The rescan interval must be a non-negative number of seconds.": "El intervalo de reescaneo debe ser un número no negativo de segundos.",
"They are retried automatically and will be synced when the error is resolved.": "Los archivos se sincronizan automáticamente cuando el error se resuelve.",
"The rate limit must be a non-negative number (0: no limit)": "El límite de velocidad debe ser un número no negativo (0: sin límite)",
"The rescan interval must be a non-negative number of seconds.": "El intervalo de actualización debe ser un número positivo de segundos.",
"They are retried automatically and will be synced when the error is resolved.": "Se reintentarán de forma automática y se sincronizarán cuando se resuelva el error.",
"This Device": "Este Dispositivo",
"This can easily give hackers access to read and change any files on your computer.": "Esto puede darle permiso a los hackers, podrán acceder a cualquier archivo, pudiéndolos leer y editar.",
"This is a major version upgrade.": "Esta es una actualización de version mayor.",
"This setting controls the free space required on the home (i.e., index database) disk.": "This setting controls the free space required on the home (i.e., index database) disk.",
"Time": "Tiempo",
"Trash Can File Versioning": "Versiones como cubo de basura",
"This can easily give hackers access to read and change any files on your computer.": "Esto podría permitir fácilmente el acceso a hackers para leer y modificar cualquier fichero de tu equipo.",
"This is a major version upgrade.": "Hay una actualización importante.",
"This setting controls the free space required on the home (i.e., index database) disk.": "Este ajuste controla el espacio libre necesario en el disco principal (por ejemplo, el índice de la base de datos).",
"Time": "Hora",
"Trash Can File Versioning": "Versionado de archivos de la papelera",
"Type": "Tipo",
"Unknown": "Desconocido",
"Unshared": "No compartido",
"Unused": "No utilizado",
"Unused": "No usado",
"Up to Date": "Actualizado",
"Updated": "Actualizado",
"Upgrade": "Actualizar",
"Upgrade To {%version%}": "Actualizar a {{version}}",
"Upgrading": "Actualizando",
"Upload Rate": "Tasa de subida",
"Uptime": "Tiempo en funcionamiento",
"Usage reporting is always enabled for candidate releases.": "Reportes anónimos de uso siempre estan enviados en las versions preliminares.",
"Use HTTPS for GUI": "Usar HTTPS para la GUI",
"Upload Rate": "Velocidad de subida",
"Uptime": "Tiempo de funcionamiento",
"Usage reporting is always enabled for candidate releases.": "El informe de uso está siempre habilitado en las versiones candidatas.",
"Use HTTPS for GUI": "Usar HTTPS para la Interfaz Gráfica de Usuario (GUI)",
"Version": "Versión",
"Versions Path": "Ruta de versiones",
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Las versiones se eliminan automáticamente si son mayores de la edad máxima o mayor que el número de archivos permitidos en un intervalo.",
"Warning, this path is a parent directory of an existing folder \"{%otherFolder%}\".": "Atención, esta ruta es un repertorio allegado por lo menos de un reparto existente (por ejemplo \" {{otherFolder}} \"). Si usted continúa, usted debería crear un nuevo subdirectorio, si no esto puede causar problemas tales como duplicaciones y/o supresiones intempestivas de ficheros.",
"Warning, this path is a parent directory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Atención, esta ruta es un repertorio allegado por lo menos de un reparto existente (por ejemplo \" {{otherFolderLabel}} \" ({{otherFolder}})). Si usted continúa, usted debería crear un nuevo subdirectorio, si no esto puede causar problemas tales como duplicaciones y/o supresiones intempestivas de ficheros.",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Atención, esta dirección es un subdirectorio de un directorio existente \"{{otherFolder}}\".",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "ATENCIÓN, esta ruta es un subdirectorio del reparto existente \" {{otherFolderLabel}} \" ({{otherFolder}}). Esto puede causar problemas tales como duplicaciones y/o supresiones intempestivas de ficheros.",
"When adding a new device, keep in mind that this device must be added on the other side too.": "Al agregar un nuevo dispositivo, tenga en cuenta que este dispositivo se debe agregar en el otro lado también.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Al agregar un nuevo repositorio, tenga en cuenta que la ID del repositorio se utiliza para conectar los repositorios entre dispositivos. Se distingue entre mayúsculas y minúsculas y debe ser exactamente igual en todos los dispositivos.",
"Yes": "Sí",
"You can change your choice at any time in the Settings dialog.": "Usted puede cambiar su elección en el cuadro de diálogo Configuración.",
"You can read more about the two release channels at the link below.": "Usted puede saber más sobre ambos canales de distribución vía el lazo más abajo.",
"You must keep at least one version.": "Debe mantener al menos una versión",
"Versions Path": "Ruta de las versiones",
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Las versiones se borran automáticamente si son más antiguas que la edad máxima o exceden el número de ficheros permitidos en un intervalo.",
"Warning, this path is a parent directory of an existing folder \"{%otherFolder%}\".": "¡Peligro! Esta ruta es un directorio principal de la carpeta ya existente \"{{otherFolder}}\".",
"Warning, this path is a parent directory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "'Peligro! Esta ruta es un subdirectorio de la carpeta ya existente \"{{otherFolderLabel}}\" ({{otherFolder}}).",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Peligro! Esta ruta es un subdirectorio de una carpeta ya existente llamada \"{{otherFolder}}\".",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Peligro, esta ruta es un subdirectorio de una carpeta ya existente llamada \"{{otherFolderLabel}}\" ({{otherFolder}}).",
"When adding a new device, keep in mind that this device must be added on the other side too.": "Cuando añada un nuevo dispositivo, tenga en cuenta que este debe añadirse también en el otro lado.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Cuando añada una nueva carpeta, tenga en cuenta que su ID se usa para unir carpetas entre dispositivos. Son sensibles a las mayúsculas y deben coincidir exactamente entre todos los dispositivos.",
"Yes": "Si",
"You can also select one of these nearby devices:": "También puede seleccionar uno de estos dispositivos cercanos:",
"You can change your choice at any time in the Settings dialog.": "Puedes cambiar tu elección en cualquier momento en el panel de Ajustes.",
"You can read more about the two release channels at the link below.": "Puedes leer más sobre los dos método de publicación de versiones en el siguiente enlace.",
"You must keep at least one version.": "Debes mantener al menos una versión.",
"days": "días",
"directories": "directorios",
"files": "archivos",
"full documentation": "documentación completa",
"items": "ítems",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} quiere compartir repositorio \"{{folder}}\".",
"full documentation": "Documentación completa",
"items": "Elementos",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} quiere compartir la carpeta \"{{folder}}\".",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} quiere compartir la carpeta \"{{folderlabel}}\" ({{folder}})."
}

View File

@@ -9,7 +9,7 @@
"Add": "Gehitu",
"Add Device": "Tresna gehitu",
"Add Folder": "Karpeta gehitu",
"Add Remote Device": "Urruneko tresna bat gehitu",
"Add Remote Device": "Urrundikako tresna bat gehitu",
"Add devices from the introducer to our device list, for mutually shared folders.": "Gure tresna zerrendan tresnak gehitzea baimendu, partekatzeetan.",
"Add new folder?": "Karpeta berria gehitu?",
"Address": "Helbidea",
@@ -44,19 +44,19 @@
"Copied from original": "Jatorrizkotik kopiatua",
"Copyright © 2014-2016 the following Contributors:": "Copyright 2014-2016, ekarle hauk:",
"Copyright © 2014-2017 the following Contributors:": "Copyright 2014-2017, ekarle hauk:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Baztertze modelo batzuen sortzea, den fitxategiari ordaina ezartzea: {{bidea}}",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Baztertze modelo batzuen sortzea, dagoen fitxategiari ordaina ezartzea: {{path}}",
"Danger!": "Lanjera !",
"Deleted": "Kendua",
"Device": "Tresna",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Tresna \"{{name}}\" ({{device}}{{address}} era) konektatu nahi du. Onhartzen duzu? ?",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Tresna \"{{name}}\" ({{device}} {{address}} era) konektatu nahi du. Onhartzen duzu ?",
"Device ID": "Tresnaren ID-a",
"Device Identification": "Tresnaren identifikazioa",
"Device Name": "Tresnaren izena",
"Devices": "Tresnak",
"Disconnected": "Deskonektatua",
"Discovered": "Agertua",
"Discovery": "Aurkikuntza",
"Discovery Failures": "Hutsegiteak",
"Discovery": "Agertzea",
"Discovery Failures": "Agertze hutsegiteak",
"Documentation": "Dokumentazioa",
"Download Rate": "Deskargatzearen bit-tasa",
"Downloaded": "Deskargatua",
@@ -65,13 +65,13 @@
"Edit Device": "Tresna aldatzea",
"Edit Folder": "Partekatze aldatzea",
"Editing": "Aldaketak",
"Editing {%path%}.": "Muntatzea {{bidea}}",
"Editing {%path%}.": "Muntatzea {{path}}",
"Enable NAT traversal": "NAT translazioa aktibatu",
"Enable Relaying": "Aldizkatzea posible",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Negatiboa ez den zenbaki bat hauta ezazu (\"2.35\" adib.) eta unitate bat hauta. Disko osoaren espazio ehunekoa",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Negatiboa ez den zenbaki bat hauta ezazu (\"2.35\" adib.) bai eta unitate bat. Disko osoaren ehuneko espazioa",
"Enter a non-privileged port number (1024 - 65535).": "Abantailatua ez den portu zenbalki bat sar ezazu (1024 - 65535)",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": " (\"tcp://ip:ataka\", \"tcp://izena:ataka\") zuzenbideak sar, krakotx batez separatuak edo bestenaz \"dynamic\", zuzenbidearen xekatze automatikoa aktibatzeko\nTu peux traduire nom et port mot à mot dans la parenthèse, c'est pas des variables du programme, juste du texte explicatif",
"Enter ignore patterns, one per line.": "Ezkluzio filtroak sar, lerro batean bakar bat",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": " (\"tcp://ip:ataka\", \"tcp://izena:ataka\") zuzenbideak sar, krakotx batez separatuak edo bestenaz \"dynamic\", zuzenbidearen xekatze automatikoa aktibatzeko",
"Enter ignore patterns, one per line.": "Ezkluzio filtroak sar, lerro bakoitzean bat bakarrik.",
"Error": "Hutsa",
"External File Versioning": "Fitxategi bertsioen kanpoko kudeaketa",
"Failed Items": "Huts egin duten fitxategiak",
@@ -81,7 +81,7 @@
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Aldaketa bilaketetan, fitxeroen baimen bitak ez dira kontuan hartuko. Fitxero FAT sistimetan erabilia.",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Fitxategiak .stbersioak errepertorioan lekutuak dira, Syncthing-ek ordezkatzen edo kentzen dituelarik",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": ".stbersioak azpi karpetan lekutuko dira fitxeroak, Syncthing-ek aldatu edo ezeztatuko dituelarik. Beren helbide errelatiboak hor berean berriz sortuak izanen dira, behar balin bada",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Syncthing-ek aldatzen edo kentzen dituelarik, fitxeroak \".stbertsioak\" peko-errepertoriorat lekutuak dira, jatorrizkoaren berdin berdina den zuhaitz-formako batean",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": ".stbersioak azpi karpetan lekutuko eta ordu-markatuko dira fitxeroak, egitura errelatibo berdin batean, Syncthing-ek aldatu edo ezeztatuko dituelarik.",
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Beste tresnetan eginak izanen diren aldaketetatik zainduak izanen dira fitxeroak; haatik, tresna huntan egindako aldaketak besteeri hedatuak izanen dira.",
"Folder": "Partekatze",
@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Aktualizatze garrantzitsu bat egin baino lehen, bertsioaren oharrak begira itzazu.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Konfigurazio leihoan asma itzazu erabiltzale izen bat eta pasahitz bat",
"Please wait": "Pazientzia pixka bat, otoi",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefix indicating that the file can be deleted if preventing directory removal",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefix indicating that the pattern should be matched without case sensitivity",
"Preview": "Aurrebista",
"Preview Usage Report": "Erabiltze estatistika txostenaren aurrebista",
"Quick guide to supported patterns": "Eredu konpatibleen gidaliburuxka",
@@ -165,7 +167,7 @@
"Random": "Aleatorioa",
"Reduced by ignore patterns": "Baztertze eredu batzuk mugatuak",
"Release Notes": "Bertsioen notak",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Azken zuzenketak eta funtzionalitateak edukitzen dituzte aitzin-bertsioek. Bi hilabete guziz egiten diren eguneratzeen berdinak dira.",
"Remote Devices": "Beste tresnak",
"Remove": "Kendu",
"Required identifier for the folder. Must be the same on all cluster devices.": "Partekatzearen erabilzaile izena. Dauden tresna guzietan berdin berdina izan behar du",
@@ -181,6 +183,7 @@
"Save": "Grabatu",
"Scan Time Remaining": "Gelditzen den azterketa denbora",
"Scanning": "Azterketa martxan",
"See external versioner help for supported templated command line parameters.": "See external versioner help for supported templated command line parameters.",
"Select the devices to share this folder with.": " Tresnak hauta itzazu partekatze honekin sinkronizatzeko ",
"Select the folders to share with this device.": "Tresna honek erabiltzen dituen partekatzeak hauta itzazu",
"Send & Receive": "Igorri eta errezibitu",
@@ -255,7 +258,7 @@
"Up to Date": "Eguneratua",
"Updated": "Berritua",
"Upgrade": "Aktualizatu",
"Upgrade To {%version%}": "Egunetaratu {{bertsio}}-ari buruz",
"Upgrade To {%version%}": "Egunetaratu {{version}}-ari buruz",
"Upgrading": "Syncthing-en egunetaratzea",
"Upload Rate": "Igortze emaria",
"Uptime": "Erabiltze denbora",
@@ -264,13 +267,14 @@
"Version": "Bertsioa",
"Versions Path": "Bertsioen kokalekua",
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Bertsioak automatikoki ezeztatuak izanen dira, kontserbatzeko iraupen denbora pasatua badute edo bitartean onartua den kopurua (fitxategi bakoitzean) gainditua balin bada",
"Warning, this path is a parent directory of an existing folder \"{%otherFolder%}\".": "Kasu, bide hau dagoen partekatze baten karpeta ahaidea da (adibidez, \" {{BestePartekatze}}\"). Segitzen baduzu, azpi-karpeta berri bat sortu behar duzu, bestenaz arazoak sortzen ahal dira, fitxategi kentzeak edo doblatzeak.",
"Warning, this path is a parent directory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Kasu, bide hau dagoen partekatze baten karpeta ahaidea da (adibidez, \"{{BestePartekatzeLabela}}\" ({{BestePartekatze}}). ",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Kasu, bide hau \"{{BestePartekatze}}\" partekatzearen azpi-karpeta da. Arazoak emaiten ahal ditu, fitxategi kentzeak edo doblatzeak, adibidez.",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Kasu, bide hau \"{{BestePartekatzeLabela}}\" ({{BestePartekatze}}) partekatzearen azpi-karpeta da. Arazoak emaiten ahal ditu, fitxategi kentzeak edo doblatzeak, adibidez.",
"Warning, this path is a parent directory of an existing folder \"{%otherFolder%}\".": "Kasu, bide hau dagoen partekatze baten karpeta ahaidea da (adibidez, \"{{otherFolder}}\"). Segitzen baduzu, azpi-karpeta berri bat sortu behar duzu, bestenaz arazoak sortzen ahal dira, fitxategi kentzeak edo doblatzeak.",
"Warning, this path is a parent directory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Kasu, bide hau dagoen partekatze baten karpeta ahaidea da (adibidez, \"{{otherFolderLabel}}\" ({{otherFolder}}). ",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Kasu, bide hau \"{{otherFolder}}\" partekatzearen azpi-karpeta da. Arazoak emaiten ahal ditu, fitxategi kentzeak edo doblatzeak, adibidez.",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Kasu, bide hau \"{{otherFolderLabel}}\" ({{otherFolder}}) partekatzearen azpi-karpeta da. Arazoak emaiten ahal ditu, fitxategi kentzeak edo doblatzeak, adibidez.",
"When adding a new device, keep in mind that this device must be added on the other side too.": "Tresna bat gehitzen duzularik, gogoan atxik ezazu zurea bestaldean gehitu behar dela ere",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Partekatze bat gehitzen delarik, gogoan atxik ezazu bere IDa erabilia dela errepertorioak lotzeko tresnen bitartez. ID-a hautskorra da eta partekatze hontan parte hartzen duten tresna guzietan berdina izan behar du.",
"Yes": "Bai",
"You can also select one of these nearby devices:": "You can also select one of these nearby devices:",
"You can change your choice at any time in the Settings dialog.": "Zure hautua aldatzen ahal duzu \"Konfigurazio\" leihatilan",
"You can read more about the two release channels at the link below.": "Bi banaketa kanal hauen bidez gehiago jakin dezakezu, lokarri honen bidez ",
"You must keep at least one version.": "Bertsio bat bederen behar duzu atxiki",
@@ -279,6 +283,6 @@
"files": "Fitxategiak",
"full documentation": "Dokumentazio osoa",
"items": "Elementuak",
"{%device%} wants to share folder \"{%folder%}\".": "{{Tresna}}-k \"{{folder}}\" partekatze hontan gomitatzen zaitu.",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{Tresna}}-ak \"{{PartekatzeLabela}}\" ({{Partekatze}}) hontan gomitatzen zaitu."
"{%device%} wants to share folder \"{%folder%}\".": "{{device}}k \"{{folder}}\" partekatze hontan gomitatzen zaitu.",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}}k \"{{folderlabel}}\" ({{folder}}) hontan gomitatzen zaitu."
}

View File

@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Tutustu julkaisutietoihin ennen kuin teet pääversion päivityksen.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Ole hyvä ja aseta käyttäjätunnus ja salasana käyttöliittymää varten asetusvalikossa.",
"Please wait": "Ole hyvä ja odota",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefix indicating that the file can be deleted if preventing directory removal",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefix indicating that the pattern should be matched without case sensitivity",
"Preview": "Esikatselu",
"Preview Usage Report": "Esikatsele käyttöraportti",
"Quick guide to supported patterns": "Tuettujen lausekkeiden pikaohje",
@@ -181,6 +183,7 @@
"Save": "Tallenna",
"Scan Time Remaining": "Skannausaikaa jäljellä",
"Scanning": "Skannataan",
"See external versioner help for supported templated command line parameters.": "See external versioner help for supported templated command line parameters.",
"Select the devices to share this folder with.": "Valitse laitteet, joiden kanssa tämä kansio jaetaan.",
"Select the folders to share with this device.": "Valitse kansiot jaettavaksi tämän laitteen kanssa.",
"Send & Receive": "Lähetä & vastaanota",
@@ -271,6 +274,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "Lisättäessä laitetta, muista että tämä laite tulee myös lisätä toiseen laitteeseen.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Lisättäessä uutta kansiota, muista että kansion ID:tä käytetään solmimaan kansiot yhteen laitteiden välillä. Ne ovat riippuvaisia kirjankoosta ja niiden tulee täsmätä kaikkien laitteiden välillä.",
"Yes": "Kyllä",
"You can also select one of these nearby devices:": "You can also select one of these nearby devices:",
"You can change your choice at any time in the Settings dialog.": "You can change your choice at any time in the Settings dialog.",
"You can read more about the two release channels at the link below.": "You can read more about the two release channels at the link below.",
"You must keep at least one version.": "Sinun tulee säilyttää ainakin yksi versio.",

View File

@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Veuillez consulter les notes de version avant de réaliser une mise à jour majeure.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Veuillez définir un nom d'utilisateur et un mot de passe dans les réglages.",
"Please wait": "Merci de patienter",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefix indicating that the file can be deleted if preventing directory removal",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefix indicating that the pattern should be matched without case sensitivity",
"Preview": "Aperçu",
"Preview Usage Report": "Aperçu du rapport de statistiques d'utilisation",
"Quick guide to supported patterns": "Guide rapide des masques compatibles ci-dessous",
@@ -181,6 +183,7 @@
"Save": "Enregistrer",
"Scan Time Remaining": "Temps d'analyse restant",
"Scanning": "Analyse en cours",
"See external versioner help for supported templated command line parameters.": "See external versioner help for supported templated command line parameters.",
"Select the devices to share this folder with.": "Synchroniser avec :",
"Select the folders to share with this device.": "Sélectionner les partages auxquels participe cet appareil.",
"Send & Receive": "Envoi & réception",
@@ -271,6 +274,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "Lorsque vous ajoutez un appareil, gardez à l'esprit que le votre doit aussi être ajouté de l'autre coté.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Lorsqu'un nouveau partage est ajouté, gardez à l'esprit que son ID est utilisée pour lier les répertoires à travers les appareils. L'ID est sensible à la casse et sera forcément la même sur tous les appareils participant à ce partage.",
"Yes": "Oui",
"You can also select one of these nearby devices:": "You can also select one of these nearby devices:",
"You can change your choice at any time in the Settings dialog.": "Vous pouvez changer votre choix dans la boîte de dialogue \"Configuration\".",
"You can read more about the two release channels at the link below.": "Vous pouvez en savoir plus sur les deux canaux de distribution via le lien ci-dessous.",
"You must keep at least one version.": "Vous devez garder au minimum une version.",

View File

@@ -1,5 +1,5 @@
{
"A device with that ID is already added.": "L'appareil portant cette ID est déjà présent.",
"A device with that ID is already added.": " L'appareil portant cet ID est déjà présent.",
"A negative number of days doesn't make sense.": "Ce champ n'accepte qu'un entier positif ou nul.",
"A new major version may not be compatible with previous versions.": "Une nouvelle version majeure peut présenter des incompatibilités avec les versions antérieures.",
"API Key": "Clé API",
@@ -37,7 +37,7 @@
"Command": "Commande",
"Comment, when used at the start of a line": "Commentaire lorsque utilisé en début de ligne",
"Compression": "Compression",
"Configured": "Configuré",
"Configured": "Configurée",
"Connection Error": "Erreur de connexion",
"Connection Type": "Type de connexion",
"Copied from elsewhere": "Copié d'ailleurs",
@@ -48,10 +48,10 @@
"Danger!": "Attention !",
"Deleted": "Supprimé",
"Device": "Appareil",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "L'appareil \"{{name}}\" ({{device}} à {{address}}) veut se connecter. L'acceptez-vous ?",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "\"{{name}}\" ({{device}}), appareil actuellement à {{address}}, demande à se connecter.\nAcceptez-vous de l'ajouter à votre liste d'appareils connus ?",
"Device ID": "ID de l'appareil",
"Device Identification": "Identifiant de l'appareil",
"Device Name": "Nom de l'appareil",
"Device Name": "Nom convivial local de l'appareil",
"Devices": "Appareils",
"Disconnected": "Déconnecté",
"Discovered": "Découvert",
@@ -61,9 +61,9 @@
"Download Rate": "Débit de réception",
"Downloaded": "Reçu",
"Downloading": "Réception",
"Edit": "Modifier",
"Edit Device": "Modifier l'appareil",
"Edit Folder": "Modifier le partage",
"Edit": "Gérer",
"Edit Device": "Gérer l'appareil",
"Edit Folder": "Gérer le partage",
"Editing": "Modifications",
"Editing {%path%}.": "Modification de {{path}}.",
"Enable NAT traversal": "Activer la translation d'adresses (NAT)",
@@ -142,7 +142,7 @@
"OK": "OK",
"Off": "Désactivé(e)",
"Oldest First": "Les plus anciens en premier",
"Optional descriptive label for the folder. Can be different on each device.": "Nom convivial et optionnel du partage, à votre guise. il peut être différent sur chaque appareil.",
"Optional descriptive label for the folder. Can be different on each device.": "Nom local, convivial et optionnel du partage, à votre guise. il peut être différent sur chaque appareil. Par notification initiale, il sera proposé tel quel aux nouveaux participants.\nAstuce : comme il est modifiable ultérieurement, pensez à indiquer un nom parlant pour les invités, puis renommez-le quand ils l'auront accepté (exemple d'un partage à deux membres où l'initiateur commence par donner son propre nom au partage, puis le renomme plus tard au nom du partenaire quand celui-ci l'a enregistré). Évitez les erreurs d'orthographe car ce nom servira aussi de base au chemin proposé en création (local et distant) et ce chemin est difficilement modifiable.",
"Options": "Options",
"Out of Sync": "Désynchronisé",
"Out of Sync Items": "Éléments non synchronisés",
@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Veuillez consulter les notes de version avant de réaliser une mise à jour majeure.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Veuillez définir un nom d'utilisateur et un mot de passe dans la fenêtre de Configuration.",
"Please wait": "Merci de patienter",
"Prefix indicating that the file can be deleted if preventing directory removal": "Ce préfixe autorise la suppression des fichiers pour permettre la suppression de répertoires.",
"Prefix indicating that the pattern should be matched without case sensitivity": "Ce préfixe, inutile sur Windows et Mac OS, indique que le masque d'exclusion est insensible à la casse.",
"Preview": "Aperçu",
"Preview Usage Report": "Aperçu du rapport de statistiques d'utilisation",
"Quick guide to supported patterns": "Guide rapide des masques compatibles ci-dessous",
@@ -167,8 +169,8 @@
"Release Notes": "Notes de version",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Les versions préliminaires contiennent les dernières fonctionnalités et derniers correctifs. Elles sont identiques aux traditionnelles mises à jour bimensuelles.",
"Remote Devices": "Autres appareils",
"Remove": "Enlever",
"Required identifier for the folder. Must be the same on all cluster devices.": "Identifiant du partage. Doit être le même sur tous les appareils concernés.",
"Remove": "Supprimer",
"Required identifier for the folder. Must be the same on all cluster devices.": "Identifiant du partage. Doit être le même sur tous les appareils concernés (généré aléatoirement, mais modifiable à la création).",
"Rescan": "Réanalyser",
"Rescan All": "Tout réanalyser",
"Rescan Interval": "Intervalle d'analyse",
@@ -181,6 +183,7 @@
"Save": "Enregistrer",
"Scan Time Remaining": "Temps d'analyse restant",
"Scanning": "Analyse en cours",
"See external versioner help for supported templated command line parameters.": "Voir l'aide sur la préservation externe des fichiers pour les paramètres supportés en lignes de commande dans les modèles.",
"Select the devices to share this folder with.": "Synchroniser avec :",
"Select the folders to share with this device.": "Sélectionner les partages auxquels cet appareil doit participer :",
"Send & Receive": "Envoi & réception",
@@ -195,7 +198,7 @@
"Show ID": "Afficher mon ID",
"Show QR": "Afficher le QR",
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Affiché à la place de l'ID de l'appareil dans l'état du groupe. Sera diffusé aux autres appareils comme nom convivial optionnel par défaut.",
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Affiché à la place de l'ID de l'appareil dans l'état du groupe. Si laissé vide, il sera renseigné par le nom convivial proposé par l'appareil distant.",
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Nom convivial local affiché à la place de l'ID de l'appareil dans la plupart des écrans. Si laissé vide, c'est le nom convivial local de l'appareil distant qui sera utilisé. (Modifiable ultérieurement).",
"Shutdown": "Arrêter",
"Shutdown Complete": "Arrêté !",
"Simple File Versioning": "Suivi simplifié des versions",
@@ -264,13 +267,14 @@
"Version": "Version",
"Versions Path": "Emplacement des versions",
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Les plus anciennes versions seront supprimées automatiquement quand elles dépassent la durée maximum de conservation ou si leur nombre (par fichier) est supérieur à la limite prédéfinie pour l'intervalle.",
"Warning, this path is a parent directory of an existing folder \"{%otherFolder%}\".": "Attention, ce chemin est un répertoire parent d'au moins un partage existant (par exemple \"{{otherFolder}}\"). Si vous continuez, vous devriez créer un nouveau sous-répertoire, sinon ceci peut causer des problèmes tels que duplications et/ou suppressions intempestives de fichiers.",
"Warning, this path is a parent directory of an existing folder \"{%otherFolder%}\".": "Attention, ce chemin est un répertoire parent d'au moins un partage existant (par exemple \"{{otherFolder}}\"). Si c'est bien ce que vous souhaitez, vous devriez créer un nouveau sous-répertoire, sinon ceci peut causer des problèmes tels que duplications et/ou suppressions intempestives de fichiers.",
"Warning, this path is a parent directory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Attention, ce chemin est un répertoire parent d'au moins un partage existant (par exemple \"{{otherFolderLabel}}\" ({{otherFolder}})). Si vous continuez, vous devriez créer un nouveau sous-répertoire, sinon ceci peut causer des problèmes tels que duplications et/ou suppressions intempestives de fichiers.",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "ATTENTION, ce chemin est un sous-répertoire du partage existant \"{{otherFolder}}\". Ceci peut causer des problèmes tels que duplications et/ou suppressions intempestives de fichiers.",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "ATTENTION, ce chemin est un sous-répertoire du partage existant \"{{otherFolderLabel}}\" ({{otherFolder}}). Ceci peut causer des problèmes tels que duplications et/ou suppressions intempestives de fichiers.",
"When adding a new device, keep in mind that this device must be added on the other side too.": "Lorsque vous ajoutez un appareil, gardez à l'esprit que le votre doit aussi être ajouté de l'autre coté.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Lorsqu'un nouveau partage est ajouté, gardez à l'esprit que son ID est utilisée pour lier les répertoires à travers les appareils. L'ID est sensible à la casse et sera forcément la même sur tous les appareils participant à ce partage.",
"Yes": "Oui",
"You can also select one of these nearby devices:": "Vous pouvez également sélectionner l'un de ces appareils proches :",
"You can change your choice at any time in the Settings dialog.": "Vous pouvez changer votre choix dans la boîte de dialogue \"Configuration\".",
"You can read more about the two release channels at the link below.": "Vous pouvez en savoir plus sur les deux canaux de distribution via le lien ci-dessous.",
"You must keep at least one version.": "Vous devez garder au minimum une version.",

View File

@@ -58,9 +58,9 @@
"Discovery": "Untdekking",
"Discovery Failures": "Untdekkingsflaters",
"Documentation": "Dokumintaasje",
"Download Rate": "Ynlaadfluggens",
"Downloaded": "Ynladen",
"Downloading": "Oan it ynladen",
"Download Rate": "Downloadfluggens",
"Downloaded": "Downloaded",
"Downloading": "Oan it downloaden",
"Edit": "Bewurkje",
"Edit Device": "Apparaat Bewurkje",
"Edit Folder": "Map Bewurkje",
@@ -75,7 +75,7 @@
"Error": "Flater",
"External File Versioning": "Ekstern ferzjebehear foar triemen",
"Failed Items": "Mislearre items",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Konneksje mei IPv6-tsjinners wol lykwols net slagje sûnder IPv6-ferbining is.",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": " Mislearjen fan it ferbinen mei IPv6-tsjinners wurd ferwachte as der gjin stipe foar IPv6-ferbinings is.",
"File Pull Order": "Triemlûkfolchoarder",
"File Versioning": "Triemferzjebehear",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Bits foar triemrjochten wurde negearre yn it sykjen foar feroarings. Brûk dit op FAT-triemsystemen.",
@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Foardat jo in wichtige fernijing ynstallearre, graach earst de fernijingsoantekenings lêze.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Graach foar GUI-ferifikaasje in brûkers-ID en wachtwurd ynstelle yn it ynstellingsdialooch.",
"Please wait": "In amerijke",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefiks dy't oanjout dat de triem fourtsmiten wurde kin wannear dit it ferwiderjen belet.",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefiks dy't oanjout dat fergelykings mei it patroans net haadlettergefoelich wêze sille.",
"Preview": "Foarbyld",
"Preview Usage Report": "Foarbyld fan brûkensrapport ",
"Quick guide to supported patterns": "Fluch-paadwizer foar stipe patroanen",
@@ -181,6 +183,7 @@
"Save": "Bewarje",
"Scan Time Remaining": "Oerbleaune skentiid",
"Scanning": "Oan it skennen",
"See external versioner help for supported templated command line parameters.": "Sjoch de eksterne help fan fersjebehearder foar stipe foarbylden fan kommando-rige-parameters.",
"Select the devices to share this folder with.": "Sykje de apparaten út om dizze map mei te dielen.",
"Select the folders to share with this device.": "Sykje de mappen út om mei dit apparaat te dielen.",
"Send & Receive": "Stjoere & Untfange",
@@ -209,7 +212,7 @@
"Start Browser": "Browser iepenje wannear't Syncthing start",
"Statistics": "Statistiken",
"Stopped": "Stoppe",
"Support": "Understeuning",
"Support": "Help (Forum)",
"Sync Protocol Listen Addresses": "Sync-protokolharkadressen",
"Syncing": "Oan it Syncen",
"Syncthing has been shut down.": "Syncthing is útsetten",
@@ -257,7 +260,7 @@
"Upgrade": "Fernije",
"Upgrade To {%version%}": "Fernije nei {{version}}",
"Upgrading": "Oan it fernijen",
"Upload Rate": "Oplaadfluggens",
"Upload Rate": "Uploadfluggens",
"Uptime": "Rintiid",
"Usage reporting is always enabled for candidate releases.": "Brûkersrapportaazje stiet altyd oan foar ferzje kandidaten.",
"Use HTTPS for GUI": "Brûk HTTPS foar GUI",
@@ -271,6 +274,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "Hâld by it taheakjen fan in nij apparaat yn de holle dat it apparaat oan de oare kant ek taheakke wurde moat. ",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Hâld by it taheakjen fan in nije map yn de holle dat de map-ID brûkt wurd om de mappen tusken apparaten mei-inoar te ferbinen. Se binne haadlettergefoelich en moatte oer alle apparaten eksakt oerienkomme.",
"Yes": "Ja",
"You can also select one of these nearby devices:": "Jo kinne ek ien fan dizze tichtbye apparaten selektearje:",
"You can change your choice at any time in the Settings dialog.": "Jo kinne jo kar op elk stuit oanpasse yn it Ynstellingsdialooch.",
"You can read more about the two release channels at the link below.": "Jo kinne mear lêze oer de twa útjeftekanalen fia de ûndersteande link.",
"You must keep at least one version.": "Jo moatte minstens ien ferzje bewarje.",

View File

@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Nagyobb frissítés előtt ellenőrizni kell a kiadási megjegyzéseket.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Be kell állítani a grafikus felület felhasználónevét és jelszavát a Beállítások párbeszédablakban.",
"Please wait": "Türelem",
"Prefix indicating that the file can be deleted if preventing directory removal": "Előtag, amely jelzi, hogy a fájl törölhető, ha tiltva van a mappák eltávolítása",
"Prefix indicating that the pattern should be matched without case sensitivity": "Előtag, amely jelzi, hogy a mintát nagy- ill. kisbetűérzékenység nélkül kell illeszteni.",
"Preview": "Előnézet",
"Preview Usage Report": "Használati jelentés áttekintése",
"Quick guide to supported patterns": "Rövid útmutató a használható mintákról",
@@ -181,6 +183,7 @@
"Save": "Mentés",
"Scan Time Remaining": "Fennmaradó átnézési idő",
"Scanning": "Átnézés",
"See external versioner help for supported templated command line parameters.": "A támogatott parancssori paraméter sablonokat a külső verziókezelő súgójában találod.",
"Select the devices to share this folder with.": "Eszközök, amelyekkel megosztandó a mappa",
"Select the folders to share with this device.": "Mappák, amelyek megosztandók ezzel az eszközzel.",
"Send & Receive": "Küldés és fogadás",
@@ -271,6 +274,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "Új eszköz hozzáadásakor nem szabad elfeledkezni arról, hogy a másik oldalon ezt az eszközt is hozzá kell adni.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Új eszköz hozzáadásakor észben kell tartani, hogy a mappaazonosító arra való, hogy összekösse a mappákat az eszközökön. Az azonosító kisbetű-nagybetű érzékeny és pontosan egyeznie kell az eszközökön.",
"Yes": "Igen",
"You can also select one of these nearby devices:": "Az alábbi közelben lévő eszközök közül lehet választani:",
"You can change your choice at any time in the Settings dialog.": "A beállításoknál bármikor módosíthatod a választásodat.",
"You can read more about the two release channels at the link below.": "A két kiadási csatornáról az alábbi linken olvashatsz további információkat.",
"You must keep at least one version.": "Legalább egy verziót meg kell tartani.",

View File

@@ -1,284 +0,0 @@
{
"A device with that ID is already added.": "Perangkat dengan ID tersebut sudah ada.",
"A negative number of days doesn't make sense.": "Tidak mungkin jumlah hari dalam nilai negatif.",
"A new major version may not be compatible with previous versions.": "Versi penting yang baru mungkin tidak kompatibel dengan versi sebelumnya.",
"API Key": "API Key",
"About": "Tentang",
"Action": "Action",
"Actions": "Aksi",
"Add": "Tambah",
"Add Device": "Tambah Perangkat",
"Add Folder": "Tambah Folder",
"Add Remote Device": "Add Remote Device",
"Add devices from the introducer to our device list, for mutually shared folders.": "Add devices from the introducer to our device list, for mutually shared folders.",
"Add new folder?": "Tambah folder baru",
"Address": "Alamat",
"Addresses": "Alamat",
"Advanced": "Tingkat Lanjut",
"Advanced Configuration": "Konfigurasi Tingkat Lanjut",
"Advanced settings": "Advanced settings",
"All Data": "Semua Data",
"Allow Anonymous Usage Reporting?": "Aktifkan Laporan Penggunaan Anonim?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "Alfabet",
"An external command handles the versioning. It has to remove the file from the shared folder.": "An external command handles the versioning. It has to remove the file from the shared folder.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Perintah eksternal mengatur pemversian. Dia harus menghapus berkas dari folder yang tersinkronisasi.",
"Anonymous Usage Reporting": "Pelaporan Penggunaan Anonim",
"Any devices configured on an introducer device will be added to this device as well.": "Semua perangkat yang dikonfigurasi di perangkat pengenal akan ditambahkan di perangkat ini juga.",
"Automatic upgrade now offers the choice between stable releases and release candidates.": "Automatic upgrade now offers the choice between stable releases and release candidates.",
"Automatic upgrades": "Ugrade Otomatis",
"Be careful!": "Harap hati-hati!",
"Bugs": "Bugs",
"CPU Utilization": "Penggunaan CPU",
"Changelog": "Log perubahan",
"Clean out after": "Bersihkan setelah",
"Click to see discovery failures": "Click to see discovery failures",
"Close": "Tutup",
"Command": "Perintah",
"Comment, when used at the start of a line": "Komentar, digunakan saat awal baris",
"Compression": "Kompresi",
"Configured": "Configured",
"Connection Error": "Koneksi Galat",
"Connection Type": "Connection Type",
"Copied from elsewhere": "Tersalin dari tempat lain",
"Copied from original": "Tersalin dari asal",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 the following Contributors:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "Bahaya!",
"Deleted": "Terhapus",
"Device": "Device",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Device \"{{name}}\" ({{device}} at {{address}}) wants to connect. Add new device?",
"Device ID": "ID Perangkat",
"Device Identification": "Identifikasi Perangkat",
"Device Name": "Nama Perangkat",
"Devices": "Perangkat",
"Disconnected": "Terputus",
"Discovered": "Discovered",
"Discovery": "Discovery",
"Discovery Failures": "Discovery Failures",
"Documentation": "Dokumentasi",
"Download Rate": "Download Rate",
"Downloaded": "Terunduh",
"Downloading": "Mengunduh",
"Edit": "Sunting",
"Edit Device": "Edit Device",
"Edit Folder": "Edit Folder",
"Editing": "Menyunting",
"Editing {%path%}.": "Editing {{path}}.",
"Enable NAT traversal": "Enable NAT traversal",
"Enable Relaying": "Aktifkan Relay",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.",
"Enter a non-privileged port number (1024 - 65535).": "Enter a non-privileged port number (1024 - 65535).",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Masukkan alamat, pisahkan dengan koma (\"tcp://ip:port\", \"tcp://host:port\") atau \"dynamic\" untuk menjalankan penemuan otomatis alamat tersebut.",
"Enter ignore patterns, one per line.": "Masukkan pola pengabaian, satu per baris.",
"Error": "Galat",
"External File Versioning": "Berkas pemversian eksternal",
"Failed Items": "Materi yang gagal",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.",
"File Pull Order": "Urutan Penarikan Berkas",
"File Versioning": "Versi Berkas",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Bit hak akses berkas diabaikan saat mencari perubahan. Digunakan pada sistem berkas FAT.",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Files are moved to .stversions directory when replaced or deleted by Syncthing.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Berkas dipindahkan ke folder .stversions jika digantikan atau dihapus oleh Syncthing.",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Berkas dipindahkan ke versi bertanggal dalam folder .stversions jika digantikan atau dihapus oleh Syncthing.",
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Berkas diproteksi dari perubahan oleh perangkat lain, tetapi perubahan yang dikirim dari perangkat ini akan dikirim ke perangkat lain dalam klaster.",
"Folder": "Folder",
"Folder ID": "ID Folder",
"Folder Label": "Folder Label",
"Folder Path": "Path Folder",
"Folder Type": "Folder Type",
"Folders": "Folder",
"GUI": "GUI",
"GUI Authentication Password": "Sandi Otentikasi GUI",
"GUI Authentication User": "Pengguna Otentikasi GUI",
"GUI Listen Address": "GUI Listen Address",
"GUI Listen Addresses": "Alamat Listen GUI",
"GUI Theme": "GUI Theme",
"Generate": "Buat Baru",
"Global Changes": "Global Changes",
"Global Discovery": "Discovery Global",
"Global Discovery Servers": "Global Discovery Servers",
"Global State": "Status Global",
"Help": "Panduan",
"Home page": "Situs",
"Ignore": "Abaikan",
"Ignore Patterns": "Pola Pengabaian",
"Ignore Permissions": "Hak Akses Pengabaian",
"Incoming Rate Limit (KiB/s)": "Incoming Rate Limit (KiB/s)",
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "Konfigurasi salah bisa merusak isi folder dan membuat Syncthing tidak bisa dijalankan.",
"Introduced By": "Introduced By",
"Introducer": "Pengenal",
"Inversion of the given condition (i.e. do not exclude)": "Inversion of the given condition (i.e. do not exclude)",
"Keep Versions": "Keep Versions",
"Largest First": "Largest First",
"Last File Received": "Last File Received",
"Last Scan": "Last Scan",
"Last seen": "Last seen",
"Later": "Later",
"Latest Change": "Latest Change",
"Learn more": "Learn more",
"Listeners": "Listeners",
"Local Discovery": "Local Discovery",
"Local State": "Local State",
"Local State (Total)": "Local State (Total)",
"Major Upgrade": "Major Upgrade",
"Master": "Master",
"Maximum Age": "Maximum Age",
"Metadata Only": "Metadata Only",
"Minimum Free Disk Space": "Minimum Free Disk Space",
"Move to top of queue": "Move to top of queue",
"Multi level wildcard (matches multiple directory levels)": "Multi level wildcard (matches multiple directory levels)",
"Never": "Never",
"New Device": "New Device",
"New Folder": "New Folder",
"Newest First": "Newest First",
"No": "No",
"No File Versioning": "No File Versioning",
"No upgrades": "No upgrades",
"Normal": "Normal",
"Notice": "Notice",
"OK": "OK",
"Off": "Off",
"Oldest First": "Oldest First",
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
"Options": "Options",
"Out of Sync": "Out of Sync",
"Out of Sync Items": "Out of Sync Items",
"Outgoing Rate Limit (KiB/s)": "Outgoing Rate Limit (KiB/s)",
"Override Changes": "Override Changes",
"Path": "Path",
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).",
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Path where versions should be stored (leave empty for the default .stversions folder in the folder).",
"Pause": "Pause",
"Pause All": "Pause All",
"Paused": "Paused",
"Please consult the release notes before performing a major upgrade.": "Please consult the release notes before performing a major upgrade.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Please set a GUI Authentication User and Password in the Settings dialog.",
"Please wait": "Please wait",
"Preview": "Preview",
"Preview Usage Report": "Preview Usage Report",
"Quick guide to supported patterns": "Quick guide to supported patterns",
"RAM Utilization": "RAM Utilization",
"Random": "Random",
"Reduced by ignore patterns": "Reduced by ignore patterns",
"Release Notes": "Release Notes",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.",
"Remote Devices": "Remote Devices",
"Remove": "Remove",
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
"Rescan": "Rescan",
"Rescan All": "Rescan All",
"Rescan Interval": "Rescan Interval",
"Restart": "Restart",
"Restart Needed": "Restart Needed",
"Restarting": "Restarting",
"Resume": "Resume",
"Resume All": "Resume All",
"Reused": "Reused",
"Save": "Save",
"Scan Time Remaining": "Scan Time Remaining",
"Scanning": "Scanning",
"Select the devices to share this folder with.": "Select the devices to share this folder with.",
"Select the folders to share with this device.": "Select the folders to share with this device.",
"Send & Receive": "Send & Receive",
"Send Only": "Send Only",
"Settings": "Settings",
"Share": "Share",
"Share Folder": "Share Folder",
"Share Folders With Device": "Share Folders With Device",
"Share With Devices": "Share With Devices",
"Share this folder?": "Share this folder?",
"Shared With": "Shared With",
"Show ID": "Show ID",
"Show QR": "Show QR",
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.",
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.",
"Shutdown": "Shutdown",
"Shutdown Complete": "Shutdown Complete",
"Simple File Versioning": "Simple File Versioning",
"Single level wildcard (matches within a directory only)": "Single level wildcard (matches within a directory only)",
"Smallest First": "Smallest First",
"Source Code": "Source Code",
"Stable releases and release candidates": "Stable releases and release candidates",
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.",
"Stable releases only": "Stable releases only",
"Staggered File Versioning": "Staggered File Versioning",
"Start Browser": "Start Browser",
"Statistics": "Statistics",
"Stopped": "Stopped",
"Support": "Support",
"Sync Protocol Listen Addresses": "Sync Protocol Listen Addresses",
"Syncing": "Syncing",
"Syncthing has been shut down.": "Syncthing has been shut down.",
"Syncthing includes the following software or portions thereof:": "Syncthing includes the following software or portions thereof:",
"Syncthing is restarting.": "Syncthing is restarting.",
"Syncthing is upgrading.": "Syncthing is upgrading.",
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…",
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.",
"The Syncthing admin interface is configured to allow remote access without a password.": "The Syncthing admin interface is configured to allow remote access without a password.",
"The aggregated statistics are publicly available at the URL below.": "The aggregated statistics are publicly available at the URL below.",
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.",
"The device ID cannot be blank.": "The device ID cannot be blank.",
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).",
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.": "The encrypted usage report is sent daily. It is used to track common platforms, folder sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.",
"The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.": "The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.",
"The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "The first command line parameter is the folder path and the second parameter is the relative path in the folder.",
"The folder ID cannot be blank.": "The folder ID cannot be blank.",
"The folder ID must be unique.": "The folder ID must be unique.",
"The folder path cannot be blank.": "The folder path cannot be blank.",
"The following intervals are used: for the first hour a version is kept every 30 seconds, for the first day a version is kept every hour, for the first 30 days a version is kept every day, until the maximum age a version is kept every week.": "The following intervals are used: for the first hour a version is kept every 30 seconds, for the first day a version is kept every hour, for the first 30 days a version is kept every day, until the maximum age a version is kept every week.",
"The following items could not be synchronized.": "The following items could not be synchronized.",
"The maximum age must be a number and cannot be blank.": "The maximum age must be a number and cannot be blank.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "The maximum time to keep a version (in days, set to 0 to keep versions forever).",
"The minimum free disk space percentage must be a non-negative number between 0 and 100 (inclusive).": "The minimum free disk space percentage must be a non-negative number between 0 and 100 (inclusive).",
"The number of days must be a number and cannot be blank.": "The number of days must be a number and cannot be blank.",
"The number of days to keep files in the trash can. Zero means forever.": "The number of days to keep files in the trash can. Zero means forever.",
"The number of old versions to keep, per file.": "The number of old versions to keep, per file.",
"The number of versions must be a number and cannot be blank.": "The number of versions must be a number and cannot be blank.",
"The path cannot be blank.": "The path cannot be blank.",
"The rate limit must be a non-negative number (0: no limit)": "The rate limit must be a non-negative number (0: no limit)",
"The rescan interval must be a non-negative number of seconds.": "The rescan interval must be a non-negative number of seconds.",
"They are retried automatically and will be synced when the error is resolved.": "They are retried automatically and will be synced when the error is resolved.",
"This Device": "This Device",
"This can easily give hackers access to read and change any files on your computer.": "This can easily give hackers access to read and change any files on your computer.",
"This is a major version upgrade.": "This is a major version upgrade.",
"This setting controls the free space required on the home (i.e., index database) disk.": "This setting controls the free space required on the home (i.e., index database) disk.",
"Time": "Time",
"Trash Can File Versioning": "Trash Can File Versioning",
"Type": "Type",
"Unknown": "Unknown",
"Unshared": "Unshared",
"Unused": "Unused",
"Up to Date": "Up to Date",
"Updated": "Updated",
"Upgrade": "Upgrade",
"Upgrade To {%version%}": "Upgrade To {{version}}",
"Upgrading": "Upgrading",
"Upload Rate": "Upload Rate",
"Uptime": "Uptime",
"Usage reporting is always enabled for candidate releases.": "Usage reporting is always enabled for candidate releases.",
"Use HTTPS for GUI": "Use HTTPS for GUI",
"Version": "Version",
"Versions Path": "Versions Path",
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.",
"Warning, this path is a parent directory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a parent directory of an existing folder \"{{otherFolder}}\".",
"Warning, this path is a parent directory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Warning, this path is a parent directory of an existing folder \"{{otherFolderLabel}}\" ({{otherFolder}}).",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Warning, this path is a subdirectory of an existing folder \"{{otherFolderLabel}}\" ({{otherFolder}}).",
"When adding a new device, keep in mind that this device must be added on the other side too.": "When adding a new device, keep in mind that this device must be added on the other side too.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.",
"Yes": "Yes",
"You can change your choice at any time in the Settings dialog.": "You can change your choice at any time in the Settings dialog.",
"You can read more about the two release channels at the link below.": "You can read more about the two release channels at the link below.",
"You must keep at least one version.": "You must keep at least one version.",
"days": "days",
"directories": "directories",
"files": "files",
"full documentation": "full documentation",
"items": "items",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} wants to share folder \"{{folder}}\".",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderlabel}}\" ({{folder}})."
}

View File

@@ -69,7 +69,7 @@
"Enable NAT traversal": "Abilita NAT traversal",
"Enable Relaying": "Abilita Reindirizzamento",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Inserisci un numero non negativo (ad esempio \"2.35\") e seleziona un'unità. Le percentuali sono parte della dimensione totale del disco.",
"Enter a non-privileged port number (1024 - 65535).": "Enter a non-privileged port number (1024 - 65535).",
"Enter a non-privileged port number (1024 - 65535).": "Inserisci un numero di porta non-privilegiata (1024 - 65535).",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Inserisci indirizzi separati da virgola (\"tcp://ip:porta\", \"tcp://host:porta\") oppure \"dynamic\" per effettuare il rilevamento automatico dell'indirizzo.",
"Enter ignore patterns, one per line.": "Inserisci gli schemi di esclusione, uno per riga.",
"Error": "Errore",
@@ -93,11 +93,11 @@
"GUI": "Interfaccia Grafica Utente",
"GUI Authentication Password": "Password dell'Interfaccia Grafica",
"GUI Authentication User": "Utente dell'Interfaccia Grafica",
"GUI Listen Address": "GUI Listen Address",
"GUI Listen Address": "Indirizzo dell'Interfaccia Grafica",
"GUI Listen Addresses": "Indirizzi dell'Interfaccia Grafica",
"GUI Theme": "Tema GUI",
"Generate": "Genera",
"Global Changes": "Modificazioni Globali",
"Global Changes": "Modifiche Globali",
"Global Discovery": "Individuazione Globale",
"Global Discovery Servers": "Server di Individuazione Globale",
"Global State": "Stato Globale",
@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Si prega di consultare le note di rilascio prima di eseguire un aggiornamento principale.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Per favore impostare Utente e Password dell'Interfaccia Grafica nelle Impostazioni.",
"Please wait": "Attendere prego",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefisso che indica che il file può essere eliminato se impedisce la rimozione della cartella",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefisso che indica che lo schema deve essere abbinato senza tener conto delle maiuscole",
"Preview": "Anteprima",
"Preview Usage Report": "Anteprima Statistiche di Utilizzo",
"Quick guide to supported patterns": "Guida veloce agli schemi supportati",
@@ -181,6 +183,7 @@
"Save": "Salva",
"Scan Time Remaining": "Tempo di Scansione Rimanente",
"Scanning": "Scansione in corso",
"See external versioner help for supported templated command line parameters.": "Consultare la guida al controllo di versione per i modelli dei parametri di riga di comando supportati.",
"Select the devices to share this folder with.": "Seleziona i dispositivi con i quali condividere questa cartella.",
"Select the folders to share with this device.": "Seleziona le cartelle da condividere con questo dispositivo.",
"Send & Receive": "Invia & Ricevi",
@@ -271,6 +274,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "Quando si aggiunge un nuovo dispositivo, tenere presente che il dispositivo deve essere aggiunto anche dall'altra parte.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Quando aggiungi una nuova cartella, ricordati che gli ID vengono utilizzati per collegare le cartelle nei dispositivi. Distinguono maiuscole e minuscole e devono corrispondere esattamente su tutti i dispositivi.",
"Yes": "Sì",
"You can also select one of these nearby devices:": "È anche possibile selezionare uno di questi dispositivi nelle vicinanze:",
"You can change your choice at any time in the Settings dialog.": "Puoi sempre cambiare la tua scelta nel dialogo Impostazioni.",
"You can read more about the two release channels at the link below.": "Puoi ottenere piu informazioni riguarda i due canali di rilascio nel collegamento sottostante.",
"You must keep at least one version.": "È necessario mantenere almeno una versione.",

View File

@@ -1,7 +1,7 @@
{
"A device with that ID is already added.": "指定されたIDのデバイスは登録済みです。",
"A negative number of days doesn't make sense.": "負の日数は指定できません。",
"A new major version may not be compatible with previous versions.": "新しいメジャーバージョンは以前のバージョンと互換性がないかもしれません。",
"A negative number of days doesn't make sense.": "日数は0以上で指定してください。",
"A new major version may not be compatible with previous versions.": "新しいメジャーバージョンは以前のバージョンと互換性がない場合があります。",
"API Key": "APIキー",
"About": "Syncthingについて",
"Action": "動作",
@@ -10,24 +10,24 @@
"Add Device": "デバイスを追加",
"Add Folder": "フォルダーを追加",
"Add Remote Device": "接続先デバイスを追加",
"Add devices from the introducer to our device list, for mutually shared folders.": "紹介者デバイスから紹介されたデバイスは、相互に共有しているフォルダーがある場合、このデバイス上でも登録されます。",
"Add new folder?": "新しいフォルダーとして追加しますか?",
"Add devices from the introducer to our device list, for mutually shared folders.": "紹介者デバイスから紹介されたデバイスは、相互に共有しているフォルダーがある場合、このデバイス上にも追加されます。",
"Add new folder?": "新しいフォルダーとして追加しますか",
"Address": "アドレス",
"Addresses": "アドレス",
"Advanced": "高度な設定",
"Advanced Configuration": "高度な設定",
"Advanced settings": "高度な設定",
"All Data": "全てのデータ",
"Allow Anonymous Usage Reporting?": "匿名で用状況をレポートすることを許可しますか?",
"Allow Anonymous Usage Reporting?": "匿名で使用状況をレポートすることを許可しますか",
"Allowed Networks": "許可されているネットワーク",
"Alphabetic": "アルファベット順",
"An external command handles the versioning. It has to remove the file from the shared folder.": "外部コマンドにバージョン管理を任せます。ここで指定するコマンドは、共有フォルダーからファイルを削除するものでなくてはなりません。",
"An external command handles the versioning. It has to remove the file from the synced folder.": "外部コマンドにバージョンを管理させます。ここで指定するコマンドは、同期フォルダーからファイルを削除するものでなくてはなりません。",
"Anonymous Usage Reporting": "匿名での用状況レポート",
"Any devices configured on an introducer device will be added to this device as well.": "紹介者デバイス上で設定されたデバイスは、このデバイス上も追加されます。",
"Automatic upgrade now offers the choice between stable releases and release candidates.": "自動アップグレードは、安定リリース版とリリース候補版のいずれかを選べるようになりました。",
"Anonymous Usage Reporting": "匿名での使用状況レポート",
"Any devices configured on an introducer device will be added to this device as well.": "紹介者デバイス上で設定されたデバイスは、このデバイス上も追加されます。",
"Automatic upgrade now offers the choice between stable releases and release candidates.": "自動アップグレードは、安定版とリリース候補版のいずれかを選べるようになりました。",
"Automatic upgrades": "自動アップグレード",
"Be careful!": "注意してください。",
"Be careful!": "注意",
"Bugs": "バグ",
"CPU Utilization": "CPU使用率",
"Changelog": "更新履歴",
@@ -35,7 +35,7 @@
"Click to see discovery failures": "接続に失敗した探索サーバーを確認するにはクリックしてください",
"Close": "閉じる",
"Command": "コマンド",
"Comment, when used at the start of a line": "行頭で使用された場合、コメント行",
"Comment, when used at the start of a line": "行頭で使用するとコメント行になります",
"Compression": "圧縮",
"Configured": "設定値",
"Connection Error": "接続エラー",
@@ -45,12 +45,12 @@
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 the following Contributors:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "無視パターンを作成中。既存のファイルが {{path}} にある場合は上書きされます。",
"Danger!": "危険",
"Danger!": "危険",
"Deleted": "削除",
"Device": "デバイス",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "デバイス「{{name}}」 ({{address}} の {{device}}) が接続を求めています。新しいデバイスとして追加しますか?",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "デバイス「{{name}}」 ({{address}} の {{device}}) が接続を求めています。新しいデバイスとして追加しますか",
"Device ID": "デバイスID",
"Device Identification": "デバイス識別情報",
"Device Identification": "デバイスID",
"Device Name": "デバイス名",
"Devices": "デバイス",
"Disconnected": "切断中",
@@ -65,24 +65,24 @@
"Edit Device": "デバイスの編集",
"Edit Folder": "フォルダーの編集",
"Editing": "編集中",
"Editing {%path%}.": "{{path}} を編集中",
"Editing {%path%}.": "{{path}} を編集中",
"Enable NAT traversal": "NATトラバーサルを有効にする",
"Enable Relaying": "中継サーバー経由の通信を有効にする",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "0以上の数 (例: 2.35) を入力し、単位を選択してください。パーセントはディスク容量全体に対する割合です。",
"Enter a non-privileged port number (1024 - 65535).": "非特権ポート番号 (1024 - 65535) を入力してください。",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "アドレスを指定する場合は「tcp://IPアドレス:ポート」または「tcp://ホスト名:ポート」コンマで区切って入力してください。自動探索を行う場合は「dynamic」と入力してください。",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "アドレスを指定する場合は「tcp://IPアドレス:ポート, tcp://ホスト名:ポート」のようにコンマで区切って入力してください。自動探索を行う場合は「dynamic」と入力してください。",
"Enter ignore patterns, one per line.": "無視するファイル名のパターンを、一行につき一条件で入力してください。",
"Error": "エラー",
"External File Versioning": "外部バージョン管理",
"Failed Items": "失敗した項目",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "お使いのネットワークIPv6の接続性がない場合、IPv6のサーバーへの接続に失敗しても異常ではありません。",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "お使いのネットワークIPv6を利用していない場合、IPv6のサーバーへの接続に失敗しても異常ではありません。",
"File Pull Order": "ファイルを取得する順序",
"File Versioning": "ファイルのバージョン管理",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "ファイルの変更を探すときにパーミッションを無視します。FATファイルシステムでご利用ください。",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Syncthingによって置き換えられたり削除されたりしたファイルは、.stversions ディレクトリに移動します。",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Syncthingがファイルを置き換えたり削除したりするとき、古い内容を .stversions フォルダーに移動します。",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Syncthingによって置き換えられたり削除されたりしたファイルは、タイムスタンプ付きのファイル名で .stversions ディレクトリに移動します。",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Syncthingがファイルを置き換えたり削除したりするとき、古い内容はファイル名にタイムスタンプを付けて .stversions フォルダーに移動します。",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "パーミッションの変更を検知しません。FATファイルシステムでご利用ください。",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Syncthingによって置き換えられたり削除されたファイルは、.stversions ディレクトリに移動します。",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Syncthingによって置き換えられたり削除されたファイルは、.stversions フォルダーに移動します。",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Syncthingによって置き換えられたり削除されたファイルは、タイムスタンプ付きのファイル名で .stversions ディレクトリに移動します。",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Syncthingによって置き換えられたり削除されたファイルは、タイムスタンプ付きのファイル名で .stversions フォルダーに移動します。",
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "ファイルを他のデバイスによる変更から保護します。一方、このデバイスでの変更は他のデバイスに送信されます。",
"Folder": "フォルダー",
"Folder ID": "フォルダーID",
@@ -94,12 +94,12 @@
"GUI Authentication Password": "GUI認証パスワード",
"GUI Authentication User": "GUI認証ユーザー名",
"GUI Listen Address": "GUI待ち受けアドレス",
"GUI Listen Addresses": "GUI待ち受けアドレスリスト",
"GUI Listen Addresses": "GUI待ち受けアドレス",
"GUI Theme": "GUIテーマ",
"Generate": "生成",
"Global Changes": "全変更点",
"Global Discovery": "大域探索",
"Global Discovery Servers": "大域探索サーバー",
"Global Discovery": "グローバル探索",
"Global Discovery Servers": "グローバル探索サーバー",
"Global State": "グローバル状態",
"Help": "ヘルプ",
"Home page": "ホームページ",
@@ -107,14 +107,14 @@
"Ignore Patterns": "無視するファイル名",
"Ignore Permissions": "パーミッションを無視する",
"Incoming Rate Limit (KiB/s)": "下り帯域制限 (KiB/s)",
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "間違った設定を行うと、フォルダーの内容を壊したり、Syncthingを操作不能にしたりする可能性があります。",
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "間違った設定を行うと、フォルダーの内容を壊したり、Syncthingが動作しなくなる可能性があります。",
"Introduced By": "紹介元",
"Introducer": "紹介者デバイス",
"Inversion of the given condition (i.e. do not exclude)": "条件の否定 (つまり、無視しないという意味になります)",
"Keep Versions": "保するバージョン数",
"Keep Versions": "保するバージョン数",
"Largest First": "大きい順",
"Last File Received": "最後に受信したファイル",
"Last Scan": "最終スキャン時",
"Last Scan": "最終スキャン時",
"Last seen": "最終接続日時",
"Later": "後で設定",
"Latest Change": "最終変更内容",
@@ -125,7 +125,7 @@
"Local State (Total)": "ローカル状態 (合計)",
"Major Upgrade": "メジャーアップグレード",
"Master": "マスター",
"Maximum Age": "最大寿命",
"Maximum Age": "最大保存日数",
"Metadata Only": "メタデータのみ",
"Minimum Free Disk Space": "同期を停止する最小空きディスク容量",
"Move to top of queue": "最優先にする",
@@ -149,18 +149,20 @@
"Outgoing Rate Limit (KiB/s)": "上り帯域制限 (KiB/s)",
"Override Changes": "他のデバイスの変更を上書きする",
"Path": "パス",
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "ローカルコンピュータ上のフォルダーパス。存在しない場合は作成されます。チルダ (~) で次のフォルダーを短縮入力できます:",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "古いバージョンを保存するパス (空欄の場合、デフォルトで共有フォルダー内の .stversions ディレクトリになります)。",
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "古いバージョンを保存するパス (空欄の場合、デフォルトで .stversions になります)。",
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "ローカルコンピュータ上のフォルダーパス。フォルダーが存在しない場合は作成されます。チルダ (~) で次のフォルダーを短縮入力できます:",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "古いバージョンを保存するパス (空欄の場合、デフォルトで共有フォルダー内の .stversions ディレクトリ)",
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "古いバージョンを保存するパス (空欄の場合、デフォルトでフォルダー内の .stversions フォルダー)",
"Pause": "一時停止",
"Pause All": "すべて一時停止",
"Paused": "一時停止中",
"Please consult the release notes before performing a major upgrade.": "メジャーアップグレードを行う前にリリースノートを参照してください。",
"Please set a GUI Authentication User and Password in the Settings dialog.": "設定ダイアログから、GUI認証ユーザー名とパスワードを設定してください。",
"Please wait": "お待ちください",
"Prefix indicating that the file can be deleted if preventing directory removal": "このファイルが中に残っているためにディレクトリを削除できない場合、このファイルごと消してもよいことを示す接頭辞",
"Prefix indicating that the pattern should be matched without case sensitivity": "大文字・小文字を同一視してマッチさせる接頭辞",
"Preview": "プレビュー",
"Preview Usage Report": "用状況レポートのプレビュー",
"Quick guide to supported patterns": "サポートされているパターンの簡易ガイド",
"Preview Usage Report": "使用状況レポートのプレビュー",
"Quick guide to supported patterns": "サポートされているパターンのクイックガイド",
"RAM Utilization": "メモリ使用量",
"Random": "ランダム",
"Reduced by ignore patterns": "無視パターン該当分を除く",
@@ -181,6 +183,7 @@
"Save": "保存",
"Scan Time Remaining": "スキャン残り時間",
"Scanning": "スキャン中",
"See external versioner help for supported templated command line parameters.": "See external versioner help for supported templated command line parameters.",
"Select the devices to share this folder with.": "このフォルダーを共有するデバイスを選択してください。",
"Select the folders to share with this device.": "このデバイスと共有するフォルダーを選択してください。",
"Send & Receive": "送受信",
@@ -189,28 +192,28 @@
"Share": "共有",
"Share Folder": "フォルダーを共有する",
"Share Folders With Device": "このデバイスと共有するフォルダー",
"Share With Devices": "共有対象のデバイス",
"Share this folder?": "このフォルダーを共有しますか?",
"Shared With": "共有相手",
"Share With Devices": "共有するデバイス",
"Share this folder?": "このフォルダーを共有しますか",
"Shared With": "共有中のデバイス",
"Show ID": "IDを表示",
"Show QR": "QRコードを表示",
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "ステータス画面でデバイスIDの代わりに表示されます。他のデバイスに対してもデフォルトの名前として通知されます。",
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "ステータス画面でデバイスIDの代わりに表示されます。空欄の場合、相手デバイスが通知してきた名前更新されます。",
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "ステータス画面でデバイスIDの代わりに表示されます。空欄にすると相手デバイスが通知してきた名前更新されます。",
"Shutdown": "シャットダウン",
"Shutdown Complete": "シャットダウン完了",
"Simple File Versioning": "単純バージョン管理",
"Single level wildcard (matches within a directory only)": "ワイルドカード (単一のディレクトリ内だけでマッチします)",
"Smallest First": "小さい順",
"Source Code": "ソースコード",
"Stable releases and release candidates": "安定リリース版とリリース候補版",
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "安定リリース版はおよそ2週間後にリリースされます。その間にリリース候補版としてテストされます。",
"Stable releases only": "安定リリース版のみ",
"Stable releases and release candidates": "安定版とリリース候補版",
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "安定版は、リリース候補版としてのテスト後およそ2週間リリースされます。",
"Stable releases only": "安定版のみ",
"Staggered File Versioning": "期間別バージョン管理",
"Start Browser": "起動時にウェブブラウザーで状態を表示する",
"Statistics": "統計情報",
"Stopped": "停止中",
"Support": "サポート",
"Sync Protocol Listen Addresses": "Syncプロトコルの待ち受けアドレスリスト",
"Sync Protocol Listen Addresses": "同期プロトコルの待ち受けアドレス",
"Syncing": "同期中",
"Syncthing has been shut down.": "Syncthingをシャットダウンしました。",
"Syncthing includes the following software or portions thereof:": "Syncthingは以下のソフトウェアまたはその一部を内包しています:",
@@ -221,26 +224,26 @@
"The Syncthing admin interface is configured to allow remote access without a password.": "Syncthingの管理画面が、パスワードなしで外部からアクセスできるように設定されています。",
"The aggregated statistics are publicly available at the URL below.": "集計結果は次のURLで公開されています。",
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "設定が保存されましたが、まだ有効になっていません。新しい設定を有効にするにはSyncthingを再起動してください。",
"The device ID cannot be blank.": "デバイスIDは空欄にできません。",
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "ここに入力するデバイスIDは、接続したい相手側デバイスの [メニュー]→[IDを表示] で確認することができます。スペースとハイフンは入力しなくてもかまいません。",
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.": "用状況レポートは暗号化されて毎日送信されます。この情報はプラットフォーム、フォルダーの大きさ、アプリのバージョンを調査するために使われます。送信するデータセットが変更された場合、このダイアログで再度確認が求められます。",
"The device ID cannot be blank.": "デバイスIDを入力してください。",
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "ここに入力するデバイスIDは、接続したい相手側デバイスの [メニュー]→[IDを表示] で確認できます。スペースとハイフンは入力しなくてもかまいません。",
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.": "使用状況レポートは暗号化されて毎日送信されます。この情報はプラットフォーム、フォルダーのサイズ、アプリケーションのバージョンを調査するために使われます。送信するデータセットが変更された場合、このダイアログで再度確認が求められます。",
"The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.": "入力されたデバイスIDが正しくありません。デバイスIDは52文字または56文字で、アルファベットと数字からなります。スペースとハイフンは入力してもしなくてもかまいません。",
"The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "第1コマンドライン引数はフォルダーのパス、第2引数はフォルダー内の相対パスです。",
"The folder ID cannot be blank.": "フォルダーIDは空欄にできません。",
"The folder ID must be unique.": "フォルダーIDが重複しています。",
"The folder path cannot be blank.": "フォルダーパスは空欄にできません。",
"The following intervals are used: for the first hour a version is kept every 30 seconds, for the first day a version is kept every hour, for the first 30 days a version is kept every day, until the maximum age a version is kept every week.": "保存間隔は次の通りです。最近1時間は30秒ごとに古いバージョンを保存します。同様に、最近1日間は1時間ごとに、最近30日間は1日ごと、その後最大寿命までは1週間ごとに、古いバージョンを保存します。",
"The following intervals are used: for the first hour a version is kept every 30 seconds, for the first day a version is kept every hour, for the first 30 days a version is kept every day, until the maximum age a version is kept every week.": "保存間隔は次の通りです。初めの1時間は30秒ごとに古いバージョンを保存します。同様に、初めの1日間は1時間ごと、初めの30日間は1日ごと、その後最大保存日数までは1週間ごとに、古いバージョンを保存します。",
"The following items could not be synchronized.": "以下の項目は同期できませんでした。",
"The maximum age must be a number and cannot be blank.": "最大寿命は数値を指定してください。空欄にはできません。",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "古いバージョンを保する最大日数 (0を指定すると無期限になります)。",
"The maximum age must be a number and cannot be blank.": "最大保存日数には数値を指定してください。空欄にはできません。",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "古いバージョンを保する最大日数 (0で無期限)",
"The minimum free disk space percentage must be a non-negative number between 0 and 100 (inclusive).": "最小空きディスク容量はパーセントで、0から100の値を入力してください。",
"The number of days must be a number and cannot be blank.": "日数は数値を指定してください。空欄にはできません。",
"The number of days to keep files in the trash can. Zero means forever.": "ゴミ箱ファイルを保する日数。0を指定すると無期限になります。",
"The number of old versions to keep, per file.": "ファイルごとに古いバージョンをいくつ保するかを指定します。",
"The number of versions must be a number and cannot be blank.": "保するバージョン数は数値を指定してください。空欄にはできません。",
"The path cannot be blank.": "パスは空欄にできません。",
"The rate limit must be a non-negative number (0: no limit)": "帯域制限の値として負の数は指定できません (0を指定すると無制限になります)。",
"The rescan interval must be a non-negative number of seconds.": "再スキャン間隔として負の数は指定できません。",
"The number of days to keep files in the trash can. Zero means forever.": "ゴミ箱ファイルを保する日数 (0で無期限)",
"The number of old versions to keep, per file.": "ファイルごとに古いバージョンをいくつ保するかを指定します。",
"The number of versions must be a number and cannot be blank.": "保するバージョン数は数値を指定してください。空欄にはできません。",
"The path cannot be blank.": "パスを入力してください。",
"The rate limit must be a non-negative number (0: no limit)": "帯域制限値は0以上で指定して下さい。 (0で無制限)",
"The rescan interval must be a non-negative number of seconds.": "再スキャン間隔は0秒以上で指定してください。",
"They are retried automatically and will be synced when the error is resolved.": "エラーが解決すると、自動的に再試行され同期されます。",
"This Device": "このデバイス",
"This can easily give hackers access to read and change any files on your computer.": "この設定のままでは、あなたのコンピューターにある任意のファイルを、他者が簡単に盗み見たり書き換えたりすることができます。",
@@ -259,21 +262,22 @@
"Upgrading": "アップグレード中",
"Upload Rate": "アップロード速度",
"Uptime": "稼働時間",
"Usage reporting is always enabled for candidate releases.": "リリース候補版では常に用状況レポートが送信されます。",
"Usage reporting is always enabled for candidate releases.": "リリース候補版では常に使用状況レポートが送信されます。",
"Use HTTPS for GUI": "GUIにHTTPSを使用する",
"Version": "バージョン",
"Versions Path": "古いバージョンを保存するパス",
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "古いバージョンは、最大寿命もしくは期間ごとの最大保存数を超えた場合、自動的に削除されます。",
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "古いバージョンは、最大保存日数もしくは期間ごとの最大保存数を超えた場合、自動的に削除されます。",
"Warning, this path is a parent directory of an existing folder \"{%otherFolder%}\".": "警告: 入力されたパスは、設定済みのフォルダー「{{otherFolder}}」の親ディレクトリです。",
"Warning, this path is a parent directory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "警告: 入力されたパスは、設定済みのフォルダー「{{otherFolderLabel}}」 ({{otherFolder}}) の親ディレクトリです。",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "警告: 入力されたパスは、設定済みのフォルダー「{{otherFolder}}」のサブディレクトリです。",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "警告: 入力されたパスは、設定済みのフォルダー「{{otherFolderLabel}}」 ({{otherFolder}}) のサブディレクトリです。",
"When adding a new device, keep in mind that this device must be added on the other side too.": "新しいデバイスを追加する際は、相手側デバイスにもこのデバイスを追加する必要があることに留意してください。",
"When adding a new device, keep in mind that this device must be added on the other side too.": "新しいデバイスを追加する際は、相手側デバイスにもこのデバイスを追加してください。",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "新しいフォルダーを追加する際、フォルダーIDはデバイス間でフォルダーの対応づけに使われることに注意してください。フォルダーIDは大文字と小文字が区別され、共有するすべてのデバイスの間で完全に一致しなくてはなりません。",
"Yes": "はい",
"You can change your choice at any time in the Settings dialog.": "どちらを選ぶかは設定ダイアログからいつでも変更できます。",
"You can also select one of these nearby devices:": "近くに検出された以下のデバイスの一つを選択できます。",
"You can change your choice at any time in the Settings dialog.": "この設定はいつでも変更できます。",
"You can read more about the two release channels at the link below.": "2種類のリリースチャネルについての詳細は、以下のリンク先を参照してください。",
"You must keep at least one version.": "少なくとも一つのバージョンを保存してください。",
"You must keep at least one version.": "少なくとも一つのバージョンを保持する必要があります。",
"days": "日",
"directories": "個のディレクトリ",
"files": "個のファイル",

View File

@@ -158,12 +158,14 @@
"Please consult the release notes before performing a major upgrade.": "메이저 업데이트를 하기 전에 먼저 릴리즈 노트를 살펴보세요.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "설정에서 GUI 인증용 User와 암호를 입력해주세요.",
"Please wait": "기다려 주십시오",
"Prefix indicating that the file can be deleted if preventing directory removal": "디렉토리 제거를 방지 할 경우 파일을 삭제할 수 있음을 나타내는 접두사",
"Prefix indicating that the pattern should be matched without case sensitivity": "대소 문자를 구분하지 않고 패턴을 일치시켜야 함을 나타내는 접두사",
"Preview": "미리보기",
"Preview Usage Report": "사용 보고서 미리보기",
"Quick guide to supported patterns": "지원하는 패턴에 대한 빠른 도움말",
"RAM Utilization": "RAM 사용량",
"Random": "무작위",
"Reduced by ignore patterns": "Reduced by ignore patterns",
"Reduced by ignore patterns": "무시 패턴으로 축소",
"Release Notes": "릴리즈 노트",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "출시 후보는 최신 기능과 버그 픽스를 포함 하고 있습니다. 이 버전은 예전 방식인 2주 주기 Syncthing 출시와 비슷합니다.",
"Remote Devices": "원격 기기",
@@ -181,6 +183,7 @@
"Save": "저장",
"Scan Time Remaining": "탐색 남은 시간",
"Scanning": "탐색중",
"See external versioner help for supported templated command line parameters.": "지원되는 템플릿 명령 행 매개 변수에 대해서는 외부 버전 도움말을 참조하십시오.",
"Select the devices to share this folder with.": "이 폴더를 공유할 장치를 선택합니다.",
"Select the folders to share with this device.": "이 장치와 공유할 폴더를 선택합니다.",
"Send & Receive": "송신 & 수신",
@@ -271,6 +274,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "새 장치를 추가할 시 추가한 기기 쪽에서도 이 장치를 추가해야 합니다.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "새 폴더를 추가할 시 폴더 ID는 장치간에 폴더를 묶을 때 사용됩니다. 대소문자를 구분하며 모든 장치에서 같은 ID를 사용해야 합니다.",
"Yes": "예",
"You can also select one of these nearby devices:": "주변 기기 중 하나를 선택할 수 있습니다:",
"You can change your choice at any time in the Settings dialog.": "설정창 에서 언제든지 원하시는 때에 설정을 변경하는 것이 가능합니다.",
"You can read more about the two release channels at the link below.": "이 두 개의 출시 채널에 대해 아래 링크에서 자세하게 읽어 보실 수 있습니다.",
"You must keep at least one version.": "최소 한 개의 버전은 유지해야 합니다.",

View File

@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Peržvelkite laidos informaciją prieš atlikdami stambų atnaujinimą.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Prašome nustatymų dialoge nustatyti valdymo skydelio vartotojo vardą ir slaptažodį.",
"Please wait": "Prašome palaukti",
"Prefix indicating that the file can be deleted if preventing directory removal": "Priešdelis, nurodantis, kad failas gali būti ištrintas tuo atveju, jei neleidžia šalinti katalogo",
"Prefix indicating that the pattern should be matched without case sensitivity": "Priešdelis, nurodantis, kad šablonas turėtų būti atitiktas neskiriant raidžių dydžio",
"Preview": "Peržiūra",
"Preview Usage Report": "Naudojimo ataskaitos peržiūra",
"Quick guide to supported patterns": "Trumpas leistinų šablonų vadovas",
@@ -181,6 +183,7 @@
"Save": "Išsaugoti",
"Scan Time Remaining": "Likęs nuskaitymo laikas",
"Scanning": "Skenuojama",
"See external versioner help for supported templated command line parameters.": "Palaikomiems šabloniniams komandų eilutės parametrams, žiūrėkite išorinį versijų valdymo žinyną.",
"Select the devices to share this folder with.": "Pasirinkite įrenginius, su kuriais dalinsitės šį aplanką.",
"Select the folders to share with this device.": "Pasirinkite aplankus kuriais norite dalintis su šiuo įrenginiu.",
"Send & Receive": "Siųsti ir gauti",
@@ -271,6 +274,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "Pridėdami įrenginį, turėkite omeny, kad šis įrenginys taip pat turi būti pridėtas kitoje pusėje.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Kai įvedate naują aplanką neužmirškite, kad jis bus naudojamas visuose įrenginiuose. Svarbu visur įvesti visiškai tokį pat aplanko vardą neužmirštant apie didžiąsias ir mažąsias raides.",
"Yes": "Taip",
"You can also select one of these nearby devices:": "Jūs taip pat galite pasirinkti vieną iš šių šalia esančių įrenginių:",
"You can change your choice at any time in the Settings dialog.": "Jūs bet kuriuo metu galite pakeisti savo pasirinkimą nustatymų dialoge.",
"You can read more about the two release channels at the link below.": "Jūs galite perskaityti daugiau apie šiuos du laidos kanalus, pasinaudodami žemiau esančia nuoroda.",
"You must keep at least one version.": "Būtina saugoti bent vieną versiją.",

View File

@@ -10,7 +10,7 @@
"Add Device": "Legg til enhet",
"Add Folder": "Legg til mappe",
"Add Remote Device": "Legg til ekstern enhet",
"Add devices from the introducer to our device list, for mutually shared folders.": "Add devices from the introducer to our device list, for mutually shared folders.",
"Add devices from the introducer to our device list, for mutually shared folders.": "Legg til enheter fra introdusøren til vår enhetsliste, for innbyrdes delte mapper.",
"Add new folder?": "Legg til ny mappe?",
"Address": "Adresse",
"Addresses": "Adresser",
@@ -19,7 +19,7 @@
"Advanced settings": "Avanserte innstillinger ",
"All Data": "Alle data",
"Allow Anonymous Usage Reporting?": "Tillat anonym innsamling av brukerdata?",
"Allowed Networks": "Allowed Networks",
"Allowed Networks": "Tillatte nettverk",
"Alphabetic": "Alfabetisk",
"An external command handles the versioning. It has to remove the file from the shared folder.": "En ekstern kommando håndterer versjonkontrollen. Den må fjerne filen fra den delte mappa.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "En ekstern kommando håndterer versjonkontrollen. Den må fjerne filen fra den synkroniserte mappa.",
@@ -44,7 +44,7 @@
"Copied from original": "Kopiert fra original",
"Copyright © 2014-2016 the following Contributors:": "Opphavsrett © 2014-2016 for følgende bidragsytere:",
"Copyright © 2014-2017 the following Contributors:": "Opphavsrett © 2014-2017 for følgende bidragsytere:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Oppretter ignoreringsmønster, overskriver eksisterende fil i {{path}}.",
"Danger!": "Fare!",
"Deleted": "Slettet",
"Device": "Enhet",
@@ -65,11 +65,11 @@
"Edit Device": "Rediger enhet",
"Edit Folder": "Rediger mappe",
"Editing": "Redigerer",
"Editing {%path%}.": "Editing {{path}}.",
"Editing {%path%}.": "Redigerer {{path}}.",
"Enable NAT traversal": "Slå på NAT-traversering",
"Enable Relaying": "Aktiver reléforsendelse",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.",
"Enter a non-privileged port number (1024 - 65535).": "Enter a non-privileged port number (1024 - 65535).",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Skriv inn et ikke-negativt nummer (f.eks. \"2.35\") og velg en enhet. Prosenter er deler av total diskstørrelse.",
"Enter a non-privileged port number (1024 - 65535).": "Skriv inn et ikke-priviligert portnummer (1024-65535).",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Skriv inn kommaseparerte (\"tcp://ip:port\", \"tcp://host:port\") adresser, eller ordet \"dynamic\" for å gjøre automatisk oppslag i adressen.",
"Enter ignore patterns, one per line.": "Skriv inn mønster som skal utelates, ett per linje.",
"Error": "Feilmelding",
@@ -93,7 +93,7 @@
"GUI": "grafisk brukergrensesnitt",
"GUI Authentication Password": "Passord for GUI-autenisering",
"GUI Authentication User": "Bruker for GUI-autenisering",
"GUI Listen Address": "GUI Listen Address",
"GUI Listen Address": "Lytteadresse for grafisk brukergrensesnitt",
"GUI Listen Addresses": "GUI-lytteadresse",
"GUI Theme": "GUI-tema",
"Generate": "Generer",
@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Sjekk utgivelsesnotatene før en storoppgradering utføres.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Vennligst angi bruker og passord for GUI-autentisering i innstillingsvinduet.",
"Please wait": "Vent",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefiks som indikerer at fila kan slettes hvis den forhindrer fjerning av mappe",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefiks som indikerer at mønsteret skal samsvare uten versalsensitivitet",
"Preview": "Forhåndsvisning",
"Preview Usage Report": "Forhåndsvisning av datainnsamling",
"Quick guide to supported patterns": "Kjapp innføring i godkjente mønster",
@@ -181,6 +183,7 @@
"Save": "Lagre",
"Scan Time Remaining": "Gjenstående tid for gjennomsøking",
"Scanning": "Gjennomsøker",
"See external versioner help for supported templated command line parameters.": "Se ekstern versjoneringshjelp for støttede mal-baserte kommandolinjeparameter.",
"Select the devices to share this folder with.": "Velg enhetene du vil dele denne mappen med.",
"Select the folders to share with this device.": "Velg hvilke mapper som skal deles med denne enheten.",
"Send & Receive": "Sende og motta",
@@ -245,7 +248,7 @@
"This Device": "Denne enheten",
"This can easily give hackers access to read and change any files on your computer.": "Dette kan lett gi hackere tilgang til å lese og endre alle filer på datamaskinen din.",
"This is a major version upgrade.": "Dette er en storoppgradering",
"This setting controls the free space required on the home (i.e., index database) disk.": "This setting controls the free space required on the home (i.e., index database) disk.",
"This setting controls the free space required on the home (i.e., index database) disk.": "Denne innstillingen kontrollerer ledig diskplass krevd på hjemme- (f.eks. indekseringsdatabase-) disken.",
"Time": "Klokkeslett",
"Trash Can File Versioning": "Papirkurv versjonskontroll",
"Type": "Type",
@@ -268,9 +271,10 @@
"Warning, this path is a parent directory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Advarsel, denne stien er en foreldremappe for en eksisterende mappe \"{{otherFolderLabel}}\" ({{otherFolder}}).",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Advarsel, denne stien er en undermappe i en eksisterende mappe \"{{otherFolder}}\".",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Advarsel, denne stien er en undermappe for en eksisterende mappe \"{{otherFolderLabel}}\" ({{otherFolder}}).",
"When adding a new device, keep in mind that this device must be added on the other side too.": "Merk at når en ny enhet blir lagt til må denne også legges til på andre siden.",
"When adding a new device, keep in mind that this device must be added on the other side too.": "Når du legger til en ny enhet, husk at enheten må legges til på andre siden også.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Når en ny mappe blir lagt til, husk at Mappe-ID blir brukt til å binde sammen mapper mellom enheter. Det er forskjell på store og små bokstaver, så IDene må være identiske på alle enhetene.",
"Yes": "Ja",
"You can also select one of these nearby devices:": "Du kan også velge en av disse enhetene i nærheten:",
"You can change your choice at any time in the Settings dialog.": "Du kan endre ditt valg når som helst i innstillingene.",
"You can read more about the two release channels at the link below.": "Du kan lese mer om de to nye utgivelseskanalene i lenken nedenfor.",
"You must keep at least one version.": "Du må beholde minst én versjon",

View File

@@ -9,7 +9,7 @@
"Add": "Toevoegen",
"Add Device": "Apparaat toevoegen",
"Add Folder": "Map toevoegen",
"Add Remote Device": "Voeg extern apparaat toe",
"Add Remote Device": "Extern apparaat toevoegen",
"Add devices from the introducer to our device list, for mutually shared folders.": "Voeg apparaten van het introductieapparaat toe aan de lijst met apparaten voor gemeenschappelijk gedeelde mappen.",
"Add new folder?": "Nieuwe map toevoegen?",
"Address": "Adres",
@@ -32,7 +32,7 @@
"CPU Utilization": "CPU-gebruik",
"Changelog": "Logboek",
"Clean out after": "Schoon op na",
"Click to see discovery failures": "Klik om ontdekkingsproblemen weer te geven",
"Click to see discovery failures": "Klikken om ontdekkingsproblemen weer te geven",
"Close": "Sluiten",
"Command": "Commando",
"Comment, when used at the start of a line": "Reageer indien gebruikt aan het begin van een lijn.",
@@ -43,7 +43,7 @@
"Copied from elsewhere": "Gekopieerd vanaf elders",
"Copied from original": "Gekopieerd van het origineel",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 voor de volgende bijdragers:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 de volgende bijdragers:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 voor de volgende bijdragers:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Negeerpatronen worden aangemaakt, bestaand bestand wordt overschreven op {{path}}.",
"Danger!": "Let op!",
"Deleted": "Verwijderd",
@@ -63,13 +63,13 @@
"Downloading": "Bezig met downloaden",
"Edit": "Bewerk",
"Edit Device": "Bewerk apparaat",
"Edit Folder": "Bewerk map",
"Edit Folder": "Map bewerken",
"Editing": "Bezig met bewerken",
"Editing {%path%}.": "Bezig met bewerken van {{path}}.",
"Enable NAT traversal": "Activeer NAT traversal",
"Enable Relaying": "Activeer doorsturen",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.",
"Enter a non-privileged port number (1024 - 65535).": "Enter a non-privileged port number (1024 - 65535).",
"Enable NAT traversal": "NAT traversal inschakelen",
"Enable Relaying": "Doorsturen inschakelen",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Voer een positief nummer in (bijv. \"2.35\") en selecteer een eenheid. Percentages zijn een onderdeel van de totale schijfgrootte.",
"Enter a non-privileged port number (1024 - 65535).": "Voer een niet-geprivilegieerd poortnummer in (1024 - 65535).",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Voer door komma's gescheiden (\"tcp://ip:port\", \"tcp://host:port\") adressen in of voer \"dynamisch\" in om automatische ontdekking van het adres uit te voeren.",
"Enter ignore patterns, one per line.": "Voer negeerpatronen in, één per regel.",
"Error": "Fout",
@@ -93,7 +93,7 @@
"GUI": "GUI",
"GUI Authentication Password": "GUI-wachtwoord",
"GUI Authentication User": "GUI-gebruikersnaam",
"GUI Listen Address": "GUI Listen Address",
"GUI Listen Address": "GUI-luisteradres",
"GUI Listen Addresses": "GUI-adres",
"GUI Theme": "GUI-thema",
"Generate": "Genereer",
@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Lees eerst de release notes voordat u een grote update uitvoert.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Stel een gebruikersnaam en wachtwoord in bij 'Instellingen'.",
"Please wait": "Even geduld",
"Prefix indicating that the file can be deleted if preventing directory removal": "Voorvoegsel dat aangeeft dat het bestand kan worden verwijderd als het bestand het verwijderen van een map voorkomt",
"Prefix indicating that the pattern should be matched without case sensitivity": "Voorvoegsel dat aangeeft dat het patroon hoofdletterongevoelig moet worden vergeleken",
"Preview": "Preview",
"Preview Usage Report": "Preview gebruiksstatistieken",
"Quick guide to supported patterns": "Snelgids voor ondersteunde patronen",
@@ -181,6 +183,7 @@
"Save": "Bewaar",
"Scan Time Remaining": "Resterende scantijd",
"Scanning": "Aan het zoeken",
"See external versioner help for supported templated command line parameters.": "Zie de documentatie van de externe versie voor ondersteunde command line parameters.",
"Select the devices to share this folder with.": "Selecteer de apparaten om deze map mee te delen.",
"Select the folders to share with this device.": "Selecteer de mappen om met dit apparaat te delen.",
"Send & Receive": "Verzenden & Ontvangen",
@@ -245,7 +248,7 @@
"This Device": "Dit apparaat",
"This can easily give hackers access to read and change any files on your computer.": "Dit kan kwaadwilligen eenvoudig toegang geven tot het lezen en wijzigen van bestanden op jouw computer.",
"This is a major version upgrade.": "Dit is een grote update.",
"This setting controls the free space required on the home (i.e., index database) disk.": "This setting controls the free space required on the home (i.e., index database) disk.",
"This setting controls the free space required on the home (i.e., index database) disk.": "Deze instelling beheert de benodigde vrije ruimte op de home (index database) schijf.",
"Time": "Tijd",
"Trash Can File Versioning": "Versiebeheer bestanden prullenbak",
"Type": "Type",
@@ -271,6 +274,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "Wanneer een nieuw toestel wordt toegevoegd, houd er dan rekening mee dat dit toestel ook aan de andere kant moet worden toegevoegd.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Houd er bij het toevoegen van nieuwe mappen rekening mee dat het map-ID gebruikt wordt om mappen tussen apparaten te verbinden. Dit ID is hoofdlettergevoelig en moet identiek zijn op andere apparaten.",
"Yes": "Ja",
"You can also select one of these nearby devices:": "U kunt ook een van de apparaten die dichtbij zijn selecteren:",
"You can change your choice at any time in the Settings dialog.": "Je kan je keuze op elk moment aanpassen in de Instellingen.",
"You can read more about the two release channels at the link below.": "Je kan meer te weten komen over de twee uitgavekanalen via de link hieronder.",
"You must keep at least one version.": "Minstens 1 versie moet bewaard blijven.",

View File

@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Sjå utgjevingsmerknadene før ei hovudoppgradering vert utført.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Ver vennleg å laga ein GUI-brukar og eit passord i Innstillingar-dialogen.",
"Please wait": "Gjer vel og vent",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefix indicating that the file can be deleted if preventing directory removal",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefix indicating that the pattern should be matched without case sensitivity",
"Preview": "Førehandsvisning",
"Preview Usage Report": "Førehandsvis bruksrapporten",
"Quick guide to supported patterns": "Kjapp innføring i godkjente mønster",
@@ -181,6 +183,7 @@
"Save": "Lagre",
"Scan Time Remaining": "Gjenståande skannetid",
"Scanning": "Skannar",
"See external versioner help for supported templated command line parameters.": "See external versioner help for supported templated command line parameters.",
"Select the devices to share this folder with.": "Vel einingane du vil dela denne mappa med.",
"Select the folders to share with this device.": "Vel mappene du vil dela med denne eininga.",
"Send & Receive": "Sende og motta",
@@ -271,6 +274,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "Hugs at når ei ny eining vert lagt til, må ho òg leggjast til på andre sida.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Hugs at når ei ny mappe vert lagt til, vert mappe-ID-en brukt til å binda saman mappene mellom einingane. Det er skilnad på store og små bokstavar, så ID-ane må vera identiske på alle einingane.",
"Yes": "Ja",
"You can also select one of these nearby devices:": "You can also select one of these nearby devices:",
"You can change your choice at any time in the Settings dialog.": "You can change your choice at any time in the Settings dialog.",
"You can read more about the two release channels at the link below.": "You can read more about the two release channels at the link below.",
"You must keep at least one version.": "Du må behalda minst ein versjon.",

View File

@@ -1,5 +1,5 @@
{
"A device with that ID is already added.": "Urządzenie o tym ID jest już dodane.",
"A device with that ID is already added.": "Urządzenie o tym ID już istnieje.",
"A negative number of days doesn't make sense.": "Ujemna ilość dni nie ma sensu.",
"A new major version may not be compatible with previous versions.": "Nowa wersja może być niekompatybilna z poprzednimi wersjami.",
"API Key": "Klucz API",
@@ -10,7 +10,7 @@
"Add Device": "Dodaj urządzenie",
"Add Folder": "Dodaj folder",
"Add Remote Device": "Dodaj urządzenie zdalne",
"Add devices from the introducer to our device list, for mutually shared folders.": "Add devices from the introducer to our device list, for mutually shared folders.",
"Add devices from the introducer to our device list, for mutually shared folders.": "Dodaj urządzenia od wprowadzającego do tej maszyny alby obustronnie dzielić katalogi.",
"Add new folder?": "Dodać nowy folder?",
"Address": "Adres",
"Addresses": "Adresy",
@@ -19,20 +19,20 @@
"Advanced settings": "Ustawienia zaawansowane",
"All Data": "Wszystkie dane",
"Allow Anonymous Usage Reporting?": "Zezwalaj na anonimowe statystyki użycia?",
"Allowed Networks": "Allowed Networks",
"Allowed Networks": "Dozwolone sieci",
"Alphabetic": "Alfabetycznie",
"An external command handles the versioning. It has to remove the file from the shared folder.": "An external command handles the versioning. It has to remove the file from the shared folder.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Zewnętrzna komenda obsługuje kontrolę wersji. Musi ona usuć ten plik z synchronizowanego folderu.",
"An external command handles the versioning. It has to remove the file from the shared folder.": "Zewnętrzna komenda odpowiedzialna za wersjonowanie. Musi usunąć plik ze współdzielonego folderu.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Zewnętrzna komenda odpowiedzialna za wersjonowanie. Musi usuwać ten plik z synchronizowanego folderu.",
"Anonymous Usage Reporting": "Anonimowe statystyki użycia",
"Any devices configured on an introducer device will be added to this device as well.": "Wszystkie urządzenia skonfigurowane na urządzeniu wprowadzającym zostaną dodane także do tego urządzenia.",
"Automatic upgrade now offers the choice between stable releases and release candidates.": "Automatic upgrade now offers the choice between stable releases and release candidates.",
"Automatic upgrade now offers the choice between stable releases and release candidates.": "Automatyczne aktualizacje pozwalają teraz wybrać pomiędzy wydaniami stabilnymi a wersjami kandydującymi.",
"Automatic upgrades": "Automatyczne aktualizacje",
"Be careful!": "Uważaj!",
"Bugs": "Błędy",
"CPU Utilization": "Użycie CPU",
"Changelog": "Historia zmian",
"Clean out after": "Uporządkuj",
"Click to see discovery failures": "Click to see discovery failures",
"Click to see discovery failures": "Kliknij aby zobaczyć błędy odnajdywania",
"Close": "Zamknij",
"Command": "Polecenie",
"Comment, when used at the start of a line": "Komentarz, jeżeli użyty na początku linii",
@@ -43,8 +43,8 @@
"Copied from elsewhere": "Skopiowane z innego miejsca ",
"Copied from original": "Skopiowane z oryginału",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016: ",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 the following Contributors:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Copyright © 2014-2017 the following Contributors:": "Prawa autorskie © 2014-2017 dla następujących autorów:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Ustawienie wzorów ignorowania, nadpisze istniejący plik w {{path}}.",
"Danger!": "Niebezpieczne!",
"Deleted": "Usunięto",
"Device": "Urządzenie",
@@ -56,7 +56,7 @@
"Disconnected": "Rozłączony",
"Discovered": "Odkryte",
"Discovery": "Odnajdywanie",
"Discovery Failures": "Discovery Failures",
"Discovery Failures": "Błędy odnajdowania",
"Documentation": "Dokumentacja",
"Download Rate": "Prędkość pobierania",
"Downloaded": "Pobrane",
@@ -65,23 +65,23 @@
"Edit Device": "Edytuj urządzenie",
"Edit Folder": "Edytuj folder",
"Editing": "Edytowanie",
"Editing {%path%}.": "Editing {{path}}.",
"Editing {%path%}.": "Edytowanie {{path}}.",
"Enable NAT traversal": "Włącz trawersowanie NAT",
"Enable Relaying": "Włącz przekazywanie",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.",
"Enter a non-privileged port number (1024 - 65535).": "Enter a non-privileged port number (1024 - 65535).",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Wpisz nieujemną liczbę (np. \"2.35\") oraz wybierz jednostkę. Wartość procentowa odnosi się do rozmiaru całego dysku.",
"Enter a non-privileged port number (1024 - 65535).": "Wpisz nieuprzywilejowany numer portu (1024-65535).",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Wpisz oddzielone przecinkiem adresy (\"tcp://ip:port\", \"tcp://host:port\") lub \"dynamic\" by przeprowadzić automatyczne odnalezienie adresu.",
"Enter ignore patterns, one per line.": "Wprowadź wzorce ignorowania, jeden w każdej linii.",
"Error": "Błąd",
"External File Versioning": "Zewnętrzne wersjonowanie pliku",
"Failed Items": "Niepowodzenia",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Błąd połączenia do serwerów IPv6 może wystąpić, jeśli brakuje połączenia po IPv6 w ogóle.",
"File Pull Order": "Kolejność pobierania plików",
"File Versioning": "Kontrola wersji",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Uprawnienia plików są ignorowane przy poszukiwaniu zmian. Używaj w systemie plików FAT.",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Files are moved to .stversions directory when replaced or deleted by Syncthing.",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Pliki są przenoszone do folderu .stversions przez Syncthing, kiedy zostaną zmienione lub usunięte.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Pliki przenoszone są do folderu .stversions gdy są zastępowane bądź usuwane przez Syncthing.",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Pliki są datowane i przenoszone do folderu .stversions przez Syncthing, kiedy zostaną zmienione lub usunięte.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Pliki przenoszone są do wersji oznaczonych datą w folderze .stversions kiedy są zastępowane bądź usuwane przez Syncthing",
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Pliki są zabezpieczone przed zmianami na innym urządzeniu, jednak zmiany w tym urządzeniu będą wysłane do reszty.",
"Folder": "Folder",
@@ -93,11 +93,11 @@
"GUI": "GUI",
"GUI Authentication Password": "Hasło",
"GUI Authentication User": "Użytkownik",
"GUI Listen Address": "GUI Listen Address",
"GUI Listen Address": "Adres nasłuchu GUI",
"GUI Listen Addresses": "Adres nasłuchiwania",
"GUI Theme": "Motyw GUI",
"Generate": "Generuj",
"Global Changes": "Globalne zmiany",
"Global Changes": "Zmiany globalne",
"Global Discovery": "Globalne odnajdywanie",
"Global Discovery Servers": "Globalne serwery odkrywania",
"Global State": "Status globalny",
@@ -108,7 +108,7 @@
"Ignore Permissions": "Ignoruj uprawnienia",
"Incoming Rate Limit (KiB/s)": "Ograniczenie prędkości odbierania (KiB/s)",
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "Niepoprawna konfiguracja może uszkodzić zawartośc Twojego folderu i uczynić Syncthing niedziałającym.",
"Introduced By": "Wprowadzony Przez",
"Introduced By": "Wprowadzony przez",
"Introducer": "Wprowadzający",
"Inversion of the given condition (i.e. do not exclude)": "Odwrócenie podanego wzorca (np. nie wykluczaj)",
"Keep Versions": "Zachowuj wersje",
@@ -118,7 +118,7 @@
"Last seen": "Ostatnio widziany",
"Later": "Później",
"Latest Change": "Ostatnia zmiana",
"Learn more": "Learn more",
"Learn more": "Zobacz więcej",
"Listeners": "Nasłuchujący",
"Local Discovery": "Lokalne odnajdywanie",
"Local State": "Status lokalny",
@@ -136,7 +136,7 @@
"Newest First": "Najnowsze na początku",
"No": "Nie",
"No File Versioning": "Bez wersjonowania pliku",
"No upgrades": "Bez aktualizacji",
"No upgrades": "Brak aktualizacji",
"Normal": "Zwykły",
"Notice": "Wskazówka",
"OK": "OK",
@@ -150,7 +150,7 @@
"Override Changes": "Nadpisz zmiany",
"Path": "Ścieżka",
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "Ścieżka do lokalnego folderu. Zostanie utworzona jeżeli nie istnieje.\nZnak tyldy (~) może zostać użyty jako skrót do",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "Ścieżka gdzie wersje będą przechowywane (pozostaw puste dla domyślnego folderu .stversions we współ. folderze).",
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Ścieżka gdzie będą przechowywane wersje (pozostaw puste dla domyślnego folderu .stversions)",
"Pause": "Zatrzymaj",
"Pause All": "Zatrzymaj wszystkie",
@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Zaleca się przeanalizowanie \"release notes\" przed przeprowadzeniem znaczącej aktualizacji.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Ustaw proszę użytkownika i hasło dostępowe do GUI w Ustawieniach",
"Please wait": "Proszę czekać",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefiks wskazujący, że plik może zostać usunięty w przypadku zapobiegania usunięciu katalogu",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefiks wskazujący, że wzorzec powinien być dopasowany bez rozróżniania wielkości liter",
"Preview": "Podgląd",
"Preview Usage Report": "Podgląd raportu użycia.",
"Quick guide to supported patterns": "Krótki przewodnik po obsługiwanych wzorcach",
@@ -165,7 +167,7 @@
"Random": "Losowo",
"Reduced by ignore patterns": "Ograniczono przez wzorce ignorowania",
"Release Notes": "Informacje o wydaniu",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Wydania kandydujące zawierają najnowsze funkcje oraz poprawki błędów. Są one podobne do tradycyjnych co dwutygodniowych wydań Syncthing.",
"Remote Devices": "Urządzenia zdalne",
"Remove": "Usuń",
"Required identifier for the folder. Must be the same on all cluster devices.": "Wymagany identyfikator dla folderu. Musi być taki sam na wszystkich urządzeniach.",
@@ -181,6 +183,7 @@
"Save": "Zapisz",
"Scan Time Remaining": "Pozostały czas skanowania",
"Scanning": "Skanowanie",
"See external versioner help for supported templated command line parameters.": "See external versioner help for supported templated command line parameters.",
"Select the devices to share this folder with.": "Wybierz urządzenie, któremu udostępnić folder.",
"Select the folders to share with this device.": "Wybierz foldery do współdzielenia z tym urządzeniem.",
"Send & Receive": "Wyślij i odbierz",
@@ -202,8 +205,8 @@
"Single level wildcard (matches within a directory only)": "Wieloznaczność na poziomie plików (uwzględnia nazwy plików)",
"Smallest First": "Najmniejsze na początku",
"Source Code": "Kod źródłowy",
"Stable releases and release candidates": "Stable releases and release candidates",
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.",
"Stable releases and release candidates": "Wydania stabilne i wydania kandydujące",
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "Wydania stabilne są opóźnione ok. dwa tygodnie. W tym czasie są testowane jako wydania kandydujące.",
"Stable releases only": "Tylko stabilne wydania",
"Staggered File Versioning": "Rozbudowane wersjonowanie pliku",
"Start Browser": "Uruchom przeglądarkę",
@@ -245,7 +248,7 @@
"This Device": "To urządzenie",
"This can easily give hackers access to read and change any files on your computer.": "Może to umożliwić osobom trzecim dostęp do odczytu i zmian dowolnych plików na urządzeniu.",
"This is a major version upgrade.": "To jest ważna aktualizacja",
"This setting controls the free space required on the home (i.e., index database) disk.": "This setting controls the free space required on the home (i.e., index database) disk.",
"This setting controls the free space required on the home (i.e., index database) disk.": "Te ustawienia kontrolują ilość potrzebnej wolnej przestrzeni na dysku domowym (np. indeksowanie bazy danych).",
"Time": "Czas",
"Trash Can File Versioning": "Kontrola werjsi plików w koszu",
"Type": "Typ",
@@ -259,7 +262,7 @@
"Upgrading": "Aktualizowanie",
"Upload Rate": "Prędkość wysyłania",
"Uptime": "Czas działania",
"Usage reporting is always enabled for candidate releases.": "Usage reporting is always enabled for candidate releases.",
"Usage reporting is always enabled for candidate releases.": "Raportowanie użycia dla wydań kandydujących jest zawsze włączone.",
"Use HTTPS for GUI": "Używaj HTTPS",
"Version": "Wersja",
"Versions Path": "Ścieżka wersji",
@@ -271,8 +274,9 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "Gdy dodajesz nowe urządzenie, pamiętaj że urządzenie musi zostać dodane także po drugiej stronie.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Przy dodawaniu nowego folderu, pamiętaj, że ID użyte jest do łączenia folderów pomiędzy urządzeniami. Wielkość liter ciągu ma znaczenie musi zgadzać się na wszystkich urządzeniach.",
"Yes": "Tak",
"You can change your choice at any time in the Settings dialog.": "Możesz zmienić swój wybór w dowolnej chwili w oknie Ustawi.",
"You can read more about the two release channels at the link below.": "You can read more about the two release channels at the link below.",
"You can also select one of these nearby devices:": "Możesz również wybrać jedno z pobliskich urządz:",
"You can change your choice at any time in the Settings dialog.": "Możesz zmienić swój wybór w dowolnej chwili w Ustawieniach",
"You can read more about the two release channels at the link below.": "Możesz więcej poczytać na temat obydwu wydań klikając poniższy link.",
"You must keep at least one version.": "Musisz posiadać przynajmniej jedną wersję",
"days": "dni",
"directories": "katalogi",

View File

@@ -79,10 +79,10 @@
"File Pull Order": "Ordem de retirada do arquivo",
"File Versioning": "Versionamento de arquivos",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Os bits de permissão de um arquivo são ignorados durante as verificações. Use em sistemas de arquivo FAT.",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Os arquivos são movidos para o diretório .stversions quando são substituídos ou apagados pelo Syncthing.",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Os arquivos são movidos para o diretório .stversions quando substituídos ou apagados pelo Syncthing.",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Os arquivos são movidos para a pasta .stversions quando substituídos ou apagados pelo Syncthing.",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Os arquivos são renomeados com datas e movidos para o diretório .stversions quando são substituídos ou apagados pelo Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Os arquivos são renomeados com suas datas na pasta .stversions após serem substituídos ou removidos pelo Syncthing.",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Os arquivos são renomeados com suas datas e movidos para o diretório .stversions quando substituídos ou apagados pelo Syncthing.",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Os arquivos são renomeados com suas datas na pasta .stversions quando substituídos ou removidos pelo Syncthing.",
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Os arquivos estão protegidos contra alterações feitas em outros dispositivos, mas alterações feitas neste dispositivo serão enviadas ao resto dos dispositivos.",
"Folder": "Pasta",
"Folder ID": "ID da pasta",
@@ -150,7 +150,7 @@
"Override Changes": "Sobrescrever alterações",
"Path": "Caminho",
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "Caminho para a pasta na máquina local. Será criado caso não exista. O caractere til (~) pode ser usado como um atalho para",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "Caminho do diretório onde as versões são salvas (deixe em branco para o diretório padrão .stversions dentro da pasta compartilhada). ",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "Caminho do diretório onde as versões são salvas (deixe em branco para que seja o diretório padrão .stversions dentro da pasta compartilhada). ",
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "O caminho onde as versões serão salvas (deixe vazio para usar a pasta padrão .stversions dentro desta pasta).",
"Pause": "Pausar",
"Pause All": "Pausar Todas",
@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Por favor, consulte as notas de lançamento antes de atualizar para uma versão \"major\".",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Por favor, defina um nome de usuário e senha para acesso à interface web, nas configurações.",
"Please wait": "Aguarde",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefixo indicando que o arquivo pode ser removido caso esteja impedindo a remoção do seu diretório",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefixo indicando que o filtro deve ser igualado sem distinção entre maiúsculas e minúsculas",
"Preview": "Visualizar",
"Preview Usage Report": "Visualizar relatório de uso",
"Quick guide to supported patterns": "Guia rápido dos padrões suportados",
@@ -181,6 +183,7 @@
"Save": "Salvar",
"Scan Time Remaining": "Tempo de verificação restante",
"Scanning": "Verificando",
"See external versioner help for supported templated command line parameters.": "See external versioner help for supported templated command line parameters.",
"Select the devices to share this folder with.": "Selecione os dispositivos com os quais esta pasta será compartilhada.",
"Select the folders to share with this device.": "Selecione as pastas a serem compartilhadas com este dispositivo.",
"Send & Receive": "Envia e recebe",
@@ -245,7 +248,7 @@
"This Device": "Este dispositivo",
"This can easily give hackers access to read and change any files on your computer.": "Isto pode dar a hackers poder de leitura e escrita de qualquer arquivo em seu dispositivo.",
"This is a major version upgrade.": "Esta é uma atualização para uma versão \"major\".",
"This setting controls the free space required on the home (i.e., index database) disk.": "This setting controls the free space required on the home (i.e., index database) disk.",
"This setting controls the free space required on the home (i.e., index database) disk.": "Este ajuste controla o espaço livre necessário no disco que contém o banco de dados do Syncthing.",
"Time": "Hora",
"Trash Can File Versioning": "Lixeira",
"Type": "Tipo",
@@ -262,7 +265,7 @@
"Usage reporting is always enabled for candidate releases.": "O relatório de uso está sempre habilitado em versões candidatas ao lançamento",
"Use HTTPS for GUI": "Usar HTTPS para a interface web",
"Version": "Versão",
"Versions Path": "Caminho das versões",
"Versions Path": "Caminho do versionamento",
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "As versões são automaticamente apagadas se elas são mais antigas do que a idade máxima ou excederem o número de arquivos permitido em um intervalo.",
"Warning, this path is a parent directory of an existing folder \"{%otherFolder%}\".": "Aviso: este caminho é o diretório pai da pasta \"{{otherFolder}}\".",
"Warning, this path is a parent directory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Aviso: este caminho é o diretório pai da pasta \"{{otherFolderLabel}}\" ({{otherFolder}}).",
@@ -271,6 +274,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "Quando estiver adicionando um dispositivo, lembre-se de que este dispositivo deve ser adicionado do outro lado também.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Quando adicionar uma nova pasta, lembre-se que o ID da pasta é utilizado para ligar pastas entre dispositivos. Ele é sensível às diferenças entre maiúsculas e minúsculas e deve ser o mesmo em todos os dispositivos.",
"Yes": "Sim",
"You can also select one of these nearby devices:": "Vocẽ também pode selecionar um destes dispositivos próximos:",
"You can change your choice at any time in the Settings dialog.": "Você pode mudar de ideia a qualquer momento na tela de configurações.",
"You can read more about the two release channels at the link below.": "Você pode se informar melhor sobre os dois canais de lançamento no link abaixo.",
"You must keep at least one version.": "Você deve manter pelo menos uma versão.",

View File

@@ -136,7 +136,7 @@
"Newest First": "Primeiro os mais recentes",
"No": "Não",
"No File Versioning": "Nenhuma",
"No upgrades": "Não existem actualizações",
"No upgrades": "Sem actualizações",
"Normal": "Normal",
"Notice": "Avisos",
"OK": "OK",
@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Consulte as notas de lançamento antes de fazer uma actualização importante.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Por favor, defina um utilizador e senha de autenticação para a interface gráfica, nas configurações.",
"Please wait": "Aguarde",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefixo para indicar que o ficheiro pode ser eliminado se estiver a impedir a eliminação da pasta",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefixo para indicar que o padrão não diferencia entre maiúsculas e minúsculas",
"Preview": "Previsão",
"Preview Usage Report": "Pré-visualizar relatório de utilização",
"Quick guide to supported patterns": "Guia rápido dos padrões suportados",
@@ -181,6 +183,7 @@
"Save": "Gravar",
"Scan Time Remaining": "Tempo restante da verificação",
"Scanning": "Verificando",
"See external versioner help for supported templated command line parameters.": "Veja a ajuda do gestor de versões externo para saber que parâmetros da linha de comandos são suportados.",
"Select the devices to share this folder with.": "Seleccione os dispositivos com os quais vai partilhar esta pasta.",
"Select the folders to share with this device.": "Seleccione as pastas a partilhar com este dispositivo.",
"Send & Receive": "Envia e recebe",
@@ -271,6 +274,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "Quando adicionar um novo dispositivo, lembre-se que este dispositivo tem que ser adicionado do outro lado também.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Quando adicionar uma nova pasta, lembre-se que o ID da pasta é utilizado para ligar as pastas entre dispositivos. É sensível às diferenças entre maiúsculas e minúsculas e tem que ter uma correspondência perfeita entre todos os dispositivos.",
"Yes": "Sim",
"You can also select one of these nearby devices:": "Também pode seleccionar um destes dispositivos que estão próximos:",
"You can change your choice at any time in the Settings dialog.": "Pode modificar a sua escolha em qualquer altura nas configurações.",
"You can read more about the two release channels at the link below.": "Pode ler mais sobre os dois canais de lançamento na ligação abaixo.",
"You must keep at least one version.": "Tem que manter pelo menos uma versão.",

View File

@@ -19,9 +19,9 @@
"Advanced settings": "Дополнительные настройки",
"All Data": "Все данные",
"Allow Anonymous Usage Reporting?": "Разрешить анонимный отчет об использовании?",
"Allowed Networks": "Allowed Networks",
"Allowed Networks": "Разрешённые сети",
"Alphabetic": "По алфавиту",
"An external command handles the versioning. It has to remove the file from the shared folder.": "An external command handles the versioning. It has to remove the file from the shared folder.",
"An external command handles the versioning. It has to remove the file from the shared folder.": "Для версионирования используется внешняя программа. Ей нужно удалить файл из общей папки.",
"An external command handles the versioning. It has to remove the file from the synced folder.": "Внешний процесс управляет версиями файлов. Процесс удалит файл из синхронизируемой папки.",
"Anonymous Usage Reporting": "Анонимный отчет об использовании",
"Any devices configured on an introducer device will be added to this device as well.": "Все устройства, подключённые к устройству-рекомендателю, будут добавлены к текущему устройству.",
@@ -43,7 +43,7 @@
"Copied from elsewhere": "Скопировано из другого места",
"Copied from original": "Скопировано с оригинала",
"Copyright © 2014-2016 the following Contributors:": "Авторские права © 20142016 принадлежат:",
"Copyright © 2014-2017 the following Contributors:": "Авторское право © 2014-2017 следующие участники:",
"Copyright © 2014-2017 the following Contributors:": "Авторские права © 20142017 следующие участники:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Danger!": "Опасно!",
"Deleted": "Удалено",
@@ -65,23 +65,23 @@
"Edit Device": "Редактирование устройства",
"Edit Folder": "Редактирование папки",
"Editing": "Редактирование",
"Editing {%path%}.": "Editing {{path}}.",
"Editing {%path%}.": "Правка {{path}}.",
"Enable NAT traversal": "Включить NAT traversal",
"Enable Relaying": "Включить релеи",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.",
"Enter a non-privileged port number (1024 - 65535).": "Enter a non-privileged port number (1024 - 65535).",
"Enter a non-privileged port number (1024 - 65535).": "Введите непривилегированный порт (102465535).",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Введите через запятую («tcp://ip:port», «tcp://host:port») адреса, либо «dynamic», чтобы выполнить автоматическое обнаружение адреса.",
"Enter ignore patterns, one per line.": "Введите шаблоны игнорирования, по одному на строку.",
"Error": "Ошибка",
"External File Versioning": "Внешний контроль версий файлов",
"Failed Items": "Сбои",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Если нет IPv6-соединений, при подключении к IPv6-серверам произойдёт ошибка.",
"File Pull Order": "Порядок получения файлов",
"File Versioning": "Управление версиями",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Права на файлы игнорируются при поиске изменений. Используется на файловой системе FAT.",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Files are moved to .stversions directory when replaced or deleted by Syncthing.",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Когда Syncthing изменяет или удаляет файлы, они помещаются в папку .stversions",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Файлы перемещаются в папку .stversions после их замены или удаления системой Syncthing.",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Когда Syncthing изменяет или удаляет файлы, их версии с таймштампами помещаются в папку .stversions",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Файлы с временнОй меткой версии помещаются в папку .stversions при их замене или удалении Syncthing.",
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Файлы защищены от изменений сделанных на других устройствах, но изменения сделанные на этом устройстве будут отправлены всему кластеру.",
"Folder": "Папка",
@@ -97,7 +97,7 @@
"GUI Listen Addresses": "Адрес панели управления",
"GUI Theme": "Тема оформления",
"Generate": "Сгенерировать",
"Global Changes": "Global Changes",
"Global Changes": "Глобальные изменения",
"Global Discovery": "Глобальное обнаружение",
"Global Discovery Servers": "Серверы глобального обнаружения",
"Global State": "Глобальное состояние",
@@ -150,7 +150,7 @@
"Override Changes": "Перезаписать изменения",
"Path": "Путь",
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "Путь к папке на локальном компьютере. Если её не существует, то она будет создана. Тильда (~) может использоваться как сокращение для",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "Путь, в котором нужно хранить версии (оставьте пустым для папки по умолчанию .stversions внутри общей папки).",
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Путь, где должны храниться версии (оставьте пустым, чтобы использовать папку по умолчанию .stversions внутри папки).",
"Pause": "Пауза",
"Pause All": "Приостановить все",
@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Перед проведением обновления основной версии ознакомтесь, пожалуйста, с Замечаниями к версии",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Установите имя пользователя и пароль для интерфейса в настройках",
"Please wait": "Пожалуйста, подождите",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefix indicating that the file can be deleted if preventing directory removal",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefix indicating that the pattern should be matched without case sensitivity",
"Preview": "Предварительный просмотр",
"Preview Usage Report": "Посмотреть отчёт об использовании",
"Quick guide to supported patterns": "Краткое руководство по поддерживаемым шаблонам",
@@ -181,6 +183,7 @@
"Save": "Сохранить",
"Scan Time Remaining": "Оставшееся время сканирования",
"Scanning": "Сканирование",
"See external versioner help for supported templated command line parameters.": "See external versioner help for supported templated command line parameters.",
"Select the devices to share this folder with.": "Выберите устройства, для которых будет доступна эта папка.",
"Select the folders to share with this device.": "Выберите папки, которые будут доступны этому устройству.",
"Send & Receive": "Отправить и получить",
@@ -245,7 +248,7 @@
"This Device": "Это устройство",
"This can easily give hackers access to read and change any files on your computer.": "Это может дать доступ хакерам для чтения и изменения любых файлов на вашем компьютере.",
"This is a major version upgrade.": "Это обновление основной версии продукта.",
"This setting controls the free space required on the home (i.e., index database) disk.": "This setting controls the free space required on the home (i.e., index database) disk.",
"This setting controls the free space required on the home (i.e., index database) disk.": "Эта настройка управляет свободным местом, необходимым на домашнем диске (например, для базы индексов).",
"Time": "Время",
"Trash Can File Versioning": "Использовать версионность для файлов в Корзине",
"Type": "Тип",
@@ -264,13 +267,14 @@
"Version": "Версия",
"Versions Path": "Путь к версиям",
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Версии удаляются автоматически, если они существуют дольше максимального срока или превышают разрешённое количество файлов за интервал.",
"Warning, this path is a parent directory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a parent directory of an existing folder \"{{otherFolder}}\".",
"Warning, this path is a parent directory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Warning, this path is a parent directory of an existing folder \"{{otherFolderLabel}}\" ({{otherFolder}}).",
"Warning, this path is a parent directory of an existing folder \"{%otherFolder%}\".": "Внимание! Этот путь — родительская директория уже существующей папки «{{otherFolder}}».",
"Warning, this path is a parent directory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Внимание! Этот путь — родительская директория уже существующей папки «{{otherFolderLabel}}» ({{otherFolder}}).",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Осторожно, этот путь является подкаталогом существующей папки «{{otherFolder}}».",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Warning, this path is a subdirectory of an existing folder \"{{otherFolderLabel}}\" ({{otherFolder}}).",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Внимание! Этот путь — поддиректория уже существующей папки «{{otherFolderLabel}}» ({{otherFolder}}).",
"When adding a new device, keep in mind that this device must be added on the other side too.": "Когда добавляете устройство, помните о том, что это же устройство должно быть добавлено и другой стороной.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Когда добавляете новую папку, помните, что ID папок используются для того, чтобы связывать папки между всеми устройствами. Они чувствительны к регистру и должны совпадать на всех используемых устройствах.",
"Yes": "Да",
"You can also select one of these nearby devices:": "Вы можете выбрать из этих устройств рядом:",
"You can change your choice at any time in the Settings dialog.": "Выбор можно изменить в любой момент в диалоге настроек.",
"You can read more about the two release channels at the link below.": "О двух каналах выпусков можно почитать подробнее по нижеприведённой ссылке.",
"You must keep at least one version.": "Вы должны хранить как минимум одну версию.",

View File

@@ -18,7 +18,7 @@
"Advanced Configuration": "Pokročilá konfigurácia",
"Advanced settings": "Pokročilé nastavenia",
"All Data": "Všetky dáta",
"Allow Anonymous Usage Reporting?": "Povoliť anoynmné hlásenie o použivaní?",
"Allow Anonymous Usage Reporting?": "Povoliť anoynmné hlásenia o použivaní?",
"Allowed Networks": "Povolené siete",
"Alphabetic": "Abecedne",
"An external command handles the versioning. It has to remove the file from the shared folder.": "Externý príkaz obstaráva verzie. Musí odstrániť ",
@@ -28,11 +28,11 @@
"Automatic upgrade now offers the choice between stable releases and release candidates.": "Automatická aktualizácia teraz ponúka voľbu medzi stabilnými vydaniami a kandidátmi na vydanie.",
"Automatic upgrades": "Automatické aktualizácie",
"Be careful!": "Buď opatrný!",
"Bugs": "Cyhby",
"Bugs": "Chyby",
"CPU Utilization": "Využitie CPU",
"Changelog": "Záznam zmien",
"Clean out after": "Vyčistenie po",
"Click to see discovery failures": "Klikni pre zobrazenie zlyhaní objavovania.",
"Click to see discovery failures": "Kliknite pre zobrazenie zlyhaní zisťovania.",
"Close": "Zatvoriť",
"Command": "Príkaz",
"Comment, when used at the start of a line": "Komentár, keď použité na začiatku riadku",
@@ -44,7 +44,7 @@
"Copied from original": "Skopírované z originálu",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 následujúci prispivatelia:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 následujúci prispivatelia:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Vytváranie vzorov ignorovania, prepísanie existujúceho súboru v {{path}}.",
"Danger!": "Pozor!",
"Deleted": "Zmazané",
"Device": "Zariadenie",
@@ -54,9 +54,9 @@
"Device Name": "Názov zariadenia",
"Devices": "Zariadenia",
"Disconnected": "Odpojené",
"Discovered": "Objavené",
"Discovery": "Objavenie",
"Discovery Failures": "Zlyhania objavovania",
"Discovered": "Zistené",
"Discovery": "Zisťovanie",
"Discovery Failures": "Zlyhania zisťovania",
"Documentation": "Dokumentácia",
"Download Rate": "Rýchlosť sťahovania",
"Downloaded": "Stiahnuté",
@@ -69,7 +69,7 @@
"Enable NAT traversal": "Povoliť priechod NAT",
"Enable Relaying": "Povoliť prenosové uzly",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Vložte kladné číslo (napr. \"2,35\") a zvoľte jednotku. Percentá sa zobrazujú ako časť celkovej veľkosti disku.",
"Enter a non-privileged port number (1024 - 65535).": "Enter a non-privileged port number (1024 - 65535).",
"Enter a non-privileged port number (1024 - 65535).": "Vložte číslo neprivilegovaného portu (1024-65535).",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Zadaj čiarkou oddelené (\"tcp://ip:port\", \"tcp://host:port\") adresy alebo \"dynamic\" na automatické zistenie adresy.",
"Enter ignore patterns, one per line.": "Zadaj ignorované vzory, jeden na riadok.",
"Error": "Chyba",
@@ -93,14 +93,14 @@
"GUI": "GUI",
"GUI Authentication Password": "Prihlasovacie heslo do GUI",
"GUI Authentication User": "Prihlasovacie meno do GUI",
"GUI Listen Address": "GUI Listen Address",
"GUI Listen Address": "Adresa pre prístup do GUI",
"GUI Listen Addresses": "Adresa pre prístup do GUI",
"GUI Theme": "Grafická téma GUI",
"Generate": "Generovať",
"Global Changes": "Globálne zmeny",
"Global Discovery": "Globálne hľadanie",
"Global Discovery Servers": "Global Discovery Servers",
"Global State": "Global State",
"Global Discovery": "Globálne vyhľadávanie",
"Global Discovery Servers": "Globálne zisťovacie servery",
"Global State": "Globálny status",
"Help": "Pomoc",
"Home page": "Domovská stránka",
"Ignore": "Ignorovať",
@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Pred spustením hlavnej aktualizácie si prosím prečítajte poznámky k vydaniu.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Zadajte prosím prihlasovanie meno a heslo v dialógovom okne nastavení.",
"Please wait": "Prosím čakajte",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefix označujúci, že súbor môže byť odstránený, ak bráni odstráneniu adresára.",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefix označujúci, že vzory by mali ignorovať veľkosť písma.",
"Preview": "Náhľad",
"Preview Usage Report": "Náhľad záznamu o používaní",
"Quick guide to supported patterns": "Rýchly sprievodca podporovanými vzormi",
@@ -165,7 +167,7 @@
"Random": "Náhodne",
"Reduced by ignore patterns": "Znížené o ignorované vzory",
"Release Notes": "Poznámky k vydaniu",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Kandidáti na vydanie obsahujú najnovšie vlastnosti a opravy. Sú podobné tradičným dvojtýždenným vydaniam programu Syncthing.",
"Remote Devices": "Vzdialené zariadenia",
"Remove": "Odstrániť",
"Required identifier for the folder. Must be the same on all cluster devices.": "Potrebný identifikátor pre adresár. Musí byť rovnaký na všetkých zariadeniach v skupine.",
@@ -181,104 +183,106 @@
"Save": "Uložiť",
"Scan Time Remaining": "Zostávajúci čas skenovania",
"Scanning": "Skenovanie",
"See external versioner help for supported templated command line parameters.": "See external versioner help for supported templated command line parameters.",
"Select the devices to share this folder with.": "Vyberte zariadenia s ktorými chcete zdieľať tento adresár.",
"Select the folders to share with this device.": "Vyberte adresáre ktoré chcete zdieľať s týmto zariadením.",
"Send & Receive": "Prijímať a odosielať",
"Send Only": "Iba odosielať",
"Settings": "Nastavenia",
"Share": "Share",
"Share Folder": "Share Folder",
"Share Folders With Device": "Share Folders With Device",
"Share With Devices": "Share With Devices",
"Share this folder?": "Share this folder?",
"Shared With": "Shared With",
"Show ID": "Show ID",
"Show QR": "Show QR",
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.",
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.",
"Share": "Zdieľať",
"Share Folder": "Zdieľať adresár",
"Share Folders With Device": "Zdieľať adresáre so zariadením",
"Share With Devices": "Zdieľať so zariadeniami",
"Share this folder?": "Zdieľať tento adresár?",
"Shared With": "Zdieľané s",
"Show ID": "Zobraziť ID",
"Show QR": "Zobraziť QR",
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Zobrazované namiesto ID zariadenia v štatúte klastra. Toto pomenovanie bude oznamovať ostatným zariadeniam ako voliteľné predvolené pomenovanie.",
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Zobrazované namiesto ID zariadenia v klastri. Ak je ponechané prázdne, bude nahradené pomenovaním, ktoré oznamuje zariadenie.",
"Shutdown": "Vypnutie",
"Shutdown Complete": "Shutdown Complete",
"Shutdown Complete": "Vypnutie ukončené",
"Simple File Versioning": "Jednoduché verzie súborov",
"Single level wildcard (matches within a directory only)": "Single level wildcard (matches within a directory only)",
"Smallest First": "Smallest First",
"Source Code": "Source Code",
"Stable releases and release candidates": "Stable releases and release candidates",
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.",
"Stable releases only": "Stable releases only",
"Smallest First": "Najmenší najprv",
"Source Code": "Zdrojový kód",
"Stable releases and release candidates": "Stabilné verzie a kandidáti na vydanie",
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "Stabilné vydania sú odložené asi o dva týždne. Počas tejto doby prechádzajú testovaním ako kandidáti na vydanie.",
"Stable releases only": "Iba stabilné verzie",
"Staggered File Versioning": "Rozložené verzie súborov",
"Start Browser": "Start Browser",
"Statistics": "Statistics",
"Stopped": "Stopped",
"Support": "Support",
"Sync Protocol Listen Addresses": "Sync Protocol Listen Addresses",
"Syncing": "Syncing",
"Syncthing has been shut down.": "Syncthing has been shut down.",
"Syncthing includes the following software or portions thereof:": "Syncthing includes the following software or portions thereof:",
"Syncthing is restarting.": "Syncthing is restarting.",
"Syncthing is upgrading.": "Syncthing is upgrading.",
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…",
"Start Browser": "Spusti prehliadač",
"Statistics": "Štatistika",
"Stopped": "Zastavené",
"Support": "Podpora",
"Sync Protocol Listen Addresses": "Adresa načúvania synchronizačného protokolu",
"Syncing": "Synchronizácia",
"Syncthing has been shut down.": "Syncthing bol vypnutý.",
"Syncthing includes the following software or portions thereof:": "Syncthing obsahuje nasledujúci software nebo jeho časti:",
"Syncthing is restarting.": "Syncthing sa reštartuje.",
"Syncthing is upgrading.": "Syncthing sa aktualizuje.",
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing se zdá byť nefunkčný, alebo je problém s internetovým pripojením. Opakujem...",
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.",
"The Syncthing admin interface is configured to allow remote access without a password.": "The Syncthing admin interface is configured to allow remote access without a password.",
"The aggregated statistics are publicly available at the URL below.": "The aggregated statistics are publicly available at the URL below.",
"The aggregated statistics are publicly available at the URL below.": "Súhrnné štatistiky sú verejne dostupné na uvedenej URL.",
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.",
"The device ID cannot be blank.": "The device ID cannot be blank.",
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).",
"The device ID cannot be blank.": "ID zariadenia nemôže byť prázdne.",
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "ID zariadenie pre vloženie môžete nájsť na druhom zariadení v dialógu \"Akcia > Zobraziť ID\". Medzery a pomlčky sú voliteľné (ignorované).",
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.": "The encrypted usage report is sent daily. It is used to track common platforms, folder sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.",
"The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.": "The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.",
"The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "The first command line parameter is the folder path and the second parameter is the relative path in the folder.",
"The folder ID cannot be blank.": "The folder ID cannot be blank.",
"The folder ID must be unique.": "The folder ID must be unique.",
"The folder path cannot be blank.": "The folder path cannot be blank.",
"The folder ID must be unique.": "ID adresára musí byť jedinečné.",
"The folder path cannot be blank.": "Cesta k adresáru nemôže byť prázdna.",
"The following intervals are used: for the first hour a version is kept every 30 seconds, for the first day a version is kept every hour, for the first 30 days a version is kept every day, until the maximum age a version is kept every week.": "The following intervals are used: for the first hour a version is kept every 30 seconds, for the first day a version is kept every hour, for the first 30 days a version is kept every day, until the maximum age a version is kept every week.",
"The following items could not be synchronized.": "The following items could not be synchronized.",
"The maximum age must be a number and cannot be blank.": "The maximum age must be a number and cannot be blank.",
"The maximum age must be a number and cannot be blank.": "Maximálny vek musí byť číslo a nemôže byť prázdne.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "The maximum time to keep a version (in days, set to 0 to keep versions forever).",
"The minimum free disk space percentage must be a non-negative number between 0 and 100 (inclusive).": "The minimum free disk space percentage must be a non-negative number between 0 and 100 (inclusive).",
"The number of days must be a number and cannot be blank.": "The number of days must be a number and cannot be blank.",
"The number of days to keep files in the trash can. Zero means forever.": "The number of days to keep files in the trash can. Zero means forever.",
"The number of old versions to keep, per file.": "The number of old versions to keep, per file.",
"The number of versions must be a number and cannot be blank.": "The number of versions must be a number and cannot be blank.",
"The path cannot be blank.": "The path cannot be blank.",
"The rate limit must be a non-negative number (0: no limit)": "The rate limit must be a non-negative number (0: no limit)",
"The minimum free disk space percentage must be a non-negative number between 0 and 100 (inclusive).": "Minimálne voľné miesto na disku v percentách musí byť kladné číslo medzi 0 a 100 (vrátane).",
"The number of days must be a number and cannot be blank.": "Počet dní musí byť číslo a nemôže byť prázdny.",
"The number of days to keep files in the trash can. Zero means forever.": "Počet dní pre uchovanie súborov v koši. Nula znamená navždy.",
"The number of old versions to keep, per file.": "Počet uchovávaných starších verzií pre každý súbor.",
"The number of versions must be a number and cannot be blank.": "Počet verzií musí byť číslo a nemôže byť prázdny.",
"The path cannot be blank.": "Cesta nemôže byť prázdna.",
"The rate limit must be a non-negative number (0: no limit)": "Limit rýchlosti musí byť kladné číslo (0: bez limitu)",
"The rescan interval must be a non-negative number of seconds.": "The rescan interval must be a non-negative number of seconds.",
"They are retried automatically and will be synced when the error is resolved.": "They are retried automatically and will be synced when the error is resolved.",
"This Device": "This Device",
"This Device": "Toto zariadenie",
"This can easily give hackers access to read and change any files on your computer.": "This can easily give hackers access to read and change any files on your computer.",
"This is a major version upgrade.": "This is a major version upgrade.",
"This setting controls the free space required on the home (i.e., index database) disk.": "This setting controls the free space required on the home (i.e., index database) disk.",
"Time": "Time",
"This is a major version upgrade.": "Toto je hlavná aktualizácia.",
"This setting controls the free space required on the home (i.e., index database) disk.": "Toto nastavenie kontroluje voľné miesto požadované na domovskom disku (napr. indexová databáza).",
"Time": "Čas",
"Trash Can File Versioning": "Verzie súborov v koši",
"Type": "Type",
"Unknown": "Unknown",
"Unshared": "Unshared",
"Unused": "Unused",
"Up to Date": "Up to Date",
"Updated": "Updated",
"Upgrade": "Upgrade",
"Upgrade To {%version%}": "Upgrade To {{version}}",
"Upgrading": "Upgrading",
"Upload Rate": "Upload Rate",
"Uptime": "Uptime",
"Usage reporting is always enabled for candidate releases.": "Usage reporting is always enabled for candidate releases.",
"Type": "Typ",
"Unknown": "Neznáme",
"Unshared": "Nezdieľané",
"Unused": "Nepoužité",
"Up to Date": "Aktuálne",
"Updated": "Aktualizované",
"Upgrade": "Aktualizácia",
"Upgrade To {%version%}": "Aktualizovať na {{version}}",
"Upgrading": "Aktualizácia",
"Upload Rate": "Rýchlosť odosielania",
"Uptime": "Doba prevádzky",
"Usage reporting is always enabled for candidate releases.": "Hlásenia o používaní sú pri kandidátoch na vydanie vždy povolené.",
"Use HTTPS for GUI": "Use HTTPS for GUI",
"Version": "Version",
"Versions Path": "Versions Path",
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.",
"Version": "Verzia",
"Versions Path": "Cesta k verziám",
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Verzie sú automaticky zmazané ak sú staršie ako je maximálny časový limit alebo presiahnu počet súborov povolených v danom intervale.",
"Warning, this path is a parent directory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a parent directory of an existing folder \"{{otherFolder}}\".",
"Warning, this path is a parent directory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Warning, this path is a parent directory of an existing folder \"{{otherFolderLabel}}\" ({{otherFolder}}).",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Warning, this path is a subdirectory of an existing folder \"{{otherFolderLabel}}\" ({{otherFolder}}).",
"When adding a new device, keep in mind that this device must be added on the other side too.": "When adding a new device, keep in mind that this device must be added on the other side too.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.",
"Yes": "Yes",
"You can change your choice at any time in the Settings dialog.": "You can change your choice at any time in the Settings dialog.",
"You can read more about the two release channels at the link below.": "You can read more about the two release channels at the link below.",
"You must keep at least one version.": "You must keep at least one version.",
"days": "days",
"directories": "directories",
"files": "files",
"full documentation": "full documentation",
"items": "items",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} wants to share folder \"{{folder}}\".",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderlabel}}\" ({{folder}})."
"Yes": "Áno",
"You can also select one of these nearby devices:": "Môžete tiež vybrať jedno z týchto blízkych zariadení:",
"You can change your choice at any time in the Settings dialog.": "Voľbu môžete kedykoľvek zmeniť v dialógu Nastavenia.",
"You can read more about the two release channels at the link below.": "O dvoch vydávacích kanáloch si môžete viacej prečítať v odkaze nižšie.",
"You must keep at least one version.": "Musíte ponechať aspoň jednu verziu",
"days": "d",
"directories": "adresáre",
"files": "súbory",
"full documentation": "úplná dokumntácia",
"items": "položiek",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} chce zdieľať adresár \"{{folder}}\".",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} chce zdieľať adresár \"{{folderlabel}}\" ({{folder}})."
}

View File

@@ -5,7 +5,7 @@
"API Key": "API-nyckel",
"About": "Om",
"Action": "Åtgärd",
"Actions": "Funktioner",
"Actions": "Åtgärder",
"Add": "Lägg till",
"Add Device": "Lägg till enhet",
"Add Folder": "Lägg till mapp",
@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Läs igenom versionsnyheterna innan den stora uppgraderingen.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Ställ in ett grafiska gränssnittets användarautentisering och lösenord i inställningsdialogrutan.",
"Please wait": "Var god vänta",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefix som indikerar att filen kan raderas om det förhindrar borttagning av katalog",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefix som indikerar att mönstret ska matchas utan skiftlägeskänslighet",
"Preview": "Förhandsgranska",
"Preview Usage Report": "Förhandsgranska statistik",
"Quick guide to supported patterns": "Snabb handledning till mönster som stöds",
@@ -181,6 +183,7 @@
"Save": "Spara",
"Scan Time Remaining": "Återstående skanningstid",
"Scanning": "Skannar",
"See external versioner help for supported templated command line parameters.": "See external versioner help for supported templated command line parameters.",
"Select the devices to share this folder with.": "Ange enheterna som den här mappen ska delas med.",
"Select the folders to share with this device.": "Välj mapparna som ska delas med den här enheten.",
"Send & Receive": "Skicka & ta emot",
@@ -271,6 +274,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "När du lägger till en ny enhet, kom ihåg att den här enheten måste läggas till på den andra enheten också.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "När du lägger till ny mapp, tänk på att mapp-ID knyter ihop mappar mellan olika enheter. De skiftlägeskänsliga och måste matcha precis mellan alla enheter.",
"Yes": "Ja",
"You can also select one of these nearby devices:": "Du kan också välja en av dessa närliggande enheter:",
"You can change your choice at any time in the Settings dialog.": "Du kan ändra ditt val när som helst i inställningsdialogrutan.",
"You can read more about the two release channels at the link below.": "Du kan läsa mer om de två publiceringsskanalerna på länken nedan.",
"You must keep at least one version.": "Du måste behålla åtminstone en version.",

View File

@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Birincil bir yükseltme gerçekleştirmeden önce lütfen sürüm notlarını tetkik edin.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "GUI üzerinden Kimlik Doğrulaması yapmak için Ayarlar penceresinde Kullanıcı ve Parola tanımlayın lütfen.",
"Please wait": "Lütfen Bekleyin",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefix indicating that the file can be deleted if preventing directory removal",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefix indicating that the pattern should be matched without case sensitivity",
"Preview": "Önizleme",
"Preview Usage Report": "Kullanım raporunu gözden geçir",
"Quick guide to supported patterns": "Desteklenen kalıp dizileri için hızlı rehber",
@@ -181,6 +183,7 @@
"Save": "Kaydet",
"Scan Time Remaining": "Kalan Tarama Zamanı",
"Scanning": "Taranıyor",
"See external versioner help for supported templated command line parameters.": "See external versioner help for supported templated command line parameters.",
"Select the devices to share this folder with.": "Bu klasörü paylaşacağın aygıtları seç.",
"Select the folders to share with this device.": "Bu aygıtla paylaşılacak klasörleri seç.",
"Send & Receive": "Gönder & Al",
@@ -271,6 +274,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "Yeni bir aygıt eklendiğinde, bu aygıtın karşı tarafa da eklenmesi gerektiğini unutmayın.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Yeni bir klasör eklendiğinde, Klasör ID'nin klasörleri aygıtlar arasında bağlantılandırmak için kullanıldığını unutmayın. Klasör ID'ler büyük - küçük harf duyarlıdır ve tüm aygıtlarda tamı tamına eşleşmelidir.",
"Yes": "Evet",
"You can also select one of these nearby devices:": "You can also select one of these nearby devices:",
"You can change your choice at any time in the Settings dialog.": "Seçiminizi herhangi bir zamanda Ayarlar penceresinde değiştirebilirsiniz.",
"You can read more about the two release channels at the link below.": "İki dağıtım kanalıyla ilgili daha çoğunu aşağıdaki bağlantıdan okuyabilirsiniz.",
"You must keep at least one version.": "En az bir sürümü tutmalısınız.",

View File

@@ -10,7 +10,7 @@
"Add Device": "Додати пристрій",
"Add Folder": "Додати директорію",
"Add Remote Device": "Додати віддалений пристрій",
"Add devices from the introducer to our device list, for mutually shared folders.": "Add devices from the introducer to our device list, for mutually shared folders.",
"Add devices from the introducer to our device list, for mutually shared folders.": "Додати пристрої від пристрою-рекомендувача до нашого списку пристроїв для спільно розділених директорій.",
"Add new folder?": "Додати нову директорію?",
"Address": "Адреса",
"Addresses": "Адреси",
@@ -32,7 +32,7 @@
"CPU Utilization": "Навантаження CPU",
"Changelog": "Перелік змін",
"Clean out after": "Очистити після",
"Click to see discovery failures": "Click to see discovery failures",
"Click to see discovery failures": "Клікніть, щоб переглянути помилки виявлення",
"Close": "Закрити",
"Command": "Команда",
"Comment, when used at the start of a line": "Коментар, якщо використовується на початку рядка",
@@ -65,11 +65,11 @@
"Edit Device": "Налаштування пристрою",
"Edit Folder": "Налаштування директорії",
"Editing": "Редагування",
"Editing {%path%}.": "Editing {{path}}.",
"Editing {%path%}.": "Редагування {{path}}.",
"Enable NAT traversal": "Увімкнути NAT traversal",
"Enable Relaying": "Увімкнути ретрансляцію (relaying)",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.",
"Enter a non-privileged port number (1024 - 65535).": "Enter a non-privileged port number (1024 - 65535).",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Введіть невід'ємне число (напр. \"2.35\") та виберіть пристрій. Проценти від загального дискового простору.",
"Enter a non-privileged port number (1024 - 65535).": "Введіть номер непривілейованого порту (1024 - 65535).",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Введіть розділені комою (\"tcp://ip:port\", \"tcp://host:port\") адреси або \"dynamic\" для автоматичного визначення адреси.",
"Enter ignore patterns, one per line.": "Введіть шаблони ігнорування, по одному на рядок.",
"Error": "Помилка",
@@ -93,7 +93,7 @@
"GUI": "Графічний інтерфейс",
"GUI Authentication Password": "Пароль для доступу до панелі управління",
"GUI Authentication User": "Логін користувача для доступу до панелі управління",
"GUI Listen Address": "GUI Listen Address",
"GUI Listen Address": "Адреса прослуховування GUI",
"GUI Listen Addresses": "Адреса доступу до панелі управління",
"GUI Theme": "Тема інтерфейсу",
"Generate": "Згенерувати",
@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Будь ласка перегляньте примітки до випуску перед мажорним оновленням. ",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Будь ласка, встановіть у налаштуваннях ім'я користувача та пароль до графічного інтерфейсу.",
"Please wait": "Будь ласка, зачекайте",
"Prefix indicating that the file can be deleted if preventing directory removal": "Префікс означає, що файл може бути видалений при запобіганні видаленню директорії",
"Prefix indicating that the pattern should be matched without case sensitivity": "Префікс означає, що шаблон має збігатися без чутливості до регістру",
"Preview": "Попередній перегляд",
"Preview Usage Report": "Попередній перегляд статистичного звіту",
"Quick guide to supported patterns": "Швидкий посібник по шаблонам, що підтримуються",
@@ -181,6 +183,7 @@
"Save": "Зберегти",
"Scan Time Remaining": "Час до кінця сканування",
"Scanning": "Сканування",
"See external versioner help for supported templated command line parameters.": "See external versioner help for supported templated command line parameters.",
"Select the devices to share this folder with.": "Оберіть пристрої, які матимуть доступ до цієї директорії.",
"Select the folders to share with this device.": "Оберіть директорії до яких матиме доступ цей пристрій.",
"Send & Receive": "Відправити та отримати",
@@ -245,7 +248,7 @@
"This Device": "Локальний пристрій",
"This can easily give hackers access to read and change any files on your computer.": "Це легко може дати хакерам доступ до читання та зміни будь-яких файлів на вашому комп'ютері.",
"This is a major version upgrade.": "Це оновлення мажорної версії",
"This setting controls the free space required on the home (i.e., index database) disk.": "This setting controls the free space required on the home (i.e., index database) disk.",
"This setting controls the free space required on the home (i.e., index database) disk.": "Це налаштування визначає необхідний вільний простір на домашньому (тобто той, що містить базу даних) диску.",
"Time": "Час",
"Trash Can File Versioning": "Версіонування файлів у кошику ",
"Type": "Тип",
@@ -271,6 +274,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "Коли додаєте новий вузол, пам’ятайте, що цей вузол повинен бути доданий і на іншій стороні.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Коли додаєте нову директорію, пам’ятайте, що ID цієї директорії використовується для того, щоб зв’язувати директорії разом між пристроями. Назви повинні точно співпадати між усіма пристроями, регістр символів має значення.",
"Yes": "Так",
"You can also select one of these nearby devices:": "Ви також можете обрати один із сусідніх пристроїв:",
"You can change your choice at any time in the Settings dialog.": "Ви завжди можете змінити свій вибір у Налаштуваннях.",
"You can read more about the two release channels at the link below.": "Ви можете прочитати більше про два канали випусків за посиланням нижче.",
"You must keep at least one version.": "Ви повинні зберігати щонайменше одну версію.",

View File

@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "Hãy xem kỹ lịch sử phát hành trước khi tiến hành bản cập nhật q.trọng.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Hãy thiết lập tên ng.dùng và mật khẩu xác minh GUI trong hộp thoại Cài đặt.",
"Please wait": "Xin chờ",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefix indicating that the file can be deleted if preventing directory removal",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefix indicating that the pattern should be matched without case sensitivity",
"Preview": "Xem trước",
"Preview Usage Report": "Xem trước báo cáo s.dụng",
"Quick guide to supported patterns": "H.dẫn sơ lược về các q.luật được hỗ trợ",
@@ -181,6 +183,7 @@
"Save": "Lưu",
"Scan Time Remaining": "Thời gian quét còn lại",
"Scanning": "Đang quét",
"See external versioner help for supported templated command line parameters.": "See external versioner help for supported templated command line parameters.",
"Select the devices to share this folder with.": "Chọn các thiết bị để chia sẻ thư mục này.",
"Select the folders to share with this device.": "Chọn các thư mục để chia sẻ với thiết bị này.",
"Send & Receive": "Send & Receive",
@@ -271,6 +274,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "Khi thêm một thiết bị mới, hãy nhớ rằng thiết bị này cũng phải được thêm vào máy kia.",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Khi thêm một thư mục mới, hãy nhớ rằng ID thư mục được dùng để gắn kết thư mục giữa các thiết bị với nhau. Chúng phải chính xác từng chữ, cả viết hoa và thường giữa tất cả thiết bị.",
"Yes": "Phải",
"You can also select one of these nearby devices:": "You can also select one of these nearby devices:",
"You can change your choice at any time in the Settings dialog.": "You can change your choice at any time in the Settings dialog.",
"You can read more about the two release channels at the link below.": "You can read more about the two release channels at the link below.",
"You must keep at least one version.": "Bạn phải giữ ít nhất một phiên bản.",

View File

@@ -10,7 +10,7 @@
"Add Device": "添加设备",
"Add Folder": "添加文件夹",
"Add Remote Device": "添加远程设备",
"Add devices from the introducer to our device list, for mutually shared folders.": "添加介绍人中的设备到我们的设备列表,以互相共享文件夹。",
"Add devices from the introducer to our device list, for mutually shared folders.": "将此新设备上拥有的“远程设备”都自动添加到您这边的“远程设备列表中(如果它们跟您存在相同的文件夹的话)",
"Add new folder?": "添加新文件夹?",
"Address": "地址",
"Addresses": "地址列表",
@@ -24,15 +24,15 @@
"An external command handles the versioning. It has to remove the file from the shared folder.": "使用外部命令接管版本控制。该命令必须自行从共享文件夹中删除该文件。",
"An external command handles the versioning. It has to remove the file from the synced folder.": "使用外部命令接管版本控制。该命令必须自行从同步文件夹中删除该文件。",
"Anonymous Usage Reporting": "匿名使用报告",
"Any devices configured on an introducer device will be added to this device as well.": "在介绍人设备上添加的其它设备,也会被添加到本机。",
"Any devices configured on an introducer device will be added to this device as well.": "在介设备上添加的任何“远程设备,也会被自动添加到本机的“远程设备”列表。",
"Automatic upgrade now offers the choice between stable releases and release candidates.": "自动升级现提供了稳定版本和发布候选版之间的选择。",
"Automatic upgrades": "自动升级",
"Be careful!": "小心!",
"Bugs": "问题回报",
"CPU Utilization": "CPU使用率",
"Changelog": "更新日志",
"Clean out after": "在该时间后清除",
"Click to see discovery failures": "点击查看发现错误",
"Clean out after": "在该时间后清除",
"Click to see discovery failures": "点击查看设备发现错误",
"Close": "关闭",
"Command": "命令",
"Comment, when used at the start of a line": "注释,在行首使用",
@@ -55,27 +55,27 @@
"Devices": "设备",
"Disconnected": "连接已断开",
"Discovered": "已发现",
"Discovery": "发现",
"Discovery Failures": "发现错误",
"Discovery": "设备发现",
"Discovery Failures": "设备发现错误",
"Documentation": "文档",
"Download Rate": "下载速度",
"Downloaded": "已下载",
"Downloading": "下载中",
"Edit": "选项",
"Edit Device": "编辑设备",
"Edit Folder": "编辑文件夹",
"Edit Device": "修改设备选项",
"Edit Folder": "修改文件夹选项",
"Editing": "正在编辑",
"Editing {%path%}.": "正在编辑 {{path}}。",
"Enable NAT traversal": "启用 NAT 遍历",
"Enable Relaying": "开启中继",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "输入一个非负数例如“2.35”)并选择单位。百分比是磁盘总大小的一部分。",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "输入一个非负数例如“2.35”)并选择单位。%表示占磁盘总容量的百分比。",
"Enter a non-privileged port number (1024 - 65535).": "输入一个非特权的端口号 (1024 - 65535)。",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "输入以半角逗号分隔的 (\"tcp://ip:port\", \"tcp://host:port\") 设置可用地址列表,或者输入 \"dynamic\" 表示自动发现地址。",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "输入以半角逗号分隔的 (\"tcp://ip:port\", \"tcp://host:port\") 设地址列表,或者输入 \"dynamic\" 自动发现设备地址。",
"Enter ignore patterns, one per line.": "请输入忽略表达式,每行一条。",
"Error": "错误",
"External File Versioning": "外部版本控制",
"Failed Items": "失败的项目",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "如果无 IPv6 连接则预期连接到 IPv6 服务器会失败。",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "如果本机没有配置IPv6则无法连接IPv6服务器是正常的。",
"File Pull Order": "文件拉取顺序",
"File Versioning": "版本控制",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "当查找文件更改时,忽略文件权限位。用在 FAT 文件系统上。",
@@ -97,7 +97,7 @@
"GUI Listen Addresses": "图形管理界面监听地址",
"GUI Theme": "GUI 主题",
"Generate": "生成",
"Global Changes": "全局更",
"Global Changes": "全局更",
"Global Discovery": "全球发现",
"Global Discovery Servers": "全球发现服务器",
"Global State": "全局状态",
@@ -109,9 +109,9 @@
"Incoming Rate Limit (KiB/s)": "下载速率限制 (KiB/s)",
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "错误的配置可能损坏您文件夹内的内容,使得 Syncthing 无法工作。",
"Introduced By": "介绍自",
"Introducer": "介绍人设备",
"Introducer": "作为中介",
"Inversion of the given condition (i.e. do not exclude)": "对本条件取反(例如:不要排除某项)",
"Keep Versions": "保留历史版本数量",
"Keep Versions": "保留版本数量",
"Largest First": "大文件优先",
"Last File Received": "最后接收的文件",
"Last Scan": "最后扫描",
@@ -125,7 +125,7 @@
"Local State (Total)": "本地状态汇总",
"Major Upgrade": "重大更新",
"Master": "自主",
"Maximum Age": "历史版本最长保留时间",
"Maximum Age": "最长保留时间",
"Metadata Only": "仅元数据",
"Minimum Free Disk Space": "最低可用磁盘空间",
"Move to top of queue": "移动到队列顶端",
@@ -158,6 +158,8 @@
"Please consult the release notes before performing a major upgrade.": "请在进行重大更新前查看发布说明。",
"Please set a GUI Authentication User and Password in the Settings dialog.": "请在设置对话框中设置 GUI 验证用户及其密码。",
"Please wait": "请稍候",
"Prefix indicating that the file can be deleted if preventing directory removal": "表示如果删除了阻止目录则文件可被删除的前缀",
"Prefix indicating that the pattern should be matched without case sensitivity": "表示该模式匹配忽略了大小写差异的前缀",
"Preview": "预览",
"Preview Usage Report": "预览使用报告",
"Quick guide to supported patterns": "支持的通配符的简单教程:",
@@ -181,6 +183,7 @@
"Save": "保存",
"Scan Time Remaining": "扫描剩余时间",
"Scanning": "扫描中",
"See external versioner help for supported templated command line parameters.": "有关支持的命令行参数模板,请参阅外部的版本控制器帮助。",
"Select the devices to share this folder with.": "选择将本文件夹共享给哪些设备。",
"Select the folders to share with this device.": "选择与该设备共享的文件夹。",
"Send & Receive": "发送与接收",
@@ -271,6 +274,7 @@
"When adding a new device, keep in mind that this device must be added on the other side too.": "若您在本机添加新设备,记住您也必须在这个设备上添加本机。",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "若你添加了新文件夹,记住文件夹 ID 是用以在不同设备间建立联系的。在不同设备间拥有相同 ID 的文件夹将会被同步。且文件夹 ID 区分大小写。",
"Yes": "是",
"You can also select one of these nearby devices:": "您也可以从这些附近的设备中选择:",
"You can change your choice at any time in the Settings dialog.": "您可以在任何时候在设置对话框中更改选择。",
"You can read more about the two release channels at the link below.": "您可以从以下链接读取更多关于两个发行渠道的信息。",
"You must keep at least one version.": "您必须保留至少一个版本。",

View File

@@ -0,0 +1,288 @@
{
"A device with that ID is already added.": "該裝置識別碼已被新增。",
"A negative number of days doesn't make sense.": "一個負的天數並不合理。",
"A new major version may not be compatible with previous versions.": "新的主要版本可能與以前的版本不相容。",
"API Key": "API 金鑰",
"About": "關於",
"Action": "動作",
"Actions": "操作",
"Add": "增加",
"Add Device": "增加裝置",
"Add Folder": "增加資料夾",
"Add Remote Device": "新增遠端裝置",
"Add devices from the introducer to our device list, for mutually shared folders.": "對於共用的資料夾,匯入引入者的裝置清單。",
"Add new folder?": "新增資料夾?",
"Address": "位址",
"Addresses": "位址",
"Advanced": "進階",
"Advanced Configuration": "進階配置",
"Advanced settings": "進階設定",
"All Data": "全部資料",
"Allow Anonymous Usage Reporting?": "允許匿名的使用資訊回報?",
"Allowed Networks": "允許的網路",
"Alphabetic": "字母順序",
"An external command handles the versioning. It has to remove the file from the shared folder.": "處理版本的外部指令。其必須從資料夾中刪除檔案。",
"An external command handles the versioning. It has to remove the file from the synced folder.": "處理版本的外部指令。其必須從資料夾中刪除檔案。",
"Anonymous Usage Reporting": "匿名的使用資訊回報",
"Any devices configured on an introducer device will be added to this device as well.": "任何在引入者裝置所設置的裝置將會一併新增至此裝置",
"Automatic upgrade now offers the choice between stable releases and release candidates.": "自動更新目前有穩定發行版及發行候選版可供選擇。",
"Automatic upgrades": "自動升級",
"Be careful!": "請小心!",
"Bugs": "程式錯誤",
"CPU Utilization": "CPU 使用",
"Changelog": "更新日誌",
"Clean out after": "於之後清空",
"Click to see discovery failures": "點擊以查閱失敗的探索",
"Close": "關閉",
"Command": "指令",
"Comment, when used at the start of a line": "註解,當輸入在一行的開頭時",
"Compression": "壓縮",
"Configured": "已設定",
"Connection Error": "連線錯誤",
"Connection Type": "連接類型",
"Copied from elsewhere": "從別處複製",
"Copied from original": "從原處複製",
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 下列貢獻者:",
"Copyright © 2014-2017 the following Contributors:": "Copyright © 2014-2017 下列貢獻者:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "建立忽略樣式,覆蓋已存在的 {{path}}。",
"Danger!": "危險!",
"Deleted": "已刪除",
"Device": "裝置",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "裝置 \"{{name}}\" ({{device}} 位於 {{address}}) 想要連線。 要增加新裝置嗎?",
"Device ID": "裝置識別碼",
"Device Identification": "裝置識別",
"Device Name": "裝置名稱",
"Devices": "裝置",
"Disconnected": "斷線",
"Discovered": "已發現",
"Discovery": "探索",
"Discovery Failures": "探索失敗",
"Documentation": "說明文件",
"Download Rate": "下載速率",
"Downloaded": "已下載",
"Downloading": "正在下載",
"Edit": "編輯",
"Edit Device": "編輯裝置",
"Edit Folder": "編輯資料夾",
"Editing": "正在編輯",
"Editing {%path%}.": "正在編輯 {{path}} 。",
"Enable NAT traversal": "啟用 NAT 穿透",
"Enable Relaying": "啟用中繼",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "請輸入一非負數(如:\"2.35\")並選擇一個單位。百分比表示佔用磁碟容量的大小。",
"Enter a non-privileged port number (1024 - 65535).": "輸入一個非特權通訊埠號 (1024 - 65535)。",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "輸入以半形逗號區隔的位址 (\"tcp://ip:port\", \"tcp://host:port\"),或輸入 \"dynamic\" 以進行位址的自動探索",
"Enter ignore patterns, one per line.": "輸入忽略樣式,每行一種。",
"Error": "錯誤",
"External File Versioning": "外部檔案版本控制",
"Failed Items": "失敗的項目",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "若未配置 IPv6則無法連接 IPv6 伺服器係屬正常。",
"File Pull Order": "提取檔案的順序",
"File Versioning": "檔案版本控制",
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "當改變時,檔案權限位元 File permission bits 會被忽略。用於 FAT 檔案系統上。",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "當檔案被 Syncthing 取代或刪除時,它們將被移至 .stversions 資料夾。",
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "當檔案被 Syncthing 取代或刪除時,它們將被移至 .stversions 資料夾。",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "當檔案被 Syncthing 取代或刪除時,它們將被移至 .stversions 資料夾並添加日期戳記。",
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "當檔案被 Syncthing 取代或刪除時,它們將被移至 .stversions 資料夾並添加日期戳記。",
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "其他裝置做的改變不會影響到此裝置的檔案,但在此裝置上的變化將被發送到叢集中的其他部分。",
"Folder": "資料夾",
"Folder ID": "資料夾識別碼",
"Folder Label": "資料夾標籤",
"Folder Path": "資料夾路徑",
"Folder Type": "資料夾類型",
"Folders": "資料夾",
"GUI": "GUI",
"GUI Authentication Password": "GUI 認證密碼",
"GUI Authentication User": "GUI 使用者認證名稱",
"GUI Listen Address": "GUI 監聽位址",
"GUI Listen Addresses": "GUI 監聽位址",
"GUI Theme": "主題",
"Generate": "產生",
"Global Changes": "全域變動",
"Global Discovery": "全域探索",
"Global Discovery Servers": "全域探索伺服器",
"Global State": "全域狀態",
"Help": "說明",
"Home page": "首頁",
"Ignore": "忽略",
"Ignore Patterns": "忽略樣式",
"Ignore Permissions": "忽略權限",
"Incoming Rate Limit (KiB/s)": "傳入速率限制 (KiB/s)",
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "不正確的設定可能會損壞您的資料夾內容,並導致 Syncthing 不正常運作。",
"Introduced By": "引入自",
"Introducer": "引入者",
"Inversion of the given condition (i.e. do not exclude)": "反轉給定條件 (即:不要排除)",
"Keep Versions": "保留歷史版本數",
"Largest First": "最大的優先",
"Last File Received": "最後接收的檔案",
"Last Scan": "最後掃描",
"Last seen": "最後發現時間",
"Later": "稍後",
"Latest Change": "最近變動",
"Learn more": "瞭解更多",
"Listeners": "中繼",
"Local Discovery": "本機探索",
"Local State": "本機狀態",
"Local State (Total)": "本機狀態 (總結)",
"Major Upgrade": "重大更新",
"Master": "Master",
"Maximum Age": "最長保留時間",
"Metadata Only": "僅中繼資料",
"Minimum Free Disk Space": "最少閒置磁碟空間",
"Move to top of queue": "移到隊列頂端",
"Multi level wildcard (matches multiple directory levels)": "多階層萬用字元 (可比對多層資料夾)",
"Never": "從未",
"New Device": "新裝置",
"New Folder": "新資料夾",
"Newest First": "最新的優先",
"No": "否",
"No File Versioning": "無檔案版本控制",
"No upgrades": "不更新",
"Normal": "Normal",
"Notice": "注意",
"OK": "確定",
"Off": "關閉",
"Oldest First": "最舊的優先",
"Optional descriptive label for the folder. Can be different on each device.": "資料夾的說明標籤(選擇性)。在不同裝置上可不一致。",
"Options": "選項",
"Out of Sync": "不同步",
"Out of Sync Items": "不同步物件",
"Outgoing Rate Limit (KiB/s)": "連出速率限制 (KiB/s)",
"Override Changes": "置換改變",
"Path": "路徑",
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "資料夾在本機的路徑。若資料夾不存在則會建立。波浪符號 (~) 可用作下列資料夾的捷徑:",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "儲存歷史版本的路徑(若為空,則預設使用資料夾中的 .stversions 資料夾)。",
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "儲存歷史版本的路徑 (若為空,則預設使用資料夾中的 .stversions 資料夾)。",
"Pause": "暫停",
"Pause All": "全部暫停",
"Paused": "暫停",
"Please consult the release notes before performing a major upgrade.": "執行重大升級前請先參閱版本資訊。",
"Please set a GUI Authentication User and Password in the Settings dialog.": "請在設定對話方塊內設置 GUI 使用者認證名稱及密碼。",
"Please wait": "請稍後",
"Prefix indicating that the file can be deleted if preventing directory removal": "前綴表示當此檔案阻礙了資料夾刪除時,可一併刪除此檔",
"Prefix indicating that the pattern should be matched without case sensitivity": "前綴表示此樣式不區分大小寫",
"Preview": "預覽",
"Preview Usage Report": "預覽使用資訊報告",
"Quick guide to supported patterns": "可支援樣式的快速指南",
"RAM Utilization": "記憶體使用",
"Random": "隨機",
"Reduced by ignore patterns": "已由忽略樣式縮減",
"Release Notes": "版本資訊",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "發行候選版包含最新的功能及修補。與傳統 Syncthing 雙週發行版相似。",
"Remote Devices": "遠端裝置",
"Remove": "移除",
"Required identifier for the folder. Must be the same on all cluster devices.": "資料夾的識別字。必須在叢集內所有的裝置上皆相同。",
"Rescan": "重新掃描",
"Rescan All": "全部重新掃描",
"Rescan Interval": "重新掃描間隔",
"Restart": "重新啟動",
"Restart Needed": "需要重新啟動",
"Restarting": "正在重新啟動",
"Resume": "繼續",
"Resume All": "全部繼續",
"Reused": "重用",
"Save": "儲存",
"Scan Time Remaining": "剩餘掃描時間",
"Scanning": "正在掃描",
"See external versioner help for supported templated command line parameters.": "關於命令列模板參數請參閱外部版本管理說明。",
"Select the devices to share this folder with.": "選擇要共享這個資料夾的裝置。",
"Select the folders to share with this device.": "選擇要共享這個資料夾的裝置。",
"Send & Receive": "傳送及接收",
"Send Only": "僅傳送",
"Settings": "設定",
"Share": "分享",
"Share Folder": "分享資料夾",
"Share Folders With Device": "與裝置共享資料夾",
"Share With Devices": "與這些裝置共享",
"Share this folder?": "分享此資料夾?",
"Shared With": "與誰共享",
"Show ID": "顯示識別碼",
"Show QR": "顯示 QR 碼",
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "代替裝置識別碼顯示在叢集狀態中。這段文字將會廣播到其他的裝置作為一個可選的預設名稱。",
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "代替裝置識別碼顯示在叢集狀態中。本欄若未填寫則將被更新為此裝置所廣播的名稱。",
"Shutdown": "關閉",
"Shutdown Complete": "關閉完成",
"Simple File Versioning": "簡單檔案版本控制",
"Single level wildcard (matches within a directory only)": "單階層萬用字元 (只在單個資料夾階層內比對)",
"Smallest First": "最小的優先",
"Source Code": "原始碼",
"Stable releases and release candidates": "穩定發行版及發行候選版",
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "穩定發行版大約延遲兩週發佈。這段期間將作為發行候選版來測試。",
"Stable releases only": "僅穩定發行版",
"Staggered File Versioning": "變動式檔案版本控制",
"Start Browser": "啟動瀏覽器",
"Statistics": "統計",
"Stopped": "已停止",
"Support": "支援",
"Sync Protocol Listen Addresses": "同步通訊協定監聽位址",
"Syncing": "正在同步",
"Syncthing has been shut down.": "Syncthing 已經關閉。",
"Syncthing includes the following software or portions thereof:": "Syncthing 包括以下軟體或其中的一部分:",
"Syncthing is restarting.": "Syncthing 正在重新啟動。",
"Syncthing is upgrading.": "Syncthing 正在進行升級。",
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing 似乎離線了,或者您的網際網路連線出現問題。正在重試...",
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing 在處理您的請求時似乎遇到了問題。請重新整理本頁面,若問題持續發生,請重新啟動 Syncthing。",
"The Syncthing admin interface is configured to allow remote access without a password.": "The Syncthing admin interface is configured to allow remote access without a password.",
"The aggregated statistics are publicly available at the URL below.": "匯總統計資訊可於下方網址取得。",
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "組態已經儲存但尚未啟用。Syncthing 必須重新啟動以便啟用新的組態。",
"The device ID cannot be blank.": "裝置識別碼不能為空白。",
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "輸入裝置識別碼,可在其它裝置的 \"動作 > 顯示識別碼\" 對話框找到。空白及連接符號可省略。",
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.": "經過加密的使用資訊報告會每天傳送。報告是用來追蹤常用的平台、資料夾的大小以及應用程式的版本。若傳送的資料集有異動,您會再次看到這個對話框。",
"The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.": "輸入的裝置識別碼似乎無效。它應該為一串包含半形英文字母及數字,並可能會含有空白或連接符號的字串,且長度為 52 或 56 個字元。",
"The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "The first command line parameter is the folder path and the second parameter is the relative path in the folder.",
"The folder ID cannot be blank.": "資料夾識別碼不能為空白。",
"The folder ID must be unique.": "資料夾識別碼必須為獨一無二的。",
"The folder path cannot be blank.": "資料夾路徑不能空白。",
"The following intervals are used: for the first hour a version is kept every 30 seconds, for the first day a version is kept every hour, for the first 30 days a version is kept every day, until the maximum age a version is kept every week.": "使用下列的間隔:在第一個小時內每 30 秒保留一個版本,在第一天內每小時保留一個版本,在第 30 天內每一天保留一個版本,在達到最長保留時間前每一星期保留一個版本。",
"The following items could not be synchronized.": "以下項目不能被同步。",
"The maximum age must be a number and cannot be blank.": "最長保留時間必須為一個數字且不得為空。",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "一個版本被保留的最長時間 (單位為天,若設定為 0 則表示永遠保留)。",
"The minimum free disk space percentage must be a non-negative number between 0 and 100 (inclusive).": "The minimum free disk space percentage must be a non-negative number between 0 and 100 (inclusive).",
"The number of days must be a number and cannot be blank.": "天數必須必須為一個數字且不得為空。",
"The number of days to keep files in the trash can. Zero means forever.": "檔案在 trash can 中保留的日子。零表示永遠地保留。",
"The number of old versions to keep, per file.": "每個檔案要保留的舊版本數量。",
"The number of versions must be a number and cannot be blank.": "每個檔案要保留的舊版本數量必須是數字且不能為空白。",
"The path cannot be blank.": "路徑不能空白。",
"The rate limit must be a non-negative number (0: no limit)": "限制速率必須為非負的數字 (0: 不設限制)",
"The rescan interval must be a non-negative number of seconds.": "重新掃描間隔必須為一個非負數的秒數。",
"They are retried automatically and will be synced when the error is resolved.": "解決間題後,將會自動重試和同步。",
"This Device": "本機",
"This can easily give hackers access to read and change any files on your computer.": "This can easily give hackers access to read and change any files on your computer.",
"This is a major version upgrade.": "這是一個主要版本更新。",
"This setting controls the free space required on the home (i.e., index database) disk.": "此設定控制家目錄(即:索引資料庫)的必須可用空間。",
"Time": "時間",
"Trash Can File Versioning": "垃圾筒式檔案版本控制",
"Type": "類型",
"Unknown": "未知",
"Unshared": "未共享",
"Unused": "未使用",
"Up to Date": "最新",
"Updated": "已更新",
"Upgrade": "升級",
"Upgrade To {%version%}": "升級至 {{version}}",
"Upgrading": "正在升級",
"Upload Rate": "上載速率",
"Uptime": "上線時間",
"Usage reporting is always enabled for candidate releases.": "發行候選版永遠回報使用數據",
"Use HTTPS for GUI": "為 GUI 使用 HTTPS",
"Version": "版本",
"Versions Path": "歷史版本路徑",
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "當檔案歷史版本的存留時間大於設定的最大值,或是其數量在一段時間內超出允許值時,則會被刪除。",
"Warning, this path is a parent directory of an existing folder \"{%otherFolder%}\".": "警告,此路徑是現存資料夾 \"{{otherFolder}}\" 的上級目錄。",
"Warning, this path is a parent directory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "警告,此路徑是現存資料夾 \"{{otherFolderLabel}}\" ({{otherFolder}}) 的上級目錄。",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "警告,此路徑是現存資料夾 \"{{otherFolder}}\" 的下級目錄。",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "警告,此路徑是現存資料夾 \"{{otherFolderLabel}}\" ({{otherFolder}}) 的下級目錄。",
"When adding a new device, keep in mind that this device must be added on the other side too.": "當新增一個裝置時,務必記住,當前的這個裝置也同樣必須被添加至另一邊。",
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "當新增一個資料夾時,請記住,資料夾識別碼是用來將裝置之間的資料夾綁定在一起的。它們有區分大小寫,且必須在所有裝置之間完全相同。",
"Yes": "是",
"You can also select one of these nearby devices:": "您亦可從這些附近裝置中擇一:",
"You can change your choice at any time in the Settings dialog.": "您可以在設定對話框中隨時更改您的選擇。",
"You can read more about the two release channels at the link below.": "您可於下方連結閱讀更多關於發行頻道的說明。",
"You must keep at least one version.": "您必須保留至少一個版本。",
"days": "日",
"directories": "個目錄",
"files": "個檔案",
"full documentation": "完整說明文件",
"items": "個項目",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} 想要分享資料夾 \"{{folder}}\"。",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} 想要分享資料夾 \"{{folderlabel}}\" ({{folder}})。"
}

View File

@@ -1 +1 @@
var langPrettyprint = {"bg":"Bulgarian","ca@valencia":"Catalan (Valencian)","cs":"Czech","da":"Danish","de":"German","el":"Greek","en":"English","en-GB":"English (United Kingdom)","eo":"Esperanto","es":"Spanish","es-ES":"Spanish (Spain)","eu":"Basque","fi":"Finnish","fr":"French","fr-CA":"French (Canada)","fy":"Western Frisian","hu":"Hungarian","id":"Indonesian","it":"Italian","ja":"Japanese","ko-KR":"Korean (Korea)","lt":"Lithuanian","nb":"Norwegian Bokmål","nl":"Dutch","nn":"Norwegian Nynorsk","pl":"Polish","pt-BR":"Portuguese (Brazil)","pt-PT":"Portuguese (Portugal)","ru":"Russian","sk":"Slovak","sv":"Swedish","tr":"Turkish","uk":"Ukrainian","vi":"Vietnamese","zh-CN":"Chinese (China)"}
var langPrettyprint = {"bg":"Bulgarian","ca@valencia":"Catalan (Valencian)","cs":"Czech","da":"Danish","de":"German","el":"Greek","en":"English","en-GB":"English (United Kingdom)","eo":"Esperanto","es":"Spanish","es-ES":"Spanish (Spain)","eu":"Basque","fi":"Finnish","fr":"French","fr-CA":"French (Canada)","fy":"Western Frisian","hu":"Hungarian","it":"Italian","ja":"Japanese","ko-KR":"Korean (Korea)","lt":"Lithuanian","nb":"Norwegian Bokmål","nl":"Dutch","nn":"Norwegian Nynorsk","pl":"Polish","pt-BR":"Portuguese (Brazil)","pt-PT":"Portuguese (Portugal)","ru":"Russian","sk":"Slovak","sv":"Swedish","tr":"Turkish","uk":"Ukrainian","vi":"Vietnamese","zh-CN":"Chinese (China)","zh-TW":"Chinese (Taiwan)"}

View File

@@ -1 +1 @@
var validLangs = ["bg","ca@valencia","cs","da","de","el","en","en-GB","eo","es","es-ES","eu","fi","fr","fr-CA","fy","hu","id","it","ja","ko-KR","lt","nb","nl","nn","pl","pt-BR","pt-PT","ru","sk","sv","tr","uk","vi","zh-CN"]
var validLangs = ["bg","ca@valencia","cs","da","de","el","en","en-GB","eo","es","es-ES","eu","fi","fr","fr-CA","fy","hu","it","ja","ko-KR","lt","nb","nl","nn","pl","pt-BR","pt-PT","ru","sk","sv","tr","uk","vi","zh-CN","zh-TW"]

View File

@@ -9,32 +9,32 @@
-->
<html lang="en" ng-app="syncthing" ng-controller="SyncthingController" class="ng-cloak">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link rel="shortcut icon" href="assets/img/favicon-{{syncthingStatus()}}.png">
<link rel="mask-icon" href="assets/img/safari-pinned-tab.svg" color="#0882c8">
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="description" content=""/>
<meta name="author" content=""/>
<link rel="shortcut icon" href="assets/img/favicon-{{syncthingStatus()}}.png"/>
<link rel="mask-icon" href="assets/img/safari-pinned-tab.svg" color="#0882c8"/>
<title ng-bind="thisDeviceName() + ' | Syncthing'"></title>
<link href="vendor/bootstrap/css/bootstrap.css" rel="stylesheet">
<link href="assets/font/raleway.css" rel="stylesheet">
<link href="vendor/font-awesome/css/font-awesome.css" rel="stylesheet">
<link href="assets/css/overrides.css" rel="stylesheet">
<link href="assets/css/theme.css" rel="stylesheet">
<link href="vendor/bootstrap/css/bootstrap.css" rel="stylesheet"/>
<link href="assets/font/raleway.css" rel="stylesheet"/>
<link href="vendor/font-awesome/css/font-awesome.css" rel="stylesheet"/>
<link href="assets/css/overrides.css" rel="stylesheet"/>
<link href="assets/css/theme.css" rel="stylesheet"/>
</head>
<body>
<script src="syncthing/development/logbar.js"></script>
<script type="text/javascript" src="syncthing/development/logbar.js"></script>
<div ng-if="version.isDevelopmentVersion" ng-include="'syncthing/development/logbar.html'"></div>
<!-- Top bar -->
<nav class="navbar navbar-top navbar-default" role="navigation">
<div class="container">
<span class="navbar-brand" aria-hidden="true">
<img class="logo hidden-xs" src="assets/img/logo-horizontal.svg" height="32" width="117"/>
<img class="logo hidden visible-xs" src="assets/img/favicon-default.png" height="32"/>
<img class="logo hidden-xs" src="assets/img/logo-horizontal.svg" height="32" width="117" alt=""/>
<img class="logo hidden visible-xs" src="assets/img/favicon-default.png" height="32" alt=""/>
</span>
<p class="navbar-text hidden-xs" ng-class="{'hidden-sm':upgradeInfo && upgradeInfo.newer}">{{thisDeviceName()}}</p>
<ul class="nav navbar-nav navbar-right">
@@ -216,6 +216,9 @@
<button type="button" class="btn btn-sm btn-default" ng-click="dismissFolderRejection(event.data.folder, event.data.device)">
<span class="fa fa-clock-o"></span>&nbsp;<span translate>Later</span>
</button>
<button type="button" class="btn btn-sm btn-default" ng-click="ignoreRejectedFolder(event.data.folder, event.data.device)">
<span class="fa fa-times"></span>&nbsp;<span translate>Ignore</span>
</button>
</div>
</div>
</div>
@@ -365,7 +368,13 @@
<span translate>Yes</span>
</td>
</tr>
<tr ng-if="folder.rescanIntervalS != 60">
<tr ng-if="folder.fsNotifications">
<th><span class="fa fa-fw fa-bolt"></span>&nbsp;<span translate>Filesystem Notifications</span></th>
<td class="text-right">
<span translate>Yes</span>
</td>
</tr>
<tr ng-if="(folder.rescanIntervalS != 60 && !folder.fsNotifications) || (folder.rescanIntervalS != 3600 && folder.fsNotifications)">
<th><span class="fa fa-fw fa-refresh"></span>&nbsp;<span translate>Rescan Interval</span></th>
<td class="text-right">{{folder.rescanIntervalS}} s</td>
</tr>
@@ -391,7 +400,7 @@
</tr>
<tr>
<th><span class="fa fa-fw fa-share-alt"></span>&nbsp;<span translate>Shared With</span></th>
<td class="text-right">{{sharesFolder(folder)}}</td>
<td class="text-right" ng-attr-title="{{sharesFolder(folder)}}">{{sharesFolder(folder)}}</td>
</tr>
<tr>
<th><span class="fa fa-fw fa-clock-o"></span>&nbsp;<span translate>Last Scan</span></th>
@@ -493,7 +502,12 @@
</tr>
<tr>
<th><span class="fa fa-fw fa-home"></span>&nbsp;<span translate>Local State (Total)</span></th>
<td class="text-right">{{localStateTotal.files | alwaysNumber}} <span translate>items</span>, ~{{localStateTotal.bytes | binary}}B</td>
<td class="text-right">
<span tooltip data-original-title="{{localStateTotal.files | alwaysNumber}} {{'files' | translate}}, {{ localStateTotal.directories | alwaysNumber}} {{'directories' | translate}}, ~{{ localStateTotal.bytes | binary}}B">
<span class="fa fa-files-o"></span>&nbsp;{{localStateTotal.files | alwaysNumber}}&ensp;
<span class="fa fa-folder-o"></span>&nbsp;{{localStateTotal.directories| alwaysNumber}}&ensp;
<span class="fa fa-hdd-o"></span>&nbsp;~{{localStateTotal.bytes | binary}}B
</td>
</tr>
<tr>
<th><span class="fa fa-fw fa-th"></span>&nbsp;<span translate>RAM Utilization</span></th>
@@ -556,7 +570,7 @@
<span ng-switch="deviceStatus(deviceCfg)" class="pull-right text-{{deviceClass(deviceCfg)}}">
<span ng-switch-when="insync"><span class="hidden-xs" translate>Up to Date</span><span class="visible-xs">&#9724;</span></span>
<span ng-switch-when="syncing">
<span class="hidden-xs" translate>Syncing</span> ({{completion[deviceCfg.deviceID]._total | number:0}}%)
<span class="hidden-xs" translate>Syncing</span> ({{completion[deviceCfg.deviceID]._total | number:0}}%, {{completion[deviceCfg.deviceID]._needBytes | binary}}B)
</span>
<span ng-switch-when="paused"><span class="hidden-xs" translate>Paused</span><span class="visible-xs">&#9724;</span></span>
<span ng-switch-when="disconnected"><span class="hidden-xs" translate>Disconnected</span><span class="visible-xs">&#9724;</span></span>
@@ -637,7 +651,7 @@
</tr>
<tr ng-if="deviceFolders(deviceCfg).length > 0">
<th><span class="fa fa-fw fa-folder"></span>&nbsp;<span translate>Folders</span></th>
<td class="text-right">{{deviceFolders(deviceCfg).map(folderLabel).join(", ")}}</td>
<td class="text-right" ng-attr-title="{{deviceFolders(deviceCfg).map(folderLabel).join(', ')}}">{{deviceFolders(deviceCfg).map(folderLabel).join(", ")}}</td>
</tr>
</tbody>
</table>
@@ -713,41 +727,42 @@
<ng-include src="'syncthing/core/discoveryFailuresModalView.html'"></ng-include>
<!-- vendor scripts -->
<script src="vendor/jquery/jquery-2.2.2.js"></script>
<script src="vendor/angular/angular.js"></script>
<script src="vendor/angular/angular-sanitize.js"></script>
<script src="vendor/angular/angular-translate.js"></script>
<script src="vendor/angular/angular-translate-loader-static-files.js"></script>
<script src="vendor/angular/angular-dirPagination.js"></script>
<script src="vendor/bootstrap/js/bootstrap.js"></script>
<script type="text/javascript" src="vendor/jquery/jquery-2.2.2.js"></script>
<script type="text/javascript" src="vendor/angular/angular.js"></script>
<script type="text/javascript" src="vendor/angular/angular-sanitize.js"></script>
<script type="text/javascript" src="vendor/angular/angular-translate.js"></script>
<script type="text/javascript" src="vendor/angular/angular-translate-loader-static-files.js"></script>
<script type="text/javascript" src="vendor/angular/angular-dirPagination.js"></script>
<script type="text/javascript" src="vendor/bootstrap/js/bootstrap.js"></script>
<!-- / vendor scripts -->
<!-- gui application code -->
<script src="syncthing/core/module.js"></script>
<script src="syncthing/core/alwaysNumberFilter.js"></script>
<script src="syncthing/core/basenameFilter.js"></script>
<script src="syncthing/core/binaryFilter.js"></script>
<script src="syncthing/core/durationFilter.js"></script>
<script src="syncthing/core/eventService.js"></script>
<script src="syncthing/core/identiconDirective.js"></script>
<script src="syncthing/core/languageSelectDirective.js"></script>
<script src="syncthing/core/lastErrorComponentFilter.js"></script>
<script src="syncthing/core/localeService.js"></script>
<script src="syncthing/core/modalDirective.js"></script>
<script src="syncthing/core/naturalFilter.js"></script>
<script src="syncthing/core/metricFilter.js"></script>
<script src="syncthing/core/notificationDirective.js"></script>
<script src="syncthing/core/pathIsSubDirDirective.js"></script>
<script src="syncthing/core/popoverDirective.js"></script>
<script src="syncthing/core/selectOnClickDirective.js"></script>
<script src="syncthing/core/syncthingController.js"></script>
<script src="syncthing/core/tooltipDirective.js"></script>
<script src="syncthing/core/uniqueFolderDirective.js"></script>
<script src="syncthing/core/validDeviceidDirective.js"></script>
<script src="assets/lang/valid-langs.js"></script>
<script src="assets/lang/prettyprint.js"></script>
<script src="meta.js"></script>
<script src="syncthing/app.js"></script>
<script type="text/javascript" src="syncthing/core/module.js"></script>
<script type="text/javascript" src="syncthing/core/alwaysNumberFilter.js"></script>
<script type="text/javascript" src="syncthing/core/basenameFilter.js"></script>
<script type="text/javascript" src="syncthing/core/binaryFilter.js"></script>
<script type="text/javascript" src="syncthing/core/durationFilter.js"></script>
<script type="text/javascript" src="syncthing/core/eventService.js"></script>
<script type="text/javascript" src="syncthing/core/identiconDirective.js"></script>
<script type="text/javascript" src="syncthing/core/languageSelectDirective.js"></script>
<script type="text/javascript" src="syncthing/core/lastErrorComponentFilter.js"></script>
<script type="text/javascript" src="syncthing/core/localeService.js"></script>
<script type="text/javascript" src="syncthing/core/modalDirective.js"></script>
<script type="text/javascript" src="syncthing/core/naturalFilter.js"></script>
<script type="text/javascript" src="syncthing/core/metricFilter.js"></script>
<script type="text/javascript" src="syncthing/core/notificationDirective.js"></script>
<script type="text/javascript" src="syncthing/core/pathIsSubDirDirective.js"></script>
<script type="text/javascript" src="syncthing/core/popoverDirective.js"></script>
<script type="text/javascript" src="syncthing/core/selectOnClickDirective.js"></script>
<script type="text/javascript" src="syncthing/core/syncthingController.js"></script>
<script type="text/javascript" src="syncthing/core/tooltipDirective.js"></script>
<script type="text/javascript" src="syncthing/core/uncamelFilter.js"></script>
<script type="text/javascript" src="syncthing/core/uniqueFolderDirective.js"></script>
<script type="text/javascript" src="syncthing/core/validDeviceidDirective.js"></script>
<script type="text/javascript" src="assets/lang/valid-langs.js"></script>
<script type="text/javascript" src="assets/lang/prettyprint.js"></script>
<script type="text/javascript" src="meta.js"></script>
<script type="text/javascript" src="syncthing/app.js"></script>
<!-- / gui application code -->
</body>

View File

@@ -12,7 +12,7 @@
<p translate>Copyright &copy; 2014-2017 the following Contributors:</p>
<div class="row">
<div class="col-md-12" id="contributor-list">
Jakob Borg, Audrius Butkevicius, Alexander Graf, Anderson Mesquita, Antony Male, Ben Schulz, Caleb Callaway, Daniel Harte, Lars K.W. Gohlke, Lode Hoste, Michael Ploujnikov, Philippe Schommers, Ryan Sullivan, Sergey Mishin, Simon Frei, Stefan Tatschner, Aaron Bieber, Adam Piggott, Adel Qalieh, Alessandro G., Alexandre Viau, Andrew Dunham, Andrey D, Antoine Lamielle, Arthur Axel fREW Schmidt, Bart De Vries, Ben Curthoys, Ben Shepherd, Ben Sidhom, Benny Ng, Brandon Philips, Brendan Long, Brian R. Becker, Carsten Hagemann, Cathryne Linenweaver, Cedric Staniewski, Chris Howie, Chris Joel, Colin Kennedy, Daniel Bergmann, Daniel Martí, Darshil Chanpura, David Rimmer, Denis A., Dennis Wilson, Dominik Heidler, Elias Jarlebring, Emil Hessman, Erik Meitner, Federico Castagnini, Felix Ableitner, Felix Unterpaintner, Francois-Xavier Gsell, Frank Isemann, Gilli Sigurdsson, Heiko Zuerker, Jaakko Hannikainen, Jacek Szafarkiewicz, Jake Peterson, James Patterson, Jaroslav Malec, Jaya Chithra, Jens Diemer, Jochen Voss, Johan Vromans, Karol Różycki, Kelong Cong, Ken'ichi Kamada, Kevin Allen, Kevin White, Jr., Kurt Fitzner, Laurent Etiemble, Leo Arias, Lord Landon Agahnim, Majed Abdulaziz, Marc Laporte, Marc Pujol, Marcin Dziadus, Mark Pulford, Mateusz Naściszewski, Matt Burke, Max Schulze, Michael Jephcote, Michael Tilli, Nate Morrison, Niels Peter Roest, Pascal Jungblut, Peter Hoeg, Phill Luby, Piotr Bejda, Robert Carosi, Roman Zaynetdinov, Sacheendra Talluri, Scott Klupfel, Stefan Kuntz, Tim Abell, Tim Howes, Tobias Nygren, Tomas Cerveny, Tully Robinson, Tyler Brazier, Unrud, Veeti Paananen, Victor Buinsky, Vil Brekin, William A. Kennington III, Wulf Weich, Xavier O., Yannic A.
Jakob Borg, Audrius Butkevicius, Alexander Graf, Anderson Mesquita, Antony Male, Ben Schulz, Caleb Callaway, Daniel Harte, Lars K.W. Gohlke, Lode Hoste, Michael Ploujnikov, Nate Morrison, Philippe Schommers, Ryan Sullivan, Sergey Mishin, Simon Frei, Stefan Tatschner, Aaron Bieber, Adam Piggott, Adel Qalieh, Alessandro G., Alexandre Viau, Andrew Dunham, Andrey D, Antoine Lamielle, Arthur Axel fREW Schmidt, Bart De Vries, Ben Curthoys, Ben Shepherd, Ben Sidhom, Benny Ng, Brandon Philips, Brendan Long, Brian R. Becker, Carsten Hagemann, Cathryne Linenweaver, Cedric Staniewski, Chris Howie, Chris Joel, Colin Kennedy, Daniel Bergmann, Daniel Martí, Darshil Chanpura, David Rimmer, Denis A., Dennis Wilson, Dominik Heidler, Elias Jarlebring, Emil Hessman, Erik Meitner, Federico Castagnini, Felix Ableitner, Felix Unterpaintner, Francois-Xavier Gsell, Frank Isemann, Gilli Sigurdsson, Heiko Zuerker, Jaakko Hannikainen, Jacek Szafarkiewicz, Jake Peterson, James Patterson, Jaroslav Malec, Jaya Chithra, Jens Diemer, Jochen Voss, Johan Vromans, Jose Manuel Delicado, Karol Różycki, Kelong Cong, Ken'ichi Kamada, Kevin Allen, Kevin White, Jr., Kurt Fitzner, Laurent Etiemble, Leo Arias, Liu Siyuan, Lord Landon Agahnim, Majed Abdulaziz, Marc Laporte, Marc Pujol, Marcin Dziadus, Mark Pulford, Mateusz Naściszewski, Matt Burke, Max Schulze, Michael Jephcote, Michael Tilli, Niels Peter Roest, Pascal Jungblut, Peter Hoeg, Phill Luby, Piotr Bejda, Robert Carosi, Roman Zaynetdinov, Ross Smith II, Sacheendra Talluri, Scott Klupfel, Stefan Kuntz, Suhas Gundimeda, Tim Abell, Tim Howes, Tobias Nygren, Tobias Tom, Tomas Cerveny, Tully Robinson, Tyler Brazier, Unrud, Veeti Paananen, Victor Buinsky, Vil Brekin, William A. Kennington III, Wulf Weich, Xavier O., Yannic A.
</div>
</div>
<hr/>

View File

@@ -1,6 +1,8 @@
angular.module('syncthing.core')
.directive('modal', function () {
return {
// If you ever change any of the petroglyphs below, please search for $parent.$parent,
// as some templates rely on the way scope is composed in this case.
restrict: 'E',
templateUrl: 'modal.html',
replace: true,

View File

@@ -40,4 +40,4 @@
<div class="clearfix"></div>
</div>
</div>
</notification>
</notification>

View File

@@ -20,22 +20,22 @@ angular.module('syncthing.core')
}).every(function(e) { return e });
}
scope.pathIsSubFolder = false;
scope.pathIsParentFolder = false;
scope.otherFolder = "";
scope.otherFolderLabel = "";
scope.folderPathErrors.isSub = false;
scope.folderPathErrors.isParent = false;
scope.folderPathErrors.otherID = "";
scope.folderPathErrors.otherLabel = "";
for (var folderID in scope.folders) {
if (isSubDir(scope.folders[folderID].path, viewValue)) {
scope.otherFolder = folderID;
scope.otherFolderLabel = scope.folders[folderID].label;
scope.pathIsSubFolder = true;
scope.folderPathErrors.otherID = folderID;
scope.folderPathErrors.otherLabel = scope.folders[folderID].label;
scope.folderPathErrors.isSub = true;
break;
}
if (viewValue !== "" &&
isSubDir(viewValue, scope.folders[folderID].path)) {
scope.otherFolder = folderID;
scope.otherFolderLabel = scope.folders[folderID].label;
scope.pathIsParentFolder = true;
scope.folderPathErrors.otherID = folderID;
scope.folderPathErrors.otherLabel = scope.folders[folderID].label;
scope.folderPathErrors.isParent = true;
break;
}
}

View File

@@ -2,7 +2,7 @@ angular.module('syncthing.core')
.config(function($locationProvider) {
$locationProvider.html5Mode({enabled: true, requireBase: false}).hashPrefix('!');
})
.controller('SyncthingController', function ($scope, $http, $location, LocaleService, Events, $filter) {
.controller('SyncthingController', function ($scope, $http, $location, LocaleService, Events, $filter, $q) {
'use strict';
// private/helper definitions
@@ -33,6 +33,9 @@ angular.module('syncthing.core')
$scope.folderRejections = {};
$scope.protocolChanged = false;
$scope.reportData = {};
$scope.reportDataPreview = '';
$scope.reportDataPreviewVersion = '';
$scope.reportDataPreviewDiff = false;
$scope.reportPreview = false;
$scope.folders = {};
$scope.seenError = '';
@@ -47,37 +50,40 @@ angular.module('syncthing.core')
$scope.neededPageSize = 10;
$scope.failed = {};
$scope.failedCurrentPage = 1;
$scope.failedCurrentFolder = undefined;
$scope.failedPageSize = 10;
$scope.scanProgress = {};
$scope.themes = [];
$scope.globalChangeEvents = {};
$scope.metricRates = false;
$scope.folderPathErrors = {};
try {
$scope.metricRates = (window.localStorage["metricRates"] == "true");
} catch (exception) { }
$scope.folderDefaults = {
selectedDevices: {},
type: "readwrite",
rescanIntervalS: 60,
minDiskFree: {value: 1, unit: "%"},
maxConflicts: 10,
fsync: true,
order: "random",
fileVersioningSelector: "none",
trashcanClean: 0,
simpleKeep: 5,
staggeredMaxAge: 365,
staggeredCleanInterval: 3600,
staggeredVersionsPath: "",
externalCommand: "",
autoNormalize: true
selectedDevices: {},
type: "readwrite",
rescanIntervalS: 60,
fsWatcherDelayS: 10,
minDiskFree: {value: 1, unit: "%"},
maxConflicts: 10,
fsync: true,
order: "random",
fileVersioningSelector: "none",
trashcanClean: 0,
simpleKeep: 5,
staggeredMaxAge: 365,
staggeredCleanInterval: 3600,
staggeredVersionsPath: "",
externalCommand: "",
autoNormalize: true,
path: ""
};
$scope.localStateTotal = {
bytes: 0,
directories: 0,
files: 0
};
@@ -131,6 +137,10 @@ angular.module('syncthing.core')
$http.get(urlbase + '/svc/report').success(function (data) {
$scope.reportData = data;
if ($scope.system && $scope.config.options.urAccepted > -1 && $scope.config.options.urSeen < $scope.system.urVersionMax && $scope.config.options.urAccepted < $scope.system.urVersionMax) {
// Usage reporting format has changed, prompt the user to re-accept.
$('#ur').modal();
}
}).error($scope.emitHTTPError);
$http.get(urlbase + '/system/upgrade').success(function (data) {
@@ -230,7 +240,8 @@ angular.module('syncthing.core')
address: arg.data.addr
};
$scope.completion[arg.data.id] = {
_total: 100
_total: 100,
_needBytes: 0
};
}
});
@@ -372,11 +383,13 @@ angular.module('syncthing.core')
$scope.config = config;
$scope.config.options._listenAddressesStr = $scope.config.options.listenAddresses.join(', ');
$scope.config.options._globalAnnounceServersStr = $scope.config.options.globalAnnounceServers.join(', ');
$scope.config.options._urAcceptedStr = "" + $scope.config.options.urAccepted;
$scope.devices = $scope.config.devices;
$scope.devices.forEach(function (deviceCfg) {
$scope.completion[deviceCfg.deviceID] = {
_total: 100
_total: 100,
_needBytes: 0
};
});
$scope.devices.sort(deviceCompare);
@@ -407,6 +420,10 @@ angular.module('syncthing.core')
$scope.myID = data.myID;
$scope.system = data;
if ($scope.reportDataPreviewVersion === '') {
$scope.reportDataPreviewVersion = $scope.system.urVersionMax;
}
var listenersFailed = [];
for (var address in data.connectionServiceStatus) {
if (data.connectionServiceStatus[address].error) {
@@ -447,19 +464,21 @@ angular.module('syncthing.core')
function recalcLocalStateTotal () {
$scope.localStateTotal = {
bytes: 0,
directories: 0,
files: 0
};
for (var f in $scope.model) {
$scope.localStateTotal.bytes += $scope.model[f].localBytes;
$scope.localStateTotal.files += $scope.model[f].localFiles;
$scope.localStateTotal.directories += $scope.model[f].localDirectories;
}
}
function recalcCompletion(device) {
var total = 0, needed = 0, deletes = 0;
for (var folder in $scope.completion[device]) {
if (folder === "_total") {
if (folder === "_total" || folder === '_needBytes') {
continue;
}
total += $scope.completion[device][folder].globalBytes;
@@ -468,8 +487,10 @@ angular.module('syncthing.core')
}
if (total == 0) {
$scope.completion[device]._total = 100;
$scope.completion[device]._needBytes = 0;
} else {
$scope.completion[device]._total = 100 * (1 - needed / total);
$scope.completion[device]._total = Math.floor(100 * (1 - needed / total));
$scope.completion[device]._needBytes = needed
}
if (needed == 0 && deletes > 0) {
@@ -477,6 +498,7 @@ angular.module('syncthing.core')
// to do. Drop down the completion percentage to indicate
// that we have stuff to do.
$scope.completion[device]._total = 95;
$scope.completion[device]._needBytes = 0;
}
console.log("recalcCompletion", device, $scope.completion[device]);
@@ -597,6 +619,25 @@ angular.module('syncthing.core')
$scope.neededTotal = data.total;
}
function pathJoin(base, name) {
base = expandTilde(base);
if (base[base.length - 1] !== $scope.system.pathSeparator) {
return base + $scope.system.pathSeparator + name;
}
return base + name;
}
function expandTilde(path) {
if (path && path.trim().charAt(0) === '~') {
return $scope.system.tilde + path.trim().substring(1);
}
return path;
}
function shouldSetDefaultFolderPath() {
return $scope.config.options && $scope.config.options.defaultFolderPath && !$scope.editingExisting && $scope.folderEditor.folderPath.$pristine
}
$scope.neededPageChanged = function (page) {
$scope.neededCurrentPage = page;
refreshNeed($scope.neededFolder);
@@ -1029,7 +1070,6 @@ angular.module('syncthing.core')
$scope.editSettings = function () {
// Make a working copy
$scope.tmpOptions = angular.copy($scope.config.options);
$scope.tmpOptions.urEnabled = ($scope.tmpOptions.urAccepted > 0);
$scope.tmpOptions.deviceName = $scope.thisDevice().name;
$scope.tmpOptions.upgrades = "none";
if ($scope.tmpOptions.autoUpgradeIntervalH > 0) {
@@ -1059,18 +1099,31 @@ angular.module('syncthing.core')
}).error($scope.emitHTTPError);
};
$scope.urVersions = function() {
var result = [];
if ($scope.system) {
for (var i = $scope.system.urVersionMax; i >= 2; i--) {
result.push("" + i);
}
}
return result;
};
$scope.saveSettings = function () {
// Make sure something changed
var changed = !angular.equals($scope.config.options, $scope.tmpOptions) || !angular.equals($scope.config.gui, $scope.tmpGUI);
var themeChanged = $scope.config.gui.theme !== $scope.tmpGUI.theme;
if (changed) {
// Angular has issues with selects with numeric values, so we handle strings here.
$scope.tmpOptions.urAccepted = parseInt($scope.tmpOptions._urAcceptedStr);
// Check if auto-upgrade has been enabled or disabled. This
// also has an effect on usage reporting, so do the check
// for that later.
if ($scope.tmpOptions.upgrades == "candidate") {
$scope.tmpOptions.autoUpgradeIntervalH = $scope.tmpOptions.autoUpgradeIntervalH || 12;
$scope.tmpOptions.upgradeToPreReleases = true;
$scope.tmpOptions.urEnabled = true;
$scope.tmpOptions.urAccepted = $scope.system.urVersionMax;
$scope.tmpOptions.urSeen = $scope.system.urVersionMax;
} else if ($scope.tmpOptions.upgrades == "stable") {
$scope.tmpOptions.autoUpgradeIntervalH = $scope.tmpOptions.autoUpgradeIntervalH || 12;
$scope.tmpOptions.upgradeToPreReleases = false;
@@ -1078,13 +1131,6 @@ angular.module('syncthing.core')
$scope.tmpOptions.autoUpgradeIntervalH = 0;
}
// Check if usage reporting has been enabled or disabled
if ($scope.tmpOptions.urEnabled && $scope.tmpOptions.urAccepted <= 0) {
$scope.tmpOptions.urAccepted = 1000;
} else if (!$scope.tmpOptions.urEnabled && $scope.tmpOptions.urAccepted > 0) {
$scope.tmpOptions.urAccepted = -1;
}
// Check if protocol will need to be changed on restart
if ($scope.config.gui.useTLS !== $scope.tmpGUI.useTLS) {
$scope.protocolChanged = true;
@@ -1181,7 +1227,19 @@ angular.module('syncthing.core')
$scope.addDevice = function (deviceID, name) {
return $http.get(urlbase + '/system/discovery')
.success(function (registry) {
$scope.discovery = registry;
$scope.discovery = [];
outer:
for (var id in registry) {
if ($scope.discovery.length === 5) {
break;
}
for (var i = 0; i < $scope.devices.length; i++) {
if ($scope.devices[i].deviceID === id) {
continue outer;
}
}
$scope.discovery.push(id);
}
})
.then(function () {
$scope.currentDevice = {
@@ -1339,9 +1397,10 @@ angular.module('syncthing.core')
$scope.directoryList = [];
$scope.$watch('currentFolder.path', function (newvalue) {
if (newvalue && newvalue.trim().charAt(0) === '~') {
$scope.currentFolder.path = $scope.system.tilde + newvalue.trim().substring(1);
if (!newvalue) {
return;
}
$scope.currentFolder.path = expandTilde(newvalue);
$http.get(urlbase + '/system/browse', {
params: { current: newvalue }
}).success(function (data) {
@@ -1349,6 +1408,20 @@ angular.module('syncthing.core')
}).error($scope.emitHTTPError);
});
$scope.$watch('currentFolder.label', function (newvalue) {
if (!newvalue || !shouldSetDefaultFolderPath()) {
return;
}
$scope.currentFolder.path = pathJoin($scope.config.options.defaultFolderPath, newvalue);
});
$scope.$watch('currentFolder.id', function (newvalue) {
if (!newvalue || !shouldSetDefaultFolderPath() || $scope.currentFolder.label) {
return;
}
$scope.currentFolder.path = pathJoin($scope.config.options.defaultFolderPath, newvalue);
});
$scope.loadFormIntoScope = function (form) {
console.log('loadFormIntoScope',form.$name);
switch (form.$name) {
@@ -1365,7 +1438,15 @@ angular.module('syncthing.core')
$('#globalChanges').modal();
};
$scope.editFolderModal = function () {
$scope.folderPathErrors = {};
$scope.folderEditor.$setPristine();
$('#editIgnores textarea').val("");
$('#editFolder').modal();
};
$scope.editFolder = function (folderCfg) {
$scope.editingExisting = true;
$scope.currentFolder = angular.copy(folderCfg);
if ($scope.currentFolder.path.slice(-1) === $scope.system.pathSeparator) {
$scope.currentFolder.path = $scope.currentFolder.path.slice(0, -1);
@@ -1408,24 +1489,21 @@ angular.module('syncthing.core')
}
$scope.currentFolder.externalCommand = $scope.currentFolder.externalCommand || "";
$scope.editingExisting = true;
$scope.folderEditor.$setPristine();
$('#editFolder').modal();
$scope.editFolderModal();
};
$scope.addFolder = function () {
$scope.currentFolder = angular.copy($scope.folderDefaults);
$scope.editingExisting = false;
$('#editIgnores textarea').val("");
$scope.folderEditor.$setPristine();
$http.get(urlbase + '/svc/random/string?length=10').success(function (data) {
$scope.editingExisting = false;
$scope.currentFolder = angular.copy($scope.folderDefaults);
$scope.currentFolder.id = (data.random.substr(0, 5) + '-' + data.random.substr(5, 5)).toLowerCase();
$('#editFolder').modal();
$scope.editFolderModal();
});
};
$scope.addFolderAndShare = function (folder, folderLabel, device) {
$scope.dismissFolderRejection(folder, device);
$scope.editingExisting = false;
$scope.currentFolder = angular.copy($scope.folderDefaults);
$scope.currentFolder.id = folder;
$scope.currentFolder.label = folderLabel;
@@ -1434,9 +1512,7 @@ angular.module('syncthing.core')
};
$scope.currentFolder.selectedDevices[device] = true;
$scope.editingExisting = false;
$scope.folderEditor.$setPristine();
$('#editFolder').modal();
$scope.editFolderModal();
};
$scope.shareFolderWithDevice = function (folder, device) {
@@ -1528,6 +1604,12 @@ angular.module('syncthing.core')
delete $scope.folderRejections[folder + "-" + device];
};
$scope.ignoreRejectedFolder = function (folder, device) {
$scope.config.ignoredFolders.push(folder);
$scope.saveConfig();
$scope.dismissFolderRejection(folder, device);
};
$scope.sharesFolder = function (folderCfg) {
var names = [];
folderCfg.devices.forEach(function (device) {
@@ -1626,13 +1708,17 @@ angular.module('syncthing.core')
};
$scope.acceptUR = function () {
$scope.config.options.urAccepted = 1000; // Larger than the largest existing report version
$scope.config.options.urAccepted = $scope.system.urVersionMax;
$scope.config.options.urSeen = $scope.system.urVersionMax;
$scope.saveConfig();
$('#ur').modal('hide');
};
$scope.declineUR = function () {
$scope.config.options.urAccepted = -1;
if ($scope.config.options.urAccepted === 0) {
$scope.config.options.urAccepted = -1;
}
$scope.config.options.urSeen = $scope.system.urVersionMax;
$scope.saveConfig();
$('#ur').modal('hide');
};
@@ -1682,6 +1768,31 @@ angular.module('syncthing.core')
$scope.reportPreview = true;
};
$scope.refreshReportDataPreview = function () {
$scope.reportDataPreview = '';
if (!$scope.reportDataPreviewVersion) {
return;
}
var version = parseInt($scope.reportDataPreviewVersion);
if ($scope.reportDataPreviewDiff && version > 2) {
$q.all([
$http.get(urlbase + '/svc/report?version=' + version),
$http.get(urlbase + '/svc/report?version=' + (version-1)),
]).then(function (responses) {
var newReport = responses[0].data;
var oldReport = responses[1].data;
angular.forEach(oldReport, function(_, key) {
delete newReport[key];
});
$scope.reportDataPreview = newReport;
});
} else {
$http.get(urlbase + '/svc/report?version=' + version).success(function (data) {
$scope.reportDataPreview = data;
}).error($scope.emitHTTPError);
}
};
$scope.rescanAllFolders = function () {
$http.post(urlbase + "/db/scan");
};

View File

@@ -0,0 +1,27 @@
angular.module('syncthing.core')
.filter('uncamel', function () {
return function (input) {
input = input.replace(/(.)([A-Z][a-z]+)/g, '$1 $2').replace(/([a-z0-9])([A-Z])/g, '$1 $2');
var parts = input.split(' ');
var lastPart = parts.splice(-1)[0];
switch (lastPart) {
case "S":
parts.push('(seconds)');
break;
case "M":
parts.push('(minutes)');
break;
case "H":
parts.push('(hours)');
break;
case "Ms":
parts.push('(milliseconds)');
break;
default:
parts.push(lastPart);
break;
}
input = parts.join(' ');
return input.charAt(0).toUpperCase() + input.slice(1);
};
});

View File

@@ -1,5 +1,5 @@
<div class="dev-top-bar" id="dev-top-bar" style="display: none">
<link href="assets/css/dev.css" rel="stylesheet">
<link href="assets/css/dev.css" rel="stylesheet"/>
<div class="row">
<div class="col-xs-4"><b>DEV</b></div>
<div id="log" class="col-xs-8">

View File

@@ -3,22 +3,30 @@
<form role="form" name="deviceEditor">
<div class="form-group" ng-class="{'has-error': deviceEditor.deviceID.$invalid && deviceEditor.deviceID.$dirty}" ng-init="loadFormIntoScope(deviceEditor)">
<label translate for="deviceID">Device ID</label>
<input ng-if="!editingExisting" name="deviceID" id="deviceID" class="form-control text-monospace" type="text" ng-model="currentDevice.deviceID" required valid-deviceid list="discovery-list" />
<datalist id="discovery-list" ng-if="!editingExisting">
<option ng-repeat="(id, data) in discovery" value="{{id}}" />
</datalist>
<div ng-if="!editingExisting">
<input name="deviceID" id="deviceID" class="form-control text-monospace" type="text" ng-model="currentDevice.deviceID" required="" valid-deviceid list="discovery-list" aria-required="true"/>
<datalist id="discovery-list">
<option ng-repeat="id in discovery" value="{{id}}" />
</datalist>
<p class="help-block" ng-if="discovery">
<span translate>You can also select one of these nearby devices:</span>
<ul>
<li ng-repeat="id in discovery"><a ng-click="currentDevice.deviceID = id">{{id}}</a></li>
</ul>
</p>
<p class="help-block">
<span translate ng-if="deviceEditor.deviceID.$valid || deviceEditor.deviceID.$pristine">The device ID to enter here can be found in the "Actions > Show ID" dialog on the other device. Spaces and dashes are optional (ignored).</span>
<span translate ng-show="deviceEditor.deviceID.$valid || deviceEditor.deviceID.$pristine">When adding a new device, keep in mind that this device must be added on the other side too.</span>
<span translate ng-if="deviceEditor.deviceID.$error.required && deviceEditor.deviceID.$dirty">The device ID cannot be blank.</span>
<span translate ng-if="deviceEditor.deviceID.$error.validDeviceid && deviceEditor.deviceID.$dirty">The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.</span>
<span translate ng-if="deviceEditor.deviceID.$error.unique && deviceEditor.deviceID.$dirty">A device with that ID is already added.</span>
</p>
</div>
<div ng-if="editingExisting" class="well well-sm text-monospace" select-on-click>{{currentDevice.deviceID}}</div>
<p class="help-block">
<span translate ng-if="deviceEditor.deviceID.$valid || deviceEditor.deviceID.$pristine">The device ID to enter here can be found in the "Actions > Show ID" dialog on the other device. Spaces and dashes are optional (ignored).</span>
<span translate ng-show="!editingExisting && (deviceEditor.deviceID.$valid || deviceEditor.deviceID.$pristine)">When adding a new device, keep in mind that this device must be added on the other side too.</span>
<span translate ng-if="deviceEditor.deviceID.$error.required && deviceEditor.deviceID.$dirty">The device ID cannot be blank.</span>
<span translate ng-if="deviceEditor.deviceID.$error.validDeviceid && deviceEditor.deviceID.$dirty">The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.</span>
<span translate ng-if="deviceEditor.deviceID.$error.unique && deviceEditor.deviceID.$dirty">A device with that ID is already added.</span>
</p>
</div>
<div class="form-group">
<label translate for="name">Device Name</label>
<input id="name" class="form-control" type="text" ng-model="currentDevice.name"></input>
<input id="name" class="form-control" type="text" ng-model="currentDevice.name" />
<p translate ng-if="currentDevice.deviceID == myID" class="help-block">Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.</p>
<p translate ng-if="currentDevice.deviceID != myID" class="help-block">Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.</p>
</div>

View File

@@ -2,21 +2,25 @@
<modal id="globalChanges" status="default" icon="{{'history'}}" heading="{{'Global Changes' | translate}}" large="yes" closeable="yes">
<div class="modal-body">
<table>
<tr>
<th translate>Device</th>
<th translate>Action</th>
<th translate>Type</th>
<th translate>Path</th>
<th translate>Time</th>
</tr>
<tr ng-repeat="changeEvent in globalChangeEvents">
<td ng-if="changeEvent.data.modifiedBy">{{friendlyNameFromShort(changeEvent.data.modifiedBy)}}</td>
<td ng-if="!changeEvent.data.modifiedBy"><span translate>Unknown</span></td>
<td>{{changeEvent.data.action}}</td>
<td>{{changeEvent.data.type}}</td>
<td class="globalChanges-path-col">{{changeEvent.data.path}}</td>
<td class="globalChanges-time-col">{{changeEvent.time | date:"yyyy-MM-dd HH:mm:ss"}}</td>
</tr>
<thead>
<tr>
<th translate>Device</th>
<th translate>Action</th>
<th translate>Type</th>
<th translate>Path</th>
<th translate>Time</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="changeEvent in globalChangeEvents">
<td ng-if="changeEvent.data.modifiedBy">{{friendlyNameFromShort(changeEvent.data.modifiedBy)}}</td>
<td ng-if="!changeEvent.data.modifiedBy"><span translate>Unknown</span></td>
<td>{{changeEvent.data.action}}</td>
<td>{{changeEvent.data.type}}</td>
<td class="globalChanges-path-col">{{changeEvent.data.path}}</td>
<td class="globalChanges-time-col">{{changeEvent.time | date:"yyyy-MM-dd HH:mm:ss"}}</td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">

View File

@@ -1,7 +1,7 @@
<modal id="idqr" status="info" icon="qrcode" heading="{{'Device Identification' | translate}} - {{deviceName(currentDevice)}}" large="yes" closeable="yes">
<div class="modal-body">
<div class="well well-sm text-monospace text-center" select-on-click>{{currentDevice.deviceID}}</div>
<img ng-if="currentDevice.deviceID" class="center-block img-thumbnail" ng-src="qr/?text={{currentDevice.deviceID}}"/>
<img ng-if="currentDevice.deviceID" class="center-block img-thumbnail" ng-src="qr/?text={{currentDevice.deviceID}}" alt="qr code"/>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">

View File

@@ -12,7 +12,7 @@
</div>
<div class="form-group" ng-class="{'has-error': folderEditor.folderID.$invalid && folderEditor.folderID.$dirty}">
<label for="folderID"><span translate>Folder ID</span></label>
<input name="folderID" ng-readonly="editingExisting || (!editingExisting && currentFolder.viewFlags.importFromOtherDevice)" id="folderID" class="form-control" type="text" ng-model="currentFolder.id" required unique-folder value="{{currentFolder.id}}"/>
<input name="folderID" ng-readonly="editingExisting || (!editingExisting && currentFolder.viewFlags.importFromOtherDevice)" id="folderID" class="form-control" type="text" ng-model="currentFolder.id" required="" aria-required="true" unique-folder value="{{currentFolder.id}}"/>
<p class="help-block">
<span translate ng-if="folderEditor.folderID.$valid || folderEditor.folderID.$pristine">Required identifier for the folder. Must be the same on all cluster devices.</span>
<span translate ng-if="folderEditor.folderID.$error.uniqueFolder">The folder ID must be unique.</span>
@@ -21,17 +21,17 @@
</div>
<div class="form-group" ng-class="{'has-error': folderEditor.folderPath.$invalid && folderEditor.folderPath.$dirty}">
<label translate for="folderPath">Folder Path</label>
<input name="folderPath" ng-readonly="editingExisting" id="folderPath" class="form-control" type="text" ng-model="currentFolder.path" list="directory-list" required path-is-sub-dir/>
<input name="folderPath" ng-readonly="editingExisting" id="folderPath" class="form-control" type="text" ng-model="currentFolder.path" list="directory-list" required="" aria-required="true" path-is-sub-dir/>
<datalist id="directory-list">
<option ng-repeat="directory in directoryList" value="{{ directory }}" />
</datalist>
<p class="help-block">
<span translate ng-if="folderEditor.folderPath.$valid || folderEditor.folderPath.$pristine">Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for</span> <code>{{system.tilde}}</code>.
<span ng-if="folderEditor.folderPath.$valid || folderEditor.folderPath.$pristine"><span translate>Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for</span> <code>{{system.tilde}}</code>.</br></span>
<span translate ng-if="folderEditor.folderPath.$error.required && folderEditor.folderPath.$dirty">The folder path cannot be blank.</span>
<span class="text-danger" translate translate-value-other-folder="{{otherFolder}}" ng-if="pathIsSubFolder && otherFolderLabel.length == 0">Warning, this path is a subdirectory of an existing folder "{%otherFolder%}".</span>
<span class="text-danger" translate translate-value-other-folder="{{otherFolder}}" translate-value-other-folder-label="{{otherFolderLabel}}" ng-if="pathIsSubFolder && otherFolderLabel.length != 0">Warning, this path is a subdirectory of an existing folder "{%otherFolderLabel%}" ({%otherFolder%}).</span>
<span class="text-danger" translate translate-value-other-folder="{{otherFolder}}" ng-if="pathIsParentFolder && otherFolderLabel.length == 0">Warning, this path is a parent directory of an existing folder "{%otherFolder%}".</span>
<span class="text-danger" translate translate-value-other-folder="{{otherFolder}}" translate-value-other-folder-label="{{otherFolderLabel}}" ng-if="pathIsParentFolder && otherFolderLabel.length != 0">Warning, this path is a parent directory of an existing folder "{%otherFolderLabel%}" ({%otherFolder%}).</span>
<span class="text-danger" translate translate-value-other-folder="{{folderPathErrors.otherID}}" ng-if="folderPathErrors.isSub && folderPathErrors.otherLabel.length == 0">Warning, this path is a subdirectory of an existing folder "{%otherFolder%}".</span>
<span class="text-danger" translate translate-value-other-folder="{{folderPathErrors.otherID}}" translate-value-other-folder-label="{{folderPathErrors.otherLabel}}" ng-if="folderPathErrors.isSub && folderPathErrors.otherLabel.length != 0">Warning, this path is a subdirectory of an existing folder "{%otherFolderLabel%}" ({%otherFolder%}).</span>
<span class="text-danger" translate translate-value-other-folder="{{folderPathErrors.otherID}}" ng-if="folderPathErrors.isParent && folderPathErrors.otherLabel.length == 0">Warning, this path is a parent directory of an existing folder "{%otherFolder%}".</span>
<span class="text-danger" translate translate-value-other-folder="{{folderPathErrors.otherID}}" translate-value-other-folder-label="{{folderPathErrors.otherLabel}}" ng-if="folderPathErrors.isParent && folderPathErrors.otherLabel.length != 0">Warning, this path is a parent directory of an existing folder "{%otherFolderLabel%}" ({%otherFolder%}).</span>
</p>
</div>
</div>
@@ -45,7 +45,7 @@
<div class="col-md-4" ng-repeat="device in otherDevices()">
<div class="checkbox">
<label>
<input type="checkbox" ng-model="currentFolder.selectedDevices[device.deviceID]"> {{deviceName(device)}}
<input type="checkbox" ng-model="currentFolder.selectedDevices[device.deviceID]"/> {{deviceName(device)}}
</label>
</div>
</div>
@@ -68,7 +68,7 @@
<div class="col-md-6">
<div class="form-group" ng-class="{'has-error': folderEditor.rescanIntervalS.$invalid && folderEditor.rescanIntervalS.$dirty}">
<label for="rescanIntervalS"><span translate>Rescan Interval</span> (s)</label><br/>
<input name="rescanIntervalS" id="rescanIntervalS" class="form-control" type="number" ng-model="currentFolder.rescanIntervalS" required min="0">
<input name="rescanIntervalS" id="rescanIntervalS" class="form-control" type="number" ng-model="currentFolder.rescanIntervalS" required="" aria-required="true" min="0"/>
<p class="help-block">
<span translate ng-if="!folderEditor.rescanIntervalS.$valid && folderEditor.rescanIntervalS.$dirty">The rescan interval must be a non-negative number of seconds.</span>
</p>
@@ -77,7 +77,7 @@
<div class="col-md-6 form-horizontal">
<div class="form-group" ng-class="{'has-error': folderEditor.minDiskFree.$invalid && folderEditor.minDiskFree.$dirty}">
<label class="col-xs-12" for="minDiskFree"><span translate>Minimum Free Disk Space</span></label><br/>
<div class="col-xs-9"><input name="minDiskFree" id="minDiskFree" class="form-control" type="number" ng-model="currentFolder.minDiskFree.value" required min="0" step="0.01"></div>
<div class="col-xs-9"><input name="minDiskFree" id="minDiskFree" class="form-control" type="number" ng-model="currentFolder.minDiskFree.value" required="" aria-required="true" min="0" step="0.01"/></div>
<div class="col-xs-3"><select class="col-sm-3 form-control" ng-model="currentFolder.minDiskFree.unit">
<option value="%">%</option>
<option value="kB">kB</option>
@@ -106,7 +106,7 @@
<div class="form-group">
<div class="checkbox">
<label>
<input type="checkbox" ng-model="currentFolder.ignorePerms"> <span translate>Ignore Permissions</span>
<input type="checkbox" ng-model="currentFolder.ignorePerms"/> <span translate>Ignore Permissions</span>
</label>
</div>
<p translate class="help-block">File permission bits are ignored when looking for changes. Use on FAT file systems.</p>
@@ -140,7 +140,7 @@
<p translate class="help-block">Files are moved to .stversions directory when replaced or deleted by Syncthing.</p>
<label translate for="trashcanClean">Clean out after</label>
<div class="input-group">
<input name="trashcanClean" id="trashcanClean" class="form-control text-right" type="number" ng-model="currentFolder.trashcanClean" required min="0">
<input name="trashcanClean" id="trashcanClean" class="form-control text-right" type="number" ng-model="currentFolder.trashcanClean" required="" aria-required="true" min="0"/>
<div class="input-group-addon" translate>days</div>
</div>
<p class="help-block">
@@ -152,7 +152,7 @@
<div class="form-group" ng-if="currentFolder.fileVersioningSelector=='simple'" ng-class="{'has-error': folderEditor.simpleKeep.$invalid && folderEditor.simpleKeep.$dirty}">
<p translate class="help-block">Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.</p>
<label translate for="simpleKeep">Keep Versions</label>
<input name="simpleKeep" id="simpleKeep" class="form-control" type="number" ng-model="currentFolder.simpleKeep" required min="1">
<input name="simpleKeep" id="simpleKeep" class="form-control" type="number" ng-model="currentFolder.simpleKeep" required="" aria-required="true" min="1"/>
<p class="help-block">
<span translate ng-if="folderEditor.simpleKeep.$valid || folderEditor.simpleKeep.$pristine">The number of old versions to keep, per file.</span>
<span translate ng-if="folderEditor.simpleKeep.$error.required && folderEditor.simpleKeep.$dirty">The number of versions must be a number and cannot be blank.</span>
@@ -163,7 +163,7 @@
<p class="help-block"><span translate>Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.</span> <span translate>Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.</span></p>
<p translate class="help-block">The following intervals are used: for the first hour a version is kept every 30 seconds, for the first day a version is kept every hour, for the first 30 days a version is kept every day, until the maximum age a version is kept every week.</p>
<label translate for="staggeredMaxAge">Maximum Age</label>
<input name="staggeredMaxAge" id="staggeredMaxAge" class="form-control" type="number" ng-model="currentFolder.staggeredMaxAge" required min="0">
<input name="staggeredMaxAge" id="staggeredMaxAge" class="form-control" type="number" ng-model="currentFolder.staggeredMaxAge" required="" aria-required="true" min="0"/>
<p class="help-block">
<span translate ng-if="folderEditor.staggeredMaxAge.$valid || folderEditor.staggeredMaxAge.$pristine">The maximum time to keep a version (in days, set to 0 to keep versions forever).</span>
<span translate ng-if="folderEditor.staggeredMaxAge.$error.required && folderEditor.staggeredMaxAge.$dirty">The maximum age must be a number and cannot be blank.</span>
@@ -172,15 +172,15 @@
</div>
<div class="form-group" ng-if="currentFolder.fileVersioningSelector == 'staggered'">
<label translate for="staggeredVersionsPath">Versions Path</label>
<input name="staggeredVersionsPath" id="staggeredVersionsPath" class="form-control" type="text" ng-model="currentFolder.staggeredVersionsPath">
<input name="staggeredVersionsPath" id="staggeredVersionsPath" class="form-control" type="text" ng-model="currentFolder.staggeredVersionsPath"/>
<p translate class="help-block">Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).</p>
</div>
<div class="form-group" ng-if="currentFolder.fileVersioningSelector=='external'" ng-class="{'has-error': folderEditor.externalCommand.$invalid && folderEditor.externalCommand.$dirty}">
<p translate class="help-block">An external command handles the versioning. It has to remove the file from the shared folder.</p>
<label translate for="externalCommand">Command</label>
<input name="externalCommand" id="externalCommand" class="form-control" type="text" ng-model="currentFolder.externalCommand" required>
<input name="externalCommand" id="externalCommand" class="form-control" type="text" ng-model="currentFolder.externalCommand" required="" aria-required="true" />
<p class="help-block">
<span translate ng-if="folderEditor.externalCommand.$valid || folderEditor.externalCommand.$pristine">The first command line parameter is the folder path and the second parameter is the relative path in the folder.</span>
<span translate ng-if="folderEditor.externalCommand.$valid || folderEditor.externalCommand.$pristine">See external versioning help for supported templated command line parameters.</span>
<span translate ng-if="folderEditor.externalCommand.$error.required && folderEditor.externalCommand.$dirty">The path cannot be blank.</span>
</p>
</div>

View File

@@ -7,6 +7,8 @@
<p class="small"><span translate>Quick guide to supported patterns</span> (<a href="https://docs.syncthing.net/users/ignoring.html" target="_blank" translate>full documentation</a>):</p>
<dl class="dl-horizontal dl-narrow small">
<dt><code>(?d)</code></dt> <dd><b><span translate>Prefix indicating that the file can be deleted if preventing directory removal</span></b></dd>
<dt><code>(?i)</code></dt> <dd><span translate>Prefix indicating that the pattern should be matched without case sensitivity</span></dd>
<dt><code>!</code></dt> <dd><span translate>Inversion of the given condition (i.e. do not exclude)</span></dd>
<dt><code>*</code></dt> <dd><span translate>Single level wildcard (matches within a directory only)</span></dd>
<dt><code>**</code></dt> <dd><span translate>Multi level wildcard (matches multiple directory levels)</span></dd>

View File

@@ -16,7 +16,7 @@
<div class="panel-body">
<form class="form-horizontal" role="form">
<div ng-repeat="(key, value) in advancedConfig.gui" ng-init="type = inputTypeFor(key, value)" ng-if="type != 'skip'" class="form-group">
<label for="guiInput{{$index}}" class="col-sm-4 control-label">{{key}}</label>
<label for="guiInput{{$index}}" class="col-sm-4 control-label">{{key | uncamel}}</label>
<div class="col-sm-8">
<input ng-if="inputTypeFor(key, value) == 'list'" id="optionsInput{{$index}}" class="form-control" type="text" ng-model="advancedConfig.gui[key]" ng-list/>
<input ng-if="inputTypeFor(key, value) != 'list'" id="optionsInput{{$index}}" class="form-control" type="{{inputTypeFor(key, value)}}" ng-model="advancedConfig.gui[key]" />
@@ -35,7 +35,7 @@
<div class="panel-body">
<form class="form-horizontal" role="form">
<div ng-repeat="(key, value) in advancedConfig.options" ng-if="inputTypeFor(key, value) != 'skip'" class="form-group">
<label for="optionsInput{{$index}}" class="col-sm-4 control-label">{{key}}</label>
<label for="optionsInput{{$index}}" class="col-sm-4 control-label">{{key | uncamel}}</label>
<div class="col-sm-8">
<input ng-if="inputTypeFor(key, value) == 'list'" id="optionsInput{{$index}}" class="form-control" type="text" ng-model="advancedConfig.options[key]" ng-list/>
<input ng-if="inputTypeFor(key, value) != 'list'" id="optionsInput{{$index}}" class="form-control" type="{{inputTypeFor(key, value)}}" ng-model="advancedConfig.options[key]" />
@@ -59,7 +59,7 @@
<div class="panel-body">
<form class="form-horizontal" role="form">
<div ng-repeat="(key, value) in folder" ng-if="inputTypeFor(key, value) != 'skip'" class="form-group">
<label for="folder{{$index}}Input{{$index}}" class="col-sm-4 control-label">{{key}}</label>
<label for="folder{{$index}}Input{{$index}}" class="col-sm-4 control-label">{{key | uncamel}}</label>
<div class="col-sm-8">
<input ng-if="inputTypeFor(key, value) == 'list'" id="optionsInput{{$index}}" class="form-control" type="text" ng-model="folder[key]" ng-list/>
<input ng-if="inputTypeFor(key, value) != 'list'" id="optionsInput{{$index}}" class="form-control" type="{{inputTypeFor(key, value)}}" ng-model="folder[key]" />
@@ -80,7 +80,7 @@
<div class="panel-body">
<form class="form-horizontal" role="form">
<div ng-repeat="(key, value) in device" ng-if="inputTypeFor(key, value) != 'skip'" class="form-group">
<label for="device{{$index}}Input{{$index}}" class="col-sm-4 control-label">{{key}}</label>
<label for="device{{$index}}Input{{$index}}" class="col-sm-4 control-label">{{key | uncamel}}</label>
<div class="col-sm-8">
<input ng-if="inputTypeFor(key, value) == 'list'" id="optionsInput{{$index}}" class="form-control" type="text" ng-model="device[key]" ng-list/>
<input ng-if="inputTypeFor(key, value) != 'list'" id="optionsInput{{$index}}" class="form-control" type="{{inputTypeFor(key, value)}}" ng-model="device[key]" />

View File

@@ -6,18 +6,18 @@
<div class="col-md-6">
<div class="form-group">
<label translate for="DeviceName">Device Name</label>
<input id="DeviceName" class="form-control" type="text" ng-model="tmpOptions.deviceName">
<input id="DeviceName" class="form-control" type="text" ng-model="tmpOptions.deviceName"/>
</div>
<div class="form-group">
<label translate for="ListenAddressesStr">Sync Protocol Listen Addresses</label>&emsp;<a href="https://docs.syncthing.net/users/config.html#listen-addresses" target="_blank"><span class="fa fa-fw fa-book"></span>&nbsp;<span translate>Help</span></a>
<input id="ListenAddressesStr" class="form-control" type="text" ng-model="tmpOptions._listenAddressesStr">
<input id="ListenAddressesStr" class="form-control" type="text" ng-model="tmpOptions._listenAddressesStr"/>
</div>
<div class="form-group" ng-class="{'has-error': settingsEditor.MaxRecvKbps.$invalid && settingsEditor.MaxRecvKbps.$dirty}">
<label translate for="MaxRecvKbps">Incoming Rate Limit (KiB/s)</label>
<input id="MaxRecvKbps" name="MaxRecvKbps" class="form-control" type="number" ng-model="tmpOptions.maxRecvKbps" min="0">
<input id="MaxRecvKbps" name="MaxRecvKbps" class="form-control" type="number" ng-model="tmpOptions.maxRecvKbps" min="0"/>
<p class="help-block">
<span translate ng-if="settingsEditor.MaxRecvKbps.$error.min && settingsEditor.MaxRecvKbps.$dirty">The rate limit must be a non-negative number (0: no limit)</span>
</p>
@@ -25,7 +25,7 @@
<div class="form-group" ng-class="{'has-error': settingsEditor.MaxSendKbps.$invalid && settingsEditor.MaxSendKbps.$dirty}">
<label translate for="MaxSendKbps">Outgoing Rate Limit (KiB/s)</label>
<input id="MaxSendKbps" name="MaxSendKbps" class="form-control" type="number" ng-model="tmpOptions.maxSendKbps" min="0">
<input id="MaxSendKbps" name="MaxSendKbps" class="form-control" type="number" ng-model="tmpOptions.maxSendKbps" min="0"/>
<p class="help-block">
<span translate ng-if="settingsEditor.MaxSendKbps.$error.min && settingsEditor.MaxSendKbps.$dirty">The rate limit must be a non-negative number (0: no limit)</span>
</p>
@@ -36,7 +36,7 @@
<div class="form-group">
<div class="checkbox">
<label>
<input id="NATEnabled" type="checkbox" ng-model="tmpOptions.natEnabled"> <span translate>Enable NAT traversal</span>
<input id="NATEnabled" type="checkbox" ng-model="tmpOptions.natEnabled"/> <span translate>Enable NAT traversal</span>
</label>
</div>
</div>
@@ -45,7 +45,7 @@
<div class="form-group">
<div class="checkbox">
<label>
<input id="LocalAnnEnabled" type="checkbox" ng-model="tmpOptions.localAnnounceEnabled"> <span translate>Local Discovery</span>
<input id="LocalAnnEnabled" type="checkbox" ng-model="tmpOptions.localAnnounceEnabled"/> <span translate>Local Discovery</span>
</label>
</div>
</div>
@@ -57,7 +57,7 @@
<div class="form-group">
<div class="checkbox">
<label>
<input id="GlobalAnnEnabled" type="checkbox" ng-model="tmpOptions.globalAnnounceEnabled"> <span translate>Global Discovery</span>
<input id="GlobalAnnEnabled" type="checkbox" ng-model="tmpOptions.globalAnnounceEnabled"/> <span translate>Global Discovery</span>
</label>
</div>
</div>
@@ -66,7 +66,7 @@
<div class="form-group">
<div class="checkbox">
<label>
<input id="RelaysEnabled" type="checkbox" ng-model="tmpOptions.relaysEnabled"> <span translate>Enable Relaying</span>
<input id="RelaysEnabled" type="checkbox" ng-model="tmpOptions.relaysEnabled"/> <span translate>Enable Relaying</span>
</label>
</div>
</div>
@@ -76,13 +76,13 @@
<div class="clearfix"></div>
<div class="form-group">
<label translate for="GlobalAnnServersStr">Global Discovery Servers</label>
<input ng-disabled="!tmpOptions.globalAnnounceEnabled" id="GlobalAnnServersStr" class="form-control" type="text" ng-model="tmpOptions._globalAnnounceServersStr">
<input ng-disabled="!tmpOptions.globalAnnounceEnabled" id="GlobalAnnServersStr" class="form-control" type="text" ng-model="tmpOptions._globalAnnounceServersStr"/>
</div>
<div class="form-horizontal">
<div class="form-group" ng-class="{'has-error': settingsEditor.minHomeDiskFree.$invalid && settingsEditor.minHomeDiskFree.$dirty}">
<label class="col-xs-12" for="minHomeDiskFree"><span translate>Minimum Free Disk Space</span></label><br/>
<div class="col-xs-9"><input name="minHomeDiskFree" id="minHomeDiskFree" class="form-control" type="number" ng-model="tmpOptions.minHomeDiskFree.value" required min="0" step="0.01"></div>
<div class="col-xs-9"><input name="minHomeDiskFree" id="minHomeDiskFree" class="form-control" type="number" ng-model="tmpOptions.minHomeDiskFree.value" required="" aria-required="true" min="0" step="0.01"/></div>
<div class="col-xs-3"><select class="col-sm-3 form-control" ng-model="tmpOptions.minHomeDiskFree.unit">
<option value="%">%</option>
<option value="kB">kB</option>
@@ -102,30 +102,30 @@
<div class="col-md-6">
<div class="form-group" ng-class="{'has-error': settingsEditor.Address.$invalid && settingsEditor.Address.$dirty}">
<label translate for="Address">GUI Listen Address</label>&emsp;<a href="https://docs.syncthing.net/users/guilisten.html" target="_blank"><span class="fa fa-fw fa-book"></span>&nbsp;<span translate>Help</span></a>
<input id="Address" name="Address" class="form-control" type="text" ng-model="tmpGUI.address" ng-pattern="/.*:0*((102[4-9])|(10[3-9][0-9])|(1[1-9][0-9][0-9])|([2-9][0-9][0-9][0-9])|([1-6]\d{4}))$/">
<input id="Address" name="Address" class="form-control" type="text" ng-model="tmpGUI.address" ng-pattern="/.*:0*((102[4-9])|(10[3-9][0-9])|(1[1-9][0-9][0-9])|([2-9][0-9][0-9][0-9])|([1-6]\d{4}))$/"/>
<p class="help-block" ng-show="settingsEditor.Address.$invalid" translate>
Enter a non-privileged port number (1024 - 65535).
</p>
</div>
<div class="form-group">
<label translate for="User">GUI Authentication User</label>
<input id="User" class="form-control" type="text" ng-model="tmpGUI.user">
<input id="User" class="form-control" type="text" ng-model="tmpGUI.user"/>
</div>
<div class="form-group">
<label translate for="Password">GUI Authentication Password</label>
<input id="Password" class="form-control" type="password" ng-model="tmpGUI.password" ng-trim="false">
<input id="Password" class="form-control" type="password" ng-model="tmpGUI.password" ng-trim="false"/>
</div>
<div class="form-group">
<div class="checkbox">
<label>
<input id="UseTLS" type="checkbox" ng-model="tmpGUI.useTLS"> <span translate>Use HTTPS for GUI</span>
<input id="UseTLS" type="checkbox" ng-model="tmpGUI.useTLS"/> <span translate>Use HTTPS for GUI</span>
</label>
</div>
</div>
<div class="form-group">
<div class="checkbox">
<label>
<input id="StartBrowser" type="checkbox" ng-model="tmpOptions.startBrowser"> <span translate>Start Browser</span>
<input id="StartBrowser" type="checkbox" ng-model="tmpOptions.startBrowser"/> <span translate>Start Browser</span>
</label>
</div>
</div>
@@ -139,10 +139,14 @@
</div>
<div class="form-group">
<div class="checkbox" ng-if="tmpOptions.upgrades != 'candidate'">
<label>
<input id="UREnabled" type="checkbox" ng-model="tmpOptions.urEnabled"> <span translate>Anonymous Usage Reporting</span> (<a href="" translate data-toggle="modal" data-target="#urPreview">Preview</a>)
</label>
<div ng-if="tmpOptions.upgrades != 'candidate'">
<label translate for="urVersion">Anonymous Usage Reporting</label> (<a href="" translate data-toggle="modal" data-target="#urPreview">Preview</a>)
<select class="form-control" id="urVersion" ng-model="tmpOptions._urAcceptedStr">
<option ng-repeat="n in urVersions()" value="{{n}}">{{'Version' | translate}} {{n}}</option>
<!-- 1 does not exist, as we did not support incremental formats back then. -->
<option value="0" translate>Undecided (will prompt)</option>
<option value="-1" translate>Disabled</option>
</select>
</div>
<p class="help-block" ng-if="tmpOptions.upgrades == 'candidate'">
<span translate>Usage reporting is always enabled for candidate releases.</span> (<a href="" translate data-toggle="modal" data-target="#urPreview">Preview</a>)

View File

@@ -14,7 +14,7 @@
<ul class="pagination pull-right">
<li ng-repeat="option in [10, 25, 50]" ng-class="{ active: failedPageSize == option }">
<a href="#" ng-click="failedChangePageSize(option)">{{option}}</a>
<li>
</li>
</ul>
<div class="clearfix"></div>
</div>

View File

@@ -60,7 +60,7 @@
<ul class="pagination pull-right">
<li ng-repeat="option in [10, 25, 50]" ng-class="{ active: neededPageSize == option }">
<a href="#" ng-click="neededChangePageSize(option)">{{option}}</a>
<li>
</li>
</ul>
<div class="clearfix"></div>
</div>

View File

@@ -1,8 +1,13 @@
<modal id="ur" status="info" icon="bar-chart" heading="{{'Allow Anonymous Usage Reporting?' | translate}}" large="yes" closeable="no">
<div class="modal-body">
<p translate>The encrypted usage report is sent daily. It is used to track common platforms, folder sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.</p>
<p translate>The aggregated statistics are publicly available at the URL below.</p>
<p><a href="https://data.syncthing.net/" target="_blank">https://data.syncthing.net/</a></p>
<div ng-if="config.options.urAccepted > 0 && config.options.urAccepted < system.urVersionMax">
<p translate>Anonymous usage report format has changed. Would you like to move to the new format?</p>
</div>
<div ng-if="!(config.options.urAccepted > 0 && config.options.urAccepted < system.urVersionMax)">
<p translate>The encrypted usage report is sent daily. It is used to track common platforms, folder sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.</p>
<p translate>The aggregated statistics are publicly available at the URL below.</p>
<p><a href="https://data.syncthing.net/" target="_blank">https://data.syncthing.net/</a></p>
</div>
<button type="button" class="btn btn-default btn-sm" ng-click="showReportPreview()" ng-show="!reportPreview">
<span class="fa fa-file-text-o"></span>&nbsp;<span translate>Preview Usage Report</span>
</button>

View File

@@ -5,8 +5,20 @@
</p>
<p translate>The aggregated statistics are publicly available at the URL below.</p>
<p><a href="https://data.syncthing.net/" target="_blank">https://data.syncthing.net/</a></p>
<label translate>Version</label>
<select id="urPreviewVersion" class="form-control" ng-model="$parent.$parent.reportDataPreviewVersion" ng-change="refreshReportDataPreview()" >
<option selected value translate>Select a version</option>
<option ng-repeat="n in urVersions()" value="{{n}}">{{'Version' | translate}} {{n}}</option>
</select>
<div class="checkbox" ng-if="$parent.$parent.reportDataPreviewVersion > 2">
<label>
<input type="checkbox" ng-model="$parent.$parent.$parent.reportDataPreviewDiff" ng-change="refreshReportDataPreview()"/>
<span translate>Show diff with previous version</span>
</label>
</div>
<hr>
<form>
<textarea class="form-control" rows="20">{{reportData | json}}</textarea>
<textarea class="form-control" rows="20" ng-if="reportDataPreview">{{reportDataPreview | json}}</textarea>
</form>
</div>
<div class="modal-footer">

View File

@@ -25,6 +25,9 @@ platforms=(
darwin-amd64 darwin-386
)
# Mac builds always require cgo
export CGO_ENABLED=1
echo Building
for plat in "${platforms[@]}"; do
echo Building "$plat"

View File

@@ -65,7 +65,30 @@ function test {
function testWithCoverage {
echo Test with coverage
CGO_ENABLED=1 ./build.sh test-cov
CGO_ENABLED=1
echo "mode: set" > coverage.out
fail=0
# For every package in the repo
for dir in $(go list ./lib/... ./cmd/...) ; do
# run the tests
GOPATH="$(pwd)/Godeps/_workspace:$GOPATH" go test -coverprofile=profile.out $dir
if [ -f profile.out ] ; then
# and if there was test output, append it to coverage.out
grep -v "mode: " profile.out >> coverage.out
rm profile.out
fi
done
gocov convert coverage.out | gocov-xml > coverage.xml
# This is usually run from within Jenkins. If it is, we need to
# tweak the paths in coverage.xml so cobertura finds the
# source.
if [[ "${WORKSPACE:-default}" != "default" ]] ; then
sed "s#$WORKSPACE##g" < coverage.xml > coverage.xml.new && mv coverage.xml.new coverage.xml
fi
notCovered=$(egrep -c '\s0$' coverage.out)
total=$(wc -l coverage.out | awk '{print $1}')
@@ -73,6 +96,8 @@ function testWithCoverage {
echo "$coverPct" > "coverage.txt"
echo "Test coverage is $coverPct%%"
echo
CGO_ENABLED=0 # reset to before
}
function buildSource {

View File

@@ -137,17 +137,11 @@ func (w *broadcastWriter) Serve() {
return
}
if err, ok := err.(net.Error); ok && err.Temporary() {
// A transient error. Lets hope for better luck in the future.
l.Debugln(err)
continue
}
if err != nil {
// Some other error that we don't expect. Bail and retry.
// Some other error that we don't expect. Debug and continue.
l.Debugln(err)
w.setError(err)
return
continue
}
l.Debugf("sent %d bytes to %s", len(bs), dst)

View File

@@ -17,10 +17,13 @@ import (
"net/url"
"os"
"path"
"path/filepath"
"runtime"
"sort"
"strconv"
"strings"
"github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/protocol"
"github.com/syncthing/syncthing/lib/rand"
"github.com/syncthing/syncthing/lib/upgrade"
@@ -29,7 +32,7 @@ import (
const (
OldestHandledVersion = 10
CurrentVersion = 20
CurrentVersion = 25
MaxRescanIntervalS = 365 * 24 * 60 * 60
)
@@ -45,11 +48,8 @@ var (
DefaultListenAddresses = []string{
util.Address("tcp", net.JoinHostPort("0.0.0.0", strconv.Itoa(DefaultTCPPort))),
"dynamic+https://relays.syncthing.net/endpoint",
util.Address("kcp", net.JoinHostPort("0.0.0.0", strconv.Itoa(DefaultKCPPort))),
}
// DefaultKCPListenAddress gets added to the default listen address set
// when the appropriate feature flag is set. Feature flag stuff to be
// removed later.
DefaultKCPListenAddress = util.Address("kcp", net.JoinHostPort("0.0.0.0", strconv.Itoa(DefaultKCPPort)))
// DefaultDiscoveryServersV4 should be substituted when the configuration
// contains <globalAnnounceServer>default-v4</globalAnnounceServer>.
DefaultDiscoveryServersV4 = []string{
@@ -155,9 +155,11 @@ type Configuration struct {
GUI GUIConfiguration `xml:"gui" json:"gui"`
Options OptionsConfiguration `xml:"options" json:"options"`
IgnoredDevices []protocol.DeviceID `xml:"ignoredDevice" json:"ignoredDevices"`
IgnoredFolders []string `xml:"ignoredFolder" json:"ignoredFolders"`
XMLName xml.Name `xml:"configuration" json:"-"`
OriginalVersion int `xml:"-" json:"-"` // The version we read from disk, before any conversion
MyID protocol.DeviceID `xml:"-" json:"-"` // Provided by the instantiator.
OriginalVersion int `xml:"-" json:"-"` // The version we read from disk, before any conversion
}
func (cfg Configuration) Copy() Configuration {
@@ -181,6 +183,10 @@ func (cfg Configuration) Copy() Configuration {
newCfg.IgnoredDevices = make([]protocol.DeviceID, len(cfg.IgnoredDevices))
copy(newCfg.IgnoredDevices, cfg.IgnoredDevices)
// FolderConfiguraion.ID is type string
newCfg.IgnoredFolders = make([]string, len(cfg.IgnoredFolders))
copy(newCfg.IgnoredFolders, cfg.IgnoredFolders)
return newCfg
}
@@ -198,6 +204,8 @@ func (cfg *Configuration) WriteXML(w io.Writer) error {
func (cfg *Configuration) prepare(myID protocol.DeviceID) error {
var myName string
cfg.MyID = myID
// Ensure this device is present in the config
for _, device := range cfg.Devices {
if device.DeviceID == myID {
@@ -235,6 +243,9 @@ func (cfg *Configuration) clean() error {
if cfg.IgnoredDevices == nil {
cfg.IgnoredDevices = []protocol.DeviceID{}
}
if cfg.IgnoredFolders == nil {
cfg.IgnoredFolders = []string{}
}
if cfg.Options.AlwaysLocalNets == nil {
cfg.Options.AlwaysLocalNets = []string{}
}
@@ -257,6 +268,14 @@ func (cfg *Configuration) clean() error {
seenFolders[folder.ID] = struct{}{}
}
// Remove ignored folders that are anyway part of the configuration.
for i := 0; i < len(cfg.IgnoredFolders); i++ {
if _, ok := seenFolders[cfg.IgnoredFolders[i]]; ok {
cfg.IgnoredFolders = append(cfg.IgnoredFolders[:i], cfg.IgnoredFolders[i+1:]...)
i-- // IgnoredFolders[i] now points to something else, so needs to be rechecked
}
}
cfg.Options.ListenAddresses = util.UniqueStrings(cfg.Options.ListenAddresses)
cfg.Options.GlobalAnnServers = util.UniqueStrings(cfg.Options.GlobalAnnServers)
@@ -295,6 +314,21 @@ func (cfg *Configuration) clean() error {
if cfg.Version == 19 {
convertV19V20(cfg)
}
if cfg.Version == 20 {
convertV20V21(cfg)
}
if cfg.Version == 21 {
convertV21V22(cfg)
}
if cfg.Version == 22 {
convertV22V23(cfg)
}
if cfg.Version == 23 {
convertV23V24(cfg)
}
if cfg.Version == 24 {
convertV24V25(cfg)
}
// Build a list of available devices
existingDevices := make(map[protocol.DeviceID]bool)
@@ -344,6 +378,87 @@ func (cfg *Configuration) clean() error {
return nil
}
func convertV24V25(cfg *Configuration) {
for i := range cfg.Folders {
cfg.Folders[i].FSWatcherDelayS = 10
}
cfg.Version = 25
}
func convertV23V24(cfg *Configuration) {
cfg.Options.URSeen = 2
cfg.Version = 24
}
func convertV22V23(cfg *Configuration) {
permBits := fs.FileMode(0777)
if runtime.GOOS == "windows" {
// Windows has no umask so we must chose a safer set of bits to
// begin with.
permBits = 0700
}
for i := range cfg.Folders {
fs := cfg.Folders[i].Filesystem()
// Invalid config posted, or tests.
if fs == nil {
continue
}
if stat, err := fs.Stat(".stfolder"); err == nil && !stat.IsDir() {
err = fs.Remove(".stfolder")
if err == nil {
err = fs.Mkdir(".stfolder", permBits)
fs.Hide(".stfolder") // ignore error
}
if err != nil {
l.Infoln("Failed to upgrade folder marker:", err)
}
}
}
cfg.Version = 23
}
func convertV21V22(cfg *Configuration) {
for i := range cfg.Folders {
cfg.Folders[i].FilesystemType = fs.FilesystemTypeBasic
// Migrate to templated external versioner commands
if cfg.Folders[i].Versioning.Type == "external" {
cfg.Folders[i].Versioning.Params["command"] += " %FOLDER_PATH% %FILE_PATH%"
}
}
cfg.Version = 22
}
func convertV20V21(cfg *Configuration) {
for _, folder := range cfg.Folders {
if folder.FilesystemType != fs.FilesystemTypeBasic {
continue
}
switch folder.Versioning.Type {
case "simple", "trashcan":
// Clean out symlinks in the known place
cleanSymlinks(folder.Filesystem(), ".stversions")
case "staggered":
versionDir := folder.Versioning.Params["versionsPath"]
if versionDir == "" {
// default place
cleanSymlinks(folder.Filesystem(), ".stversions")
} else if filepath.IsAbs(versionDir) {
// absolute
cleanSymlinks(fs.NewFilesystem(fs.FilesystemTypeBasic, versionDir), ".")
} else {
// relative to folder
cleanSymlinks(folder.Filesystem(), versionDir)
}
}
}
cfg.Version = 21
}
func convertV19V20(cfg *Configuration) {
cfg.Options.MinHomeDiskFree = Size{Value: cfg.Options.DeprecatedMinHomeDiskFreePct, Unit: "%"}
cfg.Options.DeprecatedMinHomeDiskFreePct = 0
@@ -380,9 +495,7 @@ func convertV17V18(cfg *Configuration) {
}
func convertV16V17(cfg *Configuration) {
for i := range cfg.Folders {
cfg.Folders[i].Fsync = true
}
// Fsync = true removed
cfg.Version = 17
}
@@ -621,3 +734,23 @@ loop:
}
return devices[0:count]
}
func cleanSymlinks(filesystem fs.Filesystem, dir string) {
if runtime.GOOS == "windows" {
// We don't do symlinks on Windows. Additionally, there may
// be things that look like symlinks that are not, which we
// should leave alone. Deduplicated files, for example.
return
}
filesystem.Walk(dir, func(path string, info fs.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsSymlink() {
l.Infoln("Removing incorrectly versioned symlink", path)
filesystem.Remove(path)
return fs.SkipDir
}
return nil
})
}

View File

@@ -19,6 +19,7 @@ import (
"testing"
"github.com/d4l3k/messagediff"
"github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/protocol"
)
@@ -67,12 +68,12 @@ func TestDefaultValues(t *testing.T) {
WeakHashSelectionMethod: WeakHashAuto,
StunKeepaliveS: 24,
StunServers: []string{"default"},
DefaultKCPEnabled: false,
KCPCongestionControl: true,
KCPReceiveWindowSize: 128,
KCPSendWindowSize: 128,
KCPUpdateIntervalMs: 25,
KCPFastResend: false,
DefaultFolderPath: "~",
}
cfg := New(device1)
@@ -84,7 +85,7 @@ func TestDefaultValues(t *testing.T) {
func TestDeviceConfig(t *testing.T) {
for i := OldestHandledVersion; i <= CurrentVersion; i++ {
os.Remove("testdata/.stfolder")
os.RemoveAll("testdata/.stfolder")
wr, err := Load(fmt.Sprintf("testdata/v%d.xml", i), device1)
if err != nil {
t.Fatal(err)
@@ -101,18 +102,20 @@ func TestDeviceConfig(t *testing.T) {
expectedFolders := []FolderConfiguration{
{
ID: "test",
RawPath: "testdata",
Devices: []FolderDeviceConfiguration{{DeviceID: device1}, {DeviceID: device4}},
Type: FolderTypeSendOnly,
RescanIntervalS: 600,
Copiers: 0,
Pullers: 0,
Hashers: 0,
AutoNormalize: true,
MinDiskFree: Size{1, "%"},
MaxConflicts: -1,
Fsync: true,
ID: "test",
FilesystemType: fs.FilesystemTypeBasic,
Path: "testdata",
Devices: []FolderDeviceConfiguration{{DeviceID: device1}, {DeviceID: device4}},
Type: FolderTypeSendOnly,
RescanIntervalS: 600,
FSWatcherEnabled: false,
FSWatcherDelayS: 10,
Copiers: 0,
Pullers: 0,
Hashers: 0,
AutoNormalize: true,
MinDiskFree: Size{1, "%"},
MaxConflicts: -1,
Versioning: VersioningConfiguration{
Params: map[string]string{},
},
@@ -120,15 +123,11 @@ func TestDeviceConfig(t *testing.T) {
},
}
// The cachedPath will have been resolved to an absolute path,
// The cachedFilesystem will have been resolved to an absolute path,
// depending on where the tests are running. Zero it out so we don't
// fail based on that.
for i := range cfg.Folders {
cfg.Folders[i].cachedPath = ""
}
if runtime.GOOS != "windows" {
expectedFolders[0].RawPath += string(filepath.Separator)
cfg.Folders[i].cachedFilesystem = nil
}
expectedDevices := []DeviceConfiguration{
@@ -202,6 +201,7 @@ func TestOverriddenValues(t *testing.T) {
ProgressUpdateIntervalS: 10,
LimitBandwidthInLan: true,
MinHomeDiskFree: Size{5.2, "%"},
URSeen: 2,
URURL: "https://localhost/newdata",
URInitialDelayS: 800,
URPostInsecurely: true,
@@ -215,12 +215,12 @@ func TestOverriddenValues(t *testing.T) {
WeakHashSelectionMethod: WeakHashNever,
StunKeepaliveS: 10,
StunServers: []string{"a.stun.com", "b.stun.com"},
DefaultKCPEnabled: true,
KCPCongestionControl: false,
KCPReceiveWindowSize: 1280,
KCPSendWindowSize: 1280,
KCPUpdateIntervalMs: 1000,
KCPFastResend: true,
DefaultFolderPath: "/media/syncthing",
}
os.Unsetenv("STNOUPGRADE")
@@ -375,16 +375,17 @@ func TestVersioningConfig(t *testing.T) {
}
func TestIssue1262(t *testing.T) {
if runtime.GOOS != "windows" {
t.Skipf("path gets converted to absolute as part of the filesystem initialization on linux")
}
cfg, err := Load("testdata/issue-1262.xml", device4)
if err != nil {
t.Fatal(err)
}
actual := cfg.Folders()["test"].RawPath
expected := "e:/"
if runtime.GOOS == "windows" {
expected = `e:\`
}
actual := cfg.Folders()["test"].Filesystem().URI()
expected := `e:\`
if actual != expected {
t.Errorf("%q != %q", actual, expected)
@@ -414,43 +415,12 @@ func TestIssue1750(t *testing.T) {
}
}
func TestWindowsPaths(t *testing.T) {
if runtime.GOOS != "windows" {
t.Skip("Not useful on non-Windows")
return
}
folder := FolderConfiguration{
RawPath: `e:\`,
}
expected := `\\?\e:\`
actual := folder.Path()
if actual != expected {
t.Errorf("%q != %q", actual, expected)
}
folder.RawPath = `\\192.0.2.22\network\share`
expected = folder.RawPath
actual = folder.Path()
if actual != expected {
t.Errorf("%q != %q", actual, expected)
}
folder.RawPath = `relative\path`
expected = folder.RawPath
actual = folder.Path()
if actual == expected || !strings.HasPrefix(actual, "\\\\?\\") {
t.Errorf("%q == %q, expected absolutification", actual, expected)
}
}
func TestFolderPath(t *testing.T) {
folder := FolderConfiguration{
RawPath: "~/tmp",
Path: "~/tmp",
}
realPath := folder.Path()
realPath := folder.Filesystem().URI()
if !filepath.IsAbs(realPath) {
t.Error(realPath, "should be absolute")
}
@@ -675,8 +645,8 @@ func TestEmptyFolderPaths(t *testing.T) {
t.Fatal(err)
}
folder := wrapper.Folders()["f1"]
if folder.Path() != "" {
t.Errorf("Expected %q to be empty", folder.Path())
if folder.cachedFilesystem != nil {
t.Errorf("Expected %q to be empty", folder.cachedFilesystem)
}
}
@@ -807,3 +777,34 @@ func TestSharesRemovedOnDeviceRemoval(t *testing.T) {
t.Error("Unexpected extra device")
}
}
func TestIssue4219(t *testing.T) {
// Adding a folder that was previously ignored should make it unignored.
r := bytes.NewReader([]byte(`{
"folders": [
{"id": "abcd123"}
],
"ignoredFolders": ["t1", "abcd123", "t2"]
}`))
cfg, err := ReadJSON(r, protocol.LocalDeviceID)
if err != nil {
t.Fatal(err)
}
if len(cfg.IgnoredFolders) != 2 {
t.Errorf("There should be two ignored folders, not %d", len(cfg.IgnoredFolders))
}
w := Wrap("/tmp/cfg", cfg)
if !w.IgnoredFolder("t1") {
t.Error("Folder t1 should be ignored")
}
if !w.IgnoredFolder("t2") {
t.Error("Folder t2 should be ignored")
}
if w.IgnoredFolder("abcd123") {
t.Error("Folder abcd123 should not be ignored")
}
}

View File

@@ -7,23 +7,29 @@
package config
import (
"errors"
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
"github.com/syncthing/syncthing/lib/osutil"
"github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/protocol"
)
var (
errPathMissing = errors.New("folder path missing")
errMarkerMissing = errors.New("folder marker missing")
)
type FolderConfiguration struct {
ID string `xml:"id,attr" json:"id"`
Label string `xml:"label,attr" json:"label"`
RawPath string `xml:"path,attr" json:"path"`
FilesystemType fs.FilesystemType `xml:"filesystemType" json:"filesystemType"`
Path string `xml:"path,attr" json:"path"`
Type FolderType `xml:"type,attr" json:"type"`
Devices []FolderDeviceConfiguration `xml:"device" json:"devices"`
RescanIntervalS int `xml:"rescanIntervalS,attr" json:"rescanIntervalS"`
FSWatcherEnabled bool `xml:"fsWatcherEnabled,attr" json:"fsWatcherEnabled"`
FSWatcherDelayS int `xml:"fsWatcherDelayS,attr" json:"fsWatcherDelayS"`
IgnorePerms bool `xml:"ignorePerms,attr" json:"ignorePerms"`
AutoNormalize bool `xml:"autoNormalize,attr" json:"autoNormalize"`
MinDiskFree Size `xml:"minDiskFree" json:"minDiskFree"`
@@ -39,11 +45,10 @@ type FolderConfiguration struct {
MaxConflicts int `xml:"maxConflicts" json:"maxConflicts"`
DisableSparseFiles bool `xml:"disableSparseFiles" json:"disableSparseFiles"`
DisableTempIndexes bool `xml:"disableTempIndexes" json:"disableTempIndexes"`
Fsync bool `xml:"fsync" json:"fsync"`
Paused bool `xml:"paused" json:"paused"`
WeakHashThresholdPct int `xml:"weakHashThresholdPct" json:"weakHashThresholdPct"` // Use weak hash if more than X percent of the file has changed. Set to -1 to always use weak hash.
cachedPath string
cachedFilesystem fs.Filesystem
DeprecatedReadOnly bool `xml:"ro,attr,omitempty" json:"-"`
DeprecatedMinDiskFreePct float64 `xml:"minDiskFreePct,omitempty" json:"-"`
@@ -54,10 +59,11 @@ type FolderDeviceConfiguration struct {
IntroducedBy protocol.DeviceID `xml:"introducedBy,attr" json:"introducedBy"`
}
func NewFolderConfiguration(id, path string) FolderConfiguration {
func NewFolderConfiguration(id string, fsType fs.FilesystemType, path string) FolderConfiguration {
f := FolderConfiguration{
ID: id,
RawPath: path,
ID: id,
FilesystemType: fsType,
Path: path,
}
f.prepare()
return f
@@ -71,53 +77,72 @@ func (f FolderConfiguration) Copy() FolderConfiguration {
return c
}
func (f FolderConfiguration) Path() string {
func (f FolderConfiguration) Filesystem() fs.Filesystem {
// This is intentionally not a pointer method, because things like
// cfg.Folders["default"].Path() should be valid.
if f.cachedPath == "" && f.RawPath != "" {
l.Infoln("bug: uncached path call (should only happen in tests)")
return f.cleanedPath()
// cfg.Folders["default"].Filesystem() should be valid.
if f.cachedFilesystem == nil && f.Path != "" {
l.Infoln("bug: uncached filesystem call (should only happen in tests)")
return fs.NewFilesystem(f.FilesystemType, f.Path)
}
return f.cachedPath
return f.cachedFilesystem
}
func (f *FolderConfiguration) CreateMarker() error {
if !f.HasMarker() {
marker := filepath.Join(f.Path(), ".stfolder")
fd, err := os.Create(marker)
if err != nil {
return err
}
fd.Close()
if err := osutil.SyncDir(filepath.Dir(marker)); err != nil {
l.Infof("fsync %q failed: %v", filepath.Dir(marker), err)
}
osutil.HideFile(marker)
if err := f.CheckPath(); err != errMarkerMissing {
return err
}
permBits := fs.FileMode(0777)
if runtime.GOOS == "windows" {
// Windows has no umask so we must chose a safer set of bits to
// begin with.
permBits = 0700
}
fs := f.Filesystem()
err := fs.Mkdir(".stfolder", permBits)
if err != nil {
return err
}
if dir, err := fs.Open("."); err != nil {
l.Debugln("folder marker: open . failed:", err)
} else if err := dir.Sync(); err != nil {
l.Debugln("folder marker: fsync . failed:", err)
}
fs.Hide(".stfolder")
return nil
}
// CheckPath returns nil if the folder root exists and contains the marker file
func (f *FolderConfiguration) CheckPath() error {
fi, err := f.Filesystem().Stat(".")
if err != nil || !fi.IsDir() {
return errPathMissing
}
_, err = f.Filesystem().Stat(".stfolder")
if err != nil {
return errMarkerMissing
}
return nil
}
func (f *FolderConfiguration) HasMarker() bool {
_, err := os.Stat(filepath.Join(f.Path(), ".stfolder"))
return err == nil
}
func (f *FolderConfiguration) CreateRoot() (err error) {
// Directory permission bits. Will be filtered down to something
// sane by umask on Unixes.
permBits := os.FileMode(0777)
permBits := fs.FileMode(0777)
if runtime.GOOS == "windows" {
// Windows has no umask so we must chose a safer set of bits to
// begin with.
permBits = 0700
}
if _, err = os.Stat(f.Path()); os.IsNotExist(err) {
if err = osutil.MkdirAll(f.Path(), permBits); err != nil {
l.Warnf("Creating directory for %v: %v",
f.Description(), err)
filesystem := f.Filesystem()
if _, err = filesystem.Stat("."); fs.IsNotExist(err) {
if err = filesystem.MkdirAll(".", permBits); err != nil {
l.Warnf("Creating directory for %v: %v", f.Description(), err)
}
}
@@ -140,30 +165,21 @@ func (f *FolderConfiguration) DeviceIDs() []protocol.DeviceID {
}
func (f *FolderConfiguration) prepare() {
if f.RawPath != "" {
// The reason it's done like this:
// C: -> C:\ -> C:\ (issue that this is trying to fix)
// C:\somedir -> C:\somedir\ -> C:\somedir
// C:\somedir\ -> C:\somedir\\ -> C:\somedir
// This way in the tests, we get away without OS specific separators
// in the test configs.
f.RawPath = filepath.Dir(f.RawPath + string(filepath.Separator))
// If we're not on Windows, we want the path to end with a slash to
// penetrate symlinks. On Windows, paths must not end with a slash.
if runtime.GOOS != "windows" && f.RawPath[len(f.RawPath)-1] != filepath.Separator {
f.RawPath = f.RawPath + string(filepath.Separator)
}
if f.Path != "" {
f.cachedFilesystem = fs.NewFilesystem(f.FilesystemType, f.Path)
}
f.cachedPath = f.cleanedPath()
if f.RescanIntervalS > MaxRescanIntervalS {
f.RescanIntervalS = MaxRescanIntervalS
} else if f.RescanIntervalS < 0 {
f.RescanIntervalS = 0
}
if f.FSWatcherDelayS <= 0 {
f.FSWatcherEnabled = false
f.FSWatcherDelayS = 10
}
if f.Versioning.Params == nil {
f.Versioning.Params = make(map[string]string)
}
@@ -173,43 +189,6 @@ func (f *FolderConfiguration) prepare() {
}
}
func (f *FolderConfiguration) cleanedPath() string {
if f.RawPath == "" {
return ""
}
cleaned := f.RawPath
// Attempt tilde expansion; leave unchanged in case of error
if path, err := osutil.ExpandTilde(cleaned); err == nil {
cleaned = path
}
// Attempt absolutification; leave unchanged in case of error
if !filepath.IsAbs(cleaned) {
// Abs() looks like a fairly expensive syscall on Windows, while
// IsAbs() is a whole bunch of string mangling. I think IsAbs() may be
// somewhat faster in the general case, hence the outer if...
if path, err := filepath.Abs(cleaned); err == nil {
cleaned = path
}
}
// Attempt to enable long filename support on Windows. We may still not
// have an absolute path here if the previous steps failed.
if runtime.GOOS == "windows" && filepath.IsAbs(cleaned) && !strings.HasPrefix(f.RawPath, `\\`) {
return `\\?\` + cleaned
}
// If we're not on Windows, we want the path to end with a slash to
// penetrate symlinks. On Windows, paths must not end with a slash.
if runtime.GOOS != "windows" && cleaned[len(cleaned)-1] != filepath.Separator {
cleaned = cleaned + string(filepath.Separator)
}
return cleaned
}
type FolderDeviceConfigurationList []FolderDeviceConfiguration
func (l FolderDeviceConfigurationList) Less(a, b int) bool {
@@ -223,3 +202,7 @@ func (l FolderDeviceConfigurationList) Swap(a, b int) {
func (l FolderDeviceConfigurationList) Len() int {
return len(l)
}
func (f *FolderConfiguration) CheckFreeSpace() (err error) {
return checkFreeSpace(f.MinDiskFree, f.Filesystem())
}

View File

@@ -13,16 +13,17 @@ import (
)
type GUIConfiguration struct {
Enabled bool `xml:"enabled,attr" json:"enabled" default:"true"`
RawAddress string `xml:"address" json:"address" default:"127.0.0.1:8384"`
User string `xml:"user,omitempty" json:"user"`
Password string `xml:"password,omitempty" json:"password"`
RawUseTLS bool `xml:"tls,attr" json:"useTLS"`
APIKey string `xml:"apikey,omitempty" json:"apiKey"`
InsecureAdminAccess bool `xml:"insecureAdminAccess,omitempty" json:"insecureAdminAccess"`
Theme string `xml:"theme" json:"theme" default:"default"`
Debugging bool `xml:"debugging,attr" json:"debugging"`
InsecureSkipHostCheck bool `xml:"insecureSkipHostcheck,omitempty" json:"insecureSkipHostcheck"`
Enabled bool `xml:"enabled,attr" json:"enabled" default:"true"`
RawAddress string `xml:"address" json:"address" default:"127.0.0.1:8384"`
User string `xml:"user,omitempty" json:"user"`
Password string `xml:"password,omitempty" json:"password"`
RawUseTLS bool `xml:"tls,attr" json:"useTLS"`
APIKey string `xml:"apikey,omitempty" json:"apiKey"`
InsecureAdminAccess bool `xml:"insecureAdminAccess,omitempty" json:"insecureAdminAccess"`
Theme string `xml:"theme" json:"theme" default:"default"`
Debugging bool `xml:"debugging,attr" json:"debugging"`
InsecureSkipHostCheck bool `xml:"insecureSkipHostcheck,omitempty" json:"insecureSkipHostcheck"`
InsecureAllowFrameLoading bool `xml:"insecureAllowFrameLoading,omitempty" json:"insecureAllowFrameLoading"`
}
func (c GUIConfiguration) Address() string {

View File

@@ -112,6 +112,7 @@ type OptionsConfiguration struct {
NATRenewalM int `xml:"natRenewalMinutes" json:"natRenewalMinutes" default:"30"`
NATTimeoutS int `xml:"natTimeoutSeconds" json:"natTimeoutSeconds" default:"10"`
URAccepted int `xml:"urAccepted" json:"urAccepted"` // Accepted usage reporting version; 0 for off (undecided), -1 for off (permanently)
URSeen int `xml:"urSeen" json:"urSeen"` // Report which the user has been prompted for.
URUniqueID string `xml:"urUniqueID" json:"urUniqueId"` // Unique ID for reporting purposes, regenerated when UR is turned on.
URURL string `xml:"urURL" json:"urURL" default:"https://data.syncthing.net/newdata"`
URPostInsecurely bool `xml:"urPostInsecurely" json:"urPostInsecurely" default:"false"` // For testing
@@ -133,13 +134,13 @@ type OptionsConfiguration struct {
WeakHashSelectionMethod WeakHashSelectionMethod `xml:"weakHashSelectionMethod" json:"weakHashSelectionMethod"`
StunServers []string `xml:"stunServer" json:"stunServers" default:"default"`
StunKeepaliveS int `xml:"stunKeepaliveSeconds" json:"stunKeepaliveSeconds" default:"24"`
DefaultKCPEnabled bool `xml:"defaultKCPEnabled" json:"defaultKCPEnabled" default:"false"`
KCPNoDelay bool `xml:"kcpNoDelay" json:"kcpNoDelay" default:"false"`
KCPUpdateIntervalMs int `xml:"kcpUpdateIntervalMs" json:"kcpUpdateIntervalMs" default:"25"`
KCPFastResend bool `xml:"kcpFastResend" json:"kcpFastResend" default:"false"`
KCPCongestionControl bool `xml:"kcpCongestionControl" json:"kcpCongestionControl" default:"true"`
KCPSendWindowSize int `xml:"kcpSendWindowSize" json:"kcpSendWindowSize" default:"128"`
KCPReceiveWindowSize int `xml:"kcpReceiveWindowSize" json:"kcpReceiveWindowSize" default:"128"`
DefaultFolderPath string `xml:"defaultFolderPath" json:"defaultFolderPath" default:"~"`
DeprecatedUPnPEnabled bool `xml:"upnpEnabled,omitempty" json:"-"`
DeprecatedUPnPLeaseM int `xml:"upnpLeaseMinutes,omitempty" json:"-"`

View File

@@ -10,6 +10,8 @@ import (
"fmt"
"strconv"
"strings"
"github.com/syncthing/syncthing/lib/fs"
)
type Size struct {
@@ -73,3 +75,24 @@ func (s Size) String() string {
func (Size) ParseDefault(s string) (interface{}, error) {
return ParseSize(s)
}
func checkFreeSpace(req Size, fs fs.Filesystem) error {
val := req.BaseValue()
if val <= 0 {
return nil
}
usage, err := fs.Usage(".")
if req.Percentage() {
freePct := (float64(usage.Free) / float64(usage.Total)) * 100
if err == nil && freePct < val {
return fmt.Errorf("insufficient space in %v %v: %f %% < %v", fs.Type(), fs.URI(), freePct, req)
}
} else {
if err == nil && float64(usage.Free) < val {
return fmt.Errorf("insufficient space in %v %v: %v < %v", fs.Type(), fs.URI(), usage.Free, req)
}
}
return nil
}

View File

@@ -38,11 +38,11 @@
<stunKeepaliveSeconds>10</stunKeepaliveSeconds>
<stunServer>a.stun.com</stunServer>
<stunServer>b.stun.com</stunServer>
<defaultKCPEnabled>true</defaultKCPEnabled>
<kcpCongestionControl>false</kcpCongestionControl>
<kcpReceiveWindowSize>1280</kcpReceiveWindowSize>
<kcpSendWindowSize>1280</kcpSendWindowSize>
<kcpUpdateIntervalMs>1000</kcpUpdateIntervalMs>
<kcpFastResend>true</kcpFastResend>
<kcpCongestionControl>false</kcpCongestionControl>
<kcpReceiveWindowSize>1280</kcpReceiveWindowSize>
<kcpSendWindowSize>1280</kcpSendWindowSize>
<kcpUpdateIntervalMs>1000</kcpUpdateIntervalMs>
<kcpFastResend>true</kcpFastResend>
<defaultFolderPath>/media/syncthing</defaultFolderPath>
</options>
</configuration>

15
lib/config/testdata/v21.xml vendored Normal file
View File

@@ -0,0 +1,15 @@
<configuration version="21">
<folder id="test" path="testdata" type="readonly" ignorePerms="false" rescanIntervalS="600" autoNormalize="true">
<device id="AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR"></device>
<device id="P56IOI7-MZJNU2Y-IQGDREY-DM2MGTI-MGL3BXN-PQ6W5BM-TBBZ4TJ-XZWICQ2"></device>
<minDiskFree unit="%">1</minDiskFree>
<maxConflicts>-1</maxConflicts>
<fsync>true</fsync>
</folder>
<device id="AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR" name="node one" compression="metadata">
<address>tcp://a</address>
</device>
<device id="P56IOI7-MZJNU2Y-IQGDREY-DM2MGTI-MGL3BXN-PQ6W5BM-TBBZ4TJ-XZWICQ2" name="node two" compression="metadata">
<address>tcp://b</address>
</device>
</configuration>

16
lib/config/testdata/v22.xml vendored Normal file
View File

@@ -0,0 +1,16 @@
<configuration version="22">
<folder id="test" path="testdata" type="readonly" ignorePerms="false" rescanIntervalS="600" autoNormalize="true">
<filesystemType>basic</filesystemType>
<device id="AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR"></device>
<device id="P56IOI7-MZJNU2Y-IQGDREY-DM2MGTI-MGL3BXN-PQ6W5BM-TBBZ4TJ-XZWICQ2"></device>
<minDiskFree unit="%">1</minDiskFree>
<maxConflicts>-1</maxConflicts>
<fsync>true</fsync>
</folder>
<device id="AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR" name="node one" compression="metadata">
<address>tcp://a</address>
</device>
<device id="P56IOI7-MZJNU2Y-IQGDREY-DM2MGTI-MGL3BXN-PQ6W5BM-TBBZ4TJ-XZWICQ2" name="node two" compression="metadata">
<address>tcp://b</address>
</device>
</configuration>

16
lib/config/testdata/v23.xml vendored Normal file
View File

@@ -0,0 +1,16 @@
<configuration version="22">
<folder id="test" path="testdata" type="readonly" ignorePerms="false" rescanIntervalS="600" autoNormalize="true">
<filesystemType>basic</filesystemType>
<device id="AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR"></device>
<device id="P56IOI7-MZJNU2Y-IQGDREY-DM2MGTI-MGL3BXN-PQ6W5BM-TBBZ4TJ-XZWICQ2"></device>
<minDiskFree unit="%">1</minDiskFree>
<maxConflicts>-1</maxConflicts>
<fsync>true</fsync>
</folder>
<device id="AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR" name="node one" compression="metadata">
<address>tcp://a</address>
</device>
<device id="P56IOI7-MZJNU2Y-IQGDREY-DM2MGTI-MGL3BXN-PQ6W5BM-TBBZ4TJ-XZWICQ2" name="node two" compression="metadata">
<address>tcp://b</address>
</device>
</configuration>

Some files were not shown because too many files have changed in this diff Show More